diff --git a/ALICE3/TableProducer/alice3-multicharmTable.cxx b/ALICE3/TableProducer/alice3-multicharmTable.cxx index f667b5dcd0a..3c81557082a 100644 --- a/ALICE3/TableProducer/alice3-multicharmTable.cxx +++ b/ALICE3/TableProducer/alice3-multicharmTable.cxx @@ -124,6 +124,7 @@ struct alice3multicharmTable { Configurable xiccMaxEta{"xiccMaxEta", 1.5, "Max eta"}; Configurable massWindowXi{"massWindowXi", 0.015, "Mass window around Xi peak (GeV/c)"}; Configurable massWindowXiC{"massWindowXiC", 0.015, "Mass window around XiC peak (GeV/c)"}; + Configurable massWindowXiCC{"massWindowXiCC", 0.4, "Mass window around XiCC peak (GeV/c). Make sure that bkg region is included in this window"}; 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"}; @@ -251,6 +252,11 @@ struct alice3multicharmTable { } 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}); + + if (std::fabs(thisXiCCcandidate.mass - o2::constants::physics::MassXiCCPlusPlus) > massWindowXiCC) { + return false; + } + 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; @@ -717,7 +723,7 @@ struct alice3multicharmTable { histos.fill(HIST("hDCAxyXiCC"), std::fabs(xiccdcaXY * 1e+4)); histos.fill(HIST("hDCAzXiCC"), std::fabs(xiccdcaZ * 1e+4)); - if (std::fabs(thisXiCcandidate.eta) > xiccMaxEta) + if (std::fabs(thisXiCCcandidate.eta) > xiccMaxEta) continue; // not in central barrel histos.fill(HIST("hCharmBuilding"), 3.0f); diff --git a/ALICE3/Tasks/alice3-multicharm.cxx b/ALICE3/Tasks/alice3-multicharm.cxx index 083a8e206bd..15989109919 100644 --- a/ALICE3/Tasks/alice3-multicharm.cxx +++ b/ALICE3/Tasks/alice3-multicharm.cxx @@ -84,8 +84,8 @@ struct alice3multicharm { std::string prefix = "bdt"; // JSON group name Configurable ccdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable localPath{"localPath", "MCharm_BDTModel.onnx", "(std::string) Path to the local .onnx file."}; - Configurable pathCCDB{"btdPathCCDB", "Users/j/jekarlss/MLModels2", "Path on CCDB"}; - Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB. Exceptions: > 0 for the specific timestamp, 0 gets the run dependent timestamp"}; + Configurable pathCCDB{"btdPathCCDB", "Users/j/jekarlss/MLModels", "Path on CCDB"}; + Configurable timestampCCDB{"timestampCCDB", 1695750420200, "timestamp of the ONNX file for ML model used to query in CCDB. Please use 1695750420200"}; Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; Configurable enableOptimizations{"enableOptimizations", false, "Enables the ONNX extended model-optimization: sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED)"}; Configurable enableML{"enableML", false, "Enables bdt model"}; @@ -93,7 +93,7 @@ struct alice3multicharm { } bdt; ConfigurableAxis axisEta{"axisEta", {80, -4.0f, +4.0f}, "#eta"}; - ConfigurableAxis axisXicMass{"axisXicMass", {200, 2.368f, 2.568f}, "XiC Inv Mass (GeV/c^{2})"}; + ConfigurableAxis axisXicMass{"axisXicMass", {200, 2.368f, 2.568f}, "Xic Inv Mass (GeV/c^{2})"}; ConfigurableAxis axisXiccMass{"axisXiccMass", {200, 3.521f, 3.721f}, "Xicc Inv Mass (GeV/c^{2})"}; ConfigurableAxis axisDCA{"axisDCA", {400, 0, 400}, "DCA (#mum)"}; ConfigurableAxis axisRadiusLarge{"axisRadiusLarge", {1000, 0, 20}, "Decay radius (cm)"}; @@ -102,6 +102,7 @@ struct alice3multicharm { ConfigurableAxis axisNSigma{"axisNSigma", {21, -10, 10}, "nsigma"}; ConfigurableAxis axisDecayLength{"axisDecayLength", {2000, 0, 2000}, "Decay lenght (#mum)"}; ConfigurableAxis axisDcaDaughters{"axisDcaDaughters", {200, 0, 100}, "DCA (mum)"}; + ConfigurableAxis axisBDTScore{"axisBDTScore", {100, 0, 1}, "BDT Score"}; 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"}; Configurable xiMinDCAxy{"xiMinDCAxy", -1, "[0] in |DCAxy| > [0]+[1]/pT"}; @@ -133,21 +134,6 @@ struct alice3multicharm { void init(InitContext&) { - ccdb->setURL(bdt.ccdbUrl.value); - if (bdt.loadModelsFromCCDB) { - ccdbApi.init(bdt.ccdbUrl); - LOG(info) << "Fetching model for timestamp: " << bdt.timestampCCDB.value; - bool retrieveSuccessMCharm = ccdbApi.retrieveBlob(bdt.pathCCDB.value, ".", metadata, bdt.timestampCCDB.value, false, bdt.localPath.value); - - if (retrieveSuccessMCharm) { - bdtMCharm.initModel(bdt.localPath.value, bdt.enableOptimizations.value); - } else { - LOG(fatal) << "Error encountered while fetching/loading the MCharm model from CCDB! Maybe the model doesn't exist yet for this runnumber/timestamp?"; - } - } else { - bdtMCharm.initModel(bdt.localPath.value, bdt.enableOptimizations.value); - } - histos.add("SelectionQA/hDCAXicDaughters", "hDCAXicDaughters; DCA between Xic daughters (#mum)", kTH1D, {axisDcaDaughters}); histos.add("SelectionQA/hDCAXiccDaughters", "hDCAXiccDaughters; DCA between Xicc daughters (#mum)", kTH1D, {axisDcaDaughters}); histos.add("SelectionQA/hDCAxyXi", "hDCAxyXi; Xi DCAxy to PV (#mum)", kTH1D, {axisDCA}); @@ -249,6 +235,25 @@ struct alice3multicharm { histos.add("h3dXicc", "h3dXicc; Xicc pT (GeV/#it(c)); Xicc #eta; Xicc mass (GeV/#it(c)^{2})", kTH3D, {axisPt, axisEta, axisXiccMass}); if (bdt.enableML) { + ccdb->setURL(bdt.ccdbUrl.value); + if (bdt.loadModelsFromCCDB) { + ccdbApi.init(bdt.ccdbUrl); + LOG(info) << "Fetching model for timestamp: " << bdt.timestampCCDB.value; + bool retrieveSuccessMCharm = ccdbApi.retrieveBlob(bdt.pathCCDB.value, ".", metadata, bdt.timestampCCDB.value, false, bdt.localPath.value); + + if (retrieveSuccessMCharm) { + bdtMCharm.initModel(bdt.localPath.value, bdt.enableOptimizations.value); + } else { + LOG(fatal) << "Error encountered while fetching/loading the MCharm model from CCDB! Maybe the model doesn't exist yet for this runnumber/timestamp?"; + } + } else { + bdtMCharm.initModel(bdt.localPath.value, bdt.enableOptimizations.value); + } + + histos.add("hBDTScore", "hBDTScore", kTH1D, {axisBDTScore}); + histos.add("hBDTScoreVsXiccMass", "hBDTScoreVsXiccMass", kTH2D, {axisXiccMass, axisBDTScore}); + histos.add("hBDTScoreVsXiccPt", "hBDTScoreVsXiccPt", kTH2D, {axisPt, axisBDTScore}); + histos.add("h3dBDTScore", "h3dBDTScore", kTH3D, {axisPt, axisXiccMass, axisBDTScore}); for (const auto& score : bdt.requiredScores.value) { histPath = std::format("MLQA/RequiredBDTScore_{}/", static_cast(score * 100)); histPointers.insert({histPath + "hDCAXicDaughters", histos.add((histPath + "hDCAXicDaughters").c_str(), "hDCAXicDaughters", {kTH1D, {{axisDcaDaughters}}})}); @@ -289,10 +294,9 @@ struct alice3multicharm { } template - void genericProcessXicc(TMCharmCands xiccCands) + void genericProcessXicc(TMCharmCands const& xiccCands) { for (const auto& xiccCand : xiccCands) { - if (bdt.enableML) { std::vector inputFeatures{ xiccCand.xicDauDCA(), @@ -318,6 +322,11 @@ struct alice3multicharm { float* probabilityMCharm = bdtMCharm.evalModel(inputFeatures); float bdtScore = probabilityMCharm[1]; + histos.fill(HIST("hBDTScore"), bdtScore); + histos.fill(HIST("hBDTScoreVsXiccMass"), xiccCand.xiccMass(), bdtScore); + histos.fill(HIST("hBDTScoreVsXiccPt"), xiccCand.xiccPt(), bdtScore); + histos.fill(HIST("h3dBDTScore"), xiccCand.xiccPt(), xiccCand.xiccMass(), bdtScore); + for (const auto& requiredScore : bdt.requiredScores.value) { if (bdtScore > requiredScore) { histPath = std::format("MLQA/RequiredBDTScore_{}/", static_cast(requiredScore * 100)); diff --git a/Common/CCDB/TriggerAliases.h b/Common/CCDB/TriggerAliases.h index f1baf04fdcc..3ee5c3ba87c 100644 --- a/Common/CCDB/TriggerAliases.h +++ b/Common/CCDB/TriggerAliases.h @@ -12,10 +12,11 @@ #ifndef COMMON_CCDB_TRIGGERALIASES_H_ #define COMMON_CCDB_TRIGGERALIASES_H_ +#include + #include #include #include -#include enum triggerAliases { kINT7 = 0, @@ -57,7 +58,7 @@ class TriggerAliases TriggerAliases() = default; ~TriggerAliases() = default; - void AddAlias(uint32_t aliasId, std::string classNames) { mAliasToClassNames[aliasId] = classNames; } + void AddAlias(uint32_t aliasId, std::string const& classNames) { mAliasToClassNames[aliasId] = classNames; } void AddClassIdToAlias(uint32_t aliasId, int classId); const std::map& GetAliasToClassNamesMap() const { return mAliasToClassNames; } const std::map& GetAliasToTriggerMaskMap() const { return mAliasToTriggerMask; } diff --git a/Common/CCDB/ctpRateFetcher.cxx b/Common/CCDB/ctpRateFetcher.cxx index e20fc41616c..4dbec5d8c0c 100644 --- a/Common/CCDB/ctpRateFetcher.cxx +++ b/Common/CCDB/ctpRateFetcher.cxx @@ -11,18 +11,19 @@ #include "ctpRateFetcher.h" +#include +#include +#include +#include +#include + #include +#include #include -#include "CommonConstants/LHCConstants.h" -#include "DataFormatsCTP/Configuration.h" -#include "DataFormatsCTP/Scalers.h" -#include "DataFormatsParameters/GRPLHCIFData.h" -#include "CCDB/BasicCCDBManager.h" - namespace o2 { -double ctpRateFetcher::fetch(o2::ccdb::BasicCCDBManager* ccdb, uint64_t timeStamp, int runNumber, std::string sourceName, bool fCrashOnNull) +double ctpRateFetcher::fetch(o2::ccdb::BasicCCDBManager* ccdb, uint64_t timeStamp, int runNumber, const std::string& sourceName, bool fCrashOnNull) { setupRun(runNumber, ccdb, timeStamp); if (sourceName.find("ZNC") != std::string::npos) { @@ -69,7 +70,7 @@ double ctpRateFetcher::fetchCTPratesClasses(o2::ccdb::BasicCCDBManager* /*ccdb*/ LOG(warn) << "Trigger class " << className << " not found in CTPConfiguration"; return -1.; } - auto rate{mScalers->getRateGivenT(timeStamp * 1.e-3, classIndex, inputType)}; + auto rate{mScalers->getRateGivenT(timeStamp * 1.e-3, classIndex, inputType, 1)}; return pileUpCorrection(rate.second); } @@ -77,7 +78,7 @@ double ctpRateFetcher::fetchCTPratesInputs(o2::ccdb::BasicCCDBManager* /*ccdb*/, { std::vector recs = mScalers->getScalerRecordO2(); if (recs[0].scalersInps.size() == 48) { - return pileUpCorrection(mScalers->getRateGivenT(timeStamp * 1.e-3, input, 7).second); + return pileUpCorrection(mScalers->getRateGivenT(timeStamp * 1.e-3, input, 7, 1).second); } else { LOG(error) << "Inputs not available"; return -1.; @@ -109,7 +110,7 @@ void ctpRateFetcher::setupRun(int runNumber, o2::ccdb::BasicCCDBManager* ccdb, u delete mScalers; delete mLHCIFdata; } - std::map metadata; + std::map metadata; mLHCIFdata = ccdb->getSpecific("GLO/Config/GRPLHCIF", timeStamp, metadata); if (mLHCIFdata == nullptr) { LOG(fatal) << "GRPLHCIFData not in database, timestamp:" << timeStamp; diff --git a/Common/CCDB/ctpRateFetcher.h b/Common/CCDB/ctpRateFetcher.h index 6aaf5e3ebaa..9d4de6215d3 100644 --- a/Common/CCDB/ctpRateFetcher.h +++ b/Common/CCDB/ctpRateFetcher.h @@ -12,9 +12,9 @@ #ifndef COMMON_CCDB_CTPRATEFETCHER_H_ #define COMMON_CCDB_CTPRATEFETCHER_H_ -#include +#include -#include "CCDB/BasicCCDBManager.h" +#include namespace o2 { @@ -34,7 +34,7 @@ class ctpRateFetcher { public: ctpRateFetcher() = default; - double fetch(o2::ccdb::BasicCCDBManager* ccdb, uint64_t timeStamp, int runNumber, std::string sourceName, bool fCrashOnNull = true); + double fetch(o2::ccdb::BasicCCDBManager* ccdb, uint64_t timeStamp, int runNumber, const std::string& sourceName, bool fCrashOnNull = true); void setManualCleanup(bool manualCleanup = true) { mManualCleanup = manualCleanup; } diff --git a/Common/Core/CollisionAssociation.h b/Common/Core/CollisionAssociation.h index 69ec38a24db..e6b7f9f8cc5 100644 --- a/Common/Core/CollisionAssociation.h +++ b/Common/Core/CollisionAssociation.h @@ -20,13 +20,13 @@ #ifndef COMMON_CORE_COLLISIONASSOCIATION_H_ #define COMMON_CORE_COLLISIONASSOCIATION_H_ -#include +#include +#include +#include + #include #include - -#include "CommonConstants/LHCConstants.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" +#include namespace o2::aod { @@ -191,30 +191,30 @@ class CollisionAssociation for (auto& iterationWindow : trackIterationWindows) { bool iteratorMoved = false; const bool isAssignedTrackWindow = (iterationWindow.first != iterationWindow.second) ? iterationWindow.first.has_collision() : false; - for (auto track = iterationWindow.first; track != iterationWindow.second; ++track) { - int64_t trackBC = globalBC[track.filteredIndex()]; + for (auto trackInWindow = iterationWindow.first; trackInWindow != iterationWindow.second; ++trackInWindow) { + int64_t trackBC = globalBC[trackInWindow.filteredIndex()]; if (trackBC < 0) { continue; } // Optimization to avoid looping over the full track list each time. This builds on that tracks are sorted by BCs (which they should be because collisions are sorted by BCs) - const int64_t bcOffset = trackBC - (int64_t)collBC; + const int64_t bcOffset = trackBC - static_cast(collBC); if constexpr (isCentralBarrel) { // only for blocks with collision association if (isAssignedTrackWindow) { constexpr int margin = 200; if (!iteratorMoved && bcOffset > -bcOffsetMax - margin) { - iterationWindow.first.setCursor(track.filteredIndex()); + iterationWindow.first.setCursor(trackInWindow.filteredIndex()); iteratorMoved = true; - LOGP(debug, "Moving iterator begin {}", track.filteredIndex()); + LOGP(debug, "Moving iterator begin {}", trackInWindow.filteredIndex()); } else if (bcOffset > bcOffsetMax + margin) { - LOGP(debug, "Stopping iterator {}", track.filteredIndex()); + LOGP(debug, "Stopping iterator {}", trackInWindow.filteredIndex()); break; } } } - int64_t bcOffsetWindow = trackBCCache[track.filteredIndex()] - (int64_t)collBC; + int64_t bcOffsetWindow = trackBCCache[trackInWindow.filteredIndex()] - static_cast(collBC); if (std::abs(bcOffsetWindow) > bcOffsetMax) { continue; } @@ -222,27 +222,27 @@ class CollisionAssociation float trackTime = 0; float trackTimeRes = 0; if constexpr (isCentralBarrel) { - if (mUsePvAssociation && track.isPVContributor()) { - trackTime = track.collision().collisionTime(); // if PV contributor, we assume the time to be the one of the collision - trackTimeRes = o2::constants::lhc::LHCBunchSpacingNS; // 1 BC + if (mUsePvAssociation && trackInWindow.isPVContributor()) { + trackTime = trackInWindow.collision().collisionTime(); // if PV contributor, we assume the time to be the one of the collision + trackTimeRes = o2::constants::lhc::LHCBunchSpacingNS; // 1 BC } else { - trackTime = track.trackTime(); - trackTimeRes = track.trackTimeRes(); + trackTime = trackInWindow.trackTime(); + trackTimeRes = trackInWindow.trackTimeRes(); } } else { - trackTime = track.trackTime(); - trackTimeRes = track.trackTimeRes(); + trackTime = trackInWindow.trackTime(); + trackTimeRes = trackInWindow.trackTimeRes(); } const float deltaTime = trackTime - collTime + bcOffset * o2::constants::lhc::LHCBunchSpacingNS; float sigmaTimeRes2 = collTimeRes2 + trackTimeRes * trackTimeRes; - LOGP(debug, "collision time={}, collision time res={}, track time={}, track time res={}, bc collision={}, bc track={}, delta time={}", collTime, collision.collisionTimeRes(), track.trackTime(), track.trackTimeRes(), collBC, trackBC, deltaTime); + LOGP(debug, "collision time={}, collision time res={}, track time={}, track time res={}, bc collision={}, bc track={}, delta time={}", collTime, collision.collisionTimeRes(), trackInWindow.trackTime(), trackInWindow.trackTimeRes(), collBC, trackBC, deltaTime); float thresholdTime = 0.; if constexpr (isCentralBarrel) { - if (mUsePvAssociation && track.isPVContributor()) { + if (mUsePvAssociation && trackInWindow.isPVContributor()) { thresholdTime = trackTimeRes; - } else if (TESTBIT(track.flags(), o2::aod::track::TrackTimeResIsRange)) { + } else if (TESTBIT(trackInWindow.flags(), o2::aod::track::TrackTimeResIsRange)) { // the track time resolution is a range, not a gaussian resolution thresholdTime = trackTimeRes + mNumSigmaForTimeCompat * std::sqrt(collTimeRes2) + mTimeMargin; } else { @@ -262,7 +262,7 @@ class CollisionAssociation if (std::abs(deltaTime) < thresholdTime) { const auto collIdx = collision.globalIndex(); - const auto trackIdx = track.globalIndex(); + const auto trackIdx = trackInWindow.globalIndex(); LOGP(debug, "Filling track id {} for coll id {}", trackIdx, collIdx); association(collIdx, trackIdx); if (mFillTableOfCollIdsPerTrack) { @@ -278,9 +278,9 @@ class CollisionAssociation // create reverse index track to collisions if enabled if (mFillTableOfCollIdsPerTrack) { std::vector empty{}; - for (const auto& track : tracksUnfiltered) { + for (const auto& trackUnfiltered : tracksUnfiltered) { - const auto trackId = track.globalIndex(); + const auto trackId = trackUnfiltered.globalIndex(); if (collsPerTrack[trackId] == nullptr) { reverseIndices(empty); } else { diff --git a/Common/Core/CollisionTypeHelper.cxx b/Common/Core/CollisionTypeHelper.cxx index 4d7e1de3f87..10e23f19423 100644 --- a/Common/Core/CollisionTypeHelper.cxx +++ b/Common/Core/CollisionTypeHelper.cxx @@ -17,9 +17,8 @@ #include "Common/Core/CollisionTypeHelper.h" -#include "DataFormatsParameters/GRPLHCIFData.h" - -#include +#include +#include #include diff --git a/Common/Core/EventPlaneHelper.cxx b/Common/Core/EventPlaneHelper.cxx index 75424d900d9..8c8cb88c896 100644 --- a/Common/Core/EventPlaneHelper.cxx +++ b/Common/Core/EventPlaneHelper.cxx @@ -20,13 +20,14 @@ #include "Common/Core/EventPlaneHelper.h" +#include +#include + #include +#include #include -#include #include - -#include "TMath.h" -#include "TVector3.h" +#include double EventPlaneHelper::GetPhiFV0(int chno, o2::fv0::Geometry* fv0geom) { @@ -37,8 +38,8 @@ double EventPlaneHelper::GetPhiFV0(int chno, o2::fv0::Geometry* fv0geom) float offsetX = 0.; float offsetY = 0.; - int cellsInLeft[] = {0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27, - 32, 40, 33, 41, 34, 42, 35, 43}; + const int cellsInLeft[] = {0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27, + 32, 40, 33, 41, 34, 42, 35, 43}; bool isChnoInLeft = std::find(std::begin(cellsInLeft), std::end(cellsInLeft), chno) != std::end(cellsInLeft); if (isChnoInLeft) { @@ -131,10 +132,10 @@ void EventPlaneHelper::DoCorrections(float& qx, float& qy, qy = (qy - corrections[2] * qx) / (1.0 - corrections[3] * corrections[2]); // Rescaling of the Qx-Qy into a circle. - if (fabs(corrections[4]) > 1e-8) { + if (std::fabs(corrections[4]) > 1e-8) { qx /= corrections[4]; } - if (fabs(corrections[5]) > 1e-8) { + if (std::fabs(corrections[5]) > 1e-8) { qy /= corrections[5]; } } @@ -153,9 +154,9 @@ void EventPlaneHelper::DoTwist(float& qx, float& qy, float lp, float lm) void EventPlaneHelper::DoRescale(float& qx, float& qy, float ap, float am) { - if (fabs(ap) > 1e-8) + if (std::fabs(ap) > 1e-8) qx /= ap; - if (fabs(am) > 1e-8) + if (std::fabs(am) > 1e-8) qy /= am; } diff --git a/Common/Core/FFitWeights.cxx b/Common/Core/FFitWeights.cxx index 3a92114f48c..4133d6453eb 100644 --- a/Common/Core/FFitWeights.cxx +++ b/Common/Core/FFitWeights.cxx @@ -16,12 +16,12 @@ #include "FFitWeights.h" -#include +#include + #include +#include #include -#include - ClassImp(FFitWeights) FFitWeights::FFitWeights() : TNamed("", ""), @@ -111,7 +111,7 @@ void FFitWeights::addArray(TObjArray* targ, TObjArray* sour) } }; -void FFitWeights::qSelection(std::vector nhv, std::vector stv) /* only execute OFFLINE */ +void FFitWeights::qSelection(const std::vector& nhv, const std::vector& stv) /* only execute OFFLINE */ { TObjArray* tar{nullptr}; diff --git a/Common/Core/FFitWeights.h b/Common/Core/FFitWeights.h index c80165730f7..68470f95b55 100644 --- a/Common/Core/FFitWeights.h +++ b/Common/Core/FFitWeights.h @@ -17,22 +17,22 @@ #ifndef COMMON_CORE_FFITWEIGHTS_H_ #define COMMON_CORE_FFITWEIGHTS_H_ -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include #include - -#include "TNamed.h" -#include "TObjArray.h" -#include "TH3D.h" -#include "TH2D.h" -#include "TH1D.h" -#include "TFile.h" -#include "TCollection.h" -#include "TString.h" -#include "TMath.h" +#include +#include +#include class FFitWeights : public TNamed { @@ -53,11 +53,11 @@ class FFitWeights : public TNamed TAxis* getqVecAx() { return qAxis; } Long64_t Merge(TCollection* collist); - void qSelection(std::vector nhv, std::vector stv); + void qSelection(const std::vector& nhv, const std::vector& stv); float eval(float centr, const float& dqn, const int nh, const char* pf = ""); void setResolution(int res) { nResolution = res; } int getResolution() const { return nResolution; } - void setQnType(std::vector> qninp) { qnTYPE = qninp; } + void setQnType(const std::vector>& qninp) { qnTYPE = qninp; } private: TObjArray* fW_data; diff --git a/Common/Core/MetadataHelper.cxx b/Common/Core/MetadataHelper.cxx index b8c2fe6ad22..91037d615d0 100644 --- a/Common/Core/MetadataHelper.cxx +++ b/Common/Core/MetadataHelper.cxx @@ -17,8 +17,10 @@ #include "Common/Core/MetadataHelper.h" -#include "Framework/InitContext.h" -#include "Framework/RunningWorkflowInfo.h" +#include +#include + +#include using namespace o2::common::core; diff --git a/Common/Core/MetadataHelper.h b/Common/Core/MetadataHelper.h index 45eb4e8651c..f3522a5d190 100644 --- a/Common/Core/MetadataHelper.h +++ b/Common/Core/MetadataHelper.h @@ -8,8 +8,6 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. - -/// /// \file TableHelper.h /// \author Nicolò Jacazio nicolo.jacazio@cern.ch /// \brief Utility to handle the metadata from the AOD @@ -70,6 +68,4 @@ struct MetadataHelper { } // namespace o2::common::core -using MetadataHelper = o2::common::core::MetadataHelper; // Alias for the MetadataHelper - #endif // COMMON_CORE_METADATAHELPER_H_ diff --git a/Common/Core/OrbitRange.h b/Common/Core/OrbitRange.h index 65e3abe2c69..f499b771e9b 100644 --- a/Common/Core/OrbitRange.h +++ b/Common/Core/OrbitRange.h @@ -13,16 +13,17 @@ // Container to store minimum and maximum orbit counter // -#ifndef OrbitRange_H -#define OrbitRange_H +#ifndef COMMON_CORE_ORBITRANGE_H_ +#define COMMON_CORE_ORBITRANGE_H_ + +#include -#include "TNamed.h" class TCollection; class OrbitRange : public TNamed { public: - OrbitRange(const char* name = "orbitRange") : TNamed(name, name), fRunNumber(0), fMinOrbit(0xFFFFFFFF), fMaxOrbit(0) {} + explicit OrbitRange(const char* name = "orbitRange") : TNamed(name, name), fRunNumber(0), fMinOrbit(0xFFFFFFFF), fMaxOrbit(0) {} ~OrbitRange() {} void SetRunNumber(uint32_t runNumber) { fRunNumber = runNumber; } void SetMinOrbit(uint32_t orbit) { fMinOrbit = orbit; } @@ -39,4 +40,4 @@ class OrbitRange : public TNamed ClassDef(OrbitRange, 1) }; -#endif +#endif // COMMON_CORE_ORBITRANGE_H_ diff --git a/Common/Core/PID/DetectorResponse.h b/Common/Core/PID/DetectorResponse.h index 1f687a4605c..7b8c5bb2406 100644 --- a/Common/Core/PID/DetectorResponse.h +++ b/Common/Core/PID/DetectorResponse.h @@ -17,21 +17,25 @@ /// This provides the basic quantities computed by any response i.e. expected values, resolutions and Nsigmas /// -#ifndef O2_ANALYSIS_PID_DETECTORRESPONSE_H_ -#define O2_ANALYSIS_PID_DETECTORRESPONSE_H_ +#ifndef COMMON_CORE_PID_DETECTORRESPONSE_H_ +#define COMMON_CORE_PID_DETECTORRESPONSE_H_ + +#include #include +#include #include -#include "Framework/Logger.h" // ROOT includes -#include "Rtypes.h" -#include "TMath.h" -#include "TFile.h" +#include +#include + +#include // O2 includes -#include "ReconstructionDataFormats/PID.h" #include "Common/Core/PID/ParamBase.h" +#include + namespace o2::pid { /// \brief Class to handle the general detector response @@ -52,7 +56,7 @@ class DetectorResponse /// \param fname File name used for input /// \param pname Name of the parametrization in the file /// \param ptype Type of the parametrization - void LoadParamFromFile(const TString fname, const TString pname, const Param_t ptype); + void LoadParamFromFile(const TString& fname, const TString& pname, const Param_t ptype); /// Setter for the parametrization /// \param ptype Type of the parametrization @@ -65,7 +69,7 @@ class DetectorResponse /// Setter for the parametrizations parameters, if the parametrization is not yet initialized a new parametrization is created without any implementation and just parameters /// \param ptype parametrization type /// \param p vector with parameters - void SetParameters(const Param_t ptype, std::vector p); + void SetParameters(const Param_t ptype, const std::vector& p); /// Getter for the value of the parametrization /// \param ptype parametrization type @@ -85,7 +89,7 @@ inline void DetectorResponse::LoadParam(const Param_t ptype, Parametrization* pa mParam[ptype] = param; } -inline void DetectorResponse::LoadParamFromFile(const TString fname, const TString pname, const Param_t ptype) +inline void DetectorResponse::LoadParamFromFile(const TString& fname, const TString& pname, const Param_t ptype) { TFile f(fname, "READ"); if (!f.Get(pname)) { @@ -97,7 +101,7 @@ inline void DetectorResponse::LoadParamFromFile(const TString fname, const TStri mParam[ptype]->Print(); } -inline void DetectorResponse::SetParameters(const DetectorResponse::Param_t ptype, std::vector p) +inline void DetectorResponse::SetParameters(const DetectorResponse::Param_t ptype, const std::vector& p) { if (!mParam[ptype]) { const std::string pname = std::string(ParamName[ptype]) + "_default_param"; @@ -110,4 +114,4 @@ inline void DetectorResponse::SetParameters(const DetectorResponse::Param_t ptyp } // namespace o2::pid -#endif // O2_ANALYSIS_PID_DETECTORRESPONSE_H_ +#endif // COMMON_CORE_PID_DETECTORRESPONSE_H_ diff --git a/Common/Core/PID/PIDTOF.h b/Common/Core/PID/PIDTOF.h index ad16716916c..5822732dc5c 100644 --- a/Common/Core/PID/PIDTOF.h +++ b/Common/Core/PID/PIDTOF.h @@ -24,18 +24,19 @@ #include // ROOT includes -#include "Rtypes.h" -#include "TMath.h" -#include "TGraph.h" -#include "TFile.h" -#include "TF2.h" +#include +#include +#include +#include + +#include // O2 includes -#include "DataFormatsTOF/ParameterContainers.h" -#include "Framework/Logger.h" -#include "ReconstructionDataFormats/PID.h" -#include "Framework/DataTypes.h" -#include "CommonConstants/PhysicsConstants.h" +#include +#include +#include +#include +#include namespace o2::pid::tof { @@ -444,7 +445,7 @@ class ExpTimes static constexpr float mMassZSqared = mMassZ * mMassZ; /// (M/z)^2 /// Computes the expected time of a track, given it TOF expected momentum - static float ComputeExpectedTime(const float tofExpMom, const float length) { return length * sqrt((mMassZSqared) + (tofExpMom * tofExpMom)) / (o2::constants::physics::LightSpeedCm2PS * tofExpMom); } + static float ComputeExpectedTime(const float tofExpMom, const float length) { return length * std::sqrt((mMassZSqared) + (tofExpMom * tofExpMom)) / (o2::constants::physics::LightSpeedCm2PS * tofExpMom); } /// Gets the expected signal of the track of interest under the PID assumption /// \param track Track of interest @@ -485,11 +486,11 @@ class ExpTimes static float GetExpectedSigma(const ParamType& parameters, const TrackType& track, const float tofSignal, const float collisionTimeRes) { const float& mom = track.p(); - const float& eta = track.eta(); + const float& etaTrack = track.eta(); if (mom <= 0) { return -999.f; } - const float reso = parameters.template getResolution(mom, eta); + const float reso = parameters.template getResolution(mom, etaTrack); if (reso > 0) { return std::sqrt(reso * reso + parameters[4] * parameters[4] + collisionTimeRes * collisionTimeRes); } diff --git a/Common/Core/PID/ParamBase.cxx b/Common/Core/PID/ParamBase.cxx index 74824781d07..a79ed660b7d 100644 --- a/Common/Core/PID/ParamBase.cxx +++ b/Common/Core/PID/ParamBase.cxx @@ -17,14 +17,17 @@ /// These are the basic storage elements to be kept in the CCDB /// -#include "PID/ParamBase.h" -#include "Framework/Logger.h" -#include "TFile.h" +#include +#include + +#include + +#include namespace o2::pid { -void Parameters::SetParameters(const std::vector params) +void Parameters::SetParameters(const std::vector& params) { if (mPar.size() != params.size()) { LOG(fatal) << "Updating parametrization size! Trying to fit a parametrization of size " << params.size() << " into one of size " << mPar.size(); @@ -40,7 +43,7 @@ void Parameters::Print(Option_t* /*options*/) const } }; -void Parameters::LoadParamFromFile(const TString FileName, const TString ParamName) +void Parameters::LoadParamFromFile(const TString& FileName, const TString& ParamName) { TFile f(FileName, "READ"); if (!f.Get(ParamName)) { @@ -66,7 +69,7 @@ void Parametrization::Print(Option_t* options) const mParameters.Print(options); }; -void Parametrization::LoadParamFromFile(const TString FileName, const TString ParamName) +void Parametrization::LoadParamFromFile(const TString& FileName, const TString& ParamName) { TFile f(FileName, "READ"); if (!f.Get(ParamName)) { diff --git a/Common/Core/PID/ParamBase.h b/Common/Core/PID/ParamBase.h index ec4b17083f4..cc7812c3036 100644 --- a/Common/Core/PID/ParamBase.h +++ b/Common/Core/PID/ParamBase.h @@ -26,10 +26,10 @@ #include // std::vector // ROOT includes -#include "TNamed.h" -#include "TFile.h" +#include -#include "Framework/Logger.h" +#include +#include namespace o2::pid { @@ -49,11 +49,11 @@ class Parameters : public TNamed /// Parametric constructor /// \param size Number of parameters in the container - Parameters(const TString name, unsigned int size) : TNamed(name, name), mPar(std::vector(size)) {} + Parameters(const TString& name, unsigned int size) : TNamed(name, name), mPar(std::vector(size)) {} /// Parametric constructor /// \param params Parameters to initialize the container - Parameters(const TString name, const std::vector params) : TNamed(name, name), mPar{} { SetParameters(params); } + Parameters(const TString& name, const std::vector& params) : TNamed(name, name), mPar{} { SetParameters(params); } /// Default destructor ~Parameters() override = default; @@ -69,11 +69,11 @@ class Parameters : public TNamed /// Setter for the parameter, using a vector /// \param params vector with parameters - void SetParameters(const std::vector params); + void SetParameters(const std::vector& params); /// Setter for the parameter, using a parameter object /// \param params parameter object with parameters - void SetParameters(const Parameters params) { SetParameters(params.mPar); } + void SetParameters(const Parameters& params) { SetParameters(params.mPar); } /// Setter for the parameter, using a parameter pointer /// \param params pointer to parameter object with parameters @@ -85,7 +85,7 @@ class Parameters : public TNamed /// Loader from file /// \param FileName name of the input file /// \param ParamName name of the input object - void LoadParamFromFile(const TString FileName, const TString ParamName); + void LoadParamFromFile(const TString& FileName, const TString& ParamName); /// Getter for the parameters /// \return returns an array of parameters @@ -138,7 +138,7 @@ class PidParameters : public TNamed /// Setter for the parameter, using a parameter object /// \param params parameter object with parameters - void SetParameters(const PidParameters params) { SetParameters(params.mPar); } + void SetParameters(const PidParameters& params) { SetParameters(params.mPar); } /// Setter for the parameter, using a parameter pointer /// \param params pointer to parameter object with parameters @@ -164,7 +164,7 @@ class PidParameters : public TNamed /// Loader from file /// \param FileName name of the input file /// \param ParamName name of the input object - void LoadParamFromFile(const TString FileName, const TString ParamName) + void LoadParamFromFile(const TString& FileName, const TString& ParamName) { TFile f(FileName, "READ"); if (!f.Get(ParamName)) { @@ -215,12 +215,12 @@ class Parametrization : public TNamed /// Parametric constructor /// \param name Name (and title) of the parametrization /// \param size Number of parameters of the parametrization - Parametrization(TString name, unsigned int size) : TNamed(name, name), mParameters(name + "Parameters", size) {} + Parametrization(const TString& name, unsigned int size) : TNamed(name, name), mParameters(name + "Parameters", size) {} /// Parametric constructor /// \param name Name (and title) of the parametrization /// \param params Parameters of the parametrization - Parametrization(TString name, const std::vector params) : TNamed(name, name), mParameters{name + "Parameters", params} {} + Parametrization(const TString& name, const std::vector& params) : TNamed(name, name), mParameters{name + "Parameters", params} {} /// Default destructor ~Parametrization() override = default; @@ -235,7 +235,7 @@ class Parametrization : public TNamed /// Loader from file /// \param FileName name of the input file /// \param ParamName name of the input object - void LoadParamFromFile(const TString FileName, const TString ParamName); + void LoadParamFromFile(const TString& FileName, const TString& ParamName); /// Setter for the parameter at position iparam /// \param iparam index in the array of the parameters diff --git a/Common/Core/PID/TPCPIDResponse.h b/Common/Core/PID/TPCPIDResponse.h index f25e1acd69e..deafdf4fed2 100644 --- a/Common/Core/PID/TPCPIDResponse.h +++ b/Common/Core/PID/TPCPIDResponse.h @@ -74,12 +74,18 @@ class Response /// Gets the expected resolution of the track template float GetExpectedSigma(const CollisionType& collision, const TrackType& trk, const o2::track::PID::ID id) const; + /// Gets the expected resolution of the track with multTPC explicitly provided + template + float GetExpectedSigmaAtMultiplicity(const long multTPC, const TrackType& trk, const o2::track::PID::ID id) const; /// Gets the number of sigmas with respect the expected value template float GetNumberOfSigma(const CollisionType& collision, const TrackType& trk, const o2::track::PID::ID id) const; // Number of sigmas with respect to expected for MC, defining a tune-on-data signal value template float GetNumberOfSigmaMCTuned(const CollisionType& collision, const TrackType& trk, const o2::track::PID::ID id, float mcTunedTPCSignal) const; + // Number of sigmas with respect to expected for MC, defining a tune-on-data signal value, explicit multTPC + template + float GetNumberOfSigmaMCTunedAtMultiplicity(const long multTPC, const TrackType& trk, const o2::track::PID::ID id, float mcTunedTPCSignal) const; /// Gets the deviation to the expected signal template float GetSignalDelta(const TrackType& trk, const o2::track::PID::ID id) const; @@ -116,6 +122,14 @@ inline float Response::GetExpectedSignal(const TrackType& track, const o2::track /// Gets the expected resolution of the measurement template inline float Response::GetExpectedSigma(const CollisionType& collision, const TrackType& track, const o2::track::PID::ID id) const +{ + // use multTPC (legacy behaviour) if multTPC not provided + return Response::GetExpectedSigmaAtMultiplicity(collision.multTPC(), track, id); +} + +/// Gets the expected resolution of the measurement +template +inline float Response::GetExpectedSigmaAtMultiplicity(const long multTPC, const TrackType& track, const o2::track::PID::ID id) const { if (!track.hasTPC()) { return -999.f; @@ -133,7 +147,7 @@ inline float Response::GetExpectedSigma(const CollisionType& collision, const Tr const double dEdx = o2::tpc::BetheBlochAleph(static_cast(bg), mBetheBlochParams[0], mBetheBlochParams[1], mBetheBlochParams[2], mBetheBlochParams[3], mBetheBlochParams[4]) * std::pow(static_cast(o2::track::pid_constants::sCharges[id]), mChargeFactor); const double relReso = GetRelativeResolutiondEdx(p, mass, o2::track::pid_constants::sCharges[id], mResolutionParams[3]); - const std::vector values{1.f / dEdx, track.tgl(), std::sqrt(ncl), relReso, track.signed1Pt(), collision.multTPC() / mMultNormalization}; + const std::vector values{1.f / dEdx, track.tgl(), std::sqrt(ncl), relReso, track.signed1Pt(), multTPC / mMultNormalization}; const float reso = sqrt(pow(mResolutionParams[0], 2) * values[0] + pow(mResolutionParams[1], 2) * (values[2] * mResolutionParams[5]) * pow(values[0] / sqrt(1 + pow(values[1], 2)), mResolutionParams[2]) + values[2] * pow(values[3], 2) + pow(mResolutionParams[4] * values[4], 2) + pow(values[5] * mResolutionParams[6], 2) + pow(values[5] * (values[0] / sqrt(1 + pow(values[1], 2))) * mResolutionParams[7], 2)) * dEdx * mMIP; reso >= 0.f ? resolution = reso : resolution = -999.f; @@ -160,7 +174,13 @@ inline float Response::GetNumberOfSigma(const CollisionType& collision, const Tr template inline float Response::GetNumberOfSigmaMCTuned(const CollisionType& collision, const TrackType& trk, const o2::track::PID::ID id, float mcTunedTPCSignal) const { - if (GetExpectedSigma(collision, trk, id) < 0.) { + return Response::GetNumberOfSigmaMCTunedAtMultiplicity(collision.multTPC(), trk, id, mcTunedTPCSignal); +} + +template +inline float Response::GetNumberOfSigmaMCTunedAtMultiplicity(const long multTPC, const TrackType& trk, const o2::track::PID::ID id, float mcTunedTPCSignal) const +{ + if (GetExpectedSigmaAtMultiplicity(multTPC, trk, id) < 0.) { return -999.f; } if (GetExpectedSignal(trk, id) < 0.) { @@ -169,7 +189,7 @@ inline float Response::GetNumberOfSigmaMCTuned(const CollisionType& collision, c if (!trk.hasTPC()) { return -999.f; } - return ((mcTunedTPCSignal - GetExpectedSignal(trk, id)) / GetExpectedSigma(collision, trk, id)); + return ((mcTunedTPCSignal - GetExpectedSignal(trk, id)) / GetExpectedSigmaAtMultiplicity(multTPC, trk, id)); } /// Gets the deviation between the actual signal and the expected signal diff --git a/Common/Core/TableHelper.cxx b/Common/Core/TableHelper.cxx index 04745ffe694..57f03e43c35 100644 --- a/Common/Core/TableHelper.cxx +++ b/Common/Core/TableHelper.cxx @@ -17,8 +17,8 @@ #include "Common/Core/TableHelper.h" -#include "Framework/InitContext.h" -#include "Framework/RunningWorkflowInfo.h" +#include +#include #include @@ -26,7 +26,7 @@ /// @param initContext initContext of the init function void o2::common::core::printTablesInWorkflow(o2::framework::InitContext& initContext) { - auto& workflows = initContext.services().get(); + const auto& workflows = initContext.services().get(); for (auto const& device : workflows.devices) { for (auto const& input : device.inputs) { LOG(info) << "Table: " << input.matcher.binding << " in device: " << device.name; @@ -41,7 +41,7 @@ bool o2::common::core::isTableRequiredInWorkflow(o2::framework::InitContext& ini { LOG(debug) << "Checking if table " << table << " is needed"; bool tableNeeded = false; - auto& workflows = initContext.services().get(); + const auto& workflows = initContext.services().get(); for (auto const& device : workflows.devices) { for (auto const& input : device.inputs) { if (input.matcher.binding == table) { diff --git a/Common/Core/TableHelper.h b/Common/Core/TableHelper.h index 56d2264ed6c..40f31515a79 100644 --- a/Common/Core/TableHelper.h +++ b/Common/Core/TableHelper.h @@ -18,9 +18,9 @@ #ifndef COMMON_CORE_TABLEHELPER_H_ #define COMMON_CORE_TABLEHELPER_H_ -#include "Framework/Configurable.h" -#include "Framework/InitContext.h" -#include "Framework/RunningWorkflowInfo.h" +#include +#include +#include #include @@ -70,7 +70,7 @@ bool getTaskOptionValue(o2::framework::InitContext& initContext, const std::stri if (verbose) { LOG(info) << "Checking for option '" << optName << "' in task '" << taskName << "'"; } - auto& workflows = initContext.services().get(); + const auto& workflows = initContext.services().get(); int deviceCounter = 0; bool found = false; for (auto const& device : workflows.devices) { diff --git a/Common/Core/TrackSelection.cxx b/Common/Core/TrackSelection.cxx index 717d7db77f5..474a6859e0c 100644 --- a/Common/Core/TrackSelection.cxx +++ b/Common/Core/TrackSelection.cxx @@ -13,9 +13,14 @@ // Class for track selection // -#include "Framework/Logger.h" #include "Common/Core/TrackSelection.h" +#include + +#include +#include +#include + bool TrackSelection::FulfillsITSHitRequirements(uint8_t itsClusterMap) const { constexpr uint8_t bit = 1; @@ -167,7 +172,7 @@ void TrackSelection::print() const LOG(info) << mCutNames[i] << " == " << mRequireITSRefit; break; case TrackCuts::kITSHits: - for (auto& itsRequirement : mRequiredITSHits) { + for (const auto& itsRequirement : mRequiredITSHits) { LOG(info) << mCutNames[i] << " == " << itsRequirement.first; } break; diff --git a/Common/Core/TrackSelection.h b/Common/Core/TrackSelection.h index 19d77a198e1..4be97408f73 100644 --- a/Common/Core/TrackSelection.h +++ b/Common/Core/TrackSelection.h @@ -16,13 +16,15 @@ #ifndef COMMON_CORE_TRACKSELECTION_H_ #define COMMON_CORE_TRACKSELECTION_H_ +#include "Framework/DataTypes.h" +#include "Framework/Logger.h" + +#include + #include -#include -#include #include -#include "Framework/Logger.h" -#include "Framework/DataTypes.h" -#include "Rtypes.h" +#include +#include class TrackSelection { diff --git a/Common/Core/trackUtilities.h b/Common/Core/trackUtilities.h index e67e0f82d6f..21d30990e72 100644 --- a/Common/Core/trackUtilities.h +++ b/Common/Core/trackUtilities.h @@ -17,12 +17,14 @@ #ifndef COMMON_CORE_TRACKUTILITIES_H_ #define COMMON_CORE_TRACKUTILITIES_H_ -#include // std::move -#include "CommonConstants/MathConstants.h" -#include "ReconstructionDataFormats/Track.h" -#include "ReconstructionDataFormats/Vertex.h" #include "Common/Core/RecoDecay.h" +#include +#include +#include + +#include // std::move + /// Extracts track parameters from a track. template o2::track::TrackParametrization getTrackPar(const T& track) @@ -122,12 +124,12 @@ auto getRotatedCovMatrixXX(const T& matrix, U phi, V theta) template void getPxPyPz(T const& trackPars, U& pVec) { - auto pt = 1.f / std::abs(trackPars.getQ2Pt()); + auto ptTrack = 1.f / std::abs(trackPars.getQ2Pt()); float cs = cosf(trackPars.getAlpha()), sn = sinf(trackPars.getAlpha()); auto r = std::sqrt((1.f - trackPars.getSnp()) * (1.f + trackPars.getSnp())); - pVec[0] = pt * (r * cs - trackPars.getSnp() * sn); - pVec[1] = pt * (trackPars.getSnp() * cs + r * sn); - pVec[2] = pt * trackPars.getTgl(); + pVec[0] = ptTrack * (r * cs - trackPars.getSnp() * sn); + pVec[1] = ptTrack * (trackPars.getSnp() * cs + r * sn); + pVec[2] = ptTrack * trackPars.getTgl(); } /// Calculates DCA XYZ of a track w.r.t. the primary vertex and its uncertainty if required. diff --git a/Common/DataModel/Multiplicity.h b/Common/DataModel/Multiplicity.h index d2db60732f2..8d1e9b10ab3 100644 --- a/Common/DataModel/Multiplicity.h +++ b/Common/DataModel/Multiplicity.h @@ -211,12 +211,14 @@ using MultHepMCHI = MultHepMCHIs::iterator; namespace multZeq { -DECLARE_SOA_COLUMN(MultZeqFV0A, multZeqFV0A, float); //! Multiplicity equalized for the vertex position with the FV0A detector -DECLARE_SOA_COLUMN(MultZeqFT0A, multZeqFT0A, float); //! Multiplicity equalized for the vertex position with the FT0A detector -DECLARE_SOA_COLUMN(MultZeqFT0C, multZeqFT0C, float); //! Multiplicity equalized for the vertex position with the FT0C detector -DECLARE_SOA_COLUMN(MultZeqFDDA, multZeqFDDA, float); //! Multiplicity equalized for the vertex position with the FDDA detector -DECLARE_SOA_COLUMN(MultZeqFDDC, multZeqFDDC, float); //! Multiplicity equalized for the vertex position with the FDDC detector -DECLARE_SOA_COLUMN(MultZeqNTracksPV, multZeqNTracksPV, float); //! Multiplicity equalized for the vertex position from the PV contributors +DECLARE_SOA_COLUMN(MultZeqFV0A, multZeqFV0A, float); //! Multiplicity equalized for the vertex position with the FV0A detector +DECLARE_SOA_COLUMN(MultZeqFT0A, multZeqFT0A, float); //! Multiplicity equalized for the vertex position with the FT0A detector +DECLARE_SOA_COLUMN(MultZeqFT0C, multZeqFT0C, float); //! Multiplicity equalized for the vertex position with the FT0C detector +DECLARE_SOA_COLUMN(MultZeqFDDA, multZeqFDDA, float); //! Multiplicity equalized for the vertex position with the FDDA detector +DECLARE_SOA_COLUMN(MultZeqFDDC, multZeqFDDC, float); //! Multiplicity equalized for the vertex position with the FDDC detector +DECLARE_SOA_COLUMN(MultZeqNTracksPV, multZeqNTracksPV, float); //! Multiplicity equalized for the vertex position from the PV contributors +DECLARE_SOA_COLUMN(MultZeqNTracksGlobal, multZeqNTracksGlobal, float); //! Multiplicity equalized for the vertex position, global tracks +DECLARE_SOA_COLUMN(MultZeqMFTNtracks, multZeqMFTNtracks, float); //! Multiplicity equalized for the vertex position, MFT tracks } // namespace multZeq DECLARE_SOA_TABLE(FV0MultZeqs, "AOD", "FV0MULTZEQ", //! Multiplicity equalized for the vertex position with the FV0 detector multZeq::MultZeqFV0A); @@ -226,6 +228,10 @@ DECLARE_SOA_TABLE(FDDMultZeqs, "AOD", "FDDMULTZEQ", //! Multiplicity equalized f multZeq::MultZeqFDDA, multZeq::MultZeqFDDC); DECLARE_SOA_TABLE(PVMultZeqs, "AOD", "PVMULTZEQ", //! Multiplicity equalized for the vertex position from the PV contributors multZeq::MultZeqNTracksPV); +DECLARE_SOA_TABLE(GlobalMultZeqs, "AOD", "GLOBALMULTZEQ", //! Multiplicity equalized for the vertex position, global tracks + multZeq::MultZeqNTracksGlobal); +DECLARE_SOA_TABLE(MFTMultZeqs, "AOD", "MFTMULTZEQS", //! Multiplicity equalized for the vertex position, MFT tracks + multZeq::MultZeqMFTNtracks); using MultZeqs = soa::Join; using MultZeq = MultZeqs::iterator; diff --git a/Common/TableProducer/PID/CMakeLists.txt b/Common/TableProducer/PID/CMakeLists.txt index afcda3e1be6..86787fd13b7 100644 --- a/Common/TableProducer/PID/CMakeLists.txt +++ b/Common/TableProducer/PID/CMakeLists.txt @@ -43,6 +43,11 @@ o2physics_add_dpl_workflow(pid-tof-full # TPC +o2physics_add_dpl_workflow(pid-tpc-service + SOURCES pidTPCService.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore O2Physics::AnalysisCCDB + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(pid-tpc-base SOURCES pidTPCBase.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::AnalysisCCDB @@ -50,7 +55,7 @@ o2physics_add_dpl_workflow(pid-tpc-base o2physics_add_dpl_workflow(pid-tpc SOURCES pidTPC.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DetectorsBase O2Physics::AnalysisCCDB O2Physics::MLCore COMPONENT_NAME Analysis) # HMPID diff --git a/Common/TableProducer/PID/pidBayes.cxx b/Common/TableProducer/PID/pidBayes.cxx index abedb281668..5a91afa6f70 100644 --- a/Common/TableProducer/PID/pidBayes.cxx +++ b/Common/TableProducer/PID/pidBayes.cxx @@ -16,29 +16,30 @@ /// Only the tables for the mass hypotheses requested are filled, the others are sent empty. /// -#include #include -#include #include #include +#include +#include // O2 includes -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/Array2D.h" -#include "CCDB/BasicCCDBManager.h" -#include "Common/Core/PID/TPCPIDResponse.h" +#include "pidTOFBase.h" + #include "Common/Core/PID/DetectorResponse.h" -#include "Common/Core/PID/ParamBase.h" #include "Common/Core/PID/PIDTOF.h" +#include "Common/Core/PID/ParamBase.h" +#include "Common/Core/PID/TPCPIDResponse.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/PIDResponseCombined.h" -#include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/TrackSelectionTables.h" -#include "pidTOFBase.h" +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -52,7 +53,7 @@ void customize(std::vector& workflowOptions) std::swap(workflowOptions, options); } -#include "Framework/runDataProcessing.h" +#include struct bayesPid { using Trks = soa::Join; @@ -163,7 +164,7 @@ struct bayesPid { } // Checking the tables are requested in the workflow and enabling them - auto& workflows = initContext.services().get(); + const auto& workflows = initContext.services().get(); for (DeviceSpec const& device : workflows.devices) { for (auto const& input : device.inputs) { auto enableFlag = [&input](const PID::ID& id, Configurable& flag) { @@ -284,12 +285,12 @@ struct bayesPid { // bethe = fTPCResponse.GetExpectedSignal(track, type, AliTPCPIDResponse::kdEdxDefault, fUseTPCEtaCorrection, fUseTPCMultiplicityCorrection, fUseTPCPileupCorrection); // sigma = fTPCResponse.GetExpectedSigma(track, type, AliTPCPIDResponse::kdEdxDefault, fUseTPCEtaCorrection, fUseTPCMultiplicityCorrection, fUseTPCPileupCorrection); - if (abs(dedx - bethe) > fRange * sigma) { - // Probability[kTPC][pid] = exp(-0.5 * fRange * fRange) / sigma; // BUG fix - Probability[kTPC][pid] = exp(-0.5 * fRange * fRange); + if (std::abs(dedx - bethe) > fRange * sigma) { + // Probability[kTPC][pid] = std::exp(-0.5 * fRange * fRange) / sigma; // BUG fix + Probability[kTPC][pid] = std::exp(-0.5 * fRange * fRange); } else { - // Probability[kTPC][pid] = exp(-0.5 * (dedx - bethe) * (dedx - bethe) / (sigma * sigma)) / sigma; //BUG fix - Probability[kTPC][pid] = exp(-0.5 * (dedx - bethe) * (dedx - bethe) / (sigma * sigma)); + // Probability[kTPC][pid] = std::exp(-0.5 * (dedx - bethe) * (dedx - bethe) / (sigma * sigma)) / sigma; //BUG fix + Probability[kTPC][pid] = std::exp(-0.5 * (dedx - bethe) * (dedx - bethe) / (sigma * sigma)); mismatch = false; } if (Probability[kTPC][pid] <= 0.f) { @@ -325,10 +326,10 @@ struct bayesPid { constexpr respTOF responseTOFPID; // const float pt = track.pt(); - float mismPropagationFactor[10] = {1., 1., 1., 1., 1., 1., 1., 1., 1., 1.}; + const float mismPropagationFactor[10] = {1., 1., 1., 1., 1., 1., 1., 1., 1., 1.}; // In the O2 this cannot be done because the cluster information is missing in the AOD // if (!fNoTOFmism) { // this flag allows to disable mismatch for iterative procedure to get prior probabilities - // mismPropagationFactor[3] = 1 + exp(1 - 1.12 * pt); // it has to be aligned with the one in AliPIDCombined + // mismPropagationFactor[3] = 1 + std::exp(1 - 1.12 * pt); // it has to be aligned with the one in AliPIDCombined // mismPropagationFactor[4] = 1 + 1. / (4.71114 - 5.72372 * pt + 2.94715 * pt * pt); // it has to be aligned with the one in AliPIDCombined // int nTOFcluster = 0; @@ -342,10 +343,10 @@ struct bayesPid { // nTOFcluster = 80; // break; // case kPPB: // pPb 5.05 ATeV - // nTOFcluster = int(308 - 2.12 * fCurrCentrality + exp(4.917 - 0.1604 * fCurrCentrality)); + // nTOFcluster = int(308 - 2.12 * fCurrCentrality + std::exp(4.917 - 0.1604 * fCurrCentrality)); // break; // case kPBPB: // PbPb 2.76 ATeV - // nTOFcluster = int(exp(9.4 - 0.022 * fCurrCentrality)); + // nTOFcluster = int(std::exp(9.4 - 0.022 * fCurrCentrality)); // break; // } // } @@ -376,9 +377,9 @@ struct bayesPid { const float sig = /*responseTOFPID.GetExpectedSigma(Response[kTOF], track)*/ +0.f; if (nsigmas < fTOFtail) { - Probability[kTOF][pid] = exp(-0.5 * nsigmas * nsigmas) / sig; + Probability[kTOF][pid] = std::exp(-0.5 * nsigmas * nsigmas) / sig; } else { - Probability[kTOF][pid] = exp(-(nsigmas - fTOFtail * 0.5) * fTOFtail) / sig; + Probability[kTOF][pid] = std::exp(-(nsigmas - fTOFtail * 0.5) * fTOFtail) / sig; } Probability[kTOF][pid] += fgTOFmismatchProb * mismPropagationFactor[pid]; @@ -556,7 +557,7 @@ struct bayesPidQa { double lmin = TMath::Log10(min); double ldelta = (TMath::Log10(max) - lmin) / (static_cast(kNBins)); for (int i = 0; i < kNBins; i++) { - binp[i] = exp(TMath::Log(10) * (lmin + i * ldelta)); + binp[i] = std::exp(TMath::Log(10) * (lmin + i * ldelta)); } binp[kNBins] = max + 1; h->GetXaxis()->Set(kNBins, binp); diff --git a/Common/TableProducer/PID/pidTOFBase.cxx b/Common/TableProducer/PID/pidTOFBase.cxx index f0f9722fc6b..f55a4049e04 100644 --- a/Common/TableProducer/PID/pidTOFBase.cxx +++ b/Common/TableProducer/PID/pidTOFBase.cxx @@ -15,25 +15,27 @@ /// \brief Base to build tasks for TOF PID tasks. /// +#include #include #include -#include // O2 includes -#include "CCDB/BasicCCDBManager.h" -#include "TOFBase/EventTimeMaker.h" -#include "Framework/AnalysisTask.h" -#include "ReconstructionDataFormats/Track.h" +#include +#include +#include +#include // O2Physics includes -#include "Common/DataModel/TrackSelectionTables.h" +#include "TableHelper.h" +#include "pidTOFBase.h" + #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/FT0Corrected.h" #include "Common/DataModel/Multiplicity.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "TableHelper.h" -#include "pidTOFBase.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include using namespace o2; using namespace o2::framework; @@ -111,7 +113,7 @@ struct tofSignal { if (enableTableFlags) { tableFlags.reserve(tracks.size()); } - for (auto& t : tracks) { + for (const auto& t : tracks) { const auto s = o2::pid::tof::TOFSignal::GetTOFSignal(t); if (enableQaHistograms) { histos.fill(HIST("tofSignal"), s); @@ -139,7 +141,7 @@ struct tofSignal { if (enableTableFlags) { tableFlags.reserve(tracks.size()); } - for (auto& t : tracks) { + for (const auto& t : tracks) { table(o2::pid::tof::TOFSignal::GetTOFSignal(t)); if (!enableTableFlags) { continue; @@ -388,7 +390,7 @@ struct tofEventTime { evTimeTOF.removeBias(trk, nGoodTracksForTOF, et, erret, 2); } uint8_t flags = 0; - if (erret < errDiamond && (maxEvTimeTOF <= 0.f || abs(et) < maxEvTimeTOF)) { + if (erret < errDiamond && (maxEvTimeTOF <= 0.f || std::abs(et) < maxEvTimeTOF)) { flags |= o2::aod::pidflags::enums::PIDFlags::EvTimeTOF; } else { et = 0.f; @@ -407,7 +409,7 @@ struct tofEventTime { /// /// Process function to prepare the event for each track on Run 3 data with the FT0 using EvTimeCollisionsFT0 = soa::Join; - void processFT0(TrksEvTime& tracks, + void processFT0(TrksEvTime const& tracks, aod::FT0s const&, EvTimeCollisionsFT0 const&) { @@ -463,7 +465,7 @@ struct tofEventTime { if constexpr (removeTOFEvTimeBias) { evTimeTOF.removeBias(trk, nGoodTracksForTOF, t0TOF[0], t0TOF[1], 2); } - if (t0TOF[1] < errDiamond && (maxEvTimeTOF <= 0 || abs(t0TOF[0]) < maxEvTimeTOF)) { + if (t0TOF[1] < errDiamond && (maxEvTimeTOF <= 0 || std::abs(t0TOF[0]) < maxEvTimeTOF)) { flags |= o2::aod::pidflags::enums::PIDFlags::EvTimeTOF; weight = 1.f / (t0TOF[1] * t0TOF[1]); @@ -491,7 +493,7 @@ struct tofEventTime { } else { tableFlags(flags); } - tableEvTime(eventTime / sumOfWeights, sqrt(1. / sumOfWeights)); + tableEvTime(eventTime / sumOfWeights, std::sqrt(1. / sumOfWeights)); if (enableTableTOFOnly) { tableEvTimeTOFOnly((uint8_t)filterForTOFEventTime(trk), t0TOF[0], t0TOF[1], evTimeTOF.mEventTimeMultiplicity); } @@ -502,7 +504,7 @@ struct tofEventTime { /// /// Process function to prepare the event for each track on Run 3 data with only the FT0 - void processOnlyFT0(TrksEvTime& tracks, + void processOnlyFT0(TrksEvTime const& tracks, aod::FT0s const&, EvTimeCollisionsFT0 const&) { diff --git a/Common/TableProducer/PID/pidTOFMerge.cxx b/Common/TableProducer/PID/pidTOFMerge.cxx index 7ea0ac3b3b1..91c76e6e50a 100644 --- a/Common/TableProducer/PID/pidTOFMerge.cxx +++ b/Common/TableProducer/PID/pidTOFMerge.cxx @@ -22,12 +22,12 @@ #include // O2 includes -#include "CCDB/BasicCCDBManager.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" -#include "TOFBase/EventTimeMaker.h" +#include +#include +#include +#include +#include +#include // O2Physics includes #include "CollisionTypeHelper.h" @@ -83,14 +83,14 @@ struct TOFCalibConfig { } template - void getCfg(o2::framework::InitContext& initContext, const std::string name, VType& v, const std::string task) + void getCfg(o2::framework::InitContext& initContext, const std::string& name, VType& v, const std::string& task) { if (!getTaskOptionValue(initContext, task, name, v, false)) { LOG(fatal) << "Could not get " << name << " from " << task << " task"; } } - void inheritFromBaseTask(o2::framework::InitContext& initContext, const std::string task = "tof-signal") + void inheritFromBaseTask(o2::framework::InitContext& initContext, const std::string& task = "tof-signal") { mInitMode = 2; getCfg(initContext, "ccdb-url", mUrl, task); @@ -329,7 +329,7 @@ struct TOFCalibConfig { // Configurable options std::string mUrl; std::string mPathGrpLhcIf; - int64_t mTimestamp; + int64_t mTimestamp{0}; std::string mTimeShiftCCDBPathPos; std::string mTimeShiftCCDBPathNeg; std::string mTimeShiftCCDBPathPosMC; @@ -338,10 +338,10 @@ struct TOFCalibConfig { std::string mParametrizationPath; std::string mReconstructionPass; std::string mReconstructionPassDefault; - bool mFatalOnPassNotAvailable; - bool mEnableTimeDependentResponse; - int mCollisionSystem; - bool mAutoSetProcessFunctions; + bool mFatalOnPassNotAvailable{false}; + bool mEnableTimeDependentResponse{false}; + int mCollisionSystem{-1}; + bool mAutoSetProcessFunctions{false}; }; // Part 1 TOF signal definition diff --git a/Common/TableProducer/PID/pidTPC.cxx b/Common/TableProducer/PID/pidTPC.cxx index 2ec03df592f..bd126939f0f 100644 --- a/Common/TableProducer/PID/pidTPC.cxx +++ b/Common/TableProducer/PID/pidTPC.cxx @@ -24,28 +24,29 @@ #include #include // ROOT includes -#include "TFile.h" -#include "TRandom.h" -#include "TSystem.h" +#include +#include +#include // O2 includes #include "MetadataHelper.h" #include "TableHelper.h" #include "pidTPCBase.h" +#include "Common/CCDB/ctpRateFetcher.h" #include "Common/Core/PID/TPCPIDResponse.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Tools/ML/model.h" -#include "CCDB/BasicCCDBManager.h" -#include "CCDB/CcdbApi.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" +#include +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -150,9 +151,12 @@ struct tpcPid { Configurable useNetworkHe{"useNetworkHe", 1, {"Switch for applying neural network on the helium3 mass hypothesis (if network enabled) (set to 0 to disable)"}}; Configurable useNetworkAl{"useNetworkAl", 1, {"Switch for applying neural network on the alpha mass hypothesis (if network enabled) (set to 0 to disable)"}}; Configurable networkBetaGammaCutoff{"networkBetaGammaCutoff", 0.45, {"Lower value of beta-gamma to override the NN application"}}; - + Configurable networkInputBatchedMode{"networkInputBatchedMode", -1, {"-1: Takes all tracks, >0: Takes networkInputBatchedMode number of tracks at once"}}; + Configurable irSource{"irSource", "ZNC hadronic", "Estimator of the interaction rate (Recommended: pp --> T0VTX, Pb-Pb --> ZNC hadronic)"}; + ctpRateFetcher mRateFetcher; // Parametrization configuration bool useCCDBParam = false; + std::vector track_properties; void init(o2::framework::InitContext& initContext) { @@ -164,7 +168,7 @@ struct tpcPid { } response = new o2::pid::tpc::Response(); // Checking the tables are requested in the workflow and enabling them - auto enableFlag = [&](const std::string particle, Configurable& flag) { + auto enableFlag = [&](const std::string& particle, Configurable& flag) { enableFlagIfTableRequired(initContext, "pidTPC" + particle, flag); }; enableFlag("FullEl", pidFullEl); @@ -298,8 +302,6 @@ struct tpcPid { std::vector createNetworkPrediction(C const& collisions, T const& tracks, B const& bcs, const size_t size) { - std::vector network_prediction; - auto start_network_total = std::chrono::high_resolution_clock::now(); if (autofetchNetworks) { const auto& bc = bcs.begin(); @@ -345,20 +347,24 @@ struct tpcPid { // Defining some network parameters int input_dimensions = network.getNumInputNodes(); int output_dimensions = network.getNumOutputNodes(); - const uint64_t track_prop_size = input_dimensions * size; const uint64_t prediction_size = output_dimensions * size; + const uint8_t numSpecies = 9; + const uint64_t total_eval_size = size * numSpecies; // 9 species - network_prediction = std::vector(prediction_size * 9); // For each mass hypotheses const float nNclNormalization = response->GetNClNormalization(); float duration_network = 0; - std::vector track_properties(track_prop_size); - uint64_t counter_track_props = 0; - int loop_counter = 0; + uint64_t counter_track_props = 0, exec_counter = 0, in_batch_counter = 0, total_input_count = 0; + uint64_t track_prop_size = networkInputBatchedMode.value; + if (networkInputBatchedMode.value <= 0) { + track_prop_size = size; // If the networkInputBatchedMode is not set, we use all tracks at once + } + track_properties.resize(track_prop_size * input_dimensions); // If the networkInputBatchedMode is set, we use the number of tracks specified in the config + std::vector network_prediction(prediction_size * numSpecies); // For each mass hypotheses // Filling a std::vector to be evaluated by the network // Evaluation on single tracks brings huge overhead: Thus evaluation is done on one large vector - for (int i = 0; i < 9; i++) { // Loop over particle number for which network correction is used + for (int species = 0; species < numSpecies; species++) { // Loop over particle number for which network correction is used for (auto const& trk : tracks) { if (!trk.hasTPC()) { continue; @@ -368,30 +374,48 @@ struct tpcPid { continue; } } - track_properties[counter_track_props] = trk.tpcInnerParam(); + + if ((in_batch_counter == track_prop_size) || (total_input_count == total_eval_size)) { // If the batch size is reached, reset the counter + int32_t fill_shift = (exec_counter * track_prop_size - ((total_input_count == total_eval_size) ? (total_input_count % track_prop_size) : 0)) * output_dimensions; + auto start_network_eval = std::chrono::high_resolution_clock::now(); + const float* output_network = network.evalModel(track_properties); + auto stop_network_eval = std::chrono::high_resolution_clock::now(); + duration_network += std::chrono::duration>(stop_network_eval - start_network_eval).count(); + + for (uint64_t i = 0; i < (in_batch_counter * output_dimensions); i += output_dimensions) { + for (int j = 0; j < output_dimensions; j++) { + network_prediction[i + j + fill_shift] = output_network[i + j]; + } + } + counter_track_props = 0; + in_batch_counter = 0; + exec_counter++; + } + + // LOG(info) << "counter_tracks_props: " << counter_track_props << "; in_batch_counter: " << in_batch_counter << "; total_input_count: " << total_input_count << "; exec_counter: " << exec_counter << "; track_prop_size: " << track_prop_size << "; size: " << size << "; track_properties.size(): " << track_properties.size(); + track_properties[counter_track_props] = trk.tpcInnerParam(); // (tracks.asArrowTable()->GetColumn("tpcInnerParam")).GetData(); track_properties[counter_track_props + 1] = trk.tgl(); track_properties[counter_track_props + 2] = trk.signed1Pt(); - track_properties[counter_track_props + 3] = o2::track::pid_constants::sMasses[i]; + track_properties[counter_track_props + 3] = o2::track::pid_constants::sMasses[species]; track_properties[counter_track_props + 4] = trk.has_collision() ? collisions.iteratorAt(trk.collisionId()).multTPC() / 11000. : 1.; track_properties[counter_track_props + 5] = std::sqrt(nNclNormalization / trk.tpcNClsFound()); if (input_dimensions == 7 && networkVersion == "2") { track_properties[counter_track_props + 6] = trk.has_collision() ? collisions.iteratorAt(trk.collisionId()).ft0cOccupancyInTimeRange() / 60000. : 1.; } - counter_track_props += input_dimensions; - } - - auto start_network_eval = std::chrono::high_resolution_clock::now(); - float* output_network = network.evalModel(track_properties); - auto stop_network_eval = std::chrono::high_resolution_clock::now(); - duration_network += std::chrono::duration>(stop_network_eval - start_network_eval).count(); - for (uint64_t i = 0; i < prediction_size; i += output_dimensions) { - for (int j = 0; j < output_dimensions; j++) { - network_prediction[i + j + prediction_size * loop_counter] = output_network[i + j]; + if (input_dimensions == 8 && networkVersion == "3") { + if (trk.has_collision()) { + auto trk_bc = (collisions.iteratorAt(trk.collisionId())).template bc_as(); + float hadronicRate = mRateFetcher.fetch(ccdb.service, trk_bc.timestamp(), trk_bc.runNumber(), irSource) * 1.e-3; + track_properties[counter_track_props + 7] = hadronicRate / 50.; + } else { + track_properties[counter_track_props + 7] = 1; + } } - } - counter_track_props = 0; - loop_counter += 1; + counter_track_props += input_dimensions; + in_batch_counter++; + total_input_count++; + } } track_properties.clear(); @@ -425,8 +449,8 @@ struct tpcPid { } } auto expSignal = response->GetExpectedSignal(trk, pid); - auto expSigma = trk.has_collision() ? response->GetExpectedSigma(collisions.iteratorAt(trk.collisionId()), trk, pid) : 0.07 * expSignal; // use default sigma value of 7% if no collision information to estimate resolution - if (expSignal < 0. || expSigma < 0.) { // skip if expected signal invalid + auto expSigma = trk.has_collision() ? response->GetExpectedSigma(collisions.iteratorAt(trk.collisionId()), trk, pid) : 0.07f * expSignal; // use default sigma value of 7% if no collision information to estimate resolution + if (expSignal < 0. || expSigma < 0.) { // skip if expected signal invalid if (flagFull) tableFull(-999.f, -999.f); if (flagTiny) @@ -435,6 +459,11 @@ struct tpcPid { } float nSigma = -999.f; + int multTPC = 0; + if (trk.has_collision()) { + auto collision = collisions.rawIteratorAt(trk.collisionId()); + multTPC = collision.multTPC(); + } float bg = trk.tpcInnerParam() / o2::track::pid_constants::sMasses[pid]; // estimated beta-gamma for network cutoff if (useNetworkCorrection && speciesNetworkFlags[pid] && trk.has_collision() && bg > networkBetaGammaCutoff) { @@ -457,7 +486,7 @@ struct tpcPid { LOGF(fatal, "Network output-dimensions incompatible!"); } } else { - nSigma = response->GetNumberOfSigmaMCTuned(collisions.iteratorAt(trk.collisionId()), trk, pid, tpcSignal); + nSigma = response->GetNumberOfSigmaMCTunedAtMultiplicity(multTPC, trk, pid, tpcSignal); } if (flagFull) tableFull(expSigma, nSigma); diff --git a/Common/TableProducer/PID/pidTPCModule.h b/Common/TableProducer/PID/pidTPCModule.h new file mode 100644 index 00000000000..321b6e39329 --- /dev/null +++ b/Common/TableProducer/PID/pidTPCModule.h @@ -0,0 +1,793 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file pidTPCModule.h +/// \brief Task to produce PID tables for TPC split for each particle. +/// Only the tables for the mass hypotheses requested are filled, and only for the requested table size +/// ("Full" or "Tiny"). The others are sent empty. +/// \author Nicolò Jacazio nicolo.jacazio@cern.ch +/// \author Christian Sonnabend christian.sonnabend@cern.ch +/// \author Annalena Kalteyer annalena.sophie.kalteyer@cern.ch +/// \author Jeremy Wilkinson jeremy.wilkinson@cern.ch + +#ifndef COMMON_TOOLS_PIDTPCMODULE_H_ +#define COMMON_TOOLS_PIDTPCMODULE_H_ + +#include +#include +#include +#include +#include +// ROOT includes +#include "TFile.h" +#include "TRandom.h" +#include "TSystem.h" + +// O2 includes +#include "MetadataHelper.h" +#include "TableHelper.h" +#include "pidTPCBase.h" + +#include "Common/CCDB/ctpRateFetcher.h" +#include "Common/Core/PID/TPCPIDResponse.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Tools/ML/model.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +namespace o2::aod +{ +namespace pid +{ +struct pidTPCProducts : o2::framework::ProducesGroup { + // Intermediate tables (provide only if requested) + o2::framework::Produces dEdxCorrected; + o2::framework::Produces mult; + + // Tables produced by TPC component + o2::framework::Produces tablePIDFullEl; + o2::framework::Produces tablePIDFullMu; + o2::framework::Produces tablePIDFullPi; + o2::framework::Produces tablePIDFullKa; + o2::framework::Produces tablePIDFullPr; + o2::framework::Produces tablePIDFullDe; + o2::framework::Produces tablePIDFullTr; + o2::framework::Produces tablePIDFullHe; + o2::framework::Produces tablePIDFullAl; + + o2::framework::Produces tablePIDTinyEl; + o2::framework::Produces tablePIDTinyMu; + o2::framework::Produces tablePIDTinyPi; + o2::framework::Produces tablePIDTinyKa; + o2::framework::Produces tablePIDTinyPr; + o2::framework::Produces tablePIDTinyDe; + o2::framework::Produces tablePIDTinyTr; + o2::framework::Produces tablePIDTinyHe; + o2::framework::Produces tablePIDTinyAl; + o2::framework::Produces tableTuneOnData; +}; + +struct pidTPCConfigurables : o2::framework::ConfigurableGroup { + std::string prefix = "pidTPC"; + o2::framework::Configurable paramfile{"param-file", "", "Path to the parametrization object, if empty the parametrization is not taken from file"}; + o2::framework::Configurable ccdbPath{"ccdbPath", "Analysis/PID/TPC/Response", "Path of the TPC parametrization on the CCDB"}; + o2::framework::Configurable recoPass{"recoPass", "", "Reconstruction pass name for CCDB query (automatically takes latest object for timestamp if blank)"}; + o2::framework::Configurable ccdbTimestamp{"ccdb-timestamp", 0, "timestamp of the object used to query in CCDB the detector response. Exceptions: -1 gets the latest object, 0 gets the run dependent timestamp"}; + // Parameters for loading network from a file / downloading the file + o2::framework::Configurable useNetworkCorrection{"useNetworkCorrection", 0, "(bool) Wether or not to use the network correction for the TPC dE/dx signal"}; + o2::framework::Configurable autofetchNetworks{"autofetchNetworks", 1, "(bool) Automatically fetches networks from CCDB for the correct run number"}; + o2::framework::Configurable skipTPCOnly{"skipTPCOnly", false, "Flag to skip TPC only tracks (faster but affects the analyses that use TPC only tracks)"}; + o2::framework::Configurable networkPathLocally{"networkPathLocally", "network.onnx", "(std::string) Path to the local .onnx file. If autofetching is enabled, then this is where the files will be downloaded"}; + o2::framework::Configurable networkPathCCDB{"networkPathCCDB", "Analysis/PID/TPC/ML", "Path on CCDB"}; + o2::framework::Configurable enableNetworkOptimizations{"enableNetworkOptimizations", 1, "(bool) If the neural network correction is used, this enables GraphOptimizationLevel::ORT_ENABLE_EXTENDED in the ONNX session"}; + o2::framework::Configurable networkSetNumThreads{"networkSetNumThreads", 0, "Especially important for running on a SLURM cluster. Sets the number of threads used for execution."}; + // Configuration flags to include and exclude particle hypotheses + o2::framework::Configurable savedEdxsCorrected{"savedEdxsCorrected", -1, {"Save table with corrected dE/dx calculated on the spot. 0: off, 1: on, -1: auto"}}; + o2::framework::Configurable useCorrecteddEdx{"useCorrecteddEdx", false, "(bool) If true, use corrected dEdx value in Nsigma calculation instead of the one in the AO2D"}; + + o2::framework::Configurable pidFullEl{"pid-full-el", -1, {"Produce PID information for the Electron mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}}; + o2::framework::Configurable pidFullMu{"pid-full-mu", -1, {"Produce PID information for the Muon mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}}; + o2::framework::Configurable pidFullPi{"pid-full-pi", -1, {"Produce PID information for the Pion mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}}; + o2::framework::Configurable pidFullKa{"pid-full-ka", -1, {"Produce PID information for the Kaon mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}}; + o2::framework::Configurable pidFullPr{"pid-full-pr", -1, {"Produce PID information for the Proton mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}}; + o2::framework::Configurable pidFullDe{"pid-full-de", -1, {"Produce PID information for the Deuterons mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}}; + o2::framework::Configurable pidFullTr{"pid-full-tr", -1, {"Produce PID information for the Triton mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}}; + o2::framework::Configurable pidFullHe{"pid-full-he", -1, {"Produce PID information for the Helium3 mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}}; + o2::framework::Configurable pidFullAl{"pid-full-al", -1, {"Produce PID information for the Alpha mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}}; + o2::framework::Configurable pidTinyEl{"pid-tiny-el", -1, {"Produce PID information for the Electron mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}}; + o2::framework::Configurable pidTinyMu{"pid-tiny-mu", -1, {"Produce PID information for the Muon mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}}; + o2::framework::Configurable pidTinyPi{"pid-tiny-pi", -1, {"Produce PID information for the Pion mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}}; + o2::framework::Configurable pidTinyKa{"pid-tiny-ka", -1, {"Produce PID information for the Kaon mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}}; + o2::framework::Configurable pidTinyPr{"pid-tiny-pr", -1, {"Produce PID information for the Proton mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}}; + o2::framework::Configurable pidTinyDe{"pid-tiny-de", -1, {"Produce PID information for the Deuterons mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}}; + o2::framework::Configurable pidTinyTr{"pid-tiny-tr", -1, {"Produce PID information for the Triton mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}}; + o2::framework::Configurable pidTinyHe{"pid-tiny-he", -1, {"Produce PID information for the Helium3 mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}}; + o2::framework::Configurable pidTinyAl{"pid-tiny-al", -1, {"Produce PID information for the Alpha mass hypothesis, overrides the automatic setup: the corresponding table can be set off (0) or on (1)"}}; + o2::framework::Configurable enableTuneOnDataTable{"enableTuneOnDataTable", -1, {"Produce tuned dE/dx signal table for MC to be used as raw signal in other tasks (default -1, 'only if needed'"}}; + o2::framework::Configurable useNetworkEl{"useNetworkEl", 1, {"Switch for applying neural network on the electron mass hypothesis (if network enabled) (set to 0 to disable)"}}; + o2::framework::Configurable useNetworkMu{"useNetworkMu", 1, {"Switch for applying neural network on the muon mass hypothesis (if network enabled) (set to 0 to disable)"}}; + o2::framework::Configurable useNetworkPi{"useNetworkPi", 1, {"Switch for applying neural network on the pion mass hypothesis (if network enabled) (set to 0 to disable)"}}; + o2::framework::Configurable useNetworkKa{"useNetworkKa", 1, {"Switch for applying neural network on the kaon mass hypothesis (if network enabled) (set to 0 to disable)"}}; + o2::framework::Configurable useNetworkPr{"useNetworkPr", 1, {"Switch for applying neural network on the proton mass hypothesis (if network enabled) (set to 0 to disable)"}}; + o2::framework::Configurable useNetworkDe{"useNetworkDe", 1, {"Switch for applying neural network on the deuteron mass hypothesis (if network enabled) (set to 0 to disable)"}}; + o2::framework::Configurable useNetworkTr{"useNetworkTr", 1, {"Switch for applying neural network on the triton mass hypothesis (if network enabled) (set to 0 to disable)"}}; + o2::framework::Configurable useNetworkHe{"useNetworkHe", 1, {"Switch for applying neural network on the helium3 mass hypothesis (if network enabled) (set to 0 to disable)"}}; + o2::framework::Configurable useNetworkAl{"useNetworkAl", 1, {"Switch for applying neural network on the alpha mass hypothesis (if network enabled) (set to 0 to disable)"}}; + o2::framework::Configurable networkBetaGammaCutoff{"networkBetaGammaCutoff", 0.45, {"Lower value of beta-gamma to override the NN application"}}; +}; + +// helper getter - FIXME should be separate +int getPIDIndex(const int pdgCode) // Get O2 PID index corresponding to MC PDG code +{ + switch (abs(pdgCode)) { + case 11: + return o2::track::PID::Electron; + case 13: + return o2::track::PID::Muon; + case 211: + return o2::track::PID::Pion; + case 321: + return o2::track::PID::Kaon; + case 2212: + return o2::track::PID::Proton; + case 1000010020: + return o2::track::PID::Deuteron; + case 1000010030: + return o2::track::PID::Triton; + case 1000020030: + return o2::track::PID::Helium3; + case 1000020040: + return o2::track::PID::Alpha; + default: // treat as pion if not any of the above + return o2::track::PID::Pion; + } +} + +typedef struct Str_dEdx_correction { + TMatrixD fMatrix; + bool warning = true; + + // void init(std::vector& params) + void init() + { + double elements[32] = {0.99091, -0.015053, 0.0018912, -0.012305, + 0.081387, 0.003205, -0.0087404, -0.0028608, + 0.013066, 0.017012, -0.0018469, -0.0052177, + -0.0035655, 0.0017846, 0.0019127, -0.00012964, + 0.0049428, 0.0055592, -0.0010618, -0.0016134, + -0.0059098, 0.0013335, 0.00052133, 3.1119e-05, + -0.004882, 0.00077317, -0.0013827, 0.003249, + -0.00063689, 0.0016218, -0.00045215, -1.5815e-05}; + fMatrix.ResizeTo(4, 8); + fMatrix.SetMatrixArray(elements); + } + + float fReal_fTPCSignalN(std::vector vec1, std::vector vec2) + { + float result = 0.f; + // push 1. + vec1.insert(vec1.begin(), 1.0); + vec2.insert(vec2.begin(), 1.0); + for (int i = 0; i < fMatrix.GetNrows(); i++) { + for (int j = 0; j < fMatrix.GetNcols(); j++) { + double param = fMatrix(i, j); + double value1 = i > static_cast(vec1.size()) ? 0 : vec1[i]; + double value2 = j > static_cast(vec2.size()) ? 0 : vec2[j]; + result += param * value1 * value2; + } + } + return result; + } +} Str_dEdx_correction; + +class pidTPCModule +{ + public: + pidTPCModule() + { + // constructor + } + o2::aod::pid::pidTPCConfigurables pidTPCopts; + + // TPC PID Response + o2::pid::tpc::Response* response; + + // Network correction for TPC PID response + ml::OnnxModel network; + std::map metadata; + std::map nullmetadata; + std::map headers; + std::vector speciesNetworkFlags = std::vector(9); + std::string networkVersion; + + // Parametrization configuration + bool useCCDBParam = false; + + // for dEdx correction + ctpRateFetcher mRateFetcher; + Str_dEdx_correction str_dedx_correction; + + //__________________________________________________ + template + void init(TCCDB& ccdb, TCCDBApi& ccdbApi, TContext& context, TpidTPCOpts const& external_pidtpcopts, TMetadataInfo const& metadataInfo) + { + // read in configurations from the task where it's used + pidTPCopts = external_pidtpcopts; + + if (pidTPCopts.useCorrecteddEdx.value) { + LOGF(info, "***************************************************"); + LOGF(info, " WARNING: YOU HAVE SWITCHED ON 'corrected dEdx!"); + LOGF(info, " This mode is still in development and it is meant"); + LOGF(info, " ONLY FOR EXPERTS at this time. Please switch "); + LOGF(info, " this option off UNLESS you are absolutely SURE"); + LOGF(info, " of what you're doing! You've been warned!"); + LOGF(info, "***************************************************"); + } + + // initialize PID response + response = new o2::pid::tpc::Response(); + + enableFlagIfTableRequired(context, "DEdxsCorrected", pidTPCopts.savedEdxsCorrected); + + // Checking the tables are requested in the workflow and enabling them + auto enableFlag = [&](const std::string particle, o2::framework::Configurable& flag) { + enableFlagIfTableRequired(context, "pidTPC" + particle, flag); + }; + enableFlag("FullEl", pidTPCopts.pidFullEl); + enableFlag("FullMu", pidTPCopts.pidFullMu); + enableFlag("FullPi", pidTPCopts.pidFullPi); + enableFlag("FullKa", pidTPCopts.pidFullKa); + enableFlag("FullPr", pidTPCopts.pidFullPr); + enableFlag("FullDe", pidTPCopts.pidFullDe); + enableFlag("FullTr", pidTPCopts.pidFullTr); + enableFlag("FullHe", pidTPCopts.pidFullHe); + enableFlag("FullAl", pidTPCopts.pidFullAl); + + enableFlag("El", pidTPCopts.pidTinyEl); + enableFlag("Mu", pidTPCopts.pidTinyMu); + enableFlag("Pi", pidTPCopts.pidTinyPi); + enableFlag("Ka", pidTPCopts.pidTinyKa); + enableFlag("Pr", pidTPCopts.pidTinyPr); + enableFlag("De", pidTPCopts.pidTinyDe); + enableFlag("Tr", pidTPCopts.pidTinyTr); + enableFlag("He", pidTPCopts.pidTinyHe); + enableFlag("Al", pidTPCopts.pidTinyAl); + + if (metadataInfo.isMC()) { + enableFlagIfTableRequired(context, "mcTPCTuneOnData", pidTPCopts.enableTuneOnDataTable); + } + + speciesNetworkFlags[0] = pidTPCopts.useNetworkEl; + speciesNetworkFlags[1] = pidTPCopts.useNetworkMu; + speciesNetworkFlags[2] = pidTPCopts.useNetworkPi; + speciesNetworkFlags[3] = pidTPCopts.useNetworkKa; + speciesNetworkFlags[4] = pidTPCopts.useNetworkPr; + speciesNetworkFlags[5] = pidTPCopts.useNetworkDe; + speciesNetworkFlags[6] = pidTPCopts.useNetworkTr; + speciesNetworkFlags[7] = pidTPCopts.useNetworkHe; + speciesNetworkFlags[8] = pidTPCopts.useNetworkAl; + + // Initialise metadata object for CCDB calls from AO2D metadata + if (pidTPCopts.recoPass.value == "") { + if (metadataInfo.isFullyDefined()) { + metadata["RecoPassName"] = metadataInfo.get("RecoPassName"); + LOGP(info, "Automatically setting reco pass for TPC Response to {} from AO2D", metadata["RecoPassName"]); + } + } else { + LOGP(info, "Setting reco pass for TPC response to user-defined name {}", pidTPCopts.recoPass.value); + metadata["RecoPassName"] = pidTPCopts.recoPass.value; + } + + /// TPC PID Response + const TString fname = pidTPCopts.paramfile.value; + if (fname != "") { // Loading the parametrization from file + LOGP(info, "Loading TPC response from file {}", fname.Data()); + try { + std::unique_ptr f(TFile::Open(fname, "READ")); + f->GetObject("Response", response); + } catch (...) { + LOGF(fatal, "Loading the TPC PID Response from file {} failed!", fname.Data()); + } + response->PrintAll(); + } else { + useCCDBParam = true; + const std::string path = pidTPCopts.ccdbPath.value; + const auto time = pidTPCopts.ccdbTimestamp.value; + if (time != 0) { + LOGP(info, "Initialising TPC PID response for fixed timestamp {} and reco pass {}:", time, pidTPCopts.recoPass.value); + ccdb->setTimestamp(time); + response = ccdb->template getSpecific(path, time, metadata); + headers = ccdbApi.retrieveHeaders(path, metadata, time); + if (!response) { + LOGF(warning, "Unable to find TPC parametrisation for specified pass name - falling back to latest object"); + response = ccdb->template getForTimeStamp(path, time); + headers = ccdbApi.retrieveHeaders(path, metadata, time); + networkVersion = headers["NN-Version"]; + if (!response) { + LOGF(fatal, "Unable to find any TPC object corresponding to timestamp {}!", time); + } + } + LOG(info) << "Successfully retrieved TPC PID object from CCDB for timestamp " << time << ", period " << headers["LPMProductionTag"] << ", recoPass " << headers["RecoPassName"]; + metadata["RecoPassName"] = headers["RecoPassName"]; // Force pass number for NN request to match retrieved BB + response->PrintAll(); + } + } + + /// Neural network init for TPC PID + if (!pidTPCopts.useNetworkCorrection) { + return; + } else { + /// CCDB and auto-fetching + if (!pidTPCopts.autofetchNetworks) { + if (pidTPCopts.ccdbTimestamp > 0) { + /// Fetching network for specific timestamp + LOG(info) << "Fetching network for timestamp: " << pidTPCopts.ccdbTimestamp.value; + bool retrieveSuccess = ccdbApi.retrieveBlob(pidTPCopts.networkPathCCDB.value, ".", metadata, pidTPCopts.ccdbTimestamp.value, false, pidTPCopts.networkPathLocally.value); + headers = ccdbApi.retrieveHeaders(pidTPCopts.networkPathCCDB.value, metadata, pidTPCopts.ccdbTimestamp.value); + networkVersion = headers["NN-Version"]; + if (retrieveSuccess) { + network.initModel(pidTPCopts.networkPathLocally.value, pidTPCopts.enableNetworkOptimizations.value, pidTPCopts.networkSetNumThreads.value, strtoul(headers["Valid-From"].c_str(), NULL, 0), strtoul(headers["Valid-Until"].c_str(), NULL, 0)); + std::vector dummyInput(network.getNumInputNodes(), 1.); + network.evalModel(dummyInput); /// Init the model evaluations + LOGP(info, "Retrieved NN corrections for production tag {}, pass number {}, and NN-Version {}", headers["LPMProductionTag"], headers["RecoPassName"], headers["NN-Version"]); + } else { + LOG(fatal) << "No valid NN object found matching retrieved Bethe-Bloch parametrisation for pass " << metadata["RecoPassName"] << ". Please ensure that the requested pass has dedicated NN corrections available"; + } + } else { + /// Taking the network from local file + if (pidTPCopts.networkPathLocally.value == "") { + LOG(fatal) << "Local path must be set (flag networkPathLocally)! Aborting..."; + } + LOG(info) << "Using local file [" << pidTPCopts.networkPathLocally.value << "] for the TPC PID response correction."; + network.initModel(pidTPCopts.networkPathLocally.value, pidTPCopts.enableNetworkOptimizations.value, pidTPCopts.networkSetNumThreads.value); + std::vector dummyInput(network.getNumInputNodes(), 1.); + network.evalModel(dummyInput); // This is an initialisation and might reduce the overhead of the model + } + } else { + return; + } + } + + if (pidTPCopts.useCorrecteddEdx.value && networkVersion != "5") { + LOGF(fatal, "Using corrected dE/dx with a network version other than 5 will not work. Crashing now."); + } + } // end init + + //__________________________________________________ + template + std::vector createNetworkPrediction(TCCDB& ccdb, TCCDBApi& ccdbApi, C const& collisions, M const& mults, T const& tracks, B const& bcs, const size_t size) + { + + std::vector network_prediction; + + auto start_network_total = std::chrono::high_resolution_clock::now(); + if (pidTPCopts.autofetchNetworks) { + const auto& bc = bcs.begin(); + // Initialise correct TPC response object before NN setup (for NCl normalisation) + if (useCCDBParam && pidTPCopts.ccdbTimestamp.value == 0 && !ccdb->isCachedObjectValid(pidTPCopts.ccdbPath.value, bc.timestamp())) { // Updating parametrisation only if the initial timestamp is 0 + if (pidTPCopts.recoPass.value == "") { + LOGP(info, "Retrieving latest TPC response object for timestamp {}:", bc.timestamp()); + } else { + LOGP(info, "Retrieving TPC Response for timestamp {} and recoPass {}:", bc.timestamp(), pidTPCopts.recoPass.value); + } + response = ccdb->template getSpecific(pidTPCopts.ccdbPath.value, bc.timestamp(), metadata); + headers = ccdbApi.retrieveHeaders(pidTPCopts.ccdbPath.value, metadata, bc.timestamp()); + networkVersion = headers["NN-Version"]; + if (!response) { + LOGP(warning, "!! Could not find a valid TPC response object for specific pass name {}! Falling back to latest uploaded object.", metadata["RecoPassName"]); + headers = ccdbApi.retrieveHeaders(pidTPCopts.ccdbPath.value, nullmetadata, bc.timestamp()); + response = ccdb->template getForTimeStamp(pidTPCopts.ccdbPath.value, bc.timestamp()); + if (!response) { + LOGP(fatal, "Could not find ANY TPC response object for the timestamp {}!", bc.timestamp()); + } + } + LOG(info) << "Successfully retrieved TPC PID object from CCDB for timestamp " << bc.timestamp() << ", period " << headers["LPMProductionTag"] << ", recoPass " << headers["RecoPassName"]; + metadata["RecoPassName"] = headers["RecoPassName"]; // Force pass number for NN request to match retrieved BB + response->PrintAll(); + } + + if (bc.timestamp() < network.getValidityFrom() || bc.timestamp() > network.getValidityUntil()) { // fetches network only if the runnumbers change + LOG(info) << "Fetching network for timestamp: " << bc.timestamp(); + bool retrieveSuccess = ccdbApi.retrieveBlob(pidTPCopts.networkPathCCDB.value, ".", metadata, bc.timestamp(), false, pidTPCopts.networkPathLocally.value); + headers = ccdbApi.retrieveHeaders(pidTPCopts.networkPathCCDB.value, metadata, bc.timestamp()); + networkVersion = headers["NN-Version"]; + if (retrieveSuccess) { + network.initModel(pidTPCopts.networkPathLocally.value, pidTPCopts.enableNetworkOptimizations.value, pidTPCopts.networkSetNumThreads.value, strtoul(headers["Valid-From"].c_str(), NULL, 0), strtoul(headers["Valid-Until"].c_str(), NULL, 0)); + std::vector dummyInput(network.getNumInputNodes(), 1.); + network.evalModel(dummyInput); + LOGP(info, "Retrieved NN corrections for production tag {}, pass number {}, NN-Version number{}", headers["LPMProductionTag"], headers["RecoPassName"], headers["NN-Version"]); + } else { + LOG(fatal) << "No valid NN object found matching retrieved Bethe-Bloch parametrisation for pass " << metadata["RecoPassName"] << ". Please ensure that the requested pass has dedicated NN corrections available"; + } + } + } + + // Defining some network parameters + int input_dimensions = network.getNumInputNodes(); + int output_dimensions = network.getNumOutputNodes(); + const uint64_t track_prop_size = input_dimensions * size; + const uint64_t prediction_size = output_dimensions * size; + + network_prediction = std::vector(prediction_size * 9); // For each mass hypotheses + const float nNclNormalization = response->GetNClNormalization(); + float duration_network = 0; + + std::vector track_properties(track_prop_size); + uint64_t counter_track_props = 0; + int loop_counter = 0; + + // Filling a std::vector to be evaluated by the network + // Evaluation on single tracks brings huge overhead: Thus evaluation is done on one large vector + for (int i = 0; i < 9; i++) { // Loop over particle number for which network correction is used + for (auto const& trk : tracks) { + if (!trk.hasTPC()) { + continue; + } + if (pidTPCopts.skipTPCOnly) { + if (!trk.hasITS() && !trk.hasTRD() && !trk.hasTOF()) { + continue; + } + } + track_properties[counter_track_props] = trk.tpcInnerParam(); + track_properties[counter_track_props + 1] = trk.tgl(); + track_properties[counter_track_props + 2] = trk.signed1Pt(); + track_properties[counter_track_props + 3] = o2::track::pid_constants::sMasses[i]; + track_properties[counter_track_props + 4] = trk.has_collision() ? mults[trk.collisionId()] / 11000. : 1.; + track_properties[counter_track_props + 5] = std::sqrt(nNclNormalization / trk.tpcNClsFound()); + if (input_dimensions == 7 && networkVersion == "2") { + track_properties[counter_track_props + 6] = trk.has_collision() ? collisions.iteratorAt(trk.collisionId()).ft0cOccupancyInTimeRange() / 60000. : 1.; + } + counter_track_props += input_dimensions; + } + + auto start_network_eval = std::chrono::high_resolution_clock::now(); + float* output_network = network.evalModel(track_properties); + auto stop_network_eval = std::chrono::high_resolution_clock::now(); + duration_network += std::chrono::duration>(stop_network_eval - start_network_eval).count(); + for (uint64_t i = 0; i < prediction_size; i += output_dimensions) { + for (int j = 0; j < output_dimensions; j++) { + network_prediction[i + j + prediction_size * loop_counter] = output_network[i + j]; + } + } + + counter_track_props = 0; + loop_counter += 1; + } + track_properties.clear(); + + auto stop_network_total = std::chrono::high_resolution_clock::now(); + LOG(debug) << "Neural Network for the TPC PID response correction: Time per track (eval ONNX): " << duration_network / (size * 9) << "ns ; Total time (eval ONNX): " << duration_network / 1000000000 << " s"; + LOG(debug) << "Neural Network for the TPC PID response correction: Time per track (eval + overhead): " << std::chrono::duration>(stop_network_total - start_network_total).count() / (size * 9) << "ns ; Total time (eval + overhead): " << std::chrono::duration>(stop_network_total - start_network_total).count() / 1000000000 << " s"; + + return network_prediction; + } + + //__________________________________________________ + template + void makePidTables(const int flagFull, NSF& tableFull, const int flagTiny, NST& tableTiny, const o2::track::PID::ID pid, const float tpcSignal, const T& trk, const long multTPC, const std::vector& network_prediction, const int& count_tracks, const int& tracksForNet_size) + { + if (flagFull != 1 && flagTiny != 1) { + return; + } + if (!trk.hasTPC() || tpcSignal < 0.f) { + if (flagFull) + tableFull(-999.f, -999.f); + if (flagTiny) + tableTiny(aod::pidtpc_tiny::binning::underflowBin); + return; + } + if (pidTPCopts.skipTPCOnly) { + if (!trk.hasITS() && !trk.hasTRD() && !trk.hasTOF()) { + if (flagFull) + tableFull(-999.f, -999.f); + if (flagTiny) + tableTiny(aod::pidtpc_tiny::binning::underflowBin); + return; + } + } + auto expSignal = response->GetExpectedSignal(trk, pid); + auto expSigma = trk.has_collision() ? response->GetExpectedSigmaAtMultiplicity(multTPC, trk, pid) : 0.07 * expSignal; // use default sigma value of 7% if no collision information to estimate resolution + if (expSignal < 0. || expSigma < 0.) { // skip if expected signal invalid + if (flagFull) + tableFull(-999.f, -999.f); + if (flagTiny) + tableTiny(aod::pidtpc_tiny::binning::underflowBin); + return; + } + + float nSigma = -999.f; + float bg = trk.tpcInnerParam() / o2::track::pid_constants::sMasses[pid]; // estimated beta-gamma for network cutoff + if (pidTPCopts.useNetworkCorrection && speciesNetworkFlags[pid] && trk.has_collision() && bg > pidTPCopts.networkBetaGammaCutoff) { + + // Here comes the application of the network. The output--dimensions of the network determine the application: 1: mean, 2: sigma, 3: sigma asymmetric + // For now only the option 2: sigma will be used. The other options are kept if there would be demand later on + if (network.getNumOutputNodes() == 1) { // Expected mean correction; no sigma correction + nSigma = (tpcSignal - network_prediction[count_tracks + tracksForNet_size * pid] * expSignal) / expSigma; + } else if (network.getNumOutputNodes() == 2) { // Symmetric sigma correction + expSigma = (network_prediction[2 * (count_tracks + tracksForNet_size * pid) + 1] - network_prediction[2 * (count_tracks + tracksForNet_size * pid)]) * expSignal; + nSigma = (tpcSignal / expSignal - network_prediction[2 * (count_tracks + tracksForNet_size * pid)]) / (network_prediction[2 * (count_tracks + tracksForNet_size * pid) + 1] - network_prediction[2 * (count_tracks + tracksForNet_size * pid)]); + } else if (network.getNumOutputNodes() == 3) { // Asymmetric sigma corection + if (tpcSignal / expSignal >= network_prediction[3 * (count_tracks + tracksForNet_size * pid)]) { + expSigma = (network_prediction[3 * (count_tracks + tracksForNet_size * pid) + 1] - network_prediction[3 * (count_tracks + tracksForNet_size * pid)]) * expSignal; + nSigma = (tpcSignal / expSignal - network_prediction[3 * (count_tracks + tracksForNet_size * pid)]) / (network_prediction[3 * (count_tracks + tracksForNet_size * pid) + 1] - network_prediction[3 * (count_tracks + tracksForNet_size * pid)]); + } else { + expSigma = (network_prediction[3 * (count_tracks + tracksForNet_size * pid)] - network_prediction[3 * (count_tracks + tracksForNet_size * pid) + 2]) * expSignal; + nSigma = (tpcSignal / expSignal - network_prediction[3 * (count_tracks + tracksForNet_size * pid)]) / (network_prediction[3 * (count_tracks + tracksForNet_size * pid)] - network_prediction[3 * (count_tracks + tracksForNet_size * pid) + 2]); + } + } else { + LOGF(fatal, "Network output-dimensions incompatible!"); + } + } else { + nSigma = response->GetNumberOfSigmaMCTunedAtMultiplicity(multTPC, trk, pid, tpcSignal); + } + if (flagFull) + tableFull(expSigma, nSigma); + if (flagTiny) + aod::pidtpc_tiny::binning::packInTable(nSigma, tableTiny); + }; + + //__________________________________________________ + template + void process(TCCDB& ccdb, TCCDBApi& ccdbApi, TBCs const& bcs, TCollisions const& cols, TTracks const& tracks, TTracksQA const& tracksQA, TProducts& products) + { + if (tracks.size() == 0) { + return; // empty protection + } + auto trackiterator = tracks.begin(); + if constexpr (requires { trackiterator.mcParticleId(); }) { + gRandom->SetSeed(0); // Ensure unique seed from UUID for each process call + } + + // preparatory step: we need the multiplicities for each collision + std::vector pidmults; + long totalTPCtracks = 0; + long totalTPCnotStandalone = 0; + pidmults.resize(cols.size(), 0); + + // faster counting + for (const auto& track : tracks) { + if (track.hasTPC()) { + if (track.collisionId() > -1) { + pidmults[track.collisionId()]++; + } + totalTPCtracks++; + if (track.hasITS() || track.hasTOF() || track.hasTRD()) { + totalTPCnotStandalone++; + } + } + } + + const uint64_t outTable_size = tracks.size(); + + auto reserveTable = [&outTable_size](const o2::framework::Configurable& flag, auto& table) { + if (flag.value != 1) { + return; + } + table.reserve(outTable_size); + }; + + // Prepare memory for enabled tables + reserveTable(pidTPCopts.pidFullEl, products.tablePIDFullEl); + reserveTable(pidTPCopts.pidFullMu, products.tablePIDFullMu); + reserveTable(pidTPCopts.pidFullPi, products.tablePIDFullPi); + reserveTable(pidTPCopts.pidFullKa, products.tablePIDFullKa); + reserveTable(pidTPCopts.pidFullPr, products.tablePIDFullPr); + reserveTable(pidTPCopts.pidFullDe, products.tablePIDFullDe); + reserveTable(pidTPCopts.pidFullTr, products.tablePIDFullTr); + reserveTable(pidTPCopts.pidFullHe, products.tablePIDFullHe); + reserveTable(pidTPCopts.pidFullAl, products.tablePIDFullAl); + + reserveTable(pidTPCopts.pidTinyEl, products.tablePIDTinyEl); + reserveTable(pidTPCopts.pidTinyMu, products.tablePIDTinyMu); + reserveTable(pidTPCopts.pidTinyPi, products.tablePIDTinyPi); + reserveTable(pidTPCopts.pidTinyKa, products.tablePIDTinyKa); + reserveTable(pidTPCopts.pidTinyPr, products.tablePIDTinyPr); + reserveTable(pidTPCopts.pidTinyDe, products.tablePIDTinyDe); + reserveTable(pidTPCopts.pidTinyTr, products.tablePIDTinyTr); + reserveTable(pidTPCopts.pidTinyHe, products.tablePIDTinyHe); + reserveTable(pidTPCopts.pidTinyAl, products.tablePIDTinyAl); + + const uint64_t tracksForNet_size = (pidTPCopts.skipTPCOnly) ? totalTPCnotStandalone : totalTPCtracks; + std::vector network_prediction; + + if (pidTPCopts.useNetworkCorrection) { + network_prediction = createNetworkPrediction(ccdb, ccdbApi, cols, pidmults, tracks, bcs, tracksForNet_size); + } + + uint64_t count_tracks = 0; + + //_______________________________________ + // process tracksQA in case present + std::vector indexTrack2TrackQA; + if constexpr (soa::is_table) { + for (const auto& trackQA : tracksQA) { + indexTrack2TrackQA[trackQA.trackId()] = trackQA.globalIndex(); + } + } + //_______________________________________ + + for (auto const& trk : tracks) { + // get the TPC signal to be used in the PID + float tpcSignalToEvaluatePID = trk.tpcSignal(); + + int multTPC = 0; + if (trk.has_collision()) { + multTPC = pidmults[trk.collisionId()]; + } + + // if corrected dE/dx is requested, correct it here on the spot and use that + if (pidTPCopts.useCorrecteddEdx) { + + //_________________________________________________________ + // bypass TPC signal in case TracksQA information present + if constexpr (soa::is_table) { + tpcSignalToEvaluatePID = -999.f; + if (indexTrack2TrackQA[trk.globalIndex()] != -1) { + auto trackQA = tracksQA.rawIteratorAt(indexTrack2TrackQA[trk.globalIndex()]); + tpcSignalToEvaluatePID = trackQA.tpcdEdxNorm(); + } + } + //_________________________________________________________ + + double hadronicRate; + int occupancy; + if (trk.has_collision()) { + auto collision = cols.iteratorAt(trk.collisionId()); + auto bc = collision.template bc_as(); + const int runnumber = bc.runNumber(); + hadronicRate = mRateFetcher.fetch(ccdb.service, bc.timestamp(), runnumber, "ZNC hadronic") * 1.e-3; // kHz + occupancy = collision.trackOccupancyInTimeRange(); + } else { + auto bc = bcs.begin(); + const int runnumber = bc.runNumber(); + hadronicRate = mRateFetcher.fetch(ccdb.service, bc.timestamp(), runnumber, "ZNC hadronic") * 1.e-3; // kHz + occupancy = 0; + } + + float fTPCSignal = tpcSignalToEvaluatePID; + float fNormMultTPC = multTPC / 11000.; + + float fTrackOccN = occupancy / 1000.; + float fOccTPCN = fNormMultTPC * 10; //(fNormMultTPC*10).clip(0,12) + if (fOccTPCN > 12) + fOccTPCN = 12; + else if (fOccTPCN < 0) + fOccTPCN = 0; + + float fTrackOccMeanN = hadronicRate / 5; + float side = trk.tgl() > 0 ? 1 : 0; + float a1pt = std::abs(trk.signed1Pt()); + float a1pt2 = a1pt * a1pt; + float atgl = std::abs(trk.tgl()); + float mbb0R = 50 / fTPCSignal; + if (mbb0R > 1.05) + mbb0R = 1.05; + else if (mbb0R < 0.05) + mbb0R = 0.05; + // float mbb0R = max(0.05, min(50 / fTPCSignal, 1.05)); + float a1ptmbb0R = a1pt * mbb0R; + float atglmbb0R = atgl * mbb0R; + + std::vector vec_occu = {fTrackOccN, fOccTPCN, fTrackOccMeanN}; + std::vector vec_track = {mbb0R, a1pt, atgl, atglmbb0R, a1ptmbb0R, side, a1pt2}; + + float fTPCSignalN_CR0 = str_dedx_correction.fReal_fTPCSignalN(vec_occu, vec_track); + + float mbb0R1 = 50 / (fTPCSignal / fTPCSignalN_CR0); + if (mbb0R1 > 1.05) + mbb0R1 = 1.05; + else if (mbb0R1 < 0.05) + mbb0R1 = 0.05; + + std::vector vec_track1 = {mbb0R1, a1pt, atgl, atgl * mbb0R1, a1pt * mbb0R1, side, a1pt2}; + float fTPCSignalN_CR1 = str_dedx_correction.fReal_fTPCSignalN(vec_occu, vec_track1); + + // change the signal used for PID + tpcSignalToEvaluatePID = fTPCSignal / fTPCSignalN_CR1; + + if (pidTPCopts.savedEdxsCorrected) { + // populated cursor if requested or autodetected + products.dEdxCorrected(tpcSignalToEvaluatePID); + } + } + + const auto& bc = trk.has_collision() ? cols.rawIteratorAt(trk.collisionId()).template bc_as() : bcs.begin(); + if (useCCDBParam && pidTPCopts.ccdbTimestamp.value == 0 && !ccdb->isCachedObjectValid(pidTPCopts.ccdbPath.value, bc.timestamp())) { // Updating parametrisation only if the initial timestamp is 0 + if (pidTPCopts.recoPass.value == "") { + LOGP(info, "Retrieving latest TPC response object for timestamp {}:", bc.timestamp()); + } else { + LOGP(info, "Retrieving TPC Response for timestamp {} and recoPass {}:", bc.timestamp(), pidTPCopts.recoPass.value); + } + response = ccdb->template getSpecific(pidTPCopts.ccdbPath.value, bc.timestamp(), metadata); + headers = ccdbApi.retrieveHeaders(pidTPCopts.ccdbPath.value, metadata, bc.timestamp()); + if (!response) { + LOGP(warning, "!! Could not find a valid TPC response object for specific pass name {}! Falling back to latest uploaded object.", metadata["RecoPassName"]); + response = ccdb->template getForTimeStamp(pidTPCopts.ccdbPath.value, bc.timestamp()); + headers = ccdbApi.retrieveHeaders(pidTPCopts.ccdbPath.value, nullmetadata, bc.timestamp()); + if (!response) { + LOGP(fatal, "Could not find ANY TPC response object for the timestamp {}!", bc.timestamp()); + } + } + LOG(info) << "Successfully retrieved TPC PID object from CCDB for timestamp " << bc.timestamp() << ", period " << headers["LPMProductionTag"] << ", recoPass " << headers["RecoPassName"]; + response->PrintAll(); + } + + // if this is a MC process function, go for MC tune on data processing + if constexpr (requires { trk.mcParticleId(); }) { + // Perform TuneOnData sampling for MC dE/dx + float mcTunedTPCSignal = 0.; + if (!trk.hasTPC()) { + mcTunedTPCSignal = -999.f; + } else { + if (pidTPCopts.skipTPCOnly) { + if (!trk.hasITS() && !trk.hasTRD() && !trk.hasTOF()) { + mcTunedTPCSignal = -999.f; + } + } + int pid = getPIDIndex(trk.mcParticle().pdgCode()); + + auto expSignal = response->GetExpectedSignal(trk, pid); + auto expSigma = response->GetExpectedSigmaAtMultiplicity(multTPC, trk, pid); + if (expSignal < 0. || expSigma < 0.) { // if expectation invalid then give undefined signal + mcTunedTPCSignal = -999.f; + } + float bg = trk.tpcInnerParam() / o2::track::pid_constants::sMasses[pid]; // estimated beta-gamma for network cutoff + + if (pidTPCopts.useNetworkCorrection && speciesNetworkFlags[pid] && trk.has_collision() && bg > pidTPCopts.networkBetaGammaCutoff) { + auto mean = network_prediction[2 * (count_tracks + tracksForNet_size * pid)] * expSignal; // Absolute mean, i.e. the mean dE/dx value of the data in that slice, not the mean of the NSigma distribution + auto sigma = (network_prediction[2 * (count_tracks + tracksForNet_size * pid) + 1] - network_prediction[2 * (count_tracks + tracksForNet_size * pid)]) * expSignal; + if (mean < 0.f || sigma < 0.f) { + mcTunedTPCSignal = -999.f; + } else { + mcTunedTPCSignal = gRandom->Gaus(mean, sigma); + } + } else { + mcTunedTPCSignal = gRandom->Gaus(expSignal, expSigma); + } + } + tpcSignalToEvaluatePID = mcTunedTPCSignal; // pass this for further eval + if (pidTPCopts.enableTuneOnDataTable) + products.tableTuneOnData(mcTunedTPCSignal); + } + + auto makePidTablesDefault = [&trk, &tpcSignalToEvaluatePID, &multTPC, &network_prediction, &count_tracks, &tracksForNet_size, this](const int flagFull, auto& tableFull, const int flagTiny, auto& tableTiny, const o2::track::PID::ID pid) { + this->makePidTables(flagFull, tableFull, flagTiny, tableTiny, pid, tpcSignalToEvaluatePID, trk, multTPC, network_prediction, count_tracks, tracksForNet_size); + }; + + makePidTablesDefault(pidTPCopts.pidFullEl, products.tablePIDFullEl, pidTPCopts.pidTinyEl, products.tablePIDTinyEl, o2::track::PID::Electron); + makePidTablesDefault(pidTPCopts.pidFullMu, products.tablePIDFullMu, pidTPCopts.pidTinyMu, products.tablePIDTinyMu, o2::track::PID::Muon); + makePidTablesDefault(pidTPCopts.pidFullPi, products.tablePIDFullPi, pidTPCopts.pidTinyPi, products.tablePIDTinyPi, o2::track::PID::Pion); + makePidTablesDefault(pidTPCopts.pidFullKa, products.tablePIDFullKa, pidTPCopts.pidTinyKa, products.tablePIDTinyKa, o2::track::PID::Kaon); + makePidTablesDefault(pidTPCopts.pidFullPr, products.tablePIDFullPr, pidTPCopts.pidTinyPr, products.tablePIDTinyPr, o2::track::PID::Proton); + makePidTablesDefault(pidTPCopts.pidFullDe, products.tablePIDFullDe, pidTPCopts.pidTinyDe, products.tablePIDTinyDe, o2::track::PID::Deuteron); + makePidTablesDefault(pidTPCopts.pidFullTr, products.tablePIDFullTr, pidTPCopts.pidTinyTr, products.tablePIDTinyTr, o2::track::PID::Triton); + makePidTablesDefault(pidTPCopts.pidFullHe, products.tablePIDFullHe, pidTPCopts.pidTinyHe, products.tablePIDTinyHe, o2::track::PID::Helium3); + makePidTablesDefault(pidTPCopts.pidFullAl, products.tablePIDFullAl, pidTPCopts.pidTinyAl, products.tablePIDTinyAl, o2::track::PID::Alpha); + + if (trk.hasTPC() && (!pidTPCopts.skipTPCOnly || trk.hasITS() || trk.hasTRD() || trk.hasTOF())) { + count_tracks++; // Increment network track counter only if track has TPC, and (not skipping TPConly) or (is not TPConly) + } + } + } // end process function +}; + +} // namespace pid +} // namespace o2::aod + +#endif // COMMON_TOOLS_PIDTPCMODULE_H_ diff --git a/Common/TableProducer/PID/pidTPCService.cxx b/Common/TableProducer/PID/pidTPCService.cxx new file mode 100644 index 00000000000..cff700fca1c --- /dev/null +++ b/Common/TableProducer/PID/pidTPCService.cxx @@ -0,0 +1,118 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file trackPropagationTester.cxx +/// \brief testing ground for track propagation +/// \author ALICE + +//=============================================================== +// +// Modularized version of TPC PID task +// +//=============================================================== + +#include +#include +#include +#include +#include +// ROOT includes +#include "TFile.h" +#include "TRandom.h" +#include "TSystem.h" + +// O2 includes +#include "MetadataHelper.h" +#include "TableHelper.h" +#include "pidTPCBase.h" +#include "pidTPCModule.h" + +#include "Common/Core/PID/TPCPIDResponse.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Tools/ML/model.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +using namespace o2; +using namespace o2::framework; + +o2::common::core::MetadataHelper metadataInfo; // Metadata helper + +struct pidTpcService { + + // CCDB boilerplate declarations + o2::framework::Configurable ccdburl{"ccdburl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Service ccdb; + o2::ccdb::CcdbApi ccdbApi; + + o2::aod::pid::pidTPCProducts products; + o2::aod::pid::pidTPCConfigurables pidTPCopts; + o2::aod::pid::pidTPCModule pidTPC; + + void init(o2::framework::InitContext& initContext) + { + // CCDB boilerplate init + ccdb->setURL(ccdburl.value); + ccdb->setFatalWhenNull(false); // manual fallback in case ccdb entry empty + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + ccdbApi.init(ccdburl.value); + + // task-specific + pidTPC.init(ccdb, ccdbApi, initContext, pidTPCopts, metadataInfo); + } + + void processTracks(soa::Join const& collisions, soa::Join const& tracks, aod::BCsWithTimestamps const& bcs) + { + pidTPC.process(ccdb, ccdbApi, bcs, collisions, tracks, static_cast(nullptr), products); + } + void processTracksWithTracksQA(soa::Join const& collisions, soa::Join const& tracks, aod::BCsWithTimestamps const& bcs, aod::TracksQA const& tracksQA) + { + pidTPC.process(ccdb, ccdbApi, bcs, collisions, tracks, tracksQA, products); + } + + void processTracksMC(soa::Join const& collisions, soa::Join const& tracks, aod::BCsWithTimestamps const& bcs, aod::McParticles const&) + { + pidTPC.process(ccdb, ccdbApi, bcs, collisions, tracks, static_cast(nullptr), products); + } + + void processTracksIU(soa::Join const& collisions, soa::Join const& tracks, aod::BCsWithTimestamps const& bcs) + { + pidTPC.process(ccdb, ccdbApi, bcs, collisions, tracks, static_cast(nullptr), products); + } + + PROCESS_SWITCH(pidTpcService, processTracks, "Process Tracks", false); + PROCESS_SWITCH(pidTpcService, processTracksMC, "Process Tracks in MC (enables tune-on-data)", false); + PROCESS_SWITCH(pidTpcService, processTracksIU, "Process TracksIU (experimental)", true); +}; + +//**************************************************************************************** +/** + * Workflow definition. + */ +//**************************************************************************************** +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + // Parse the metadata for later too + metadataInfo.initMetadata(cfgc); + + WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; + return workflow; +} diff --git a/Common/TableProducer/caloClusterProducer.cxx b/Common/TableProducer/caloClusterProducer.cxx index 086885beb4c..6b660ad4c68 100644 --- a/Common/TableProducer/caloClusterProducer.cxx +++ b/Common/TableProducer/caloClusterProducer.cxx @@ -14,36 +14,35 @@ /// /// \author Dmitri Peresunko +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/CaloClusters.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include #include #include #include -#include "Framework/ConfigParamSpec.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/CaloClusters.h" -#include "Common/Core/trackUtilities.h" -#include "ReconstructionDataFormats/TrackParametrization.h" -#include "DetectorsBase/Propagator.h" - -#include "CommonUtils/NameConf.h" -#include "CCDB/BasicCCDBManager.h" -#include "SimulationDataFormat/MCTruthContainer.h" - -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsPHOS/Cell.h" -#include "DataFormatsPHOS/Cluster.h" -#include "DataFormatsPHOS/TriggerRecord.h" -#include "DataFormatsPHOS/MCLabel.h" -#include "DataFormatsPHOS/BadChannelsMap.h" -#include "DataFormatsPHOS/CalibParams.h" -#include "PHOSBase/Geometry.h" -#include "PHOSReconstruction/Clusterer.h" - using namespace o2::framework; using namespace o2; @@ -105,9 +104,9 @@ struct CaloClusterProducer { ~TrackTrigRec() = default; public: - int64_t mTR; // BC ref - int mStart[kCpvCells]; // X (phi) track coordinate in PHOS plane - int mEnd[kCpvCells]; // Z (theta) track coordinate in PHOS plane + int64_t mTR{-1}; // BC ref + int mStart[kCpvCells] = {0}; // X (phi) track coordinate in PHOS plane + int mEnd[kCpvCells] = {0}; // Z (theta) track coordinate in PHOS plane }; void init(o2::framework::InitContext&) @@ -141,18 +140,18 @@ struct CaloClusterProducer { // If several collisions appear in BC, choose one with largers number of contributors std::map colMap; - int colId = 0; + int colIdOuter = 0; for (const auto& cl : colls) { auto colbc = colMap.find(cl.bc_as().globalBC()); if (colbc == colMap.end()) { // single collision per BC - colMap[cl.bc_as().globalBC()] = colId; + colMap[cl.bc_as().globalBC()] = colIdOuter; } else { // not unique collision per BC auto coll2 = colls.begin() + colbc->second; if (cl.numContrib() > coll2.numContrib()) { - colMap[cl.bc_as().globalBC()] = colId; + colMap[cl.bc_as().globalBC()] = colIdOuter; } } - colId++; + colIdOuter++; } // Fill list of cells and cell TrigRecs per TF as an input for clusterizer @@ -272,13 +271,13 @@ struct CaloClusterProducer { // Extract primary vertex TVector3 vtx = {0., 0., 0.}; // default, if not collision will be found - int colId = -1; + int colIdInner = -1; auto coliter = colMap.find(cluTR.getBCData().toLong()); if (coliter != colMap.end()) { // get vertex from collision // find collision corresponding to current BC auto clvtx = colls.begin() + coliter->second; vtx.SetXYZ(clvtx.posX(), clvtx.posY(), clvtx.posZ()); - colId = coliter->second; + colIdInner = coliter->second; } bool cpvExist = false; @@ -381,7 +380,7 @@ struct CaloClusterProducer { clu.getElipsAxis(lambdaShort, lambdaLong); // Clear Collision assignment - if (colId == -1) { + if (colIdInner == -1) { // Ambiguos Collision assignment cluambcursor( bcMap[cluTR.getBCData().toLong()], @@ -395,7 +394,7 @@ struct CaloClusterProducer { clu.getDistanceToBadChannel()); } else { // Normal collision - auto col = colls.begin() + colId; + auto col = colls.begin() + colIdInner; clucursor( col, mom.X(), mom.Y(), mom.Z(), e, @@ -435,18 +434,18 @@ struct CaloClusterProducer { // If several collisions appear in BC, choose one with largers number of contributors std::map colMap; - int colId = 0; + int colIdOuter = 0; for (auto const& cl : colls) { auto colbc = colMap.find(cl.bc_as().globalBC()); if (colbc == colMap.end()) { // single collision per BC - colMap[cl.bc_as().globalBC()] = colId; + colMap[cl.bc_as().globalBC()] = colIdOuter; } else { // not unique collision per BC auto coll2 = colls.begin() + colbc->second; if (cl.numContrib() > coll2.numContrib()) { - colMap[cl.bc_as().globalBC()] = colId; + colMap[cl.bc_as().globalBC()] = colIdOuter; } } - colId++; + colIdOuter++; } // Fill list of cells and cell TrigRecs per TF as an input for clusterizer @@ -588,13 +587,13 @@ struct CaloClusterProducer { // Extract primary vertex TVector3 vtx = {0., 0., 0.}; // default, if not collision will be found - int colId = -1; + int colIdInner = -1; auto coliter = colMap.find(cluTR.getBCData().toLong()); if (coliter != colMap.end()) { // get vertex from collision // find collision corresponding to current BC auto clvtx = colls.begin() + coliter->second; vtx.SetXYZ(clvtx.posX(), clvtx.posY(), clvtx.posZ()); - colId = coliter->second; + colIdInner = coliter->second; } bool cpvExist = false; @@ -705,7 +704,7 @@ struct CaloClusterProducer { mcamplitudes.push_back(cellLab.getEdep()); } // Clear Collision assignment - if (colId == -1) { + if (colIdInner == -1) { // Ambiguos Collision assignment cluambcursor( bcMap[cluTR.getBCData().toLong()], @@ -722,7 +721,7 @@ struct CaloClusterProducer { mcamplitudes); } else { // Normal collision - auto col = colls.begin() + colId; + auto col = colls.begin() + colIdInner; clucursor( col, mom.X(), mom.Y(), mom.Z(), e, @@ -778,18 +777,18 @@ struct CaloClusterProducer { // If several collisions appear in BC, choose one with largers number of contributors std::map colMap; - int colId = 0; + int colIdOuter = 0; for (const auto& cl : colls) { auto colbc = colMap.find(cl.bc_as().globalBC()); if (colbc == colMap.end()) { // single collision per BC - colMap[cl.bc_as().globalBC()] = colId; + colMap[cl.bc_as().globalBC()] = colIdOuter; } else { // not unique collision per BC auto coll2 = colls.begin() + colbc->second; if (cl.numContrib() > coll2.numContrib()) { - colMap[cl.bc_as().globalBC()] = colId; + colMap[cl.bc_as().globalBC()] = colIdOuter; } } - colId++; + colIdOuter++; } // Fill list of cells and cell TrigRecs per TF as an input for clusterizer // clusterize @@ -982,13 +981,13 @@ struct CaloClusterProducer { // Extract primary vertex TVector3 vtx = {0., 0., 0.}; // default, if not collision will be found - int colId = -1; + int colIdInner = -1; auto coliter = colMap.find(cluTR.getBCData().toLong()); if (coliter != colMap.end()) { // get vertex from collision // find collision corresponding to current BC auto clvtx = colls.begin() + coliter->second; vtx.SetXYZ(clvtx.posX(), clvtx.posY(), clvtx.posZ()); - colId = coliter->second; + colIdInner = coliter->second; } bool cpvExist = false; @@ -1119,7 +1118,7 @@ struct CaloClusterProducer { if (cpvExist) { cpvindex = -1; // there were CPV clusters } - if (colId == -1) { + if (colIdInner == -1) { // Ambiguos Collision assignment cluambcursor( bcMap[cluTR.getBCData().toLong()], @@ -1133,7 +1132,7 @@ struct CaloClusterProducer { clu.getDistanceToBadChannel()); } else { // Normal collision - auto col = colls.begin() + colId; + auto col = colls.begin() + colIdInner; clucursor( col, mom.X(), mom.Y(), mom.Z(), e, @@ -1187,18 +1186,18 @@ struct CaloClusterProducer { // If several collisions appear in BC, choose one with largers number of contributors std::map colMap; - int colId = 0; + int colIdOuter = 0; for (const auto& cl : colls) { auto colbc = colMap.find(cl.bc_as().globalBC()); if (colbc == colMap.end()) { // single collision per BC - colMap[cl.bc_as().globalBC()] = colId; + colMap[cl.bc_as().globalBC()] = colIdOuter; } else { // not unique collision per BC auto coll2 = colls.begin() + colbc->second; if (cl.numContrib() > coll2.numContrib()) { - colMap[cl.bc_as().globalBC()] = colId; + colMap[cl.bc_as().globalBC()] = colIdOuter; } } - colId++; + colIdOuter++; } // Fill list of cells and cell TrigRecs per TF as an input for clusterizer // clusterize @@ -1413,13 +1412,13 @@ struct CaloClusterProducer { // Extract primary vertex TVector3 vtx = {0., 0., 0.}; // default, if not collision will be found - int colId = -1; + int colIdInner = -1; auto coliter = colMap.find(cluTR.getBCData().toLong()); if (coliter != colMap.end()) { // get vertex from collision // find collision corresponding to current BC auto clvtx = colls.begin() + coliter->second; vtx.SetXYZ(clvtx.posX(), clvtx.posY(), clvtx.posZ()); - colId = coliter->second; + colIdInner = coliter->second; } bool cpvExist = false; @@ -1555,7 +1554,7 @@ struct CaloClusterProducer { mclabels.push_back(cellLab.getTrackID()); // Track ID in current event? mcamplitudes.push_back(cellLab.getEdep()); } - if (colId == -1) { + if (colIdInner == -1) { // Ambiguos Collision assignment cluambcursor( bcMap[cluTR.getBCData().toLong()], @@ -1571,7 +1570,7 @@ struct CaloClusterProducer { mclabels, mcamplitudes); } else { // Normal collision - auto col = colls.begin() + colId; + auto col = colls.begin() + colIdInner; clucursor( col, mom.X(), mom.Y(), mom.Z(), e, diff --git a/Common/TableProducer/centralityTable.cxx b/Common/TableProducer/centralityTable.cxx index 9198f79499e..e83c41d00c1 100644 --- a/Common/TableProducer/centralityTable.cxx +++ b/Common/TableProducer/centralityTable.cxx @@ -15,25 +15,28 @@ /// \author ALICE // -#include -#include -#include -#include +#include "MetadataHelper.h" +#include "TableHelper.h" -#include -#include -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/HistogramRegistry.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" -#include "MetadataHelper.h" -#include "TableHelper.h" -#include "TList.h" +#include "Common/DataModel/Multiplicity.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -410,7 +413,7 @@ struct CentralityTable { } } - auto scaleMC = [](float x, float pars[6]) { + auto scaleMC = [](float x, const float pars[6]) { return std::pow(((pars[0] + pars[1] * std::pow(x, pars[2])) - pars[3]) / pars[4], 1.0f / pars[5]); }; @@ -647,7 +650,7 @@ struct CentralityTable { auto populateTable = [&](auto& table, struct CalibrationInfo& estimator, float multiplicity) { const bool assignOutOfRange = embedINELgtZEROselection && !collision.isInelGt0(); - auto scaleMC = [](float x, float pars[6]) { + auto scaleMC = [](float x, const float pars[6]) { return std::pow(((pars[0] + pars[1] * std::pow(x, pars[2])) - pars[3]) / pars[4], 1.0f / pars[5]); }; diff --git a/Common/TableProducer/eventSelection.cxx b/Common/TableProducer/eventSelection.cxx index b517bb90010..25225144ab5 100644 --- a/Common/TableProducer/eventSelection.cxx +++ b/Common/TableProducer/eventSelection.cxx @@ -14,34 +14,55 @@ /// /// \author Evgeny Kryshen and Igor Altsybeev -#include -#include -#include -#include - -#include "Framework/ConfigParamSpec.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" #include "Common/DataModel/EventSelection.h" + #include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/RCTSelectionFlags.h" #include "Common/CCDB/TriggerAliases.h" -#include "CCDB/BasicCCDBManager.h" -#include "CommonConstants/LHCConstants.h" -#include "Framework/HistogramRegistry.h" -#include "DataFormatsFT0/Digit.h" -#include "DataFormatsParameters/GRPLHCIFData.h" -#include "DataFormatsParameters/GRPECSObject.h" -#include "ITSMFTBase/DPLAlpideParam.h" -#include "MetadataHelper.h" -#include "DataFormatsParameters/AggregatedRunInfo.h" -#include "DataFormatsITSMFT/NoiseMap.h" // missing include in TimeDeadMap.h -#include "DataFormatsITSMFT/TimeDeadMap.h" -#include "ITSMFTReconstruction/ChipMappingITS.h" -#include "DataFormatsCTP/Configuration.h" -#include "DataFormatsCTP/Scalers.h" - -#include "TH1D.h" +#include "Common/Core/MetadataHelper.h" + +#include +#include +#include +#include +#include +#include // missing include in TimeDeadMap. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -317,7 +338,7 @@ struct BcSelectionTask { if (mapRCT == nullptr) { LOGP(info, "rct object missing... inserting dummy rct flags"); mapRCT = new std::map; - uint32_t dummyValue = 1 << 31; // setting bit 31 to indicate that rct object is missing + uint32_t dummyValue = 1u << 31; // setting bit 31 to indicate that rct object is missing mapRCT->insert(std::pair(sorTimestamp, dummyValue)); } } @@ -521,7 +542,7 @@ struct EventSelectionTask { int rofLength = -1; // ITS ROF length, in bc std::string strLPMProductionTag = ""; // MC production tag to be retrieved from AO2D metadata - int32_t findClosest(int64_t globalBC, std::map& bcs) + int32_t findClosest(int64_t globalBC, const std::map& bcs) { auto it = bcs.lower_bound(globalBC); int64_t bc1 = it->first; @@ -1286,7 +1307,7 @@ struct LumiTask { LOGP(warn, "Cross section for z={} + z={} @ {} GeV is not defined", beamZ1, beamZ2, sqrts); } // getting CTP config to extract lumi class indices (used for rate fetching and pileup correction) - std::map metadata; + std::map metadata; metadata["runNumber"] = std::to_string(run); auto config = ccdb->getSpecific("CTP/Config/Config", ts, metadata); auto classes = config->getCTPClasses(); diff --git a/Common/TableProducer/multiplicityExtraTable.cxx b/Common/TableProducer/multiplicityExtraTable.cxx index 001e75e6adb..5b0840e5f2d 100644 --- a/Common/TableProducer/multiplicityExtraTable.cxx +++ b/Common/TableProducer/multiplicityExtraTable.cxx @@ -36,6 +36,9 @@ struct MultiplicityExtraTable { Produces mult2bc; Produces bc2mult; + // auxiliary for MC + Produces multHepMCHIs; + // Allow for downscaling of BC table for less space use in derived data Configurable bcDownscaleFactor{"bcDownscaleFactor", 2, "Downscale factor for BC table (0: save nothing, 1: save all)"}; Configurable minFT0CforBCTable{"minFT0CforBCTable", 25.0f, "Minimum FT0C amplitude to fill BC table to reduce data"}; @@ -277,9 +280,22 @@ struct MultiplicityExtraTable { } } + void processHepMCHeavyIons(aod::HepMCHeavyIons const& hepmchis) + { + for (auto const& hepmchi : hepmchis) { + multHepMCHIs(hepmchi.mcCollisionId(), + hepmchi.ncollHard(), + hepmchi.npartProj(), + hepmchi.npartTarg(), + hepmchi.ncoll(), + hepmchi.impactParameter()); + } + } + // Process switches PROCESS_SWITCH(MultiplicityExtraTable, processBCs, "Produce BC tables", true); PROCESS_SWITCH(MultiplicityExtraTable, processCollisionNeighbors, "Produce neighbor timing tables", true); + PROCESS_SWITCH(MultiplicityExtraTable, processHepMCHeavyIons, "Produce MultHepMCHIs tables", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/Common/TableProducer/multiplicityTable.cxx b/Common/TableProducer/multiplicityTable.cxx index 12cde8a9869..efbb87908d2 100644 --- a/Common/TableProducer/multiplicityTable.cxx +++ b/Common/TableProducer/multiplicityTable.cxx @@ -15,26 +15,29 @@ /// \author ALICE /// -#include -#include -#include -#include +#include "PWGMM/Mult/DataModel/bestCollisionTable.h" -#include "Framework/ConfigParamSpec.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "CCDB/BasicCCDBManager.h" -#include "Common/DataModel/Multiplicity.h" +#include "Common/Core/MetadataHelper.h" +#include "Common/Core/TableHelper.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "TableHelper.h" -#include "MetadataHelper.h" -#include "TList.h" -#include "PWGMM/Mult/DataModel/bestCollisionTable.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -100,9 +103,9 @@ struct MultiplicityTable { Produces tablePVZeqs; // 12 Produces tableExtraMc; // 13 Produces tableExtraMult2MCExtras; - Produces multHepMCHIs; // Not accounted for, produced using custom process function to avoid dependencies - Produces mftMults; // Not accounted for, produced using custom process function to avoid dependencies - Produces multsGlobal; // Not accounted for, produced based on process function processGlobalTrackingCounters + Produces multHepMCHIs; // Not accounted for, produced using custom process function to avoid dependencies + Produces mftMults; // Not accounted for, produced using custom process function to avoid dependencies + Produces multsGlobal; // Not accounted for, produced based on process function processGlobalTrackingCounters // For vertex-Z corrections in calibration Service ccdb; @@ -521,12 +524,6 @@ struct MultiplicityTable { } break; case kZDCMults: // ZDC { - multZNA = -1.f; - multZNC = -1.f; - multZEM1 = -1.f; - multZEM2 = -1.f; - multZPA = -1.f; - multZPC = -1.f; if (bc.has_zdc()) { multZNA = bc.zdc().amplitudeZNA(); multZNC = bc.zdc().amplitudeZNC(); diff --git a/Common/TableProducer/qVectorsTable.cxx b/Common/TableProducer/qVectorsTable.cxx index 9de8faf028f..9b6189ef121 100644 --- a/Common/TableProducer/qVectorsTable.cxx +++ b/Common/TableProducer/qVectorsTable.cxx @@ -18,32 +18,29 @@ /// (with or without corrections) and save the results in a dedicated table. /// -// C++/ROOT includes. -#include -#include -#include -#include -#include - -// o2Physics includes. -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/RunningWorkflowInfo.h" - #include "Common/Core/EventPlaneHelper.h" +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/FT0Corrected.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/Centrality.h" - #include "Common/DataModel/Qvectors.h" - -#include "Common/Core/TrackSelection.h" #include "Common/DataModel/TrackSelectionTables.h" -// o2 includes. -#include "CCDB/BasicCCDBManager.h" -#include "DetectorsCommonDataFormats/AlignParam.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -78,6 +75,9 @@ struct qVectorsTable { Configurable cfgMinPtOnTPC{"cfgMinPtOnTPC", 0.15, "minimum transverse momentum selection for TPC tracks participating in Q-vector reconstruction"}; Configurable cfgMaxPtOnTPC{"cfgMaxPtOnTPC", 5., "maximum transverse momentum selection for TPC tracks participating in Q-vector reconstruction"}; + Configurable cfgEtaMax{"cfgEtaMax", 0.8, "Maximum pseudorapidiy for charged track"}; + Configurable cfgEtaMin{"cfgEtaMin", -0.8, "Minimum pseudorapidiy for charged track"}; + Configurable cfgCorrLevel{"cfgCorrLevel", 4, "calibration step: 0 = no corr, 1 = gain corr, 2 = rectr, 3 = twist, 4 = full"}; Configurable> cfgnMods{"cfgnMods", {2, 3}, "Modulation of interest"}; Configurable cfgMaxCentrality{"cfgMaxCentrality", 100.f, "max. centrality for Q vector calibration"}; @@ -149,7 +149,7 @@ struct qVectorsTable { Produces qVectorBTotVec; ///////////////////////////////////////////////////////////////// - std::unordered_map useDetector = { + std::unordered_map useDetector = { {"QvectorBTots", cfgUseBTot}, {"QvectorBNegs", cfgUseBNeg}, {"QvectorBPoss", cfgUseBPos}, @@ -164,7 +164,7 @@ struct qVectorsTable { void init(InitContext& initContext) { // Check the sub-detector used - auto& workflows = initContext.services().get(); + const auto& workflows = initContext.services().get(); for (DeviceSpec const& device : workflows.devices) { for (auto const& input : device.inputs) { if (input.matcher.binding == "Qvectors") { @@ -255,7 +255,7 @@ struct qVectorsTable { } fullPath = cfgGainEqPath; fullPath += "/FT0"; - auto objft0Gain = getForTsOrRun>(fullPath, timestamp, runnumber); + const auto objft0Gain = getForTsOrRun>(fullPath, timestamp, runnumber); if (!objft0Gain || cfgCorrLevel == 0) { for (auto i{0u}; i < 208; i++) { FT0RelGainConst.push_back(1.); @@ -266,7 +266,7 @@ struct qVectorsTable { fullPath = cfgGainEqPath; fullPath += "/FV0"; - auto objfv0Gain = getForTsOrRun>(fullPath, timestamp, runnumber); + const auto objfv0Gain = getForTsOrRun>(fullPath, timestamp, runnumber); if (!objfv0Gain || cfgCorrLevel == 0) { for (auto i{0u}; i < 48; i++) { FV0RelGainConst.push_back(1.); @@ -437,7 +437,10 @@ struct qVectorsTable { continue; } histosQA.fill(HIST("ChTracks"), trk.pt(), trk.eta(), trk.phi(), cent); - if (std::abs(trk.eta()) > 0.8) { + if (trk.eta() > cfgEtaMax) { + continue; + } + if (trk.eta() < cfgEtaMin) { continue; } qVectTPCall[0] += trk.pt() * std::cos(trk.phi() * nmode); @@ -552,7 +555,7 @@ struct qVectorsTable { runNumber = currentRun; } - float centAllEstim[4] = { + const float centAllEstim[4] = { coll.centFT0M(), coll.centFT0A(), coll.centFT0C(), coll.centFV0A()}; cent = centAllEstim[cfgCentEsti]; diff --git a/Common/TableProducer/trackPropagationTester.cxx b/Common/TableProducer/trackPropagationTester.cxx index 694ff77d3c0..18543ee0994 100644 --- a/Common/TableProducer/trackPropagationTester.cxx +++ b/Common/TableProducer/trackPropagationTester.cxx @@ -23,24 +23,28 @@ // //=============================================================== -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Common/DataModel/TrackSelectionTables.h" #include "Common/Core/trackUtilities.h" -#include "ReconstructionDataFormats/DCA.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "CommonUtils/NameConf.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/Tools/StandardCCDBLoader.h" +#include "Common/Tools/TrackPropagationModule.h" +#include "Common/Tools/TrackTuner.h" + +#include "CCDB/BasicCCDBManager.h" #include "CCDB/CcdbApi.h" +#include "CommonConstants/GeomConstants.h" +#include "CommonUtils/NameConf.h" +#include "DataFormatsCalibration/MeanVertexObject.h" #include "DataFormatsParameters/GRPMagField.h" -#include "CCDB/BasicCCDBManager.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" -#include "DataFormatsCalibration/MeanVertexObject.h" -#include "CommonConstants/GeomConstants.h" -#include "Common/Tools/TrackPropagationModule.h" -#include "Common/Tools/StandardCCDBLoader.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/DCA.h" + +#include // The Run 3 AO2D stores the tracks at the point of innermost update. For a track with ITS this is the innermost (or second innermost) // ITS layer. For a track without ITS, this is the TPC inner wall or for loopers in the TPC even a radius beyond that. @@ -59,6 +63,9 @@ struct TrackPropagationTester { o2::common::TrackPropagationProducts trackPropagationProducts; o2::common::TrackPropagationConfigurables trackPropagationConfigurables; + // the track tuner object -> needs to be here as it inherits from ConfigurableGroup (+ has its own copy of ccdbApi) + TrackTuner trackTunerObj; + // CCDB boilerplate declarations o2::framework::Configurable ccdburl{"ccdburl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Service ccdb; @@ -76,14 +83,14 @@ struct TrackPropagationTester { ccdb->setURL(ccdburl.value); // task-specific - trackPropagation.init(trackPropagationConfigurables, registry, initContext); + trackPropagation.init(trackPropagationConfigurables, trackTunerObj, registry, initContext); } void processReal(aod::Collisions const& collisions, soa::Join const& tracks, aod::Collisions const&, aod::BCs const& bcs) { // task-specific ccdbLoader.initCCDBfromBCs(standardCCDBLoaderConfigurables, ccdb, bcs); - trackPropagation.fillTrackTables(trackPropagationConfigurables, ccdbLoader, collisions, tracks, trackPropagationProducts, registry); + trackPropagation.fillTrackTables(trackPropagationConfigurables, trackTunerObj, ccdbLoader, collisions, tracks, trackPropagationProducts, registry); } PROCESS_SWITCH(TrackPropagationTester, processReal, "Process Real Data", true); @@ -91,7 +98,7 @@ struct TrackPropagationTester { void processMc(aod::Collisions const& collisions, soa::Join const& tracks, aod::McParticles const&, aod::Collisions const&, aod::BCs const& bcs) { ccdbLoader.initCCDBfromBCs(standardCCDBLoaderConfigurables, ccdb, bcs); - trackPropagation.fillTrackTables(trackPropagationConfigurables, ccdbLoader, collisions, tracks, trackPropagationProducts, registry); + trackPropagation.fillTrackTables(trackPropagationConfigurables, trackTunerObj, ccdbLoader, collisions, tracks, trackPropagationProducts, registry); } PROCESS_SWITCH(TrackPropagationTester, processMc, "Process Monte Carlo", false); }; diff --git a/Common/TableProducer/trackselection.cxx b/Common/TableProducer/trackselection.cxx index 8ce5a88e0bd..142ae81a2e1 100644 --- a/Common/TableProducer/trackselection.cxx +++ b/Common/TableProducer/trackselection.cxx @@ -17,14 +17,16 @@ /// \brief Task performing basic track selection. /// -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" #include "Common/Core/TrackSelection.h" + +#include "Common/Core/TableHelper.h" #include "Common/Core/TrackSelectionDefaults.h" -#include "Common/DataModel/TrackSelectionTables.h" #include "Common/Core/trackUtilities.h" -#include "TableHelper.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -149,7 +151,7 @@ struct TrackSelectionTask { return; } if (isRun3) { - for (auto& track : tracks) { + for (const auto& track : tracks) { if (produceTable == 1) { filterTable((uint8_t)0, @@ -190,7 +192,7 @@ struct TrackSelectionTask { return; } - for (auto& track : tracks) { + for (const auto& track : tracks) { o2::aod::track::TrackSelectionFlags::flagtype trackflagGlob = globalTracks.IsSelectedMask(track); if (produceTable == 1) { filterTable((uint8_t)globalTracksSDD.IsSelected(track), diff --git a/Common/Tasks/centralityStudy.cxx b/Common/Tasks/centralityStudy.cxx index 7a0d4c35ab1..a8cdea5ac09 100644 --- a/Common/Tasks/centralityStudy.cxx +++ b/Common/Tasks/centralityStudy.cxx @@ -49,7 +49,20 @@ struct centralityStudy { int mRunNumber; uint64_t startOfRunTimestamp; + // vertex Z equalization + TList* hCalibObjects; + TProfile* hVtxZFV0A; + TProfile* hVtxZFT0A; + TProfile* hVtxZFT0C; + TProfile* hVtxZNTracks; + TProfile* hVtxZNGlobals; + TProfile* hVtxZMFT; + TProfile* hVtxZFDDA; + TProfile* hVtxZFDDC; + // Configurables + Configurable applyVertexZEqualization{"applyVertexZEqualization", false, "0 - no, 1 - yes"}; + Configurable do2DPlots{"do2DPlots", true, "0 - no, 1 - yes"}; Configurable doOccupancyStudyVsCentrality2d{"doOccupancyStudyVsCentrality2d", true, "0 - no, 1 - yes"}; Configurable doOccupancyStudyVsRawValues2d{"doOccupancyStudyVsRawValues2d", true, "0 - no, 1 - yes"}; @@ -64,10 +77,10 @@ struct centralityStudy { // Apply extra event selections Configurable rejectITSROFBorder{"rejectITSROFBorder", true, "reject events at ITS ROF border"}; Configurable rejectTFBorder{"rejectTFBorder", true, "reject events at TF border"}; - Configurable requireIsVertexITSTPC{"requireIsVertexITSTPC", true, "require events with at least one ITS-TPC track"}; - Configurable requireIsGoodZvtxFT0VsPV{"requireIsGoodZvtxFT0VsPV", true, "require events with PV position along z consistent (within 1 cm) between PV reconstructed using tracks and PV using FT0 A-C time difference"}; - Configurable requireIsVertexTOFmatched{"requireIsVertexTOFmatched", true, "require events with at least one of vertex contributors matched to TOF"}; - Configurable requireIsVertexTRDmatched{"requireIsVertexTRDmatched", true, "require events with at least one of vertex contributors matched to TRD"}; + Configurable requireIsVertexITSTPC{"requireIsVertexITSTPC", false, "require events with at least one ITS-TPC track"}; + Configurable requireIsGoodZvtxFT0VsPV{"requireIsGoodZvtxFT0VsPV", false, "require events with PV position along z consistent (within 1 cm) between PV reconstructed using tracks and PV using FT0 A-C time difference"}; + Configurable requireIsVertexTOFmatched{"requireIsVertexTOFmatched", false, "require events with at least one of vertex contributors matched to TOF"}; + Configurable requireIsVertexTRDmatched{"requireIsVertexTRDmatched", false, "require events with at least one of vertex contributors matched to TRD"}; Configurable rejectSameBunchPileup{"rejectSameBunchPileup", true, "reject collisions in case of pileup with another collision in the same foundBC"}; Configurable rejectITSinROFpileupStandard{"rejectITSinROFpileupStandard", false, "reject collisions in case of in-ROF ITS pileup (standard)"}; @@ -82,7 +95,7 @@ struct centralityStudy { Configurable vertexZwithT0{"vertexZwithT0", 1000.0f, "require a certain vertex-Z in BC analysis"}; Configurable minTimeDelta{"minTimeDelta", -1.0f, "reject collision if another collision is this close or less in time"}; - Configurable minFT0CforVertexZ{"minFT0CforVertexZ", 250, "minimum FT0C for vertex-Z profile calculation"}; + Configurable minFT0CforVertexZ{"minFT0CforVertexZ", -1.0f, "minimum FT0C for vertex-Z profile calculation"}; Configurable scaleSignalFT0C{"scaleSignalFT0C", 1.00f, "scale FT0C signal for convenience"}; Configurable scaleSignalFT0M{"scaleSignalFT0M", 1.00f, "scale FT0M signal for convenience"}; @@ -90,6 +103,7 @@ struct centralityStudy { Configurable ccdbURL{"ccdbURL", "http://alice-ccdb.cern.ch", "ccdb url"}; Configurable pathGRPECSObject{"pathGRPECSObject", "GLO/Config/GRPECS", "Path to GRPECS object"}; + Configurable pathVertexZ{"pathVertexZ", "Users/d/ddobrigk/Centrality/Calibration", "Path to vertexZ profiles"}; Configurable irSource{"irSource", "ZNC hadronic", "Source of the interaction rate: (Recommended: pp --> T0VTX, Pb-Pb --> ZNC hadronic)"}; Configurable irCrashOnNull{"irCrashOnNull", false, "Flag to avoid CTP RateFetcher crash."}; Configurable irDoRateVsTime{"irDoRateVsTime", true, "Do IR plots"}; @@ -148,6 +162,16 @@ struct centralityStudy { void init(InitContext&) { + hCalibObjects = nullptr; + hVtxZFV0A = nullptr; + hVtxZFT0A = nullptr; + hVtxZFT0C = nullptr; + hVtxZNTracks = nullptr; + hVtxZNGlobals = nullptr; + hVtxZMFT = nullptr; + hVtxZFDDA = nullptr; + hVtxZFDDC = nullptr; + if (doprocessCollisions || doprocessCollisionsWithCentrality) { const AxisSpec axisCollisions{100, -0.5f, 99.5f, "Number of collisions"}; histos.add("hCollisionSelection", "hCollisionSelection", kTH1D, {{20, -0.5f, +19.5f}}); @@ -186,9 +210,9 @@ struct centralityStudy { histos.add("hFV0A_BCs", "hFV0A_BCs", kTH1D, {axisMultUltraFineFV0A}); histos.add("hFT0CvsPVz_BCs_All", "hFT0CvsPVz_BCs_All", kTProfile, {axisPVz}); histos.add("hFT0CvsPVz_BCs", "hFT0CvsPVz_BCs", kTProfile, {axisPVz}); - histos.add("hVertexZ_BCvsCO", "hVertexZ_BCvsCO", kTH2D, {axisPVz, axisPVz}); - histos.add("hZNAvsFT0C_BCs", "hZNAvsFT0C_BCs", kTH2D, {axisMultFT0C, axisZN}); - histos.add("hZNCvsFT0C_BCs", "hZNCvsFT0C_BCs", kTH2D, {axisMultFT0C, axisZN}); + histos.add("hVertexZ_BCvsCO", "hVertexZ_BCvsCO", kTH2F, {axisPVz, axisPVz}); + histos.add("hZNAvsFT0C_BCs", "hZNAvsFT0C_BCs", kTH2F, {axisMultFT0C, axisZN}); + histos.add("hZNCvsFT0C_BCs", "hZNCvsFT0C_BCs", kTH2F, {axisMultFT0C, axisZN}); } if (do2DPlots) { @@ -213,6 +237,7 @@ struct centralityStudy { histos.add("hNGlobalTracksVsZNA", "hNGlobalTracksVsZNA", kTH2F, {axisZN, axisMultGlobalTracks}); histos.add("hNGlobalTracksVsZNC", "hNGlobalTracksVsZNC", kTH2F, {axisZN, axisMultGlobalTracks}); histos.add("hNGlobalTracksVsNMFTTracks", "hNGlobalTracksVsNMFTTracks", kTH2F, {axisMultMFTTracks, axisMultGlobalTracks}); + histos.add("hNGlobalTracksVsNTPV", "hNGlobalTracksVsNTPV", kTH2F, {axisMultPVContributors, axisMultGlobalTracks}); } if (doOccupancyStudyVsRawValues2d) { @@ -274,13 +299,32 @@ struct centralityStudy { } mRunNumber = collision.multRunNumber(); - LOGF(info, "Setting up for run: %i", mRunNumber); // only get object when switching runs o2::parameters::GRPECSObject* grpo = ccdb->getForRun(pathGRPECSObject, mRunNumber); startOfRunTimestamp = grpo->getTimeStart(); + if (applyVertexZEqualization.value) { + // acquire vertex-Z equalization histograms if requested + LOGF(info, "Acquiring vertex-Z profiles for run %i", mRunNumber); + hCalibObjects = ccdb->getForRun(pathVertexZ, mRunNumber); + + hVtxZFV0A = static_cast(hCalibObjects->FindObject("hVtxZFV0A")); + hVtxZFT0A = static_cast(hCalibObjects->FindObject("hVtxZFT0A")); + hVtxZFT0C = static_cast(hCalibObjects->FindObject("hVtxZFT0C")); + // hVtxZFDDA = static_cast(hCalibObjects->FindObject("hVtxZFDDA")); + // hVtxZFDDC = static_cast(hCalibObjects->FindObject("hVtxZFDDC")); + hVtxZNTracks = static_cast(hCalibObjects->FindObject("hVtxZNTracksPV")); + hVtxZNGlobals = static_cast(hCalibObjects->FindObject("hVtxZNGlobals")); + hVtxZMFT = static_cast(hCalibObjects->FindObject("hVtxZMFT")); + + // Capture error + if (!hVtxZFV0A || !hVtxZFT0A || !hVtxZFT0C || !hVtxZNTracks || !hVtxZNGlobals || !hVtxZMFT) { + LOGF(error, "Problem loading CCDB objects! Please check"); + } + } + histPath = std::format("Run_{}/", mRunNumber); if (doprocessCollisions || doprocessCollisionsWithCentrality) { @@ -306,11 +350,22 @@ struct centralityStudy { histPointers.insert({histPath + "hNMFTTracks", histos.add((histPath + "hNMFTTracks").c_str(), "hNMFTTracks", {kTH1D, {{axisMultUltraFineMFTTracks}}})}); histPointers.insert({histPath + "hNPVContributors", histos.add((histPath + "hNPVContributors").c_str(), "hNPVContributors", {kTH1D, {{axisMultUltraFinePVContributors}}})}); + if (applyVertexZEqualization) { + histPointers.insert({histPath + "hFT0C_Collisions_Unequalized", histos.add((histPath + "hFT0C_Collisions_Unequalized").c_str(), "hFT0C_Collisions_Unequalized", {kTH1D, {{axisMultUltraFineFT0C}}})}); + histPointers.insert({histPath + "hFT0M_Collisions_Unequalized", histos.add((histPath + "hFT0M_Collisions_Unequalized").c_str(), "hFT0M_Collisions_Unequalized", {kTH1D, {{axisMultUltraFineFT0M}}})}); + histPointers.insert({histPath + "hFV0A_Collisions_Unequalized", histos.add((histPath + "hFV0A_Collisions_Unequalized").c_str(), "hFV0A_Collisions_Unequalized", {kTH1D, {{axisMultUltraFineFV0A}}})}); + histPointers.insert({histPath + "hNGlobalTracks_Unequalized", histos.add((histPath + "hNGlobalTracks_Unequalized").c_str(), "hNGlobalTracks_Unequalized", {kTH1D, {{axisMultUltraFineGlobalTracks}}})}); + histPointers.insert({histPath + "hNMFTTracks_Unequalized", histos.add((histPath + "hNMFTTracks_Unequalized").c_str(), "hNMFTTracks_Unequalized", {kTH1D, {{axisMultUltraFineMFTTracks}}})}); + histPointers.insert({histPath + "hNPVContributors_Unequalized", histos.add((histPath + "hNPVContributors_Unequalized").c_str(), "hNPVContributors_Unequalized", {kTH1D, {{axisMultUltraFinePVContributors}}})}); + } + histPointers.insert({histPath + "hFT0CvsPVz_Collisions_All", histos.add((histPath + "hFT0CvsPVz_Collisions_All").c_str(), "hFT0CvsPVz_Collisions_All", {kTProfile, {{axisPVz}}})}); + histPointers.insert({histPath + "hFT0AvsPVz_Collisions", histos.add((histPath + "hFT0AvsPVz_Collisions").c_str(), "hFT0AvsPVz_Collisions", {kTProfile, {{axisPVz}}})}); histPointers.insert({histPath + "hFT0CvsPVz_Collisions", histos.add((histPath + "hFT0CvsPVz_Collisions").c_str(), "hFT0CvsPVz_Collisions", {kTProfile, {{axisPVz}}})}); histPointers.insert({histPath + "hFV0AvsPVz_Collisions", histos.add((histPath + "hFV0AvsPVz_Collisions").c_str(), "hFV0AvsPVz_Collisions", {kTProfile, {{axisPVz}}})}); histPointers.insert({histPath + "hNGlobalTracksvsPVz_Collisions", histos.add((histPath + "hNGlobalTracksvsPVz_Collisions").c_str(), "hNGlobalTracksvsPVz_Collisions", {kTProfile, {{axisPVz}}})}); histPointers.insert({histPath + "hNMFTTracksvsPVz_Collisions", histos.add((histPath + "hNMFTTracksvsPVz_Collisions").c_str(), "hNMFTTracksvsPVz_Collisions", {kTProfile, {{axisPVz}}})}); + histPointers.insert({histPath + "hNTPVvsPVz_Collisions", histos.add((histPath + "hNTPVvsPVz_Collisions").c_str(), "hNTPVvsPVz_Collisions", {kTProfile, {{axisPVz}}})}); } if (do2DPlots) { @@ -337,15 +392,24 @@ struct centralityStudy { histPointers.insert({histPath + "hDeltaTimeVsCentrality", histos.add((histPath + "hDeltaTimeVsCentrality").c_str(), "hDeltaTimeVsCentrality", {kTH2F, {{axisCentrality, axisDeltaTime}}})}); } + if (doNGlobalTracksVsRawSignals) { + histPointers.insert({histPath + "hNGlobalTracksVsFT0A", histos.add((histPath + "hNGlobalTracksVsFT0A").c_str(), "hNGlobalTracksVsFT0A", {kTH2F, {{axisMultFT0A, axisMultGlobalTracks}}})}); + histPointers.insert({histPath + "hNGlobalTracksVsFT0C", histos.add((histPath + "hNGlobalTracksVsFT0C").c_str(), "hNGlobalTracksVsFT0C", {kTH2F, {{axisMultFT0C, axisMultGlobalTracks}}})}); + histPointers.insert({histPath + "hNGlobalTracksVsFT0M", histos.add((histPath + "hNGlobalTracksVsFT0M").c_str(), "hNGlobalTracksVsFT0M", {kTH2F, {{axisMultFT0M, axisMultGlobalTracks}}})}); + histPointers.insert({histPath + "hNGlobalTracksVsFV0A", histos.add((histPath + "hNGlobalTracksVsFV0A").c_str(), "hNGlobalTracksVsFV0A", {kTH2F, {{axisMultFV0A, axisMultGlobalTracks}}})}); + histPointers.insert({histPath + "hNGlobalTracksVsNMFTTracks", histos.add((histPath + "hNGlobalTracksVsNMFTTracks").c_str(), "hNGlobalTracksVsNMFTTracks", {kTH2F, {{axisMultMFTTracks, axisMultGlobalTracks}}})}); + histPointers.insert({histPath + "hNGlobalTracksVsNTPV", histos.add((histPath + "hNGlobalTracksVsNTPV").c_str(), "hNGlobalTracksVsNTPV", {kTH2F, {{axisMultPVContributors, axisMultGlobalTracks}}})}); + } + if (doTimeStudies) { - histPointers.insert({histPath + "hFT0AVsTime", histos.add((histPath + "hFT0AVsTime").c_str(), "hFT0AVsTime", {kTH2D, {{axisDeltaTimestamp, axisMultFT0A}}})}); - histPointers.insert({histPath + "hFT0CVsTime", histos.add((histPath + "hFT0CVsTime").c_str(), "hFT0CVsTime", {kTH2D, {{axisDeltaTimestamp, axisMultFT0C}}})}); - histPointers.insert({histPath + "hFT0MVsTime", histos.add((histPath + "hFT0MVsTime").c_str(), "hFT0MVsTime", {kTH2D, {{axisDeltaTimestamp, axisMultFT0M}}})}); - histPointers.insert({histPath + "hFV0AVsTime", histos.add((histPath + "hFV0AVsTime").c_str(), "hFV0AVsTime", {kTH2D, {{axisDeltaTimestamp, axisMultFV0A}}})}); - histPointers.insert({histPath + "hFV0AOuterVsTime", histos.add((histPath + "hFV0AOuterVsTime").c_str(), "hFV0AOuterVsTime", {kTH2D, {{axisDeltaTimestamp, axisMultFV0A}}})}); - histPointers.insert({histPath + "hMFTTracksVsTime", histos.add((histPath + "hMFTTracksVsTime").c_str(), "hMFTTracksVsTime", {kTH2D, {{axisDeltaTimestamp, axisMultMFTTracks}}})}); - histPointers.insert({histPath + "hNGlobalVsTime", histos.add((histPath + "hNGlobalVsTime").c_str(), "hNGlobalVsTime", {kTH2D, {{axisDeltaTimestamp, axisMultGlobalTracks}}})}); - histPointers.insert({histPath + "hNTPVContributorsVsTime", histos.add((histPath + "hNTPVContributorsVsTime").c_str(), "hNTPVContributorsVsTime", {kTH2D, {{axisDeltaTimestamp, axisMultPVContributors}}})}); + histPointers.insert({histPath + "hFT0AVsTime", histos.add((histPath + "hFT0AVsTime").c_str(), "hFT0AVsTime", {kTH2F, {{axisDeltaTimestamp, axisMultFT0A}}})}); + histPointers.insert({histPath + "hFT0CVsTime", histos.add((histPath + "hFT0CVsTime").c_str(), "hFT0CVsTime", {kTH2F, {{axisDeltaTimestamp, axisMultFT0C}}})}); + histPointers.insert({histPath + "hFT0MVsTime", histos.add((histPath + "hFT0MVsTime").c_str(), "hFT0MVsTime", {kTH2F, {{axisDeltaTimestamp, axisMultFT0M}}})}); + histPointers.insert({histPath + "hFV0AVsTime", histos.add((histPath + "hFV0AVsTime").c_str(), "hFV0AVsTime", {kTH2F, {{axisDeltaTimestamp, axisMultFV0A}}})}); + histPointers.insert({histPath + "hFV0AOuterVsTime", histos.add((histPath + "hFV0AOuterVsTime").c_str(), "hFV0AOuterVsTime", {kTH2F, {{axisDeltaTimestamp, axisMultFV0A}}})}); + histPointers.insert({histPath + "hMFTTracksVsTime", histos.add((histPath + "hMFTTracksVsTime").c_str(), "hMFTTracksVsTime", {kTH2F, {{axisDeltaTimestamp, axisMultMFTTracks}}})}); + histPointers.insert({histPath + "hNGlobalVsTime", histos.add((histPath + "hNGlobalVsTime").c_str(), "hNGlobalVsTime", {kTH2F, {{axisDeltaTimestamp, axisMultGlobalTracks}}})}); + histPointers.insert({histPath + "hNTPVContributorsVsTime", histos.add((histPath + "hNTPVContributorsVsTime").c_str(), "hNTPVContributorsVsTime", {kTH2F, {{axisDeltaTimestamp, axisMultPVContributors}}})}); histPointers.insert({histPath + "hPVzProfileCoVsTime", histos.add((histPath + "hPVzProfileCoVsTime").c_str(), "hPVzProfileCoVsTime", {kTProfile, {{axisDeltaTimestamp}}})}); histPointers.insert({histPath + "hPVzProfileBcVsTime", histos.add((histPath + "hPVzProfileBcVsTime").c_str(), "hPVzProfileBcVsTime", {kTProfile, {{axisDeltaTimestamp}}})}); if (irDoRateVsTime) { @@ -359,7 +423,6 @@ struct centralityStudy { // process this collisions { initRun(collision); - histos.fill(HIST("hCollisionSelection"), 0); // all collisions getHist(TH1, histPath + "hCollisionSelection")->Fill(0); @@ -368,6 +431,69 @@ struct centralityStudy { histos.fill(HIST("hCollisionSelection"), 1); getHist(TH1, histPath + "hCollisionSelection")->Fill(1); + // calculate vertex-Z-equalized quantities if desired + float multFV0A = collision.multFV0A(); + float multFT0A = collision.multFT0A(); + float multFT0C = collision.multFT0C(); + float multNTracksGlobal = collision.multNTracksGlobal(); + float mftNtracks = collision.mftNtracks(); + float multNTracksPV = collision.multNTracksPV(); + if (applyVertexZEqualization) { + float epsilon = 1e-2; // average value after which this collision will be disregarded + multFV0A = -1.0f; + multFT0A = -1.0f; + multFT0C = -1.0f; + multNTracksGlobal = -1.0f; + mftNtracks = -1.0f; + multNTracksPV = -1.0f; + + if (hVtxZFV0A->Interpolate(collision.multPVz()) > epsilon) { + multFV0A = hVtxZFV0A->Interpolate(0.0) * collision.multFV0A() / hVtxZFV0A->Interpolate(collision.multPVz()); + } + if (hVtxZFT0A->Interpolate(collision.multPVz()) > epsilon) { + multFT0A = hVtxZFT0A->Interpolate(0.0) * collision.multFT0A() / hVtxZFT0A->Interpolate(collision.multPVz()); + } + if (hVtxZFT0C->Interpolate(collision.multPVz()) > epsilon) { + multFT0C = hVtxZFT0C->Interpolate(0.0) * collision.multFT0C() / hVtxZFT0C->Interpolate(collision.multPVz()); + } + if (hVtxZNGlobals->Interpolate(collision.multPVz()) > epsilon) { + multNTracksGlobal = hVtxZNGlobals->Interpolate(0.0) * collision.multNTracksGlobal() / hVtxZNGlobals->Interpolate(collision.multPVz()); + } + if (hVtxZMFT->Interpolate(collision.multPVz()) > epsilon) { + mftNtracks = hVtxZMFT->Interpolate(0.0) * collision.mftNtracks() / hVtxZMFT->Interpolate(collision.multPVz()); + } + if (hVtxZNTracks->Interpolate(collision.multPVz()) > epsilon) { + multNTracksPV = hVtxZNTracks->Interpolate(0.0) * collision.multNTracksPV() / hVtxZNTracks->Interpolate(collision.multPVz()); + } + } + + bool passRejectITSROFBorder = !(rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)); + bool passRejectTFBorder = !(rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)); + bool passRequireIsVertexITSTPC = !(requireIsVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)); + bool passRequireIsGoodZvtxFT0VsPV = !(requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)); + bool passRequireIsVertexTOFmatched = !(requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)); + bool passRequireIsVertexTRDmatched = !(requireIsVertexTRDmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)); + bool passRejectSameBunchPileup = !(rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)); + bool passRejectITSinROFpileupStandard = !(rejectITSinROFpileupStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)); + bool passRejectITSinROFpileupStrict = !(rejectITSinROFpileupStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStrict)); + bool passSelectUPCcollisions = !(selectUPCcollisions && collision.flags() < 1); + bool passRejectCollInTimeRangeNarrow = !(rejectCollInTimeRangeNarrow && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)); + // _______________________________________________________ + // sidestep vertex-Z rejection for vertex-Z profile histograms + if (passRejectITSROFBorder && passRejectTFBorder && passRequireIsVertexITSTPC && passRequireIsGoodZvtxFT0VsPV && + passRequireIsVertexTOFmatched && passRequireIsVertexTRDmatched && passRejectSameBunchPileup && passRejectITSinROFpileupStandard && passRejectITSinROFpileupStrict && + passSelectUPCcollisions && passRejectCollInTimeRangeNarrow) { + getHist(TProfile, histPath + "hFT0CvsPVz_Collisions_All")->Fill(collision.multPVz(), multFT0C * scaleSignalFT0C); + getHist(TProfile, histPath + "hFT0CvsPVz_Collisions")->Fill(collision.multPVz(), multFT0C * scaleSignalFT0C); + getHist(TProfile, histPath + "hFT0AvsPVz_Collisions")->Fill(collision.multPVz(), multFT0A * scaleSignalFT0C); + getHist(TProfile, histPath + "hFV0AvsPVz_Collisions")->Fill(collision.multPVz(), multFV0A * scaleSignalFV0A); + getHist(TProfile, histPath + "hNGlobalTracksvsPVz_Collisions")->Fill(collision.multPVz(), multNTracksGlobal); + getHist(TProfile, histPath + "hNMFTTracksvsPVz_Collisions")->Fill(collision.multPVz(), mftNtracks); + getHist(TProfile, histPath + "hNTPVvsPVz_Collisions")->Fill(collision.multPVz(), multNTracksPV); + } + + // _______________________________________________________ + if (applyVtxZ && TMath::Abs(collision.multPVz()) > 10) return; histos.fill(HIST("hCollisionSelection"), 2); @@ -375,43 +501,43 @@ struct centralityStudy { // _______________________________________________________ // Extra event selections start here - if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { + if (!passRejectITSROFBorder) { return; } histos.fill(HIST("hCollisionSelection"), 3 /* Not at ITS ROF border */); getHist(TH1, histPath + "hCollisionSelection")->Fill(3); - if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { + if (!passRejectTFBorder) { return; } histos.fill(HIST("hCollisionSelection"), 4 /* Not at TF border */); getHist(TH1, histPath + "hCollisionSelection")->Fill(4); - if (requireIsVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { + if (!passRequireIsVertexITSTPC) { return; } histos.fill(HIST("hCollisionSelection"), 5 /* Contains at least one ITS-TPC track */); getHist(TH1, histPath + "hCollisionSelection")->Fill(5); - if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + if (!passRequireIsGoodZvtxFT0VsPV) { return; } histos.fill(HIST("hCollisionSelection"), 6 /* PV position consistency check */); getHist(TH1, histPath + "hCollisionSelection")->Fill(6); - if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { + if (!passRequireIsVertexTOFmatched) { return; } histos.fill(HIST("hCollisionSelection"), 7 /* PV with at least one contributor matched with TOF */); getHist(TH1, histPath + "hCollisionSelection")->Fill(7); - if (requireIsVertexTRDmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)) { + if (!passRequireIsVertexTRDmatched) { return; } histos.fill(HIST("hCollisionSelection"), 8 /* PV with at least one contributor matched with TRD */); getHist(TH1, histPath + "hCollisionSelection")->Fill(8); - if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + if (!passRejectSameBunchPileup) { return; } histos.fill(HIST("hCollisionSelection"), 9 /* Not at same bunch pile-up */); @@ -430,25 +556,25 @@ struct centralityStudy { getHist(TH1, histPath + "hCollisionSelection")->Fill(10); } - if (rejectITSinROFpileupStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + if (!passRejectITSinROFpileupStandard) { return; } histos.fill(HIST("hCollisionSelection"), 11 /* Not ITS ROF pileup (standard) */); getHist(TH1, histPath + "hCollisionSelection")->Fill(11); - if (rejectITSinROFpileupStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStrict)) { + if (!passRejectITSinROFpileupStrict) { return; } histos.fill(HIST("hCollisionSelection"), 12 /* Not ITS ROF pileup (strict) */); getHist(TH1, histPath + "hCollisionSelection")->Fill(12); - if (selectUPCcollisions && collision.flags() < 1) { // if zero then NOT upc, otherwise UPC + if (!passSelectUPCcollisions) { // if zero then NOT upc, otherwise UPC return; } histos.fill(HIST("hCollisionSelection"), 13 /* is UPC event */); getHist(TH1, histPath + "hCollisionSelection")->Fill(13); - if (rejectCollInTimeRangeNarrow && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) { + if (!passRejectCollInTimeRangeNarrow) { return; } histos.fill(HIST("hCollisionSelection"), 14 /* Not ITS ROF pileup (strict) */); @@ -482,21 +608,24 @@ struct centralityStudy { histos.fill(HIST("hNGlobalTracksvsPVz_Collisions"), collision.multPVz(), collision.multNTracksGlobal()); histos.fill(HIST("hNMFTTracksvsPVz_Collisions"), collision.multPVz(), collision.mftNtracks()); - getHist(TH1, histPath + "hNPVContributors")->Fill(collision.multNTracksPV()); - getHist(TH1, histPath + "hFT0C_Collisions")->Fill(collision.multFT0C() * scaleSignalFT0C); - getHist(TH1, histPath + "hFT0M_Collisions")->Fill((collision.multFT0A() + collision.multFT0C()) * scaleSignalFT0M); - getHist(TH1, histPath + "hFV0A_Collisions")->Fill(collision.multFV0A() * scaleSignalFV0A); - getHist(TH1, histPath + "hNGlobalTracks")->Fill(collision.multNTracksGlobal()); - getHist(TH1, histPath + "hNMFTTracks")->Fill(collision.mftNtracks()); - getHist(TProfile, histPath + "hFT0CvsPVz_Collisions_All")->Fill(collision.multPVz(), collision.multFT0C() * scaleSignalFT0C); - getHist(TProfile, histPath + "hFV0AvsPVz_Collisions")->Fill(collision.multPVz(), collision.multFV0A() * scaleSignalFV0A); - getHist(TProfile, histPath + "hNGlobalTracksvsPVz_Collisions")->Fill(collision.multPVz(), collision.multNTracksGlobal()); - getHist(TProfile, histPath + "hNMFTTracksvsPVz_Collisions")->Fill(collision.multPVz(), collision.mftNtracks()); - - if (collision.multFT0C() > minFT0CforVertexZ) { - histos.fill(HIST("hFT0CvsPVz_Collisions"), collision.multPVz(), collision.multFT0C() * scaleSignalFT0C); - getHist(TProfile, histPath + "hFT0CvsPVz_Collisions")->Fill(collision.multPVz(), collision.multFT0C() * scaleSignalFT0C); + // save vertex-Z equalized + getHist(TH1, histPath + "hNPVContributors")->Fill(multNTracksPV); + getHist(TH1, histPath + "hFT0C_Collisions")->Fill(multFT0C * scaleSignalFT0C); + getHist(TH1, histPath + "hFT0M_Collisions")->Fill((multFT0A + multFT0C) * scaleSignalFT0M); + getHist(TH1, histPath + "hFV0A_Collisions")->Fill(multFV0A * scaleSignalFV0A); + getHist(TH1, histPath + "hNGlobalTracks")->Fill(multNTracksGlobal); + getHist(TH1, histPath + "hNMFTTracks")->Fill(mftNtracks); + + if (applyVertexZEqualization.value) { + // save unequalized for cross-checks + getHist(TH1, histPath + "hNPVContributors_Unequalized")->Fill(collision.multNTracksPV()); + getHist(TH1, histPath + "hFT0C_Collisions_Unequalized")->Fill(collision.multFT0C() * scaleSignalFT0C); + getHist(TH1, histPath + "hFT0M_Collisions_Unequalized")->Fill((collision.multFT0A() + collision.multFT0C()) * scaleSignalFT0M); + getHist(TH1, histPath + "hFV0A_Collisions_Unequalized")->Fill(collision.multFV0A() * scaleSignalFV0A); + getHist(TH1, histPath + "hNGlobalTracks_Unequalized")->Fill(collision.multNTracksGlobal()); + getHist(TH1, histPath + "hNMFTTracks_Unequalized")->Fill(collision.mftNtracks()); } + if (do2DPlots) { histos.fill(HIST("hNContribsVsFT0C"), collision.multFT0C() * scaleSignalFT0C, collision.multPVTotalContributors()); histos.fill(HIST("hNContribsVsFV0A"), collision.multFV0A() * scaleSignalFV0A, collision.multPVTotalContributors()); @@ -531,15 +660,20 @@ struct centralityStudy { } if (doNGlobalTracksVsRawSignals) { - histos.fill(HIST("hNGlobalTracksVsFT0A"), collision.multFT0A(), collision.multNTracksGlobal()); - histos.fill(HIST("hNGlobalTracksVsFT0C"), collision.multFT0C(), collision.multNTracksGlobal()); - histos.fill(HIST("hNGlobalTracksVsFT0M"), collision.multFT0A() + collision.multFT0C(), collision.multNTracksGlobal()); - histos.fill(HIST("hNGlobalTracksVsFV0A"), collision.multFV0A(), collision.multNTracksGlobal()); - histos.fill(HIST("hNGlobalTracksVsFDDA"), collision.multFDDA(), collision.multNTracksGlobal()); - histos.fill(HIST("hNGlobalTracksVsFDDC"), collision.multFDDC(), collision.multNTracksGlobal()); - histos.fill(HIST("hNGlobalTracksVsZNA"), collision.multZNA(), collision.multNTracksGlobal()); - histos.fill(HIST("hNGlobalTracksVsZNC"), collision.multZNC(), collision.multNTracksGlobal()); - histos.fill(HIST("hNGlobalTracksVsNMFTTracks"), collision.mftNtracks(), collision.multNTracksGlobal()); + histos.fill(HIST("hNGlobalTracksVsFT0A"), multFT0A, multNTracksGlobal); + histos.fill(HIST("hNGlobalTracksVsFT0C"), multFT0C, multNTracksGlobal); + histos.fill(HIST("hNGlobalTracksVsFT0M"), (multFT0A + multFT0C), multNTracksGlobal); + histos.fill(HIST("hNGlobalTracksVsFV0A"), multFV0A, multNTracksGlobal); + histos.fill(HIST("hNGlobalTracksVsNMFTTracks"), mftNtracks, multNTracksGlobal); + histos.fill(HIST("hNGlobalTracksVsNTPV"), multNTracksPV, multNTracksGlobal); + + // per run + getHist(TH2, histPath + "hNGlobalTracksVsFT0A")->Fill(multFT0A, multNTracksGlobal); + getHist(TH2, histPath + "hNGlobalTracksVsFT0C")->Fill(multFT0C, multNTracksGlobal); + getHist(TH2, histPath + "hNGlobalTracksVsFT0M")->Fill(multFT0A + multFT0C, multNTracksGlobal); + getHist(TH2, histPath + "hNGlobalTracksVsFV0A")->Fill(multFV0A, multNTracksGlobal); + getHist(TH2, histPath + "hNGlobalTracksVsNMFTTracks")->Fill(mftNtracks, multNTracksGlobal); + getHist(TH2, histPath + "hNGlobalTracksVsNTPV")->Fill(multNTracksPV, multNTracksGlobal); } // if the table has centrality information @@ -576,9 +710,9 @@ struct centralityStudy { } if (doTimeStudies && collision.has_multBC()) { + initRun(collision); auto multbc = collision.template multBC_as(); uint64_t bcTimestamp = multbc.timestamp(); - float hoursAfterStartOfRun = static_cast(bcTimestamp - startOfRunTimestamp) / 3600000.0; getHist(TH2, histPath + "hFT0AVsTime")->Fill(hoursAfterStartOfRun, collision.multFT0A()); diff --git a/Common/Tasks/checkDataModelMC.cxx b/Common/Tasks/checkDataModelMC.cxx index fb2762a02b7..c8c0ecdda62 100644 --- a/Common/Tasks/checkDataModelMC.cxx +++ b/Common/Tasks/checkDataModelMC.cxx @@ -13,8 +13,11 @@ /// \author /// \since -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" +#include +#include + +#include +#include using namespace o2; using namespace o2::framework; @@ -42,7 +45,7 @@ void checkDaughters(const T& particlesMC, LOG(fatal) << "MC particle " << particle.globalIndex() << " with PDG " << particle.pdgCode() << " has first and last daughter indices " << firstDauIdx << ", " << lastDauIdx; } } - for (auto& idxDau : particle.daughtersIds()) { + for (const auto& idxDau : particle.daughtersIds()) { if (idxDau >= 0 && ((unsigned long int)idxDau > offset + particlesMC.size() || (unsigned long int)idxDau < offset)) { if (debugMode) { debugHisto->Fill(1); @@ -88,7 +91,7 @@ struct CheckMcParticlesIndices { void process(aod::McParticles const& particlesMC) { long unsigned int offset = 0; - for (auto& particle : particlesMC) { + for (const auto& particle : particlesMC) { checkDaughters(particlesMC, particle, offset, debugMode.value, hDebug); } } @@ -112,7 +115,7 @@ struct CheckMcParticlesIndicesGrouped { void process(aod::McCollision const&, aod::McParticles const& particlesMC) { - for (auto& particle : particlesMC) { + for (const auto& particle : particlesMC) { checkDaughters(particlesMC, particle, particlesMC.offset(), debugMode.value, hDebug); } } diff --git a/Common/Tasks/evtPlanesResolution.cxx b/Common/Tasks/evtPlanesResolution.cxx deleted file mode 100644 index e493ff3f00e..00000000000 --- a/Common/Tasks/evtPlanesResolution.cxx +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// -/// \file evtPlanesResolution.cxx -/// \author Cindy Mordasini -/// \author Anna Önnerstad -/// -/// \brief ... -/// - -// C++/ROOT includes. -#include -#include -#include -#include -#include -#include -#include - -// o2Physics includes. -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StaticFor.h" - -#include "Common/DataModel/EvtPlanes.h" -#include "Common/Core/EventPlaneHelper.h" - -// o2 includes. - -using namespace o2; -using namespace o2::framework; - -namespace ep -{ -static constexpr std::string_view centClasses[] = { - "Centrality_0-5/", "Centrality_5-10/", "Centrality_10-20/", "Centrality_20-30/", - "Centrality_30-40/", "Centrality_40-50/", "Centrality_50-60/", "Centrality_60-80/"}; -} // namespace ep - -struct evtPlanesResolution { - // Configurables. - - // Histogram registry for the output QA figures and list of centrality classes for it. - // Objects are NOT saved in alphabetical orders, and registry names are NOT saved - // as TDirectoryFile. - HistogramRegistry histosQA{"histosQA", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; - - // Helper variables. - EventPlaneHelper helperEP; - - Configurable cfgMinTPCTracks{"cfgMinTPCTracks", 20, "minimum TPC tracks participating in Q-vector reconstruction"}; - Configurable cfgnMod{"cfgnMod", 2, "Modulation of interest"}; - - void init(InitContext const&) - { - // Fill the registry with the needed objects. - const AxisSpec axisEvtPl{360, -constants::math::PI, constants::math::PI}; - - histosQA.add("Centrality_0-5/histEvtPlUncor", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlRectr", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlTwist", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlFinal", "", {HistType::kTH1F, {axisEvtPl}}); - - histosQA.add("Centrality_0-5/histEvtPlBPosUncor", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlBPosRectr", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlBPosTwist", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlBPosFinal", "", {HistType::kTH1F, {axisEvtPl}}); - - histosQA.add("Centrality_0-5/histEvtPlBNegUncor", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlBNegRectr", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlBNegTwist", "", {HistType::kTH1F, {axisEvtPl}}); - histosQA.add("Centrality_0-5/histEvtPlBNegFinal", "", {HistType::kTH1F, {axisEvtPl}}); - - histosQA.add("Centrality_0-5/histEvtPlResolution", "", {HistType::kTH1F, {axisEvtPl}}); - - for (int iBin = 1; iBin < 8; iBin++) { - histosQA.addClone("Centrality_0-5/", ep::centClasses[iBin].data()); - } - } // End void init(InitContext const&) - - template - void fillHistosEvtPl(const T& vec) - { - histosQA.fill(HIST(ep::centClasses[cBin]) + HIST("histEvtPlUncor"), vec.evtPlUncor()); - histosQA.fill(HIST(ep::centClasses[cBin]) + HIST("histEvtPlRectr"), vec.evtPlRectr()); - histosQA.fill(HIST(ep::centClasses[cBin]) + HIST("histEvtPlTwist"), vec.evtPlTwist()); - histosQA.fill(HIST(ep::centClasses[cBin]) + HIST("histEvtPlFinal"), vec.evtPlFinal()); - - if (vec.nTrkBPos() < cfgMinTPCTracks || vec.nTrkBNeg() < cfgMinTPCTracks) - return; - - histosQA.fill(HIST(ep::centClasses[cBin]) + HIST("histEvtPlBPosUncor"), vec.evtPlBPosUncor()); - histosQA.fill(HIST(ep::centClasses[cBin]) + HIST("histEvtPlBPosRectr"), vec.evtPlBPosRectr()); - histosQA.fill(HIST(ep::centClasses[cBin]) + HIST("histEvtPlBPosTwist"), vec.evtPlBPosTwist()); - histosQA.fill(HIST(ep::centClasses[cBin]) + HIST("histEvtPlBPosFinal"), vec.evtPlBPosFinal()); - - histosQA.fill(HIST(ep::centClasses[cBin]) + HIST("histEvtPlBNegUncor"), vec.evtPlBNegUncor()); - histosQA.fill(HIST(ep::centClasses[cBin]) + HIST("histEvtPlBNegRectr"), vec.evtPlBNegRectr()); - histosQA.fill(HIST(ep::centClasses[cBin]) + HIST("histEvtPlBNegTwist"), vec.evtPlBNegTwist()); - histosQA.fill(HIST(ep::centClasses[cBin]) + HIST("histEvtPlBNegFinal"), vec.evtPlBNegFinal()); - - histosQA.fill(HIST(ep::centClasses[cBin]) + HIST("histEvtPlResolution"), - std::sqrt(std::cos((vec.evtPlFinal() - vec.evtPlBPosFinal()) * cfgnMod) * std::cos((vec.evtPlFinal() - vec.evtPlBNegFinal()) * cfgnMod) / - std::cos((vec.evtPlBPosFinal() - vec.evtPlBNegFinal()) * cfgnMod))); - } - - void process(aod::EvtPlane const& evPl) - { - int centBin = helperEP.GetCentBin(evPl.cent()); - switch (centBin) { - case 0: - fillHistosEvtPl<0>(evPl); - break; - case 1: - fillHistosEvtPl<1>(evPl); - break; - case 2: - fillHistosEvtPl<2>(evPl); - break; - case 3: - fillHistosEvtPl<3>(evPl); - break; - case 4: - fillHistosEvtPl<4>(evPl); - break; - case 5: - fillHistosEvtPl<5>(evPl); - break; - case 6: - fillHistosEvtPl<6>(evPl); - break; - case 7: - fillHistosEvtPl<7>(evPl); - break; - } // End switch(centBin) - } // End void process(...) -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; -} diff --git a/Common/Tasks/propagatorQa.cxx b/Common/Tasks/propagatorQa.cxx index f978f8bc564..3a426d2cf09 100644 --- a/Common/Tasks/propagatorQa.cxx +++ b/Common/Tasks/propagatorQa.cxx @@ -14,27 +14,29 @@ // Work in progress! More to follow, use at your own peril // -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Common/DataModel/TrackSelectionTables.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" -#include "ReconstructionDataFormats/Track.h" #include "Common/Core/trackUtilities.h" -#include "CCDB/BasicCCDBManager.h" -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DetectorsBase/Propagator.h" -#include "trackSelectionRequest.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/Tools/trackSelectionRequest.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -#include "Framework/runDataProcessing.h" - struct propagatorQa { Service ccdb; @@ -100,12 +102,12 @@ struct propagatorQa { ccdb->setFatalWhenNull(false); // output objects - const AxisSpec axisX{(int)NbinsX, 0.0f, +250.0f, "X value"}; - const AxisSpec axisDCAxy{(int)NbinsDCA, -windowDCA, windowDCA, "DCA_{xy} (cm)"}; - const AxisSpec axisPt{(int)NbinsPt, 0.0f, 10.0f, "#it{p}_{T} (GeV/#it{c})"}; - const AxisSpec axisPtCoarse{(int)NbinsPtCoarse, 0.0f, 10.0f, "#it{p}_{T} (GeV/#it{c})"}; - const AxisSpec axisTanLambda{(int)NbinsTanLambda, -TanLambdaLimit, +TanLambdaLimit, "tan(#lambda)"}; - const AxisSpec axisDeltaPt{(int)NbinsDeltaPt, -DeltaPtLimit, +DeltaPtLimit, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec axisX{NbinsX, 0.0f, +250.0f, "X value"}; + const AxisSpec axisDCAxy{NbinsDCA, -windowDCA, windowDCA, "DCA_{xy} (cm)"}; + const AxisSpec axisPt{NbinsPt, 0.0f, 10.0f, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec axisPtCoarse{NbinsPtCoarse, 0.0f, 10.0f, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec axisTanLambda{NbinsTanLambda, -TanLambdaLimit, +TanLambdaLimit, "tan(#lambda)"}; + const AxisSpec axisDeltaPt{NbinsDeltaPt, -DeltaPtLimit, +DeltaPtLimit, "#it{p}_{T} (GeV/#it{c})"}; // All tracks histos.add("hTrackX", "hTrackX", kTH1F, {axisX}); @@ -145,8 +147,8 @@ struct propagatorQa { histos.add("hdcaXYusedInSVertexer", "hdcaXYusedInSVertexer", kTH1F, {axisDCAxy}); histos.add("hUpdateRadiiusedInSVertexer", "hUpdateRadiiusedInSVertexer", kTH1F, {axisX}); // bit packed ITS cluster map - const AxisSpec axisITSCluMap{(int)128, -0.5f, +127.5f, "Packed ITS map"}; - const AxisSpec axisRadius{(int)dQANBinsRadius, 0.0f, +50.0f, "Radius (cm)"}; + const AxisSpec axisITSCluMap{128, -0.5f, +127.5f, "Packed ITS map"}; + const AxisSpec axisRadius{dQANBinsRadius, 0.0f, +50.0f, "Radius (cm)"}; // Histogram to bookkeep cluster maps histos.add("h2dITSCluMap", "h2dITSCluMap", kTH3D, {axisITSCluMap, axisRadius, axisPtCoarse}); @@ -170,7 +172,7 @@ struct propagatorQa { if (d_bz_input > -990) { d_bz = d_bz_input; o2::parameters::GRPMagField grpmag; - if (fabs(d_bz) > 1e-5) { + if (std::fabs(d_bz) > 1e-5) { grpmag.setL3Current(30000.f / (d_bz / 5.0f)); } o2::base::Propagator::initFieldFromGRP(&grpmag); @@ -210,7 +212,7 @@ struct propagatorQa { initCCDB(bc); std::array dcaInfo; - for (auto& track : tracks) { + for (const auto& track : tracks) { if (track.tpcNClsFound() < minTPCClustersRequired) continue; @@ -273,7 +275,7 @@ struct propagatorQa { // ITS cluster map float lMCCreation = TMath::Sqrt(mctrack.vx() * mctrack.vx() + mctrack.vy() * mctrack.vy()); - histos.fill(HIST("h2dITSCluMap"), (float)track.itsClusterMap(), lMCCreation, track.pt()); + histos.fill(HIST("h2dITSCluMap"), static_cast(track.itsClusterMap()), lMCCreation, track.pt()); if (lIsPrimary) { histos.fill(HIST("hPrimaryDeltaTanLambdaVsPt"), track.tgl(), track.tgl() - lTrackParametrization.getTgl()); @@ -291,12 +293,12 @@ struct propagatorQa { histos.fill(HIST("hPrimaryDeltaDCAs"), lCircleDCA - lDCA); histos.fill(HIST("hPrimaryDeltaDCAsVsPt"), track.pt(), lCircleDCA - lDCA); histos.fill(HIST("hPrimaryRecalculatedDeltaDCAsVsPt"), track.pt(), lRecalculatedDCA - lDCA); - histos.fill(HIST("h2dITSCluMapPrimaries"), (float)track.itsClusterMap(), lMCCreation, track.pt()); + histos.fill(HIST("h2dITSCluMapPrimaries"), static_cast(track.itsClusterMap()), lMCCreation, track.pt()); } // determine if track was used in svertexer bool usedInSVertexer = false; bool lUsedByV0 = false, lUsedByCascade = false; - for (auto& V0 : V0s) { + for (const auto& V0 : V0s) { if (V0.posTrackId() == track.globalIndex()) { lUsedByV0 = true; break; @@ -306,7 +308,7 @@ struct propagatorQa { break; } } - for (auto& cascade : cascades) { + for (const auto& cascade : cascades) { if (cascade.bachelorId() == track.globalIndex()) { lUsedByCascade = true; break; @@ -315,10 +317,10 @@ struct propagatorQa { if (lUsedByV0 || lUsedByCascade) usedInSVertexer = true; - if (usedInSVertexer) + if (usedInSVertexer) { histos.fill(HIST("hUpdateRadiiusedInSVertexer"), lRadiusOfLastUpdate); - if (usedInSVertexer) histos.fill(HIST("hdcaXYusedInSVertexer"), lDCA); + } } } PROCESS_SWITCH(propagatorQa, processMC, "process MC", true); @@ -330,7 +332,7 @@ struct propagatorQa { initCCDB(bc); std::array dcaInfo; - for (auto& track : tracks) { + for (const auto& track : tracks) { if (track.tpcNClsFound() < minTPCClustersRequired) continue; @@ -388,7 +390,7 @@ struct propagatorQa { // ITS cluster map float lMCCreation = 0.1; // dummy value, we don't know - histos.fill(HIST("h2dITSCluMap"), (float)track.itsClusterMap(), lMCCreation, track.pt()); + histos.fill(HIST("h2dITSCluMap"), static_cast(track.itsClusterMap()), lMCCreation, track.pt()); // A hack: use DCA as equiv to primary if (TMath::Abs(lDCA) < 0.05) { // 500 microns @@ -406,13 +408,13 @@ struct propagatorQa { histos.fill(HIST("hPrimaryDeltaDCAs"), lCircleDCA - lDCA); histos.fill(HIST("hPrimaryDeltaDCAsVsPt"), track.pt(), lCircleDCA - lDCA); histos.fill(HIST("hPrimaryRecalculatedDeltaDCAsVsPt"), track.pt(), lRecalculatedDCA - lDCA); - histos.fill(HIST("h2dITSCluMapPrimaries"), (float)track.itsClusterMap(), lMCCreation, track.pt()); + histos.fill(HIST("h2dITSCluMapPrimaries"), static_cast(track.itsClusterMap()), lMCCreation, track.pt()); } // determine if track was used in svertexer bool usedInSVertexer = false; bool lUsedByV0 = false, lUsedByCascade = false; - for (auto& V0 : V0s) { + for (const auto& V0 : V0s) { if (V0.posTrackId() == track.globalIndex()) { lUsedByV0 = true; break; @@ -422,7 +424,7 @@ struct propagatorQa { break; } } - for (auto& cascade : cascades) { + for (const auto& cascade : cascades) { if (cascade.bachelorId() == track.globalIndex()) { lUsedByCascade = true; break; @@ -431,10 +433,10 @@ struct propagatorQa { if (lUsedByV0 || lUsedByCascade) usedInSVertexer = true; - if (usedInSVertexer) + if (usedInSVertexer) { histos.fill(HIST("hUpdateRadiiusedInSVertexer"), lRadiusOfLastUpdate); - if (usedInSVertexer) histos.fill(HIST("hdcaXYusedInSVertexer"), lDCA); + } } } PROCESS_SWITCH(propagatorQa, processData, "process data", false); @@ -446,7 +448,7 @@ struct propagatorQa { initCCDB(bc); std::array dcaInfo; - for (auto& trackIU : tracksIU) { + for (const auto& trackIU : tracksIU) { if (trackIU.tpcNClsFound() < minTPCClustersRequired) continue; // skip if not enough TPC clusters diff --git a/Common/Tasks/qVectorsCorrection.cxx b/Common/Tasks/qVectorsCorrection.cxx index 10e37a4c210..2d3c5c78804 100644 --- a/Common/Tasks/qVectorsCorrection.cxx +++ b/Common/Tasks/qVectorsCorrection.cxx @@ -68,6 +68,8 @@ struct qVectorsCorrection { Configurable cfgRefBName{"cfgRefBName", "TPCneg", "The name of detector for reference B"}; Configurable cfgAddEvtSel{"cfgAddEvtSel", true, "event selection"}; + Configurable cfgEvtSel{"cfgEvtSel", 0, "Event selection flags\n0: Sel8\n1: Sel8+kIsGoodZvtxFT0vsPV+kNoSameBunchPileup\n2: Sel8+kIsGoodZvtxFT0vsPV+kNoSameBunchPileup+kNoCollInTimeRangeStandard\n3: Sel8+kNoSameBunchPileup"}; + Configurable cfgnTotalSystem{"cfgnTotalSystem", 7, "total qvector number"}; Configurable cfgNbinsEP{"cfgNbinsEP", 360, "nbins for EP histograms"}; @@ -75,7 +77,6 @@ struct qVectorsCorrection { Configurable cfgQAFinal{"cfgQAFinal", false, "draw final q-vector steps"}; Configurable cfgQAFlowStudy{"cfgQAFlowStudy", false, "configurable for flow study"}; Configurable cfgQAOccupancyStudy{"cfgQAOccupancyStudy", false, "configurable for occupancy study"}; - Configurable cfgAddEvtSelPileup{"cfgAddEvtSelPileup", false, "configurable for pileup selection"}; Configurable cfgMinPt{"cfgMinPt", 0.15, "Minimum transverse momentum for charged track"}; Configurable cfgMaxEta{"cfgMaxEta", 0.8, "Maximum pseudorapidiy for charged track"}; @@ -541,16 +542,31 @@ struct qVectorsCorrection { void process(MyCollisions::iterator const& qVec, MyTracks const& tracks) { histosQA.fill(HIST("histCentFull"), qVec.cent()); - if (cfgAddEvtSel && (!qVec.sel8() || - !qVec.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || - !qVec.selection_bit(aod::evsel::kNoSameBunchPileup))) { - return; - } - if (cfgAddEvtSel && (qVec.trackOccupancyInTimeRange() > cfgMaxOccupancy || qVec.trackOccupancyInTimeRange() < cfgMinOccupancy)) { - return; - } - if (cfgAddEvtSelPileup && !qVec.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { - return; + if (cfgAddEvtSel) { + switch (cfgEvtSel) { + case 0: // Sel8 + if (!qVec.sel8()) + return; + break; + case 1: // PbPb standard + if (!qVec.sel8() || !qVec.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !qVec.selection_bit(aod::evsel::kNoSameBunchPileup)) + return; + break; + case 2: // PbPb with pileup + if (!qVec.sel8() || !qVec.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard) || + !qVec.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !qVec.selection_bit(aod::evsel::kNoSameBunchPileup)) + return; + break; + case 3: // Small systems (OO, NeNe, pp) + if (!qVec.sel8() || !qVec.selection_bit(aod::evsel::kNoSameBunchPileup)) + return; + break; + default: + LOGF(warning, "Event selection flag was not found, continuing without basic event selections!\n"); + } + // Check occupancy + if (qVec.trackOccupancyInTimeRange() > cfgMaxOccupancy || qVec.trackOccupancyInTimeRange() < cfgMinOccupancy) + return; } for (uint i = 0; i < cfgnMods->size(); i++) { diff --git a/Common/Tasks/trackqa.cxx b/Common/Tasks/trackqa.cxx index d10d42af8da..788fba7e29b 100644 --- a/Common/Tasks/trackqa.cxx +++ b/Common/Tasks/trackqa.cxx @@ -13,15 +13,25 @@ // Task producing basic tracking qa histograms // +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + #include // std::swap #include -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectionDefaults.h" +#include using namespace o2; using namespace o2::framework; @@ -34,7 +44,7 @@ void customize(std::vector& workflowOptions) {"add-cut-qa", VariantType::Int, 0, {"Add track cut QA histograms."}}}; std::swap(workflowOptions, options); } -#include "Framework/runDataProcessing.h" +#include //**************************************************************************************** /** @@ -105,7 +115,7 @@ struct TrackQa { histos.fill(HIST("TrackPar/snp"), track.snp()); histos.fill(HIST("TrackPar/tgl"), track.tgl()); for (unsigned int i = 0; i < 32; i++) { - if (track.flags() & (1 << i)) { + if (track.flags() & (1u << i)) { histos.fill(HIST("TrackPar/flags"), i); } } diff --git a/Common/Tools/EventSelectionTools.h b/Common/Tools/EventSelectionTools.h index d32cc2dcbcc..a798e1b7142 100644 --- a/Common/Tools/EventSelectionTools.h +++ b/Common/Tools/EventSelectionTools.h @@ -19,33 +19,35 @@ #define bitcheck(var, nbit) ((var) & (static_cast(1) << (nbit))) #define bitcheck64(var, nbit) ((var) & (static_cast(1) << (nbit))) -#include "MetadataHelper.h" -#include "TableHelper.h" - #include "Common/CCDB/EventSelectionParams.h" #include "Common/CCDB/TriggerAliases.h" +#include "Common/Core/MetadataHelper.h" +#include "Common/Core/TableHelper.h" #include "Common/DataModel/EventSelection.h" -#include "CCDB/BasicCCDBManager.h" -#include "CommonConstants/LHCConstants.h" -#include "DataFormatsCTP/Configuration.h" -#include "DataFormatsCTP/Scalers.h" -#include "DataFormatsFT0/Digit.h" -#include "DataFormatsITSMFT/NoiseMap.h" // missing include in TimeDeadMap.h -#include "DataFormatsITSMFT/TimeDeadMap.h" -#include "DataFormatsParameters/AggregatedRunInfo.h" -#include "DataFormatsParameters/GRPECSObject.h" -#include "DataFormatsParameters/GRPLHCIFData.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/HistogramRegistry.h" -#include "ITSMFTBase/DPLAlpideParam.h" -#include "ITSMFTReconstruction/ChipMappingITS.h" +#include +#include +#include +#include +#include +#include // missing include in TimeDeadMap.h +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include +#include #include #include +#include //__________________________________________ // MultModule @@ -106,6 +108,13 @@ struct evselConfigurables : o2::framework::ConfigurableGroup { o2::framework::Configurable confEpsilonVzDiffVetoInROF{"EpsilonVzDiffVetoInROF", 0.3, "Minumum distance to nearby collisions along z inside this ITS ROF, cm"}; // o2-linter: disable=name/configurable (temporary fix) o2::framework::Configurable confUseWeightsForOccupancyVariable{"UseWeightsForOccupancyEstimator", 1, "Use or not the delta-time weights for the occupancy estimator"}; // o2-linter: disable=name/configurable (temporary fix) o2::framework::Configurable confNumberOfOrbitsPerTF{"NumberOfOrbitsPerTF", -1, "Number of orbits per Time Frame. Take from CCDB if -1"}; // o2-linter: disable=name/configurable (temporary fix) + + // configurables for light-ion event selection (testing mode) + o2::framework::Configurable confLightIonsAlternativeBcMatching{"TestAlternativeBcMatching", 0, "0 - use standard matching, 1 - try alternative for light ions"}; // o2-linter: disable=name/configurable (temporary fix) + o2::framework::Configurable confLightIonsModifyTimeVetoOnNearbyColl{"TestModifyTimeVetoOnNearbyColl", 0, "0 - use standard time veto, 1 - modify time range"}; // o2-linter: disable=name/configurable (temporary fix) + o2::framework::Configurable confLightIonsVetoOnTRDinPast{"TestVetoOnTRDinPast", 0, "0 - use standard time veto, 1 - use veto on TRD in the past events"}; // o2-linter: disable=name/configurable (temporary fix) + o2::framework::Configurable confLightIonsNsigmaOnVzDiff{"TestVzDiffNsigma", 3.0, "+/- nSigma on vZ difference by FT0 and by tracks"}; // o2-linter: disable=name/configurable (temporary fix) + o2::framework::Configurable confLightIonsMarginVzDiff{"TestVzDiffMargin", 0.2, "margin for +/- nSigma on vZ difference by FT0 and by tracks"}; // o2-linter: disable=name/configurable (temporary fix) }; // luminosity configurables @@ -184,8 +193,9 @@ class BcSelectionModule template bool configure(TCCDB& ccdb, TBCs const& bcs) { - if (bcs.size() == 0) + if (bcs.size() == 0) { return false; + } int run = bcs.iteratorAt(0).runNumber(); if (run != lastRun) { lastRun = run; @@ -259,7 +269,7 @@ class BcSelectionModule if (mapRCT == nullptr) { LOGP(info, "rct object missing... inserting dummy rct flags"); mapRCT = new std::map; - uint32_t dummyValue = 1 << 31; // setting bit 31 to indicate that rct object is missing + uint32_t dummyValue = 1u << 31; // setting bit 31 to indicate that rct object is missing mapRCT->insert(std::pair(sorTimestamp, dummyValue)); } } @@ -602,6 +612,7 @@ class EventSelectionModule int run3min = 500000; int lastRun = -1; // last run number (needed to access ccdb only if run!=lastRun) std::bitset bcPatternB; // bc pattern of colliding bunches + std::vector bcsPattern; // pattern of colliding BCs int64_t bcSOR = -1; // global bc of the start of the first orbit int64_t nBCsPerTF = -1; // duration of TF in bcs, should be 128*3564 or 32*3564 @@ -609,7 +620,13 @@ class EventSelectionModule int rofLength = -1; // ITS ROF length, in bc std::string strLPMProductionTag = ""; // MC production tag to be retrieved from AO2D metadata - int32_t findClosest(int64_t globalBC, std::map& bcs) + // temporary (?) parameterizations for light ion runs + int runLightIons = -1; + int runListLightIons[11] = {564356, 564359, 564373, 564374, 564387, 564400, 564414, 564430, 564445, 564468, 564472}; + std::vector diffVzParMean; // parameterization for mean of diff vZ by FT0 vs by tracks + std::vector diffVzParSigma; // parameterization for stddev of diff vZ by FT0 vs by tracks + + int32_t findClosest(const int64_t globalBC, const std::map& bcs) { auto it = bcs.lower_bound(globalBC); int64_t bc1 = it->first; @@ -702,6 +719,9 @@ class EventSelectionModule template bool configure(TCCDB& ccdb, TTimestamps const& timestamps, TBCs const& bcs) { + if (bcs.size() == 0) { + return false; + } int run = bcs.iteratorAt(0).runNumber(); // extract bc pattern from CCDB for data or anchored MC only if (run != lastRun && run >= run3min) { @@ -718,12 +738,38 @@ class EventSelectionModule // avoids crash related to specific run number auto grplhcif = ccdb->template getSpecific("GLO/Config/GRPLHCIF", ts); bcPatternB = grplhcif->getBunchFilling().getBCPattern(); + bcsPattern = grplhcif->getBunchFilling().getFilledBCs(); // extract ITS ROF parameters auto alppar = ccdb->template getForTimeStamp>("ITS/Config/AlpideParam", ts); rofOffset = alppar->roFrameBiasInBC; rofLength = alppar->roFrameLengthInBC; LOGP(debug, "ITS ROF Offset={} ITS ROF Length={}", rofOffset, rofLength); + if (evselOpts.confLightIonsAlternativeBcMatching) { + for (unsigned long i = 0; i < bcsPattern.size(); i++) + LOGP(info, "bcsPattern: i={} bc={}", i, bcsPattern.at(i)); + } + + // special treatment of light ion runs + if (lastRun >= 564356 && lastRun <= 564472) { + for (unsigned long i = 0; i < sizeof(runListLightIons) / sizeof(*runListLightIons); i++) { + if (runListLightIons[i] == lastRun) { + runLightIons = lastRun; + // extract parameterization for diff of vZ by FT0 vs by tracks + auto parMeans = ccdb->template getForTimeStamp>("Users/a/altsybee/diffVzCollVsFTOmeanPar", ts); + auto parSigmas = ccdb->template getForTimeStamp>("Users/a/altsybee/diffVzCollVsFTOsigmaPar", ts); + diffVzParMean = *parMeans; + diffVzParSigma = *parSigmas; + LOGP(info, ">>> special treatment for diffVz for light ion run {}", runLightIons); + for (int i = 0; i < 5; i++) + LOGP(info, " mean par {} = {}", i, diffVzParMean[i]); + for (int i = 0; i < 5; i++) + LOGP(info, " sigma par {} = {}", i, diffVzParSigma[i]); + break; + } + } + } + } // if run != lastRun return true; } @@ -824,6 +870,7 @@ class EventSelectionModule // create maps from globalBC to bc index for TVX-fired bcs // to be used for closest TVX searches std::map mapGlobalBcWithTVX; + std::map mapGlobalBcWithOrInFT0; std::map mapGlobalBcVtxZ; for (const auto& bc : bcs) { int64_t globalBC = bc.globalBC(); @@ -831,6 +878,11 @@ class EventSelectionModule if (run >= run3min && bcPatternB[globalBC % nBCsPerOrbit] == 0) { continue; } + + if (bc.has_ft0()) { + mapGlobalBcWithOrInFT0[globalBC] = bc.globalIndex(); + } + auto selection = bcselbuffer[bc.globalIndex()].selection; if (bitcheck64(selection, aod::evsel::kIsTriggerTVX)) { mapGlobalBcWithTVX[globalBC] = bc.globalIndex(); @@ -863,9 +915,11 @@ class EventSelectionModule std::vector vIsVertexTOFmatched(cols.size(), 0); // at least one of vertex contributors is matched to TOF std::vector vIsVertexTRDmatched(cols.size(), 0); // at least one of vertex contributors is matched to TRD - std::vector vCollisionsPerBc(bcs.size(), 0); // counter of collisions per found bc for pileup checks - std::vector vFoundBCindex(cols.size(), -1); // indices of found bcs - std::vector vFoundGlobalBC(cols.size(), 0); // global BCs for collisions + std::vector vCollisionsPerBc(bcs.size(), 0); // counter of collisions per found bc for pileup checks + std::vector vCollisionsPileupPerColl(cols.size(), 0); // counter of pileup in the same bc as a given collision + std::vector vBCinPatternPerColl(cols.size(), 0); // found nominal BCs for collisions + std::vector vFoundBCindex(cols.size(), -1); // indices of found bcs + std::vector vFoundGlobalBC(cols.size(), 0); // global BCs for collisions std::vector vIsVertexTOF(cols.size(), 0); std::vector vIsVertexTRD(cols.size(), 0); @@ -937,7 +991,67 @@ class EventSelectionModule int64_t foundGlobalBC = 0; int32_t foundBCindex = -1; - if (nPvTracksTOF > 0) { + // alternative collision-BC matching (currently: test mode, the aim is to improve pileup rejection) + if (evselOpts.confLightIonsAlternativeBcMatching) { + foundGlobalBC = globalBC; + // find closest nominal bc in pattern + for (unsigned long i = 0; i < bcsPattern.size(); i++) { + int32_t localBC = globalBC % nBCsPerOrbit; + int32_t bcFromPattern = bcsPattern.at(i); + int64_t bcDiff = bcFromPattern - localBC; + if (std::abs(bcDiff) <= 20) { + foundGlobalBC = (globalBC / nBCsPerOrbit) * nBCsPerOrbit + bcFromPattern; + break; // the bc in pattern is found + } + } + + // matched with TOF --> precise time, match to TVX, but keep the nominal foundGlobalBC from pattern + if (vIsVertexTOFmatched[colIndex]) { + std::map::iterator it = mapGlobalBcWithTVX.find(foundGlobalBC); + if (it != mapGlobalBcWithTVX.end()) { + foundBCindex = it->second; // TVX at foundGlobalBC is found + } else { // check if TVX is in nearby bcs + it = mapGlobalBcWithTVX.find(foundGlobalBC + 1); // next bc + if (it != mapGlobalBcWithTVX.end()) { + // foundGlobalBC += 1; + foundBCindex = it->second; + } else { + it = mapGlobalBcWithTVX.find(foundGlobalBC - 1); // previous bc + if (it != mapGlobalBcWithTVX.end()) { + // foundGlobalBC -= 1; + foundBCindex = it->second; + } else { + foundBCindex = bc.globalIndex(); // keep original BC index + } + } + } + } // end of if TOF-matched vertex + else { // for non-TOF and low-mult vertices, consider nearby nominal bcs + int64_t meanBC = globalBC + TMath::Nint(sumHighPtTime / sumHighPtW / bcNS); + int64_t bestGlobalBC = findBestGlobalBC(meanBC, evselOpts.confSigmaBCforHighPtTracks, vNcontributors[colIndex], col.posZ(), mapGlobalBcVtxZ); + if (bestGlobalBC > 0) { + foundGlobalBC = bestGlobalBC; + // find closest nominal bc in pattern + for (unsigned long j = 0; j < bcsPattern.size(); j++) { + int32_t bcFromPatternBest = bcsPattern.at(j); + int64_t bcDiff = bcFromPatternBest - (bestGlobalBC % nBCsPerOrbit); + if (std::abs(bcDiff) <= 20) { + foundGlobalBC = (bestGlobalBC / nBCsPerOrbit) * nBCsPerOrbit + bcFromPatternBest; + break; // the bc in pattern is found + } + } + foundBCindex = mapGlobalBcWithTVX[bestGlobalBC]; + } else { // failed to find a proper TVX with small vZ difference + foundBCindex = bc.globalIndex(); // keep original BC index + } + } // end of non-TOF matched vertices + // sanitity check: if BC was not found + if (foundBCindex == -1) { + foundBCindex = bc.globalIndex(); + } + vBCinPatternPerColl[colIndex] = foundGlobalBC; + // end of alternative coll-BC matching (test) + } else if (nPvTracksTOF > 0) { // "standard matching": // for collisions with TOF tracks: // take bc corresponding to TOF track with median time int64_t tofGlobalBC = globalBC + TMath::Nint(getMedian(vTrackTimesTOF) / bcNS); @@ -975,23 +1089,34 @@ class EventSelectionModule if (foundBCindex >= 0) mapGlobalBcVtxZ.erase(foundGlobalBC); } - - // second loop to match remaining low-pt TPCnoTOFnoTRD collisions - for (const auto& col : cols) { - int32_t colIndex = col.globalIndex(); - if (vIsVertexTPC[colIndex] > 0 && vIsVertexTOF[colIndex] == 0 && vIsVertexHighPtTPC[colIndex] == 0) { - float weightedTime = vWeightedTimesTPCnoTOFnoTRD[colIndex]; - float weightedSigma = vWeightedSigmaTPCnoTOFnoTRD[colIndex]; - auto bc = col.template bc_as>(); - int64_t globalBC = bc.globalBC(); - int64_t meanBC = globalBC + TMath::Nint(weightedTime / bcNS); - int64_t sigmaBC = TMath::CeilNint(weightedSigma / bcNS); - int64_t bestGlobalBC = findBestGlobalBC(meanBC, sigmaBC, vNcontributors[colIndex], col.posZ(), mapGlobalBcVtxZ); - vFoundGlobalBC[colIndex] = bestGlobalBC > 0 ? bestGlobalBC : globalBC; - vFoundBCindex[colIndex] = bestGlobalBC > 0 ? mapGlobalBcWithTVX[bestGlobalBC] : bc.globalIndex(); + // alternative matching: looking for collisions with the same nominal BC + if (evselOpts.confLightIonsAlternativeBcMatching) { + for (unsigned long iCol = 0; iCol < vBCinPatternPerColl.size(); iCol++) { + int64_t foundNominalBC = vBCinPatternPerColl[iCol]; + for (unsigned long jCol = 0; jCol < vBCinPatternPerColl.size(); jCol++) { + int64_t foundNominalBC2 = vBCinPatternPerColl[jCol]; + if (foundNominalBC2 == foundNominalBC) { + vCollisionsPileupPerColl[iCol]++; + } + } + } + } else { // continue standard matching: second loop to match remaining low-pt TPCnoTOFnoTRD collisions + for (const auto& col : cols) { + int32_t colIndex = col.globalIndex(); + if (vIsVertexTPC[colIndex] > 0 && vIsVertexTOF[colIndex] == 0 && vIsVertexHighPtTPC[colIndex] == 0) { + float weightedTime = vWeightedTimesTPCnoTOFnoTRD[colIndex]; + float weightedSigma = vWeightedSigmaTPCnoTOFnoTRD[colIndex]; + auto bc = col.template bc_as>(); + int64_t globalBC = bc.globalBC(); + int64_t meanBC = globalBC + TMath::Nint(weightedTime / bcNS); + int64_t sigmaBC = TMath::CeilNint(weightedSigma / bcNS); + int64_t bestGlobalBC = findBestGlobalBC(meanBC, sigmaBC, vNcontributors[colIndex], col.posZ(), mapGlobalBcVtxZ); + vFoundGlobalBC[colIndex] = bestGlobalBC > 0 ? bestGlobalBC : globalBC; + vFoundBCindex[colIndex] = bestGlobalBC > 0 ? mapGlobalBcWithTVX[bestGlobalBC] : bc.globalIndex(); + } + // fill pileup counter + vCollisionsPerBc[vFoundBCindex[colIndex]]++; } - // fill pileup counter - vCollisionsPerBc[vFoundBCindex[colIndex]]++; } // save indices of collisions for occupancy calculation (both in ROF and in time range) @@ -1188,10 +1313,24 @@ class EventSelectionModule sumAmpFT0CInFullTimeWindow += wOccup * vAmpFT0CperColl[thisColIndex]; // counting tracks from other collisions in fixed time windows - if (std::fabs(dt) < evselOpts.confTimeRangeVetoOnCollNarrow) - nITS567tracksForVetoNarrow += vTracksITS567perColl[thisColIndex]; - if (std::fabs(dt) < evselOpts.confTimeRangeVetoOnCollStandard) - nITS567tracksForVetoStrict += vTracksITS567perColl[thisColIndex]; + if (!evselOpts.confLightIonsModifyTimeVetoOnNearbyColl) { + if (std::fabs(dt) < evselOpts.confTimeRangeVetoOnCollNarrow) + nITS567tracksForVetoNarrow += vTracksITS567perColl[thisColIndex]; + if (std::fabs(dt) < evselOpts.confTimeRangeVetoOnCollStandard) + nITS567tracksForVetoStrict += vTracksITS567perColl[thisColIndex]; + } else { // special veto ranges (tests for light ion runs) + if (dt > -4.5 && dt < 2.5) // avoid TOF- and TRD-related structures, with 0.5 us margin + nITS567tracksForVetoNarrow += vTracksITS567perColl[thisColIndex]; + + if (!evselOpts.confLightIonsVetoOnTRDinPast) { + if (dt > -25.5 && dt < 2.5) // test effect from TRD triggers in the past + nITS567tracksForVetoStrict += vTracksITS567perColl[thisColIndex]; + } else { + // counting TRD-matched vertices in a long time interval in the past + if (dt > -25.5 && dt < 2.5) + nITS567tracksForVetoStrict += vIsVertexTRDmatched[thisColIndex]; + } + } // standard cut on other collisions vs delta-times const float driftV = 2.5; // drift velocity in cm/us, TPC drift_length / drift_time = 250 cm / 100 us @@ -1210,7 +1349,11 @@ class EventSelectionModule vSumAmpFT0CinFullTimeWin[colIndex] = sumAmpFT0CInFullTimeWindow; // occupancy by a sum of FT0C amplitudes (without a current collision) // occupancy flags based on nearby collisions vNoCollInTimeRangeNarrow[colIndex] = (nITS567tracksForVetoNarrow == 0); - vNoCollInTimeRangeStrict[colIndex] = (nITS567tracksForVetoStrict == 0); + if (!evselOpts.confLightIonsVetoOnTRDinPast) + vNoCollInTimeRangeStrict[colIndex] = (nITS567tracksForVetoStrict == 0); + else + vNoCollInTimeRangeStrict[colIndex] = (nITS567tracksForVetoStrict == 0 && nITS567tracksForVetoNarrow == 0); + vNoHighMultCollInTimeRange[colIndex] = (nCollsWithFT0CAboveVetoStandard == 0); } @@ -1227,8 +1370,24 @@ class EventSelectionModule // compare zVtx from FT0 and from PV bool isGoodZvtxFT0vsPV = 0; if (bcselEntry.foundFT0Id > -1) { - auto foundFT0 = ft0s.rawIteratorAt(bcselEntry.foundFT0Id); - isGoodZvtxFT0vsPV = std::fabs(foundFT0.posZ() - col.posZ()) < evselOpts.maxDiffZvtxFT0vsPV; + auto foundFT0Inner = ft0s.rawIteratorAt(bcselEntry.foundFT0Id); + float diffVz = foundFT0Inner.posZ() - col.posZ(); + if (runLightIons == -1) { + isGoodZvtxFT0vsPV = std::fabs(diffVz) < evselOpts.maxDiffZvtxFT0vsPV; + } else { // special treatment of light ion runs + float multT0A = bc.ft0().sumAmpA(); + float multT0C = bc.ft0().sumAmpC(); + float T0M = multT0A + multT0C; + // calc mean at this T0 ampl. + float x = (T0M < 50 ? 50 : T0M); + double diffMean = diffVzParMean[0] + diffVzParMean[1] * pow(x, diffVzParMean[2]) + diffVzParMean[3] * pow(x, diffVzParMean[4]); + // calc sigma at this T0 ampl. + x = (T0M < 20 ? 20 : (T0M > 1.2e4 ? 1.2e4 : T0M)); + double diffSigma = diffVzParSigma[0] + diffVzParSigma[1] * pow(x, diffVzParSigma[2]) + diffVzParSigma[3] * pow(x, diffVzParSigma[4]); + float nSigma = evselOpts.confLightIonsNsigmaOnVzDiff; + float margin = evselOpts.confLightIonsMarginVzDiff; + isGoodZvtxFT0vsPV = (diffVz > diffMean - nSigma * diffSigma - margin && diffVz < diffMean + nSigma * diffSigma + margin); + } } // copy alias decisions from bcsel table @@ -1236,7 +1395,10 @@ class EventSelectionModule // copy selection decisions from bcsel table uint64_t selection = bcselbuffer[bc.globalIndex()].selection; - selection |= vCollisionsPerBc[foundBC] <= 1 ? BIT(aod::evsel::kNoSameBunchPileup) : 0; + if (evselOpts.confLightIonsAlternativeBcMatching) + selection |= vCollisionsPileupPerColl[colIndex] <= 1 ? BIT(aod::evsel::kNoSameBunchPileup) : 0; + else + selection |= vCollisionsPerBc[foundBC] <= 1 ? BIT(aod::evsel::kNoSameBunchPileup) : 0; selection |= vIsVertexITSTPC[colIndex] ? BIT(aod::evsel::kIsVertexITSTPC) : 0; selection |= vIsVertexTOFmatched[colIndex] ? BIT(aod::evsel::kIsVertexTOFmatched) : 0; selection |= vIsVertexTRDmatched[colIndex] ? BIT(aod::evsel::kIsVertexTRDmatched) : 0; @@ -1384,11 +1546,13 @@ class LumiModule template bool configure(TCCDB& ccdb, TTimestamps const& timestamps, TBCs const& bcs) { - if (bcs.size() == 0) + if (bcs.size() == 0) { return false; + } int run = bcs.iteratorAt(0).runNumber(); - if (run < 500000) // o2-linter: disable=magic-number (skip for unanchored MCs) + if (run < 500000) { // o2-linter: disable=magic-number (skip for unanchored MCs) return false; + } if (run != lastRun && run >= 520259) { // o2-linter: disable=magic-number (scalers available for runs above 520120) lastRun = run; int64_t ts = timestamps[0]; diff --git a/Common/Tools/MultModule.h b/Common/Tools/MultModule.h index 56078d520c2..3623543a54d 100644 --- a/Common/Tools/MultModule.h +++ b/Common/Tools/MultModule.h @@ -16,22 +16,26 @@ #ifndef COMMON_TOOLS_MULTMODULE_H_ #define COMMON_TOOLS_MULTMODULE_H_ -#include -#include -#include -#include -#include -#include -#include -#include "Framework/AnalysisDataModel.h" -#include "Framework/Configurable.h" -#include "Framework/HistogramSpec.h" -#include "TableHelper.h" +#include "PWGMM/Mult/DataModel/bestCollisionTable.h" + #include "Common/Core/TPCVDriftManager.h" -#include "Common/DataModel/Multiplicity.h" +#include "Common/Core/TableHelper.h" #include "Common/DataModel/Centrality.h" -#include "PWGMM/Mult/DataModel/bestCollisionTable.h" -#include "TFormula.h" +#include "Common/DataModel/Multiplicity.h" + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include //__________________________________________ // MultModule @@ -61,6 +65,8 @@ static const std::vector tableNames{ "FT0MultZeqs", "FDDMultZeqs", "PVMultZeqs", + "GlobalMultZeqs", + "MFTMultZeqs", "MultMCExtras", "Mult2MCExtras", "MFTMults", @@ -86,7 +92,7 @@ static const std::vector tableNames{ "BCCentFT0As", "BCCentFT0Cs"}; -static constexpr int nTablesConst = 36; +static constexpr int nTablesConst = 38; static const std::vector parameterNames{"enable"}; static const int defaultParameters[nTablesConst][nParameters]{ @@ -125,6 +131,8 @@ static const int defaultParameters[nTablesConst][nParameters]{ {-1}, {-1}, {-1}, + {-1}, + {-1}, {-1}}; // table index : match order above @@ -142,6 +150,8 @@ enum tableIndex { kFV0Mults, // standard kFT0MultZeqs, // zeq calib, standard kFDDMultZeqs, // zeq calib, standard kPVMultZeqs, // zeq calib, standard + kGlobalMultZeqs, // zeq calib, extra + kMFTMultZeqs, // zeq calib, extra kMultMCExtras, // MC exclusive kMult2MCExtras, // MC exclusive kMFTMults, // requires MFT task @@ -185,6 +195,8 @@ struct products : o2::framework::ProducesGroup { o2::framework::Produces tableFT0Zeqs; o2::framework::Produces tableFDDZeqs; o2::framework::Produces tablePVZeqs; + o2::framework::Produces tableNGlobalZeqs; + o2::framework::Produces tableNMFTZeqs; o2::framework::Produces tableExtraMc; o2::framework::Produces tableExtraMult2MCExtras; o2::framework::Produces mftMults; @@ -256,6 +268,8 @@ struct multEntry { float multFDDAZeq = -999.0f; float multFDDCZeq = -999.0f; float multNContribsZeq = 0; + float multMFTTracksZeq = 0; + float multGlobalTracksZeq = 0; int multGlobalTracks = 0; // multsGlobal int multNbrContribsEta05GlobalTrackWoDCA = 0; // multsGlobal @@ -317,6 +331,8 @@ class MultModule hVtxZFDDA = nullptr; hVtxZFDDC = nullptr; hVtxZNTracks = nullptr; + hVtxZNMFTTracks = nullptr; + hVtxZNGlobalTracks = nullptr; } // internal: calib related, vtx-z profiles @@ -330,6 +346,8 @@ class MultModule TProfile* hVtxZFDDA; TProfile* hVtxZFDDC; TProfile* hVtxZNTracks; + TProfile* hVtxZNMFTTracks; // non-legacy, added August/2025 + TProfile* hVtxZNGlobalTracks; // non-legacy, added August/2025 // declaration of structs here // (N.B.: will be invisible to the outside, create your own copies) @@ -421,7 +439,7 @@ class MultModule internalOpts.mEnabledTables.resize(nTablesConst, 0); LOGF(info, "Configuring tables to generate"); - auto& workflows = context.services().template get(); + const auto& workflows = context.services().template get(); TString listOfRequestors[nTablesConst]; for (int i = 0; i < nTablesConst; i++) { @@ -452,16 +470,6 @@ class MultModule } } - opts = internalOpts; - - // list enabled tables - for (int i = 0; i < nTablesConst; i++) { - // printout to be improved in the future - if (internalOpts.mEnabledTables[i]) { - LOGF(info, " -~> Table enabled: %s, requested by %s", tableNames[i], listOfRequestors[i].Data()); - } - } - // dependency checker if (internalOpts.mEnabledTables[kCentFV0As] && !internalOpts.mEnabledTables[kFV0MultZeqs]) { internalOpts.mEnabledTables[kFV0MultZeqs] = 1; @@ -479,10 +487,18 @@ class MultModule internalOpts.mEnabledTables[kMFTMults] = 1; listOfRequestors[kMFTMults].Append(Form("%s ", "dependency check")); } + if (internalOpts.mEnabledTables[kCentMFTs] && !internalOpts.mEnabledTables[kMFTMultZeqs]) { + internalOpts.mEnabledTables[kMFTMultZeqs] = 1; + listOfRequestors[kMFTMultZeqs].Append(Form("%s ", "dependency check")); + } if (internalOpts.mEnabledTables[kCentNGlobals] && !internalOpts.mEnabledTables[kMultsGlobal]) { internalOpts.mEnabledTables[kMultsGlobal] = 1; listOfRequestors[kMultsGlobal].Append(Form("%s ", "dependency check")); } + if (internalOpts.mEnabledTables[kCentNGlobals] && !internalOpts.mEnabledTables[kGlobalMultZeqs]) { + internalOpts.mEnabledTables[kGlobalMultZeqs] = 1; + listOfRequestors[kGlobalMultZeqs].Append(Form("%s ", "dependency check")); + } if (internalOpts.embedINELgtZEROselection.value > 0 && !internalOpts.mEnabledTables[kPVMults]) { internalOpts.mEnabledTables[kPVMults] = 1; listOfRequestors[kPVMults].Append(Form("%s ", "dependency check")); @@ -493,6 +509,19 @@ class MultModule internalOpts.generatorName.value = "PYTHIA"; } + // capture the need for PYTHIA calibration in light ion runs automatically + if (metadataInfo.isMC() && mRunNumber >= 564250 && mRunNumber <= 564472) { + internalOpts.generatorName.value = "PYTHIA"; + } + + // list enabled tables + for (int i = 0; i < nTablesConst; i++) { + // printout to be improved in the future + if (internalOpts.mEnabledTables[i]) { + LOGF(info, " -~> Table enabled: %s, requested by %s", tableNames[i], listOfRequestors[i].Data()); + } + } + mRunNumber = 0; mRunNumberCentrality = 0; lCalibLoaded = false; @@ -502,6 +531,10 @@ class MultModule hVtxZFDDA = nullptr; hVtxZFDDC = nullptr; hVtxZNTracks = nullptr; + hVtxZNMFTTracks = nullptr; + hVtxZNGlobalTracks = nullptr; + + opts = internalOpts; } //__________________________________________________ @@ -631,12 +664,20 @@ class MultModule hVtxZFDDA = static_cast(lCalibObjects->FindObject("hVtxZFDDA")); hVtxZFDDC = static_cast(lCalibObjects->FindObject("hVtxZFDDC")); hVtxZNTracks = static_cast(lCalibObjects->FindObject("hVtxZNTracksPV")); + hVtxZNMFTTracks = static_cast(lCalibObjects->FindObject("hVtxZMFT")); + hVtxZNGlobalTracks = static_cast(lCalibObjects->FindObject("hVtxZNGlobals")); lCalibLoaded = true; // Capture error if (!hVtxZFV0A || !hVtxZFT0A || !hVtxZFT0C || !hVtxZFDDA || !hVtxZFDDC || !hVtxZNTracks) { LOGF(error, "Problem loading CCDB objects! Please check"); lCalibLoaded = false; } + if (!hVtxZNMFTTracks) { + LOGF(info, "MFT track counter: vertex-Z calibration not loaded, will run without."); + } + if (!hVtxZNGlobalTracks) { + LOGF(info, "Global track counter: vertex-Z calibration not loaded, will run without."); + } } else { LOGF(error, "Problem loading CCDB object! Please check"); lCalibLoaded = false; @@ -721,9 +762,15 @@ class MultModule } //_______________________________________________________________________ - // forward detector signals, vertex-Z equalized + // fill selections (for posterior derived analysis if requested) + if (internalOpts.mEnabledTables[kMultSelections]) { + cursors.multSelections(collision.selection_raw()); + } + + //_______________________________________________________________________ + // vertex-Z equalized signals if (internalOpts.mEnabledTables[kFV0MultZeqs]) { - if (std::fabs(collision.posZ() && lCalibLoaded)) { + if (std::fabs(collision.posZ()) < 15.0f && lCalibLoaded) { mults.multFV0AZeq = hVtxZFV0A->Interpolate(0.0) * mults.multFV0A / hVtxZFV0A->Interpolate(collision.posZ()); } else { mults.multFV0AZeq = 0.0f; @@ -731,7 +778,7 @@ class MultModule cursors.tableFV0Zeqs(mults.multFV0AZeq); } if (internalOpts.mEnabledTables[kFT0MultZeqs]) { - if (std::fabs(collision.posZ() && lCalibLoaded)) { + if (std::fabs(collision.posZ()) < 15.0f && lCalibLoaded) { mults.multFT0AZeq = hVtxZFT0A->Interpolate(0.0) * mults.multFT0A / hVtxZFT0A->Interpolate(collision.posZ()); mults.multFT0CZeq = hVtxZFT0C->Interpolate(0.0) * mults.multFT0C / hVtxZFT0C->Interpolate(collision.posZ()); } else { @@ -741,7 +788,7 @@ class MultModule cursors.tableFT0Zeqs(mults.multFT0AZeq, mults.multFT0CZeq); } if (internalOpts.mEnabledTables[kFDDMultZeqs]) { - if (std::fabs(collision.posZ() && lCalibLoaded)) { + if (std::fabs(collision.posZ()) < 15.0f && lCalibLoaded) { mults.multFDDAZeq = hVtxZFDDA->Interpolate(0.0) * mults.multFDDA / hVtxZFDDA->Interpolate(collision.posZ()); mults.multFDDCZeq = hVtxZFDDC->Interpolate(0.0) * mults.multFDDC / hVtxZFDDC->Interpolate(collision.posZ()); } else { @@ -753,7 +800,7 @@ class MultModule //_______________________________________________________________________ // determine if barrel track loop is required, do it (once!) if so but save CPU if not - if (internalOpts.mEnabledTables[kTPCMults] || internalOpts.mEnabledTables[kPVMults] || internalOpts.mEnabledTables[kMultsExtra] || internalOpts.mEnabledTables[kPVMultZeqs] || internalOpts.mEnabledTables[kMultsGlobal]) { + if (internalOpts.mEnabledTables[kTPCMults] || internalOpts.mEnabledTables[kPVMults] || internalOpts.mEnabledTables[kMultsExtra] || internalOpts.mEnabledTables[kPVMultZeqs] || internalOpts.mEnabledTables[kMultsGlobal] || internalOpts.mEnabledTables[kGlobalMultZeqs]) { // single loop to calculate all for (const auto& track : tracks) { if (track.hasTPC()) { @@ -821,6 +868,17 @@ class MultModule } cursors.multsGlobal(mults.multGlobalTracks, mults.multNbrContribsEta08GlobalTrackWoDCA, mults.multNbrContribsEta10GlobalTrackWoDCA, mults.multNbrContribsEta05GlobalTrackWoDCA); + + if (!hVtxZNGlobalTracks || std::fabs(collision.posZ()) > 15.0f) { + mults.multGlobalTracksZeq = mults.multGlobalTracks; // if no equalization available, don't do it + } else { + mults.multGlobalTracksZeq = hVtxZNGlobalTracks->Interpolate(0.0) * mults.multGlobalTracks / hVtxZNGlobalTracks->Interpolate(collision.posZ()); + } + + // provide vertex-Z equalized Nglobals (or non-equalized if missing or beyond range) + if (internalOpts.mEnabledTables[kGlobalMultZeqs]) { + cursors.tableNGlobalZeqs(mults.multGlobalTracksZeq); + } } // fill track counters at this stage if requested @@ -841,7 +899,7 @@ class MultModule collision.flags()); } if (internalOpts.mEnabledTables[kPVMultZeqs]) { - if (std::fabs(collision.posZ()) && lCalibLoaded) { + if (std::fabs(collision.posZ()) < 15.0f && lCalibLoaded) { mults.multNContribsZeq = hVtxZNTracks->Interpolate(0.0) * mults.multNContribs / hVtxZNTracks->Interpolate(collision.posZ()); } else { mults.multNContribsZeq = 0.0f; @@ -933,6 +991,18 @@ class MultModule cursors.mftMults(nAllTracks, nTracks); mults[collision.globalIndex()].multMFTAllTracks = nAllTracks; mults[collision.globalIndex()].multMFTTracks = nTracks; + + // vertex-Z equalized MFT + if (!hVtxZNMFTTracks || std::fabs(collision.posZ()) > 15.0f) { + mults[collision.globalIndex()].multMFTTracksZeq = mults[collision.globalIndex()].multMFTTracks; // if no equalization available, don't do it + } else { + mults[collision.globalIndex()].multMFTTracksZeq = hVtxZNMFTTracks->Interpolate(0.0) * mults[collision.globalIndex()].multMFTTracks / hVtxZNMFTTracks->Interpolate(collision.posZ()); + } + + // provide vertex-Z equalized Nglobals (or non-equalized if missing or beyond range) + if (internalOpts.mEnabledTables[kMFTMultZeqs]) { + cursors.tableNMFTZeqs(mults[collision.globalIndex()].multMFTTracksZeq); + } } //__________________________________________________ @@ -1186,7 +1256,7 @@ class MultModule auto populateTable = [&](auto& table, struct CalibrationInfo& estimator, float multiplicity, bool isInelGt0) { const bool assignOutOfRange = internalOpts.embedINELgtZEROselection && !isInelGt0; - auto scaleMC = [](float x, float pars[6]) { + auto scaleMC = [](float x, const float pars[6]) { return std::pow(((pars[0] + pars[1] * std::pow(x, pars[2])) - pars[3]) / pars[4], 1.0f / pars[5]); }; @@ -1224,9 +1294,9 @@ class MultModule if (internalOpts.mEnabledTables[kCentNTPVs]) populateTable(cursors.centNTPV, ntpvInfo, mults[iEv].multNContribs, isInelGt0); if (internalOpts.mEnabledTables[kCentNGlobals]) - populateTable(cursors.centNGlobals, nGlobalInfo, mults[iEv].multGlobalTracks, isInelGt0); + populateTable(cursors.centNGlobals, nGlobalInfo, mults[iEv].multGlobalTracksZeq, isInelGt0); if (internalOpts.mEnabledTables[kCentMFTs]) - populateTable(cursors.centMFTs, mftInfo, mults[iEv].multMFTTracks, isInelGt0); + populateTable(cursors.centMFTs, mftInfo, mults[iEv].multMFTTracksZeq, isInelGt0); } // populate centralities per BC @@ -1271,7 +1341,7 @@ class MultModule const auto& firstbc = bcs.begin(); ConfigureCentralityRun2(ccdb, metadataInfo, firstbc); - auto scaleMC = [](float x, float pars[6]) { + auto scaleMC = [](float x, const float pars[6]) { return std::pow(((pars[0] + pars[1] * std::pow(x, pars[2])) - pars[3]) / pars[4], 1.0f / pars[5]); }; diff --git a/Common/Tools/Multiplicity/multCalibrator.cxx b/Common/Tools/Multiplicity/multCalibrator.cxx index e9931c0389f..493a3d5feac 100644 --- a/Common/Tools/Multiplicity/multCalibrator.cxx +++ b/Common/Tools/Multiplicity/multCalibrator.cxx @@ -16,17 +16,20 @@ // - victor.gonzalez@cern.ch // - david.dobrigkeit.chinellato@cern.ch // -#include "TList.h" -#include "TDirectory.h" -#include "TFile.h" -#include "TH1F.h" -#include "TH1D.h" -#include "TProfile.h" -#include "TStopwatch.h" -#include "TArrayL64.h" -#include "TArrayF.h" #include "multCalibrator.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include // FIXME + using namespace std; const TString multCalibrator::fCentEstimName[kNCentEstim] = { @@ -100,10 +103,10 @@ Bool_t multCalibrator::Calibrate() return kFALSE; } - //Step 1: verify if input file contains desired histograms + // Step 1: verify if input file contains desired histograms TH1D* hRaw[kNCentEstim]; for (Int_t iv = 0; iv < kNCentEstim; iv++) { - hRaw[iv] = (TH1D*)fileInput->Get(Form("multiplicity-qa/multiplicityQa/h%s", fCentEstimName[iv].Data())); + hRaw[iv] = reinterpret_cast(fileInput->Get(Form("multiplicity-qa/multiplicityQa/h%s", fCentEstimName[iv].Data()))); if (!hRaw[iv]) { cout << Form("File does not contain histogram h%s, which is necessary for calibration!", fCentEstimName[iv].Data()) << endl; return kFALSE; @@ -112,7 +115,7 @@ Bool_t multCalibrator::Calibrate() cout << "Histograms loaded! Will now calibrate..." << endl; - //Create output file + // Create output file TFile* fOut = new TFile(fOutputFileName.Data(), "RECREATE"); TH1F* hCalib[kNCentEstim]; for (Int_t iv = 0; iv < kNCentEstim; iv++) { @@ -129,7 +132,7 @@ Bool_t multCalibrator::Calibrate() Double_t multCalibrator::GetRawMax(TH1* histo) { - //This function gets the max X value (right edge) which is filled. + // This function gets the max X value (right edge) which is filled. for (Int_t ii = histo->GetNbinsX(); ii > 0; ii--) { if (histo->GetBinContent(ii) < 1e-10) return histo->GetBinLowEdge(ii + 1); @@ -139,24 +142,24 @@ Double_t multCalibrator::GetRawMax(TH1* histo) Double_t multCalibrator::GetBoundaryForPercentile(TH1* histo, Double_t lPercentileRequested, Double_t& lPrecisionEstimate) { - //This function returns the boundary for a specific percentile. - //It uses a linear interpolation in an attempt to get more precision - //than the binning of the histogram used for quantiling. + // This function returns the boundary for a specific percentile. + // It uses a linear interpolation in an attempt to get more precision + // than the binning of the histogram used for quantiling. // - //It also estimates a certain level of precision of the procedure - //by explicitly comparing the bin content of the bins around the boundary - //with the entire cross section, effectively reporting back a percentage - //that corresponds to those bins. If this percentage is O(percentile bin - //width requested), then the user should worry and we print out a warning. + // It also estimates a certain level of precision of the procedure + // by explicitly comparing the bin content of the bins around the boundary + // with the entire cross section, effectively reporting back a percentage + // that corresponds to those bins. If this percentage is O(percentile bin + // width requested), then the user should worry and we print out a warning. const Double_t lPrecisionConstant = 2.0; Double_t lRawMax = GetRawMax(histo); if (lPercentileRequested < 1e-7) - return lRawMax; //safeguard + return lRawMax; // safeguard if (lPercentileRequested > 100 - 1e-7) - return 0.0; //safeguard + return 0.0; // safeguard Double_t lReturnValue = 0.0; Double_t lPercentile = 100.0 - lPercentileRequested; @@ -182,7 +185,7 @@ Double_t multCalibrator::GetBoundaryForPercentile(TH1* histo, Double_t lPercenti for (Long_t ibin = lFirstBin; ibin < lNBins; ibin++) { lCount += histo->GetBinContent(ibin); if (lCount >= lCountDesired) { - //Found bin I am looking for! + // Found bin I am looking for! Double_t lWidth = histo->GetBinWidth(ibin); Double_t lLeftPercentile = 100. * (lCount - histo->GetBinContent(ibin)) / lHadronicTotal; Double_t lRightPercentile = 100. * lCount / lHadronicTotal; @@ -200,12 +203,12 @@ Double_t multCalibrator::GetBoundaryForPercentile(TH1* histo, Double_t lPercenti //________________________________________________________________ void multCalibrator::SetStandardAdaptiveBoundaries() { - //Function to set standard adaptive boundaries - //Typically used in pp, goes to 0.001% binning for highest multiplicity + // Function to set standard adaptive boundaries + // Typically used in pp, goes to 0.001% binning for highest multiplicity lNDesiredBoundaries = 0; lDesiredBoundaries = new Double_t[1100]; lDesiredBoundaries[0] = 100; - //From Low To High Multiplicity + // From Low To High Multiplicity for (Int_t ib = 1; ib < 91; ib++) { lNDesiredBoundaries++; lDesiredBoundaries[lNDesiredBoundaries] = lDesiredBoundaries[lNDesiredBoundaries - 1] - 1.0; @@ -229,12 +232,12 @@ void multCalibrator::SetStandardAdaptiveBoundaries() //________________________________________________________________ void multCalibrator::SetStandardOnePercentBoundaries() { - //Function to set standard adaptive boundaries - //Typically used in pp, goes to 0.001% binning for highest multiplicity + // Function to set standard adaptive boundaries + // Typically used in pp, goes to 0.001% binning for highest multiplicity lNDesiredBoundaries = 101; lDesiredBoundaries = new Double_t[101]; lDesiredBoundaries[0] = 100; - //From Low To High Multiplicity + // From Low To High Multiplicity for (Int_t ib = 1; ib < 101; ib++) lDesiredBoundaries[ib] = lDesiredBoundaries[ib - 1] - 1.0; cout << "Set standard 1%-wide percentile boundaries! Nboundaries: " << lNDesiredBoundaries << endl; @@ -243,10 +246,10 @@ void multCalibrator::SetStandardOnePercentBoundaries() //________________________________________________________________ TH1F* multCalibrator::GetCalibrationHistogram(TH1* histoRaw, TString lHistoName) { - //This function returns a calibration histogram + // This function returns a calibration histogram //(pp or p-Pb like, no anchor point considered) - //Reset + recreate precision histogram + // Reset + recreate precision histogram ResetPrecisionHistogram(); // Consistency check @@ -256,10 +259,10 @@ TH1F* multCalibrator::GetCalibrationHistogram(TH1* histoRaw, TString lHistoName) cout << "Last boundary: " << lDesiredBoundaries[0] << endl; } - //Aux vars + // Aux vars Double_t lMiddleOfBins[1000]; for (Long_t lB = 1; lB < lNDesiredBoundaries; lB++) { - //place squarely at the middle to ensure it's all fine + // place squarely at the middle to ensure it's all fine lMiddleOfBins[lB - 1] = 0.5 * (lDesiredBoundaries[lB] + lDesiredBoundaries[lB - 1]); } Double_t lBounds[lNDesiredBoundaries + 1]; @@ -276,7 +279,7 @@ TH1F* multCalibrator::GetCalibrationHistogram(TH1* histoRaw, TString lHistoName) lBounds[lDisplacedii] = GetBoundaryForPercentile(histoRaw, lDesiredBoundaries[ii], lPrecision[ii]); TString lPrecisionString = "(Precision OK)"; if (ii != 0 && ii != lNDesiredBoundaries - 1) { - //check precision, please + // check precision, please if (lPrecision[ii] / TMath::Abs(lDesiredBoundaries[ii + 1] - lDesiredBoundaries[ii]) > fkPrecisionWarningThreshold) lPrecisionString = "(WARNING: BINNING MAY LEAD TO IMPRECISION!)"; if (lPrecision[ii] / TMath::Abs(lDesiredBoundaries[ii - 1] - lDesiredBoundaries[ii]) > fkPrecisionWarningThreshold) @@ -302,8 +305,8 @@ void multCalibrator::ResetPrecisionHistogram() delete fPrecisionHistogram; fPrecisionHistogram = 0x0; } - if (lNDesiredBoundaries > 0) { //only if initialized - //invert boundaries, please + if (lNDesiredBoundaries > 0) { // only if initialized + // invert boundaries, please Double_t lInverseDesiredBoundaries[1100]; for (Int_t ii = 0; ii < lNDesiredBoundaries; ii++) { lInverseDesiredBoundaries[ii] = lDesiredBoundaries[lNDesiredBoundaries - (ii + 1)]; diff --git a/Common/Tools/Multiplicity/multCalibrator.h b/Common/Tools/Multiplicity/multCalibrator.h index b5c618bdc3d..1ad8839a1f1 100644 --- a/Common/Tools/Multiplicity/multCalibrator.h +++ b/Common/Tools/Multiplicity/multCalibrator.h @@ -16,33 +16,33 @@ // - victor.gonzalez@cern.ch // - david.dobrigkeit.chinellato@cern.ch // -#ifndef MULTCALIBRATOR_H -#define MULTCALIBRATOR_H +#ifndef COMMON_TOOLS_MULTIPLICITY_MULTCALIBRATOR_H_ +#define COMMON_TOOLS_MULTIPLICITY_MULTCALIBRATOR_H_ + +#include +#include #include #include -#include "TNamed.h" -#include "TH1D.h" - class multCalibrator : public TNamed { public: - //Constructors/Destructor + // Constructors/Destructor multCalibrator(); - multCalibrator(const char* name, const char* title = "Multiplicity Calibration Class"); + explicit multCalibrator(const char* name, const char* title = "Multiplicity Calibration Class"); ~multCalibrator(); - //void Print(Option_t *option="") const; + // void Print(Option_t *option="") const; //_________________________________________________________________________ - //Interface: steering functions to be used in calibration macro + // Interface: steering functions to be used in calibration macro - //Set Filenames + // Set Filenames void SetInputFile(TString lFile) { fInputFileName = lFile.Data(); } void SetOutputFile(TString lFile) { fOutputFileName = lFile.Data(); } - //Set Boundaries to find + // Set Boundaries to find void SetBoundaries(Long_t lNB, Double_t* lB) { if (lNB < 2 || lNB > 1e+6) { @@ -56,24 +56,24 @@ class multCalibrator : public TNamed void SetAnchorPointRaw(Float_t lRaw) { fAnchorPointValue = lRaw; } void SetAnchorPointPercentage(Float_t lPer) { fAnchorPointPercentage = lPer; } - void SetStandardAdaptiveBoundaries(); //standard adaptive (pp-like) - void SetStandardOnePercentBoundaries(); //standard 1% (Pb-Pb like) + void SetStandardAdaptiveBoundaries(); // standard adaptive (pp-like) + void SetStandardOnePercentBoundaries(); // standard 1% (Pb-Pb like) - //Master Function in this Class: To be called once filenames are set + // Master Function in this Class: To be called once filenames are set Bool_t Calibrate(); - //Aux function. Keep public, accessible outside as rather useful utility + // Aux function. Keep public, accessible outside as rather useful utility TH1F* GetCalibrationHistogram(TH1* histoRaw, TString lHistoName = "hCalib"); - //Auxiliary functions + // Auxiliary functions Double_t GetRawMax(TH1* histo); Double_t GetBoundaryForPercentile(TH1* histo, Double_t lPercentileRequested, Double_t& lPrecisionEstimate); - //Precision bookkeeping - TH1D* GetPrecisionHistogram() { return fPrecisionHistogram; }; //gets precision histogram from current object - void ResetPrecisionHistogram(); //Reset precision histogram, if it exists + // Precision bookkeeping + TH1D* GetPrecisionHistogram() { return fPrecisionHistogram; } // gets precision histogram from current object + void ResetPrecisionHistogram(); // Reset precision histogram, if it exists - //Aliases for centrality estimators + // Aliases for centrality estimators enum fCentEstim { kCentRawV0M = 0, kCentRawT0M, @@ -89,7 +89,7 @@ class multCalibrator : public TNamed static const TString fCentEstimName[kNCentEstim]; //! name (internal) private: - //Calibration Boundaries to locate + // Calibration Boundaries to locate Double_t* lDesiredBoundaries; Long_t lNDesiredBoundaries; Double_t fkPrecisionWarningThreshold; @@ -105,11 +105,11 @@ class multCalibrator : public TNamed // TList object for storing histograms TList* fCalibHists; - TH1D* fPrecisionHistogram; //for bookkeeping of precision report + TH1D* fPrecisionHistogram; // for bookkeeping of precision report ClassDef(multCalibrator, 1); //(this classdef is only for bookkeeping, class will not usually // be streamed according to current workflow except in very specific // tests!) }; -#endif +#endif // COMMON_TOOLS_MULTIPLICITY_MULTCALIBRATOR_H_ diff --git a/Common/Tools/Multiplicity/multGlauberNBDFitter.cxx b/Common/Tools/Multiplicity/multGlauberNBDFitter.cxx index a765db72448..dbdefd874d4 100644 --- a/Common/Tools/Multiplicity/multGlauberNBDFitter.cxx +++ b/Common/Tools/Multiplicity/multGlauberNBDFitter.cxx @@ -26,13 +26,16 @@ **********************************************/ #include "multGlauberNBDFitter.h" -#include "TList.h" -#include "TFile.h" -#include "TF1.h" -#include "TStopwatch.h" -#include "TVirtualFitter.h" -#include "TProfile.h" -#include "TFitResult.h" + +#include +#include +#include +#include +#include +#include +#include + +#include // FIXME using namespace std; @@ -42,6 +45,7 @@ multGlauberNBDFitter::multGlauberNBDFitter() : TNamed(), fNBD(0x0), fhNanc(0x0), fhNpNc(0x0), + fhV0M(0x0), ffChanged(kTRUE), fCurrentf(-1), fAncestorMode(2), @@ -63,14 +67,14 @@ multGlauberNBDFitter::multGlauberNBDFitter() : TNamed(), fNcoll = new Double_t[fMaxNpNcPairs]; fContent = new Long_t[fMaxNpNcPairs]; - //Ancestor histo + // Ancestor histo fhNanc = new TH1D("fhNanc", "", 1000, -0.5, 999.5); - //NBD + // NBD fNBD = new TF1("fNBD", "ROOT::Math::negative_binomial_pdf(x,[0],[1])", 0, 45000); fNBD->SetNpx(45000); - //master function + // master function fGlauberNBD = new TF1("fGlauberNBD", this, &multGlauberNBDFitter::ProbDistrib, 0, 50000, 4, "multGlauberNBDFitter", "ProbDistrib"); fGlauberNBD->SetParameter(0, fMu); @@ -89,6 +93,7 @@ multGlauberNBDFitter::multGlauberNBDFitter(const char* name, const char* title) fNBD(0x0), fhNanc(0x0), fhNpNc(0x0), + fhV0M(0x0), ffChanged(kTRUE), fCurrentf(-1), fAncestorMode(2), @@ -105,19 +110,19 @@ multGlauberNBDFitter::multGlauberNBDFitter(const char* name, const char* title) fFitOptions("R0"), fFitNpx(5000) { - //Named constructor + // Named constructor fNpart = new Double_t[fMaxNpNcPairs]; fNcoll = new Double_t[fMaxNpNcPairs]; fContent = new Long_t[fMaxNpNcPairs]; - //Ancestor histo - //fhNanc = new TH1D("fhNanc", "", fAncestorMode==2?10000:1000, -0.5, 999.5); + // Ancestor histo + // fhNanc = new TH1D("fhNanc", "", fAncestorMode==2?10000:1000, -0.5, 999.5); - //NBD + // NBD fNBD = new TF1("fNBD", "ROOT::Math::negative_binomial_pdf(x,[0],[1])", 0, 45000); fNBD->SetNpx(45000); - //master function + // master function fGlauberNBD = new TF1("fGlauberNBD", this, &multGlauberNBDFitter::ProbDistrib, 0, 50000, 5, "multGlauberNBDFitter", "ProbDistrib"); fGlauberNBD->SetParameter(0, fMu); @@ -157,18 +162,18 @@ multGlauberNBDFitter::~multGlauberNBDFitter() //______________________________________________________ Double_t multGlauberNBDFitter::ProbDistrib(Double_t* x, Double_t* par) -//Master fitter function +// Master fitter function { Double_t lMultValue = x[0]; Double_t lProbability = 0.0; ffChanged = kTRUE; const Double_t lAlmost0 = 1.e-13; - //Comment this line in order to make the code evaluate Nancestor all the time + // Comment this line in order to make the code evaluate Nancestor all the time if (TMath::Abs(fCurrentf - par[2]) < lAlmost0) ffChanged = kFALSE; //______________________________________________________ - //Recalculate the ancestor distribution in case f changed + // Recalculate the ancestor distribution in case f changed if (ffChanged) { fCurrentf = par[2]; fhNanc->Reset(); @@ -192,12 +197,12 @@ Double_t multGlauberNBDFitter::ProbDistrib(Double_t* x, Double_t* par) fhNanc->Scale(1. / fhNanc->Integral()); } //______________________________________________________ - //Actually evaluate function + // Actually evaluate function Int_t lStartBin = fhNanc->FindBin(0.0) + 1; for (Long_t iNanc = lStartBin; iNanc < fhNanc->GetNbinsX() + 1; iNanc++) { Double_t lNancestors = fhNanc->GetBinCenter(iNanc); Double_t lNancestorCount = fhNanc->GetBinContent(iNanc); - //if(lNancestorCount<1e-12&&lNancestors>10) break; + // if(lNancestorCount<1e-12&&lNancestors>10) break; // allow for variable mu in case requested Double_t lThisMu = (((Double_t)lNancestors)) * (par[0] + par[4] * lNancestors); @@ -219,7 +224,7 @@ Bool_t multGlauberNBDFitter::SetNpartNcollCorrelation(TH2* hNpNc) { Bool_t lReturnValue = kTRUE; if (hNpNc) { - fhNpNc = (TH2*)hNpNc; + fhNpNc = reinterpret_cast(hNpNc); } else { lReturnValue = kFALSE; } @@ -231,7 +236,7 @@ Bool_t multGlauberNBDFitter::SetInputV0M(TH1* hV0M) { Bool_t lReturnValue = kTRUE; if (hV0M) { - fhV0M = (TH1*)hV0M; + fhV0M = reinterpret_cast(hV0M); } else { lReturnValue = kFALSE; } @@ -279,7 +284,7 @@ void multGlauberNBDFitter::InitAncestor() Bool_t multGlauberNBDFitter::DoFit() { InitAncestor(); - //Try very hard, please + // Try very hard, please TVirtualFitter::SetMaxIterations(5000000); if (!InitializeNpNc()) { cout << "---> Initialization of Npart x Ncoll correlation info failed!" << endl; @@ -317,12 +322,12 @@ Bool_t multGlauberNBDFitter::DoFit() //________________________________________________________________ Bool_t multGlauberNBDFitter::InitializeNpNc() { - //This function initializes fhNpNc - //Warning: X == Npart, Y == Ncoll + // This function initializes fhNpNc + // Warning: X == Npart, Y == Ncoll Bool_t lReturnValue = kFALSE; if (fhNpNc) { fNNpNcPairs = 0; - //Sweep all allowed values of Npart, Ncoll; find counters + // Sweep all allowed values of Npart, Ncoll; find counters for (int xbin = 1; xbin < 500; xbin++) { for (int ybin = 1; ybin < 3000; ybin++) { if (fhNpNc->GetBinContent(fhNpNc->FindBin(xbin, ybin)) != 0) { @@ -345,12 +350,12 @@ Bool_t multGlauberNBDFitter::InitializeNpNc() //________________________________________________________________ Double_t multGlauberNBDFitter::ContinuousNBD(Double_t n, Double_t mu, Double_t k) { - //Adaptation of the negative binomial distribution - //for non-integer arguments: analytical continuation + // Adaptation of the negative binomial distribution + // for non-integer arguments: analytical continuation // - //This function would actually also be fine with integers; - //in fact it is equivalent to that if 'n' is typecast as - //an integer prior to use + // This function would actually also be fine with integers; + // in fact it is equivalent to that if 'n' is typecast as + // an integer prior to use Double_t F; Double_t f; @@ -390,10 +395,10 @@ void multGlauberNBDFitter::CalculateAvNpNc(TProfile* lNPartProf, TProfile* lNCol cout << "Glauber NBD norm ..........: " << fnorm << endl; cout << "Glauber NBD dmu/dNanc .....: " << fdMu << endl; - //2-fold nested loop: - // + looping over all Nancestor combinations - // + looping over all possible final multiplicities - // ^---> final product already multiplicity-binned + // 2-fold nested loop: + // + looping over all Nancestor combinations + // + looping over all possible final multiplicities + // ^---> final product already multiplicity-binned //______________________________________________________ if (lLoRange < -1 && lHiRange < -1) { diff --git a/Common/Tools/Multiplicity/multGlauberNBDFitter.h b/Common/Tools/Multiplicity/multGlauberNBDFitter.h index 42d5cab046f..951be39bd50 100644 --- a/Common/Tools/Multiplicity/multGlauberNBDFitter.h +++ b/Common/Tools/Multiplicity/multGlauberNBDFitter.h @@ -9,59 +9,60 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. // -#ifndef MULTGLAUBERNBDFITTER_H -#define MULTGLAUBERNBDFITTER_H +#ifndef COMMON_TOOLS_MULTIPLICITY_MULTGLAUBERNBDFITTER_H_ +#define COMMON_TOOLS_MULTIPLICITY_MULTGLAUBERNBDFITTER_H_ + +#include +#include +#include +#include +#include +#include #include -#include "TNamed.h" -#include "TF1.h" -#include "TH1.h" -#include "TH1D.h" -#include "TH2.h" -#include "TProfile.h" class multGlauberNBDFitter : public TNamed { public: - //basic functionality + // basic functionality multGlauberNBDFitter(); - multGlauberNBDFitter(const char* name, const char* title = "Glauber+NBD fitter"); + explicit multGlauberNBDFitter(const char* name, const char* title = "Glauber+NBD fitter"); ~multGlauberNBDFitter(); - //Master fitter function + // Master fitter function Double_t ProbDistrib(Double_t* x, Double_t* par); void InitAncestor(); - //Do Fit: where everything happens + // Do Fit: where everything happens Bool_t DoFit(); - //Set input characteristics: the 2D plot with Npart, Nanc + // Set input characteristics: the 2D plot with Npart, Nanc Bool_t SetNpartNcollCorrelation(TH2* hNpNc); - //Set main input to be fitted (the V0M distribution) + // Set main input to be fitted (the V0M distribution) Bool_t SetInputV0M(TH1* hV0M); - //Interface to get funtions if asked to + // Interface to get funtions if asked to TF1* GetNBD(); TF1* GetGlauberNBD(); - //Helper + // Helper Bool_t InitializeNpNc(); - //Interface for debug + // Interface for debug void SetAncestorMode(Int_t lAncMode = 0) { fAncestorMode = lAncMode; } Int_t GetAncestorMode() { return fAncestorMode; } TH1D* GetAncestorHistogram() { return fhNanc; } - //Interface to set vals + // Interface to set vals void SetMu(Double_t lVal) { fMu = lVal; } void Setk(Double_t lVal) { fk = lVal; } void Setf(Double_t lVal) { ff = lVal; } void SetNorm(Double_t lVal) { fnorm = lVal; } - //Interface to get vals + // Interface to get vals Double_t GetMu() { return fMu; } Double_t Getk() { return fk; } Double_t Getf() { return ff; } @@ -71,41 +72,41 @@ class multGlauberNBDFitter : public TNamed void SetFitOptions(TString lOpt); void SetFitNpx(Long_t lNpx); - //For ancestor mode 2 + // For ancestor mode 2 Double_t ContinuousNBD(Double_t n, Double_t mu, Double_t k); - //For estimating Npart, Ncoll in multiplicity bins + // For estimating Npart, Ncoll in multiplicity bins void CalculateAvNpNc(TProfile* lNPartProf, TProfile* lNCollProf, TH2F* lNPart2DPlot, TH2F* lNColl2DPlot, TH1F* hPercentileMap, Double_t lLoRange = -1, Double_t lHiRange = -1); - //void Print(Option_t *option="") const; + // void Print(Option_t *option="") const; private: - //This function serves as the (analytical) NBD + // This function serves as the (analytical) NBD TF1* fNBD; - //This function is the key fitting function + // This function is the key fitting function TF1* fGlauberNBD; - //Reference histo - TH1D* fhNanc; //basic ancestor distribution - TH2* fhNpNc; //correlation between Npart and Ncoll - TH1* fhV0M; //basic ancestor distribution + // Reference histo + TH1D* fhNanc; // basic ancestor distribution + TH2* fhNpNc; // correlation between Npart and Ncoll + TH1* fhV0M; // basic ancestor distribution - //Fitting utilities + // Fitting utilities Bool_t ffChanged; Double_t fCurrentf; - //0: truncation, 1: rounding, 2: analytical continuation + // 0: truncation, 1: rounding, 2: analytical continuation Int_t fAncestorMode; - //Buffer for (Npart, Ncoll) pairs in memory + // Buffer for (Npart, Ncoll) pairs in memory Double_t* fNpart; Double_t* fNcoll; Long_t* fContent; - Long_t fNNpNcPairs; //number of pairs to use + Long_t fNNpNcPairs; // number of pairs to use Long_t fMaxNpNcPairs; - //The actual output: mu, k, f, norm + // The actual output: mu, k, f, norm Double_t fMu; Double_t fdMu; // variable mu option Double_t fk; @@ -117,4 +118,4 @@ class multGlauberNBDFitter : public TNamed ClassDef(multGlauberNBDFitter, 1); }; -#endif +#endif // COMMON_TOOLS_MULTIPLICITY_MULTGLAUBERNBDFITTER_H_ diff --git a/Common/Tools/Multiplicity/multMCCalibrator.cxx b/Common/Tools/Multiplicity/multMCCalibrator.cxx index 5b490daf77d..7e93e9b023e 100644 --- a/Common/Tools/Multiplicity/multMCCalibrator.cxx +++ b/Common/Tools/Multiplicity/multMCCalibrator.cxx @@ -16,19 +16,23 @@ // - victor.gonzalez@cern.ch // - david.dobrigkeit.chinellato@cern.ch // -#include "TList.h" -#include "TDirectory.h" -#include "TFile.h" -#include "TF1.h" -#include "TH1F.h" -#include "TH1D.h" -#include "TProfile.h" -#include "TStopwatch.h" -#include "TArrayL64.h" -#include "TArrayF.h" -#include "multCalibrator.h" #include "multMCCalibrator.h" +#include "multCalibrator.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include // FIXME + using namespace std; multMCCalibrator::multMCCalibrator() : TNamed(), @@ -79,22 +83,22 @@ Bool_t multMCCalibrator::Calibrate() cout << " * Output File............: " << fOutputFileName.Data() << endl; cout << endl; - //Opening data and simulation file... + // Opening data and simulation file... TFile* fileData = new TFile(fDataInputFileName.Data(), "READ"); TFile* fileSim = new TFile(fSimInputFileName.Data(), "READ"); - //Step 1: verify if input file contains desired histograms + // Step 1: verify if input file contains desired histograms TProfile* hProfData[multCalibrator::kNCentEstim]; TProfile* hProfSim[multCalibrator::kNCentEstim]; cout << " * acquiring input profiles..." << endl; for (Int_t iv = 0; iv < multCalibrator::kNCentEstim; iv++) { - hProfData[iv] = (TProfile*)fileData->Get(Form("multiplicity-qa/multiplicityQa/hProf%s", multCalibrator::fCentEstimName[iv].Data())); + hProfData[iv] = reinterpret_cast(fileData->Get(Form("multiplicity-qa/multiplicityQa/hProf%s", multCalibrator::fCentEstimName[iv].Data()))); if (!hProfData[iv]) { cout << Form("Data file does not contain histogram h%s, which is necessary for calibration!", multCalibrator::fCentEstimName[iv].Data()) << endl; return kFALSE; } hProfData[iv]->SetName(Form("hProfData_%s", multCalibrator::fCentEstimName[iv].Data())); - hProfSim[iv] = (TProfile*)fileSim->Get(Form("multiplicity-qa/multiplicityQa/hProf%s", multCalibrator::fCentEstimName[iv].Data())); + hProfSim[iv] = reinterpret_cast(fileSim->Get(Form("multiplicity-qa/multiplicityQa/hProf%s", multCalibrator::fCentEstimName[iv].Data()))); if (!hProfSim[iv]) { cout << Form("Sim file does not contain histogram h%s, which is necessary for calibration!", multCalibrator::fCentEstimName[iv].Data()) << endl; return kFALSE; @@ -135,14 +139,14 @@ Bool_t multMCCalibrator::Calibrate() //________________________________________________________________ TF1* multMCCalibrator::GetFit(TProfile* fProf, Bool_t lQuadratic) { - TString fFormula = "[0]*x"; //old/deprecated (avoid if possible, please) + TString fFormula = "[0]*x"; // old/deprecated (avoid if possible, please) if (lQuadratic) fFormula = "[0]+[1]*TMath::Power(x,[2])"; // Function to return fit function to profile for posterior inversion TF1* fit = new TF1(Form("%s_fit", fProf->GetName()), fFormula.Data(), fProf->GetBinLowEdge(1), fProf->GetBinLowEdge(fProf->GetNbinsX())); - //Guesstimate inclination from data points in profile + // Guesstimate inclination from data points in profile Double_t lMeanInclination = 0; Long_t lInclinationCount = 0; for (Int_t ii = 2; ii < fProf->GetNbinsX(); ii++) { @@ -158,7 +162,7 @@ TF1* multMCCalibrator::GetFit(TProfile* fProf, Bool_t lQuadratic) if (lInclinationCount >= 5) lMeanInclination /= lInclinationCount; - //Give it a little nudge, cause life's hard + // Give it a little nudge, cause life's hard fit->SetParameter(0, 0.0); fit->SetParameter(1, lMeanInclination); fit->SetParameter(2, 1.0); diff --git a/Common/Tools/Multiplicity/multMCCalibrator.h b/Common/Tools/Multiplicity/multMCCalibrator.h index f88bddf98c3..7d355146728 100644 --- a/Common/Tools/Multiplicity/multMCCalibrator.h +++ b/Common/Tools/Multiplicity/multMCCalibrator.h @@ -16,34 +16,35 @@ // - victor.gonzalez@cern.ch // - david.dobrigkeit.chinellato@cern.ch // -#ifndef MULTMCCALIBRATOR_H -#define MULTMCCALIBRATOR_H +#ifndef COMMON_TOOLS_MULTIPLICITY_MULTMCCALIBRATOR_H_ +#define COMMON_TOOLS_MULTIPLICITY_MULTMCCALIBRATOR_H_ -#include -#include "TNamed.h" -#include "TF1.h" -#include "TH1D.h" -#include "TProfile.h" +#include +#include +#include +#include + +#include // FIXME #include class multMCCalibrator : public TNamed { public: - //Constructors/Destructor + // Constructors/Destructor multMCCalibrator(); - multMCCalibrator(const char* name, const char* title = "MC Multiplicity Calibration Class"); + explicit multMCCalibrator(const char* name, const char* title = "MC Multiplicity Calibration Class"); ~multMCCalibrator(); //_________________________________________________________________________ - //Interface: steering functions to be used in calibration macro + // Interface: steering functions to be used in calibration macro - //Set Filenames + // Set Filenames void SetDataInputFile(TString lFile) { fDataInputFileName = lFile.Data(); } void SetSimInputFile(TString lFile) { fSimInputFileName = lFile.Data(); } void SetOutputFile(TString lFile) { fOutputFileName = lFile.Data(); } - //Master Function in this Class: To be called once filenames are set + // Master Function in this Class: To be called once filenames are set Bool_t Calibrate(); TF1* GetFit(TProfile* fProf, Bool_t lQuadratic = kTRUE); @@ -63,4 +64,4 @@ class multMCCalibrator : public TNamed // be streamed according to current workflow except in very specific // tests!) }; -#endif +#endif // COMMON_TOOLS_MULTIPLICITY_MULTMCCALIBRATOR_H_ diff --git a/Common/Tools/PID/handleParamBase.h b/Common/Tools/PID/handleParamBase.h index 01c2a66ab8b..53938f26b7f 100644 --- a/Common/Tools/PID/handleParamBase.h +++ b/Common/Tools/PID/handleParamBase.h @@ -19,12 +19,15 @@ #ifndef COMMON_TOOLS_PID_HANDLEPARAMBASE_H_ #define COMMON_TOOLS_PID_HANDLEPARAMBASE_H_ +#include +#include + +#include + +#include + #include #include -#include "CCDB/CcdbApi.h" -#include -#include "Framework/Logger.h" -#include "TFile.h" // Global executable arguments namespace bpo = boost::program_options; @@ -79,9 +82,9 @@ void setStandardOpt(bpo::options_description& options) } template -T* retrieveFromCCDB(const std::string path, +T* retrieveFromCCDB(const std::string& path, const int64_t timestamp, - std::map metadata) + const std::map& metadata) { std::map headers; LOG(info) << "Object " << path << " for timestamp " << timestamp << " -> " << timeStampToHReadble(timestamp); @@ -99,7 +102,7 @@ T* retrieveFromCCDB(const std::string path, } template -T* retrieveFromCCDB(const std::string path, +T* retrieveFromCCDB(const std::string& path, const int64_t timestamp) { std::map metadata; diff --git a/Common/Tools/PID/handleParamTPCResponse.cxx b/Common/Tools/PID/handleParamTPCResponse.cxx index 64741503fae..242503f16e1 100644 --- a/Common/Tools/PID/handleParamTPCResponse.cxx +++ b/Common/Tools/PID/handleParamTPCResponse.cxx @@ -48,7 +48,7 @@ bool initOptionsAndParse(bpo::options_description& options, int argc, char* argv "paramMultNormalization", bpo::value()->default_value(11000.), "Multiplicity Normalization")( "paramnClNormalization", bpo::value()->default_value(152.), "Maximum nClusters for normalisation (159 for run 2, 152 for run 3)")( "useDefaultParam", bpo::value()->default_value(true), "Use default sigma parametrisation")( - "mode", bpo::value()->default_value(""), "Running mode ('read' from file, 'write' to file, 'pull' from CCDB, 'push' to CCDB)")( + "mode", bpo::value()->default_value(""), "Running mode ('read' from file, 'write' to file, 'pull' from CCDB, 'push' to CCDB)")( "help,h", "Produce help message."); setStandardOpt(options); try { diff --git a/Common/Tools/StandardCCDBLoader.h b/Common/Tools/StandardCCDBLoader.h index 6ba4c9be9a1..2134fec2666 100644 --- a/Common/Tools/StandardCCDBLoader.h +++ b/Common/Tools/StandardCCDBLoader.h @@ -16,12 +16,18 @@ #ifndef COMMON_TOOLS_STANDARDCCDBLOADER_H_ #define COMMON_TOOLS_STANDARDCCDBLOADER_H_ -#include -#include -#include -#include +#include "CCDB/BasicCCDBManager.h" +#include "DataFormatsCalibration/MeanVertexObject.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" #include "Framework/AnalysisDataModel.h" +#include +#include +#include +#include + //__________________________________________ // Standard class to load stuff // such as matLUT, B and mean Vertex diff --git a/Common/Tools/TrackPropagationModule.h b/Common/Tools/TrackPropagationModule.h index d8cc3fd4f28..a08ec358993 100644 --- a/Common/Tools/TrackPropagationModule.h +++ b/Common/Tools/TrackPropagationModule.h @@ -16,16 +16,31 @@ #ifndef COMMON_TOOLS_TRACKPROPAGATIONMODULE_H_ #define COMMON_TOOLS_TRACKPROPAGATIONMODULE_H_ -#include -#include -#include +#include "Common/Core/TableHelper.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/Tools/TrackTuner.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + #include +#include +#include +#include #include -#include "Framework/AnalysisDataModel.h" -#include "Framework/Configurable.h" -#include "Framework/HistogramSpec.h" -#include "Common/Tools/TrackTuner.h" -#include "TableHelper.h" //__________________________________________ // track propagation module @@ -81,17 +96,16 @@ class TrackPropagationModule // pointers to objs needed for operation std::shared_ptr trackTunedTracks; - TrackTuner trackTunerObj; // Running variables - std::array mDcaInfo; + std::array mDcaInfo{}; o2::dataformats::DCA mDcaInfoCov; o2::dataformats::VertexBase mVtx; o2::track::TrackParametrization mTrackPar; o2::track::TrackParametrizationWithError mTrackParCov; template - void init(TConfigurableGroup const& cGroup, THistoRegistry& registry, TInitContext& initContext) + void init(TConfigurableGroup const& cGroup, TrackTuner& trackTunerObj, THistoRegistry& registry, TInitContext& initContext) { // Checking if the tables are requested in the workflow and enabling them fillTracks = isTableRequiredInWorkflow(initContext, "Tracks"); @@ -154,7 +168,7 @@ class TrackPropagationModule } template - void fillTrackTables(TConfigurableGroup const& cGroup, TCCDBLoader const& ccdbLoader, TCollisions const& collisions, TTracks const& tracks, TOutputGroup& cursors, THistoRegistry& registry) + void fillTrackTables(TConfigurableGroup const& cGroup, TrackTuner& trackTunerObj, TCCDBLoader const& ccdbLoader, TCollisions const& collisions, TTracks const& tracks, TOutputGroup& cursors, THistoRegistry& registry) { if (!fillTracks) { return; // suppress everything diff --git a/Common/Tools/TrackTuner.h b/Common/Tools/TrackTuner.h index 26937eb9131..60cf377a410 100644 --- a/Common/Tools/TrackTuner.h +++ b/Common/Tools/TrackTuner.h @@ -18,34 +18,37 @@ #ifndef COMMON_TOOLS_TRACKTUNER_H_ #define COMMON_TOOLS_TRACKTUNER_H_ +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include #include #include +#include #include #include #include -#include -#include -#include - -#include "CCDB/BasicCCDBManager.h" -#include "CCDB/CcdbApi.h" -#include "CommonConstants/GeomConstants.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "CommonUtils/NameConf.h" -#include "DataFormatsCalibration/MeanVertexObject.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/Configurable.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "Framework/RunningWorkflowInfo.h" -#include "ReconstructionDataFormats/DCA.h" -#include "ReconstructionDataFormats/Track.h" -#include namespace o2::aod { @@ -246,7 +249,7 @@ struct TrackTuner : o2::framework::ConfigurableGroup { LOG(info) << "[TrackTuner]"; LOG(info) << "[TrackTuner] >>> String slices:"; - for (std::string& s : slices) + for (const std::string& s : slices) LOG(info) << "[TrackTuner] " << s; /// check if the number of input parameters is correct @@ -260,7 +263,7 @@ struct TrackTuner : o2::framework::ConfigurableGroup { /// lambda expression to search for the parameter value (as string) in the configuration string auto getValueString = [&](uint8_t iPar) { /// this allows to search the parameter configuration even if they are not written in order - auto it = std::find_if(slices.begin(), slices.end(), [&](std::string s) { return s.find(mapParNames[iPar]) != std::string::npos; }); + auto it = std::find_if(slices.begin(), slices.end(), [&](const std::string& s) { return s.find(mapParNames[iPar]) != std::string::npos; }); if (it == std::end(slices)) { // parameter not found LOG(fatal) << "\"" << mapParNames[iPar] << "\" not found in the configuration string"; @@ -274,7 +277,7 @@ struct TrackTuner : o2::framework::ConfigurableGroup { }; /// further lambda expression to handle bool initialization - auto setBoolFromString = [=](bool& b, std::string str) { + auto setBoolFromString = [=](bool& b, const std::string& str) { if (!str.compare("1") || str.find("true") != std::string::npos || str.find("True") != std::string::npos || str.find("TRUE") != std::string::npos) { b = true; } else if (!str.compare("0") || str.find("false") != std::string::npos || str.find("False") != std::string::npos || str.find("FALSE") != std::string::npos) { diff --git a/Common/Tools/trackSelectionRequest.h b/Common/Tools/trackSelectionRequest.h index 123392611f0..a056eaaaed0 100644 --- a/Common/Tools/trackSelectionRequest.h +++ b/Common/Tools/trackSelectionRequest.h @@ -21,18 +21,20 @@ // Because of this, it is particularly important that the cuts in this object // in an analysis! -#ifndef TRACKSELECTIONREQUEST_H -#define TRACKSELECTIONREQUEST_H +#ifndef COMMON_TOOLS_TRACKSELECTIONREQUEST_H_ +#define COMMON_TOOLS_TRACKSELECTIONREQUEST_H_ -#include -#include #include +#include + +#include + class trackSelectionRequest { public: trackSelectionRequest() - : trackPhysicsType{0}, minPt{0.0}, maxPt{1e+6}, minEta{-100}, maxEta{+100}, maxDCAz{1e+6}, maxDCAxyPtDep{1e+6}, requireTPC{false}, minTPCclusters{-1}, minTPCcrossedrows{-1}, minTPCcrossedrowsoverfindable{0.0}, requireITS{false}, minITSclusters{-1}, maxITSChi2percluster{1e+6} + : trackPhysicsType{0}, minPt{0.0}, maxPt{1e+6}, minEta{-100}, maxEta{+100}, maxDCAz{1e+6}, maxDCAxyPtDep{1e+6}, requireTPC{false}, minTPCclusters{-1}, minTPCcrossedrows{-1}, minTPCcrossedrowsoverfindable{0.0}, maxTPCFractionSharedCls{0.0}, requireITS{false}, minITSclusters{-1}, maxITSChi2percluster{1e+6} { // constructor } @@ -88,7 +90,7 @@ class trackSelectionRequest if (lTrack.eta() > maxEta) return false; // DCA to PV - if (fabs(lTrack.dcaXY()) < maxDCAz) + if (std::fabs(lTrack.dcaXY()) < maxDCAz) return false; // TracksExtra-based if (lTrack.hasTPC() == false && requireTPC) @@ -163,4 +165,4 @@ class trackSelectionRequest std::ostream& operator<<(std::ostream& os, trackSelectionRequest const& c); -#endif // TRACKSELECTIONREQUEST_H +#endif // COMMON_TOOLS_TRACKSELECTIONREQUEST_H_ diff --git a/DPG/Tasks/AOTEvent/CMakeLists.txt b/DPG/Tasks/AOTEvent/CMakeLists.txt index 83503f45254..59e049e6356 100644 --- a/DPG/Tasks/AOTEvent/CMakeLists.txt +++ b/DPG/Tasks/AOTEvent/CMakeLists.txt @@ -44,6 +44,11 @@ o2physics_add_dpl_workflow(rof-occupancy-qa PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::AnalysisCCDB O2::DetectorsBase COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(light-ions-evsel-qa + SOURCES lightIonsEvSelQa.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::AnalysisCCDB O2::DetectorsBase + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(occupancy-vs-dedx-qa SOURCES dEdxVsOccupancyWithTrackQAinfo.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::AnalysisCCDB O2::DetectorsBase diff --git a/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx b/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx index a47d4dc870f..7d23ded67aa 100644 --- a/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx +++ b/DPG/Tasks/AOTEvent/detectorOccupancyQa.cxx @@ -14,39 +14,37 @@ /// /// \author Igor Altsybeev -#include -#include - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Common/DataModel/EventSelection.h" #include "Common/CCDB/EventSelectionParams.h" -#include "CCDB/BasicCCDBManager.h" -#include "Framework/HistogramRegistry.h" -#include "CommonDataFormat/BunchFilling.h" -#include "DataFormatsParameters/GRPLHCIFData.h" -#include "DataFormatsParameters/GRPECSObject.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CommonDataFormat/BunchFilling.h" #include "DataFormatsParameters/AggregatedRunInfo.h" +#include "DataFormatsParameters/GRPECSObject.h" +#include "DataFormatsParameters/GRPLHCIFData.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" #include "TH1F.h" #include "TH2F.h" #include "TH3.h" +#include +#include + using namespace o2; using namespace o2::framework; using namespace o2::aod::evsel; -// using BCsRun2 = soa::Join; using BCsRun3 = soa::Join; -// using ColEvSels = soa::Join; using ColEvSels = soa::Join; -// using FullTracksIU = soa::Join; using FullTracksIU = soa::Join; struct DetectorOccupancyQaTask { @@ -78,7 +76,7 @@ struct DetectorOccupancyQaTask { Configurable confCutPtMaxThisEvent{"PtMaxThisEvent", 100., "pt cut for particles in a current event"}; // o2-linter: disable=name/configurable (temporary fix) Configurable confCutEtaMinTracksThisEvent{"EtaMinTracksThisEvent", -0.8, "eta cut for particles in a current event"}; // o2-linter: disable=name/configurable (temporary fix) Configurable confCutEtaMaxTracksThisEvent{"EtaMaxTracksThisEvent", 0.8, "eta cut for particles in a current event"}; // o2-linter: disable=name/configurable (temporary fix) - Configurable confCutMinTPCcls{"MinNumTPCcls", 70, "min number of TPC clusters for a current event"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable confCutMinTPCcls{"MinNumTPCcls", 50, "min number of TPC clusters for a current event"}; // o2-linter: disable=name/configurable (temporary fix) // config for QA histograms Configurable confAddTracksVsFwdHistos{"AddTracksVsFwdHistos", true, "0 - add histograms, 1 - skip"}; // o2-linter: disable=name/configurable (temporary fix) @@ -93,6 +91,20 @@ struct DetectorOccupancyQaTask { Configurable nMaxBcInTFforAnalysis{"nMaxBcInTFforAnalysis", -1, "When to stop taking collisions in TF, if -1: take all collisions"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable confNPhiBins{"nPhiBins", 810, "N phi bits for histograms"}; // o2-linter: disable=name/configurable (temporary fix) + + ConfigurableAxis confAxisPtBinsForPhiStudy{"PtBinsForPhiStudy", {VARIABLE_WIDTH, 0.2, 0.6, 1.0, 2.0, 10}, "pt axis"}; + ConfigurableAxis confAxisOccupForKine{"AxisOccupForKine", {VARIABLE_WIDTH, 0, 500, 1000, 2000, 4000, 6000, 8000, 10000, 20000}, "weighted occupancy"}; + + Configurable confUsePhiAtTPCinnerR{"UsePhiAtTPCinnerR", false, "0 - not use, 1 - use"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable confUseAorCsideForPhiStudy{"UseAorCsideForPhiStudy", -1, "-1 - use full eta range, 0 - A, 1 - C sides"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable confRadiusForPhiCorrection{"RadiusForPhiCorrection", 0.8, "default: inner TPC radius, cm"}; // o2-linter: disable=name/configurable (temporary fix) + + Configurable confApplyGoodITSstavesFlaginEvSel{"ApplyGoodITSstavesFlaginEvSel", 0, "0 - no, 1 - yes"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable confMinITSclsPerTrack{"MinITSclsPerTrack", 5, "should be in 4..7"}; // o2-linter: disable=name/configurable (temporary fix) + + Configurable> confTimeSlicesForPastFutureStudies{"TimeSlicesForPastFutureStudies", {-40, -10, 20, 50, 80}, "Time slices for past/future studies, us"}; + uint64_t minGlobalBC = 0; Service ccdb; HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -260,7 +272,7 @@ struct DetectorOccupancyQaTask { histos.add("track_distr_nITStrThisEv_above_2000/hEta_highOccupInDistantFuture", ";#eta;n tracks", kTH1D, {axisEta}); histos.add("track_distr_nITStrThisEv_above_2000/hEta_highOccupInNeighbourEvents", ";#eta;n tracks", kTH1D, {axisEta}); - const int nPhiBins = 810; // 18*45 + const int nPhiBins = confNPhiBins; // 810=18*45 AxisSpec axisPhi{nPhiBins, 0, TMath::TwoPi(), "#varphi"}; // o2-linter: disable=external-pi (temporary fix) histos.add("track_distr_nITStrThisEv_10_200/hPhi_lowOccupInTPC", ";#varphi;n tracks", kTH1D, {axisPhi}); histos.add("track_distr_nITStrThisEv_10_200/hPhi_highOccupInRecentPast", ";#varphi;n tracks", kTH1D, {axisPhi}); @@ -268,6 +280,18 @@ struct DetectorOccupancyQaTask { histos.add("track_distr_nITStrThisEv_10_200/hPhi_highOccupInDistantFuture", ";#varphi;n tracks", kTH1D, {axisPhi}); histos.add("track_distr_nITStrThisEv_10_200/hPhi_highOccupInNeighbourEvents", ";#varphi;n tracks", kTH1D, {axisPhi}); + histos.add("track_distr_nITStrThisEv_10_200/hPhi_lowOccupInTPC_pos_vs_pt", ";#varphi;n tracks", kTH2D, {axisPhi, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_10_200/hPhi_highOccupInRecentPast_pos_vs_pt", ";#varphi;n tracks", kTH2D, {axisPhi, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_10_200/hPhi_highOccupInCloseFuture_pos_vs_pt", ";#varphi;n tracks", kTH2D, {axisPhi, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_10_200/hPhi_highOccupInDistantFuture_pos_vs_pt", ";#varphi;n tracks", kTH2D, {axisPhi, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_10_200/hPhi_highOccupInNeighbourEvents_pos_vs_pt", ";#varphi;n tracks", kTH2D, {axisPhi, confAxisPtBinsForPhiStudy}); + + histos.add("track_distr_nITStrThisEv_10_200/hPhi_lowOccupInTPC_neg_vs_pt", ";#varphi;n tracks", kTH2D, {axisPhi, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_10_200/hPhi_highOccupInRecentPast_neg_vs_pt", ";#varphi;n tracks", kTH2D, {axisPhi, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_10_200/hPhi_highOccupInCloseFuture_neg_vs_pt", ";#varphi;n tracks", kTH2D, {axisPhi, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_10_200/hPhi_highOccupInDistantFuture_neg_vs_pt", ";#varphi;n tracks", kTH2D, {axisPhi, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_10_200/hPhi_highOccupInNeighbourEvents_neg_vs_pt", ";#varphi;n tracks", kTH2D, {axisPhi, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_above_2000/hPhi_lowOccupInTPC", ";#varphi;n tracks", kTH1D, {axisPhi}); histos.add("track_distr_nITStrThisEv_above_2000/hPhi_highOccupInRecentPast", ";#varphi;n tracks", kTH1D, {axisPhi}); histos.add("track_distr_nITStrThisEv_above_2000/hPhi_highOccupInCloseFuture", ";#varphi;n tracks", kTH1D, {axisPhi}); @@ -290,46 +314,63 @@ struct DetectorOccupancyQaTask { histos.add("track_distr_nITStrThisEv_above_2000/hPt_highOccupInNeighbourEvents", ";p_{T};n tracks", kTH1D, {axisLogPt}); // July 2025: to compare data and MC (pt, eta, phi) - // AxisSpec axisOccupForKine{{0, 500, 1000, 2000, 4000, 6000, 20000}, "weighted occupancy"}; - AxisSpec axisOccupForKine{{0, 500, 1000, 2000, 4000, 6000, 8000, 10000, 20000}, "weighted occupancy"}; - AxisSpec axisPtForKine{{0.2, 0.6, 1.0, 2.0, 10}, "centrality percentile"}; - histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPt_pos", ";p_{T};weighted occupancy", kTH2D, {axisLogPt, axisOccupForKine}); - histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPt_neg", ";p_{T};weighted occupancy", kTH2D, {axisLogPt, axisOccupForKine}); - histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hEta_pos", ";#eta;weighted occupancy", kTH2D, {axisEta, axisOccupForKine}); - histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hEta_neg", ";#eta;weighted occupancy", kTH2D, {axisEta, axisOccupForKine}); - histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPhi_pos", ";#varphi;n tracks", kTH3D, {axisPhi, axisOccupForKine, axisPtForKine}); - histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPhi_neg", ";#varphi;n tracks", kTH3D, {axisPhi, axisOccupForKine, axisPtForKine}); - - histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/PV_hPt_pos", ";p_{T};weighted occupancy", kTH2D, {axisLogPt, axisOccupForKine}); - histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/PV_hPt_neg", ";p_{T};weighted occupancy", kTH2D, {axisLogPt, axisOccupForKine}); - histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/PV_hEta_pos", ";#eta;weighted occupancy", kTH2D, {axisEta, axisOccupForKine}); - histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/PV_hEta_neg", ";#eta;weighted occupancy", kTH2D, {axisEta, axisOccupForKine}); - histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/PV_hPhi_pos", ";#varphi;n tracks", kTH3D, {axisPhi, axisOccupForKine, axisPtForKine}); - histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/PV_hPhi_neg", ";#varphi;n tracks", kTH3D, {axisPhi, axisOccupForKine, axisPtForKine}); - - histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPt_pos", ";p_{T};weighted occupancy", kTH2D, {axisLogPt, axisOccupForKine}); - histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPt_neg", ";p_{T};weighted occupancy", kTH2D, {axisLogPt, axisOccupForKine}); - histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hEta_pos", ";#eta;weighted occupancy", kTH2D, {axisEta, axisOccupForKine}); - histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hEta_neg", ";#eta;weighted occupancy", kTH2D, {axisEta, axisOccupForKine}); - histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPhi_pos", ";#varphi;n tracks", kTH3D, {axisPhi, axisOccupForKine, axisPtForKine}); - histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPhi_neg", ";#varphi;n tracks", kTH3D, {axisPhi, axisOccupForKine, axisPtForKine}); - - histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/PV_hPt_pos", ";p_{T};weighted occupancy", kTH2D, {axisLogPt, axisOccupForKine}); - histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/PV_hPt_neg", ";p_{T};weighted occupancy", kTH2D, {axisLogPt, axisOccupForKine}); - histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/PV_hEta_pos", ";#eta;weighted occupancy", kTH2D, {axisEta, axisOccupForKine}); - histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/PV_hEta_neg", ";#eta;weighted occupancy", kTH2D, {axisEta, axisOccupForKine}); - histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/PV_hPhi_pos", ";#varphi;n tracks", kTH3D, {axisPhi, axisOccupForKine, axisPtForKine}); - histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/PV_hPhi_neg", ";#varphi;n tracks", kTH3D, {axisPhi, axisOccupForKine, axisPtForKine}); + // AxisSpec confAxisOccupForKine{{0, 500, 1000, 2000, 4000, 6000, 20000}, "weighted occupancy"}; + // AxisSpec confAxisOccupForKine{{0, 500, 1000, 2000, 4000, 6000, 8000, 10000, 20000}, "weighted occupancy"}; + // AxisSpec confAxisPtBinsForPhiStudy{{0.2, 0.6, 1.0, 2.0, 10}, "pt bins for phi study"}; + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPt_pos", ";p_{T};weighted occupancy", kTH2D, {axisLogPt, confAxisOccupForKine}); + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPt_neg", ";p_{T};weighted occupancy", kTH2D, {axisLogPt, confAxisOccupForKine}); + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hEta_pos", ";#eta;weighted occupancy", kTH2D, {axisEta, confAxisOccupForKine}); + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hEta_neg", ";#eta;weighted occupancy", kTH2D, {axisEta, confAxisOccupForKine}); + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPhi_pos", ";#varphi;n tracks", kTH3D, {axisPhi, confAxisOccupForKine, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPhi_neg", ";#varphi;n tracks", kTH3D, {axisPhi, confAxisOccupForKine, confAxisPtBinsForPhiStudy}); + + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPhi_tpcNClsFindable_pos", ";#varphi;n tracks", kTH3D, {axisPhi, confAxisOccupForKine, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPhi_tpcNClsFound_pos", ";#varphi;n tracks", kTH3D, {axisPhi, confAxisOccupForKine, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPhi_tpcNClsCrossedRows_pos", ";#varphi;n tracks", kTH3D, {axisPhi, confAxisOccupForKine, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPhi_tpcNClsFindable_neg", ";#varphi;n tracks", kTH3D, {axisPhi, confAxisOccupForKine, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPhi_tpcNClsFound_neg", ";#varphi;n tracks", kTH3D, {axisPhi, confAxisOccupForKine, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPhi_tpcNClsCrossedRows_neg", ";#varphi;n tracks", kTH3D, {axisPhi, confAxisOccupForKine, confAxisPtBinsForPhiStudy}); + + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/PV_hPt_pos", ";p_{T};weighted occupancy", kTH2D, {axisLogPt, confAxisOccupForKine}); + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/PV_hPt_neg", ";p_{T};weighted occupancy", kTH2D, {axisLogPt, confAxisOccupForKine}); + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/PV_hEta_pos", ";#eta;weighted occupancy", kTH2D, {axisEta, confAxisOccupForKine}); + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/PV_hEta_neg", ";#eta;weighted occupancy", kTH2D, {axisEta, confAxisOccupForKine}); + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/PV_hPhi_pos", ";#varphi;n tracks", kTH3D, {axisPhi, confAxisOccupForKine, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/PV_hPhi_neg", ";#varphi;n tracks", kTH3D, {axisPhi, confAxisOccupForKine, confAxisPtBinsForPhiStudy}); + + histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPt_pos", ";p_{T};weighted occupancy", kTH2D, {axisLogPt, confAxisOccupForKine}); + histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPt_neg", ";p_{T};weighted occupancy", kTH2D, {axisLogPt, confAxisOccupForKine}); + histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hEta_pos", ";#eta;weighted occupancy", kTH2D, {axisEta, confAxisOccupForKine}); + histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hEta_neg", ";#eta;weighted occupancy", kTH2D, {axisEta, confAxisOccupForKine}); + histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPhi_pos", ";#varphi;n tracks", kTH3D, {axisPhi, confAxisOccupForKine, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPhi_neg", ";#varphi;n tracks", kTH3D, {axisPhi, confAxisOccupForKine, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPhi_posInitialQA", ";#varphi;n tracks", kTH1D, {{3 * 810, -TMath::TwoPi(), 2 * TMath::TwoPi(), "#varphi"}}); + histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPhi_posModifiedQA", ";#varphi;n tracks", kTH1D, {{3 * 810, -TMath::TwoPi(), 2 * TMath::TwoPi(), "#varphi"}}); + histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPhi_negInitialQA", ";#varphi;n tracks", kTH1D, {{3 * 810, -TMath::TwoPi(), 2 * TMath::TwoPi(), "#varphi"}}); + histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPhi_negModifiedQA", ";#varphi;n tracks", kTH1D, {{3 * 810, -TMath::TwoPi(), 2 * TMath::TwoPi(), "#varphi"}}); + + histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/PV_hPt_pos", ";p_{T};weighted occupancy", kTH2D, {axisLogPt, confAxisOccupForKine}); + histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/PV_hPt_neg", ";p_{T};weighted occupancy", kTH2D, {axisLogPt, confAxisOccupForKine}); + histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/PV_hEta_pos", ";#eta;weighted occupancy", kTH2D, {axisEta, confAxisOccupForKine}); + histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/PV_hEta_neg", ";#eta;weighted occupancy", kTH2D, {axisEta, confAxisOccupForKine}); + histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/PV_hPhi_pos", ";#varphi;n tracks", kTH3D, {axisPhi, confAxisOccupForKine, confAxisPtBinsForPhiStudy}); + histos.add("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/PV_hPhi_neg", ";#varphi;n tracks", kTH3D, {axisPhi, confAxisOccupForKine, confAxisPtBinsForPhiStudy}); + + // QA nTPCcls + AxisSpec axisNTPCclsPlusMinusQA{521, -260, 260, "n TPC clusters"}; + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/QA_tpcNClsFindable_pos", "", kTH1D, {axisNTPCclsPlusMinusQA}); + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/QA_tpcNClsFound_pos", "", kTH1D, {axisNTPCclsPlusMinusQA}); + histos.add("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/QA_tpcNClsCrossedRows_pos", "", kTH1D, {axisNTPCclsPlusMinusQA}); AxisSpec axisLogPtFor2D{50, 0.05, 10, "p_{T}"}; AxisSpec axisLogPtTpcFor2D{50, 0.05, 10, "p_{T} TPC inner"}; - histos.add("track_distr_nITStrThisEv_10_200/hPt_vs_tpcInnerPt_vs_occup", ";p_{T};p_{T} TPC inner;weighted occupancy", kTH3D, {axisLogPtFor2D, axisLogPtTpcFor2D, axisOccupForKine}); - histos.add("track_distr_nITStrThisEv_above_2000/hPt_vs_tpcInnerPt_vs_occup", ";p_{T};p_{T} TPC inner;weighted occupancy", kTH3D, {axisLogPtFor2D, axisLogPtTpcFor2D, axisOccupForKine}); + histos.add("track_distr_nITStrThisEv_10_200/hPt_vs_tpcInnerPt_vs_occup", ";p_{T};p_{T} TPC inner;weighted occupancy", kTH3D, {axisLogPtFor2D, axisLogPtTpcFor2D, confAxisOccupForKine}); + histos.add("track_distr_nITStrThisEv_above_2000/hPt_vs_tpcInnerPt_vs_occup", ";p_{T};p_{T} TPC inner;weighted occupancy", kTH3D, {axisLogPtFor2D, axisLogPtTpcFor2D, confAxisOccupForKine}); - histos.add("hNcolVsBcInTF/hNcolVsBcInTF_vs_occupancy", ";bc in TF;weighted occupancy", kTH2F, {axisBCinTF, axisOccupForKine}); - histos.add("hNcolVsBcInTF/hNcolVsBcInTF_vs_occupancy_vertexTOFmatched", ";bc in TF;weighted occupancy", kTH2F, {axisBCinTF, axisOccupForKine}); - histos.add("hNcolVsBcInTF/hNcolVsBcInTF_vs_occupancy_nPV_10_200", ";bc in TF;weighted occupancy", kTH2F, {axisBCinTF, axisOccupForKine}); - histos.add("hNcolVsBcInTF/hNcolVsBcInTF_vs_occupancy_nPV_above2000", ";bc in TF;weighted occupancy", kTH2F, {axisBCinTF, axisOccupForKine}); + histos.add("hNcolVsBcInTF/hNcolVsBcInTF_vs_occupancy", ";bc in TF;weighted occupancy", kTH2F, {axisBCinTF, confAxisOccupForKine}); + histos.add("hNcolVsBcInTF/hNcolVsBcInTF_vs_occupancy_vertexTOFmatched", ";bc in TF;weighted occupancy", kTH2F, {axisBCinTF, confAxisOccupForKine}); + histos.add("hNcolVsBcInTF/hNcolVsBcInTF_vs_occupancy_nPV_10_200", ";bc in TF;weighted occupancy", kTH2F, {axisBCinTF, confAxisOccupForKine}); + histos.add("hNcolVsBcInTF/hNcolVsBcInTF_vs_occupancy_nPV_above2000", ";bc in TF;weighted occupancy", kTH2F, {axisBCinTF, confAxisOccupForKine}); // end of July 2025: to compare data and MC (pt, eta, phi) // 3D: pt vs centr vs occup @@ -566,7 +607,7 @@ struct DetectorOccupancyQaTask { if (!track.isPVContributor()) { continue; } - if (track.itsNCls() < 5) + if (track.itsNCls() < confMinITSclsPerTrack) continue; nITS567cls++; nITSTPCtracks += track.hasITS() && track.hasTPC(); @@ -729,7 +770,7 @@ struct DetectorOccupancyQaTask { int nCollInTimeWindowSelIfTOF = 0; double multFT0CmainCollision = 0.f; double multFT0CInTimeWindow = 0.f; - map mUniqueBC; + std::map mUniqueBC; bool sel = col.selection_bit(kIsTriggerTVX); @@ -836,17 +877,17 @@ struct DetectorOccupancyQaTask { // counters of occupancy in specified delta-time ranges, to monitor eta, phi, pt distributions later float integralFullDeltaTime = histos.get(HIST("thisEventITStracksInTimeBins"))->Integral(); - int binMin = histos.get(HIST("thisEventITStracksInTimeBins"))->FindBin(-39.5); // us - int binMax = histos.get(HIST("thisEventITStracksInTimeBins"))->FindBin(-10.5); + int binMin = histos.get(HIST("thisEventITStracksInTimeBins"))->FindBin(confTimeSlicesForPastFutureStudies->at(0) + 0.5); // default was: -39.5 us + int binMax = histos.get(HIST("thisEventITStracksInTimeBins"))->FindBin(confTimeSlicesForPastFutureStudies->at(1) - 0.5); // -10.5 float integralPast = histos.get(HIST("thisEventITStracksInTimeBins"))->Integral(binMin, binMax); - binMin = histos.get(HIST("thisEventITStracksInTimeBins"))->FindBin(20.5); - binMax = histos.get(HIST("thisEventITStracksInTimeBins"))->FindBin(49.5); + binMin = histos.get(HIST("thisEventITStracksInTimeBins"))->FindBin(confTimeSlicesForPastFutureStudies->at(2) + 0.5); // 20.5 + binMax = histos.get(HIST("thisEventITStracksInTimeBins"))->FindBin(confTimeSlicesForPastFutureStudies->at(3) - 0.5); // 49.5 float integralFuture1 = histos.get(HIST("thisEventITStracksInTimeBins"))->Integral(binMin, binMax); - binMin = histos.get(HIST("thisEventITStracksInTimeBins"))->FindBin(50.5); - binMax = histos.get(HIST("thisEventITStracksInTimeBins"))->FindBin(79.5); + binMin = histos.get(HIST("thisEventITStracksInTimeBins"))->FindBin(confTimeSlicesForPastFutureStudies->at(3) + 0.5); // 50.5 + binMax = histos.get(HIST("thisEventITStracksInTimeBins"))->FindBin(confTimeSlicesForPastFutureStudies->at(4) - 0.5); // 79.5 float integralFuture2 = histos.get(HIST("thisEventITStracksInTimeBins"))->Integral(binMin, binMax); - binMin = histos.get(HIST("thisEventITStracksInTimeBins"))->FindBin(-9.5); - binMax = histos.get(HIST("thisEventITStracksInTimeBins"))->FindBin(19.5); + binMin = histos.get(HIST("thisEventITStracksInTimeBins"))->FindBin(confTimeSlicesForPastFutureStudies->at(1) + 0.5); // -9.5 + binMax = histos.get(HIST("thisEventITStracksInTimeBins"))->FindBin(confTimeSlicesForPastFutureStudies->at(2) - 0.5); // 19.5 float integralNeighbourEvents = histos.get(HIST("thisEventITStracksInTimeBins"))->Integral(binMin, binMax); // recent past @@ -937,6 +978,9 @@ struct DetectorOccupancyQaTask { if (!col.sel8()) continue; + if (confApplyGoodITSstavesFlaginEvSel && !col.selection_bit(aod::evsel::kIsGoodITSLayersAll)) + continue; + // if (!col.selection_bit(kIsTriggerTVX)) // continue; @@ -973,7 +1017,7 @@ struct DetectorOccupancyQaTask { continue; if (track.eta() < confCutEtaMinTracksThisEvent || track.eta() > confCutEtaMaxTracksThisEvent) continue; - if (track.itsNCls() < 5) + if (track.itsNCls() < confMinITSclsPerTrack) continue; nPV++; } @@ -999,7 +1043,7 @@ struct DetectorOccupancyQaTask { if (track.eta() < confCutEtaMinTracksThisEvent || track.eta() > confCutEtaMaxTracksThisEvent) continue; histos.fill(HIST("nTrackCounter_after_cuts_QA"), 3); - if (track.itsNCls() < 5) + if (track.itsNCls() < confMinITSclsPerTrack) continue; histos.fill(HIST("nTrackCounter_after_cuts_QA"), 4); // nPV++; @@ -1212,79 +1256,128 @@ struct DetectorOccupancyQaTask { for (const auto& track : tracksGrouped) { if (!track.isPVContributor()) continue; - if (track.itsNCls() < 5) + if (track.itsNCls() < confMinITSclsPerTrack) continue; // if (!(track.isGlobalTrack() && track.tpcNClsFound() >= confCutMinTPCcls)) // continue; bool isGoodGlobal = (track.isGlobalTrack() && track.tpcNClsFound() >= confCutMinTPCcls); + bool hasTPCspecCuts = (track.hasTPC() && track.tpcNClsFound() >= confCutMinTPCcls && track.tpcNClsCrossedRows() > 80 && track.tpcChi2NCl() < 4); // ### kine distr vs centr vs occup float sign = track.sign(); float pt = track.pt(); float eta = track.eta(); float phi = track.phi(); + float phiInitial = phi; + + if (confUsePhiAtTPCinnerR) { + phi -= asin(confRadiusForPhiCorrection /*inner TPC radius*/ / 2 * 0.3 * sign * 0.5 / pt); + if (phi < 0) + phi += TMath::TwoPi(); + else if (phi > TMath::TwoPi()) + phi -= TMath::TwoPi(); + } - if (occupancy >= 0 && fabs(eta) < 0.8 && pt > 0.15) { - // if (confFlagManyHeavyHistos) { - // histos.fill(HIST("ptGlobal_vs_centr_vs_occup"), nPV, occupancy, pt); - // histos.fill(HIST("ptPV_vs_centr_vs_occup"), nPV, occupancy, pt); - // if (col.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { - // histos.fill(HIST("ptGlobal_vs_centr_vs_occup_NoCollStd"), nPV, occupancy, pt); - // histos.fill(HIST("ptPV_vs_centr_vs_occup_NoCollStd"), nPV, occupancy, pt); - // } - // } + bool etaInRange = true; + if (confUseAorCsideForPhiStudy == 0 && eta < 0.1) // check if we are in A side + etaInRange = false; + if (confUseAorCsideForPhiStudy == 1 && eta > -0.1) // check if we are in C side + etaInRange = false; + if (occupancy >= 0 && fabs(eta) < 0.8 && pt > 0.15 && etaInRange) { if (nPV >= 10 && nPV < 200) { if (isGoodGlobal) { if (flagWhichDeltaTimeWin == 1 && flagNoCollNearby) { histos.fill(HIST("track_distr_nITStrThisEv_10_200/hEta_lowOccupInTPC"), eta); histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPhi_lowOccupInTPC"), phi); histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPt_lowOccupInTPC"), pt); + + if (sign > 0) + histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPhi_lowOccupInTPC_pos_vs_pt"), phi, pt); + else + histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPhi_lowOccupInTPC_neg_vs_pt"), phi, pt); } if (flagWhichDeltaTimeWin == 2 && flagNoCollNearby) { histos.fill(HIST("track_distr_nITStrThisEv_10_200/hEta_highOccupInRecentPast"), eta); histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPhi_highOccupInRecentPast"), phi); histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPt_highOccupInRecentPast"), pt); + + if (sign > 0) + histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPhi_highOccupInRecentPast_pos_vs_pt"), phi, pt); + else + histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPhi_highOccupInRecentPast_neg_vs_pt"), phi, pt); } if (flagWhichDeltaTimeWin == 3 && flagNoCollNearby) { histos.fill(HIST("track_distr_nITStrThisEv_10_200/hEta_highOccupInCloseFuture"), eta); histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPhi_highOccupInCloseFuture"), phi); histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPt_highOccupInCloseFuture"), pt); + + if (sign > 0) + histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPhi_highOccupInCloseFuture_pos_vs_pt"), phi, pt); + else + histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPhi_highOccupInCloseFuture_neg_vs_pt"), phi, pt); } if (flagWhichDeltaTimeWin == 4 && flagNoCollNearby) { histos.fill(HIST("track_distr_nITStrThisEv_10_200/hEta_highOccupInDistantFuture"), eta); histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPhi_highOccupInDistantFuture"), phi); histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPt_highOccupInDistantFuture"), pt); + + if (sign > 0) + histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPhi_highOccupInDistantFuture_pos_vs_pt"), phi, pt); + else + histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPhi_highOccupInDistantFuture_neg_vs_pt"), phi, pt); } if (flagWhichDeltaTimeWin == 5) { histos.fill(HIST("track_distr_nITStrThisEv_10_200/hEta_highOccupInNeighbourEvents"), eta); histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPhi_highOccupInNeighbourEvents"), phi); histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPt_highOccupInNeighbourEvents"), pt); + + if (sign > 0) + histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPhi_highOccupInNeighbourEvents_pos_vs_pt"), phi, pt); + else + histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPhi_highOccupInNeighbourEvents_neg_vs_pt"), phi, pt); } histos.fill(HIST("track_distr_nITStrThisEv_10_200/hPt_vs_tpcInnerPt_vs_occup"), pt, track.tpcInnerParam(), occupancy); } // end of TPC good global // July 2025: for data vs MC kine distr comparison - if (sign > 0) // positive + + int tpcNClsFindable = track.tpcNClsFindable(); + int tpcNClsFound = track.tpcNClsFound(); + int tpcNClsCrossedRows = track.tpcNClsCrossedRows(); + + if (sign > 0) // positive tracks { histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/PV_hPt_pos"), pt, occupancy); histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/PV_hEta_pos"), eta, occupancy); histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/PV_hPhi_pos"), phi, occupancy, pt); - if (isGoodGlobal) { + if (hasTPCspecCuts) { histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPt_pos"), pt, occupancy); histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hEta_pos"), eta, occupancy); histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPhi_pos"), phi, occupancy, pt); + + histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPhi_tpcNClsFindable_pos"), phi, occupancy, pt, tpcNClsFindable); + histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPhi_tpcNClsFound_pos"), phi, occupancy, pt, tpcNClsFound); + histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPhi_tpcNClsCrossedRows_pos"), phi, occupancy, pt, tpcNClsCrossedRows); + + histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/QA_tpcNClsFindable_pos"), tpcNClsFindable); + histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/QA_tpcNClsFound_pos"), tpcNClsFound); + histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/QA_tpcNClsCrossedRows_pos"), tpcNClsCrossedRows); } - } else // negative + } else // negative tracks { histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/PV_hPt_neg"), pt, occupancy); histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/PV_hEta_neg"), eta, occupancy); histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/PV_hPhi_neg"), phi, occupancy, pt); - if (track.hasTPC()) { + if (hasTPCspecCuts) { histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPt_neg"), pt, occupancy); histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hEta_neg"), eta, occupancy); histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPhi_neg"), phi, occupancy, pt); + + histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPhi_tpcNClsFindable_neg"), phi, occupancy, pt, tpcNClsFindable); + histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPhi_tpcNClsFound_neg"), phi, occupancy, pt, tpcNClsFound); + histos.fill(HIST("track_distr_nITStrThisEv_10_200/kine_vs_weighted_occup/hPhi_tpcNClsCrossedRows_neg"), phi, occupancy, pt, tpcNClsCrossedRows); } } // end of July 2025: for data vs MC kine distr comparison @@ -1320,30 +1413,38 @@ struct DetectorOccupancyQaTask { } // end of TPC good global // July 2025: for data vs MC kine distr comparison - if (sign > 0) // positive + if (sign > 0) // positive tracks { histos.fill(HIST("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/PV_hPt_pos"), pt, occupancy); histos.fill(HIST("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/PV_hEta_pos"), eta, occupancy); histos.fill(HIST("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/PV_hPhi_pos"), phi, occupancy, pt); - if (isGoodGlobal) { + if (hasTPCspecCuts) { histos.fill(HIST("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPt_pos"), pt, occupancy); histos.fill(HIST("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hEta_pos"), eta, occupancy); histos.fill(HIST("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPhi_pos"), phi, occupancy, pt); + if (pt > 0.7 && pt < 1.0) { + histos.fill(HIST("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPhi_posInitialQA"), phiInitial); + histos.fill(HIST("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPhi_posModifiedQA"), phi); + } } - } else // negative + } else // negative tracks { histos.fill(HIST("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/PV_hPt_neg"), pt, occupancy); histos.fill(HIST("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/PV_hEta_neg"), eta, occupancy); histos.fill(HIST("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/PV_hPhi_neg"), phi, occupancy, pt); - if (track.hasTPC()) { + if (hasTPCspecCuts) { histos.fill(HIST("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPt_neg"), pt, occupancy); histos.fill(HIST("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hEta_neg"), eta, occupancy); histos.fill(HIST("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPhi_neg"), phi, occupancy, pt); + if (pt > 0.7 && pt < 1.0) { + histos.fill(HIST("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPhi_negInitialQA"), phiInitial); + histos.fill(HIST("track_distr_nITStrThisEv_above_2000/kine_vs_weighted_occup/hPhi_negModifiedQA"), phi); + } } } // end of July 2025: for data vs MC kine distr comparison } // end of if (nPV >= 2000) - } // end of if (occupancy >= 0) + } // end of if (occupancy >= 0) && kine cuts } // end of spec track loop to fill track histograms } // end of if (confAddBasicQAhistos) diff --git a/DPG/Tasks/AOTEvent/eventSelectionQa.cxx b/DPG/Tasks/AOTEvent/eventSelectionQa.cxx index c02ac2deda5..e890b9fbab9 100644 --- a/DPG/Tasks/AOTEvent/eventSelectionQa.cxx +++ b/DPG/Tasks/AOTEvent/eventSelectionQa.cxx @@ -1185,7 +1185,7 @@ struct EventSelectionQaTask { histos.fill(HIST("occupancyQA/tpcNCrossedRows_vs_V0A_vs_occupancy"), multV0A, track.tpcNClsFindable() - tpcNClsFindableMinusCrossedRowsCorrected, occupancyByTracks); } } // end of hasTPC - if (track.tpcNClsFound() > 50 && track.tpcNClsCrossedRows() > 80 && track.itsChi2NCl() < 36 && track.tpcChi2NCl() < 4) { + if (col.sel8() && fabs(col.posZ()) < 10 && track.tpcNClsFound() > 50 && track.tpcNClsCrossedRows() > 80 && track.itsChi2NCl() < 36 && track.tpcChi2NCl() < 4) { nContributorsAfterEtaTPCCuts++; // ROF border QA histos.fill(HIST("ITSROFborderQA/hFoundBC_kTVX_nITSlayers_for_ITSTPCtracks"), localBC, track.itsNCls()); diff --git a/DPG/Tasks/AOTEvent/lightIonsEvSelQa.cxx b/DPG/Tasks/AOTEvent/lightIonsEvSelQa.cxx new file mode 100644 index 00000000000..a98bf5b1300 --- /dev/null +++ b/DPG/Tasks/AOTEvent/lightIonsEvSelQa.cxx @@ -0,0 +1,1674 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file detectorOccupancyQa.cxx +/// \brief Occupancy QA task +/// +/// \author Igor Altsybeev + +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +// #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/FT0Corrected.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CommonDataFormat/BunchFilling.h" +#include "DataFormatsFT0/Digit.h" +#include "DataFormatsFT0/RecPoints.h" +#include "DataFormatsParameters/AggregatedRunInfo.h" +#include "DataFormatsParameters/GRPECSObject.h" +#include "DataFormatsParameters/GRPLHCIFData.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include "TH1F.h" +#include "TH2F.h" +#include "TH3.h" + +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::aod::evsel; + +using BCsRun3 = soa::Join; +using ColEvSels = soa::Join; //, aod::CentFT0Cs>; +// using FullTracksIU = soa::Join; +using FullTracksIU = soa::Join; + +struct LightIonsEvSelQa { + Configurable confCutMinTPCcls{"MinNumTPCcls", 50, "min number of TPC clusters for a current event"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable nBinsTracks{"nBinsTracks", 450, "N bins in n tracks histo"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable nMaxTracks{"nMaxTracks", 450, "N max in n tracks histo"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable nMaxGlobalTracks{"nMaxGlobalTracks", 450, "N max in n tracks histo"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable nBinsMultFwd{"nBinsMultFwd", 1000, "N bins in mult fwd histo"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable nMaxMultFwd{"nMaxMultFwd", 100000, "N max in mult fwd histo"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable timeBinWidthInSec{"TimeBinWidthInSec", 10, "Width of time bins in seconds"}; // o2-linter: disable=name/configurable (temporary fix) + + Configurable nSigmaForVzDiff{"nSigmaForVzDiff", 2.5, "n +/- sigma for diff vZ"}; // o2-linter: disable=name/configurable (temporary fix) + Configurable safetyDiffVzMargin{"SafetyDiffVzMargin", 0.5, "margin for diff vZ, cm"}; // o2-linter: disable=name/configurable (temporary fix) + + Configurable confUseDiffVzCutFromEvSel{"UseDiffVzCutFromEvSel", 0, "0 - custom diffVz cut from this task, 1 - cut from event selection"}; // o2-linter: disable=name/configurable (temporary fix) + + uint64_t minGlobalBC = 0; + Service ccdb; + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + bool* applySelection = NULL; + int nBCsPerOrbit = 3564; + int lastRunNumber = -1; + double maxSec = 1; + double minSec = 0; + int64_t bcSOR = 0; // global bc of the start of the first orbit, setting 0 by default for unanchored MC + int64_t nBCsPerTF = 32 * nBCsPerOrbit; // duration of TF in bcs, should be 128*3564 or 32*3564, setting 128 orbits by default sfor unanchored MC + + // save time "slices" for several collisions for QA + bool flagFillQAtimeOccupHist = false; + int nCollisionsForTimeBinQA = 40; + int counterQAtimeOccupHistos = 0; + + void init(InitContext&) + { + // ccdb->setURL("http://ccdb-test.cern.ch:8080"); + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + + // const AxisSpec axisBCinTF{static_cast(nBCsPerTF), 0, static_cast(nBCsPerTF), "bc in TF"}; + // histos.add("hNcolVsBcInTF/hNcolVsBcInTF", ";bc in TF; n collisions", kTH1F, {axisBCinTF}); + // histos.add("hNcolVsBcInTF/hNcolVsBcInTF_vertexTOFmatched", ";bc in TF; n collisions", kTH1F, {axisBCinTF}); + + // ############## + const AxisSpec axisBCs{nBCsPerOrbit, 0., static_cast(nBCsPerOrbit), ""}; + + histos.add("bcQA/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("bcQA/pastActivity/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("bcQA/futureActivity/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("bcQA/noPastActivity/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("bcQA/noFutureActivity/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("bcQA/noPastFutureActivity/hBcFV0", "", kTH1F, {axisBCs}); + + histos.add("bcQA/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("bcQA/pastActivity/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("bcQA/futureActivity/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("bcQA/noPastActivity/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("bcQA/noFutureActivity/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("bcQA/noPastFutureActivity/hBcFT0", "", kTH1F, {axisBCs}); + + histos.add("bcQA/hBcFDD", "", kTH1F, {axisBCs}); + histos.add("bcQA/pastActivity/hBcFDD", "", kTH1F, {axisBCs}); + histos.add("bcQA/futureActivity/hBcFDD", "", kTH1F, {axisBCs}); + histos.add("bcQA/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("bcQA/pastActivity/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("bcQA/futureActivity/hBcZDC", "", kTH1F, {axisBCs}); + + histos.add("bcQA/specFT0bits/hBc_kIsActiveSideA", "", kTH1F, {axisBCs}); + histos.add("bcQA/specFT0bits/hBc_kIsActiveSideC", "", kTH1F, {axisBCs}); + histos.add("bcQA/specFT0bits/hBc_kIsFlangeEvent", "", kTH1F, {axisBCs}); + + histos.add("bcQA/specFT0bits/hBc_kIsActiveSideA_inTVX", "", kTH1F, {axisBCs}); + histos.add("bcQA/specFT0bits/hBc_kIsActiveSideC_inTVX", "", kTH1F, {axisBCs}); + histos.add("bcQA/specFT0bits/hBc_kIsFlangeEvent_inTVX", "", kTH1F, {axisBCs}); + + const AxisSpec axisNtracks{nBinsTracks, -0.5, nMaxTracks - 0.5, "n tracks"}; + const AxisSpec axisNtracksGlobal{nBinsTracks, -0.5, nMaxGlobalTracks - 0.5, "n tracks"}; + const AxisSpec axisMultV0A{nBinsMultFwd, 0., static_cast(nMaxMultFwd), "mult V0A"}; + const AxisSpec axisMultFT0A{nBinsMultFwd, 0., static_cast(nMaxMultFwd * 0.4), "mult FT0C"}; + const AxisSpec axisMultFT0C{nBinsMultFwd, 0., static_cast(nMaxMultFwd * 0.15), "mult FT0C"}; + const AxisSpec axisMultT0M{nBinsMultFwd * 2, 0., static_cast(nMaxMultFwd * 0.4), "mult FT0M"}; + + const AxisSpec axisMultT0MlargeBins{nBinsMultFwd, 0., static_cast(nMaxMultFwd * 0.75), "mult FT0M"}; + histos.add("multT0M_vs_multSumFT0", ";multT0M;multT0M_uncorrected", kTH2F, {axisMultT0MlargeBins, axisMultT0MlargeBins}); + + const AxisSpec axisVtxZ{800, -20., 20., ""}; + const AxisSpec axisBcDiff{600, -300., 300., "bc difference"}; + + const AxisSpec axisNcontrib{801, -0.5, 800.5, "n contributors"}; + const AxisSpec axisColTimeRes{1500, 0., 1500., "collision time resolution (ns)"}; + + AxisSpec axisVertexChi2{100, 0, 500, "Chi2 of vertex fit"}; + AxisSpec axisVertexChi2perContrib{100, 0, 10, "Chi2 of vertex fit"}; + + histos.add("noSpecSelections/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("noSpecSelections/hBcOrigNoSel8", "", kTH1F, {axisBCs}); + // histos.add("noSpecSelections/hBcColNoSel8TOF", "", kTH1F, {axisBCs}); + histos.add("noSpecSelections/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("noSpecSelections/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("noSpecSelections/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("noSpecSelections/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("noSpecSelections/hBcFDD", "", kTH1F, {axisBCs}); + histos.add("noSpecSelections/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("noSpecSelections/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("noSpecSelections/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("noSpecSelections/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noSpecSelections/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("noSpecSelections/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + histos.add("noSpecSelections/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + histos.add("noSpecSelections/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + histos.add("noSpecSelections/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("noSpecSelections/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("noSpecSelections/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("noSpecSelections/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("noSpecSelections/hVertexChi2VsNcontrib", "", kTH2F, {axisNcontrib, axisVertexChi2perContrib}); + histos.add("noSpecSelections/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("noPU/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU/hBcOrigNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("noPU/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("noPU/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("noPU/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("noPU/hBcFDD", "", kTH1F, {axisBCs}); + histos.add("noPU/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("noPU/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("noPU/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("noPU/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noPU/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("noPU/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + histos.add("noPU/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + histos.add("noPU/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + histos.add("noPU/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("noPU/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("noPU/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("noPU/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("noPU/hVertexChi2VsNcontrib", "", kTH2F, {axisNcontrib, axisVertexChi2perContrib}); + histos.add("noPU/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("noPU_pvTOFmatched/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU_pvTOFmatched/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("noPU_pvTOFmatched/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("noPU_pvTOFmatched/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("noPU_pvTOFmatched/hBcFV0", "", kTH1F, {axisBCs}); + // histos.add("noPU_pvTOFmatched/hBcFDD", "", kTH1F, {axisBCs}); + histos.add("noPU_pvTOFmatched/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("noPU_pvTOFmatched/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("noPU_pvTOFmatched/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("noPU_pvTOFmatched/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noPU_pvTOFmatched/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("noPU_pvTOFmatched/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + histos.add("noPU_pvTOFmatched/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + histos.add("noPU_pvTOFmatched/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + histos.add("noPU_pvTOFmatched/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("noPU_pvTOFmatched/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("noPU_pvTOFmatched/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("noPU_pvTOFmatched/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("noPU_pvTOFmatched/hVertexChi2VsNcontrib", "", kTH2F, {axisNcontrib, axisVertexChi2perContrib}); + histos.add("noPU_pvTOFmatched/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("noPU_pvTRDmatched/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU_pvTRDmatched/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("noPU_pvTRDmatched/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("noPU_pvTRDmatched/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("noPU_pvTRDmatched/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("noPU_pvTRDmatched/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("noPU_pvTRDmatched/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("noPU_pvTRDmatched/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("noPU_pvTRDmatched/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noPU_pvTRDmatched/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("noPU_pvTRDmatched/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + histos.add("noPU_pvTRDmatched/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + histos.add("noPU_pvTRDmatched/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + histos.add("noPU_pvTRDmatched/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("noPU_pvTRDmatched/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("noPU_pvTRDmatched/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("noPU_pvTRDmatched/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("noPU_pvTRDmatched/hVertexChi2VsNcontrib", "", kTH2F, {axisNcontrib, axisVertexChi2perContrib}); + histos.add("noPU_pvTRDmatched/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("noPU_notTRDmatched/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU_notTRDmatched/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("noPU_notTRDmatched/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("noPU_notTRDmatched/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("noPU_notTRDmatched/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("noPU_notTRDmatched/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("noPU_notTRDmatched/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("noPU_notTRDmatched/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("noPU_notTRDmatched/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noPU_notTRDmatched/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("noPU_notTRDmatched/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + histos.add("noPU_notTRDmatched/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + histos.add("noPU_notTRDmatched/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + histos.add("noPU_notTRDmatched/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("noPU_notTRDmatched/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("noPU_notTRDmatched/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("noPU_notTRDmatched/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("noPU_notTRDmatched/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("noPU_pvTOFmatched_notTRDmatched/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("noPU_pvTOFmatched_notTRDmatched/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noPU_pvTOFmatched_notTRDmatched/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + histos.add("noPU_pvTOFmatched_notTRDmatched/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("bcDiffWrtClosestTVXCut/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("bcDiffWrtClosestTVXCut/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("bcDiffWrtClosestTVXCut/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("bcDiffWrtClosestTVXCut/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("bcDiffWrtClosestTVXCut/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("bcDiffWrtClosestTVXCut/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("bcDiffWrtClosestTVXCut/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("bcDiffWrtClosestTVXCut/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("bcDiffWrtClosestTVXCut/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("bcDiffWrtClosestTVXCut/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("bcDiffWrtClosestTVXCut/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + // histos.add("bcDiffWrtClosestTVXCut/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + // histos.add("bcDiffWrtClosestTVXCut/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + // histos.add("bcDiffWrtClosestTVXCut/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("bcDiffWrtClosestTVXCut/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("bcDiffWrtClosestTVXCut/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("bcDiffWrtClosestTVXCut/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("bcDiffWrtClosestTVXCut/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("noPU_bcDiffWrtOriginalBcCut/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU_bcDiffWrtOriginalBcCut/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("noPU_bcDiffWrtOriginalBcCut/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("noPU_bcDiffWrtOriginalBcCut/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("noPU_bcDiffWrtOriginalBcCut/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("noPU_bcDiffWrtOriginalBcCut/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("noPU_bcDiffWrtOriginalBcCut/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("noPU_bcDiffWrtOriginalBcCut/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("noPU_bcDiffWrtOriginalBcCut/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noPU_bcDiffWrtOriginalBcCut/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("noPU_bcDiffWrtOriginalBcCut/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + // histos.add("noPU_bcDiffWrtOriginalBcCut/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + // histos.add("noPU_bcDiffWrtOriginalBcCut/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + // histos.add("noPU_bcDiffWrtOriginalBcCut/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("noPU_bcDiffWrtOriginalBcCut/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("noPU_bcDiffWrtOriginalBcCut/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("noPU_bcDiffWrtOriginalBcCut/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("noPU_bcDiffWrtOriginalBcCut/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("noPU_goodVertexChi2/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVertexChi2/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVertexChi2/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVertexChi2/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVertexChi2/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVertexChi2/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVertexChi2/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("noPU_goodVertexChi2/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("noPU_goodVertexChi2/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noPU_goodVertexChi2/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("noPU_goodVertexChi2/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + // histos.add("noPU_goodVertexChi2/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + // histos.add("noPU_goodVertexChi2/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + // histos.add("noPU_goodVertexChi2/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("noPU_goodVertexChi2/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("noPU_goodVertexChi2/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("noPU_goodVertexChi2/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("noPU_goodVertexChi2/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("narrowTimeVeto/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("narrowTimeVeto/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("narrowTimeVeto/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("narrowTimeVeto/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("narrowTimeVeto/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("narrowTimeVeto/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("narrowTimeVeto/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("narrowTimeVeto/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("narrowTimeVeto/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("narrowTimeVeto/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("narrowTimeVeto/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + histos.add("narrowTimeVeto/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + histos.add("narrowTimeVeto/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + histos.add("narrowTimeVeto/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("narrowTimeVeto/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("narrowTimeVeto/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("narrowTimeVeto/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("narrowTimeVeto/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("strictTimeVeto/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("strictTimeVeto/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("strictTimeVeto/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("strictTimeVeto/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("strictTimeVeto/hBcFV0", "", kTH1F, {axisBCs}); + // histos.add("strictTimeVeto/hBcFDD", "", kTH1F, {axisBCs}); + histos.add("strictTimeVeto/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("strictTimeVeto/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("strictTimeVeto/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("strictTimeVeto/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("strictTimeVeto/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("strictTimeVeto/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + histos.add("strictTimeVeto/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + histos.add("strictTimeVeto/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + histos.add("strictTimeVeto/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("strictTimeVeto/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("strictTimeVeto/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("strictTimeVeto/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("strictTimeVeto/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("noCollSameROF/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("noCollSameROF/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("noCollSameROF/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("noCollSameROF/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("noCollSameROF/hBcFV0", "", kTH1F, {axisBCs}); + // histos.add("noCollSameROF/hBcFDD", "", kTH1F, {axisBCs}); + histos.add("noCollSameROF/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("noCollSameROF/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("noCollSameROF/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("noCollSameROF/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noCollSameROF/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("noCollSameROF/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + histos.add("noCollSameROF/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + histos.add("noCollSameROF/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + histos.add("noCollSameROF/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("noCollSameROF/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("noCollSameROF/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("noCollSameROF/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("noCollSameROF/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("lowMultCut/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("lowMultCut/hBcOrigNoSel8", "", kTH1F, {axisBCs}); + histos.add("lowMultCut/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + + histos.add("noPU_lowMultCut/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU_lowMultCut/hBcOrigNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU_lowMultCut/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("noPU_lowMultCut/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("noPU_lowMultCut/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("noPU_lowMultCut/hBcFV0", "", kTH1F, {axisBCs}); + // histos.add("noPU_lowMultCut/hBcFDD", "", kTH1F, {axisBCs}); + histos.add("noPU_lowMultCut/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("noPU_lowMultCut/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("noPU_lowMultCut/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("noPU_lowMultCut/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noPU_lowMultCut/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("noPU_lowMultCut/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + histos.add("noPU_lowMultCut/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + histos.add("noPU_lowMultCut/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + histos.add("noPU_lowMultCut/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("noPU_lowMultCut/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("noPU_lowMultCut/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("noPU_lowMultCut/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("noPU_lowMultCut/hVertexChi2VsNcontrib", "", kTH2F, {axisNcontrib, axisVertexChi2perContrib}); + histos.add("noPU_lowMultCut/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("highMultCloudCut/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("highMultCloudCut/hBcOrigNoSel8", "", kTH1F, {axisBCs}); + histos.add("highMultCloudCut/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + + histos.add("noPU_highMultCloudCut/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU_highMultCloudCut/hBcOrigNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU_highMultCloudCut/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("noPU_highMultCloudCut/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("noPU_highMultCloudCut/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("noPU_highMultCloudCut/hBcFV0", "", kTH1F, {axisBCs}); + // histos.add("noPU_highMultCloudCut/hBcFDD", "", kTH1F, {axisBCs}); + histos.add("noPU_highMultCloudCut/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("noPU_highMultCloudCut/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("noPU_highMultCloudCut/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("noPU_highMultCloudCut/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noPU_highMultCloudCut/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("noPU_highMultCloudCut/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + histos.add("noPU_highMultCloudCut/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + histos.add("noPU_highMultCloudCut/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + histos.add("noPU_highMultCloudCut/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("noPU_highMultCloudCut/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("noPU_highMultCloudCut/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("noPU_highMultCloudCut/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("noPU_highMultCloudCut/hVertexChi2VsNcontrib", "", kTH2F, {axisNcontrib, axisVertexChi2perContrib}); + histos.add("noPU_highMultCloudCut/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("noPU_badVzDiff/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU_badVzDiff/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("noPU_badVzDiff/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("noPU_badVzDiff/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("noPU_badVzDiff/hBcFV0", "", kTH1F, {axisBCs}); + // histos.add("noPU_badVzDiff/hBcFDD", "", kTH1F, {axisBCs}); + histos.add("noPU_badVzDiff/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("noPU_badVzDiff/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("noPU_badVzDiff/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("noPU_badVzDiff/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noPU_badVzDiff/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("noPU_badVzDiff/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + histos.add("noPU_badVzDiff/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + histos.add("noPU_badVzDiff/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + histos.add("noPU_badVzDiff/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("noPU_badVzDiff/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("noPU_badVzDiff/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("noPU_badVzDiff/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("noPU_badVzDiff/hVertexChi2VsNcontrib", "", kTH2F, {axisNcontrib, axisVertexChi2perContrib}); + histos.add("noPU_badVzDiff/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("noPU_goodVzDiff/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVzDiff/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVzDiff/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVzDiff/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVzDiff/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVzDiff/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVzDiff/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("noPU_goodVzDiff/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("noPU_goodVzDiff/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noPU_goodVzDiff/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("noPU_goodVzDiff/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + histos.add("noPU_goodVzDiff/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + histos.add("noPU_goodVzDiff/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + histos.add("noPU_goodVzDiff/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("noPU_goodVzDiff/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("noPU_goodVzDiff/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("noPU_goodVzDiff/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("noPU_goodVzDiff/hVertexChi2VsNcontrib", "", kTH2F, {axisNcontrib, axisVertexChi2perContrib}); + histos.add("noPU_goodVzDiff/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("noPU_goodVzDiff_narrowTimeVeto/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVzDiff_narrowTimeVeto/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVzDiff_narrowTimeVeto/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVzDiff_narrowTimeVeto/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVzDiff_narrowTimeVeto/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVzDiff_narrowTimeVeto/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVzDiff_narrowTimeVeto/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("noPU_goodVzDiff_narrowTimeVeto/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("noPU_goodVzDiff_narrowTimeVeto/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noPU_goodVzDiff_narrowTimeVeto/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("noPU_goodVzDiff_narrowTimeVeto/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + histos.add("noPU_goodVzDiff_narrowTimeVeto/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + histos.add("noPU_goodVzDiff_narrowTimeVeto/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + histos.add("noPU_goodVzDiff_narrowTimeVeto/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("noPU_goodVzDiff_narrowTimeVeto/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("noPU_goodVzDiff_narrowTimeVeto/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("noPU_goodVzDiff_narrowTimeVeto/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("noPU_goodVzDiff_narrowTimeVeto/hVertexChi2VsNcontrib", "", kTH2F, {axisNcontrib, axisVertexChi2perContrib}); + histos.add("noPU_goodVzDiff_narrowTimeVeto/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("noPU_goodVzDiff_strictTimeVeto/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVzDiff_strictTimeVeto/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVzDiff_strictTimeVeto/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVzDiff_strictTimeVeto/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVzDiff_strictTimeVeto/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVzDiff_strictTimeVeto/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("noPU_goodVzDiff_strictTimeVeto/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("noPU_goodVzDiff_strictTimeVeto/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("noPU_goodVzDiff_strictTimeVeto/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noPU_goodVzDiff_strictTimeVeto/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("noPU_goodVzDiff_strictTimeVeto/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + histos.add("noPU_goodVzDiff_strictTimeVeto/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + histos.add("noPU_goodVzDiff_strictTimeVeto/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + histos.add("noPU_goodVzDiff_strictTimeVeto/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("noPU_goodVzDiff_strictTimeVeto/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("noPU_goodVzDiff_strictTimeVeto/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("noPU_goodVzDiff_strictTimeVeto/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("noPU_goodVzDiff_strictTimeVeto/hVertexChi2VsNcontrib", "", kTH2F, {axisNcontrib, axisVertexChi2perContrib}); + histos.add("noPU_goodVzDiff_strictTimeVeto/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("noPU_noPastActivity/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU_noPastActivity/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("noPU_noPastActivity/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("noPU_noPastActivity/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("noPU_noPastActivity/hBcFV0", "", kTH1F, {axisBCs}); + // histos.add("noPU_noPastActivity/hBcFDD", "", kTH1F, {axisBCs}); + histos.add("noPU_noPastActivity/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("noPU_noPastActivity/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("noPU_noPastActivity/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("noPU_noPastActivity/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noPU_noPastActivity/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("noPU_noPastActivity/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + // histos.add("noPU_noPastActivity/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + // histos.add("noPU_noPastActivity/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + // histos.add("noPU_noPastActivity/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("noPU_noPastActivity/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("noPU_noPastActivity/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("noPU_noPastActivity/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("noPU_noPastActivity/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("noPU_noFT0activityNearby/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU_noFT0activityNearby/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("noPU_noFT0activityNearby/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("noPU_noFT0activityNearby/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("noPU_noFT0activityNearby/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("noPU_noFT0activityNearby/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("noPU_noFT0activityNearby/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("noPU_noFT0activityNearby/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("noPU_noFT0activityNearby/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noPU_noFT0activityNearby/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("noPU_noFT0activityNearby/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + // histos.add("noPU_noFT0activityNearby/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + // histos.add("noPU_noFT0activityNearby/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + // histos.add("noPU_noFT0activityNearby/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("noPU_noFT0activityNearby/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("noPU_noFT0activityNearby/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("noPU_noFT0activityNearby/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("noPU_noFT0activityNearby/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("noPU_cutByVzDiff_pvTOF/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU_cutByVzDiff_pvTOF/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("noPU_cutByVzDiff_pvTOF/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("noPU_cutByVzDiff_pvTOF/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("noPU_cutByVzDiff_pvTOF/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("noPU_cutByVzDiff_pvTOF/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("noPU_cutByVzDiff_pvTOF/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("noPU_cutByVzDiff_pvTOF/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("noPU_cutByVzDiff_pvTOF/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noPU_cutByVzDiff_pvTOF/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("noPU_cutByVzDiff_pvTOF/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + histos.add("noPU_cutByVzDiff_pvTOF/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + histos.add("noPU_cutByVzDiff_pvTOF/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + histos.add("noPU_cutByVzDiff_pvTOF/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("noPU_cutByVzDiff_pvTOF/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("noPU_cutByVzDiff_pvTOF/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("noPU_cutByVzDiff_pvTOF/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("noPU_cutByVzDiff_pvTOF/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("noPU_cutByVzDiff_noFT0activityNearby/hBcColNoSel8", "", kTH1F, {axisBCs}); + histos.add("noPU_cutByVzDiff_noFT0activityNearby/hBcTVX", "", kTH1F, {axisBCs}); + histos.add("noPU_cutByVzDiff_noFT0activityNearby/hBcOrig", "", kTH1F, {axisBCs}); + histos.add("noPU_cutByVzDiff_noFT0activityNearby/hBcFT0", "", kTH1F, {axisBCs}); + histos.add("noPU_cutByVzDiff_noFT0activityNearby/hBcFV0", "", kTH1F, {axisBCs}); + histos.add("noPU_cutByVzDiff_noFT0activityNearby/hBcZDC", "", kTH1F, {axisBCs}); + histos.add("noPU_cutByVzDiff_noFT0activityNearby/hVtxFT0VsVtxCol", "", kTH2F, {axisVtxZ, axisVtxZ}); + histos.add("noPU_cutByVzDiff_noFT0activityNearby/hVtxFT0MinusVtxColVsMultT0M", "", kTH2F, {axisVtxZ, axisMultT0M}); + histos.add("noPU_cutByVzDiff_noFT0activityNearby/nTracksPV_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracks}); + histos.add("noPU_cutByVzDiff_noFT0activityNearby/nTracksPV_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracks}); + histos.add("noPU_cutByVzDiff_noFT0activityNearby/nTracksPV_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracks}); + // histos.add("noPU_cutByVzDiff_noFT0activityNearby/nTracksGlobal_vs_V0A", "", kTH2F, {axisMultV0A, axisNtracksGlobal}); + // histos.add("noPU_cutByVzDiff_noFT0activityNearby/nTracksGlobal_vs_T0A", "", kTH2F, {axisMultFT0A, axisNtracksGlobal}); + // histos.add("noPU_cutByVzDiff_noFT0activityNearby/nTracksGlobal_vs_T0C", "", kTH2F, {axisMultFT0C, axisNtracksGlobal}); + histos.add("noPU_cutByVzDiff_noFT0activityNearby/hTVXvsBcDiffwrtOrigBc", "", kTH1F, {axisBcDiff}); + histos.add("noPU_cutByVzDiff_noFT0activityNearby/hColTimeResVsNcontrib", "", kTH2F, {axisNcontrib, axisColTimeRes}); + histos.add("noPU_cutByVzDiff_noFT0activityNearby/hColBcDiffVsNcontrib", "", kTH2F, {axisNcontrib, axisBcDiff}); + histos.add("noPU_cutByVzDiff_noFT0activityNearby/hNPVvsNch", "", kTH2F, {axisNcontrib, axisNcontrib}); + + histos.add("hNcontribColFromData", "", kTH1F, {axisNcontrib}); + histos.add("hNcontribAccFromData", "", kTH1F, {axisNcontrib}); + } + + Preslice perCollision = aod::track::collisionId; + + int32_t findClosest(int64_t globalBC, std::map& bcs) + { + auto it = bcs.lower_bound(globalBC); + int64_t bc1 = it->first; + int32_t index1 = it->second; + if (it != bcs.begin()) + --it; + int64_t bc2 = it->first; + int32_t index2 = it->second; + int64_t dbc1 = std::abs(bc1 - globalBC); + int64_t dbc2 = std::abs(bc2 - globalBC); + return (dbc1 <= dbc2) ? index1 : index2; + } + + // ##### + void processRun3( + ColEvSels const& cols, + FullTracksIU const& tracks, + BCsRun3 const& bcs, + aod::FT0s const&) + { + int runNumber = bcs.iteratorAt(0).runNumber(); + if (runNumber != lastRunNumber) { + lastRunNumber = runNumber; // do it only once + + int64_t tsSOR = 0; // dummy start-of-run timestamp + int64_t tsEOR = 1; // dummy end-of-run timestamp + + if (runNumber >= 500000) { + auto runInfo = o2::parameters::AggregatedRunInfo::buildAggregatedRunInfo(o2::ccdb::BasicCCDBManager::instance(), runNumber); + // first bc of the first orbit + bcSOR = runInfo.orbitSOR * o2::constants::lhc::LHCMaxBunches; + // duration of TF in bcs + nBCsPerTF = runInfo.orbitsPerTF * o2::constants::lhc::LHCMaxBunches; + + // start-of-run timestamp + tsSOR = runInfo.sor; + // end-of-run timestamp + tsEOR = runInfo.eor; + + LOGP(info, "bcSOR = {}, nBCsPerTF = {}", bcSOR, nBCsPerTF); + } + + minSec = floor(tsSOR / 1000.); + maxSec = ceil(tsEOR / 1000.); + int nTimeBins = static_cast((maxSec - minSec) / timeBinWidthInSec); + double timeInterval = nTimeBins * timeBinWidthInSec; + + const AxisSpec axisSeconds{nTimeBins, 0, timeInterval, "seconds"}; + histos.add("hSecondsCollisions/sel8", "", kTH1F, {axisSeconds}); + histos.add("hSecondsCollisions/noPU", "", kTH1F, {axisSeconds}); + histos.add("hSecondsCollisions/noPU_underLine", "", kTH1F, {axisSeconds}); + histos.add("hSecondsCollisions/noPU_grassOnTheRight", "", kTH1F, {axisSeconds}); + histos.add("hSecondsCollisions/noPU_good", "", kTH1F, {axisSeconds}); + + const AxisSpec axisDiffMeanVz{80, -4, 4, ""}; + const AxisSpec axisVzNarrow{40, -10, 10, ""}; + histos.add("hSecondsCollisions/noPU_meanDiffVz", "", kTH2F, {axisSeconds, axisDiffMeanVz}); + histos.add("hSecondsCollisions/noPU_meanDiffVz_lowMult", "", kTH2F, {axisSeconds, axisDiffMeanVz}); + histos.add("hSecondsCollisions/noPU_meanDiffVz_highMult", "", kTH2F, {axisSeconds, axisDiffMeanVz}); + histos.add("hSecondsCollisions/noPU_Vz", "", kTH2F, {axisSeconds, axisVzNarrow}); + histos.add("hSecondsCollisions/noPU_VzByFT0", "", kTH2F, {axisSeconds, axisVzNarrow}); + + const AxisSpec axisVz{200, -20, 20, ""}; + histos.add("noSpecSelections/Vz", "", kTH1F, {axisVz}); + histos.add("noPU/Vz", "", kTH1F, {axisVz}); + histos.add("noPU_badVzDiff/Vz", "", kTH1F, {axisVz}); + histos.add("noPU_goodVzDiff/Vz", "", kTH1F, {axisVz}); + + } // end of runNumber check + + // vectors of TVX flags used for past-future studies + int nBCs = bcs.size(); + std::vector vIsTVX(nBCs, 0); + std::vector vGlobalBCs(nBCs, 0); + + std::vector vPastActivity(nBCs, 0); + std::vector vFutureActivity(nBCs, 0); + std::vector vNearbyFT0activity(nBCs, 0); + + // create maps from globalBC to bc index for TVX or FT0-OR fired bcs + // to be used for closest TVX (FT0-OR) searches + std::map mapGlobalBcWithTVX; + std::map mapGlobalBcWithTOR; + + // ### BC loop + for (const auto& bc : bcs) { + uint64_t globalBC = bc.globalBC(); + + int indexBc = bc.globalIndex(); + + if (bc.selection_bit(kIsBBT0A) || bc.selection_bit(kIsBBT0C)) { + mapGlobalBcWithTOR[globalBC] = indexBc; + } + if (bc.selection_bit(kIsTriggerTVX)) { + mapGlobalBcWithTVX[globalBC] = indexBc; + } + + // fill TVX flags for past-future searches + vIsTVX[indexBc] = bc.selection_bit(kIsTriggerTVX); + vGlobalBCs[indexBc] = globalBC; + + // ### checking nearby activities + int deltaIndex = 0; // backward move counts + int deltaBC = 0; // current difference wrt globalBC + int maxDeltaBC = 30; // maximum difference + + bool nearbyFT0activity = 0; + + // past + bool pastActivityFT0 = 0; + // bool pastActivityFDD = 0; + bool pastActivityFV0 = 0; + while (deltaBC < maxDeltaBC) { + deltaIndex++; + if (bc.globalIndex() - deltaIndex < 0) { + break; + } + const auto& bcPast = bcs.iteratorAt(bc.globalIndex() - deltaIndex); + deltaBC = globalBC - bcPast.globalBC(); + if (deltaBC < maxDeltaBC) { + pastActivityFT0 |= bcPast.has_ft0(); + pastActivityFV0 |= bcPast.has_fv0a(); + // pastActivityFDD |= bcPast.has_fdd(); + } + if (deltaBC < 2) { + if (bcPast.has_ft0()) { + std::bitset<8> triggers = bcPast.ft0().triggerMask(); + nearbyFT0activity |= (triggers[o2::ft0::RecPoints::ETriggerBits::kIsActiveSideA] || triggers[o2::ft0::RecPoints::ETriggerBits::kIsActiveSideC]); + } + } + } + // bool pastActivity = pastActivityFT0 | pastActivityFV0 | pastActivityFDD; + bool pastActivity = pastActivityFT0 | pastActivityFV0; // | pastActivityFDD; + vPastActivity[indexBc] = pastActivity; + + // future + deltaIndex = 0; + deltaBC = 0; + bool futureActivityFT0 = 0; + bool futureActivityFDD = 0; + bool futureActivityFV0 = 0; + while (deltaBC < maxDeltaBC) { + deltaIndex++; + if (bc.globalIndex() + deltaIndex >= bcs.size()) { + break; + } + const auto& bcFuture = bcs.iteratorAt(bc.globalIndex() + deltaIndex); + deltaBC = bcFuture.globalBC() - globalBC; + if (deltaBC < maxDeltaBC) { + futureActivityFT0 |= bcFuture.has_ft0(); + futureActivityFV0 |= bcFuture.has_fv0a(); + futureActivityFDD |= bcFuture.has_fdd(); + } + if (deltaBC < 2) { + if (bcFuture.has_ft0()) { + std::bitset<8> triggers = bcFuture.ft0().triggerMask(); + nearbyFT0activity |= (triggers[o2::ft0::RecPoints::ETriggerBits::kIsActiveSideA] || triggers[o2::ft0::RecPoints::ETriggerBits::kIsActiveSideC]); + } + } + } + bool futureActivity = futureActivityFT0 | futureActivityFV0 | futureActivityFDD; + vFutureActivity[indexBc] = futureActivity; + vNearbyFT0activity[indexBc] = nearbyFT0activity; + + // monitor BCs with nearby activity: + + int localBC = globalBC % nBCsPerOrbit; + if (bc.has_fv0a()) { + histos.fill(HIST("bcQA/hBcFV0"), localBC); + if (pastActivity) + histos.fill(HIST("bcQA/pastActivity/hBcFV0"), localBC); + if (futureActivity) + histos.fill(HIST("bcQA/futureActivity/hBcFV0"), localBC); + if (!pastActivity) + histos.fill(HIST("bcQA/noPastActivity/hBcFV0"), localBC); + if (!futureActivity) + histos.fill(HIST("bcQA/noFutureActivity/hBcFV0"), localBC); + if (!pastActivity && !futureActivity) + histos.fill(HIST("bcQA/noPastFutureActivity/hBcFV0"), localBC); + } + if (bc.has_ft0()) { + histos.fill(HIST("bcQA/hBcFT0"), localBC); + if (pastActivity) + histos.fill(HIST("bcQA/pastActivity/hBcFT0"), localBC); + if (futureActivity) + histos.fill(HIST("bcQA/futureActivity/hBcFT0"), localBC); + if (!pastActivity) + histos.fill(HIST("bcQA/noPastActivity/hBcFT0"), localBC); + if (!futureActivity) + histos.fill(HIST("bcQA/noFutureActivity/hBcFT0"), localBC); + if (!pastActivity && !futureActivity) + histos.fill(HIST("bcQA/noPastFutureActivity/hBcFT0"), localBC); + + // spec bits: + std::bitset<8> triggers = bc.ft0().triggerMask(); + bool isTVX = bc.selection_bit(kIsTriggerTVX); + if (triggers[o2::ft0::RecPoints::ETriggerBits::kIsActiveSideA]) { + histos.fill(HIST("bcQA/specFT0bits/hBc_kIsActiveSideA"), localBC); + if (isTVX) + histos.fill(HIST("bcQA/specFT0bits/hBc_kIsActiveSideA_inTVX"), localBC); + } + if (triggers[o2::ft0::RecPoints::ETriggerBits::kIsActiveSideC]) { + histos.fill(HIST("bcQA/specFT0bits/hBc_kIsActiveSideC"), localBC); + if (isTVX) + histos.fill(HIST("bcQA/specFT0bits/hBc_kIsActiveSideC_inTVX"), localBC); + } + if (triggers[o2::ft0::RecPoints::ETriggerBits::kIsFlangeEvent]) { + histos.fill(HIST("bcQA/specFT0bits/hBc_kIsFlangeEvent"), localBC); + if (isTVX) + histos.fill(HIST("bcQA/specFT0bits/hBc_kIsFlangeEvent_inTVX"), localBC); + } + } + if (bc.has_fdd()) { + histos.fill(HIST("bcQA/hBcFDD"), localBC); + if (pastActivity) + histos.fill(HIST("bcQA/pastActivity/hBcFDD"), localBC); + if (futureActivity) + histos.fill(HIST("bcQA/futureActivity/hBcFDD"), localBC); + } + if (bc.has_zdc()) { + histos.fill(HIST("bcQA/hBcZDC"), localBC); + if (pastActivity) + histos.fill(HIST("bcQA/pastActivity/hBcZDC"), localBC); + if (futureActivity) + histos.fill(HIST("bcQA/futureActivity/hBcZDC"), localBC); + } + + } // end of bc loop + + // ### collision loop + for (const auto& col : cols) { + if (std::abs(col.posZ()) > 10) + continue; + + const auto& foundBC = col.foundBC_as(); + uint64_t globalBC = foundBC.globalBC(); + // uint64_t orbit = globalBC / nBCsPerOrbit; + int localBC = globalBC % nBCsPerOrbit; + + int64_t ts = foundBC.timestamp(); + double secFromSOR = ts / 1000. - minSec; + + // search for nearest ft0a&ft0c entry + uint64_t globalOrigBC = col.bc_as().globalBC(); + int32_t indexClosestTVX = findClosest(globalOrigBC, mapGlobalBcWithTVX); + int bcToClosestTVXdiff = static_cast(globalOrigBC - vGlobalBCs[indexClosestTVX]); + + // selection decisions: + bool noPU = col.selection_bit(kNoSameBunchPileup); + bool pvTOFmatched = col.selection_bit(kIsVertexTOFmatched); + bool pvTRDmatched = col.selection_bit(kIsVertexTRDmatched); + bool narrowTimeVeto = col.selection_bit(kNoCollInTimeRangeNarrow); + bool strictTimeVeto = col.selection_bit(kNoCollInTimeRangeStrict); + bool noCollSameROF = col.selection_bit(kNoCollInRofStrict); + bool bcDiffWrtClosestTVXCut = (bcToClosestTVXdiff == 0); + + auto bcIndex = foundBC.globalIndex(); + // bool noNearbyActivity = (vPastActivity[bcIndex] == 0 && vFutureActivity[bcIndex] == 0); + bool noPastActivity = (vPastActivity[bcIndex] == 0); + + // ### count tracks of different types + int nPVtracks = 0; + int nGlobalTracksPV = 0; + int nGlobalTracksAll = 0; + // int nTOFtracks = 0; + auto tracksGrouped = tracks.sliceBy(perCollision, col.globalIndex()); + for (const auto& track : tracksGrouped) { + if (track.itsNCls() < 5) + continue; + if (track.pt() < 0.2 || track.pt() > 10) + continue; + if (std::abs(track.eta()) > 0.8) + continue; + + if (track.hasITS() && track.hasTPC() && track.tpcNClsFound() > 50 && track.tpcNClsCrossedRows() > 50 && track.tpcChi2NCl() < 4) + nGlobalTracksAll++; + + if (!track.isPVContributor()) { + continue; + } + nPVtracks++; + if (track.hasITS() && track.hasTPC() && track.tpcNClsFound() > 50 && track.tpcNClsCrossedRows() > 50 && track.tpcChi2NCl() < 4) + nGlobalTracksPV++; + } // end of track loop + + histos.fill(HIST("hNcontribColFromData"), nPVtracks); + if (col.selection_bit(kIsTriggerTVX)) + histos.fill(HIST("hNcontribAccFromData"), nPVtracks); + + bool hasFT0 = foundBC.has_ft0(); + bool hasFV0A = foundBC.has_fv0a(); + + // bool noFT0activityNearby = false; + bool noFT0activityNearby = (vNearbyFT0activity[bcIndex] == 0); + // check kIsFlangeEvent + if (hasFT0) { + std::bitset<8> triggers = foundBC.ft0().triggerMask(); + if (triggers[o2::ft0::RecPoints::ETriggerBits::kIsFlangeEvent]) + noFT0activityNearby = false; + } + + float vZ = col.posZ(); + float vZft0 = hasFT0 ? foundBC.ft0().posZ() : -1000; + float diffVz = vZft0 - vZ; + + float multV0A = hasFV0A ? col.multFV0A() : 0; + + float multT0A = hasFT0 ? col.multFT0A() : 0; + float multT0C = hasFT0 ? col.multFT0C() : 0; + float multT0M = multT0A + multT0C; + if (hasFT0) { + float multT0A_uncorr = foundBC.ft0().sumAmpA(); + float multT0C_uncorr = foundBC.ft0().sumAmpC(); + float multT0M_uncorr = multT0A_uncorr + multT0C_uncorr; + + histos.fill(HIST("multT0M_vs_multSumFT0"), multT0M, multT0M_uncorr); + } + + // vZ diff (FT0 vs by tracks) + bool badVzDiff = 0; + if (confUseDiffVzCutFromEvSel) + badVzDiff = !col.selection_bit(kIsGoodZvtxFT0vsPV); + else { // tune by hand + float meanDiff = 0.0; // cm + // O-O + if (lastRunNumber == 564356) + meanDiff = -0.01; + if (lastRunNumber == 564359) + meanDiff = -0.17; + if (lastRunNumber == 564373) + meanDiff = 0.99; + if (lastRunNumber == 564374) + meanDiff = 0.57; + // Ne-Ne + if (lastRunNumber == 564468) + meanDiff = -0.51; + if (lastRunNumber == 564468) + meanDiff = -0.60; + + float stdDev = (multT0M > 10) ? 0.144723 + 13.5345 / sqrt(multT0M) : 1.5; // cm + if (multT0M > 5000) + stdDev = stdDev > 0.2 ? stdDev : 0.2; // 0.35; // cm + badVzDiff = diffVz < (meanDiff - stdDev * nSigmaForVzDiff - safetyDiffVzMargin) || diffVz > (meanDiff + stdDev * nSigmaForVzDiff + safetyDiffVzMargin); + } + + bool underLine = false; + if (hasFT0 && nPVtracks < 45. / 40000 * multV0A - 4 && nPVtracks < 20) { + underLine = true; + } + bool grassOnTheRight = false; + if (hasFT0 && nPVtracks < 220. / 40000 * multV0A - 100 && nPVtracks >= 25) { + grassOnTheRight = true; + } + + // study bc diff wrt original bc: + // auto bc = col.bc_as(); + auto bcOriginal = globalOrigBC % 3564; + float bcDiffWrtOriginal = bcOriginal - localBC; + bool bcDiffWrtOriginalBcCut = (bcDiffWrtOriginal == 0); + + // SPEC REMOVAL OF BC RANGES + // if (bcOriginal > 1200 && bcOriginal < 1300) + // continue; + // if (bcOriginal > 1700 && bcOriginal < 1900) + // continue; + + int nContributors = col.numContrib(); + float timeRes = col.collisionTimeRes(); + // int64_t bcInTF = (globalBC - bcSOR) % nBCsPerTF; + // if (col.selection_bit(kIsVertexTOFmatched)) { + // histos.fill(HIST("hColBcDiffVsNcontribWithTOF"), nContributors, bcToClosestTVXdiff); + // histos.fill(HIST("hColTimeResVsNcontribWithTOF"), nContributors, timeRes); + // histos.fill(HIST("hBcColTOF"), localBC); + // } + + float vChi2 = col.chi2(); + float vChi2perContrib = nContributors > 0 ? vChi2 / nContributors : 0; + bool goodVertexChi2 = (vChi2perContrib < 3.5); + + histos.fill(HIST("noSpecSelections/hBcColNoSel8"), localBC); + histos.fill(HIST("noSpecSelections/hBcOrigNoSel8"), bcOriginal); + histos.fill(HIST("noSpecSelections/Vz"), vZ); + + if (noPU) { + histos.fill(HIST("noPU/hBcColNoSel8"), localBC); + histos.fill(HIST("noPU/hBcOrigNoSel8"), bcOriginal); + histos.fill(HIST("noPU/Vz"), vZ); + } + if (noPU && pvTOFmatched) { + histos.fill(HIST("noPU_pvTOFmatched/hBcColNoSel8"), localBC); + } + if (noPU && pvTRDmatched) { + histos.fill(HIST("noPU_pvTRDmatched/hBcColNoSel8"), localBC); + } + if (noPU && !pvTRDmatched) { + histos.fill(HIST("noPU_notTRDmatched/hBcColNoSel8"), localBC); + } + if (bcDiffWrtClosestTVXCut) { + histos.fill(HIST("bcDiffWrtClosestTVXCut/hBcColNoSel8"), localBC); + } + if (noPU && bcDiffWrtOriginalBcCut) { + histos.fill(HIST("noPU_bcDiffWrtOriginalBcCut/hBcColNoSel8"), localBC); + } + if (noPU && noPastActivity) { + histos.fill(HIST("noPU_noPastActivity/hBcColNoSel8"), localBC); + } + if (noPU && noFT0activityNearby) { + histos.fill(HIST("noPU_noFT0activityNearby/hBcColNoSel8"), localBC); + } + if (noPU && badVzDiff) { + histos.fill(HIST("noPU_badVzDiff/hBcColNoSel8"), localBC); + histos.fill(HIST("noPU_badVzDiff/Vz"), vZ); + } + if (noPU && !badVzDiff) { + histos.fill(HIST("noPU_goodVzDiff/hBcColNoSel8"), localBC); + histos.fill(HIST("noPU_goodVzDiff/Vz"), vZ); + } + if (noPU && !badVzDiff && narrowTimeVeto) { + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/hBcColNoSel8"), localBC); + } + if (noPU && !badVzDiff && strictTimeVeto) { + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/hBcColNoSel8"), localBC); + } + if (noPU && goodVertexChi2) { + histos.fill(HIST("noPU_goodVertexChi2/hBcColNoSel8"), localBC); + } + if (narrowTimeVeto) { + histos.fill(HIST("narrowTimeVeto/hBcColNoSel8"), localBC); + } + if (strictTimeVeto) { + histos.fill(HIST("strictTimeVeto/hBcColNoSel8"), localBC); + } + if (noCollSameROF) { + histos.fill(HIST("noCollSameROF/hBcColNoSel8"), localBC); + } + if (underLine) { + histos.fill(HIST("lowMultCut/hBcColNoSel8"), localBC); + histos.fill(HIST("lowMultCut/hBcOrigNoSel8"), bcOriginal); + } + if (noPU && underLine) { + histos.fill(HIST("noPU_lowMultCut/hBcColNoSel8"), localBC); + histos.fill(HIST("noPU_lowMultCut/hBcOrigNoSel8"), bcOriginal); + } + if (grassOnTheRight) { + histos.fill(HIST("highMultCloudCut/hBcColNoSel8"), localBC); + histos.fill(HIST("highMultCloudCut/hBcOrigNoSel8"), bcOriginal); + } + if (noPU && grassOnTheRight) { + histos.fill(HIST("noPU_highMultCloudCut/hBcColNoSel8"), localBC); + histos.fill(HIST("noPU_highMultCloudCut/hBcOrigNoSel8"), bcOriginal); + } + if (noPU && !badVzDiff && pvTOFmatched) { // noPileup_cutByVzDiff_pvTOF_noFT0act + histos.fill(HIST("noPU_cutByVzDiff_pvTOF/hBcColNoSel8"), localBC); + } + + // only here cut on sel8: + if (!col.sel8()) + continue; + + // vs time + histos.fill(HIST("hSecondsCollisions/sel8"), secFromSOR); + if (noPU) { + histos.fill(HIST("hSecondsCollisions/noPU"), secFromSOR); + if (underLine) + histos.fill(HIST("hSecondsCollisions/noPU_underLine"), secFromSOR); + if (grassOnTheRight) + histos.fill(HIST("hSecondsCollisions/noPU_grassOnTheRight"), secFromSOR); + if (!underLine && !grassOnTheRight) + histos.fill(HIST("hSecondsCollisions/noPU_good"), secFromSOR); + + histos.fill(HIST("hSecondsCollisions/noPU_Vz"), secFromSOR, vZ); + histos.fill(HIST("hSecondsCollisions/noPU_VzByFT0"), secFromSOR, vZft0); + + if (std::abs(diffVz) < 4) { + histos.fill(HIST("hSecondsCollisions/noPU_meanDiffVz"), secFromSOR, diffVz); + if (multT0M < 1000) + histos.fill(HIST("hSecondsCollisions/noPU_meanDiffVz_lowMult"), secFromSOR, diffVz); + if (multT0M > 10000) + histos.fill(HIST("hSecondsCollisions/noPU_meanDiffVz_highMult"), secFromSOR, diffVz); + } + } + + histos.fill(HIST("noSpecSelections/hBcTVX"), localBC); + histos.fill(HIST("noSpecSelections/hBcOrig"), bcOriginal); + histos.fill(HIST("noSpecSelections/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("noSpecSelections/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("noSpecSelections/hVertexChi2VsNcontrib"), nContributors, vChi2perContrib); + histos.fill(HIST("noSpecSelections/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + + if (noPU) { + histos.fill(HIST("noPU/hBcTVX"), localBC); + histos.fill(HIST("noPU/hBcOrig"), bcOriginal); + histos.fill(HIST("noPU/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("noPU/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("noPU/hVertexChi2VsNcontrib"), nContributors, vChi2perContrib); + histos.fill(HIST("noPU/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (noPU && pvTOFmatched) { + histos.fill(HIST("noPU_pvTOFmatched/hBcTVX"), localBC); + histos.fill(HIST("noPU_pvTOFmatched/hBcOrig"), bcOriginal); + histos.fill(HIST("noPU_pvTOFmatched/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("noPU_pvTOFmatched/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("noPU_pvTOFmatched/hVertexChi2VsNcontrib"), nContributors, vChi2perContrib); + histos.fill(HIST("noPU_pvTOFmatched/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (noPU && pvTRDmatched) { + histos.fill(HIST("noPU_pvTRDmatched/hBcTVX"), localBC); + histos.fill(HIST("noPU_pvTRDmatched/hBcOrig"), bcOriginal); + histos.fill(HIST("noPU_pvTRDmatched/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("noPU_pvTRDmatched/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("noPU_pvTRDmatched/hVertexChi2VsNcontrib"), nContributors, vChi2perContrib); + histos.fill(HIST("noPU_pvTRDmatched/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (noPU && !pvTRDmatched) { + histos.fill(HIST("noPU_notTRDmatched/hBcTVX"), localBC); + histos.fill(HIST("noPU_notTRDmatched/hBcOrig"), bcOriginal); + histos.fill(HIST("noPU_notTRDmatched/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("noPU_notTRDmatched/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("noPU_notTRDmatched/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (bcDiffWrtClosestTVXCut) { + histos.fill(HIST("bcDiffWrtClosestTVXCut/hBcTVX"), localBC); + histos.fill(HIST("bcDiffWrtClosestTVXCut/hBcOrig"), bcOriginal); + histos.fill(HIST("bcDiffWrtClosestTVXCut/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("bcDiffWrtClosestTVXCut/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("bcDiffWrtClosestTVXCut/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (noPU && bcDiffWrtOriginalBcCut) { + histos.fill(HIST("noPU_bcDiffWrtOriginalBcCut/hBcTVX"), localBC); + histos.fill(HIST("noPU_bcDiffWrtOriginalBcCut/hBcOrig"), bcOriginal); + histos.fill(HIST("noPU_bcDiffWrtOriginalBcCut/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("noPU_bcDiffWrtOriginalBcCut/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("noPU_bcDiffWrtOriginalBcCut/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (noPU && noPastActivity) { + histos.fill(HIST("noPU_noPastActivity/hBcTVX"), localBC); + histos.fill(HIST("noPU_noPastActivity/hBcOrig"), bcOriginal); + histos.fill(HIST("noPU_noPastActivity/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("noPU_noPastActivity/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("noPU_noPastActivity/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (noPU && noFT0activityNearby) { + histos.fill(HIST("noPU_noFT0activityNearby/hBcTVX"), localBC); + histos.fill(HIST("noPU_noFT0activityNearby/hBcOrig"), bcOriginal); + histos.fill(HIST("noPU_noFT0activityNearby/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("noPU_noFT0activityNearby/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("noPU_noFT0activityNearby/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (noPU && badVzDiff) { + histos.fill(HIST("noPU_badVzDiff/hBcTVX"), localBC); + histos.fill(HIST("noPU_badVzDiff/hBcOrig"), bcOriginal); + histos.fill(HIST("noPU_badVzDiff/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("noPU_badVzDiff/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("noPU_badVzDiff/hVertexChi2VsNcontrib"), nContributors, vChi2perContrib); + histos.fill(HIST("noPU_badVzDiff/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (noPU && !badVzDiff) { + histos.fill(HIST("noPU_goodVzDiff/hBcTVX"), localBC); + histos.fill(HIST("noPU_goodVzDiff/hBcOrig"), bcOriginal); + histos.fill(HIST("noPU_goodVzDiff/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("noPU_goodVzDiff/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("noPU_goodVzDiff/hVertexChi2VsNcontrib"), nContributors, vChi2perContrib); + histos.fill(HIST("noPU_goodVzDiff/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (noPU && !badVzDiff && narrowTimeVeto) { + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/hBcTVX"), localBC); + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/hBcOrig"), bcOriginal); + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/hVertexChi2VsNcontrib"), nContributors, vChi2perContrib); + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (noPU && !badVzDiff && strictTimeVeto) { + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/hBcTVX"), localBC); + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/hBcOrig"), bcOriginal); + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/hVertexChi2VsNcontrib"), nContributors, vChi2perContrib); + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (noPU && goodVertexChi2) { + histos.fill(HIST("noPU_goodVertexChi2/hBcTVX"), localBC); + histos.fill(HIST("noPU_goodVertexChi2/hBcOrig"), bcOriginal); + histos.fill(HIST("noPU_goodVertexChi2/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("noPU_goodVertexChi2/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("noPU_goodVertexChi2/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (narrowTimeVeto) { + histos.fill(HIST("narrowTimeVeto/hBcTVX"), localBC); + histos.fill(HIST("narrowTimeVeto/hBcOrig"), bcOriginal); + histos.fill(HIST("narrowTimeVeto/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("narrowTimeVeto/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("narrowTimeVeto/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (strictTimeVeto) { + histos.fill(HIST("strictTimeVeto/hBcTVX"), localBC); + histos.fill(HIST("strictTimeVeto/hBcOrig"), bcOriginal); + histos.fill(HIST("strictTimeVeto/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("strictTimeVeto/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("strictTimeVeto/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (noCollSameROF) { + histos.fill(HIST("noCollSameROF/hBcTVX"), localBC); + histos.fill(HIST("noCollSameROF/hBcOrig"), bcOriginal); + histos.fill(HIST("noCollSameROF/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("noCollSameROF/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("noCollSameROF/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (noPU && underLine) { + histos.fill(HIST("noPU_lowMultCut/hBcTVX"), localBC); + histos.fill(HIST("noPU_lowMultCut/hBcOrig"), bcOriginal); + histos.fill(HIST("noPU_lowMultCut/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("noPU_lowMultCut/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("noPU_lowMultCut/hVertexChi2VsNcontrib"), nContributors, vChi2perContrib); + histos.fill(HIST("noPU_lowMultCut/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (noPU && grassOnTheRight) { + histos.fill(HIST("noPU_highMultCloudCut/hBcTVX"), localBC); + histos.fill(HIST("noPU_highMultCloudCut/hBcOrig"), bcOriginal); + histos.fill(HIST("noPU_highMultCloudCut/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("noPU_highMultCloudCut/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("noPU_highMultCloudCut/hVertexChi2VsNcontrib"), nContributors, vChi2perContrib); + histos.fill(HIST("noPU_highMultCloudCut/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (noPU && !badVzDiff && pvTOFmatched) { // noPileup_cutByVzDiff_pvTOF_noFT0act + histos.fill(HIST("noPU_cutByVzDiff_pvTOF/hBcTVX"), localBC); + histos.fill(HIST("noPU_cutByVzDiff_pvTOF/hBcOrig"), bcOriginal); + histos.fill(HIST("noPU_cutByVzDiff_pvTOF/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("noPU_cutByVzDiff_pvTOF/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("noPU_cutByVzDiff_pvTOF/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + if (noPU && !badVzDiff && noFT0activityNearby) { + histos.fill(HIST("noPU_cutByVzDiff_noFT0activityNearby/hBcTVX"), localBC); + histos.fill(HIST("noPU_cutByVzDiff_noFT0activityNearby/hBcOrig"), bcOriginal); + histos.fill(HIST("noPU_cutByVzDiff_noFT0activityNearby/hColBcDiffVsNcontrib"), nContributors, bcToClosestTVXdiff); + histos.fill(HIST("noPU_cutByVzDiff_noFT0activityNearby/hColTimeResVsNcontrib"), nContributors, timeRes); + histos.fill(HIST("noPU_cutByVzDiff_noFT0activityNearby/hNPVvsNch"), nPVtracks, nGlobalTracksAll); + } + + if (foundBC.has_ft0()) { + // float multT0A = foundBC.has_ft0() ? foundBC.ft0().sumAmpA() : -999.f; + // float multT0C = foundBC.has_ft0() ? foundBC.ft0().sumAmpC() : -999.f; + + histos.fill(HIST("noSpecSelections/hBcFT0"), localBC); + histos.fill(HIST("noSpecSelections/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("noSpecSelections/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("noSpecSelections/nTracksPV_vs_T0A"), multT0A, nPVtracks); + histos.fill(HIST("noSpecSelections/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("noSpecSelections/nTracksPV_vs_T0C"), multT0C, nPVtracks); + histos.fill(HIST("noSpecSelections/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + + if (noPU) { + histos.fill(HIST("noPU/hBcFT0"), localBC); + histos.fill(HIST("noPU/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("noPU/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("noPU/nTracksPV_vs_T0A"), multT0A, nPVtracks); + histos.fill(HIST("noPU/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("noPU/nTracksPV_vs_T0C"), multT0C, nPVtracks); + histos.fill(HIST("noPU/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (noPU && pvTOFmatched) { + histos.fill(HIST("noPU_pvTOFmatched/hBcFT0"), localBC); + histos.fill(HIST("noPU_pvTOFmatched/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("noPU_pvTOFmatched/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("noPU_pvTOFmatched/nTracksPV_vs_T0A"), multT0A, nPVtracks); + histos.fill(HIST("noPU_pvTOFmatched/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("noPU_pvTOFmatched/nTracksPV_vs_T0C"), multT0C, nPVtracks); + histos.fill(HIST("noPU_pvTOFmatched/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (noPU && pvTRDmatched) { + histos.fill(HIST("noPU_pvTRDmatched/hBcFT0"), localBC); + histos.fill(HIST("noPU_pvTRDmatched/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("noPU_pvTRDmatched/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("noPU_pvTRDmatched/nTracksPV_vs_T0A"), multT0A, nPVtracks); + histos.fill(HIST("noPU_pvTRDmatched/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("noPU_pvTRDmatched/nTracksPV_vs_T0C"), multT0C, nPVtracks); + histos.fill(HIST("noPU_pvTRDmatched/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (noPU && !pvTRDmatched) { + histos.fill(HIST("noPU_notTRDmatched/hBcFT0"), localBC); + histos.fill(HIST("noPU_notTRDmatched/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("noPU_notTRDmatched/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("noPU_notTRDmatched/nTracksPV_vs_T0A"), multT0A, nPVtracks); + histos.fill(HIST("noPU_notTRDmatched/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("noPU_notTRDmatched/nTracksPV_vs_T0C"), multT0C, nPVtracks); + histos.fill(HIST("noPU_notTRDmatched/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (bcDiffWrtClosestTVXCut) { + histos.fill(HIST("bcDiffWrtClosestTVXCut/hBcFT0"), localBC); + histos.fill(HIST("bcDiffWrtClosestTVXCut/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("bcDiffWrtClosestTVXCut/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("bcDiffWrtClosestTVXCut/nTracksPV_vs_T0A"), multT0A, nPVtracks); + // histos.fill(HIST("bcDiffWrtClosestTVXCut/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("bcDiffWrtClosestTVXCut/nTracksPV_vs_T0C"), multT0C, nPVtracks); + // histos.fill(HIST("bcDiffWrtClosestTVXCut/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (noPU && bcDiffWrtOriginalBcCut) { + histos.fill(HIST("noPU_bcDiffWrtOriginalBcCut/hBcFT0"), localBC); + histos.fill(HIST("noPU_bcDiffWrtOriginalBcCut/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("noPU_bcDiffWrtOriginalBcCut/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("noPU_bcDiffWrtOriginalBcCut/nTracksPV_vs_T0A"), multT0A, nPVtracks); + // histos.fill(HIST("noPU_bcDiffWrtOriginalBcCut/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("noPU_bcDiffWrtOriginalBcCut/nTracksPV_vs_T0C"), multT0C, nPVtracks); + // histos.fill(HIST("noPU_bcDiffWrtOriginalBcCut/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (noPU && badVzDiff) { + histos.fill(HIST("noPU_badVzDiff/hBcFT0"), localBC); + histos.fill(HIST("noPU_badVzDiff/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("noPU_badVzDiff/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("noPU_badVzDiff/nTracksPV_vs_T0A"), multT0A, nPVtracks); + histos.fill(HIST("noPU_badVzDiff/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("noPU_badVzDiff/nTracksPV_vs_T0C"), multT0C, nPVtracks); + histos.fill(HIST("noPU_badVzDiff/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (noPU && !badVzDiff) { + histos.fill(HIST("noPU_goodVzDiff/hBcFT0"), localBC); + histos.fill(HIST("noPU_goodVzDiff/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("noPU_goodVzDiff/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("noPU_goodVzDiff/nTracksPV_vs_T0A"), multT0A, nPVtracks); + histos.fill(HIST("noPU_goodVzDiff/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("noPU_goodVzDiff/nTracksPV_vs_T0C"), multT0C, nPVtracks); + histos.fill(HIST("noPU_goodVzDiff/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (noPU && !badVzDiff && narrowTimeVeto) { + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/hBcFT0"), localBC); + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/nTracksPV_vs_T0A"), multT0A, nPVtracks); + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/nTracksPV_vs_T0C"), multT0C, nPVtracks); + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (noPU && !badVzDiff && strictTimeVeto) { + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/hBcFT0"), localBC); + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/nTracksPV_vs_T0A"), multT0A, nPVtracks); + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/nTracksPV_vs_T0C"), multT0C, nPVtracks); + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (noPU && noPastActivity) { + histos.fill(HIST("noPU_noPastActivity/hBcFT0"), localBC); + histos.fill(HIST("noPU_noPastActivity/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("noPU_noPastActivity/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("noPU_noPastActivity/nTracksPV_vs_T0A"), multT0A, nPVtracks); + // histos.fill(HIST("noPU_noPastActivity/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("noPU_noPastActivity/nTracksPV_vs_T0C"), multT0C, nPVtracks); + // histos.fill(HIST("noPU_noPastActivity/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (noPU && noFT0activityNearby) { + histos.fill(HIST("noPU_noFT0activityNearby/hBcFT0"), localBC); + histos.fill(HIST("noPU_noFT0activityNearby/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("noPU_noFT0activityNearby/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("noPU_noFT0activityNearby/nTracksPV_vs_T0A"), multT0A, nPVtracks); + // histos.fill(HIST("noPU_noFT0activityNearby/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("noPU_noFT0activityNearby/nTracksPV_vs_T0C"), multT0C, nPVtracks); + // histos.fill(HIST("noPU_noFT0activityNearby/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (noPU && goodVertexChi2) { + histos.fill(HIST("noPU_goodVertexChi2/hBcFT0"), localBC); + histos.fill(HIST("noPU_goodVertexChi2/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("noPU_goodVertexChi2/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("noPU_goodVertexChi2/nTracksPV_vs_T0A"), multT0A, nPVtracks); + // histos.fill(HIST("noPU_goodVertexChi2/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("noPU_goodVertexChi2/nTracksPV_vs_T0C"), multT0C, nPVtracks); + // histos.fill(HIST("noPU_goodVertexChi2/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (narrowTimeVeto) { + histos.fill(HIST("narrowTimeVeto/hBcFT0"), localBC); + histos.fill(HIST("narrowTimeVeto/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("narrowTimeVeto/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("narrowTimeVeto/nTracksPV_vs_T0A"), multT0A, nPVtracks); + histos.fill(HIST("narrowTimeVeto/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("narrowTimeVeto/nTracksPV_vs_T0C"), multT0C, nPVtracks); + histos.fill(HIST("narrowTimeVeto/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (strictTimeVeto) { + histos.fill(HIST("strictTimeVeto/hBcFT0"), localBC); + histos.fill(HIST("strictTimeVeto/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("strictTimeVeto/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("strictTimeVeto/nTracksPV_vs_T0A"), multT0A, nPVtracks); + histos.fill(HIST("strictTimeVeto/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("strictTimeVeto/nTracksPV_vs_T0C"), multT0C, nPVtracks); + histos.fill(HIST("strictTimeVeto/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (noCollSameROF) { + histos.fill(HIST("noCollSameROF/hBcFT0"), localBC); + histos.fill(HIST("noCollSameROF/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("noCollSameROF/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("noCollSameROF/nTracksPV_vs_T0A"), multT0A, nPVtracks); + histos.fill(HIST("noCollSameROF/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("noCollSameROF/nTracksPV_vs_T0C"), multT0C, nPVtracks); + histos.fill(HIST("noCollSameROF/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (noPU && underLine) { + histos.fill(HIST("noPU_lowMultCut/hBcFT0"), localBC); + histos.fill(HIST("noPU_lowMultCut/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("noPU_lowMultCut/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("noPU_lowMultCut/nTracksPV_vs_T0A"), multT0A, nPVtracks); + histos.fill(HIST("noPU_lowMultCut/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("noPU_lowMultCut/nTracksPV_vs_T0C"), multT0C, nPVtracks); + histos.fill(HIST("noPU_lowMultCut/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (noPU && grassOnTheRight) { + histos.fill(HIST("noPU_highMultCloudCut/hBcFT0"), localBC); + histos.fill(HIST("noPU_highMultCloudCut/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("noPU_highMultCloudCut/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("noPU_highMultCloudCut/nTracksPV_vs_T0A"), multT0A, nPVtracks); + histos.fill(HIST("noPU_highMultCloudCut/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("noPU_highMultCloudCut/nTracksPV_vs_T0C"), multT0C, nPVtracks); + histos.fill(HIST("noPU_highMultCloudCut/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (noPU && !badVzDiff && pvTOFmatched) { // noPileup_cutByVzDiff_pvTOF_noFT0act + histos.fill(HIST("noPU_cutByVzDiff_pvTOF/hBcFT0"), localBC); + histos.fill(HIST("noPU_cutByVzDiff_pvTOF/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("noPU_cutByVzDiff_pvTOF/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("noPU_cutByVzDiff_pvTOF/nTracksPV_vs_T0A"), multT0A, nPVtracks); + histos.fill(HIST("noPU_cutByVzDiff_pvTOF/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("noPU_cutByVzDiff_pvTOF/nTracksPV_vs_T0C"), multT0C, nPVtracks); + histos.fill(HIST("noPU_cutByVzDiff_pvTOF/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + if (noPU && !badVzDiff && noFT0activityNearby) { + histos.fill(HIST("noPU_cutByVzDiff_noFT0activityNearby/hBcFT0"), localBC); + histos.fill(HIST("noPU_cutByVzDiff_noFT0activityNearby/hVtxFT0VsVtxCol"), vZft0, vZ); + histos.fill(HIST("noPU_cutByVzDiff_noFT0activityNearby/hVtxFT0MinusVtxColVsMultT0M"), diffVz, multT0A + multT0C); + histos.fill(HIST("noPU_cutByVzDiff_noFT0activityNearby/nTracksPV_vs_T0A"), multT0A, nPVtracks); + // histos.fill(HIST("noPU_cutByVzDiff_noFT0activityNearby/nTracksGlobal_vs_T0A"), multT0A, nGlobalTracksPV); + histos.fill(HIST("noPU_cutByVzDiff_noFT0activityNearby/nTracksPV_vs_T0C"), multT0C, nPVtracks); + // histos.fill(HIST("noPU_cutByVzDiff_noFT0activityNearby/nTracksGlobal_vs_T0C"), multT0C, nGlobalTracksPV); + } + } + + if (foundBC.has_fv0a()) { + histos.fill(HIST("noSpecSelections/hBcFV0"), localBC); + histos.fill(HIST("noSpecSelections/nTracksPV_vs_V0A"), multV0A, nPVtracks); + histos.fill(HIST("noSpecSelections/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + if (noPU) { + histos.fill(HIST("noPU/hBcFV0"), localBC); + histos.fill(HIST("noPU/nTracksPV_vs_V0A"), multV0A, nPVtracks); + histos.fill(HIST("noPU/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (noPU && pvTOFmatched) { + histos.fill(HIST("noPU_pvTOFmatched/hBcFV0"), localBC); + histos.fill(HIST("noPU_pvTOFmatched/nTracksPV_vs_V0A"), multV0A, nPVtracks); + histos.fill(HIST("noPU_pvTOFmatched/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (noPU && pvTRDmatched) { + histos.fill(HIST("noPU_pvTRDmatched/hBcFV0"), localBC); + histos.fill(HIST("noPU_pvTRDmatched/nTracksPV_vs_V0A"), multV0A, nPVtracks); + histos.fill(HIST("noPU_pvTRDmatched/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (noPU && !pvTRDmatched) { + histos.fill(HIST("noPU_notTRDmatched/hBcFV0"), localBC); + histos.fill(HIST("noPU_notTRDmatched/nTracksPV_vs_V0A"), multV0A, nPVtracks); + histos.fill(HIST("noPU_notTRDmatched/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (noPU && pvTOFmatched && !pvTRDmatched) { // SPEC CHECK! + histos.fill(HIST("noPU_pvTOFmatched_notTRDmatched/hBcFV0"), localBC); + histos.fill(HIST("noPU_pvTOFmatched_notTRDmatched/nTracksPV_vs_V0A"), multV0A, nPVtracks); + histos.fill(HIST("noPU_pvTOFmatched_notTRDmatched/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (bcDiffWrtClosestTVXCut) { + histos.fill(HIST("bcDiffWrtClosestTVXCut/hBcFV0"), localBC); + histos.fill(HIST("bcDiffWrtClosestTVXCut/nTracksPV_vs_V0A"), multV0A, nPVtracks); + // histos.fill(HIST("bcDiffWrtClosestTVXCut/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (noPU && bcDiffWrtOriginalBcCut) { + histos.fill(HIST("noPU_bcDiffWrtOriginalBcCut/hBcFV0"), localBC); + histos.fill(HIST("noPU_bcDiffWrtOriginalBcCut/nTracksPV_vs_V0A"), multV0A, nPVtracks); + // histos.fill(HIST("noPU_bcDiffWrtOriginalBcCut/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (noPU && badVzDiff) { + histos.fill(HIST("noPU_badVzDiff/hBcFV0"), localBC); + histos.fill(HIST("noPU_badVzDiff/nTracksPV_vs_V0A"), multV0A, nPVtracks); + histos.fill(HIST("noPU_badVzDiff/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (noPU && !badVzDiff) { + histos.fill(HIST("noPU_goodVzDiff/hBcFV0"), localBC); + histos.fill(HIST("noPU_goodVzDiff/nTracksPV_vs_V0A"), multV0A, nPVtracks); + histos.fill(HIST("noPU_goodVzDiff/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (noPU && !badVzDiff && narrowTimeVeto) { + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/hBcFV0"), localBC); + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/nTracksPV_vs_V0A"), multV0A, nPVtracks); + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (noPU && !badVzDiff && strictTimeVeto) { + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/hBcFV0"), localBC); + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/nTracksPV_vs_V0A"), multV0A, nPVtracks); + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (noPU && noPastActivity) { + histos.fill(HIST("noPU_noPastActivity/hBcFV0"), localBC); + histos.fill(HIST("noPU_noPastActivity/nTracksPV_vs_V0A"), multV0A, nPVtracks); + // histos.fill(HIST("noPU_noPastActivity/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (noPU && noFT0activityNearby) { + histos.fill(HIST("noPU_noFT0activityNearby/hBcFV0"), localBC); + histos.fill(HIST("noPU_noFT0activityNearby/nTracksPV_vs_V0A"), multV0A, nPVtracks); + // histos.fill(HIST("noPU_noFT0activityNearby/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (noPU && goodVertexChi2) { + histos.fill(HIST("noPU_goodVertexChi2/hBcFV0"), localBC); + histos.fill(HIST("noPU_goodVertexChi2/nTracksPV_vs_V0A"), multV0A, nPVtracks); + // histos.fill(HIST("noPU_goodVertexChi2/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (narrowTimeVeto) { + histos.fill(HIST("narrowTimeVeto/hBcFV0"), localBC); + histos.fill(HIST("narrowTimeVeto/nTracksPV_vs_V0A"), multV0A, nPVtracks); + histos.fill(HIST("narrowTimeVeto/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (strictTimeVeto) { + histos.fill(HIST("strictTimeVeto/hBcFV0"), localBC); + histos.fill(HIST("strictTimeVeto/nTracksPV_vs_V0A"), multV0A, nPVtracks); + histos.fill(HIST("strictTimeVeto/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (noCollSameROF) { + histos.fill(HIST("noCollSameROF/hBcFV0"), localBC); + histos.fill(HIST("noCollSameROF/nTracksPV_vs_V0A"), multV0A, nPVtracks); + histos.fill(HIST("noCollSameROF/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (underLine) { + histos.fill(HIST("lowMultCut/nTracksPV_vs_V0A"), multV0A, nPVtracks); + } + if (noPU && underLine) { + histos.fill(HIST("noPU_lowMultCut/hBcFV0"), localBC); + histos.fill(HIST("noPU_lowMultCut/nTracksPV_vs_V0A"), multV0A, nPVtracks); + histos.fill(HIST("noPU_lowMultCut/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (grassOnTheRight) { + histos.fill(HIST("highMultCloudCut/nTracksPV_vs_V0A"), multV0A, nPVtracks); + } + if (noPU && grassOnTheRight) { + histos.fill(HIST("noPU_highMultCloudCut/hBcFV0"), localBC); + histos.fill(HIST("noPU_highMultCloudCut/nTracksPV_vs_V0A"), multV0A, nPVtracks); + histos.fill(HIST("noPU_highMultCloudCut/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (noPU && !badVzDiff && pvTOFmatched) { // noPileup_cutByVzDiff_pvTOF_noFT0act + histos.fill(HIST("noPU_cutByVzDiff_pvTOF/hBcFV0"), localBC); + histos.fill(HIST("noPU_cutByVzDiff_pvTOF/nTracksPV_vs_V0A"), multV0A, nPVtracks); + histos.fill(HIST("noPU_cutByVzDiff_pvTOF/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + if (noPU && !badVzDiff && noFT0activityNearby) { + histos.fill(HIST("noPU_cutByVzDiff_noFT0activityNearby/hBcFV0"), localBC); + histos.fill(HIST("noPU_cutByVzDiff_noFT0activityNearby/nTracksPV_vs_V0A"), multV0A, nPVtracks); + // histos.fill(HIST("noPU_cutByVzDiff_noFT0activityNearby/nTracksGlobal_vs_V0A"), multV0A, nGlobalTracksPV); + } + } + if (foundBC.has_zdc()) { + histos.fill(HIST("noSpecSelections/hBcZDC"), localBC); + if (noPU) { + histos.fill(HIST("noPU/hBcZDC"), localBC); + } + if (noPU && pvTOFmatched) { + histos.fill(HIST("noPU_pvTOFmatched/hBcZDC"), localBC); + } + if (noPU && pvTRDmatched) { + histos.fill(HIST("noPU_pvTRDmatched/hBcZDC"), localBC); + } + if (noPU && !pvTRDmatched) { + histos.fill(HIST("noPU_notTRDmatched/hBcZDC"), localBC); + } + if (bcDiffWrtClosestTVXCut) { + histos.fill(HIST("bcDiffWrtClosestTVXCut/hBcZDC"), localBC); + } + if (noPU && bcDiffWrtOriginalBcCut) { + histos.fill(HIST("noPU_bcDiffWrtOriginalBcCut/hBcZDC"), localBC); + } + if (noPU && badVzDiff) { + histos.fill(HIST("noPU_badVzDiff/hBcZDC"), localBC); + } + if (noPU && !badVzDiff) { + histos.fill(HIST("noPU_goodVzDiff/hBcZDC"), localBC); + } + if (noPU && !badVzDiff && narrowTimeVeto) { + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/hBcZDC"), localBC); + } + if (noPU && !badVzDiff && strictTimeVeto) { + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/hBcZDC"), localBC); + } + if (noPU && noPastActivity) { + histos.fill(HIST("noPU_noPastActivity/hBcZDC"), localBC); + } + if (noPU && noFT0activityNearby) { + histos.fill(HIST("noPU_noFT0activityNearby/hBcZDC"), localBC); + } + if (noPU && goodVertexChi2) { + histos.fill(HIST("noPU_goodVertexChi2/hBcZDC"), localBC); + } + if (narrowTimeVeto) { + histos.fill(HIST("narrowTimeVeto/hBcZDC"), localBC); + } + if (strictTimeVeto) { + histos.fill(HIST("strictTimeVeto/hBcZDC"), localBC); + } + if (noCollSameROF) { + histos.fill(HIST("noCollSameROF/hBcZDC"), localBC); + } + if (noPU && underLine) { + histos.fill(HIST("noPU_lowMultCut/hBcZDC"), localBC); + } + if (noPU && grassOnTheRight) { + histos.fill(HIST("noPU_highMultCloudCut/hBcZDC"), localBC); + } + if (noPU && !badVzDiff && pvTOFmatched) { // noPileup_cutByVzDiff_pvTOF_noFT0act + histos.fill(HIST("noPU_cutByVzDiff_pvTOF/hBcZDC"), localBC); + } + if (noPU && !badVzDiff && noFT0activityNearby) { + histos.fill(HIST("noPU_cutByVzDiff_noFT0activityNearby/hBcZDC"), localBC); + } + } + + // bc diff wrt original bc + histos.fill(HIST("noSpecSelections/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + if (noPU) { + histos.fill(HIST("noPU/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (noPU && pvTOFmatched) { + histos.fill(HIST("noPU_pvTOFmatched/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (noPU && pvTRDmatched) { + histos.fill(HIST("noPU_pvTRDmatched/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (noPU && !pvTRDmatched) { + histos.fill(HIST("noPU_notTRDmatched/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (bcDiffWrtClosestTVXCut) { + histos.fill(HIST("bcDiffWrtClosestTVXCut/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (noPU && bcDiffWrtOriginalBcCut) { + histos.fill(HIST("noPU_bcDiffWrtOriginalBcCut/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (noPU && badVzDiff) { + histos.fill(HIST("noPU_badVzDiff/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (noPU && !badVzDiff) { + histos.fill(HIST("noPU_goodVzDiff/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (noPU && !badVzDiff && narrowTimeVeto) { + histos.fill(HIST("noPU_goodVzDiff_narrowTimeVeto/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (noPU && !badVzDiff && strictTimeVeto) { + histos.fill(HIST("noPU_goodVzDiff_strictTimeVeto/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (noPU && noPastActivity) { + histos.fill(HIST("noPU_noPastActivity/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (noPU && noFT0activityNearby) { + histos.fill(HIST("noPU_noFT0activityNearby/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (noPU && goodVertexChi2) { + histos.fill(HIST("noPU_goodVertexChi2/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (narrowTimeVeto) { + histos.fill(HIST("narrowTimeVeto/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (strictTimeVeto) { + histos.fill(HIST("strictTimeVeto/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (noCollSameROF) { + histos.fill(HIST("noCollSameROF/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (noPU && underLine) { + histos.fill(HIST("noPU_lowMultCut/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (noPU && grassOnTheRight) { + histos.fill(HIST("noPU_highMultCloudCut/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (noPU && !badVzDiff && pvTOFmatched) { // noPileup_cutByVzDiff_pvTOF_noFT0act + histos.fill(HIST("noPU_cutByVzDiff_pvTOF/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + if (noPU && !badVzDiff && noFT0activityNearby) { + histos.fill(HIST("noPU_cutByVzDiff_noFT0activityNearby/hTVXvsBcDiffwrtOrigBc"), bcDiffWrtOriginal); + } + + } // end of collisions loop + } + PROCESS_SWITCH(LightIonsEvSelQa, processRun3, "Process Run3 tracking vs detector occupancy QA", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/DPG/Tasks/AOTTrack/qaImpPar.cxx b/DPG/Tasks/AOTTrack/qaImpPar.cxx index 45f66123aee..90c9252f5a4 100644 --- a/DPG/Tasks/AOTTrack/qaImpPar.cxx +++ b/DPG/Tasks/AOTTrack/qaImpPar.cxx @@ -54,12 +54,12 @@ struct QaImpactPar { /// Input parameters Configurable fDebug{"fDebug", false, "Debug flag enabling outputs"}; Configurable fEnablePulls{"fEnablePulls", false, "Enable storage of pulls"}; + Configurable fEnableNuclei{"fEnableNuclei", false, "Enable storage of nuclei"}; ConfigurableAxis binningImpPar{"binningImpPar", {200, -500.f, 500.f}, "Impact parameter binning"}; ConfigurableAxis binningPulls{"binningPulls", {200, -10.f, 10.f}, "Pulls binning"}; ConfigurableAxis binningPt{"binningPt", {100, 0.f, 10.f}, "Pt binning"}; ConfigurableAxis binningEta{"binningEta", {40, -2.f, 2.f}, "Eta binning"}; ConfigurableAxis binningPhi{"binningPhi", {24, 0.f, o2::constants::math::TwoPI}, "Phi binning"}; - ConfigurableAxis binningPDG{"binningPDG", {5, -1.5f, 3.5f}, "PDG species binning (-1: not matched, 0: unknown, 1: pi, 2: K, 3: p)"}; ConfigurableAxis binningCharge{"binningCharge", {2, -2.f, 2.f}, "charge binning (-1: negative; +1: positive)"}; ConfigurableAxis binningIuPosX{"binningIuPosX", {100, -10.f, 10.f}, "Track IU x position"}; ConfigurableAxis binningIuPosY{"binningIuPosY", {100, -10.f, 10.f}, "Track IU y position"}; @@ -336,7 +336,13 @@ struct QaImpactPar { const AxisSpec trackNSigmaTOFPionAxis{20, -10.f, 10.f, "Number of #sigma TOF #pi^{#pm}"}; const AxisSpec trackNSigmaTOFKaonAxis{20, -10.f, 10.f, "Number of #sigma TOF K^{#pm}"}; const AxisSpec trackNSigmaTOFProtonAxis{20, -10.f, 10.f, "Number of #sigma TOF proton"}; - const AxisSpec trackPDGAxis{binningPDG, "species (-1: not matched, 0: unknown, 1: pi, 2: K, 3: p)"}; + AxisSpec trackPDGAxis{5, -1.5f, 3.5f, "species (-1: not matched, 0: unknown, 1: pi, 2: K, 3: p)"}; + if (fEnableNuclei) { + trackPDGAxis.nBins = 9; + trackPDGAxis.binEdges[1] = 7.5; + trackPDGAxis.title = "species (-1: not matched, 0: unknown, 1: pi, 2: K, 3: p, 4: d, 5: t, 6: he3, 7: alpha)"; + } + const AxisSpec trackChargeAxis{binningCharge, "charge binning (-1: negative; +1: positive)"}; const AxisSpec axisVertexNumContrib{binsNumPvContrib, "Number of original PV contributors"}; const AxisSpec trackIsPvContrib{2, -0.5f, 1.5f, "is PV contributor: 1=yes, 0=no"}; @@ -420,6 +426,14 @@ struct QaImpactPar { return 2; case 2212: // proton return 3; + case o2::constants::physics::Pdg::kDeuteron: // deuteron + return 4; + case o2::constants::physics::Pdg::kTriton: // triton + return 5; + case o2::constants::physics::Pdg::kHelium3: // helium-3 + return 6; + case o2::constants::physics::Pdg::kAlpha: // alpha + return 7; default: // not identified return 0; } @@ -569,7 +583,7 @@ struct QaImpactPar { continue; } auto particle = track.mcParticle(); - if (keepOnlyPhysPrimary && particle.isPhysicalPrimary()) { + if (!particle.isPhysicalPrimary()) { continue; } pdgIndex = PDGtoIndex(std::abs(particle.pdgCode())); diff --git a/DPG/Tasks/ITS/filterTracks.cxx b/DPG/Tasks/ITS/filterTracks.cxx index dc9c8ef777f..ed35c1dd95c 100644 --- a/DPG/Tasks/ITS/filterTracks.cxx +++ b/DPG/Tasks/ITS/filterTracks.cxx @@ -112,8 +112,9 @@ DECLARE_SOA_TABLE(FilterCollPos, "AOD", "FILTERCOLLPOS", o2::aod::collision::Chi2, o2::aod::collision::NumContrib, o2::aod::collision::CollisionTime); +DECLARE_SOA_TABLE(FiltTrackColIdx, "AOD", "FILTTRACKCOLIDX", + o2::aod::track::CollisionId); DECLARE_SOA_TABLE(FilterTrack, "AOD", "FILTERTRACK", - o2::aod::track::CollisionId, aod::filtertracks::IsInsideBeamPipe, o2::aod::track::TrackType, o2::aod::track::X, @@ -166,6 +167,7 @@ DECLARE_SOA_TABLE(GenParticles, "AOD", "GENPARTICLES", struct FilterTracks { const static int nStudiedParticlesMc = 3; + Produces filteredTracksCollIdx; Produces filteredTracksTableExtra; Produces filteredTracksTable; Produces filteredTracksTableExtraDet; @@ -182,7 +184,7 @@ struct FilterTracks { Configurable trackPtSampling{"trackPtSampling", 0, "track sampling mode"}; Configurable produceCollTableFull{"produceCollTableFull", false, "produce full collision table"}; Configurable produceCollTableLite{"produceCollTableLite", false, "produce lite collision table"}; - Configurable produceCollTableExtraLite{"produceCollTableExtraLite", true, "produce extra lite collision table"}; + Configurable produceCollTableExtraLite{"produceCollTableExtraLite", 2, "produce extra lite collision table"}; Configurable trackPtWeightLowPt{"trackPtWeightLowPt", 0.01f, "trackPtWeightLowPt"}; Configurable trackPtWeightMidPt{"trackPtWeightMidPt", 0.10f, "trackPtWeightMidPt"}; Configurable collFilterFraction{"collFilterFraction", 0.05f, "collFilterFraction"}; @@ -218,8 +220,9 @@ struct FilterTracks { void fillTableData(auto track) { + filteredTracksCollIdx(track.collisionId()); filteredTracksTableExtra(track.pt(), track.eta(), track.sign(), track.dcaXY(), track.dcaZ(), track.sigmaDcaXY2(), track.sigmaDcaZ2(), track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr()); - filteredTracksTable(track.collisionId(), track.isWithinBeamPipe() ? 1 : 0, track.trackType(), track.x(), track.alpha(), track.y(), track.z(), track.snp(), track.tgl(), track.signed1Pt()); + filteredTracksTable(track.isWithinBeamPipe() ? 1 : 0, track.trackType(), track.x(), track.alpha(), track.y(), track.z(), track.snp(), track.tgl(), track.signed1Pt()); filteredTracksTableExtraDet(track.itsClusterSizes(), track.itsChi2NCl(), track.tpcChi2NCl(), track.tpcNClsFound(), track.trackTime()); } @@ -302,19 +305,31 @@ struct FilterTracks { if (trackPtSampling == 0) { for (auto const& track : tracks) { fillTableData(track); + if (produceCollTableExtraLite == 2) { + filterCollPosTable(collision.posX(), collision.posY(), collision.posZ(), collision.chi2(), collision.numContrib(), collision.collisionTime()); + }; } } else { auto lowPtTracksThisColl = lowPtTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); for (auto const& track : lowPtTracksThisColl) { fillTableData(track); + if (produceCollTableExtraLite == 2) { + filterCollPosTable(collision.posX(), collision.posY(), collision.posZ(), collision.chi2(), collision.numContrib(), collision.collisionTime()); + }; } auto midPtTracksThisColl = midPtTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); for (auto const& track : midPtTracksThisColl) { fillTableData(track); + if (produceCollTableExtraLite == 2) { + filterCollPosTable(collision.posX(), collision.posY(), collision.posZ(), collision.chi2(), collision.numContrib(), collision.collisionTime()); + }; } auto highPtTracksThisColl = highPtTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); for (auto const& track : highPtTracksThisColl) { fillTableData(track); + if (produceCollTableExtraLite == 2) { + filterCollPosTable(collision.posX(), collision.posY(), collision.posZ(), collision.chi2(), collision.numContrib(), collision.collisionTime()); + }; } } } @@ -325,7 +340,7 @@ struct FilterTracks { filterCollTable(collision.bcId(), collision.posX(), collision.posY(), collision.posZ(), collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ(), collision.flags(), collision.chi2(), collision.numContrib(), collision.collisionTime(), collision.collisionTimeRes()); if (produceCollTableLite) filterCollLiteTable(collision.posX(), collision.posY(), collision.posZ(), collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ(), collision.chi2(), collision.numContrib(), collision.collisionTime()); - if (produceCollTableExtraLite) + if (produceCollTableExtraLite == 1) filterCollPosTable(collision.posX(), collision.posY(), collision.posZ(), collision.chi2(), collision.numContrib(), collision.collisionTime()); } PROCESS_SWITCH(FilterTracks, processCollisions, "process collisions", true); diff --git a/EventFiltering/PWGCF/CFFilterQA.cxx b/EventFiltering/PWGCF/CFFilterQA.cxx index 372b3387dc1..fe084669b8a 100644 --- a/EventFiltering/PWGCF/CFFilterQA.cxx +++ b/EventFiltering/PWGCF/CFFilterQA.cxx @@ -1033,7 +1033,7 @@ struct CFFilterQA { std::vector setValuesBB(aod::BCsWithTimestamps::iterator const& bunchCrossing, const std::string ccdbPath) { - map metadata; + std::map metadata; auto h = ccdbApi.retrieveFromTFileAny(ccdbPath, metadata, bunchCrossing.timestamp()); // auto h = ccdb->getForTimeStamp(ccdbPath, bunchCrossing.timestamp()); //check if possible to use this without getting fatal if (!h) { @@ -1055,7 +1055,7 @@ struct CFFilterQA { std::vector setValuesAvg(aod::BCsWithTimestamps::iterator const& bunchCrossing, const std::string ccdbPath) { - map metadata; + std::map metadata; auto h = ccdbApi.retrieveFromTFileAny(ccdbPath, metadata, bunchCrossing.timestamp()); // auto h = ccdb->getForTimeStamp(ccdbPath, bunchCrossing.timestamp()); //check if possible to use this without getting fatal if (!h) { diff --git a/EventFiltering/PWGEM/EMPhotonFilter.cxx b/EventFiltering/PWGEM/EMPhotonFilter.cxx index a254c7245a1..3e88524a89b 100644 --- a/EventFiltering/PWGEM/EMPhotonFilter.cxx +++ b/EventFiltering/PWGEM/EMPhotonFilter.cxx @@ -12,16 +12,19 @@ // \brief software trigger for EM photon // \author daiki.sekihata@cern.ch -#include "Math/Vector4D.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "Common/DataModel/CaloClusters.h" -#include "DataFormatsPHOS/TriggerRecord.h" #include "PWGEM/PhotonMeson/DataModel/gammaTables.h" + +#include "Common/DataModel/CaloClusters.h" #include "EventFiltering/filterTables.h" + +#include "DataFormatsPHOS/TriggerRecord.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include "Math/Vector4D.h" using namespace o2; using namespace o2::soa; @@ -128,7 +131,7 @@ struct EMPhotonFilter { return false; } - if (track.pt() < minpt || abs(track.eta()) > maxeta) { + if (track.pt() < minpt || std::fabs(track.eta()) > maxeta) { return false; } @@ -158,7 +161,7 @@ struct EMPhotonFilter { dca_3d = 999.f; } else { float chi2 = (track.dcaXY() * track.dcaXY() * track.cZZ() + track.dcaZ() * track.dcaZ() * track.cYY() - 2. * track.dcaXY() * track.dcaZ() * track.cZY()) / det; - dca_3d = std::sqrt(std::abs(chi2) / 2.); + dca_3d = std::sqrt(std::fabs(chi2) / 2.); } if (dca_3d > dca_3d_sigma_max) { return false; @@ -174,23 +177,23 @@ struct EMPhotonFilter { template void runFilter(TCollisions const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPhotons3 const& /*photons3*/, TV0Legs const&, TDielectrons const& dielectrons, TEMPrimaryElectrons const& /*emprimaryelectrons*/) { - for (auto& collision : collisions) { + for (const auto& collision : collisions) { mHistManager.fill(HIST("hEventCounter"), 1.); bool keepEvent[kNtrg]{false}; if (collision.sel8()) { mHistManager.fill(HIST("hEventCounter"), 2.); } - if (abs(collision.posZ()) < 10.f) { + if (std::fabs(collision.posZ()) < 10.f) { mHistManager.fill(HIST("hEventCounter"), 3.); } if (collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { mHistManager.fill(HIST("hEventCounter"), 4.); } - if (collision.sel8() && abs(collision.posZ()) < 10.f) { + if (collision.sel8() && std::fabs(collision.posZ()) < 10.f) { mHistManager.fill(HIST("hEventCounter"), 5.); } - if (collision.sel8() && abs(collision.posZ()) < 10.f && collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { + if (collision.sel8() && std::fabs(collision.posZ()) < 10.f && collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { mHistManager.fill(HIST("hEventCounter"), 6.); } @@ -203,7 +206,7 @@ struct EMPhotonFilter { auto photons1_per_coll = photons1.sliceBy(perCollision_pcm, collision.globalIndex()); auto dielectrons_per_coll = dielectrons.sliceBy(perCollision_ee, collision.globalIndex()); - for (auto& v0photon : photons1_per_coll) { + for (const auto& v0photon : photons1_per_coll) { auto pos_sv = v0photon.template posTrack_as(); auto ele_sv = v0photon.template negTrack_as(); if (!isSelectedSecondary(pos_sv) || !isSelectedSecondary(ele_sv)) { @@ -215,7 +218,7 @@ struct EMPhotonFilter { } } // end of single v0 photon loop - for (auto& [g1, g2] : combinations(CombinationsFullIndexPolicy(photons1_per_coll, dielectrons_per_coll))) { + for (const auto& [g1, g2] : combinations(CombinationsFullIndexPolicy(photons1_per_coll, dielectrons_per_coll))) { auto pos_sv = g1.template posTrack_as(); auto ele_sv = g1.template negTrack_as(); if (!isSelectedSecondary(pos_sv) || !isSelectedSecondary(ele_sv)) { @@ -279,8 +282,8 @@ struct EMPhotonFilter { if (clu2.trackdist() < 1.) { // select neutral clusters. Disp, Ncell cuts? continue; } - double m = pow(clu.e() + clu2.e(), 2) - pow(clu.px() + clu2.px(), 2) - - pow(clu.py() + clu2.py(), 2) - pow(clu.pz() + clu2.pz(), 2); + double m = std::pow(clu.e() + clu2.e(), 2) - std::pow(clu.px() + clu2.px(), 2) - + std::pow(clu.py() + clu2.py(), 2) - std::pow(clu.pz() + clu2.pz(), 2); if (m > ePair * ePair) { keepEvent[kPHOS_Pair] |= true; break; @@ -325,13 +328,10 @@ struct EMPhotonFilter { } // end of collision loop } - Filter PCMFilter = o2::aod::v0photonkf::dcaXYtopv < max_dcatopv_xy_v0 && o2::aod::v0photonkf::dcaZtopv < max_dcatopv_z_v0; - using filteredV0PhotonsKF = Filtered; - Filter DalitzEEFilter = o2::aod::dalitzee::sign == 0; // analyze only uls using filteredDalitzEEs = Filtered; - void process_PCM(MyCollisions const& collisions, filteredV0PhotonsKF const& v0photons, aod::V0Legs const& v0legs, filteredDalitzEEs const& dielectrons, MyPrimaryElectrons const& emprimaryelectrons) + void process_PCM(MyCollisions const& collisions, aod::V0PhotonsKF const& v0photons, aod::V0Legs const& v0legs, filteredDalitzEEs const& dielectrons, MyPrimaryElectrons const& emprimaryelectrons) { const uint8_t system = EM_Filter_PhotonType::kPCM; runFilter(collisions, v0photons, nullptr, nullptr, v0legs, dielectrons, emprimaryelectrons); @@ -351,7 +351,7 @@ struct EMPhotonFilter { runFilter(collisions, nullptr, nullptr, clusters, nullptr, nullptr, nullptr); } - void process_PCM_PHOS(MyCollisions const& collisions, filteredV0PhotonsKF const& v0photons, aod::V0Legs const& v0legs, filteredDalitzEEs const& dielectrons, MyPrimaryElectrons const& emprimaryelectrons, CluCandidates const& clusters) + void process_PCM_PHOS(MyCollisions const& collisions, aod::V0PhotonsKF const& v0photons, aod::V0Legs const& v0legs, filteredDalitzEEs const& dielectrons, MyPrimaryElectrons const& emprimaryelectrons, CluCandidates const& clusters) { const uint8_t system = EM_Filter_PhotonType::kPCM | EM_Filter_PhotonType::kPHOS; runFilter(collisions, v0photons, clusters, nullptr, v0legs, dielectrons, emprimaryelectrons); diff --git a/EventFiltering/PWGLF/filterf1proton.cxx b/EventFiltering/PWGLF/filterf1proton.cxx index abdfe9c272a..8919d851580 100644 --- a/EventFiltering/PWGLF/filterf1proton.cxx +++ b/EventFiltering/PWGLF/filterf1proton.cxx @@ -436,7 +436,7 @@ struct filterf1proton { std::vector setValuesBB(o2::ccdb::CcdbApi& ccdbApi, aod::BCsWithTimestamps::iterator const& bunchCrossing, const std::string ccdbPath) { - map metadata; + std::map metadata; auto h = ccdbApi.retrieveFromTFileAny(ccdbPath, metadata, bunchCrossing.timestamp()); // auto h = ccdb->getForTimeStamp(ccdbPath, bunchCrossing.timestamp()); // check if possible to use this without getting fatal if (!h) { diff --git a/EventFiltering/PWGLF/nucleiFilter.cxx b/EventFiltering/PWGLF/nucleiFilter.cxx index 54f3ed507ad..443df675533 100644 --- a/EventFiltering/PWGLF/nucleiFilter.cxx +++ b/EventFiltering/PWGLF/nucleiFilter.cxx @@ -10,42 +10,48 @@ // or submit itself to any jurisdiction. // O2 includes -#include -#include +#include "../filterTables.h" -#include "Math/Vector4D.h" -#include "Math/GenVector/Boost.h" +#include "PWGLF/DataModel/LFPIDTOFGenericTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/Vtx3BodyTables.h" +#include "PWGLF/Utils/pidTOFGeneric.h" + +#include "Common/Core/PID/PIDTOF.h" +#include "Common/Core/trackUtilities.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" + +#include "CCDB/BasicCCDBManager.h" +#include "DCAFitter/DCAFitterN.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DataFormatsTOF/ParameterContainers.h" #include "DataFormatsTPC/BetheBlochAleph.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/Track.h" -#include "PWGLF/DataModel/Vtx3BodyTables.h" -#include "../filterTables.h" +#include "Math/GenVector/Boost.h" +#include "Math/Vector4D.h" -#include "ReconstructionDataFormats/Track.h" -#include "Common/Core/trackUtilities.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsTOF/ParameterContainers.h" -#include "CCDB/BasicCCDBManager.h" -#include "DCAFitter/DCAFitterN.h" -#include "PWGLF/DataModel/pidTOFGeneric.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "Common/Core/PID/PIDTOF.h" +#include +#include +#include +#include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +o2::common::core::MetadataHelper metadataInfo; + namespace { @@ -120,7 +126,9 @@ struct nucleiFilter { o2::base::MatLayerCylSet* lut = nullptr; o2::vertexing::DCAFitterN<2> fitter2body; o2::vertexing::DCAFitterN<3> fitter3body; - o2::pid::tof::TOFResoParamsV2 mRespParamsV2; + // TOF response and input parameters + o2::pid::tof::TOFResoParamsV3 mRespParamsV3; + o2::aod::pidtofgeneric::TOFCalibConfig mTOFCalibConfig; // TOF Calib configuration // configurable for hypertriton 3body decay struct : ConfigurableGroup { Configurable bFieldInput{"trgH3L3Body.mBz", -999, "bz field, -999 is automatic"}; @@ -153,20 +161,12 @@ struct nucleiFilter { Configurable grpmagPath{"trgH3L3Body.grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable lutPath{"trgH3L3Body.lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; Configurable geoPath{"trgH3L3Body.geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; - // CCDB TOF PID paras - Configurable timestamp{"trgH3L3Body.ccdb-timestamp", -1, "timestamp of the object"}; - Configurable paramFileName{"trgH3L3Body.paramFileName", "", "Path to the parametrization object. If empty the parametrization is not taken from file"}; - Configurable parametrizationPath{"trgH3L3Body.parametrizationPath", "TOF/Calib/Params", "Path of the TOF parametrization on the CCDB or in the file, if the paramFileName is not empty"}; - Configurable passName{"trgH3L3Body.passName", "", "Name of the pass inside of the CCDB parameter collection. If empty, the automatically deceted from metadata (to be implemented!!!)"}; - Configurable timeShiftCCDBPath{"trgH3L3Body.timeShiftCCDBPath", "", "Path of the TOF time shift vs eta. If empty none is taken"}; - Configurable loadResponseFromCCDB{"trgH3L3Body.loadResponseFromCCDB", false, "Flag to load the response from the CCDB"}; - Configurable fatalOnPassNotAvailable{"trgH3L3Body.fatalOnPassNotAvailable", false, "Flag to throw a fatal if the pass is not available in the retrieved CCDB object"}; } trgH3L3Body; HistogramRegistry qaHists{"qaHists", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; OutputObj hProcessedEvents{TH1D("hProcessedEvents", ";;Number of filtered events", kNtriggers + 1, -0.5, static_cast(kNtriggers) + 0.5)}; - void init(InitContext&) + void init(InitContext& initContext) { std::vector ptBinning = {0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.8, 2.0, 2.2, 2.4, 2.8, 3.2, 3.6, 4., 5.}; @@ -214,6 +214,11 @@ struct nucleiFilter { ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); ccdb->setFatalWhenNull(false); + + // Initialization of TOF PID parameters for fH3L3Body + mTOFCalibConfig.metadataInfo = metadataInfo; + mTOFCalibConfig.inheritFromBaseTask(initContext); + mTOFCalibConfig.initSetup(mRespParamsV3, ccdb); // Getting the parametrization parameters } void initCCDB(aod::BCsWithTimestamps::iterator const& bc) @@ -264,65 +269,7 @@ struct nucleiFilter { o2::base::Propagator::Instance()->setMatLUT(lut); } - // Initial TOF PID Paras, copied from pidTOF.cxx - trgH3L3Body.timestamp.value = bc.timestamp(); - ccdb->setTimestamp(trgH3L3Body.timestamp.value); - // Not later than now objects - ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); - // TODO: implement the automatic pass name detection from metadata - if (trgH3L3Body.passName.value == "") { - trgH3L3Body.passName.value = "unanchored"; // temporary default - LOG(warning) << "Passed autodetect mode for pass, not implemented yet, waiting for metadata. Taking '" << trgH3L3Body.passName.value << "'"; - } - LOG(info) << "Using parameter collection, starting from pass '" << trgH3L3Body.passName.value << "'"; - - const std::string fname = trgH3L3Body.paramFileName.value; - if (!fname.empty()) { // Loading the parametrization from file - LOG(info) << "Loading exp. sigma parametrization from file " << fname << ", using param: " << trgH3L3Body.parametrizationPath.value; - if (1) { - o2::tof::ParameterCollection paramCollection; - paramCollection.loadParamFromFile(fname, trgH3L3Body.parametrizationPath.value); - LOG(info) << "+++ Loaded parameter collection from file +++"; - if (!paramCollection.retrieveParameters(mRespParamsV2, trgH3L3Body.passName.value)) { - if (trgH3L3Body.fatalOnPassNotAvailable) { - LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", trgH3L3Body.passName.value.data()); - } else { - LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", trgH3L3Body.passName.value.data()); - } - } else { - mRespParamsV2.setShiftParameters(paramCollection.getPars(trgH3L3Body.passName.value)); - mRespParamsV2.printShiftParameters(); - } - } else { - mRespParamsV2.loadParamFromFile(fname.data(), trgH3L3Body.parametrizationPath.value); - } - } else if (trgH3L3Body.loadResponseFromCCDB) { // Loading it from CCDB - LOG(info) << "Loading exp. sigma parametrization from CCDB, using path: " << trgH3L3Body.parametrizationPath.value << " for timestamp " << trgH3L3Body.timestamp.value; - o2::tof::ParameterCollection* paramCollection = ccdb->getForTimeStamp(trgH3L3Body.parametrizationPath.value, trgH3L3Body.timestamp.value); - paramCollection->print(); - if (!paramCollection->retrieveParameters(mRespParamsV2, trgH3L3Body.passName.value)) { // Attempt at loading the parameters with the pass defined - if (trgH3L3Body.fatalOnPassNotAvailable) { - LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", trgH3L3Body.passName.value.data()); - } else { - LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", trgH3L3Body.passName.value.data()); - } - } else { // Pass is available, load non standard parameters - mRespParamsV2.setShiftParameters(paramCollection->getPars(trgH3L3Body.passName.value)); - mRespParamsV2.printShiftParameters(); - } - } - mRespParamsV2.print(); - if (trgH3L3Body.timeShiftCCDBPath.value != "") { - if (trgH3L3Body.timeShiftCCDBPath.value.find(".root") != std::string::npos) { - mRespParamsV2.setTimeShiftParameters(trgH3L3Body.timeShiftCCDBPath.value, "gmean_Pos", true); - mRespParamsV2.setTimeShiftParameters(trgH3L3Body.timeShiftCCDBPath.value, "gmean_Neg", false); - } else { - mRespParamsV2.setTimeShiftParameters(ccdb->getForTimeStamp(Form("%s/pos", trgH3L3Body.timeShiftCCDBPath.value.c_str()), trgH3L3Body.timestamp.value), true); - mRespParamsV2.setTimeShiftParameters(ccdb->getForTimeStamp(Form("%s/neg", trgH3L3Body.timeShiftCCDBPath.value.c_str()), trgH3L3Body.timestamp.value), false); - } - } - - bachelorTOFPID.SetParams(mRespParamsV2); + mTOFCalibConfig.processSetup(mRespParamsV3, ccdb, bc); } enum { @@ -568,7 +515,7 @@ struct nucleiFilter { float tofNSigmaDeuteron = -999; if (track2.has_collision() && track2.hasTOF()) { auto originalcol = track2.collision_as(); - tofNSigmaDeuteron = bachelorTOFPID.GetTOFNSigma(track2, originalcol, collision); + tofNSigmaDeuteron = bachelorTOFPID.GetTOFNSigma(mRespParamsV3, track2, originalcol, collision); } if (track2.p() > trgH3L3Body.minDeuteronPUseTOF && (tofNSigmaDeuteron < trgH3L3Body.tofPIDNSigmaMin || tofNSigmaDeuteron > trgH3L3Body.tofPIDNSigmaMax)) { continue; @@ -671,6 +618,7 @@ struct nucleiFilter { WorkflowSpec defineDataProcessing(ConfigContext const& cfg) { + metadataInfo.initMetadata(cfg); return WorkflowSpec{ adaptAnalysisTask(cfg)}; } diff --git a/EventFiltering/Zorro.cxx b/EventFiltering/Zorro.cxx index ccdf063307d..3f9ca800024 100644 --- a/EventFiltering/Zorro.cxx +++ b/EventFiltering/Zorro.cxx @@ -185,15 +185,11 @@ std::vector Zorro::initCCDB(o2::ccdb::BasicCCDBManager* ccdb, int runNumber mCCDB = ccdb; mRunNumber = runNumber; mBCtolerance = bcRange; - std::map metadata; - metadata["runNumber"] = std::to_string(runNumber); - mRunDuration = mCCDB->getRunDuration(runNumber, true); - int64_t runTs = (mRunDuration.first / 2 + mRunDuration.second / 2); - auto ctp = ccdb->getForTimeStamp>("CTP/Calib/OrbitReset", runTs); + auto ctp = ccdb->getForRun>("CTP/Calib/OrbitReset", runNumber, false); mOrbitResetTimestamp = (*ctp)[0]; - mScalers = mCCDB->getSpecific(mBaseCCDBPath + "FilterCounters", runTs, metadata); - mSelections = mCCDB->getSpecific(mBaseCCDBPath + "SelectionCounters", runTs, metadata); - mInspectedTVX = mCCDB->getSpecific(mBaseCCDBPath + "InspectedTVX", runTs, metadata); + mScalers = mCCDB->getForRun(mBaseCCDBPath + "FilterCounters", runNumber, true); + mSelections = mCCDB->getForRun(mBaseCCDBPath + "SelectionCounters", runNumber, true); + mInspectedTVX = mCCDB->getForRun(mBaseCCDBPath + "InspectedTVX", runNumber, true); setupHelpers(timestamp); mLastBCglobalId = 0; mLastSelectedIdx = 0; diff --git a/EventFiltering/Zorro.h b/EventFiltering/Zorro.h index f03badab2ce..8cab70192c5 100644 --- a/EventFiltering/Zorro.h +++ b/EventFiltering/Zorro.h @@ -74,7 +74,7 @@ class Zorro ZorroSummary mZorroSummary{"ZorroSummary", "ZorroSummary"}; - std::string mBaseCCDBPath = "Users/m/mpuccio/EventFiltering/OTS/Chunked/"; + std::string mBaseCCDBPath = "EventFiltering/Zorro/"; int mRunNumber = 0; std::pair mRunDuration; int64_t mOrbitResetTimestamp = 0; diff --git a/EventFiltering/macros/uploadOTSobjects.C b/EventFiltering/macros/uploadOTSobjects.C index 2a9be2de17e..eb2011308ce 100644 --- a/EventFiltering/macros/uploadOTSobjects.C +++ b/EventFiltering/macros/uploadOTSobjects.C @@ -31,13 +31,10 @@ constexpr uint32_t chunkSize = 1000000; -void uploadOTSobjects(std::string inputList, std::string passName, bool useAlien, bool chunkedProcessing) +void uploadOTSobjects(std::string inputList, std::string passName, bool useAlien, bool chunkedProcessing = true) { - const std::string kBaseCCDBPath = "Users/m/mpuccio/EventFiltering/OTS/"; + const std::string kBaseCCDBPath = "EventFiltering/Zorro/"; std::string baseCCDBpath = passName.empty() ? kBaseCCDBPath : kBaseCCDBPath + passName + "/"; - if (chunkedProcessing) { - baseCCDBpath += "Chunked/"; - } if (useAlien) { TGrid::Connect("alien://"); } @@ -67,6 +64,13 @@ void uploadOTSobjects(std::string inputList, std::string passName, bool useAlien api.storeAsTFile(scalers, baseCCDBpath + "FilterCounters", metadata, duration.first, duration.second + 1); api.storeAsTFile(filters, baseCCDBpath + "SelectionCounters", metadata, duration.first, duration.second + 1); TH1* hCounterTVX = static_cast(scalersFile->Get("bc-selection-task/hCounterTVX")); + if (!hCounterTVX) { + hCounterTVX = static_cast(scalersFile->Get("lumi-task/hCounterTVX")); + if (!hCounterTVX) { + std::cout << "No hCounterTVX histogram found in the file, skipping upload for run " << runString << std::endl; + continue; + } + } api.storeAsTFile(hCounterTVX, baseCCDBpath + "InspectedTVX", metadata, duration.first, duration.second + 1); std::vector zorroHelpers; @@ -134,9 +138,9 @@ void uploadOTSobjects(std::string inputList, std::string passName, bool useAlien } } -void uploadOTSobjects(std::string periodName, bool chunkedProcessing) +void uploadOTSobjects(std::string periodName) { int year = 2000 + std::stoi(periodName.substr(3, 2)); gSystem->Exec(Form("alien_find /alice/data/%i/%s/ ctf_skim_full/AnalysisResults_fullrun.root | sed 's:/AnalysisResults_fullrun\\.root::' > list_%s.txt", year, periodName.data(), periodName.data())); - uploadOTSobjects(Form("list_%s.txt", periodName.data()), "", true, chunkedProcessing); + uploadOTSobjects(Form("list_%s.txt", periodName.data()), "", true, true); } diff --git a/PWGCF/DataModel/CorrelationsDerived.h b/PWGCF/DataModel/CorrelationsDerived.h index 62bcf8716bc..9be8ac7d58e 100644 --- a/PWGCF/DataModel/CorrelationsDerived.h +++ b/PWGCF/DataModel/CorrelationsDerived.h @@ -86,6 +86,22 @@ using CFTrackWithLabel = CFTracksWithLabel::iterator; //------transient CF-filter to CF-2prong-filter DECLARE_SOA_TABLE(CFCollRefs, "AOD", "CFCOLLREF", o2::soa::Index<>, track::CollisionId); //! Transient cf collision index table +//------multiplicity set +namespace cfmultset +{ +DECLARE_SOA_COLUMN(Multiplicities, multiplicities, std::vector); //! List of auxiliary multiplicities +enum MultiplicityEstimators : uint8_t { + CentFT0C = 0x1, + MultFV0A = 0x2, + MultNTracksPV = 0x4, + MultNTracksGlobal = 0x8 +}; + +} // namespace cfmultset +DECLARE_SOA_TABLE(CFMultSets, "AOD", "CFMULTSET", cfmultset::Multiplicities); //! Auxilary multiplicity set table + +using CFMultSet = CFMultSets::iterator; + // Reco using CFCollRef = CFCollRefs::iterator; diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index 4caf0166303..3be2baadc37 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -208,7 +208,8 @@ namespace fdhf enum CharmHadronMassHypo { wrongParticle = 0, lcToPKPi = 1, - lcToPiKP = 2 + lcToPiKP = 2, + dplusToPiKPi = 4 }; DECLARE_SOA_COLUMN(GIndexCol, gIndexCol, int); //! Global index for the collision DECLARE_SOA_COLUMN(TimeStamp, timeStamp, int64_t); //! Timestamp for the collision @@ -227,7 +228,7 @@ DECLARE_SOA_COLUMN(Prong2Eta, prong2Eta, float); //! Track et DECLARE_SOA_COLUMN(Prong0Phi, prong0Phi, float); //! Track phi of charm hadron prong0 DECLARE_SOA_COLUMN(Prong1Phi, prong1Phi, float); //! Track phi of charm hadron prong1 DECLARE_SOA_COLUMN(Prong2Phi, prong2Phi, float); //! Track phi of charm hadron prong2 -DECLARE_SOA_COLUMN(CandidateSelFlag, candidateSelFlag, int8_t); //! Selection of mass hypothesis for charm hadron (1 for Lc -> pkpi, 2 for Lc -> pikp) +DECLARE_SOA_COLUMN(CandidateSelFlag, candidateSelFlag, int8_t); //! Selection of mass hypothesis for charm hadron (1 for Lc -> pkpi, 2 for Lc -> pikp, 4 for D+ -> pikpi) DECLARE_SOA_COLUMN(BDTBkg, bdtBkg, float); //! Background score using Boosted Decision Tree for charm hadron DECLARE_SOA_COLUMN(BDTPrompt, bdtPrompt, float); //! Prompt signal score using Boosted Decision Tree for charm hadron DECLARE_SOA_COLUMN(BDTFD, bdtFD, float); //! Feed-down score using Boosted Decision Tree for charm hadron @@ -312,6 +313,24 @@ DECLARE_SOA_TABLE(FDHfCand, "AOD", "FDHFCAND", //! Table to store the derived da fdhf::Phi, fdhf::Pt); +DECLARE_SOA_TABLE(FDHfPairs, "AOD", "FDHFPAIRS", //! table to store results for HF femtoscopy + fdhf::CharmM, + fdhf::CharmPt, + fdhf::TrkPt, + fdhf::BDTBkg, + fdhf::BDTPrompt, + fdhf::BDTFD, + fdhf::Kstar, + fdhf::KT, + fdhf::MT, + fdhf::Mult, + fdhf::MultPercentile, + fdhf::Charge, + fdhf::PairSign, + fdhf::ProcessType, + fdhf::FlagMc, + fdhf::OriginMcRec); + DECLARE_SOA_TABLE(FDHfCharm, "AOD", "FDHFCHARM", //! table to store results for HF femtoscopy fdhf::GIndexCol, fdhf::TimeStamp, @@ -319,12 +338,13 @@ DECLARE_SOA_TABLE(FDHfCharm, "AOD", "FDHFCHARM", //! table to store results for fdhf::CharmPt, fdhf::CharmEta, fdhf::CharmPhi, + fdhf::Prong0Id, + fdhf::Prong1Id, + fdhf::Prong2Id, fdhf::Charge, fdhf::BDTBkg, fdhf::BDTPrompt, - fdhf::BDTFD, - fdhf::FlagMc, - fdhf::OriginMcRec); + fdhf::BDTFD); DECLARE_SOA_TABLE(FDHfTrk, "AOD", "FDHFTRK", //! table to store results for HF femtoscopy fdhf::GIndexCol, @@ -332,6 +352,7 @@ DECLARE_SOA_TABLE(FDHfTrk, "AOD", "FDHFTRK", //! table to store results for HF f fdhf::TrkPt, fdhf::TrkEta, fdhf::TrkPhi, + fdhf::TrackId, femtodreamparticle::Sign, femtodreamparticle::TPCNClsFound, track::TPCNClsFindable, @@ -353,6 +374,9 @@ DECLARE_SOA_TABLE(FDHfCandMC, "AOD", "FDHFCANDMC", //! Table for reconstructed M DECLARE_SOA_TABLE(FDParticlesIndex, "AOD", "FDPARTICLEINDEX", //! Table track index to match associate particle with charm hadron prongs o2::soa::Index<>, fdhf::TrackId); +DECLARE_SOA_TABLE(FDTrkTimeStamp, "AOD", "FDHFTRKTIMESTAMP", //! Time Stampe of track associate event + o2::soa::Index<>, + fdhf::TimeStamp); DECLARE_SOA_TABLE_STAGED(FDParticles, "FDPARTICLE", o2::soa::Index<>, diff --git a/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx b/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx index 1229cb4dfc6..dd212faf22d 100644 --- a/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx @@ -46,16 +46,16 @@ namespace o2::aod { -namespace ptQn +namespace pt_qn { DECLARE_SOA_COLUMN(Q1, q1, float); //! sum of pT of tracks in an event DECLARE_SOA_COLUMN(Q2, q2, float); //! sum of (pT)^2 of tracks in an event DECLARE_SOA_COLUMN(Q3, q3, float); //! sum of (pT)^3 of tracks in an event DECLARE_SOA_COLUMN(Q4, q4, float); //! sum of (pT)^4 of tracks in an event -DECLARE_SOA_COLUMN(N_ch, n_ch, float); //! no of charged particles/multiplicity in an event +DECLARE_SOA_COLUMN(Nch, nch, float); //! no of charged particles/multiplicity in an event DECLARE_SOA_COLUMN(Centrality, centrality, float); //! Centrality of event -} // namespace ptQn -DECLARE_SOA_TABLE(MultPtQn, "AOD", "PTQN", ptQn::Q1, ptQn::Q2, ptQn::Q3, ptQn::Q4, ptQn::N_ch, ptQn::Centrality); //! table to store e-by-e sum of pT, (pT)^2, (pT)^3, (pT)^4 of tracks, multiplicity and centrality +} // namespace pt_qn +DECLARE_SOA_TABLE(MultPtQn, "AOD", "PTQN", pt_qn::Q1, pt_qn::Q2, pt_qn::Q3, pt_qn::Q4, pt_qn::Nch, pt_qn::Centrality); //! table to store e-by-e sum of pT, (pT)^2, (pT)^3, (pT)^4 of tracks, multiplicity and centrality } // namespace o2::aod using namespace o2; @@ -64,9 +64,11 @@ using namespace o2::framework::expressions; #define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; -struct MeanptFluctuations_QA_QnTable { +struct MeanptFluctuationsQAQnTable { Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; + Configurable cfgCutPreSelEta{"cfgCutPreSelEta", 0.8f, "|eta| cfgCutPreSelPt{"cfgCutPreSelPt", 5.0f, "Maximum allowed pT"}; Configurable cfgCutPtLower{"cfgCutPtLower", 0.2f, "Lower pT cut"}; Configurable cfgCutPtUpper{"cfgCutPtUpper", 3.0f, "Higher pT cut"}; Configurable cfgCutTpcChi2NCl{"cfgCutTpcChi2NCl", 2.5f, "Maximum TPCchi2NCl"}; @@ -75,27 +77,71 @@ struct MeanptFluctuations_QA_QnTable { Configurable cfgITScluster{"cfgITScluster", 1, "Minimum Number of ITS cluster"}; Configurable cfgTPCcluster{"cfgTPCcluster", 80, "Minimum Number of TPC cluster"}; Configurable cfgTPCnCrossedRows{"cfgTPCnCrossedRows", 70, "Minimum Number of TPC crossed-rows"}; - ConfigurableAxis nchAxis{"nchAxis", {5000, 0.5, 5000.5}, ""}; + ConfigurableAxis nchAxis{"nchAxis", {500, 0.5, 500.5}, "Axis for multiplicity of GlobalTracks/PVTracks"}; + ConfigurableAxis nchAxis2{"nchAxis2", {1000, 0.5, 30000.5}, "Axis for multiplicity of FT0A/FT0C/FV0A"}; + ConfigurableAxis nchAxis3{"nchAxis3", {1000, 0.5, 100000.5}, "Axis for multiplicity of FT0A/FT0C/FV0A"}; + ConfigurableAxis centAxis{"centAxis", {90, 0., 90.0}, ""}; Configurable cfgEvSelkNoSameBunchPileup{"cfgEvSelkNoSameBunchPileup", true, "Pileup removal"}; Configurable cfgUseGoodITSLayerAllCut{"cfgUseGoodITSLayerAllCut", true, "Remove time interval with dead ITS zone"}; + Configurable cfgEvSelkNoITSROFrameBorder{"cfgEvSelkNoITSROFrameBorder", true, "ITSROFrame border event selection cut"}; + Configurable cfgEvSelkNoTimeFrameBorder{"cfgEvSelkNoTimeFrameBorder", true, "TimeFrame border event selection cut"}; + Configurable cfgCentralityEstimator{"cfgCentralityEstimator", 1, "Centrlaity estimatore choice: 1-->FT0C, 2-->FT0A; 3-->FT0M, 4-->FV0A"}; + + O2_DEFINE_CONFIGURABLE(cfgEvSelMultCorrelation, bool, true, "Multiplicity correlation cut") + O2_DEFINE_CONFIGURABLE(cfgEvSelV0AT0ACut, bool, true, "V0A T0A 5 sigma cut") + struct : ConfigurableGroup { + O2_DEFINE_CONFIGURABLE(cfgMultCentHighCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x + 10.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultCentLowCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x - 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultT0CCutEnabled, bool, false, "Enable Global multiplicity vs T0C centrality cut") + Configurable> cfgMultT0CCutPars{"cfgMultT0CCutPars", std::vector{143.04, -4.58368, 0.0766055, -0.000727796, 2.86153e-06, 23.3108, -0.36304, 0.00437706, -4.717e-05, 1.98332e-07}, "Global multiplicity vs T0C centrality cut parameter values"}; + O2_DEFINE_CONFIGURABLE(cfgMultPVT0CCutEnabled, bool, false, "Enable PV multiplicity vs T0C centrality cut") + Configurable> cfgMultPVT0CCutPars{"cfgMultPVT0CCutPars", std::vector{195.357, -6.15194, 0.101313, -0.000955828, 3.74793e-06, 30.0326, -0.43322, 0.00476265, -5.11206e-05, 2.13613e-07}, "PV multiplicity vs T0C centrality cut parameter values"}; + + O2_DEFINE_CONFIGURABLE(cfgMultMultPVHighCutFunction, std::string, "[0]+[1]*x + 5.*([2]+[3]*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultMultPVLowCutFunction, std::string, "[0]+[1]*x - 5.*([2]+[3]*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultGlobalPVCutEnabled, bool, false, "Enable global multiplicity vs PV multiplicity cut") + Configurable> cfgMultGlobalPVCutPars{"cfgMultGlobalPVCutPars", std::vector{-0.140809, 0.734344, 2.77495, 0.0165935}, "PV multiplicity vs T0C centrality cut parameter values"}; + + O2_DEFINE_CONFIGURABLE(cfgMultMultV0AHighCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x + 4.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultMultV0ALowCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x - 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultMultV0ACutEnabled, bool, false, "Enable global multiplicity vs V0A multiplicity cut") + Configurable> cfgMultMultV0ACutPars{"cfgMultMultV0ACutPars", std::vector{534.893, 184.344, 0.423539, -0.00331436, 5.34622e-06, 871.239, 53.3735, -0.203528, 0.000122758, 5.41027e-07}, "Global multiplicity vs V0A multiplicity cut parameter values"}; + + std::vector multT0CCutPars; + std::vector multPVT0CCutPars; + std::vector multGlobalPVCutPars; + std::vector multMultV0ACutPars; + TF1* fMultPVT0CCutLow = nullptr; + TF1* fMultPVT0CCutHigh = nullptr; + TF1* fMultT0CCutLow = nullptr; + TF1* fMultT0CCutHigh = nullptr; + TF1* fMultGlobalPVCutLow = nullptr; + TF1* fMultGlobalPVCutHigh = nullptr; + TF1* fMultMultV0ACutLow = nullptr; + TF1* fMultMultV0ACutHigh = nullptr; + TF1* fT0AV0AMean = nullptr; + TF1* fT0AV0ASigma = nullptr; + + } cfgFuncParas; O2_DEFINE_CONFIGURABLE(cfgUse22sEventCut, bool, true, "Use 22s event cut on mult correlations") + O2_DEFINE_CONFIGURABLE(cfgUseSmallIonAdditionalEventCut, bool, true, "Use additional event cut on mult correlations for small ions") // Filter command*********** Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; - Filter trackFilter = (nabs(aod::track::eta) < 0.8f) && (aod::track::pt > cfgCutPtLower) && (aod::track::pt < 5.0f) && (requireGlobalTrackInFilter()) && (aod::track::tpcChi2NCl < cfgCutTpcChi2NCl) && (aod::track::itsChi2NCl < cfgCutItsChi2NCl) && (nabs(aod::track::dcaZ) < cfgCutTrackDcaZ); + Filter trackFilter = (nabs(aod::track::eta) < cfgCutPreSelEta) && (aod::track::pt > cfgCutPtLower) && (aod::track::pt < cfgCutPreSelPt) && (requireGlobalTrackInFilter()) && (aod::track::tpcChi2NCl < cfgCutTpcChi2NCl) && (aod::track::itsChi2NCl < cfgCutItsChi2NCl) && (nabs(aod::track::dcaZ) < cfgCutTrackDcaZ); // Connect to ccdb Service ccdb; - Configurable nolaterthan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; - Configurable url{"ccdb-url", "http://ccdb-test.cern.ch:8080", "url of the ccdb repository"}; + Configurable ccdbnolaterthan{"ccdbnolaterthan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; + Configurable ccdburl{"ccdburl", "http://ccdb-test.cern.ch:8080", "url of the ccdb repository"}; HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; // filtering collisions and tracks*********** - using aodCollisions = soa::Filtered>; + using AodCollisions = soa::Filtered>; // using aodCollisions = soa::Filtered>; - using aodTracks = soa::Filtered>; + using AodTracks = soa::Filtered>; // Event selection cuts - Alex TF1* fMultPVCutLow = nullptr; @@ -113,8 +159,6 @@ struct MeanptFluctuations_QA_QnTable { // Variable bin width axis std::vector ptBinning = {0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.8, 2.0, 2.2, 2.4, 2.8, 3.2, 3.6, 4.}; AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; - std::vector centBining = {0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90}; - AxisSpec centAxis = {centBining, "centrality (%)"}; // Add histograms to histogram manager (as in the output object of in AliPhysics) histos.add("hZvtx_after_sel", ";Z (cm)", kTH1F, {vtxZAxis}); @@ -128,6 +172,22 @@ struct MeanptFluctuations_QA_QnTable { histos.add("hMeanPt", "", kTProfile, {centAxis}); histos.add("Hist2D_globalTracks_PVTracks", "", {HistType::kTH2D, {nchAxis, nchAxis}}); histos.add("Hist2D_cent_nch", "", {HistType::kTH2D, {nchAxis, centAxis}}); + // before selection + histos.add("MultCorrelationPlots/BeforeSelection/His2D_globalTracks_PVTracks_beforeSel", "", {HistType::kTH2D, {nchAxis, nchAxis}}); + histos.add("MultCorrelationPlots/BeforeSelection/His2D_globalTracks_centFT0C_beforeSel", "", {HistType::kTH2D, {centAxis, nchAxis}}); + histos.add("MultCorrelationPlots/BeforeSelection/His2D_PVTracks_centFT0C_beforeSel", "", {HistType::kTH2D, {centAxis, nchAxis}}); + histos.add("MultCorrelationPlots/BeforeSelection/His2D_globalTracks_V0ATracks_beforeSel", "", {HistType::kTH2D, {nchAxis3, nchAxis}}); + histos.add("MultCorrelationPlots/BeforeSelection/His2D_globalTracks_T0ATracks_beforeSel", "", {HistType::kTH2D, {nchAxis2, nchAxis}}); + histos.add("MultCorrelationPlots/BeforeSelection/His2D_V0ATracks_T0CTracks_beforeSel", "", {HistType::kTH2D, {nchAxis2, nchAxis3}}); + // after selection + if (cfgUseSmallIonAdditionalEventCut) { + histos.add("MultCorrelationPlots/AfterSelection/His2D_globalTracks_PVTracks_afterSel", "", {HistType::kTH2D, {nchAxis, nchAxis}}); + histos.add("MultCorrelationPlots/AfterSelection/His2D_globalTracks_centFT0C_afterSel", "", {HistType::kTH2D, {centAxis, nchAxis}}); + histos.add("MultCorrelationPlots/AfterSelection/His2D_PVTracks_centFT0C_afterSel", "", {HistType::kTH2D, {centAxis, nchAxis}}); + histos.add("MultCorrelationPlots/AfterSelection/His2D_globalTracks_V0ATracks_afterSel", "", {HistType::kTH2D, {nchAxis3, nchAxis}}); + histos.add("MultCorrelationPlots/AfterSelection/His2D_globalTracks_T0ATracks_afterSel", "", {HistType::kTH2D, {nchAxis2, nchAxis}}); + histos.add("MultCorrelationPlots/AfterSelection/His2D_V0ATracks_T0CTracks_afterSel", "", {HistType::kTH2D, {nchAxis2, nchAxis3}}); + } // Event selection - Alex if (cfgUse22sEventCut) { @@ -144,6 +204,33 @@ struct MeanptFluctuations_QA_QnTable { fMultMultPVCut->SetParameters(-0.1, 0.785, -4.7e-05); } + if (cfgEvSelMultCorrelation) { + cfgFuncParas.multT0CCutPars = cfgFuncParas.cfgMultT0CCutPars; + cfgFuncParas.multPVT0CCutPars = cfgFuncParas.cfgMultPVT0CCutPars; + cfgFuncParas.multGlobalPVCutPars = cfgFuncParas.cfgMultGlobalPVCutPars; + cfgFuncParas.multMultV0ACutPars = cfgFuncParas.cfgMultMultV0ACutPars; + cfgFuncParas.fMultPVT0CCutLow = new TF1("fMultPVT0CCutLow", cfgFuncParas.cfgMultCentLowCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultPVT0CCutLow->SetParameters(&(cfgFuncParas.multPVT0CCutPars[0])); + cfgFuncParas.fMultPVT0CCutHigh = new TF1("fMultPVT0CCutHigh", cfgFuncParas.cfgMultCentHighCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultPVT0CCutHigh->SetParameters(&(cfgFuncParas.multPVT0CCutPars[0])); + cfgFuncParas.fMultT0CCutLow = new TF1("fMultT0CCutLow", cfgFuncParas.cfgMultCentLowCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultT0CCutLow->SetParameters(&(cfgFuncParas.multT0CCutPars[0])); + cfgFuncParas.fMultT0CCutHigh = new TF1("fMultT0CCutHigh", cfgFuncParas.cfgMultCentHighCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultT0CCutHigh->SetParameters(&(cfgFuncParas.multT0CCutPars[0])); + cfgFuncParas.fMultGlobalPVCutLow = new TF1("fMultGlobalPVCutLow", cfgFuncParas.cfgMultMultPVLowCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultGlobalPVCutLow->SetParameters(&(cfgFuncParas.multGlobalPVCutPars[0])); + cfgFuncParas.fMultGlobalPVCutHigh = new TF1("fMultGlobalPVCutHigh", cfgFuncParas.cfgMultMultPVHighCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultGlobalPVCutHigh->SetParameters(&(cfgFuncParas.multGlobalPVCutPars[0])); + cfgFuncParas.fMultMultV0ACutLow = new TF1("fMultMultV0ACutLow", cfgFuncParas.cfgMultMultV0ALowCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultMultV0ACutLow->SetParameters(&(cfgFuncParas.multMultV0ACutPars[0])); + cfgFuncParas.fMultMultV0ACutHigh = new TF1("fMultMultV0ACutHigh", cfgFuncParas.cfgMultMultV0AHighCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultMultV0ACutHigh->SetParameters(&(cfgFuncParas.multMultV0ACutPars[0])); + cfgFuncParas.fT0AV0AMean = new TF1("fT0AV0AMean", "[0]+[1]*x", 0, 200000); + cfgFuncParas.fT0AV0AMean->SetParameters(-1601.0581, 9.417652e-01); + cfgFuncParas.fT0AV0ASigma = new TF1("fT0AV0ASigma", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 200000); + cfgFuncParas.fT0AV0ASigma->SetParameters(463.4144, 6.796509e-02, -9.097136e-07, 7.971088e-12, -2.600581e-17); + } + } //! end init function template @@ -157,7 +244,9 @@ struct MeanptFluctuations_QA_QnTable { if (collision.numContrib() > 1) { vtxz = collision.posZ(); float zRes = std::sqrt(collision.covZZ()); - if (zRes > 0.25 && collision.numContrib() < 20) + float zResMax = 0.25; + float numContribMin = 20; + if (zRes > zResMax && collision.numContrib() < numContribMin) vtxz = -999; } auto multNTracksPV = collision.multNTracksPV(); @@ -178,10 +267,52 @@ struct MeanptFluctuations_QA_QnTable { return 1; } - Produces mult_ptQn; + template + bool eventSelectedSmallion(TCollision collision, const int multTrk, const float centrality) + { + auto multNTracksPV = collision.multNTracksPV(); + + if (cfgEvSelMultCorrelation) { + if (cfgFuncParas.cfgMultPVT0CCutEnabled) { + if (multNTracksPV < cfgFuncParas.fMultPVT0CCutLow->Eval(centrality)) + return 0; + if (multNTracksPV > cfgFuncParas.fMultPVT0CCutHigh->Eval(centrality)) + return 0; + } + + if (cfgFuncParas.cfgMultT0CCutEnabled) { + if (multTrk < cfgFuncParas.fMultT0CCutLow->Eval(centrality)) + return 0; + if (multTrk > cfgFuncParas.fMultT0CCutHigh->Eval(centrality)) + return 0; + } + + if (cfgFuncParas.cfgMultGlobalPVCutEnabled) { + if (multTrk < cfgFuncParas.fMultGlobalPVCutLow->Eval(multNTracksPV)) + return 0; + if (multTrk > cfgFuncParas.fMultGlobalPVCutHigh->Eval(multNTracksPV)) + return 0; + } + + if (cfgFuncParas.cfgMultMultV0ACutEnabled) { + if (collision.multFV0A() < cfgFuncParas.fMultMultV0ACutLow->Eval(multTrk)) + return 0; + if (collision.multFV0A() > cfgFuncParas.fMultMultV0ACutHigh->Eval(multTrk)) + return 0; + } + } + + float sigma = 5.0; + if (cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - cfgFuncParas.fT0AV0AMean->Eval(collision.multFT0A())) > sigma * cfgFuncParas.fT0AV0ASigma->Eval(collision.multFT0A()))) + return 0; + + return 1; + } + + Produces multPtQn; // void process(aod::Collision const& coll, aod::Tracks const& inputTracks) - void process(aodCollisions::iterator const& coll, aod::BCsWithTimestamps const&, aodTracks const& inputTracks) + void process(AodCollisions::iterator const& coll, aod::BCsWithTimestamps const&, AodTracks const& inputTracks) { if (!coll.sel8()) { return; @@ -192,26 +323,65 @@ struct MeanptFluctuations_QA_QnTable { if (cfgEvSelkNoSameBunchPileup && !(coll.selection_bit(o2::aod::evsel::kNoSameBunchPileup))) { return; } + if (cfgEvSelkNoITSROFrameBorder && !(coll.selection_bit(o2::aod::evsel::kNoITSROFrameBorder))) { + return; + } + if (cfgEvSelkNoTimeFrameBorder && !(coll.selection_bit(o2::aod::evsel::kNoTimeFrameBorder))) { + return; + } + + histos.fill(HIST("MultCorrelationPlots/BeforeSelection/His2D_globalTracks_PVTracks_beforeSel"), coll.multNTracksPV(), inputTracks.size()); + histos.fill(HIST("MultCorrelationPlots/BeforeSelection/His2D_globalTracks_centFT0C_beforeSel"), coll.centFT0C(), inputTracks.size()); + histos.fill(HIST("MultCorrelationPlots/BeforeSelection/His2D_PVTracks_centFT0C_beforeSel"), coll.centFT0C(), coll.multNTracksPV()); + histos.fill(HIST("MultCorrelationPlots/BeforeSelection/His2D_globalTracks_V0ATracks_beforeSel"), coll.multFV0A(), inputTracks.size()); + histos.fill(HIST("MultCorrelationPlots/BeforeSelection/His2D_globalTracks_T0ATracks_beforeSel"), coll.multFT0A(), inputTracks.size()); + histos.fill(HIST("MultCorrelationPlots/BeforeSelection/His2D_V0ATracks_T0CTracks_beforeSel"), coll.multFT0C(), coll.multFV0A()); - const auto CentralityFT0C = coll.centFT0C(); - if (cfgUse22sEventCut && !eventSelected(coll, inputTracks.size(), CentralityFT0C)) + const auto centralityFT0C = coll.centFT0C(); + if (cfgUse22sEventCut && !eventSelected(coll, inputTracks.size(), centralityFT0C)) + return; + if (cfgUseSmallIonAdditionalEventCut && !eventSelectedSmallion(coll, inputTracks.size(), centralityFT0C)) return; + if (cfgUseSmallIonAdditionalEventCut) { + histos.fill(HIST("MultCorrelationPlots/AfterSelection/His2D_globalTracks_PVTracks_afterSel"), coll.multNTracksPV(), inputTracks.size()); + histos.fill(HIST("MultCorrelationPlots/AfterSelection/His2D_globalTracks_centFT0C_afterSel"), coll.centFT0C(), inputTracks.size()); + histos.fill(HIST("MultCorrelationPlots/AfterSelection/His2D_PVTracks_centFT0C_afterSel"), coll.centFT0C(), coll.multNTracksPV()); + histos.fill(HIST("MultCorrelationPlots/AfterSelection/His2D_globalTracks_V0ATracks_afterSel"), coll.multFV0A(), inputTracks.size()); + histos.fill(HIST("MultCorrelationPlots/AfterSelection/His2D_globalTracks_T0ATracks_afterSel"), coll.multFT0A(), inputTracks.size()); + histos.fill(HIST("MultCorrelationPlots/AfterSelection/His2D_V0ATracks_T0CTracks_afterSel"), coll.multFT0C(), coll.multFV0A()); + } + histos.fill(HIST("hZvtx_after_sel"), coll.posZ()); - histos.fill(HIST("hCentrality"), coll.centFT0C()); + + double cent = 0.0; + int centChoiceFT0C = 1; + int centChoiceFT0A = 2; + int centChoiceFT0M = 3; + int centChoiceFV0A = 4; + if (cfgCentralityEstimator == centChoiceFT0C) + cent = coll.centFT0C(); + else if (cfgCentralityEstimator == centChoiceFT0A) + cent = coll.centFT0A(); + else if (cfgCentralityEstimator == centChoiceFT0M) + cent = coll.centFT0M(); + else if (cfgCentralityEstimator == centChoiceFV0A) + cent = coll.centFV0A(); + + histos.fill(HIST("hCentrality"), cent); + histos.fill(HIST("Hist2D_globalTracks_PVTracks"), coll.multNTracksPV(), inputTracks.size()); - histos.fill(HIST("Hist2D_cent_nch"), inputTracks.size(), CentralityFT0C); + histos.fill(HIST("Hist2D_cent_nch"), inputTracks.size(), centralityFT0C); // variables - double cent = coll.centFT0C(); - double pT_sum = 0.0; - double N = 0.0; + double pTsum = 0.0; + double nN = 0.0; float q1 = 0.0; float q2 = 0.0; float q3 = 0.0; float q4 = 0.0; - float n_ch = 0.0; + float nCh = 0.0; for (const auto& track : inputTracks) { // Loop over tracks @@ -234,44 +404,45 @@ struct MeanptFluctuations_QA_QnTable { histos.fill(HIST("hDcaXY"), track.dcaXY()); histos.fill(HIST("hDcaZ"), track.dcaZ()); - pT_sum += track.pt(); - N += 1.0; + pTsum += track.pt(); + nN += 1.0; float pT = track.pt(); - // calculating Q1, Q2, Q3, Q4. N_ch + // calculating Q1, Q2, Q3, Q4. Nch if (track.pt() > cfgCutPtLower && track.pt() < cfgCutPtUpper && track.sign() != 0) { q1 = q1 + std::pow(pT, 1.0); q2 = q2 + std::pow(pT, 2.0); q3 = q3 + std::pow(pT, 3.0); q4 = q4 + std::pow(pT, 4.0); - n_ch = n_ch + 1; + nCh = nCh + 1; } } - mult_ptQn(q1, q2, q3, q4, n_ch, cent); + multPtQn(q1, q2, q3, q4, nCh, cent); // MeanPt - if (N > 0.0f) - histos.fill(HIST("hMeanPt"), cent, pT_sum / N); + if (nN > 0.0f) + histos.fill(HIST("hMeanPt"), cent, pTsum / nN); } }; -struct MeanptFluctuations_analysis { +struct MeanptFluctuationsAnalysis { - Configurable cfgNSubsample{"cfgNSubsample", 10, "Number of subsamples"}; + Configurable cfgNsubSample{"cfgNsubSample", 10, "Number of subsamples"}; ConfigurableAxis centAxis{"centAxis", {90, 0, 90}, ""}; ConfigurableAxis multAxis{"multAxis", {5000, 0.5, 5000.5}, ""}; ConfigurableAxis meanpTAxis{"meanpTAxis", {500, 0, 5.0}, ""}; - expressions::Filter Nch_filter = aod::ptQn::n_ch > 3.0f; + float minNch = 3.0f; + expressions::Filter nchFilter = aod::pt_qn::nch > minNch; using FilteredMultPtQn = soa::Filtered; // Connect to ccdb Service ccdb; - Configurable nolaterthan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; - Configurable url{"ccdb-url", "http://ccdb-test.cern.ch:8080", "url of the ccdb repository"}; + Configurable ccdbnolaterthan{"ccdbnolaterthan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; + Configurable ccdburl{"ccdburl", "http://ccdb-test.cern.ch:8080", "url of the ccdb repository"}; // Define output HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; - std::vector>> Subsample; + std::vector>> subSample; TRandom3* fRndm = new TRandom3(0); void init(o2::framework::InitContext&) @@ -287,49 +458,49 @@ struct MeanptFluctuations_analysis { registry.add("Hist2D_meanpt_centrality", "", {HistType::kTH2D, {centAxis, meanpTAxis}}); // initial array - Subsample.resize(cfgNSubsample); - for (int i = 0; i < cfgNSubsample; i++) { - Subsample[i].resize(4); + subSample.resize(cfgNsubSample); + for (int i = 0; i < cfgNsubSample; i++) { + subSample[i].resize(4); } - for (int i = 0; i < cfgNSubsample; i++) { - Subsample[i][0] = std::get>(registry.add(Form("Subsample_%d/Prof_mean_t1", i), "", {HistType::kTProfile2D, {centAxis, multAxis}})); - Subsample[i][1] = std::get>(registry.add(Form("Subsample_%d/Prof_var_t1", i), "", {HistType::kTProfile2D, {centAxis, multAxis}})); - Subsample[i][2] = std::get>(registry.add(Form("Subsample_%d/Prof_skew_t1", i), "", {HistType::kTProfile2D, {centAxis, multAxis}})); - Subsample[i][3] = std::get>(registry.add(Form("Subsample_%d/Prof_kurt_t1", i), "", {HistType::kTProfile2D, {centAxis, multAxis}})); + for (int i = 0; i < cfgNsubSample; i++) { + subSample[i][0] = std::get>(registry.add(Form("subSample_%d/Prof_mean_t1", i), "", {HistType::kTProfile2D, {centAxis, multAxis}})); + subSample[i][1] = std::get>(registry.add(Form("subSample_%d/Prof_var_t1", i), "", {HistType::kTProfile2D, {centAxis, multAxis}})); + subSample[i][2] = std::get>(registry.add(Form("subSample_%d/Prof_skew_t1", i), "", {HistType::kTProfile2D, {centAxis, multAxis}})); + subSample[i][3] = std::get>(registry.add(Form("subSample_%d/Prof_kurt_t1", i), "", {HistType::kTProfile2D, {centAxis, multAxis}})); } } - float mean_term1; - float variance_term1; - float skewness_term1; - float kurtosis_term1; + float meanTerm1; + float varianceTerm1; + float skewnessTerm1; + float kurtosisTerm1; // void process(aod::MultPtQn::iterator const& event_ptqn) void process(FilteredMultPtQn::iterator const& event_ptqn) { - // LOGF(info, "Centrality= %f Nch= %f Q1= %f Q2= %f", event_ptqn.centrality(), event_ptqn.n_ch(), event_ptqn.q1(), event_ptqn.q2()); + // LOGF(info, "Centrality= %f Nch= %f Q1= %f Q2= %f", event_ptqn.centrality(), event_ptqn.nch(), event_ptqn.q1(), event_ptqn.q2()); // calculating observables - mean_term1 = event_ptqn.q1() / event_ptqn.n_ch(); - variance_term1 = (std::pow(event_ptqn.q1(), 2.0f) - event_ptqn.q2()) / (event_ptqn.n_ch() * (event_ptqn.n_ch() - 1.0f)); - skewness_term1 = (std::pow(event_ptqn.q1(), 3.0f) - 3.0f * event_ptqn.q2() * event_ptqn.q1() + 2.0f * event_ptqn.q3()) / (event_ptqn.n_ch() * (event_ptqn.n_ch() - 1.0f) * (event_ptqn.n_ch() - 2.0f)); - kurtosis_term1 = (std::pow(event_ptqn.q1(), 4.0f) - (6.0f * event_ptqn.q4()) + (8.0f * event_ptqn.q1() * event_ptqn.q3()) - (6.0f * std::pow(event_ptqn.q1(), 2.0f) * event_ptqn.q2()) + (3.0f * std::pow(event_ptqn.q2(), 2.0f))) / (event_ptqn.n_ch() * (event_ptqn.n_ch() - 1.0f) * (event_ptqn.n_ch() - 2.0f) * (event_ptqn.n_ch() - 3.0f)); + meanTerm1 = event_ptqn.q1() / event_ptqn.nch(); + varianceTerm1 = (std::pow(event_ptqn.q1(), 2.0f) - event_ptqn.q2()) / (event_ptqn.nch() * (event_ptqn.nch() - 1.0f)); + skewnessTerm1 = (std::pow(event_ptqn.q1(), 3.0f) - 3.0f * event_ptqn.q2() * event_ptqn.q1() + 2.0f * event_ptqn.q3()) / (event_ptqn.nch() * (event_ptqn.nch() - 1.0f) * (event_ptqn.nch() - 2.0f)); + kurtosisTerm1 = (std::pow(event_ptqn.q1(), 4.0f) - (6.0f * event_ptqn.q4()) + (8.0f * event_ptqn.q1() * event_ptqn.q3()) - (6.0f * std::pow(event_ptqn.q1(), 2.0f) * event_ptqn.q2()) + (3.0f * std::pow(event_ptqn.q2(), 2.0f))) / (event_ptqn.nch() * (event_ptqn.nch() - 1.0f) * (event_ptqn.nch() - 2.0f) * (event_ptqn.nch() - 3.0f)); // filling profiles and histograms for central values - registry.get(HIST("Prof_mean_t1"))->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), mean_term1); - registry.get(HIST("Prof_var_t1"))->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), variance_term1); - registry.get(HIST("Prof_skew_t1"))->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), skewness_term1); - registry.get(HIST("Prof_kurt_t1"))->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), kurtosis_term1); - registry.fill(HIST("Hist2D_Nch_centrality"), event_ptqn.centrality(), event_ptqn.n_ch()); - registry.fill(HIST("Hist2D_meanpt_centrality"), event_ptqn.centrality(), mean_term1); + registry.get(HIST("Prof_mean_t1"))->Fill(event_ptqn.centrality(), event_ptqn.nch(), meanTerm1); + registry.get(HIST("Prof_var_t1"))->Fill(event_ptqn.centrality(), event_ptqn.nch(), varianceTerm1); + registry.get(HIST("Prof_skew_t1"))->Fill(event_ptqn.centrality(), event_ptqn.nch(), skewnessTerm1); + registry.get(HIST("Prof_kurt_t1"))->Fill(event_ptqn.centrality(), event_ptqn.nch(), kurtosisTerm1); + registry.fill(HIST("Hist2D_Nch_centrality"), event_ptqn.centrality(), event_ptqn.nch()); + registry.fill(HIST("Hist2D_meanpt_centrality"), event_ptqn.centrality(), meanTerm1); // selecting subsample and filling profiles - float l_Random = fRndm->Rndm(); - int SampleIndex = static_cast(cfgNSubsample * l_Random); - Subsample[SampleIndex][0]->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), mean_term1); - Subsample[SampleIndex][1]->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), variance_term1); - Subsample[SampleIndex][2]->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), skewness_term1); - Subsample[SampleIndex][3]->Fill(event_ptqn.centrality(), event_ptqn.n_ch(), kurtosis_term1); + float lRandom = fRndm->Rndm(); + int sampleIndex = static_cast(cfgNsubSample * lRandom); + subSample[sampleIndex][0]->Fill(event_ptqn.centrality(), event_ptqn.nch(), meanTerm1); + subSample[sampleIndex][1]->Fill(event_ptqn.centrality(), event_ptqn.nch(), varianceTerm1); + subSample[sampleIndex][2]->Fill(event_ptqn.centrality(), event_ptqn.nch(), skewnessTerm1); + subSample[sampleIndex][3]->Fill(event_ptqn.centrality(), event_ptqn.nch(), kurtosisTerm1); } }; @@ -337,7 +508,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { // Equivalent to the AddTask in AliPhysics return WorkflowSpec{ - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), }; } diff --git a/PWGCF/EbyEFluctuations/Tasks/eventMeanPtId.cxx b/PWGCF/EbyEFluctuations/Tasks/eventMeanPtId.cxx index 182876d39d1..7ef12c2b69f 100644 --- a/PWGCF/EbyEFluctuations/Tasks/eventMeanPtId.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/eventMeanPtId.cxx @@ -86,20 +86,11 @@ struct EventMeanPtId { Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable cfgUrlCCDB{"cfgUrlCCDB", "http://alice-ccdb.cern.ch", "url of ccdb"}; - Configurable cfgPathCCDB{"cfgPathCCDB", "Users/s/swsingh/My/Object/eff_Pb", "Path for ccdb-object"}; + Configurable cfgPathCCDB{"cfgPathCCDB", "Users/s/swsingh/My/Object/test", "Path for ccdb-object"}; Configurable cfgLoadEff{"cfgLoadEff", true, "Load efficiency"}; HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - TH1D* ptHistogramAllchargeRec = nullptr; - TH1D* ptHistogramPionrec = nullptr; - TH1D* ptHistogramKaonrec = nullptr; - TH1D* ptHistogramProtonrec = nullptr; - TH1D* hRecoPi = nullptr; - TH1D* hRecoKa = nullptr; - TH1D* hRecoPr = nullptr; - TH2D* hPtyPion = nullptr; - TH2D* hPtyKaon = nullptr; - TH2D* hPtyProton = nullptr; + TH2D* ptHistogramAllchargeRec = nullptr; Configurable ptMax{"ptMax", 2.0, "maximum pT"}; Configurable ptMin{"ptMin", 0.15, "minimum pT"}; @@ -117,20 +108,7 @@ struct EventMeanPtId { // LOGF(info, "Getting object %s", ccdbPath.value.data()); TList* lst = ccdb->getForTimeStamp(cfgPathCCDB.value, -1); - ptHistogramAllchargeRec = reinterpret_cast(lst->FindObject("ptHistogramAllchargeRec")); - ptHistogramPionrec = reinterpret_cast(lst->FindObject("ptHistogramPionrec")); - ptHistogramKaonrec = reinterpret_cast(lst->FindObject("ptHistogramKaonrec")); - ptHistogramProtonrec = reinterpret_cast(lst->FindObject("ptHistogramProtonrec")); - hRecoPi = reinterpret_cast(lst->FindObject("hRecoPi")); - hRecoKa = reinterpret_cast(lst->FindObject("hRecoKa")); - hRecoPr = reinterpret_cast(lst->FindObject("hRecoPr")); - hPtyPion = reinterpret_cast(lst->FindObject("hPtyPion")); - hPtyKaon = reinterpret_cast(lst->FindObject("hPtyKaon")); - hPtyProton = reinterpret_cast(lst->FindObject("hPtyProton")); - - if (!ptHistogramAllchargeRec || !ptHistogramPionrec || !ptHistogramKaonrec || !ptHistogramProtonrec || !hRecoPi || !hRecoKa || !hRecoPr || !hPtyPion || !hPtyKaon || !hPtyProton) { - LOGF(info, "FATAL!! Could not find required histograms in CCDB"); - } + ptHistogramAllchargeRec = reinterpret_cast(lst->FindObject("hPtEta_rec")); } std::vector ptBinning = {0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4.0}; @@ -148,7 +126,8 @@ struct EventMeanPtId { AxisSpec nSigmaTOFAxispid = {170, -8.5, 8.5, "n#sigma_{TOF}"}; AxisSpec centAxis = {100, 0., 100., "centrality"}; AxisSpec subAxis = {30, 0., 30., "sample"}; - AxisSpec nchAxis = {4000, 0., 4000., "nch"}; + // AxisSpec nchAxis = {4000, 0., 4000., "nch"}; + AxisSpec nchAxis = {nchBins, nchMin, nchMax, "nch"}; AxisSpec varAxis1 = {400, 0., 4., "var1"}; AxisSpec varAxis2 = {400, 0., 4., "var2"}; AxisSpec chi2Axis = {100, 0., 100., "Chi2"}; @@ -157,7 +136,7 @@ struct EventMeanPtId { // QA Plots histos.add("hEventcounter", "event counts", kTH1D, {counter}); - auto h = histos.add("tracksel", "tracksel", HistType::kTH1D, {{10, 0.5, 10.5}}); + auto h = histos.add("tracksel", "tracksel", HistType::kTH1D, {{15, 0.5, 15.5}}); h->GetXaxis()->SetBinLabel(1, "Tracks read"); h->GetXaxis()->SetBinLabel(2, "Global track passed"); h->GetXaxis()->SetBinLabel(3, "DCAxy passed"); @@ -167,8 +146,9 @@ struct EventMeanPtId { h->GetXaxis()->SetBinLabel(7, "TPC crossed rows passed"); h->GetXaxis()->SetBinLabel(8, "TPC Chai2cluster passed"); h->GetXaxis()->SetBinLabel(9, "ITS Chai2cluster passed"); + h->GetXaxis()->SetBinLabel(10, "No. of ITS cluster 5 passed"); + h->GetXaxis()->SetBinLabel(11, "No. of TPC cluster 80 passed"); - histos.add("hEventcounter_recMC", "event counts rec MC", kTH1D, {counter}); auto hRec = histos.add("trackSelRec", "trackSelRec", HistType::kTH1D, {{10, 0.5, 10.5}}); hRec->GetXaxis()->SetBinLabel(1, "has_mcCollision() read"); hRec->GetXaxis()->SetBinLabel(2, "Vertex Z > 10cm passed"); @@ -179,7 +159,6 @@ struct EventMeanPtId { hRec->GetXaxis()->SetBinLabel(7, "klsVertexITSTPC passed"); histos.add("Data/hZvtx_before_sel", "hZvtx_before_sel", kTH1D, {vtxZAxis}); - histos.add("Data/hZvtx_after_sel", "hZvtx_after_sel", kTH1D, {vtxZAxis}); histos.add("Data/hZvtx_after_sel8", "hZvtx_after_sel8", kTH1D, {vtxZAxis}); histos.add("Data/hP", "hP", kTH1D, {pAxis}); histos.add("Data/hEta", ";hEta", kTH1D, {etaAxis}); @@ -207,29 +186,16 @@ struct EventMeanPtId { histos.add("Data/hyPion", ";hyPion", kTH1D, {etaAxis}); histos.add("Data/hyKaon", ";hyKaon", kTH1D, {etaAxis}); histos.add("Data/hyProton", ";hyProton", kTH1D, {etaAxis}); - histos.add("Data/hPtCh", "hPtCh", kTH2D, {nchAxis, ptAxis}); - histos.add("Data/hPtChPion", "hPtChPion", kTH2D, {nchAxis, ptAxis}); - histos.add("Data/hPtChKaon", "hPtChKaon", kTH2D, {nchAxis, ptAxis}); - histos.add("Data/hPtChProton", "hPtChProton", kTH2D, {nchAxis, ptAxis}); - histos.add("Data/hPtCent", "hPtCent", kTH2D, {centAxis, ptAxis}); - histos.add("Data/hPtCentPion", "hPtCentPion", kTH2D, {centAxis, ptAxis}); - histos.add("Data/hPtCentKaon", "hPtCentKaon", kTH2D, {centAxis, ptAxis}); - histos.add("Data/hPtCentProton", "hPtCentProton", kTH2D, {centAxis, ptAxis}); - histos.add("Data/hMeanPtCh", "hMeanPtCh", kTH2D, {nchAxis, ptAxis}); - histos.add("Data/hCent", "hCent", kTH2D, {nchAxis, centAxis}); histos.add("Data/hVar1", "hVar1", kTH2D, {subAxis, centAxis}); histos.add("Data/hVar2", "hVar2", kTH2D, {subAxis, centAxis}); histos.add("Data/hVar2meanpt", "hVar2meanpt", kTH2D, {centAxis, varAxis2}); - histos.add("Data/hVar", "hVar", kTH2D, {subAxis, centAxis}); histos.add("Data/hVarc", "hVarc", kTH2D, {subAxis, centAxis}); histos.add("Data/hVar1pi", "hVar1pi", kTH2D, {subAxis, centAxis}); histos.add("Data/hVar2pi", "hVar2pi", kTH2D, {subAxis, centAxis}); - histos.add("Data/hVarpi", "hVarpi", kTH2D, {subAxis, centAxis}); histos.add("Data/hVar2meanptpi", "hVar2meanptpi", kTH2D, {centAxis, varAxis2}); histos.add("Data/hVar1k", "hVar1k", kTH2D, {subAxis, centAxis}); histos.add("Data/hVar2k", "hVar2k", kTH2D, {subAxis, centAxis}); - histos.add("Data/hVark", "hVark", kTH2D, {subAxis, centAxis}); histos.add("Data/hVar2meanptk", "hVar2meanptk", kTH2D, {centAxis, varAxis2}); histos.add("Data/hVar1p", "hVar1p", kTH2D, {subAxis, centAxis}); histos.add("Data/hVar2p", "hVar2p", kTH2D, {subAxis, centAxis}); @@ -258,12 +224,9 @@ struct EventMeanPtId { histos.add("Data/hVar2px", "hVar2px", kTH2D, {subAxis, nchAxis}); histos.add("Data/hVarpx", "hVarpx", kTH2D, {subAxis, nchAxis}); histos.add("Data/hVar2meanptpx", "hVar2meanptpx", kTH2D, {nchAxis, varAxis2}); - histos.add("Data/ht", "ht", kTH1D, {centAxis}); histos.add("Data/hCentrality", "hCentrality", kTH1D, {centAxis}); histos.add("Data/hPEta", "hPEta", kTH2D, {pAxis, etaAxis}); histos.add("Data/hPtEta", "hPtEta", kTH2D, {ptAxis, etaAxis}); - histos.add("Data/hPy", "hPy", kTH2D, {pAxis, etaAxis}); - histos.add("Data/hPty", "hPty", kTH2D, {ptAxis, etaAxis}); histos.add("Data/hPtyPion", "hPtyPion", kTH2D, {ptAxis, etaAxis}); histos.add("Data/hPtyKaon", "hPtyKaon", kTH2D, {ptAxis, etaAxis}); histos.add("Data/hPtyProton", "hPtyProton", kTH2D, {ptAxis, etaAxis}); @@ -279,11 +242,11 @@ struct EventMeanPtId { histos.add("Data/hTPCchi2perCluster_after", "TPC #Chi^{2}/Cluster", kTH1D, {chi2Axis}); histos.add("Data/hITSchi2perCluster_after", "ITS #Chi^{2}/Cluster", kTH1D, {chi2Axis}); histos.add("Data/hTPCCrossedrows_after", "Crossed TPC rows", kTH1D, {crossedRowTpcAxis}); - histos.add("Data/hdEdx_rec_bf_anycut", "hdEdx_rec_bf_anycut", kTH2D, {pAxis, dEdxAxis}); histos.add("Data/hcent_nacc", "hcent_nacc", kTH2D, {centAxis, nchAxis}); histos.addClone("Data/", "Rec/"); // rec histograms + histos.add("hcent_nacc_corr", "hcent_nacc_corr", kTH2D, {centAxis, nchAxis}); histos.add("NSigamaTPCpion_rec", "NSigamaTPCpion_rec", kTH2D, {pAxis, nSigmaTPCAxispid}); histos.add("NSigamaTPCkaon_rec", "NSigamaTPCkaon_rec", kTH2D, {pAxis, nSigmaTPCAxispid}); histos.add("NSigamaTPCproton_rec", "NSigamaTPCproton_rec", kTH2D, {pAxis, nSigmaTPCAxispid}); @@ -293,56 +256,15 @@ struct EventMeanPtId { histos.add("NSigamaTPCTOFpion_rec", "NSigamaTPCTOFpion_rec", kTH2D, {nSigmaTPCAxispid, nSigmaTOFAxispid}); histos.add("NSigamaTPCTOFkaon_rec", "NSigamaTPCTOFkaon_rec", kTH2D, {nSigmaTPCAxispid, nSigmaTOFAxispid}); histos.add("NSigamaTPCTOFproton_rec", "NSigamaTPCTOFproton_rec", kTH2D, {nSigmaTPCAxispid, nSigmaTOFAxispid}); - histos.add("NSigamaTPCpion_rec_bf_sel", "NSigamaTPCpion_rec_bf_sel", kTH2D, {pAxis, nSigmaTPCAxispid}); - histos.add("NSigamaTPCkaon_rec_bf_sel", "NSigamaTPCkaon_rec_bf_sel", kTH2D, {pAxis, nSigmaTPCAxispid}); - histos.add("NSigamaTPCproton_rec_bf_sel", "NSigamaTPCproton_rec_bf_sel", kTH2D, {pAxis, nSigmaTPCAxispid}); - histos.add("NSigamaTOFpion_rec_bf_sel", "NSigamaTOFpion_rec_bf_sel", kTH2D, {pAxis, nSigmaTOFAxispid}); - histos.add("NSigamaTOFkaon_rec_bf_sel", "NSigamaTOFkaon_rec_bf_sel", kTH2D, {pAxis, nSigmaTOFAxispid}); - histos.add("NSigamaTOFproton_rec_bf_sel", "NSigamaTOFproton_rec_bf_sel", kTH2D, {pAxis, nSigmaTOFAxispid}); - histos.add("NSigamaTPCTOFpion_rec_bf_sel", "NSigamaTPCTOFpion_rec_bf_sel", kTH2D, {nSigmaTPCAxispid, nSigmaTOFAxispid}); - histos.add("NSigamaTPCTOFkaon_rec_bf_sel", "NSigamaTPCTOFkaon_rec_bf_sel", kTH2D, {nSigmaTPCAxispid, nSigmaTOFAxispid}); - histos.add("NSigamaTPCTOFproton_rec_bf_sel", "NSigamaTPCTOFproton_rec_bf_sel", kTH2D, {nSigmaTPCAxispid, nSigmaTOFAxispid}); histos.add("hPtyPion_rec", "hPtyPion_rec", kTH2D, {ptAxis, etaAxis}); histos.add("hPtyKaon_rec", "hPtyKaon_rec", kTH2D, {ptAxis, etaAxis}); histos.add("hPtyProton_rec", "hPtyProton_rec", kTH2D, {ptAxis, etaAxis}); histos.add("hPyPion_rec", "hPyPion_rec", kTH2D, {pAxis, etaAxis}); histos.add("hPyKaon_rec", "hPyKaon_rec", kTH2D, {pAxis, etaAxis}); histos.add("hPyProton_rec", "hPyProton_rec", kTH2D, {pAxis, etaAxis}); - histos.add("hTOFbeta_afterselection_rec_afterpidcut", "hTOFbeta_afterselection_rec_afterpidcut", kTH2D, {pAxis, betaAxis}); - histos.add("hdEdx_afterselection_rec_afterpidcut", "hdEdx_afterselection_rec_afterpidcut", kTH2D, {pAxis, dEdxAxis}); histos.add("hTOFbeta_afterselection_rec_beforepidcut", "hTOFbeta_afterselection_rec_beforepidcut", kTH2D, {pAxis, betaAxis}); histos.add("hdEdx_afterselection_rec_beforepidcut", "hdEdx_afterselection_rec_beforepidcut", kTH2D, {pAxis, dEdxAxis}); - histos.add("heffVar1x", "heffVar1x", kTH2D, {subAxis, nchAxis}); - histos.add("heffVar2x", "heffVar2x", kTH2D, {subAxis, nchAxis}); - histos.add("heffVarx", "heffVarx", kTH2D, {subAxis, nchAxis}); - histos.add("heffVar2meanptx", "heffVar2meanptx", kTH2D, {nchAxis, varAxis2}); - histos.add("hnchRec_all", ";hnchRec_all", kTH1D, {nchAxis}); - histos.add("hnchRec", ";hnchRec", kTH1D, {nchAxis}); - histos.add("hnchRec_true", ";hnchRec_true", kTH1D, {nchAxis}); - histos.add("hVar1x_rec_old", "hVar1x_rec_old", kTH2D, {subAxis, nchAxis}); - histos.add("hVar2x_rec_old", "hVar2x_rec_old", kTH2D, {subAxis, nchAxis}); - histos.add("hVarx_rec_old", "hVarx_rec_old", kTH2D, {subAxis, nchAxis}); - histos.add("hVar1x_rec", "hVar1x_rec", kTH2D, {subAxis, nchAxis}); - histos.add("hVar2x_rec", "hVar2x_rec", kTH2D, {subAxis, nchAxis}); - histos.add("hVarx_rec", "hVarx_rec", kTH2D, {subAxis, nchAxis}); - histos.add("hVar2meanptx_rec", "hVar2meanptx_rec", kTH2D, {nchAxis, varAxis2}); - histos.add("hVar1pix_rec", "hVar1pix_rec", kTH2D, {subAxis, nchAxis}); - histos.add("hVar2pix_rec", "hVar2pix_rec", kTH2D, {subAxis, nchAxis}); - histos.add("hVarpix_rec", "hVarpix_rec", kTH2D, {subAxis, nchAxis}); - histos.add("hVar2meanptpix_rec", "hVar2meanptpix_rec", kTH2D, {nchAxis, varAxis2}); - histos.add("hVar1kx_rec", "hVar1kx_rec", kTH2D, {subAxis, nchAxis}); - histos.add("hVar2kx_rec", "hVar2kx_rec", kTH2D, {subAxis, nchAxis}); - histos.add("hVarkx_rec", "hVarkx_rec", kTH2D, {subAxis, nchAxis}); - histos.add("hVar2meanptkx_rec", "hVar2meanptkx_rec", kTH2D, {nchAxis, varAxis2}); - histos.add("hVar1px_rec", "hVar1px_rec", kTH2D, {subAxis, nchAxis}); - histos.add("hVar2px_rec", "hVar2px_rec", kTH2D, {subAxis, nchAxis}); - histos.add("hVarpx_rec", "hVarpx_rec", kTH2D, {subAxis, nchAxis}); - histos.add("hVar2meanptpx_rec", "hVar2meanptpx_rec", kTH2D, {nchAxis, varAxis2}); - histos.add("hZvtx_after_sel_rec", "hZvtx_after_sel_rec", kTH1D, {vtxZAxis}); - histos.add("hZvtx_after_sel8_rec", "hZvtx_after_sel8_rec", kTH1D, {vtxZAxis}); - histos.add("etaHistogram_allcharge_rec", "etaHistogram_allcharge_rec", kTH1D, {etaAxis}); - histos.add("ptHistogram_allcharge_bfptcut_rec", "ptHistogram_allcharge_bfptcut_rec", kTH1D, {ptAxis}); histos.add("ptHistogramAllchargeRec", "ptHistogramAllchargeRec", kTH1D, {ptAxis}); histos.add("ptHistogramPionrec", "ptHistogramPionrec", kTH1D, {ptAxis}); histos.add("ptHistogramKaonrec", "ptHistogramKaonrec", kTH1D, {ptAxis}); @@ -353,11 +275,9 @@ struct EventMeanPtId { histos.add("ptHistogramPionrec_pdg", "ptHistogramPionrec_pdg", kTH1D, {ptAxis}); histos.add("ptHistogramKaonrec_pdg", "ptHistogramKaonrec_pdg", kTH1D, {ptAxis}); histos.add("ptHistogramProtonrec_pdg", "ptHistogramProtonrec_pdg", kTH1D, {ptAxis}); - histos.add("Histogram_mass2_p_rec_beforesel", "Histogram_mass2_p_rec_beforesel", kTH1D, {ptAxis}); - histos.add("Histogram_mass2_p_rec_aftersel", "Histogram_mass2_p_rec_aftersel", kTH1D, {ptAxis}); - histos.add("hEffVar1x", "hEffVar1x", kTH2D, {subAxis, nchAxis}); - histos.add("hEffVar2x", "hEffVar2x", kTH2D, {subAxis, nchAxis}); - histos.add("hEffVarx", "hEffVarx", kTH2D, {subAxis, nchAxis}); + histos.add("hEffVar1x_rec", "hEffVar1x_rec", kTH2D, {subAxis, nchAxis}); + histos.add("hEffVar2x_rec", "hEffVar2x_rec", kTH2D, {subAxis, nchAxis}); + histos.add("hEffVarx_rec", "hEffVarx_rec", kTH2D, {subAxis, nchAxis}); histos.add("hEffVar1pix", "hEffVar1pix", kTH2D, {subAxis, nchAxis}); histos.add("hEffVar2pix", "hEffVar2pix", kTH2D, {subAxis, nchAxis}); histos.add("hEffVarpix", "hEffVarpix", kTH2D, {subAxis, nchAxis}); @@ -367,7 +287,7 @@ struct EventMeanPtId { histos.add("hEffVar1px", "hEffVar1px", kTH2D, {subAxis, nchAxis}); histos.add("hEffVar2px", "hEffVar2px", kTH2D, {subAxis, nchAxis}); histos.add("hEffVarpx", "hEffVarpx", kTH2D, {subAxis, nchAxis}); - histos.add("hEffVar2Meanptx", "hEffVar2Meanptx", kTH2D, {nchAxis, varAxis2}); + histos.add("hEffVar2Meanptx_rec", "hEffVar2Meanptx_rec", kTH2D, {nchAxis, varAxis2}); histos.add("hEffVar2Meanptpix", "hEffVar2Meanptpix", kTH2D, {nchAxis, varAxis2}); histos.add("hEffVar2Meanptkx", "hEffVar2Meanptkx", kTH2D, {nchAxis, varAxis2}); histos.add("hEffVar2Meanptpx", "hEffVar2Meanptpx", kTH2D, {nchAxis, varAxis2}); @@ -376,14 +296,8 @@ struct EventMeanPtId { histos.add("ptHistogramPion", "ptHistogramPion", kTH1D, {ptAxis}); histos.add("ptHistogramKaon", "ptHistogramKaon", kTH1D, {ptAxis}); histos.add("ptHistogramProton", "ptHistogramProton", kTH1D, {ptAxis}); - histos.add("hMC_Pt", ";#it{p}_{T} (GeV/#it{c})", kTH1D, {ptAxis}); - histos.add("MC_hZvtx_after_sel", ";#it{p}_{T} (GeV/#it{c})", kTH1D, {vtxZAxis}); - histos.add("hTOFbeta_gen_pion", "hTOFbeta_gen_pion", kTH2D, {pAxis, betaAxis}); - histos.add("hdEdx_gen_pion", "hdEdx_gen_pion", kTH2D, {pAxis, dEdxAxis}); histos.add("hnch_gen_all", ";hnch_gen_all", kTH1D, {nchAxis}); - histos.add("hnch_gen", ";hnch_gen", kTH1D, {nchAxis}); histos.add("hnch_gen_true", ";hnch_gen_true", kTH1D, {nchAxis}); - histos.add("hnch_gen_eta", ";hnch_gen_eta", kTH1D, {etaAxis}); histos.add("hnch1", ";hnch1", kTH1D, {nchAxis}); histos.add("hnch2", ";hnch2", kTH1D, {nchAxis}); histos.add("hnch3", ";hnch3", kTH1D, {nchAxis}); @@ -391,9 +305,6 @@ struct EventMeanPtId { histos.add("hnch_ka", ";hnch_ka", kTH1D, {nchAxis}); histos.add("hnch_pr", ";hnch_pr", kTH1D, {nchAxis}); - histos.add("hVar1x_gen_old", "hVar1x_gen_old", kTH2D, {subAxis, nchAxis}); - histos.add("hVar2x_gen_old", "hVar2x_gen_old", kTH2D, {subAxis, nchAxis}); - histos.add("hVarx_gen_old", "hVarx_gen_old", kTH2D, {subAxis, nchAxis}); histos.add("hVar1x_gen", "hVar1x_gen", kTH2D, {subAxis, nchAxis}); histos.add("hVar2x_gen", "hVar2x_gen", kTH2D, {subAxis, nchAxis}); histos.add("hVarx_gen", "hVarx_gen", kTH2D, {subAxis, nchAxis}); @@ -410,28 +321,63 @@ struct EventMeanPtId { histos.add("hVar2px_gen", "hVar2px_gen", kTH2D, {subAxis, nchAxis}); histos.add("hVarpx_gen", "hVarpx_gen", kTH2D, {subAxis, nchAxis}); histos.add("hVar2meanptpx_gen", "hVar2meanptpx_gen", kTH2D, {nchAxis, varAxis2}); - histos.add("hcent_nacc_rec", "hcent_nacc_rec", kTH2D, {centAxis, nchAxis}); histos.add("hcent_nacc_gen", "hcent_nacc_gen", kTH2D, {centAxis, nchAxis}); - histos.add("hGenCentrality", "hGenCentrality", kTH1D, {centAxis}); histos.add("hVtxZ_before_gen", "", kTH1F, {vtxZAxis}); - histos.add("hVtxZ_after_gen", "", kTH1F, {vtxZAxis}); + histos.add("hVtxZ_after_gensim", "", kTH1F, {vtxZAxis}); histos.add("hEta_gen", "", kTH1F, {etaAxis}); histos.add("hEta_rec", "", kTH1F, {etaAxis}); histos.add("hPt_gen", "", kTH1F, {ptAxis}); histos.add("hPt_rec", "", kTH1F, {ptAxis}); + histos.add("hEta_rec_corr", "", kTH1F, {etaAxis}); + histos.add("hPt_rec_corr", "", kTH1F, {ptAxis}); + histos.add("hPtEta_rec", "hPtEta_rec", kTH2D, {ptAxis, etaAxis}); + histos.add("hPtEta_pi_rec", "hPtEta_pi_rec", kTH2D, {ptAxis, etaAxis}); + histos.add("hPtEta_ka_rec", "hPtEta_ka_rec", kTH2D, {ptAxis, etaAxis}); + histos.add("hPtEta_pr_rec", "hPtEta_pr_rec", kTH2D, {ptAxis, etaAxis}); + histos.add("hPtEta_gen", "hPtEta_gen", kTH2D, {ptAxis, etaAxis}); + histos.add("hPtEta_pi_gen", "hPtEta_pi_gen", kTH2D, {ptAxis, etaAxis}); + histos.add("hPtEta_ka_gen", "hPtEta_ka_gen", kTH2D, {ptAxis, etaAxis}); + histos.add("hPtEta_pr_gen", "hPtEta_pr_gen", kTH2D, {ptAxis, etaAxis}); + histos.add("hPty_pi_gen", "hPty_pi_gen", kTH2D, {ptAxis, etaAxis}); + histos.add("hPty_ka_gen", "hPty_ka_gen", kTH2D, {ptAxis, etaAxis}); + histos.add("hPty_pr_gen", "hPty_pr_gen", kTH2D, {ptAxis, etaAxis}); + histos.add("hNch_vs_corr", "hNch_vs_corr", kTH1D, {nchAxis}); + histos.add("hVar1_gen", "hVar1_gen", kTH2D, {subAxis, centAxis}); + histos.add("hVar2_gen", "hVar2_gen", kTH2D, {subAxis, centAxis}); + histos.add("hVarc_gen", "hVarc_gen", kTH2D, {subAxis, centAxis}); + histos.add("hEffVar1x_Naccorr_rec", "hEffVar1x_Naccorr_rec", kTH2D, {subAxis, nchAxis}); + histos.add("hEffVar2x_Naccorr_rec", "hEffVar2x_Naccorr_rec", kTH2D, {subAxis, nchAxis}); + histos.add("hEffVarx_Naccorr_rec", "hEffVarx_Naccorr_rec", kTH2D, {subAxis, nchAxis}); + histos.add("hEffVar1x_Naccorr_xaxis_rec", "hEffVar1x_Naccorr_xaxis_rec", kTH2D, {subAxis, nchAxis}); + histos.add("hEffVar2x_Naccorr_xaxis_rec", "hEffVar2x_Naccorr_xaxis_rec", kTH2D, {subAxis, nchAxis}); + histos.add("hEffVarx_Naccorr_xaxis_rec", "hEffVarx_Naccorr_xaxis_rec", kTH2D, {subAxis, nchAxis}); + histos.add("hEffVar1x_Naccorr_data", "hEffVar1x_Naccorr_data", kTH2D, {subAxis, nchAxis}); + histos.add("hEffVar2x_Naccorr_data", "hEffVar2x_Naccorr_data", kTH2D, {subAxis, nchAxis}); + histos.add("hEffVarx_Naccorr_data", "hEffVarx_Naccorr_data", kTH2D, {subAxis, nchAxis}); + histos.add("hEffVar1x_Naccorr_xaxis_data", "hEffVar1x_Naccorr_xaxis_data", kTH2D, {subAxis, nchAxis}); + histos.add("hEffVar2x_Naccorr_xaxis_data", "hEffVar2x_Naccorr_xaxis_data", kTH2D, {subAxis, nchAxis}); + histos.add("hEffVarx_Naccorr_xaxis_data", "hEffVarx_Naccorr_xaxis_data", kTH2D, {subAxis, nchAxis}); + histos.add("hEffVar1x_data", "hEffVar1x_data", kTH2D, {subAxis, nchAxis}); + histos.add("hEffVar2x_data", "hEffVar2x_data", kTH2D, {subAxis, nchAxis}); + histos.add("hEffVarx_data", "hEffVarx_data", kTH2D, {subAxis, nchAxis}); + histos.add("hEffVar2Meanptx_data", "hEffVar2Meanptx_data", kTH2D, {nchAxis, varAxis2}); } + // Configurables Configurable cVtxZcut{"cVtxZcut", 10.f, "Vertex Z"}; Configurable cEtacut{"cEtacut", 0.8, "Eta cut"}; Configurable cPtmincut{"cPtmincut", 0.2, "Pt min cut"}; Configurable cPtmaxcut{"cPtmaxcut", 2.0, "Pt max cut"}; Configurable cDcaXYcut{"cDcaXYcut", 0.12, "DCA XY cut"}; - Configurable cDcaZcut{"cDcaZcut", 0.3, "DCA Z cut"}; + Configurable cDcaZcut{"cDcaZcut", 2.0, "DCA Z cut"}; Configurable cCentmincut{"cCentmincut", 0.0, "Min cent cut"}; Configurable cCentmaxcut{"cCentmaxcut", 90.0, "Max cent cut"}; Configurable cTPCcrosscut{"cTPCcrosscut", 70, "TPC crossrows cut"}; - Configurable cItsChiCut{"cItsChiCut", 70, "ITS chi2 cluster cut"}; - Configurable cTpcChiCut{"cTpcChiCut", 70, "TPC chi2 cluster cut"}; + Configurable cItsChiCut{"cItsChiCut", 36, "ITS chi2 cluster cut"}; + Configurable cTpcChiCut{"cTpcChiCut", 4, "TPC chi2 cluster cut"}; + Configurable cnITSClustersCut{"cnITSClustersCut", 5, "Number of ITS clusters cut"}; + Configurable ctpcNClsCut{"ctpcNClsCut", 80, "No. of TPC clusters cut"}; + Configurable threshold{"threshold", 1e-6, "Delta eta bin count"}; // Event selections Configurable cSel8Trig{"cSel8Trig", true, "Sel8 (T0A + T0C) Selection Run3"}; @@ -443,7 +389,10 @@ struct EventMeanPtId { Configurable cIsGoodITSLayers{"cIsGoodITSLayers", true, "Good ITS Layers All"}; Configurable cItslayerall{"cItslayerall", true, "dead staves of ITS removed"}; Configurable cvtxtofmatched{"cvtxtofmatched", true, "TOF vertex matched"}; - Configurable cfgRejEl{"cfgRejEl", true, "Rejected electrons"}; + Configurable cfgRejEl{"cfgRejEl", false, "Rejected electrons"}; + Configurable cdata{"cdata", false, "Enable histogram filling for processData"}; + Configurable citsNCluster{"citsNCluster", false, "Enable Number of ITS clusters"}; + Configurable ctpcNClusterFound{"ctpcNClusterFound", false, "Enable Number of TPC clusters"}; // PID selection configurables Configurable cPionPmincut{"cPionPmincut", 0.2, "pion min cut of pion"}; @@ -461,6 +410,9 @@ struct EventMeanPtId { Configurable cElMaxCut{"cElMaxCut", 5.0, "electron max cut"}; Configurable cTwoPtlCut2{"cTwoPtlCut2", 2.0, "n2ptl cut"}; Configurable cRapidityCut05{"cRapidityCut05", 0.5, "rapidity cut"}; + Configurable nchBins{"nchBins", 4000, "Number of bins for nch axis"}; + Configurable nchMin{"nchMin", 0.0, "Minimum value for nch axis"}; + Configurable nchMax{"nchMax", 4000.0, "Maximum value for nch axis"}; template bool selCollision(C const& coll) @@ -522,7 +474,9 @@ struct EventMeanPtId { // if (std::fabs(track.dcaXY()) > cDcaXYcut) {return false;} histos.fill(HIST("tracksel"), 3); - // if (std::fabs(track.dcaZ()) > cDcaZcut) {return false;} + if (std::fabs(track.dcaZ()) > cDcaZcut) { + return false; + } histos.fill(HIST("tracksel"), 4); if (std::fabs(track.eta()) >= cEtacut) { @@ -538,18 +492,38 @@ struct EventMeanPtId { } histos.fill(HIST("tracksel"), 6); - // if (track.tpcNClsCrossedRows() < cTPCcrosscut) {return false;} + if (track.tpcNClsCrossedRows() < cTPCcrosscut) { + return false; + } histos.fill(HIST("tracksel"), 7); - // if (track.itsChi2NCl() > cItsChiCut) {return false;} + if (track.itsChi2NCl() > cItsChiCut) { + return false; + } histos.fill(HIST("tracksel"), 8); - // if (track.tpcChi2NCl() > cTpcChiCut) {return false;} + if (track.tpcChi2NCl() > cTpcChiCut) { + return false; + } histos.fill(HIST("tracksel"), 9); if (track.sign() == 0) return false; + if (citsNCluster) { + if (track.itsNCls() < cnITSClustersCut) { + return false; + } + histos.fill(HIST("tracksel"), 10); + } + + if (ctpcNClusterFound) { + if (track.tpcNClsFound() < ctpcNClsCut) { + return false; + } + histos.fill(HIST("tracksel"), 11); + } + return true; // if all checks pass, accept the collision } @@ -643,16 +617,21 @@ struct EventMeanPtId { return false; } - double getEfficiency(double pt, TH1D* ptHistogramAllchargeRec) + double getEfficiency(double pt, double eta, TH2D* ptHistogramAllchargeRec) { - int bin = ptHistogramAllchargeRec->FindBin(pt); - double eff = ptHistogramAllchargeRec->GetBinContent(bin); + int xbin = ptHistogramAllchargeRec->GetXaxis()->FindBin(pt); + int ybin = ptHistogramAllchargeRec->GetYaxis()->FindBin(eta); + + if (xbin < 1 || xbin > ptHistogramAllchargeRec->GetNbinsX() || ybin < 1 || ybin > ptHistogramAllchargeRec->GetNbinsY()) { + LOGF(warn, "pt or eta out of histograms bounds : %f, eta = %f", pt, eta); + return 1e-6; + } + double eff = ptHistogramAllchargeRec->GetBinContent(xbin, ybin); return (eff > 0) ? eff : 1e-6; // Avoid division by zero } //++++++++++++++++++++++++++++++++++++DATA CALCULATION +++++++++++++++++++++++++++++++++++++++++++++++++++++// - - void process(aod::MyCollision const& coll, aod::MyTracks const& inputTracks) + void processData(aod::MyCollision const& coll, aod::MyTracks const& inputTracks) { histos.fill(HIST("hEventcounter"), 1.); histos.fill(HIST("Data/hZvtx_before_sel"), coll.posZ()); @@ -666,13 +645,12 @@ struct EventMeanPtId { const auto cent = coll.centFT0C(); histos.fill(HIST("Data/hCentrality"), cent); - double nch = 0., nchPi = 0., nchKa = 0., nchPr = 0., nchAll = 0., nchAllBfCut = 0., nchEta = 0., nchPt = 0.; - double q1 = 0., q2 = 0.; - double q1Pi = 0., q2Pi = 0., q1Ka = 0., q2Ka = 0., q1Pr = 0., q2Pr = 0.; - double var1 = 0., var2 = 0., twoParAllCharge = 0.; - double var1Pi = 0., var2Pi = 0.; - double var1Ka = 0., var2Ka = 0.; - double var1Pr = 0., var2Pr = 0.; + double nchAll = 0., nchAllBfCut = 0., nchEta = 0., nchPt = 0., nch = 0., nchPi = 0., nchKa = 0., nchPr = 0.; + double q1 = 0., q2 = 0., var1 = 0., var2 = 0.; + double sumPtWeight = 0., sumWeight = 0., sumPtPtWeight = 0., var1Eff = 0., var2Eff = 0.; + double q1Pi = 0., q2Pi = 0., var1Pi = 0., var2Pi = 0.; + double q1Ka = 0., q2Ka = 0., var1Ka = 0., var2Ka = 0.; + double q1Pr = 0., q2Pr = 0., var1Pr = 0., var2Pr = 0.; int sample = histos.get(HIST("Data/hZvtx_after_sel8"))->GetEntries(); sample = sample % 30; // subsample error estimation @@ -693,37 +671,44 @@ struct EventMeanPtId { nchPt += 1.; histos.fill(HIST("Data/hnchTrue_pt"), nchPt); } - if (track.sign() == 0) continue; if (!selTrack(track)) continue; nchAll += 1.; + q1 += track.pt(); + q2 += (track.pt() * track.pt()); + histos.fill(HIST("Data/hnchAll"), nchAll); + histos.fill(HIST("Data/hPt"), track.pt()); + histos.fill(HIST("Data/hEta"), track.eta()); histos.fill(HIST("Data/hDCAxy"), track.dcaXY()); histos.fill(HIST("Data/hDCAz"), track.dcaZ()); histos.fill(HIST("Data/hTPCCrossedrows_after"), track.tpcNClsCrossedRows()); histos.fill(HIST("Data/hTPCchi2perCluster_after"), track.tpcChi2NCl()); histos.fill(HIST("Data/hITSchi2perCluster_after"), track.itsChi2NCl()); histos.fill(HIST("Data/hP"), track.p()); - histos.fill(HIST("Data/hPt"), track.pt()); - histos.fill(HIST("Data/hEta"), track.eta()); histos.fill(HIST("Data/hPtDCAxy"), track.pt(), track.dcaXY()); histos.fill(HIST("Data/hPtDCAz"), track.pt(), track.dcaZ()); histos.fill(HIST("Data/hPtEta"), track.pt(), track.eta()); histos.fill(HIST("Data/hPEta"), track.p(), track.eta()); histos.fill(HIST("Data/hNsigmaTPC"), track.p(), track.tpcNSigmaPr()); + double eff = getEfficiency(track.pt(), track.eta(), ptHistogramAllchargeRec); + if (eff < threshold) + continue; + double weight = 1. / eff; + sumPtWeight += track.pt() / eff; + sumPtPtWeight += (track.pt() * track.pt()) / (eff * eff); + sumWeight += weight; + if (track.pt() >= cPtmincut || track.pt() <= cPtmaxcut) // do not change this (it is for different pt work) { nch += 1.; histos.fill(HIST("Data/hnch"), nch); } - q1 += track.pt(); - q2 += (track.pt() * track.pt()); - // only TPC tracks: Pion, Kaon, Proton if (track.hasTPC() && std::abs(track.tpcNSigmaPi()) < cNSigCut3) histos.fill(HIST("Data/NSigamaTPCpion"), track.pt(), track.tpcNSigmaPi()); @@ -753,7 +738,6 @@ struct EventMeanPtId { histos.fill(HIST("Data/hdEdx_afterselection"), track.p(), track.tpcSignal()); histos.fill(HIST("Data/hTOFbeta_afterselection"), track.p(), track.beta()); } - if (selPion(track)) { histos.fill(HIST("Data/hPtPion"), track.pt()); histos.fill(HIST("Data/hEtaPion"), track.eta()); @@ -762,7 +746,6 @@ struct EventMeanPtId { nchPi += 1.; q1Pi += track.pt(); q2Pi += (track.pt() * track.pt()); - if (track.beta() > 1) continue; histos.fill(HIST("Data/hdEdx_afterselection1"), track.p(), track.tpcSignal()); @@ -775,7 +758,6 @@ struct EventMeanPtId { histos.fill(HIST("Data/hdEdx_afterselection"), track.p(), track.tpcSignal()); histos.fill(HIST("Data/hTOFbeta_afterselection"), track.p(), track.beta()); } - if (selKaon(track)) { histos.fill(HIST("Data/hPtKaon"), track.pt()); histos.fill(HIST("Data/hEtaKaon"), track.eta()); @@ -784,7 +766,6 @@ struct EventMeanPtId { nchKa += 1.; q1Ka += track.pt(); q2Ka += (track.pt() * track.pt()); - if (track.beta() > 1) continue; histos.fill(HIST("Data/hdEdx_afterselection1"), track.p(), track.tpcSignal()); @@ -797,7 +778,6 @@ struct EventMeanPtId { histos.fill(HIST("Data/hdEdx_afterselection"), track.p(), track.tpcSignal()); histos.fill(HIST("Data/hTOFbeta_afterselection"), track.p(), track.beta()); } - if (selProton(track)) { histos.fill(HIST("Data/hPtProton"), track.pt()); histos.fill(HIST("Data/hEtaProton"), track.eta()); @@ -806,12 +786,12 @@ struct EventMeanPtId { nchPr += 1.; q1Pr += track.pt(); q2Pr += (track.pt() * track.pt()); - if (track.beta() > 1) continue; histos.fill(HIST("Data/hdEdx_afterselection1"), track.p(), track.tpcSignal()); histos.fill(HIST("Data/hTOFbeta_afterselection1"), track.p(), track.beta()); } + } // Track loop ends! histos.fill(HIST("Data/hcent_nacc"), cent, nchAll); @@ -820,41 +800,37 @@ struct EventMeanPtId { var1 = (q1 * q1 - q2) / (nchAll * (nchAll - 1)); var2 = (q1 / nchAll); - //------------------ all charges------------------------------------- - histos.fill(HIST("Data/hVar1"), sample, cent, var1); - histos.fill(HIST("Data/hVar2"), sample, cent, var2); - histos.fill(HIST("Data/hVarc"), sample, cent); - histos.fill(HIST("Data/hVar2meanpt"), cent, var2); - twoParAllCharge = (var1 - var2); - histos.fill(HIST("Data/hVar"), nchAll, twoParAllCharge); + //------------------ Efficiency corrected histograms --------------- + var1Eff = (sumPtWeight * sumPtWeight - sumPtPtWeight) / (sumWeight * (sumWeight - 1)); + var2Eff = (sumPtWeight / sumWeight); //---------------------- pions ---------------------------------------- if (nchPi >= cTwoPtlCut2) { var1Pi = (q1Pi * q1Pi - q2Pi) / (nchPi * (nchPi - 1)); var2Pi = (q1Pi / nchPi); } - //----------------------- kaons --------------------------------------- if (nchKa >= cTwoPtlCut2) { var1Ka = (q1Ka * q1Ka - q2Ka) / (nchKa * (nchKa - 1)); var2Ka = (q1Ka / nchKa); } - //---------------------------- protons ---------------------------------- if (nchPr >= cTwoPtlCut2) { var1Pr = (q1Pr * q1Pr - q2Pr) / (nchPr * (nchPr - 1)); var2Pr = (q1Pr / nchPr); } - //========================centrality========================================== + //------------------ all charges------------------------------------- + histos.fill(HIST("Data/hVar1"), sample, cent, var1); + histos.fill(HIST("Data/hVar2"), sample, cent, var2); + histos.fill(HIST("Data/hVarc"), sample, cent); + histos.fill(HIST("Data/hVar2meanpt"), cent, var2); histos.fill(HIST("Data/hVar1pi"), sample, cent, var1Pi); histos.fill(HIST("Data/hVar2pi"), sample, cent, var2Pi); histos.fill(HIST("Data/hVar2meanptpi"), cent, var2Pi); - histos.fill(HIST("Data/hVar1k"), sample, cent, var1Ka); histos.fill(HIST("Data/hVar2k"), sample, cent, var2Ka); histos.fill(HIST("Data/hVar2meanptk"), cent, var2Ka); - histos.fill(HIST("Data/hVar1p"), sample, cent, var1Pr); histos.fill(HIST("Data/hVar2p"), sample, cent, var2Pr); histos.fill(HIST("Data/hVar2meanptp"), cent, var2Pr); @@ -865,6 +841,20 @@ struct EventMeanPtId { histos.fill(HIST("Data/hVarx"), sample, nchAll); histos.fill(HIST("Data/hVar2meanptx"), nchAll, var2); + histos.fill(HIST("hEffVar1x_data"), sample, nchAll, var1Eff); + histos.fill(HIST("hEffVar2x_data"), sample, nchAll, var2Eff); + histos.fill(HIST("hEffVarx_data"), sample, nchAll); + histos.fill(HIST("hEffVar2Meanptx_data"), nchAll, var2Eff); + histos.fill(HIST("hEffVar1x_Naccorr_data"), sample, sumWeight, var1Eff); + histos.fill(HIST("hEffVar2x_Naccorr_data"), sample, sumWeight, var2Eff); + histos.fill(HIST("hEffVarx_Naccorr_data"), sample, sumWeight); + histos.fill(HIST("hEffVar1x_Naccorr_data"), sample, nchAll, var1Eff); + histos.fill(HIST("hEffVar2x_Naccorr_data"), sample, nchAll, var2Eff); + histos.fill(HIST("hEffVarx_Naccorr_data"), sample, nchAll, sumWeight); + histos.fill(HIST("hEffVar1x_Naccorr_xaxis_data"), sample, sumWeight, var1); + histos.fill(HIST("hEffVar2x_Naccorr_xaxis_data"), sample, sumWeight, var2); + histos.fill(HIST("hEffVarx_Naccorr_xaxis_data"), sample, sumWeight); + histos.fill(HIST("Data/hVar1pix"), sample, nchAll, var1Pi); histos.fill(HIST("Data/hVar2pix"), sample, nchAll, var2Pi); histos.fill(HIST("Data/hVarpix"), sample, nchPi); @@ -879,10 +869,9 @@ struct EventMeanPtId { histos.fill(HIST("Data/hVar2px"), sample, nchAll, var2Pr); histos.fill(HIST("Data/hVarpx"), sample, nchPr); histos.fill(HIST("Data/hVar2meanptpx"), nchAll, var2Pr); - } // event loop ends! - PROCESS_SWITCH(EventMeanPtId, process, "process real data information", false); + PROCESS_SWITCH(EventMeanPtId, processData, "process real data information", false); //++++++++++++++++++++++++++++++++++++MC Reconstructed +++++++++++++++++++++++++++++++++++++++++++++++++++++// @@ -897,43 +886,19 @@ struct EventMeanPtId { histos.fill(HIST("Rec/hZvtx_before_sel"), coll.posZ()); histos.fill(HIST("hVtxZ_before_gen"), coll.mcCollision().posZ()); - if (cTFBorder && !coll.selection_bit(aod::evsel::kNoTimeFrameBorder)) { - return; - } - if (cNoItsROBorder && !coll.selection_bit(aod::evsel::kNoITSROFrameBorder)) { - return; - } - if (cPileupReject && !coll.selection_bit(aod::evsel::kNoSameBunchPileup)) { - return; - } - if (cZVtxTimeDiff && !coll.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { - return; - } - if (cItsTpcVtx && !coll.selection_bit(aod::evsel::kIsVertexITSTPC)) { - return; - } - if (cvtxtofmatched && !coll.selection_bit(aod::evsel::kIsVertexTOFmatched)) { - return; - } - if (std::abs(coll.posZ()) > cVtxZcut) { + if (!selCollision(coll)) // add return; - } - if (!coll.sel8()) { - return; - } float cent = coll.centFT0C(); histos.fill(HIST("Rec/hZvtx_after_sel8"), coll.posZ()); + histos.fill(HIST("Rec/hCentrality"), cent); double nch = 0., nchPi = 0., nchKa = 0., nchPr = 0., nchAll = 0., nchAllBfCut = 0., nchEta = 0., nchPt = 0.; double q1 = 0., q2 = 0.; double q1Pi = 0., q2Pi = 0., q1Ka = 0., q2Ka = 0., q1Pr = 0., q2Pr = 0.; - double var1 = 0., var2 = 0., twoParAllCharge = 0.; + double var1 = 0., var2 = 0.; double var1Pi = 0., var2Pi = 0., var1Ka = 0., var2Ka = 0., var1Pr = 0., var2Pr = 0.; double sumPtWeight = 0., sumWeight = 0., sumPtPtWeight = 0., var1Eff = 0., var2Eff = 0.; - double sumPtWeightPi = 0., sumWeightPi = 0., sumPtPtWeightPi = 0., var1EffPi = 0., var2EffPi = 0.; - double sumPtWeightKa = 0., sumWeightKa = 0., sumPtPtWeightKa = 0., var1EffKa = 0., var2EffKa = 0.; - double sumPtWeightPr = 0., sumWeightPr = 0., sumPtPtWeightPr = 0., var1EffPr = 0., var2EffPr = 0.; int sample = histos.get(HIST("Rec/hZvtx_after_sel8"))->GetEntries(); sample = sample % 30; @@ -953,18 +918,23 @@ struct EventMeanPtId { nchPt += 1.; histos.fill(HIST("Rec/hnchTrue_pt"), nchPt); } - if (!track.isGlobalTrack()) - continue; - if (std::fabs(track.eta()) > cEtacut) - continue; - if ((track.pt() <= cPtmincut) || (track.pt() >= cPtmaxcut)) - continue; - if (track.sign() == 0) + if (!selTrack(track)) continue; // if (std::fabs(track.y()) > 0.5) continue; histos.fill(HIST("hPt_rec"), track.pt()); histos.fill(HIST("hEta_rec"), track.eta()); + double eff = getEfficiency(track.pt(), track.eta(), ptHistogramAllchargeRec); + if (eff < threshold) + continue; + double weight = 1.0 / eff; + sumPtWeight += track.pt() * weight; + sumPtPtWeight += (track.pt() * track.pt() * weight * weight); + sumWeight += weight; + + histos.fill(HIST("hPt_rec_corr"), track.pt(), weight); + histos.fill(HIST("hEta_rec_corr"), track.eta(), weight); + auto mcParticle = track.mcParticle(); nchAll += 1.; histos.fill(HIST("Rec/hnchAll"), nchAll); @@ -982,6 +952,7 @@ struct EventMeanPtId { histos.fill(HIST("Rec/hPtEta"), track.pt(), track.eta()); histos.fill(HIST("Rec/hPEta"), track.p(), track.eta()); histos.fill(HIST("Rec/hNsigmaTPC"), track.p(), track.tpcNSigmaPr()); + histos.fill(HIST("hPtEta_rec"), track.pt(), track.eta()); if (track.pt() >= cPtmincut || track.pt() <= cPtmaxcut) // do not change this (it is for different pt work) { @@ -991,12 +962,6 @@ struct EventMeanPtId { q1 += track.pt(); q2 += (track.pt() * track.pt()); - double eff = getEfficiency(track.pt(), ptHistogramAllchargeRec); - // LOGF(info, " with value %.2f", eff); - sumPtWeight += track.pt() / eff; - sumPtPtWeight += (track.pt() * track.pt()) / (eff * eff); - sumWeight += 1. / eff; - if (std::abs(mcParticle.pdgCode()) == PDG_t::kPiPlus) histos.fill(HIST("ptHistogramPionrec_pdg"), track.pt()); if (std::abs(mcParticle.pdgCode()) == PDG_t::kKPlus) @@ -1004,10 +969,6 @@ struct EventMeanPtId { if (std::abs(mcParticle.pdgCode()) == PDG_t::kProton) histos.fill(HIST("ptHistogramProtonrec_pdg"), track.pt()); - if (cfgRejEl == false && rejEl(track)) { - return; - } - // only TPC tracks: Pion, Kaon, Proton if (track.hasTPC() && std::abs(track.tpcNSigmaPi()) < cNSigCut3) histos.fill(HIST("Rec/NSigamaTPCpion"), track.pt(), track.tpcNSigmaPi()); @@ -1047,6 +1008,7 @@ struct EventMeanPtId { if (track.beta() > 1) continue; histos.fill(HIST("ptHistogramPionrec"), track.pt()); + histos.fill(HIST("hPtEta_pi_rec"), track.pt(), track.eta()); histos.fill(HIST("Rec/hPtPion"), track.pt()); histos.fill(HIST("Rec/hEtaPion"), track.eta()); histos.fill(HIST("Rec/hyPion"), track.rapidity(massPi)); @@ -1063,12 +1025,6 @@ struct EventMeanPtId { q1Pi += track.pt(); q2Pi += (track.pt() * track.pt()); - double effPi = getEfficiency(track.pt(), ptHistogramPionrec); - // LOGF(info, " with value %.2f", eff); - sumPtWeightPi += track.pt() / effPi; - sumPtPtWeightPi += (track.pt() * track.pt()) / (effPi * effPi); - sumWeightPi += 1. / effPi; - histos.fill(HIST("hPyPion_rec"), track.p(), track.rapidity(massPi)); histos.fill(HIST("hPtyPion_rec"), track.pt(), track.rapidity(massPi)); } @@ -1087,6 +1043,7 @@ struct EventMeanPtId { if (track.beta() > 1) continue; histos.fill(HIST("ptHistogramKaonrec"), track.pt()); + histos.fill(HIST("hPtEta_ka_rec"), track.pt(), track.eta()); histos.fill(HIST("Rec/hPtKaon"), track.pt()); histos.fill(HIST("Rec/hEtaKaon"), track.eta()); histos.fill(HIST("Rec/hyKaon"), track.rapidity(massKa)); @@ -1103,12 +1060,6 @@ struct EventMeanPtId { q1Ka += track.pt(); q2Ka += (track.pt() * track.pt()); - double effKa = getEfficiency(track.pt(), ptHistogramKaonrec); - // LOGF(info, " with value %.2f", eff); - sumPtWeightKa += track.pt() / effKa; - sumPtPtWeightKa += (track.pt() * track.pt()) / (effKa * effKa); - sumWeightKa += 1. / effKa; - histos.fill(HIST("hPyKaon_rec"), track.p(), track.rapidity(massKa)); histos.fill(HIST("hPtyKaon_rec"), track.pt(), track.rapidity(massKa)); } @@ -1127,6 +1078,7 @@ struct EventMeanPtId { if (track.beta() > 1) continue; histos.fill(HIST("ptHistogramProtonrec"), track.pt()); + histos.fill(HIST("hPtEta_pr_rec"), track.pt(), track.eta()); histos.fill(HIST("Rec/hPtProton"), track.pt()); histos.fill(HIST("Rec/hEtaProton"), track.eta()); histos.fill(HIST("Rec/hyProton"), track.rapidity(massPr)); @@ -1143,18 +1095,14 @@ struct EventMeanPtId { q1Pr += track.pt(); q2Pr += (track.pt() * track.pt()); - double effPr = getEfficiency(track.pt(), ptHistogramProtonrec); - // LOGF(info, " with value %.2f", eff); - sumPtWeightPr += track.pt() / effPr; - sumPtPtWeightPr += (track.pt() * track.pt()) / (effPr * effPr); - sumWeightPr += 1. / effPr; - histos.fill(HIST("hPyProton_rec"), track.p(), track.rapidity(massPr)); histos.fill(HIST("hPtyProton_rec"), track.pt(), track.rapidity(massPr)); } } // loop over tracks histos.fill(HIST("Rec/hcent_nacc"), cent, nchAll); + histos.fill(HIST("hcent_nacc_corr"), cent, sumWeight); + histos.fill(HIST("hNch_vs_corr"), nchAll, sumWeight); if (nchAll < cTwoPtlCut2) return; @@ -1170,32 +1118,21 @@ struct EventMeanPtId { histos.fill(HIST("Rec/hVar2"), sample, cent, var2); histos.fill(HIST("Rec/hVarc"), sample, cent); histos.fill(HIST("Rec/hVar2meanpt"), cent, var2); - twoParAllCharge = (var1 - var2); - histos.fill(HIST("Rec/hVar"), nchAll, twoParAllCharge); //---------------------- pions ---------------------------------------- if (nchPi >= cTwoPtlCut2) { var1Pi = (q1Pi * q1Pi - q2Pi) / (nchPi * (nchPi - 1)); var2Pi = (q1Pi / nchPi); - - var1EffPi = (sumPtWeightPi * sumPtWeightPi - sumPtPtWeightPi) / (sumWeightPi * (sumWeightPi - 1)); - var2EffPi = (sumPtWeightPi / sumWeightPi); } //----------------------- kaons --------------------------------------- if (nchKa >= cTwoPtlCut2) { var1Ka = (q1Ka * q1Ka - q2Ka) / (nchKa * (nchKa - 1)); var2Ka = (q1Ka / nchKa); - - var1EffKa = (sumPtWeightKa * sumPtWeightKa - sumPtPtWeightKa) / (sumWeightKa * (sumWeightKa - 1)); - var2EffKa = (sumPtWeightKa / sumWeightKa); } //---------------------------- protons ---------------------------------- if (nchPr >= cTwoPtlCut2) { var1Pr = (q1Pr * q1Pr - q2Pr) / (nchPr * (nchPr - 1)); var2Pr = (q1Pr / nchPr); - - var1EffPr = (sumPtWeightPr * sumPtWeightPr - sumPtPtWeightPr) / (sumWeightPr * (sumWeightPr - 1)); - var2EffPr = (sumPtWeightPr / sumWeightPr); } //========================centrality========================================== @@ -1227,25 +1164,16 @@ struct EventMeanPtId { histos.fill(HIST("Rec/hVarpx"), sample, nchPr); histos.fill(HIST("Rec/hVar2meanptpx"), nchAll, var2Pr); - histos.fill(HIST("hEffVar1x"), sample, nchAll, var1Eff); - histos.fill(HIST("hEffVar2x"), sample, nchAll, var2Eff); - histos.fill(HIST("hEffVarx"), sample, nchAll); - histos.fill(HIST("hEffVar2Meanptx"), nchAll, var2Eff); - - histos.fill(HIST("hEffVar1pix"), sample, nchAll, var1EffPi); - histos.fill(HIST("hEffVar2pix"), sample, nchAll, var2EffPi); - histos.fill(HIST("hEffVarpix"), sample, nchAll); - histos.fill(HIST("hEffVar2Meanptpix"), nchAll, var2EffPi); - - histos.fill(HIST("hEffVar1kx"), sample, nchAll, var1EffKa); - histos.fill(HIST("hEffVar2kx"), sample, nchAll, var2EffKa); - histos.fill(HIST("hEffVarkx"), sample, nchAll); - histos.fill(HIST("hEffVar2Meanptkx"), nchAll, var2EffKa); - - histos.fill(HIST("hEffVar1px"), sample, nchAll, var1EffPr); - histos.fill(HIST("hEffVar2px"), sample, nchAll, var2EffPr); - histos.fill(HIST("hEffVarpx"), sample, nchAll); - histos.fill(HIST("hEffVar2Meanptpx"), nchAll, var2EffPr); + histos.fill(HIST("hEffVar1x_rec"), sample, nchAll, var1Eff); + histos.fill(HIST("hEffVar2x_rec"), sample, nchAll, var2Eff); + histos.fill(HIST("hEffVarx_rec"), sample, nchAll); + histos.fill(HIST("hEffVar2Meanptx_rec"), nchAll, var2Eff); + histos.fill(HIST("hEffVar1x_Naccorr_rec"), sample, sumWeight, var1Eff); + histos.fill(HIST("hEffVar2x_Naccorr_rec"), sample, sumWeight, var2Eff); + histos.fill(HIST("hEffVarx_Naccorr_rec"), sample, sumWeight); + histos.fill(HIST("hEffVar1x_Naccorr_xaxis_rec"), sample, sumWeight, var1); + histos.fill(HIST("hEffVar2x_Naccorr_xaxis_rec"), sample, sumWeight, var2); + histos.fill(HIST("hEffVarx_Naccorr_xaxis_rec"), sample, sumWeight); //================= generated level============================== @@ -1254,9 +1182,9 @@ struct EventMeanPtId { return; } const auto& mcpartgen = mcParticles.sliceByCached(aod::mcparticle::mcCollisionId, mccolgen.globalIndex(), cache); - histos.fill(HIST("hVtxZ_after_gen"), mccolgen.posZ()); + histos.fill(HIST("hVtxZ_after_gensim"), mccolgen.posZ()); - double nchGen = 0., nchGenAll = 0., nchGenTrue = 0.; + double nchGenAll = 0., nchGenTrue = 0.; double nchPiGen = 0., nchKaGen = 0., nchPrGen = 0.; double nch1 = 0., nch2 = 0., nch3 = 0.; double q1AllGen = 0, q2AllGen = 0.; @@ -1264,7 +1192,7 @@ struct EventMeanPtId { double var1AllGen = 0, var2AllGen = 0.; double var1PiGen = 0, var2PiGen = 0, var1KaGen = 0, var2KaGen = 0, var1PrGen = 0, var2PrGen = 0; - int sampleGen = histos.get(HIST("hVtxZ_after_gen"))->GetEntries(); + int sampleGen = histos.get(HIST("hVtxZ_after_gensim"))->GetEntries(); sampleGen = sampleGen % 30; for (const auto& mcpart : mcpartgen) { @@ -1302,10 +1230,14 @@ struct EventMeanPtId { q1AllGen += mcpart.pt(); q2AllGen += (mcpart.pt() * mcpart.pt()); histos.fill(HIST("hnch_gen_all"), nchGenAll); + histos.fill(HIST("hPtEta_gen"), mcpart.pt(), mcpart.eta()); + if (std::fabs(mcpart.y()) < cRapidityCut05) { if (mcpart.pdgCode() == PDG_t::kPiPlus || mcpart.pdgCode() == PDG_t::kPiMinus) { histos.fill(HIST("ptHistogramPion"), mcpart.pt()); + histos.fill(HIST("hPtEta_pi_gen"), mcpart.pt(), mcpart.eta()); + histos.fill(HIST("hPty_pi_gen"), mcpart.pt(), mcpart.y()); nchPiGen += 1.; q1PiGen += mcpart.pt(); q2PiGen += (mcpart.pt() * mcpart.pt()); @@ -1314,6 +1246,8 @@ struct EventMeanPtId { if (mcpart.pdgCode() == PDG_t::kKPlus || mcpart.pdgCode() == PDG_t::kKMinus) { histos.fill(HIST("ptHistogramKaon"), mcpart.pt()); + histos.fill(HIST("hPtEta_ka_gen"), mcpart.pt(), mcpart.eta()); + histos.fill(HIST("hPty_ka_gen"), mcpart.pt(), mcpart.y()); nchKaGen += 1.; q1KaGen += mcpart.pt(); q2KaGen += (mcpart.pt() * mcpart.pt()); @@ -1322,6 +1256,8 @@ struct EventMeanPtId { if (mcpart.pdgCode() == PDG_t::kProton || mcpart.pdgCode() == PDG_t::kProtonBar) { histos.fill(HIST("ptHistogramProton"), mcpart.pt()); + histos.fill(HIST("hPtEta_pr_gen"), mcpart.pt(), mcpart.eta()); + histos.fill(HIST("hPty_pr_gen"), mcpart.pt(), mcpart.y()); nchPrGen += 1.; q1PrGen += mcpart.pt(); q2PrGen += (mcpart.pt() * mcpart.pt()); @@ -1331,18 +1267,22 @@ struct EventMeanPtId { } //|y| < 0.5 cut ends! } // particle - histos.fill(HIST("hcent_nacc_gen"), cent, nchGen); + histos.fill(HIST("hcent_nacc_gen"), cent, nchGenAll); if (nchGenAll < cTwoPtlCut2) return; var1AllGen = (q1AllGen * q1AllGen - q2AllGen) / (nchGenAll * (nchGenAll - 1)); var2AllGen = (q1AllGen / nchGenAll); + histos.fill(HIST("hVar1_gen"), sampleGen, cent, var1AllGen); + histos.fill(HIST("hVar2_gen"), sampleGen, cent, var2AllGen); + histos.fill(HIST("hVarc_gen"), sampleGen, cent); + + //--------------------------Pions------------------------------------------- if (nchPiGen >= cTwoPtlCut2) { var1PiGen = (q1PiGen * q1PiGen - q2PiGen) / (nchPiGen * (nchPiGen - 1)); var2PiGen = (q1PiGen / nchPiGen); } - //----------------------- kaons --------------------------------------- if (nchKaGen >= cTwoPtlCut2) { var1KaGen = (q1KaGen * q1KaGen - q2KaGen) / (nchKaGen * (nchKaGen - 1)); diff --git a/PWGCF/EbyEFluctuations/Tasks/netchargeFluctuations.cxx b/PWGCF/EbyEFluctuations/Tasks/netchargeFluctuations.cxx index d248c5d6620..c33bdd9cb22 100644 --- a/PWGCF/EbyEFluctuations/Tasks/netchargeFluctuations.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/netchargeFluctuations.cxx @@ -29,6 +29,7 @@ #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" +#include "CCDB/BasicCCDBManager.h" #include "CommonConstants/MathConstants.h" #include "CommonConstants/PhysicsConstants.h" #include "Framework/ASoAHelpers.h" @@ -43,7 +44,8 @@ #include "TProfile2D.h" #include "TRandom3.h" -#include +#include +#include // Include for std::vector using namespace o2; using namespace o2::framework; @@ -55,50 +57,6 @@ namespace o2 { namespace aod { -namespace net_charge -{ -DECLARE_SOA_COLUMN(PosCharge, posCharge, float); -DECLARE_SOA_COLUMN(NegCharge, negCharge, float); -DECLARE_SOA_COLUMN(PosSqCharge, posSqCharge, float); -DECLARE_SOA_COLUMN(NegSqCharge, negSqCharge, float); -DECLARE_SOA_COLUMN(TermPCharge, termPCharge, float); -DECLARE_SOA_COLUMN(TermNCharge, termNCharge, float); -DECLARE_SOA_COLUMN(PosNegCharge, posNegCharge, float); -DECLARE_SOA_COLUMN(Centrality, centrality, float); -} // namespace net_charge - -namespace net_charge_gen -{ -DECLARE_SOA_COLUMN(PosCharge, posCharge, float); -DECLARE_SOA_COLUMN(NegCharge, negCharge, float); -DECLARE_SOA_COLUMN(PosSqCharge, posSqCharge, float); -DECLARE_SOA_COLUMN(NegSqCharge, negSqCharge, float); -DECLARE_SOA_COLUMN(TermPCharge, termPCharge, float); -DECLARE_SOA_COLUMN(TermNCharge, termNCharge, float); -DECLARE_SOA_COLUMN(PosNegCharge, posNegCharge, float); -DECLARE_SOA_COLUMN(Centrality, centrality, float); -} // namespace net_charge_gen - -DECLARE_SOA_TABLE(NetCharge, "AOD", "NETChargefluct", - net_charge::PosCharge, - net_charge::NegCharge, - net_charge::PosSqCharge, - net_charge::NegSqCharge, - net_charge::TermPCharge, - net_charge::TermNCharge, - net_charge::PosNegCharge, - net_charge::Centrality); - -DECLARE_SOA_TABLE(NetChargeGen, "AOD", "NETfluctGen", - net_charge_gen::PosCharge, - net_charge_gen::NegCharge, - net_charge_gen::PosSqCharge, - net_charge_gen::NegSqCharge, - net_charge_gen::TermPCharge, - net_charge_gen::TermNCharge, - net_charge_gen::PosNegCharge, - net_charge_gen::Centrality); - using MyCollisionsRun2 = soa::Join; using MyCollisionRun2 = MyCollisionsRun2::iterator; using MyCollisionsRun3 = soa::Join; @@ -123,15 +81,19 @@ enum RunType { }; struct NetchargeFluctuations { - Produces netCharge; - Produces netChargeGen; Service pdgService; - + Service ccdb; + TRandom3* fRndm = new TRandom3(0); HistogramRegistry histogramRegistry{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; // Configurables + Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; + Configurable cfgUrlCCDB{"cfgUrlCCDB", "http://alice-ccdb.cern.ch", "url of ccdb"}; + Configurable cfgPathCCDB{"cfgPathCCDB", "Users/n/nimalik/efftest", "Path for ccdb-object"}; + Configurable cfgLoadEff{"cfgLoadEff", true, "Load efficiency"}; + Configurable vertexZcut{"vertexZcut", 10.f, "Vertex Z"}; - Configurable etaCut{"etaCut", 0.8, "Eta cut"}; + Configurable etaCut{"etaCut", 0.8f, "Eta cut"}; Configurable ptMinCut{"ptMinCut", 0.2, "Pt min cut"}; Configurable ptMaxCut{"ptMaxCut", 5.0, "Pt max cut"}; Configurable dcaXYCut{"dcaXYCut", 0.12, "DCA XY cut"}; @@ -139,17 +101,30 @@ struct NetchargeFluctuations { Configurable tpcCrossCut{"tpcCrossCut", 70, "TPC crossrows cut"}; Configurable itsChiCut{"itsChiCut", 70, "ITS chi2 cluster cut"}; Configurable tpcChiCut{"tpcChiCut", 70, "TPC chi2 cluster cut"}; + Configurable centMin{"centMin", 0.0f, "cenrality min for delta eta"}; + Configurable centMax{"centMax", 10.0f, "cenrality max for delta eta"}; + Configurable cfgNSubsample{"cfgNSubsample", 30, "Number of subsamples for Error"}; + Configurable deltaEta{"deltaEta", 8, "Delta eta bin count"}; + Configurable threshold{"threshold", 1e-6, "Delta eta bin count"}; // Event selections - Configurable cSel8Trig{"cSel8Trig", true, "Sel8 (T0A + T0C) Selection Run3"}; // sel8 - Configurable cInt7Trig{"cInt7Trig", true, "kINT7 MB Trigger"}; // kINT7 - Configurable cSel7Trig{"cSel7Trig", true, "Sel7 (V0A + V0C) Selection Run2"}; // sel7 - Configurable cTFBorder{"cTFBorder", false, "Timeframe Border Selection"}; // pileup - Configurable cNoItsROBorder{"cNoItsROBorder", false, "No ITSRO Border Cut"}; // pileup - Configurable cItsTpcVtx{"cItsTpcVtx", false, "ITS+TPC Vertex Selection"}; // pileup - Configurable cPileupReject{"cPileupReject", false, "Pileup rejection"}; // pileup - Configurable cZVtxTimeDiff{"cZVtxTimeDiff", false, "z-vtx time diff selection"}; // pileup - Configurable cIsGoodITSLayers{"cIsGoodITSLayers", false, "Good ITS Layers All"}; // pileup + Configurable cSel8Trig{"cSel8Trig", true, "Sel8 (T0A + T0C) Selection Run3"}; // sel8 + Configurable cInt7Trig{"cInt7Trig", true, "kINT7 MB Trigger"}; // kINT7 + Configurable cSel7Trig{"cSel7Trig", true, "Sel7 (V0A + V0C) Selection Run2"}; // sel7 + Configurable cTFBorder{"cTFBorder", false, "Timeframe Border Selection"}; // pileup + Configurable cNoItsROBorder{"cNoItsROBorder", false, "No ITSRO Border Cut"}; // pileup + Configurable cItsTpcVtx{"cItsTpcVtx", false, "ITS+TPC Vertex Selection"}; // pileup + Configurable cPileupReject{"cPileupReject", false, "Pileup rejection"}; // pileup + Configurable cZVtxTimeDiff{"cZVtxTimeDiff", false, "z-vtx time diff selection"}; // pileup + Configurable cfgUseGoodItsLayerAllCut{"cfgUseGoodItsLayerAllCut", false, "Good ITS Layers All"}; // pileup + Configurable cDcaXy{"cDcaXy", false, "Dca XY cut"}; + Configurable cDcaZ{"cDcaZ", false, "Dca Z cut"}; + Configurable cTpcCr{"cTpcCr", false, "tpc crossrows"}; + Configurable cItsChi{"cItsChi", false, "ITS chi"}; + Configurable cTpcChi{"cTpcChi", false, "TPC chi"}; + + // CCDB efficiency histograms + TH2D* efficiency = nullptr; // Initialization void init(o2::framework::InitContext&) @@ -158,8 +133,8 @@ struct NetchargeFluctuations { const AxisSpec dcaAxis = {250, -0.5, 0.5, "DCA_{xy} (cm)"}; const AxisSpec dcazAxis = {250, -0.5, 0.5, "DCA_{z} (cm)"}; const AxisSpec ptAxis = {70, 0.0, 7.0, "#it{p}_{T} (GeV/#it{c})"}; - const AxisSpec etaAxis = {200, -1., 1., "#eta"}; - const AxisSpec cent1Axis = {10, 0., 100., "centrality"}; + const AxisSpec etaAxis = {20, -1., 1., "#eta"}; + const AxisSpec deltaEtaAxis = {9, 0, 1.8, "#eta"}; const AxisSpec centAxis = {100, 0., 100., "centrality"}; const AxisSpec multAxis = {200, 0., 10000., "FT0M Amplitude"}; const AxisSpec tpcChiAxis = {1400, 0., 7., "Chi2"}; @@ -167,72 +142,144 @@ struct NetchargeFluctuations { const AxisSpec crossedRowAxis = {1600, 0., 160., "TPC Crossed rows"}; const AxisSpec eventsAxis = {10, 0, 10, ""}; const AxisSpec signAxis = {20, -10, 10, ""}; - const AxisSpec nchAxis = {3000, 0, 3000, "Nch"}; + const AxisSpec nchAxis = {5000, 0, 5000, "Nch"}; + const AxisSpec nch1Axis = {1500, 0, 1500, "Nch"}; const AxisSpec nchpAxis = {50000, 0, 50000, "Nch"}; - histogramRegistry.add("hVtxZ_before", "", kTH1F, {vtxzAxis}); - histogramRegistry.add("hDcaXY_before", "", kTH1F, {dcaAxis}); - histogramRegistry.add("hDcaZ_before", "", kTH1F, {dcazAxis}); - histogramRegistry.add("hTPCchi2perCluster_before", "", kTH1D, {tpcChiAxis}); - histogramRegistry.add("hITSchi2perCluster_before", "", kTH1D, {itsChiAxis}); - histogramRegistry.add("hTPCCrossedrows_before", "", kTH1D, {crossedRowAxis}); - histogramRegistry.add("hPtDcaXY_before", "", kTH2D, {ptAxis, dcaAxis}); - histogramRegistry.add("hPtDcaZ_before", "", kTH2D, {ptAxis, dcazAxis}); - histogramRegistry.add("hVtxZ_after", "", kTH1F, {vtxzAxis}); - histogramRegistry.add("hDcaXY_after", "", kTH1F, {dcaAxis}); - histogramRegistry.add("hDcaZ_after", "", kTH1F, {dcazAxis}); - histogramRegistry.add("hTPCchi2perCluster_after", "", kTH1D, {tpcChiAxis}); - histogramRegistry.add("hITSchi2perCluster_after", "", kTH1D, {itsChiAxis}); - histogramRegistry.add("hTPCCrossedrows_after", "", kTH1D, {crossedRowAxis}); - histogramRegistry.add("hPtDcaXY_after", "", kTH2D, {ptAxis, dcaAxis}); - histogramRegistry.add("hPtDcaZ_after", "", kTH2D, {ptAxis, dcazAxis}); - histogramRegistry.add("hEta", "", kTH1F, {etaAxis}); - histogramRegistry.add("hPt", "", kTH1F, {ptAxis}); - histogramRegistry.add("hCentrality", "", kTH1F, {centAxis}); - histogramRegistry.add("hMultiplicity", "", kTH1F, {multAxis}); - histogramRegistry.add("gen_hVtxZ_before", "", kTH1F, {vtxzAxis}); - histogramRegistry.add("gen_hVtxZ_after", "", kTH1F, {vtxzAxis}); - histogramRegistry.add("gen_hEta", "", kTH1F, {etaAxis}); - histogramRegistry.add("gen_hSign", "", kTH1F, {signAxis}); - histogramRegistry.add("gen_hPt", "", kTH1F, {ptAxis}); - - histogramRegistry.add("nch", "", kTH1D, {nchAxis}); - histogramRegistry.add("nch0", "", kTH1D, {nchAxis}); - histogramRegistry.add("nch1", "", kTH1D, {nchAxis}); - histogramRegistry.add("nch2", "", kTH1D, {nchAxis}); - histogramRegistry.add("nch3", "", kTH1D, {nchAxis}); - histogramRegistry.add("nch4", "", kTH1D, {nchAxis}); - histogramRegistry.add("nch5", "", kTH1D, {nchAxis}); - histogramRegistry.add("nch6", "", kTH1D, {nchAxis}); - histogramRegistry.add("nch7", "", kTH1D, {nchAxis}); - histogramRegistry.add("nch8", "", kTH1D, {nchAxis}); - histogramRegistry.add("nch9", "", kTH1D, {nchAxis}); - histogramRegistry.add("nch_pos", "", kTH1D, {nchAxis}); - histogramRegistry.add("nch_neg", "", kTH1D, {nchAxis}); - histogramRegistry.add("nch_negpos", "", kTH1D, {nchpAxis}); - - histogramRegistry.add("nch_cent", "", kTH2D, {centAxis, nchAxis}); - histogramRegistry.add("nch_pos_cent", "", kTH2D, {centAxis, nchAxis}); - histogramRegistry.add("nch_neg_cent", "", kTH2D, {centAxis, nchAxis}); - histogramRegistry.add("nch_negpos_cent", "", kTH2D, {centAxis, nchpAxis}); + std::vector centBining = {0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; + AxisSpec cent1Axis = {centBining, "Multiplicity percentile from FT0M (%)"}; + + auto noSubsample = static_cast(cfgNSubsample); + float maxSubsample = 1.0 * noSubsample; + AxisSpec subsampleAxis = {noSubsample, 0.0, maxSubsample, "subsample no."}; + + histogramRegistry.add("QA/hVtxZ_before", "", kTH1F, {vtxzAxis}); + histogramRegistry.add("QA/hDcaXY_before", "", kTH1F, {dcaAxis}); + histogramRegistry.add("QA/hDcaZ_before", "", kTH1F, {dcazAxis}); + histogramRegistry.add("QA/hTPCchi2perCluster_before", "", kTH1D, {tpcChiAxis}); + histogramRegistry.add("QA/hITSchi2perCluster_before", "", kTH1D, {itsChiAxis}); + histogramRegistry.add("QA/hTPCCrossedrows_before", "", kTH1D, {crossedRowAxis}); + histogramRegistry.add("QA/hPtDcaXY_before", "", kTH2D, {ptAxis, dcaAxis}); + histogramRegistry.add("QA/hPtDcaZ_before", "", kTH2D, {ptAxis, dcazAxis}); + histogramRegistry.add("QA/hVtxZ_after", "", kTH1F, {vtxzAxis}); + histogramRegistry.add("QA/hDcaXY_after", "", kTH1F, {dcaAxis}); + histogramRegistry.add("QA/hDcaZ_after", "", kTH1F, {dcazAxis}); + histogramRegistry.add("QA/hTPCchi2perCluster_after", "", kTH1D, {tpcChiAxis}); + histogramRegistry.add("QA/hITSchi2perCluster_after", "", kTH1D, {itsChiAxis}); + histogramRegistry.add("QA/hTPCCrossedrows_after", "", kTH1D, {crossedRowAxis}); + histogramRegistry.add("QA/hPtDcaXY_after", "", kTH2D, {ptAxis, dcaAxis}); + histogramRegistry.add("QA/hPtDcaZ_after", "", kTH2D, {ptAxis, dcazAxis}); + histogramRegistry.add("QA/hEta", "", kTH1F, {etaAxis}); + histogramRegistry.add("QA/cent_hEta", "", kTH2F, {cent1Axis, etaAxis}); + histogramRegistry.add("QA/hPt", "", kTH1F, {ptAxis}); + histogramRegistry.add("QA/cent_hPt", "", kTH2F, {cent1Axis, ptAxis}); + histogramRegistry.add("QA/hPt_eta", "", kTH2F, {ptAxis, etaAxis}); + histogramRegistry.add("QA/hCentrality", "", kTH1F, {centAxis}); + histogramRegistry.add("QA/hMultiplicity", "", kTH1F, {multAxis}); + + histogramRegistry.add("gen/hVtxZ_before", "", kTH1F, {vtxzAxis}); + histogramRegistry.add("gen/hVtxZ_after", "", kTH1F, {vtxzAxis}); + histogramRegistry.add("gen/hPt", "", kTH1F, {ptAxis}); + histogramRegistry.add("gen/cent_hPt", "", kTH2F, {centAxis, ptAxis}); + histogramRegistry.add("gen/hEta", "", kTH1F, {etaAxis}); + histogramRegistry.add("gen/cent_hEta", "", kTH2F, {centAxis, etaAxis}); + histogramRegistry.add("gen/hSign", "", kTH1F, {signAxis}); + histogramRegistry.add("gen/hPt_eta", "", kTH2F, {ptAxis, etaAxis}); + histogramRegistry.add("gen/cent_pos", "cent vs fpos", kTProfile, {cent1Axis}); + histogramRegistry.add("gen/cent_neg", "cent vs fneg", kTProfile, {cent1Axis}); + histogramRegistry.add("gen/cent_termp", "cent vs termp", kTProfile, {cent1Axis}); + histogramRegistry.add("gen/cent_termn", "cent vs termn", kTProfile, {cent1Axis}); + histogramRegistry.add("gen/cent_pos_sq", "cent vs sqfpos", kTProfile, {cent1Axis}); + histogramRegistry.add("gen/cent_neg_sq", "cent vs sqfneg", kTProfile, {cent1Axis}); + histogramRegistry.add("gen/cent_posneg", "cent vs fpos*fneg", kTProfile, {cent1Axis}); + histogramRegistry.add("gen/cent_nch", "cent vs nch", kTProfile, {cent1Axis}); + histogramRegistry.add("gen/nch", "", kTH1F, {nchAxis}); + histogramRegistry.add("gen/delta_eta_eta", "delta_eta ", kTH1F, {etaAxis}); + histogramRegistry.add("gen/delta_eta_pos", "delta_eta vs fpos ", kTProfile, {deltaEtaAxis}); + histogramRegistry.add("gen/delta_eta_neg", "delta_eta vs fneg ", kTProfile, {deltaEtaAxis}); + histogramRegistry.add("gen/delta_eta_termp", "delta_eta vs termp ", kTProfile, {deltaEtaAxis}); + histogramRegistry.add("gen/delta_eta_termn", "delta_eta vs termn ", kTProfile, {deltaEtaAxis}); + histogramRegistry.add("gen/delta_eta_pos_sq", "delta_eta vs pos_sq ", kTProfile, {deltaEtaAxis}); + histogramRegistry.add("gen/delta_eta_neg_sq", "delta_eta vs neg_sq ", kTProfile, {deltaEtaAxis}); + histogramRegistry.add("gen/delta_eta_posneg", "delta_eta vs posneg ", kTProfile, {deltaEtaAxis}); + histogramRegistry.add("gen/delta_eta_nch", "delta_eta vs nchGen ", kTProfile, {deltaEtaAxis}); + + histogramRegistry.add("data/nch", "", kTH1D, {nchAxis}); + histogramRegistry.add("data/cent_nch", "", kTProfile, {cent1Axis}); + histogramRegistry.add("data/nch_pos", "", kTH1D, {nchAxis}); + histogramRegistry.add("data/cent_nch_pos", "", kTH2D, {centAxis, nchAxis}); + histogramRegistry.add("data/nch_neg", "", kTH1D, {nchAxis}); + histogramRegistry.add("data/cent_nch_neg", "", kTH2D, {centAxis, nchAxis}); + histogramRegistry.add("data/nch_negpos", "", kTH1D, {nchpAxis}); + histogramRegistry.add("data/cent_nch_negpos", "", kTH2D, {centAxis, nchpAxis}); + histogramRegistry.add("data/cent_pos", "cent vs fpos", kTProfile, {cent1Axis}); + histogramRegistry.add("data/cent_neg", "cent vs fneg", kTProfile, {cent1Axis}); + histogramRegistry.add("data/cent_termp", "cent vs termp", kTProfile, {cent1Axis}); + histogramRegistry.add("data/cent_termn", "cent vs termn", kTProfile, {cent1Axis}); + histogramRegistry.add("data/cent_pos_sq", "cent vs sqfpos", kTProfile, {cent1Axis}); + histogramRegistry.add("data/cent_neg_sq", "cent vs sqfneg", kTProfile, {cent1Axis}); + histogramRegistry.add("data/cent_posneg", "cent vs fpos*fneg", kTProfile, {cent1Axis}); + histogramRegistry.add("data/hPt_cor", "", kTH1F, {ptAxis}); + histogramRegistry.add("data/hEta_cor", "", kTH1F, {etaAxis}); + histogramRegistry.add("data/cent_nchTotal", "cent vs nchTotal", kTProfile, {cent1Axis}); + histogramRegistry.add("data/cent_nchTotalCor", "cent vs nchTotalCor", kTProfile, {cent1Axis}); + histogramRegistry.add("data/nch_nchCor", "", kTProfile, {nchAxis}); + histogramRegistry.add("data/nchCor", "", kTH1F, {nchAxis}); + histogramRegistry.add("data/cent_nchCor", "", kTProfile, {cent1Axis}); + histogramRegistry.add("data/cent_pos_cor", "", kTProfile, {cent1Axis}); + histogramRegistry.add("data/cent_neg_cor", "", kTProfile, {cent1Axis}); + histogramRegistry.add("data/delta_eta_cent", "Centrality", kTH1F, {cent1Axis}); + histogramRegistry.add("data/delta_eta_eta", "eta", kTH1F, {etaAxis}); + histogramRegistry.add("data/delta_eta_nchTotal", "delta_eta vs nchTotal", kTProfile, {deltaEtaAxis}); + histogramRegistry.add("data/delta_eta_nch", "delta_eta vs nch", kTProfile, {deltaEtaAxis}); + histogramRegistry.add("data/delta_eta_nchCor", "delta_eta vs nchCor", kTProfile, {deltaEtaAxis}); + histogramRegistry.add("data/delta_eta_pos", "delta_eta vs fpos", kTProfile, {deltaEtaAxis}); + histogramRegistry.add("data/delta_eta_neg", "delta_eta vs fneg", kTProfile, {deltaEtaAxis}); + histogramRegistry.add("data/delta_eta_termp", "delta_eta vs termp", kTProfile, {deltaEtaAxis}); + histogramRegistry.add("data/delta_eta_termn", "delta_eta vs termn", kTProfile, {deltaEtaAxis}); + histogramRegistry.add("data/delta_eta_pos_sq", "delta_eta vs sqfpos", kTProfile, {deltaEtaAxis}); + histogramRegistry.add("data/delta_eta_neg_sq", "delta_eta vs sqfneg", kTProfile, {deltaEtaAxis}); + histogramRegistry.add("data/delta_eta_posneg", "delta_eta vs fpos*fneg", kTProfile, {deltaEtaAxis}); + histogramRegistry.add("data/delta_eta_pos_cor", "delta_eta vs fpos_cor", kTProfile, {deltaEtaAxis}); + histogramRegistry.add("data/delta_eta_neg_cor", "delta_eta vs fneg_cor", kTProfile, {deltaEtaAxis}); + + histogramRegistry.add("subsample/pos", "", kTProfile2D, {cent1Axis, subsampleAxis}); + histogramRegistry.add("subsample/neg", "", kTProfile2D, {cent1Axis, subsampleAxis}); + histogramRegistry.add("subsample/termp", "", kTProfile2D, {cent1Axis, subsampleAxis}); + histogramRegistry.add("subsample/termn", "", kTProfile2D, {cent1Axis, subsampleAxis}); + histogramRegistry.add("subsample/pos_sq", "", kTProfile2D, {cent1Axis, subsampleAxis}); + histogramRegistry.add("subsample/neg_sq", "", kTProfile2D, {cent1Axis, subsampleAxis}); + histogramRegistry.add("subsample/posneg", "", kTProfile2D, {cent1Axis, subsampleAxis}); + + if (cfgLoadEff) { + ccdb->setURL(cfgUrlCCDB.value); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + + // ccdb->setCreatedNotAfter(ccdbNoLaterThan.value); + // LOGF(info, "Getting object %s", ccdbPath.value.data()); + + TList* list = ccdb->getForTimeStamp(cfgPathCCDB.value, -1); + efficiency = reinterpret_cast(list->FindObject("efficiency_Run3")); + if (!efficiency) { + LOGF(info, "FATAL!! Could not find required histograms in CCDB"); + } + } } + template bool selCollision(C const& coll, float& cent, float& mult) { - histogramRegistry.fill(HIST("hVtxZ_before"), coll.posZ()); - if (std::abs(coll.posZ()) > vertexZcut) { + if (std::abs(coll.posZ()) > vertexZcut) return false; - } - if constexpr (run == kRun3) { - if (cSel8Trig && !coll.sel8()) { return false; } // require min bias trigger cent = coll.centFT0M(); // centrality for run3 mult = coll.multFT0M(); // multiplicity for run3 - } else { + } else if constexpr (run == kRun2) { if (cInt7Trig && !coll.alias_bit(kINT7)) { return false; } @@ -243,428 +290,536 @@ struct NetchargeFluctuations { mult = coll.multFV0M(); // multiplicity for run2 } - if (cNoItsROBorder && !coll.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + if (cNoItsROBorder && !coll.selection_bit(aod::evsel::kNoITSROFrameBorder)) return false; - } - - if (cTFBorder && !coll.selection_bit(aod::evsel::kNoTimeFrameBorder)) { + if (cTFBorder && !coll.selection_bit(aod::evsel::kNoTimeFrameBorder)) return false; - } - - if (cPileupReject && !coll.selection_bit(aod::evsel::kNoSameBunchPileup)) { + if (cPileupReject && !coll.selection_bit(aod::evsel::kNoSameBunchPileup)) return false; - } - - if (cZVtxTimeDiff && !coll.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { + if (cZVtxTimeDiff && !coll.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) return false; - } - - if (cItsTpcVtx && !coll.selection_bit(aod::evsel::kIsVertexITSTPC)) { + if (cItsTpcVtx && !coll.selection_bit(aod::evsel::kIsVertexITSTPC)) + return false; + if (cfgUseGoodItsLayerAllCut && !(coll.selection_bit(aod::evsel::kIsGoodITSLayersAll))) return false; - } - histogramRegistry.fill(HIST("hVtxZ_after"), coll.posZ()); - histogramRegistry.fill(HIST("hCentrality"), cent); - histogramRegistry.fill(HIST("hMultiplicity"), mult); return true; } + template void fillBeforeQA(T const& track) { - histogramRegistry.fill(HIST("hTPCchi2perCluster_before"), track.tpcChi2NCl()); - histogramRegistry.fill(HIST("hITSchi2perCluster_before"), track.itsChi2NCl()); - histogramRegistry.fill(HIST("hTPCCrossedrows_before"), track.tpcNClsCrossedRows()); - histogramRegistry.fill(HIST("hDcaXY_before"), track.dcaXY()); - histogramRegistry.fill(HIST("hDcaZ_before"), track.dcaZ()); - histogramRegistry.fill(HIST("hPtDcaXY_before"), track.pt(), track.dcaXY()); - histogramRegistry.fill(HIST("hPtDcaZ_before"), track.pt(), track.dcaZ()); + histogramRegistry.fill(HIST("QA/hTPCchi2perCluster_before"), track.tpcChi2NCl()); + histogramRegistry.fill(HIST("QA/hITSchi2perCluster_before"), track.itsChi2NCl()); + histogramRegistry.fill(HIST("QA/hTPCCrossedrows_before"), track.tpcNClsCrossedRows()); + histogramRegistry.fill(HIST("QA/hDcaXY_before"), track.dcaXY()); + histogramRegistry.fill(HIST("QA/hDcaZ_before"), track.dcaZ()); + histogramRegistry.fill(HIST("QA/hPtDcaXY_before"), track.pt(), track.dcaXY()); + histogramRegistry.fill(HIST("QA/hPtDcaZ_before"), track.pt(), track.dcaZ()); } template void fillAfterQA(T const& track) { - histogramRegistry.fill(HIST("hDcaXY_after"), track.dcaXY()); - histogramRegistry.fill(HIST("hDcaZ_after"), track.dcaZ()); - histogramRegistry.fill(HIST("hPt"), track.pt()); - histogramRegistry.fill(HIST("hEta"), track.eta()); - histogramRegistry.fill(HIST("hPtDcaXY_after"), track.pt(), track.dcaXY()); - histogramRegistry.fill(HIST("hPtDcaZ_after"), track.pt(), track.dcaZ()); - histogramRegistry.fill(HIST("hTPCCrossedrows_after"), track.tpcNClsCrossedRows()); - histogramRegistry.fill(HIST("hTPCchi2perCluster_after"), track.tpcChi2NCl()); - histogramRegistry.fill(HIST("hITSchi2perCluster_after"), track.itsChi2NCl()); - } - - template - void nchDistribution(N const& nch, C const& cent) - { - constexpr int kCent0Min = 0, kCent0Max = 5; - constexpr int kCent1Min = 5, kCent1Max = 10; - constexpr int kCent2Min = 10, kCent2Max = 20; - constexpr int kCent3Min = 20, kCent3Max = 30; - constexpr int kCent4Min = 30, kCent4Max = 40; - constexpr int kCent5Min = 40, kCent5Max = 50; - constexpr int kCent6Min = 50, kCent6Max = 60; - constexpr int kCent7Min = 60, kCent7Max = 70; - constexpr int kCent8Min = 70, kCent8Max = 80; - constexpr int kCent9Min = 80, kCent9Max = 90; - - histogramRegistry.fill(HIST("nch"), nch); - histogramRegistry.fill(HIST("nch_cent"), cent, nch); - - if (cent >= kCent0Min && cent < kCent0Max) - histogramRegistry.fill(HIST("nch0"), nch); - else if (cent >= kCent1Min && cent < kCent1Max) - histogramRegistry.fill(HIST("nch1"), nch); - else if (cent >= kCent2Min && cent < kCent2Max) - histogramRegistry.fill(HIST("nch2"), nch); - else if (cent >= kCent3Min && cent < kCent3Max) - histogramRegistry.fill(HIST("nch3"), nch); - else if (cent >= kCent4Min && cent < kCent4Max) - histogramRegistry.fill(HIST("nch4"), nch); - else if (cent >= kCent5Min && cent < kCent5Max) - histogramRegistry.fill(HIST("nch5"), nch); - else if (cent >= kCent6Min && cent < kCent6Max) - histogramRegistry.fill(HIST("nch6"), nch); - else if (cent >= kCent7Min && cent < kCent7Max) - histogramRegistry.fill(HIST("nch7"), nch); - else if (cent >= kCent8Min && cent < kCent8Max) - histogramRegistry.fill(HIST("nch8"), nch); - else if (cent >= kCent9Min && cent < kCent9Max) - histogramRegistry.fill(HIST("nch9"), nch); + histogramRegistry.fill(HIST("QA/hDcaXY_after"), track.dcaXY()); + histogramRegistry.fill(HIST("QA/hDcaZ_after"), track.dcaZ()); + histogramRegistry.fill(HIST("QA/hPt"), track.pt()); + histogramRegistry.fill(HIST("QA/hEta"), track.eta()); + histogramRegistry.fill(HIST("QA/hPt_eta"), track.pt(), track.eta()); + histogramRegistry.fill(HIST("QA/hPtDcaXY_after"), track.pt(), track.dcaXY()); + histogramRegistry.fill(HIST("QA/hPtDcaZ_after"), track.pt(), track.dcaZ()); + histogramRegistry.fill(HIST("QA/hTPCCrossedrows_after"), track.tpcNClsCrossedRows()); + histogramRegistry.fill(HIST("QA/hTPCchi2perCluster_after"), track.tpcChi2NCl()); + histogramRegistry.fill(HIST("QA/hITSchi2perCluster_after"), track.itsChi2NCl()); } template bool selTrack(T const& track) { - if (!track.isGlobalTrack()) { + if (!track.isGlobalTrack()) return false; - } // accept only global tracks - - if (std::fabs(track.eta()) >= etaCut) { + if (std::fabs(track.eta()) >= etaCut) return false; - } - - if (track.pt() <= ptMinCut || track.pt() >= ptMaxCut) { + if (track.pt() <= ptMinCut || track.pt() >= ptMaxCut) return false; - } - - if (track.sign() == 0) { + if (track.sign() == 0) return false; - } - /* if (std::fabs(track.dcaXY()) > dcaXYCut) { - return false; - } - - if (std::fabs(track.dcaZ()) > dcaZCut) { - return false ; - }*/ - - /* - if (track.tpcNClsCrossedRows() < tpcCrossCut) { + if (cDcaXy && std::fabs(track.dcaXY()) > dcaXYCut) return false; - } - - if (track.itsChi2NCl() > itsChiCut) { + if (cDcaZ && std::fabs(track.dcaZ()) > dcaZCut) return false; - } - - if (track.tpcChi2NCl() > tpcChiCut) { + if (cTpcCr && track.tpcNClsCrossedRows() < tpcCrossCut) + return false; + if (cItsChi && track.itsChi2NCl() > itsChiCut) + return false; + if (cTpcChi && track.tpcChi2NCl() > tpcChiCut) return false; - } - -*/ return true; } + double getEfficiency(float pt, float eta, TH2D* hEff) + { + if (!hEff) { + return 1e-6; + } + int binX = hEff->GetXaxis()->FindBin(pt); + int binY = hEff->GetYaxis()->FindBin(eta); + if (binX < 1 || binX > hEff->GetNbinsX() || binY < 1 || binY > hEff->GetNbinsY()) { + return 1e-6; + } + double eff = hEff->GetBinContent(binX, binY); + return eff; + } + + void fillHistograms(float nch, float cent, float fpos, float fneg, float posneg, float termp, float termn) + { + histogramRegistry.fill(HIST("data/nch"), nch); + histogramRegistry.fill(HIST("data/cent_nch"), cent, nch); + histogramRegistry.fill(HIST("data/nch_pos"), fpos); + histogramRegistry.fill(HIST("data/cent_nch_pos"), cent, fpos); + histogramRegistry.fill(HIST("data/nch_neg"), fneg); + histogramRegistry.fill(HIST("data/cent_nch_neg"), cent, fneg); + histogramRegistry.fill(HIST("data/nch_negpos"), posneg); + histogramRegistry.fill(HIST("data/cent_nch_negpos"), cent, posneg); + + histogramRegistry.fill(HIST("data/cent_pos"), cent, fpos); + histogramRegistry.fill(HIST("data/cent_neg"), cent, fneg); + histogramRegistry.fill(HIST("data/cent_termp"), cent, termp); + histogramRegistry.fill(HIST("data/cent_termn"), cent, termn); + histogramRegistry.fill(HIST("data/cent_pos_sq"), cent, fpos * fpos); + histogramRegistry.fill(HIST("data/cent_neg_sq"), cent, fneg * fneg); + histogramRegistry.fill(HIST("data/cent_posneg"), cent, posneg); + + float lRandom = fRndm->Rndm(); + int sampleIndex = static_cast(cfgNSubsample * lRandom); + + histogramRegistry.fill(HIST("subsample/pos"), cent, sampleIndex, fpos); + histogramRegistry.fill(HIST("subsample/neg"), cent, sampleIndex, fneg); + histogramRegistry.fill(HIST("subsample/termp"), cent, sampleIndex, termp); + histogramRegistry.fill(HIST("subsample/termn"), cent, sampleIndex, termn); + histogramRegistry.fill(HIST("subsample/pos_sq"), cent, sampleIndex, fpos * fpos); + histogramRegistry.fill(HIST("subsample/neg_sq"), cent, sampleIndex, fneg * fneg); + histogramRegistry.fill(HIST("subsample/posneg"), cent, sampleIndex, posneg); + } + template void calculationData(C const& coll, T const& tracks) { float cent = -1, mult = -1; + histogramRegistry.fill(HIST("QA/hVtxZ_before"), coll.posZ()); if (!selCollision(coll, cent, mult)) { return; } + histogramRegistry.fill(HIST("QA/hVtxZ_after"), coll.posZ()); + histogramRegistry.fill(HIST("QA/hCentrality"), cent); + histogramRegistry.fill(HIST("QA/hMultiplicity"), mult); + int fpos = 0, fneg = 0, posneg = 0, termn = 0, termp = 0; - int nch = 0; + int nch = 0, nchTotal = 0; + double posWeight = 0, negWeight = 0, nchCor = 0, nchTotalCor = 0; for (const auto& track : tracks) { - fillBeforeQA(track); - if (!selTrack(track)) { + double eff = getEfficiency(track.pt(), track.eta(), efficiency); + if (eff < threshold) continue; - } - nch += 1; + double weight = 1.0 / eff; + fillBeforeQA(track); + nchTotal += 1; + nchTotalCor += weight; + if (!selTrack(track)) + continue; + nch += 1; fillAfterQA(track); + histogramRegistry.fill(HIST("QA/cent_hEta"), cent, track.eta()); + histogramRegistry.fill(HIST("QA/cent_hPt"), cent, track.pt()); + histogramRegistry.fill(HIST("data/hPt_cor"), track.pt(), weight); + histogramRegistry.fill(HIST("data/hEta_cor"), track.eta(), weight); + + nchCor += weight; if (track.sign() == 1) { fpos += 1; + posWeight += weight; } else if (track.sign() == -1) { fneg += 1; + negWeight += weight; } + } // track termp = fpos * (fpos - 1); termn = fneg * (fneg - 1); posneg = fpos * fneg; - - nchDistribution(nch, cent); - - histogramRegistry.fill(HIST("nch_pos"), fpos); - histogramRegistry.fill(HIST("nch_pos_cent"), cent, fpos); - histogramRegistry.fill(HIST("nch_neg"), fneg); - histogramRegistry.fill(HIST("nch_neg_cent"), cent, fneg); - histogramRegistry.fill(HIST("nch_negpos"), posneg); - histogramRegistry.fill(HIST("nch_negpos_cent"), cent, posneg); - - netCharge(fpos, fneg, fpos * fpos, fneg * fneg, termp, termn, posneg, cent); + histogramRegistry.fill(HIST("data/cent_nchTotal"), cent, nchTotal); + histogramRegistry.fill(HIST("data/cent_nchTotalCor"), cent, nchTotalCor); + histogramRegistry.fill(HIST("data/nch_nchCor"), nch, nchCor); + histogramRegistry.fill(HIST("data/nchCor"), nchCor); + histogramRegistry.fill(HIST("data/cent_nchCor"), cent, nchCor); + histogramRegistry.fill(HIST("data/cent_pos_cor"), cent, posWeight); + histogramRegistry.fill(HIST("data/cent_neg_cor"), cent, negWeight); + fillHistograms(nch, cent, fpos, fneg, posneg, termp, termn); } template void calculationMc(C const& coll, T const& inputTracks, M const& mcCollisions, P const& mcParticles) { (void)mcCollisions; - if (!coll.has_mcCollision()) { return; } - histogramRegistry.fill(HIST("gen_hVtxZ_before"), coll.mcCollision().posZ()); - + histogramRegistry.fill(HIST("gen/hVtxZ_before"), coll.mcCollision().posZ()); float cent = -1, mult = -1; - + histogramRegistry.fill(HIST("QA/hVtxZ_before"), coll.posZ()); if (!selCollision(coll, cent, mult)) { return; } + histogramRegistry.fill(HIST("QA/hVtxZ_after"), coll.posZ()); + histogramRegistry.fill(HIST("QA/hCentrality"), cent); + histogramRegistry.fill(HIST("QA/hMultiplicity"), mult); int fpos = 0, fneg = 0, posneg = 0, termn = 0, termp = 0; - int nch = 0; + int nch = 0, nchCor = 0; + double posRecWeight = 0, negRecWeight = 0; for (const auto& track : inputTracks) { - fillBeforeQA(track); - - if (!selTrack(track)) { + if (!selTrack(track)) continue; - } nch += 1; - fillAfterQA(track); + histogramRegistry.fill(HIST("QA/cent_hEta"), cent, track.eta()); + histogramRegistry.fill(HIST("QA/cent_hPt"), cent, track.pt()); + + double eff = getEfficiency(track.pt(), track.eta(), efficiency); + if (eff < threshold) + continue; + double weight = 1.0 / eff; + histogramRegistry.fill(HIST("data/hPt_cor"), track.pt(), weight); + histogramRegistry.fill(HIST("data/hEta_cor"), track.eta(), weight); if (track.sign() == 1) { fpos += 1; + posRecWeight += weight; } else if (track.sign() == -1) { fneg += 1; + negRecWeight += weight; } + nchCor = posRecWeight + negRecWeight; } // track termp = fpos * (fpos - 1); termn = fneg * (fneg - 1); posneg = fpos * fneg; + histogramRegistry.fill(HIST("data/nch_nchCor"), nch, nchCor); + histogramRegistry.fill(HIST("data/nchCor"), nchCor); + histogramRegistry.fill(HIST("data/cent_nchCor"), cent, nchCor); + histogramRegistry.fill(HIST("data/cent_pos_cor"), cent, posRecWeight); + histogramRegistry.fill(HIST("data/cent_neg_cor"), cent, negRecWeight); - nchDistribution(nch, cent); - - histogramRegistry.fill(HIST("nch_pos"), fpos); - histogramRegistry.fill(HIST("nch_pos_cent"), cent, fpos); - histogramRegistry.fill(HIST("nch_neg"), fneg); - histogramRegistry.fill(HIST("nch_neg_cent"), cent, fneg); - histogramRegistry.fill(HIST("nch_negpos"), posneg); - histogramRegistry.fill(HIST("nch_negpos_cent"), cent, posneg); - - netCharge(fpos, fneg, fpos * fpos, fneg * fneg, termp, termn, posneg, cent); + fillHistograms(nch, cent, fpos, fneg, posneg, termp, termn); - int posGen = 0, negGen = 0, posNegGen = 0, termNGen = 0, termPGen = 0; + int posGen = 0, negGen = 0, posNegGen = 0, termNGen = 0, termPGen = 0, nchGen = 0; const auto& mccolgen = coll.template mcCollision_as(); - - /* if (std::abs(mccolgen.posZ()) > vertexZcut) { - return; - }*/ - + if (std::abs(mccolgen.posZ()) > vertexZcut) + return; const auto& mcpartgen = mcParticles.sliceByCached(aod::mcparticle::mcCollisionId, mccolgen.globalIndex(), cache); - histogramRegistry.fill(HIST("gen_hVtxZ_after"), mccolgen.posZ()); - + histogramRegistry.fill(HIST("gen/hVtxZ_after"), mccolgen.posZ()); for (const auto& mcpart : mcpartgen) { - - if (!mcpart.isPhysicalPrimary()) { + if (std::fabs(mcpart.eta()) >= etaCut) + continue; + if (!mcpart.isPhysicalPrimary()) continue; - } int pid = mcpart.pdgCode(); auto sign = 0; auto* pd = pdgService->GetParticle(pid); if (pd != nullptr) { sign = pd->Charge() / 3.; } + if (sign == 0) + continue; + if (std::abs(pid) != kElectron && + std::abs(pid) != kMuonMinus && + std::abs(pid) != kPiPlus && + std::abs(pid) != kKPlus && + std::abs(pid) != kProton) + continue; + if (std::fabs(mcpart.eta()) >= etaCut) + continue; + if ((mcpart.pt() <= ptMinCut) || (mcpart.pt() >= ptMaxCut)) + continue; + histogramRegistry.fill(HIST("gen/hPt"), mcpart.pt()); + histogramRegistry.fill(HIST("gen/cent_hPt"), cent, mcpart.pt()); + histogramRegistry.fill(HIST("gen/hEta"), mcpart.eta()); + histogramRegistry.fill(HIST("gen/cent_hEta"), cent, mcpart.eta()); + histogramRegistry.fill(HIST("gen/hSign"), sign); + histogramRegistry.fill(HIST("gen/hPt_eta"), mcpart.pt(), mcpart.eta()); + nchGen += 1; + if (sign == 1) { + posGen += 1; + } + if (sign == -1) { + negGen += 1; + } + } + termPGen = posGen * (posGen - 1); + termNGen = negGen * (negGen - 1); + posNegGen = posGen * negGen; + histogramRegistry.fill(HIST("gen/cent_pos"), cent, posGen); + histogramRegistry.fill(HIST("gen/cent_neg"), cent, negGen); + histogramRegistry.fill(HIST("gen/cent_termp"), cent, termPGen); + histogramRegistry.fill(HIST("gen/cent_termn"), cent, termNGen); + histogramRegistry.fill(HIST("gen/cent_pos_sq"), cent, posGen * posGen); + histogramRegistry.fill(HIST("gen/cent_neg_sq"), cent, negGen * negGen); + histogramRegistry.fill(HIST("gen/cent_posneg"), cent, posNegGen); + histogramRegistry.fill(HIST("gen/cent_nch"), cent, nchGen); + histogramRegistry.fill(HIST("gen/nch"), nchGen); + + } // void - if (sign == 0) { + template + void calculationDeltaEta(C const& coll, T const& tracks, float deta1, float deta2) + { + float cent = -1, mult = -1; + if (!selCollision(coll, cent, mult)) + return; + if (!(cent >= centMin && cent < centMax)) + return; + histogramRegistry.fill(HIST("data/delta_eta_cent"), cent); + + int fpos = 0, fneg = 0, posneg = 0, termn = 0, termp = 0, nch = 0, nchTotal = 0; + double nchCor = 0, posWeight = 0, negWeight = 0; + for (const auto& track : tracks) { + nchTotal += 1; + if (!selTrack(track)) + continue; + nch += 1; + double eff = getEfficiency(track.pt(), track.eta(), efficiency); + if (eff < threshold) continue; + double weight = 1.0 / eff; + nchCor += weight; + double eta = track.eta(); + if (eta < deta1 || eta > deta2) + continue; + + histogramRegistry.fill(HIST("data/delta_eta_eta"), eta); + + if (track.sign() == 1) { + fpos++; + posWeight += weight; + } else if (track.sign() == -1) { + fneg++; + negWeight += weight; } + } + termp = fpos * (fpos - 1); + termn = fneg * (fneg - 1); + posneg = fpos * fneg; + + float deltaEtaWidth = deta2 - deta1 + 1e-5f; + + histogramRegistry.fill(HIST("data/delta_eta_nchTotal"), deltaEtaWidth, nchTotal); + histogramRegistry.fill(HIST("data/delta_eta_nch"), deltaEtaWidth, nch); + histogramRegistry.fill(HIST("data/delta_eta_nchCor"), deltaEtaWidth, nchCor); + histogramRegistry.fill(HIST("data/delta_eta_pos"), deltaEtaWidth, fpos); + histogramRegistry.fill(HIST("data/delta_eta_pos_cor"), deltaEtaWidth, posWeight); + histogramRegistry.fill(HIST("data/delta_eta_neg"), deltaEtaWidth, fneg); + histogramRegistry.fill(HIST("data/delta_eta_neg_cor"), deltaEtaWidth, negWeight); + histogramRegistry.fill(HIST("data/delta_eta_termp"), deltaEtaWidth, termp); + histogramRegistry.fill(HIST("data/delta_eta_termn"), deltaEtaWidth, termn); + histogramRegistry.fill(HIST("data/delta_eta_pos_sq"), deltaEtaWidth, fpos * fpos); + histogramRegistry.fill(HIST("data/delta_eta_neg_sq"), deltaEtaWidth, fneg * fneg); + histogramRegistry.fill(HIST("data/delta_eta_posneg"), deltaEtaWidth, posneg); + } + + template + void calculationMcDeltaEta(C const& coll, T const& inputTracks, M const& mcCollisions, P const& mcParticles, float deta1, float deta2) + { + (void)mcCollisions; - if (std::abs(pid) != kElectron && std::abs(pid) != kMuonMinus && std::abs(pid) != kPiPlus && std::abs(pid) != kKPlus && std::abs(pid) != kProton) { + if (!coll.has_mcCollision()) + return; + + float cent = -1, mult = -1; + if (!selCollision(coll, cent, mult)) + return; + if (!(cent >= centMin && cent < centMax)) + return; + histogramRegistry.fill(HIST("data/delta_eta_cent"), cent); + + float deltaEtaWidth = deta2 - deta1 + 1e-5f; + + int fpos = 0, fneg = 0, posneg = 0, termn = 0, termp = 0; + int nch = 0, nchTotal = 0; + double nchCor = 0, posRecWeight = 0, negRecWeight = 0; + + for (const auto& track : inputTracks) { + nchTotal += 1; + if (!selTrack(track)) + continue; + double eta = track.eta(); + if (eta < deta1 || eta > deta2) + continue; + + histogramRegistry.fill(HIST("data/delta_eta_eta"), eta); + double eff = getEfficiency(track.pt(), eta, efficiency); + if (eff < threshold) continue; + double weight = 1.0 / eff; + nch += 1; + nchCor += weight; + if (track.sign() == 1) { + fpos += 1; + posRecWeight += weight; + } else if (track.sign() == -1) { + fneg += 1; + negRecWeight += weight; } + } // tracks + + termp = fpos * (fpos - 1); + termn = fneg * (fneg - 1); + posneg = fpos * fneg; + + histogramRegistry.fill(HIST("data/delta_eta_nchTotal"), deltaEtaWidth, nchTotal); + histogramRegistry.fill(HIST("data/delta_eta_nch"), deltaEtaWidth, nch); + histogramRegistry.fill(HIST("data/delta_eta_nchCor"), deltaEtaWidth, nchCor); + histogramRegistry.fill(HIST("data/delta_eta_pos"), deltaEtaWidth, fpos); + histogramRegistry.fill(HIST("data/delta_eta_pos_cor"), deltaEtaWidth, posRecWeight); + histogramRegistry.fill(HIST("data/delta_eta_neg"), deltaEtaWidth, fneg); + histogramRegistry.fill(HIST("data/delta_eta_neg_cor"), deltaEtaWidth, negRecWeight); + histogramRegistry.fill(HIST("data/delta_eta_termp"), deltaEtaWidth, termp); + histogramRegistry.fill(HIST("data/delta_eta_termn"), deltaEtaWidth, termn); + histogramRegistry.fill(HIST("data/delta_eta_pos_sq"), deltaEtaWidth, fpos * fpos); + histogramRegistry.fill(HIST("data/delta_eta_neg_sq"), deltaEtaWidth, fneg * fneg); + histogramRegistry.fill(HIST("data/delta_eta_posneg"), deltaEtaWidth, posneg); + + const auto& mccolgen = coll.template mcCollision_as(); + + if (std::abs(mccolgen.posZ()) > vertexZcut) + return; + + const auto& mcpartgen = mcParticles.sliceByCached(aod::mcparticle::mcCollisionId, mccolgen.globalIndex(), cache); + + int posGen = 0, negGen = 0, posNegGen = 0, termNGen = 0, termPGen = 0, nchGen = 0; + for (const auto& mcpart : mcpartgen) { + if (!mcpart.isPhysicalPrimary()) + continue; - if (std::fabs(mcpart.eta()) > etaCut) + int pid = mcpart.pdgCode(); + auto sign = 0; + auto* pd = pdgService->GetParticle(pid); + if (pd != nullptr) { + sign = pd->Charge() / 3.; + } + if (sign == 0) + continue; + if (std::abs(pid) != kElectron && + std::abs(pid) != kMuonMinus && + std::abs(pid) != kPiPlus && + std::abs(pid) != kKPlus && + std::abs(pid) != kProton) continue; + if (std::fabs(mcpart.eta()) >= etaCut) + continue; if ((mcpart.pt() <= ptMinCut) || (mcpart.pt() >= ptMaxCut)) continue; - histogramRegistry.fill(HIST("gen_hPt"), mcpart.pt()); - histogramRegistry.fill(HIST("gen_hEta"), mcpart.eta()); - histogramRegistry.fill(HIST("gen_hSign"), sign); + double mcEta = mcpart.eta(); + if (mcEta < deta1 || mcEta > deta2) + continue; + + histogramRegistry.fill(HIST("gen/delta_eta_eta"), mcpart.eta()); + nchGen += 1; if (sign == 1) { posGen += 1; } - if (sign == -1) { negGen += 1; } - } // particle + } + termPGen = posGen * (posGen - 1); termNGen = negGen * (negGen - 1); posNegGen = posGen * negGen; - netChargeGen(posGen, negGen, posGen * posGen, negGen * negGen, - termPGen, termNGen, posNegGen, cent); + histogramRegistry.fill(HIST("gen/delta_eta_pos"), deltaEtaWidth, posGen); + histogramRegistry.fill(HIST("gen/delta_eta_neg"), deltaEtaWidth, negGen); + histogramRegistry.fill(HIST("gen/delta_eta_termp"), deltaEtaWidth, termPGen); + histogramRegistry.fill(HIST("gen/delta_eta_termn"), deltaEtaWidth, termNGen); + histogramRegistry.fill(HIST("gen/delta_eta_pos_sq"), deltaEtaWidth, posGen * posGen); + histogramRegistry.fill(HIST("gen/delta_eta_neg_sq"), deltaEtaWidth, negGen * negGen); + histogramRegistry.fill(HIST("gen/delta_eta_posneg"), deltaEtaWidth, posNegGen); + histogramRegistry.fill(HIST("gen/delta_eta_nch"), deltaEtaWidth, nchGen); } // void SliceCache cache; Preslice mcTrack = o2::aod::mcparticle::mcCollisionId; + // process function for Data Run3 void processDataRun3(aod::MyCollisionRun3 const& coll, aod::MyTracks const& tracks) { calculationData(coll, tracks); + for (int ii = 0; ii < deltaEta; ii++) { + float etaMin = -0.1f * (ii + 1); + float etaMax = 0.1f * (ii + 1); + + calculationDeltaEta(coll, tracks, etaMin, etaMax); + } } PROCESS_SWITCH(NetchargeFluctuations, processDataRun3, "Process for Run3 DATA", true); + // process function for Data Run2 void processDataRun2(aod::MyCollisionRun2 const& coll, aod::MyTracks const& tracks) { calculationData(coll, tracks); + for (int ii = 0; ii < deltaEta; ii++) { + float etaMin = -0.1f * (ii + 1); // -0.1, -0.2, ..., -0.8 + float etaMax = 0.1f * (ii + 1); // +0.1, +0.2, ..., +0.8 + + calculationDeltaEta(coll, tracks, etaMin, etaMax); + } } PROCESS_SWITCH(NetchargeFluctuations, processDataRun2, "Process for Run2 DATA", false); + // process function for MC Run3 + void processMcRun3(aod::MyMCCollisionRun3 const& coll, aod::MyMCTracks const& inputTracks, aod::McCollisions const& mcCollisions, aod::McParticles const& mcParticles) { calculationMc(coll, inputTracks, mcCollisions, mcParticles); + for (int ii = 0; ii < deltaEta; ii++) { + float etaMin = -0.1f * (ii + 1); + float etaMax = 0.1f * (ii + 1); + calculationMcDeltaEta(coll, inputTracks, mcCollisions, mcParticles, etaMin, etaMax); + } } - PROCESS_SWITCH(NetchargeFluctuations, processMcRun3, "Process reconstructed", false); + // process function for MC Run2 + void processMcRun2(aod::MyMCCollisionRun2 const& coll, aod::MyMCTracks const& inputTracks, aod::McCollisions const& mcCollisions, aod::McParticles const& mcParticles) { calculationMc(coll, inputTracks, mcCollisions, mcParticles); + for (int ii = 0; ii < deltaEta; ii++) { + float etaMin = -0.1f * (ii + 1); + float etaMax = 0.1f * (ii + 1); + calculationMcDeltaEta(coll, inputTracks, mcCollisions, mcParticles, etaMin, etaMax); + } } PROCESS_SWITCH(NetchargeFluctuations, processMcRun2, "Process reconstructed", false); +}; -}; // struct - -struct NetchargeAnalysis { - Configurable cfSubSample{"cfSubSample", 30, "Number of subsamples"}; - HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; - std::vector>> net; - std::vector>> subSample; - std::vector>> genSubSample; - TRandom3* fRndm = new TRandom3(0); - - void init(o2::framework::InitContext&) - { - std::vector centBinning = {0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; - AxisSpec centAxis = {centBinning, "centrality"}; - - registry.add("data/pos_vs_cent", "", {HistType::kTProfile, {centAxis}}); - registry.add("data/neg_vs_cent", "", {HistType::kTProfile, {centAxis}}); - registry.add("data/termp_vs_cent", "", {HistType::kTProfile, {centAxis}}); - registry.add("data/termn_vs_cent", "", {HistType::kTProfile, {centAxis}}); - registry.add("data/pos_sq_vs_cent", "", {HistType::kTProfile, {centAxis}}); - registry.add("data/neg_sq_vs_cent", "", {HistType::kTProfile, {centAxis}}); - registry.add("data/posneg_vs_cent", "", {HistType::kTProfile, {centAxis}}); - - registry.add("gen/pos_vs_cent", "", {HistType::kTProfile, {centAxis}}); - registry.add("gen/neg_vs_cent", "", {HistType::kTProfile, {centAxis}}); - registry.add("gen/termp_vs_cent", "", {HistType::kTProfile, {centAxis}}); - registry.add("gen/termn_vs_cent", "", {HistType::kTProfile, {centAxis}}); - registry.add("gen/pos_sq_vs_cent", "", {HistType::kTProfile, {centAxis}}); - registry.add("gen/neg_sq_vs_cent", "", {HistType::kTProfile, {centAxis}}); - registry.add("gen/posneg_vs_cent", "", {HistType::kTProfile, {centAxis}}); - - subSample.resize(cfSubSample); - genSubSample.resize(cfSubSample); - - for (int i = 0; i < cfSubSample; ++i) { - subSample[i].resize(7); - genSubSample[i].resize(7); - - subSample[i][0] = std::get>(registry.add(Form("data/subSample_%d/pos_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); - subSample[i][1] = std::get>(registry.add(Form("data/subSample_%d/neg_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); - subSample[i][2] = std::get>(registry.add(Form("data/subSample_%d/termp_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); - subSample[i][3] = std::get>(registry.add(Form("data/subSample_%d/termn_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); - subSample[i][4] = std::get>(registry.add(Form("data/subSample_%d/pos_sq_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); - subSample[i][5] = std::get>(registry.add(Form("data/subSample_%d/neg_sq_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); - subSample[i][6] = std::get>(registry.add(Form("data/subSample_%d/posneg_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); - - genSubSample[i][0] = std::get>(registry.add(Form("gen/genSubSample_%d/pos_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); - genSubSample[i][1] = std::get>(registry.add(Form("gen/genSubSample_%d/neg_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); - genSubSample[i][2] = std::get>(registry.add(Form("gen/genSubSample_%d/termp_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); - genSubSample[i][3] = std::get>(registry.add(Form("gen/genSubSample_%d/termn_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); - genSubSample[i][4] = std::get>(registry.add(Form("gen/genSubSample_%d/pos_sq_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); - genSubSample[i][5] = std::get>(registry.add(Form("gen/genSubSample_%d/neg_sq_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); - genSubSample[i][6] = std::get>(registry.add(Form("gen/genSubSample_%d/posneg_vs_cent", i), "", {HistType::kTProfile, {centAxis}})); - } - - } // void - - void processData(aod::NetCharge::iterator const& event_netcharge) - { - registry.get(HIST("data/pos_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.posCharge()); - registry.get(HIST("data/neg_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.negCharge()); - registry.get(HIST("data/termp_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.termPCharge()); - registry.get(HIST("data/termn_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.termNCharge()); - registry.get(HIST("data/pos_sq_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.posSqCharge()); - registry.get(HIST("data/neg_sq_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.negSqCharge()); - registry.get(HIST("data/posneg_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.posNegCharge()); - - int sampleIndex = static_cast(cfSubSample * fRndm->Rndm()); - subSample[sampleIndex][0]->Fill(event_netcharge.centrality(), event_netcharge.posCharge()); - subSample[sampleIndex][1]->Fill(event_netcharge.centrality(), event_netcharge.negCharge()); - subSample[sampleIndex][2]->Fill(event_netcharge.centrality(), event_netcharge.termPCharge()); - subSample[sampleIndex][3]->Fill(event_netcharge.centrality(), event_netcharge.termNCharge()); - subSample[sampleIndex][4]->Fill(event_netcharge.centrality(), event_netcharge.posSqCharge()); - subSample[sampleIndex][5]->Fill(event_netcharge.centrality(), event_netcharge.negSqCharge()); - subSample[sampleIndex][6]->Fill(event_netcharge.centrality(), event_netcharge.posNegCharge()); - } // void - PROCESS_SWITCH(NetchargeAnalysis, processData, "Process reconstructed and Data", true); - - void processGen(aod::NetChargeGen::iterator const& event_netcharge) - { - registry.get(HIST("gen/pos_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.posCharge()); - registry.get(HIST("gen/neg_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.negCharge()); - registry.get(HIST("gen/termp_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.termPCharge()); - registry.get(HIST("gen/termn_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.termNCharge()); - registry.get(HIST("gen/pos_sq_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.posSqCharge()); - registry.get(HIST("gen/neg_sq_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.negSqCharge()); - registry.get(HIST("gen/posneg_vs_cent"))->Fill(event_netcharge.centrality(), event_netcharge.posNegCharge()); - - int sampleIndex = static_cast(cfSubSample * fRndm->Rndm()); - genSubSample[sampleIndex][0]->Fill(event_netcharge.centrality(), event_netcharge.posCharge()); - genSubSample[sampleIndex][1]->Fill(event_netcharge.centrality(), event_netcharge.negCharge()); - genSubSample[sampleIndex][2]->Fill(event_netcharge.centrality(), event_netcharge.termPCharge()); - genSubSample[sampleIndex][3]->Fill(event_netcharge.centrality(), event_netcharge.termNCharge()); - genSubSample[sampleIndex][4]->Fill(event_netcharge.centrality(), event_netcharge.posSqCharge()); - genSubSample[sampleIndex][5]->Fill(event_netcharge.centrality(), event_netcharge.negSqCharge()); - genSubSample[sampleIndex][6]->Fill(event_netcharge.centrality(), event_netcharge.posNegCharge()); - } // void - PROCESS_SWITCH(NetchargeAnalysis, processGen, "Process generated", true); - -}; // struct Netcharge_analysis - +// struct WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ - {adaptAnalysisTask(cfgc)}, - {adaptAnalysisTask(cfgc)} - - }; + {adaptAnalysisTask(cfgc)}}; } diff --git a/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx b/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx index 855ea4d58b9..f0ec5f81685 100644 --- a/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/v0ptHadPiKaProt.cxx @@ -87,9 +87,11 @@ struct V0ptHadPiKaProt { Configurable cfgCutEtaLeft{"cfgCutEtaLeft", 0.8f, "Left end of eta gap"}; Configurable cfgCutEtaRight{"cfgCutEtaRight", 0.8f, "Right end of eta gap"}; Configurable cfgNSubsample{"cfgNSubsample", 10, "Number of subsamples"}; - Configurable cfgCentralityChoice{"cfgCentralityChoice", 1, "Which centrality estimator? 0-->FT0M, 1-->FT0C"}; + Configurable cfgCentralityChoice{"cfgCentralityChoice", 1, "Which centrality estimator? 1-->FT0C, 2-->FT0A, 3-->FT0M, 4-->FV0A"}; Configurable cfgEvSelkNoSameBunchPileup{"cfgEvSelkNoSameBunchPileup", true, "Pileup removal"}; Configurable cfgUseGoodITSLayerAllCut{"cfgUseGoodITSLayerAllCut", true, "Remove time interval with dead ITS zone"}; + Configurable cfgEvSelkNoITSROFrameBorder{"cfgEvSelkNoITSROFrameBorder", true, "ITSROFrame border event selection cut"}; + Configurable cfgEvSelkNoTimeFrameBorder{"cfgEvSelkNoTimeFrameBorder", true, "TimeFrame border event selection cut"}; // Connect to ccdb Service ccdb; @@ -342,13 +344,23 @@ struct V0ptHadPiKaProt { if (cfgEvSelkNoSameBunchPileup && !(coll.selection_bit(o2::aod::evsel::kNoSameBunchPileup))) { return; } + if (cfgEvSelkNoITSROFrameBorder && !(coll.selection_bit(o2::aod::evsel::kNoITSROFrameBorder))) { + return; + } + if (cfgEvSelkNoTimeFrameBorder && !(coll.selection_bit(o2::aod::evsel::kNoTimeFrameBorder))) { + return; + } // Centrality double cent = 0.0; - if (cfgCentralityChoice == 0) - cent = coll.centFT0M(); - else if (cfgCentralityChoice == 1) + if (cfgCentralityChoice == 1) + cent = coll.centFT0C(); + else if (cfgCentralityChoice == 2) + cent = coll.centFT0A(); + else if (cfgCentralityChoice == 3) cent = coll.centFT0M(); + else if (cfgCentralityChoice == 4) + cent = coll.centFV0A(); histos.fill(HIST("hZvtx_after_sel"), coll.posZ()); histos.fill(HIST("hCentrality"), cent); @@ -483,7 +495,6 @@ struct V0ptHadPiKaProt { subSample[sampleIndex][0]->Fill(cent, fPtProfileHad->GetBinCenter(i + 1), (fPtProfileHad->GetBinContent(i + 1) / nSumEtaLeftHad)); subSample[sampleIndex][1]->Fill(cent, fPtProfileHad->GetBinCenter(i + 1), ((fPtProfileHad->GetBinContent(i + 1) / nSumEtaLeftHad) * (pTsumEtaRightHad / nSumEtaRightHad))); subSample[sampleIndex][2]->Fill(cent, 0.5, ((pTsumEtaLeftHad / nSumEtaLeftHad) * (pTsumEtaRightHad / nSumEtaRightHad))); - ; subSample[sampleIndex][3]->Fill(cent, 0.5, (pTsumEtaLeftHad / nSumEtaLeftHad)); subSample[sampleIndex][4]->Fill(cent, 0.5, (pTsumEtaRightHad / nSumEtaRightHad)); } @@ -500,7 +511,6 @@ struct V0ptHadPiKaProt { subSample[sampleIndex][5]->Fill(cent, fPtProfilePi->GetBinCenter(i + 1), (fPtProfilePi->GetBinContent(i + 1) / nSumEtaLeftPi)); subSample[sampleIndex][6]->Fill(cent, fPtProfilePi->GetBinCenter(i + 1), ((fPtProfilePi->GetBinContent(i + 1) / nSumEtaLeftPi) * (pTsumEtaRightHad / nSumEtaRightHad))); subSample[sampleIndex][7]->Fill(cent, 0.5, ((pTsumEtaLeftHad / nSumEtaLeftHad) * (pTsumEtaRightHad / nSumEtaRightHad))); - ; subSample[sampleIndex][8]->Fill(cent, 0.5, (pTsumEtaLeftHad / nSumEtaLeftHad)); subSample[sampleIndex][9]->Fill(cent, 0.5, (pTsumEtaRightHad / nSumEtaRightHad)); } @@ -517,7 +527,6 @@ struct V0ptHadPiKaProt { subSample[sampleIndex][10]->Fill(cent, fPtProfileKa->GetBinCenter(i + 1), (fPtProfileKa->GetBinContent(i + 1) / nSumEtaLeftKa)); subSample[sampleIndex][11]->Fill(cent, fPtProfileKa->GetBinCenter(i + 1), ((fPtProfileKa->GetBinContent(i + 1) / nSumEtaLeftKa) * (pTsumEtaRightHad / nSumEtaRightHad))); subSample[sampleIndex][12]->Fill(cent, 0.5, ((pTsumEtaLeftHad / nSumEtaLeftHad) * (pTsumEtaRightHad / nSumEtaRightHad))); - ; subSample[sampleIndex][13]->Fill(cent, 0.5, (pTsumEtaLeftHad / nSumEtaLeftHad)); subSample[sampleIndex][14]->Fill(cent, 0.5, (pTsumEtaRightHad / nSumEtaRightHad)); } @@ -533,7 +542,6 @@ struct V0ptHadPiKaProt { subSample[sampleIndex][15]->Fill(cent, fPtProfileProt->GetBinCenter(i + 1), (fPtProfileProt->GetBinContent(i + 1) / nSumEtaLeftProt)); subSample[sampleIndex][16]->Fill(cent, fPtProfileProt->GetBinCenter(i + 1), ((fPtProfileProt->GetBinContent(i + 1) / nSumEtaLeftProt) * (pTsumEtaRightHad / nSumEtaRightHad))); subSample[sampleIndex][17]->Fill(cent, 0.5, ((pTsumEtaLeftHad / nSumEtaLeftHad) * (pTsumEtaRightHad / nSumEtaRightHad))); - ; subSample[sampleIndex][18]->Fill(cent, 0.5, (pTsumEtaLeftHad / nSumEtaLeftHad)); subSample[sampleIndex][19]->Fill(cent, 0.5, (pTsumEtaRightHad / nSumEtaRightHad)); } diff --git a/PWGCF/Femto/TableProducer/PiDeuteronFemto.cxx b/PWGCF/Femto/TableProducer/PiDeuteronFemto.cxx index 4988e4d1068..6eaf78e8036 100644 --- a/PWGCF/Femto/TableProducer/PiDeuteronFemto.cxx +++ b/PWGCF/Femto/TableProducer/PiDeuteronFemto.cxx @@ -230,6 +230,7 @@ struct PiDeuteronFemto { {"hEmptyPool", "svPoolCreator did not find track pairs false/true", {HistType::kTH1F, {{2, -0.5, 1.5}}}}, {"hdcaxyDe", ";DCA_{xy} (cm)", {HistType::kTH1F, {{200, -1.0f, 1.0f}}}}, {"hdcazDe", ";DCA_{z} (cm)", {HistType::kTH1F, {{200, -1.0f, 1.0f}}}}, + {"hdcazDe_min", ";DCA_{z}-min (cm)", {HistType::kTH1F, {{20, -1.0f, 1.0f}}}}, {"hNClsDeITS", ";N_{ITS} Cluster", {HistType::kTH1F, {{20, -10.0f, 10.0f}}}}, {"hNClsPiITS", ";N_{ITS} Cluster", {HistType::kTH1F, {{20, -10.0f, 10.0f}}}}, {"hDePitInvMass", "; M(De + p) (GeV/#it{c}^{2})", {HistType::kTH1F, {{300, 3.74f, 4.34f}}}}, @@ -403,13 +404,10 @@ struct PiDeuteronFemto { mQaRegistry.fill(HIST("h2NsigmaPiTPC_preselection"), candidate.tpcInnerParam(), tpcNSigmaPi); if (std::abs(candidate.pt()) < settingCutPiptMin || std::abs(candidate.pt()) > settingCutPiptMax) return false; - if (candidate.hasTOF() && candidate.tpcInnerParam() > settingCutPinMinTOFPi) { + if (candidate.hasTOF() && candidate.tpcInnerParam() >= settingCutPinMinTOFPi) { auto tofNSigmaPi = candidate.tofNSigmaPi(); auto combNsigma = std::sqrt(tofNSigmaPi * tofNSigmaPi + tpcNSigmaPi * tpcNSigmaPi); - if (std::abs(tpcNSigmaPi) > settingCutNsigmaTPCPi) { - return false; - } mQaRegistry.fill(HIST("h2NsigmaPiTOF_preselection"), candidate.pt(), tofNSigmaPi); if (combNsigma > settingCutNsigmaTOFTPCPi) { return false; @@ -418,7 +416,10 @@ struct PiDeuteronFemto { mQaRegistry.fill(HIST("h2NsigmaPiTOF"), candidate.sign() * candidate.pt(), tofNSigmaPi); mQaRegistry.fill(HIST("h2NsigmaPiComb"), candidate.sign() * candidate.pt(), combNsigma); return true; - } else if (std::abs(tpcNSigmaPi) < settingCutNsigmaTPCPi) { + } else if (candidate.tpcInnerParam() < settingCutPinMinTOFPi) { + if (std::abs(tpcNSigmaPi) > settingCutNsigmaTPCPi) { + return false; + } mQaRegistry.fill(HIST("h2NsigmaPiTPC"), candidate.sign() * candidate.pt(), tpcNSigmaPi); return true; } @@ -464,8 +465,10 @@ struct PiDeuteronFemto { mQaRegistry.fill(HIST("h2NsigmaDeTPC"), candidate.sign() * candidate.pt(), tpcNSigmaDe); mQaRegistry.fill(HIST("h2NsigmaDeTOF"), candidate.sign() * candidate.pt(), tofNSigmaDe); return true; - } else if (std::abs(tpcNSigmaDe) < settingCutNsigmaTPCDe) { - + } else if (candidate.tpcInnerParam() <= settingCutPinMinTOFITSDe) { + if (std::abs(tpcNSigmaDe) > settingCutNsigmaTPCDe) { + return false; + } o2::aod::ITSResponse mResponseITS; auto itsnSigmaDe = mResponseITS.nSigmaITS(candidate.itsClusterSizes(), candidate.p(), candidate.eta()); mQaRegistry.fill(HIST("h2NSigmaDeITS_preselection"), candidate.sign() * candidate.pt(), itsnSigmaDe); @@ -719,6 +722,7 @@ struct PiDeuteronFemto { mQaRegistry.fill(HIST("hDePitInvMass"), piDecand.invMass); mQaRegistry.fill(HIST("hdcaxyDe"), piDecand.dcaxyDe); mQaRegistry.fill(HIST("hdcazDe"), piDecand.dcazDe); + mQaRegistry.fill(HIST("hdcazDe_min"), (abs(piDecand.dcazDe) - settingCutDeDCAzMin)); mQaRegistry.fill(HIST("hNClsDeITS"), piDecand.nClsItsDe); mQaRegistry.fill(HIST("hNClsPiITS"), piDecand.nClsItsPi); mQaRegistry.fill(HIST("hisBkgEM"), piDecand.isBkgEM); @@ -781,7 +785,6 @@ struct PiDeuteronFemto { float DeDCAxyMin = 0.015 + 0.0305 / TMath::Power(piDecand.recoPtDe(), 1.1); if (abs(piDecand.dcaxyDe) > DeDCAxyMin || abs(piDecand.dcazDe) > settingCutDeDCAzMin || abs(piDecand.dcaxyPi) > settingCutPiDCAxyMin || abs(piDecand.dcazPi) > settingCutPiDCAzMin) return; - fillHistograms(piDecand); double kstar = computeKstar(piDecand); diff --git a/PWGCF/Femto3D/DataModel/singletrackselector.h b/PWGCF/Femto3D/DataModel/singletrackselector.h index c7323d15a32..d7f4f0822d3 100644 --- a/PWGCF/Femto3D/DataModel/singletrackselector.h +++ b/PWGCF/Femto3D/DataModel/singletrackselector.h @@ -135,7 +135,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(dIsGoodZvtxFT0vsPV, isGoodZvtxFT0vsPV, [](uint64_t se DECLARE_SOA_DYNAMIC_COLUMN(dIsVertexITSTPC, isVertexITSTPC, [](uint64_t selBit) -> bool { return TESTBIT(selBit, evsel::kIsVertexITSTPC); }); DECLARE_SOA_DYNAMIC_COLUMN(dIsVertexTOForTRDmatched, isVertexTOForTRDmatched, [](uint64_t selBit) -> int { return static_cast(TESTBIT(selBit, evsel::kIsVertexTOFmatched)) + static_cast(TESTBIT(selBit, evsel::kIsVertexTRDmatched)); }); DECLARE_SOA_DYNAMIC_COLUMN(dNoCollInTimeRangeStandard, noCollInTimeRangeStandard, [](uint64_t selBit) -> bool { return TESTBIT(selBit, evsel::kNoCollInTimeRangeStandard); }); - +DECLARE_SOA_DYNAMIC_COLUMN(dIsGoodITSLayersAll, isGoodITSLayersAll, [](uint64_t selBit) -> bool { return TESTBIT(selBit, evsel::kIsGoodITSLayersAll); }); } // namespace singletrackselector DECLARE_SOA_TABLE(SingleCollSels, "AOD", "SINGLECOLLSEL", // Table of the variables for single track selection. @@ -154,7 +154,8 @@ DECLARE_SOA_TABLE(SingleCollExtras_v1, "AOD", "SINGLECOLLEXTR1", // Joinable col singletrackselector::dIsGoodZvtxFT0vsPV, singletrackselector::dIsVertexITSTPC, singletrackselector::dIsVertexTOForTRDmatched, - singletrackselector::dNoCollInTimeRangeStandard); + singletrackselector::dNoCollInTimeRangeStandard, + singletrackselector::dIsGoodITSLayersAll); using SingleCollExtras = SingleCollExtras_v1; diff --git a/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx b/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx index 83aa740795c..db6c12dc14c 100644 --- a/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx +++ b/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx @@ -55,6 +55,7 @@ struct FemtoCorrelations { Configurable _requestVertexITSTPC{"requestVertexITSTPC", false, ""}; Configurable _requestVertexTOForTRDmatched{"requestVertexTOFmatched", 0, "0 -> no selectio; 1 -> vertex is matched to TOF or TRD; 2 -> matched to both;"}; Configurable _requestNoCollInTimeRangeStandard{"requestNoCollInTimeRangeStandard", false, ""}; + Configurable _requestIsGoodITSLayersAll{"requestIsGoodITSLayersAll", false, "cut time intervals with dead ITS staves"}; Configurable> _IRcut{"IRcut", std::pair{0.f, 100.f}, "[min., max.] IR range to keep events within"}; Configurable> _OccupancyCut{"OccupancyCut", std::pair{0, 10000}, "[min., max.] occupancy range to keep events within"}; @@ -423,6 +424,8 @@ struct FemtoCorrelations { continue; if (_requestNoCollInTimeRangeStandard && !track.template singleCollSel_as>().noCollInTimeRangeStandard()) continue; + if (_requestIsGoodITSLayersAll && !track.template singleCollSel_as>().isGoodITSLayersAll()) + continue; if (track.tpcFractionSharedCls() > _tpcFractionSharedCls || track.itsNCls() < _itsNCls) continue; if (track.template singleCollSel_as>().multPerc() < *_centBins.value.begin() || track.template singleCollSel_as>().multPerc() >= *(_centBins.value.end() - 1)) @@ -473,7 +476,8 @@ struct FemtoCorrelations { continue; if (_requestNoCollInTimeRangeStandard && !collision.noCollInTimeRangeStandard()) continue; - + if (_requestIsGoodITSLayersAll && !collision.isGoodITSLayersAll()) + continue; if (selectedtracks_1.find(collision.globalIndex()) == selectedtracks_1.end()) { if (IsIdentical) continue; diff --git a/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx b/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx index b776d34e629..252fb5fc410 100644 --- a/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx +++ b/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx @@ -51,6 +51,7 @@ struct FemtoCorrelationsMC { Configurable _requestVertexITSTPC{"requestVertexITSTPC", false, ""}; Configurable _requestVertexTOForTRDmatched{"requestVertexTOFmatched", 0, "0 -> no selectio; 1 -> vertex is matched to TOF or TRD; 2 -> matched to both;"}; Configurable _requestNoCollInTimeRangeStandard{"requestNoCollInTimeRangeStandard", false, ""}; + Configurable _requestIsGoodITSLayersAll{"requestIsGoodITSLayersAll", false, "cut time intervals with dead ITS staves"}; Configurable> _IRcut{"IRcut", std::pair{0.f, 100.f}, "[min., max.] IR range to keep events within"}; Configurable> _OccupancyCut{"OccupancyCut", std::pair{0, 10000}, "[min., max.] occupancy range to keep events within"}; @@ -350,7 +351,8 @@ struct FemtoCorrelationsMC { continue; if (_requestNoCollInTimeRangeStandard && !track.template singleCollSel_as>().noCollInTimeRangeStandard()) continue; - + if (_requestIsGoodITSLayersAll && !track.template singleCollSel_as>().isGoodITSLayersAll()) + continue; unsigned int centBin = o2::aod::singletrackselector::getBinIndex(track.template singleCollSel_as>().multPerc(), _centBins); if (track.sign() == _sign_1 && (track.p() < _PIDtrshld_1 ? o2::aod::singletrackselector::TPCselection(track, TPCcuts_1, _itsNSigma_1.value) : o2::aod::singletrackselector::TOFselection(track, TOFcuts_1, _tpcNSigmaResidual_1.value))) { @@ -412,7 +414,8 @@ struct FemtoCorrelationsMC { continue; if (_requestNoCollInTimeRangeStandard && !collision.noCollInTimeRangeStandard()) continue; - + if (_requestIsGoodITSLayersAll && !collision.isGoodITSLayersAll()) + continue; if (selectedtracks_1.find(collision.globalIndex()) == selectedtracks_1.end()) { if (IsIdentical) continue; diff --git a/PWGCF/Femto3D/Tasks/femto3dQA.cxx b/PWGCF/Femto3D/Tasks/femto3dQA.cxx index 64858324b48..b31f3cd970e 100644 --- a/PWGCF/Femto3D/Tasks/femto3dQA.cxx +++ b/PWGCF/Femto3D/Tasks/femto3dQA.cxx @@ -52,6 +52,7 @@ struct QAHistograms { Configurable _requestVertexITSTPC{"requestVertexITSTPC", false, ""}; Configurable _requestVertexTOForTRDmatched{"requestVertexTOFmatched", 0, "0 -> no selectio; 1 -> vertex is matched to TOF or TRD; 2 -> matched to both;"}; Configurable _requestNoCollInTimeRangeStandard{"requestNoCollInTimeRangeStandard", false, ""}; + Configurable _requestIsGoodITSLayersAll{"requestIsGoodITSLayersAll", false, "cut time intervals with dead ITS staves"}; Configurable> _IRcut{"IRcut", std::pair{0.f, 100.f}, "[min., max.] IR range to keep events within"}; Configurable> _OccupancyCut{"OccupancyCut", std::pair{0, 10000}, "[min., max.] occupancy range to keep events within"}; @@ -181,6 +182,8 @@ struct QAHistograms { continue; if (_requestNoCollInTimeRangeStandard && !collision.noCollInTimeRangeStandard()) continue; + if (_requestIsGoodITSLayersAll && !collision.isGoodITSLayersAll()) + continue; if (collision.multPerc() < _centCut.value.first || collision.multPerc() >= _centCut.value.second) continue; if (collision.hadronicRate() < _IRcut.value.first || collision.hadronicRate() >= _IRcut.value.second) @@ -206,7 +209,8 @@ struct QAHistograms { continue; if (_requestNoCollInTimeRangeStandard && !track.template singleCollSel_as().noCollInTimeRangeStandard()) continue; - + if (_requestIsGoodITSLayersAll && !track.template singleCollSel_as().isGoodITSLayersAll()) + continue; if (std::fabs(track.template singleCollSel_as().posZ()) > _vertexZ) continue; if (track.template singleCollSel_as().multPerc() < _centCut.value.first || track.template singleCollSel_as().multPerc() >= _centCut.value.second) diff --git a/PWGCF/FemtoDream/Core/femtoDreamContainer.h b/PWGCF/FemtoDream/Core/femtoDreamContainer.h index 5e0222a4f07..3d95fc08311 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamContainer.h +++ b/PWGCF/FemtoDream/Core/femtoDreamContainer.h @@ -202,10 +202,12 @@ class FemtoDreamContainer { const float kT = FemtoDreamMath::getkT(part1, mMassOne, part2, mMassTwo); if constexpr (isHF) { - float mP2; - if (part2.candidateSelFlag() == o2::aod::fdhf::lcToPKPi) { + float mP2 = 0.0; + if (part2.candidateSelFlag() == o2::aod::fdhf::dplusToPiKPi) { + mP2 = part2.m(std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); + } else if (part2.candidateSelFlag() == o2::aod::fdhf::lcToPKPi) { mP2 = part2.m(std::array{o2::constants::physics::MassProton, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); - } else { + } else if (part2.candidateSelFlag() == o2::aod::fdhf::lcToPiKP) { mP2 = part2.m(std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus, o2::constants::physics::MassProton}); } mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/relPairkstarmP2"), femtoObs, mP2); diff --git a/PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h b/PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h index 58dc6c9ded4..7dadb08df78 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h +++ b/PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h @@ -16,11 +16,13 @@ #ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMDETADPHISTAR_H_ #define PWGCF_FEMTODREAM_CORE_FEMTODREAMDETADPHISTAR_H_ +#include "PWGCF/DataModel/FemtoDerived.h" + +#include "Framework/HistogramRegistry.h" + #include #include #include -#include "PWGCF/DataModel/FemtoDerived.h" -#include "Framework/HistogramRegistry.h" using namespace o2; using namespace o2::framework; @@ -98,6 +100,24 @@ class FemtoDreamDetaDphiStar } } } + if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kV0 && mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kV0) { + for (int i = 0; i < 4; i++) { + std::string dirName = static_cast(dirNames[1]); + histdetadpi[i][0] = mHistogramRegistry->add((dirName + static_cast(histNames[0][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][1] = mHistogramRegistry->add((dirName + static_cast(histNames[1][i]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][2] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_before" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpi[i][3] = mHistogramRegistry->add((dirName + "at_PV_" + std::to_string(i) + "_after" + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + if (plotForEveryRadii) { + for (int j = 0; j < 9; j++) { + histdetadpiRadii[i][j] = mHistogramRegistryQA->add((dirName + static_cast(histNamesRadii[i][j]) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + } + } + if (fillQA) { + histdetadpi_eta[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Eta_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #eta_{1}; #eta_{2}", kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, -0.8, 0.8}, {100, -0.8, 0.8}}); + histdetadpi_phi[i] = mHistogramRegistry->add((dirName + "dEtadPhi_Phi_" + std::to_string(i) + static_cast(histNameSEorME[meORse])).c_str(), "; #Delta #eta; #Delta #phi^{*}; #phi_{1}; #phi_{2}", kTHnSparseF, {{100, -0.15, 0.15}, {100, -0.15, 0.15}, {100, 0, 6.28}, {100, 0, 6.28}}); + } + } + } if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCharmHadron) { for (int i = 0; i < Nprongs; i++) { std::string dirName = static_cast(dirNames[2]); @@ -293,6 +313,86 @@ class FemtoDreamDetaDphiStar } } } + return pass; + } else if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kV0 && mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kV0) { + /// V0-V0 combination + // check if provided particles are in agreement with the class instantiation + if (part1.partType() != o2::aod::femtodreamparticle::ParticleType::kV0 || part2.partType() != o2::aod::femtodreamparticle::ParticleType::kV0) { + LOG(fatal) << "FemtoDreamDetaDphiStar: passed arguments don't agree with FemtoDreamDetaDphiStar instantiation! Please provide kV0,kV0 candidates."; + return false; + } + + bool pass = false; + int nhist = 0; + for (int i = 0; i < 2; i++) { + int indexOfDaughterPart1, indexOfDaughterPart2; + for (int j = 0; j < 2; j++) { + if (isMixedEventLambda) { + indexOfDaughterPart1 = part1.globalIndex() - 2 + i; + indexOfDaughterPart2 = part2.globalIndex() - 2 + j; + } else { + indexOfDaughterPart1 = part1.index() - 2 + i; + indexOfDaughterPart2 = part2.index() - 2 + j; + } + + auto daughterPart1 = particles.begin() + indexOfDaughterPart1; + auto daughterPart2 = particles.begin() + indexOfDaughterPart2; + auto deta = daughterPart1.eta() - daughterPart2.eta(); + auto dphi_AT_PV = daughterPart1.phi() - daughterPart2.phi(); + auto dphi_AT_SpecificRadii = PhiAtSpecificRadiiTPC(daughterPart1, radiiTPC) - PhiAtSpecificRadiiTPC(daughterPart2, radiiTPC); + bool sameCharge = false; + auto dphiAvg = AveragePhiStar(*daughterPart1, *daughterPart2, nhist, &sameCharge); + if (Q3 == 999) { + histdetadpi[nhist][0]->Fill(deta, dphiAvg); + histdetadpi[nhist][2]->Fill(deta, dphi_AT_PV); + if (fillQA) { + histdetadpi_eta[nhist]->Fill(deta, dphiAvg, daughterPart1.eta(), daughterPart2.eta()); + histdetadpi_phi[nhist]->Fill(deta, dphiAvg, daughterPart1.phi(), daughterPart2.phi()); + } + } + if (sameCharge) { + if (atWhichRadiiToSelect == 1) { + if (pow(dphiAvg, 2) / pow(deltaPhiMax, 2) + pow(deta, 2) / pow(deltaEtaMax, 2) < 1.) { + pass = true; + } else { + if (Q3 == 999) { + histdetadpi[nhist][1]->Fill(deta, dphiAvg); + histdetadpi[nhist][3]->Fill(deta, dphi_AT_PV); + } else if (Q3 < upperQ3LimitForPlotting) { + histdetadpi[nhist][1]->Fill(deta, dphiAvg); + histdetadpi[nhist][3]->Fill(deta, dphi_AT_PV); + } + } + } else if (atWhichRadiiToSelect == 0) { + if (pow(dphi_AT_PV, 2) / pow(deltaPhiMax, 2) + pow(deta, 2) / pow(deltaEtaMax, 2) < 1.) { + pass = true; + } else { + if (Q3 == 999) { + histdetadpi[nhist][1]->Fill(deta, dphiAvg); + histdetadpi[nhist][3]->Fill(deta, dphi_AT_PV); + } else if (Q3 < upperQ3LimitForPlotting) { + histdetadpi[nhist][1]->Fill(deta, dphiAvg); + histdetadpi[nhist][3]->Fill(deta, dphi_AT_PV); + } + } + } else if (atWhichRadiiToSelect == 2) { + if (pow(dphi_AT_SpecificRadii, 2) / pow(deltaPhiMax, 2) + pow(deta, 2) / pow(deltaEtaMax, 2) < 1.) { + pass = true; + } else { + if (Q3 == 999) { + histdetadpi[nhist][1]->Fill(deta, dphiAvg); + histdetadpi[nhist][3]->Fill(deta, dphi_AT_PV); + } else if (Q3 < upperQ3LimitForPlotting) { + histdetadpi[nhist][1]->Fill(deta, dphiAvg); + histdetadpi[nhist][3]->Fill(deta, dphi_AT_PV); + } + } + } + } + nhist += 1; + } + } + return pass; } else if constexpr (mPartOneType == o2::aod::femtodreamparticle::ParticleType::kTrack && mPartTwoType == o2::aod::femtodreamparticle::ParticleType::kCharmHadron) { // check if provided particles are in agreement with the class instantiation diff --git a/PWGCF/FemtoDream/Core/femtoDreamUtils.h b/PWGCF/FemtoDream/Core/femtoDreamUtils.h index c5db8dcc70e..f9bb60633f3 100644 --- a/PWGCF/FemtoDream/Core/femtoDreamUtils.h +++ b/PWGCF/FemtoDream/Core/femtoDreamUtils.h @@ -52,6 +52,9 @@ inline float getMass(int pdgCode) case o2::constants::physics::Pdg::kPhi: mass = o2::constants::physics::MassPhi; break; + case o2::constants::physics::Pdg::kDPlus: + mass = o2::constants::physics::MassDPlus; + break; case o2::constants::physics::Pdg::kLambdaCPlus: mass = o2::constants::physics::MassLambdaCPlus; break; diff --git a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx index 7272382f357..0e190295508 100644 --- a/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx @@ -13,39 +13,45 @@ /// \brief Tasks that produces the track tables used for the pairing /// \author Laura Serksnyte, TU München, laura.serksnyte@tum.de -#include -#include -#include -#include +#include "PWGCF/DataModel/FemtoDerived.h" +#include "PWGCF/FemtoDream/Core/femtoDreamCascadeSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" +#include "PWGCF/FemtoDream/Core/femtoDreamV0Selection.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + #include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/Centrality.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/PIDResponseITS.h" #include "Common/DataModel/TrackSelectionTables.h" +#include "EventFiltering/Zorro.h" + #include "DataFormatsParameters/GRPMagField.h" #include "DataFormatsParameters/GRPObject.h" -#include "PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h" -#include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" -#include "PWGCF/FemtoDream/Core/femtoDreamV0Selection.h" -#include "PWGCF/FemtoDream/Core/femtoDreamCascadeSelection.h" -#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "EventFiltering/Zorro.h" -#include "PWGCF/DataModel/FemtoDerived.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" #include "ReconstructionDataFormats/Track.h" -#include "TMath.h" +#include + #include "Math/Vector4D.h" +#include "TMath.h" + +#include + +#include +#include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::aod::rctsel; using namespace o2::analysis::femtoDream; namespace o2::aod @@ -205,6 +211,12 @@ struct femtoDreamProducerTask { } OptionTrackSpecialSelections; + struct : o2::framework::ConfigurableGroup { + Configurable requireRCTFlagChecker{"requireRCTFlagChecker", false, "Check event quality in run condition table"}; + Configurable cfgEvtRCTFlagCheckerLabel{"cfgEvtRCTFlagCheckerLabel", "CBT_hadronPID", "Evt sel: RCT flag checker label"}; + Configurable cfgEvtRCTFlagCheckerLimitAcceptAsBad{"cfgEvtRCTFlagCheckerLimitAcceptAsBad", true, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"}; + } rctCut; + HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry TrackRegistry{"Tracks", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry V0Registry{"V0", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -214,6 +226,7 @@ struct femtoDreamProducerTask { float mMagField; std::string zorroTriggerNames = ""; Service ccdb; /// Accessing the CCDB + RCTFlagsChecker rctChecker; void init(InitContext&) { @@ -255,6 +268,8 @@ struct femtoDreamProducerTask { zorroTriggerNames.pop_back(); } + rctChecker.init(rctCut.cfgEvtRCTFlagCheckerLabel, false, rctCut.cfgEvtRCTFlagCheckerLimitAcceptAsBad); + colCuts.setCuts(ConfEvtZvtx.value, ConfEvtTriggerCheck.value, ConfEvtTriggerSel.value, ConfEvtOfflineCheck.value, ConfEvtAddOfflineCheck.value, ConfIsRun3.value); colCuts.init(&qaRegistry); @@ -568,6 +583,7 @@ struct femtoDreamProducerTask { if (!colCuts.isSelectedCollision(col)) { return; } + if (ConfIsActivateV0.value) { if (colCuts.isEmptyCollision(col, tracks, trackCuts) && colCuts.isEmptyCollision(col, fullV0s, v0Cuts, tracks)) { return; @@ -578,6 +594,10 @@ struct femtoDreamProducerTask { } } + if (rctCut.requireRCTFlagChecker && !rctChecker(col)) { + return; + } + outputCollision(vtxZ, mult, multNtr, spher, mMagField); if constexpr (isMC) { fillMCCollision(col); diff --git a/PWGCF/FemtoDream/Tasks/CMakeLists.txt b/PWGCF/FemtoDream/Tasks/CMakeLists.txt index 3341346bb24..933d50035a9 100644 --- a/PWGCF/FemtoDream/Tasks/CMakeLists.txt +++ b/PWGCF/FemtoDream/Tasks/CMakeLists.txt @@ -19,11 +19,6 @@ o2physics_add_dpl_workflow(femtodream-triplet-track-track-track PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(femtodream-triplet-track-track-track-pb-pb - SOURCES femtoDreamTripletTaskTrackTrackTrackPbPb.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(femtodream-pair-track-v0 SOURCES femtoDreamPairTaskTrackV0.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore @@ -59,12 +54,12 @@ o2physics_add_dpl_workflow(femtodream-collision-masker PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(femtodream-pair-efficiency - SOURCES femtoDreamPairEfficiency.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(femtodream-hash SOURCES femtoDreamHashTask.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(femtodream-pair-v0-v0 + SOURCES femtoDreamPairTaskV0V0.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskV0V0.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskV0V0.cxx new file mode 100644 index 00000000000..21be57205e3 --- /dev/null +++ b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskV0V0.cxx @@ -0,0 +1,426 @@ +// Copyright 2019-2025 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file femtoDreamPairTaskV0V0.cxx +/// \brief Tasks that reads the track tables used for the pairing and builds pairs of two tracks +/// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de +/// \author Georgios Mantzaridis, TU München, georgios.mantzaridis@tum.de +/// \author Anton Riedel, TU München, anton.riedel@tum.de +/// \author Bianca Popa, TU München, bianca.popa@tum.de + +#include "PWGCF/DataModel/FemtoDerived.h" +#include "PWGCF/FemtoDream/Core/femtoDreamContainer.h" +#include "PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h" +#include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" +#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" + +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/Configurable.h" +#include "Framework/Expressions.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" + +#include "TRandom3.h" + +#include +#include +#include +#include + +using namespace o2::aod; +using namespace o2::soa; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::analysis::femtoDream; + +struct femtoDreamPairTaskV0V0 { + SliceCache cache; + Preslice perCol = aod::femtodreamparticle::fdCollisionId; + + /// General options + struct : ConfigurableGroup { + std::string prefix = std::string("Option"); + Configurable IsMC{"IsMC", false, "Enable additional Histogramms in the case of runninger over Monte Carlo"}; + Configurable Use4D{"Use4D", false, "Enable four dimensional histogramms (to be used only for analysis with high statistics): k* vs multiplicity vs multiplicity percentil vs mT"}; + Configurable ExtendedPlots{"ExtendedPlots", false, "Enable additional three dimensional histogramms. High memory consumption. Use for debugging"}; + Configurable HighkstarCut{"HighkstarCut", -1., "Set a cut for high k*, above which the pairs are rejected. Set it to -1 to deactivate it"}; + Configurable SameSpecies{"SameSpecies", true, "Set to true if particle 1 and particle 2 are the same species"}; + Configurable MixEventWithPairs{"MixEventWithPairs", false, "Only use events that contain particle 1 and partile 2 for the event mixing"}; + Configurable RandomizePair{"RandomizePair", false, "Randomly mix particle 1 and particle 2 in case both are identical"}; + Configurable CPROn{"CPROn", true, "Close Pair Rejection"}; + Configurable CPROld{"CPROld", false, "Set to FALSE to use fixed version of CPR (for testing now, will be default soon)"}; + Configurable CPRSepMeSe{"CPRSepMESE", true, "Use seperated plots for same and mixed event for CPR plots"}; + Configurable CPRPlotPerRadii{"CPRPlotPerRadii", false, "Plot CPR per radii"}; + Configurable CPRdeltaPhiMax{"CPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; + Configurable CPRdeltaEtaMax{"CPRdeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; + Configurable DCACutPtDep{"DCACutPtDep", false, "Use pt dependent dca cut"}; + Configurable SmearingByOrigin{"SmearingByOrigin", false, "Obtain the smearing matrix differential in the MC origin of particle 1 and particle 2. High memory consumption"}; + ConfigurableAxis Dummy{"Dummy", {1, 0, 1}, "Dummy axis"}; + } Option; + + /// Event selection + struct : ConfigurableGroup { + std::string prefix = std::string("EventSel"); + Configurable MultMin{"MultMin", 0, "Minimum Multiplicity (MultNtr)"}; + Configurable MultMax{"MultMax", 99999, "Maximum Multiplicity (MultNtr)"}; + Configurable MultPercentileMin{"MultPercentileMin", 0, "Maximum Multiplicity Percentile"}; + Configurable MultPercentileMax{"MultPercentileMax", 100, "Minimum Multiplicity Percentile"}; + } EventSel; + + Filter EventMultiplicity = aod::femtodreamcollision::multNtr >= EventSel.MultMin && aod::femtodreamcollision::multNtr <= EventSel.MultMax; + Filter EventMultiplicityPercentile = aod::femtodreamcollision::multV0M >= EventSel.MultPercentileMin && aod::femtodreamcollision::multV0M <= EventSel.MultPercentileMax; + + using FilteredCollisions = soa::Filtered; + using FilteredCollision = FilteredCollisions::iterator; + using FilteredMCCollisions = soa::Filtered>; + using FilteredMCCollision = FilteredMCCollisions::iterator; + + using FilteredMaskedCollisions = soa::Filtered>; + using FilteredMaskedCollision = FilteredMaskedCollisions::iterator; + using FilteredMaskedMCCollisions = soa::Filtered>; + using FilteredMaskedMCCollision = FilteredMaskedMCCollisions::iterator; + + femtodreamcollision::BitMaskType BitMask = 0; + + /// Particle 1 (V0) + struct : ConfigurableGroup { + std::string prefix = std::string("V01"); + Configurable PDGCode{"PDGCode", 3122, "PDG code of particle 1 (V0)"}; + Configurable CutBit{"CutBit", 7518, "Selection bit for particle 1 (V0)"}; + Configurable ChildPos_CutBit{"ChildPos_CutBit", 210, "Selection bit for positive child of V0"}; + Configurable ChildPos_TPCBit{"ChildPos_TPCBit", 64, "PID TPC bit for positive child of V0"}; + Configurable ChildNeg_CutBit{"ChildNeg_CutBit", 209, "Selection bit for negative child of V0"}; + Configurable ChildNeg_TPCBit{"ChildNeg_TPCBit", 256, "PID TPC bit for negative child of V0"}; + + Configurable InvMassMin{"InvMassMin", 1.08, "Minimum invariant mass of Partricle 1 (particle) (V0)"}; + Configurable InvMassMax{"InvMassMax", 1.15, "Maximum invariant mass of Partricle 1 (particle) (V0)"}; + Configurable InvMassAntiMin{"InvMassAntiMin", 0., "Minimum invariant mass of Partricle 1 (antiparticle) (V0)"}; + Configurable InvMassAntiMax{"InvMassAntiMax", 999., "Maximum invariant mass of Partricle 1 (antiparticle) (V0)"}; + + Configurable PtMin{"PtMin", 0., "Minimum pT of Partricle 1 (V0)"}; + Configurable PtMax{"PtMax", 999., "Maximum pT of Partricle 1 (V0)"}; + Configurable EtaMin{"EtaMin", -10., "Minimum eta of Partricle 1 (V0)"}; + Configurable EtaMax{"EtaMax", 10., "Maximum eta of Partricle 1 (V0)"}; + } V01; + + /// Partition for particle 1 + Partition PartitionV01 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0)) && + ((aod::femtodreamparticle::cut & V01.CutBit) == V01.CutBit) && + (aod::femtodreamparticle::pt > V01.PtMin) && + (aod::femtodreamparticle::pt < V01.PtMax) && + (aod::femtodreamparticle::eta > V01.EtaMin) && + (aod::femtodreamparticle::eta < V01.EtaMax) && + (aod::femtodreamparticle::mLambda > V01.InvMassMin) && + (aod::femtodreamparticle::mLambda < V01.InvMassMax) && + (aod::femtodreamparticle::mAntiLambda > V01.InvMassAntiMin) && + (aod::femtodreamparticle::mAntiLambda < V01.InvMassAntiMax); + + /// Histogramming for particle 1 + FemtoDreamParticleHisto trackHistoPartOne; + FemtoDreamParticleHisto posChildHistos; + FemtoDreamParticleHisto negChildHistos; + + /// Particle 2 (V0) + struct : ConfigurableGroup { + std::string prefix = std::string("V02"); + Configurable PDGCode{"PDGCode", 3122, "PDG code of particle 2 (V0)"}; + Configurable CutBit{"CutBit", 7518, "Selection bit for particle 2 (V0)"}; + Configurable ChildPos_CutBit{"ChildPos_CutBit", 210, "Selection bit for positive child of V0"}; + Configurable ChildPos_TPCBit{"ChildPos_TPCBit", 64, "PID TPC bit for positive child of V0"}; + Configurable ChildNeg_CutBit{"ChildNeg_CutBit", 209, "Selection bit for negative child of V0"}; + Configurable ChildNeg_TPCBit{"ChildNeg_TPCBit", 256, "PID TPC bit for negative child of V0"}; + + Configurable InvMassMin{"InvMassMin", 1.08, "Minimum invariant mass of Partricle 2 (particle) (V0)"}; + Configurable InvMassMax{"InvMassMax", 1.15, "Maximum invariant mass of Partricle 2 (particle) (V0)"}; + Configurable InvMassAntiMin{"InvMassAntiMin", 0., "Minimum invariant mass of Partricle 2 (antiparticle) (V0)"}; + Configurable InvMassAntiMax{"InvMassAntiMax", 999., "Maximum invariant mass of Partricle 2 (antiparticle) (V0)"}; + + Configurable PtMin{"PtMin", 0., "Minimum pT of Partricle 2 (V0)"}; + Configurable PtMax{"PtMax", 999., "Maximum pT of Partricle 2 (V0)"}; + Configurable EtaMin{"EtaMin", -10., "Minimum eta of Partricle 2 (V0)"}; + Configurable EtaMax{"EtaMax", 10., "Maximum eta of Partricle 2 (V0)"}; + } V02; + + /// Partition for particle 2 + Partition PartitionV02 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kV0)) && + ((aod::femtodreamparticle::cut & V02.CutBit) == V02.CutBit) && + (aod::femtodreamparticle::pt > V02.PtMin) && + (aod::femtodreamparticle::pt < V02.PtMax) && + (aod::femtodreamparticle::eta > V02.EtaMin) && + (aod::femtodreamparticle::eta < V02.EtaMax) && + (aod::femtodreamparticle::mLambda > V02.InvMassMin) && + (aod::femtodreamparticle::mLambda < V02.InvMassMax) && + (aod::femtodreamparticle::mAntiLambda > V02.InvMassAntiMin) && + (aod::femtodreamparticle::mAntiLambda < V02.InvMassAntiMax); + + /// Histogramming for Event + FemtoDreamEventHisto eventHisto; + + /// Binning configurables + struct : ConfigurableGroup { + std::string prefix = std::string("Binning"); + ConfigurableAxis TempFitVarTrack{"TempFitVarTrack", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot (Track)"}; + ConfigurableAxis TempFitVarV0{"TempFitVarV0", {300, 0.9, 1}, "binning of the TempFitVar in the pT vs. TempFitVar plot (V0)"}; + ConfigurableAxis TempFitVarV0Child{"TempFitVarV0Child", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot (V0 child)"}; + ConfigurableAxis InvMass{"InvMass", {200, 1, 1.2}, "InvMass binning"}; + ConfigurableAxis pTTrack{"pTTrack", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot (Track)"}; + ConfigurableAxis pTV0{"pTV0", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot (V0)"}; + ConfigurableAxis pTV0Child{"pTV0Child", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot (V0)"}; + ConfigurableAxis pT{"pT", {20, 0.5, 4.05}, "pT binning"}; + ConfigurableAxis kstar{"kstar", {1500, 0., 6.}, "binning kstar"}; + ConfigurableAxis kT{"kT", {150, 0., 9.}, "binning kT"}; + ConfigurableAxis mT{"mT", {225, 0., 7.5}, "binning mT"}; + ConfigurableAxis multTempFit{"multTempFit", {1, 0, 1}, "multiplicity for the TempFitVar plot"}; + } Binning; + + struct : ConfigurableGroup { + std::string prefix = "Binning4D"; + ConfigurableAxis kstar{"kstar", {1500, 0., 6.}, "binning kstar for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true)"}; + ConfigurableAxis mT{"mT", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true)"}; + ConfigurableAxis mult{"mult", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f}, "multiplicity Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true)"}; + ConfigurableAxis multPercentile{"multPercentile", {10, 0.0f, 100.0f}, "multiplicity percentile Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true)"}; + } Binning4D; + + // Mixing configurables + struct : ConfigurableGroup { + std::string prefix = "Mixing"; + ConfigurableAxis MultMixBins{"MultMixBins", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f}, "Mixing bins - multiplicity"}; + ConfigurableAxis MultPercentileMixBins{"MultPercentileMixBins", {VARIABLE_WIDTH, 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f}, "Mixing bins - multiplicity percentile"}; + ConfigurableAxis VztxMixBins{"VztxMixBins", {VARIABLE_WIDTH, -10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}, "Mixing bins - z-vertex"}; + Configurable Depth{"Depth", 5, "Number of events for mixing"}; + Configurable Policy{"Policy", 0, "Binning policy for mixing - 0: multiplicity, 1: multipliciy percentile, 2: both"}; + } Mixing; + + ColumnBinningPolicy colBinningMult{{Mixing.VztxMixBins, Mixing.MultMixBins}, true}; + ColumnBinningPolicy colBinningMultPercentile{{Mixing.VztxMixBins, Mixing.MultPercentileMixBins}, true}; + ColumnBinningPolicy colBinningMultMultPercentile{{Mixing.VztxMixBins, Mixing.MultMixBins, Mixing.MultPercentileMixBins}, true}; + + FemtoDreamContainer sameEventCont; + FemtoDreamContainer mixedEventCont; + // FemtoDreamPairCleaner pairCleaner; + FemtoDreamDetaDphiStar pairCloseRejectionSE; + FemtoDreamDetaDphiStar pairCloseRejectionME; + /// Histogram output + HistogramRegistry Registry{"Output", {}, OutputObjHandlingPolicy::AnalysisObject}; + + TRandom3* random; + + void init(InitContext&) + { + // setup columnpolicy for binning + colBinningMult = {{Mixing.VztxMixBins, Mixing.MultMixBins}, true}; + colBinningMultPercentile = {{Mixing.VztxMixBins, Mixing.MultPercentileMixBins}, true}; + colBinningMultMultPercentile = {{Mixing.VztxMixBins, Mixing.MultMixBins, Mixing.MultPercentileMixBins}, true}; + + if (Option.RandomizePair.value) { + random = new TRandom3(0); + } + eventHisto.init(&Registry, Option.IsMC); + trackHistoPartOne.init(&Registry, Binning.multTempFit, Option.Dummy, Binning.pT, Option.Dummy, Option.Dummy, Binning.TempFitVarV0, Option.Dummy, Option.Dummy, Option.Dummy, Option.Dummy, Binning.InvMass, Option.Dummy, Option.IsMC, V01.PDGCode); + posChildHistos.init(&Registry, Binning.multTempFit, Option.Dummy, Binning.pTV0Child, Option.Dummy, Option.Dummy, Binning.TempFitVarV0Child, Option.Dummy, Option.Dummy, Option.Dummy, Option.Dummy, Option.Dummy, Option.Dummy, false, 0); + negChildHistos.init(&Registry, Binning.multTempFit, Option.Dummy, Binning.pTV0Child, Option.Dummy, Option.Dummy, Binning.TempFitVarV0Child, Option.Dummy, Option.Dummy, Option.Dummy, Option.Dummy, Option.Dummy, Option.Dummy, false, 0); + + sameEventCont.init(&Registry, + Binning.kstar, Binning.pT, Binning.kT, Binning.mT, Mixing.MultMixBins, Mixing.MultPercentileMixBins, + Binning4D.kstar, Binning4D.mT, Binning4D.mult, Binning4D.multPercentile, + Option.IsMC, Option.Use4D, Option.ExtendedPlots, + Option.HighkstarCut, + Option.SmearingByOrigin); + + mixedEventCont.init(&Registry, + Binning.kstar, Binning.pT, Binning.kT, Binning.mT, Mixing.MultMixBins, Mixing.MultPercentileMixBins, + Binning4D.kstar, Binning4D.mT, Binning4D.mult, Binning4D.multPercentile, + Option.IsMC, Option.Use4D, Option.ExtendedPlots, + Option.HighkstarCut, + Option.SmearingByOrigin); + sameEventCont.setPDGCodes(V01.PDGCode, V02.PDGCode); + mixedEventCont.setPDGCodes(V01.PDGCode, V02.PDGCode); + // pairCleaner.init(&Registry); + + if (Option.CPROn.value) { + pairCloseRejectionSE.init(&Registry, &Registry, Option.CPRdeltaPhiMax.value, Option.CPRdeltaEtaMax.value, Option.CPRPlotPerRadii.value, 1, Option.CPROld.value); + pairCloseRejectionME.init(&Registry, &Registry, Option.CPRdeltaPhiMax.value, Option.CPRdeltaEtaMax.value, Option.CPRPlotPerRadii.value, 2, Option.CPROld.value); + } + }; + + template + void fillCollision(CollisionType col) + { + eventHisto.fillQA(col); + } + + /// This function processes the same event and takes care of all the histogramming + /// \todo the trivial loops over the tracks should be factored out since they will be common to all combinations of T-T, T-V0, V0-V0, ... + /// @tparam PartitionType + /// @tparam PartType + /// @tparam isMC: enables Monte Carlo truth specific histograms + /// @param groupPartsOne partition for the first particle passed by the process function + /// @param groupPartsTwo partition for the second particle passed by the process function + /// @param parts femtoDreamParticles table (in case of Monte Carlo joined with FemtoDreamMCLabels) + /// @param magFieldTesla magnetic field of the collision + /// @param multCol multiplicity of the collision + template + void doSameEvent(PartitionType SliceV01, PartitionType SliceV02, PartType parts, Collision col) + { + for (auto& v0 : SliceV01) { + const auto& posChild = parts.iteratorAt(v0.index() - 2); + const auto& negChild = parts.iteratorAt(v0.index() - 1); + if (((posChild.cut() & V01.ChildPos_CutBit) == V01.ChildPos_CutBit) && + ((posChild.pidcut() & V01.ChildPos_TPCBit) == V01.ChildPos_TPCBit) && + ((negChild.cut() & V01.ChildNeg_CutBit) == V01.ChildNeg_CutBit) && + ((negChild.pidcut() & V01.ChildNeg_TPCBit) == V01.ChildNeg_TPCBit)) { + trackHistoPartOne.fillQA(v0, aod::femtodreamparticle::kPt, col.multNtr(), col.multV0M()); + posChildHistos.fillQA(posChild, aod::femtodreamparticle::kPt, col.multNtr(), col.multV0M()); + negChildHistos.fillQA(negChild, aod::femtodreamparticle::kPt, col.multNtr(), col.multV0M()); + } + } + + /// Now build the combinations + float rand = 0.; + if (Option.SameSpecies.value) { + for (auto& [p1, p2] : combinations(CombinationsStrictlyUpperIndexPolicy(SliceV01, SliceV02))) { + const auto& posChild_1 = parts.iteratorAt(p1.index() - 2); + const auto& negChild_1 = parts.iteratorAt(p1.index() - 1); + const auto& posChild_2 = parts.iteratorAt(p2.index() - 2); + const auto& negChild_2 = parts.iteratorAt(p2.index() - 1); + if (((posChild_1.cut() & V01.ChildPos_CutBit) == V01.ChildPos_CutBit) && + ((posChild_1.pidcut() & V01.ChildPos_TPCBit) == V01.ChildPos_TPCBit) && + ((negChild_1.cut() & V01.ChildNeg_CutBit) == V01.ChildNeg_CutBit) && + ((negChild_1.pidcut() & V01.ChildNeg_TPCBit) == V01.ChildNeg_TPCBit) && + ((posChild_2.cut() & V02.ChildPos_CutBit) == V02.ChildPos_CutBit) && + ((posChild_2.pidcut() & V02.ChildPos_TPCBit) == V02.ChildPos_TPCBit) && + ((negChild_2.cut() & V02.ChildNeg_CutBit) == V02.ChildNeg_CutBit) && + ((negChild_2.pidcut() & V02.ChildNeg_TPCBit) == V02.ChildNeg_TPCBit)) { + + if (Option.CPROn.value) { + if (pairCloseRejectionSE.isClosePair(p1, p2, parts, col.magField())) { + continue; + } + } + /* + // track cleaning + if (!pairCleaner.isCleanPair(p1, p2, parts)) { + continue; + } + */ + + if (Option.RandomizePair.value) { + rand = random->Rndm(); + } + if (rand <= 0.5) { + sameEventCont.setPair(p1, p2, col.multNtr(), col.multV0M(), Option.Use4D, Option.ExtendedPlots, Option.SmearingByOrigin); + } else { + sameEventCont.setPair(p2, p1, col.multNtr(), col.multV0M(), Option.Use4D, Option.ExtendedPlots, Option.SmearingByOrigin); + } + } + } + } else { + for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(SliceV01, SliceV02))) { + if (Option.CPROn.value) { + if (pairCloseRejectionSE.isClosePair(p1, p2, parts, col.magField())) { + continue; + } + } + /* + // track cleaning + if (!pairCleaner.isCleanPair(p1, p2, parts)) { + continue; + } + */ + sameEventCont.setPair(p1, p2, col.multNtr(), col.multV0M(), Option.Use4D, Option.ExtendedPlots, Option.SmearingByOrigin); + } + } + } + + /// process function for to call doSameEvent with Data + /// \param col subscribe to the collision table (Data) + /// \param parts subscribe to the femtoDreamParticleTable + void processSameEvent(FilteredCollision& col, o2::aod::FDParticles& parts) + { + fillCollision(col); + auto SliceV01 = PartitionV01->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + auto SliceV02 = PartitionV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + if (SliceV01.size() == 0 && SliceV02.size() == 0) { + return; + } + doSameEvent(SliceV01, SliceV02, parts, col); + } + PROCESS_SWITCH(femtoDreamPairTaskV0V0, processSameEvent, "Enable processing same event", true); + + template + void doMixedEvent_NotMasked(CollisionType& cols, PartType& parts, PartitionType& part1, PartitionType& part2, BinningType policy) + { + for (auto const& [collision1, collision2] : soa::selfCombinations(policy, Mixing.Depth.value, -1, cols, cols)) { + auto SliceV01 = part1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto SliceV02 = part2->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + if (SliceV01.size() == 0 || SliceV02.size() == 0) { + continue; + } + for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(SliceV01, SliceV02))) { + const auto& posChild_1 = parts.iteratorAt(p1.index() - 2); + const auto& negChild_1 = parts.iteratorAt(p1.index() - 1); + const auto& posChild_2 = parts.iteratorAt(p2.index() - 2); + const auto& negChild_2 = parts.iteratorAt(p2.index() - 1); + if (((posChild_1.cut() & V01.ChildPos_CutBit) == V01.ChildPos_CutBit) && + ((posChild_1.pidcut() & V01.ChildPos_TPCBit) == V01.ChildPos_TPCBit) && + ((negChild_1.cut() & V01.ChildNeg_CutBit) == V01.ChildNeg_CutBit) && + ((negChild_1.pidcut() & V01.ChildNeg_TPCBit) == V01.ChildNeg_TPCBit) && + ((posChild_2.cut() & V02.ChildPos_CutBit) == V02.ChildPos_CutBit) && + ((posChild_2.pidcut() & V02.ChildPos_TPCBit) == V02.ChildPos_TPCBit) && + ((negChild_2.cut() & V02.ChildNeg_CutBit) == V02.ChildNeg_CutBit) && + ((negChild_2.pidcut() & V02.ChildNeg_TPCBit) == V02.ChildNeg_TPCBit)) { + + if (Option.CPROn.value) { + if (pairCloseRejectionME.isClosePair(p1, p2, parts, collision1.magField())) { + continue; + } + } + mixedEventCont.setPair(p1, p2, collision1.multNtr(), collision1.multV0M(), Option.Use4D, Option.ExtendedPlots, Option.SmearingByOrigin); + } + } + } + } + + /// process function for to call doMixedEvent with Data + /// @param cols subscribe to the collisions table (Data) + /// @param parts subscribe to the femtoDreamParticleTable + void processMixedEvent(FilteredCollisions& cols, o2::aod::FDParticles& parts) + { + switch (Mixing.Policy.value) { + case femtodreamcollision::kMult: + doMixedEvent_NotMasked(cols, parts, PartitionV01, PartitionV02, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent_NotMasked(cols, parts, PartitionV01, PartitionV02, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent_NotMasked(cols, parts, PartitionV01, PartitionV02, colBinningMultMultPercentile); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + PROCESS_SWITCH(femtoDreamPairTaskV0V0, processMixedEvent, "Enable processing mixed events", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{ + adaptAnalysisTask(cfgc), + }; + return workflow; +} diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h b/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h index 864487cdcb0..77c8798a3b7 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverse3DContainer.h @@ -17,15 +17,18 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSE3DCONTAINER_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSE3DCONTAINER_H_ -#include -#include -#include +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" #include "Framework/HistogramRegistry.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" +#include + #include "Math/Vector4D.h" -#include "TMath.h" #include "TDatabasePDG.h" +#include "TMath.h" + +#include +#include using namespace o2::framework; diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseAngularContainer.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseAngularContainer.h index 4d267fb67d3..4a1fb507b4a 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseAngularContainer.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseAngularContainer.h @@ -20,17 +20,20 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEANGULARCONTAINER_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEANGULARCONTAINER_H_ -#include -#include -#include +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" -#include "Framework/HistogramRegistry.h" #include "Common/Core/RecoDecay.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" + +#include "Framework/HistogramRegistry.h" +#include #include "Math/Vector4D.h" -#include "TMath.h" #include "TDatabasePDG.h" +#include "TMath.h" + +#include +#include using namespace o2::framework; diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseCascadeSelection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseCascadeSelection.h index 3a389da705e..7a9e078c7ce 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseCascadeSelection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseCascadeSelection.h @@ -21,15 +21,18 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSECASCADESELECTION_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSECASCADESELECTION_H_ -#include -#include #include "PWGCF/FemtoUniverse/Core/FemtoUniverseObjectSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" + #include "Common/Core/RecoDecay.h" + #include "Framework/HistogramRegistry.h" #include "ReconstructionDataFormats/PID.h" +#include +#include + namespace o2::analysis::femto_universe { namespace femto_universe_cascade_selection @@ -252,9 +255,9 @@ class FemtoUniverseCascadeSelection femto_universe_selection::kLowerLimit, // cascade tran rad min femto_universe_selection::kUpperLimit, // cascade tran rad max femto_universe_selection::kUpperLimit, // cascade maximum distance of decay vertex to PV - femto_universe_selection::kLowerLimit, // DCA pos to PV max - femto_universe_selection::kLowerLimit, // DCA neg to PV max - femto_universe_selection::kLowerLimit, // DCA bach to PV max + femto_universe_selection::kLowerLimit, // DCA pos to PV min + femto_universe_selection::kLowerLimit, // DCA neg to PV min + femto_universe_selection::kLowerLimit, // DCA bach to PV min femto_universe_selection::kLowerLimit, // DCA v0 to PV max femto_universe_selection::kLowerLimit, // v0 mass min femto_universe_selection::kUpperLimit, // v0 mass max @@ -276,10 +279,10 @@ class FemtoUniverseCascadeSelection "Minimum cascade transverse radius (cm)", "Maximum cascade transverse radius (cm)", "Maximum distance of cascade from primary vertex", - "Maximum DCA of positive track form primary vertex", - "Maximum DCA of negative track form primary vertex", - "Maximum DCA of bachelor track form primary vertex", - "Maximum DCA of v0 form primary vertex", + "Minimum DCA of positive track form primary vertex", + "Minimum DCA of negative track form primary vertex", + "Minimum DCA of bachelor track form primary vertex", + "Minimum DCA of v0 form primary vertex", "Minimum V0 mass", "Maximum V0 mass"}; ///< Helper information for the ///< different selections diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseCollisionSelection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseCollisionSelection.h index 633bba05760..ab47405cb9c 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseCollisionSelection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseCollisionSelection.h @@ -18,11 +18,13 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSECOLLISIONSELECTION_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSECOLLISIONSELECTION_H_ -#include #include "Common/CCDB/TriggerAliases.h" + #include "Framework/HistogramRegistry.h" #include "Framework/Logger.h" +#include + using namespace o2::framework; namespace o2::analysis::femto_universe diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h index fb2af0a02df..6f45d43f977 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h @@ -26,13 +26,12 @@ #include "Common/Core/RecoDecay.h" #include "Framework/HistogramRegistry.h" +#include #include "Math/Vector4D.h" #include "TDatabasePDG.h" #include "TMath.h" -#include - #include #include @@ -57,7 +56,7 @@ enum EventType { same, ///< Pair from same event /// \brief Container for all histogramming related to the correlation function. The two /// particles of the pair are passed here, and the correlation function and QA histograms /// are filled according to the specified observable -/// \tparam eventType Type of the event (same/mixed) +/// \tparam eventType Type of the event (same or mixed) /// \tparam obs Observable to be computed (k*/Q_inv/...) template class FemtoUniverseContainer diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseCutculator.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseCutculator.h index 40b7c425e5c..58e278cdde7 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseCutculator.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseCutculator.h @@ -18,19 +18,20 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSECUTCULATOR_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSECUTCULATOR_H_ +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseV0Selection.h" + +#include +#include + +#include #include #include +#include #include #include #include -#include -#include -#include -#include - -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseV0Selection.h" namespace o2::analysis::femto_universe { diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h index e8941e7cbd9..ac5f1c9aad5 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h @@ -19,16 +19,19 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEDETADPHISTAR_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEDETADPHISTAR_H_ -#include -#include -#include -#include "TMath.h" -#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseFemtoContainer.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseAngularContainer.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h" -#include "Framework/HistogramRegistry.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseFemtoContainer.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" + +#include "Framework/HistogramRegistry.h" + +#include "TMath.h" + +#include +#include +#include namespace o2::analysis { @@ -108,7 +111,7 @@ class FemtoUniverseDetaDphiStar } } if constexpr (kPartOneType == o2::aod::femtouniverseparticle::ParticleType::kCascade && kPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kCascade) { - /// Xi-Xi and Omega-Omega combination + /// Cascade-Cascade combination for (int k = 0; k < 7; k++) { std::string dirName = static_cast(DirNames[5]); histdetadpisame[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); @@ -122,6 +125,36 @@ class FemtoUniverseDetaDphiStar } } } + if constexpr (kPartOneType == o2::aod::femtouniverseparticle::ParticleType::kTrack && kPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kCascade) { + /// Track-Cascade combination + for (int k = 0; k < 3; k++) { + std::string dirName = static_cast(DirNames[6]); + histdetadpisame[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpisame[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpimixed[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpimixed[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + if (plotForEveryRadii) { + for (int l = 0; l < 9; l++) { + histdetadpiRadii[k][l] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[k][l])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + } + } + } + } + if constexpr (kPartOneType == o2::aod::femtouniverseparticle::ParticleType::kV0 && kPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kCascade) { + /// V0-Cascade combination + for (int k = 0; k < 3; k++) { + std::string dirName = static_cast(DirNames[7]); + histdetadpisame[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[0][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpisame[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesSame[1][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpimixed[k][0] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[0][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + histdetadpimixed[k][1] = mHistogramRegistry->add((dirName + static_cast(HistNamesMixed[1][k])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + if (plotForEveryRadii) { + for (int l = 0; l < 9; l++) { + histdetadpiRadii[k][l] = mHistogramRegistryQA->add((dirName + static_cast(HistNamesRadii[k][l])).c_str(), "; #Delta #eta; #Delta #phi", kTH2F, {{100, -0.15, 0.15}, {100, -0.15, 0.15}}); + } + } + } + } if constexpr (kPartOneType == o2::aod::femtouniverseparticle::ParticleType::kTrack && kPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kPhi) { for (int i = 0; i < 2; i++) { std::string dirName = static_cast(DirNames[3]); @@ -201,7 +234,6 @@ class FemtoUniverseDetaDphiStar bool pass = false; for (int i = 0; i < 2; i++) { auto indexOfDaughter = (ChosenEventType == femto_universe_container::EventType::mixed ? part2.globalIndex() : part2.index()) - 2 + i; - // auto indexOfDaughter = part2.globalIndex() - 2 + i; auto daughter = particles.begin() + indexOfDaughter; auto deta = part1.eta() - daughter.eta(); auto dphiAvg = averagePhiStar(part1, *daughter, i); @@ -266,7 +298,7 @@ class FemtoUniverseDetaDphiStar return pass; } else if constexpr (kPartOneType == o2::aod::femtouniverseparticle::ParticleType::kCascade && kPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kCascade) { - /// Xi-Xi and Omega-Omega combination + /// Cascade-Cascade combination if (part1.partType() != o2::aod::femtouniverseparticle::ParticleType::kCascade || part2.partType() != o2::aod::femtouniverseparticle::ParticleType::kCascade) { LOG(fatal) << "FemtoUniverseDetaDphiStar: passed arguments don't agree with FemtoUniverseDetaDphiStar instantiation! Please provide kCascade,kCascade candidates."; return false; @@ -274,12 +306,12 @@ class FemtoUniverseDetaDphiStar bool pass = false; static constexpr int CascChildTable[][2] = {{-1, -1}, {-1, -2}, {-1, -3}, {-2, -2}, {-3, -3}, {-2, -1}, {-3, -1}}; - for (int i = 0; i < 5; i++) { + for (int i = 0; i < 7; i++) { auto indexOfDaughterpart1 = (ChosenEventType == femto_universe_container::EventType::mixed ? part1.globalIndex() : part1.index()) + CascChildTable[i][0]; auto indexOfDaughterpart2 = (ChosenEventType == femto_universe_container::EventType::mixed ? part2.globalIndex() : part2.index()) + CascChildTable[i][1]; auto daughterpart1 = particles.begin() + indexOfDaughterpart1; auto daughterpart2 = particles.begin() + indexOfDaughterpart2; - if (isSameSignCPR && (daughterpart1.sign() != daughterpart2.sign())) + if (isSameSignCPR && (daughterpart1.mAntiLambda() != daughterpart2.mAntiLambda())) // mAntiLambda() is used here as sign getter continue; auto deta = daughterpart1.eta() - daughterpart2.eta(); auto dphiAvg = averagePhiStar(*daughterpart1, *daughterpart2, i); @@ -305,6 +337,83 @@ class FemtoUniverseDetaDphiStar } return pass; + } else if constexpr (kPartOneType == o2::aod::femtouniverseparticle::ParticleType::kTrack && kPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kCascade) { + /// Track-Cascade combination + if (part1.partType() != o2::aod::femtouniverseparticle::ParticleType::kTrack || part2.partType() != o2::aod::femtouniverseparticle::ParticleType::kCascade) { + LOG(fatal) << "FemtoUniverseDetaDphiStar: passed arguments don't agree with FemtoUniverseDetaDphiStar instantiation! Please provide kTrack,kCascade candidates."; + return false; + } + + bool pass = false; + for (int i = 0; i < 3; i++) { + auto indexOfDaughter = (ChosenEventType == femto_universe_container::EventType::mixed ? part2.globalIndex() : part2.index()) - 3 + i; + auto daughter = particles.begin() + indexOfDaughter; + if (isSameSignCPR && (part1.mAntiLambda() != daughter.mAntiLambda())) // mAntiLambda() is used here as sign getter + continue; + auto deta = part1.eta() - daughter.eta(); + auto dphiAvg = averagePhiStar(*part1, *daughter, i); + if (ChosenEventType == femto_universe_container::EventType::same) { + histdetadpisame[i][0]->Fill(deta, dphiAvg); + } else if (ChosenEventType == femto_universe_container::EventType::mixed) { + histdetadpimixed[i][0]->Fill(deta, dphiAvg); + } else { + LOG(fatal) << "FemtoUniverseDetaDphiStar: passed arguments don't agree with FemtoUniverseDetaDphiStar's type of events! Please provide same or mixed."; + } + + if ((dphiAvg > cutDeltaPhiStarMin) && (dphiAvg < cutDeltaPhiStarMax) && (deta > cutDeltaEtaMin) && (deta < cutDeltaEtaMax)) { + pass = true; + } else { + if (ChosenEventType == femto_universe_container::EventType::same) { + histdetadpisame[i][1]->Fill(deta, dphiAvg); + } else if (ChosenEventType == femto_universe_container::EventType::mixed) { + histdetadpimixed[i][1]->Fill(deta, dphiAvg); + } else { + LOG(fatal) << "FemtoUniverseDetaDphiStar: passed arguments don't agree with FemtoUniverseDetaDphiStar's type of events! Please provide same or mixed."; + } + } + } + return pass; + + } else if constexpr (kPartOneType == o2::aod::femtouniverseparticle::ParticleType::kV0 && kPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kCascade) { + /// V0-Cascade combination + if (part1.partType() != o2::aod::femtouniverseparticle::ParticleType::kV0 || part2.partType() != o2::aod::femtouniverseparticle::ParticleType::kCascade) { + LOG(fatal) << "FemtoUniverseDetaDphiStar: passed arguments don't agree with FemtoUniverseDetaDphiStar instantiation! Please provide kV0,kCascade candidates."; + return false; + } + + bool pass = false; + static constexpr int V0CascChildTable[][2] = {{-1, -1}, {-1, -2}, {-1, -3}, {-2, -1}, {-2, -2}, {-2, -3}}; + for (int i = 0; i < 3; i++) { + auto indexOfDaughterV0 = (ChosenEventType == femto_universe_container::EventType::mixed ? part1.globalIndex() : part1.index()) + V0CascChildTable[i][0]; + auto indexOfDaughterCasc = (ChosenEventType == femto_universe_container::EventType::mixed ? part2.globalIndex() : part2.index()) + V0CascChildTable[i][1]; + auto daughterV0 = particles.begin() + indexOfDaughterV0; + auto daughterCasc = particles.begin() + indexOfDaughterCasc; + if (isSameSignCPR && (daughterV0.mAntiLambda() != daughterCasc.mAntiLambda())) // mAntiLambda() is used here as sign getter + continue; + auto deta = daughterV0.eta() - daughterCasc.eta(); + auto dphiAvg = averagePhiStar(*daughterV0, *daughterCasc, i); + if (ChosenEventType == femto_universe_container::EventType::same) { + histdetadpisame[i][0]->Fill(deta, dphiAvg); + } else if (ChosenEventType == femto_universe_container::EventType::mixed) { + histdetadpimixed[i][0]->Fill(deta, dphiAvg); + } else { + LOG(fatal) << "FemtoUniverseDetaDphiStar: passed arguments don't agree with FemtoUniverseDetaDphiStar's type of events! Please provide same or mixed."; + } + + if ((dphiAvg > cutDeltaPhiStarMin) && (dphiAvg < cutDeltaPhiStarMax) && (deta > cutDeltaEtaMin) && (deta < cutDeltaEtaMax)) { + pass = true; + } else { + if (ChosenEventType == femto_universe_container::EventType::same) { + histdetadpisame[i][1]->Fill(deta, dphiAvg); + } else if (ChosenEventType == femto_universe_container::EventType::mixed) { + histdetadpimixed[i][1]->Fill(deta, dphiAvg); + } else { + LOG(fatal) << "FemtoUniverseDetaDphiStar: passed arguments don't agree with FemtoUniverseDetaDphiStar's type of events! Please provide same or mixed."; + } + } + } + return pass; + } else if constexpr (kPartOneType == o2::aod::femtouniverseparticle::ParticleType::kTrack && kPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kD0) { /// Track-D0 combination // check if provided particles are in agreement with the class instantiation @@ -410,6 +519,47 @@ class FemtoUniverseDetaDphiStar } } + /// Check if pair is close or not + template + bool isClosePairAtITS(Part const& part1, Part const& part2, float lmagfield, uint8_t ChosenEventType) + { + magfield = lmagfield; + + if constexpr (kPartOneType == o2::aod::femtouniverseparticle::ParticleType::kTrack && kPartTwoType == o2::aod::femtouniverseparticle::ParticleType::kTrack) { + /// Track-Track combination + // check if provided particles are in agreement with the class instantiation + if (part1.partType() != o2::aod::femtouniverseparticle::ParticleType::kTrack || part2.partType() != o2::aod::femtouniverseparticle::ParticleType::kTrack) { + LOG(fatal) << "FemtoUniverseDetaDphiStar: passed arguments don't agree with FemtoUniverseDetaDphiStar instantiation! Please provide kTrack,kTrack candidates."; + return false; + } + auto deta = part1.eta() - part2.eta(); + auto dphiAvg = part1.phi() - part2.phi(); + if (ChosenEventType == femto_universe_container::EventType::same) { + histdetadpisame[0][0]->Fill(deta, dphiAvg); + } else if (ChosenEventType == femto_universe_container::EventType::mixed) { + histdetadpimixed[0][0]->Fill(deta, dphiAvg); + } else { + LOG(fatal) << "FemtoUniverseDetaDphiStar: passed arguments don't agree with FemtoUniverseDetaDphiStar's type of events! Please provide same or mixed."; + } + + if (std::pow(dphiAvg, 2) / std::pow(cutDeltaPhiStarMax, 2) + std::pow(deta, 2) / std::pow(cutDeltaEtaMax, 2) < 1.) { + return true; + } else { + if (ChosenEventType == femto_universe_container::EventType::same) { + histdetadpisame[0][1]->Fill(deta, dphiAvg); + } else if (ChosenEventType == femto_universe_container::EventType::mixed) { + histdetadpimixed[0][1]->Fill(deta, dphiAvg); + } else { + LOG(fatal) << "FemtoUniverseDetaDphiStar: passed arguments don't agree with FemtoUniverseDetaDphiStar's type of events! Please provide same or mixed."; + } + return false; + } + } else { + LOG(fatal) << "FemtoUniversePairCleaner: Combination of objects not defined - quitting!"; + return false; + } + } + /// Check if pair is close or not template bool isClosePairFrac(Part const& part1, Part const& part2, float lmagfield, uint8_t ChosenEventType, bool IsDphiAvgOrDist, float DistMax, float FracMax) @@ -490,7 +640,7 @@ class FemtoUniverseDetaDphiStar private: HistogramRegistry* mHistogramRegistry = nullptr; ///< For main output HistogramRegistry* mHistogramRegistryQA = nullptr; ///< For QA output - static constexpr std::string_view DirNames[6] = {"kTrack_kTrack/", "kTrack_kV0/", "kV0_kV0/", "kTrack_kPhi/", "kTrack_kD0/", "kCascade_kCascade/"}; + static constexpr std::string_view DirNames[8] = {"kTrack_kTrack/", "kTrack_kV0/", "kV0_kV0/", "kTrack_kPhi/", "kTrack_kD0/", "kCascade_kCascade/", "kTrack_kCascade/", "kV0_kCascade/"}; static constexpr std::string_view HistNamesSame[2][8] = {{"detadphidetadphi0BeforeSame_0", "detadphidetadphi0BeforeSame_1", "detadphidetadphi0BeforeSame_2", "detadphidetadphi0BeforeSame_3", "detadphidetadphi0BeforeSame_4", "detadphidetadphi0BeforeSame_5", diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCalculator.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCalculator.h index a96b70180aa..da40cfbf4d3 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCalculator.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCalculator.h @@ -16,15 +16,17 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEEFFICIENCYCALCULATOR_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEEFFICIENCYCALCULATOR_H_ -#include -#include -#include -#include +#include "FemtoUniverseParticleHisto.h" -#include "Framework/Configurable.h" -#include "CCDB/BasicCCDBManager.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "FemtoUniverseParticleHisto.h" + +#include "CCDB/BasicCCDBManager.h" +#include "Framework/Configurable.h" + +#include +#include +#include +#include namespace o2::analysis::femto_universe::efficiency { diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h index 03d4b5b1fb4..dfe2bd35d62 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h @@ -18,6 +18,7 @@ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEEVENTHISTO_H_ #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" + #include "Framework/HistogramRegistry.h" using namespace o2::framework; diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseFemtoContainer.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseFemtoContainer.h index 4719561ccf6..eb9f25dff14 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseFemtoContainer.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseFemtoContainer.h @@ -20,16 +20,17 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEFEMTOCONTAINER_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEFEMTOCONTAINER_H_ -#include -#include -#include +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" #include "Framework/HistogramRegistry.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" +#include #include "Math/Vector4D.h" -#include "TMath.h" #include "TDatabasePDG.h" +#include "TMath.h" + +#include +#include using namespace o2::framework; diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h index ec40ea035e6..aee87f1a057 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h @@ -19,14 +19,14 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEMATH_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEMATH_H_ -#include -#include - -#include "Math/Vector4D.h" #include "Math/Boost.h" +#include "Math/Vector4D.h" #include "TLorentzVector.h" #include "TMath.h" +#include +#include + namespace o2::analysis::femto_universe { diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseObjectSelection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseObjectSelection.h index 07491f92c8f..8487ef11bc0 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseObjectSelection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseObjectSelection.h @@ -17,15 +17,16 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEOBJECTSELECTION_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEOBJECTSELECTION_H_ +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h" +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" + +#include "Framework/HistogramRegistry.h" +#include "ReconstructionDataFormats/PID.h" + #include #include #include -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h" -#include "ReconstructionDataFormats/PID.h" -#include "Framework/HistogramRegistry.h" -#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" - using namespace o2; using namespace o2::framework; @@ -181,7 +182,8 @@ class FemtoUniverseObjectSelection std::vector selVarVec; for (auto it : mSelections) { auto selVar = it.getSelectionVariable(); - if (std::none_of(selVarVec.begin(), selVarVec.end(), [selVar](selVariable a) { return a == selVar; })) { + if (std::none_of(selVarVec.begin(), selVarVec.end(), + [selVar](selVariable a) { return a == selVar; })) { selVarVec.push_back(selVar); } } diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniversePairAngularWithCentMultKt.h b/PWGCF/FemtoUniverse/Core/FemtoUniversePairAngularWithCentMultKt.h index 31b256f43f7..b63455ee3cf 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniversePairAngularWithCentMultKt.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniversePairAngularWithCentMultKt.h @@ -17,9 +17,10 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEPAIRANGULARWITHCENTMULTKT_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEPAIRANGULARWITHCENTMULTKT_H_ +#include "Framework/HistogramRegistry.h" + #include #include -#include "Framework/HistogramRegistry.h" namespace o2::analysis::femto_universe { diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h b/PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h index b27d8e25abf..32da4810b85 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h @@ -20,6 +20,7 @@ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEPAIRCLEANER_H_ #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" + #include "Framework/HistogramRegistry.h" namespace o2::analysis::femto_universe diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h b/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h index ea8626cbe32..377e7677c0b 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h @@ -16,11 +16,14 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEPAIRSHCENTMULTKT_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEPAIRSHCENTMULTKT_H_ -#include -#include +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h" + +#include "Framework/HistogramRegistry.h" + #include #include -#include "Framework/HistogramRegistry.h" +#include +#include // using namespace o2::constants::physics; diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniversePairWithCentMultKt.h b/PWGCF/FemtoUniverse/Core/FemtoUniversePairWithCentMultKt.h index 5cfef9c433f..1f2651ad2f6 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniversePairWithCentMultKt.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniversePairWithCentMultKt.h @@ -17,9 +17,10 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEPAIRWITHCENTMULTKT_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEPAIRWITHCENTMULTKT_H_ +#include "Framework/HistogramRegistry.h" + #include #include -#include "Framework/HistogramRegistry.h" namespace o2::analysis::femto_universe { diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h index 865efa0f36d..0fa792fb3be 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h @@ -20,11 +20,13 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEPARTICLEHISTO_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEPARTICLEHISTO_H_ -#include -#include #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Framework/HistogramRegistry.h" + #include "CommonConstants/MathConstants.h" +#include "Framework/HistogramRegistry.h" + +#include +#include using namespace o2::framework; // o2-linter: disable=using-directive @@ -67,8 +69,8 @@ class FemtoUniverseParticleHisto } // comment - template - void init_debug(std::string folderName) // o2-linter: disable=name/function-variable + template + void init_debug(std::string folderName, T& tempFitVarpTAxis) // o2-linter: disable=name/function-variable { std::string folderSuffix = static_cast(o2::aod::femtouniverse_mc_particle::MCTypeName[mc]).c_str(); if constexpr (mParticleType == o2::aod::femtouniverseparticle::ParticleType::kTrack || mParticleType == o2::aod::femtouniverseparticle::ParticleType::kV0Child || mParticleType == o2::aod::femtouniverseparticle::ParticleType::kCascadeBachelor || mParticleType == o2::aod::femtouniverseparticle::ParticleType::kMCTruthTrack) { @@ -84,22 +86,22 @@ class FemtoUniverseParticleHisto mHistogramRegistry->add((folderName + folderSuffix + "/hITSclustersIB").c_str(), "; ITS clusters in IB; Entries", kTH1F, {{10, -0.5, 9.5}}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCAz").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA_{z} (cm)", kTH2F, {{100, 0, 10}, {500, -5, 5}}); mHistogramRegistry->add((folderName + folderSuffix + "/hDCA").c_str(), "; #it{p}_{T} (GeV/#it{c}); DCA (cm)", kTH2F, {{100, 0, 10}, {301, 0., 1.5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/hTPCdEdX").c_str(), "; #it{p} (GeV/#it{c}); TPC Signal", kTH2F, {{100, 0, 10}, {1000, 0, 1000}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{e}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{#pi}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{K}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{p}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{d}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{e}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{#pi}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{K}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{p}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{d}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{e}", kTH2F, {{100, 0, 10}, {100, 0, 5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{#pi}", kTH2F, {{100, 0, 10}, {100, 0, 5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{K}", kTH2F, {{100, 0, 10}, {100, 0, 5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{p}", kTH2F, {{100, 0, 10}, {100, 0, 5}}); - mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{d}", kTH2F, {{100, 0, 10}, {100, 0, 5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/hTPCdEdX").c_str(), "; #it{p} (GeV/#it{c}); TPC Signal", kTH2F, {{tempFitVarpTAxis}, {1000, 0, 1000}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{e}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{#pi}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{K}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{p}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTPC_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TPC}^{d}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{e}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{#pi}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{K}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{p}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaTOF_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{TOF}^{d}", kTH2F, {{tempFitVarpTAxis}, {200, -4.975, 5.025}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_el").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{e}", kTH2F, {{tempFitVarpTAxis}, {100, 0, 5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_pi").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{#pi}", kTH2F, {{tempFitVarpTAxis}, {100, 0, 5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_K").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{K}", kTH2F, {{tempFitVarpTAxis}, {100, 0, 5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_p").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{p}", kTH2F, {{tempFitVarpTAxis}, {100, 0, 5}}); + mHistogramRegistry->add((folderName + folderSuffix + "/nSigmaComb_d").c_str(), "; #it{p} (GeV/#it{c}); n#sigma_{comb}^{d}", kTH2F, {{tempFitVarpTAxis}, {100, 0, 5}}); } else if constexpr (mParticleType == o2::aod::femtouniverseparticle::ParticleType::kV0) { mHistogramRegistry->add((folderName + folderSuffix + "/hDaughDCA").c_str(), "; DCA^{daugh} (cm); Entries", kTH1F, {{1000, 0, 10}}); mHistogramRegistry->add((folderName + folderSuffix + "/hTransRadius").c_str(), "; #it{r}_{xy} (cm); Entries", kTH1F, {{1500, 0, 150}}); @@ -240,7 +242,7 @@ class FemtoUniverseParticleHisto // Fill here the actual histogramms by calling init_base and init_MC init_base(folderName, tempFitVarAxisTitle, tempFitVarpTAxis, tempFitVarAxis); if (isDebug) { - init_debug(folderName); + init_debug(folderName, tempFitVarpTAxis); } if (isMC) { init_base(folderName, tempFitVarAxisTitle, tempFitVarpTAxis, tempFitVarAxis); @@ -266,6 +268,10 @@ class FemtoUniverseParticleHisto if constexpr (mc == o2::aod::femtouniverse_mc_particle::MCType::kRecon) { mHistogramRegistry->fill(histFolder + HIST(o2::aod::femtouniverse_mc_particle::MCTypeName[mc]) + HIST(o2::aod::femtouniverseparticle::TempFitVarName[mParticleType]), part.pt(), part.tempFitVar()); } + if constexpr (mParticleType == o2::aod::femtouniverseparticle::ParticleType::kCascade) { + mHistogramRegistry->fill(histFolder + HIST(o2::aod::femtouniverse_mc_particle::MCTypeName[mc]) + HIST("/hInvMassXi"), part.mLambda()); + mHistogramRegistry->fill(histFolder + HIST(o2::aod::femtouniverse_mc_particle::MCTypeName[mc]) + HIST("/hInvMassOmega"), part.mAntiLambda()); + } } template @@ -318,8 +324,6 @@ class FemtoUniverseParticleHisto mHistogramRegistry->fill(histFolder + HIST(o2::aod::femtouniverse_mc_particle::MCTypeName[mc]) + HIST("/hDecayVtxX"), part.decayVtxX()); mHistogramRegistry->fill(histFolder + HIST(o2::aod::femtouniverse_mc_particle::MCTypeName[mc]) + HIST("/hDecayVtxY"), part.decayVtxY()); mHistogramRegistry->fill(histFolder + HIST(o2::aod::femtouniverse_mc_particle::MCTypeName[mc]) + HIST("/hDecayVtxZ"), part.decayVtxZ()); - mHistogramRegistry->fill(histFolder + HIST(o2::aod::femtouniverse_mc_particle::MCTypeName[mc]) + HIST("/hInvMassXi"), part.mLambda()); - mHistogramRegistry->fill(histFolder + HIST(o2::aod::femtouniverse_mc_particle::MCTypeName[mc]) + HIST("/hInvMassOmega"), part.mAntiLambda()); } } diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniversePhiSelection.h b/PWGCF/FemtoUniverse/Core/FemtoUniversePhiSelection.h index 0ee0bfe4162..c43217ceb72 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniversePhiSelection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniversePhiSelection.h @@ -19,18 +19,20 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEPHISELECTION_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEPHISELECTION_H_ -#include -#include - #include "PWGCF/FemtoUniverse/Core/FemtoUniverseObjectSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" #include "Common/Core/RecoDecay.h" + #include "Framework/HistogramRegistry.h" #include "ReconstructionDataFormats/PID.h" + #include "TLorentzVector.h" +#include +#include + namespace o2::analysis::femto_universe { namespace femto_universe_phi_selection diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h index 558874133cb..b99cccb338a 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h @@ -17,18 +17,20 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSESHCONTAINER_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSESHCONTAINER_H_ -#include -#include -#include -#include -#include - -#include "Framework/HistogramRegistry.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseSpherHarMath.h" + +#include "Framework/HistogramRegistry.h" +#include + #include "Math/Vector4D.h" -#include "TMath.h" #include "TDatabasePDG.h" +#include "TMath.h" + +#include +#include +#include +#include namespace o2::analysis::femto_universe { diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseSoftPionRemoval.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseSoftPionRemoval.h index 9631b5b3377..4a97c83865d 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseSoftPionRemoval.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseSoftPionRemoval.h @@ -16,11 +16,12 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSESOFTPIONREMOVAL_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSESOFTPIONREMOVAL_H_ -#include - #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" + #include "Framework/HistogramRegistry.h" +#include + namespace o2::analysis::femto_universe { diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseSpherHarMath.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseSpherHarMath.h index d92560ceb72..082ddd25663 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseSpherHarMath.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseSpherHarMath.h @@ -16,14 +16,15 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSESPHERHARMATH_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSESPHERHARMATH_H_ -#include -#include - -#include "Math/Vector4D.h" #include "Math/Boost.h" +#include "Math/Vector4D.h" #include "TLorentzVector.h" #include "TMath.h" +#include +#include +#include + namespace o2::analysis::femto_universe { diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h index 75276f24a6d..51c711c8165 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h @@ -18,17 +18,19 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSETRACKSELECTION_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSETRACKSELECTION_H_ -#include -#include -#include - +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseObjectSelection.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "Common/DataModel/TrackSelectionTables.h" + #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseObjectSelection.h" -#include "ReconstructionDataFormats/PID.h" +#include "Common/DataModel/TrackSelectionTables.h" + #include "Framework/HistogramRegistry.h" +#include "ReconstructionDataFormats/PID.h" + +#include +#include +#include // using namespace o2::framework; diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseV0Selection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseV0Selection.h index 805da180cc3..8b45f664f15 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseV0Selection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseV0Selection.h @@ -19,17 +19,18 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEV0SELECTION_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSEV0SELECTION_H_ -#include -#include - #include "PWGCF/FemtoUniverse/Core/FemtoUniverseObjectSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseSelection.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" #include "Common/Core/RecoDecay.h" + #include "Framework/HistogramRegistry.h" #include "ReconstructionDataFormats/PID.h" +#include +#include + namespace o2::analysis::femto_universe { namespace femto_universe_v0_selection diff --git a/PWGCF/FemtoUniverse/Core/femtoUtils.h b/PWGCF/FemtoUniverse/Core/femtoUtils.h index 70a02e98b8c..ddc1833c335 100644 --- a/PWGCF/FemtoUniverse/Core/femtoUtils.h +++ b/PWGCF/FemtoUniverse/Core/femtoUtils.h @@ -17,12 +17,14 @@ #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUTILS_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUTILS_H_ -#include -#include -#include -#include "Framework/ASoAHelpers.h" #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" +#include "Framework/ASoAHelpers.h" + +#include +#include +#include + namespace o2::analysis::femto_universe { diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx index 9ab5dcecd68..83c197ea0ad 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx @@ -19,6 +19,7 @@ #include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" #include "Common/CCDB/TriggerAliases.h" +#include "Common/Core/RecoDecay.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" @@ -171,10 +172,10 @@ struct FemtoUniverseProducerMCTruthTask { if (confAnalysisWithPID) { bool pass = false; std::vector tmpPDGCodes = confPDGCodes; // necessary due to some features of the Configurable - for (const int& pdg : tmpPDGCodes) { + for (auto const& pdg : tmpPDGCodes) { if (pdgCode == Pdg::kPhi) { // phi meson pass = true; - } else if (pdgCode == Pdg::kD0) { // D0 meson + } else if (std::abs(pdgCode) == Pdg::kD0) { // D0(bar) meson pass = true; } else if (pdgCode == Pdg::kDPlus) { // D+ meson pass = true; @@ -187,6 +188,13 @@ struct FemtoUniverseProducerMCTruthTask { continue; } + /// check if we end-up with the correct final state using MC info + int8_t sign = 0; + if (std::abs(pdgCode) == Pdg::kD0 && !RecoDecay::isMatchedMCGen(tracks, particle, Pdg::kD0, std::array{+kPiPlus, -kKPlus}, true, &sign)) { + /// check if we have D0(bar) → π± K∓ + continue; + } + // we cannot use isSelectedMinimal since it takes Ncls // if (!trackCuts.isSelectedMinimal(track)) { // continue; diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index e337ecf7f7e..d4cdefecf3b 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -38,6 +38,8 @@ #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" +#include "EventFiltering/Zorro.h" +#include "EventFiltering/ZorroSummary.h" #include "CommonConstants/PhysicsConstants.h" #include "DataFormatsParameters/GRPMagField.h" @@ -59,6 +61,7 @@ #include #include #include +#include #include using namespace o2; @@ -125,6 +128,7 @@ struct FemtoUniverseProducerTask { Produces outputCascParts; Configurable confIsDebug{"confIsDebug", true, "Enable Debug tables"}; + Configurable confIsUseCutculator{"confIsUseCutculator", true, "Enable cutculator for track cuts"}; // Choose if filtering or skimming version is run // Configurable confIsTrigger{"confIsTrigger", false, "Store all collisions"}; //Commented: not used configurable // Choose if running on converted data or Run3 / Pilot @@ -137,31 +141,35 @@ struct FemtoUniverseProducerTask { Configurable confStoreMCmothers{"confStoreMCmothers", false, "MC truth: Fill with not only primary particles and store mothers' PDG in tempFitVar."}; Configurable confFillCollExt{"confFillCollExt", false, "Option to fill collision extended table"}; + /// Event filtering (used for v0-cascade analysis) + Configurable zorroMask{"zorroMask", "", "zorro trigger class to select on (empty: none)"}; + /// Event cuts FemtoUniverseCollisionSelection colCuts; - Configurable confEvtUseTPCmult{"confEvtUseTPCmult", false, "Use multiplicity based on the number of tracks with TPC information"}; - Configurable confEvtZvtx{"confEvtZvtx", 10.f, "Evt sel: Max. z-Vertex (cm)"}; - Configurable confEvtTriggerCheck{"confEvtTriggerCheck", true, "Evt sel: check for trigger"}; - Configurable confEvtTriggerSel{"confEvtTriggerSel", kINT7, "Evt sel: trigger"}; - Configurable confEvtOfflineCheck{"confEvtOfflineCheck", false, "Evt sel: check for offline selection"}; - Configurable confIsActivateV0{"confIsActivateV0", false, "Activate filling of V0 into femtouniverse tables"}; - Configurable confActivateSecondaries{"confActivateSecondaries", false, "Fill secondary MC gen particles that were reconstructed"}; - Configurable confIsActivateCascade{"confIsActivateCascade", false, "Activate filling of Cascade into femtouniverse tables"}; - Configurable confIsActivatePhi{"confIsActivatePhi", false, "Activate filling of Phi into femtouniverse tables"}; - Configurable confIsActiveD0{"confIsActiveD0", false, "Activate filling FU tables for D0/D0bar mesons"}; - Configurable confMCTruthAnalysisWithPID{"confMCTruthAnalysisWithPID", true, "1: take only particles with specified PDG, 0: all particles (for MC Truth)"}; - Configurable> confMCTruthPDGCodes{"confMCTruthPDGCodes", std::vector{211, -211, 2212, -2212, 333}, "PDG of particles to be stored"}; - Configurable confCentFT0Min{"confCentFT0Min", 0.f, "Min CentFT0 value for centrality selection"}; - Configurable confCentFT0Max{"confCentFT0Max", 200.f, "Max CentFT0 value for centrality selection"}; - Configurable confEvIsGoodZvtxFT0vsPV{"confEvIsGoodZvtxFT0vsPV", true, "Require kIsGoodZvtxFT0vsPV selection on Events."}; - Configurable confEvNoSameBunchPileup{"confEvNoSameBunchPileup", true, "Require kNoSameBunchPileup selection on Events."}; - Configurable confIsUsePileUp{"confIsUsePileUp", true, "Required for choosing whether to run the pile-up cuts"}; - Configurable confEvIsVertexITSTPC{"confEvIsVertexITSTPC", true, "Require kIsVertexITSTPC selection on Events"}; - Configurable confTPCOccupancyMin{"confTPCOccupancyMin", 0, "Minimum value for TPC Occupancy selection"}; - Configurable confTPCOccupancyMax{"confTPCOccupancyMax", 500, "Maximum value for TPC Occupancy selection"}; - - Filter customCollCentFilter = (aod::cent::centFT0C > confCentFT0Min) && - (aod::cent::centFT0C < confCentFT0Max); + struct : o2::framework::ConfigurableGroup { + Configurable confEvtUseTPCmult{"confEvtUseTPCmult", false, "Use multiplicity based on the number of tracks with TPC information"}; + Configurable confEvtZvtx{"confEvtZvtx", 10.f, "Evt sel: Max. z-Vertex (cm)"}; + Configurable confEvtTriggerCheck{"confEvtTriggerCheck", true, "Evt sel: check for trigger"}; + Configurable confEvtTriggerSel{"confEvtTriggerSel", kINT7, "Evt sel: trigger"}; + Configurable confEvtOfflineCheck{"confEvtOfflineCheck", false, "Evt sel: check for offline selection"}; + Configurable confIsActivateV0{"confIsActivateV0", false, "Activate filling of V0 into femtouniverse tables"}; + Configurable confActivateSecondaries{"confActivateSecondaries", false, "Fill secondary MC gen particles that were reconstructed"}; + Configurable confIsActivateCascade{"confIsActivateCascade", false, "Activate filling of Cascade into femtouniverse tables"}; + Configurable confIsActivatePhi{"confIsActivatePhi", false, "Activate filling of Phi into femtouniverse tables"}; + Configurable confIsActiveD0{"confIsActiveD0", false, "Activate filling FU tables for D0/D0bar mesons"}; + Configurable confMCTruthAnalysisWithPID{"confMCTruthAnalysisWithPID", true, "1: take only particles with specified PDG, 0: all particles (for MC Truth)"}; + Configurable> confMCTruthPDGCodes{"confMCTruthPDGCodes", std::vector{211, -211, 2212, -2212, 333}, "PDG of particles to be stored"}; + Configurable confCentFT0Min{"confCentFT0Min", 0.f, "Min CentFT0 value for centrality selection"}; + Configurable confCentFT0Max{"confCentFT0Max", 200.f, "Max CentFT0 value for centrality selection"}; + Configurable confEvIsGoodZvtxFT0vsPV{"confEvIsGoodZvtxFT0vsPV", true, "Require kIsGoodZvtxFT0vsPV selection on Events."}; + Configurable confEvNoSameBunchPileup{"confEvNoSameBunchPileup", true, "Require kNoSameBunchPileup selection on Events."}; + Configurable confIsUsePileUp{"confIsUsePileUp", true, "Required for choosing whether to run the pile-up cuts"}; + Configurable confEvIsVertexITSTPC{"confEvIsVertexITSTPC", true, "Require kIsVertexITSTPC selection on Events"}; + Configurable confTPCOccupancyMin{"confTPCOccupancyMin", 0, "Minimum value for TPC Occupancy selection"}; + Configurable confTPCOccupancyMax{"confTPCOccupancyMax", 500, "Maximum value for TPC Occupancy selection"}; + } ConfGeneral; + Filter customCollCentFilter = (aod::cent::centFT0C > ConfGeneral.confCentFT0Min) && + (aod::cent::centFT0C < ConfGeneral.confCentFT0Max); // just sanity check to make sure in case there are problems in conversion or // MC production it does not affect results @@ -200,7 +208,6 @@ struct FemtoUniverseProducerTask { // V0 FemtoUniverseV0Selection v0Cuts; struct : o2::framework::ConfigurableGroup { - // Configurable confIsFillV0s{"confIsFillV0s", false, "Choice to fill V0s"}; //Commented: not used configurable Configurable> confV0Sign{FemtoUniverseV0Selection::getSelectionName(femto_universe_v0_selection::kV0Sign, "ConfV0"), std::vector{-1, 1}, FemtoUniverseV0Selection::getSelectionHelper(femto_universe_v0_selection::kV0Sign, "V0 selection: ")}; Configurable> confV0PtMin{FemtoUniverseV0Selection::getSelectionName(femto_universe_v0_selection::kV0pTMin, "ConfV0"), std::vector{0.3f, 0.4f, 0.5f}, FemtoUniverseV0Selection::getSelectionHelper(femto_universe_v0_selection::kV0pTMin, "V0 selection: ")}; Configurable> confV0PtMax{FemtoUniverseV0Selection::getSelectionName(femto_universe_v0_selection::kV0pTMax, "ConfV0"), std::vector{3.3f, 3.4f, 3.5f}, FemtoUniverseV0Selection::getSelectionHelper(femto_universe_v0_selection::kV0pTMax, "V0 selection: ")}; @@ -249,7 +256,6 @@ struct FemtoUniverseProducerTask { // CASCADE FemtoUniverseCascadeSelection cascadeCuts; struct : o2::framework::ConfigurableGroup { - // Configurable confIsFillCascades{"confIsFillCascades", false, "Choice to fill cascades"}; //Commented: not used configurable Configurable> confCascSign{FemtoUniverseCascadeSelection::getSelectionName(femto_universe_cascade_selection::kCascadeSign, "ConfCasc"), std::vector{-1, 1}, FemtoUniverseCascadeSelection::getSelectionHelper(femto_universe_cascade_selection::kCascadeSign, "Cascade selection: ")}; Configurable> confCascPtMin{FemtoUniverseCascadeSelection::getSelectionName(femto_universe_cascade_selection::kCascadepTMin, "ConfCasc"), std::vector{0.3f, 0.4f, 0.5f}, FemtoUniverseCascadeSelection::getSelectionHelper(femto_universe_cascade_selection::kCascadepTMin, "Cascade selection: ")}; Configurable> confCascPtMax{FemtoUniverseCascadeSelection::getSelectionName(femto_universe_cascade_selection::kCascadepTMax, "ConfCasc"), std::vector{3.3f, 3.4f, 3.5f}, FemtoUniverseCascadeSelection::getSelectionHelper(femto_universe_cascade_selection::kCascadepTMax, "Cascade selection: ")}; @@ -283,10 +289,6 @@ struct FemtoUniverseProducerTask { Configurable confXiInvMassUpLimit{"confXiInvMassUpLimit", 1.40, "Upper limit of the Xi invariant mass"}; Configurable confOmegaInvMassLowLimit{"confOmegaInvMassLowLimit", 1.60, "Lower limit of the Omega invariant mass"}; Configurable confOmegaInvMassUpLimit{"confOmegaInvMassUpLimit", 1.80, "Upper limit of the Omega invariant mass"}; - - // Configurable confCascRejectCompetingMass{"confCascRejectCompetingMass", false, "Switch on to reject Omegas (for Xi) or Xis (for Omegas)"}; - // Configurable confCascInvCompetingMassLowLimit{"confCascInvCompetingMassLowLimit", 1.66, "Lower limit of the cascade invariant mass for competing mass rejection"}; - // Configurable confCascInvCompetingMassUpLimit{"confCascInvCompetingMassUpLimit", 1.68, "Upper limit of the cascade invariant mass for competing mass rejection"}; } ConfCascadeSelection; // PHI @@ -295,6 +297,7 @@ struct FemtoUniverseProducerTask { /// Phi meson Configurable confPhiPtLowLimit{"confPhiPtLowLimit", 0.8, "Lower limit of the Phi pT."}; Configurable confPhiPtHighLimit{"confPhiPtHighLimit", 4.0, "Higher limit of the Phi pT."}; + Configurable confPhiEtaHighLimit{"confPhiEtaHighLimit", 0.8, "Maximum eta value of the Phi"}; Configurable confPhiInvMassLowLimit{"confPhiInvMassLowLimit", 1.011, "Lower limit of the Phi invariant mass"}; Configurable confPhiInvMassUpLimit{"confPhiInvMassUpLimit", 1.027, "Upper limit of the Phi invariant mass"}; // Phi meson daughters @@ -302,13 +305,21 @@ struct FemtoUniverseProducerTask { Configurable confPhiKaonRejectProtonNsigma{"confPhiKaonRejectProtonNsigma", 3.0, "Reject if particle could be a Proton combined nsigma value."}; // Kaons Configurable confPhiDoLFPID4Kaons{"confPhiDoLFPID4Kaons", true, "Switch on do PID for Kaons as in LF"}; - Configurable confPhiKaonNsigmaTPCfrom0_0to0_3{"confPhiKaonNsigmaTPCfrom0_0to0_3", 3.0, "Reject if Kaons in 0.0-0.3 are have TPC n sigma above this value."}; - Configurable confPhiKaonNsigmaTPCfrom0_3to0_45{"confPhiKaonNsigmaTPCfrom0_3to0_45", 2.0, "Reject if Kaons in 0.3-0.45 are have TPC n sigma above this value."}; - Configurable confPhiKaonNsigmaTPCfrom0_45to0_55{"confPhiKaonNsigmaTPCfrom0_45to0_55", 1.0, "Reject if Kaons in 0.45-0.55 are have TPC n sigma above this value."}; - Configurable confPhiKaonNsigmaTPCfrom0_55to1_5{"confPhiKaonNsigmaTPCfrom0_55to1_5", 3.0, "Reject if Kaons in 0.55-1.5 are have TPC n sigma above this value."}; - Configurable confPhiKaonNsigmaTOFfrom0_55to1_5{"confPhiKaonNsigmaTOFfrom0_55to1_5", 3.0, "Reject if Kaons in 0.55-1.5 are have TOF n sigma above this value."}; - Configurable confPhiKaonNsigmaTPCfrom1_5{"confPhiKaonNsigmaTPCfrom1_5", 3.0, "Reject if Kaons above 1.5 are have TPC n sigma above this value."}; - Configurable confPhiKaonNsigmaTOFfrom1_5{"confPhiKaonNsigmaTOFfrom1_5", 3.0, "Reject if Kaons above 1.5 are have TOF n sigma above this value."}; + Configurable confNSigmaTPCKaonLF{"confNSigmaTPCKaonLF", 3.0, "TPC Kaon Sigma as in LF"}; + Configurable confNSigmaCombKaonLF{"confNSigmaCombKaonLF", 3.0, "TPC and TOF Kaon Sigma (combined) as in LF"}; + Configurable confMomKaonLF{"confMomKaonLF", 0.5, "Momentum threshold for kaon identification as in LF"}; + Configurable confMomKaonRejected{"confMomKaonRejected", 0.5, "Momentum threshold for rejected kaon"}; + Configurable confMomKaon03{"confMomKaon03", 0.3, "Momentum threshold for kaon identification pT = 0.3 GeV/c"}; + Configurable confMomKaon045{"confMomKaon045", 0.45, "Momentum threshold for kaon identification pT = 0.45 GeV/c"}; + Configurable confMomKaon055{"confMomKaon055", 0.55, "Momentum threshold for kaon identification pT = 0.55 GeV/c"}; + Configurable confMomKaon15{"confMomKaon15", 1.5, "Momentum threshold for kaon identification pT = 1.5 GeV/c"}; + Configurable confPhiKaonNsigmaTPCfrom00to03{"confPhiKaonNsigmaTPCfrom00to03", 3.0, "Reject if Kaons in 0.0-0.3 are have TPC n sigma above this value."}; + Configurable confPhiKaonNsigmaTPCfrom03to045{"confPhiKaonNsigmaTPCfrom03to045", 2.0, "Reject if Kaons in 0.3-0.45 are have TPC n sigma above this value."}; + Configurable confPhiKaonNsigmaTPCfrom045to055{"confPhiKaonNsigmaTPCfrom045to055", 1.0, "Reject if Kaons in 0.45-0.55 are have TPC n sigma above this value."}; + Configurable confPhiKaonNsigmaTPCfrom055to15{"confPhiKaonNsigmaTPCfrom055to15", 3.0, "Reject if Kaons in 0.55-1.5 are have TPC n sigma above this value."}; + Configurable confPhiKaonNsigmaTOFfrom055to15{"confPhiKaonNsigmaTOFfrom055to15", 3.0, "Reject if Kaons in 0.55-1.5 are have TOF n sigma above this value."}; + Configurable confPhiKaonNsigmaTPCfrom15{"confPhiKaonNsigmaTPCfrom15", 3.0, "Reject if Kaons above 1.5 are have TPC n sigma above this value."}; + Configurable confPhiKaonNsigmaTOFfrom15{"confPhiKaonNsigmaTOFfrom15", 3.0, "Reject if Kaons above 1.5 are have TOF n sigma above this value."}; } ConfPhiSelection; // PDG codes for fillMCParticle function @@ -317,46 +328,54 @@ struct FemtoUniverseProducerTask { // D0/D0bar mesons struct : o2::framework::ConfigurableGroup { - Configurable confD0D0barCandMaxY{"confD0D0barCandMaxY", -1., "max. cand. rapidity"}; Configurable confD0D0barCandEtaCut{"confD0D0barCandEtaCut", 0.8, "max. cand. pseudorapidity"}; - Configurable yD0D0barCandRecoMax{"yD0D0barCandRecoMax", 0.8, "MC Reco, max. rapidity of D0/D0bar cand."}; - Configurable yD0D0barCandGenMax{"yD0D0barCandGenMax", 0.8, "MC Truth, max. rapidity of D0/D0bar cand."}; + Configurable trackD0pTGenMin{"trackD0pTGenMin", 0.0, "MC Truth, min. pT for tracks and D0/D0bar cand."}; + Configurable trackD0pTGenMax{"trackD0pTGenMax", 24.0, "MC Truth, max. pT for tracks and D0/D0bar cand."}; Configurable storeD0D0barDoubleMassHypo{"storeD0D0barDoubleMassHypo", false, "Store D0/D0bar cand. which pass selection criteria for both, D0 and D0bar"}; Configurable> classMlD0D0bar{"classMlD0D0bar", {0, 1, 2}, "Indexes of ML scores to be stored. Three indexes max."}; } ConfD0Selection; + // PID bitmask configurables + struct : o2::framework::ConfigurableGroup { + Configurable confMinMomTOF{"confMinMomTOF", 0.75, "momentum threshold for particle identification using TOF"}; + Configurable confNsigmaTPCParticleChild{"confNsigmaTPCParticleChild", 3.0, "TPC Sigma for particle (daugh & bach) momentum < Confmom"}; + Configurable confNsigmaTOFParticleChild{"confNsigmaTOFParticleChild", 3.0, "TOF Sigma for particle (daugh & bach) momentum > Confmom"}; + Configurable confNsigmaTPCParticle{"confNsigmaTPCParticle", 3.0, "TPC Sigma for particle (track) momentum < Confmom"}; + Configurable confNsigmaCombinedParticle{"confNsigmaCombinedParticle", 3.0, "TPC and TOF Sigma (combined) for particle (track) momentum > Confmom"}; + } ConfPIDBitmask; + HfHelper hfHelper; bool isKaonNSigma(float mom, float nsigmaTPCK, float nsigmaTOFK) { - if (mom < 0.3) { // 0.0-0.3 - if (std::abs(nsigmaTPCK) < ConfPhiSelection.confPhiKaonNsigmaTPCfrom0_0to0_3) { + if (mom < ConfPhiSelection.confMomKaon03) { // 0.0-0.3 + if (std::abs(nsigmaTPCK) < ConfPhiSelection.confPhiKaonNsigmaTPCfrom00to03) { return true; } else { return false; } - } else if (mom < 0.45) { // 0.30 - 0.45 - if (std::abs(nsigmaTPCK) < ConfPhiSelection.confPhiKaonNsigmaTPCfrom0_3to0_45) { + } else if (mom < ConfPhiSelection.confMomKaon045) { // 0.30 - 0.45 + if (std::abs(nsigmaTPCK) < ConfPhiSelection.confPhiKaonNsigmaTPCfrom03to045) { return true; } else { return false; } - } else if (mom < 0.55) { // 0.45-0.55 - if (std::abs(nsigmaTPCK) < ConfPhiSelection.confPhiKaonNsigmaTPCfrom0_45to0_55) { + } else if (mom < ConfPhiSelection.confMomKaon055) { // 0.45-0.55 + if (std::abs(nsigmaTPCK) < ConfPhiSelection.confPhiKaonNsigmaTPCfrom045to055) { return true; } else { return false; } - } else if (mom < 1.5) { // 0.55-1.5 (now we use TPC and TOF) - if ((std::abs(nsigmaTOFK) < ConfPhiSelection.confPhiKaonNsigmaTOFfrom0_55to1_5) && (std::abs(nsigmaTPCK) < ConfPhiSelection.confPhiKaonNsigmaTPCfrom0_55to1_5)) { + } else if (mom < ConfPhiSelection.confMomKaon15) { // 0.55-1.5 (now we use TPC and TOF) + if ((std::abs(nsigmaTOFK) < ConfPhiSelection.confPhiKaonNsigmaTOFfrom055to15) && (std::abs(nsigmaTPCK) < ConfPhiSelection.confPhiKaonNsigmaTPCfrom055to15)) { { return true; } } else { return false; } - } else if (mom > 1.5) { // 1.5 - - if ((std::abs(nsigmaTOFK) < ConfPhiSelection.confPhiKaonNsigmaTOFfrom1_5) && (std::abs(nsigmaTPCK) < ConfPhiSelection.confPhiKaonNsigmaTPCfrom1_5)) { + } else if (mom > ConfPhiSelection.confMomKaon15) { // 1.5 - + if ((std::abs(nsigmaTOFK) < ConfPhiSelection.confPhiKaonNsigmaTOFfrom15) && (std::abs(nsigmaTPCK) < ConfPhiSelection.confPhiKaonNsigmaTPCfrom15)) { return true; } else { return false; @@ -368,17 +387,17 @@ struct FemtoUniverseProducerTask { bool isKaonNSigmaLF(float mom, float nsigmaTPCK, float nsigmaTOFK, bool hasTOF) { - if (mom < 0.5) { - if (std::abs(nsigmaTPCK) < 3.0) { + if (mom < ConfPhiSelection.confMomKaonLF) { + if (std::abs(nsigmaTPCK) < ConfPhiSelection.confNSigmaTPCKaonLF) { return true; } else { return false; } - } else if (mom >= 0.5) { // 0.55-1.5 (now we use TPC and TOF) + } else if (mom >= ConfPhiSelection.confMomKaonLF) { // 0.5-1.5 (now we use TPC and TOF) if (!hasTOF) { return false; } else { - if (std::sqrt(nsigmaTPCK * nsigmaTPCK + nsigmaTOFK * nsigmaTOFK) < 3.0) { + if (std::sqrt(nsigmaTPCK * nsigmaTPCK + nsigmaTOFK * nsigmaTOFK) < ConfPhiSelection.confNSigmaCombKaonLF) { return true; } else { return false; @@ -391,14 +410,14 @@ struct FemtoUniverseProducerTask { bool isKaonRejected(float mom, float nsigmaTPCPr, float nsigmaTOFPr, float nsigmaTPCPi, float nsigmaTOFPi) { - if (mom < 0.5) { + if (mom < ConfPhiSelection.confMomKaonRejected) { if (std::abs(nsigmaTPCPi) < ConfPhiSelection.confPhiKaonRejectPionNsigma.value) { return true; } else if (std::abs(nsigmaTPCPr) < ConfPhiSelection.confPhiKaonRejectProtonNsigma.value) { return true; } } - if (mom > 0.5) { + if (mom > ConfPhiSelection.confMomKaonRejected) { if (std::hypot(nsigmaTOFPi, nsigmaTPCPi) < ConfPhiSelection.confPhiKaonRejectPionNsigma.value) { return true; } else if (std::hypot(nsigmaTOFPr, nsigmaTPCPr) < ConfPhiSelection.confPhiKaonRejectProtonNsigma.value) { @@ -411,6 +430,65 @@ struct FemtoUniverseProducerTask { } } + bool isNSigmaTPC(float nsigmaTPCParticle) + { + return (std::abs(nsigmaTPCParticle) < ConfPIDBitmask.confNsigmaTPCParticleChild); + } + + bool isNSigmaTOF(float mom, float nsigmaTOFParticle, bool hasTOF) + { + // Cut only on daughter and bachelor tracks, that have TOF signal + if (mom > ConfPIDBitmask.confMinMomTOF && hasTOF) { + return (std::abs(nsigmaTOFParticle) < ConfPIDBitmask.confNsigmaTOFParticleChild); + } else { + return true; + } + } + + bool isNSigmaCombined(float mom, float nsigmaTPCParticle, float nsigmaTOFParticle) + { + if (mom <= ConfPIDBitmask.confMinMomTOF) { + return (std::abs(nsigmaTPCParticle) < ConfPIDBitmask.confNsigmaTPCParticle); + } else { + return (std::hypot(nsigmaTOFParticle, nsigmaTPCParticle) < ConfPIDBitmask.confNsigmaCombinedParticle); + } + } + + template + aod::femtouniverseparticle::CutContainerType PIDBitmask(const TrackType& track) + { + static const o2::track::PID pids[] = {o2::track::PID::Proton, o2::track::PID::Pion, o2::track::PID::Kaon}; + aod::femtouniverseparticle::CutContainerType mask = 0u; + for (UInt_t i = 0; i < 3; ++i) { + if (isNSigmaTPC(trackCuts.getNsigmaTPC(track, pids[i]))) + mask |= (1u << i); + if (isNSigmaTOF(track.p(), trackCuts.getNsigmaTOF(track, pids[i]), track.hasTOF())) + mask |= (8u << i); + if (isNSigmaCombined(track.p(), trackCuts.getNsigmaTPC(track, pids[i]), trackCuts.getNsigmaTOF(track, pids[i]))) + mask |= (64u << i); + } + if (track.hasTOF()) + mask |= (512u); + return mask; + } + + Zorro zorro; + OutputObj zorroSummary{"zorroSummary"}; + int mRunNumberZorro = 0; + + HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::QAObject}; + HistogramRegistry cascadeQaRegistry{"CascadeQAHistos", {}, OutputObjHandlingPolicy::QAObject}; + + void initZorro(aod::BCsWithTimestamps::iterator const& bc) + { + if (mRunNumberZorro == bc.runNumber()) + return; + + zorro.initCCDB(ccdb.service, bc.runNumber(), bc.timestamp(), zorroMask.value); + zorro.populateHistRegistry(qaRegistry, bc.runNumber()); + mRunNumberZorro = bc.runNumber(); + } + /// \todo should we add filter on min value pT/eta of V0 and daughters? /*Filter v0Filter = (nabs(aod::v0data::x) < V0DecVtxMax.value) && (nabs(aod::v0data::y) < V0DecVtxMax.value) && @@ -418,9 +496,6 @@ struct FemtoUniverseProducerTask { // (aod::v0data::v0radius > V0TranRadV0Min.value); to be added, not working // for now do not know why - HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::QAObject}; - HistogramRegistry cascadeQaRegistry{"CascadeQAHistos", {}, OutputObjHandlingPolicy::QAObject}; - int mRunNumber = 0; float mMagField; Service ccdb; /// Accessing the CCDB @@ -428,16 +503,18 @@ struct FemtoUniverseProducerTask { void init(InitContext&) { - if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0 || doprocessTrackCascadeData || doprocessTrackD0mesonData || doprocessTrackD0DataML || doprocessTrackCentRun2Data || doprocessTrackV0CentRun2Data || doprocessTrackCentRun3Data || doprocessV0CentRun3Data || doprocessCascadeCentRun3Data || doprocessTrackDataCentPP) == false && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth || doprocessTrackMCGen || doprocessTruthAndFullMCV0 || doprocessTrackD0MC || doprocessTruthAndFullMCCasc || doprocessFullMCCent || doprocessTrackCentRun3DataMC || doprocessTruthAndFullMCCentRun3 || doprocessTruthAndFullMCCentRun3V0) == false) { + if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0 || doprocessTrackCascadeData || doprocessTrackV0Cascade || doprocessTrackD0mesonData || doprocessTrackD0DataML || doprocessTrackCentRun2Data || doprocessTrackV0CentRun2Data || doprocessTrackCentRun3Data || doprocessV0CentRun3Data || doprocessCascadeCentRun3Data || doprocessTrackDataCentPP) == false && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth || doprocessTrackMCGen || doprocessTruthAndFullMCV0 || doprocessTrackD0MC || doprocessTruthAndFullMCCasc || doprocessFullMCCent || doprocessTrackCentRun3DataMC || doprocessTruthAndFullMCCentRun3 || doprocessTruthAndFullMCCentRun3V0) == false) { LOGF(fatal, "Neither processFullData nor processFullMC enabled. Please choose one."); } - if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0 || doprocessTrackCascadeData || doprocessTrackD0mesonData || doprocessTrackD0DataML || doprocessTrackCentRun2Data || doprocessTrackV0CentRun2Data || doprocessTrackCentRun3Data || doprocessV0CentRun3Data || doprocessCascadeCentRun3Data || doprocessTrackDataCentPP) == true && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth || doprocessTrackMCGen || doprocessTruthAndFullMCV0 || doprocessTrackD0MC || doprocessTruthAndFullMCCasc || doprocessFullMCCent || doprocessTrackCentRun3DataMC || doprocessTruthAndFullMCCentRun3 || doprocessTruthAndFullMCCentRun3V0) == true) { + if ((doprocessFullData || doprocessTrackPhiData || doprocessTrackData || doprocessTrackV0 || doprocessTrackCascadeData || doprocessTrackV0Cascade || doprocessTrackD0mesonData || doprocessTrackD0DataML || doprocessTrackCentRun2Data || doprocessTrackV0CentRun2Data || doprocessTrackCentRun3Data || doprocessV0CentRun3Data || doprocessCascadeCentRun3Data || doprocessTrackDataCentPP) == true && (doprocessFullMC || doprocessTrackMC || doprocessTrackMCTruth || doprocessTrackMCGen || doprocessTruthAndFullMCV0 || doprocessTrackD0MC || doprocessTruthAndFullMCCasc || doprocessFullMCCent || doprocessTrackCentRun3DataMC || doprocessTruthAndFullMCCentRun3 || doprocessTruthAndFullMCCentRun3V0) == true) { LOGF(fatal, "Cannot enable process Data and process MC at the same time. " "Please choose one."); } - colCuts.setCuts(confEvtZvtx, confEvtTriggerCheck, confEvtTriggerSel, confEvtOfflineCheck, confIsRun3, confCentFT0Min, confCentFT0Max); + zorroSummary.setObject(zorro.getZorroSummary()); + + colCuts.setCuts(ConfGeneral.confEvtZvtx, ConfGeneral.confEvtTriggerCheck, ConfGeneral.confEvtTriggerSel, ConfGeneral.confEvtOfflineCheck, confIsRun3, ConfGeneral.confCentFT0Min, ConfGeneral.confCentFT0Max); colCuts.init(&qaRegistry); trackCuts.setSelection(ConfTrkSelection.confTrkCharge, femto_universe_track_selection::kSign, femto_universe_selection::kEqual); @@ -462,7 +539,7 @@ struct FemtoUniverseProducerTask { /// different type! // v0Cuts.setSelection(ConfV0Selection->getRow(0), // femto_universe_v0_selection::kDecVtxMax, femto_universe_selection::kAbsUpperLimit); - if (confIsActivateV0) { + if (ConfGeneral.confIsActivateV0) { // initializing for V0 v0Cuts.setSelection(ConfV0Selection.confV0Sign, femto_universe_v0_selection::kV0Sign, femto_universe_selection::kEqual); v0Cuts.setSelection(ConfV0Selection.confV0PtMin, femto_universe_v0_selection::kV0pTMin, femto_universe_selection::kLowerLimit); @@ -505,7 +582,7 @@ struct FemtoUniverseProducerTask { // } } - if (confIsActivateCascade) { + if (ConfGeneral.confIsActivateCascade) { // initializing for cascades cascadeCuts.setSelection(ConfCascadeSelection.confCascSign, femto_universe_cascade_selection::kCascadeSign, femto_universe_selection::kEqual); cascadeCuts.setSelection(ConfCascadeSelection.confCascPtMin, femto_universe_cascade_selection::kCascadepTMin, femto_universe_selection::kLowerLimit); @@ -552,13 +629,9 @@ struct FemtoUniverseProducerTask { cascadeCuts.init(&cascadeQaRegistry); // invmass cuts cascadeCuts.setInvMassLimits(ConfCascadeSelection.confXiInvMassLowLimit, ConfCascadeSelection.confOmegaInvMassLowLimit, ConfCascadeSelection.confXiInvMassUpLimit, ConfCascadeSelection.confOmegaInvMassUpLimit); - - /*if (ConfCascadeSelection.confCascRejectCompetingMass) { - cascadeCuts.setCompetingInvMassLimits(ConfCascadeSelection.confCascInvCompetingMassLowLimit, ConfCascadeSelection.confCascInvCompetingMassUpLimit); - }*/ } - if (confIsActivatePhi) { + if (ConfGeneral.confIsActivatePhi) { // initializing for Phi meson phiCuts.init(&qaRegistry); } @@ -658,7 +731,8 @@ struct FemtoUniverseProducerTask { outputDebugParts(-999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., - -999., -999., + -999., + hfHelper.yD0(particle), // getter transRadius particle.mlProbD0()[0], // getter decayVtxX particle.mlProbD0()[1], // getter decayVtxY particle.mlProbD0()[2], // getter decayVtxZ @@ -667,7 +741,48 @@ struct FemtoUniverseProducerTask { outputDebugParts(-999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., -999., - -999., -999., + -999., + hfHelper.yD0(particle), // getter transRadius + particle.mlProbD0bar()[0], // getter decayVtxX + particle.mlProbD0bar()[1], // getter decayVtxY + particle.mlProbD0bar()[2], // getter decayVtxZ + -999.); // Additional info for D0/D0bar + } else { + outputDebugParts(-999., -999., -999., -999., -999., -999., -999., -999., -999., + -999., -999., -999., -999., -999., -999., -999., -999., + -999., -999., -999., -999., -999., + -999., -999., -999., -999., -999., -999.); + } + } + + template + void fillDebugD0D0barMcMl(ParticleType const& particle) + { + int8_t originMcReco = 2; // 0 - prompt, 1 - non-prompt, 2 - default/else + if (particle.originMcRec() == RecoDecay::OriginType::Prompt) { + originMcReco = 0; + } else if (particle.originMcRec() == RecoDecay::OriginType::NonPrompt) { + originMcReco = 1; + } else { + originMcReco = 2; + } + if constexpr (isD0ML) { + outputDebugParts(particle.flagMcMatchRec(), // getter sign + originMcReco, -999., -999., -999., -999., -999., -999., -999., + -999., -999., -999., -999., -999., -999., -999., -999., + -999., -999., -999., -999., -999., + -999., + hfHelper.yD0(particle), // getter transRadius + particle.mlProbD0()[0], // getter decayVtxX + particle.mlProbD0()[1], // getter decayVtxY + particle.mlProbD0()[2], // getter decayVtxZ + -999.); // Additional info for D0/D0bar + } else if constexpr (isD0barML) { + outputDebugParts(particle.flagMcMatchRec(), -999., -999., -999., -999., -999., -999., -999., -999., + originMcReco, -999., -999., -999., -999., -999., -999., -999., + -999., -999., -999., -999., -999., + -999., + hfHelper.yD0(particle), // getter transRadius particle.mlProbD0bar()[0], // getter decayVtxX particle.mlProbD0bar()[1], // getter decayVtxY particle.mlProbD0bar()[2], // getter decayVtxZ @@ -750,7 +865,7 @@ struct FemtoUniverseProducerTask { if ((kaon1MC.isPhysicalPrimary() && kaon2MC.isPhysicalPrimary()) && (!motherskaon1MC.empty() && !motherskaon2MC.empty())) { for (const auto& particleMotherOfNeg : motherskaon1MC) { for (const auto& particleMotherOfPos : motherskaon2MC) { - if (particleMotherOfNeg == particleMotherOfPos && particleMotherOfNeg.pdgCode() == 333) { + if (particleMotherOfNeg == particleMotherOfPos && particleMotherOfNeg.pdgCode() == Pdg::kPhi) { phiOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kPrimary; } else { phiOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kFake; @@ -787,44 +902,6 @@ struct FemtoUniverseProducerTask { } } - template - void fillMCParticleD0(ParticleType const& hfCand) - { - if (std::abs(hfCand.flagMcMatchRec()) == o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) { - // get corresponding MC particle and its info - int pdgCode = 0; - int hfCandOrigin = 99; - - if (hfCand.originMcRec() == RecoDecay::OriginType::Prompt) { - if (hfCand.isSelD0() == 1 && hfCand.isSelD0bar() == 0) { - hfCandOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kPrompt; - pdgCode = static_cast(Pdg::kD0); - } else if (hfCand.isSelD0() == 0 && hfCand.isSelD0bar() == 1) { - hfCandOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kPrompt; - pdgCode = static_cast(Pdg::kD0Bar); - } else { - hfCandOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kFake; - pdgCode = 0; - } - } else { - if (hfCand.isSelD0() == 1 && hfCand.isSelD0bar() == 0) { - hfCandOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kNonPrompt; - pdgCode = static_cast(Pdg::kD0); - } else if (hfCand.isSelD0() == 0 && hfCand.isSelD0bar() == 1) { - hfCandOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kNonPrompt; - pdgCode = static_cast(Pdg::kD0Bar); - } else { - hfCandOrigin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kFake; - pdgCode = 0; - } - } - outputPartsMC(hfCandOrigin, pdgCode, hfCand.pt(), hfHelper.yD0(hfCand), hfCand.phi()); - outputPartsMCLabels(outputPartsMC.lastIndex()); - } else { - outputPartsMCLabels(-1); - } - } - template bool fillCollisions(CollisionType const& col, TrackType const& tracks) { @@ -839,7 +916,7 @@ struct FemtoUniverseProducerTask { /// FemtoUniverseRun2 is defined V0M/2 multNtr = col.multTracklets(); } - if (confEvtUseTPCmult) { + if (ConfGeneral.confEvtUseTPCmult) { multNtr = col.multTPC(); } @@ -851,11 +928,19 @@ struct FemtoUniverseProducerTask { if (!colCuts.isSelected(col)) { return false; } - if (!confIsUsePileUp) { + + if (zorroMask.value != "") { + auto bc = col.template bc_as(); + initZorro(bc); + if (!zorro.isSelected(col.template bc_as().globalBC())) + return false; + } + + if (!ConfGeneral.confIsUsePileUp) { outputCollision(vtxZ, mult, multNtr, confDoSpher ? colCuts.computeSphericity(col, tracks) : 2, mMagField); colCuts.fillQA(col); return true; - } else if ((!confEvNoSameBunchPileup || col.selection_bit(aod::evsel::kNoSameBunchPileup)) && (!confEvIsGoodZvtxFT0vsPV || col.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) && (!confEvIsVertexITSTPC || col.selection_bit(aod::evsel::kIsVertexITSTPC))) { + } else if ((!ConfGeneral.confEvNoSameBunchPileup || col.selection_bit(aod::evsel::kNoSameBunchPileup)) && (!ConfGeneral.confEvIsGoodZvtxFT0vsPV || col.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) && (!ConfGeneral.confEvIsVertexITSTPC || col.selection_bit(aod::evsel::kIsVertexITSTPC))) { outputCollision(vtxZ, mult, multNtr, confDoSpher ? colCuts.computeSphericity(col, tracks) : 2, mMagField); colCuts.fillQA(col); return true; @@ -878,7 +963,7 @@ struct FemtoUniverseProducerTask { /// FemtoUniverseRun2 is defined V0M/2 multNtr = col.multTracklets(); } - if (confEvtUseTPCmult) { + if (ConfGeneral.confEvtUseTPCmult) { multNtr = col.multTPC(); } @@ -890,11 +975,11 @@ struct FemtoUniverseProducerTask { if (!colCuts.isSelected(col)) { return false; } - if (!confIsUsePileUp) { + if (!ConfGeneral.confIsUsePileUp) { outputCollision(vtxZ, mult, multNtr, confDoSpher ? colCuts.computeSphericity(col, tracks) : 2, mMagField); colCuts.fillQA(col); return true; - } else if ((!confEvNoSameBunchPileup || col.selection_bit(aod::evsel::kNoSameBunchPileup)) && (!confEvIsGoodZvtxFT0vsPV || col.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) && (!confEvIsVertexITSTPC || col.selection_bit(aod::evsel::kIsVertexITSTPC))) { + } else if ((!ConfGeneral.confEvNoSameBunchPileup || col.selection_bit(aod::evsel::kNoSameBunchPileup)) && (!ConfGeneral.confEvIsGoodZvtxFT0vsPV || col.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) && (!ConfGeneral.confEvIsVertexITSTPC || col.selection_bit(aod::evsel::kIsVertexITSTPC))) { outputCollision(vtxZ, mult, multNtr, confDoSpher ? colCuts.computeSphericity(col, tracks) : 2, mMagField); colCuts.fillQA(col); return true; @@ -911,7 +996,7 @@ struct FemtoUniverseProducerTask { float mult = confIsRun3 ? c.multFV0M() : 0.5 * (c.multFV0M()); int multNtr = confIsRun3 ? c.multNTracksPV() : c.multTracklets(); - if (std::abs(vtxZ) > confEvtZvtx) { + if (std::abs(vtxZ) > ConfGeneral.confEvtZvtx) { continue; } @@ -957,7 +1042,7 @@ struct FemtoUniverseProducerTask { // in case of trigger run - store such collisions but don't store any // particle candidates for such collisions - if (!colCuts.isSelectedRun3(col) || (occupancy < confTPCOccupancyMin || occupancy > confTPCOccupancyMax)) { + if (!colCuts.isSelectedRun3(col) || (occupancy < ConfGeneral.confTPCOccupancyMin || occupancy > ConfGeneral.confTPCOccupancyMax)) { return false; } else { if (col.selection_bit(aod::evsel::kNoSameBunchPileup) && @@ -979,7 +1064,7 @@ struct FemtoUniverseProducerTask { { const auto vtxZ = col.posZ(); - if (std::abs(vtxZ) > confEvtZvtx) { + if (std::abs(vtxZ) > ConfGeneral.confEvtZvtx) { return false; } else { outputCollision(vtxZ, 0, 0, 2, mMagField); @@ -1023,8 +1108,9 @@ struct FemtoUniverseProducerTask { track.phi(), aod::femtouniverseparticle::ParticleType::kTrack, cutContainer.at( femto_universe_track_selection::TrackContainerPosition::kCuts), - cutContainer.at( - femto_universe_track_selection::TrackContainerPosition::kPID), + confIsUseCutculator ? cutContainer.at( + femto_universe_track_selection::TrackContainerPosition::kPID) + : PIDBitmask(track), track.dcaXY(), childIDs, 0, track.sign()); // sign getter is mAntiLambda() @@ -1078,11 +1164,11 @@ struct FemtoUniverseProducerTask { v0.positiveeta(), v0.positivephi(), aod::femtouniverseparticle::ParticleType::kV0Child, cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kPosCuts), - cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kPosPID), + confIsUseCutculator ? cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kPosPID) : PIDBitmask(postrack), 0., childIDs, 0, - 0); + postrack.sign()); const int rowOfPosTrack = outputParts.lastIndex(); if constexpr (isMC) { fillMCParticle(postrack, o2::aod::femtouniverseparticle::ParticleType::kV0Child); @@ -1098,11 +1184,11 @@ struct FemtoUniverseProducerTask { v0.negativephi(), aod::femtouniverseparticle::ParticleType::kV0Child, cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kNegCuts), - cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kNegPID), + confIsUseCutculator ? cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kNegPID) : PIDBitmask(negtrack), 0., childIDs, 0, - 0); + negtrack.sign()); const int rowOfNegTrack = outputParts.lastIndex(); if constexpr (isMC) { fillMCParticle(negtrack, o2::aod::femtouniverseparticle::ParticleType::kV0Child); @@ -1160,12 +1246,12 @@ struct FemtoUniverseProducerTask { casc.positiveeta(), casc.positivephi(), aod::femtouniverseparticle::ParticleType::kV0Child, - 0, // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kPosCuts), - 0, // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kPosPID), + 0, // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kPosCuts), + PIDBitmask(posTrackCasc), // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kPosPID), hasTOF, childIDs, 0, - 0); + posTrackCasc.sign()); const int rowOfPosTrack = outputParts.lastIndex(); if constexpr (isMC) { fillMCParticle(posTrackCasc, o2::aod::femtouniverseparticle::ParticleType::kV0Child); @@ -1182,12 +1268,12 @@ struct FemtoUniverseProducerTask { casc.negativeeta(), casc.negativephi(), aod::femtouniverseparticle::ParticleType::kV0Child, - 0, // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kNegCuts), - 0, // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kNegPID), + 0, // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kNegCuts), + PIDBitmask(negTrackCasc), // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kNegPID), hasTOF, childIDs, 0, - 0); + negTrackCasc.sign()); const int rowOfNegTrack = outputParts.lastIndex(); if constexpr (isMC) { fillMCParticle(negTrackCasc, o2::aod::femtouniverseparticle::ParticleType::kV0Child); @@ -1205,12 +1291,12 @@ struct FemtoUniverseProducerTask { casc.bacheloreta(), casc.bachelorphi(), aod::femtouniverseparticle::ParticleType::kCascadeBachelor, - 0, // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kNegCuts), - 0, // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kNegPID), + 0, // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kNegCuts), + PIDBitmask(bachTrackCasc), // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kNegPID), hasTOF, childIDs, 0, - 0); + bachTrackCasc.sign()); const int rowOfBachTrack = outputParts.lastIndex(); if constexpr (isMC) { fillMCParticle(bachTrackCasc, o2::aod::femtouniverseparticle::ParticleType::kCascadeBachelor); @@ -1253,7 +1339,7 @@ struct FemtoUniverseProducerTask { } template - void fillD0mesons(CollisionType const&, TrackType const&, HfCandidate const& hfCands) + void fillD0D0barData(CollisionType const&, TrackType const&, HfCandidate const& hfCands) { std::vector childIDs = {0, 0}; // these IDs are necessary to keep track of the children std::vector tmpIDtrack; // this vector keeps track of the matching of the primary track table row <-> aod::track table global index @@ -1268,10 +1354,6 @@ struct FemtoUniverseProducerTask { continue; } - if (ConfD0Selection.confD0D0barCandMaxY >= 0. && std::abs(hfHelper.yD0(hfCand)) > ConfD0Selection.confD0D0barCandMaxY) { - continue; - } - if (std::abs(hfCand.eta()) > ConfD0Selection.confD0D0barCandEtaCut) { continue; } @@ -1376,15 +1458,14 @@ struct FemtoUniverseProducerTask { } template - void fillD0D0barUsingML(CollisionType const&, TrackType const&, HfCandidate const& hfCands) + void fillD0D0barDataMl(CollisionType const&, TrackType const&, HfCandidate const& hfCands) { std::vector childIDs = {0, 0}; // these IDs are necessary to keep track of the children std::vector tmpIDtrack; // this vector keeps track of the matching of the primary track table row <-> aod::track table global index double invMassD0 = 0.0; double invMassD0bar = 0.0; bool isD0D0bar = false; - double mlProbD0D0barBg = 0.0; - uint8_t daughFlag = 0; // flag = 0 (daugh of D0 or D0bar), 1 (daug of D0), -1 (daugh of D0bar) + int8_t daughFlag = 0; // flag = 0 (daugh of D0 or D0bar), 1 (daug of D0), -1 (daugh of D0bar) for (const auto& hfCand : hfCands) { @@ -1392,15 +1473,10 @@ struct FemtoUniverseProducerTask { continue; } - if (ConfD0Selection.confD0D0barCandMaxY >= 0. && std::abs(hfHelper.yD0(hfCand)) > ConfD0Selection.confD0D0barCandMaxY) { - continue; - } - if (std::abs(hfCand.eta()) > ConfD0Selection.confD0D0barCandEtaCut) { continue; } - // int postrackID = hfCand.prong0().globalIndex(); int postrackID = hfCand.prong0Id(); // Index to first prong int rowInPrimaryTrackTablePos = -1; rowInPrimaryTrackTablePos = getRowDaughters(postrackID, tmpIDtrack); @@ -1412,13 +1488,11 @@ struct FemtoUniverseProducerTask { if (hfCand.isSelD0() == 1 && hfCand.isSelD0bar() == 0) { invMassD0 = hfHelper.invMassD0ToPiK(hfCand); invMassD0bar = -hfHelper.invMassD0barToKPi(hfCand); - mlProbD0D0barBg = hfCand.mlProbD0()[0]; isD0D0bar = true; daughFlag = 1; } else if (hfCand.isSelD0() == 0 && hfCand.isSelD0bar() == 1) { invMassD0 = -hfHelper.invMassD0ToPiK(hfCand); invMassD0bar = hfHelper.invMassD0barToKPi(hfCand); - mlProbD0D0barBg = hfCand.mlProbD0bar()[0]; isD0D0bar = true; daughFlag = -1; } else if (hfCand.isSelD0() == 1 && hfCand.isSelD0bar() == 1) { @@ -1482,9 +1556,9 @@ struct FemtoUniverseProducerTask { hfCand.eta(), hfCand.phi(), aod::femtouniverseparticle::ParticleType::kD0, - -999, // cut, CutContainerType - -999, // PID, CutContainerType - mlProbD0D0barBg, // saving the probability for ML score class 1 + -999, // cut, CutContainerType + -999, // PID, CutContainerType + -999., // tempFitVar indexChildID, invMassD0, // D0 mass (mLambda) invMassD0bar); // D0bar mass (mAntiLambda) @@ -1492,9 +1566,9 @@ struct FemtoUniverseProducerTask { if (confIsDebug) { fillDebugParticle(postrack); // QA for positive daughter fillDebugParticle(negtrack); // QA for negative daughter - if (hfCand.isSelD0() == 1 && hfCand.isSelD0bar() == 0) { + if (hfCand.isSelD0() == 1) { fillDebugD0D0barML(hfCand); // QA for D0/D0bar - } else if (hfCand.isSelD0() == 0 && hfCand.isSelD0bar() == 1) { + } else if (hfCand.isSelD0bar() == 1) { fillDebugD0D0barML(hfCand); } else { fillDebugD0D0barML(hfCand); @@ -1507,6 +1581,145 @@ struct FemtoUniverseProducerTask { } } + template + void fillD0D0barMcMl(CollisionType const&, TrackType const&, HfCandidate const& hfCands, McPart const& mcParticles) + { + std::vector childIDs = {0, 0}; // these IDs are necessary to keep track of the children + std::vector tmpIDtrack; // this vector keeps track of the matching of the primary track table row <-> aod::track table global index + double invMassD0 = 0.0; + double invMassD0bar = 0.0; + bool isD0D0bar = false; + int indexMcRec = -1; + int8_t sign = 0; + int8_t daughFlag = 0; // flag = 0 (daugh of D0 or D0bar), 1 (daug of D0), -1 (daugh of D0bar) + + for (const auto& hfCand : hfCands) { + + if (!(hfCand.hfflag() & 1 << aod::hf_cand_2prong::DecayType::D0ToPiK)) { + continue; + } + + if (std::abs(hfCand.eta()) > ConfD0Selection.confD0D0barCandEtaCut) { + continue; + } + + // Check whether the D0 candidate has the corresponding MC particle + auto postrack = hfCand.template prong0_as(); + auto negtrack = hfCand.template prong1_as(); + auto arrayDaughters = std::array{postrack, negtrack}; + indexMcRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughters, Pdg::kD0, std::array{+kPiPlus, -kKPlus}, true, &sign); + + if (!(indexMcRec > -1)) { + continue; + } + + if (std::abs(hfCand.flagMcMatchRec()) == o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) { + int postrackID = hfCand.prong0Id(); // Index to first prong + int rowInPrimaryTrackTablePos = -1; + rowInPrimaryTrackTablePos = getRowDaughters(postrackID, tmpIDtrack); + childIDs[0] = rowInPrimaryTrackTablePos; + childIDs[1] = 0; + + if (hfCand.isSelD0() == 1 && hfCand.isSelD0bar() == 0) { + invMassD0 = hfHelper.invMassD0ToPiK(hfCand); + invMassD0bar = -hfHelper.invMassD0barToKPi(hfCand); + isD0D0bar = true; + daughFlag = 1; + } else if (hfCand.isSelD0() == 0 && hfCand.isSelD0bar() == 1) { + invMassD0 = -hfHelper.invMassD0ToPiK(hfCand); + invMassD0bar = hfHelper.invMassD0barToKPi(hfCand); + isD0D0bar = true; + daughFlag = -1; + } else if (hfCand.isSelD0() == 1 && hfCand.isSelD0bar() == 1) { + invMassD0 = hfHelper.invMassD0ToPiK(hfCand); + invMassD0bar = hfHelper.invMassD0barToKPi(hfCand); + if (ConfD0Selection.storeD0D0barDoubleMassHypo) { + isD0D0bar = true; + daughFlag = 0; + } else { + isD0D0bar = false; + daughFlag = 0; + } + } else { + invMassD0 = 0.0; + invMassD0bar = 0.0; + isD0D0bar = false; + } + + if (isD0D0bar) { + outputParts(outputCollision.lastIndex(), + hfCand.ptProng0(), + RecoDecay::eta(std::array{hfCand.pxProng0(), hfCand.pyProng0(), hfCand.pzProng0()}), // eta + RecoDecay::phi(hfCand.pxProng0(), hfCand.pyProng0()), // phi + aod::femtouniverseparticle::ParticleType::kD0Child, + -999, // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kPosCuts), + -999, // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kPosPID), + -999, + childIDs, + postrack.sign(), // D0 mass -> positive daughter of D0/D0bar + daughFlag); // D0bar mass -> sign that the daugh is from D0 or D0 decay + const int rowOfPosTrack = outputParts.lastIndex(); + if constexpr (isMC) { + fillMCParticle(postrack, o2::aod::femtouniverseparticle::ParticleType::kD0Child); + } + // int negtrackID = hfCand.prong1().globalIndex(); + int negtrackID = hfCand.prong1Id(); + int rowInPrimaryTrackTableNeg = -1; + rowInPrimaryTrackTableNeg = getRowDaughters(negtrackID, tmpIDtrack); + childIDs[0] = 0; + childIDs[1] = rowInPrimaryTrackTableNeg; + + outputParts(outputCollision.lastIndex(), + hfCand.ptProng1(), + RecoDecay::eta(std::array{hfCand.pxProng1(), hfCand.pyProng1(), hfCand.pzProng1()}), // eta + RecoDecay::phi(hfCand.pxProng1(), hfCand.pyProng1()), // phi + aod::femtouniverseparticle::ParticleType::kD0Child, + -999, // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kNegCuts), + -999, // cutContainerV0.at(femto_universe_v0_selection::V0ContainerPosition::kNegPID), + -999, + childIDs, + negtrack.sign(), // negative daughter of D0/D0bar + daughFlag); // sign that the daugh is from D0 or D0 decay + const int rowOfNegTrack = outputParts.lastIndex(); + if constexpr (isMC) { + fillMCParticle(negtrack, o2::aod::femtouniverseparticle::ParticleType::kD0Child); + } + std::vector indexChildID = {rowOfPosTrack, rowOfNegTrack}; + + outputParts(outputCollision.lastIndex(), + hfCand.pt(), + hfCand.eta(), + hfCand.phi(), + aod::femtouniverseparticle::ParticleType::kD0, + -999, // cut, CutContainerType + -999, // PID, CutContainerType + -999., // tempFitVar + indexChildID, + invMassD0, // D0 mass (mLambda) + invMassD0bar); // D0bar mass (mAntiLambda) + + if (confIsDebug) { + fillDebugParticle(postrack); // QA for positive daughter + fillDebugParticle(negtrack); // QA for negative daughter + if (hfCand.isSelD0() == 1) { + fillDebugD0D0barMcMl(hfCand); // QA for D0/D0bar + } else if (hfCand.isSelD0bar() == 1) { + fillDebugD0D0barMcMl(hfCand); + } else { + fillDebugD0D0barMcMl(hfCand); + } + } + if constexpr (isMC) { + auto particleMother = mcParticles.rawIteratorAt(indexMcRec); // gen. level pT + auto yGen = RecoDecay::y(particleMother.pVector(), o2::constants::physics::MassD0); // gen. level y + outputPartsMC(0, particleMother.pdgCode(), particleMother.pt(), yGen, particleMother.phi()); + outputPartsMCLabels(outputPartsMC.lastIndex()); + } + } + } + } + } + template void fillPhi(CollisionType const& col, TrackType const& tracks) { @@ -1559,7 +1772,7 @@ struct FemtoUniverseProducerTask { sumVec += part2Vec; float phiEta = sumVec.Eta(); - if (std::abs(phiEta) > 0.8) { + if (std::abs(phiEta) > ConfPhiSelection.confPhiEtaHighLimit.value) { continue; } @@ -1657,15 +1870,17 @@ struct FemtoUniverseProducerTask { uint32_t pdgCode = static_cast(particle.pdgCode()); - if (confMCTruthAnalysisWithPID) { + if (ConfGeneral.confMCTruthAnalysisWithPID) { bool pass = false; - std::vector tmpPDGCodes = confMCTruthPDGCodes; // necessary due to some features of the Configurable + std::vector tmpPDGCodes = ConfGeneral.confMCTruthPDGCodes; // necessary due to some features of the Configurable for (auto const& pdg : tmpPDGCodes) { if (static_cast(pdg) == static_cast(pdgCode)) { - if (pdgCode == 333) { // && (recoMcIds && recoMcIds->get().contains(particle.globalIndex()))) { // ATTENTION: all Phi mesons are NOT primary particles + if (pdgCode == Pdg::kPhi) { // && (recoMcIds && recoMcIds->get().contains(particle.globalIndex()))) { // ATTENTION: all Phi mesons are NOT primary particles + pass = true; + } else if (pdgCode == Pdg::kD0) { pass = true; } else { - if (confStoreMCmothers || particle.isPhysicalPrimary() || (confActivateSecondaries && recoMcIds && recoMcIds->get().contains(particle.globalIndex()))) + if (confStoreMCmothers || particle.isPhysicalPrimary() || (ConfGeneral.confActivateSecondaries && recoMcIds && recoMcIds->get().contains(particle.globalIndex()))) pass = true; } } @@ -1693,7 +1908,7 @@ struct FemtoUniverseProducerTask { continue; } - if (confIsActivateCascade) + if (ConfGeneral.confIsActivateCascade) childIDs.push_back(0); outputParts(outputCollision.lastIndex(), particle.pt(), @@ -1722,7 +1937,7 @@ struct FemtoUniverseProducerTask { childIDs[0] = 0; childIDs[1] = 0; auto minDaughs = 2ul; - if (confIsActivateCascade) { + if (ConfGeneral.confIsActivateCascade) { childIDs.push_back(0); minDaughs = 3ul; } @@ -1766,34 +1981,31 @@ struct FemtoUniverseProducerTask { } } - template - void fillMCTruthParticlesD0(TrackType const& tracks, std::optional>> recoMcIds = std::nullopt) + template + void fillMCTruthParticlesD0(TrackType const& mcParts) { std::vector childIDs = {0, 0}; // these IDs are necessary to keep track of the children std::vector tmpIDtrack; - for (const auto& particle : tracks) { - /// if the most open selection criteria are not fulfilled there is no - /// point looking further at the track - + for (const auto& particle : mcParts) { if (particle.eta() < -ConfFilterCuts.confEtaFilterCut || particle.eta() > ConfFilterCuts.confEtaFilterCut) continue; - if (particle.pt() < ConfFilterCuts.confPtLowFilterCut || particle.pt() > ConfFilterCuts.confPtHighFilterCut) + if (particle.pt() < ConfD0Selection.trackD0pTGenMin || particle.pt() > ConfD0Selection.trackD0pTGenMax) continue; - uint32_t pdgCode = static_cast(particle.pdgCode()); + int pdgCode = particle.pdgCode(); - if (confMCTruthAnalysisWithPID) { + if (ConfGeneral.confMCTruthAnalysisWithPID) { bool pass = false; - std::vector tmpPDGCodes = confMCTruthPDGCodes; // necessary due to some features of the Configurable + std::vector tmpPDGCodes = ConfGeneral.confMCTruthPDGCodes; // necessary due to some features of the Configurable for (auto const& pdg : tmpPDGCodes) { if (static_cast(pdg) == static_cast(pdgCode)) { - if (pdgCode == 333) { // && (recoMcIds && recoMcIds->get().contains(particle.globalIndex()))) { // ATTENTION: all Phi mesons are NOT primary particles + if (pdgCode == Pdg::kPhi) { pass = true; - } else if (pdgCode == 421) { + } else if (std::abs(pdgCode) == Pdg::kD0) { pass = true; } else { - if (particle.isPhysicalPrimary() || (confActivateSecondaries && recoMcIds && recoMcIds->get().contains(particle.globalIndex()))) + if (particle.isPhysicalPrimary()) pass = true; } } @@ -1802,51 +2014,31 @@ struct FemtoUniverseProducerTask { continue; } - // now the table is filled - if constexpr (resolveDaughs) { - tmpIDtrack.push_back(particle.globalIndex()); + /// check if we end-up with the correct final state using MC info + int8_t sign = 0; + int8_t origin = -99; + int8_t mcGenFlag = -99; + if (std::abs(particle.pdgCode()) == Pdg::kD0 && !RecoDecay::isMatchedMCGen(mcParts, particle, Pdg::kD0, std::array{+kPiPlus, -kKPlus}, true, &sign)) { + /// check if we have D0(bar) → π± K∓ continue; } - if (confIsActiveD0) { - - auto mcD0origin = aod::femtouniverseparticle::ParticleType::kMCTruthTrack; - float ptGenB = -1; - if (std::abs(particle.flagMcMatchGen()) == o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) { - if (ConfD0Selection.yD0D0barCandGenMax >= 0. && std::abs(RecoDecay::y(particle.pVector(), o2::constants::physics::MassD0)) > ConfD0Selection.yD0D0barCandGenMax) { - continue; - } - mcD0origin = aod::femtouniverseparticle::ParticleType::kMCTruthTrack; - // WORK IN PROGRESS: If needed changed it to prompt and non-prompt - /*if (particle.originMcGen() == RecoDecay::OriginType::Prompt) { - mcD0origin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kPrompt; - ptGenB = -1; - } else { - mcD0origin = aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kNonPrompt; - ptGenB = particle.idxBhadMotherPart().pt(); - }*/ - outputParts(outputCollision.lastIndex(), - particle.pt(), - particle.eta(), - particle.phi(), - mcD0origin, - 0, - pdgCode, - pdgCode, - childIDs, - RecoDecay::y(particle.pVector(), o2::constants::physics::MassD0), - ptGenB); // pT of the B hadron (mother particle, only when non-prompt D0) - } - } else { - outputParts(outputCollision.lastIndex(), - particle.pt(), - particle.eta(), - particle.phi(), - aod::femtouniverseparticle::ParticleType::kMCTruthTrack, - 0, - pdgCode, - pdgCode, - childIDs, 0, 0); + if (std::abs(particle.pdgCode()) == Pdg::kD0) { + origin = RecoDecay::getCharmHadronOrigin(mcParts, particle); + mcGenFlag = particle.flagMcMatchGen(); } + + outputParts(outputCollision.lastIndex(), + particle.pt(), + particle.eta(), + particle.phi(), + aod::femtouniverseparticle::ParticleType::kMCTruthTrack, + -999., + pdgCode, + pdgCode, // getter tempFitVar + childIDs, + mcGenFlag, + origin); // D0(bar) origin + if (confIsDebug) { fillDebugParticle(particle); } @@ -1855,44 +2047,7 @@ struct FemtoUniverseProducerTask { // aligned, so that they can be joined in the task. if constexpr (transientLabels) { outputPartsMCLabels(-1); - outputDebugPartsMC(9999); - } - } - if constexpr (resolveDaughs) { - childIDs[0] = 0; - childIDs[1] = 0; - for (std::size_t i = 0; i < tmpIDtrack.size(); i++) { - const auto& particle = tracks.iteratorAt(tmpIDtrack[i] - tracks.begin().globalIndex()); - for (int daughIndex = 0, n = std::min(2ul, particle.daughtersIds().size()); daughIndex < n; daughIndex++) { - // loop to find the corresponding index of the daughters - for (std::size_t j = 0; j < tmpIDtrack.size(); j++) { - if (tmpIDtrack[j] == particle.daughtersIds()[daughIndex]) { - childIDs[daughIndex] = i - j; - break; - } - } - } - outputParts(outputCollision.lastIndex(), - particle.pt(), - particle.eta(), - particle.phi(), - aod::femtouniverseparticle::ParticleType::kMCTruthTrack, - 0, - static_cast(particle.pdgCode()), - particle.pdgCode(), - childIDs, - 0, - 0); - if (confIsDebug) { - fillDebugParticle(particle); - } - - // Workaround to keep the FDParticles and MC label tables - // aligned, so that they can be joined in the task. - if constexpr (transientLabels) { - outputPartsMCLabels(-1); - outputDebugPartsMC(9999); - } + outputDebugPartsMC(-999); } } } @@ -1904,10 +2059,10 @@ struct FemtoUniverseProducerTask { const auto colcheck = fillCollisions(col, tracks); if (colcheck) { fillTracks(tracks); - if (confIsActivateV0) { + if (ConfGeneral.confIsActivateV0) { fillV0(col, fullV0s, tracks); } - if (confIsActivatePhi) { + if (ConfGeneral.confIsActivatePhi) { fillPhi(col, tracks); } } @@ -1963,10 +2118,10 @@ struct FemtoUniverseProducerTask { const auto colcheck = fillCollisions(col, tracks); if (colcheck) { fillTracks(tracks); - if (confIsActivateV0) { + if (ConfGeneral.confIsActivateV0) { fillV0(col, fullV0s, tracks); } - if (confIsActivateCascade) { + if (ConfGeneral.confIsActivateCascade) { fillCascade(col, fullCascades, tracks); } } @@ -2100,7 +2255,7 @@ struct FemtoUniverseProducerTask { const auto colcheck = fillCollisions(col, tracks); if (colcheck) { fillTracks(tracks); - fillD0mesons(col, tracks, candidates); + fillD0D0barData(col, tracks, candidates); } } PROCESS_SWITCH(FemtoUniverseProducerTask, processTrackD0mesonData, @@ -2117,7 +2272,7 @@ struct FemtoUniverseProducerTask { const auto colcheck = fillCollisions(col, tracks); if (colcheck) { fillTracks(tracks); - fillD0D0barUsingML(col, tracks, candidates); + fillD0D0barDataMl(col, tracks, candidates); } } PROCESS_SWITCH(FemtoUniverseProducerTask, processTrackD0DataML, @@ -2341,17 +2496,17 @@ struct FemtoUniverseProducerTask { } PROCESS_SWITCH(FemtoUniverseProducerTask, processTruthAndFullMCCentRun3Casc, "Provide both MC truth and reco for tracks and cascades with centrality", false); + Preslice> mcPartPerMcColl = aod::mcparticle::mcCollisionId; Preslice> perCollisionD0s = aod::track::collisionId; void processTrackD0MC(aod::McCollisions const& mccols, - aod::TracksWMc const&, soa::Join const& collisions, soa::Filtered> const& tracks, soa::Join const& hfMcGenCands, soa::Join const& hfMcRecoCands, - aod::BCsWithTimestamps const&) + aod::BCsWithTimestamps const&, + aod::McParticles const& mcParts) { // MC Reco - std::set recoMcIds; for (const auto& col : collisions) { auto groupedTracks = tracks.sliceBy(perCollisionTracks, col.globalIndex()); auto groupedD0s = hfMcRecoCands.sliceBy(perCollisionD0s, col.globalIndex()); @@ -2360,20 +2515,16 @@ struct FemtoUniverseProducerTask { // fill the tables const auto colcheck = fillCollisions(col, tracks); if (colcheck) { - fillTracks(tracks); - fillD0D0barUsingML(col, groupedTracks, groupedD0s); - for (const auto& track : groupedTracks) { - if (trackCuts.isSelectedMinimal(track)) - recoMcIds.insert(track.mcParticleId()); - } + fillTracks(groupedTracks); + fillD0D0barMcMl(col, groupedTracks, groupedD0s, mcParts); } } // MC Truth for (const auto& mccol : mccols) { - auto groupedMCParticles = hfMcGenCands.sliceBy(perMCCollision, mccol.globalIndex()); + auto groupedMCParticles = hfMcGenCands.sliceBy(mcPartPerMcColl, mccol.globalIndex()); auto groupedCollisions = collisions.sliceBy(recoCollsPerMCColl, mccol.globalIndex()); - fillMCTruthCollisions(groupedCollisions, groupedMCParticles); // fills the reco collisions for mc collision - fillMCTruthParticlesD0(groupedMCParticles, recoMcIds); // fills mc particles + fillMCTruthCollisions(groupedCollisions, groupedMCParticles); // fills the reco collisions for mc collision + fillMCTruthParticlesD0(groupedMCParticles); // fills mc particles } } PROCESS_SWITCH(FemtoUniverseProducerTask, processTrackD0MC, "Provide MC data for track D0 analysis", false); diff --git a/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt b/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt index cae7a17fc56..346188d08fd 100644 --- a/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt +++ b/PWGCF/FemtoUniverse/Tasks/CMakeLists.txt @@ -34,6 +34,11 @@ o2physics_add_dpl_workflow(femtouniverse-pair-track-nucleus PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(femtouniverse-pair-track-v0-helicity + SOURCES femtoUniversePairTaskTrackV0Helicity.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(femtouniverse-pair-track-track-threedrelmom-mult-kt-extended SOURCES femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx index fe1bf2e7983..f82657be1d9 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniverseDebugV0.cxx @@ -13,25 +13,30 @@ /// \brief Tasks that reads the particle tables and fills QA histograms for V0s /// \author Luca Barioglio, TU München, luca.barioglio@cern.ch /// \author Zuzanna Chochulska, WUT Warsaw & CTU Prague, zchochul@cern.ch +/// \author Anna-Mariia Andrushko, WUT Warsaw, anna-mariia.andrushko@cern.ch -#include -#include -#include -#include +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" +#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" + +#include "Common/DataModel/PIDResponse.h" + +#include "DataFormatsParameters/GRPObject.h" +#include "Framework/ASoAHelpers.h" #include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" #include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" +#include "Framework/O2DatabasePDGPlugin.h" #include "Framework/RunningWorkflowInfo.h" #include "Framework/StepTHn.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "DataFormatsParameters/GRPObject.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/PID.h" -#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" -#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" +#include + +#include +#include using namespace o2; using namespace o2::analysis::femto_universe; @@ -45,51 +50,70 @@ struct FemtoUniverseDebugV0 { SliceCache cache; - Configurable confPDGCodeV0{"confPDGCodeV0", 3122, "V0 -- PDG code"}; - Configurable confPDGCodePositiveChild{"confPDGCodePositiveChild", 2212, "Positive Child -- PDG code"}; - Configurable confPDGCodeNegativeChild{"confPDGCodeNegativeChild", 211, "Negative Child -- PDG code"}; - Configurable confCutV0{"confCutV0", 338, "V0 -- Selection bit from cutCulator"}; - ConfigurableAxis confV0TempFitVarBins{"confV0TempFitVarBins", {300, 0.95, 1.}, "V0: binning of the TempFitVar in the pT vs. TempFitVar plot"}; - ConfigurableAxis confV0TempFitVarpTBins{"confV0TempFitVarpTBins", {20, 0.5, 4.05}, "V0: pT binning of the pT vs. TempFitVar plot"}; - - Configurable confCutPositiveChild{"confCutPositiveChild", 150, "Positive Child of V0 -- Selection bit from cutCulator"}; - Configurable confCutNegativeChild{"confCutNegativeChild", 149, "Negative Child of V0 -- Selection bit from cutCulator"}; - Configurable confPositiveChildPIDnSigmaMax{"confPositiveChildPIDnSigmaMax", 3.f, "Positive Child of V0 -- Selection bit from cutCulator"}; - Configurable confNegativeChildPIDnSigmaMax{"confNegativeChildPIDnSigmaMax", 3.f, "Negative Child of V0 -- Selection bit from cutCulator"}; - Configurable confPositiveChildIndex{"confPositiveChildIndex", 1, "Positive Child of V0 -- Index from cutCulator"}; - Configurable confNegativeChildIndex{"confNegativeChildIndex", 0, "Negative Child of V0 -- Index from cutCulator"}; - Configurable> confChildPIDnSigmaMax{"confChildPIDnSigmaMax", std::vector{4.f, 3.f}, "V0 child selection: max. PID nSigma TPC"}; - Configurable confChildnSpecies{"confChildnSpecies", 2, "Number of particle spieces (for V0 children) with PID info"}; - ConfigurableAxis confChildTempFitVarBins{"confChildTempFitVarBins", {300, -0.15, 0.15}, "V0 child: binning of the TempFitVar in the pT vs. TempFitVar plot"}; - ConfigurableAxis confChildTempFitVarpTBins{"confChildTempFitVarpTBins", {20, 0.5, 4.05}, "V0 child: pT binning of the pT vs. TempFitVar plot"}; - + /// V0 configurables + struct : o2::framework::ConfigurableGroup { + Configurable confPDGCodeV0{"confPDGCodeV0", 3122, "V0 -- PDG code"}; + Configurable confPDGCodePositiveChild{"confPDGCodePositiveChild", 2212, "Positive Child -- PDG code"}; + Configurable confPDGCodeNegativeChild{"confPDGCodeNegativeChild", 211, "Negative Child -- PDG code"}; + Configurable confCutV0{"confCutV0", 338, "V0 -- Selection bit from cutCulator"}; + ConfigurableAxis confV0TempFitVarBins{"confV0TempFitVarBins", {300, 0.95, 1.}, "V0: binning of the TempFitVar in the pT vs. TempFitVar plot"}; + ConfigurableAxis confV0TempFitVarpTBins{"confV0TempFitVarpTBins", {20, 0.5, 4.05}, "V0: pT binning of the pT vs. TempFitVar plot"}; + } V0configs; // o2-linter: disable=name/function-variable + + /// Children configurables + struct : o2::framework::ConfigurableGroup { + Configurable confCutPositiveChild{"confCutPositiveChild", 150, "Positive Child of V0 -- Selection bit from cutCulator"}; + Configurable confCutNegativeChild{"confCutNegativeChild", 149, "Negative Child of V0 -- Selection bit from cutCulator"}; + Configurable confPositiveChildPIDnSigmaMax{"confPositiveChildPIDnSigmaMax", 3.f, "Positive Child of V0 -- Selection bit from cutCulator"}; + Configurable confNegativeChildPIDnSigmaMax{"confNegativeChildPIDnSigmaMax", 3.f, "Negative Child of V0 -- Selection bit from cutCulator"}; + Configurable confPositiveChildIndex{"confPositiveChildIndex", 1, "Positive Child of V0 -- Index from cutCulator"}; + Configurable confNegativeChildIndex{"confNegativeChildIndex", 0, "Negative Child of V0 -- Index from cutCulator"}; + Configurable> confChildPIDnSigmaMax{"confChildPIDnSigmaMax", std::vector{4.f, 3.f}, "V0 child selection: max. PID nSigma TPC"}; + Configurable confChildnSpecies{"confChildnSpecies", 2, "Number of particle spieces (for V0 children) with PID info"}; + ConfigurableAxis confChildTempFitVarBins{"confChildTempFitVarBins", {300, -0.15, 0.15}, "V0 child: binning of the TempFitVar in the pT vs. TempFitVar plot"}; + ConfigurableAxis confChildTempFitVarpTBins{"confChildTempFitVarpTBins", {20, 0.5, 4.05}, "V0 child: pT binning of the pT vs. TempFitVar plot"}; + } childconfigs; + + Configurable confIsMC{"confIsMC", false, "Enable additional histograms in the case of a Monte Carlo run"}; + + /// Partitioning using FemtoFullParticles = soa::Join; - Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kV0)) && ((aod::femtouniverseparticle::cut & confCutV0) == confCutV0); + + Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kV0)) && ((aod::femtouniverseparticle::cut & V0configs.confCutV0) == V0configs.confCutV0); + + Partition> partsOneMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kV0)) && ((aod::femtouniverseparticle::cut & V0configs.confCutV0) == V0configs.confCutV0); + Preslice perCol = aod::femtouniverseparticle::fdCollisionId; /// Histogramming FemtoUniverseEventHisto eventHisto; FemtoUniverseParticleHisto positiveChildHistos; FemtoUniverseParticleHisto negativeChildHistos; - FemtoUniverseParticleHisto V0Histos; + FemtoUniverseParticleHisto V0Histos; // o2-linter: disable=name/function-variable /// Histogram output - HistogramRegistry EventRegistry{"Event", {}, OutputObjHandlingPolicy::AnalysisObject}; - HistogramRegistry V0Registry{"FullV0QA", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry eventRegistry{"Event", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry V0Registry{"FullV0QA", {}, OutputObjHandlingPolicy::AnalysisObject}; // o2-linter: disable=name/function-variable HistogramRegistry thetaRegistry{"ThetaQA", {}, OutputObjHandlingPolicy::AnalysisObject}; void init(InitContext&) { - eventHisto.init(&EventRegistry); - positiveChildHistos.init(&V0Registry, confChildTempFitVarpTBins, confChildTempFitVarBins, false, confPDGCodePositiveChild.value, true); - negativeChildHistos.init(&V0Registry, confChildTempFitVarpTBins, confChildTempFitVarBins, false, confPDGCodeNegativeChild, true); - V0Histos.init(&V0Registry, confV0TempFitVarpTBins, confV0TempFitVarBins, false, confPDGCodeV0.value, true); + eventHisto.init(&eventRegistry); + positiveChildHistos.init(&V0Registry, childconfigs.confChildTempFitVarpTBins, childconfigs.confChildTempFitVarBins, confIsMC, V0configs.confPDGCodePositiveChild.value, true); + negativeChildHistos.init(&V0Registry, childconfigs.confChildTempFitVarpTBins, childconfigs.confChildTempFitVarBins, confIsMC, V0configs.confPDGCodeNegativeChild.value, true); + V0Histos.init(&V0Registry, V0configs.confV0TempFitVarpTBins, V0configs.confV0TempFitVarBins, confIsMC, V0configs.confPDGCodeV0.value, true); thetaRegistry.add("Theta/hTheta", " ; p (GeV/#it{c}); cos(#theta)", kTH2F, {{100, 0, 10}, {110, -1.1, 1.1}}); + thetaRegistry.add("Theta/PositiveChild/hThetaPt", " ; p_{T} (GeV/#it{c}); cos(#theta)", kTH2F, {{100, 0, 10}, {110, -1.1, 1.1}}); + thetaRegistry.add("Theta/PositiveChild/hThetaEta", " ; #eta; cos(#theta)", kTH2F, {{100, -1, 1}, {110, -1.1, 1.1}}); + thetaRegistry.add("Theta/PositiveChild/hThetaPhi", " ; #phi; cos(#theta)", kTH2F, {{100, -1, 7}, {110, -1.1, 1.1}}); + thetaRegistry.add("Theta/NegativeChild/hThetaPt", " ; p_{T} (GeV/#it{c}); cos(#theta)", kTH2F, {{100, 0, 10}, {110, -1.1, 1.1}}); + thetaRegistry.add("Theta/NegativeChild/hThetaEta", " ; #eta; cos(#theta)", kTH2F, {{100, -1, 1}, {110, -1.1, 1.1}}); + thetaRegistry.add("Theta/NegativeChild/hThetaPhi", " ; #phi; cos(#theta)", kTH2F, {{100, -1, 7}, {110, -1.1, 1.1}}); } - /// Produce QA plots for V0 selection in FemtoUniverse framework - void process(o2::aod::FdCollision const& col, FemtoFullParticles const& parts) + /// Produce QA plots for V0 and its children on real data + void processData(o2::aod::FdCollision const& col, FemtoFullParticles const& parts) { auto groupPartsOne = partsOne->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); eventHisto.fillQA(col); @@ -107,20 +131,70 @@ struct FemtoUniverseDebugV0 { // Check cuts on V0 children if (positiveChild.partType() == uint8_t(aod::femtouniverseparticle::ParticleType::kV0Child) && negativeChild.partType() == uint8_t(aod::femtouniverseparticle::ParticleType::kV0Child) && - isFullPIDSelected(positiveChild.pidCut(), positiveChild.p(), 999.f, confPositiveChildIndex.value, confChildnSpecies.value, confChildPIDnSigmaMax.value, confPositiveChildPIDnSigmaMax.value, 1.f) && - isFullPIDSelected(negativeChild.pidCut(), negativeChild.p(), 999.f, confNegativeChildIndex.value, confChildnSpecies.value, confChildPIDnSigmaMax.value, confNegativeChildPIDnSigmaMax.value, 1.f)) { - auto positiveChildMass = pdg->Mass(confPDGCodePositiveChild); - auto negativeChildMass = pdg->Mass(confPDGCodeNegativeChild); + isFullPIDSelected(positiveChild.pidCut(), positiveChild.p(), 999.f, childconfigs.confPositiveChildIndex.value, childconfigs.confChildnSpecies.value, childconfigs.confChildPIDnSigmaMax.value, childconfigs.confPositiveChildPIDnSigmaMax.value, 1.f) && + isFullPIDSelected(negativeChild.pidCut(), negativeChild.p(), 999.f, childconfigs.confNegativeChildIndex.value, childconfigs.confChildnSpecies.value, childconfigs.confChildPIDnSigmaMax.value, childconfigs.confNegativeChildPIDnSigmaMax.value, 1.f)) { + auto positiveChildMass = pdg->Mass(V0configs.confPDGCodePositiveChild); + auto negativeChildMass = pdg->Mass(V0configs.confPDGCodeNegativeChild); + auto positiveChildBoosted = FemtoUniverseMath::boostPRF(positiveChild, positiveChildMass, negativeChild, negativeChildMass); + auto cosineTheta = (positiveChildBoosted.Px() * part.px() + positiveChildBoosted.Py() * part.py() + positiveChildBoosted.Pz() * part.pz()) / (positiveChildBoosted.P() * part.p()); + + V0Histos.fillQA(part); + positiveChildHistos.fillQA(positiveChild); + negativeChildHistos.fillQA(negativeChild); + + thetaRegistry.fill(HIST("Theta/hTheta"), part.p(), cosineTheta); + thetaRegistry.fill(HIST("Theta/PositiveChild/hThetaPt"), positiveChild.pt(), cosineTheta); + thetaRegistry.fill(HIST("Theta/PositiveChild/hThetaEta"), positiveChild.eta(), cosineTheta); + thetaRegistry.fill(HIST("Theta/PositiveChild/hThetaPhi"), positiveChild.phi(), cosineTheta); + thetaRegistry.fill(HIST("Theta/NegativeChild/hThetaPt"), negativeChild.pt(), cosineTheta); + thetaRegistry.fill(HIST("Theta/NegativeChild/hThetaEta"), negativeChild.eta(), cosineTheta); + thetaRegistry.fill(HIST("Theta/NegativeChild/hThetaPhi"), negativeChild.phi(), cosineTheta); + } + } + } + PROCESS_SWITCH(FemtoUniverseDebugV0, processData, "Enable processing on real data", true); + + /// Produce QA plots for V0 and its children on Monte Carlo + void processMC(o2::aod::FdCollision const& col, soa::Join const& parts, o2::aod::FdMCParticles const&) + { + auto groupPartsOne = partsOneMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + eventHisto.fillQA(col); + for (const auto& part : groupPartsOne) { + if (!part.has_children()) { + continue; + } + const auto& positiveChild = parts.iteratorAt(part.index() - 2); + const auto& negativeChild = parts.iteratorAt(part.index() - 1); + if (positiveChild.globalIndex() != part.childrenIds()[0] || negativeChild.globalIndex() != part.childrenIds()[1]) { + LOG(warn) << "Indices of V0 children do not match"; + continue; + } + + // Check cuts on V0 children + if (positiveChild.partType() == uint8_t(aod::femtouniverseparticle::ParticleType::kV0Child) && + negativeChild.partType() == uint8_t(aod::femtouniverseparticle::ParticleType::kV0Child) && + isFullPIDSelected(positiveChild.pidCut(), positiveChild.p(), 999.f, childconfigs.confPositiveChildIndex.value, childconfigs.confChildnSpecies.value, childconfigs.confChildPIDnSigmaMax.value, childconfigs.confPositiveChildPIDnSigmaMax.value, 1.f) && + isFullPIDSelected(negativeChild.pidCut(), negativeChild.p(), 999.f, childconfigs.confNegativeChildIndex.value, childconfigs.confChildnSpecies.value, childconfigs.confChildPIDnSigmaMax.value, childconfigs.confNegativeChildPIDnSigmaMax.value, 1.f)) { + auto positiveChildMass = pdg->Mass(V0configs.confPDGCodePositiveChild); + auto negativeChildMass = pdg->Mass(V0configs.confPDGCodeNegativeChild); auto positiveChildBoosted = FemtoUniverseMath::boostPRF(positiveChild, positiveChildMass, negativeChild, negativeChildMass); auto cosineTheta = (positiveChildBoosted.Px() * part.px() + positiveChildBoosted.Py() * part.py() + positiveChildBoosted.Pz() * part.pz()) / (positiveChildBoosted.P() * part.p()); V0Histos.fillQA(part); positiveChildHistos.fillQA(positiveChild); negativeChildHistos.fillQA(negativeChild); + thetaRegistry.fill(HIST("Theta/hTheta"), part.p(), cosineTheta); + thetaRegistry.fill(HIST("Theta/PositiveChild/hThetaPt"), positiveChild.pt(), cosineTheta); + thetaRegistry.fill(HIST("Theta/PositiveChild/hThetaEta"), positiveChild.eta(), cosineTheta); + thetaRegistry.fill(HIST("Theta/PositiveChild/hThetaPhi"), positiveChild.phi(), cosineTheta); + thetaRegistry.fill(HIST("Theta/NegativeChild/hThetaPt"), negativeChild.pt(), cosineTheta); + thetaRegistry.fill(HIST("Theta/NegativeChild/hThetaEta"), negativeChild.eta(), cosineTheta); + thetaRegistry.fill(HIST("Theta/NegativeChild/hThetaPhi"), negativeChild.phi(), cosineTheta); } } } + PROCESS_SWITCH(FemtoUniverseDebugV0, processMC, "Enable processing on Monte Carlo", false); }; WorkflowSpec diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx index cc0ab0077c8..d974dd0f408 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniverseEfficiencyBase.cxx @@ -70,6 +70,7 @@ struct FemtoUniverseEfficiencyBase { /// Kaon configurable Configurable isKaonRun2{"isKaonRun2", false, "Enable kaon selection used in Run2"}; // to check consistency with Run2 results + Configurable isKaonLF{"isKaonLF", false, "Enable kaon selection used in LF group"}; // select kaons according to the selection in LF group struct : o2::framework::ConfigurableGroup { // Momentum thresholds for Run2 and Run3 Configurable confMomKaonRun2{"confMomKaonRun2", 0.4, "Momentum threshold for kaon identification using ToF (Run2)"}; @@ -93,6 +94,10 @@ struct FemtoUniverseEfficiencyBase { Configurable confKaonNsigmaTOFfrom055to15{"confKaonNsigmaTOFfrom055to15", 3.0, "Reject kaons within pT from 0.55 to 1.5 if ToF n sigma is above this value."}; Configurable confKaonNsigmaTPCfrom15{"confKaonNsigmaTPCfrom15", 3.0, "Reject kaons with pT above 1.5 if TPC n sigma is above this value."}; Configurable confKaonNsigmaTOFfrom15{"confKaonNsigmaTOFfrom15", 2.0, "Reject kaons with pT above 1.5 if ToF n sigma is above this value.."}; + // n sigma cuts as in LF + Configurable confMomKaonLF{"confMomKaonLF", 0.5, "Momentum threshold for kaon identification using TOF (LF selection)"}; + Configurable confNSigmaTPCKaonLF{"confNSigmaTPCKaonLF", 3.0, "TPC Kaon Sigma as in LF"}; + Configurable confNSigmaCombKaonLF{"confNSigmaCombKaonLF", 3.0, "TPC and TOF Kaon Sigma (combined) as in LF"}; } ConfKaonSelection; /// Deuteron configurables @@ -259,6 +264,25 @@ struct FemtoUniverseEfficiencyBase { } } + bool isKaonNSigmaLF(float mom, float nsigmaTPCK, float nsigmaTOFK) + { + if (mom < ConfKaonSelection.confMomKaonLF) { + if (std::abs(nsigmaTPCK) < ConfKaonSelection.confNSigmaTPCKaonLF) { + return true; + } else { + return false; + } + } else if (mom >= ConfKaonSelection.confMomKaonLF) { + if (std::sqrt(nsigmaTPCK * nsigmaTPCK + nsigmaTOFK * nsigmaTOFK) < ConfKaonSelection.confNSigmaCombKaonLF) { + return true; + } else { + return false; + } + } else { + return false; + } + } + bool isPionNSigma(float mom, float nsigmaTPCPi, float nsigmaTOFPi) { if (mom < ConfBothTracks.confMomPion) { @@ -303,7 +327,11 @@ struct FemtoUniverseEfficiencyBase { break; case 321: // Kaon+ case -321: // Kaon- - return isKaonNSigma(mom, nsigmaTPCK, nsigmaTOFK); + if (isKaonLF) { + return isKaonNSigmaLF(mom, nsigmaTPCK, nsigmaTOFK); + } else { + return isKaonNSigma(mom, nsigmaTPCK, nsigmaTOFK); + } break; case 1000010020: // Deuteron case -1000010020: // Antideuteron diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx index dd019a046db..8cad618d1dd 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackCascadeExtended.cxx @@ -14,22 +14,28 @@ /// \author Barbara Chytla, WUT Warsaw, barbara.chytla@cern.ch /// \author Shirajum Monira, WUT Warsaw, shirajum.monira@cern.ch -#include -#include -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" #include "PWGCF/FemtoUniverse/Core/femtoUtils.h" +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" + +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" #include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" + +#include + +#include +#include +#include +#include using namespace o2; using namespace o2::soa; @@ -43,16 +49,13 @@ struct femtoUniversePairTaskTrackCascadeExtended { Service pdgMC; SliceCache cache; using FemtoFullParticles = soa::Join; - Preslice perCol = aod::femtouniverseparticle::fdCollisionId; - - using FemtoRecoParticles = soa::Join; - Preslice perColReco = aod::femtouniverseparticle::fdCollisionId; + using FemtoRecoFullParticles = soa::Join; + using FemtoRecoBasicParticles = soa::Join; ConfigurableAxis confChildTempFitVarpTBins{"confChildTempFitVarpTBins", {20, 0.5, 4.05}, "V0 child: pT binning of the pT vs. TempFitVar plot"}; ConfigurableAxis confChildTempFitVarBins{"confChildTempFitVarBins", {300, -0.15, 0.15}, "V0 child: binning of the TempFitVar in the pT vs. TempFitVar plot"}; Configurable confCascInvMassLowLimit{"confCascInvMassLowLimit", 1.315, "Lower limit of the Casc invariant mass"}; Configurable confCascInvMassUpLimit{"confCascInvMassUpLimit", 1.325, "Upper limit of the Casc invariant mass"}; - Configurable confCascTranRad{"confCascTranRad", 0.5, "Cascade transverse radius"}; Configurable confNSigmaTPCPion{"confNSigmaTPCPion", 4, "NSigmaTPCPion"}; Configurable confNSigmaTPCProton{"confNSigmaTPCProton", 4, "NSigmaTPCProton"}; @@ -64,6 +67,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { // configurations for correlation part Configurable confTrackChoicePartOne{"confTrackChoicePartOne", 0, "0:Proton, 1:Pion, 2:Kaon"}; Configurable confTrkPDGCodePartOne{"confTrkPDGCodePartOne", 2212, "Particle 1 (Track) - PDG code"}; + Configurable confCascPDGCodePartTwo{"confCascPDGCodePartTwo", 3312, "Particle 2 (Cascade) - PDG code"}; Configurable confCascType1{"confCascType1", 0, "select one of the Cascades (Omega = 0, Xi = 1, anti-Omega = 2, anti-Xi = 3) for track-cascade combination"}; Configurable confCascType2{"confCascType2", 0, "select one of the Cascades (Omega = 0, Xi = 1, anti-Omega = 2, anti-Xi = 3) for cascade-cascade combination"}; Configurable confIsCPR{"confIsCPR", false, "Close Pair Rejection"}; @@ -83,6 +87,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { Configurable confNsigmaTPCParticle{"confNsigmaTPCParticle", 3.0, "TPC Sigma for particle (track) momentum < Confmom"}; Configurable confNsigmaCombinedParticle{"confNsigmaCombinedParticle", 3.0, "TPC and TOF Sigma (combined) for particle (track) momentum > Confmom"}; Configurable confNsigmaTPCParticleChild{"confNsigmaTPCParticleChild", 3.0, "TPC Sigma for particle (daugh & bach) momentum < Confmom"}; + Configurable confCheckTOFBachelorOnly{"confCheckTOFBachelorOnly", false, "Enable TOF for Cascade bachelor only"}; Configurable confNsigmaTOFParticleChild{"confNsigmaTOFParticleChild", 3.0, "TOF Sigma for particle (daugh & bach) momentum > Confmom"}; ConfigurableAxis confkstarBins{"confkstarBins", {1500, 0., 6.}, "binning kstar"}; @@ -101,22 +106,28 @@ struct femtoUniversePairTaskTrackCascadeExtended { ConfigurableAxis confTrkTempFitVarBins{"confTrkTempFitVarBins", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; Configurable confNEventsMix{"confNEventsMix", 5, "Number of events for mixing"}; + // Efficiency + Configurable confLocalEfficiency{"confLocalEfficiency", "", "Local path to efficiency .root file"}; + Filter collisionFilter = (nabs(aod::collision::posZ) < confZVertexCut); using FilteredFDCollisions = soa::Filtered; using FilteredFDCollision = FilteredFDCollisions::iterator; - /// Partition for particle 1 (track) - Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::sign == confChargePart1) && (nabs(aod::femtouniverseparticle::eta) < confEta) && (aod::femtouniverseparticle::pt < confHPtPart1) && (aod::femtouniverseparticle::pt > confLPtPart1); - Partition partsOneMCgen = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && (nabs(aod::femtouniverseparticle::eta) < confEta) && (aod::femtouniverseparticle::pt < confHPtPart1) && (aod::femtouniverseparticle::pt > confLPtPart1); - Partition partsOneMCreco = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::sign == confChargePart1) && (nabs(aod::femtouniverseparticle::eta) < confEta) && (aod::femtouniverseparticle::pt < confHPtPart1) && (aod::femtouniverseparticle::pt > confLPtPart1); + /// Partition for particle 1 using extended table (track) + Partition partsOneFull = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::mAntiLambda == confChargePart1) && (nabs(aod::femtouniverseparticle::eta) < confEta) && (aod::femtouniverseparticle::pt < confHPtPart1) && (aod::femtouniverseparticle::pt > confLPtPart1); + + /// Partition for particle 1 without extended table (track) + Partition partsOneBasic = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::mAntiLambda == confChargePart1) && (nabs(aod::femtouniverseparticle::eta) < confEta) && (aod::femtouniverseparticle::pt < confHPtPart1) && (aod::femtouniverseparticle::pt > confLPtPart1); + Partition partsOneMCgenBasic = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && (nabs(aod::femtouniverseparticle::eta) < confEta) && (aod::femtouniverseparticle::pt < confHPtPart1) && (aod::femtouniverseparticle::pt > confLPtPart1); + Partition partsOneMCrecoBasic = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::mAntiLambda == confChargePart1) && (nabs(aod::femtouniverseparticle::eta) < confEta) && (aod::femtouniverseparticle::pt < confHPtPart1) && (aod::femtouniverseparticle::pt > confLPtPart1); - /// Partition for particle 2 (cascade) - Partition partsTwo = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kCascade)) && (aod::femtouniverseparticle::pt < confHPtPart2) && (aod::femtouniverseparticle::pt > confLPtPart2); - Partition partsTwoMCgen = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && (aod::femtouniverseparticle::pt < confHPtPart2) && (aod::femtouniverseparticle::pt > confLPtPart2); - Partition partsTwoMCreco = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kCascade)) && (aod::femtouniverseparticle::pt < confHPtPart2) && (aod::femtouniverseparticle::pt > confLPtPart2); + /// Partition for particle 2 using extended table (cascade) + Partition partsTwoFull = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kCascade)) && (aod::femtouniverseparticle::pt < confHPtPart2) && (aod::femtouniverseparticle::pt > confLPtPart2); - /// Partition for cascades - Partition cascs = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kCascade)); + /// Partition for particle 2 without extended table (cascade) + Partition partsTwoBasic = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kCascade)) && (aod::femtouniverseparticle::pt < confHPtPart2) && (aod::femtouniverseparticle::pt > confLPtPart2); + Partition partsTwoMCgenBasic = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && (aod::femtouniverseparticle::pt < confHPtPart2) && (aod::femtouniverseparticle::pt > confLPtPart2); + Partition partsTwoMCrecoBasic = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kCascade)) && (aod::femtouniverseparticle::pt < confHPtPart2) && (aod::femtouniverseparticle::pt > confLPtPart2); /// Histogramming for track particle FemtoUniverseParticleHisto trackHistoPartOnePos; @@ -135,7 +146,8 @@ struct femtoUniversePairTaskTrackCascadeExtended { FemtoUniverseContainer mixedEventCont; FemtoUniversePairCleaner pairCleaner; FemtoUniversePairCleaner pairCleanerCasc; - FemtoUniverseDetaDphiStar pairCloseRejection; + FemtoUniverseDetaDphiStar pairCloseRejection; + FemtoUniverseDetaDphiStar pairCloseRejectionCasc; HistogramRegistry rXiQA{"xi", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; HistogramRegistry qaRegistry{"TrackQA", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -145,6 +157,10 @@ struct femtoUniversePairTaskTrackCascadeExtended { std::set cascDuplicates; + std::unique_ptr plocalEffFile; + std::unique_ptr plocalEffp1; + std::unique_ptr plocalEffp2; + // Table to select cascade daughters // Charges: = +--, +--, +-+, +-+ static constexpr unsigned int CascChildTable[][3] = {{0, 1, 2}, {0, 1, 1}, {1, 0, 2}, {1, 0, 1}}; @@ -187,18 +203,20 @@ struct femtoUniversePairTaskTrackCascadeExtended { } template - bool isParticleTPC(const T& part, int id) + bool isParticleTPC(const T& part, int id, float* partSigma = 0) { const float tpcNSigmas[3] = {unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tpcNSigmaStorePi()), unPackInTable(part.tpcNSigmaStoreKa())}; - + if (partSigma) + *partSigma = tpcNSigmas[id]; return isNSigmaTPC(tpcNSigmas[id]); } template - bool isParticleTOF(const T& part, int id) + bool isParticleTOF(const T& part, int id, float* partSigma = 0) { const float tofNSigmas[3] = {unPackInTable(part.tofNSigmaStorePr()), unPackInTable(part.tofNSigmaStorePi()), unPackInTable(part.tofNSigmaStoreKa())}; - + if (partSigma) + *partSigma = tofNSigmas[id]; return isNSigmaTOF(part.p(), tofNSigmas[id], part.tempFitVar()); } @@ -245,12 +263,20 @@ struct femtoUniversePairTaskTrackCascadeExtended { rXiQA.add("hInvMpTmult", "hInvMpTmult", kTH3F, {{ptAxis}, {aXiMassAxis}, {multAxis}}); eventHisto.init(&qaRegistry); + /// nSigma debug histograms for the selected particle species only i.e. not sigmas of all particles mixed together qaRegistry.add("Tracks_pos/nSigmaTPC", "; #it{p} (GeV/#it{c}); n#sigma_{TPC}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); qaRegistry.add("Tracks_pos/nSigmaTOF", "; #it{p} (GeV/#it{c}); n#sigma_{TOF}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); qaRegistry.add("Tracks_neg/nSigmaTPC", "; #it{p} (GeV/#it{c}); n#sigma_{TPC}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); qaRegistry.add("Tracks_neg/nSigmaTOF", "; #it{p} (GeV/#it{c}); n#sigma_{TOF}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); qaRegistry.add("MixingQA/hMECollisionBins", ";bin;Entries", kTH1F, {{120, -0.5, 119.5}}); + qaRegistry.add("V0Child_pos/nSigmaTPC", "; #it{p} (GeV/#it{c}); n#sigma_{TPC}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + qaRegistry.add("V0Child_neg/nSigmaTPC", "; #it{p} (GeV/#it{c}); n#sigma_{TPC}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + qaRegistry.add("hBachelor/nSigmaTPC", "; #it{p} (GeV/#it{c}); n#sigma_{TPC}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + qaRegistry.add("V0Child_pos/nSigmaTOF", "; #it{p} (GeV/#it{c}); n#sigma_{TOF}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + qaRegistry.add("V0Child_neg/nSigmaTOF", "; #it{p} (GeV/#it{c}); n#sigma_{TOF}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + qaRegistry.add("hBachelor/nSigmaTOF", "; #it{p} (GeV/#it{c}); n#sigma_{TOF}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + // MC gen registryMCgen.add("plus/MCgenCasc", "MC gen cascades;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); registryMCgen.add("minus/MCgenCasc", "MC gen cascades;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); @@ -286,36 +312,45 @@ struct femtoUniversePairTaskTrackCascadeExtended { sameEventCont.init(&resultRegistry, confkstarBins, confMultBins, confkTBins, confmTBins, confMultBins3D, confmTBins3D, confEtaBins, confPhiBins, confIsMC, confUse3D); mixedEventCont.init(&resultRegistry, confkstarBins, confMultBins, confkTBins, confmTBins, confMultBins3D, confmTBins3D, confEtaBins, confPhiBins, confIsMC, confUse3D); + sameEventCont.setPDGCodes(confTrkPDGCodePartOne, confCascPDGCodePartTwo); + mixedEventCont.setPDGCodes(confTrkPDGCodePartOne, confCascPDGCodePartTwo); + pairCleaner.init(&qaRegistry); pairCleanerCasc.init(&qaRegistry); if (confIsCPR.value) { - pairCloseRejection.init(&resultRegistry, &qaRegistry, confCPRdeltaPhiCutMin.value, confCPRdeltaPhiCutMax.value, confCPRdeltaEtaCutMin.value, confCPRdeltaEtaCutMax.value, confCPRChosenRadii.value, confCPRPlotPerRadii.value, 0, 0, confIsSameSignCPR.value); + if (doprocessSameEvent || doprocessSameEventBitmask || doprocessMixedEvent || doprocessMixedEventBitmask) + pairCloseRejection.init(&resultRegistry, &qaRegistry, confCPRdeltaPhiCutMin.value, confCPRdeltaPhiCutMax.value, confCPRdeltaEtaCutMin.value, confCPRdeltaEtaCutMax.value, confCPRChosenRadii.value, confCPRPlotPerRadii.value, 0, 0, confIsSameSignCPR.value); + if (doprocessSameEventCasc || doprocessSameEventCascBitmask || doprocessMixedEventCasc || doprocessMixedEventCascBitmask) + pairCloseRejectionCasc.init(&resultRegistry, &qaRegistry, confCPRdeltaPhiCutMin.value, confCPRdeltaPhiCutMax.value, confCPRdeltaEtaCutMin.value, confCPRdeltaEtaCutMax.value, confCPRChosenRadii.value, confCPRPlotPerRadii.value, 0, 0, confIsSameSignCPR.value); + } + + if (!confLocalEfficiency.value.empty()) { + plocalEffFile = std::unique_ptr(TFile::Open(confLocalEfficiency.value.c_str(), "read")); + if (!plocalEffFile || plocalEffFile.get()->IsZombie()) + LOGF(fatal, "Could not load efficiency histogram from %s", confLocalEfficiency.value.c_str()); + if (doprocessSameEvent || doprocessSameEventBitmask || doprocessMixedEvent || doprocessMixedEventBitmask) { + plocalEffp1 = (confChargePart1 > 0) ? std::unique_ptr(plocalEffFile.get()->Get("PrPlus")) : std::unique_ptr(plocalEffFile.get()->Get("PrMinus")); // note: works only for protons for now + plocalEffp2 = (confCascType1 == 0 || confCascType1 == 1) ? std::unique_ptr(plocalEffFile.get()->Get("Cascade")) : std::unique_ptr(plocalEffFile.get()->Get("AntiCascade")); + LOGF(info, "Loaded efficiency histograms for track-Cascade."); + } else if (doprocessSameEventCasc || doprocessSameEventCascBitmask || doprocessMixedEventCasc || doprocessMixedEventCascBitmask) { + plocalEffp1 = (confCascType1 == 0 || confCascType1 == 1) ? std::unique_ptr(plocalEffFile.get()->Get("Cascade")) : std::unique_ptr(plocalEffFile.get()->Get("AntiCascade")); + plocalEffp2 = (confCascType2 == 0 || confCascType2 == 1) ? std::unique_ptr(plocalEffFile.get()->Get("Cascade")) : std::unique_ptr(plocalEffFile.get()->Get("AntiCascade")); + LOGF(info, "Loaded efficiency histograms for Cascade-Cascade."); + } } } - void processCascades([[maybe_unused]] const FilteredFDCollision& col, const FemtoFullParticles& parts, const aod::FDCascParticles& fdcascs) + void processCascadeQA([[maybe_unused]] const FilteredFDCollision& col, const FemtoFullParticles& parts, const aod::FDCascParticles& fdcascs) { - // auto groupCascs = cascs->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - // const int multCol = col.multNtr(); - for (const auto& casc : fdcascs) { const auto& part = casc.fdParticle_as(); rXiQA.fill(HIST("hMassXi"), part.mLambda()); - // if (!invMCascade(casc.mLambda(), casc.mAntiLambda())) - // continue; - const auto& posChild = parts.iteratorAt(part.globalIndex() - 3 - parts.begin().globalIndex()); const auto& negChild = parts.iteratorAt(part.globalIndex() - 2 - parts.begin().globalIndex()); const auto& bachelor = parts.iteratorAt(part.globalIndex() - 1 - parts.begin().globalIndex()); - // if (casc.transRadius() < confCascTranRad) - // continue; - // std::cout< confNSigmaTPCProton) { continue; @@ -350,16 +385,19 @@ struct femtoUniversePairTaskTrackCascadeExtended { rXiQA.fill(HIST("hDcaBachtoPV"), casc.dcabachtopv()); rXiQA.fill(HIST("hDcaV0toPV"), casc.dcav0topv()); rXiQA.fill(HIST("hInvMpT"), part.pt(), part.mLambda()); - - posChildHistos.fillQA(posChild); - negChildHistos.fillQA(negChild); - bachHistos.fillQABase(bachelor, HIST("hBachelor")); } } - PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processCascades, "Enable processing cascades", false); + PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processCascadeQA, "Enable processing cascades", false); + + template + using hasSigma = decltype(std::declval().tpcNSigmaStorePr()); + /// track - cascade correlations - void processSameEvent(const FilteredFDCollision& col, const FemtoFullParticles& parts) + template + void doSameEvent(const FilteredFDCollision& col, const TableType& parts, PartitionType& partsOne, PartitionType& partsTwo) { + const auto& magFieldTesla = col.magField(); + auto groupPartsOne = partsOne->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); auto groupPartsTwo = partsTwo->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); @@ -371,70 +409,127 @@ struct femtoUniversePairTaskTrackCascadeExtended { if (!invMCascade(part.mLambda(), part.mAntiLambda(), confCascType1)) /// mLambda stores Xi mass, mAntiLambda stores Omega mass continue; - cascQAHistos.fillQA(part); - - const auto& posChild = parts.iteratorAt(part.index() - 3); - const auto& negChild = parts.iteratorAt(part.index() - 2); - const auto& bachelor = parts.iteratorAt(part.index() - 1); + const auto& posChild = parts.iteratorAt(part.globalIndex() - 3 - parts.begin().globalIndex()); + const auto& negChild = parts.iteratorAt(part.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& bachelor = parts.iteratorAt(part.globalIndex() - 1 - parts.begin().globalIndex()); /// Child particles must pass this condition to be selected - if (!isParticleTPC(posChild, CascChildTable[confCascType1][0]) || !isParticleTPC(negChild, CascChildTable[confCascType1][1]) || !isParticleTPC(bachelor, CascChildTable[confCascType1][2])) - continue; + if constexpr (std::experimental::is_detected::value) { + float posChildTPC, negChildTPC, bachelorTPC, posChildTOF, negChildTOF, bachelorTOF; + if (!isParticleTPC(posChild, CascChildTable[confCascType1][0], &posChildTPC) || !isParticleTPC(negChild, CascChildTable[confCascType1][1], &negChildTPC) || !isParticleTPC(bachelor, CascChildTable[confCascType1][2], &bachelorTPC)) + continue; - if (!isParticleTOF(posChild, CascChildTable[confCascType1][0]) || !isParticleTOF(negChild, CascChildTable[confCascType1][1]) || !isParticleTOF(bachelor, CascChildTable[confCascType1][2])) - continue; + if ((!confCheckTOFBachelorOnly && (!isParticleTOF(posChild, CascChildTable[confCascType1][0], &posChildTOF) || !isParticleTOF(negChild, CascChildTable[confCascType1][1], &negChildTOF))) || !isParticleTOF(bachelor, CascChildTable[confCascType1][2], &bachelorTOF)) + continue; + + posChildHistos.fillQA(posChild); + negChildHistos.fillQA(negChild); + bachHistos.fillQABase(bachelor, HIST("hBachelor")); - posChildHistos.fillQA(posChild); - negChildHistos.fillQA(negChild); - bachHistos.fillQABase(bachelor, HIST("hBachelor")); + qaRegistry.fill(HIST("V0Child_pos/nSigmaTPC"), posChild.p(), posChildTPC); + qaRegistry.fill(HIST("V0Child_neg/nSigmaTPC"), negChild.p(), negChildTPC); + qaRegistry.fill(HIST("hBachelor/nSigmaTPC"), bachelor.p(), bachelorTPC); + if (!confCheckTOFBachelorOnly) { + qaRegistry.fill(HIST("V0Child_pos/nSigmaTOF"), posChild.p(), posChildTOF); + qaRegistry.fill(HIST("V0Child_neg/nSigmaTOF"), negChild.p(), negChildTOF); + } + qaRegistry.fill(HIST("hBachelor/nSigmaTOF"), bachelor.p(), bachelorTOF); + + cascQAHistos.fillQA(part); + + } else { + if ((posChild.pidCut() & (1u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[confCascType1][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[confCascType1][2])) == 0) + continue; + + if ((!confCheckTOFBachelorOnly && ((posChild.pidCut() & (8u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[confCascType1][1])) == 0)) || (bachelor.pidCut() & (8u << CascChildTable[confCascType1][2])) == 0) + continue; + posChildHistos.fillQA(posChild); + negChildHistos.fillQA(negChild); + bachHistos.fillQABase(bachelor, HIST("hBachelor")); + cascQAHistos.fillQA(part); + } rXiQA.fill(HIST("hInvMpTmult"), part.pt(), part.mLambda(), multCol); } - for (const auto& part : groupPartsOne) { - /// PID plot for track particle - const float tpcNSigmas[3] = {unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tpcNSigmaStorePi()), unPackInTable(part.tpcNSigmaStoreKa())}; - const float tofNSigmas[3] = {unPackInTable(part.tofNSigmaStorePr()), unPackInTable(part.tofNSigmaStorePi()), unPackInTable(part.tofNSigmaStoreKa())}; + if constexpr (std::experimental::is_detected::value) { + for (const auto& part : groupPartsOne) { + /// PID plot for track particle + const float tpcNSigmas[3] = {unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tpcNSigmaStorePi()), unPackInTable(part.tpcNSigmaStoreKa())}; + const float tofNSigmas[3] = {unPackInTable(part.tofNSigmaStorePr()), unPackInTable(part.tofNSigmaStorePi()), unPackInTable(part.tofNSigmaStoreKa())}; - if (!isNSigmaCombined(part.p(), tpcNSigmas[confTrackChoicePartOne], tofNSigmas[confTrackChoicePartOne])) - continue; + if (!isNSigmaCombined(part.p(), tpcNSigmas[confTrackChoicePartOne], tofNSigmas[confTrackChoicePartOne])) + continue; - if (part.sign() > 0) { - qaRegistry.fill(HIST("Tracks_pos/nSigmaTPC"), part.p(), tpcNSigmas[confTrackChoicePartOne]); - qaRegistry.fill(HIST("Tracks_pos/nSigmaTOF"), part.p(), tofNSigmas[confTrackChoicePartOne]); - trackHistoPartOnePos.fillQA(part); - } else if (part.sign() < 0) { - qaRegistry.fill(HIST("Tracks_neg/nSigmaTPC"), part.p(), tpcNSigmas[confTrackChoicePartOne]); - qaRegistry.fill(HIST("Tracks_neg/nSigmaTOF"), part.p(), tofNSigmas[confTrackChoicePartOne]); - trackHistoPartOneNeg.fillQA(part); + if (part.mAntiLambda() > 0) { + qaRegistry.fill(HIST("Tracks_pos/nSigmaTPC"), part.p(), tpcNSigmas[confTrackChoicePartOne]); + qaRegistry.fill(HIST("Tracks_pos/nSigmaTOF"), part.p(), tofNSigmas[confTrackChoicePartOne]); + trackHistoPartOnePos.fillQA(part); + } else if (part.mAntiLambda() < 0) { + qaRegistry.fill(HIST("Tracks_neg/nSigmaTPC"), part.p(), tpcNSigmas[confTrackChoicePartOne]); + qaRegistry.fill(HIST("Tracks_neg/nSigmaTOF"), part.p(), tofNSigmas[confTrackChoicePartOne]); + trackHistoPartOneNeg.fillQA(part); + } } } - for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { // Cascade inv mass cut (mLambda stores Xi mass, mAntiLambda stores Omega mass) if (!invMCascade(p2.mLambda(), p2.mAntiLambda(), confCascType1)) continue; // PID - if (!isParticleCombined(p1, confTrackChoicePartOne)) - continue; + if constexpr (std::experimental::is_detected::value) { + if (!isParticleCombined(p1, confTrackChoicePartOne)) + continue; + } else { + if ((p1.pidCut() & (64u << confTrackChoicePartOne)) == 0) + continue; + } // track cleaning if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; } - const auto& posChild = parts.iteratorAt(p2.index() - 3); - const auto& negChild = parts.iteratorAt(p2.index() - 2); - const auto& bachelor = parts.iteratorAt(p2.index() - 1); - /// Child particles must pass this condition to be selected - if (!isParticleTPC(posChild, CascChildTable[confCascType1][0]) || !isParticleTPC(negChild, CascChildTable[confCascType1][1]) || !isParticleTPC(bachelor, CascChildTable[confCascType1][2])) - continue; - if (!isParticleTOF(posChild, CascChildTable[confCascType1][0]) || !isParticleTOF(negChild, CascChildTable[confCascType1][1]) || !isParticleTOF(bachelor, CascChildTable[confCascType1][2])) - continue; + if (confIsCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla, femto_universe_container::EventType::same)) { + continue; + } + } - sameEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); + const auto& posChild = parts.iteratorAt(p2.globalIndex() - 3 - parts.begin().globalIndex()); + const auto& negChild = parts.iteratorAt(p2.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& bachelor = parts.iteratorAt(p2.globalIndex() - 1 - parts.begin().globalIndex()); + /// Child particles must pass this condition to be selected + if constexpr (std::experimental::is_detected::value) { + if (!isParticleTPC(posChild, CascChildTable[confCascType1][0]) || !isParticleTPC(negChild, CascChildTable[confCascType1][1]) || !isParticleTPC(bachelor, CascChildTable[confCascType1][2])) + continue; + if ((!confCheckTOFBachelorOnly && (!isParticleTOF(posChild, CascChildTable[confCascType1][0]) || !isParticleTOF(negChild, CascChildTable[confCascType1][1]))) || !isParticleTOF(bachelor, CascChildTable[confCascType1][2])) + continue; + } else { + if ((posChild.pidCut() & (1u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[confCascType1][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[confCascType1][2])) == 0) + continue; + if ((!confCheckTOFBachelorOnly && ((posChild.pidCut() & (8u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[confCascType1][1])) == 0)) || (bachelor.pidCut() & (8u << CascChildTable[confCascType1][2])) == 0) + continue; + } + float weight = 1.0f; + if (plocalEffp1) + weight = plocalEffp1.get()->GetBinContent(plocalEffp1->FindBin(p1.pt(), p1.eta())) * plocalEffp2.get()->GetBinContent(plocalEffp2->FindBin(p2.pt(), p2.eta())); + sameEventCont.setPair(p1, p2, multCol, confUse3D, weight); } } + + void processSameEvent(const FilteredFDCollision& col, const FemtoFullParticles& parts) + { + doSameEvent(col, parts, partsOneFull, partsTwoFull); + } PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processSameEvent, "Enable processing same event for track - cascade", false); + + void processSameEventBitmask(const FilteredFDCollision& col, const aod::FDParticles& parts) + { + doSameEvent(col, parts, partsOneBasic, partsTwoBasic); + } + PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processSameEventBitmask, "Enable processing same event for track - cascade using bitmask for PID", false); + /// cascade - cascade correlations - void processSameEventCasc(const FilteredFDCollision& col, const FemtoFullParticles& parts) + template + void doSameEventCasc(const FilteredFDCollision& col, const TableType& parts, PartitionType& partsTwo) { const auto& magFieldTesla = col.magField(); @@ -448,23 +543,34 @@ struct femtoUniversePairTaskTrackCascadeExtended { if (!invMCascade(part.mLambda(), part.mAntiLambda(), confCascType1)) /// mLambda stores Xi mass, mAntiLambda stores Omega mass continue; - cascQAHistos.fillQA(part); + if constexpr (std::experimental::is_detected::value) + cascQAHistos.fillQA(part); + else + cascQAHistos.fillQA(part); - const auto& posChild = parts.iteratorAt(part.index() - 3); - const auto& negChild = parts.iteratorAt(part.index() - 2); - const auto& bachelor = parts.iteratorAt(part.index() - 1); + const auto& posChild = parts.iteratorAt(part.globalIndex() - 3 - parts.begin().globalIndex()); + const auto& negChild = parts.iteratorAt(part.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& bachelor = parts.iteratorAt(part.globalIndex() - 1 - parts.begin().globalIndex()); /// Check daughters of first cascade - if (!isParticleTPC(posChild, CascChildTable[confCascType1][0]) || !isParticleTPC(negChild, CascChildTable[confCascType1][1]) || !isParticleTPC(bachelor, CascChildTable[confCascType1][2])) - continue; - if (!isParticleTOF(posChild, CascChildTable[confCascType1][0]) || !isParticleTOF(negChild, CascChildTable[confCascType1][1]) || !isParticleTOF(bachelor, CascChildTable[confCascType1][2])) - continue; + if constexpr (std::experimental::is_detected::value) { + if (!isParticleTPC(posChild, CascChildTable[confCascType1][0]) || !isParticleTPC(negChild, CascChildTable[confCascType1][1]) || !isParticleTPC(bachelor, CascChildTable[confCascType1][2])) + continue; + if ((!confCheckTOFBachelorOnly && (!isParticleTOF(posChild, CascChildTable[confCascType1][0]) || !isParticleTOF(negChild, CascChildTable[confCascType1][1]))) || !isParticleTOF(bachelor, CascChildTable[confCascType1][2])) + continue; - posChildHistos.fillQA(posChild); - negChildHistos.fillQA(negChild); - bachHistos.fillQABase(bachelor, HIST("hBachelor")); - /// Check daughters of second cascade - /*if (isParticleTPC(posChild, CascChildTable[confCascType2][0]) && isParticleTPC(negChild, CascChildTable[confCascType2][1]) && isParticleTPC(bachelor, CascChildTable[confCascType2][2])) { - }*/ + posChildHistos.fillQA(posChild); + negChildHistos.fillQA(negChild); + bachHistos.fillQABase(bachelor, HIST("hBachelor")); + } else { + if ((posChild.pidCut() & (1u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[confCascType1][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[confCascType1][2])) == 0) + continue; + if ((!confCheckTOFBachelorOnly && ((posChild.pidCut() & (8u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[confCascType1][1])) == 0)) || (bachelor.pidCut() & (8u << CascChildTable[confCascType1][2])) == 0) + continue; + + posChildHistos.fillQA(posChild); + negChildHistos.fillQA(negChild); + bachHistos.fillQABase(bachelor, HIST("hBachelor")); + } } auto pairDuplicateCheckFunc = [&](auto& p1, auto& p2) -> void { @@ -490,28 +596,47 @@ struct femtoUniversePairTaskTrackCascadeExtended { if (!invMCascade(p2.mLambda(), p2.mAntiLambda(), confCascType2)) return; if (confIsCPR.value) { - if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla, femto_universe_container::EventType::same)) { + if (pairCloseRejectionCasc.isClosePair(p1, p2, parts, magFieldTesla, femto_universe_container::EventType::same)) { return; } } - const auto& posChild1 = parts.iteratorAt(p1.index() - 3); - const auto& negChild1 = parts.iteratorAt(p1.index() - 2); - const auto& bachelor1 = parts.iteratorAt(p1.index() - 1); + + const auto& posChild1 = parts.iteratorAt(p1.globalIndex() - 3 - parts.begin().globalIndex()); + const auto& negChild1 = parts.iteratorAt(p1.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& bachelor1 = parts.iteratorAt(p1.globalIndex() - 1 - parts.begin().globalIndex()); /// Child particles must pass this condition to be selected - if (!isParticleTPC(posChild1, CascChildTable[confCascType1][0]) || !isParticleTPC(negChild1, CascChildTable[confCascType1][1]) || !isParticleTPC(bachelor1, CascChildTable[confCascType1][2])) - return; - if (!isParticleTOF(posChild1, CascChildTable[confCascType1][0]) || !isParticleTOF(negChild1, CascChildTable[confCascType1][1]) || !isParticleTOF(bachelor1, CascChildTable[confCascType1][2])) - return; - const auto& posChild2 = parts.iteratorAt(p2.index() - 3); - const auto& negChild2 = parts.iteratorAt(p2.index() - 2); - const auto& bachelor2 = parts.iteratorAt(p2.index() - 1); + if constexpr (std::experimental::is_detected::value) { + if (!isParticleTPC(posChild1, CascChildTable[confCascType1][0]) || !isParticleTPC(negChild1, CascChildTable[confCascType1][1]) || !isParticleTPC(bachelor1, CascChildTable[confCascType1][2])) + return; + if ((!confCheckTOFBachelorOnly && (!isParticleTOF(posChild1, CascChildTable[confCascType1][0]) || !isParticleTOF(negChild1, CascChildTable[confCascType1][1]))) || !isParticleTOF(bachelor1, CascChildTable[confCascType1][2])) + return; + } else { + if ((posChild1.pidCut() & (1u << CascChildTable[confCascType1][0])) == 0 || (negChild1.pidCut() & (1u << CascChildTable[confCascType1][1])) == 0 || (bachelor1.pidCut() & (1u << CascChildTable[confCascType1][2])) == 0) + return; + if ((!confCheckTOFBachelorOnly && ((posChild1.pidCut() & (8u << CascChildTable[confCascType1][0])) == 0 || (negChild1.pidCut() & (8u << CascChildTable[confCascType1][1])) == 0)) || (bachelor1.pidCut() & (8u << CascChildTable[confCascType1][2])) == 0) + return; + } + + const auto& posChild2 = parts.iteratorAt(p2.globalIndex() - 3 - parts.begin().globalIndex()); + const auto& negChild2 = parts.iteratorAt(p2.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& bachelor2 = parts.iteratorAt(p2.globalIndex() - 1 - parts.begin().globalIndex()); /// Child particles must pass this condition to be selected - if (!isParticleTPC(posChild2, CascChildTable[confCascType2][0]) || !isParticleTPC(negChild2, CascChildTable[confCascType2][1]) || !isParticleTPC(bachelor2, CascChildTable[confCascType2][2])) - return; - if (!isParticleTOF(posChild2, CascChildTable[confCascType2][0]) || !isParticleTOF(negChild2, CascChildTable[confCascType2][1]) || !isParticleTOF(bachelor2, CascChildTable[confCascType2][2])) - return; + if constexpr (std::experimental::is_detected::value) { + if (!isParticleTPC(posChild2, CascChildTable[confCascType2][0]) || !isParticleTPC(negChild2, CascChildTable[confCascType2][1]) || !isParticleTPC(bachelor2, CascChildTable[confCascType2][2])) + return; + if ((!confCheckTOFBachelorOnly && (!isParticleTOF(posChild2, CascChildTable[confCascType2][0]) || !isParticleTOF(negChild2, CascChildTable[confCascType2][1]))) || !isParticleTOF(bachelor2, CascChildTable[confCascType2][2])) + return; + } else { + if ((posChild2.pidCut() & (1u << CascChildTable[confCascType1][0])) == 0 || (negChild2.pidCut() & (1u << CascChildTable[confCascType1][1])) == 0 || (bachelor2.pidCut() & (1u << CascChildTable[confCascType1][2])) == 0) + return; + if ((!confCheckTOFBachelorOnly && ((posChild2.pidCut() & (8u << CascChildTable[confCascType1][0])) == 0 || (negChild2.pidCut() & (8u << CascChildTable[confCascType1][1])) == 0)) || (bachelor2.pidCut() & (8u << CascChildTable[confCascType1][2])) == 0) + return; + } - sameEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); + float weight = 1.0f; + if (plocalEffp1) + weight = plocalEffp1.get()->GetBinContent(plocalEffp1->FindBin(p1.pt(), p1.eta())) * plocalEffp2.get()->GetBinContent(plocalEffp2->FindBin(p2.pt(), p2.eta())); + sameEventCont.setPair(p1, p2, multCol, confUse3D, weight); }; cascDuplicates.clear(); if (confCascType1 == confCascType2) { @@ -532,9 +657,22 @@ struct femtoUniversePairTaskTrackCascadeExtended { } } } + + void processSameEventCasc(const FilteredFDCollision& col, const FemtoFullParticles& parts) + { + doSameEventCasc(col, parts, partsTwoFull); + } PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processSameEventCasc, "Enable processing same event for cascade - cascade", false); + + void processSameEventCascBitmask(const FilteredFDCollision& col, const aod::FDParticles& parts) + { + doSameEventCasc(col, parts, partsTwoBasic); + } + PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processSameEventCascBitmask, "Enable processing same event for cascade - cascade using bitmask for PID", false); + /// track - cascade correlations - void processMixedEvent(const FilteredFDCollisions& cols, const FemtoFullParticles& parts) + template + void doMixedEvent(const FilteredFDCollisions& cols, const TableType& parts, PartitionType& partsOne, PartitionType& partsTwo) { ColumnBinningPolicy colBinningMult{{confVtxBins, confMultBins}, true}; ColumnBinningPolicy colBinningCent{{confVtxBins, confMultBins}, true}; @@ -556,24 +694,44 @@ struct femtoUniversePairTaskTrackCascadeExtended { if (!invMCascade(p2.mLambda(), p2.mAntiLambda(), confCascType1)) continue; // PID - if (!isParticleCombined(p1, confTrackChoicePartOne)) - continue; + if constexpr (std::experimental::is_detected::value) { + if (!isParticleCombined(p1, confTrackChoicePartOne)) + continue; + } else { + if ((p1.pidCut() & (64u << confTrackChoicePartOne)) == 0) + continue; + } - const auto& posChild = parts.iteratorAt(p2.index() - 3); - const auto& negChild = parts.iteratorAt(p2.index() - 2); - const auto& bachelor = parts.iteratorAt(p2.index() - 1); + const auto& posChild = parts.iteratorAt(p2.globalIndex() - 3 - parts.begin().globalIndex()); + const auto& negChild = parts.iteratorAt(p2.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& bachelor = parts.iteratorAt(p2.globalIndex() - 1 - parts.begin().globalIndex()); /// Child particles must pass this condition to be selected - if (!isParticleTPC(posChild, CascChildTable[confCascType1][0]) || !isParticleTPC(negChild, CascChildTable[confCascType1][1]) || !isParticleTPC(bachelor, CascChildTable[confCascType1][2])) - continue; - if (!isParticleTOF(posChild, CascChildTable[confCascType1][0]) || !isParticleTOF(negChild, CascChildTable[confCascType1][1]) || !isParticleTOF(bachelor, CascChildTable[confCascType1][2])) - continue; + if constexpr (std::experimental::is_detected::value) { + if (!isParticleTPC(posChild, CascChildTable[confCascType1][0]) || !isParticleTPC(negChild, CascChildTable[confCascType1][1]) || !isParticleTPC(bachelor, CascChildTable[confCascType1][2])) + continue; + if ((!confCheckTOFBachelorOnly && (!isParticleTOF(posChild, CascChildTable[confCascType1][0]) || !isParticleTOF(negChild, CascChildTable[confCascType1][1]))) || !isParticleTOF(bachelor, CascChildTable[confCascType1][2])) + continue; + } else { + if ((posChild.pidCut() & (1u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[confCascType1][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[confCascType1][2])) == 0) + continue; + if ((!confCheckTOFBachelorOnly && ((posChild.pidCut() & (8u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[confCascType1][1])) == 0)) || (bachelor.pidCut() & (8u << CascChildTable[confCascType1][2])) == 0) + continue; + } // track cleaning if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; } + if (confIsCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla1, femto_universe_container::EventType::mixed)) { + continue; + } + } - mixedEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); + float weight = 1.0f; + if (plocalEffp1) + weight = plocalEffp1.get()->GetBinContent(plocalEffp1->FindBin(p1.pt(), p1.eta())) * plocalEffp2.get()->GetBinContent(plocalEffp2->FindBin(p2.pt(), p2.eta())); + mixedEventCont.setPair(p1, p2, multCol, confUse3D, weight); } }; @@ -589,9 +747,22 @@ struct femtoUniversePairTaskTrackCascadeExtended { } } } + + void processMixedEvent(const FilteredFDCollisions& cols, const FemtoFullParticles& parts) + { + doMixedEvent(cols, parts, partsOneFull, partsTwoFull); + } PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processMixedEvent, "Enable processing mixed event for track - cascade", false); + + void processMixedEventBitmask(const FilteredFDCollisions& cols, const aod::FDParticles& parts) + { + doMixedEvent(cols, parts, partsOneBasic, partsTwoBasic); + } + PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processMixedEventBitmask, "Enable processing mixed event for track - cascade using bitmask for PID", false); + /// cascade - cascade correlations - void processMixedEventCasc(const FilteredFDCollisions& cols, const FemtoFullParticles& parts) + template + void doMixedEventCasc(const FilteredFDCollisions& cols, const TableType& parts, PartitionType& partsTwo) { ColumnBinningPolicy colBinning{{confVtxBins, confMultBins}, true}; @@ -615,53 +786,83 @@ struct femtoUniversePairTaskTrackCascadeExtended { if (!invMCascade(p2.mLambda(), p2.mAntiLambda(), confCascType2)) continue; - const auto& posChild1 = parts.iteratorAt(p1.index() - 3); - const auto& negChild1 = parts.iteratorAt(p1.index() - 2); - const auto& bachelor1 = parts.iteratorAt(p1.index() - 1); + const auto& posChild1 = parts.iteratorAt(p1.globalIndex() - 3 - parts.begin().globalIndex()); + const auto& negChild1 = parts.iteratorAt(p1.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& bachelor1 = parts.iteratorAt(p1.globalIndex() - 1 - parts.begin().globalIndex()); /// Child particles must pass this condition to be selected - if (!isParticleTPC(posChild1, CascChildTable[confCascType1][0]) || !isParticleTPC(negChild1, CascChildTable[confCascType1][1]) || !isParticleTPC(bachelor1, CascChildTable[confCascType1][2])) - return; - if (!isParticleTOF(posChild1, CascChildTable[confCascType1][0]) || !isParticleTOF(negChild1, CascChildTable[confCascType1][1]) || !isParticleTOF(bachelor1, CascChildTable[confCascType1][2])) - return; - const auto& posChild2 = parts.iteratorAt(p2.index() - 3); - const auto& negChild2 = parts.iteratorAt(p2.index() - 2); - const auto& bachelor2 = parts.iteratorAt(p2.index() - 1); + if constexpr (std::experimental::is_detected::value) { + if (!isParticleTPC(posChild1, CascChildTable[confCascType1][0]) || !isParticleTPC(negChild1, CascChildTable[confCascType1][1]) || !isParticleTPC(bachelor1, CascChildTable[confCascType1][2])) + continue; + if ((!confCheckTOFBachelorOnly && (!isParticleTOF(posChild1, CascChildTable[confCascType1][0]) || !isParticleTOF(negChild1, CascChildTable[confCascType1][1]))) || !isParticleTOF(bachelor1, CascChildTable[confCascType1][2])) + continue; + } else { + if ((posChild1.pidCut() & (1u << CascChildTable[confCascType1][0])) == 0 || (negChild1.pidCut() & (1u << CascChildTable[confCascType1][1])) == 0 || (bachelor1.pidCut() & (1u << CascChildTable[confCascType1][2])) == 0) + continue; + if ((!confCheckTOFBachelorOnly && ((posChild1.pidCut() & (8u << CascChildTable[confCascType1][0])) == 0 || (negChild1.pidCut() & (8u << CascChildTable[confCascType1][1])) == 0)) || (bachelor1.pidCut() & (8u << CascChildTable[confCascType1][2])) == 0) + continue; + } + + const auto& posChild2 = parts.iteratorAt(p2.globalIndex() - 3 - parts.begin().globalIndex()); + const auto& negChild2 = parts.iteratorAt(p2.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& bachelor2 = parts.iteratorAt(p2.globalIndex() - 1 - parts.begin().globalIndex()); /// Child particles must pass this condition to be selected - if (!isParticleTPC(posChild2, CascChildTable[confCascType2][0]) || !isParticleTPC(negChild2, CascChildTable[confCascType2][1]) || !isParticleTPC(bachelor2, CascChildTable[confCascType2][2])) - return; - if (!isParticleTOF(posChild2, CascChildTable[confCascType2][0]) || !isParticleTOF(negChild2, CascChildTable[confCascType2][1]) || !isParticleTOF(bachelor2, CascChildTable[confCascType2][2])) - return; + if constexpr (std::experimental::is_detected::value) { + if (!isParticleTPC(posChild2, CascChildTable[confCascType2][0]) || !isParticleTPC(negChild2, CascChildTable[confCascType2][1]) || !isParticleTPC(bachelor2, CascChildTable[confCascType2][2])) + continue; + if ((!confCheckTOFBachelorOnly && (!isParticleTOF(posChild2, CascChildTable[confCascType2][0]) || !isParticleTOF(negChild2, CascChildTable[confCascType2][1]))) || !isParticleTOF(bachelor2, CascChildTable[confCascType2][2])) + continue; + } else { + if ((posChild2.pidCut() & (1u << CascChildTable[confCascType1][0])) == 0 || (negChild2.pidCut() & (1u << CascChildTable[confCascType1][1])) == 0 || (bachelor2.pidCut() & (1u << CascChildTable[confCascType1][2])) == 0) + continue; + if ((!confCheckTOFBachelorOnly && ((posChild2.pidCut() & (8u << CascChildTable[confCascType1][0])) == 0 || (negChild2.pidCut() & (8u << CascChildTable[confCascType1][1])) == 0)) || (bachelor2.pidCut() & (8u << CascChildTable[confCascType1][2])) == 0) + continue; + } // track cleaning if (!pairCleanerCasc.isCleanPair(p1, p2, parts)) { continue; } if (confIsCPR.value) { - if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla1, femto_universe_container::EventType::mixed)) { + if (pairCloseRejectionCasc.isClosePair(p1, p2, parts, magFieldTesla1, femto_universe_container::EventType::mixed)) { continue; } } - mixedEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); + float weight = 1.0f; + if (plocalEffp1) + weight = plocalEffp1.get()->GetBinContent(plocalEffp1->FindBin(p1.pt(), p1.eta())) * plocalEffp2.get()->GetBinContent(plocalEffp2->FindBin(p2.pt(), p2.eta())); + mixedEventCont.setPair(p1, p2, multCol, confUse3D, weight); } } } + + void processMixedEventCasc(const FilteredFDCollisions& cols, const FemtoFullParticles& parts) + { + doMixedEventCasc(cols, parts, partsTwoFull); + } PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processMixedEventCasc, "Enable processing mixed event for cascade - cascade", false); - // MC truth - void processSameEventMCgen(const FilteredFDCollision& col, [[maybe_unused]] const FemtoFullParticles& parts) + + void processMixedEventCascBitmask(const FilteredFDCollisions& cols, const aod::FDParticles& parts) + { + doMixedEventCasc(cols, parts, partsTwoBasic); + } + PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processMixedEventCascBitmask, "Enable processing mixed event for cascade - cascade using bitmask for PID", false); + + // MC truth for track - cascade + void processSameEventMCgen(const FilteredFDCollision& col, [[maybe_unused]] const aod::FDParticles& parts) { const int multCol = confUseCent ? col.multV0M() : col.multNtr(); - auto groupPartsOne = partsOneMCgen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - auto groupPartsTwo = partsTwoMCgen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto groupPartsOne = partsOneMCgenBasic->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto groupPartsTwo = partsTwoMCgenBasic->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); eventHisto.fillQA(col); for (const auto& part : groupPartsTwo) { int pdgCode = static_cast(part.pidCut()); - if ((confCascType1 == 0 && pdgCode != 3334) || (confCascType1 == 2 && pdgCode != -3334) || (confCascType1 == 1 && pdgCode != 3312) || (confCascType1 == 3 && pdgCode != -3312)) + if ((confCascType1 == 0 && pdgCode != kOmegaMinus) || (confCascType1 == 2 && pdgCode != kOmegaPlusBar) || (confCascType1 == 1 && pdgCode != kXiMinus) || (confCascType1 == 3 && pdgCode != kXiPlusBar)) continue; - cascQAHistos.fillQA(part); + cascQAHistos.fillQA(part); for (const auto& part : groupPartsOne) { int pdgCode = static_cast(part.pidCut()); @@ -683,7 +884,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { if (static_cast(p1.pidCut()) != confTrkPDGCodePartOne) continue; int pdgCodeCasc = static_cast(p2.pidCut()); - if ((confCascType1 == 0 && pdgCodeCasc != 3334) || (confCascType1 == 2 && pdgCodeCasc != -3334) || (confCascType1 == 1 && pdgCodeCasc != 3312) || (confCascType1 == 3 && pdgCodeCasc != -3312)) + if ((confCascType1 == 0 && pdgCodeCasc != kOmegaMinus) || (confCascType1 == 2 && pdgCodeCasc != kOmegaPlusBar) || (confCascType1 == 1 && pdgCodeCasc != kXiMinus) || (confCascType1 == 3 && pdgCodeCasc != kXiPlusBar)) continue; sameEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); } @@ -691,15 +892,53 @@ struct femtoUniversePairTaskTrackCascadeExtended { } PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processSameEventMCgen, "Enable processing same event MC truth for track - cascade", false); - void processMixedEventMCgen(const FilteredFDCollisions& cols, [[maybe_unused]] const FemtoFullParticles& parts) + // MC truth for cascade - cascade + void processSameEventCascMCgen(const FilteredFDCollision& col, [[maybe_unused]] const aod::FDParticles& parts) + { + const int multCol = confUseCent ? col.multV0M() : col.multNtr(); + + auto groupPartsTwo = partsTwoMCgenBasic->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + + eventHisto.fillQA(col); + + for (const auto& part : groupPartsTwo) { + int pdgCode = static_cast(part.pidCut()); + if ((confCascType1 == 0 && pdgCode != kOmegaMinus) || (confCascType1 == 2 && pdgCode != kOmegaPlusBar) || (confCascType1 == 1 && pdgCode != kXiMinus) || (confCascType1 == 3 && pdgCode != kXiPlusBar)) + continue; + + cascQAHistos.fillQA(part); + + auto pairProcessFunc = [&](auto& p1, auto& p2) -> void { + int pdgCodeCasc1 = static_cast(p1.pidCut()); + if ((confCascType1 == 0 && pdgCodeCasc1 != kOmegaMinus) || (confCascType1 == 2 && pdgCodeCasc1 != kOmegaPlusBar) || (confCascType1 == 1 && pdgCodeCasc1 != kXiMinus) || (confCascType1 == 3 && pdgCodeCasc1 != kXiPlusBar)) + return; + int pdgCodeCasc2 = static_cast(p2.pidCut()); + if ((confCascType2 == 0 && pdgCodeCasc2 != kOmegaMinus) || (confCascType2 == 2 && pdgCodeCasc2 != kOmegaPlusBar) || (confCascType2 == 1 && pdgCodeCasc2 != kXiMinus) || (confCascType2 == 3 && pdgCodeCasc2 != kXiPlusBar)) + return; + sameEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); + }; + + if (confCascType1 == confCascType2) { + for (const auto& [p1, p2] : combinations(CombinationsStrictlyUpperIndexPolicy(groupPartsTwo, groupPartsTwo))) + pairProcessFunc(p1, p2); + } else { + for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsTwo, groupPartsTwo))) + pairProcessFunc(p1, p2); + } + } + } + PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processSameEventCascMCgen, "Enable processing same event MC truth for cascade - cascade", false); + + // MC truth for track - cascade + void processMixedEventMCgen(const FilteredFDCollisions& cols, [[maybe_unused]] const aod::FDParticles& parts) { ColumnBinningPolicy colBinning{{confVtxBins, confMultBins}, true}; for (const auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { const int multCol = confUseCent ? collision1.multV0M() : collision1.multNtr(); - auto groupPartsOne = partsOneMCgen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); - auto groupPartsTwo = partsTwoMCgen->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); + auto groupPartsOne = partsOneMCgenBasic->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsTwo = partsTwoMCgenBasic->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); const auto& magFieldTesla1 = collision1.magField(); const auto& magFieldTesla2 = collision2.magField(); @@ -711,7 +950,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { if (static_cast(p1.pidCut()) != confTrkPDGCodePartOne) continue; int pdgCodeCasc = static_cast(p2.pidCut()); - if ((confCascType1 == 0 && pdgCodeCasc != 3334) || (confCascType1 == 2 && pdgCodeCasc != -3334) || (confCascType1 == 1 && pdgCodeCasc != 3312) || (confCascType1 == 3 && pdgCodeCasc != -3312)) + if ((confCascType1 == 0 && pdgCodeCasc != kOmegaMinus) || (confCascType1 == 2 && pdgCodeCasc != kOmegaPlusBar) || (confCascType1 == 1 && pdgCodeCasc != kXiMinus) || (confCascType1 == 3 && pdgCodeCasc != kXiPlusBar)) continue; mixedEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); } @@ -719,6 +958,36 @@ struct femtoUniversePairTaskTrackCascadeExtended { } PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processMixedEventMCgen, "Enable processing mixed event MC truth for track - cascade", false); + // MC truth for cascade - cascade + void processMixedEventCascMCgen(const FilteredFDCollisions& cols, [[maybe_unused]] const aod::FDParticles& parts) + { + ColumnBinningPolicy colBinning{{confVtxBins, confMultBins}, true}; + + for (const auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + const int multCol = confUseCent ? collision1.multV0M() : collision1.multNtr(); + + auto groupPartsOne = partsTwoMCgenBasic->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsTwo = partsTwoMCgenBasic->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); + + const auto& magFieldTesla1 = collision1.magField(); + const auto& magFieldTesla2 = collision2.magField(); + + if (magFieldTesla1 != magFieldTesla2) { + continue; + } + for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { + int pdgCodeCasc1 = static_cast(p1.pidCut()); + if ((confCascType1 == 0 && pdgCodeCasc1 != kOmegaMinus) || (confCascType1 == 2 && pdgCodeCasc1 != kOmegaPlusBar) || (confCascType1 == 1 && pdgCodeCasc1 != kXiMinus) || (confCascType1 == 3 && pdgCodeCasc1 != kXiPlusBar)) + continue; + int pdgCodeCasc2 = static_cast(p2.pidCut()); + if ((confCascType2 == 0 && pdgCodeCasc2 != kOmegaMinus) || (confCascType2 == 2 && pdgCodeCasc2 != kOmegaPlusBar) || (confCascType2 == 1 && pdgCodeCasc2 != kXiMinus) || (confCascType2 == 3 && pdgCodeCasc2 != kXiPlusBar)) + continue; + mixedEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); + } + } + } + PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processMixedEventCascMCgen, "Enable processing mixed event MC truth for cascade - cascade", false); + /// This function fills MC truth particles from derived MC table void processMCgen(aod::FDParticles const& parts) { @@ -732,10 +1001,10 @@ struct femtoUniversePairTaskTrackCascadeExtended { continue; } - if ((confCascType1 == 0 && pdgCode == 3334) || (confCascType1 == 1 && pdgCode == 3312)) { + if ((confCascType1 == 0 && pdgCode == kOmegaMinus) || (confCascType1 == 1 && pdgCode == kXiMinus)) { registryMCgen.fill(HIST("plus/MCgenCasc"), part.pt(), part.eta()); continue; - } else if ((confCascType1 == 0 && pdgCode == -3334) || (confCascType1 == 1 && pdgCode == -3312)) { + } else if ((confCascType1 == 0 && pdgCode == kOmegaPlusBar) || (confCascType1 == 1 && pdgCode == kXiPlusBar)) { registryMCgen.fill(HIST("minus/MCgenCasc"), part.pt(), part.eta()); continue; } @@ -743,7 +1012,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { if (pdgParticle->Charge() > 0.0) { registryMCgen.fill(HIST("plus/MCgenAllPt"), part.pt()); } - if (pdgCode == 2212) { + if (pdgCode == kProton) { registryMCgen.fill(HIST("plus/MCgenPr"), part.pt(), part.eta()); registryMCgen.fill(HIST("plus/MCgenPrPt"), part.pt()); } @@ -751,7 +1020,7 @@ struct femtoUniversePairTaskTrackCascadeExtended { if (pdgParticle->Charge() < 0.0) { registryMCgen.fill(HIST("minus/MCgenAllPt"), part.pt()); } - if (pdgCode == -2212) { + if (pdgCode == kProtonBar) { registryMCgen.fill(HIST("minus/MCgenPr"), part.pt(), part.eta()); registryMCgen.fill(HIST("minus/MCgenPrPt"), part.pt()); } @@ -760,7 +1029,8 @@ struct femtoUniversePairTaskTrackCascadeExtended { PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processMCgen, "Process MC truth data for cascades", false); - void processMCReco(FemtoRecoParticles const& parts, aod::FdMCParticles const& mcparts) + template + void doMCReco(TableType const& parts, aod::FdMCParticles const& mcparts) { for (const auto& part : parts) { auto mcPartId = part.fdMCParticleId(); @@ -769,44 +1039,85 @@ struct femtoUniversePairTaskTrackCascadeExtended { const auto& mcpart = mcparts.iteratorAt(mcPartId); // if (part.partType() == aod::femtouniverseparticle::ParticleType::kCascade) { - if ((confCascType1 == 0 && mcpart.pdgMCTruth() == 3334) || (confCascType1 == 1 && mcpart.pdgMCTruth() == 3312)) { - const auto& posChild = parts.iteratorAt(part.index() - 3); - const auto& negChild = parts.iteratorAt(part.index() - 2); - const auto& bachelor = parts.iteratorAt(part.index() - 1); + if ((confCascType1 == 0 && mcpart.pdgMCTruth() == kOmegaMinus) || (confCascType1 == 1 && mcpart.pdgMCTruth() == kXiMinus)) { + const auto& posChild = parts.iteratorAt(part.globalIndex() - 3 - parts.begin().globalIndex()); + const auto& negChild = parts.iteratorAt(part.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& bachelor = parts.iteratorAt(part.globalIndex() - 1 - parts.begin().globalIndex()); /// Daughters that do not pass this condition are not selected - if (isParticleTPC(posChild, CascChildTable[confCascType1][0]) && isParticleTPC(negChild, CascChildTable[confCascType1][1]) && isParticleTPC(bachelor, CascChildTable[confCascType1][2])) { - registryMCreco.fill(HIST("plus/MCrecoCascade"), mcpart.pt(), mcpart.eta()); + if constexpr (std::experimental::is_detected::value) { + if (!isParticleTPC(posChild, CascChildTable[confCascType1][0]) || !isParticleTPC(negChild, CascChildTable[confCascType1][1]) || !isParticleTPC(bachelor, CascChildTable[confCascType1][2])) + continue; + if ((!confCheckTOFBachelorOnly && (!isParticleTOF(posChild, CascChildTable[confCascType1][0]) || !isParticleTOF(negChild, CascChildTable[confCascType1][1]))) || !isParticleTOF(bachelor, CascChildTable[confCascType1][2])) + continue; + } else { + if ((posChild.pidCut() & (1u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[confCascType1][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[confCascType1][2])) == 0) + continue; + if ((!confCheckTOFBachelorOnly && ((posChild.pidCut() & (8u << CascChildTable[confCascType1][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[confCascType1][1])) == 0)) || (bachelor.pidCut() & (8u << CascChildTable[confCascType1][2])) == 0) + continue; } - } else if ((confCascType1 == 0 && mcpart.pdgMCTruth() == -3334) || (confCascType1 == 1 && mcpart.pdgMCTruth() == -3312)) { - /// Daughters that do not pass this condition are not selected - const auto& posChild = parts.iteratorAt(part.index() - 3); - const auto& negChild = parts.iteratorAt(part.index() - 2); - const auto& bachelor = parts.iteratorAt(part.index() - 1); - if (isParticleTPC(posChild, CascChildTable[confCascType1 + 2][0]) && isParticleTPC(negChild, CascChildTable[confCascType1 + 2][1]) && isParticleTPC(bachelor, CascChildTable[confCascType1 + 2][2])) { - registryMCreco.fill(HIST("minus/MCrecoCascade"), mcpart.pt(), mcpart.eta()); + registryMCreco.fill(HIST("plus/MCrecoCascade"), mcpart.pt(), mcpart.eta()); + + } else if ((confCascType1 == 0 && mcpart.pdgMCTruth() == kOmegaPlusBar) || (confCascType1 == 1 && mcpart.pdgMCTruth() == kXiPlusBar)) { + const auto& posChild = parts.iteratorAt(part.globalIndex() - 3 - parts.begin().globalIndex()); + const auto& negChild = parts.iteratorAt(part.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& bachelor = parts.iteratorAt(part.globalIndex() - 1 - parts.begin().globalIndex()); + if constexpr (std::experimental::is_detected::value) { + if (!isParticleTPC(posChild, CascChildTable[confCascType1 + 2][0]) && !isParticleTPC(negChild, CascChildTable[confCascType1 + 2][1]) && !isParticleTPC(bachelor, CascChildTable[confCascType1 + 2][2])) + continue; + if ((!confCheckTOFBachelorOnly && (!isParticleTOF(posChild, CascChildTable[confCascType1 + 2][0]) || !isParticleTOF(negChild, CascChildTable[confCascType1 + 2][1]))) || !isParticleTOF(bachelor, CascChildTable[confCascType1 + 2][2])) + continue; + } else { + if ((posChild.pidCut() & (1u << CascChildTable[confCascType1 + 2][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[confCascType1 + 2][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[confCascType1 + 2][2])) == 0) + continue; + if ((!confCheckTOFBachelorOnly && ((posChild.pidCut() & (8u << CascChildTable[confCascType1 + 2][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[confCascType1 + 2][1])) == 0)) || (bachelor.pidCut() & (8u << CascChildTable[confCascType1 + 2][2])) == 0) + continue; } + registryMCreco.fill(HIST("minus/MCrecoCascade"), mcpart.pt(), mcpart.eta()); } + } else if (part.partType() == aod::femtouniverseparticle::ParticleType::kTrack) { - if (part.sign() > 0) { + if (part.mAntiLambda() > 0) { registryMCreco.fill(HIST("plus/MCrecoAllPt"), mcpart.pt()); - if (mcpart.pdgMCTruth() == 2212 && isNSigmaCombined(part.p(), unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tofNSigmaStorePr()))) { - registryMCreco.fill(HIST("plus/MCrecoPr"), mcpart.pt(), mcpart.eta()); - registryMCreco.fill(HIST("plus/MCrecoPrPt"), mcpart.pt()); + if (mcpart.pdgMCTruth() != kProton) + continue; + if constexpr (std::experimental::is_detected::value) { + if (!isNSigmaCombined(part.p(), unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tofNSigmaStorePr()))) + continue; + } else { + if ((part.pidCut() & 64u) == 0) + continue; } - } - - if (part.sign() < 0) { + registryMCreco.fill(HIST("plus/MCrecoPr"), mcpart.pt(), mcpart.eta()); + registryMCreco.fill(HIST("plus/MCrecoPrPt"), mcpart.pt()); + } else if (part.mAntiLambda() < 0) { registryMCreco.fill(HIST("minus/MCrecoAllPt"), mcpart.pt()); - if (mcpart.pdgMCTruth() == -2212 && isNSigmaCombined(part.p(), unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tofNSigmaStorePr()))) { - registryMCreco.fill(HIST("minus/MCrecoPr"), mcpart.pt(), mcpart.eta()); - registryMCreco.fill(HIST("minus/MCrecoPrPt"), mcpart.pt()); + if (mcpart.pdgMCTruth() != kProtonBar) + continue; + if constexpr (std::experimental::is_detected::value) { + if (!isNSigmaCombined(part.p(), unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tofNSigmaStorePr()))) + continue; + } else { + if ((part.pidCut() & 64u) == 0) + continue; } + registryMCreco.fill(HIST("minus/MCrecoPr"), mcpart.pt(), mcpart.eta()); + registryMCreco.fill(HIST("minus/MCrecoPrPt"), mcpart.pt()); } } } } - PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processMCReco, "Process MC reco data for cascades", false); + void processMCReco(FemtoRecoFullParticles const& parts, aod::FdMCParticles const& mcparts) + { + doMCReco(parts, mcparts); + } + PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processMCReco, "Process MC reco data for cascades using nSigma for PID", false); + + void processMCRecoBitmask(FemtoRecoBasicParticles const& parts, aod::FdMCParticles const& mcparts) + { + doMCReco(parts, mcparts); + } + PROCESS_SWITCH(femtoUniversePairTaskTrackCascadeExtended, processMCRecoBitmask, "Process MC reco data for cascades using Bitmask for PID", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx index 3e68a275452..698865577b1 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx @@ -17,38 +17,37 @@ /// \author Zuzanna Chochulska, WUT Warsaw & CTU Prague, zchochul@cern.ch /// \author Katarzyna Gwiździel, WUT Warsaw, katarzyna.gwizdziel@cern.ch -#include -#include - -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StepTHn.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "ReconstructionDataFormats/PID.h" - -#include "Common/DataModel/PIDResponse.h" -#include "Common/Core/RecoDecay.h" - -#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCalculator.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseFemtoContainer.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseAngularContainer.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h" -#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" #include "PWGCF/FemtoUniverse/Core/FemtoUniverseSoftPionRemoval.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseEfficiencyCalculator.h" - +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" +#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" +#include "PWGHF/Core/DecayChannels.h" #include "PWGHF/Core/HfHelper.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/PIDResponse.h" + +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/PID.h" + +#include +#include + using namespace o2; using namespace o2::analysis; using namespace o2::analysis::femto_universe; @@ -84,15 +83,17 @@ struct FemtoUniversePairTaskTrackD0 { SliceCache cache; Preslice perCol = aod::femtouniverseparticle::fdCollisionId; - using FemtoMCParticles = soa::Join; - Preslice perColMC = aod::femtouniverseparticle::fdCollisionId; + using FemtoMcRecoParticles = soa::Join; + Preslice perColMc = aod::femtouniverseparticle::fdCollisionId; /// Table for both particles struct : o2::framework::ConfigurableGroup { - Configurable confNsigmaCombinedProton{"confNsigmaCombinedProton", 3.0, "TPC and TOF Proton Sigma (combined) for momentum > 0.5"}; - Configurable confNsigmaTPCProton{"confNsigmaTPCProton", 3.0, "TPC Proton Sigma for momentum < 0.5"}; - Configurable confNsigmaCombinedPion{"confNsigmaCombinedPion", 3.0, "TPC and TOF Pion Sigma (combined) for momentum > 0.5"}; - Configurable confNsigmaTPCPion{"confNsigmaTPCPion", 3.0, "TPC Pion Sigma for momentum < 0.5"}; + Configurable confNsigmaCombinedProton{"confNsigmaCombinedProton", 3.0, "TPC and TOF Proton Sigma (combined)"}; + Configurable confNsigmaTPCProton{"confNsigmaTPCProton", 3.0, "TPC Proton Sigma"}; + Configurable confNsigmaCombinedPion{"confNsigmaCombinedPion", 3.0, "TPC and TOF Pion Sigma (combined)"}; + Configurable confNsigmaTPCPion{"confNsigmaTPCPion", 3.0, "TPC Pion Sigma"}; + Configurable confNsigmaCombinedKaon{"confNsigmaCombinedKaon", 3.0, "TPC and TOF Kaon Sigma (combined)"}; + Configurable confNsigmaTPCKaon{"confNsigmaTPCKaon", 3.0, "TPC Kaon Sigma"}; Configurable confIsMC{"confIsMC", false, "Enable additional Histogramms in the case of a MonteCarlo Run"}; Configurable> confTrkPIDnSigmaMax{"confTrkPIDnSigmaMax", std::vector{4.f, 3.f, 2.f}, "This configurable needs to be the same as the one used in the producer task"}; @@ -110,8 +111,9 @@ struct FemtoUniversePairTaskTrackD0 { Configurable confIsTrackIdentified{"confIsTrackIdentified", true, "Enable PID for the track"}; Configurable confTrackLowPtCut{"confTrackLowPtCut", 0.5, "Low pT cut of the track"}; Configurable confTrackHighPtCut{"confTrackHighPtCut", 2.5, "High pT cut of the track"}; - Configurable protonMinPtPidTpcTof{"protonMinPtPidTpcTof", 0.5, "Momentum threshold for change of the PID method (from using TPC to TPC and TOF)."}; - Configurable pionMinPtPidTpcTof{"pionMinPtPidTpcTof", 0.5, "Momentum threshold for change of the PID method (from using TPC to TPC and TOF)."}; + Configurable minPtPidTpcTofProton{"minPtPidTpcTofProton", 0.5, "Momentum threshold for change of the PID method (from using TPC to TPC and TOF)."}; + Configurable minPtPidTpcTofPion{"minPtPidTpcTofPion", 0.5, "Momentum threshold for change of the PID method (from using TPC to TPC and TOF)."}; + Configurable minPtPidTpcTofKaonLF{"minPtPidTpcTofKaonLF", 0.5, "Momentum threshold for change of the PID method (from using TPC to TPC and TOF)."}; } ConfTrack; /// Particle 2 --- D0/D0bar meson @@ -120,6 +122,8 @@ struct FemtoUniversePairTaskTrackD0 { Configurable confPDGCodeD0bar{"confPDGCodeD0bar", -421, "D0bar meson - PDG code"}; Configurable confMinPtD0D0bar{"confMinPtD0D0bar", 1.0, "D0/D0bar sel. - min. pT"}; Configurable confMaxPtD0D0bar{"confMaxPtD0D0bar", 3.0, "D0/D0bar sel. - max. pT"}; + Configurable confMinPtD0D0barReco{"confMinPtD0D0barReco", 0.5, "MC Reco - D0/D0bar sel. - min. pT"}; + Configurable confMaxPtD0D0barReco{"confMaxPtD0D0barReco", 24.0, "MC Reco - D0/D0bar sel. - max. pT"}; Configurable minInvMassD0D0barSignal{"minInvMassD0D0barSignal", 1.81, "Min. inv. mass of D0/D0bar for signal region"}; Configurable maxInvMassD0D0barSignal{"maxInvMassD0D0barSignal", 1.922, "Max. inv. mass of D0/D0bar for signal region"}; Configurable minInvMassD0D0barLeftSB{"minInvMassD0D0barLeftSB", 1.65, "Min. inv. mass of D0/D0bar for left SB region"}; @@ -148,34 +152,35 @@ struct FemtoUniversePairTaskTrackD0 { /// Partitions for particle 1 Partition partsTrack = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::sign == int8_t(ConfTrack.confTrackSign)) && (aod::femtouniverseparticle::pt > ConfTrack.confTrackLowPtCut) && (aod::femtouniverseparticle::pt < ConfTrack.confTrackHighPtCut); - Partition partsTrackMCReco = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::sign == int8_t(ConfTrack.confTrackSign)) && (aod::femtouniverseparticle::pt > ConfTrack.confTrackLowPtCut) && (aod::femtouniverseparticle::pt < ConfTrack.confTrackHighPtCut); - Partition partsTrackMCTruth = (aod::femtouniverseparticle::partType == static_cast(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && (aod::femtouniverseparticle::pidCut == static_cast(ConfTrack.confPDGCodeTrack)) && (aod::femtouniverseparticle::pt > ConfTrack.confTrackLowPtCut) && (aod::femtouniverseparticle::pt < ConfTrack.confTrackHighPtCut); + Partition partsTrackMCReco = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::sign == int8_t(ConfTrack.confTrackSign)) && (aod::femtouniverseparticle::pt > ConfTrack.confTrackLowPtCut) && (aod::femtouniverseparticle::pt < ConfTrack.confTrackHighPtCut); + Partition partsTrackMCTruth = (aod::femtouniverseparticle::partType == static_cast(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && (aod::femtouniverseparticle::pidCut == static_cast(ConfTrack.confPDGCodeTrack)) && (aod::femtouniverseparticle::pt > ConfTrack.confTrackLowPtCut) && (aod::femtouniverseparticle::pt < ConfTrack.confTrackHighPtCut); /// Partitions for particle 2 - /// Partition with all D0/D0bar mesons (which pass double mass hypothesis) - Partition partsAllDmesons = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)) && ((aod::femtouniverseparticle::mLambda > 0.0f) || (aod::femtouniverseparticle::mAntiLambda > 0.0f)); + /// Partition with all D0/D0bar mesons (which pass one and double mass hypothesis) + Partition partsAllDmesons = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)) && ((aod::femtouniverseparticle::mLambda > 0.0f) || (aod::femtouniverseparticle::mAntiLambda > 0.0f)) && (aod::femtouniverseparticle::decayVtxX < ConfMlOpt.confMaxProbMlClass1Bg) && (aod::femtouniverseparticle::decayVtxY > ConfMlOpt.confMinProbMlClass2Prompt); /// Partition with D0/D0bar candidates, which pass only one mass hypothesis - Partition partsOnlyD0D0bar = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)) && (aod::femtouniverseparticle::mLambda < 0.0f || aod::femtouniverseparticle::mAntiLambda < 0.0f) && (aod::femtouniverseparticle::tempFitVar < ConfMlOpt.confMaxProbMlClass1Bg) && (aod::femtouniverseparticle::decayVtxY > ConfMlOpt.confMinProbMlClass2Prompt); + Partition partsOnlyD0D0bar = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)) && (aod::femtouniverseparticle::mLambda < 0.0f || aod::femtouniverseparticle::mAntiLambda < 0.0f) && (aod::femtouniverseparticle::decayVtxX < ConfMlOpt.confMaxProbMlClass1Bg) && (aod::femtouniverseparticle::decayVtxY > ConfMlOpt.confMinProbMlClass2Prompt); /// Partition with D0 mesons only (one and double mass hypothesis) Partition partsAllD0s = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)) && (aod::femtouniverseparticle::mLambda > ConfDmesons.minInvMassD0D0barSignal) && (aod::femtouniverseparticle::mLambda < ConfDmesons.maxInvMassD0D0barSignal) && (aod::femtouniverseparticle::pt > ConfDmesons.confMinPtD0D0bar) && (aod::femtouniverseparticle::pt < ConfDmesons.confMaxPtD0D0bar); /// Partition with D0 mesons only (one mass hypothesis) - Partition partsD0s = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)) && (aod::femtouniverseparticle::mLambda > ConfDmesons.minInvMassD0D0barSignal) && (aod::femtouniverseparticle::mLambda < ConfDmesons.maxInvMassD0D0barSignal) && (aod::femtouniverseparticle::mAntiLambda < 0.0f) && (aod::femtouniverseparticle::pt > ConfDmesons.confMinPtD0D0bar) && (aod::femtouniverseparticle::pt < ConfDmesons.confMaxPtD0D0bar) && (aod::femtouniverseparticle::tempFitVar < ConfMlOpt.confMaxProbMlClass1Bg) && (aod::femtouniverseparticle::decayVtxY > ConfMlOpt.confMinProbMlClass2Prompt); + Partition partsD0s = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)) && (aod::femtouniverseparticle::mLambda > ConfDmesons.minInvMassD0D0barSignal) && (aod::femtouniverseparticle::mLambda < ConfDmesons.maxInvMassD0D0barSignal) && (aod::femtouniverseparticle::mAntiLambda < 0.0f) && (aod::femtouniverseparticle::pt > ConfDmesons.confMinPtD0D0bar) && (aod::femtouniverseparticle::pt < ConfDmesons.confMaxPtD0D0bar) && (aod::femtouniverseparticle::decayVtxX < ConfMlOpt.confMaxProbMlClass1Bg) && (aod::femtouniverseparticle::decayVtxY > ConfMlOpt.confMinProbMlClass2Prompt); /// Partition with D0s selected from the side-band (SB) regions (candidates with double mass hypothesis included) Partition partsD0sFromSB = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)) && ((aod::femtouniverseparticle::mLambda > ConfDmesons.minInvMassD0D0barLeftSB && aod::femtouniverseparticle::mLambda < ConfDmesons.maxInvMassD0D0barLeftSB) || (aod::femtouniverseparticle::mLambda > ConfDmesons.minInvMassD0D0barRightSB && aod::femtouniverseparticle::mLambda < ConfDmesons.maxInvMassD0D0barRightSB)) && (aod::femtouniverseparticle::pt > ConfDmesons.confMinPtD0D0bar) && (aod::femtouniverseparticle::pt < ConfDmesons.confMaxPtD0D0bar); /// Partition with D0bar mesons only (one and double mass hypothesis) Partition partsAllD0bars = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)) && (aod::femtouniverseparticle::mAntiLambda > ConfDmesons.minInvMassD0D0barSignal) && (aod::femtouniverseparticle::mAntiLambda < ConfDmesons.maxInvMassD0D0barSignal) && (aod::femtouniverseparticle::pt > ConfDmesons.confMinPtD0D0bar) && (aod::femtouniverseparticle::pt < ConfDmesons.confMaxPtD0D0bar); /// Partition with D0bar mesons only (one mass hypothesis) - Partition partsD0bars = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)) && (aod::femtouniverseparticle::mLambda < 0.0f) && (aod::femtouniverseparticle::mAntiLambda > ConfDmesons.minInvMassD0D0barSignal) && (aod::femtouniverseparticle::mAntiLambda < ConfDmesons.maxInvMassD0D0barSignal) && (aod::femtouniverseparticle::pt > ConfDmesons.confMinPtD0D0bar) && (aod::femtouniverseparticle::pt < ConfDmesons.confMaxPtD0D0bar) && (aod::femtouniverseparticle::tempFitVar < ConfMlOpt.confMaxProbMlClass1Bg) && (aod::femtouniverseparticle::decayVtxY > ConfMlOpt.confMinProbMlClass2Prompt); + Partition partsD0bars = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)) && (aod::femtouniverseparticle::mLambda < 0.0f) && (aod::femtouniverseparticle::mAntiLambda > ConfDmesons.minInvMassD0D0barSignal) && (aod::femtouniverseparticle::mAntiLambda < ConfDmesons.maxInvMassD0D0barSignal) && (aod::femtouniverseparticle::pt > ConfDmesons.confMinPtD0D0bar) && (aod::femtouniverseparticle::pt < ConfDmesons.confMaxPtD0D0bar) && (aod::femtouniverseparticle::decayVtxX < ConfMlOpt.confMaxProbMlClass1Bg) && (aod::femtouniverseparticle::decayVtxY > ConfMlOpt.confMinProbMlClass2Prompt); /// Partition with D0bars selected from the side-band (SB) regions (candidates with double mass hypothesis included) Partition partsD0barsFromSB = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)) && ((aod::femtouniverseparticle::mAntiLambda > ConfDmesons.minInvMassD0D0barLeftSB && aod::femtouniverseparticle::mAntiLambda < ConfDmesons.maxInvMassD0D0barLeftSB) || (aod::femtouniverseparticle::mAntiLambda > ConfDmesons.minInvMassD0D0barRightSB && aod::femtouniverseparticle::mAntiLambda < ConfDmesons.maxInvMassD0D0barRightSB)) && (aod::femtouniverseparticle::pt > ConfDmesons.confMinPtD0D0bar) && (aod::femtouniverseparticle::pt < ConfDmesons.confMaxPtD0D0bar); /// Partition for D0/D0bar mesons from MC - Partition partsD0D0barMCReco = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)) && (aod::femtouniverseparticle::mLambda < 0.0f || aod::femtouniverseparticle::mAntiLambda < 0.0f) && (aod::femtouniverseparticle::pt > ConfDmesons.confMinPtD0D0bar) && (aod::femtouniverseparticle::pt < ConfDmesons.confMaxPtD0D0bar) && (aod::femtouniverseparticle::tempFitVar < ConfMlOpt.confMaxProbMlClass1Bg) && (aod::femtouniverseparticle::decayVtxY > ConfMlOpt.confMinProbMlClass2Prompt); - Partition partsD0D0barMCTruth = (aod::femtouniverseparticle::partType == static_cast(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && (aod::femtouniverseparticle::pidCut == static_cast(ConfDmesons.confPDGCodeD0) || aod::femtouniverseparticle::pidCut == static_cast(ConfDmesons.confPDGCodeD0bar)) && (aod::femtouniverseparticle::pt > ConfDmesons.confMinPtD0D0bar) && (aod::femtouniverseparticle::pt < ConfDmesons.confMaxPtD0D0bar); + Partition partsD0D0barMCReco = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)) && (aod::femtouniverseparticle::mLambda < 0.0f || aod::femtouniverseparticle::mAntiLambda < 0.0f) && (aod::femtouniverseparticle::pt > ConfDmesons.confMinPtD0D0bar) && (aod::femtouniverseparticle::pt < ConfDmesons.confMaxPtD0D0bar) && (aod::femtouniverseparticle::decayVtxX < ConfMlOpt.confMaxProbMlClass1Bg) && (aod::femtouniverseparticle::decayVtxY > ConfMlOpt.confMinProbMlClass2Prompt); + Partition partsD0D0barMCTruth = (aod::femtouniverseparticle::partType == static_cast(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && (aod::femtouniverseparticle::pidCut == static_cast(ConfDmesons.confPDGCodeD0) || aod::femtouniverseparticle::pidCut == static_cast(ConfDmesons.confPDGCodeD0bar)) && (aod::femtouniverseparticle::pt > ConfDmesons.confMinPtD0D0bar) && (aod::femtouniverseparticle::pt < ConfDmesons.confMaxPtD0D0bar); /// Partition for D0/D0bar daughters Partition partsDmesonsChildren = aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0Child); /// Histogramming for particle 1 - FemtoUniverseParticleHisto trackHistoPartTrack; + FemtoUniverseParticleHisto trackHistoPartTrack; + FemtoUniverseParticleHisto hTrackDCA; /// Histogramming for particle 2 FemtoUniverseParticleHisto trackHistoPartD0D0bar; @@ -191,6 +196,7 @@ struct FemtoUniversePairTaskTrackD0 { ConfigurableAxis confTempFitVarBins{"confTempFitVarBins", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; ConfigurableAxis confTempFitVarInvMassBins{"confTempFitVarInvMassBins", {6000, 0.9, 4.0}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; ConfigurableAxis confTempFitVarpTBins{"confTempFitVarpTBins", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot"}; + ConfigurableAxis confTempFitVarDCABins{"confTempFitVarDCABins", {500, -1.0, 1.0}, "binning of the DCA histograms"}; /// Correlation part ConfigurableAxis confMultBins{"confMultBins", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; // \todo to be obtained from the hash task @@ -223,8 +229,8 @@ struct FemtoUniversePairTaskTrackD0 { // Event mixing configurables Configurable confNEventsMix{"confNEventsMix", 5, "Number of events for mixing"}; - FemtoUniverseAngularContainer sameEventAngularCont; - FemtoUniverseAngularContainer mixedEventAngularCont; + FemtoUniverseContainer sameEventAngularCont; + FemtoUniverseContainer mixedEventAngularCont; FemtoUniversePairCleaner pairCleaner; FemtoUniverseDetaDphiStar pairCloseRejection; FemtoUniverseSoftPionRemoval softPionRemoval; @@ -237,8 +243,9 @@ struct FemtoUniversePairTaskTrackD0 { HistogramRegistry qaRegistry{"TrackQA", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry resultRegistry{"Correlations", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry mixQaRegistry{"mixQaRegistry", {}, OutputObjHandlingPolicy::AnalysisObject}; - HistogramRegistry mcRecoRegistry{"mcRecoRegistry", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; - HistogramRegistry mcTruthRegistry{"mcTruthRegistry", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; + HistogramRegistry mcRecoRegistry{"McRecoHistos", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; + HistogramRegistry mcTruthRegistry{"McGenHistos", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; + HistogramRegistry registryDCA{"registryDCA", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; // Efficiency EfficiencyConfigurableGroup effConfGroup; @@ -246,16 +253,13 @@ struct FemtoUniversePairTaskTrackD0 { float weight = 1.0; HistogramRegistry registry{"registry", - {{"hInvMassD0", ";#it{M}(K^{-}#pi^{+}) (GeV/#it{c}^{2});counts", {HistType::kTH1F, {confInvMassBins}}}, - {"hInvMassD0bar", ";#it{M}(#pi^{-}K^{+}) (GeV/#it{c}^{2});counts", {HistType::kTH1F, {confInvMassBins}}}, - {"hPtDmesonCand", "2-prong candidates;#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {confPtBins}}}, - {"hPtD0", "D^{0} cand.;#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {confPtBins}}}, + {{"hPtD0", "D^{0} cand.;#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {confPtBins}}}, {"hPtD0bar", "#bar{D^{0}};#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {confPtBins}}}, {"hPtD0D0bar", "#bar{D^{0}};#it{p}_{T} (GeV/#it{c});counts", {HistType::kTH1F, {confPtBins}}}, - {"hPhiDmesonCand", ";#varphi (rad);counts", {HistType::kTH1F, {{80, 0., o2::constants::math::TwoPI}}}}, + {"hPhiD0D0bar", ";#varphi (rad);counts", {HistType::kTH1F, {{80, 0., o2::constants::math::TwoPI}}}}, {"hPhiD0", ";#varphi (rad);counts", {HistType::kTH1F, {{80, 0., o2::constants::math::TwoPI}}}}, {"hPhiD0bar", ";#varphi (rad);counts", {HistType::kTH1F, {{80, 0., o2::constants::math::TwoPI}}}}, - {"hEtaDmesonCand", ";#eta ;counts", {HistType::kTH1F, {{200, -1., 1.}}}}, + {"hEtaD0D0bar", ";#eta ;counts", {HistType::kTH1F, {{200, -1., 1.}}}}, {"hEtaD0", ";#eta ;counts", {HistType::kTH1F, {{200, -1., 1.}}}}, {"hEtaD0bar", ";#eta ;counts", {HistType::kTH1F, {{200, -1., 1.}}}}, {"hDecayLengthD0", ";decay length (cm);counts", {HistType::kTH1F, {{800, 0., 4.}}}}, @@ -268,13 +272,13 @@ struct FemtoUniversePairTaskTrackD0 { // PID for protons bool isProtonNSigma(float mom, float nsigmaTPCPr, float nsigmaTOFPr) // previous version from: https://github.com/alisw/AliPhysics/blob/master/PWGCF/FEMTOSCOPY/AliFemtoUser/AliFemtoMJTrackCut.cxx { - if (mom < ConfTrack.protonMinPtPidTpcTof) { + if (mom < ConfTrack.minPtPidTpcTofProton) { if (std::abs(nsigmaTPCPr) < ConfBothTracks.confNsigmaTPCProton) { return true; } else { return false; } - } else if (mom > ConfTrack.protonMinPtPidTpcTof) { + } else if (mom > ConfTrack.minPtPidTpcTofProton) { if (std::hypot(nsigmaTOFPr, nsigmaTPCPr) < ConfBothTracks.confNsigmaCombinedProton) { return true; } else { @@ -284,36 +288,16 @@ struct FemtoUniversePairTaskTrackD0 { return false; } - bool isKaonNSigma(float mom, float nsigmaTPCK, float nsigmaTOFK) + bool isKaonNSigmaLF(float mom, float nsigmaTPCK, float nsigmaTOFK) { - if (mom < 0.3) { // 0.0-0.3 - if (std::abs(nsigmaTPCK) < 3.0) { - return true; - } else { - return false; - } - } else if (mom < 0.45) { // 0.30 - 0.45 - if (std::abs(nsigmaTPCK) < 2.0) { + if (mom < ConfTrack.minPtPidTpcTofKaonLF) { + if (std::abs(nsigmaTPCK) < ConfBothTracks.confNsigmaTPCKaon) { return true; } else { return false; } - } else if (mom < 0.55) { // 0.45-0.55 - if (std::abs(nsigmaTPCK) < 1.0) { - return true; - } else { - return false; - } - } else if (mom < 1.5) { // 0.55-1.5 (now we use TPC and TOF) - if ((std::abs(nsigmaTOFK) < 3.0) && (std::abs(nsigmaTPCK) < 3.0)) { - { - return true; - } - } else { - return false; - } - } else if (mom > 1.5) { - if ((std::abs(nsigmaTOFK) < 2.0) && (std::abs(nsigmaTPCK) < 3.0)) { + } else if (mom >= ConfTrack.minPtPidTpcTofKaonLF) { + if (std::sqrt(nsigmaTPCK * nsigmaTPCK + nsigmaTOFK * nsigmaTOFK) < ConfBothTracks.confNsigmaCombinedKaon) { return true; } else { return false; @@ -326,16 +310,16 @@ struct FemtoUniversePairTaskTrackD0 { bool isPionNSigma(float mom, float nsigmaTPCPi, float nsigmaTOFPi) { // using configurables: - // confNsigmaTPCPion -> TPC Pion Sigma for momentum < 0.5 GeV/c - // confNsigmaCombinedPion -> TPC and TOF Pion Sigma (combined) for momentum > 0.5 GeV/c + // confNsigmaTPCPion -> TPC Pion Sigma for a given momentum + // confNsigmaCombinedPion -> TPC and TOF Pion Sigma (combined) for a given momentum if (true) { - if (mom < ConfTrack.pionMinPtPidTpcTof) { + if (mom < ConfTrack.minPtPidTpcTofPion) { if (std::abs(nsigmaTPCPi) < ConfBothTracks.confNsigmaTPCPion) { return true; } else { return false; } - } else if (mom > ConfTrack.pionMinPtPidTpcTof) { + } else if (mom > ConfTrack.minPtPidTpcTofPion) { if (std::hypot(nsigmaTOFPi, nsigmaTPCPi) < ConfBothTracks.confNsigmaCombinedPion) { return true; } else { @@ -359,7 +343,7 @@ struct FemtoUniversePairTaskTrackD0 { break; case 321: // Kaon+ case -321: // Kaon- - return isKaonNSigma(mom, nsigmaTPCK, nsigmaTOFK); + return isKaonNSigmaLF(mom, nsigmaTPCK, nsigmaTOFK); break; default: return false; @@ -368,12 +352,8 @@ struct FemtoUniversePairTaskTrackD0 { void init(InitContext&) { - // if (effConfGroup.confEfficiencyDoMCTruth) { - // WORK IN PROGRESS - // hMCTruth1.init(&qaRegistry, confBinsTempFitVarpT, confBinsTempFitVarPDG, false, ConfTrack.confTrackPDGCode, false); - // hMCTruth2.init(&qaRegistry, confBinsTempFitVarpT, confBinsTempFitVarPDG, false, 333, false); - // } efficiencyCalculator.init(); + hTrackDCA.init(®istryDCA, confTempFitVarpTBins, confTempFitVarDCABins, true, ConfTrack.confPDGCodeTrack, true); eventHisto.init(&qaRegistry); qaRegistry.add("QA_D0D0barSelection/hInvMassD0", ";#it{M}(K^{-}#pi^{+}) (GeV/#it{c}^{2});counts", kTH1F, {confInvMassBins}); @@ -418,22 +398,94 @@ struct FemtoUniversePairTaskTrackD0 { qaRegistry.add("Hadron/nSigmaTPCKa", "; #it{p} (GeV/#it{c}); n#sigma_{TPCKa}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); qaRegistry.add("Hadron/nSigmaTOFKa", "; #it{p} (GeV/#it{c}); n#sigma_{TOFKa}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + // D0/D0bar histograms + auto vbins = (std::vector)binsPt; + if (doEfficiencyCorr) { + registry.add("D0D0bar_oneMassHypo/hMassVsPtEffCorr", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_oneMassHypo/hMassVsPtD0EffCorr", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_oneMassHypo/hMassVsPtD0barEffCorr", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_doubleMassHypo/hMassVsPtEffCorr", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_doubleMassHypo/hMassVsPtD0EffCorr", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_doubleMassHypo/hMassVsPtD0barEffCorr", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + } else { + registry.add("D0D0bar_oneMassHypo/hMassVsPt", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_oneMassHypo/hMassVsPtD0", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_oneMassHypo/hMassVsPtD0bar", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_doubleMassHypo/hMassVsPt", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_doubleMassHypo/hMassVsPtD0", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_doubleMassHypo/hMassVsPtD0bar", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + } + // Histograms for BDT score classes' check + registry.add("DebugBdt/hBdtScore1VsStatus", ";BDT score;status", {HistType::kTH2F, {axisBdtScore, axisSelStatus}}); + registry.add("DebugBdt/hBdtScore2VsStatus", ";BDT score;status", {HistType::kTH2F, {axisBdtScore, axisSelStatus}}); + registry.add("DebugBdt/hBdtScore3VsStatus", ";BDT score;status", {HistType::kTH2F, {axisBdtScore, axisSelStatus}}); + if (applyMLOpt) { + registry.add("D0D0bar_MLSel/hMassVsPt1", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_MLSel/hMassVsPt2", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_MLSel/hMassVsPt3", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_MLSel/hMassVsPt4", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_MLSel/hMassVsPt5", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_MLSel/hMassVsPt6", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_MLSel/hMassVsPt7", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_MLSel/hMassVsPt8", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_MLSel/hMassVsPt9", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("D0D0bar_MLSel/hMassVsPt10", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + } + // MC Reco + mcRecoRegistry.add("hMcRecD0", "MC Reco all D0s;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {400, -1.0, 1.0}}}); + mcRecoRegistry.add("hMcRecD0Prompt", "MC Reco prompt D0s;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {400, -1.0, 1.0}}}); + mcRecoRegistry.add("hMcRecD0NonPrompt", "MC Reco non-prompt D0s;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {400, -1.0, 1.0}}}); + mcRecoRegistry.add("hMcRecD0Phi", "MC Reco all D0s;#varphi (rad); counts", {HistType::kTH1F, {{80, 0., o2::constants::math::TwoPI}}}); + mcRecoRegistry.add("hMcRecD0bar", "MC Reco all D0bars;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {400, -1.0, 1.0}}}); + mcRecoRegistry.add("hMcRecD0barPrompt", "MC Reco prompt D0bars;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {400, -1.0, 1.0}}}); + mcRecoRegistry.add("hMcRecD0barNonPrompt", "MC Reco non-prompt D0bars;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {400, -1.0, 1.0}}}); + mcRecoRegistry.add("hMcRecD0barPhi", "MC Reco all D0bars;#varphi (rad); counts", {HistType::kTH1F, {{80, 0., o2::constants::math::TwoPI}}}); + // Inv. mass histograms + mcRecoRegistry.add("hMassVsPtD0Sig", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + mcRecoRegistry.add("hMassVsPtD0Refl", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + mcRecoRegistry.add("hMassVsPtD0Bkg", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + mcRecoRegistry.add("hMassVsPtD0Prompt", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + mcRecoRegistry.add("hMassVsPtD0NonPrompt", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + mcRecoRegistry.add("hMassVsPtD0barSig", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + mcRecoRegistry.add("hMassVsPtD0barRefl", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + mcRecoRegistry.add("hMassVsPtD0barBkg", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + mcRecoRegistry.add("hMassVsPtD0barPrompt", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + mcRecoRegistry.add("hMassVsPtD0barNonPrompt", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + // Histograms for identified hadrons + mcRecoRegistry.add("hMcRecKpPt", "MC Reco K+;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); + mcRecoRegistry.add("hMcRecKpPtGenEtaGen", "MC Reco K+;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + mcRecoRegistry.add("hMcRecKmPt", "MC Reco K-;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); + mcRecoRegistry.add("hMcRecKmPtGenEtaGen", "MC Reco K-;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + mcRecoRegistry.add("hMcRecPipPt", "MC Reco #pi+;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); + mcRecoRegistry.add("hMcRecPipPtGenEtaGen", "MC Reco #pi+;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + mcRecoRegistry.add("hMcRecPimPt", "MC Reco #pi-;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); + mcRecoRegistry.add("hMcRecPimPtGenEtaGen", "MC Reco #pi-;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + mcRecoRegistry.add("hMcRecPrPt", "MC Reco proton;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); + mcRecoRegistry.add("hMcRecPrPtGenEtaGen", "MC Reco proton;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + mcRecoRegistry.add("hMcRecAntiPrPt", "MC Reco antiproton;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); + mcRecoRegistry.add("hMcRecAntiPrPtGenEtaGen", "MC Reco antiproton;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + // MC truth - mcTruthRegistry.add("MCTruthD0D0bar", "MC Truth D0/D0bar;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{360, 0, 36}, {400, -1.0, 1.0}}}); - mcTruthRegistry.add("MCTruthAllPositivePt", "MC Truth all positive;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{360, 0, 36}}}); - mcTruthRegistry.add("MCTruthAllNegativePt", "MC Truth all negative;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{360, 0, 36}}}); - mcTruthRegistry.add("MCTruthKpPtVsEta", "MC Truth K+;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); - mcTruthRegistry.add("MCTruthKmPtVsEta", "MC Truth K-;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); - mcTruthRegistry.add("MCTruthPipPtVsEta", "MC Truth #pi+;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); - mcTruthRegistry.add("MCTruthPimPtVsEta", "MC Truth #pi-;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); - mcTruthRegistry.add("MCTruthProtonPtVsEta", "MC Truth proton;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); - mcTruthRegistry.add("MCTruthAntiProtonPtVsEta", "MC Truth antiproton;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); - mcTruthRegistry.add("MCTruthKpPt", "MC Truth K+;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); - mcTruthRegistry.add("MCTruthKmPt", "MC Truth K-;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); - mcTruthRegistry.add("MCTruthPipPt", "MC Truth #pi+;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); - mcTruthRegistry.add("MCTruthPimPt", "MC Truth #pi-;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); - mcTruthRegistry.add("MCTruthProtonPt", "MC Truth proton;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); - mcTruthRegistry.add("MCTruthAntiProtonPt", "MC Truth antiproton;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); + mcTruthRegistry.add("hMcGenD0", "MC Truth all D0s;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {400, -1.0, 1.0}}}); + mcTruthRegistry.add("hMcGenD0Prompt", "MC Truth prompt D0s;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {400, -1.0, 1.0}}}); + mcTruthRegistry.add("hMcGenD0NonPrompt", "MC Truth non-prompt D0s;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {400, -1.0, 1.0}}}); + mcTruthRegistry.add("hMcGenD0bar", "MC Truth all D0bars;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {400, -1.0, 1.0}}}); + mcTruthRegistry.add("hMcGenD0barPrompt", "MC Truth prompt D0bars;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {400, -1.0, 1.0}}}); + mcTruthRegistry.add("hMcGenD0barNonPrompt", "MC Truth non-prompt D0bars;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{vbins, "#it{p}_{T} (GeV/#it{c})"}, {400, -1.0, 1.0}}}); + mcTruthRegistry.add("hMcGenAllPositivePt", "MC Truth all positive;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{360, 0, 36}}}); + mcTruthRegistry.add("hMcGenAllNegativePt", "MC Truth all negative;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{360, 0, 36}}}); + mcTruthRegistry.add("hMcGenKpPtVsEta", "MC Truth K+;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + mcTruthRegistry.add("hMcGenKmPtVsEta", "MC Truth K-;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + mcTruthRegistry.add("hMcGenPipPtVsEta", "MC Truth #pi+;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + mcTruthRegistry.add("hMcGenPimPtVsEta", "MC Truth #pi-;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + mcTruthRegistry.add("hMcGenPrPtVsEta", "MC Truth proton;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + mcTruthRegistry.add("hMcGenAntiPrPtVsEta", "MC Truth antiproton;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + mcTruthRegistry.add("hMcGenKpPt", "MC Truth K+;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); + mcTruthRegistry.add("hMcGenKmPt", "MC Truth K-;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); + mcTruthRegistry.add("hMcGenPipPt", "MC Truth #pi+;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); + mcTruthRegistry.add("hMcGenPimPt", "MC Truth #pi-;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); + mcTruthRegistry.add("hMcGenPrPt", "MC Truth proton;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); + mcTruthRegistry.add("hMcGenAntiPrPt", "MC Truth antiproton;#it{p}_{T} (GeV/c); counts", {HistType::kTH1F, {{500, 0, 5}}}); trackHistoPartD0D0bar.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarInvMassBins, ConfBothTracks.confIsMC, ConfDmesons.confPDGCodeD0); if (!ConfTrack.confIsSame) { @@ -457,34 +509,6 @@ struct FemtoUniversePairTaskTrackD0 { vPIDTrack = ConfTrack.confPIDTrack.value; kNsigma = ConfBothTracks.confTrkPIDnSigmaMax.value; - - // D0/D0bar histograms - auto vbins = (std::vector)binsPt; - registry.add("D0D0bar_oneMassHypo/hMassVsPt", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("D0D0bar_oneMassHypo/hMassVsPtReflected", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("D0D0bar_oneMassHypo/hMassVsPtD0", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("D0D0bar_oneMassHypo/hMassVsPtD0bar", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("D0D0bar_oneMassHypo/hMassVsPtD0Reflected", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("D0D0bar_oneMassHypo/hMassVsPtD0barReflected", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("D0D0bar_doubleMassHypo/hMassVsPt", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("D0D0bar_doubleMassHypo/hMassVsPtD0", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("D0D0bar_doubleMassHypo/hMassVsPtD0bar", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - // Histograms for BDT score classes' check - registry.add("DebugBdt/hBdtScore1VsStatus", ";BDT score;status", {HistType::kTH2F, {axisBdtScore, axisSelStatus}}); - registry.add("DebugBdt/hBdtScore2VsStatus", ";BDT score;status", {HistType::kTH2F, {axisBdtScore, axisSelStatus}}); - registry.add("DebugBdt/hBdtScore3VsStatus", ";BDT score;status", {HistType::kTH2F, {axisBdtScore, axisSelStatus}}); - if (applyMLOpt) { - registry.add("D0D0bar_MLSel/hMassVsPt1", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("D0D0bar_MLSel/hMassVsPt2", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("D0D0bar_MLSel/hMassVsPt3", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("D0D0bar_MLSel/hMassVsPt4", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("D0D0bar_MLSel/hMassVsPt5", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("D0D0bar_MLSel/hMassVsPt6", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("D0D0bar_MLSel/hMassVsPt7", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("D0D0bar_MLSel/hMassVsPt8", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("D0D0bar_MLSel/hMassVsPt9", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("D0D0bar_MLSel/hMassVsPt10", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {confInvMassBins, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); - } } template @@ -496,7 +520,7 @@ struct FemtoUniversePairTaskTrackD0 { void processD0MLOptBg(o2::aod::FdCollision const& col, FemtoFullParticles const&) { - auto groupD0D0barCands = partsOnlyD0D0bar->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto groupD0D0barCands = partsAllDmesons->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); // loop over selected D0/D0bar candidates for (auto const& charmCand : groupD0D0barCands) { @@ -552,7 +576,7 @@ struct FemtoUniversePairTaskTrackD0 { void processD0MLOptBgAndPrompt(o2::aod::FdCollision const& col, FemtoFullParticles const&) { - auto groupD0D0barCands = partsOnlyD0D0bar->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto groupD0D0barCands = partsAllDmesons->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); // loop over selected D0/D0bar candidates for (auto const& charmCand : groupD0D0barCands) { @@ -639,143 +663,106 @@ struct FemtoUniversePairTaskTrackD0 { void processAllDmesons(o2::aod::FdCollision const& col, FemtoFullParticles const&) { auto groupPartsAllD0D0barCands = partsAllDmesons->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - auto groupPartsD0D0barChildren = partsDmesonsChildren->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - // loop over D0/D0bar mesons (ONLY) + // loop over D0/D0bar mesons for (auto const& d0d0bar : groupPartsAllD0D0barCands) { registry.fill(HIST("hPtD0D0bar"), d0d0bar.pt()); - registry.fill(HIST("hPhiDmesonCand"), d0d0bar.phi()); - registry.fill(HIST("hEtaDmesonCand"), d0d0bar.eta()); + registry.fill(HIST("hPhiD0D0bar"), d0d0bar.phi()); + registry.fill(HIST("hEtaD0D0bar"), d0d0bar.eta()); // BDT score classes registry.fill(HIST("DebugBdt/hBdtScore1VsStatus"), d0d0bar.decayVtxX(), 1); registry.fill(HIST("DebugBdt/hBdtScore2VsStatus"), d0d0bar.decayVtxY(), 1); registry.fill(HIST("DebugBdt/hBdtScore3VsStatus"), d0d0bar.decayVtxZ(), 1); - if (d0d0bar.mLambda() > 0.0f) { - registry.fill(HIST("D0D0bar_doubleMassHypo/hMassVsPt"), d0d0bar.mLambda(), d0d0bar.pt()); - registry.fill(HIST("D0D0bar_doubleMassHypo/hMassVsPtD0"), d0d0bar.mLambda(), d0d0bar.pt()); - if (d0d0bar.mAntiLambda() < 0.0f) { - registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPt"), d0d0bar.mLambda(), d0d0bar.pt()); - registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPtD0"), d0d0bar.mLambda(), d0d0bar.pt()); - registry.fill(HIST("hPtD0"), d0d0bar.pt()); - registry.fill(HIST("hPhiD0"), d0d0bar.phi()); - registry.fill(HIST("hEtaD0"), d0d0bar.eta()); + weight = 1.0f; + if (doEfficiencyCorr) { + weight = efficiencyCalculator.getWeight(ParticleNo::TWO, d0d0bar.pt()); + if (d0d0bar.mLambda() > 0.0f) { + registry.fill(HIST("D0D0bar_doubleMassHypo/hMassVsPtEffCorr"), d0d0bar.mLambda(), d0d0bar.pt(), weight); + registry.fill(HIST("D0D0bar_doubleMassHypo/hMassVsPtD0EffCorr"), d0d0bar.mLambda(), d0d0bar.pt(), weight); + if (d0d0bar.mAntiLambda() < 0.0f) { + registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPtEffCorr"), d0d0bar.mLambda(), d0d0bar.pt(), weight); + registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPtD0EffCorr"), d0d0bar.mLambda(), d0d0bar.pt(), weight); + registry.fill(HIST("hPtD0"), d0d0bar.pt()); + registry.fill(HIST("hPhiD0"), d0d0bar.phi()); + registry.fill(HIST("hEtaD0"), d0d0bar.eta()); + } } - } - if (d0d0bar.mAntiLambda() > 0.0f) { - registry.fill(HIST("D0D0bar_doubleMassHypo/hMassVsPt"), d0d0bar.mLambda(), d0d0bar.pt()); - registry.fill(HIST("D0D0bar_doubleMassHypo/hMassVsPtD0bar"), d0d0bar.mLambda(), d0d0bar.pt()); - if (d0d0bar.mLambda() < 0.0f) { - registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPt"), d0d0bar.mAntiLambda(), d0d0bar.pt()); - registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPtD0bar"), d0d0bar.mAntiLambda(), d0d0bar.pt()); - registry.fill(HIST("hPtD0bar"), d0d0bar.pt()); - registry.fill(HIST("hPhiD0bar"), d0d0bar.phi()); - registry.fill(HIST("hEtaD0bar"), d0d0bar.eta()); + if (d0d0bar.mAntiLambda() > 0.0f) { + registry.fill(HIST("D0D0bar_doubleMassHypo/hMassVsPtEffCorr"), d0d0bar.mLambda(), d0d0bar.pt(), weight); + registry.fill(HIST("D0D0bar_doubleMassHypo/hMassVsPtD0barEffCorr"), d0d0bar.mLambda(), d0d0bar.pt(), weight); + if (d0d0bar.mLambda() < 0.0f) { + registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPtEffCorr"), d0d0bar.mAntiLambda(), d0d0bar.pt(), weight); + registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPtD0barEffCorr"), d0d0bar.mAntiLambda(), d0d0bar.pt(), weight); + registry.fill(HIST("hPtD0bar"), d0d0bar.pt()); + registry.fill(HIST("hPhiD0bar"), d0d0bar.phi()); + registry.fill(HIST("hEtaD0bar"), d0d0bar.eta()); + } + } + } else { + if (d0d0bar.mLambda() > 0.0f) { + registry.fill(HIST("D0D0bar_doubleMassHypo/hMassVsPt"), d0d0bar.mLambda(), d0d0bar.pt()); + registry.fill(HIST("D0D0bar_doubleMassHypo/hMassVsPtD0"), d0d0bar.mLambda(), d0d0bar.pt()); + if (d0d0bar.mAntiLambda() < 0.0f) { + registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPt"), d0d0bar.mLambda(), d0d0bar.pt()); + registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPtD0"), d0d0bar.mLambda(), d0d0bar.pt()); + registry.fill(HIST("hPtD0"), d0d0bar.pt()); + registry.fill(HIST("hPhiD0"), d0d0bar.phi()); + registry.fill(HIST("hEtaD0"), d0d0bar.eta()); + } + } + if (d0d0bar.mAntiLambda() > 0.0f) { + registry.fill(HIST("D0D0bar_doubleMassHypo/hMassVsPt"), d0d0bar.mLambda(), d0d0bar.pt()); + registry.fill(HIST("D0D0bar_doubleMassHypo/hMassVsPtD0bar"), d0d0bar.mLambda(), d0d0bar.pt()); + if (d0d0bar.mLambda() < 0.0f) { + registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPt"), d0d0bar.mAntiLambda(), d0d0bar.pt()); + registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPtD0bar"), d0d0bar.mAntiLambda(), d0d0bar.pt()); + registry.fill(HIST("hPtD0bar"), d0d0bar.pt()); + registry.fill(HIST("hPhiD0bar"), d0d0bar.phi()); + registry.fill(HIST("hEtaD0bar"), d0d0bar.eta()); + } } - } - } - - // loop over D mesons childen - for (auto const& daughD0D0bar : groupPartsD0D0barChildren) { - registry.fill(HIST("hPtDaughters"), daughD0D0bar.pt()); - registry.fill(HIST("hSignDaughters"), daughD0D0bar.mLambda()); - // filling QA plots for D0 mesons' positive daughters (K+) - if (daughD0D0bar.mLambda() == 1 && (daughD0D0bar.mAntiLambda() == 1 || daughD0D0bar.mAntiLambda() == 0)) { - qaRegistry.fill(HIST("D0_pos_daugh/pt"), daughD0D0bar.pt()); - qaRegistry.fill(HIST("D0_pos_daugh/eta"), daughD0D0bar.eta()); - qaRegistry.fill(HIST("D0_pos_daugh/phi"), daughD0D0bar.phi()); - } - // filling QA plots for D0 mesons' negative daughters (pi-) - if (daughD0D0bar.mLambda() == -1 && (daughD0D0bar.mAntiLambda() == 1 || daughD0D0bar.mAntiLambda() == 0)) { - qaRegistry.fill(HIST("D0_neg_daugh/pt"), daughD0D0bar.pt()); - qaRegistry.fill(HIST("D0_neg_daugh/eta"), daughD0D0bar.eta()); - qaRegistry.fill(HIST("D0_neg_daugh/phi"), daughD0D0bar.phi()); - } - // filling QA plots for D0bar mesons' positive daughters (pi+) - if (daughD0D0bar.mLambda() == 1 && (daughD0D0bar.mAntiLambda() == -1 || daughD0D0bar.mAntiLambda() == 0)) { - qaRegistry.fill(HIST("D0bar_pos_daugh/pt"), daughD0D0bar.pt()); - qaRegistry.fill(HIST("D0bar_pos_daugh/eta"), daughD0D0bar.eta()); - qaRegistry.fill(HIST("D0bar_pos_daugh/phi"), daughD0D0bar.phi()); - } - // filling QA plots for D0bar mesons' negative daughters (K-) - if (daughD0D0bar.mLambda() == -1 && (daughD0D0bar.mAntiLambda() == -1 || daughD0D0bar.mAntiLambda() == 0)) { - qaRegistry.fill(HIST("D0bar_neg_daugh/pt"), daughD0D0bar.pt()); - qaRegistry.fill(HIST("D0bar_neg_daugh/eta"), daughD0D0bar.eta()); - qaRegistry.fill(HIST("D0bar_neg_daugh/phi"), daughD0D0bar.phi()); } } } PROCESS_SWITCH(FemtoUniversePairTaskTrackD0, processAllDmesons, "Enable processing over all D meson candidates", false); - void processD0mesons(o2::aod::FdCollision const& col, FemtoFullParticles const&) + void processD0Children(o2::aod::FdCollision const& col, FemtoFullParticles const&) { - auto groupPartsAllD0D0barCands = partsAllDmesons->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - auto groupPartsOnlyD0D0bar = partsOnlyD0D0bar->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); auto groupPartsD0D0barChildren = partsDmesonsChildren->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - // loop over D0/D0bar mesons (ONLY) - for (auto const& d0d0bar : groupPartsOnlyD0D0bar) { - - registry.fill(HIST("hPtD0D0bar"), d0d0bar.pt()); - // BDT score classes - registry.fill(HIST("DebugBdt/hBdtScore1VsStatus"), d0d0bar.decayVtxX(), 1); - registry.fill(HIST("DebugBdt/hBdtScore2VsStatus"), d0d0bar.decayVtxY(), 1); - registry.fill(HIST("DebugBdt/hBdtScore3VsStatus"), d0d0bar.decayVtxZ(), 1); - - if (d0d0bar.mLambda() > 0.0f && d0d0bar.mAntiLambda() < 0.0f) { - registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPt"), d0d0bar.mLambda(), d0d0bar.pt()); - registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPtD0"), d0d0bar.mLambda(), d0d0bar.pt()); - registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPtReflected"), std::abs(d0d0bar.mAntiLambda()), d0d0bar.pt()); - registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPtD0Reflected"), std::abs(d0d0bar.mAntiLambda()), d0d0bar.pt()); - registry.fill(HIST("hInvMassD0"), d0d0bar.mLambda()); - registry.fill(HIST("hPtD0"), d0d0bar.pt()); - registry.fill(HIST("hPhiD0"), d0d0bar.phi()); - registry.fill(HIST("hEtaD0"), d0d0bar.eta()); - } - if (d0d0bar.mLambda() < 0.0f && d0d0bar.mAntiLambda() > 0.0f) { - registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPt"), d0d0bar.mAntiLambda(), d0d0bar.pt()); - registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPtD0bar"), d0d0bar.mAntiLambda(), d0d0bar.pt()); - registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPtReflected"), std::abs(d0d0bar.mLambda()), d0d0bar.pt()); - registry.fill(HIST("D0D0bar_oneMassHypo/hMassVsPtD0barReflected"), std::abs(d0d0bar.mLambda()), d0d0bar.pt()); - registry.fill(HIST("hInvMassD0bar"), d0d0bar.mAntiLambda()); - registry.fill(HIST("hPtD0bar"), d0d0bar.pt()); - registry.fill(HIST("hPhiD0bar"), d0d0bar.phi()); - registry.fill(HIST("hEtaD0bar"), d0d0bar.eta()); - } - } - // loop over D mesons childen for (auto const& daughD0D0bar : groupPartsD0D0barChildren) { registry.fill(HIST("hPtDaughters"), daughD0D0bar.pt()); registry.fill(HIST("hSignDaughters"), daughD0D0bar.mLambda()); // filling QA plots for D0 mesons' positive daughters (K+) - if (daughD0D0bar.mLambda() == 1 && daughD0D0bar.mAntiLambda() == 1) { + if (daughD0D0bar.mLambda() == 1 && (daughD0D0bar.mAntiLambda() == 1 || daughD0D0bar.mAntiLambda() == 0)) { qaRegistry.fill(HIST("D0_pos_daugh/pt"), daughD0D0bar.pt()); qaRegistry.fill(HIST("D0_pos_daugh/eta"), daughD0D0bar.eta()); qaRegistry.fill(HIST("D0_pos_daugh/phi"), daughD0D0bar.phi()); } // filling QA plots for D0 mesons' negative daughters (pi-) - if (daughD0D0bar.mLambda() == -1 && daughD0D0bar.mAntiLambda() == 1) { + if (daughD0D0bar.mLambda() == -1 && (daughD0D0bar.mAntiLambda() == 1 || daughD0D0bar.mAntiLambda() == 0)) { qaRegistry.fill(HIST("D0_neg_daugh/pt"), daughD0D0bar.pt()); qaRegistry.fill(HIST("D0_neg_daugh/eta"), daughD0D0bar.eta()); qaRegistry.fill(HIST("D0_neg_daugh/phi"), daughD0D0bar.phi()); } // filling QA plots for D0bar mesons' positive daughters (pi+) - if (daughD0D0bar.mLambda() == 1 && daughD0D0bar.mAntiLambda() == -1) { + if (daughD0D0bar.mLambda() == 1 && (daughD0D0bar.mAntiLambda() == -1 || daughD0D0bar.mAntiLambda() == 0)) { qaRegistry.fill(HIST("D0bar_pos_daugh/pt"), daughD0D0bar.pt()); qaRegistry.fill(HIST("D0bar_pos_daugh/eta"), daughD0D0bar.eta()); qaRegistry.fill(HIST("D0bar_pos_daugh/phi"), daughD0D0bar.phi()); } // filling QA plots for D0bar mesons' negative daughters (K-) - if (daughD0D0bar.mLambda() == -1 && daughD0D0bar.mAntiLambda() == -1) { + if (daughD0D0bar.mLambda() == -1 && (daughD0D0bar.mAntiLambda() == -1 || daughD0D0bar.mAntiLambda() == 0)) { qaRegistry.fill(HIST("D0bar_neg_daugh/pt"), daughD0D0bar.pt()); qaRegistry.fill(HIST("D0bar_neg_daugh/eta"), daughD0D0bar.eta()); qaRegistry.fill(HIST("D0bar_neg_daugh/phi"), daughD0D0bar.phi()); } } } - PROCESS_SWITCH(FemtoUniversePairTaskTrackD0, processD0mesons, "Enable processing D0 mesons", true); + PROCESS_SWITCH(FemtoUniversePairTaskTrackD0, processD0Children, "Enable processing over daughters of D0 meson candidates", false); /// This function processes the same event and takes care of all the histogramming /// \todo the trivial loops over the tracks should be factored out since they will be common to all combinations of T-T, T-V0, V0-V0, ... @@ -925,9 +912,7 @@ struct FemtoUniversePairTaskTrackD0 { /// \param col subscribe to the collision table (Monte Carlo Reconstructed reconstructed) /// \param parts subscribe to joined table FemtoUniverseParticles and FemtoUniverseMCLables to access Monte Carlo truth /// \param FemtoUniverseMCParticles subscribe to the Monte Carlo truth table - void processSameEventMC(o2::aod::FdCollision const& col, - soa::Join const& parts, - o2::aod::FdMCParticles const&) + void processSameEventMC(aod::FdCollision const& col, FemtoMcRecoParticles const& parts, aod::FdMCParticles const&) { fillCollision(col); @@ -1094,9 +1079,7 @@ struct FemtoUniversePairTaskTrackD0 { /// @param cols subscribe to the collisions table (Monte Carlo Reconstructed reconstructed) /// @param parts subscribe to joined table FemtoUniverseParticles and FemtoUniverseMCLables to access Monte Carlo truth /// @param FemtoUniverseMCParticles subscribe to the Monte Carlo truth table - void processMixedEventMC(o2::aod::FdCollisions const& cols, - soa::Join const& parts, - o2::aod::FdMCParticles const&) + void processMixedEventMC(aod::FdCollisions const& cols, FemtoMcRecoParticles const& parts, aod::FdMCParticles const&) { for (auto const& [collision1, collision2] : soa::selfCombinations(colBinning, confNEventsMix, -1, cols, cols)) { @@ -1120,65 +1103,195 @@ struct FemtoUniversePairTaskTrackD0 { } PROCESS_SWITCH(FemtoUniversePairTaskTrackD0, processMixedEventMC, "Enable processing mixed events MC", false); - void processMCReco(FemtoMCParticles const&, aod::FdMCParticles const&) + void processMcReco(FemtoMcRecoParticles const& recoParts, aod::FdMCParticles const& mcParts) + { + for (auto const& part : recoParts) { + auto mcPartId = part.fdMCParticleId(); + if (mcPartId == -1) { + continue; // no MC particle + } + const auto& mcpart = mcParts.iteratorAt(mcPartId); + weight = 1.0f; + + // filling the histograms for identified hadrons + if (part.partType() == aod::femtouniverseparticle::ParticleType::kTrack) { + if (part.sign() > 0) { + if ((mcpart.pdgMCTruth() == PDG_t::kProton) && (part.pt() > ConfTrack.confTrackLowPtCut) && (part.pt() < ConfTrack.confTrackHighPtCut) && isParticleNSigma(part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon))) { + mcRecoRegistry.fill(HIST("hMcRecPrPt"), part.pt()); + if (mcpart.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kPrimary) { + mcRecoRegistry.fill(HIST("hMcRecPrPtGenEtaGen"), mcpart.pt(), mcpart.eta()); + } + } + if ((mcpart.pdgMCTruth() == PDG_t::kPiPlus) && (part.pt() > ConfTrack.confTrackLowPtCut) && (part.pt() < ConfTrack.confTrackHighPtCut) && isParticleNSigma(part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon))) { + mcRecoRegistry.fill(HIST("hMcRecPipPt"), part.pt()); + if (mcpart.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kPrimary) { + mcRecoRegistry.fill(HIST("hMcRecPipPtGenEtaGen"), mcpart.pt(), mcpart.eta()); + } + } + if ((mcpart.pdgMCTruth() == PDG_t::kKPlus) && (part.pt() > ConfTrack.confTrackLowPtCut) && (part.pt() < ConfTrack.confTrackHighPtCut) && isParticleNSigma(part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon))) { + mcRecoRegistry.fill(HIST("hMcRecKpPt"), part.pt()); + if (mcpart.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kPrimary) { + mcRecoRegistry.fill(HIST("hMcRecKpPtGenEtaGen"), mcpart.pt(), mcpart.eta()); + } + } + } else if (part.sign() < 0) { + if ((mcpart.pdgMCTruth() == -PDG_t::kProton) && (part.pt() > ConfTrack.confTrackLowPtCut) && (part.pt() < ConfTrack.confTrackHighPtCut) && isParticleNSigma(part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon))) { + mcRecoRegistry.fill(HIST("hMcRecAntiPrPt"), part.pt()); + if (mcpart.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kPrimary) { + mcRecoRegistry.fill(HIST("hMcRecAntiPrPtGenEtaGen"), mcpart.pt(), mcpart.eta()); + } + } + if ((mcpart.pdgMCTruth() == -PDG_t::kPiPlus) && (part.pt() > ConfTrack.confTrackLowPtCut) && (part.pt() < ConfTrack.confTrackHighPtCut) && isParticleNSigma(part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon))) { + mcRecoRegistry.fill(HIST("hMcRecPimPt"), part.pt()); + if (mcpart.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kPrimary) { + mcRecoRegistry.fill(HIST("hMcRecPimPtGenEtaGen"), mcpart.pt(), mcpart.eta()); + } + } + if ((mcpart.pdgMCTruth() == -PDG_t::kKPlus) && (part.pt() > ConfTrack.confTrackLowPtCut) && (part.pt() < ConfTrack.confTrackHighPtCut) && isParticleNSigma(part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon))) { + mcRecoRegistry.fill(HIST("hMcRecKmPt"), part.pt()); + if (mcpart.partOriginMCTruth() == aod::femtouniverse_mc_particle::ParticleOriginMCTruth::kPrimary) { + mcRecoRegistry.fill(HIST("hMcRecKmPtGenEtaGen"), mcpart.pt(), mcpart.eta()); + } + } + } + } else if ((part.partType() == aod::femtouniverseparticle::ParticleType::kD0) && (part.pt() > ConfDmesons.confMinPtD0D0barReco) && (part.pt() < ConfDmesons.confMaxPtD0D0barReco)) { + if (mcpart.pdgMCTruth() == ConfDmesons.confPDGCodeD0) { + mcRecoRegistry.fill(HIST("hMcRecD0"), part.pt(), part.eta()); + mcRecoRegistry.fill(HIST("hMcRecD0Phi"), part.phi()); + if (part.tpcNClsFound() == 0) { // prompt candidates + mcRecoRegistry.fill(HIST("hMcRecD0Prompt"), part.pt(), part.eta()); + } else if (part.tpcNClsFound() == 1) { // non-prompt candidates + mcRecoRegistry.fill(HIST("hMcRecD0NonPrompt"), part.pt(), part.eta()); + } + } else if (mcpart.pdgMCTruth() == ConfDmesons.confPDGCodeD0bar) { + mcRecoRegistry.fill(HIST("hMcRecD0bar"), part.pt(), part.eta()); + mcRecoRegistry.fill(HIST("hMcRecD0barPhi"), part.phi()); + if (part.tpcNClsFound() == 0) { // prompt candidates + mcRecoRegistry.fill(HIST("hMcRecD0barPrompt"), part.pt(), part.eta()); + } else if (part.tpcNClsFound() == 1) { // non-prompt candidates + mcRecoRegistry.fill(HIST("hMcRecD0barNonPrompt"), part.pt(), part.eta()); + } + } + } + if (isParticleNSigma(part.p(), trackCuts.getNsigmaTPC(part, o2::track::PID::Proton), trackCuts.getNsigmaTOF(part, o2::track::PID::Proton), trackCuts.getNsigmaTPC(part, o2::track::PID::Pion), trackCuts.getNsigmaTOF(part, o2::track::PID::Pion), trackCuts.getNsigmaTPC(part, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(part, o2::track::PID::Kaon))) { + hTrackDCA.fillQA(part); + } + } + } + PROCESS_SWITCH(FemtoUniversePairTaskTrackD0, processMcReco, "Process MC reco data", false); + + void processMcRecoD0InvMass(FemtoMcRecoParticles const& recoParts) { - // WORK IN PROGRESS - // for (auto const& part : parts) {} + for (auto const& part : recoParts) { + // filling the histograms for identified hadrons + if ((part.partType() == aod::femtouniverseparticle::ParticleType::kD0) && (part.pt() > ConfDmesons.confMinPtD0D0barReco) && (part.pt() < ConfDmesons.confMaxPtD0D0barReco)) { + // getting the efficiency value + if (doEfficiencyCorr) { + weight = efficiencyCalculator.getWeight(ParticleNo::TWO, part.pt()); + } else { + weight = 1.0f; + } + // filling the inv. mass histograms + if (part.mLambda() > 0) { + if (part.sign() == o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) { + mcRecoRegistry.fill(HIST("hMassVsPtD0Sig"), part.mLambda(), part.pt(), weight); + } else if (part.sign() == -o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) { + mcRecoRegistry.fill(HIST("hMassVsPtD0Refl"), part.mLambda(), part.pt(), weight); + } else { + mcRecoRegistry.fill(HIST("hMassVsPtD0Bkg"), part.mLambda(), part.pt(), weight); + } + if (part.tpcNClsFound() == 0) { // prompt candidates + mcRecoRegistry.fill(HIST("hMassVsPtD0Prompt"), part.mLambda(), part.pt(), weight); + } else if (part.tpcNClsFound() == 1) { // non-prompt candidates + mcRecoRegistry.fill(HIST("hMassVsPtD0NonPrompt"), part.mLambda(), part.pt(), weight); + } + } else if (part.mAntiLambda() > 0) { + if (part.sign() == -o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) { + mcRecoRegistry.fill(HIST("hMassVsPtD0barSig"), part.mAntiLambda(), part.pt(), weight); + } else if (part.sign() == o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) { + mcRecoRegistry.fill(HIST("hMassVsPtD0barRefl"), part.mAntiLambda(), part.pt(), weight); + } else { + mcRecoRegistry.fill(HIST("hMassVsPtD0barBkg"), part.mAntiLambda(), part.pt(), weight); + } + if (part.tpcNClsFound() == 0) { // prompt candidates + mcRecoRegistry.fill(HIST("hMassVsPtD0barPrompt"), part.mAntiLambda(), part.pt(), weight); + } else if (part.tpcNClsFound() == 1) { // non-prompt candidates + mcRecoRegistry.fill(HIST("hMassVsPtD0barNonPrompt"), part.mAntiLambda(), part.pt(), weight); + } + } + } + } } - PROCESS_SWITCH(FemtoUniversePairTaskTrackD0, processMCReco, "Process MC reco data", false); + PROCESS_SWITCH(FemtoUniversePairTaskTrackD0, processMcRecoD0InvMass, "Process MC reco inv. mass histograms for D0", false); - void processMCTruth(aod::FDParticles const& parts) // WORK IN PROGRESS + void processMcTruth(aod::FDParticles const& parts) { for (auto const& part : parts) { - if (part.partType() != uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) + if (part.partType() != uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) { continue; + } - int pdgCode = static_cast(part.pidCut()); + int pdgCode = static_cast(part.tempFitVar()); + int8_t hfFlagMcGen = static_cast(part.mLambda()); const auto& pdgParticle = pdgMC->GetParticle(pdgCode); if (!pdgParticle) { continue; } if (pdgParticle->Charge() > 0.0) { - mcTruthRegistry.fill(HIST("MCTruthAllPositivePt"), part.pt()); + mcTruthRegistry.fill(HIST("hMcGenAllPositivePt"), part.pt()); } - if (pdgCode == 211) { - mcTruthRegistry.fill(HIST("MCTruthPipPtVsEta"), part.pt(), part.eta()); - mcTruthRegistry.fill(HIST("MCTruthPipPt"), part.pt()); + if (pdgCode == PDG_t::kPiPlus) { + mcTruthRegistry.fill(HIST("hMcGenPipPtVsEta"), part.pt(), part.eta()); + mcTruthRegistry.fill(HIST("hMcGenPipPt"), part.pt()); } - if (pdgCode == 321) { - mcTruthRegistry.fill(HIST("MCTruthKpPtVsEta"), part.pt(), part.eta()); - mcTruthRegistry.fill(HIST("MCTruthKpPt"), part.pt()); + if (pdgCode == PDG_t::kKPlus) { + mcTruthRegistry.fill(HIST("hMcGenKpPtVsEta"), part.pt(), part.eta()); + mcTruthRegistry.fill(HIST("hMcGenKpPt"), part.pt()); } - if (pdgCode == 421) { - mcTruthRegistry.fill(HIST("MCTruthD0D0bar"), part.pt(), part.eta()); + if (pdgCode == o2::constants::physics::Pdg::kD0) { + if (std::abs(hfFlagMcGen) == o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) { + mcTruthRegistry.fill(HIST("hMcGenD0"), part.pt(), part.eta()); + if (part.mAntiLambda() == 1) { + mcTruthRegistry.fill(HIST("hMcGenD0Prompt"), part.pt(), part.eta()); + } else if (part.mAntiLambda() == 2) { + mcTruthRegistry.fill(HIST("hMcGenD0NonPrompt"), part.pt(), part.eta()); + } + } } - if (pdgCode == 2212) { - mcTruthRegistry.fill(HIST("MCTruthProtonPtVsEta"), part.pt(), part.eta()); - mcTruthRegistry.fill(HIST("MCTruthProtonPt"), part.pt()); + if (pdgCode == PDG_t::kProton) { + mcTruthRegistry.fill(HIST("hMcGenPrPtVsEta"), part.pt(), part.eta()); + mcTruthRegistry.fill(HIST("hMcGenPrPt"), part.pt()); } if (pdgParticle->Charge() < 0.0) { - mcTruthRegistry.fill(HIST("MCTruthAllNegativePt"), part.pt()); + mcTruthRegistry.fill(HIST("hMcGenAllNegativePt"), part.pt()); } - if (pdgCode == -211) { - mcTruthRegistry.fill(HIST("MCTruthPimPtVsEta"), part.pt(), part.eta()); - mcTruthRegistry.fill(HIST("MCTruthPimPt"), part.pt()); + if (pdgCode == PDG_t::kPiMinus) { + mcTruthRegistry.fill(HIST("hMcGenPimPtVsEta"), part.pt(), part.eta()); + mcTruthRegistry.fill(HIST("hMcGenPimPt"), part.pt()); } - if (pdgCode == -321) { - mcTruthRegistry.fill(HIST("MCTruthKmPtVsEta"), part.pt(), part.eta()); - mcTruthRegistry.fill(HIST("MCTruthKmPt"), part.pt()); + if (pdgCode == PDG_t::kKMinus) { + mcTruthRegistry.fill(HIST("hMcGenKmPtVsEta"), part.pt(), part.eta()); + mcTruthRegistry.fill(HIST("hMcGenKmPt"), part.pt()); } - if (pdgCode == -421) { - mcTruthRegistry.fill(HIST("MCTruthD0D0bar"), part.pt(), part.eta()); + if (pdgCode == o2::constants::physics::Pdg::kD0Bar) { + if (std::abs(hfFlagMcGen) == o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) { + mcTruthRegistry.fill(HIST("hMcGenD0bar"), part.pt(), part.eta()); + if (part.mAntiLambda() == 1) { + mcTruthRegistry.fill(HIST("hMcGenD0barPrompt"), part.pt(), part.eta()); + } else if (part.mAntiLambda() == 2) { + mcTruthRegistry.fill(HIST("hMcGenD0barNonPrompt"), part.pt(), part.eta()); + } + } } - if (pdgCode == -2212) { - mcTruthRegistry.fill(HIST("MCTruthAntiProtonPtVsEta"), part.pt(), part.eta()); - mcTruthRegistry.fill(HIST("MCTruthAntiProtonPt"), part.pt()); + if (pdgCode == -PDG_t::kProton) { + mcTruthRegistry.fill(HIST("hMcGenAntiPrPtVsEta"), part.pt(), part.eta()); + mcTruthRegistry.fill(HIST("hMcGenAntiPrPt"), part.pt()); } } } - PROCESS_SWITCH(FemtoUniversePairTaskTrackD0, processMCTruth, "Process MC truth data", false); + PROCESS_SWITCH(FemtoUniversePairTaskTrackD0, processMcTruth, "Process MC truth data", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMcTruth.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMcTruth.cxx index d74b76ab237..a678a6a078e 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMcTruth.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMcTruth.cxx @@ -14,24 +14,24 @@ /// \author Malgorzata Janik, WUT, majanik@cern.ch /// \author Zuzanna Chochulska, WUT Warsaw & CTU Prague, zchochul@cern.ch -#include -#include +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" +#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" + +#include "Framework/ASoAHelpers.h" #include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" #include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" +#include "Framework/O2DatabasePDGPlugin.h" #include "Framework/RunningWorkflowInfo.h" #include "Framework/StepTHn.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "TDatabasePDG.h" +#include "Framework/runDataProcessing.h" -#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h" -#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" +#include +#include using namespace o2; using namespace o2::analysis::femto_universe; @@ -39,39 +39,39 @@ using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::soa; -struct femtoUniversePairTaskTrackTrackMcTruth { +struct FemtoUniversePairTaskTrackTrackMcTruth { SliceCache cache; Preslice perCol = aod::femtouniverseparticle::fdCollisionId; /// Particle selection part /// Configurables for both particles - Configurable ConfUse3D{"ConfUse3D", false, "Enable three dimensional histogramms (to be used only for analysis with high statistics): k* vs mT vs multiplicity"}; - Configurable ConfEtaMax{"ConfEtaMax", 0.8f, "Higher limit for |Eta| (the same for both particles)"}; + Configurable confUse3D{"confUse3D", false, "Enable three dimensional histogramms (to be used only for analysis with high statistics): k* vs mT vs multiplicity"}; + Configurable confEtaMax{"confEtaMax", 0.8f, "Higher limit for |Eta| (the same for both particles)"}; /// Particle 1 - Configurable ConfPDGCodePartOne{"ConfPDGCodePartOne", 2212, "Particle 1 - PDG code"}; - Configurable ConfNoPDGPartOne{"ConfNoPDGPartOne", false, "0: selecting part by PDG, 1: no PID selection"}; - Configurable ConfPtLowPart1{"ConfPtLowPart1", 0.2, "Lower limit for Pt for the first particle"}; - Configurable ConfPtHighPart1{"ConfPtHighPart1", 2.5, "Higher limit for Pt for the first particle"}; + Configurable confPDGCodePartOne{"confPDGCodePartOne", 2212, "Particle 1 - PDG code"}; + Configurable confNoPDGPartOne{"confNoPDGPartOne", false, "0: selecting part by PDG, 1: no PID selection"}; + Configurable confPtLowPart1{"confPtLowPart1", 0.2, "Lower limit for Pt for the first particle"}; + Configurable confPtHighPart1{"confPtHighPart1", 2.5, "Higher limit for Pt for the first particle"}; /// Partition for particle 1 Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && - (aod::femtouniverseparticle::pt < ConfPtHighPart1) && (aod::femtouniverseparticle::pt > ConfPtLowPart1) && (nabs(aod::femtouniverseparticle::eta) < ConfEtaMax); + (aod::femtouniverseparticle::pt < confPtHighPart1) && (aod::femtouniverseparticle::pt > confPtLowPart1) && (nabs(aod::femtouniverseparticle::eta) < confEtaMax); /// Histogramming for particle 1 FemtoUniverseParticleHisto trackHistoPartOne; /// Particle 2 - Configurable ConfIsSame{"ConfIsSame", false, "Pairs of the same particle"}; - Configurable ConfPDGCodePartTwo{"ConfPDGCodePartTwo", 333, "Particle 2 - PDG code"}; - Configurable ConfNoPDGPartTwo{"ConfNoPDGPartTwo", false, "0: selecting part by PDG, 1: no PID selection"}; - Configurable ConfPtLowPart2{"ConfPtLowPart2", 0.2, "Lower limit for Pt for the second particle"}; - Configurable ConfPtHighPart2{"ConfPtHighPart2", 2.5, "Higher limit for Pt for the second particle"}; + Configurable confIsSame{"confIsSame", false, "Pairs of the same particle"}; + Configurable confPDGCodePartTwo{"confPDGCodePartTwo", 333, "Particle 2 - PDG code"}; + Configurable confNoPDGPartTwo{"confNoPDGPartTwo", false, "0: selecting part by PDG, 1: no PID selection"}; + Configurable confPtLowPart2{"confPtLowPart2", 0.2, "Lower limit for Pt for the second particle"}; + Configurable confPtHighPart2{"confPtHighPart2", 2.5, "Higher limit for Pt for the second particle"}; /// Partition for particle 2 Partition partsTwo = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && - (aod::femtouniverseparticle::pt < ConfPtHighPart2) && (aod::femtouniverseparticle::pt > ConfPtLowPart2) && (nabs(aod::femtouniverseparticle::eta) < ConfEtaMax); + (aod::femtouniverseparticle::pt < confPtHighPart2) && (aod::femtouniverseparticle::pt > confPtLowPart2) && (nabs(aod::femtouniverseparticle::eta) < confEtaMax); /// Histogramming for particle 2 FemtoUniverseParticleHisto trackHistoPartTwo; @@ -84,27 +84,27 @@ struct femtoUniversePairTaskTrackTrackMcTruth { std::vector kNsigma; /// particle part - ConfigurableAxis ConfTempFitVarpTBins{"ConfTempFitVarpTBins", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot"}; - ConfigurableAxis ConfTempFitVarPDGBins{"ConfDTempFitVarInvMassBins", {6000, -2300, 2300}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; + ConfigurableAxis confTempFitVarpTBins{"confTempFitVarpTBins", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot"}; + ConfigurableAxis confTempFitVarPDGBins{"confTempFitVarPDGBins", {6000, -2300, 2300}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; /// Correlation part - ConfigurableAxis ConfMultBins{"ConfMultBins", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; // \todo to be obtained from the hash task - // ConfigurableAxis ConfMultBins{"CfgMultBins", {VARIABLE_WIDTH, 0.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; - ConfigurableAxis ConfVtxBins{"ConfVtxBins", {VARIABLE_WIDTH, -10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}, "Mixing bins - z-vertex"}; + ConfigurableAxis confMultBins{"confMultBins", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; // \todo to be obtained from the hash task + // ConfigurableAxis confMultBins{"CfgMultBins", {VARIABLE_WIDTH, 0.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; + ConfigurableAxis confVtxBins{"confVtxBins", {VARIABLE_WIDTH, -10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}, "Mixing bins - z-vertex"}; - ConfigurableAxis ConfmTBins3D{"ConfmTBins3D", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; - ConfigurableAxis ConfmultBins3D{"ConfmultBins3D", {VARIABLE_WIDTH, 0.0f, 20.0f, 30.0f, 40.0f, 99999.0f}, "multiplicity Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; + ConfigurableAxis confmTBins3D{"confmTBins3D", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; + ConfigurableAxis confMultBins3D{"confMultBins3D", {VARIABLE_WIDTH, 0.0f, 20.0f, 30.0f, 40.0f, 99999.0f}, "multiplicity Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; - ColumnBinningPolicy colBinning{{ConfVtxBins, ConfMultBins}, true}; + ColumnBinningPolicy colBinning{{confVtxBins, confMultBins}, true}; - ConfigurableAxis ConfkstarBins{"ConfkstarBins", {1500, 0., 6.}, "binning kstar"}; - ConfigurableAxis ConfkTBins{"ConfkTBins", {150, 0., 9.}, "binning kT"}; - ConfigurableAxis ConfmTBins{"ConfmTBins", {225, 0., 7.5}, "binning mT"}; - Configurable ConfNEventsMix{"ConfNEventsMix", 5, "Number of events for mixing"}; - Configurable ConfIsCPR{"ConfIsCPR", true, "Close Pair Rejection"}; - Configurable ConfCPRPlotPerRadii{"ConfCPRPlotPerRadii", false, "Plot CPR per radii"}; - Configurable ConfPhiBins{"ConfPhiBins", 29, "Number of phi bins in deta dphi"}; - Configurable ConfEtaBins{"ConfEtaBins", 29, "Number of eta bins in deta dphi"}; + ConfigurableAxis confkstarBins{"confkstarBins", {1500, 0., 6.}, "binning kstar"}; + ConfigurableAxis confkTBins{"confkTBins", {150, 0., 9.}, "binning kT"}; + ConfigurableAxis confmTBins{"confmTBins", {225, 0., 7.5}, "binning mT"}; + Configurable confNEventsMix{"confNEventsMix", 5, "Number of events for mixing"}; + Configurable confIsCPR{"confIsCPR", true, "Close Pair Rejection"}; + Configurable confCPRPlotPerRadii{"confCPRPlotPerRadii", false, "Plot CPR per radii"}; + Configurable confPhiBins{"confPhiBins", 29, "Number of phi bins in deta dphi"}; + Configurable confEtaBins{"confEtaBins", 29, "Number of eta bins in deta dphi"}; FemtoUniverseContainer sameEventCont; FemtoUniverseContainer mixedEventCont; @@ -112,7 +112,7 @@ struct femtoUniversePairTaskTrackTrackMcTruth { /// Histogram output HistogramRegistry qaRegistry{"TrackQA", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry resultRegistry{"Correlations", {}, OutputObjHandlingPolicy::AnalysisObject}; - HistogramRegistry MixQaRegistry{"MixQaRegistry", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry mixQaRegistry{"mixQaRegistry", {}, OutputObjHandlingPolicy::AnalysisObject}; /// @brief Counter for particle swapping int fNeventsProcessed = 0; @@ -121,25 +121,25 @@ struct femtoUniversePairTaskTrackTrackMcTruth { { eventHisto.init(&qaRegistry); - trackHistoPartOne.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarPDGBins, 0, ConfPDGCodePartOne, false); - if (!ConfIsSame) { - trackHistoPartTwo.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarPDGBins, 0, ConfPDGCodePartTwo, false); + trackHistoPartOne.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarPDGBins, 0, confPDGCodePartOne, false); + if (!confIsSame) { + trackHistoPartTwo.init(&qaRegistry, confTempFitVarpTBins, confTempFitVarPDGBins, 0, confPDGCodePartTwo, false); } - MixQaRegistry.add("MixingQA/hSECollisionBins", ";bin;Entries", kTH1F, {{120, -0.5, 119.5}}); - MixQaRegistry.add("MixingQA/hMECollisionBins", ";bin;Entries", kTH1F, {{120, -0.5, 119.5}}); + mixQaRegistry.add("MixingQA/hSECollisionBins", ";bin;Entries", kTH1F, {{120, -0.5, 119.5}}); + mixQaRegistry.add("MixingQA/hMECollisionBins", ";bin;Entries", kTH1F, {{120, -0.5, 119.5}}); - sameEventCont.init(&resultRegistry, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, ConfEtaBins, ConfPhiBins, 0, ConfUse3D); - mixedEventCont.init(&resultRegistry, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, ConfEtaBins, ConfPhiBins, 0, ConfUse3D); - sameEventCont.setPDGCodes(ConfPDGCodePartOne, ConfPDGCodePartTwo); - mixedEventCont.setPDGCodes(ConfPDGCodePartOne, ConfPDGCodePartTwo); + sameEventCont.init(&resultRegistry, confkstarBins, confMultBins, confkTBins, confmTBins, confMultBins3D, confmTBins3D, confEtaBins, confPhiBins, 0, confUse3D); + mixedEventCont.init(&resultRegistry, confkstarBins, confMultBins, confkTBins, confmTBins, confMultBins3D, confmTBins3D, confEtaBins, confPhiBins, 0, confUse3D); + sameEventCont.setPDGCodes(confPDGCodePartOne, confPDGCodePartTwo); + mixedEventCont.setPDGCodes(confPDGCodePartOne, confPDGCodePartTwo); pairCleaner.init(&qaRegistry); } template void fillCollision(CollisionType col) { - MixQaRegistry.fill(HIST("MixingQA/hSECollisionBins"), colBinning.getBin({col.posZ(), col.multNtr()})); + mixQaRegistry.fill(HIST("MixingQA/hSECollisionBins"), colBinning.getBin({col.posZ(), col.multNtr()})); eventHisto.fillQA(col); } @@ -160,53 +160,53 @@ struct femtoUniversePairTaskTrackTrackMcTruth { fNeventsProcessed++; /// Histogramming same event - for (auto& part : groupPartsOne) { - if (!ConfNoPDGPartOne && part.tempFitVar() != ConfPDGCodePartOne) { + for (auto const& part : groupPartsOne) { + if (!confNoPDGPartOne && part.tempFitVar() != confPDGCodePartOne) { continue; } trackHistoPartOne.fillQA(part); } - if (!ConfIsSame) { - for (auto& part : groupPartsTwo) { - if (!ConfNoPDGPartTwo && part.tempFitVar() != ConfPDGCodePartTwo) { + if (!confIsSame) { + for (auto const& part : groupPartsTwo) { + if (!confNoPDGPartTwo && part.tempFitVar() != confPDGCodePartTwo) { continue; } trackHistoPartTwo.fillQA(part); } } /// Now build the combinations - if (!ConfIsSame) { + if (!confIsSame) { // Build the combinations for pairs of non-identical particles - for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { + for (auto const& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { // track cleaning if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; } - if ((!ConfNoPDGPartOne && p2.tempFitVar() != ConfPDGCodePartOne) || (!ConfNoPDGPartTwo && p1.tempFitVar() != ConfPDGCodePartTwo)) { + if ((!confNoPDGPartOne && p2.tempFitVar() != confPDGCodePartOne) || (!confNoPDGPartTwo && p1.tempFitVar() != confPDGCodePartTwo)) { continue; } if (swpart) - sameEventCont.setPair(p1, p2, multCol, ConfUse3D); + sameEventCont.setPair(p1, p2, multCol, confUse3D); else - sameEventCont.setPair(p2, p1, multCol, ConfUse3D); + sameEventCont.setPair(p2, p1, multCol, confUse3D); swpart = !swpart; } } else { // Build the combinations for pairs of identical pairs - for (auto& [p1, p2] : combinations(CombinationsStrictlyUpperIndexPolicy(groupPartsOne, groupPartsTwo))) { + for (auto const& [p1, p2] : combinations(CombinationsStrictlyUpperIndexPolicy(groupPartsOne, groupPartsTwo))) { // track cleaning if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; } - if ((!ConfNoPDGPartOne && p2.tempFitVar() != ConfPDGCodePartOne) || (!ConfNoPDGPartTwo && p1.tempFitVar() != ConfPDGCodePartTwo)) { + if ((!confNoPDGPartOne && p2.tempFitVar() != confPDGCodePartOne) || (!confNoPDGPartTwo && p1.tempFitVar() != confPDGCodePartTwo)) { continue; } if (swpart) - sameEventCont.setPair(p1, p2, multCol, ConfUse3D); + sameEventCont.setPair(p1, p2, multCol, confUse3D); else - sameEventCont.setPair(p2, p1, multCol, ConfUse3D); + sameEventCont.setPair(p2, p1, multCol, confUse3D); swpart = !swpart; } @@ -215,8 +215,8 @@ struct femtoUniversePairTaskTrackTrackMcTruth { /// process function for to call doSameEvent with Data /// \param col subscribe to the collision table (Data) /// \param parts subscribe to the femtoUniverseParticleTable - void processSameEvent(o2::aod::FdCollision& col, - o2::aod::FDParticles& parts) + void processSameEvent(o2::aod::FdCollision const& col, + o2::aod::FDParticles const& parts) { fillCollision(col); @@ -225,7 +225,7 @@ struct femtoUniversePairTaskTrackTrackMcTruth { doSameEvent(thegroupPartsOne, thegroupPartsTwo, parts, col.magField(), col.multNtr()); } - PROCESS_SWITCH(femtoUniversePairTaskTrackTrackMcTruth, processSameEvent, "Enable processing same event", true); + PROCESS_SWITCH(FemtoUniversePairTaskTrackTrackMcTruth, processSameEvent, "Enable processing same event", true); /// This function processes the mixed event /// \todo the trivial loops over the collisions and tracks should be factored out since they will be common to all combinations of T-T, T-V0, V0-V0, ... @@ -243,14 +243,14 @@ struct femtoUniversePairTaskTrackTrackMcTruth { bool swpart = fNeventsProcessed % 2; fNeventsProcessed++; - for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { - if ((!ConfNoPDGPartOne && p2.tempFitVar() != ConfPDGCodePartOne) || (!ConfNoPDGPartTwo && p1.tempFitVar() != ConfPDGCodePartTwo)) { + for (auto const& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { + if ((!confNoPDGPartOne && p2.tempFitVar() != confPDGCodePartOne) || (!confNoPDGPartTwo && p1.tempFitVar() != confPDGCodePartTwo)) { continue; } if (swpart) - mixedEventCont.setPair(p1, p2, multCol, ConfUse3D); + mixedEventCont.setPair(p1, p2, multCol, confUse3D); else - mixedEventCont.setPair(p2, p1, multCol, ConfUse3D); + mixedEventCont.setPair(p2, p1, multCol, confUse3D); swpart = !swpart; } @@ -259,13 +259,13 @@ struct femtoUniversePairTaskTrackTrackMcTruth { /// process function for to call doMixedEvent with Data /// @param cols subscribe to the collisions table (Data) /// @param parts subscribe to the femtoUniverseParticleTable - void processMixedEvent(o2::aod::FdCollisions& cols, - o2::aod::FDParticles& parts) + void processMixedEvent(o2::aod::FdCollisions const& cols, + o2::aod::FDParticles const& parts) { - for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { + for (auto const& [collision1, collision2] : soa::selfCombinations(colBinning, 5, -1, cols, cols)) { const int multiplicityCol = collision1.multNtr(); - MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); + mixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); auto groupPartsOne = partsOne->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); auto groupPartsTwo = partsTwo->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); @@ -282,13 +282,13 @@ struct femtoUniversePairTaskTrackTrackMcTruth { doMixedEvent(groupPartsOne, groupPartsTwo, parts, magFieldTesla1, multiplicityCol); } } - PROCESS_SWITCH(femtoUniversePairTaskTrackTrackMcTruth, processMixedEvent, "Enable processing mixed events", true); + PROCESS_SWITCH(FemtoUniversePairTaskTrackTrackMcTruth, processMixedEvent, "Enable processing mixed events", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), }; return workflow; } diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx index 05c910b0b24..3dfb7d7f4ed 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackSpherHarMultKtExtended.cxx @@ -14,29 +14,32 @@ /// \remark This file is inherited from ~/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx on 17/06/2024 /// \author Pritam Chakraborty, WUT Warsaw, pritam.chakraborty@pw.edu.pl -#include -#include -#include "TRandom2.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" +#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" + +#include "Common/DataModel/PIDResponse.h" + +#include "Framework/ASoAHelpers.h" #include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" #include "Framework/HistogramRegistry.h" -#include "Framework/ASoAHelpers.h" +#include "Framework/O2DatabasePDGPlugin.h" #include "Framework/RunningWorkflowInfo.h" #include "Framework/StepTHn.h" -#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/PID.h" -#include "Common/DataModel/PIDResponse.h" -#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseSHContainer.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h" -#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniverseTrackSelection.h" -#include "PWGCF/FemtoUniverse/Core/FemtoUniversePairSHCentMultKt.h" +#include "TRandom2.h" + +#include +#include using namespace o2; using namespace o2::analysis::femto_universe; @@ -73,6 +76,15 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { Configurable ConfIsMC{"ConfIsMC", false, "Enable additional Histogramms in the case of a MonteCarlo Run"}; Configurable> ConfTrkPIDnSigmaMax{"ConfTrkPIDnSigmaMax", std::vector{4.f, 3.f, 2.f}, "This configurable needs to be the same as the one used in the producer task"}; Configurable ConfUse3D{"ConfUse3D", false, "Enable three dimensional histogramms (to be used only for analysis with high statistics): k* vs mT vs multiplicity"}; + Configurable ConfPhiBins{"ConfPhiBins", 29, "Number of phi bins in deta dphi"}; + Configurable ConfEtaBins{"ConfEtaBins", 29, "Number of eta bins in deta dphi"}; + Configurable ConfIsCPR{"ConfIsCPR", true, "Close Pair Rejection"}; + Configurable ConfCPRPlotPerRadii{"ConfCPRPlotPerRadii", false, "Plot CPR per radii"}; + Configurable ConfCPRdeltaPhiCutMax{"ConfCPRdeltaPhiCutMax", 0.0, "Delta Phi max cut for Close Pair Rejection"}; + Configurable ConfCPRdeltaPhiCutMin{"ConfCPRdeltaPhiCutMin", 0.0, "Delta Phi min cut for Close Pair Rejection"}; + Configurable ConfCPRdeltaEtaCutMax{"ConfCPRdeltaEtaCutMax", 0.0, "Delta Eta max cut for Close Pair Rejection"}; + Configurable ConfCPRdeltaEtaCutMin{"ConfCPRdeltaEtaCutMin", 0.0, "Delta Eta min cut for Close Pair Rejection"}; + Configurable ConfCPRChosenRadii{"ConfCPRChosenRadii", 0.80, "Delta Eta cut for Close Pair Rejection"}; } twotracksconfigs; using FemtoFullParticles = soa::Join; @@ -80,6 +92,8 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { Filter trackAdditionalfilter = (nabs(aod::femtouniverseparticle::eta) < twotracksconfigs.ConfEtaMax); // example filtering on configurable using FilteredFemtoFullParticles = soa::Filtered; // using FilteredFemtoFullParticles = FemtoFullParticles; //if no filtering is applied uncomment this option + using FemtoRecoParticles = soa::Join; + using FilteredFemtoRecoParticles = soa::Filtered; SliceCache cache; Preslice perCol = aod::femtouniverseparticle::fdCollisionId; @@ -96,8 +110,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { /// Partition for particle 1 Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && aod::femtouniverseparticle::sign == trackonefilter.ConfChargePart1 && aod::femtouniverseparticle::pt < trackonefilter.ConfPtHighPart1 && aod::femtouniverseparticle::pt > trackonefilter.ConfPtLowPart1; - - Partition> partsOneMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && aod::femtouniverseparticle::sign == trackonefilter.ConfChargePart1 && aod::femtouniverseparticle::pt < trackonefilter.ConfPtHighPart1 && aod::femtouniverseparticle::pt > trackonefilter.ConfPtLowPart1; + Partition partsOneMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && aod::femtouniverseparticle::sign == trackonefilter.ConfChargePart1 && aod::femtouniverseparticle::pt < trackonefilter.ConfPtHighPart1 && aod::femtouniverseparticle::pt > trackonefilter.ConfPtLowPart1; // /// Histogramming for particle 1 @@ -116,8 +129,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { /// Partition for particle 2 Partition partsTwo = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::sign == tracktwofilter.ConfChargePart2) && aod::femtouniverseparticle::pt < tracktwofilter.ConfPtHighPart2 && aod::femtouniverseparticle::pt > tracktwofilter.ConfPtLowPart2; - - Partition> partsTwoMC = aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack) && (aod::femtouniverseparticle::sign == tracktwofilter.ConfChargePart2) && aod::femtouniverseparticle::pt < tracktwofilter.ConfPtHighPart2 && aod::femtouniverseparticle::pt > tracktwofilter.ConfPtLowPart2; + Partition partsTwoMC = aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack) && (aod::femtouniverseparticle::sign == tracktwofilter.ConfChargePart2) && aod::femtouniverseparticle::pt < tracktwofilter.ConfPtHighPart2 && aod::femtouniverseparticle::pt > tracktwofilter.ConfPtLowPart2; /// Histogramming for particle 2 FemtoUniverseParticleHisto trackHistoPartTwo; @@ -169,13 +181,6 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { Configurable ConfIsLCMS{"ConfIsLCMS", true, "Choosing LCMS or PRF"}; Configurable ConfNEventsMix{"ConfNEventsMix", 5, "Number of events for mixing"}; Configurable ConfLMax{"ConfLMax", 2, "Maximum value of l"}; - Configurable ConfIsCPR{"ConfIsCPR", true, "Close Pair Rejection"}; - Configurable ConfCPRPlotPerRadii{"ConfCPRPlotPerRadii", false, "Plot CPR per radii"}; - Configurable ConfCPRdeltaPhiCutMax{"ConfCPRdeltaPhiCutMax", 0.0, "Delta Phi max cut for Close Pair Rejection"}; - Configurable ConfCPRdeltaPhiCutMin{"ConfCPRdeltaPhiCutMin", 0.0, "Delta Phi min cut for Close Pair Rejection"}; - Configurable ConfCPRdeltaEtaCutMax{"ConfCPRdeltaEtaCutMax", 0.0, "Delta Eta max cut for Close Pair Rejection"}; - Configurable ConfCPRdeltaEtaCutMin{"ConfCPRdeltaEtaCutMin", 0.0, "Delta Eta min cut for Close Pair Rejection"}; - Configurable ConfCPRChosenRadii{"ConfCPRChosenRadii", 0.80, "Delta Eta cut for Close Pair Rejection"}; Configurable cfgProcessPM{"cfgProcessPM", false, "Process particles of the opposite charge"}; Configurable cfgProcessPP{"cfgProcessPP", true, "Process particles of the same, positice charge"}; Configurable cfgProcessMM{"cfgProcessMM", true, "Process particles of the same, positice charge"}; @@ -185,6 +190,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { Configurable ConfIsFillAngqLCMS{"ConfIsFillAngqLCMS", true, "Fill qLCMS vs dEta vs dPhi"}; Configurable confCPRDistMax{"confCPRDistMax", 0.0, "Max. radial seperation between two closed-pairs"}; Configurable confCPRFracMax{"confCPRFracMax", 0.0, "Max. allowed fraction bad to all TPC points of radial seperation between two closed-pairs"}; + Configurable confCPRIsAtITS{"confCPRIsAtITS", false, "Close Pair Rejection at ITS or TPC"}; Configurable confCPRDphiAvgOrDist{"confCPRDphiAvgOrDist", true, "Close Pair Rejection by radial or angular seperation"}; FemtoUniverseSHContainer sameEventCont; @@ -196,6 +202,8 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { FemtoUniverseSHContainer sameEventContMM; FemtoUniverseSHContainer mixedEventContMM; + FemtoUniverseContainer sameEventCont1D; + FemtoUniversePairCleaner pairCleaner; FemtoUniverseDetaDphiStar pairCloseRejection; FemtoUniverseTrackSelection trackCuts; @@ -215,6 +223,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { /// Histogram output HistogramRegistry qaRegistry{"TrackQA", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry resultRegistry{"Correlations", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry resultRegistry1D{"Correlations1D", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; HistogramRegistry resultRegistryPM{"CorrelationsPM", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; HistogramRegistry resultRegistryPP{"CorrelationsPP", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; HistogramRegistry resultRegistryMM{"CorrelationsMM", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; @@ -403,6 +412,8 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { sameEventMultContPP.init(&SameMultRegistryPP, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, ConfLMax); mixedEventMultContPP.init(&MixedMultRegistryPP, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, ConfLMax); } + sameEventCont1D.init(&resultRegistry1D, ConfkstarBins, ConfMultBinsCent, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, twotracksconfigs.ConfEtaBins, twotracksconfigs.ConfPhiBins, twotracksconfigs.ConfIsMC, twotracksconfigs.ConfUse3D); + sameEventCont1D.setPDGCodes(trackonefilter.ConfPDGCodePartOne, tracktwofilter.ConfPDGCodePartTwo); } if (cfgProcessMM) { @@ -415,11 +426,13 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { sameEventMultContMM.init(&SameMultRegistryMM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, ConfLMax); mixedEventMultContMM.init(&MixedMultRegistryMM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, ConfLMax); } + sameEventCont1D.init(&resultRegistry1D, ConfkstarBins, ConfMultBinsCent, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, twotracksconfigs.ConfEtaBins, twotracksconfigs.ConfPhiBins, twotracksconfigs.ConfIsMC, twotracksconfigs.ConfUse3D); + sameEventCont1D.setPDGCodes(trackonefilter.ConfPDGCodePartOne, tracktwofilter.ConfPDGCodePartTwo); } pairCleaner.init(&qaRegistry); - if (ConfIsCPR.value) { - pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiCutMin.value, ConfCPRdeltaPhiCutMax.value, ConfCPRdeltaEtaCutMin.value, ConfCPRdeltaEtaCutMax.value, ConfCPRChosenRadii.value, ConfCPRPlotPerRadii.value); + if (twotracksconfigs.ConfIsCPR.value) { + pairCloseRejection.init(&resultRegistry, &qaRegistry, twotracksconfigs.ConfCPRdeltaPhiCutMin.value, twotracksconfigs.ConfCPRdeltaPhiCutMax.value, twotracksconfigs.ConfCPRdeltaEtaCutMin.value, twotracksconfigs.ConfCPRdeltaEtaCutMax.value, twotracksconfigs.ConfCPRChosenRadii.value, twotracksconfigs.ConfCPRPlotPerRadii.value); } vPIDPartOne = trackonefilter.ConfPIDPartOne.value; @@ -459,6 +472,7 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { continue; } trackHistoPartOne.fillQA(part); + trackHistoPartOne.fillQAMisIden(part, trackonefilter.ConfPDGCodePartOne); } } @@ -484,9 +498,15 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { continue; } - if (ConfIsCPR.value) { - if (pairCloseRejection.isClosePairFrac(p1, p2, magFieldTesla, femto_universe_container::EventType::same, confCPRDphiAvgOrDist, confCPRDistMax, confCPRFracMax)) { - continue; + if (twotracksconfigs.ConfIsCPR.value) { + if (confCPRIsAtITS.value) { + if (pairCloseRejection.isClosePairAtITS(p1, p2, magFieldTesla, femto_universe_container::EventType::same)) { + continue; + } + } else { + if (pairCloseRejection.isClosePairFrac(p1, p2, magFieldTesla, femto_universe_container::EventType::same, confCPRDphiAvgOrDist, confCPRDistMax, confCPRFracMax)) { + continue; + } } } @@ -508,9 +528,15 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { continue; } - if (ConfIsCPR.value) { - if (pairCloseRejection.isClosePairFrac(p1, p2, magFieldTesla, femto_universe_container::EventType::same, confCPRDphiAvgOrDist, confCPRDistMax, confCPRFracMax)) { - continue; + if (twotracksconfigs.ConfIsCPR.value) { + if (confCPRIsAtITS.value) { + if (pairCloseRejection.isClosePairAtITS(p1, p2, magFieldTesla, femto_universe_container::EventType::same)) { + continue; + } + } else { + if (pairCloseRejection.isClosePairFrac(p1, p2, magFieldTesla, femto_universe_container::EventType::same, confCPRDphiAvgOrDist, confCPRDistMax, confCPRFracMax)) { + continue; + } } } @@ -531,9 +557,17 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { if (rand > 0.5) { sameEventMultContPP.fillMultNumDen(p1, p2, femto_universe_sh_container::EventType::same, 2, multCol, kT, ConfIsIden); f3d = FemtoUniverseMath::newpairfunc(p1, mass1, p2, mass2, ConfIsIden); + if (twotracksconfigs.ConfIsMC) { + float weight = 1.0f; + sameEventCont1D.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, weight, ConfIsIden); + } } else if (rand <= 0.5) { sameEventMultContPP.fillMultNumDen(p2, p1, femto_universe_sh_container::EventType::same, 2, multCol, kT, ConfIsIden); f3d = FemtoUniverseMath::newpairfunc(p2, mass2, p1, mass1, ConfIsIden); + if (twotracksconfigs.ConfIsMC) { + float weight = 1.0f; + sameEventCont1D.setPair(p2, p1, multCol, twotracksconfigs.ConfUse3D, weight, ConfIsIden); + } } if (ConfIsFillAngqLCMS) { kv = std::sqrt(f3d[1] * f3d[1] + f3d[2] * f3d[2] + f3d[3] * f3d[3]); @@ -546,9 +580,17 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { if (rand > 0.5) { sameEventMultContMM.fillMultNumDen(p1, p2, femto_universe_sh_container::EventType::same, 2, multCol, kT, ConfIsIden); f3d = FemtoUniverseMath::newpairfunc(p1, mass1, p2, mass2, ConfIsIden); + if (twotracksconfigs.ConfIsMC) { + float weight = 1.0f; + sameEventCont1D.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, weight, ConfIsIden); + } } else if (rand <= 0.5) { sameEventMultContMM.fillMultNumDen(p2, p1, femto_universe_sh_container::EventType::same, 2, multCol, kT, ConfIsIden); f3d = FemtoUniverseMath::newpairfunc(p2, mass2, p1, mass1, ConfIsIden); + if (twotracksconfigs.ConfIsMC) { + float weight = 1.0f; + sameEventCont1D.setPair(p2, p1, multCol, twotracksconfigs.ConfUse3D, weight, ConfIsIden); + } } if (ConfIsFillAngqLCMS) { kv = std::sqrt(f3d[1] * f3d[1] + f3d[2] * f3d[2] + f3d[3] * f3d[3]); @@ -607,8 +649,8 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { /// \param parts subscribe to joined table FemtoUniverseParticles and FemtoUniverseMCLables to access Monte Carlo truth /// \param FemtoUniverseMCParticles subscribe to the Monte Carlo truth table void processSameEventMC(o2::aod::FdCollision const& col, - soa::Join const& parts, - o2::aod::FdMCParticles const&) + FilteredFemtoRecoParticles const& parts, + aod::FdMCParticles const&) { fillCollision(col, ConfIsCent); @@ -622,20 +664,20 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { doSameEvent(thegroupPartsOne, thegroupPartsTwo, parts, col.magField(), col.multV0M(), 1, fillQA); } if (cfgProcessPP) { - doSameEvent(thegroupPartsOne, thegroupPartsOne, parts, col.magField(), col.multV0M(), 2, fillQA); + doSameEvent(thegroupPartsOne, thegroupPartsOne, parts, col.magField(), col.multV0M(), 2, fillQA); } if (cfgProcessMM) { - doSameEvent(thegroupPartsTwo, thegroupPartsTwo, parts, col.magField(), col.multV0M(), 3, fillQA); + doSameEvent(thegroupPartsTwo, thegroupPartsTwo, parts, col.magField(), col.multV0M(), 3, fillQA); } } else { if (cfgProcessPM) { doSameEvent(thegroupPartsOne, thegroupPartsTwo, parts, col.magField(), col.multNtr(), 1, fillQA); } if (cfgProcessPP) { - doSameEvent(thegroupPartsOne, thegroupPartsOne, parts, col.magField(), col.multNtr(), 2, fillQA); + doSameEvent(thegroupPartsOne, thegroupPartsOne, parts, col.magField(), col.multNtr(), 2, fillQA); } if (cfgProcessMM) { - doSameEvent(thegroupPartsTwo, thegroupPartsTwo, parts, col.magField(), col.multNtr(), 3, fillQA); + doSameEvent(thegroupPartsTwo, thegroupPartsTwo, parts, col.magField(), col.multNtr(), 3, fillQA); } } delete randgen; @@ -666,9 +708,15 @@ struct femtoUniversePairTaskTrackTrackSpherHarMultKtExtended { continue; } - if (ConfIsCPR.value) { - if (pairCloseRejection.isClosePairFrac(p1, p2, magFieldTesla, femto_universe_container::EventType::mixed, confCPRDphiAvgOrDist, confCPRDistMax, confCPRFracMax)) { - continue; + if (twotracksconfigs.ConfIsCPR.value) { + if (confCPRIsAtITS.value) { + if (pairCloseRejection.isClosePairAtITS(p1, p2, magFieldTesla, femto_universe_container::EventType::mixed)) { + continue; + } + } else { + if (pairCloseRejection.isClosePairFrac(p1, p2, magFieldTesla, femto_universe_container::EventType::mixed, confCPRDphiAvgOrDist, confCPRDistMax, confCPRFracMax)) { + continue; + } } } diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Helicity.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Helicity.cxx new file mode 100644 index 00000000000..bd66de7dc37 --- /dev/null +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Helicity.cxx @@ -0,0 +1,998 @@ +// Copyright 2019-2022 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file femtoUniversePairTaskTrackV0Helicity.cxx +/// \brief Tasks that build pairs of track particles and v0s +/// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de +/// \author Zuzanna Chochulska, WUT Warsaw & CTU Prague, zchochul@cern.ch +/// \author Shirajum Monira, WUT Warsaw, shirajum.monira.dokt@pw.edu.pl + +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseContainer.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseDetaDphiStar.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseEventHisto.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseMath.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniversePairCleaner.h" +#include "PWGCF/FemtoUniverse/Core/FemtoUniverseParticleHisto.h" +#include "PWGCF/FemtoUniverse/Core/femtoUtils.h" +#include "PWGCF/FemtoUniverse/DataModel/FemtoDerived.h" + +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" + +#include +#include + +#include +#include +#include + +using namespace o2; +using namespace o2::soa; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::analysis::femto_universe; +using namespace o2::aod::pidutils; +using namespace o2::track; + +struct FemtoUniversePairTaskTrackV0Helicity { + + Service pdg; + Service pdgMC; + + SliceCache cache; + using FemtoFullParticles = soa::Join; + Preslice perCol = aod::femtouniverseparticle::fdCollisionId; + + using FemtoRecoParticles = soa::Join; + Preslice perColMC = aod::femtouniverseparticle::fdCollisionId; + + /// To apply narrow cut + Configurable confZVertexCut{"confZVertexCut", 10.f, "Event sel: Maximum z-Vertex (cm)"}; + Configurable confEta{"confEta", 0.8, "Eta cut for the global track"}; + + /// Particle 1 (track) + Configurable confTrkPDGCodePartOne{"confTrkPDGCodePartOne", 211, "Particle 1 (Track) - PDG code"}; + Configurable confTrackChoicePartOne{"confTrackChoicePartOne", 1, "0:Proton, 1:Pion, 2:Kaon"}; + ConfigurableAxis confTrkTempFitVarBins{"confTrkTempFitVarBins", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; + ConfigurableAxis confTrkTempFitVarpTBins{"confTrkTempFitVarpTBins", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot"}; + Configurable confChargePart1{"confChargePart1", 0, "sign of particle 1"}; + Configurable confHPtPart1{"confHPtPart1", 4.0f, "higher limit for pt of particle 1"}; + Configurable confLPtPart1{"confLPtPart1", 0.3f, "lower limit for pt of particle 1"}; + Configurable confmom{"confmom", 0.5, "momentum threshold for particle identification using TOF"}; + Configurable confNsigmaTPCParticle{"confNsigmaTPCParticle", 3.0, "TPC Sigma for particle momentum < confmom"}; + Configurable confNsigmaCombinedParticle{"confNsigmaCombinedParticle", 3.0, "TPC and TOF Sigma (combined) for particle momentum > confmom"}; + + Filter collisionFilter = (nabs(aod::collision::posZ) < confZVertexCut); + using FilteredFDCollisions = soa::Filtered; + using FilteredFDCollision = FilteredFDCollisions::iterator; + + /// Partition for particle 1 + Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::sign == confChargePart1) && (nabs(aod::femtouniverseparticle::eta) < confEta) && (aod::femtouniverseparticle::pt < confHPtPart1) && (aod::femtouniverseparticle::pt > confLPtPart1); + Partition partsOneMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && (nabs(aod::femtouniverseparticle::eta) < confEta) && (aod::femtouniverseparticle::pt < confHPtPart1) && (aod::femtouniverseparticle::pt > confLPtPart1); + Partition partsOneMCReco = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::sign == confChargePart1) && (nabs(aod::femtouniverseparticle::eta) < confEta) && (aod::femtouniverseparticle::pt < confHPtPart1) && (aod::femtouniverseparticle::pt > confLPtPart1); + + /// Histogramming for particle 1 + FemtoUniverseParticleHisto trackHistoPartOnePos; + FemtoUniverseParticleHisto trackHistoPartOneNeg; + + /// Particle 2 (V0) + Configurable confV0PDGCodePartTwo{"confV0PDGCodePartTwo", 3122, "Particle 2 (V0) - PDG code"}; + ConfigurableAxis confV0TempFitVarBins{"confV0TempFitVarBins", {300, 0.95, 1.}, "V0: binning of the TempFitVar in the pT vs. TempFitVar plot"}; + ConfigurableAxis confV0TempFitVarpTBins{"confV0TempFitVarpTBins", {20, 0.5, 4.05}, "V0: pT binning of the pT vs. TempFitVar plot"}; + Configurable confV0Type1{"confV0Type1", 0, "select one of the V0s (lambda = 0, anti-lambda = 1, k0 = 2) for v0-v0 and Track-v0 combination"}; + Configurable confV0Type2{"confV0Type2", 0, "select one of the V0s (lambda = 0, anti-lambda = 1, k0 = 2) for v0-v0 combination"}; + Configurable confV0InvMassLowLimit{"confV0InvMassLowLimit", 1.10, "Lower limit of the V0 invariant mass"}; + Configurable confV0InvMassUpLimit{"confV0InvMassUpLimit", 1.13, "Upper limit of the V0 invariant mass"}; + ConfigurableAxis confChildTempFitVarBins{"confChildTempFitVarBins", {300, -0.15, 0.15}, "V0 child: binning of the TempFitVar in the pT vs. TempFitVar plot"}; + ConfigurableAxis confChildTempFitVarpTBins{"confChildTempFitVarpTBins", {20, 0.5, 4.05}, "V0 child: pT binning of the pT vs. TempFitVar plot"}; + Configurable confHPtPart2{"confHPtPart2", 4.0f, "higher limit for pt of particle 2"}; + Configurable confLPtPart2{"confLPtPart2", 0.3f, "lower limit for pt of particle 2"}; + Configurable confPDGCodeV0{"confPDGCodeV0", 3122, "V0 -- PDG code"}; + Configurable confPDGCodePosChild{"confPDGCodePosChild", 2212, "Positive Child -- PDG code"}; + Configurable confPDGCodeNegChild{"confPDGCodeNegChild", 211, "Negative Child -- PDG code"}; + + /// Partition for particle 2 + Partition partsTwo = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kV0)) && (aod::femtouniverseparticle::pt < confHPtPart2) && (aod::femtouniverseparticle::pt > confLPtPart2); + Partition partsTwoMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && (aod::femtouniverseparticle::pt < confHPtPart2) && (aod::femtouniverseparticle::pt > confLPtPart2); + Partition partsTwoMCReco = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kV0)) && (aod::femtouniverseparticle::pt < confHPtPart2) && (aod::femtouniverseparticle::pt > confLPtPart2); + + /// Histogramming for particle 2 + FemtoUniverseParticleHisto trackHistoPartTwo; + FemtoUniverseParticleHisto posChildHistos; + FemtoUniverseParticleHisto negChildHistos; + + FemtoUniverseParticleHisto trackHistoV0Type1; + FemtoUniverseParticleHisto posChildV0Type1; + FemtoUniverseParticleHisto negChildV0Type1; + FemtoUniverseParticleHisto trackHistoV0Type2; + FemtoUniverseParticleHisto posChildV0Type2; + FemtoUniverseParticleHisto negChildV0Type2; + + /// Histogramming for Event + FemtoUniverseEventHisto eventHisto; + + /// Correlation part + // Configurable confTrackChoicePartTwo{"confTrackChoicePartTwo", 1, "0:Proton, 1:Pion, 2:Kaon"}; //not used + Configurable confIsMC{"confIsMC", false, "Enable additional Histograms in the case of a MonteCarlo Run"}; + Configurable confUse3D{"confUse3D", false, "Enable three dimensional histogramms (to be used only for analysis with high statistics): k* vs mT vs multiplicity"}; + Configurable confUseCent{"confUseCent", false, "Use centrality in place of multiplicity"}; + ConfigurableAxis confMultBins{"confMultBins", {VARIABLE_WIDTH, 0.0f, 20.0f, 40.0f, 60.0f, 80.0f, 100.0f, 200.0f, 99999.f}, "Mixing bins - multiplicity"}; + ConfigurableAxis confVtxBins{"confVtxBins", {VARIABLE_WIDTH, -10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}, "Mixing bins - z-vertex"}; + Configurable confNEventsMix{"confNEventsMix", 5, "Number of events for mixing"}; + ConfigurableAxis confkstarBins{"confkstarBins", {1500, 0., 6.}, "binning kstar"}; + ConfigurableAxis confkTBins{"confkTBins", {150, 0., 9.}, "binning kT"}; + ConfigurableAxis confmTBins{"confmTBins", {225, 0., 7.5}, "binning mT"}; + Configurable confIsCPR{"confIsCPR", true, "Close Pair Rejection"}; + Configurable confCPRPlotPerRadii{"confCPRPlotPerRadii", false, "Plot CPR per radii"}; + Configurable confCPRdeltaPhiCutMax{"confCPRdeltaPhiCutMax", 0.0, "Delta Phi max cut for Close Pair Rejection"}; + Configurable confCPRdeltaPhiCutMin{"confCPRdeltaPhiCutMin", 0.0, "Delta Phi min cut for Close Pair Rejection"}; + Configurable confCPRdeltaEtaCutMax{"confCPRdeltaEtaCutMax", 0.0, "Delta Eta max cut for Close Pair Rejection"}; + Configurable confCPRdeltaEtaCutMin{"confCPRdeltaEtaCutMin", 0.0, "Delta Eta min cut for Close Pair Rejection"}; + Configurable confCPRChosenRadii{"confCPRChosenRadii", 0.80, "Delta Eta cut for Close Pair Rejection"}; + Configurable confPhiBins{"confPhiBins", 29, "Number of phi bins in deta dphi"}; + Configurable confEtaBins{"confEtaBins", 29, "Number of eta bins in deta dphi"}; + ConfigurableAxis confmTBins3D{"confmTBins3D", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; + ConfigurableAxis confMultBins3D{"confMultBins3D", {VARIABLE_WIDTH, 0.0f, 20.0f, 30.0f, 40.0f, 99999.0f}, "multiplicity Binning for the 3Dimensional plot: k* vs multiplicity vs mT (set <> to true in order to use)"}; + + // Efficiency + Configurable confLocalEfficiency{"confLocalEfficiency", "", "Local path to efficiency .root file"}; + + static constexpr unsigned int V0ChildTable[][2] = {{0, 1}, {1, 0}, {1, 1}}; // Table to select the V0 children + + FemtoUniverseContainer sameEventCont; + FemtoUniverseContainer mixedEventCont; + FemtoUniversePairCleaner pairCleaner; + FemtoUniversePairCleaner pairCleanerV0; + FemtoUniverseDetaDphiStar pairCloseRejection; + FemtoUniverseDetaDphiStar pairCloseRejectionV0; + + /// Histogram output + HistogramRegistry qaRegistry{"TrackQA", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry thetaRegistry{"ThetaQA", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry resultRegistry{"Correlations", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry registryMCtruth{"MCtruthHistos", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; + HistogramRegistry registryMCreco{"MCrecoHistos", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; + HistogramRegistry mixQaRegistry{"mixQaRegistry", {}, OutputObjHandlingPolicy::AnalysisObject}; + + std::unique_ptr plocalEffFile; + std::unique_ptr plocalEffp1; + std::unique_ptr plocalEffp2; + + bool isNSigmaCombined(float mom, float nsigmaTPCParticle, float nsigmaTOFParticle) + { + if (mom <= confmom) { + return (std::abs(nsigmaTPCParticle) < confNsigmaTPCParticle); + } else { + return (std::hypot(nsigmaTOFParticle, nsigmaTPCParticle) < confNsigmaCombinedParticle); + } + } + + bool invMLambda(float invMassLambda, float invMassAntiLambda) + { + if ((invMassLambda < confV0InvMassLowLimit || invMassLambda > confV0InvMassUpLimit) && (invMassAntiLambda < confV0InvMassLowLimit || invMassAntiLambda > confV0InvMassUpLimit)) { + return false; + } + return true; + } + + bool isNSigmaTPC(float nsigmaTPCParticle) + { + if (std::abs(nsigmaTPCParticle) < confNsigmaTPCParticle) { + return true; + } else { + return false; + } + } + + template + bool isParticleCombined(const T& part, int id) + { + const float tpcNSigmas[3] = {unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tpcNSigmaStorePi()), unPackInTable(part.tpcNSigmaStoreKa())}; + // const float tofNSigmas[3] = {part.tofNSigmaPr(), part.tofNSigmaPi(), part.tofNSigmaKa()}; + const float tofNSigmas[3] = {unPackInTable(part.tofNSigmaStorePr()), unPackInTable(part.tofNSigmaStorePi()), unPackInTable(part.tofNSigmaStoreKa())}; + + return isNSigmaCombined(part.p(), tpcNSigmas[id], tofNSigmas[id]); + } + + template + bool isParticleTPC(const T& part, int id) + { + const float tpcNSigmas[3] = {unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tpcNSigmaStorePi()), unPackInTable(part.tpcNSigmaStoreKa())}; + + return isNSigmaTPC(tpcNSigmas[id]); + } + + void init(InitContext&) + { + eventHisto.init(&qaRegistry); + qaRegistry.add("Tracks_pos/nSigmaTPC", "; #it{p} (GeV/#it{c}); n#sigma_{TPC}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + qaRegistry.add("Tracks_pos/nSigmaTOF", "; #it{p} (GeV/#it{c}); n#sigma_{TOF}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + qaRegistry.add("Tracks_neg/nSigmaTPC", "; #it{p} (GeV/#it{c}); n#sigma_{TPC}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + qaRegistry.add("Tracks_neg/nSigmaTOF", "; #it{p} (GeV/#it{c}); n#sigma_{TOF}", kTH2F, {{100, 0, 10}, {200, -4.975, 5.025}}); + trackHistoPartOnePos.init(&qaRegistry, confTrkTempFitVarpTBins, confTrkTempFitVarBins, confIsMC, confTrkPDGCodePartOne); + trackHistoPartOneNeg.init(&qaRegistry, confTrkTempFitVarpTBins, confTrkTempFitVarBins, confIsMC, confTrkPDGCodePartOne); + trackHistoPartTwo.init(&qaRegistry, confV0TempFitVarpTBins, confV0TempFitVarBins, confIsMC, confV0PDGCodePartTwo, true); + posChildHistos.init(&qaRegistry, confChildTempFitVarpTBins, confChildTempFitVarBins, false, 0, true); + negChildHistos.init(&qaRegistry, confChildTempFitVarpTBins, confChildTempFitVarBins, false, 0, true); + + trackHistoV0Type1.init(&qaRegistry, confV0TempFitVarpTBins, confV0TempFitVarBins, confIsMC, confV0PDGCodePartTwo, true, "V0Type1"); + posChildV0Type1.init(&qaRegistry, confChildTempFitVarpTBins, confChildTempFitVarBins, false, 0, true, "posChildV0Type1"); + negChildV0Type1.init(&qaRegistry, confChildTempFitVarpTBins, confChildTempFitVarBins, false, 0, true, "negChildV0Type1"); + trackHistoV0Type2.init(&qaRegistry, confV0TempFitVarpTBins, confV0TempFitVarBins, confIsMC, confV0PDGCodePartTwo, true, "V0Type2"); + posChildV0Type2.init(&qaRegistry, confChildTempFitVarpTBins, confChildTempFitVarBins, false, 0, true, "posChildV0Type2"); + negChildV0Type2.init(&qaRegistry, confChildTempFitVarpTBins, confChildTempFitVarBins, false, 0, true, "negChildV0Type2"); + + // Helicity angle + thetaRegistry.add("Theta/hTheta", " ; p (GeV/#it{c}); cos(#theta)", kTH2F, {{100, 0, 10}, {110, -1.1, 1.1}}); + thetaRegistry.add("Theta/hTheta3D_PosChild", " ; p_{V0} (GeV/#it{c}); cos(#theta); p_{Positive Child} (GeV/#it{c})", kTH3F, {{100, 0, 10}, {110, -1.1, 1.1}, {100, 0, 10}}); + thetaRegistry.add("Theta/hTheta3D_NegChild", " ; p_{V0} (GeV/#it{c}); cos(#theta); p_{Negative Child} (GeV/#it{c})", kTH3F, {{100, 0, 10}, {110, -1.1, 1.1}, {100, 0, 10}}); + thetaRegistry.add("Theta/PositiveChild/hThetaPt", " ; p_{T} (GeV/#it{c}); cos(#theta)", kTH2F, {{100, 0, 10}, {110, -1.1, 1.1}}); + thetaRegistry.add("Theta/PositiveChild/hThetaEta", " ; #eta; cos(#theta)", kTH2F, {{100, -1, 1}, {110, -1.1, 1.1}}); + thetaRegistry.add("Theta/PositiveChild/hThetaPhi", " ; #phi; cos(#theta)", kTH2F, {{100, -1, 7}, {110, -1.1, 1.1}}); + thetaRegistry.add("Theta/NegativeChild/hThetaPt", " ; p_{T} (GeV/#it{c}); cos(#theta)", kTH2F, {{100, 0, 10}, {110, -1.1, 1.1}}); + thetaRegistry.add("Theta/NegativeChild/hThetaEta", " ; #eta; cos(#theta)", kTH2F, {{100, -1, 1}, {110, -1.1, 1.1}}); + thetaRegistry.add("Theta/NegativeChild/hThetaPhi", " ; #phi; cos(#theta)", kTH2F, {{100, -1, 7}, {110, -1.1, 1.1}}); + + mixQaRegistry.add("MixingQA/hMECollisionBins", ";bin;Entries", kTH1F, {{120, -0.5, 119.5}}); + + // MC truth + registryMCtruth.add("plus/MCtruthLambda", "MC truth Lambdas;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + registryMCtruth.add("minus/MCtruthLambda", "MC truth Lambdas;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + + registryMCtruth.add("plus/MCtruthAllPt", "MC truth all;#it{p}_{T} (GeV/c); #eta", {HistType::kTH1F, {{500, 0, 5}}}); + registryMCtruth.add("minus/MCtruthAllPt", "MC truth all;#it{p}_{T} (GeV/c); #eta", {HistType::kTH1F, {{500, 0, 5}}}); + + registryMCtruth.add("plus/MCtruthPi", "MC truth pions;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + registryMCtruth.add("plus/MCtruthPr", "MC truth protons;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + + registryMCtruth.add("minus/MCtruthPi", "MC truth pions;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + registryMCtruth.add("minus/MCtruthPr", "MC truth protons;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + + registryMCtruth.add("plus/MCtruthPiPt", "MC truth pions;#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); + registryMCtruth.add("plus/MCtruthPrPt", "MC truth protons;#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); + registryMCtruth.add("minus/MCtruthPiPt", "MC truth pions;#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); + registryMCtruth.add("minus/MCtruthPrPt", "MC truth protons;#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); + + registryMCtruth.add("PosChildMCTruth/hPt", " ; p_{T} (GeV/#it{c}); ", {HistType::kTH1F, {{100, 0, 5}}}); + registryMCtruth.add("NegChildMCTruth/hPt", " ; p_{T} (GeV/#it{c}); ", {HistType::kTH1F, {{100, 0, 5}}}); + + registryMCtruth.add("ThetaMCTruth/hTheta", " ; p (GeV/#it{c}); cos(#theta)", kTH2F, {{100, 0, 10}, {110, -1.1, 1.1}}); + registryMCtruth.add("ThetaMCTruth/hTheta3D_PosChild", " ; p_{V0} (GeV/#it{c}); cos(#theta); p_{Positive Child} (GeV/#it{c})", kTH3F, {{100, 0, 10}, {110, -1.1, 1.1}, {100, 0, 10}}); + registryMCtruth.add("ThetaMCTruth/hTheta3D_NegChild", " ; p_{V0} (GeV/#it{c}); cos(#theta); p_{Negative Child} (GeV/#it{c})", kTH3F, {{100, 0, 10}, {110, -1.1, 1.1}, {100, 0, 10}}); + registryMCtruth.add("ThetaMCTruth/PositiveChild/hThetaPt", " ; p_{T} (GeV/#it{c}); cos(#theta)", kTH2F, {{100, 0, 10}, {110, -1.1, 1.1}}); + registryMCtruth.add("ThetaMCTruth/PositiveChild/hThetaEta", " ; #eta; cos(#theta)", kTH2F, {{100, -1, 1}, {110, -1.1, 1.1}}); + registryMCtruth.add("ThetaMCTruth/PositiveChild/hThetaPhi", " ; #phi; cos(#theta)", kTH2F, {{100, -1, 7}, {110, -1.1, 1.1}}); + registryMCtruth.add("ThetaMCTruth/NegativeChild/hThetaPt", " ; p_{T} (GeV/#it{c}); cos(#theta)", kTH2F, {{100, 0, 10}, {110, -1.1, 1.1}}); + registryMCtruth.add("ThetaMCTruth/NegativeChild/hThetaEta", " ; #eta; cos(#theta)", kTH2F, {{100, -1, 1}, {110, -1.1, 1.1}}); + registryMCtruth.add("ThetaMCTruth/NegativeChild/hThetaPhi", " ; #phi; cos(#theta)", kTH2F, {{100, -1, 7}, {110, -1.1, 1.1}}); + + // MC reco + registryMCreco.add("plus/MCrecoLambda", "MC reco Lambdas;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + registryMCreco.add("plus/MCrecoLambdaChildPr", "MC reco Lambdas;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + registryMCreco.add("plus/MCrecoLambdaChildPi", "MC reco Lambdas;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + registryMCreco.add("minus/MCrecoLambda", "MC reco Lambdas;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + registryMCreco.add("minus/MCrecoLambdaChildPr", "MC reco Lambdas;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + registryMCreco.add("minus/MCrecoLambdaChildPi", "MC reco Lambdas;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + + registryMCreco.add("plus/MCrecoAllPt", "MC reco all;#it{p}_{T} (GeV/c); #eta", {HistType::kTH1F, {{500, 0, 5}}}); + registryMCreco.add("minus/MCrecoAllPt", "MC reco all;#it{p}_{T} (GeV/c); #eta", {HistType::kTH1F, {{500, 0, 5}}}); + + registryMCreco.add("plus/MCrecoPi", "MC reco pions;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + registryMCreco.add("plus/MCrecoPr", "MC reco protons;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + + registryMCreco.add("minus/MCrecoPi", "MC reco pions;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + registryMCreco.add("minus/MCrecoPr", "MC reco protons;#it{p}_{T} (GeV/c); #eta", {HistType::kTH2F, {{500, 0, 5}, {400, -1.0, 1.0}}}); + + registryMCreco.add("plus/MCrecoPiPt", "MC reco pions;#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); + registryMCreco.add("plus/MCrecoPrPt", "MC reco protons;#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); + registryMCreco.add("minus/MCrecoPiPt", "MC reco pions;#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); + registryMCreco.add("minus/MCrecoPrPt", "MC reco protons;#it{p}_{T} (GeV/c)", {HistType::kTH1F, {{500, 0, 5}}}); + + registryMCreco.add("ThetaMCReco/hTheta", " ; p (GeV/#it{c}); cos(#theta)", kTH2F, {{100, 0, 10}, {110, -1.1, 1.1}}); + registryMCreco.add("ThetaMCReco/PositiveChild/hThetaPt", " ; p_{T} (GeV/#it{c}); cos(#theta)", kTH2F, {{100, 0, 10}, {110, -1.1, 1.1}}); + registryMCreco.add("ThetaMCReco/PositiveChild/hThetaEta", " ; #eta; cos(#theta)", kTH2F, {{100, -1, 1}, {110, -1.1, 1.1}}); + registryMCreco.add("ThetaMCReco/PositiveChild/hThetaPhi", " ; #phi; cos(#theta)", kTH2F, {{100, -1, 7}, {110, -1.1, 1.1}}); + registryMCreco.add("ThetaMCReco/NegativeChild/hThetaPt", " ; p_{T} (GeV/#it{c}); cos(#theta)", kTH2F, {{100, 0, 10}, {110, -1.1, 1.1}}); + registryMCreco.add("ThetaMCReco/NegativeChild/hThetaEta", " ; #eta; cos(#theta)", kTH2F, {{100, -1, 1}, {110, -1.1, 1.1}}); + registryMCreco.add("ThetaMCReco/NegativeChild/hThetaPhi", " ; #phi; cos(#theta)", kTH2F, {{100, -1, 7}, {110, -1.1, 1.1}}); + + sameEventCont.init(&resultRegistry, confkstarBins, confMultBins, confkTBins, confmTBins, confMultBins3D, confmTBins3D, confEtaBins, confPhiBins, confIsMC, confUse3D); + sameEventCont.setPDGCodes(confTrkPDGCodePartOne, confV0PDGCodePartTwo); + mixedEventCont.init(&resultRegistry, confkstarBins, confMultBins, confkTBins, confmTBins, confMultBins3D, confmTBins3D, confEtaBins, confPhiBins, confIsMC, confUse3D); + mixedEventCont.setPDGCodes(confTrkPDGCodePartOne, confV0PDGCodePartTwo); + + pairCleaner.init(&qaRegistry); + pairCleanerV0.init(&qaRegistry); + if (confIsCPR.value) { + pairCloseRejection.init(&resultRegistry, &qaRegistry, confCPRdeltaPhiCutMin.value, confCPRdeltaPhiCutMax.value, confCPRdeltaEtaCutMin.value, confCPRdeltaEtaCutMax.value, confCPRChosenRadii.value, confCPRPlotPerRadii.value); + pairCloseRejectionV0.init(&resultRegistry, &qaRegistry, confCPRdeltaPhiCutMin.value, confCPRdeltaPhiCutMax.value, confCPRdeltaEtaCutMin.value, confCPRdeltaEtaCutMax.value, confCPRChosenRadii.value, confCPRPlotPerRadii.value); + } + + if (!confLocalEfficiency.value.empty()) { + plocalEffFile = std::unique_ptr(TFile::Open(confLocalEfficiency.value.c_str(), "read")); + if (!plocalEffFile || plocalEffFile.get()->IsZombie()) + LOGF(fatal, "Could not load efficiency histogram from %s", confLocalEfficiency.value.c_str()); + if (doprocessSameEvent || doprocessMixedEvent) { + plocalEffp1 = (confChargePart1 > 0) ? std::unique_ptr(plocalEffFile.get()->Get("PrPlus")) : std::unique_ptr(plocalEffFile.get()->Get("PrMinus")); // note: works only for protons for now + plocalEffp2 = (confV0Type1 == 0) ? std::unique_ptr(plocalEffFile.get()->Get("Lambda")) : std::unique_ptr(plocalEffFile.get()->Get("AntiLambda")); + LOGF(info, "Loaded efficiency histograms for track-V0."); + } else if (doprocessSameEventV0 || doprocessMixedEventV0) { + plocalEffp1 = (confV0Type1 == 0) ? std::unique_ptr(plocalEffFile.get()->Get("Lambda")) : std::unique_ptr(plocalEffFile.get()->Get("AntiLambda")); + plocalEffp2 = (confV0Type2 == 0) ? std::unique_ptr(plocalEffFile.get()->Get("Lambda")) : std::unique_ptr(plocalEffFile.get()->Get("AntiLambda")); + LOGF(info, "Loaded efficiency histograms for V0-V0."); + } + } + } + /// This function processes the same event for track - V0 + template + void doSameEvent(FilteredFDCollision const& col, PartType const& parts, PartitionType& groupPartsOne, PartitionType& groupPartsTwo, [[maybe_unused]] MCParticles mcParts = nullptr) + { + const auto& magFieldTesla = col.magField(); + + const int multCol = confUseCent ? col.multV0M() : col.multNtr(); + + eventHisto.fillQA(col); + + /// Histogramming same event + for (const auto& part : groupPartsTwo) { + if (!invMLambda(part.mLambda(), part.mAntiLambda())) + continue; + const auto& posChild = parts.iteratorAt(part.index() - 2); + const auto& negChild = parts.iteratorAt(part.index() - 1); + /// Daughters that do not pass this condition are not selected + if (!isParticleTPC(posChild, V0ChildTable[confV0Type1][0]) || !isParticleTPC(negChild, V0ChildTable[confV0Type1][1])) + continue; + + auto posChildMass = pdg->Mass(confPDGCodePosChild); + auto negChildMass = pdg->Mass(confPDGCodeNegChild); + auto posChildBoosted = FemtoUniverseMath::boostPRF(posChild, posChildMass, negChild, negChildMass); + auto cosineTheta = (posChildBoosted.Px() * part.px() + posChildBoosted.Py() * part.py() + posChildBoosted.Pz() * part.pz()) / (posChildBoosted.P() * part.p()); + + trackHistoPartTwo.fillQA(part); + posChildHistos.fillQA(posChild); + negChildHistos.fillQA(negChild); + + thetaRegistry.fill(HIST("Theta/hTheta"), part.p(), cosineTheta); + thetaRegistry.fill(HIST("Theta/hTheta3D_PosChild"), part.p(), cosineTheta, posChild.p()); + thetaRegistry.fill(HIST("Theta/hTheta3D_NegChild"), part.p(), cosineTheta, negChild.p()); + thetaRegistry.fill(HIST("Theta/PositiveChild/hThetaPt"), posChild.pt(), cosineTheta); + thetaRegistry.fill(HIST("Theta/PositiveChild/hThetaEta"), posChild.eta(), cosineTheta); + thetaRegistry.fill(HIST("Theta/PositiveChild/hThetaPhi"), posChild.phi(), cosineTheta); + thetaRegistry.fill(HIST("Theta/NegativeChild/hThetaPt"), negChild.pt(), cosineTheta); + thetaRegistry.fill(HIST("Theta/NegativeChild/hThetaEta"), negChild.eta(), cosineTheta); + thetaRegistry.fill(HIST("Theta/NegativeChild/hThetaPhi"), negChild.phi(), cosineTheta); + } + + for (const auto& part : groupPartsOne) { + /// PID plot for particle 1 + const float tpcNSigmas[3] = {unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tpcNSigmaStorePi()), unPackInTable(part.tpcNSigmaStoreKa())}; + const float tofNSigmas[3] = {unPackInTable(part.tofNSigmaStorePr()), unPackInTable(part.tofNSigmaStorePi()), unPackInTable(part.tofNSigmaStoreKa())}; + + if (!isNSigmaCombined(part.p(), tpcNSigmas[confTrackChoicePartOne], tofNSigmas[confTrackChoicePartOne])) + continue; + if (part.sign() > 0) { + qaRegistry.fill(HIST("Tracks_pos/nSigmaTPC"), part.p(), tpcNSigmas[confTrackChoicePartOne]); + qaRegistry.fill(HIST("Tracks_pos/nSigmaTOF"), part.p(), tofNSigmas[confTrackChoicePartOne]); + trackHistoPartOnePos.fillQA(part); + } else if (part.sign() < 0) { + qaRegistry.fill(HIST("Tracks_neg/nSigmaTPC"), part.p(), tpcNSigmas[confTrackChoicePartOne]); + qaRegistry.fill(HIST("Tracks_neg/nSigmaTOF"), part.p(), tofNSigmas[confTrackChoicePartOne]); + trackHistoPartOneNeg.fillQA(part); + } + } + + /// Now build the combinations + for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { + // Lambda invariant mass cut + if (!invMLambda(p2.mLambda(), p2.mAntiLambda())) + continue; + /// PID using stored binned nsigma + if (!isParticleCombined(p1, confTrackChoicePartOne)) + continue; + // track cleaning + if (!pairCleaner.isCleanPair(p1, p2, parts)) { + continue; + } + if (confIsCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla, femto_universe_container::EventType::same)) { + continue; + } + } + const auto& posChild = parts.iteratorAt(p2.index() - 2); + const auto& negChild = parts.iteratorAt(p2.index() - 1); + + /// Daughters that do not pass this condition are not selected + if (!isParticleTPC(posChild, V0ChildTable[confV0Type1][0]) || !isParticleTPC(negChild, V0ChildTable[confV0Type1][1])) + continue; + + float weight = 1.0f; + if (plocalEffp1) + weight = plocalEffp1.get()->GetBinContent(plocalEffp1->FindBin(p1.pt(), p1.eta())) * plocalEffp2.get()->GetBinContent(plocalEffp2->FindBin(p2.pt(), p2.eta())); + if constexpr (std::is_same::value) + sameEventCont.setPair(p1, p2, multCol, confUse3D, weight); + else + sameEventCont.setPair(p1, p2, multCol, confUse3D, weight); + } + } + + void processSameEvent(FilteredFDCollision const& col, FemtoFullParticles const& parts) + { + auto groupPartsOne = partsOne->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto groupPartsTwo = partsTwo->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + doSameEvent(col, parts, groupPartsOne, groupPartsTwo); + } + PROCESS_SWITCH(FemtoUniversePairTaskTrackV0Helicity, processSameEvent, "Enable processing same event for track - V0", false); + + void processSameEventMCReco(FilteredFDCollision const& col, FemtoRecoParticles const& parts, aod::FdMCParticles const& mcparts) + { + auto groupPartsOne = partsOneMCReco->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto groupPartsTwo = partsTwoMCReco->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + doSameEvent(col, parts, groupPartsOne, groupPartsTwo, mcparts); + } + PROCESS_SWITCH(FemtoUniversePairTaskTrackV0Helicity, processSameEventMCReco, "Enable processing same event for track - V0 MC Reco", false); + + /// This function processes the same event for V0 - V0 + void processSameEventV0(FilteredFDCollision const& col, FemtoFullParticles const& parts) + { + const auto& magFieldTesla = col.magField(); + + auto groupPartsTwo = partsTwo->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + const int multCol = confUseCent ? col.multV0M() : col.multNtr(); + + eventHisto.fillQA(col); + + /// Histogramming same event + for (const auto& part : groupPartsTwo) { + if (!invMLambda(part.mLambda(), part.mAntiLambda())) + continue; + const auto& posChild = parts.iteratorAt(part.index() - 2); + const auto& negChild = parts.iteratorAt(part.index() - 1); + + /// Check daughters of first V0 particle + if (isParticleTPC(posChild, V0ChildTable[confV0Type1][0]) && isParticleTPC(negChild, V0ChildTable[confV0Type1][1])) { + trackHistoV0Type1.fillQABase(part, HIST("V0Type1")); + posChildV0Type1.fillQABase(posChild, HIST("posChildV0Type1")); + negChildV0Type1.fillQABase(negChild, HIST("negChildV0Type1")); + } + /// Check daughters of second V0 particle + if (isParticleTPC(posChild, V0ChildTable[confV0Type2][0]) && isParticleTPC(negChild, V0ChildTable[confV0Type2][1])) { + trackHistoV0Type2.fillQABase(part, HIST("V0Type2")); + posChildV0Type2.fillQABase(posChild, HIST("posChildV0Type2")); + negChildV0Type2.fillQABase(negChild, HIST("negChildV0Type2")); + } + } + + auto pairProcessFunc = [&](auto& p1, auto& p2) -> void { + // Lambda invariant mass cut for p1 + if (!invMLambda(p1.mLambda(), p1.mAntiLambda())) + return; + // Lambda invariant mass cut for p2 + if (!invMLambda(p2.mLambda(), p2.mAntiLambda())) + return; + // track cleaning + if (!pairCleanerV0.isCleanPair(p1, p2, parts)) { + return; + } + if (confIsCPR.value) { + if (pairCloseRejectionV0.isClosePair(p1, p2, parts, magFieldTesla, femto_universe_container::EventType::same)) { + return; + } + } + const auto& posChild1 = parts.iteratorAt(p1.index() - 2); + const auto& negChild1 = parts.iteratorAt(p1.index() - 1); + /// Daughters that do not pass this condition are not selected + if (!isParticleTPC(posChild1, V0ChildTable[confV0Type1][0]) || !isParticleTPC(negChild1, V0ChildTable[confV0Type1][1])) + return; + + const auto& posChild2 = parts.iteratorAt(p2.index() - 2); + const auto& negChild2 = parts.iteratorAt(p2.index() - 1); + /// Daughters that do not pass this condition are not selected + if (!isParticleTPC(posChild2, V0ChildTable[confV0Type2][0]) || !isParticleTPC(negChild2, V0ChildTable[confV0Type2][1])) + return; + + sameEventCont.setPair(p1, p2, multCol, confUse3D); + }; + if (confV0Type1 == confV0Type2) { + /// Now build the combinations for identical V0s + for (const auto& [p1, p2] : combinations(CombinationsStrictlyUpperIndexPolicy(groupPartsTwo, groupPartsTwo))) { + pairProcessFunc(p1, p2); + } + } else { + /// Now build the combinations for not identical identical V0s + for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsTwo, groupPartsTwo))) { + pairProcessFunc(p1, p2); + } + } + } + + PROCESS_SWITCH(FemtoUniversePairTaskTrackV0Helicity, processSameEventV0, "Enable processing same event for V0 - V0", false); + + /// This function processes MC same events for Track - V0 + void processMCSameEvent(FilteredFDCollision const& col, FemtoFullParticles const& parts) + { + const auto& magFieldTesla = col.magField(); + + auto groupPartsOne = partsOneMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto groupPartsTwo = partsTwoMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + const int multCol = confUseCent ? col.multV0M() : col.multNtr(); + + eventHisto.fillQA(col); + + /// Histogramming same event + for (const auto& part : groupPartsTwo) { + int pdgCode = static_cast(part.pidCut()); + if ((confV0Type1 == 0 && pdgCode != confPDGCodeV0) || (confV0Type1 == 1 && pdgCode != -confPDGCodeV0)) + continue; + trackHistoPartTwo.fillQA(part); + } + + for (const auto& part : groupPartsOne) { + int pdgCode = static_cast(part.pidCut()); + if (pdgCode != confTrkPDGCodePartOne) + continue; + const auto& pdgParticle = pdgMC->GetParticle(pdgCode); + if (!pdgParticle) { + continue; + } + /// PID plot for particle 1 + if (pdgParticle->Charge() > 0.0) { + trackHistoPartOnePos.fillQA(part); + } else if (pdgParticle->Charge() < 0.0) { + trackHistoPartOneNeg.fillQA(part); + } + } + + /// Now build the combinations + for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { + if (static_cast(p1.pidCut()) != confTrkPDGCodePartOne) + continue; + int pdgCode2 = static_cast(p2.pidCut()); + if ((confV0Type1 == 0 && pdgCode2 != confPDGCodeV0) || (confV0Type1 == 1 && pdgCode2 != -confPDGCodeV0)) + continue; + // track cleaning + if (confIsCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla, femto_universe_container::EventType::same)) { + continue; + } + } + sameEventCont.setPair(p1, p2, multCol, confUse3D); + } + } + + PROCESS_SWITCH(FemtoUniversePairTaskTrackV0Helicity, processMCSameEvent, "Enable processing same event for MC truth track - V0", false); + + /// This function processes MC same events for V0 - V0 + void processMCSameEventV0(FilteredFDCollision const& col, FemtoFullParticles const& /*parts*/) + { + auto groupPartsTwo = partsTwoMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + const int multCol = confUseCent ? col.multV0M() : col.multNtr(); + + eventHisto.fillQA(col); + + /// Histogramming same event + for (const auto& part : groupPartsTwo) { + int pdgCode = static_cast(part.pidCut()); + if ((confV0Type1 == 0 && pdgCode != confPDGCodeV0) || (confV0Type1 == 1 && pdgCode != -confPDGCodeV0)) + continue; + trackHistoPartTwo.fillQA(part); + } + + auto pairProcessFunc = [&](auto& p1, auto& p2) -> void { + int pdgCode1 = static_cast(p1.pidCut()); + if ((confV0Type1 == 0 && pdgCode1 != confPDGCodeV0) || (confV0Type1 == 1 && pdgCode1 != -confPDGCodeV0)) + return; + int pdgCode2 = static_cast(p2.pidCut()); + if ((confV0Type2 == 0 && pdgCode2 != confPDGCodeV0) || (confV0Type2 == 1 && pdgCode2 != -confPDGCodeV0)) + return; + sameEventCont.setPair(p1, p2, multCol, confUse3D); + }; + /// Now build the combinations + if (confV0Type1 == confV0Type2) { + /// Now build the combinations for identical V0s + for (const auto& [p1, p2] : combinations(CombinationsStrictlyUpperIndexPolicy(groupPartsTwo, groupPartsTwo))) { + pairProcessFunc(p1, p2); + } + } else { + /// Now build the combinations for not identical identical V0s + for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsTwo, groupPartsTwo))) { + pairProcessFunc(p1, p2); + } + } + } + + PROCESS_SWITCH(FemtoUniversePairTaskTrackV0Helicity, processMCSameEventV0, "Enable processing same event for MC truth V0 - V0", false); + + /// This function processes the mixed event for track - V0 + template + void doMixedEvent(FilteredFDCollisions const& cols, PartType const& parts, PartitionType& partitionOne, PartitionType& partitionTwo, [[maybe_unused]] MCParticles mcParts = nullptr) + { + ColumnBinningPolicy colBinningMult{{confVtxBins, confMultBins}, true}; + ColumnBinningPolicy colBinningCent{{confVtxBins, confMultBins}, true}; + + auto mixedCollProcessFunc = [&](auto& collision1, auto& collision2) -> void { + const int multCol = confUseCent ? collision1.multV0M() : collision1.multNtr(); + + auto groupPartsOne = partitionOne->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsTwo = partitionTwo->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); + + const auto& magFieldTesla1 = collision1.magField(); + const auto& magFieldTesla2 = collision2.magField(); + + if (magFieldTesla1 != magFieldTesla2) { + return; + } + + for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { + // Lambda invariant mass cut + if (!invMLambda(p2.mLambda(), p2.mAntiLambda())) + continue; + /// PID using stored binned nsigma + if (!isParticleCombined(p1, confTrackChoicePartOne)) + continue; + + const auto& posChild = parts.iteratorAt(p2.globalIndex() - 2); + const auto& negChild = parts.iteratorAt(p2.globalIndex() - 1); + /// Daughters that do not pass this condition are not selected + if (!isParticleTPC(posChild, V0ChildTable[confV0Type1][0]) || !isParticleTPC(negChild, V0ChildTable[confV0Type1][1])) + continue; + + // track cleaning + if (!pairCleaner.isCleanPair(p1, p2, parts)) { + continue; + } + if (confIsCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla1, femto_universe_container::EventType::mixed)) { + continue; + } + } + float weight = 1.0f; + if (plocalEffp1) + weight = plocalEffp1.get()->GetBinContent(plocalEffp1->FindBin(p1.pt(), p1.eta())) * plocalEffp2.get()->GetBinContent(plocalEffp2->FindBin(p2.pt(), p2.eta())); + + if constexpr (std::is_same::value) + mixedEventCont.setPair(p1, p2, multCol, confUse3D, weight); + else + mixedEventCont.setPair(p1, p2, multCol, confUse3D, weight); + } + }; + + if (confUseCent) { + for (const auto& [collision1, collision2] : soa::selfCombinations(colBinningCent, confNEventsMix, -1, cols, cols)) { + mixedCollProcessFunc(collision1, collision2); + mixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinningCent.getBin({collision1.posZ(), collision1.multV0M()})); + } + } else { + for (const auto& [collision1, collision2] : soa::selfCombinations(colBinningMult, confNEventsMix, -1, cols, cols)) { + mixedCollProcessFunc(collision1, collision2); + mixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinningMult.getBin({collision1.posZ(), collision1.multNtr()})); + } + } + } + + void processMixedEvent(FilteredFDCollisions const& cols, FemtoFullParticles const& parts) + { + doMixedEvent(cols, parts, partsOne, partsTwo); + } + PROCESS_SWITCH(FemtoUniversePairTaskTrackV0Helicity, processMixedEvent, "Enable processing mixed event for track - V0", false); + + void processMixedEventMCReco(FilteredFDCollisions const& cols, FemtoRecoParticles const& parts, aod::FdMCParticles const& mcparts) + { + doMixedEvent(cols, parts, partsOneMCReco, partsTwoMCReco, mcparts); + } + PROCESS_SWITCH(FemtoUniversePairTaskTrackV0Helicity, processMixedEventMCReco, "Enable processing mixed event for track - V0 for MC Reco", false); + + /// This function processes the mixed event for V0 - V0 + void processMixedEventV0(FilteredFDCollisions const& cols, FemtoFullParticles const& parts) + { + ColumnBinningPolicy colBinningMult{{confVtxBins, confMultBins}, true}; + ColumnBinningPolicy colBinningCent{{confVtxBins, confMultBins}, true}; + + auto mixedCollProcessFunc = [&](auto& collision1, auto& collision2) -> void { + const int multCol = confUseCent ? collision1.multV0M() : collision1.multNtr(); + + auto groupPartsOne = partsTwo->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsTwo = partsTwo->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); + + const auto& magFieldTesla1 = collision1.magField(); + const auto& magFieldTesla2 = collision2.magField(); + + if (magFieldTesla1 != magFieldTesla2) { + return; + } + + for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { + // Lambda invariant mass cut for p1 + if (!invMLambda(p1.mLambda(), p1.mAntiLambda())) { + continue; + } + // Lambda invariant mass cut for p2 + if (!invMLambda(p2.mLambda(), p2.mAntiLambda())) { + continue; + } + + const auto& posChild1 = parts.iteratorAt(p1.globalIndex() - 2); + const auto& negChild1 = parts.iteratorAt(p1.globalIndex() - 1); + /// Daughters that do not pass this condition are not selected + if (!isParticleTPC(posChild1, V0ChildTable[confV0Type1][0]) || !isParticleTPC(negChild1, V0ChildTable[confV0Type1][1])) + continue; + + const auto& posChild2 = parts.iteratorAt(p2.globalIndex() - 2); + const auto& negChild2 = parts.iteratorAt(p2.globalIndex() - 1); + /// Daughters that do not pass this condition are not selected + if (!isParticleTPC(posChild2, V0ChildTable[confV0Type2][0]) || !isParticleTPC(negChild2, V0ChildTable[confV0Type2][1])) + continue; + + // track cleaning + if (!pairCleanerV0.isCleanPair(p1, p2, parts)) { + continue; + } + if (confIsCPR.value) { + if (pairCloseRejectionV0.isClosePair(p1, p2, parts, magFieldTesla1, femto_universe_container::EventType::mixed)) { + continue; + } + } + mixedEventCont.setPair(p1, p2, multCol, confUse3D); + } + }; + + if (confUseCent) { + for (const auto& [collision1, collision2] : soa::selfCombinations(colBinningCent, confNEventsMix, -1, cols, cols)) { + mixedCollProcessFunc(collision1, collision2); + mixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinningCent.getBin({collision1.posZ(), collision1.multV0M()})); + } + } else { + for (const auto& [collision1, collision2] : soa::selfCombinations(colBinningMult, confNEventsMix, -1, cols, cols)) { + mixedCollProcessFunc(collision1, collision2); + mixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinningMult.getBin({collision1.posZ(), collision1.multNtr()})); + } + } + } + PROCESS_SWITCH(FemtoUniversePairTaskTrackV0Helicity, processMixedEventV0, "Enable processing mixed events for V0 - V0", false); + + /// This function processes MC mixed events for Track - V0 + void processMCMixedEvent(FilteredFDCollisions const& cols, FemtoFullParticles const& parts) + { + ColumnBinningPolicy colBinningMult{{confVtxBins, confMultBins}, true}; + ColumnBinningPolicy colBinningCent{{confVtxBins, confMultBins}, true}; + + auto mixedCollProcessFunc = [&](auto& collision1, auto& collision2) -> void { + const int multCol = confUseCent ? collision1.multV0M() : collision1.multNtr(); + + auto groupPartsOne = partsOneMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsTwo = partsTwoMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); + + const auto& magFieldTesla1 = collision1.magField(); + const auto& magFieldTesla2 = collision2.magField(); + + if (magFieldTesla1 != magFieldTesla2) { + return; + } + for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { + if (static_cast(p1.pidCut()) != confTrkPDGCodePartOne) + continue; + int pdgCode2 = static_cast(p2.pidCut()); + if ((confV0Type1 == 0 && pdgCode2 != confPDGCodeV0) || (confV0Type1 == 1 && pdgCode2 != -confPDGCodeV0)) + continue; + if (confIsCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla1, femto_universe_container::EventType::mixed)) { + continue; + } + } + mixedEventCont.setPair(p1, p2, multCol, confUse3D); + } + }; + + if (confUseCent) { + for (const auto& [collision1, collision2] : soa::selfCombinations(colBinningCent, confNEventsMix, -1, cols, cols)) { + mixedCollProcessFunc(collision1, collision2); + mixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinningCent.getBin({collision1.posZ(), collision1.multV0M()})); + } + } else { + for (const auto& [collision1, collision2] : soa::selfCombinations(colBinningMult, confNEventsMix, -1, cols, cols)) { + mixedCollProcessFunc(collision1, collision2); + mixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinningMult.getBin({collision1.posZ(), collision1.multNtr()})); + } + } + } + + PROCESS_SWITCH(FemtoUniversePairTaskTrackV0Helicity, processMCMixedEvent, "Enable processing mixed events for MC truth track - V0", false); + + /// This function processes MC mixed events for V0 - V0 + void processMCMixedEventV0(FilteredFDCollisions const& cols, FemtoFullParticles const& /*parts*/) + { + ColumnBinningPolicy colBinningMult{{confVtxBins, confMultBins}, true}; + ColumnBinningPolicy colBinningCent{{confVtxBins, confMultBins}, true}; + + auto mixedCollProcessFunc = [&](auto& collision1, auto& collision2) -> void { + const int multCol = confUseCent ? collision1.multV0M() : collision1.multNtr(); + + auto groupPartsOne = partsTwoMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsTwo = partsTwoMC->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); + + for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { + int pdgCode1 = static_cast(p1.pidCut()); + if ((confV0Type1 == 0 && pdgCode1 != confPDGCodeV0) || (confV0Type1 == 1 && pdgCode1 != -confPDGCodeV0)) + continue; + int pdgCode2 = static_cast(p2.pidCut()); + if ((confV0Type2 == 0 && pdgCode2 != confPDGCodeV0) || (confV0Type2 == 1 && pdgCode2 != -confPDGCodeV0)) + continue; + mixedEventCont.setPair(p1, p2, multCol, confUse3D); + } + }; + + if (confUseCent) { + for (const auto& [collision1, collision2] : soa::selfCombinations(colBinningCent, confNEventsMix, -1, cols, cols)) { + mixedCollProcessFunc(collision1, collision2); + mixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinningCent.getBin({collision1.posZ(), collision1.multV0M()})); + } + } else { + for (const auto& [collision1, collision2] : soa::selfCombinations(colBinningMult, confNEventsMix, -1, cols, cols)) { + mixedCollProcessFunc(collision1, collision2); + mixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinningMult.getBin({collision1.posZ(), collision1.multNtr()})); + } + } + } + + PROCESS_SWITCH(FemtoUniversePairTaskTrackV0Helicity, processMCMixedEventV0, "Enable processing mixed events for MC truth V0 - V0", false); + ///--------------------------------------------MC-------------------------------------------------/// + + /// This function fills MC truth particles from derived MC table + void processMCTruth(aod::FDParticles const& parts) + { + for (const auto& part : parts) { + if (part.partType() != uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) + continue; + + int pdgCode = static_cast(part.pidCut()); + const auto& pdgParticle = pdgMC->GetParticle(pdgCode); + if (!pdgParticle) { + continue; + } + + if (pdgCode == 3122) { + registryMCtruth.fill(HIST("plus/MCtruthLambda"), part.pt(), part.eta()); + continue; + } else if (pdgCode == -3122) { + registryMCtruth.fill(HIST("minus/MCtruthLambda"), part.pt(), part.eta()); + continue; + } + + if (pdgParticle->Charge() > 0.0) { + registryMCtruth.fill(HIST("plus/MCtruthAllPt"), part.pt()); + } + if (pdgCode == 211) { + registryMCtruth.fill(HIST("plus/MCtruthPi"), part.pt(), part.eta()); + registryMCtruth.fill(HIST("plus/MCtruthPiPt"), part.pt()); + } + if (pdgCode == 2212) { + registryMCtruth.fill(HIST("plus/MCtruthPr"), part.pt(), part.eta()); + registryMCtruth.fill(HIST("plus/MCtruthPrPt"), part.pt()); + } + + if (pdgParticle->Charge() < 0.0) { + registryMCtruth.fill(HIST("minus/MCtruthAllPt"), part.pt()); + } + if (pdgCode == -211) { + registryMCtruth.fill(HIST("minus/MCtruthPi"), part.pt(), part.eta()); + registryMCtruth.fill(HIST("minus/MCtruthPiPt"), part.pt()); + } + if (pdgCode == -2212) { + registryMCtruth.fill(HIST("minus/MCtruthPr"), part.pt(), part.eta()); + registryMCtruth.fill(HIST("minus/MCtruthPrPt"), part.pt()); + } + + // Helicity angle + const auto& posChild = parts.iteratorAt(part.index() - 2); + const auto& negChild = parts.iteratorAt(part.index() - 1); + + registryMCtruth.fill(HIST("PosChildMCTruth/hPt"), posChild.pt()); + registryMCtruth.fill(HIST("NegChildMCTruth/hPt"), negChild.pt()); + + auto posChildMass = pdg->Mass(confPDGCodePosChild); + auto negChildMass = pdg->Mass(confPDGCodeNegChild); + auto posChildBoosted = FemtoUniverseMath::boostPRF(posChild, posChildMass, negChild, negChildMass); + auto cosineTheta = (posChildBoosted.Px() * part.px() + posChildBoosted.Py() * part.py() + posChildBoosted.Pz() * part.pz()) / (posChildBoosted.P() * part.p()); + + registryMCtruth.fill(HIST("ThetaMCTruth/hTheta"), part.p(), cosineTheta); + registryMCtruth.fill(HIST("ThetaMCTruth/hTheta3D_PosChild"), part.p(), cosineTheta, posChild.p()); + registryMCtruth.fill(HIST("ThetaMCTruth/hTheta3D_NegChild"), part.p(), cosineTheta, negChild.p()); + registryMCtruth.fill(HIST("ThetaMCTruth/PositiveChild/hThetaPt"), posChild.pt(), cosineTheta); + registryMCtruth.fill(HIST("ThetaMCTruth/PositiveChild/hThetaEta"), posChild.eta(), cosineTheta); + registryMCtruth.fill(HIST("ThetaMCTruth/PositiveChild/hThetaPhi"), posChild.phi(), cosineTheta); + registryMCtruth.fill(HIST("ThetaMCTruth/NegativeChild/hThetaPt"), negChild.pt(), cosineTheta); + registryMCtruth.fill(HIST("ThetaMCTruth/NegativeChild/hThetaEta"), negChild.eta(), cosineTheta); + registryMCtruth.fill(HIST("ThetaMCTruth/NegativeChild/hThetaPhi"), negChild.phi(), cosineTheta); + } + } + + PROCESS_SWITCH(FemtoUniversePairTaskTrackV0Helicity, processMCTruth, "Process MC truth data", false); + + void processMCReco(FemtoRecoParticles const& parts, aod::FdMCParticles const& mcparts) + { + for (const auto& part : parts) { + auto mcPartId = part.fdMCParticleId(); + if (mcPartId == -1) + continue; // no MC particle + const auto& mcpart = mcparts.iteratorAt(mcPartId); + // + if (part.partType() == aod::femtouniverseparticle::ParticleType::kV0) { + if (mcpart.pdgMCTruth() == 3122) { + const auto& posChild = parts.iteratorAt(part.globalIndex() - 2); + const auto& negChild = parts.iteratorAt(part.globalIndex() - 1); + /// Daughters that do not pass this condition are not selected + if (isParticleTPC(posChild, 0) && isParticleTPC(negChild, 1)) { + registryMCreco.fill(HIST("plus/MCrecoLambda"), mcpart.pt(), mcpart.eta()); // lambda + if (auto mcpartIdChild = posChild.fdMCParticleId(); mcpartIdChild != -1) { + const auto& mcpartChild = mcparts.iteratorAt(mcpartIdChild); + registryMCreco.fill(HIST("plus/MCrecoLambdaChildPr"), mcpartChild.pt(), mcpartChild.eta()); // lambda proton child + } + if (auto mcpartIdChild = negChild.fdMCParticleId(); mcpartIdChild != -1) { + const auto& mcpartChild = mcparts.iteratorAt(mcpartIdChild); + registryMCreco.fill(HIST("plus/MCrecoLambdaChildPi"), mcpartChild.pt(), mcpartChild.eta()); // lambda pion child + } + } + } else if (mcpart.pdgMCTruth() == -3122) { + const auto& posChild = parts.iteratorAt(part.globalIndex() - 2); + const auto& negChild = parts.iteratorAt(part.globalIndex() - 1); + /// Daughters that do not pass this condition are not selected + if (isParticleTPC(posChild, 1) && isParticleTPC(negChild, 0)) { + registryMCreco.fill(HIST("minus/MCrecoLambda"), mcpart.pt(), mcpart.eta()); // anti-lambda + if (auto mcpartIdChild = posChild.fdMCParticleId(); mcpartIdChild != -1) { + const auto& mcpartChild = mcparts.iteratorAt(mcpartIdChild); + registryMCreco.fill(HIST("minus/MCrecoLambdaChildPi"), mcpartChild.pt(), mcpartChild.eta()); // anti-lambda pion child + } + if (auto mcpartIdChild = negChild.fdMCParticleId(); mcpartIdChild != -1) { + const auto& mcpartChild = mcparts.iteratorAt(mcpartIdChild); + registryMCreco.fill(HIST("minus/MCrecoLambdaChildPr"), mcpartChild.pt(), mcpartChild.eta()); // anti-lambda proton child + } + } + } + } else if (part.partType() == aod::femtouniverseparticle::ParticleType::kTrack) { + if (part.sign() > 0) { + registryMCreco.fill(HIST("plus/MCrecoAllPt"), mcpart.pt()); + if (mcpart.pdgMCTruth() == 211 && isNSigmaCombined(part.p(), unPackInTable(part.tpcNSigmaStorePi()), unPackInTable(part.tofNSigmaStorePi()))) { + registryMCreco.fill(HIST("plus/MCrecoPi"), mcpart.pt(), mcpart.eta()); + registryMCreco.fill(HIST("plus/MCrecoPiPt"), mcpart.pt()); + } else if (mcpart.pdgMCTruth() == 2212 && isNSigmaCombined(part.p(), unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tofNSigmaStorePr()))) { + registryMCreco.fill(HIST("plus/MCrecoPr"), mcpart.pt(), mcpart.eta()); + registryMCreco.fill(HIST("plus/MCrecoPrPt"), mcpart.pt()); + } + } + + if (part.sign() < 0) { + registryMCreco.fill(HIST("minus/MCrecoAllPt"), mcpart.pt()); + if (mcpart.pdgMCTruth() == -211 && isNSigmaCombined(part.p(), unPackInTable(part.tpcNSigmaStorePi()), unPackInTable(part.tofNSigmaStorePi()))) { + registryMCreco.fill(HIST("minus/MCrecoPi"), mcpart.pt(), mcpart.eta()); + registryMCreco.fill(HIST("minus/MCrecoPiPt"), mcpart.pt()); + } else if (mcpart.pdgMCTruth() == -2212 && isNSigmaCombined(part.p(), unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tofNSigmaStorePr()))) { + registryMCreco.fill(HIST("minus/MCrecoPr"), mcpart.pt(), mcpart.eta()); + registryMCreco.fill(HIST("minus/MCrecoPrPt"), mcpart.pt()); + } + } + } // partType + } + } + + PROCESS_SWITCH(FemtoUniversePairTaskTrackV0Helicity, processMCReco, "Process MC reco data", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{ + adaptAnalysisTask(cfgc), + }; + return workflow; +} diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskV0CascadeExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskV0CascadeExtended.cxx index a9212ab208a..1df76704efd 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskV0CascadeExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskV0CascadeExtended.cxx @@ -43,7 +43,6 @@ struct FemtoUniversePairTaskV0CascadeExtended { SliceCache cache; using FemtoParticles = soa::Join; - Preslice perCol = aod::femtouniverseparticle::fdCollisionId; /// applying narrow cut Configurable confZVertexCut{"confZVertexCut", 10.f, "Event sel: Maximum z-Vertex (cm)"}; @@ -66,12 +65,23 @@ struct FemtoUniversePairTaskV0CascadeExtended { Configurable confCascType{"confCascType", 0, "select one of the cascades (Omega = 0, Xi = 1, anti-Omega = 2, anti-Xi = 3)"}; Configurable confCascInvMassLowLimit{"confCascInvMassLowLimit", 1.315, "Lower limit of the cascade invariant mass"}; Configurable confCascInvMassUpLimit{"confCascInvMassUpLimit", 1.325, "Upper limit of the cascade invariant mass"}; + Configurable confCascPDGCode{"confCascPDGCode", 3312, "Particle 2 (Cascade) - PDG code"}; /// nSigma cuts Configurable confmom{"confmom", 0.75, "momentum threshold for particle identification using TOF"}; Configurable confNsigmaTPCParticleChild{"confNsigmaTPCParticleChild", 3.0, "TPC Sigma for cascade (daugh & bach) momentum < Confmom"}; Configurable confNsigmaTOFParticleChild{"confNsigmaTOFParticleChild", 3.0, "TOF Sigma for cascade (daugh & bach) momentum > Confmom"}; + /// CPR + Configurable confIsCPR{"confIsCPR", false, "Close Pair Rejection"}; + Configurable confCPRdeltaPhiCutMax{"confCPRdeltaPhiCutMax", 0.0, "Delta Phi max cut for CPR"}; + Configurable confCPRdeltaPhiCutMin{"confCPRdeltaPhiCutMin", 0.0, "Delta Phi min cut for CPR"}; + Configurable confCPRdeltaEtaCutMax{"confCPRdeltaEtaCutMax", 0.0, "Delta Eta max cut for CPR"}; + Configurable confCPRdeltaEtaCutMin{"confCPRdeltaEtaCutMin", 0.0, "Delta Eta min cut for CPR"}; + Configurable confCPRPlotPerRadii{"confCPRPlotPerRadii", false, "Plot CPR per radii"}; + Configurable confCPRChosenRadii{"confCPRChosenRadii", 0.0, "Delta Eta cut for Close Pair Rejection"}; + Configurable confIsSameSignCPR{"confIsSameSignCPR", false, "Close Pair Rejection for same sign children of cascades"}; + /// for correlation part Configurable confIsMC{"confIsMC", false, "Enable additional Histograms in the case of a MonteCarlo Run"}; ConfigurableAxis confkstarBins{"confkstarBins", {1500, 0., 6.}, "binning kstar"}; @@ -91,12 +101,18 @@ struct FemtoUniversePairTaskV0CascadeExtended { ConfigurableAxis confV0TempFitVarpTBins{"confV0TempFitVarpTBins", {20, 0.5, 4.05}, "V0: pT binning of the pT vs. TempFitVar plot"}; ConfigurableAxis confV0TempFitVarBins{"confV0TempFitVarBins", {300, 0.95, 1.}, "V0: binning of the TempFitVar in the pT vs. TempFitVar plot"}; - /// Partition for particle 1 + /// Partition for particle 1 (V0) Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kV0)) && (aod::femtouniverseparticle::pt < confHPtPart1) && (aod::femtouniverseparticle::pt > confLPtPart1); - /// Partition for particle 2 + /// Partition for particle 1 (V0) without extended table + Partition partsOnebitmask = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kV0)) && (aod::femtouniverseparticle::pt < confHPtPart1) && (aod::femtouniverseparticle::pt > confLPtPart1); + + /// Partition for particle 2 (Cascade) Partition partsTwo = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kCascade)) && (aod::femtouniverseparticle::pt < confHPtPart2) && (aod::femtouniverseparticle::pt > confLPtPart2); + /// Partition for particle 2 (Cascade) without extended table + Partition partsTwobitmask = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kCascade)) && (aod::femtouniverseparticle::pt < confHPtPart2) && (aod::femtouniverseparticle::pt > confLPtPart2); + /// Histogramming for v0 FemtoUniverseParticleHisto trackHistoV0; FemtoUniverseParticleHisto posChildV0; @@ -114,6 +130,7 @@ struct FemtoUniversePairTaskV0CascadeExtended { FemtoUniverseContainer sameEventCont; FemtoUniverseContainer mixedEventCont; FemtoUniversePairCleaner pairCleaner; + FemtoUniverseDetaDphiStar pairCloseRejection; HistogramRegistry qaRegistry{"TrackQA", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry resultRegistry{"Correlations", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -162,18 +179,20 @@ struct FemtoUniversePairTaskV0CascadeExtended { } template - bool isParticleTPC(const T& part, int id) + bool isParticleTPC(const T& part, int id, float* partSigma = 0) { const float tpcNSigmas[3] = {unPackInTable(part.tpcNSigmaStorePr()), unPackInTable(part.tpcNSigmaStorePi()), unPackInTable(part.tpcNSigmaStoreKa())}; - + if (partSigma) + *partSigma = tpcNSigmas[id]; return isNSigmaTPC(tpcNSigmas[id]); } template - bool isParticleTOF(const T& part, int id) + bool isParticleTOF(const T& part, int id, float* partSigma = 0) { const float tofNSigmas[3] = {unPackInTable(part.tofNSigmaStorePr()), unPackInTable(part.tofNSigmaStorePi()), unPackInTable(part.tofNSigmaStoreKa())}; - + if (partSigma) + *partSigma = tofNSigmas[id]; return isNSigmaTOF(part.p(), tofNSigmas[id], part.tempFitVar()); } @@ -190,12 +209,24 @@ struct FemtoUniversePairTaskV0CascadeExtended { sameEventCont.init(&resultRegistry, confkstarBins, confMultBins, confkTBins, confmTBins, confMultBins3D, confmTBins3D, confEtaBins, confPhiBins, confIsMC, confUse3D); mixedEventCont.init(&resultRegistry, confkstarBins, confMultBins, confkTBins, confmTBins, confMultBins3D, confmTBins3D, confEtaBins, confPhiBins, confIsMC, confUse3D); + sameEventCont.setPDGCodes(confV0PDGCode, confCascPDGCode); + mixedEventCont.setPDGCodes(confV0PDGCode, confCascPDGCode); + pairCleaner.init(&qaRegistry); + if (confIsCPR.value) { + pairCloseRejection.init(&resultRegistry, &qaRegistry, confCPRdeltaPhiCutMin.value, confCPRdeltaPhiCutMax.value, confCPRdeltaEtaCutMin.value, confCPRdeltaEtaCutMax.value, confCPRChosenRadii.value, confCPRPlotPerRadii.value, 0, 0, confIsSameSignCPR.value); + } } + template + using hasSigma = decltype(std::declval().tpcNSigmaStorePr()); + /// v0-cascade correlations same event - void processSameEvent(const FilteredFDCollision& col, const FemtoParticles& parts) + template + void doSameEvent(const FilteredFDCollision& col, const TableType& parts, PartitionType& partsOne, PartitionType& partsTwo) { + const auto& magFieldTesla = col.magField(); + auto groupPartsOne = partsOne->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); auto groupPartsTwo = partsTwo->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); @@ -206,70 +237,136 @@ struct FemtoUniversePairTaskV0CascadeExtended { if (!invMCascade(part.mLambda(), part.mAntiLambda(), confCascType)) continue; - cascQAHistos.fillQA(part); - - const auto& posChild1 = parts.iteratorAt(part.index() - 3); - const auto& negChild1 = parts.iteratorAt(part.index() - 2); - const auto& bachelor1 = parts.iteratorAt(part.index() - 1); + const auto& posChild = parts.iteratorAt(part.globalIndex() - 3 - parts.begin().globalIndex()); + const auto& negChild = parts.iteratorAt(part.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& bachelor = parts.iteratorAt(part.globalIndex() - 1 - parts.begin().globalIndex()); /// Children of cascade must pass this condition to be selected - if (!isParticleTPC(posChild1, CascChildTable[confCascType][0]) || !isParticleTPC(negChild1, CascChildTable[confCascType][1]) || !isParticleTPC(bachelor1, CascChildTable[confCascType][2])) - continue; + if constexpr (std::experimental::is_detected::value) { + if (!isParticleTPC(posChild, CascChildTable[confCascType][0]) || !isParticleTPC(negChild, CascChildTable[confCascType][1]) || !isParticleTPC(bachelor, CascChildTable[confCascType][2])) + continue; - if (!isParticleTOF(posChild1, CascChildTable[confCascType][0]) || !isParticleTOF(negChild1, CascChildTable[confCascType][1]) || !isParticleTOF(bachelor1, CascChildTable[confCascType][2])) - continue; + if (!isParticleTOF(posChild, CascChildTable[confCascType][0]) || !isParticleTOF(negChild, CascChildTable[confCascType][1]) || !isParticleTOF(bachelor, CascChildTable[confCascType][2])) + continue; + + posChildHistosCasc.fillQABase(posChild, HIST("posChildCasc")); + negChildHistosCasc.fillQABase(negChild, HIST("negChildCasc")); + bachHistosCasc.fillQABase(bachelor, HIST("hBachelor")); + cascQAHistos.fillQA(part); - posChildHistosCasc.fillQABase(posChild1, HIST("posChildCasc")); - negChildHistosCasc.fillQABase(negChild1, HIST("negChildCasc")); - bachHistosCasc.fillQABase(bachelor1, HIST("hBachelor")); + } else { + if ((posChild.pidCut() & (1u << CascChildTable[confCascType][0])) == 0 || (negChild.pidCut() & (1u << CascChildTable[confCascType][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[confCascType][2])) == 0) + continue; + + if ((posChild.pidCut() & (8u << CascChildTable[confCascType][0])) == 0 || (negChild.pidCut() & (8u << CascChildTable[confCascType][1])) == 0 || (bachelor.pidCut() & (8u << CascChildTable[confCascType][2])) == 0) + continue; + + posChildHistosCasc.fillQABase(posChild, HIST("posChildCasc")); + negChildHistosCasc.fillQABase(negChild, HIST("negChildCasc")); + bachHistosCasc.fillQABase(bachelor, HIST("hBachelor")); + cascQAHistos.fillQA(part); + } } + for (const auto& part : groupPartsOne) { /// inv Mass check for V0s if (!invMLambda(part.mLambda(), part.mAntiLambda())) continue; - const auto& posChild2 = parts.iteratorAt(part.index() - 2); - const auto& negChild2 = parts.iteratorAt(part.index() - 1); + + const auto& posChild = parts.iteratorAt(part.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& negChild = parts.iteratorAt(part.globalIndex() - 1 - parts.begin().globalIndex()); /// Daughters of v0 must pass this condition to be selected - if (!isParticleTPC(posChild2, V0ChildTable[confV0Type][0]) || !isParticleTPC(negChild2, V0ChildTable[confV0Type][1])) - continue; + if constexpr (std::experimental::is_detected::value) { + if (!isParticleTPC(posChild, V0ChildTable[confV0Type][0]) || !isParticleTPC(negChild, V0ChildTable[confV0Type][1])) + continue; + + if (!isParticleTOF(posChild, V0ChildTable[confV0Type][0]) || !isParticleTOF(negChild, V0ChildTable[confV0Type][1])) + continue; - trackHistoV0.fillQABase(part, HIST("trackHistoV0")); - posChildV0.fillQABase(posChild2, HIST("posChildV0")); - negChildV0.fillQABase(negChild2, HIST("negChildV0")); + trackHistoV0.fillQABase(part, HIST("trackHistoV0")); + posChildV0.fillQABase(posChild, HIST("posChildV0")); + negChildV0.fillQABase(negChild, HIST("negChildV0")); + + } else { + if ((posChild.pidCut() & (1u << V0ChildTable[confV0Type][0])) == 0 || (negChild.pidCut() & (1u << V0ChildTable[confV0Type][1])) == 0) + continue; + + if ((posChild.pidCut() & (8u << V0ChildTable[confV0Type][0])) == 0 || (negChild.pidCut() & (8u << V0ChildTable[confV0Type][1])) == 0) + continue; + + trackHistoV0.fillQABase(part, HIST("trackHistoV0")); + posChildV0.fillQABase(posChild, HIST("posChildV0")); + negChildV0.fillQABase(negChild, HIST("negChildV0")); + } } + for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo))) { if (!invMLambda(p1.mLambda(), p1.mAntiLambda())) continue; // Cascase inv Mass cut (mLambda stores Xi mass, mAntiLambda stored Omega mass) if (!invMCascade(p2.mLambda(), p2.mAntiLambda(), confCascType)) continue; - // track cleaning - if (!pairCleaner.isCleanPair(p1, p2, parts)) { - continue; - } + // V0 - const auto& posChild2 = parts.iteratorAt(p1.index() - 2); - const auto& negChild2 = parts.iteratorAt(p1.index() - 1); + const auto& posChild1 = parts.iteratorAt(p1.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& negChild1 = parts.iteratorAt(p1.globalIndex() - 1 - parts.begin().globalIndex()); /// Daughters of v0 must pass this condition to be selected - if (!isParticleTPC(posChild2, V0ChildTable[confV0Type][0]) || !isParticleTPC(negChild2, V0ChildTable[confV0Type][1])) - continue; + if constexpr (std::experimental::is_detected::value) { + if (!isParticleTPC(posChild1, V0ChildTable[confV0Type][0]) || !isParticleTPC(negChild1, V0ChildTable[confV0Type][1])) + continue; + if (!isParticleTOF(posChild1, V0ChildTable[confV0Type][0]) || !isParticleTOF(negChild1, V0ChildTable[confV0Type][1])) + continue; + } else { + if ((posChild1.pidCut() & (1u << V0ChildTable[confV0Type][0])) == 0 || (negChild1.pidCut() & (1u << V0ChildTable[confV0Type][1])) == 0) + continue; + if ((posChild1.pidCut() & (8u << V0ChildTable[confV0Type][0])) == 0 || (negChild1.pidCut() & (8u << V0ChildTable[confV0Type][1])) == 0) + continue; + } + // cascade - const auto& posChild1 = parts.iteratorAt(p2.index() - 3); - const auto& negChild1 = parts.iteratorAt(p2.index() - 2); - const auto& bachelor1 = parts.iteratorAt(p2.index() - 1); + const auto& posChild2 = parts.iteratorAt(p2.globalIndex() - 3 - parts.begin().globalIndex()); + const auto& negChild2 = parts.iteratorAt(p2.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& bachelor = parts.iteratorAt(p2.globalIndex() - 1 - parts.begin().globalIndex()); /// Daughters of cascade must pass this condition to be selected - if (!isParticleTPC(posChild1, CascChildTable[confCascType][0]) || !isParticleTPC(negChild1, CascChildTable[confCascType][1]) || !isParticleTPC(bachelor1, CascChildTable[confCascType][2])) - continue; + if constexpr (std::experimental::is_detected::value) { + if (!isParticleTPC(posChild2, CascChildTable[confCascType][0]) || !isParticleTPC(negChild2, CascChildTable[confCascType][1]) || !isParticleTPC(bachelor, CascChildTable[confCascType][2])) + continue; + if (!isParticleTOF(posChild2, CascChildTable[confCascType][0]) || !isParticleTOF(negChild2, CascChildTable[confCascType][1]) || !isParticleTOF(bachelor, CascChildTable[confCascType][2])) + continue; + } else { + if ((posChild2.pidCut() & (1u << CascChildTable[confCascType][0])) == 0 || (negChild2.pidCut() & (1u << CascChildTable[confCascType][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[confCascType][2])) == 0) + continue; + if ((posChild2.pidCut() & (8u << CascChildTable[confCascType][0])) == 0 || (negChild2.pidCut() & (8u << CascChildTable[confCascType][1])) == 0 || (bachelor.pidCut() & (8u << CascChildTable[confCascType][2])) == 0) + continue; + } - if (!isParticleTOF(posChild1, CascChildTable[confCascType][0]) || !isParticleTOF(negChild1, CascChildTable[confCascType][1]) || !isParticleTOF(bachelor1, CascChildTable[confCascType][2])) + // track cleaning + if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; - + } + if (confIsCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla, femto_universe_container::EventType::same)) { + return; + } + } sameEventCont.setPair(p1, p2, col.multNtr(), confUse3D, 1.0f); } } - PROCESS_SWITCH(FemtoUniversePairTaskV0CascadeExtended, processSameEvent, "Enable processing same event for v0 - cascade", false); + + void processSameEvent(const FilteredFDCollision& col, const FemtoParticles& parts) + { + doSameEvent(col, parts, partsOne, partsTwo); + } + PROCESS_SWITCH(FemtoUniversePairTaskV0CascadeExtended, processSameEvent, "Enable processing same event for v0 - cascade with debug table", false); + + void processSameEventBitmask(const FilteredFDCollision& col, const aod::FDParticles& parts) + { + doSameEvent(col, parts, partsOnebitmask, partsTwobitmask); + } + PROCESS_SWITCH(FemtoUniversePairTaskV0CascadeExtended, processSameEventBitmask, "Enable processing same event for v0 - cascade with bitmask", false); /// v0-cascade correlations mixed event - void processMixedEvent(const FilteredFDCollisions& cols, const FemtoParticles& parts) + template + void doMixedEvent(const FilteredFDCollisions& cols, const TableType& parts, PartitionType& partsOne, PartitionType& partsTwo) { ColumnBinningPolicy colBinning{{confVtxBins, confMultBins}, true}; @@ -291,33 +388,65 @@ struct FemtoUniversePairTaskV0CascadeExtended { // Cascase inv Mass cut (mLambda stores Xi mass, mAntiLambda stored Omega mass) if (!invMCascade(p2.mLambda(), p2.mAntiLambda(), confCascType)) continue; + // V0 - const auto& posChild2 = parts.iteratorAt(p1.index() - 2); - const auto& negChild2 = parts.iteratorAt(p1.index() - 1); + const auto& posChild1 = parts.iteratorAt(p1.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& negChild1 = parts.iteratorAt(p1.globalIndex() - 1 - parts.begin().globalIndex()); /// Daughters of v0 must pass this condition to be selected - if (!isParticleTPC(posChild2, V0ChildTable[confV0Type][0]) || !isParticleTPC(negChild2, V0ChildTable[confV0Type][1])) - continue; - // cascade - const auto& posChild1 = parts.iteratorAt(p2.index() - 3); - const auto& negChild1 = parts.iteratorAt(p2.index() - 2); - const auto& bachelor1 = parts.iteratorAt(p2.index() - 1); - /// Daughters of cascade must pass this condition to be selected - if (!isParticleTPC(posChild1, CascChildTable[confCascType][0]) || !isParticleTPC(negChild1, CascChildTable[confCascType][1]) || !isParticleTPC(bachelor1, CascChildTable[confCascType][2])) - continue; + if constexpr (std::experimental::is_detected::value) { + if (!isParticleTPC(posChild1, V0ChildTable[confV0Type][0]) || !isParticleTPC(negChild1, V0ChildTable[confV0Type][1])) + continue; + if (!isParticleTOF(posChild1, V0ChildTable[confV0Type][0]) || !isParticleTOF(negChild1, V0ChildTable[confV0Type][1])) + continue; + } else { + if ((posChild1.pidCut() & (1u << V0ChildTable[confV0Type][0])) == 0 || (negChild1.pidCut() & (1u << V0ChildTable[confV0Type][1])) == 0) + continue; + if ((posChild1.pidCut() & (8u << V0ChildTable[confV0Type][0])) == 0 || (negChild1.pidCut() & (8u << V0ChildTable[confV0Type][1])) == 0) + continue; + } - if (!isParticleTOF(posChild1, CascChildTable[confCascType][0]) || !isParticleTOF(negChild1, CascChildTable[confCascType][1]) || !isParticleTOF(bachelor1, CascChildTable[confCascType][2])) - continue; + // Cascade + const auto& posChild2 = parts.iteratorAt(p2.globalIndex() - 3 - parts.begin().globalIndex()); + const auto& negChild2 = parts.iteratorAt(p2.globalIndex() - 2 - parts.begin().globalIndex()); + const auto& bachelor = parts.iteratorAt(p2.globalIndex() - 1 - parts.begin().globalIndex()); + /// Daughters of cascade must pass this condition to be selected + if constexpr (std::experimental::is_detected::value) { + if (!isParticleTPC(posChild2, CascChildTable[confCascType][0]) || !isParticleTPC(negChild2, CascChildTable[confCascType][1]) || !isParticleTPC(bachelor, CascChildTable[confCascType][2])) + continue; + if (!isParticleTOF(posChild2, CascChildTable[confCascType][0]) || !isParticleTOF(negChild2, CascChildTable[confCascType][1]) || !isParticleTOF(bachelor, CascChildTable[confCascType][2])) + continue; + } else { + if ((posChild2.pidCut() & (1u << CascChildTable[confCascType][0])) == 0 || (negChild2.pidCut() & (1u << CascChildTable[confCascType][1])) == 0 || (bachelor.pidCut() & (1u << CascChildTable[confCascType][2])) == 0) + continue; + if ((posChild2.pidCut() & (8u << CascChildTable[confCascType][0])) == 0 || (negChild2.pidCut() & (8u << CascChildTable[confCascType][1])) == 0 || (bachelor.pidCut() & (8u << CascChildTable[confCascType][2])) == 0) + continue; + } // track cleaning if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; } + if (confIsCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla1, femto_universe_container::EventType::same)) { + return; + } + } mixedEventCont.setPair(p1, p2, multCol, confUse3D, 1.0f); } } } - PROCESS_SWITCH(FemtoUniversePairTaskV0CascadeExtended, processMixedEvent, "Enable processing mixed event for v0 - cascade", false); + void processMixedEvent(const FilteredFDCollisions& cols, const FemtoParticles& parts) + { + doMixedEvent(cols, parts, partsOne, partsTwo); + } + PROCESS_SWITCH(FemtoUniversePairTaskV0CascadeExtended, processMixedEvent, "Enable processing mixed event for v0 - cascade with debug table", false); + + void processMixedEventBitmask(const FilteredFDCollisions& cols, const aod::FDParticles& parts) + { + doMixedEvent(cols, parts, partsOnebitmask, partsTwobitmask); + } + PROCESS_SWITCH(FemtoUniversePairTaskV0CascadeExtended, processMixedEventBitmask, "Enable processing mixed event for v0 - cascade with bitmask", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/Flow/Tasks/CMakeLists.txt b/PWGCF/Flow/Tasks/CMakeLists.txt index e368eef4c73..532351a316b 100644 --- a/PWGCF/Flow/Tasks/CMakeLists.txt +++ b/PWGCF/Flow/Tasks/CMakeLists.txt @@ -88,3 +88,8 @@ o2physics_add_dpl_workflow(flow-ese-task SOURCES flowEseTask.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::GFWCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(flow-gfw-ese + SOURCES flowGfwEse.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::GFWCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/Flow/Tasks/flowEseTask.cxx b/PWGCF/Flow/Tasks/flowEseTask.cxx index 15bb95d27be..6ab2155788a 100644 --- a/PWGCF/Flow/Tasks/flowEseTask.cxx +++ b/PWGCF/Flow/Tasks/flowEseTask.cxx @@ -9,443 +9,1040 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. +/// \author Junlee Kim (jikim1290@gmail.com) /// \file flowEseTask.cxx /// \brief Task for flow and event shape engineering correlation with other observation. -/// \author Alice Collaboration /// \since 2023-05-15 /// \version 1.0 -/// -/// This task calculates flow and event shape engineering -/// using Q-vector and event plane methods. - -// C++/ROOT includes. -#include -#include -#include -#include -#include -#include -#include -#include +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGMM/Mult/DataModel/Index.h" // for Particles2Tracks table -// o2Physics includes. -#include "Common/Core/EventPlaneHelper.h" +#include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/PIDResponseITS.h" #include "Common/DataModel/Qvectors.h" #include "Common/DataModel/TrackSelectionTables.h" +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" #include "CommonConstants/PhysicsConstants.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" -#include "Framework/RunningWorkflowInfo.h" +#include "Framework/O2DatabasePDGPlugin.h" #include "Framework/StaticFor.h" +#include "Framework/StepTHn.h" #include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" -// o2 includes. +#include "Math/GenVector/Boost.h" +#include "Math/Vector3D.h" +#include "Math/Vector4D.h" +#include "TF1.h" +#include "TRandom3.h" +#include "TVector2.h" +#include + +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; - -using MyCollisions = soa::Join; -using MyTracks = soa::Join; -using BCsWithRun3Matchings = soa::Join; +using namespace o2::framework::expressions; +using namespace o2::soa; +using namespace o2::constants::physics; struct FlowEseTask { - HistogramRegistry histosQA{"histosQA", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; + // using EventCandidates = soa::Filtered>; + using EventCandidates = soa::Join; + using TrackCandidates = soa::Join; + using V0TrackCandidate = aod::V0Datas; + + HistogramRegistry histos{ + "histos", + {}, + OutputObjHandlingPolicy::AnalysisObject}; + + struct : ConfigurableGroup { + Configurable cfgURL{"cfgURL", + "http://alice-ccdb.cern.ch", "Address of the CCDB to browse"}; + Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "Latest acceptable timestamp of creation for the object"}; + } cfgCcdbParam; + Service ccdb; + o2::ccdb::CcdbApi ccdbApi; + + Configurable cfgCentSel{"cfgCentSel", 80., "Centrality selection"}; + Configurable cfgCentEst{"cfgCentEst", 1, "Centrality estimator, 1: FT0C, 2: FT0M"}; + + Configurable cfgPVSel{"cfgPVSel", false, "Additional PV selection flag for syst"}; + Configurable cfgPV{"cfgPV", 8.0, "Additional PV selection range for syst"}; + Configurable cfgAddEvtSelPileup{"cfgAddEvtSelPileup", false, "flag for additional pileup selection"}; + Configurable cfgMaxOccupancy{"cfgMaxOccupancy", 999999, "maximum occupancy of tracks in neighbouring collisions in a given time range"}; + Configurable cfgMinOccupancy{"cfgMinOccupancy", 0, "maximum occupancy of tracks in neighbouring collisions in a given time range"}; + + Configurable cfgv0radiusMin{"cfgv0radiusMin", 1.2, "minimum decay radius"}; + Configurable cfgDCAPrToPVMin{"cfgDCAPrToPVMin", 0.05, "minimum DCA to PV for proton track"}; + Configurable cfgDCAPiToPVMin{"cfgDCAPiToPVMin", 0.1, "minimum DCA to PV for pion track"}; + Configurable cfgv0CosPA{"cfgv0CosPA", 0.995, "minimum v0 cosine"}; + Configurable cfgDCAV0Dau{"cfgDCAV0Dau", 1.0, "maximum DCA between daughters"}; + + Configurable cfgV0PtMin{"cfgV0PtMin", 0, "minimum pT for lambda"}; + Configurable cfgV0EtaMin{"cfgV0EtaMin", -0.5, "maximum rapidity"}; + Configurable cfgV0EtaMax{"cfgV0EtaMax", 0.5, "maximum rapidity"}; + Configurable cfgV0LifeTime{"cfgV0LifeTime", 30., "maximum lambda lifetime"}; - Configurable> cfgNmods{"cfgNmods", {2}, "Modulation of interest"}; - Configurable cfgDetName{"cfgDetName", "FT0C", "The name of detector to be analyzed"}; - Configurable cfgRefAName{"cfgRefAName", "TPCpos", "The name of detector for reference A"}; - Configurable cfgRefBName{"cfgRefBName", "TPCneg", "The name of detector for reference B"}; + Configurable cfgQAv0{"cfgQAv0", true, "QA plot"}; - Configurable cfgMinPt{"cfgMinPt", 0.15f, "Minimum transverse momentum for charged track"}; - Configurable cfgMaxEta{"cfgMaxEta", 0.8f, "Maximum pseudorapidiy for charged track"}; - Configurable cfgMaxDCArToPVcut{"cfgMaxDCArToPVcut", 0.1f, "Maximum transverse DCA"}; - Configurable cfgMaxDCAzToPVcut{"cfgMaxDCAzToPVcut", 1.0f, "Maximum longitudinal DCA"}; + Configurable cfgDaughTPCnclsMin{"cfgDaughTPCnclsMin", 70, "minimum fired crossed rows"}; + Configurable cfgDaughPIDCutsTPCPr{"cfgDaughPIDCutsTPCPr", 5, "proton nsigma for TPC"}; + Configurable cfgDaughPIDCutsTPCPi{"cfgDaughPIDCutsTPCPi", 5, "pion nsigma for TPC"}; + Configurable cfgDaughEtaMin{"cfgDaughEtaMin", -0.8, "minimum daughter eta"}; + Configurable cfgDaughEtaMax{"cfgDaughEtaMax", 0.8, "maximum daughter eta"}; + Configurable cfgDaughPrPt{"cfgDaughPrPt", 0.5, "minimum daughter proton pt"}; + Configurable cfgDaughPiPt{"cfgDaughPiPt", 0.5, "minimum daughter pion pt"}; - ConfigurableAxis cfgAxisQvecF{"cfgAxisQvecF", {300, -1, 1}, ""}; - ConfigurableAxis cfgAxisQvec{"cfgAxisQvec", {100, -3, 3}, ""}; - ConfigurableAxis cfgAxisCent{"cfgAxisCent", {100, 0, 100}, ""}; + Configurable cfgnMods{"cfgnMods", 1, "The number of modulations of interest starting from 2"}; + Configurable cfgNQvec{"cfgNQvec", 7, "The number of total Qvectors for looping over the task"}; - ConfigurableAxis cfgAxisCos{"cfgAxisCos", {102, -1.02, 1.02}, ""}; - ConfigurableAxis cfgAxisPt{"cfgAxisPt", {100, 0, 10}, ""}; - ConfigurableAxis cfgAxisCentMerged{"cfgAxisCentMerged", {20, 0, 100}, ""}; - ConfigurableAxis cfgAxisMultNum{"cfgAxisMultNum", {300, 0, 2700}, ""}; - ConfigurableAxis cfgaxisQ{"cfgaxisQ", {1000, 0, 1000}, ""}; + Configurable cfgQvecDetName{"cfgQvecDetName", "FT0C", "The name of detector to be analyzed"}; + Configurable cfgQvecRefAName{"cfgQvecRefAName", "TPCpos", "The name of detector for reference A"}; + Configurable cfgQvecRefBName{"cfgQvecRefBName", "TPCneg", "The name of detector for reference B"}; - static constexpr float kMinAmplitudeThreshold = 1e-4f; - static constexpr int kDefaultModulation = 2; - static constexpr std::array kCent = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; - static constexpr std::array kSeparator = {125, 204, 110, 172, 92, 143, 74, 116, 57, 92, 43, 70, 31, 50, 21, 34, 14, 22, 5, 9}; + Configurable cfgPhiDepStudy{"cfgPhiDepStudy", false, "cfg for phi dependent study"}; + Configurable cfgUSESP{"cfgUSESP", false, "cfg for sp"}; + Configurable cfgPhiDepSig{"cfgPhiDepSig", 0.2, "cfg for significance on phi dependent study"}; - EventPlaneHelper helperEP; + Configurable cfgShiftCorr{"cfgShiftCorr", false, "additional shift correction"}; + Configurable cfgShiftCorrDef{"cfgShiftCorrDef", false, "additional shift correction definition"}; + Configurable cfgShiftPath{"cfgShiftPath", "Users/j/junlee/Qvector/QvecCalib/Shift", "Path for Shift"}; - void init(InitContext const&) + Configurable cfgEffCor{"cfgEffCor", false, "flag to apply efficiency correction"}; + Configurable cfgEffCorPath{"cfgEffCorPath", "", "path for pseudo efficiency correction"}; + + Configurable cfgAccCor{"cfgAccCor", false, "flag to apply acceptance correction"}; + Configurable cfgAccCorPath{"cfgAccCorPath", "", "path for pseudo acceptance correction"}; + + Configurable cfgCalcCum{"cfgCalcCum", false, "flag to calculate cumulants of cossin"}; + Configurable cfgCalcCum1{"cfgCalcCum1", false, "flag to calculate cumulants of coscos"}; + + Configurable cfgRapidityDep{"cfgRapidityDep", false, "flag for rapidity dependent study"}; + Configurable cfgAccAzimuth{"cfgAccAzimuth", false, "flag for azimuth closure study"}; + + ConfigurableAxis massAxis{"massAxis", {30, 1.1, 1.13}, "Invariant mass axis"}; + ConfigurableAxis ptAxis{"ptAxis", {VARIABLE_WIDTH, 0.2, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.5, 8.0, 10.0, 100.0}, "Transverse momentum bins"}; + ConfigurableAxis centAxis{"centAxis", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 100}, "Centrality interval"}; + ConfigurableAxis cosAxis{"cosAxis", {110, -1.05, 1.05}, "Cosine axis"}; + ConfigurableAxis rapAxis{"rapAxis", {10, -0.5, 0.5}, "Rapidity axis"}; + ConfigurableAxis qqAxis{"qqAxis", {100, -0.1, 0.1}, "qq axis"}; + ConfigurableAxis lowerQAxis{"lowerQAxis", {800, 0, 800}, "result of q2"}; + ConfigurableAxis multNumAxis{"multNumAxis", {300, 0, 2700}, "mult num"}; + ConfigurableAxis qvecAxis{"qvecAxis", {300, -1, 1}, "range of Qvector"}; + + static constexpr float kMinAmplitudeThreshold = 1e-5f; + static constexpr int kShiftLevel = 10; + static constexpr int kLambdaId = 3122; + static constexpr std::array kCorrLevel = {2, 3, 4, 1}; + static constexpr std::array kCentBoundaries = {0.0f, 3.49f, 4.93f, 6.98f, 8.55f, 9.87f, 11.0f, 12.1f, 13.1f, 14.0f}; + static constexpr std::array kCentValues = {2.5f, 7.5f, 15.0f, 25.0f, 35.0f, 45.0f, 55.0f, 65.0f, 75.0f}; + static constexpr float kEtaAcceptance = 0.8f; + static constexpr float kCentUpperLimit = 80.0f; + + TF1* fMultPVCutLow = nullptr; + TF1* fMultPVCutHigh = nullptr; + + int detId; + int refAId; + int refBId; + + int qvecDetInd; + int qvecRefAInd; + int qvecRefBInd; + + float centrality; + + double angle; + double psi; + double relphi; + + int currentRunNumber = -999; + int lastRunNumber = -999; + std::vector shiftprofile{}; + TProfile2D* effMap = nullptr; + TProfile2D* accMap = nullptr; + + std::string fullCCDBShiftCorrPath; + + template + int getDetId(const T& name) { - AxisSpec axisCent{cfgAxisCent, "centrality"}; - AxisSpec axisQvec{cfgAxisQvec, "Q"}; - AxisSpec axisQvecF{cfgAxisQvecF, "Q"}; - AxisSpec axisEvtPl = {100, -1.0 * constants::math::PI, constants::math::PI}; - - AxisSpec axisCos{cfgAxisCos, "angle function"}; - AxisSpec axisPt{cfgAxisPt, "trasverse momentum"}; - AxisSpec axisCentMerged{cfgAxisCentMerged, "merged centrality"}; - AxisSpec axisMultNum{cfgAxisMultNum, "statistic of mult"}; - AxisSpec axisQ{cfgaxisQ, "result of q2"}; - - histosQA.add(Form("histQvecV2"), "", {HistType::kTH3F, {axisQvecF, axisQvecF, axisCent}}); - histosQA.add(Form("histQvecCent"), "", {HistType::kTH2F, {axisQ, axisCent}}); - histosQA.add(Form("histEvtPlV2"), "", {HistType::kTH2F, {axisEvtPl, axisCent}}); - histosQA.add(Form("histQvecRes_SigRefAV2"), "", {HistType::kTH2F, {axisQvecF, axisCent}}); - histosQA.add(Form("histCosDetV2"), "", {HistType::kTH3F, {axisCentMerged, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_0010Left"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_0010Mid"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_0010Right"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_1020Left"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_1020Mid"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_1020Right"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_2030Left"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_2030Mid"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_2030Right"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_3040Left"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_3040Mid"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_3040Right"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_4050Left"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_4050Mid"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_4050Right"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_5060Left"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_5060Mid"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_5060Right"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_6070Left"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_6070Mid"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_6070Right"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_7080Left"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_7080Mid"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_7080Right"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_8090Left"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_8090Mid"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_8090Right"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_9010Left"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_9010Mid"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histCosDetV2_9010Right"), "", {HistType::kTH3F, {axisQvecF, axisPt, axisCos}}); - histosQA.add(Form("histMult_Cent"), "", {HistType::kTH2F, {axisMultNum, axisCent}}); + if (name.value == "FT0C") { + return 0; + } else if (name.value == "FT0A") { + return 1; + } else if (name.value == "FT0M") { + return 2; + } else if (name.value == "FV0A") { + return 3; + } else if (name.value == "TPCpos") { + return 4; + } else if (name.value == "TPCneg") { + return 5; + } else if (name.value == "TPCall") { + return 6; + } else { + return 0; + } + } + + void init(o2::framework::InitContext&) + { + AxisSpec centQaAxis = {80, 0.0, 80.0}; + AxisSpec pVzQaAxis = {300, -15.0, 15.0}; + AxisSpec epAxis = {6, 0.0, o2::constants::math::TwoPI}; + AxisSpec epQaAxis = {100, -1.0 * o2::constants::math::PI, o2::constants::math::PI}; + + AxisSpec pidAxis = {100, -10, 10}; + + AxisSpec shiftAxis = {10, 0, 10, "shift"}; + AxisSpec basisAxis = {20, 0, 20, "basis"}; + + histos.add(Form("histQvecV2"), "", {HistType::kTH3F, {qvecAxis, qvecAxis, centAxis}}); + histos.add(Form("histMult_Cent"), "", {HistType::kTH2F, {multNumAxis, centAxis}}); + histos.add(Form("histQvecCent"), "", {HistType::kTH2F, {lowerQAxis, centAxis}}); + + for (auto i = 2; i < cfgnMods + 2; i++) { + histos.add(Form("psi%d/h_lambda_cos", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, epAxis}}); + histos.add(Form("psi%d/h_alambda_cos", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, epAxis}}); + histos.add(Form("psi%d/h_lambda_cos2", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, epAxis}}); + histos.add(Form("psi%d/h_alambda_cos2", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, epAxis}}); + + if (cfgRapidityDep) { + histos.add(Form("psi%d/h_lambda_cos2_rap", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, rapAxis}}); + histos.add(Form("psi%d/h_alambda_cos2_rap", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis, rapAxis}}); + } + + histos.add(Form("psi%d/h_lambda_cossin", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add(Form("psi%d/h_alambda_cossin", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + + if (cfgAccAzimuth) { + histos.add(Form("psi%d/h_lambda_coscos", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add(Form("psi%d/h_alambda_coscos", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + } + + histos.add(Form("psi%d/h_lambda_vncos", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add(Form("psi%d/h_lambda_vnsin", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add(Form("psi%d/h_alambda_vncos", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add(Form("psi%d/h_alambda_vnsin", i), "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + } + histos.add("QA/ptspec_l", "", {HistType::kTH3F, {massAxis, ptAxis, centAxis}}); + histos.add("QA/ptspec_al", "", {HistType::kTH3F, {massAxis, ptAxis, centAxis}}); + histos.add("QA/ptspecCor_l", "", {HistType::kTH3F, {massAxis, ptAxis, centAxis}}); + histos.add("QA/ptspecCor_al", "", {HistType::kTH3F, {massAxis, ptAxis, centAxis}}); + + if (cfgCalcCum) { + histos.add("psi2/QA/cosTheta_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosPsi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosPhi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + + histos.add("psi2/QA/sinPsi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/sinPhi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + + histos.add("psi2/QA/cosTheta_cosPhi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosTheta_cosPsi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + + histos.add("psi2/QA/cosTheta_sinPhi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosTheta_sinPsi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + + histos.add("psi2/QA/cosPhi_sinPsi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/sinPhi_cosPsi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + + histos.add("psi2/QA/cosTheta_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosPsi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosPhi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + + histos.add("psi2/QA/sinPsi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/sinPhi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + + histos.add("psi2/QA/cosTheta_cosPhi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosTheta_cosPsi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + + histos.add("psi2/QA/cosTheta_sinPhi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosTheta_sinPsi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + + histos.add("psi2/QA/cosPhi_sinPsi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/sinPhi_cosPsi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + } + + if (cfgCalcCum1) { + histos.add("psi2/QA/cosTheta_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosPsi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosPhi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + + histos.add("psi2/QA/cosPhi_cosPsi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosTheta_cosPhi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosTheta_cosPsi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + + histos.add("psi2/QA/sinPhi_sinPsi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosTheta_sinPhi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosTheta_sinPsi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + + histos.add("psi2/QA/sinPsi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/sinPhi_l", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + + histos.add("psi2/QA/cosTheta_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosPsi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosPhi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + + histos.add("psi2/QA/cosPhi_cosPsi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosTheta_cosPhi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosTheta_cosPsi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + + histos.add("psi2/QA/sinPhi_sinPsi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosTheta_sinPhi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/cosTheta_sinPsi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + + histos.add("psi2/QA/sinPsi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + histos.add("psi2/QA/sinPhi_al", "", {HistType::kTHnSparseF, {massAxis, ptAxis, cosAxis, centAxis}}); + } + + if (cfgQAv0) { + histos.add("QA/CentDist", "", {HistType::kTH1F, {centQaAxis}}); + histos.add("QA/PVzDist", "", {HistType::kTH1F, {pVzQaAxis}}); + + histos.add("QA/nsigma_tpc_pt_ppr", "", {HistType::kTH2F, {ptAxis, pidAxis}}); + histos.add("QA/nsigma_tpc_pt_ppi", "", {HistType::kTH2F, {ptAxis, pidAxis}}); + histos.add("QA/nsigma_tpc_pt_mpr", "", {HistType::kTH2F, {ptAxis, pidAxis}}); + histos.add("QA/nsigma_tpc_pt_mpi", "", {HistType::kTH2F, {ptAxis, pidAxis}}); + + for (auto i = 2; i < cfgnMods + 2; i++) { + histos.add(Form("psi%d/QA/EP_Det", i), "", {HistType::kTH2F, {centQaAxis, epQaAxis}}); + histos.add(Form("psi%d/QA/EP_RefA", i), "", {HistType::kTH2F, {centQaAxis, epQaAxis}}); + histos.add(Form("psi%d/QA/EP_RefB", i), "", {HistType::kTH2F, {centQaAxis, epQaAxis}}); + + histos.add(Form("psi%d/QA/qqAxis_Det_RefA_xx", i), "", {HistType::kTH2F, {centQaAxis, qqAxis}}); + histos.add(Form("psi%d/QA/qqAxis_Det_RefB_xx", i), "", {HistType::kTH2F, {centQaAxis, qqAxis}}); + histos.add(Form("psi%d/QA/qqAxis_RefA_RefB_xx", i), "", {HistType::kTH2F, {centQaAxis, qqAxis}}); + + histos.add(Form("psi%d/QA/qqAxis_Det_RefA_yy", i), "", {HistType::kTH2F, {centQaAxis, qqAxis}}); + histos.add(Form("psi%d/QA/qqAxis_Det_RefB_yy", i), "", {HistType::kTH2F, {centQaAxis, qqAxis}}); + histos.add(Form("psi%d/QA/qqAxis_RefA_RefB_yy", i), "", {HistType::kTH2F, {centQaAxis, qqAxis}}); + + histos.add(Form("psi%d/QA/EPRes_Det_RefA", i), "", {HistType::kTH2F, {centQaAxis, cosAxis}}); + histos.add(Form("psi%d/QA/EPRes_Det_RefB", i), "", {HistType::kTH2F, {centQaAxis, cosAxis}}); + histos.add(Form("psi%d/QA/EPRes_RefA_RefB", i), "", {HistType::kTH2F, {centQaAxis, cosAxis}}); + + histos.add(Form("psi%d/QA/EP_FT0C_shifted", i), "", {HistType::kTH2F, {centQaAxis, epQaAxis}}); + histos.add(Form("psi%d/QA/EP_FT0A_shifted", i), "", {HistType::kTH2F, {centQaAxis, epQaAxis}}); + histos.add(Form("psi%d/QA/EP_FV0A_shifted", i), "", {HistType::kTH2F, {centQaAxis, epQaAxis}}); + + histos.add(Form("psi%d/QA/EPRes_FT0C_FT0A_shifted", i), "", {HistType::kTH2F, {centQaAxis, cosAxis}}); + histos.add(Form("psi%d/QA/EPRes_FT0C_FV0A_shifted", i), "", {HistType::kTH2F, {centQaAxis, cosAxis}}); + histos.add(Form("psi%d/QA/EPRes_FT0A_FV0A_shifted", i), "", {HistType::kTH2F, {centQaAxis, cosAxis}}); + } + } + + if (doprocessMcItsTpc) { + histos.add("hImpactParameter", "Impact parameter", kTH1F, {{200, 0.0f, 20.0f}}); + histos.add("hEventPlaneAngle", "hEventPlaneAngle", kTH1F, {{200, -1.0 * o2::constants::math::TwoPI, 1.0 * o2::constants::math::TwoPI}}); + histos.add("hEventPlaneAngleRec", "hEventPlaneAngleRec", kTH1F, {{200, -1.0 * o2::constants::math::TwoPI, 1.0 * o2::constants::math::TwoPI}}); + histos.add("hNchVsImpactParameter", "hNchVsImpactParameter", kTH2F, {{200, 0.0f, 20.0f}, {500, -0.5f, 5000.5f}}); + histos.add("hSparseMCGenWeight", "hSparseMCGenWeight", HistType::kTHnSparseF, {centAxis, {36, 0.0f, o2::constants::math::PI}, {50, 0.0f, 1}, ptAxis, {8, -0.8, 0.8}}); + histos.add("hSparseMCRecWeight", "hSparseMCRecWeight", HistType::kTHnSparseF, {centAxis, {36, 0.0f, o2::constants::math::PI}, {50, 0.0f, 1}, ptAxis, {8, -0.8, 0.8}}); + histos.add("hSparseMCRecAllTrackWeight", "hSparseMCRecAllTrackWeight", HistType::kTHnSparseF, {centAxis, {36, 0.0, o2::constants::math::PI}, {50, 0.0f, 1}, ptAxis, {8, -0.8, 0.8}}); + } + + if (cfgShiftCorrDef) { + for (auto i = 2; i < cfgnMods + 2; i++) { + histos.add(Form("psi%d/ShiftFIT", i), "", kTProfile3D, {centQaAxis, basisAxis, shiftAxis}); + } + } + + detId = getDetId(cfgQvecDetName); + refAId = getDetId(cfgQvecRefAName); + refBId = getDetId(cfgQvecRefBName); + + if (detId == refAId || detId == refBId || refAId == refBId) { + LOGF(info, "Wrong detector configuration \n The FT0C will be used to get Q-Vector \n The TPCpos and TPCneg will be used as reference systems"); + detId = 0; + refAId = 4; + refBId = 5; + } + + fMultPVCutLow = new TF1("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.5*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); + fMultPVCutLow->SetParameters(2834.66, -87.0127, 0.915126, -0.00330136, 332.513, -12.3476, 0.251663, -0.00272819, 1.12242e-05); + fMultPVCutHigh = new TF1("fMultPVCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 2.5*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); + fMultPVCutHigh->SetParameters(2834.66, -87.0127, 0.915126, -0.00330136, 332.513, -12.3476, 0.251663, -0.00272819, 1.12242e-05); + + ccdb->setURL(cfgCcdbParam.cfgURL); + ccdbApi.init("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); } - template - bool selectEvent(CollType const& collision) + double massLambda = o2::constants::physics::MassLambda; + double massPr = o2::constants::physics::MassProton; + double massPi = o2::constants::physics::MassPionCharged; + + ROOT::Math::PxPyPzMVector protonVec, pionVec, LambdaVec, protonBoostedVec, pionBoostedVec; + + template + bool eventSelected(TCollision collision) { if (!collision.sel8()) { - return false; + return 0; } + + if (cfgCentSel < centrality) { + return 0; + } + /* + auto multNTracksPV = collision.multNTracksPV(); + if (multNTracksPV < fMultPVCutLow->Eval(centrality)) { + return 0; + } + if (multNTracksPV > fMultPVCutHigh->Eval(centrality)) { + return 0; + } + */ if (!collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { - return false; + return 0; } if (!collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { - return false; + return 0; } - if (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { - return false; + if (cfgPVSel && std::abs(collision.posZ()) > cfgPV) { + return 0; + } + if (cfgAddEvtSelPileup && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return 0; + } + if (collision.trackOccupancyInTimeRange() > cfgMaxOccupancy || collision.trackOccupancyInTimeRange() < cfgMinOccupancy) { + return 0; } - return true; - } + return 1; + } // event selection - template - bool selectTrack(TrackType const& track) + template + bool selectionV0(TCollision const& collision, V0 const& candidate, int lambdaTag) { - if (track.pt() < cfgMinPt) { + if (candidate.v0radius() < cfgv0radiusMin) return false; + if (lambdaTag) { + if (std::abs(candidate.dcapostopv()) < cfgDCAPrToPVMin) + return false; + if (std::abs(candidate.dcanegtopv()) < cfgDCAPiToPVMin) + return false; + } else if (!lambdaTag) { + if (std::abs(candidate.dcapostopv()) < cfgDCAPiToPVMin) + return false; + if (std::abs(candidate.dcanegtopv()) < cfgDCAPrToPVMin) + return false; } - if (std::abs(track.eta()) > cfgMaxEta) { + if (candidate.v0cosPA() < cfgv0CosPA) return false; - } - if (!track.passedITSNCls()) { + if (std::abs(candidate.dcaV0daughters()) > cfgDCAV0Dau) return false; - } - if (!track.passedITSChi2NDF()) { + if (candidate.pt() < cfgV0PtMin) return false; - } - if (!track.passedITSHits()) { + if (candidate.yLambda() < cfgV0EtaMin) return false; - } - if (!track.passedTPCCrossedRowsOverNCls()) { + if (candidate.yLambda() > cfgV0EtaMax) return false; - } - if (!track.passedTPCChi2NDF()) { + if (candidate.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * massLambda > cfgV0LifeTime) return false; - } - if (!track.passedDCAxy()) { + + return true; + } + + template + bool isSelectedV0Daughter(T const& track, int pid) // pid 0: proton, pid 1: pion + { + if (track.tpcNClsFound() < cfgDaughTPCnclsMin) return false; - } - if (!track.passedDCAz()) { + if (pid == 0 && std::abs(track.tpcNSigmaPr()) > cfgDaughPIDCutsTPCPr) + return false; + if (pid == 1 && std::abs(track.tpcNSigmaPi()) > cfgDaughPIDCutsTPCPi) + return false; + if (track.eta() > cfgDaughEtaMax) + return false; + if (track.eta() < cfgDaughEtaMin) + return false; + if (pid == 0 && track.pt() < cfgDaughPrPt) + return false; + if (pid == 1 && track.pt() < cfgDaughPiPt) return false; - } return true; } - template - void fillHistosQvec(CollType const& collision, int nmode) + template + void fillShiftCorrection(TCollision const& collision, int nmode) { - if (nmode == kDefaultModulation) { - histosQA.fill(HIST("histQvecV2"), collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], - collision.centFT0C()); - histosQA.fill(HIST("histQvecCent"), std::sqrt(collision.qvecFT0CReVec()[0] * collision.qvecFT0CReVec()[0] + collision.qvecFT0CImVec()[0] * collision.qvecFT0CImVec()[0]) * std::sqrt(collision.sumAmplFT0C()), collision.centFT0C()); - histosQA.fill(HIST("histEvtPlV2"), - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), - collision.centFT0C()); - histosQA.fill(HIST("histQvecRes_SigRefAV2"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), - collision.centFT0C()); - histosQA.fill(HIST("histMult_Cent"), collision.sumAmplFT0C(), collision.centFT0C()); + qvecDetInd = detId * 4 + 3 + (nmode - 2) * cfgNQvec * 4; + qvecRefAInd = refAId * 4 + 3 + (nmode - 2) * cfgNQvec * 4; + qvecRefBInd = refBId * 4 + 3 + (nmode - 2) * cfgNQvec * 4; + + for (int ishift = 1; ishift <= kShiftLevel; ishift++) { + if (nmode == kCorrLevel[0]) { + histos.fill(HIST("psi2/ShiftFIT"), centrality, 0.5, ishift - 0.5, std::sin(ishift * static_cast(nmode) * std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) / static_cast(nmode))); + histos.fill(HIST("psi2/ShiftFIT"), centrality, 1.5, ishift - 0.5, std::cos(ishift * static_cast(nmode) * std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) / static_cast(nmode))); + + histos.fill(HIST("psi2/ShiftFIT"), centrality, 2.5, ishift - 0.5, std::sin(ishift * static_cast(nmode) * std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd]) / static_cast(nmode))); + histos.fill(HIST("psi2/ShiftFIT"), centrality, 3.5, ishift - 0.5, std::cos(ishift * static_cast(nmode) * std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd]) / static_cast(nmode))); + + histos.fill(HIST("psi2/ShiftFIT"), centrality, 4.5, ishift - 0.5, std::sin(ishift * static_cast(nmode) * std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd]) / static_cast(nmode))); + histos.fill(HIST("psi2/ShiftFIT"), centrality, 5.5, ishift - 0.5, std::cos(ishift * static_cast(nmode) * std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd]) / static_cast(nmode))); + } else if (nmode == kCorrLevel[1]) { + histos.fill(HIST("psi3/ShiftFIT"), centrality, 0.5, ishift - 0.5, std::sin(ishift * static_cast(nmode) * std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) / static_cast(nmode))); + histos.fill(HIST("psi3/ShiftFIT"), centrality, 1.5, ishift - 0.5, std::cos(ishift * static_cast(nmode) * std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) / static_cast(nmode))); + + histos.fill(HIST("psi3/ShiftFIT"), centrality, 2.5, ishift - 0.5, std::sin(ishift * static_cast(nmode) * std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd]) / static_cast(nmode))); + histos.fill(HIST("psi3/ShiftFIT"), centrality, 3.5, ishift - 0.5, std::cos(ishift * static_cast(nmode) * std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd]) / static_cast(nmode))); + + histos.fill(HIST("psi3/ShiftFIT"), centrality, 4.5, ishift - 0.5, std::sin(ishift * static_cast(nmode) * std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd]) / static_cast(nmode))); + histos.fill(HIST("psi3/ShiftFIT"), centrality, 5.5, ishift - 0.5, std::cos(ishift * static_cast(nmode) * std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd]) / static_cast(nmode))); + } else if (nmode == kCorrLevel[2]) { + histos.fill(HIST("psi4/ShiftFIT"), centrality, 0.5, ishift - 0.5, std::sin(ishift * static_cast(nmode) * std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) / static_cast(nmode))); + histos.fill(HIST("psi4/ShiftFIT"), centrality, 1.5, ishift - 0.5, std::cos(ishift * static_cast(nmode) * std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) / static_cast(nmode))); + + histos.fill(HIST("psi4/ShiftFIT"), centrality, 2.5, ishift - 0.5, std::sin(ishift * static_cast(nmode) * std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd]) / static_cast(nmode))); + histos.fill(HIST("psi4/ShiftFIT"), centrality, 3.5, ishift - 0.5, std::cos(ishift * static_cast(nmode) * std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd]) / static_cast(nmode))); + + histos.fill(HIST("psi4/ShiftFIT"), centrality, 4.5, ishift - 0.5, std::sin(ishift * static_cast(nmode) * std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd]) / static_cast(nmode))); + histos.fill(HIST("psi4/ShiftFIT"), centrality, 5.5, ishift - 0.5, std::cos(ishift * static_cast(nmode) * std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd]) / static_cast(nmode))); + } } } - template - void fillHistosFlow(CollType const& collision, TrackType const& tracks, int nmode) + template + void fillEPQA(TCollision const& collision, int nmode) { - double q2 = std::sqrt(collision.qvecFT0CReVec()[0] * collision.qvecFT0CReVec()[0] + collision.qvecFT0CImVec()[0] * collision.qvecFT0CImVec()[0]) * std::sqrt(collision.sumAmplFT0C()); - if (collision.sumAmplFT0C() < kMinAmplitudeThreshold) { + qvecDetInd = detId * 4 + 3 + (nmode - 2) * cfgNQvec * 4; + qvecRefAInd = refAId * 4 + 3 + (nmode - 2) * cfgNQvec * 4; + qvecRefBInd = refBId * 4 + 3 + (nmode - 2) * cfgNQvec * 4; + + if (collision.qvecAmp()[detId] < kMinAmplitudeThreshold || collision.qvecAmp()[refAId] < kMinAmplitudeThreshold || collision.qvecAmp()[refBId] < kMinAmplitudeThreshold) return; + + if (nmode == kCorrLevel[0]) { + histos.fill(HIST("psi2/QA/EP_Det"), centrality, std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) / static_cast(nmode)); + histos.fill(HIST("psi2/QA/EP_RefA"), centrality, std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd]) / static_cast(nmode)); + histos.fill(HIST("psi2/QA/EP_RefB"), centrality, std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd]) / static_cast(nmode)); + + histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_xx"), centrality, collision.qvecRe()[qvecDetInd] * collision.qvecRe()[qvecRefAInd]); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_xx"), centrality, collision.qvecRe()[qvecDetInd] * collision.qvecRe()[qvecRefBInd]); + histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_xx"), centrality, collision.qvecRe()[qvecRefAInd] * collision.qvecRe()[qvecRefBInd]); + + histos.fill(HIST("psi2/QA/qqAxis_Det_RefA_yy"), centrality, collision.qvecIm()[qvecDetInd] * collision.qvecIm()[qvecRefAInd]); + histos.fill(HIST("psi2/QA/qqAxis_Det_RefB_yy"), centrality, collision.qvecIm()[qvecDetInd] * collision.qvecIm()[qvecRefBInd]); + histos.fill(HIST("psi2/QA/qqAxis_RefA_RefB_yy"), centrality, collision.qvecIm()[qvecRefAInd] * collision.qvecIm()[qvecRefBInd]); + + histos.fill(HIST("psi2/QA/EPRes_Det_RefA"), centrality, std::cos(std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) - std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd]))); + histos.fill(HIST("psi2/QA/EPRes_Det_RefB"), centrality, std::cos(std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) - std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd]))); + histos.fill(HIST("psi2/QA/EPRes_RefA_RefB"), centrality, std::cos(std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd]) - std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd]))); + } else if (nmode == kCorrLevel[1]) { + histos.fill(HIST("psi3/QA/EP_Det"), centrality, std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) / static_cast(nmode)); + histos.fill(HIST("psi3/QA/EP_RefA"), centrality, std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd]) / static_cast(nmode)); + histos.fill(HIST("psi3/QA/EP_RefB"), centrality, std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd]) / static_cast(nmode)); + + histos.fill(HIST("psi3/QA/qqAxis_Det_RefA_xx"), centrality, collision.qvecRe()[qvecDetInd] * collision.qvecRe()[qvecRefAInd]); + histos.fill(HIST("psi3/QA/qqAxis_Det_RefB_xx"), centrality, collision.qvecRe()[qvecDetInd] * collision.qvecRe()[qvecRefBInd]); + histos.fill(HIST("psi3/QA/qqAxis_RefA_RefB_xx"), centrality, collision.qvecRe()[qvecRefAInd] * collision.qvecRe()[qvecRefBInd]); + + histos.fill(HIST("psi3/QA/qqAxis_Det_RefA_yy"), centrality, collision.qvecIm()[qvecDetInd] * collision.qvecIm()[qvecRefAInd]); + histos.fill(HIST("psi3/QA/qqAxis_Det_RefB_yy"), centrality, collision.qvecIm()[qvecDetInd] * collision.qvecIm()[qvecRefBInd]); + histos.fill(HIST("psi3/QA/qqAxis_RefA_RefB_yy"), centrality, collision.qvecIm()[qvecRefAInd] * collision.qvecIm()[qvecRefBInd]); + + histos.fill(HIST("psi3/QA/EPRes_Det_RefA"), centrality, std::cos(std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) - std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd]))); + histos.fill(HIST("psi3/QA/EPRes_Det_RefB"), centrality, std::cos(std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) - std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd]))); + histos.fill(HIST("psi3/QA/EPRes_RefA_RefB"), centrality, std::cos(std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd]) - std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd]))); + } else if (nmode == kCorrLevel[2]) { + histos.fill(HIST("psi4/QA/EP_Det"), centrality, std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) / static_cast(nmode)); + histos.fill(HIST("psi4/QA/EP_RefA"), centrality, std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd]) / static_cast(nmode)); + histos.fill(HIST("psi4/QA/EP_RefB"), centrality, std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd]) / static_cast(nmode)); + + histos.fill(HIST("psi4/QA/qqAxis_Det_RefA_xx"), centrality, collision.qvecRe()[qvecDetInd] * collision.qvecRe()[qvecRefAInd]); + histos.fill(HIST("psi4/QA/qqAxis_Det_RefB_xx"), centrality, collision.qvecRe()[qvecDetInd] * collision.qvecRe()[qvecRefBInd]); + histos.fill(HIST("psi4/QA/qqAxis_RefA_RefB_xx"), centrality, collision.qvecRe()[qvecRefAInd] * collision.qvecRe()[qvecRefBInd]); + + histos.fill(HIST("psi4/QA/qqAxis_Det_RefA_yy"), centrality, collision.qvecIm()[qvecDetInd] * collision.qvecIm()[qvecRefAInd]); + histos.fill(HIST("psi4/QA/qqAxis_Det_RefB_yy"), centrality, collision.qvecIm()[qvecDetInd] * collision.qvecIm()[qvecRefBInd]); + histos.fill(HIST("psi4/QA/qqAxis_RefA_RefB_yy"), centrality, collision.qvecIm()[qvecRefAInd] * collision.qvecIm()[qvecRefBInd]); + + histos.fill(HIST("psi4/QA/EPRes_Det_RefA"), centrality, std::cos(std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) - std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd]))); + histos.fill(HIST("psi4/QA/EPRes_Det_RefB"), centrality, std::cos(std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) - std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd]))); + histos.fill(HIST("psi4/QA/EPRes_RefA_RefB"), centrality, std::cos(std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd]) - std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd]))); + } + + if (cfgShiftCorr) { + auto deltapsiFT0C = 0.0; + auto deltapsiFT0A = 0.0; + auto deltapsiFV0A = 0.0; + + auto psidefFT0C = std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) / static_cast(nmode); + auto psidefFT0A = std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd]) / static_cast(nmode); + auto psidefFV0A = std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd]) / static_cast(nmode); + for (int ishift = 1; ishift <= kShiftLevel; ishift++) { + auto coeffshiftxFT0C = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(centrality, 0.5, ishift - 0.5)); + auto coeffshiftyFT0C = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(centrality, 1.5, ishift - 0.5)); + auto coeffshiftxFT0A = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(centrality, 2.5, ishift - 0.5)); + auto coeffshiftyFT0A = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(centrality, 3.5, ishift - 0.5)); + auto coeffshiftxFV0A = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(centrality, 4.5, ishift - 0.5)); + auto coeffshiftyFV0A = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(centrality, 5.5, ishift - 0.5)); + + deltapsiFT0C += ((1 / (1.0 * ishift)) * (-coeffshiftxFT0C * std::cos(ishift * static_cast(nmode) * psidefFT0C) + coeffshiftyFT0C * std::sin(ishift * static_cast(nmode) * psidefFT0C))); + deltapsiFT0A += ((1 / (1.0 * ishift)) * (-coeffshiftxFT0A * std::cos(ishift * static_cast(nmode) * psidefFT0A) + coeffshiftyFT0A * std::sin(ishift * static_cast(nmode) * psidefFT0A))); + deltapsiFV0A += ((1 / (1.0 * ishift)) * (-coeffshiftxFV0A * std::cos(ishift * static_cast(nmode) * psidefFV0A) + coeffshiftyFV0A * std::sin(ishift * static_cast(nmode) * psidefFV0A))); + } + if (nmode == kCorrLevel[0]) { + histos.fill(HIST("psi2/QA/EP_FT0C_shifted"), centrality, psidefFT0C + deltapsiFT0C); + histos.fill(HIST("psi2/QA/EP_FT0A_shifted"), centrality, psidefFT0A + deltapsiFT0A); + histos.fill(HIST("psi2/QA/EP_FV0A_shifted"), centrality, psidefFV0A + deltapsiFV0A); + + histos.fill(HIST("psi2/QA/EPRes_FT0C_FT0A_shifted"), centrality, std::cos(static_cast(nmode) * (psidefFT0C + deltapsiFT0C - psidefFT0A - deltapsiFT0A))); + histos.fill(HIST("psi2/QA/EPRes_FT0C_FV0A_shifted"), centrality, std::cos(static_cast(nmode) * (psidefFT0C + deltapsiFT0C - psidefFV0A - deltapsiFV0A))); + histos.fill(HIST("psi2/QA/EPRes_FT0A_FV0A_shifted"), centrality, std::cos(static_cast(nmode) * (psidefFT0A + deltapsiFT0A - psidefFV0A - deltapsiFV0A))); + } else if (nmode == kCorrLevel[1]) { + histos.fill(HIST("psi3/QA/EP_FT0C_shifted"), centrality, psidefFT0C + deltapsiFT0C); + histos.fill(HIST("psi3/QA/EP_FT0A_shifted"), centrality, psidefFT0A + deltapsiFT0A); + histos.fill(HIST("psi3/QA/EP_FV0A_shifted"), centrality, psidefFV0A + deltapsiFV0A); + + histos.fill(HIST("psi3/QA/EPRes_FT0C_FT0A_shifted"), centrality, std::cos(static_cast(nmode) * (psidefFT0C + deltapsiFT0C - psidefFT0A - deltapsiFT0A))); + histos.fill(HIST("psi3/QA/EPRes_FT0C_FV0A_shifted"), centrality, std::cos(static_cast(nmode) * (psidefFT0C + deltapsiFT0C - psidefFV0A - deltapsiFV0A))); + histos.fill(HIST("psi3/QA/EPRes_FT0A_FV0A_shifted"), centrality, std::cos(static_cast(nmode) * (psidefFT0A + deltapsiFT0A - psidefFV0A - deltapsiFV0A))); + } else if (nmode == kCorrLevel[2]) { + histos.fill(HIST("psi4/QA/EP_FT0C_shifted"), centrality, psidefFT0C + deltapsiFT0C); + histos.fill(HIST("psi4/QA/EP_FT0A_shifted"), centrality, psidefFT0A + deltapsiFT0A); + histos.fill(HIST("psi4/QA/EP_FV0A_shifted"), centrality, psidefFV0A + deltapsiFV0A); + + histos.fill(HIST("psi4/QA/EPRes_FT0C_FT0A_shifted"), centrality, std::cos(static_cast(nmode) * (psidefFT0C + deltapsiFT0C - psidefFT0A - deltapsiFT0A))); + histos.fill(HIST("psi4/QA/EPRes_FT0C_FV0A_shifted"), centrality, std::cos(static_cast(nmode) * (psidefFT0C + deltapsiFT0C - psidefFV0A - deltapsiFV0A))); + histos.fill(HIST("psi4/QA/EPRes_FT0A_FV0A_shifted"), centrality, std::cos(static_cast(nmode) * (psidefFT0A + deltapsiFT0A - psidefFV0A - deltapsiFV0A))); + } } - for (auto const& trk : tracks) { - if (!selectTrack(trk)) { + } + + template + void fillHistograms(TCollision const& collision, V0 const& V0s, int nmode) + { + qvecDetInd = detId * 4 + 3 + (nmode - 2) * cfgNQvec * 4; + qvecRefAInd = refAId * 4 + 3 + (nmode - 2) * cfgNQvec * 4; + qvecRefBInd = refBId * 4 + 3 + (nmode - 2) * cfgNQvec * 4; + + histos.fill(HIST("histQvecCent"), std::sqrt(collision.qvecFT0CReVec()[0] * collision.qvecFT0CReVec()[0] + collision.qvecFT0CImVec()[0] * collision.qvecFT0CImVec()[0]) * std::sqrt(collision.sumAmplFT0C()), collision.centFT0C()); + histos.fill(HIST("histQvecV2"), collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], collision.centFT0C()); + histos.fill(HIST("histMult_Cent"), collision.sumAmplFT0C(), collision.centFT0C()); + + for (const auto& v0 : V0s) { + auto postrack = v0.template posTrack_as(); + auto negtrack = v0.template negTrack_as(); + + double nTPCSigmaPosPr = postrack.tpcNSigmaPr(); + double nTPCSigmaNegPi = negtrack.tpcNSigmaPi(); + + double nTPCSigmaNegPr = negtrack.tpcNSigmaPr(); + double nTPCSigmaPosPi = postrack.tpcNSigmaPi(); + + if (cfgQAv0 && nmode == kCorrLevel[0]) { + histos.fill(HIST("QA/nsigma_tpc_pt_ppr"), postrack.pt(), nTPCSigmaPosPr); + histos.fill(HIST("QA/nsigma_tpc_pt_ppi"), postrack.pt(), nTPCSigmaPosPi); + + histos.fill(HIST("QA/nsigma_tpc_pt_mpr"), negtrack.pt(), nTPCSigmaNegPr); + histos.fill(HIST("QA/nsigma_tpc_pt_mpi"), negtrack.pt(), nTPCSigmaNegPi); + } + + int lambdaTag = 0; + int aLambdaTag = 0; + + if (isSelectedV0Daughter(postrack, 0) && isSelectedV0Daughter(negtrack, 1)) { + lambdaTag = 1; + } + if (isSelectedV0Daughter(negtrack, 0) && isSelectedV0Daughter(postrack, 1)) { + aLambdaTag = 1; + } + + if (lambdaTag == aLambdaTag) + continue; + + if (!selectionV0(collision, v0, lambdaTag)) continue; + + if (lambdaTag) { + protonVec = ROOT::Math::PxPyPzMVector(v0.pxpos(), v0.pypos(), v0.pzpos(), massPr); + pionVec = ROOT::Math::PxPyPzMVector(v0.pxneg(), v0.pyneg(), v0.pzneg(), massPi); } - if (nmode == kDefaultModulation) { - histosQA.fill(HIST("histCosDetV2"), collision.centFT0C(), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - if (collision.centFT0C() > kCent[0] && collision.centFT0C() <= kCent[1] && q2 < kSeparator[0]) { - histosQA.fill(HIST("histCosDetV2_0010Left"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[0] && collision.centFT0C() <= kCent[1] && q2 > kSeparator[0] && q2 <= kSeparator[1]) { - histosQA.fill(HIST("histCosDetV2_0010Mid"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[0] && collision.centFT0C() <= kCent[1] && q2 > kSeparator[1]) { - histosQA.fill(HIST("histCosDetV2_0010Right"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[1] && collision.centFT0C() <= kCent[2] && q2 < kSeparator[2]) { - histosQA.fill(HIST("histCosDetV2_1020Left"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[1] && collision.centFT0C() <= kCent[2] && q2 > kSeparator[2] && q2 <= kSeparator[3]) { - histosQA.fill(HIST("histCosDetV2_1020Mid"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[1] && collision.centFT0C() <= kCent[2] && q2 > kSeparator[3]) { - histosQA.fill(HIST("histCosDetV2_1020Right"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[2] && collision.centFT0C() <= kCent[3] && q2 < kSeparator[4]) { - histosQA.fill(HIST("histCosDetV2_2030Left"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[2] && collision.centFT0C() <= kCent[3] && q2 > kSeparator[4] && q2 <= kSeparator[5]) { - histosQA.fill(HIST("histCosDetV2_2030Mid"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[2] && collision.centFT0C() <= kCent[3] && q2 > kSeparator[5]) { - histosQA.fill(HIST("histCosDetV2_2030Right"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[3] && collision.centFT0C() <= kCent[4] && q2 < kSeparator[6]) { - histosQA.fill(HIST("histCosDetV2_3040Left"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[3] && collision.centFT0C() <= kCent[4] && q2 > kSeparator[6] && q2 <= kSeparator[7]) { - histosQA.fill(HIST("histCosDetV2_3040Mid"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[3] && collision.centFT0C() <= kCent[4] && q2 > kSeparator[7]) { - histosQA.fill(HIST("histCosDetV2_3040Right"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[4] && collision.centFT0C() <= kCent[5] && q2 < kSeparator[8]) { - histosQA.fill(HIST("histCosDetV2_4050Left"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[4] && collision.centFT0C() <= kCent[5] && q2 > kSeparator[8] && q2 <= kSeparator[9]) { - histosQA.fill(HIST("histCosDetV2_4050Mid"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[4] && collision.centFT0C() <= kCent[5] && q2 > kSeparator[9]) { - histosQA.fill(HIST("histCosDetV2_4050Right"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[5] && collision.centFT0C() <= kCent[6] && q2 < kSeparator[10]) { - histosQA.fill(HIST("histCosDetV2_5060Left"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[5] && collision.centFT0C() <= kCent[6] && q2 > kSeparator[10] && q2 <= kSeparator[11]) { - histosQA.fill(HIST("histCosDetV2_5060Mid"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[5] && collision.centFT0C() <= kCent[6] && q2 > kSeparator[11]) { - histosQA.fill(HIST("histCosDetV2_5060Right"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[6] && collision.centFT0C() <= kCent[7] && q2 < kSeparator[12]) { - histosQA.fill(HIST("histCosDetV2_6070Left"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[6] && collision.centFT0C() <= kCent[7] && q2 > kSeparator[12] && q2 <= kSeparator[13]) { - histosQA.fill(HIST("histCosDetV2_6070Mid"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); - } - if (collision.centFT0C() > kCent[6] && collision.centFT0C() <= kCent[7] && q2 > kSeparator[13]) { - histosQA.fill(HIST("histCosDetV2_6070Right"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); + if (aLambdaTag) { + protonVec = ROOT::Math::PxPyPzMVector(v0.pxneg(), v0.pyneg(), v0.pzneg(), massPr); + pionVec = ROOT::Math::PxPyPzMVector(v0.pxpos(), v0.pypos(), v0.pzpos(), massPi); + } + LambdaVec = protonVec + pionVec; + LambdaVec.SetM(massLambda); + + ROOT::Math::Boost boost{LambdaVec.BoostToCM()}; + protonBoostedVec = boost(protonVec); + + angle = protonBoostedVec.Pz() / protonBoostedVec.P(); + psi = std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) / static_cast(nmode); + relphi = TVector2::Phi_0_2pi(static_cast(nmode) * (LambdaVec.Phi() - psi)); + + if (cfgShiftCorr) { + auto deltapsiFT0C = 0.0; + auto deltapsiFT0A = 0.0; + auto deltapsiFV0A = 0.0; + + auto psidefFT0C = std::atan2(collision.qvecIm()[qvecDetInd], collision.qvecRe()[qvecDetInd]) / static_cast(nmode); + auto psidefFT0A = std::atan2(collision.qvecIm()[qvecRefAInd], collision.qvecRe()[qvecRefAInd]) / static_cast(nmode); + auto psidefFV0A = std::atan2(collision.qvecIm()[qvecRefBInd], collision.qvecRe()[qvecRefBInd]) / static_cast(nmode); + for (int ishift = 1; ishift <= kShiftLevel; ishift++) { + auto coeffshiftxFT0C = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(centrality, 0.5, ishift - 0.5)); + auto coeffshiftyFT0C = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(centrality, 1.5, ishift - 0.5)); + auto coeffshiftxFT0A = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(centrality, 2.5, ishift - 0.5)); + auto coeffshiftyFT0A = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(centrality, 3.5, ishift - 0.5)); + auto coeffshiftxFV0A = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(centrality, 4.5, ishift - 0.5)); + auto coeffshiftyFV0A = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(centrality, 5.5, ishift - 0.5)); + + deltapsiFT0C += ((1 / (1.0 * ishift)) * (-coeffshiftxFT0C * std::cos(ishift * static_cast(nmode) * psidefFT0C) + coeffshiftyFT0C * std::sin(ishift * static_cast(nmode) * psidefFT0C))); + deltapsiFT0A += ((1 / (1.0 * ishift)) * (-coeffshiftxFT0A * std::cos(ishift * static_cast(nmode) * psidefFT0A) + coeffshiftyFT0A * std::sin(ishift * static_cast(nmode) * psidefFT0A))); + deltapsiFV0A += ((1 / (1.0 * ishift)) * (-coeffshiftxFV0A * std::cos(ishift * static_cast(nmode) * psidefFV0A) + coeffshiftyFV0A * std::sin(ishift * static_cast(nmode) * psidefFV0A))); } - if (collision.centFT0C() > kCent[7] && collision.centFT0C() <= kCent[8] && q2 < kSeparator[14]) { - histosQA.fill(HIST("histCosDetV2_7080Left"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); + psi += deltapsiFT0C; + relphi = TVector2::Phi_0_2pi(static_cast(nmode) * (LambdaVec.Phi() - psidefFT0C - deltapsiFT0C)); + } + + if (cfgPhiDepStudy && cfgPhiDepSig * std::abs(std::sin(relphi)) > gRandom->Uniform(0, 1)) { + continue; + } + + if (lambdaTag) { + histos.fill(HIST("QA/ptspec_l"), v0.mLambda(), v0.pt(), centrality); + if (cfgEffCor) { + histos.fill(HIST("QA/ptspecCor_l"), v0.mLambda(), v0.pt(), centrality, + 1.0 / effMap->GetBinContent(effMap->GetXaxis()->FindBin(v0.pt()), effMap->GetYaxis()->FindBin(centrality))); } - if (collision.centFT0C() > kCent[7] && collision.centFT0C() <= kCent[8] && q2 > kSeparator[14] && q2 <= kSeparator[15]) { - histosQA.fill(HIST("histCosDetV2_7080Mid"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); + } + if (aLambdaTag) { + histos.fill(HIST("QA/ptspec_al"), v0.mAntiLambda(), v0.pt(), centrality); + if (cfgEffCor) { + histos.fill(HIST("QA/ptspecCor_al"), v0.mAntiLambda(), v0.pt(), centrality, + 1.0 / effMap->GetBinContent(effMap->GetXaxis()->FindBin(v0.pt()), effMap->GetYaxis()->FindBin(centrality))); } - if (collision.centFT0C() > kCent[7] && collision.centFT0C() <= kCent[8] && q2 > kSeparator[15]) { - histosQA.fill(HIST("histCosDetV2_7080Right"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); + } + double weight = 1.0; + weight *= cfgEffCor ? 1.0 / effMap->GetBinContent(effMap->GetXaxis()->FindBin(v0.pt()), effMap->GetYaxis()->FindBin(centrality)) : 1.; + weight *= cfgAccCor ? 1.0 / accMap->GetBinContent(accMap->GetXaxis()->FindBin(v0.pt()), accMap->GetYaxis()->FindBin(v0.yLambda())) : 1.; + + double qvecMag = 1.0; + if (cfgUSESP) + qvecMag *= std::sqrt(std::pow(collision.qvecIm()[3 + (nmode - 2) * 28], 2) + std::pow(collision.qvecRe()[3 + (nmode - 2) * 28], 2)); + + if (nmode == kCorrLevel[0]) { //////////// + if (lambdaTag) { + histos.fill(HIST("psi2/h_lambda_cos"), v0.mLambda(), v0.pt(), angle * weight, centrality, relphi); + histos.fill(HIST("psi2/h_lambda_cos2"), v0.mLambda(), v0.pt(), angle * angle, centrality, relphi); + histos.fill(HIST("psi2/h_lambda_cossin"), v0.mLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality); + histos.fill(HIST("psi2/h_lambda_vncos"), v0.mLambda(), v0.pt(), qvecMag * std::cos(relphi) * weight, centrality); + histos.fill(HIST("psi2/h_lambda_vnsin"), v0.mLambda(), v0.pt(), std::sin(relphi), centrality); + + if (cfgRapidityDep) { + histos.fill(HIST("psi2/h_lambda_cos2_rap"), v0.mLambda(), v0.pt(), angle * angle, centrality, v0.yLambda(), weight); + } + + if (cfgAccAzimuth) { + histos.fill(HIST("psi2/h_lambda_coscos"), v0.mLambda(), v0.pt(), angle * std::cos(relphi), centrality, weight); + } + + if (cfgCalcCum) { + histos.fill(HIST("psi2/QA/cosTheta_l"), v0.mLambda(), v0.pt(), angle, centrality); + histos.fill(HIST("psi2/QA/cosPsi_l"), v0.mLambda(), v0.pt(), std::cos(psi * 2.0), centrality); + histos.fill(HIST("psi2/QA/cosPhi_l"), v0.mLambda(), v0.pt(), std::cos(v0.phi() * 2.0), centrality); + + histos.fill(HIST("psi2/QA/sinPsi_l"), v0.mLambda(), v0.pt(), std::sin(psi * 2.0), centrality); + histos.fill(HIST("psi2/QA/sinPhi_l"), v0.mLambda(), v0.pt(), std::sin(v0.phi() * 2.0), centrality); + + histos.fill(HIST("psi2/QA/cosTheta_cosPhi_l"), v0.mLambda(), v0.pt(), angle * std::cos(v0.phi() * 2.0), centrality); + histos.fill(HIST("psi2/QA/cosTheta_cosPsi_l"), v0.mLambda(), v0.pt(), angle * std::cos(psi * 2.0), centrality); + + histos.fill(HIST("psi2/QA/cosTheta_sinPhi_l"), v0.mLambda(), v0.pt(), angle * std::sin(v0.phi() * 2.0), centrality); + histos.fill(HIST("psi2/QA/cosTheta_sinPsi_l"), v0.mLambda(), v0.pt(), angle * std::sin(psi * 2.0), centrality); + + histos.fill(HIST("psi2/QA/cosPhi_sinPsi_l"), v0.mLambda(), v0.pt(), std::cos(v0.phi() * 2.0) * std::sin(psi * 2.0), centrality); + histos.fill(HIST("psi2/QA/sinPhi_cosPsi_l"), v0.mLambda(), v0.pt(), std::sin(v0.phi() * 2.0) * std::cos(psi * 2.0), centrality); + } + if (cfgCalcCum1) { + histos.fill(HIST("psi2/QA/cosTheta_l"), v0.mLambda(), v0.pt(), angle, centrality); + histos.fill(HIST("psi2/QA/cosPsi_l"), v0.mLambda(), v0.pt(), std::cos(psi * 2.0), centrality); + histos.fill(HIST("psi2/QA/cosPhi_l"), v0.mLambda(), v0.pt(), std::cos(v0.phi() * 2.0), centrality); + + histos.fill(HIST("psi2/QA/cosPhi_cosPsi_l"), v0.mLambda(), v0.pt(), std::cos(v0.phi() * 2.0) * std::cos(psi * 2.0), centrality); + histos.fill(HIST("psi2/QA/cosTheta_cosPhi_l"), v0.mLambda(), v0.pt(), angle * std::cos(v0.phi() * 2.0), centrality); + histos.fill(HIST("psi2/QA/cosTheta_cosPsi_l"), v0.mLambda(), v0.pt(), angle * std::cos(psi * 2.0), centrality); + + histos.fill(HIST("psi2/QA/sinPhi_sinPsi_l"), v0.mLambda(), v0.pt(), std::sin(v0.phi() * 2.0) * std::sin(psi * 2.0), centrality); + histos.fill(HIST("psi2/QA/cosTheta_sinPhi_l"), v0.mLambda(), v0.pt(), angle * std::sin(v0.phi() * 2.0), centrality); + histos.fill(HIST("psi2/QA/cosTheta_sinPsi_l"), v0.mLambda(), v0.pt(), angle * std::sin(psi * 2.0), centrality); + + histos.fill(HIST("psi2/QA/sinPsi_l"), v0.mLambda(), v0.pt(), std::sin(psi * 2.0), centrality); + histos.fill(HIST("psi2/QA/sinPhi_l"), v0.mLambda(), v0.pt(), std::sin(v0.phi() * 2.0), centrality); + } } - if (collision.centFT0C() > kCent[8] && collision.centFT0C() <= kCent[9] && q2 < kSeparator[16]) { - histosQA.fill(HIST("histCosDetV2_8090Left"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); + if (aLambdaTag) { + histos.fill(HIST("psi2/h_alambda_cos"), v0.mAntiLambda(), v0.pt(), angle * weight, centrality, relphi); + histos.fill(HIST("psi2/h_alambda_cos2"), v0.mAntiLambda(), v0.pt(), angle * angle, centrality, relphi); + histos.fill(HIST("psi2/h_alambda_cossin"), v0.mAntiLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality); + histos.fill(HIST("psi2/h_alambda_vncos"), v0.mAntiLambda(), v0.pt(), qvecMag * std::cos(relphi) * weight, centrality); + histos.fill(HIST("psi2/h_alambda_vnsin"), v0.mAntiLambda(), v0.pt(), std::sin(relphi), centrality); + + if (cfgRapidityDep) { + histos.fill(HIST("psi2/h_alambda_cos2_rap"), v0.mAntiLambda(), v0.pt(), angle * angle, centrality, v0.yLambda(), weight); + } + + if (cfgAccAzimuth) { + histos.fill(HIST("psi2/h_alambda_coscos"), v0.mAntiLambda(), v0.pt(), angle * std::cos(relphi), centrality, weight); + } + + if (cfgCalcCum) { + histos.fill(HIST("psi2/QA/cosTheta_al"), v0.mAntiLambda(), v0.pt(), angle, centrality); + histos.fill(HIST("psi2/QA/cosPsi_al"), v0.mAntiLambda(), v0.pt(), std::cos(psi * 2.0), centrality); + histos.fill(HIST("psi2/QA/cosPhi_al"), v0.mAntiLambda(), v0.pt(), std::cos(v0.phi() * 2.0), centrality); + + histos.fill(HIST("psi2/QA/sinPsi_al"), v0.mAntiLambda(), v0.pt(), std::sin(psi * 2.0), centrality); + histos.fill(HIST("psi2/QA/sinPhi_al"), v0.mAntiLambda(), v0.pt(), std::sin(v0.phi() * 2.0), centrality); + + histos.fill(HIST("psi2/QA/cosTheta_cosPhi_al"), v0.mAntiLambda(), v0.pt(), angle * std::cos(v0.phi() * 2.0), centrality); + histos.fill(HIST("psi2/QA/cosTheta_cosPsi_al"), v0.mAntiLambda(), v0.pt(), angle * std::cos(psi * 2.0), centrality); + + histos.fill(HIST("psi2/QA/cosTheta_sinPhi_al"), v0.mAntiLambda(), v0.pt(), angle * std::sin(v0.phi() * 2.0), centrality); + histos.fill(HIST("psi2/QA/cosTheta_sinPsi_al"), v0.mAntiLambda(), v0.pt(), angle * std::sin(psi * 2.0), centrality); + + histos.fill(HIST("psi2/QA/cosPhi_sinPsi_al"), v0.mAntiLambda(), v0.pt(), std::cos(v0.phi() * 2.0) * std::sin(psi * 2.0), centrality); + histos.fill(HIST("psi2/QA/sinPhi_cosPsi_al"), v0.mAntiLambda(), v0.pt(), std::sin(v0.phi() * 2.0) * std::cos(psi * 2.0), centrality); + } + if (cfgCalcCum1) { + histos.fill(HIST("psi2/QA/cosTheta_al"), v0.mAntiLambda(), v0.pt(), angle, centrality); + histos.fill(HIST("psi2/QA/cosPsi_al"), v0.mAntiLambda(), v0.pt(), std::cos(psi * 2.0), centrality); + histos.fill(HIST("psi2/QA/cosPhi_al"), v0.mAntiLambda(), v0.pt(), std::cos(v0.phi() * 2.0), centrality); + + histos.fill(HIST("psi2/QA/cosPhi_cosPsi_al"), v0.mAntiLambda(), v0.pt(), std::cos(v0.phi() * 2.0) * std::cos(psi * 2.0), centrality); + histos.fill(HIST("psi2/QA/cosTheta_cosPhi_al"), v0.mAntiLambda(), v0.pt(), angle * std::cos(v0.phi() * 2.0), centrality); + histos.fill(HIST("psi2/QA/cosTheta_cosPsi_al"), v0.mAntiLambda(), v0.pt(), angle * std::cos(psi * 2.0), centrality); + + histos.fill(HIST("psi2/QA/sinPhi_sinPsi_al"), v0.mAntiLambda(), v0.pt(), std::sin(v0.phi() * 2.0) * std::sin(psi * 2.0), centrality); + histos.fill(HIST("psi2/QA/cosTheta_sinPhi_al"), v0.mAntiLambda(), v0.pt(), angle * std::sin(v0.phi() * 2.0), centrality); + histos.fill(HIST("psi2/QA/cosTheta_sinPsi_al"), v0.mAntiLambda(), v0.pt(), angle * std::sin(psi * 2.0), centrality); + + histos.fill(HIST("psi2/QA/sinPsi_al"), v0.mAntiLambda(), v0.pt(), std::sin(psi * 2.0), centrality); + histos.fill(HIST("psi2/QA/sinPhi_al"), v0.mAntiLambda(), v0.pt(), std::sin(v0.phi() * 2.0), centrality); + } } - if (collision.centFT0C() > kCent[8] && collision.centFT0C() <= kCent[9] && q2 > kSeparator[16] && q2 <= kSeparator[17]) { - histosQA.fill(HIST("histCosDetV2_8090Mid"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); + } else if (nmode == kCorrLevel[1]) { + if (lambdaTag) { + histos.fill(HIST("psi3/h_lambda_cos"), v0.mLambda(), v0.pt(), angle * weight, centrality, relphi); + histos.fill(HIST("psi3/h_lambda_cos2"), v0.mLambda(), v0.pt(), angle * angle, centrality, relphi); + histos.fill(HIST("psi3/h_lambda_cossin"), v0.mLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality); + histos.fill(HIST("psi3/h_lambda_vncos"), v0.mLambda(), v0.pt(), qvecMag * std::cos(relphi) * weight, centrality); + histos.fill(HIST("psi3/h_lambda_vnsin"), v0.mLambda(), v0.pt(), std::sin(relphi), centrality); + + if (cfgRapidityDep) { + histos.fill(HIST("psi3/h_lambda_cos2_rap"), v0.mLambda(), v0.pt(), angle * angle, centrality, v0.yLambda(), weight); + } + + if (cfgAccAzimuth) { + histos.fill(HIST("psi3/h_lambda_coscos"), v0.mLambda(), v0.pt(), angle * std::cos(relphi), centrality, weight); + } } - if (collision.centFT0C() > kCent[8] && collision.centFT0C() <= kCent[9] && q2 > kSeparator[17]) { - histosQA.fill(HIST("histCosDetV2_8090Right"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); + if (aLambdaTag) { + histos.fill(HIST("psi3/h_alambda_cos"), v0.mAntiLambda(), v0.pt(), angle * weight, centrality, relphi); + histos.fill(HIST("psi3/h_alambda_cos2"), v0.mAntiLambda(), v0.pt(), angle * angle, centrality, relphi, weight); + histos.fill(HIST("psi3/h_alambda_cossin"), v0.mAntiLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality); + histos.fill(HIST("psi3/h_alambda_vncos"), v0.mAntiLambda(), v0.pt(), qvecMag * std::cos(relphi) * weight, centrality); + histos.fill(HIST("psi3/h_alambda_vnsin"), v0.mAntiLambda(), v0.pt(), std::sin(relphi), centrality); + + if (cfgRapidityDep) { + histos.fill(HIST("psi3/h_alambda_cos2_rap"), v0.mAntiLambda(), v0.pt(), angle * angle, centrality, v0.yLambda(), weight); + } + + if (cfgAccAzimuth) { + histos.fill(HIST("psi3/h_alambda_coscos"), v0.mAntiLambda(), v0.pt(), angle * std::cos(relphi), centrality, weight); + } } - if (collision.centFT0C() > kCent[9] && collision.centFT0C() <= kCent[10] && q2 < kSeparator[18]) { - histosQA.fill(HIST("histCosDetV2_9010Left"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); + } else if (nmode == kCorrLevel[2]) { + if (lambdaTag) { + histos.fill(HIST("psi4/h_lambda_cos"), v0.mLambda(), v0.pt(), angle * weight, centrality, relphi); + histos.fill(HIST("psi4/h_lambda_cos2"), v0.mLambda(), v0.pt(), angle * angle, centrality, relphi); + histos.fill(HIST("psi4/h_lambda_cossin"), v0.mLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality); + histos.fill(HIST("psi4/h_lambda_vncos"), v0.mLambda(), v0.pt(), qvecMag * std::cos(relphi) * weight, centrality); + histos.fill(HIST("psi4/h_lambda_vnsin"), v0.mLambda(), v0.pt(), std::sin(relphi), centrality); + + if (cfgRapidityDep) { + histos.fill(HIST("psi4/h_lambda_cos2_rap"), v0.mLambda(), v0.pt(), angle * angle, centrality, v0.yLambda(), weight); + } + + if (cfgAccAzimuth) { + histos.fill(HIST("psi4/h_lambda_coscos"), v0.mLambda(), v0.pt(), angle * std::cos(relphi), centrality, weight); + } } - if (collision.centFT0C() > kCent[9] && collision.centFT0C() <= kCent[10] && q2 > kSeparator[18] && q2 <= kSeparator[19]) { - histosQA.fill(HIST("histCosDetV2_9010Mid"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); + if (aLambdaTag) { + histos.fill(HIST("psi4/h_alambda_cos"), v0.mAntiLambda(), v0.pt(), angle * weight, centrality, relphi); + histos.fill(HIST("psi4/h_alambda_cos2"), v0.mAntiLambda(), v0.pt(), angle * angle, centrality, relphi); + histos.fill(HIST("psi4/h_alambda_cossin"), v0.mAntiLambda(), v0.pt(), angle * std::sin(relphi) * weight, centrality); + histos.fill(HIST("psi4/h_alambda_vncos"), v0.mAntiLambda(), v0.pt(), qvecMag * std::cos(relphi) * weight, centrality); + histos.fill(HIST("psi4/h_alambda_vnsin"), v0.mAntiLambda(), v0.pt(), std::sin(relphi), centrality); + + if (cfgRapidityDep) { + histos.fill(HIST("psi4/h_alambda_cos2_rap"), v0.mAntiLambda(), v0.pt(), angle * angle, centrality, v0.yLambda(), weight); + } + + if (cfgAccAzimuth) { + histos.fill(HIST("psi4/h_alambda_coscos"), v0.mAntiLambda(), v0.pt(), angle * std::cos(relphi), centrality, weight); + } } - if (collision.centFT0C() > kCent[9] && collision.centFT0C() <= kCent[10] && q2 > kSeparator[19]) { - histosQA.fill(HIST("histCosDetV2_9010Right"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], collision.qvecFT0CImVec()[0], nmode), helperEP.GetEventPlane(collision.qvecTPCposReVec()[0], collision.qvecTPCposImVec()[0], nmode), nmode), trk.pt(), - std::cos(static_cast(nmode) * (trk.phi() - - helperEP.GetEventPlane(collision.qvecFT0CReVec()[0], - collision.qvecFT0CImVec()[0], - nmode)))); + } ////////// FIXME: not possible to get histograms using nmode + } + } + + void processData(EventCandidates::iterator const& collision, + TrackCandidates const& /*tracks*/, aod::V0Datas const& V0s, + aod::BCsWithTimestamps const&) + { + if (cfgCentEst == kCorrLevel[3]) { + centrality = collision.centFT0C(); + } else if (cfgCentEst == kCorrLevel[0]) { + centrality = collision.centFT0M(); + } + if (!eventSelected(collision)) { + return; + } + histos.fill(HIST("QA/CentDist"), centrality, 1.0); + histos.fill(HIST("QA/PVzDist"), collision.posZ(), 1.0); + + if (cfgShiftCorr) { + auto bc = collision.bc_as(); + currentRunNumber = bc.runNumber(); + if (currentRunNumber != lastRunNumber) { + shiftprofile.clear(); + for (int i = 2; i < cfgnMods + 2; i++) { + fullCCDBShiftCorrPath = cfgShiftPath; + fullCCDBShiftCorrPath += "/v"; + fullCCDBShiftCorrPath += std::to_string(i); + auto objshift = ccdb->getForTimeStamp(fullCCDBShiftCorrPath, bc.timestamp()); + shiftprofile.push_back(objshift); } + lastRunNumber = currentRunNumber; } } + auto bc = collision.bc_as(); + if (cfgEffCor) { + effMap = ccdb->getForTimeStamp(cfgEffCorPath.value, bc.timestamp()); + } + if (cfgAccCor) { + accMap = ccdb->getForTimeStamp(cfgAccCorPath.value, bc.timestamp()); + } + for (int i = 2; i < cfgnMods + 2; i++) { + if (cfgShiftCorrDef) { + fillShiftCorrection(collision, i); + } + if (cfgQAv0) { + fillEPQA(collision, i); + } + fillHistograms(collision, V0s, i); + } // FIXME: need to fill different histograms for different harmonic } + PROCESS_SWITCH(FlowEseTask, processData, "Process Event for data", true); - void process(MyCollisions::iterator const& collision, MyTracks const& tracks) + using RecoTracks = soa::Join; + void processMcItsTpc(aod::McCollision const& mcCollision, soa::Join const& mcParticles, RecoTracks const&) { - if (!selectEvent(collision)) { - return; + float imp = mcCollision.impactParameter(); + float evPhi = mcCollision.eventPlaneAngle() / 2.0; + float centclass = -999; + if (imp >= kCentBoundaries[0] && imp < kCentBoundaries[1]) { + centclass = kCentValues[0]; + } + if (imp >= kCentBoundaries[1] && imp < kCentBoundaries[2]) { + centclass = kCentValues[1]; + } + if (imp >= kCentBoundaries[2] && imp < kCentBoundaries[3]) { + centclass = kCentValues[2]; + } + if (imp >= kCentBoundaries[3] && imp < kCentBoundaries[4]) { + centclass = kCentValues[3]; + } + if (imp >= kCentBoundaries[4] && imp < kCentBoundaries[5]) { + centclass = kCentValues[4]; + } + if (imp >= kCentBoundaries[5] && imp < kCentBoundaries[6]) { + centclass = kCentValues[5]; + } + if (imp >= kCentBoundaries[6] && imp < kCentBoundaries[7]) { + centclass = kCentValues[6]; + } + if (imp >= kCentBoundaries[7] && imp < kCentBoundaries[8]) { + centclass = kCentValues[7]; } - for (std::size_t i = 0; i < cfgNmods->size(); i++) { - fillHistosQvec(collision, cfgNmods->at(i)); - fillHistosFlow(collision, tracks, cfgNmods->at(i)); + if (imp >= kCentBoundaries[8] && imp < kCentBoundaries[9]) { + centclass = kCentValues[8]; + } + + int nCh = 0; + + if (centclass > 0 && centclass < kCentUpperLimit) { + // event within range + histos.fill(HIST("hImpactParameter"), imp); + histos.fill(HIST("hEventPlaneAngle"), evPhi); + for (auto const& mcParticle : mcParticles) { + float deltaPhi = mcParticle.phi() - mcCollision.eventPlaneAngle(); + // focus on bulk: e, mu, pi, k, p + int pdgCode = std::abs(mcParticle.pdgCode()); + if (pdgCode != kLambdaId) + continue; + if (!mcParticle.isPhysicalPrimary()) + continue; + if (std::abs(mcParticle.eta()) > kEtaAcceptance) // main acceptance + continue; + histos.fill(HIST("hSparseMCGenWeight"), centclass, RecoDecay::constrainAngle(deltaPhi), std::pow(std::cos(2.0 * RecoDecay::constrainAngle(deltaPhi)), 2.0), mcParticle.pt(), mcParticle.eta()); + nCh++; + bool validGlobal = false; + bool validAny = false; + if (mcParticle.has_tracks()) { + auto const& tracks = mcParticle.tracks_as(); + for (auto const& track : tracks) { + if (track.hasTPC() && track.hasITS()) { + validGlobal = true; + } + if (track.hasTPC() || track.hasITS()) { + validAny = true; + } + } + } + // if valid global, fill + if (validGlobal) { + histos.fill(HIST("hSparseMCRecWeight"), centclass, RecoDecay::constrainAngle(deltaPhi), std::pow(std::cos(2.0 * RecoDecay::constrainAngle(deltaPhi)), 2.0), mcParticle.pt(), mcParticle.eta()); + } + if (validAny) { + histos.fill(HIST("hSparseMCRecAllTrackWeight"), centclass, RecoDecay::constrainAngle(deltaPhi), std::pow(std::cos(2.0 * RecoDecay::constrainAngle(deltaPhi)), 2.0), mcParticle.pt(), mcParticle.eta()); + histos.fill(HIST("hEventPlaneAngleRec"), RecoDecay::constrainAngle(deltaPhi)); + } + // if any track present, fill + } } + histos.fill(HIST("hNchVsImpactParameter"), imp, nCh); } + PROCESS_SWITCH(FlowEseTask, processMcItsTpc, "Process MC for ITSTPC", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/Flow/Tasks/flowGfwEse.cxx b/PWGCF/Flow/Tasks/flowGfwEse.cxx new file mode 100644 index 00000000000..fc4e06240f1 --- /dev/null +++ b/PWGCF/Flow/Tasks/flowGfwEse.cxx @@ -0,0 +1,1200 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file flowGfwEse.cxx +/// \brief Dedicated GFW task to analyse angular correlations using ESE primarily in light ions +/// \author Emil Gorm Nielsen, NBI, emil.gorm.nielsen@cern.ch, Joachim C. K. B. Hansen, Lund University, joachim.hansen@cern.ch + +#include "FlowContainer.h" +#include "FlowPtContainer.h" +#include "GFW.h" +#include "GFWConfig.h" +#include "GFWCumulant.h" +#include "GFWPowerArray.h" +#include "GFWWeights.h" +#include "GFWWeightsList.h" + +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EseTable.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/Qvectors.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; + +#define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; + +namespace o2::analysis::gfwflowese +{ +std::vector ptbinning = {0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}; +float ptpoilow = 0.2, ptpoiup = 10.0; +float ptreflow = 0.2, ptrefup = 3.0; +float ptlow = 0.2, ptup = 10.0; +int etabins = 16; +float etalow = -0.8, etaup = 0.8; +int vtxZbins = 40; +float vtxZlow = -10.0, vtxZup = 10.0; +int phibins = 72; +float philow = 0.0; +float phiup = o2::constants::math::TwoPI; +int nchbins = 300; +float nchlow = 0; +float nchup = 3000; +std::vector centbinning(90); +int nBootstrap = 10; +GFWRegions regions; +GFWCorrConfigs configs; +std::vector multGlobalCorrCutPars; +std::vector multPVCorrCutPars; +std::vector multGlobalPVCorrCutPars; +std::vector multGlobalV0ACutPars; +std::vector multGlobalT0ACutPars; +std::vector firstRunsOfFill; +} // namespace o2::analysis::gfwflowese + +struct FlowGfwEse { + + O2_DEFINE_CONFIGURABLE(cfgNbootstrap, int, 10, "Number of subsamples") + O2_DEFINE_CONFIGURABLE(cfgMpar, int, 4, "Highest order of pt-pt correlations") + O2_DEFINE_CONFIGURABLE(cfgCentEstimator, int, 0, "0:FT0C; 1:FT0CVariant1; 2:FT0M; 3:FV0A, 4:NTPV, 5:NGlobals, 6:MFT") + O2_DEFINE_CONFIGURABLE(cfgUseNch, bool, false, "Do correlations as function of Nch") + O2_DEFINE_CONFIGURABLE(cfgFillWeights, bool, false, "Fill NUA weights") + O2_DEFINE_CONFIGURABLE(cfgRunByRun, bool, false, "Fill histograms on a run-by-run basis") + O2_DEFINE_CONFIGURABLE(cfgFillFlowRunByRun, bool, false, "Fill flow profile run-by-run (only for v22)") + O2_DEFINE_CONFIGURABLE(cfgTimeDependent, bool, false, "Fill output as function of time (for contamination studies)") + O2_DEFINE_CONFIGURABLE(cfgFirstRunsOfFill, std::vector, {}, "First runs of a fill for time dependent analysis") + O2_DEFINE_CONFIGURABLE(cfgFillQA, bool, false, "Fill QA histograms") + O2_DEFINE_CONFIGURABLE(cfgUseAdditionalEventCut, bool, false, "Use additional event cut on mult correlations") + O2_DEFINE_CONFIGURABLE(cfgUseCentralMoments, bool, true, "Use central moments in vn-pt calculations") + O2_DEFINE_CONFIGURABLE(cfgEfficiency, std::string, "", "CCDB path to efficiency object") + O2_DEFINE_CONFIGURABLE(cfgAcceptance, std::string, "", "CCDB path to acceptance object") + O2_DEFINE_CONFIGURABLE(cfgDCAxyNSigma, float, 7, "Cut on number of sigma deviations from expected DCA in the transverse direction"); + O2_DEFINE_CONFIGURABLE(cfgDCAxy, std::string, "(0.0026+0.005/(x^1.01))", "Functional form of pt-dependent DCAxy cut"); + O2_DEFINE_CONFIGURABLE(cfgDCAz, float, 2, "Cut on DCA in the longitudinal direction (cm)"); + O2_DEFINE_CONFIGURABLE(cfgNTPCCls, float, 50, "Cut on number of TPC clusters found"); + O2_DEFINE_CONFIGURABLE(cfgNTPCXrows, float, 70, "Cut on number of TPC crossed rows"); + O2_DEFINE_CONFIGURABLE(cfgMinNITSCls, float, 5, "Cut on minimum number of ITS clusters found"); + O2_DEFINE_CONFIGURABLE(cfgChi2PrITSCls, float, 36, "Cut on chi^2 per ITS clusters found"); + O2_DEFINE_CONFIGURABLE(cfgChi2PrTPCCls, float, 2.5, "Cut on chi^2 per TPC clusters found"); + O2_DEFINE_CONFIGURABLE(cfgPtmin, float, 0.2, "minimum pt (GeV/c)"); + O2_DEFINE_CONFIGURABLE(cfgPtmax, float, 10, "maximum pt (GeV/c)"); + O2_DEFINE_CONFIGURABLE(cfgEta, float, 0.8, "eta cut"); + O2_DEFINE_CONFIGURABLE(cfgEtaPtPt, float, 0.4, "eta cut for pt-pt correlations"); + O2_DEFINE_CONFIGURABLE(cfgVtxZ, float, 10, "vertex cut (cm)"); + O2_DEFINE_CONFIGURABLE(cfgOccupancySelection, int, 2000, "Max occupancy selection, -999 to disable"); + O2_DEFINE_CONFIGURABLE(cfgNoSameBunchPileupCut, bool, true, "kNoSameBunchPileupCut"); + O2_DEFINE_CONFIGURABLE(cfgIsGoodZvtxFT0vsPV, bool, true, "kIsGoodZvtxFT0vsPV"); + O2_DEFINE_CONFIGURABLE(cfgIsGoodITSLayersAll, bool, true, "kIsGoodITSLayersAll"); + O2_DEFINE_CONFIGURABLE(cfgNoCollInTimeRangeStandard, bool, true, "kNoCollInTimeRangeStandard"); + O2_DEFINE_CONFIGURABLE(cfgDoOccupancySel, bool, true, "Bool for event selection on detector occupancy"); + O2_DEFINE_CONFIGURABLE(cfgMultCut, bool, true, "Use additional event cut on mult correlations"); + O2_DEFINE_CONFIGURABLE(cfgTVXinTRD, bool, true, "Use kTVXinTRD (reject TRD triggered events)"); + O2_DEFINE_CONFIGURABLE(cfgIsVertexITSTPC, bool, true, "Selects collisions with at least one ITS-TPC track"); + O2_DEFINE_CONFIGURABLE(cfgMagField, float, 99999, "Configurable magnetic field; default CCDB will be queried"); + O2_DEFINE_CONFIGURABLE(cfgFixedMultMin, int, 1, "Minimum for fixed nch range"); + O2_DEFINE_CONFIGURABLE(cfgFixedMultMax, int, 3000, "Maximum for fixed nch range"); + O2_DEFINE_CONFIGURABLE(cfgUseMultiplicityFlowWeights, bool, true, "Enable or disable the use of multiplicity-based event weighting"); + O2_DEFINE_CONFIGURABLE(cfgConsistentEventFlag, int, 0, "Flag to select consistent events - 0: off, 1: v2{2} gap calculable, 2: v2{4} full calculable, 4: v2{4} gap calculable, 8: v2{4} 3sub calculable"); + O2_DEFINE_CONFIGURABLE(cfgUseDensityDependentCorrection, bool, false, "Use density dependent efficiency correction based on Run 2 measurements"); + Configurable> cfgTrackDensityP0{"cfgTrackDensityP0", std::vector{0.7217476707, 0.7384792571, 0.7542625668, 0.7640680200, 0.7701951667, 0.7755299053, 0.7805901710, 0.7849446786, 0.7957356586, 0.8113039262, 0.8211968966, 0.8280558878, 0.8329342135}, "parameter 0 for track density efficiency correction"}; + Configurable> cfgTrackDensityP1{"cfgTrackDensityP1", std::vector{-2.169488e-05, -2.191913e-05, -2.295484e-05, -2.556538e-05, -2.754463e-05, -2.816832e-05, -2.846502e-05, -2.843857e-05, -2.705974e-05, -2.477018e-05, -2.321730e-05, -2.203315e-05, -2.109474e-05}, "parameter 1 for track density efficiency correction"}; + Configurable> cfgMultGlobalCutPars{"cfgMultGlobalCutPars", std::vector{2272.16, -76.6932, 1.01204, -0.00631545, 1.59868e-05, 136.336, -4.97006, 0.121199, -0.0015921, 7.66197e-06}, "Global vs FT0C multiplicity cut parameter values"}; + Configurable> cfgMultPVCutPars{"cfgMultPVCutPars", std::vector{3074.43, -106.192, 1.46176, -0.00968364, 2.61923e-05, 182.128, -7.43492, 0.193901, -0.00256715, 1.22594e-05}, "PV vs FT0C multiplicity cut parameter values"}; + Configurable> cfgMultGlobalPVCutPars{"cfgMultGlobalPVCutPars", std::vector{-0.223013, 0.715849, 0.664242, 0.0829653, -0.000503733, 1.21185e-06}, "Global vs PV multiplicity cut parameter values"}; + O2_DEFINE_CONFIGURABLE(cfgMultCorrHighCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x + 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultCorrLowCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x - 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultGlobalPVCorrCutFunction, std::string, "[0] + [1]*x + 3*([2] + [3]*x + [4]*x*x + [5]*x*x*x)", "Functional for global vs pv multiplicity correlation cut"); + struct : ConfigurableGroup { + O2_DEFINE_CONFIGURABLE(cfgMultGlobalASideCorrCutFunction, std::string, "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x + [10]*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", "Functional for global vs V0A multiplicity low correlation cut"); + Configurable> cfgMultGlobalV0ACutPars{"cfgMultGlobalV0ACutPars", std::vector{567.785, 172.715, 0.77888, -0.00693466, 1.40564e-05, 679.853, 66.8068, -0.444332, 0.00115002, -4.92064e-07}, "Global vs FV0A multiplicity cut parameter values"}; + Configurable> cfgMultGlobalT0ACutPars{"cfgMultGlobalT0ACutPars", std::vector{241.618, 61.8402, 0.348049, -0.00306078, 6.20357e-06, 315.235, 29.1491, -0.188639, 0.00044528, -9.08912e-08}, "Global vs FT0A multiplicity cut parameter values"}; + O2_DEFINE_CONFIGURABLE(cfgGlobalV0ALowSigma, float, -3, "Number of sigma deviations below expected value in global vs V0A correlation"); + O2_DEFINE_CONFIGURABLE(cfgGlobalV0AHighSigma, float, 4, "Number of sigma deviations above expected value in global vs V0A correlation"); + O2_DEFINE_CONFIGURABLE(cfgGlobalT0ALowSigma, float, -3., "Number of sigma deviations below expected value in global vs T0A correlation"); + O2_DEFINE_CONFIGURABLE(cfgGlobalT0AHighSigma, float, 4, "Number of sigma deviations above expected value in global vs T0A correlation"); + } cfgGlobalAsideCorrCuts; + Configurable cfgGFWBinning{"cfgGFWBinning", {40, 16, 72, 300, 0, 3000, 0.2, 10.0, 0.2, 3.0, {0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5, 3.75, 4, 4.5, 5, 5.5, 6, 7, 8, 9, 10}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90}}, "Configuration for binning"}; + Configurable cfgRegions{"cfgRegions", {{"refN", "refP", "refFull"}, {-0.8, 0.4, -0.8}, {-0.4, 0.8, 0.8}, {0, 0, 0}, {1, 1, 1}}, "Configurations for GFW regions"}; + Configurable cfgCorrConfig{"cfgCorrConfig", {{"refP {2} refN {-2}", "refP {3} refN {-3}", "refP {4} refN {-4}", "refFull {2 -2}", "refFull {2 2 -2 -2}"}, {"ChGap22", "ChGap32", "ChGap42", "ChFull22", "ChFull24"}, {1, 0, 0, 0, 0}, {15, 1, 1, 0, 0}}, "Configurations for each correlation to calculate"}; + // Configurable cfgESEbinning{"cfgESEbinning", 100, "Number of ESE bins"}; + + // Connect to ccdb + Service ccdb; + + struct Config { + TH1D* mEfficiency = nullptr; + GFWWeights* mAcceptance; + bool correctionsLoaded = false; + } cfg; + + // Define output + OutputObj fFC{FlowContainer("FlowContainer")}; + OutputObj fFCpt{FlowPtContainer("FlowPtContainer")}; + OutputObj fFCgen{FlowContainer("FlowContainer_gen")}; + OutputObj fFCptgen{FlowPtContainer("FlowPtContainer_gen")}; + HistogramRegistry registry{"registry"}; + + // QA outputs + std::map>> th1sList; + std::map>> tpfsList; + std::map>> th3sList; + enum OutputTH1Names { + hPhi = 0, + hEta, + hVtxZ, + hMult, + hCent, + hEventSel, + kCount_TH1Names + }; + enum OutputTProfileNames { + pfCorr22 = 0, + kCount_TProfileNames + }; + // NUA outputs + enum OutputTH3Names { + hNUAref = 0, + kCount_TH3Names + }; + enum CentEstimators { + kCentFT0C = 0, + kCentFT0CVariant1, + kCentFT0M, + kCentFV0A, + kCentNTPV, + kCentNGlobal, + kCentMFT + }; + enum EventSelFlags { + kFilteredEvent = 1, + kSel8, + kOccupancy, + kTVXTRD, + kNoSamebunchPU, + kZVtxFT0PV, + kNoCollTRStd, + kVtxITSTPC, + kGoodITSLayers, + kMultCuts, + kTrackCent + }; + + // Define global variables + // Generic Framework + GFW* fGFW = new GFW(); + std::vector corrconfigs; + + TRandom3* fRndm = new TRandom3(0); + TAxis* fSecondAxis; + int lastRun = -1; + std::vector::iterator firstRunOfCurrentFill; + std::vector runNumbers; + + // Density dependent eff correction + std::vector funcEff; + TH1D* hFindPtBin; + TF1* funcV2; + TF1* funcV3; + TF1* funcV4; + struct DensityCorr { + double psi2Est; + double psi3Est; + double psi4Est; + double v2; + double v3; + double v4; + int density; + DensityCorr() : psi2Est(0.), psi3Est(0.), psi4Est(0.), v2(0.), v3(0.), v4(0.), density(0) {} + }; + static constexpr int EseBins = 100; + + // region indices for consistency flag + int posRegionIndex = -1; + int negRegionIndex = -1; + int fullRegionIndex = -1; + int midRegionIndex = -1; + + // Event selection cuts - Alex + TF1* fMultPVCutLow = nullptr; + TF1* fMultPVCutHigh = nullptr; + TF1* fMultCutLow = nullptr; + TF1* fMultCutHigh = nullptr; + TF1* fMultPVGlobalCutHigh = nullptr; + TF1* fMultGlobalV0ACutLow = nullptr; + TF1* fMultGlobalV0ACutHigh = nullptr; + TF1* fMultGlobalT0ACutLow = nullptr; + TF1* fMultGlobalT0ACutHigh = nullptr; + + TF1* fPtDepDCAxy = nullptr; + + o2::framework::expressions::Filter collisionFilter = nabs(aod::collision::posZ) < cfgVtxZ; + o2::framework::expressions::Filter trackFilter = nabs(aod::track::eta) < cfgEta && aod::track::pt > cfgPtmin&& aod::track::pt < cfgPtmax && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == static_cast(true))) && (aod::track::itsChi2NCl < cfgChi2PrITSCls) && (aod::track::tpcChi2NCl < cfgChi2PrTPCCls) && nabs(aod::track::dcaZ) < cfgDCAz; + + Preslice perCollision = aod::track::collisionId; + o2::framework::expressions::Filter mcCollFilter = nabs(aod::mccollision::posZ) < cfgVtxZ; + o2::framework::expressions::Filter mcParticlesFilter = (aod::mcparticle::eta > o2::analysis::gfwflowese::etalow && aod::mcparticle::eta < o2::analysis::gfwflowese::etaup && aod::mcparticle::pt > o2::analysis::gfwflowese::ptlow && aod::mcparticle::pt < o2::analysis::gfwflowese::ptup); + + using GFWTracks = soa::Filtered>; + + void init(InitContext const&) + { + LOGF(info, "FlowGfwEse::init()"); + o2::analysis::gfwflowese::regions.SetNames(cfgRegions->GetNames()); + o2::analysis::gfwflowese::regions.SetEtaMin(cfgRegions->GetEtaMin()); + o2::analysis::gfwflowese::regions.SetEtaMax(cfgRegions->GetEtaMax()); + o2::analysis::gfwflowese::regions.SetpTDifs(cfgRegions->GetpTDifs()); + o2::analysis::gfwflowese::regions.SetBitmasks(cfgRegions->GetBitmasks()); + o2::analysis::gfwflowese::configs.SetCorrs(cfgCorrConfig->GetCorrs()); + o2::analysis::gfwflowese::configs.SetHeads(cfgCorrConfig->GetHeads()); + o2::analysis::gfwflowese::configs.SetpTDifs(cfgCorrConfig->GetpTDifs()); + o2::analysis::gfwflowese::configs.SetpTCorrMasks(cfgCorrConfig->GetpTCorrMasks()); + o2::analysis::gfwflowese::regions.Print(); + o2::analysis::gfwflowese::configs.Print(); + o2::analysis::gfwflowese::ptbinning = cfgGFWBinning->GetPtBinning(); + o2::analysis::gfwflowese::ptpoilow = cfgGFWBinning->GetPtPOImin(); + o2::analysis::gfwflowese::ptpoiup = cfgGFWBinning->GetPtPOImax(); + o2::analysis::gfwflowese::ptreflow = cfgGFWBinning->GetPtRefMin(); + o2::analysis::gfwflowese::ptrefup = cfgGFWBinning->GetPtRefMax(); + o2::analysis::gfwflowese::ptlow = cfgPtmin; + o2::analysis::gfwflowese::ptup = cfgPtmax; + o2::analysis::gfwflowese::etabins = cfgGFWBinning->GetEtaBins(); + o2::analysis::gfwflowese::vtxZbins = cfgGFWBinning->GetVtxZbins(); + o2::analysis::gfwflowese::phibins = cfgGFWBinning->GetPhiBins(); + o2::analysis::gfwflowese::philow = 0.0f; + o2::analysis::gfwflowese::phiup = o2::constants::math::TwoPI; + o2::analysis::gfwflowese::nchbins = cfgGFWBinning->GetNchBins(); + o2::analysis::gfwflowese::nchlow = cfgGFWBinning->GetNchMin(); + o2::analysis::gfwflowese::nchup = cfgGFWBinning->GetNchMax(); + o2::analysis::gfwflowese::centbinning = cfgGFWBinning->GetCentBinning(); + cfgGFWBinning->Print(); + o2::analysis::gfwflowese::multGlobalCorrCutPars = cfgMultGlobalCutPars; + o2::analysis::gfwflowese::multPVCorrCutPars = cfgMultPVCutPars; + o2::analysis::gfwflowese::multGlobalPVCorrCutPars = cfgMultGlobalPVCutPars; + o2::analysis::gfwflowese::multGlobalV0ACutPars = cfgGlobalAsideCorrCuts.cfgMultGlobalV0ACutPars; + o2::analysis::gfwflowese::multGlobalT0ACutPars = cfgGlobalAsideCorrCuts.cfgMultGlobalT0ACutPars; + o2::analysis::gfwflowese::firstRunsOfFill = cfgFirstRunsOfFill; + if (cfgTimeDependent && !std::is_sorted(o2::analysis::gfwflowese::firstRunsOfFill.begin(), o2::analysis::gfwflowese::firstRunsOfFill.end())) { + std::sort(o2::analysis::gfwflowese::firstRunsOfFill.begin(), o2::analysis::gfwflowese::firstRunsOfFill.end()); + } + firstRunOfCurrentFill = o2::analysis::gfwflowese::firstRunsOfFill.begin(); + + AxisSpec phiAxis = {o2::analysis::gfwflowese::phibins, o2::analysis::gfwflowese::philow, o2::analysis::gfwflowese::phiup, "#phi"}; + AxisSpec etaAxis = {o2::analysis::gfwflowese::etabins, -cfgEta, cfgEta, "#eta"}; + AxisSpec vtxAxis = {o2::analysis::gfwflowese::vtxZbins, -cfgVtxZ, cfgVtxZ, "Vtx_{z} (cm)"}; + AxisSpec ptAxis = {o2::analysis::gfwflowese::ptbinning, "#it{p}_{T} GeV/#it{c}"}; + std::string sCentralityEstimator; + std::map centEstimatorMap = { + {kCentFT0C, "FT0C"}, + {kCentFT0CVariant1, "FT0C variant 1"}, + {kCentFT0M, "FT0M"}, + {kCentFV0A, "FV0A"}, + {kCentNTPV, "NTPV"}, + {kCentNGlobal, "NGlobals"}, + {kCentMFT, "MFT"}}; + + sCentralityEstimator = centEstimatorMap.at(cfgCentEstimator); + sCentralityEstimator += " centrality (%)"; + AxisSpec centAxis = {o2::analysis::gfwflowese::centbinning, sCentralityEstimator.c_str()}; + std::vector nchbinning; + int nchskip = (o2::analysis::gfwflowese::nchup - o2::analysis::gfwflowese::nchlow) / o2::analysis::gfwflowese::nchbins; + for (int i = 0; i <= o2::analysis::gfwflowese::nchbins; ++i) { + nchbinning.push_back(nchskip * i + o2::analysis::gfwflowese::nchlow + 0.5); + } + AxisSpec nchAxis = {nchbinning, "N_{ch}"}; + std::vector bbinning(201); + std::generate(bbinning.begin(), bbinning.end(), [n = -0.1, step = 0.1]() mutable { + n += step; + return n; + }); + AxisSpec bAxis = {bbinning, "#it{b}"}; + AxisSpec t0cAxis = {1000, 0, 10000, "N_{ch} (T0C)"}; + AxisSpec t0aAxis = {300, 0, 30000, "N_{ch} (T0A)"}; + AxisSpec v0aAxis = {800, 0, 80000, "N_{ch} (V0A)"}; + AxisSpec multpvAxis = {600, 0, 600, "N_{ch} (PV)"}; + AxisSpec dcaZAXis = {200, -2, 2, "DCA_{z} (cm)"}; + AxisSpec dcaXYAXis = {200, -0.5, 0.5, "DCA_{xy} (cm)"}; + std::vector timebinning(289); + std::generate(timebinning.begin(), timebinning.end(), [n = -24 / 288., step = 24 / 288.]() mutable { + n += step; + return n; + }); + AxisSpec timeAxis = {timebinning, "time (hrs)"}; + + AxisSpec multAxis = (cfgTimeDependent) ? timeAxis : (cfgUseNch) ? nchAxis + : centAxis; + + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + + int64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + ccdb->setCreatedNotAfter(now); + + int ptbins = o2::analysis::gfwflowese::ptbinning.size() - 1; + fSecondAxis = (cfgTimeDependent) ? new TAxis(timeAxis.binEdges.size() - 1, &(timeAxis.binEdges[0])) : new TAxis(ptbins, &o2::analysis::gfwflowese::ptbinning[0]); + + if (doprocessData) { + registry.add("trackQA/before/phi_eta_vtxZ", "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); + registry.add("trackQA/before/pt_dcaXY_dcaZ", "", {HistType::kTH3D, {ptAxis, dcaXYAXis, dcaZAXis}}); + registry.add("trackQA/before/nch_pt", "#it{p}_{T} vs multiplicity; N_{ch}; #it{p}_{T}", {HistType::kTH2D, {nchAxis, ptAxis}}); + registry.add("trackQA/before/chi2prTPCcls", "#chi^{2}/cluster for the TPC track segment; #chi^{2}/TPC cluster", {HistType::kTH1D, {{100, 0., 5.}}}); + registry.add("trackQA/before/chi2prITScls", "#chi^{2}/cluster for the ITS track; #chi^{2}/ITS cluster", {HistType::kTH1D, {{100, 0., 50.}}}); + registry.add("trackQA/before/nTPCClusters", "Number of found TPC clusters; TPC N_{cls}; Counts", {HistType::kTH1D, {{100, 40, 180}}}); + registry.add("trackQA/before/nITSClusters", "Number of found ITS clusters; ITS N_{cls}; Counts", {HistType::kTH1D, {{100, 0, 20}}}); + registry.add("trackQA/before/nTPCCrossedRows", "Number of crossed TPC Rows; TPC X-rows; Counts", {HistType::kTH1D, {{100, 40, 180}}}); + + registry.addClone("trackQA/before/", "trackQA/after/"); + registry.add("trackQA/after/pt_ref", "", {HistType::kTH1D, {{100, o2::analysis::gfwflowese::ptreflow, o2::analysis::gfwflowese::ptrefup}}}); + registry.add("trackQA/after/pt_poi", "", {HistType::kTH1D, {{100, o2::analysis::gfwflowese::ptpoilow, o2::analysis::gfwflowese::ptpoiup}}}); + + registry.add("eventQA/before/multiplicity", "", {HistType::kTH1D, {nchAxis}}); + if (cfgTimeDependent) { + registry.add("eventQA/before/multiplicity_time", "Multiplicity vs time; time (hrs); N_{ch}", {HistType::kTH2D, {timeAxis, nchAxis}}); + registry.add("eventQA/before/multT0C_time", "T0C Multiplicity vs time; time (hrs); N_{ch} (T0C)", {HistType::kTH2D, {timeAxis, t0cAxis}}); + registry.add("eventQA/before/multT0A_time", "T0A Multiplicity vs time; time (hrs); N_{ch} (T0A)", {HistType::kTH2D, {timeAxis, t0aAxis}}); + registry.add("eventQA/before/multV0A_time", "V0A Multiplicity vs time; time (hrs); N_{ch} (V0A)", {HistType::kTH2D, {timeAxis, v0aAxis}}); + registry.add("eventQA/before/multPV_time", "PV Multiplicity vs time; time (hrs); N_{ch} (PV)", {HistType::kTH2D, {timeAxis, multpvAxis}}); + } + registry.add("eventQA/before/globalTracks_PVTracks", "", {HistType::kTH2D, {multpvAxis, nchAxis}}); + registry.add("eventQA/before/globalTracks_multT0A", "", {HistType::kTH2D, {t0aAxis, nchAxis}}); + registry.add("eventQA/before/globalTracks_multV0A", "", {HistType::kTH2D, {v0aAxis, nchAxis}}); + registry.add("eventQA/before/multV0A_multT0A", "", {HistType::kTH2D, {t0aAxis, v0aAxis}}); + + if (doprocessData) { + registry.add("eventQA/before/centrality", "", {HistType::kTH1D, {centAxis}}); + registry.add("eventQA/before/globalTracks_centT0C", "", {HistType::kTH2D, {centAxis, nchAxis}}); + registry.add("eventQA/before/PVTracks_centT0C", "", {HistType::kTH2D, {centAxis, multpvAxis}}); + registry.add("eventQA/before/multT0C_centT0C", "", {HistType::kTH2D, {centAxis, t0cAxis}}); + + registry.add("eventQA/before/centT0M_centT0C", "", {HistType::kTH2D, {centAxis, centAxis}}); + registry.add("eventQA/before/centV0A_centT0C", "", {HistType::kTH2D, {centAxis, centAxis}}); + registry.add("eventQA/before/centGlobal_centT0C", "", {HistType::kTH2D, {centAxis, centAxis}}); + registry.add("eventQA/before/centNTPV_centT0C", "", {HistType::kTH2D, {centAxis, centAxis}}); + registry.add("eventQA/before/centMFT_centT0C", "", {HistType::kTH2D, {centAxis, centAxis}}); + } + + registry.addClone("eventQA/before/", "eventQA/after/"); + registry.add("eventQA/eventSel", "Number of Events;; Counts", {HistType::kTH1D, {{11, 0.5, 11.5}}}); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kFilteredEvent, "Filtered event"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kSel8, "sel8"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kOccupancy, "occupancy"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kTVXTRD, "kTVXinTRD"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kNoSamebunchPU, "kNoSameBunchPileup"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kZVtxFT0PV, "kIsGoodZvtxFT0vsPV"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kNoCollTRStd, "kNoCollInTimeRangeStandard"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kVtxITSTPC, "kIsVertexITSTPC"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kGoodITSLayers, "kIsGoodITSLayersAll"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kMultCuts, "after Mult cuts"); + registry.get(HIST("eventQA/eventSel"))->GetXaxis()->SetBinLabel(kTrackCent, "has track + within cent"); + if (!cfgRunByRun && cfgFillWeights) { + registry.add("phi_eta_vtxz_ref", "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); + } + } + + if (o2::analysis::gfwflowese::regions.GetSize() < 0) + LOGF(error, "Configuration contains vectors of different size - check the GFWRegions configurable"); + for (auto i(0); i < o2::analysis::gfwflowese::regions.GetSize(); ++i) { + fGFW->AddRegion(o2::analysis::gfwflowese::regions.GetNames()[i], o2::analysis::gfwflowese::regions.GetEtaMin()[i], o2::analysis::gfwflowese::regions.GetEtaMax()[i], (o2::analysis::gfwflowese::regions.GetpTDifs()[i]) ? ptbins + 1 : 1, o2::analysis::gfwflowese::regions.GetBitmasks()[i]); + } + for (auto i = 0; i < o2::analysis::gfwflowese::configs.GetSize(); ++i) { + corrconfigs.push_back(fGFW->GetCorrelatorConfig(o2::analysis::gfwflowese::configs.GetCorrs()[i], o2::analysis::gfwflowese::configs.GetHeads()[i], o2::analysis::gfwflowese::configs.GetpTDifs()[i])); + } + if (corrconfigs.empty()) + LOGF(error, "Configuration contains vectors of different size - check the GFWCorrConfig configurable"); + fGFW->CreateRegions(); + TObjArray* oba = new TObjArray(); + addConfigObjectsToObjArray(oba, corrconfigs); + if (doprocessData) { + fFC->SetName("FlowContainer"); + fFC->SetXAxis(fSecondAxis); + fFC->Initialize(oba, multAxis, cfgNbootstrap); + } + delete oba; + fFCpt->setUseCentralMoments(cfgUseCentralMoments); + fFCpt->setUseGapMethod(true); + fFCpt->initialise(multAxis, cfgMpar, o2::analysis::gfwflowese::configs, cfgNbootstrap); + fFCptgen->setUseCentralMoments(cfgUseCentralMoments); + fFCptgen->setUseGapMethod(true); + fFCptgen->initialise(multAxis, cfgMpar, o2::analysis::gfwflowese::configs, cfgNbootstrap); + + fPtDepDCAxy = new TF1("ptDepDCAxy", Form("[0]*%s", cfgDCAxy->c_str()), 0.001, 100); + fPtDepDCAxy->SetParameter(0, cfgDCAxyNSigma); + LOGF(info, "DCAxy pt-dependence function: %s", Form("[0]*%s", cfgDCAxy->c_str())); + if (cfgUseAdditionalEventCut) { + fMultPVCutLow = new TF1("fMultPVCutLow", cfgMultCorrLowCutFunction->c_str(), 0, 100); + fMultPVCutLow->SetParameters(&(o2::analysis::gfwflowese::multPVCorrCutPars[0])); + fMultPVCutHigh = new TF1("fMultPVCutHigh", cfgMultCorrHighCutFunction->c_str(), 0, 100); + fMultPVCutHigh->SetParameters(&(o2::analysis::gfwflowese::multPVCorrCutPars[0])); + fMultCutLow = new TF1("fMultCutLow", cfgMultCorrLowCutFunction->c_str(), 0, 100); + fMultCutLow->SetParameters(&(o2::analysis::gfwflowese::multGlobalCorrCutPars[0])); + fMultCutHigh = new TF1("fMultCutHigh", cfgMultCorrHighCutFunction->c_str(), 0, 100); + fMultCutHigh->SetParameters(&(o2::analysis::gfwflowese::multGlobalCorrCutPars[0])); + fMultPVGlobalCutHigh = new TF1("fMultPVGlobalCutHigh", cfgMultGlobalPVCorrCutFunction->c_str(), 0, nchbinning.back()); + fMultPVGlobalCutHigh->SetParameters(&(o2::analysis::gfwflowese::multGlobalPVCorrCutPars[0])); + + LOGF(info, "Global V0A function: %s in range 0-%g", cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), v0aAxis.binEdges.back()); + fMultGlobalV0ACutLow = new TF1("fMultGlobalV0ACutLow", cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), 0, v0aAxis.binEdges.back()); + for (std::size_t i = 0; i < o2::analysis::gfwflowese::multGlobalV0ACutPars.size(); ++i) + fMultGlobalV0ACutLow->SetParameter(i, o2::analysis::gfwflowese::multGlobalV0ACutPars[i]); + fMultGlobalV0ACutLow->SetParameter(o2::analysis::gfwflowese::multGlobalV0ACutPars.size(), cfgGlobalAsideCorrCuts.cfgGlobalV0ALowSigma); + for (int i = 0; i < fMultGlobalV0ACutLow->GetNpar(); ++i) + LOGF(info, "fMultGlobalV0ACutLow par %d = %g", i, fMultGlobalV0ACutLow->GetParameter(i)); + + fMultGlobalV0ACutHigh = new TF1("fMultGlobalV0ACutHigh", cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), 0, v0aAxis.binEdges.back()); + for (std::size_t i = 0; i < o2::analysis::gfwflowese::multGlobalV0ACutPars.size(); ++i) + fMultGlobalV0ACutHigh->SetParameter(i, o2::analysis::gfwflowese::multGlobalV0ACutPars[i]); + fMultGlobalV0ACutHigh->SetParameter(o2::analysis::gfwflowese::multGlobalV0ACutPars.size(), cfgGlobalAsideCorrCuts.cfgGlobalV0AHighSigma); + for (int i = 0; i < fMultGlobalV0ACutHigh->GetNpar(); ++i) + LOGF(info, "fMultGlobalV0ACutHigh par %d = %g", i, fMultGlobalV0ACutHigh->GetParameter(i)); + + LOGF(info, "Global T0A function: %s", cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str()); + fMultGlobalT0ACutLow = new TF1("fMultGlobalT0ACutLow", cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), 0, t0aAxis.binEdges.back()); + for (std::size_t i = 0; i < o2::analysis::gfwflowese::multGlobalT0ACutPars.size(); ++i) + fMultGlobalT0ACutLow->SetParameter(i, o2::analysis::gfwflowese::multGlobalT0ACutPars[i]); + fMultGlobalT0ACutLow->SetParameter(o2::analysis::gfwflowese::multGlobalT0ACutPars.size(), cfgGlobalAsideCorrCuts.cfgGlobalT0ALowSigma); + for (int i = 0; i < fMultGlobalT0ACutLow->GetNpar(); ++i) + LOGF(info, "fMultGlobalT0ACutLow par %d = %g", i, fMultGlobalT0ACutLow->GetParameter(i)); + + fMultGlobalT0ACutHigh = new TF1("fMultGlobalT0ACutHigh", cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), 0, t0aAxis.binEdges.back()); + for (std::size_t i = 0; i < o2::analysis::gfwflowese::multGlobalT0ACutPars.size(); ++i) + fMultGlobalT0ACutHigh->SetParameter(i, o2::analysis::gfwflowese::multGlobalT0ACutPars[i]); + fMultGlobalT0ACutHigh->SetParameter(o2::analysis::gfwflowese::multGlobalT0ACutPars.size(), cfgGlobalAsideCorrCuts.cfgGlobalT0AHighSigma); + for (int i = 0; i < fMultGlobalT0ACutHigh->GetNpar(); ++i) + LOGF(info, "fMultGlobalT0ACutHigh par %d = %g", i, fMultGlobalT0ACutHigh->GetParameter(i)); + } + if (cfgUseDensityDependentCorrection) { + std::vector pTEffBins = {0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.4, 1.8, 2.2, 2.6, 3.0}; + hFindPtBin = new TH1D("hFindPtBin", "hFindPtBin", pTEffBins.size() - 1, &pTEffBins[0]); + funcEff.resize(pTEffBins.size() - 1); + // LHC24g3 Eff + std::vector f1p0 = cfgTrackDensityP0; + std::vector f1p1 = cfgTrackDensityP1; + for (uint ifunc = 0; ifunc < pTEffBins.size() - 1; ifunc++) { + funcEff[ifunc] = new TF1(Form("funcEff%i", ifunc), "[0]+[1]*x", 0, 3000); + funcEff[ifunc]->SetParameters(f1p0[ifunc], f1p1[ifunc]); + } + funcV2 = new TF1("funcV2", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); + funcV2->SetParameters(0.0186111, 0.00351907, -4.38264e-05, 1.35383e-07, -3.96266e-10); + funcV3 = new TF1("funcV3", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); + funcV3->SetParameters(0.0174056, 0.000703329, -1.45044e-05, 1.91991e-07, -1.62137e-09); + funcV4 = new TF1("funcV4", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 100); + funcV4->SetParameters(0.008845, 0.000259668, -3.24435e-06, 4.54837e-08, -6.01825e-10); + } + if (cfgConsistentEventFlag) { + auto findRegionIndex = [&](const std::string& name) { + auto begin = cfgRegions->GetNames().begin(); + auto end = cfgRegions->GetNames().end(); + auto it = std::find(begin, end, name); + return (it != end) ? std::distance(begin, it) : -1; + }; + posRegionIndex = findRegionIndex("refP"); + negRegionIndex = findRegionIndex("refN"); + fullRegionIndex = findRegionIndex("refFull"); + midRegionIndex = findRegionIndex("refMid"); + } + } + + static constexpr std::string_view FillTimeName[] = {"before/", "after/"}; + + enum QAFillTime { + kBefore, + kAfter + }; + + void addConfigObjectsToObjArray(TObjArray* oba, const std::vector& configs) + { + for (auto it = configs.begin(); it != configs.end(); ++it) { + for (int jese = 0; jese < EseBins; ++jese) { + if (it->pTDif) { + for (int i = 0; i < fSecondAxis->GetNbins(); ++i) { + std::string name = Form("ese_%d_%s_pt_%d", jese, it->Head.c_str(), i + 1); + std::string title = it->Head + std::string("_ptDiff"); + oba->Add(new TNamed(name.c_str(), title.c_str())); + } + } else { + std::string name = Form("ese_%d_%s", jese, it->Head.c_str()); + std::string title = it->Head + std::string("_ese"); + oba->Add(new TNamed(name.c_str(), title.c_str())); + } + } + } + } + + int getMagneticField(uint64_t timestamp) + { + static o2::parameters::GRPMagField* grpo = nullptr; + if (grpo == nullptr) { + // grpo = ccdb->getForTimeStamp("GLO/GRP/GRP", timestamp); + grpo = ccdb->getForTimeStamp("GLO/Config/GRPMagField", timestamp); + if (grpo == nullptr) { + LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); + return 0; + } + LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", timestamp, grpo->getNominalL3Field()); + } + return grpo->getNominalL3Field(); + } + + void loadCorrections(aod::BCsWithTimestamps::iterator const& bc) + { + uint64_t timestamp = bc.timestamp(); + if (!cfgRunByRun && cfg.correctionsLoaded) + return; + if (!cfgAcceptance.value.empty()) { + std::string runstr = (cfgRunByRun) ? "RunByRun/" : ""; + cfg.mAcceptance = ccdb->getForTimeStamp(cfgAcceptance.value + runstr, timestamp); + } + if (!cfgEfficiency.value.empty()) { + cfg.mEfficiency = ccdb->getForTimeStamp(cfgEfficiency, timestamp); + if (cfg.mEfficiency == nullptr) { + LOGF(fatal, "Could not load efficiency histogram from %s", cfgEfficiency.value.c_str()); + } + LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgEfficiency.value.c_str(), (void*)cfg.mEfficiency); + } + cfg.correctionsLoaded = true; + } + + template + double getAcceptance(TTrack track, const double& vtxz) + { + double wacc = 1; + if (cfg.mAcceptance) + wacc = cfg.mAcceptance->getNUA(track.phi(), track.eta(), vtxz); + return wacc; + } + + template + double getEfficiency(TTrack track) + { + double eff = 1.; + if (cfg.mEfficiency) + eff = cfg.mEfficiency->GetBinContent(cfg.mEfficiency->FindBin(track.pt())); + if (eff == 0) + return -1.; + else + return 1. / eff; + } + + template + bool eventSelected(TCollision collision, const int& multTrk, const float& centrality, const int& run) + { + if (cfgTVXinTRD) { + if (collision.alias_bit(kTVXinTRD)) { + // TRD triggered + // "CMTVX-B-NOPF-TRD,minbias_TVX" + return 0; + } + registry.fill(HIST("eventQA/eventSel"), kTVXTRD); + if (cfgRunByRun) + th1sList[run][hEventSel]->Fill(kTVXTRD); + } + if (cfgNoSameBunchPileupCut) { + if (!collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + // rejects collisions which are associated with the same "found-by-T0" bunch crossing + // https://indico.cern.ch/event/1396220/#1-event-selection-with-its-rof + return 0; + } + registry.fill(HIST("eventQA/eventSel"), kNoSamebunchPU); + if (cfgRunByRun) + th1sList[run][hEventSel]->Fill(kNoSamebunchPU); + } + if (cfgIsGoodZvtxFT0vsPV) { + if (!collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + // removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference + // use this cut at low multiplicities with caution + return 0; + } + registry.fill(HIST("eventQA/eventSel"), kZVtxFT0PV); + if (cfgRunByRun) + th1sList[run][hEventSel]->Fill(kZVtxFT0PV); + } + if (cfgNoCollInTimeRangeStandard) { + if (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + // Rejection of the collisions which have other events nearby + return 0; + } + registry.fill(HIST("eventQA/eventSel"), kNoCollTRStd); + if (cfgRunByRun) + th1sList[run][hEventSel]->Fill(kNoCollTRStd); + } + + if (cfgIsVertexITSTPC) { + if (!collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { + // selects collisions with at least one ITS-TPC track, and thus rejects vertices built from ITS-only tracks + return 0; + } + registry.fill(HIST("eventQA/eventSel"), kVtxITSTPC); + if (cfgRunByRun) + th1sList[run][hEventSel]->Fill(kVtxITSTPC); + } + + if (cfgIsGoodITSLayersAll) { + if (!collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + return 0; + } + registry.fill(HIST("eventQA/eventSel"), kGoodITSLayers); + if (cfgRunByRun) + th1sList[run][hEventSel]->Fill(kGoodITSLayers); + } + + float vtxz = -999; + if (collision.numContrib() > 1) { + vtxz = collision.posZ(); + float zRes = std::sqrt(collision.covZZ()); + float minZRes = 0.25; + int minNContrib = 20; + if (zRes > minZRes && collision.numContrib() < minNContrib) + vtxz = -999; + } + auto multNTracksPV = collision.multNTracksPV(); + + if (vtxz > o2::analysis::gfwflowese::vtxZup || vtxz < o2::analysis::gfwflowese::vtxZlow) + return 0; + + if (cfgMultCut) { + if (multNTracksPV < fMultPVCutLow->Eval(centrality)) + return 0; + if (multNTracksPV > fMultPVCutHigh->Eval(centrality)) + return 0; + if (multTrk < fMultCutLow->Eval(centrality)) + return 0; + if (multTrk > fMultCutHigh->Eval(centrality)) + return 0; + if (multTrk > fMultPVGlobalCutHigh->Eval(collision.multNTracksPV())) + return 0; + + if (!(cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFV0A()) < fMultGlobalV0ACutLow->Eval(multTrk)) + return 0; + if (!(cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFV0A()) > fMultGlobalV0ACutHigh->Eval(multTrk)) + return 0; + if (!(cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFT0A()) < fMultGlobalT0ACutLow->Eval(multTrk)) + return 0; + if (!(cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFT0A()) > fMultGlobalT0ACutHigh->Eval(multTrk)) + return 0; + registry.fill(HIST("eventQA/eventSel"), kMultCuts); + if (cfgRunByRun) + th1sList[run][hEventSel]->Fill(kMultCuts); + } + return 1; + } + + template + bool trackSelected(TTrack track) + { + if (cfgDCAxyNSigma && (std::fabs(track.dcaXY()) > fPtDepDCAxy->Eval(track.pt()))) + return false; + return ((track.tpcNClsCrossedRows() >= cfgNTPCXrows) && (track.tpcNClsFound() >= cfgNTPCCls) && (track.itsNCls() >= cfgMinNITSCls)); + } + + enum DataType { + kReco, + kGen + }; + + template + void fillWeights(const TTrack track, const double vtxz, const int& run) + { + if (cfgRunByRun) + th3sList[run][hNUAref]->Fill(track.phi(), track.eta(), vtxz); + else + registry.fill(HIST("phi_eta_vtxz_ref"), track.phi(), track.eta(), vtxz); + return; + } + + void createRunByRunHistograms(const int& run) + { + AxisSpec phiAxis = {o2::analysis::gfwflowese::phibins, o2::analysis::gfwflowese::philow, o2::analysis::gfwflowese::phiup, "#phi"}; + AxisSpec etaAxis = {o2::analysis::gfwflowese::etabins, -cfgEta, cfgEta, "#eta"}; + AxisSpec vtxAxis = {o2::analysis::gfwflowese::vtxZbins, -cfgVtxZ, cfgVtxZ, "Vtx_{z} (cm)"}; + AxisSpec nchAxis = {o2::analysis::gfwflowese::nchbins, o2::analysis::gfwflowese::nchlow, o2::analysis::gfwflowese::nchup, "N_{ch}"}; + AxisSpec centAxis = {o2::analysis::gfwflowese::centbinning, "Centrality (%)"}; + std::vector> histos(kCount_TH1Names); + histos[hPhi] = registry.add(Form("%d/phi", run), "", {HistType::kTH1D, {phiAxis}}); + histos[hEta] = registry.add(Form("%d/eta", run), "", {HistType::kTH1D, {etaAxis}}); + histos[hVtxZ] = registry.add(Form("%d/vtxz", run), "", {HistType::kTH1D, {vtxAxis}}); + histos[hMult] = registry.add(Form("%d/mult", run), "", {HistType::kTH1D, {nchAxis}}); + histos[hCent] = registry.add(Form("%d/cent", run), "", {HistType::kTH1D, {centAxis}}); + if (cfgFillFlowRunByRun) { + std::vector> profiles(kCount_TProfileNames); + profiles[pfCorr22] = registry.add(Form("%d/corr22", run), "", {HistType::kTProfile, {(cfgUseNch) ? nchAxis : centAxis}}); + tpfsList.insert(std::make_pair(run, profiles)); + } + histos[hEventSel] = registry.add(Form("%d/eventSel", run), "Number of Events;; Counts", {HistType::kTH1D, {{11, 0.5, 11.5}}}); + histos[hEventSel]->GetXaxis()->SetBinLabel(kFilteredEvent, "Filtered event"); + histos[hEventSel]->GetXaxis()->SetBinLabel(kSel8, "sel8"); + histos[hEventSel]->GetXaxis()->SetBinLabel(kOccupancy, "occupancy"); + histos[hEventSel]->GetXaxis()->SetBinLabel(kTVXTRD, "kTVXinTRD"); + histos[hEventSel]->GetXaxis()->SetBinLabel(kNoSamebunchPU, "kNoSameBunchPileup"); + histos[hEventSel]->GetXaxis()->SetBinLabel(kZVtxFT0PV, "kIsGoodZvtxFT0vsPV"); + histos[hEventSel]->GetXaxis()->SetBinLabel(kNoCollTRStd, "kNoCollInTimeRangeStandard"); + histos[hEventSel]->GetXaxis()->SetBinLabel(kVtxITSTPC, "kIsVertexITSTPC"); + histos[hEventSel]->GetXaxis()->SetBinLabel(kGoodITSLayers, "kIsGoodITSLayersAll"); + histos[hEventSel]->GetXaxis()->SetBinLabel(kMultCuts, "after Mult cuts"); + histos[hEventSel]->GetXaxis()->SetBinLabel(kTrackCent, "has track + within cent"); + th1sList.insert(std::make_pair(run, histos)); + std::vector> histos3d(kCount_TH3Names); + histos3d[hNUAref] = registry.add(Form("%d/phi_eta_vtxz_ref", run), "", {HistType::kTH3D, {phiAxis, etaAxis, vtxAxis}}); + th3sList.insert(std::make_pair(run, histos3d)); + return; + } + + template + void fillOutputContainers(const float& centmult, const double& rndm, const int& run = 0, const float& qPerc = -1.0f) + { + (dt == kGen) ? fFCptgen->calculateCorrelations() : fFCpt->calculateCorrelations(); + (dt == kGen) ? fFCptgen->fillPtProfiles(centmult, rndm) : fFCpt->fillPtProfiles(centmult, rndm); + (dt == kGen) ? fFCptgen->fillCMProfiles(centmult, rndm) : fFCpt->fillCMProfiles(centmult, rndm); + int qPtmp = static_cast(qPerc); + for (uint l_ind = 0; l_ind < corrconfigs.size(); ++l_ind) { + if (!corrconfigs.at(l_ind).pTDif) { + auto dnx = fGFW->Calculate(corrconfigs.at(l_ind), 0, kTRUE).real(); + if (dnx == 0) + continue; + auto val = fGFW->Calculate(corrconfigs.at(l_ind), 0, kFALSE).real() / dnx; + if (std::abs(val) < 1) { + (dt == kGen) ? fFCgen->FillProfile(corrconfigs.at(l_ind).Head.c_str(), centmult, val, (cfgUseMultiplicityFlowWeights) ? dnx : 1.0, rndm) : fFC->FillProfile(Form("ese_%i_%s", qPtmp, corrconfigs.at(l_ind).Head.c_str()), centmult, val, (cfgUseMultiplicityFlowWeights) ? dnx : 1.0, rndm); + (dt == kGen) ? fFCptgen->fillVnPtProfiles(centmult, val, (cfgUseMultiplicityFlowWeights) ? dnx : 1.0, rndm, o2::analysis::gfwflowese::configs.GetpTCorrMasks()[l_ind]) : fFCpt->fillVnPtProfiles(centmult, val, (cfgUseMultiplicityFlowWeights) ? dnx : 1.0, rndm, o2::analysis::gfwflowese::configs.GetpTCorrMasks()[l_ind]); + if (cfgRunByRun && cfgFillFlowRunByRun && dt != kGen && l_ind == 0) { + tpfsList[run][pfCorr22]->Fill(centmult, val, (cfgUseMultiplicityFlowWeights) ? dnx : 1.0); + } + } + continue; + } + for (int i = 1; i <= fSecondAxis->GetNbins(); i++) { + auto dnx = fGFW->Calculate(corrconfigs.at(l_ind), i - 1, kTRUE).real(); + if (dnx == 0) + continue; + auto val = fGFW->Calculate(corrconfigs.at(l_ind), i - 1, kFALSE).real() / dnx; + if (std::abs(val) < 1) + (dt == kGen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigs.at(l_ind).Head.c_str(), i), centmult, val, (cfgUseMultiplicityFlowWeights) ? dnx : 1.0, rndm) : fFC->FillProfile(Form("ese_%i_%s_pt_%i", qPtmp, corrconfigs.at(l_ind).Head.c_str(), i), centmult, val, (cfgUseMultiplicityFlowWeights) ? dnx : 1.0, rndm); + // (dt == kGen) ? fFCgen->FillProfile(Form("%s_pt_%i", corrconfigs.at(l_ind).Head.c_str(), i), centmult, val, (cfgUseMultiplicityFlowWeights) ? dnx : 1.0, rndm) : fFC->FillProfile(Form("%s_pt_%i", corrconfigs.at(l_ind).Head.c_str(), i), centmult, val, (cfgUseMultiplicityFlowWeights) ? dnx : 1.0, rndm); + } + } + return; + } + + struct XAxis { + float centrality; + int64_t multiplicity; + double time; + }; + + struct AcceptedTracks { + int nPos; + int nNeg; + int nFull; + int nMid; + }; + + template + void processCollision(TCollision collision, TTracks tracks, const XAxis& xaxis, const int& run) + { + if (tracks.size() < 1) + return; + if (dt != kGen && xaxis.centrality >= 0 && (xaxis.centrality < o2::analysis::gfwflowese::centbinning.front() || xaxis.centrality > o2::analysis::gfwflowese::centbinning.back())) + return; + if (xaxis.multiplicity < cfgFixedMultMin || xaxis.multiplicity > cfgFixedMultMax) + return; + if (dt != kGen) { + registry.fill(HIST("eventQA/eventSel"), kTrackCent); + if (cfgRunByRun) + th1sList[run][hEventSel]->Fill(kTrackCent); + } + if (xaxis.centrality >= 0) + registry.fill(HIST("eventQA/after/centrality"), xaxis.centrality); + registry.fill(HIST("eventQA/after/multiplicity"), xaxis.multiplicity); + float vtxz = collision.posZ(); + if (dt != kGen && cfgRunByRun) { + th1sList[run][hVtxZ]->Fill(vtxz); + th1sList[run][hMult]->Fill(xaxis.multiplicity); + th1sList[run][hCent]->Fill(xaxis.centrality); + } + fGFW->Clear(); + (dt == kGen) ? fFCptgen->clearVector() : fFCpt->clearVector(); + + float lRandom = fRndm->Rndm(); + + // be cautious, this only works for Pb-Pb + // esimate the Event plane and vn for this event + DensityCorr densitycorrections; + if (cfgUseDensityDependentCorrection) { + double psi2Est = 0, psi3Est = 0, psi4Est = 0; + double v2 = 0, v3 = 0, v4 = 0; + double q2x = 0, q2y = 0; + double q3x = 0, q3y = 0; + double q4x = 0, q4y = 0; + for (const auto& track : tracks) { + bool withinPtRef = (o2::analysis::gfwflowese::ptreflow < track.pt()) && (track.pt() < o2::analysis::gfwflowese::ptrefup); // within RF pT rang + if (withinPtRef) { + q2x += std::cos(2 * track.phi()); + q2y += std::sin(2 * track.phi()); + q3x += std::cos(3 * track.phi()); + q3y += std::sin(3 * track.phi()); + q4x += std::cos(4 * track.phi()); + q4y += std::sin(4 * track.phi()); + } + } + psi2Est = std::atan2(q2y, q2x) / 2.; + psi3Est = std::atan2(q3y, q3x) / 3.; + psi4Est = std::atan2(q4y, q4x) / 4.; + v2 = funcV2->Eval(xaxis.centrality); + v3 = funcV3->Eval(xaxis.centrality); + v4 = funcV4->Eval(xaxis.centrality); + densitycorrections.psi2Est = psi2Est; + densitycorrections.psi3Est = psi3Est; + densitycorrections.psi4Est = psi4Est; + densitycorrections.v2 = v2; + densitycorrections.v3 = v3; + densitycorrections.v4 = v4; + densitycorrections.density = tracks.size(); + } + AcceptedTracks acceptedTracks{0, 0, 0, 0}; + for (const auto& track : tracks) { + processTrack(track, vtxz, xaxis.multiplicity, run, densitycorrections, acceptedTracks); + if (cfgConsistentEventFlag & 1) + if (!acceptedTracks.nPos || !acceptedTracks.nNeg) + return; + if (cfgConsistentEventFlag & 2) + if (acceptedTracks.nFull < 4) // o2-linter: disable=magic-number (at least four tracks in full acceptance) + return; + if (cfgConsistentEventFlag & 4) + if (acceptedTracks.nPos < 2 || acceptedTracks.nNeg < 2) // o2-linter: disable=magic-number (at least two tracks in each subevent) + return; + if (cfgConsistentEventFlag & 8) + if (acceptedTracks.nPos < 2 || acceptedTracks.nMid < 2 || acceptedTracks.nNeg < 2) // o2-linter: disable=magic-number (at least two tracks in all three subevents) + return; + } + const auto qPerc{collision.qPERCFT0C()}; + if (!cfgFillWeights) + fillOutputContainers
((cfgTimeDependent) ? xaxis.time : (cfgUseNch) ? xaxis.multiplicity + : xaxis.centrality, + lRandom, run, qPerc[0]); + } + + bool isStable(int pdg) + { + if (std::abs(pdg) == PDG_t::kPiPlus) + return true; + if (std::abs(pdg) == PDG_t::kKPlus) + return true; + if (std::abs(pdg) == PDG_t::kProton) + return true; + if (std::abs(pdg) == PDG_t::kElectron) + return true; + if (std::abs(pdg) == PDG_t::kMuonMinus) + return true; + return false; + } + + template + void fillAcceptedTracks(TTrack track, AcceptedTracks& acceptedTracks) + { + if (posRegionIndex >= 0 && track.eta() > o2::analysis::gfwflowese::regions.GetEtaMin()[posRegionIndex] && track.eta() < o2::analysis::gfwflowese::regions.GetEtaMax()[posRegionIndex]) + ++acceptedTracks.nPos; + if (negRegionIndex >= 0 && track.eta() > o2::analysis::gfwflowese::regions.GetEtaMin()[negRegionIndex] && track.eta() < o2::analysis::gfwflowese::regions.GetEtaMax()[negRegionIndex]) + ++acceptedTracks.nNeg; + if (fullRegionIndex >= 0 && track.eta() > o2::analysis::gfwflowese::regions.GetEtaMin()[fullRegionIndex] && track.eta() < o2::analysis::gfwflowese::regions.GetEtaMax()[fullRegionIndex]) + ++acceptedTracks.nFull; + if (midRegionIndex >= 0 && track.eta() > o2::analysis::gfwflowese::regions.GetEtaMin()[midRegionIndex] && track.eta() < o2::analysis::gfwflowese::regions.GetEtaMax()[midRegionIndex]) + ++acceptedTracks.nMid; + } + + template + inline void processTrack(TTrack const& track, const float& vtxz, const int& multiplicity, const int& run, DensityCorr densitycorrections, AcceptedTracks& acceptedTracks) + { + if constexpr (framework::has_type_v) { + if (track.mcParticleId() < 0 || !(track.has_mcParticle())) + return; + + auto mcParticle = track.mcParticle(); + if (!mcParticle.isPhysicalPrimary()) + return; + if (!isStable(mcParticle.pdgCode())) + return; + if (cfgFillQA) { + fillTrackQA(track, vtxz); + registry.fill(HIST("trackQA/before/nch_pt"), multiplicity, track.pt()); + } + if (!trackSelected(track)) + return; + + if (cfgFillWeights) { + fillWeights(track, vtxz, run); + } else { + fillPtSums(track); + fillGFW(track, vtxz, densitycorrections); + fillAcceptedTracks(track, acceptedTracks); + } + + if (cfgFillQA) { + fillTrackQA(track, vtxz); + registry.fill(HIST("trackQA/after/nch_pt"), multiplicity, track.pt()); + if (cfgRunByRun) { + th1sList[run][hPhi]->Fill(track.phi()); + th1sList[run][hEta]->Fill(track.eta()); + } + } + + } else if constexpr (framework::has_type_v) { + if (!track.isPhysicalPrimary() || !isStable(track.pdgCode())) + return; + + fillPtSums(track); + fillGFW(track, vtxz, densitycorrections); + fillAcceptedTracks(track, acceptedTracks); + if (cfgFillQA) { + fillTrackQA(track, vtxz); + registry.fill(HIST("MCGen/trackQA/nch_pt"), multiplicity, track.pt()); + } + } else { + if (cfgFillQA) { + fillTrackQA(track, vtxz); + registry.fill(HIST("trackQA/before/nch_pt"), multiplicity, track.pt()); + } + if (!trackSelected(track)) + return; + + if (cfgFillWeights) { + fillWeights(track, vtxz, run); + } else { + fillPtSums(track); + fillGFW(track, vtxz, densitycorrections); + fillAcceptedTracks(track, acceptedTracks); + } + if (cfgFillQA) { + fillTrackQA(track, vtxz); + registry.fill(HIST("trackQA/after/nch_pt"), multiplicity, track.pt()); + if (cfgRunByRun) { + th1sList[run][hPhi]->Fill(track.phi()); + th1sList[run][hEta]->Fill(track.eta()); + th3sList[run][hNUAref]->Fill(track.phi(), track.eta(), vtxz, getAcceptance(track, vtxz)); + } + } + } + return; + } + + template + inline void fillGFW(TTrack track, const double& vtxz, DensityCorr densitycorrections) + { + bool withinPtRef = (track.pt() > o2::analysis::gfwflowese::ptreflow && track.pt() < o2::analysis::gfwflowese::ptrefup); + bool withinPtPOI = (track.pt() > o2::analysis::gfwflowese::ptpoilow && track.pt() < o2::analysis::gfwflowese::ptpoiup); + if (!withinPtPOI && !withinPtRef) + return; + double weff = (dt == kGen) ? 1. : getEfficiency(track); + if (weff < 0) + return; + if (cfgUseDensityDependentCorrection && withinPtRef && dt != kGen) { + double fphi = densitycorrections.v2 * std::cos(2 * (track.phi() - densitycorrections.psi2Est)) + densitycorrections.v3 * std::cos(3 * (track.phi() - densitycorrections.psi3Est)) + densitycorrections.v4 * std::cos(4 * (track.phi() - densitycorrections.psi4Est)); + fphi = (1 + 2 * fphi); + int pTBinForEff = hFindPtBin->FindBin(track.pt()); + if (pTBinForEff >= 1 && pTBinForEff <= hFindPtBin->GetNbinsX()) { + float wEPeff = funcEff[pTBinForEff - 1]->Eval(fphi * densitycorrections.density); + if (wEPeff > 0.) { + wEPeff = 1. / wEPeff; + weff *= wEPeff; + } + } + } + double wacc = (dt == kGen) ? 1. : getAcceptance(track, vtxz); + if (withinPtRef) + fGFW->Fill(track.eta(), fSecondAxis->FindBin(track.pt()) - 1, track.phi(), weff * wacc, 1); + if (withinPtPOI) + fGFW->Fill(track.eta(), fSecondAxis->FindBin(track.pt()) - 1, track.phi(), weff * wacc, 2); + if (withinPtRef && withinPtPOI) + fGFW->Fill(track.eta(), fSecondAxis->FindBin(track.pt()) - 1, track.phi(), weff * wacc, 4); + return; + } + + template + inline void fillPtSums(TTrack track) + { + double weff = (dt == kGen) ? 1. : getEfficiency(track); + if (weff < 0) + return; + if (std::abs(track.eta()) < cfgEtaPtPt && track.pt() > o2::analysis::gfwflowese::ptreflow && track.pt() < o2::analysis::gfwflowese::ptrefup) { + (dt == kGen) ? fFCptgen->fill(1., track.pt()) : fFCpt->fill(weff, track.pt()); + } + } + + template + inline void fillTrackQA(TTrack track, const float vtxz) + { + if constexpr (dt == kGen) { + registry.fill(HIST("MCGen/trackQA/phi_eta_vtxZ"), track.phi(), track.eta(), vtxz); + registry.fill(HIST("MCGen/trackQA/pt_ref"), track.pt()); + registry.fill(HIST("MCGen/trackQA/pt_poi"), track.pt()); + } else { + double wacc = getAcceptance(track, vtxz); + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("phi_eta_vtxZ"), track.phi(), track.eta(), vtxz, (ft == kAfter) ? wacc : 1.0); + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("pt_dcaXY_dcaZ"), track.pt(), track.dcaXY(), track.dcaZ()); + + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("chi2prTPCcls"), track.tpcChi2NCl()); + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("chi2prITScls"), track.itsChi2NCl()); + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("nTPCClusters"), track.tpcNClsFound()); + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("nITSClusters"), track.itsNCls()); + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("nTPCCrossedRows"), track.tpcNClsCrossedRows()); + + if (ft == kAfter) { + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("pt_ref"), track.pt()); + registry.fill(HIST("trackQA/") + HIST(FillTimeName[ft]) + HIST("pt_poi"), track.pt()); + } + } + } + + template + float getCentrality(TCollision collision) + { + switch (cfgCentEstimator) { + case kCentFT0C: + return collision.centFT0C(); + case kCentFT0CVariant1: + return collision.centFT0CVariant1(); + case kCentFT0M: + return collision.centFT0M(); + case kCentFV0A: + return collision.centFV0A(); + case kCentNTPV: + return collision.centNTPV(); + case kCentNGlobal: + return collision.centNGlobal(); + case kCentMFT: + return collision.centMFT(); + default: + return collision.centFT0C(); + } + } + + template + inline void fillEventQA(TCollision collision, XAxis xaxis) + { + if constexpr (framework::has_type_v) { + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("globalTracks_centT0C"), collision.centFT0C(), xaxis.multiplicity); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("PVTracks_centT0C"), collision.centFT0C(), collision.multNTracksPV()); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("multT0C_centT0C"), collision.centFT0C(), collision.multFT0C()); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("centT0M_centT0C"), collision.centFT0C(), collision.centFT0M()); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("centV0A_centT0C"), collision.centFT0C(), collision.centFV0A()); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("centGlobal_centT0C"), collision.centFT0C(), collision.centNGlobal()); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("centNTPV_centT0C"), collision.centFT0C(), collision.centNTPV()); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("centMFT_centT0C"), collision.centFT0C(), collision.centMFT()); + } + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("globalTracks_PVTracks"), collision.multNTracksPV(), xaxis.multiplicity); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("globalTracks_multT0A"), collision.multFT0A(), xaxis.multiplicity); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("globalTracks_multV0A"), collision.multFV0A(), xaxis.multiplicity); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("multV0A_multT0A"), collision.multFT0A(), collision.multFV0A()); + if (cfgTimeDependent) { + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("multiplicity_time"), xaxis.time, xaxis.multiplicity); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("multT0C_time"), xaxis.time, collision.multFT0C()); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("multT0A_time"), xaxis.time, collision.multFT0A()); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("multV0A_time"), xaxis.time, collision.multFV0A()); + registry.fill(HIST("eventQA/") + HIST(FillTimeName[ft]) + HIST("multPV_time"), xaxis.time, collision.multNTracksPV()); + } + return; + } + + double getTimeSinceStartOfFill(uint64_t timestamp, int firstRun) + { + auto runDuration = ccdb->getRunDuration(firstRun); + uint64_t tsSOF = runDuration.first; + uint64_t diff = timestamp - tsSOF; + return static_cast(diff) / 3600000.0; + } + + void processData(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, GFWTracks const& tracks) + { + auto bc = collision.bc_as(); + int run = bc.runNumber(); + if (run != lastRun) { + lastRun = run; + LOGF(info, "run = %d", run); + if (cfgRunByRun) { + if (std::find(runNumbers.begin(), runNumbers.end(), run) == runNumbers.end()) { + LOGF(info, "Creating histograms for run %d", run); + createRunByRunHistograms(run); + runNumbers.push_back(run); + } else { + LOGF(info, "run %d already in runNumbers", run); + } + if (!cfgFillWeights) + loadCorrections(bc); + } + } + if (!cfgFillWeights && !cfgRunByRun) + loadCorrections(bc); + registry.fill(HIST("eventQA/eventSel"), kFilteredEvent); + if (cfgRunByRun) + th1sList[run][hEventSel]->Fill(kFilteredEvent); + if (!collision.sel8()) + return; + registry.fill(HIST("eventQA/eventSel"), kSel8); + if (cfgRunByRun) + th1sList[run][hEventSel]->Fill(kSel8); + if (cfgDoOccupancySel) { + int occupancy = collision.trackOccupancyInTimeRange(); + if (occupancy < 0 || occupancy > cfgOccupancySelection) + return; + } + const auto qPerc{collision.qPERCFT0C()}; + if (qPerc[0] < 0) + return; + registry.fill(HIST("eventQA/eventSel"), kOccupancy); + if (cfgRunByRun) + th1sList[run][hEventSel]->Fill(kOccupancy); + + const XAxis xaxis{getCentrality(collision), tracks.size(), (cfgTimeDependent) ? getTimeSinceStartOfFill(bc.timestamp(), *firstRunOfCurrentFill) : -1.0}; + if (cfgTimeDependent && run == *firstRunOfCurrentFill && firstRunOfCurrentFill != o2::analysis::gfwflowese::firstRunsOfFill.end() - 1) + ++firstRunOfCurrentFill; + + if (cfgFillQA) + fillEventQA(collision, xaxis); + registry.fill(HIST("eventQA/before/centrality"), xaxis.centrality); + registry.fill(HIST("eventQA/before/multiplicity"), xaxis.multiplicity); + if (cfgUseAdditionalEventCut && !eventSelected(collision, xaxis.multiplicity, xaxis.centrality, run)) + return; + if (cfgFillQA) + fillEventQA(collision, xaxis); + processCollision(collision, tracks, xaxis, run); + } + PROCESS_SWITCH(FlowGfwEse, processData, "Process analysis for non-derived data", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + }; +} diff --git a/PWGCF/Flow/Tasks/flowGfwOmegaXi.cxx b/PWGCF/Flow/Tasks/flowGfwOmegaXi.cxx index 741f4b5b33a..bf001b02df2 100644 --- a/PWGCF/Flow/Tasks/flowGfwOmegaXi.cxx +++ b/PWGCF/Flow/Tasks/flowGfwOmegaXi.cxx @@ -384,8 +384,6 @@ struct FlowGfwOmegaXi { registry.add("Xic24_gapdpt", ";pt ; C_{2}{4} ", {HistType::kTProfile3D, {cfgaxisPtXi, cfgaxisXiMassforflow, axisMultiplicity}}); registry.add("Omegac24_gapdpt", ";pt ; C_{2}{4} ", {HistType::kTProfile3D, {cfgaxisPtOmega, cfgaxisOmegaMassforflow, axisMultiplicity}}); - registry.add("Xic22Full_oldpt", ";pt ; C_{2}{2} ", {HistType::kTProfile3D, {cfgaxisPtXi, cfgaxisXiMassforflow, axisMultiplicity}}); - registry.add("Omegac22Full_oldpt", ";pt ; C_{2}{2} ", {HistType::kTProfile3D, {cfgaxisPtOmega, cfgaxisOmegaMassforflow, axisMultiplicity}}); // v3 registry.add("Xic32dpt", ";pt ; C_{2}{2} ", {HistType::kTProfile3D, {cfgaxisPtXi, cfgaxisXiMassforflow, axisMultiplicity}}); registry.add("Omegac32dpt", ";pt ; C_{2}{2} ", {HistType::kTProfile3D, {cfgaxisPtOmega, cfgaxisOmegaMassforflow, axisMultiplicity}}); @@ -450,6 +448,8 @@ struct FlowGfwOmegaXi { fGFW->AddRegion("reffull", -0.8, 0.8, 1, 1); // ("name", etamin, etamax, ptbinnum, bitmask)eta region -0.8 to 0.8 fGFW->AddRegion("refN10", -0.8, -0.4, 1, 1); fGFW->AddRegion("refP10", 0.4, 0.8, 1, 1); + fGFW->AddRegion("olxidaudpt", -0.8, 0.8, 1, 2048); + fGFW->AddRegion("olomegadaudpt", -0.8, 0.8, 1, 4096); // POI fGFW->AddRegion("poiN10dpt", -0.8, -0.4, nPtBins, 32); fGFW->AddRegion("poiP10dpt", 0.4, 0.8, nPtBins, 32); @@ -462,26 +462,20 @@ struct FlowGfwOmegaXi { fGFW->AddRegion("poiXifulldpt", -0.8, 0.8, nXiptMassBins, 2); fGFW->AddRegion("poiXiP", 0.4, 0.8, 1, 2); fGFW->AddRegion("poiXiN", -0.8, -0.4, 1, 2); - fGFW->AddRegion("Xioldpt", -0.8, 0.8, nXiptMassBins, 2048); int nOmegaptMassBins = nXiPtBins * cfgmassbins[3]; fGFW->AddRegion("poiOmegaPdpt", 0.4, 0.8, nOmegaptMassBins, 4); fGFW->AddRegion("poiOmegaNdpt", -0.8, -0.4, nOmegaptMassBins, 4); fGFW->AddRegion("poiOmegafulldpt", -0.8, 0.8, nOmegaptMassBins, 4); fGFW->AddRegion("poiOmegaP", 0.4, 0.8, 1, 4); fGFW->AddRegion("poiOmegaN", -0.8, -0.4, 1, 4); - fGFW->AddRegion("Omegaoldpt", -0.8, 0.8, nOmegaptMassBins, 4096); int nK0sptMassBins = nK0sPtBins * cfgmassbins[0]; fGFW->AddRegion("poiK0sPdpt", 0.4, 0.8, nK0sptMassBins, 8); fGFW->AddRegion("poiK0sNdpt", -0.8, -0.4, nK0sptMassBins, 8); fGFW->AddRegion("poiK0sfulldpt", -0.8, 0.8, nK0sptMassBins, 8); - fGFW->AddRegion("poiK0sP", 0.4, 0.8, 1, 8); - fGFW->AddRegion("poiK0sN", -0.8, 0.4, 1, 8); int nLambdaptMassBins = nLambdaPtBins * cfgmassbins[1]; fGFW->AddRegion("poiLambdaPdpt", 0.4, 0.8, nLambdaptMassBins, 16); fGFW->AddRegion("poiLambdaNdpt", -0.8, -0.4, nLambdaptMassBins, 16); fGFW->AddRegion("poiLambdafulldpt", -0.8, 0.8, nLambdaptMassBins, 16); - fGFW->AddRegion("poiLambdaP", 0.4, 0.8, 1, 16); - fGFW->AddRegion("poiLambdaN", -0.8, -0.4, 1, 16); // MC fGFW->AddRegion("refN10MC", -0.8, -0.4, 1, 64); fGFW->AddRegion("refP10MC", 0.4, 0.8, 1, 64); @@ -506,15 +500,15 @@ struct FlowGfwOmegaXi { corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiXifulldpt {2} reffull {-2}", "XiFull22", kTRUE)); corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiOmegaPdpt {2} refN10 {-2}", "Omega10Gap22a", kTRUE)); corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiOmegaNdpt {2} refP10 {-2}", "Omega10Gap22b", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiOmegafulldpt reffull {2 2 -2 -2}", "Xi10Gap24", kTRUE)); // 10 + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiOmegafulldpt reffull {2 2 -2 -2}", "Omega10Gap24", kTRUE)); // 10 corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiOmegafulldpt {2} reffull {-2}", "OmegaFull22", kTRUE)); corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiK0sPdpt {2} refN10 {-2}", "K0short10Gap22a", kTRUE)); corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiK0sNdpt {2} refP10 {-2}", "K0short10Gap22b", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiK0sfulldpt reffull {2 2 -2 -2}", "Xi10Gap24", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiK0sfulldpt {2} reffull {-2}", "K0sFull22", kTRUE)); // 15 + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiK0sfulldpt reffull {2 2 -2 -2}", "K0short10Gap24", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiK0sfulldpt {2} reffull {-2}", "K0shortFull22", kTRUE)); // 15 corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiLambdaPdpt {2} refN10 {-2}", "Lambda10Gap22a", kTRUE)); corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiLambdaNdpt {2} refP10 {-2}", "Lambda10Gap22b", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiLambdafulldpt reffull {2 2 -2 -2}", "Xi10Gap24a", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiLambdafulldpt reffull {2 2 -2 -2}", "LambdaFull24", kTRUE)); corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiLambdafulldpt {2} reffull {-2}", "LambdaFull22", kTRUE)); corrconfigs.push_back(fGFW->GetCorrelatorConfig("refP10 {2} refN10 {-2}", "Ref10Gap22a", kFALSE)); // 20 corrconfigs.push_back(fGFW->GetCorrelatorConfig("reffull reffull {2 2 -2 -2}", "Ref10Gap24", kFALSE)); @@ -542,10 +536,12 @@ struct FlowGfwOmegaXi { corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiXiPdpt refN10 {2 2 -2 -2}", "Xi10Gap24a", kTRUE)); corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiXiNdpt refP10 {2 2 -2 -2}", "Xi10Gap24b", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiXifulldpt reffull | Xioldpt {2 -2}", "XiFullol22", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiOmegaPdpt refN10 {2 2 -2 -2}", "Xi10Gap24a", kTRUE)); - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiOmegaNdpt refP10 {2 2 -2 -2}", "Xi10Gap24b", kTRUE)); // 45 - corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiOmegafulldpt reffull | Omegaoldpt {2 -2}", "OmegaFullol22", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiXifulldpt {2} olxidaudpt {-2}", "XiFullol22", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiXifulldpt olxidaudpt {2 2 -2 -2}", "XiFullol24", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiOmegaPdpt refN10 {2 2 -2 -2}", "Omega10Gap24a", kTRUE)); // 45 + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiOmegaNdpt refP10 {2 2 -2 -2}", "Omega10Gap24b", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiOmegafulldpt {2} olomegadaudpt {-2}", "OmegaFullol22", kTRUE)); + corrconfigs.push_back(fGFW->GetCorrelatorConfig("poiOmegafulldpt olomegadaudpt {2 2 -2 -2}", "OmegaFullol24", kTRUE)); fGFW->CreateRegions(); // finalize the initialization // used for event selection @@ -706,6 +702,56 @@ struct FlowGfwOmegaXi { return; } + // remove auto-corr + template + void fillProfilepTMass(const GFW::CorrConfig& corrconf, const GFW::CorrConfig& corrconfol, const ConstStr& tarName, const int& ptbin, const int& PDGCode, const float& cent) + { + int nMassBins = 0; + int nptbins = 0; + TAxis* fMass = nullptr; + TAxis* fpt = nullptr; + if (PDGCode == kXiMinus) { + nMassBins = cfgmassbins[2]; + nptbins = nXiPtBins; + fpt = fXiPtAxis; + fMass = fXiMass; + } else if (PDGCode == kOmegaMinus) { + nMassBins = cfgmassbins[3]; + nptbins = nOmegaPtBins; + fpt = fOmegaPtAxis; + fMass = fOmegaMass; + } else if (PDGCode == kK0Short) { + nMassBins = cfgmassbins[0]; + nptbins = nK0sPtBins; + fpt = fK0sPtAxis; + fMass = fK0sMass; + } else if (PDGCode == kLambda0) { + nMassBins = cfgmassbins[1]; + nptbins = nLambdaPtBins; + fpt = fLambdaPtAxis; + fMass = fLambdaMass; + } else { + LOGF(error, "Error, please put in correct PDGCode of K0s, Lambda, Xi or Omega"); + return; + } + for (int massbin = 1; massbin <= nMassBins; massbin++) { + float dnx = 0; + float val = 0; + float dnxol = 0; + dnx = fGFW->Calculate(corrconf, (ptbin - 1) + ((massbin - 1) * nptbins), kTRUE).real(); + dnxol = fGFW->Calculate(corrconfol, (ptbin - 1) + ((massbin - 1) * nptbins), kTRUE).real(); + dnx = dnx - dnxol; + if (dnx == 0) + continue; + val = (fGFW->Calculate(corrconf, (ptbin - 1) + ((massbin - 1) * nptbins), kFALSE).real() - fGFW->Calculate(corrconfol, (ptbin - 1) + ((massbin - 1) * nptbins), kFALSE).real()) / dnx; + + if (std::fabs(val) < 1) { + registry.fill(tarName, fpt->GetBinCenter(ptbin), fMass->GetBinCenter(massbin), cent, val, dnx); + } + } + return; + } + // input shared_ptr void fillProfilepTMass(const GFW::CorrConfig& corrconf, std::shared_ptr TProfile3D, const int& ptbin, const int& PDGCode, const float& cent) { @@ -751,6 +797,54 @@ struct FlowGfwOmegaXi { return; } + // remove auto-corr + void fillProfilepTMass(const GFW::CorrConfig& corrconf, const GFW::CorrConfig& corrconfol, std::shared_ptr TProfile3D, const int& ptbin, const int& PDGCode, const float& cent) + { + int nMassBins = 0; + int nptbins = 0; + TAxis* fMass = nullptr; + TAxis* fpt = nullptr; + if (PDGCode == kXiMinus) { + nMassBins = cfgmassbins[2]; + nptbins = nXiPtBins; + fpt = fXiPtAxis; + fMass = fXiMass; + } else if (PDGCode == kOmegaMinus) { + nMassBins = cfgmassbins[3]; + nptbins = nOmegaPtBins; + fpt = fOmegaPtAxis; + fMass = fOmegaMass; + } else if (PDGCode == kK0Short) { + nMassBins = cfgmassbins[0]; + nptbins = nK0sPtBins; + fpt = fK0sPtAxis; + fMass = fK0sMass; + } else if (PDGCode == kLambda0) { + nMassBins = cfgmassbins[1]; + nptbins = nLambdaPtBins; + fpt = fLambdaPtAxis; + fMass = fLambdaMass; + } else { + LOGF(error, "Error, please put in correct PDGCode of K0s, Lambda, Xi or Omega"); + return; + } + for (int massbin = 1; massbin <= nMassBins; massbin++) { + float dnx = 0; + float val = 0; + float dnxol = 0; + dnx = fGFW->Calculate(corrconf, (ptbin - 1) + ((massbin - 1) * nptbins), kTRUE).real(); + dnxol = fGFW->Calculate(corrconfol, (ptbin - 1) + ((massbin - 1) * nptbins), kTRUE).real(); + dnx = dnx - dnxol; + if (dnx == 0) + continue; + val = (fGFW->Calculate(corrconf, (ptbin - 1) + ((massbin - 1) * nptbins), kFALSE).real() - fGFW->Calculate(corrconfol, (ptbin - 1) + ((massbin - 1) * nptbins), kFALSE).real()) / dnx; + if (std::fabs(val) < 1) { + TProfile3D->Fill(fpt->GetBinCenter(ptbin), fMass->GetBinCenter(massbin), cent, val, dnx); + } + } + return; + } + void loadCorrections(uint64_t timestamp) { if (correctionsLoaded) @@ -1191,10 +1285,10 @@ struct FlowGfwOmegaXi { if (!negdau.hasTPC() || !negdau.hasITS()) continue; } - if (isXi && (casc.mOmega() - o2::constants::physics::MassOmegaMinus) < cascBuilderOpts.cfgcasc_compmassrej.value) { + if (isXi && std::fabs(casc.mOmega() - o2::constants::physics::MassOmegaMinus) < cascBuilderOpts.cfgcasc_compmassrej.value) { isXi = false; } - if (isOmega && (casc.mXi() - o2::constants::physics::MassXiMinus) < cascBuilderOpts.cfgcasc_compmassrej.value) { + if (isOmega && std::fabs(casc.mXi() - o2::constants::physics::MassXiMinus) < cascBuilderOpts.cfgcasc_compmassrej.value) { isXi = false; } // fill QA @@ -1207,9 +1301,19 @@ struct FlowGfwOmegaXi { registry.fill(HIST("QAhisto/Casc/hqadcaCascV0dauafter"), casc.dcaV0daughters()); } + float weffBac = 1; + float weffPos = 1; + float weffNeg = 1; + float waccBac = 1; + float waccPos = 1; + float waccNeg = 1; if (isOmega) { - if (cfgDoAccEffCorr) + if (cfgDoAccEffCorr) { setCurrentParticleWeights(weff, wacc, casc, vtxz, 4); + setCurrentParticleWeights(weffBac, waccBac, bachelor, vtxz, 0); + setCurrentParticleWeights(weffPos, waccPos, posdau, vtxz, 0); + setCurrentParticleWeights(weffNeg, waccNeg, negdau, vtxz, 0); + } if (cfgDoLocDenCorr) { int phibin = -999; phibin = hLocalDensity->FindBin(RecoDecay::constrainAngle(casc.phi(), -constants::math::PI)); @@ -1221,17 +1325,20 @@ struct FlowGfwOmegaXi { registry.fill(HIST("hEtaPhiVtxzPOIOmega"), casc.phi(), casc.eta(), vtxz, wacc); registry.fill(HIST("InvMassOmega"), casc.pt(), casc.mOmega(), casc.eta(), cent); fGFW->Fill(casc.eta(), fOmegaPtAxis->FindBin(casc.pt()) - 1 + ((fOmegaMass->FindBin(casc.mOmega()) - 1) * nOmegaPtBins), casc.phi(), wacc * weff * wloc, 4); - - fGFW->Fill(casc.eta(), fOmegaPtAxis->FindBin(casc.pt()) - 1 + ((fOmegaMass->FindBin(casc.mOmega()) - 1) * nOmegaPtBins), bachelor.phi(), wacc * weff * wloc, 4096); - fGFW->Fill(casc.eta(), fOmegaPtAxis->FindBin(casc.pt()) - 1 + ((fOmegaMass->FindBin(casc.mOmega()) - 1) * nOmegaPtBins), posdau.phi(), wacc * weff * wloc, 4096); - fGFW->Fill(casc.eta(), fOmegaPtAxis->FindBin(casc.pt()) - 1 + ((fOmegaMass->FindBin(casc.mOmega()) - 1) * nOmegaPtBins), negdau.phi(), wacc * weff * wloc, 4096); + fGFW->Fill(bachelor.eta(), 1, bachelor.phi(), waccBac * weffBac * wloc, 4096); + fGFW->Fill(posdau.eta(), 1, posdau.phi(), waccPos * weffPos * wloc, 4096); + fGFW->Fill(negdau.eta(), 1, negdau.phi(), waccNeg * weffNeg * wloc, 4096); if (cfgOutputNUAWeights) fWeightsOmega->fill(casc.phi(), casc.eta(), vtxz, casc.pt(), cent, 0); } if (isXi) { - if (cfgDoAccEffCorr) + if (cfgDoAccEffCorr) { setCurrentParticleWeights(weff, wacc, casc, vtxz, 3); + setCurrentParticleWeights(weffBac, waccBac, bachelor, vtxz, 0); + setCurrentParticleWeights(weffPos, waccPos, posdau, vtxz, 0); + setCurrentParticleWeights(weffNeg, waccNeg, negdau, vtxz, 0); + } if (cfgDoLocDenCorr) { int phibin = -999; phibin = hLocalDensity->FindBin(RecoDecay::constrainAngle(casc.phi(), -constants::math::PI)); @@ -1243,10 +1350,9 @@ struct FlowGfwOmegaXi { registry.fill(HIST("hEtaPhiVtxzPOIXi"), casc.phi(), casc.eta(), vtxz, wacc); registry.fill(HIST("InvMassXi"), casc.pt(), casc.mXi(), casc.eta(), cent); fGFW->Fill(casc.eta(), fXiPtAxis->FindBin(casc.pt()) - 1 + ((fXiMass->FindBin(casc.mXi()) - 1) * nXiPtBins), casc.phi(), wacc * weff * wloc, 2); - - fGFW->Fill(casc.eta(), fXiPtAxis->FindBin(casc.pt()) - 1 + ((fXiMass->FindBin(casc.mXi()) - 1) * nXiPtBins), bachelor.phi(), wacc * weff * wloc, 2048); - fGFW->Fill(casc.eta(), fXiPtAxis->FindBin(casc.pt()) - 1 + ((fXiMass->FindBin(casc.mXi()) - 1) * nXiPtBins), posdau.phi(), wacc * weff * wloc, 2048); - fGFW->Fill(casc.eta(), fXiPtAxis->FindBin(casc.pt()) - 1 + ((fXiMass->FindBin(casc.mXi()) - 1) * nXiPtBins), negdau.phi(), wacc * weff * wloc, 2048); + fGFW->Fill(bachelor.eta(), 1, bachelor.phi(), waccBac * weffBac * wloc, 2048); + fGFW->Fill(posdau.eta(), 1, posdau.phi(), waccPos * weffPos * wloc, 2048); + fGFW->Fill(negdau.eta(), 1, negdau.phi(), waccNeg * weffNeg * wloc, 2048); if (cfgOutputNUAWeights) fWeightsXi->fill(casc.phi(), casc.eta(), vtxz, casc.pt(), cent, 0); @@ -1288,26 +1394,24 @@ struct FlowGfwOmegaXi { for (int i = 1; i <= nXiPtBins; i++) { fillProfilepTMass(corrconfigs.at(4), HIST("Xic22dpt"), i, kXiMinus, cent); fillProfilepTMass(corrconfigs.at(5), HIST("Xic22dpt"), i, kXiMinus, cent); - fillProfilepTMass(corrconfigs.at(6), HIST("Xic24dpt"), i, kXiMinus, cent); - fillProfilepTMass(corrconfigs.at(7), HIST("Xic22Fulldpt"), i, kXiMinus, cent); + fillProfilepTMass(corrconfigs.at(6), corrconfigs.at(44), HIST("Xic24dpt"), i, kXiMinus, cent); + fillProfilepTMass(corrconfigs.at(7), corrconfigs.at(43), HIST("Xic22Fulldpt"), i, kXiMinus, cent); fillProfilepTMass(corrconfigs.at(23), HIST("Xic32dpt"), i, kXiMinus, cent); fillProfilepTMass(corrconfigs.at(24), HIST("Xic32dpt"), i, kXiMinus, cent); fillProfilepTMass(corrconfigs.at(41), HIST("Xic24_gapdpt"), i, kXiMinus, cent); fillProfilepTMass(corrconfigs.at(42), HIST("Xic24_gapdpt"), i, kXiMinus, cent); - fillProfilepTMass(corrconfigs.at(43), HIST("Xic22Full_oldpt"), i, kXiMinus, cent); } for (int i = 1; i <= nOmegaPtBins; i++) { fillProfilepTMass(corrconfigs.at(8), HIST("Omegac22dpt"), i, kOmegaMinus, cent); fillProfilepTMass(corrconfigs.at(9), HIST("Omegac22dpt"), i, kOmegaMinus, cent); - fillProfilepTMass(corrconfigs.at(10), HIST("Omegac24dpt"), i, kOmegaMinus, cent); - fillProfilepTMass(corrconfigs.at(11), HIST("Omegac22Fulldpt"), i, kOmegaMinus, cent); + fillProfilepTMass(corrconfigs.at(10), corrconfigs.at(48), HIST("Omegac24dpt"), i, kOmegaMinus, cent); + fillProfilepTMass(corrconfigs.at(11), corrconfigs.at(47), HIST("Omegac22Fulldpt"), i, kOmegaMinus, cent); fillProfilepTMass(corrconfigs.at(25), HIST("Omegac32dpt"), i, kOmegaMinus, cent); fillProfilepTMass(corrconfigs.at(26), HIST("Omegac32dpt"), i, kOmegaMinus, cent); - fillProfilepTMass(corrconfigs.at(44), HIST("Omegac24_gapdpt"), i, kOmegaMinus, cent); fillProfilepTMass(corrconfigs.at(45), HIST("Omegac24_gapdpt"), i, kOmegaMinus, cent); - fillProfilepTMass(corrconfigs.at(46), HIST("Omegac22Full_oldpt"), i, kOmegaMinus, cent); + fillProfilepTMass(corrconfigs.at(46), HIST("Omegac24_gapdpt"), i, kOmegaMinus, cent); } } // Fill subevents flow @@ -1344,16 +1448,16 @@ struct FlowGfwOmegaXi { for (int i = 1; i <= nXiPtBins; i++) { fillProfilepTMass(corrconfigs.at(4), xic22[j - 1], i, kXiMinus, cent); fillProfilepTMass(corrconfigs.at(5), xic22[j - 1], i, kXiMinus, cent); - fillProfilepTMass(corrconfigs.at(6), xic24[j - 1], i, kXiMinus, cent); - fillProfilepTMass(corrconfigs.at(7), xic22Full[j - 1], i, kXiMinus, cent); + fillProfilepTMass(corrconfigs.at(6), corrconfigs.at(44), xic24[j - 1], i, kXiMinus, cent); + fillProfilepTMass(corrconfigs.at(7), corrconfigs.at(43), xic22Full[j - 1], i, kXiMinus, cent); fillProfilepTMass(corrconfigs.at(23), xic32[j - 1], i, kXiMinus, cent); fillProfilepTMass(corrconfigs.at(24), xic32[j - 1], i, kXiMinus, cent); } for (int i = 1; i <= nOmegaPtBins; i++) { fillProfilepTMass(corrconfigs.at(8), omegac22[j - 1], i, kOmegaMinus, cent); fillProfilepTMass(corrconfigs.at(9), omegac22[j - 1], i, kOmegaMinus, cent); - fillProfilepTMass(corrconfigs.at(10), omegac24[j - 1], i, kOmegaMinus, cent); - fillProfilepTMass(corrconfigs.at(11), omegac22Full[j - 1], i, kOmegaMinus, cent); + fillProfilepTMass(corrconfigs.at(10), corrconfigs.at(48), omegac24[j - 1], i, kOmegaMinus, cent); + fillProfilepTMass(corrconfigs.at(11), corrconfigs.at(47), omegac22Full[j - 1], i, kOmegaMinus, cent); fillProfilepTMass(corrconfigs.at(25), omegac32[j - 1], i, kOmegaMinus, cent); fillProfilepTMass(corrconfigs.at(26), omegac32[j - 1], i, kOmegaMinus, cent); } diff --git a/PWGCF/Flow/Tasks/flowMc.cxx b/PWGCF/Flow/Tasks/flowMc.cxx index 682eeece738..5884fa0e127 100644 --- a/PWGCF/Flow/Tasks/flowMc.cxx +++ b/PWGCF/Flow/Tasks/flowMc.cxx @@ -67,6 +67,13 @@ struct FlowMc { O2_DEFINE_CONFIGURABLE(cfgCutITSclu, float, 5.0f, "minimum ITS clusters") O2_DEFINE_CONFIGURABLE(cfgCutChi2prTPCcls, float, 2.5f, "max chi2 per TPC clusters") O2_DEFINE_CONFIGURABLE(cfgCutTPCcrossedrows, float, 70.0f, "minimum TPC crossed rows") + O2_DEFINE_CONFIGURABLE(cfgCutDCAxy, float, 0.2f, "DCAxy cut for tracks") + O2_DEFINE_CONFIGURABLE(cfgDCAxyNSigma, float, 7, "Cut on number of sigma deviations from expected DCA in the transverse direction"); + O2_DEFINE_CONFIGURABLE(cfgDCAxyFunction, std::string, "(0.0015+0.005/(x^1.1))", "Functional form of pt-dependent DCAxy cut"); + O2_DEFINE_CONFIGURABLE(cfgCutDCAz, float, 2.0f, "DCAz cut for tracks") + O2_DEFINE_CONFIGURABLE(cfgCutDCAzPtDepEnabled, bool, false, "switch of DCAz pt dependent cut") + O2_DEFINE_CONFIGURABLE(cfgEnableITSCuts, bool, true, "switch of enabling ITS based track selection cuts") + O2_DEFINE_CONFIGURABLE(cfgTrkSelRun3ITSMatch, bool, false, "GlobalTrackRun3ITSMatching::Run3ITSall7Layers selection") O2_DEFINE_CONFIGURABLE(cfgFlowAcceptance, std::string, "", "CCDB path to acceptance object") O2_DEFINE_CONFIGURABLE(cfgFlowEfficiency, std::string, "", "CCDB path to efficiency object") O2_DEFINE_CONFIGURABLE(cfgCentVsIPTruth, std::string, "", "CCDB path to centrality vs IP truth") @@ -103,6 +110,10 @@ struct FlowMc { // using FilteredTracks = soa::Join; + // Additional filters for tracks + TrackSelection myTrackSel; + TF1* fPtDepDCAxy = nullptr; + // Cent vs IP TH1D* mCentVsIPTruth = nullptr; bool centVsIPTruthLoaded = false; @@ -247,6 +258,28 @@ struct FlowMc { fGFWReco->CreateRegions(); } + if (cfgEnableITSCuts) { + if (cfgTrkSelRun3ITSMatch) { + myTrackSel = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSall7Layers, TrackSelection::GlobalTrackRun3DCAxyCut::Default); + } else { + myTrackSel = getGlobalTrackSelectionRun3ITSMatch(TrackSelection::GlobalTrackRun3ITSMatching::Run3ITSibAny, TrackSelection::GlobalTrackRun3DCAxyCut::Default); + } + } + if (cfgCutDCAxy != 0.0) { + myTrackSel.SetMaxDcaXY(cfgCutDCAxy); + } else { + fPtDepDCAxy = new TF1("ptDepDCAxy", Form("[0]*%s", cfgDCAxyFunction->c_str()), 0.001, 100); + fPtDepDCAxy->SetParameter(0, cfgDCAxyNSigma); + LOGF(info, "DCAxy pt-dependence function: %s", Form("[0]*%s", cfgDCAxyFunction->c_str())); + myTrackSel.SetMaxDcaXYPtDep([fPtDepDCAxy = this->fPtDepDCAxy](float pt) { return fPtDepDCAxy->Eval(pt); }); + } + myTrackSel.SetMinNClustersTPC(cfgCutTPCclu); + myTrackSel.SetMinNCrossedRowsTPC(cfgCutTPCcrossedrows); + if (cfgEnableITSCuts) + myTrackSel.SetMinNClustersITS(cfgCutITSclu); + if (!cfgCutDCAzPtDepEnabled) + myTrackSel.SetMaxDcaZ(cfgCutDCAz); + if (cfgTrackDensityCorrUse) { std::vector pTEffBins = {0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.4, 1.8, 2.2, 2.6, 3.0}; hFindPtBin = new TH1D("hFindPtBin", "hFindPtBin", pTEffBins.size() - 1, &pTEffBins[0]); @@ -378,7 +411,10 @@ struct FlowMc { template bool trackSelected(TTrack track) { - return ((track.tpcNClsFound() >= cfgCutTPCclu) && (track.tpcNClsCrossedRows() >= cfgCutTPCcrossedrows) && (track.itsNCls() >= cfgCutITSclu)); + if (cfgCutDCAzPtDepEnabled && (track.dcaZ() > (0.004f + 0.013f / track.pt()))) { + return false; + } + return myTrackSel.IsSelected(track); } void process(FilteredMcCollisions::iterator const& mcCollision, aod::BCsWithTimestamps const&, soa::SmallGroups> const& collisions, FilteredMcParticles const& mcParticles, FilteredTracks const&) diff --git a/PWGCF/Flow/Tasks/flowPidCme.cxx b/PWGCF/Flow/Tasks/flowPidCme.cxx index bd91bdc4450..2e55268a334 100644 --- a/PWGCF/Flow/Tasks/flowPidCme.cxx +++ b/PWGCF/Flow/Tasks/flowPidCme.cxx @@ -9,44 +9,45 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \author ZhengqingWang(zhengqing.wang@cern.ch) +/// \author ZhengqingWang(zhengqing.wang@cern.ch), KegangXiong(kxiong@cern.ch) /// \file flowPidCme.cxx /// \brief task to calculate the pikp cme signal and bacground. // C++/ROOT includes. #include -#include -#include -#include -#include -#include -#include + #include +#include #include #include #include #include -// o2Physics includes. -#include "Framework/ASoA.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/StaticFor.h" +#include +#include +#include +#include +#include -#include "Common/DataModel/Qvectors.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/Multiplicity.h" +// o2Physics includes. #include "Common/Core/EventPlaneHelper.h" #include "Common/Core/TrackSelection.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/PIDResponseITS.h" +#include "Common/DataModel/Qvectors.h" +#include "Common/DataModel/TrackSelectionTables.h" #include "CommonConstants/PhysicsConstants.h" +#include "Framework/ASoA.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/StaticFor.h" +#include "Framework/runDataProcessing.h" // o2 includes. @@ -158,6 +159,7 @@ struct FillPIDcolums { Configurable cfgOpenITSCut{"cfgOpenITSCut", true, "open ITSnsigma cut"}; Configurable cfgOpenITSCutQAPlots{"cfgOpenITSCutQAPlots", true, "open QA plots after ITS nsigma cut"}; Configurable cfgOpenDetailPlotsTPCITSContaimination{"cfgOpenDetailPlotsTPCITSContaimination", false, "open detail TH3D plots for nSigmaTPC-ITS Pt-eta-Phi nSigmaITS-clustersize"}; + Configurable cfgUseStrictPID{"cfgUseStrictPID", true, "More strict pid strategy"}; Configurable cfgOpenAllowCrossTrack{"cfgOpenAllowCrossTrack", false, "Allow one track to be identified as different kind of PID particles"}; Configurable cfgOpenCrossTrackQAPlots{"cfgOpenCrossTrackQAPlots", true, "open cross pid track QA plots"}; Configurable cfgOpenTOFOnlyPID{"cfgOpenTOFOnlyPID", true, "only accept tracks who has TOF infomation and use TOFnsigma for PID(priority greater than TPConly and combined"}; @@ -311,9 +313,17 @@ struct FillPIDcolums { pidVectorUpper = pidVectorTPCPtUpper; pidVectorLower = pidVectorTPCPtLower; } else { - nSigmaToUse = (candidate.pt() > cfgPtMaxforTPCOnlyPID && candidate.hasTOF()) ? nSigmaCombined : nSigmaTPC; - pidVectorUpper = (candidate.pt() > cfgPtMaxforTPCOnlyPID && candidate.hasTOF()) ? cfgnSigmaCutRMSUpper.value : cfgnSigmaCutTPCUpper.value; - pidVectorLower = (candidate.pt() > cfgPtMaxforTPCOnlyPID && candidate.hasTOF()) ? cfgnSigmaCutRMSLower.value : cfgnSigmaCutTPCLower.value; + if (candidate.pt() > cfgPtMaxforTPCOnlyPID && candidate.hasTOF()) { + nSigmaToUse = nSigmaCombined; + pidVectorUpper = cfgnSigmaCutRMSUpper.value; + pidVectorLower = cfgnSigmaCutRMSLower.value; + } else if (candidate.pt() > cfgPtMaxforTPCOnlyPID && !candidate.hasTOF() && cfgUseStrictPID) { + return 0; + } else { + nSigmaToUse = nSigmaTPC; + pidVectorUpper = cfgnSigmaCutTPCUpper.value; + pidVectorLower = cfgnSigmaCutTPCLower.value; + } } float nsigma = 9999.99; const int nPOI = 3; @@ -448,20 +458,27 @@ struct FillPIDcolums { } } } - if (cfgOpenAllowCrossTrack) { - // one track can be recognized as different PID particles + if (cfgUseStrictPID) { + // Only use the track which was recognized as an unique PID particle int index = (kIsPr << 2) | (kIsKa << 1) | kIsPi; - const int map[] = {0, 1, 2, 7, 3, 8, 9, 10}; + const int map[] = {0, 1, 2, 0, 3, 0, 0, 0}; return map[index]; } else { - // Select particle with the lowest nsigma (If not allow cross track) - for (int i = 0; i < nPOI; ++i) { - if (std::abs(nSigmaToUse[i]) < nsigma && (nSigmaToUse[i] > pidVectorLower[i] && nSigmaToUse[i] < pidVectorUpper[i])) { - pid = i; - nsigma = std::abs(nSigmaToUse[i]); + if (cfgOpenAllowCrossTrack) { + // one track can be recognized as different PID particles + int index = (kIsPr << 2) | (kIsKa << 1) | kIsPi; + const int map[] = {0, 1, 2, 7, 3, 8, 9, 10}; + return map[index]; + } else { + // Select particle with the lowest nsigma (If not allow cross track) + for (int i = 0; i < nPOI; ++i) { + if (std::abs(nSigmaToUse[i]) < nsigma && (nSigmaToUse[i] > pidVectorLower[i] && nSigmaToUse[i] < pidVectorUpper[i])) { + pid = i; + nsigma = std::abs(nSigmaToUse[i]); + } } + return pid + 1; // shift the pid by 1, 1 = pion, 2 = kaon, 3 = proton } - return pid + 1; // shift the pid by 1, 1 = pion, 2 = kaon, 3 = proton } // Clear the vectors std::vector().swap(pidVectorLower); @@ -2682,8 +2699,9 @@ struct FlowPidCme { int detInd = detId * 4 + cfgnTotalSystem * 4 * (nmode - 2); int refAInd = refAId * 4 + cfgnTotalSystem * 4 * (nmode - 2); int refBInd = refBId * 4 + cfgnTotalSystem * 4 * (nmode - 2); + double nonzero = 1e-8; if (nmode == fourier_mode::kMode2) { - if (collision.qvecAmp()[detId] > 1e-8) { + if (collision.qvecAmp()[detId] > nonzero) { histosQA.fill(HIST("QA/histQvec_CorrL0_V2"), collision.qvecRe()[detInd], collision.qvecIm()[detInd], collision.centFT0C()); histosQA.fill(HIST("QA/histQvec_CorrL1_V2"), collision.qvecRe()[detInd + 1], collision.qvecIm()[detInd + 1], collision.centFT0C()); histosQA.fill(HIST("QA/histQvec_CorrL2_V2"), collision.qvecRe()[detInd + 2], collision.qvecIm()[detInd + 2], collision.centFT0C()); @@ -2693,7 +2711,7 @@ struct FlowPidCme { histosQA.fill(HIST("QA/histEvtPl_CorrL2_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 2], collision.qvecIm()[detInd + 2], nmode), collision.centFT0C()); histosQA.fill(HIST("QA/histEvtPl_CorrL3_V2"), helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), collision.centFT0C()); } - if (collision.qvecAmp()[detId] > 1e-8 && collision.qvecAmp()[refAId] > 1e-8 && collision.qvecAmp()[refBId] > 1e-8) { + if (collision.qvecAmp()[detId] > nonzero && collision.qvecAmp()[refAId] > nonzero && collision.qvecAmp()[refBId] > nonzero) { histosQA.fill(HIST("QA/histQvecRes_SigRefAV2"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refAInd + 3], collision.qvecIm()[refAInd + 3], nmode), nmode), collision.centFT0C()); histosQA.fill(HIST("QA/histQvecRes_SigRefBV2"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[detInd + 3], collision.qvecIm()[detInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], nmode), nmode), collision.centFT0C()); histosQA.fill(HIST("QA/histQvecRes_RefARefBV2"), helperEP.GetResolution(helperEP.GetEventPlane(collision.qvecRe()[refAInd + 3], collision.qvecIm()[refAInd + 3], nmode), helperEP.GetEventPlane(collision.qvecRe()[refBInd + 3], collision.qvecIm()[refBInd + 3], nmode), nmode), collision.centFT0C()); @@ -2704,7 +2722,8 @@ struct FlowPidCme { template void fillHistosFlowGammaDelta(const CollType& collision, const TrackType& track1, const TrackType& track2, const TrackType& track3, int nmode) { - if (collision.qvecAmp()[detId] < 1e-8) { + double nonzero2 = 1e-8; + if (collision.qvecAmp()[detId] < nonzero2) { return; } auto cent = collision.centFT0C(); diff --git a/PWGCF/Flow/Tasks/flowRunbyRun.cxx b/PWGCF/Flow/Tasks/flowRunbyRun.cxx index 620063e1d5d..9259eb8be9e 100644 --- a/PWGCF/Flow/Tasks/flowRunbyRun.cxx +++ b/PWGCF/Flow/Tasks/flowRunbyRun.cxx @@ -68,6 +68,7 @@ struct FlowRunbyRun { O2_DEFINE_CONFIGURABLE(cfgCutDCAz, float, 2.0f, "max DCA to vertex z") O2_DEFINE_CONFIGURABLE(cfgCutDCAzPtDepEnabled, bool, false, "switch of DCAz pt dependent cut") O2_DEFINE_CONFIGURABLE(cfgUseAdditionalEventCut, bool, false, "Use additional event cut on mult correlations") + O2_DEFINE_CONFIGURABLE(cfgOutputCorrelationQA, bool, false, "Fill correlation QA histograms") O2_DEFINE_CONFIGURABLE(cfgEvSelkNoSameBunchPileup, bool, false, "rejects collisions which are associated with the same found-by-T0 bunch crossing") O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodZvtxFT0vsPV, bool, false, "removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference, use this cut at low multiplicities with caution") O2_DEFINE_CONFIGURABLE(cfgEvSelkNoCollInTimeRangeStandard, bool, false, "no collisions in specified time range") @@ -101,6 +102,10 @@ struct FlowRunbyRun { ConfigurableAxis axisEta{"axisEta", {40, -1., 1.}, "eta axis for histograms"}; ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.2, 2.4, 2.6, 2.8, 3, 3.5, 4, 5, 6, 8, 10}, "pt axis for histograms"}; ConfigurableAxis axisIndependent{"axisIndependent", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90}, "X axis for histograms"}; + ConfigurableAxis axisNch{"axisNch", {4000, 0, 4000}, "N_{ch}"}; + ConfigurableAxis axisCentForQA{"axisCentForQA", {100, 0, 100}, "centrality (%)"}; + ConfigurableAxis axisT0C{"axisT0C", {70, 0, 70000}, "N_{ch} (T0C)"}; + ConfigurableAxis axisT0A{"axisT0A", {200, 0, 200000}, "N_{ch} (T0A)"}; Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; Filter trackFilter = ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); @@ -113,7 +118,6 @@ struct FlowRunbyRun { // Connect to ccdb Service ccdb; - Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; // Define output @@ -129,6 +133,7 @@ struct FlowRunbyRun { int lastRunNumer = -1; std::vector runNumbers; // vector of run numbers std::map>> th1sList; // map of histograms for all runs + std::map>> th2sList; // map of TH2 histograms for all runs std::map>> th3sList; // map of TH3 histograms for all runs std::map>> profilesList; // map of profiles for all runs enum OutputTH1Names { @@ -142,6 +147,14 @@ struct FlowRunbyRun { hEventCountSpecific, kCount_TH1Names }; + enum OutputTH2Names { + // here are TH2 histograms + hglobalTracks_centT0C = 0, + hglobalTracks_PVTracks, + hglobalTracks_multV0A, + hcentFV0A_centFT0C, + kCount_TH2Names + }; enum OutputTH3Names { hPhiEtaVtxz = 0, kCount_TH3Names @@ -170,14 +183,15 @@ struct FlowRunbyRun { TF1* fT0AV0AMean = nullptr; TF1* fT0AV0ASigma = nullptr; - using AodCollisions = soa::Filtered>; + using AodCollisions = soa::Filtered>; using AodTracks = soa::Filtered>; void init(InitContext const&) { ccdb->setURL(ccdbUrl.value); ccdb->setCaching(true); - ccdb->setCreatedNotAfter(ccdbNoLaterThan.value); + auto now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + ccdb->setCreatedNotAfter(now); // Add output histograms to the registry runNumbers = cfgRunNumbers; @@ -358,6 +372,15 @@ struct FlowRunbyRun { histos[hEventCountSpecific]->GetXaxis()->SetBinLabel(10, "cfgEvSelV0AT0ACut"); th1sList.insert(std::make_pair(runNumber, histos)); + if (cfgOutputCorrelationQA) { + std::vector> th2s(kCount_TH2Names); + th2s[hglobalTracks_centT0C] = registry.add(Form("%d/globalTracks_centT0C", runNumber), "after cut;Centrality T0C;mulplicity global tracks", {HistType::kTH2D, {axisCentForQA, axisNch}}); + th2s[hglobalTracks_PVTracks] = registry.add(Form("%d/globalTracks_PVTracks", runNumber), "after cut;mulplicity PV tracks;mulplicity global tracks", {HistType::kTH2D, {axisNch, axisNch}}); + th2s[hglobalTracks_multV0A] = registry.add(Form("%d/globalTracks_multV0A", runNumber), "after cut;mulplicity V0A;mulplicity global tracks", {HistType::kTH2D, {axisT0A, axisNch}}); + th2s[hcentFV0A_centFT0C] = registry.add(Form("%d/centFV0A_centFT0C", runNumber), "after cut;Centrality T0C;Centrality V0A", {HistType::kTH2D, {axisCentForQA, axisCentForQA}}); + th2sList.insert(std::make_pair(runNumber, th2s)); + } + std::vector> profiles(kCount_TProfileNames); profiles[c22] = registry.add(Form("%d/c22", runNumber), "", {HistType::kTProfile, {axisIndependent}}); profiles[c22_gap10] = registry.add(Form("%d/c22_gap10", runNumber), "", {HistType::kTProfile, {axisIndependent}}); @@ -455,7 +478,8 @@ struct FlowRunbyRun { th1sList[runNumber][hEventCountSpecific]->Fill(8.5); // V0A T0A 5 sigma cut - if (cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > 5 * fT0AV0ASigma->Eval(collision.multFT0A()))) + float nSigma = 5.; // 5 sigma cut + if (cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > nSigma * fT0AV0ASigma->Eval(collision.multFT0A()))) return 0; if (cfgEvSelV0AT0ACut) th1sList[runNumber][hEventCountSpecific]->Fill(9.5); @@ -511,6 +535,12 @@ struct FlowRunbyRun { th1sList[runNumber][hVtxZ]->Fill(collision.posZ()); th1sList[runNumber][hMult]->Fill(tracks.size()); th1sList[runNumber][hCent]->Fill(collision.centFT0C()); + if (cfgOutputCorrelationQA) { + th2sList[runNumber][hglobalTracks_centT0C]->Fill(collision.centFT0C(), tracks.size()); + th2sList[runNumber][hglobalTracks_PVTracks]->Fill(collision.multNTracksPV(), tracks.size()); + th2sList[runNumber][hglobalTracks_multV0A]->Fill(collision.multFV0A(), tracks.size()); + th2sList[runNumber][hcentFV0A_centFT0C]->Fill(collision.centFT0C(), collision.centFV0A()); + } loadCorrections(bc.timestamp(), runNumber); diff --git a/PWGCF/Flow/Tasks/flowTask.cxx b/PWGCF/Flow/Tasks/flowTask.cxx index 158cb8820d9..9f27ffa0005 100644 --- a/PWGCF/Flow/Tasks/flowTask.cxx +++ b/PWGCF/Flow/Tasks/flowTask.cxx @@ -119,13 +119,28 @@ struct FlowTask { Configurable> cfgMultT0CCutPars{"cfgMultT0CCutPars", std::vector{143.04, -4.58368, 0.0766055, -0.000727796, 2.86153e-06, 23.3108, -0.36304, 0.00437706, -4.717e-05, 1.98332e-07}, "Global multiplicity vs T0C centrality cut parameter values"}; O2_DEFINE_CONFIGURABLE(cfgMultPVT0CCutEnabled, bool, false, "Enable PV multiplicity vs T0C centrality cut") Configurable> cfgMultPVT0CCutPars{"cfgMultPVT0CCutPars", std::vector{195.357, -6.15194, 0.101313, -0.000955828, 3.74793e-06, 30.0326, -0.43322, 0.00476265, -5.11206e-05, 2.13613e-07}, "PV multiplicity vs T0C centrality cut parameter values"}; - O2_DEFINE_CONFIGURABLE(cfgMultMultHighCutFunction, std::string, "[0]+[1]*x + 5.*([2]+[3]*x)", "Functional for multiplicity correlation cut"); - O2_DEFINE_CONFIGURABLE(cfgMultMultLowCutFunction, std::string, "[0]+[1]*x - 5.*([2]+[3]*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultMultPVHighCutFunction, std::string, "[0]+[1]*x + 5.*([2]+[3]*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultMultPVLowCutFunction, std::string, "[0]+[1]*x - 5.*([2]+[3]*x)", "Functional for multiplicity correlation cut"); O2_DEFINE_CONFIGURABLE(cfgMultGlobalPVCutEnabled, bool, false, "Enable global multiplicity vs PV multiplicity cut") Configurable> cfgMultGlobalPVCutPars{"cfgMultGlobalPVCutPars", std::vector{-0.140809, 0.734344, 2.77495, 0.0165935}, "PV multiplicity vs T0C centrality cut parameter values"}; + O2_DEFINE_CONFIGURABLE(cfgMultMultV0AHighCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x + 4.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultMultV0ALowCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x - 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultMultV0ACutEnabled, bool, false, "Enable global multiplicity vs V0A multiplicity cut") + Configurable> cfgMultMultV0ACutPars{"cfgMultMultV0ACutPars", std::vector{534.893, 184.344, 0.423539, -0.00331436, 5.34622e-06, 871.239, 53.3735, -0.203528, 0.000122758, 5.41027e-07}, "Global multiplicity vs V0A multiplicity cut parameter values"}; std::vector multT0CCutPars; std::vector multPVT0CCutPars; std::vector multGlobalPVCutPars; + std::vector multMultV0ACutPars; + TF1* fMultPVT0CCutLow = nullptr; + TF1* fMultPVT0CCutHigh = nullptr; + TF1* fMultT0CCutLow = nullptr; + TF1* fMultT0CCutHigh = nullptr; + TF1* fMultGlobalPVCutLow = nullptr; + TF1* fMultGlobalPVCutHigh = nullptr; + TF1* fMultMultV0ACutLow = nullptr; + TF1* fMultMultV0ACutHigh = nullptr; + TF1* fT0AV0AMean = nullptr; + TF1* fT0AV0ASigma = nullptr; } cfgFuncParas; ConfigurableAxis axisPtHist{"axisPtHist", {100, 0., 10.}, "pt axis for histograms"}; @@ -198,16 +213,6 @@ struct FlowTask { TF1* funcV3; TF1* funcV4; - // Additional Event selection cuts - Copy from flowGenericFramework.cxx - TF1* fMultPVT0CCutLow = nullptr; - TF1* fMultPVT0CCutHigh = nullptr; - TF1* fMultT0CCutLow = nullptr; - TF1* fMultT0CCutHigh = nullptr; - TF1* fMultGlobalPVCutLow = nullptr; - TF1* fMultGlobalPVCutHigh = nullptr; - TF1* fT0AV0AMean = nullptr; - TF1* fT0AV0ASigma = nullptr; - void init(InitContext const&) { const AxisSpec axisVertex{40, -20, 20, "Vtxz (cm)"}; @@ -246,11 +251,11 @@ struct FlowTask { registry.add("hVtxZ", "Vexter Z distribution", {HistType::kTH1D, {axisVertex}}); registry.add("hMult", "Multiplicity distribution", {HistType::kTH1D, {{3000, 0.5, 3000.5}}}); std::string hCentTitle = "Centrality distribution, Estimator " + std::to_string(cfgCentEstimator); - registry.add("hCent", hCentTitle.c_str(), {HistType::kTH1D, {{90, 0, 90}}}); + registry.add("hCent", hCentTitle.c_str(), {HistType::kTH1D, {{100, 0, 100}}}); if (doprocessMCGen) { registry.add("MCGen/MChVtxZ", "Vexter Z distribution", {HistType::kTH1D, {axisVertex}}); registry.add("MCGen/MChMult", "Multiplicity distribution", {HistType::kTH1D, {{3000, 0.5, 3000.5}}}); - registry.add("MCGen/MChCent", hCentTitle.c_str(), {HistType::kTH1D, {{90, 0, 90}}}); + registry.add("MCGen/MChCent", hCentTitle.c_str(), {HistType::kTH1D, {{100, 0, 100}}}); } if (!cfgUseSmallMemory) { registry.add("BeforeSel8_globalTracks_centT0C", "before sel8;Centrality T0C;mulplicity global tracks", {HistType::kTH2D, {axisCentForQA, axisNch}}); @@ -469,25 +474,31 @@ struct FlowTask { cfgFuncParas.multT0CCutPars = cfgFuncParas.cfgMultT0CCutPars; cfgFuncParas.multPVT0CCutPars = cfgFuncParas.cfgMultPVT0CCutPars; cfgFuncParas.multGlobalPVCutPars = cfgFuncParas.cfgMultGlobalPVCutPars; - fMultPVT0CCutLow = new TF1("fMultPVT0CCutLow", cfgFuncParas.cfgMultCentLowCutFunction->c_str(), 0, 100); - fMultPVT0CCutLow->SetParameters(&(cfgFuncParas.multPVT0CCutPars[0])); - fMultPVT0CCutHigh = new TF1("fMultPVT0CCutHigh", cfgFuncParas.cfgMultCentHighCutFunction->c_str(), 0, 100); - fMultPVT0CCutHigh->SetParameters(&(cfgFuncParas.multPVT0CCutPars[0])); + cfgFuncParas.multMultV0ACutPars = cfgFuncParas.cfgMultMultV0ACutPars; + cfgFuncParas.fMultPVT0CCutLow = new TF1("fMultPVT0CCutLow", cfgFuncParas.cfgMultCentLowCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultPVT0CCutLow->SetParameters(&(cfgFuncParas.multPVT0CCutPars[0])); + cfgFuncParas.fMultPVT0CCutHigh = new TF1("fMultPVT0CCutHigh", cfgFuncParas.cfgMultCentHighCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultPVT0CCutHigh->SetParameters(&(cfgFuncParas.multPVT0CCutPars[0])); + + cfgFuncParas.fMultT0CCutLow = new TF1("fMultT0CCutLow", cfgFuncParas.cfgMultCentLowCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultT0CCutLow->SetParameters(&(cfgFuncParas.multT0CCutPars[0])); + cfgFuncParas.fMultT0CCutHigh = new TF1("fMultT0CCutHigh", cfgFuncParas.cfgMultCentHighCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultT0CCutHigh->SetParameters(&(cfgFuncParas.multT0CCutPars[0])); - fMultT0CCutLow = new TF1("fMultT0CCutLow", cfgFuncParas.cfgMultCentLowCutFunction->c_str(), 0, 100); - fMultT0CCutLow->SetParameters(&(cfgFuncParas.multT0CCutPars[0])); - fMultT0CCutHigh = new TF1("fMultT0CCutHigh", cfgFuncParas.cfgMultCentHighCutFunction->c_str(), 0, 100); - fMultT0CCutHigh->SetParameters(&(cfgFuncParas.multT0CCutPars[0])); + cfgFuncParas.fMultGlobalPVCutLow = new TF1("fMultGlobalPVCutLow", cfgFuncParas.cfgMultMultPVLowCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultGlobalPVCutLow->SetParameters(&(cfgFuncParas.multGlobalPVCutPars[0])); + cfgFuncParas.fMultGlobalPVCutHigh = new TF1("fMultGlobalPVCutHigh", cfgFuncParas.cfgMultMultPVHighCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultGlobalPVCutHigh->SetParameters(&(cfgFuncParas.multGlobalPVCutPars[0])); - fMultGlobalPVCutLow = new TF1("fMultGlobalPVCutLow", cfgFuncParas.cfgMultMultLowCutFunction->c_str(), 0, 4000); - fMultGlobalPVCutLow->SetParameters(&(cfgFuncParas.multGlobalPVCutPars[0])); - fMultGlobalPVCutHigh = new TF1("fMultGlobalPVCutHigh", cfgFuncParas.cfgMultMultHighCutFunction->c_str(), 0, 4000); - fMultGlobalPVCutHigh->SetParameters(&(cfgFuncParas.multGlobalPVCutPars[0])); + cfgFuncParas.fMultMultV0ACutLow = new TF1("fMultMultV0ACutLow", cfgFuncParas.cfgMultMultV0ALowCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultMultV0ACutLow->SetParameters(&(cfgFuncParas.multMultV0ACutPars[0])); + cfgFuncParas.fMultMultV0ACutHigh = new TF1("fMultMultV0ACutHigh", cfgFuncParas.cfgMultMultV0AHighCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultMultV0ACutHigh->SetParameters(&(cfgFuncParas.multMultV0ACutPars[0])); - fT0AV0AMean = new TF1("fT0AV0AMean", "[0]+[1]*x", 0, 200000); - fT0AV0AMean->SetParameters(-1601.0581, 9.417652e-01); - fT0AV0ASigma = new TF1("fT0AV0ASigma", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 200000); - fT0AV0ASigma->SetParameters(463.4144, 6.796509e-02, -9.097136e-07, 7.971088e-12, -2.600581e-17); + cfgFuncParas.fT0AV0AMean = new TF1("fT0AV0AMean", "[0]+[1]*x", 0, 200000); + cfgFuncParas.fT0AV0AMean->SetParameters(-1601.0581, 9.417652e-01); + cfgFuncParas.fT0AV0ASigma = new TF1("fT0AV0ASigma", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 200000); + cfgFuncParas.fT0AV0ASigma->SetParameters(463.4144, 6.796509e-02, -9.097136e-07, 7.971088e-12, -2.600581e-17); } if (cfgTrackDensityCorrUse) { @@ -682,21 +693,27 @@ struct FlowTask { if (cfgEvSelMultCorrelation) { if (cfgFuncParas.cfgMultPVT0CCutEnabled) { - if (multNTracksPV < fMultPVT0CCutLow->Eval(centrality)) + if (multNTracksPV < cfgFuncParas.fMultPVT0CCutLow->Eval(centrality)) return 0; - if (multNTracksPV > fMultPVT0CCutHigh->Eval(centrality)) + if (multNTracksPV > cfgFuncParas.fMultPVT0CCutHigh->Eval(centrality)) return 0; } if (cfgFuncParas.cfgMultT0CCutEnabled) { - if (multTrk < fMultT0CCutLow->Eval(centrality)) + if (multTrk < cfgFuncParas.fMultT0CCutLow->Eval(centrality)) return 0; - if (multTrk > fMultT0CCutHigh->Eval(centrality)) + if (multTrk > cfgFuncParas.fMultT0CCutHigh->Eval(centrality)) return 0; } if (cfgFuncParas.cfgMultGlobalPVCutEnabled) { - if (multTrk < fMultGlobalPVCutLow->Eval(multNTracksPV)) + if (multTrk < cfgFuncParas.fMultGlobalPVCutLow->Eval(multNTracksPV)) + return 0; + if (multTrk > cfgFuncParas.fMultGlobalPVCutHigh->Eval(multNTracksPV)) + return 0; + } + if (cfgFuncParas.cfgMultMultV0ACutEnabled) { + if (collision.multFV0A() < cfgFuncParas.fMultMultV0ACutLow->Eval(multTrk)) return 0; - if (multTrk > fMultGlobalPVCutHigh->Eval(multNTracksPV)) + if (collision.multFV0A() > cfgFuncParas.fMultMultV0ACutHigh->Eval(multTrk)) return 0; } } @@ -705,7 +722,7 @@ struct FlowTask { // V0A T0A 5 sigma cut float sigma = 5.0; - if (cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > sigma * fT0AV0ASigma->Eval(collision.multFT0A()))) + if (cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - cfgFuncParas.fT0AV0AMean->Eval(collision.multFT0A())) > sigma * cfgFuncParas.fT0AV0ASigma->Eval(collision.multFT0A()))) return 0; if (cfgEvSelV0AT0ACut) registry.fill(HIST("hEventCountSpecific"), 11.5); diff --git a/PWGCF/Flow/Tasks/flowZdcTask.cxx b/PWGCF/Flow/Tasks/flowZdcTask.cxx index 0d8a4acfd8c..80844482e83 100644 --- a/PWGCF/Flow/Tasks/flowZdcTask.cxx +++ b/PWGCF/Flow/Tasks/flowZdcTask.cxx @@ -62,6 +62,7 @@ struct FlowZdcTask { Configurable maxZem{"maxZem", 3099.5, "Max ZEM signal"}; // for ZDC info and analysis Configurable nBinsAmp{"nBinsAmp", 1025, "nbinsAmp"}; + Configurable nBinsCent{"nBinsCent", 90, "nBinsCent"}; Configurable maxZn{"maxZn", 125.5, "Max ZN signal"}; Configurable vtxRange{"vtxRange", 10.0f, "Vertex Z range to consider"}; Configurable etaRange{"etaRange", 1.0f, "Eta range to consider"}; @@ -76,6 +77,7 @@ struct FlowZdcTask { Configurable nBinsZP{"nBinsZP", 160, "N bins ZP"}; Configurable minNch{"minNch", 0, "Min Nch (|eta|<0.8)"}; Configurable maxNch{"maxNch", 2500, "Max Nch (|eta|<0.8)"}; + Configurable oneNeutron{"oneNeutron", 1.0, "one neutron, energy or integer"}; Configurable nBinsTDC{"nBinsTDC", 150, "nbinsTDC"}; Configurable minTdc{"minTdc", -15.0, "minimum TDC"}; Configurable maxTdc{"maxTdc", 15.0, "maximum TDC"}; @@ -95,6 +97,7 @@ struct FlowZdcTask { Configurable applyEff{"applyEff", true, "Apply track-by-track efficiency correction"}; Configurable applyFD{"applyFD", false, "Apply track-by-track feed down correction"}; Configurable correctNch{"correctNch", true, "Correct also Nch"}; + Configurable isOneNeutronFound{"isOneNeutronFound", true, "Require at least 1 neutron in ZNA/ZNC to fill ZPA/ZPC"}; Configurable nSigmaNchCut{"nSigmaNchCut", 1., "nSigma Nch selection"}; Configurable minNchSel{"minNchSel", 5., "min Nch Selection"}; @@ -266,10 +269,14 @@ struct FlowZdcTask { histos.add("ZNVsFT0C", ";T0C (#times 1/100);ZNA+ZNC;", kTH2F, {{{nBinsAmpFT0, 0., maxAmpFT0}, {nBinsZDC, -0.5, maxZn}}}); histos.add("ZNVsFT0M", ";T0A+T0C (#times 1/100);ZNA+ZNC;", kTH2F, {{{nBinsAmpFT0, 0., 3000.}, {nBinsZDC, -0.5, maxZn}}}); histos.add("ZN", ";ZNA+ZNC;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZn}}); - histos.add("ZNA", ";ZNA;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZn}}); - histos.add("ZPA", ";ZPA;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZp}}); - histos.add("ZNC", ";ZNC;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZn}}); - histos.add("ZPC", ";ZPC;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZp}}); + histos.add("ZNA", ";ZNA Amplitude;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZn}}); + histos.add("ZPA", ";ZPA Amplitude;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZp}}); + histos.add("ZNC", ";ZNC Amplitude;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZn}}); + histos.add("ZPC", ";ZPC Amplitude;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZp}}); + histos.add("ZNACommon", ";ZNA Common Energy;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZn}}); + histos.add("ZPACommon", ";ZPA Common Energy;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZp}}); + histos.add("ZNCCommon", ";ZNC Common Energy;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZn}}); + histos.add("ZPCCommon", ";ZPC Common Energy;Entries;", kTH1F, {{nBinsZDC, -0.5, maxZp}}); histos.add("ZNAVsZNC", ";ZNC;ZNA", kTH2F, {{{30, -0.5, maxZn}, {30, -0.5, maxZn}}}); histos.add("ZPAVsZPC", ";ZPC;ZPA;", kTH2F, {{{100, -0.5, maxZp}, {100, -0.5, maxZp}}}); histos.add("ZNAVsZPA", ";ZPA;ZNA;", kTH2F, {{{20, -0.5, maxZp}, {30, -0.5, maxZn}}}); @@ -305,6 +312,12 @@ struct FlowZdcTask { histos.add("ZNAVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA;", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, minNch, maxZn}}}); histos.add("ZNVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA+ZNC;", kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZDC, minNch, maxZn}}}); histos.add("ZNDifVsNch", ";#it{N}_{ch} (|#eta|<0.8);ZNA-ZNC;", kTH2F, {{{nBinsNch, minNch, maxNch}, {100, -50., 50.}}}); + histos.add("ZPAvsCent", ";centFT0C;ZPA", kTH2F, {{{axisCent}, {nBinsZDC, -0.5, maxZp}}}); + histos.add("ZPCvsCent", ";centFT0C;ZPC", kTH2F, {{{axisCent}, {nBinsZDC, -0.5, maxZp}}}); + histos.add("pZPAvsFT0Ccent", ";FT0C centrality;ZPA Amplitude", kTProfile, {{nBinsCent, minT0CcentCut, maxT0CcentCut}}); + histos.add("pZPCvsFT0Ccent", ";FT0C centrality;ZPC Amplitude", kTProfile, {{nBinsCent, minT0CcentCut, maxT0CcentCut}}); + histos.add("pZPAvsGlbTrack", ";Global Tracks (ITS + TPC);ZPA Amplitude", kTProfile, {{nBinsNch, minNch, maxNch}}); + histos.add("pZPCvsGlbTrack", ";Global Tracks (ITS + TPC);ZPC Amplitude", kTProfile, {{nBinsNch, minNch, maxNch}}); } ccdb->setURL("http://alice-ccdb.cern.ch"); @@ -403,6 +416,7 @@ struct FlowZdcTask { void processQA(ColEvSels::iterator const& collision, BCsRun3 const& /*bcs*/, aod::Zdcs const& /*zdcsData*/, aod::FV0As const& /*fv0as*/, aod::FT0s const& /*ft0s*/, TheFilteredTracks const& tracks) { const auto& foundBC = collision.foundBC_as(); + const auto cent = collision.centFT0C(); if (!isEventSelected(collision)) { return; } @@ -442,6 +456,10 @@ struct FlowZdcTask { float znC = zdc.amplitudeZNC() / cfgCollisionEnergy; float zpA = zdc.amplitudeZPA() / cfgCollisionEnergy; float zpC = zdc.amplitudeZPC() / cfgCollisionEnergy; + float commonSumZnc = zdc.energyCommonZNC() / cfgCollisionEnergy; + float commonSumZna = zdc.energyCommonZNA() / cfgCollisionEnergy; + float commonSumZpc = zdc.energyCommonZPC() / cfgCollisionEnergy; + float commonSumZpa = zdc.energyCommonZPA() / cfgCollisionEnergy; float aZEM1{zdc.amplitudeZEM1()}; float aZEM2{zdc.amplitudeZEM2()}; float sumZEMs{aZEM1 + aZEM2}; @@ -533,39 +551,62 @@ struct FlowZdcTask { } histos.fill(HIST("zPos"), collision.posZ()); histos.fill(HIST("T0Ccent"), collision.centFT0C()); - histos.fill(HIST("ZNCcvsZNCsum"), sumZNC / cfgCollisionEnergy, zdc.energyCommonZNC() / cfgCollisionEnergy); histos.fill(HIST("ZNAcvsZNAsum"), sumZNA / cfgCollisionEnergy, zdc.energyCommonZNA() / cfgCollisionEnergy); histos.fill(HIST("ZPCcvsZPCsum"), sumZPC / cfgCollisionEnergy, zdc.energyCommonZPC() / cfgCollisionEnergy); histos.fill(HIST("ZPAcvsZPAsum"), sumZPA / cfgCollisionEnergy, zdc.energyCommonZPA() / cfgCollisionEnergy); - histos.fill(HIST("GlbTracks"), glbTracks); + + // Neutron ZDC histos.fill(HIST("ZNA"), znA); histos.fill(HIST("ZNC"), znC); - histos.fill(HIST("ZPA"), zpA); - histos.fill(HIST("ZPC"), zpC); + histos.fill(HIST("ZNACommon"), commonSumZna); + histos.fill(HIST("ZNCCommon"), commonSumZnc); histos.fill(HIST("ZNASector"), sumZNA / cfgCollisionEnergy); histos.fill(HIST("ZNCSector"), sumZNC / cfgCollisionEnergy); - histos.fill(HIST("ZPASector"), sumZPA / cfgCollisionEnergy); - histos.fill(HIST("ZPCSector"), sumZPC / cfgCollisionEnergy); histos.fill(HIST("ZN"), znA + znC); - histos.fill(HIST("ZNAVsZNC"), znC, znA); - histos.fill(HIST("ZNAVsZPA"), zpA, znA); - histos.fill(HIST("ZNCVsZPC"), zpC, znC); - histos.fill(HIST("ZPAVsZPC"), zpC, zpA); histos.fill(HIST("ZNVsZEM"), sumZEMs, sumZNs); histos.fill(HIST("ZNCVstdc"), tZNC, znC); histos.fill(HIST("ZNAVstdc"), tZNA, znA); histos.fill(HIST("ZPCVstdc"), tZPC, zpC); - histos.fill(HIST("ZPAVstdc"), tZPA, zpA); - histos.fill(HIST("ZEM1Vstdc"), tZEM1, aZEM1); - histos.fill(HIST("ZEM2Vstdc"), tZEM2, aZEM2); - histos.fill(HIST("debunch"), tZDCdif, tZDCsum); - histos.fill(HIST("ZNVsFT0A"), aT0A / 100., sumZNs); histos.fill(HIST("ZNVsFT0C"), aT0C / 100., sumZNs); histos.fill(HIST("ZNVsFT0M"), (aT0A + aT0C) / 100., sumZNs); + // Proton ZDC + if (!isOneNeutronFound || znA >= oneNeutron) { + histos.fill(HIST("ZPA"), zpA); + histos.fill(HIST("ZPACommon"), commonSumZpa); + histos.fill(HIST("ZPASector"), sumZPA / cfgCollisionEnergy); + histos.fill(HIST("ZPAVstdc"), tZPA, zpA); + histos.fill(HIST("ZPAvsCent"), cent, zpA); + if (std::isfinite(zpA) && !std::isnan(zpA) && + cent >= minT0CcentCut && cent < maxT0CcentCut && glbTracks >= minNch && glbTracks < maxNch) { + histos.fill(HIST("pZPAvsFT0Ccent"), cent, zpA); + histos.fill(HIST("pZPAvsGlbTrack"), glbTracks, zpA); + } + } + if (!isOneNeutronFound || znC >= oneNeutron) { + histos.fill(HIST("ZPC"), zpC); + histos.fill(HIST("ZPCCommon"), commonSumZpc); + histos.fill(HIST("ZPCSector"), sumZPC / cfgCollisionEnergy); + histos.fill(HIST("ZPCvsCent"), cent, zpC); + if (std::isfinite(zpC) && !std::isnan(zpC) && + cent >= minT0CcentCut && cent < maxT0CcentCut && glbTracks >= minNch && glbTracks < maxNch) { + histos.fill(HIST("pZPCvsFT0Ccent"), cent, zpC); + histos.fill(HIST("pZPCvsGlbTrack"), glbTracks, zpC); + } + } + + // ZDC Correlations + histos.fill(HIST("ZNAVsZNC"), znC, znA); + histos.fill(HIST("ZNAVsZPA"), zpA, znA); + histos.fill(HIST("ZNCVsZPC"), zpC, znC); + histos.fill(HIST("ZPAVsZPC"), zpC, zpA); + histos.fill(HIST("ZEM1Vstdc"), tZEM1, aZEM1); + histos.fill(HIST("ZEM2Vstdc"), tZEM2, aZEM2); + histos.fill(HIST("debunch"), tZDCdif, tZDCsum); + if (sumZNs > znBasedCut) { return; } diff --git a/PWGCF/Flow/Tasks/resonancesGfwFlow.cxx b/PWGCF/Flow/Tasks/resonancesGfwFlow.cxx index 8a2c634e31f..5e9662b49b4 100644 --- a/PWGCF/Flow/Tasks/resonancesGfwFlow.cxx +++ b/PWGCF/Flow/Tasks/resonancesGfwFlow.cxx @@ -203,7 +203,7 @@ struct ResonancesGfwFlow { O2_DEFINE_CONFIGURABLE(cfgUseBootStrap, bool, true, "Use bootstrap for error estimation") O2_DEFINE_CONFIGURABLE(cfgTrackDensityCorrUse, bool, true, "Use track density efficiency correction") O2_DEFINE_CONFIGURABLE(cfgV0AT0Acut, int, 5, "V0AT0A cut") - + O2_DEFINE_CONFIGURABLE(cfgUseLsPhi, bool, true, "Use LikeSign for Phi v2") O2_DEFINE_CONFIGURABLE(cfgUseOnlyTPC, bool, true, "Use only TPC PID for daughter selection") O2_DEFINE_CONFIGURABLE(cfgUseStrictPID, bool, true, "Use strict PID cuts for TPC") O2_DEFINE_CONFIGURABLE(cfgUseAsymmetricPID, bool, false, "Use asymmetric PID cuts") @@ -357,6 +357,10 @@ struct ResonancesGfwFlow { } // end of configs loop + if (cfgUseLsPhi) { + histos.add("hLsPhiMass_sparse", "", {HistType::kTHnSparseD, {{axisPhiMass, axisPt, axisMultiplicity}}}); + } + if (resoSwitchVals[PHI][kUseParticle]) { histos.add("KaPlusTPC", "", {HistType::kTH2D, {{axisPt, axisNsigmaTPC}}}); histos.add("KaMinusTPC", "", {HistType::kTH2D, {{axisPt, axisNsigmaTPC}}}); @@ -365,7 +369,6 @@ struct ResonancesGfwFlow { histos.add("hPhiPhi", "", {HistType::kTH1D, {axisPhi}}); histos.add("hPhiEta", "", {HistType::kTH1D, {axisEta}}); histos.add("hPhiMass_sparse", "", {HistType::kTHnSparseD, {{axisPhiMass, axisPt, axisMultiplicity}}}); - histos.add("hPhimassSparse_RD", "", {HistType::kTHnSparseD, {{axisPhiMass, axisPt, axisMultiplicity}}}); histos.add("hPhiCount", "Number of Phi;; Count", {HistType::kTH1D, {{5, 0, 5}}}); histos.get(HIST("hPhiCount"))->GetXaxis()->SetBinLabel(1, "Phi candidates"); @@ -878,6 +881,35 @@ struct ResonancesGfwFlow { } } + template + bool selectionV0Daughter(TTrack const& track, int pid) + { + if (!(track.itsNCls() > cfgITScluster)) + return 0; + if (!track.hasTPC()) + return false; + if (track.tpcNClsFound() < cfgTpcCluster) + return false; + if (!(track.tpcNClsCrossedRows() > cfgTpcCrossRows)) + return 0; + + if (cfgUseOnlyTPC) { + if (pid == PIONS && std::abs(track.tpcNSigmaPi()) > cfgTpcCut) + return false; + if (pid == KAONS && std::abs(track.tpcNSigmaKa()) > cfgTpcCut) + return false; + if (pid == PROTONS && std::abs(track.tpcNSigmaPr()) > cfgTpcCut) + return false; + } else { + int partIndex = cfgUseAsymmetricPID ? getNsigmaPIDAssymmetric(track) : getNsigmaPIDTpcTof(track); + int pidIndex = partIndex - 1; // 0 = pion, 1 = kaon, 2 = proton + if (pidIndex != pid) + return false; + } + + return true; + } + template void resurrectPhi(TTrack trackplus, TTrack trackminus, const TCollision collision, vector plusdaug, vector minusdaug, vector mom, double plusmass, const ConstStr& hist) { @@ -900,13 +932,6 @@ struct ResonancesGfwFlow { histos.fill(HIST("KaMinusTPC"), partminus.pt(), partminus.tpcNSigmaKa()); histos.fill(HIST("KaMinusTOF"), partminus.pt(), partminus.tofNSigmaKa()); - std::array, 2> ptarr = {{{partplus.px(), partplus.py(), partplus.pz()}, {partminus.px(), partminus.py(), partminus.pz()}}}; - std::array massarr = {plusmass, plusmass}; - - // Calculation using RecoDecay - double invMassRD = RecoDecay::m2(ptarr, massarr); - double ptRD = std::sqrt(RecoDecay::sumOfSquares(partplus.pt(), partminus.pt())); - // Calculation using ROOT vectors plusdaug = ROOT::Math::PxPyPzMVector(partplus.px(), partplus.py(), partplus.pz(), plusmass); minusdaug = ROOT::Math::PxPyPzMVector(partminus.px(), partminus.py(), partminus.pz(), plusmass); @@ -926,7 +951,6 @@ struct ResonancesGfwFlow { histos.fill(hist, invMass, pt, collision.centFT0C()); histos.fill(HIST("hPhiPhi"), phi); histos.fill(HIST("hPhiEta"), mom.Eta()); - histos.fill(HIST("hPhimassSparse_RD"), invMassRD, ptRD, collision.centFT0C()); // fill RecoDecay mass and pt // Fill Phi weights if (cfgOutputNUAWeights && withinPtPOI) { @@ -942,37 +966,37 @@ struct ResonancesGfwFlow { if (withinPtPOI && withinPtRef) fGFW->Fill(mom.Eta(), ((fPtAxis->FindBin(pt) - 1) * fPhiMassAxis->GetNbins()) + (fPhiMassAxis->FindBin(invMass) - 1), phi, weff * waccPOI, 32); } - } + } // end of combinations loop return; } - template - bool selectionV0Daughter(TTrack const& track, int pid) + template + void likeSignPhi(TTrack track, const TCollision collision, double plusmass, const ConstStr& hist) { - if (!(track.itsNCls() > cfgITScluster)) - return 0; - if (!track.hasTPC()) - return false; - if (track.tpcNClsFound() < cfgTpcCluster) - return false; - if (!(track.tpcNClsCrossedRows() > cfgTpcCrossRows)) - return 0; + ROOT::Math::PxPyPzMVector daug1, daug2, mom; + for (auto const& [part1, part2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(track, track))) { - if (cfgUseOnlyTPC) { - if (pid == PIONS && std::abs(track.tpcNSigmaPi()) > cfgTpcCut) - return false; - if (pid == KAONS && std::abs(track.tpcNSigmaKa()) > cfgTpcCut) - return false; - if (pid == PROTONS && std::abs(track.tpcNSigmaPr()) > cfgTpcCut) - return false; - } else { - int partIndex = cfgUseAsymmetricPID ? getNsigmaPIDAssymmetric(track) : getNsigmaPIDTpcTof(track); - int pidIndex = partIndex - 1; // 0 = pion, 1 = kaon, 2 = proton - if (pidIndex != pid) - return false; - } + if (!selectionV0Daughter(part1, KAONS) || !selectionV0Daughter(part2, KAONS)) // 0 = pion, 1 = kaon, 2 = proton + continue; + if (isFakeKaon(part1) || isFakeKaon(part2)) + continue; - return true; + // Calculation using ROOT vectors + daug1 = ROOT::Math::PxPyPzMVector(part1.px(), part1.py(), part1.pz(), plusmass); + daug2 = ROOT::Math::PxPyPzMVector(part2.px(), part2.py(), part2.pz(), plusmass); + mom = daug1 + daug2; + + double pt = mom.Pt(); + double invMass = mom.M(); + double phi = mom.Phi(); + + phi = RecoDecay::constrainAngle(phi, 0.0, 1); // constrain azimuthal angle to [0,2pi] + + if (std::abs(mom.Rapidity()) < resoCutVals[PHI][kRapidity]) { + histos.fill(hist, invMass, pt, collision.centFT0C()); + } + } // end of positive combinations loop + return; } template @@ -1348,6 +1372,11 @@ struct ResonancesGfwFlow { resurrectPhi(posSlicedTracks, negSlicedTracks, collision, kaonPlus, kaonMinus, phiMom, massKaPlus, HIST("hPhiMass_sparse")); } + if (cfgUseLsPhi) { + likeSignPhi(posSlicedTracks, collision, massKaPlus, HIST("hLsPhiMass_sparse")); + likeSignPhi(negSlicedTracks, collision, massKaPlus, HIST("hLsPhiMass_sparse")); + } + // ---------------------- Analyzing the V0s for (auto const& v0s : V0s) { if (resoSwitchVals[K0][kUseParticle]) { @@ -1360,7 +1389,7 @@ struct ResonancesGfwFlow { } } // End of v0 loop - // Filling the cumulant profiles + // Filling cumulant profiles double r = fRndm->Rndm(); int bootId = static_cast(r * 10); diff --git a/PWGCF/GenericFramework/Tasks/flowGfwLightIons.cxx b/PWGCF/GenericFramework/Tasks/flowGfwLightIons.cxx index fb654b6014a..7a74223e5ac 100644 --- a/PWGCF/GenericFramework/Tasks/flowGfwLightIons.cxx +++ b/PWGCF/GenericFramework/Tasks/flowGfwLightIons.cxx @@ -79,6 +79,8 @@ GFWCorrConfigs configs; std::vector multGlobalCorrCutPars; std::vector multPVCorrCutPars; std::vector multGlobalPVCorrCutPars; +std::vector multGlobalV0ACutPars; +std::vector multGlobalT0ACutPars; std::vector firstRunsOfFill; } // namespace o2::analysis::gfw @@ -134,6 +136,15 @@ struct FlowGfwLightIons { O2_DEFINE_CONFIGURABLE(cfgMultCorrHighCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x + 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); O2_DEFINE_CONFIGURABLE(cfgMultCorrLowCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x - 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); O2_DEFINE_CONFIGURABLE(cfgMultGlobalPVCorrCutFunction, std::string, "[0] + [1]*x + 3*([2] + [3]*x + [4]*x*x + [5]*x*x*x)", "Functional for global vs pv multiplicity correlation cut"); + struct : ConfigurableGroup { + O2_DEFINE_CONFIGURABLE(cfgMultGlobalASideCorrCutFunction, std::string, "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x + [10]*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", "Functional for global vs V0A multiplicity low correlation cut"); + Configurable> cfgMultGlobalV0ACutPars{"cfgMultGlobalV0ACutPars", std::vector{567.785, 172.715, 0.77888, -0.00693466, 1.40564e-05, 679.853, 66.8068, -0.444332, 0.00115002, -4.92064e-07}, "Global vs FV0A multiplicity cut parameter values"}; + Configurable> cfgMultGlobalT0ACutPars{"cfgMultGlobalT0ACutPars", std::vector{241.618, 61.8402, 0.348049, -0.00306078, 6.20357e-06, 315.235, 29.1491, -0.188639, 0.00044528, -9.08912e-08}, "Global vs FT0A multiplicity cut parameter values"}; + O2_DEFINE_CONFIGURABLE(cfgGlobalV0ALowSigma, float, -3, "Number of sigma deviations below expected value in global vs V0A correlation"); + O2_DEFINE_CONFIGURABLE(cfgGlobalV0AHighSigma, float, 4, "Number of sigma deviations above expected value in global vs V0A correlation"); + O2_DEFINE_CONFIGURABLE(cfgGlobalT0ALowSigma, float, -3., "Number of sigma deviations below expected value in global vs T0A correlation"); + O2_DEFINE_CONFIGURABLE(cfgGlobalT0AHighSigma, float, 4, "Number of sigma deviations above expected value in global vs T0A correlation"); + } cfgGlobalAsideCorrCuts; Configurable cfgGFWBinning{"cfgGFWBinning", {40, 16, 72, 300, 0, 3000, 0.2, 10.0, 0.2, 3.0, {0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5, 3.75, 4, 4.5, 5, 5.5, 6, 7, 8, 9, 10}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90}}, "Configuration for binning"}; Configurable cfgRegions{"cfgRegions", {{"refN", "refP", "refFull"}, {-0.8, 0.4, -0.8}, {-0.4, 0.8, 0.8}, {0, 0, 0}, {1, 1, 1}}, "Configurations for GFW regions"}; @@ -241,6 +252,10 @@ struct FlowGfwLightIons { TF1* fMultCutLow = nullptr; TF1* fMultCutHigh = nullptr; TF1* fMultPVGlobalCutHigh = nullptr; + TF1* fMultGlobalV0ACutLow = nullptr; + TF1* fMultGlobalV0ACutHigh = nullptr; + TF1* fMultGlobalT0ACutLow = nullptr; + TF1* fMultGlobalT0ACutHigh = nullptr; TF1* fPtDepDCAxy = nullptr; @@ -287,6 +302,8 @@ struct FlowGfwLightIons { o2::analysis::gfw::multGlobalCorrCutPars = cfgMultGlobalCutPars; o2::analysis::gfw::multPVCorrCutPars = cfgMultPVCutPars; o2::analysis::gfw::multGlobalPVCorrCutPars = cfgMultGlobalPVCutPars; + o2::analysis::gfw::multGlobalV0ACutPars = cfgGlobalAsideCorrCuts.cfgMultGlobalV0ACutPars; + o2::analysis::gfw::multGlobalT0ACutPars = cfgGlobalAsideCorrCuts.cfgMultGlobalT0ACutPars; o2::analysis::gfw::firstRunsOfFill = cfgFirstRunsOfFill; if (cfgTimeDependent && !std::is_sorted(o2::analysis::gfw::firstRunsOfFill.begin(), o2::analysis::gfw::firstRunsOfFill.end())) { std::sort(o2::analysis::gfw::firstRunsOfFill.begin(), o2::analysis::gfw::firstRunsOfFill.end()); @@ -479,6 +496,36 @@ struct FlowGfwLightIons { fMultCutHigh->SetParameters(&(o2::analysis::gfw::multGlobalCorrCutPars[0])); fMultPVGlobalCutHigh = new TF1("fMultPVGlobalCutHigh", cfgMultGlobalPVCorrCutFunction->c_str(), 0, nchbinning.back()); fMultPVGlobalCutHigh->SetParameters(&(o2::analysis::gfw::multGlobalPVCorrCutPars[0])); + + LOGF(info, "Global V0A function: %s in range 0-%g", cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), v0aAxis.binEdges.back()); + fMultGlobalV0ACutLow = new TF1("fMultGlobalV0ACutLow", cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), 0, v0aAxis.binEdges.back()); + for (std::size_t i = 0; i < o2::analysis::gfw::multGlobalV0ACutPars.size(); ++i) + fMultGlobalV0ACutLow->SetParameter(i, o2::analysis::gfw::multGlobalV0ACutPars[i]); + fMultGlobalV0ACutLow->SetParameter(o2::analysis::gfw::multGlobalV0ACutPars.size(), cfgGlobalAsideCorrCuts.cfgGlobalV0ALowSigma); + for (int i = 0; i < fMultGlobalV0ACutLow->GetNpar(); ++i) + LOGF(info, "fMultGlobalV0ACutLow par %d = %g", i, fMultGlobalV0ACutLow->GetParameter(i)); + + fMultGlobalV0ACutHigh = new TF1("fMultGlobalV0ACutHigh", cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), 0, v0aAxis.binEdges.back()); + for (std::size_t i = 0; i < o2::analysis::gfw::multGlobalV0ACutPars.size(); ++i) + fMultGlobalV0ACutHigh->SetParameter(i, o2::analysis::gfw::multGlobalV0ACutPars[i]); + fMultGlobalV0ACutHigh->SetParameter(o2::analysis::gfw::multGlobalV0ACutPars.size(), cfgGlobalAsideCorrCuts.cfgGlobalV0AHighSigma); + for (int i = 0; i < fMultGlobalV0ACutHigh->GetNpar(); ++i) + LOGF(info, "fMultGlobalV0ACutHigh par %d = %g", i, fMultGlobalV0ACutHigh->GetParameter(i)); + + LOGF(info, "Global T0A function: %s", cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str()); + fMultGlobalT0ACutLow = new TF1("fMultGlobalT0ACutLow", cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), 0, t0aAxis.binEdges.back()); + for (std::size_t i = 0; i < o2::analysis::gfw::multGlobalT0ACutPars.size(); ++i) + fMultGlobalT0ACutLow->SetParameter(i, o2::analysis::gfw::multGlobalT0ACutPars[i]); + fMultGlobalT0ACutLow->SetParameter(o2::analysis::gfw::multGlobalT0ACutPars.size(), cfgGlobalAsideCorrCuts.cfgGlobalT0ALowSigma); + for (int i = 0; i < fMultGlobalT0ACutLow->GetNpar(); ++i) + LOGF(info, "fMultGlobalT0ACutLow par %d = %g", i, fMultGlobalT0ACutLow->GetParameter(i)); + + fMultGlobalT0ACutHigh = new TF1("fMultGlobalT0ACutHigh", cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->c_str(), 0, t0aAxis.binEdges.back()); + for (std::size_t i = 0; i < o2::analysis::gfw::multGlobalT0ACutPars.size(); ++i) + fMultGlobalT0ACutHigh->SetParameter(i, o2::analysis::gfw::multGlobalT0ACutPars[i]); + fMultGlobalT0ACutHigh->SetParameter(o2::analysis::gfw::multGlobalT0ACutPars.size(), cfgGlobalAsideCorrCuts.cfgGlobalT0AHighSigma); + for (int i = 0; i < fMultGlobalT0ACutHigh->GetNpar(); ++i) + LOGF(info, "fMultGlobalT0ACutHigh par %d = %g", i, fMultGlobalT0ACutHigh->GetParameter(i)); } if (cfgUseDensityDependentCorrection) { std::vector pTEffBins = {0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.4, 1.8, 2.2, 2.6, 3.0}; @@ -690,6 +737,15 @@ struct FlowGfwLightIons { return 0; if (multTrk > fMultPVGlobalCutHigh->Eval(collision.multNTracksPV())) return 0; + + if (!(cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFV0A()) < fMultGlobalV0ACutLow->Eval(multTrk)) + return 0; + if (!(cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFV0A()) > fMultGlobalV0ACutHigh->Eval(multTrk)) + return 0; + if (!(cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFT0A()) < fMultGlobalT0ACutLow->Eval(multTrk)) + return 0; + if (!(cfgGlobalAsideCorrCuts.cfgMultGlobalASideCorrCutFunction->empty()) && static_cast(collision.multFT0A()) > fMultGlobalT0ACutHigh->Eval(multTrk)) + return 0; registry.fill(HIST("eventQA/eventSel"), kMultCuts); if (cfgRunByRun) th1sList[run][hEventSel]->Fill(kMultCuts); diff --git a/PWGCF/JCorran/Core/JFFlucAnalysis.cxx b/PWGCF/JCorran/Core/JFFlucAnalysis.cxx index 9dc4189a810..4c3b01adeca 100644 --- a/PWGCF/JCorran/Core/JFFlucAnalysis.cxx +++ b/PWGCF/JCorran/Core/JFFlucAnalysis.cxx @@ -12,10 +12,12 @@ /// \author Jasper Parkkila (jparkkil@cern.ch) /// \since Sep 2022 -#include +#include "JFFlucAnalysis.h" + #include +#include + #include -#include "JFFlucAnalysis.h" JFFlucAnalysis::JFFlucAnalysis() : TNamed(), fVertex(0), diff --git a/PWGCF/JCorran/Core/JFFlucAnalysis.h b/PWGCF/JCorran/Core/JFFlucAnalysis.h index 01589a09849..b728c809173 100644 --- a/PWGCF/JCorran/Core/JFFlucAnalysis.h +++ b/PWGCF/JCorran/Core/JFFlucAnalysis.h @@ -15,13 +15,16 @@ #ifndef PWGCF_JCORRAN_CORE_JFFLUCANALYSIS_H_ #define PWGCF_JCORRAN_CORE_JFFLUCANALYSIS_H_ -#include #include "JQVectors.h" + #include -#include #include #include #include +#include + +#include +#include class JFFlucAnalysis : public TNamed { @@ -61,7 +64,6 @@ class JFFlucAnalysis : public TNamed enum HIST_THN { HIST_THN_PHIETAZ, HIST_THN_PTETA, - HIST_THN_PHIETA, HIST_THN_SC_with_QC_4corr, HIST_THN_SC_with_QC_2corr, HIST_THN_SC_with_QC_2corr_gap, @@ -98,6 +100,7 @@ class JFFlucAnalysis : public TNamed enum HIST_THN_SPARSE { HIST_THN_SPARSE_VN, HIST_THN_SPARSE_VN_VN, + HIST_THN_SPARSE_MULTCORR, HIST_THN_SPARSE_COUNT }; enum { @@ -144,29 +147,42 @@ class JFFlucAnalysis : public TNamed using hasWeightEff = decltype(std::declval().weightEff()); template using hasSign = decltype(std::declval().sign()); + template + using hasMultSet = decltype(std::declval().multiplicities()); template inline void FillQA(JInputClass& inputInst, UInt_t type = 0u) { - ph1[HIST_TH1_CENTRALITY]->Fill(fCent); - ph1[HIST_TH1_IMPACTPARAM]->Fill(fImpactParameter); + if (type == 0u) { + ph1[HIST_TH1_CENTRALITY]->Fill(fCent); + ph1[HIST_TH1_ZVERTEX]->Fill(fVertex); + ph1[HIST_TH1_IMPACTPARAM]->Fill(fImpactParameter); + } for (auto& track : inputInst) { Double_t corrInv = 1.0; using JInputClassIter = typename JInputClass::iterator; if constexpr (std::experimental::is_detected::value) - corrInv /= track.weightEff(); + corrInv *= track.weightEff(); if constexpr (std::experimental::is_detected::value) pht[HIST_THN_PTETA]->Fill(fCent, track.pt(), track.eta(), track.sign(), corrInv); else pht[HIST_THN_PTETA]->Fill(fCent, track.pt(), track.eta(), 0.0, corrInv); if constexpr (std::experimental::is_detected::value) corrInv /= track.weightNUA(); - pht[HIST_THN_PHIETA]->Fill(fCent, track.phi(), track.eta(), corrInv); pht[HIST_THN_PHIETAZ]->Fill(fCent, static_cast(type), track.phi(), track.eta(), fVertex, corrInv); } + } - ph1[HIST_TH1_ZVERTEX]->Fill(fVertex); + template + inline void FillMultSet(JEventClass& event) + { + // + if constexpr (std::experimental::is_detected::value) { + // need to convert to vec of doubles since THnSparse has no way to fill vec of floats directly + std::vector v(event.multiplicities().begin(), event.multiplicities().end()); + phs[HIST_THN_SPARSE_MULTCORR]->Fill(v.data()); + } } #define kcNH kH4 // max second dimension + 1 diff --git a/PWGCF/JCorran/Core/JFFlucAnalysisO2Hist.cxx b/PWGCF/JCorran/Core/JFFlucAnalysisO2Hist.cxx index b3419ff7dc8..502a14c6b28 100644 --- a/PWGCF/JCorran/Core/JFFlucAnalysisO2Hist.cxx +++ b/PWGCF/JCorran/Core/JFFlucAnalysisO2Hist.cxx @@ -12,24 +12,41 @@ /// \since Sep 2024 #include "JFFlucAnalysisO2Hist.h" -#include -#include + +#include "PWGCF/DataModel/CorrelationsDerived.h" + #include "CommonConstants/MathConstants.h" +#include +#include + using namespace o2; -JFFlucAnalysisO2Hist::JFFlucAnalysisO2Hist(HistogramRegistry& registry, AxisSpec& axisMultiplicity, AxisSpec& phiAxis, AxisSpec& etaAxis, AxisSpec& zvtAxis, AxisSpec& ptAxis, AxisSpec& massAxis, const TString& folder) : JFFlucAnalysis() +JFFlucAnalysisO2Hist::JFFlucAnalysisO2Hist(HistogramRegistry& registry, AxisSpec& axisMultiplicity, AxisSpec& phiAxis, AxisSpec& etaAxis, AxisSpec& zvtAxis, AxisSpec& ptAxis, AxisSpec& massAxis, uint16_t multCorrMask, const TString& folder) : JFFlucAnalysis() { ph1[HIST_TH1_CENTRALITY] = std::get>(registry.add(Form("%s/h_cent", folder.Data()), "multiplicity/centrality", {HistType::kTH1F, {axisMultiplicity}})).get(); ph1[HIST_TH1_IMPACTPARAM] = std::get>(registry.add(Form("%s/h_IP", folder.Data()), "impact parameter", {HistType::kTH1F, {{400, -2.0, 20.0}}})).get(); ph1[HIST_TH1_ZVERTEX] = std::get>(registry.add(Form("%s/h_vertex", folder.Data()), "z vertex", {HistType::kTH1F, {{100, -20.0, 20.0}}})).get(); + if (multCorrMask != 0) { + std::vector multAxes; + if (multCorrMask & aod::cfmultset::CentFT0C) + multAxes.emplace_back(100, 0, 100, "FT0C centrality"); + if (multCorrMask & aod::cfmultset::MultFV0A) + multAxes.emplace_back(100, 0, 100000, "V0A multiplicity"); + if (multCorrMask & aod::cfmultset::MultNTracksPV) + multAxes.emplace_back(100, 0, 1000, "Nch PV"); + if (multCorrMask & aod::cfmultset::MultNTracksGlobal) + multAxes.emplace_back(100, 0, 1000, "Nch Global"); + registry.add("multCorrelations", "Multiplicity correlations", {HistType::kTHnSparseF, multAxes}); + phs[HIST_THN_SPARSE_MULTCORR] = std::get>(registry.add(Form("%s/h_multcorr", folder.Data()), "multiplicity/centrality correlations", {HistType::kTHnSparseF, multAxes})).get(); + } + AxisSpec chgAxis = {3, -1.5, 1.5, "charge"}; AxisSpec typeAxis = {2, -0.5, 1.5, "type"}; - pht[HIST_THN_PHIETAZ] = std::get>(registry.add(Form("%s/h_phietaz", folder.Data()), "multiplicity/centrality, type, phi, eta, z", {HistType::kTHnSparseF, {axisMultiplicity, typeAxis, phiAxis, etaAxis, zvtAxis}})).get(); + pht[HIST_THN_PHIETAZ] = std::get>(registry.add(Form("%s/h_phietaz", folder.Data()), "(corrected) multiplicity/centrality, type, phi, eta, z", {HistType::kTHnSparseF, {axisMultiplicity, typeAxis, phiAxis, etaAxis, zvtAxis}})).get(); pht[HIST_THN_PTETA] = std::get>(registry.add(Form("%s/h_pteta", folder.Data()), "(corrected) multiplicity/centrality, pT, eta, charge", {HistType::kTHnSparseF, {axisMultiplicity, ptAxis, etaAxis, chgAxis}})).get(); - pht[HIST_THN_PHIETA] = std::get>(registry.add(Form("%s/h_phieta", folder.Data()), "(corrected) multiplicity/centrality, phi, eta", {HistType::kTHnSparseF, {axisMultiplicity, phiAxis, etaAxis}})).get(); AxisSpec hAxis = {kNH, -0.5, static_cast(kNH - 1) + 0.5, "#it{n}"}; AxisSpec kAxis = {nKL, -0.5, static_cast(nKL - 1) + 0.5, "#it{k}"}; AxisSpec vnAxis = {2048, -0.1, 0.1, "#it{V}_#it{n}"}; diff --git a/PWGCF/JCorran/Core/JFFlucAnalysisO2Hist.h b/PWGCF/JCorran/Core/JFFlucAnalysisO2Hist.h index a9de2fd7864..8821c64a225 100644 --- a/PWGCF/JCorran/Core/JFFlucAnalysisO2Hist.h +++ b/PWGCF/JCorran/Core/JFFlucAnalysisO2Hist.h @@ -15,6 +15,7 @@ #define PWGCF_JCORRAN_CORE_JFFLUCANALYSISO2HIST_H_ #include "JFFlucAnalysis.h" + #include "Framework/HistogramRegistry.h" using namespace o2; @@ -23,7 +24,7 @@ using namespace o2::framework; class JFFlucAnalysisO2Hist : public JFFlucAnalysis { public: - JFFlucAnalysisO2Hist(HistogramRegistry&, AxisSpec&, AxisSpec&, AxisSpec&, AxisSpec&, AxisSpec&, AxisSpec&, const TString&); + JFFlucAnalysisO2Hist(HistogramRegistry&, AxisSpec&, AxisSpec&, AxisSpec&, AxisSpec&, AxisSpec&, AxisSpec&, uint16_t, const TString&); ~JFFlucAnalysisO2Hist(); }; diff --git a/PWGCF/JCorran/Core/JQVectors.h b/PWGCF/JCorran/Core/JQVectors.h index c96aac454b7..01693ae6073 100644 --- a/PWGCF/JCorran/Core/JQVectors.h +++ b/PWGCF/JCorran/Core/JQVectors.h @@ -84,7 +84,7 @@ class JQVectors : public std::conditional_t, JQ if constexpr (std::experimental::is_detected::value) tf /= track.weightNUA(); if constexpr (std::experimental::is_detected::value) - tf /= track.weightEff(); + tf *= track.weightEff(); } } } diff --git a/PWGCF/JCorran/Tasks/jFlucEfficiencyTask.cxx b/PWGCF/JCorran/Tasks/jFlucEfficiencyTask.cxx index 59ca8b18903..213e7ff7ae4 100644 --- a/PWGCF/JCorran/Tasks/jFlucEfficiencyTask.cxx +++ b/PWGCF/JCorran/Tasks/jFlucEfficiencyTask.cxx @@ -14,25 +14,33 @@ /// \author DongJo Kim, Jasper Parkkila, Bong-Hwi Lim (djkim@cern.ch, jparkkil@cern.ch, bong-hwi.lim@cern.ch) /// \since March 2024 -#include -#include -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" -#include "Framework/O2DatabasePDGPlugin.h" +#include "PWGCF/DataModel/CorrelationsDerived.h" +#include "PWGLF/Utils/collisionCuts.h" + #include "Common/Core/TrackSelection.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "PWGCF/DataModel/CorrelationsDerived.h" -#include "PWGLF/Utils/collisionCuts.h" + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" + +#include + +#include +#include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::soa; using namespace o2::aod::rctsel; +using namespace o2::constants::physics; struct JFlucEfficiencyTask { Service pdg; @@ -49,6 +57,8 @@ struct JFlucEfficiencyTask { 170.0, 180.0, 190.0, 200.0, 210.0, 220.0, 230.0, 240.0, 250.0, 260.0, 270.0, 280.0, 290.0, 300.0}; + static constexpr double kChargeThreshold = 3.0; // PDG charge units: 3 = |e| + // Update the axisPt configuration with proper vector initialization ConfigurableAxis axisPt{"axisPt", std::vector(PttJacek.begin(), PttJacek.end()), "pT axis"}; @@ -103,8 +113,12 @@ struct JFlucEfficiencyTask { // DCA to PV Configurable cfgMaxbDCArToPVcut{"cfgMaxbDCArToPVcut", 0.5, "Track DCAr cut to PV Maximum"}; Configurable cfgMaxbDCAzToPVcut{"cfgMaxbDCAzToPVcut", 1.0, "Track DCAz cut to PV Maximum"}; + // PID + Configurable cfgPIDnSigmaCut{"cfgPIDnSigmaCut", 3.0, "PID nSigma cut"}; } TrackCuts; + Configurable applyMCStudy{"applyMCStudy", false, "Apply MC study"}; + // Configurable for track selection Configurable trackSelection{"trackSelection", 0, "Track selection: 0 -> No Cut, 1 -> kGlobalTrack, 2 -> kGlobalTrackWoPtEta, 3 -> kGlobalTrackWoDCA, 4 -> kQualityTracks, 5 -> kInAcceptanceTracks"}; @@ -126,10 +140,12 @@ struct JFlucEfficiencyTask { Configurable cfgCentBinsForMC{"cfgCentBinsForMC", 1, "Centrality bins for MC, 0: off, 1: on"}; using CollisionCandidates = soa::Join; using CollisionRun2Candidates = soa::Join; - using TrackCandidates = soa::Join; + using TrackCandidates = soa::Join; + using TrackCandidatesPID = soa::Join; using MCCollisionCandidates = soa::Join; using MCRun2CollisionCandidates = soa::Join; using MCTrackCandidates = soa::Join; + using MCTrackCandidatesPID = soa::Join; using BCsWithRun2Info = soa::Join; // Histogram Registry @@ -168,25 +184,71 @@ struct JFlucEfficiencyTask { rctChecker.init(EventCuts.cfgEvtRCTFlagCheckerLabel, EventCuts.cfgEvtRCTFlagCheckerZDCCheck, EventCuts.cfgEvtRCTFlagCheckerLimitAcceptAsBad); - if (doprocessDerivedMC || doprocessMC || doprocessMCRun2) { - registry.add("hPtGen", "Generated p_{T} (all);p_{T} (GeV/c);Centrality (%);Counts", - o2::framework::HistType::kTH2F, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}); + // Helper function to add histograms with consistent naming + auto addHistograms = [this](const std::string& prefix, bool isMC = false) { + if (isMC) { + // Generated (MC) histograms - pT has all variations + registry.add(Form("hPtGen%s", prefix.c_str()), + Form("Generated p_{T} %s;p_{T} (GeV/c);Centrality (%%);Counts", prefix.c_str()), + {HistType::kTH2F, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}}); + } + + // Reconstructed histograms - pT has all variations + registry.add(Form("hPtRec%s", prefix.c_str()), + Form("Reconstructed p_{T} %s;p_{T} (GeV/c);Centrality (%%);Counts", prefix.c_str()), + {HistType::kTH2F, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}}); + }; + + // Add MC histograms if MC processing is enabled + if (doprocessDerivedMC || doprocessMC || doprocessMCRun2 || doprocessMCPID) { + addHistograms("", true); // hPtGen, hPtRec + addHistograms("Pos", true); // hPtGenPos, hPtRecPos + addHistograms("Neg", true); // hPtGenNeg, hPtRecNeg + addHistograms("_Pos", true); // hPtGen_Pos, hPtRec_Pos + addHistograms("_Neg", true); // hPtGen_Neg, hPtRec_Neg + addHistograms("Pos_Pos", true); // hPtGenPos_Pos, hPtRecPos_Pos + addHistograms("Pos_Neg", true); // hPtGenPos_Neg, hPtRecPos_Neg + addHistograms("Neg_Pos", true); // hPtGenNeg_Pos, hPtRecNeg_Pos + addHistograms("Neg_Neg", true); // hPtGenNeg_Neg, hPtRecNeg_Neg + } else { + // Add reconstructed histograms + addHistograms(""); // hPtRec + addHistograms("_Pos"); // hPtRec_Pos + addHistograms("_Neg"); // hPtRec_Neg + addHistograms("Pos"); // hPtRecPos + addHistograms("Neg"); // hPtRecNeg + addHistograms("Pos_Pos"); // hPtRecPos_Pos + addHistograms("Pos_Neg"); // hPtRecPos_Neg + addHistograms("Neg_Pos"); // hPtRecNeg_Pos + addHistograms("Neg_Neg"); // hPtRecNeg_Neg + } + // Add basic eta histograms separately + if (doprocessDerivedMC || doprocessMC || doprocessMCRun2 || doprocessMCPID) { registry.add("hEtaGen", "Generated #eta (all);#eta;Centrality (%);Counts", - o2::framework::HistType::kTH2F, {AxisSpec(100, -1, 1), AxisSpec(axisMultiplicity)}); - registry.add("hPtGenPos", "Generated p_{T} (positive);p_{T} (GeV/c);Centrality (%);Counts", - o2::framework::HistType::kTH2F, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}); - registry.add("hPtGenNeg", "Generated p_{T} (negative);p_{T} (GeV/c);Centrality (%);Counts", - o2::framework::HistType::kTH2F, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}); - } - registry.add("hPtRec", "Reconstructed p_{T} (all);p_{T} (GeV/c);Centrality (%);Counts", - o2::framework::HistType::kTH2F, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}); + {HistType::kTH2F, {AxisSpec(100, -1, 1), AxisSpec(axisMultiplicity)}}); + } registry.add("hEtaRec", "Reconstructed #eta (all);#eta;Centrality (%);Counts", - o2::framework::HistType::kTH2F, {AxisSpec(100, -1, 1), AxisSpec(axisMultiplicity)}); - registry.add("hPtRecPos", "Reconstructed p_{T} (positive);p_{T} (GeV/c);Centrality (%);Counts", - o2::framework::HistType::kTH2F, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}); - registry.add("hPtRecNeg", "Reconstructed p_{T} (negative);p_{T} (GeV/c);Centrality (%);Counts", - o2::framework::HistType::kTH2F, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}); + {HistType::kTH2F, {AxisSpec(100, -1, 1), AxisSpec(axisMultiplicity)}}); + + // Add pT uncertainty histograms + registry.add("hPtUncertainty", "Track p_{T} uncertainty;p_{T} (GeV/c);Centrality (%);p_{T} uncertainty (GeV/c)", + {HistType::kTH3F, {AxisSpec(axisPt), AxisSpec(axisMultiplicity), AxisSpec(100, 0, 10)}}); + registry.add("hPtUncertaintyPos", "Track p_{T} uncertainty (positive);p_{T} (GeV/c);Centrality (%);p_{T} uncertainty (GeV/c)", + {HistType::kTH3F, {AxisSpec(axisPt), AxisSpec(axisMultiplicity), AxisSpec(100, 0, 10)}}); + registry.add("hPtUncertaintyNeg", "Track p_{T} uncertainty (negative);p_{T} (GeV/c);Centrality (%);p_{T} uncertainty (GeV/c)", + {HistType::kTH3F, {AxisSpec(axisPt), AxisSpec(axisMultiplicity), AxisSpec(100, 0, 10)}}); + + // Add MC study histograms if enabled + if (applyMCStudy && (doprocessDerivedMC || doprocessMC || doprocessMCRun2 || doprocessMCPID)) { + registry.add("hChargeSignMismatch", "Charge-Sign mismatch cases", {HistType::kTH2D, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}}); + registry.add("hChargeSignMismatchPos", "MC charge + but track sign -", {HistType::kTH2D, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}}); + registry.add("hChargeSignMismatchNeg", "MC charge - but track sign +", {HistType::kTH2D, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}}); + registry.add("hChargeSignMatch", "Charge-Sign match cases", {HistType::kTH2D, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}}); + registry.add("hChargeSignMatchPos", "MC charge + and track sign +", {HistType::kTH2D, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}}); + registry.add("hChargeSignMatchNeg", "MC charge - and track sign -", {HistType::kTH2D, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}}); + } + // Add efficiency histograms if enabled if (doprocessEfficiency) { registry.add("hPtGenData", "Generated p_{T} from data events (all);p_{T} (GeV/c);Centrality (%);Counts", {HistType::kTH2F, {axisPt, axisMultiplicity}}); @@ -197,16 +259,16 @@ struct JFlucEfficiencyTask { registry.add("hPtGenDataNeg", "Generated p_{T} from data events (negative);p_{T} (GeV/c);Centrality (%);Counts", {HistType::kTH2F, {axisPt, axisMultiplicity}}); registry.add("hPtRecData", "Reconstructed p_{T} (all);p_{T} (GeV/c);Centrality (%);Counts", - o2::framework::HistType::kTH2F, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}); + {HistType::kTH2F, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}}); registry.add("hEtaRecData", "Reconstructed #eta (all);#eta;Centrality (%);Counts", - o2::framework::HistType::kTH2F, {AxisSpec(100, -1, 1), AxisSpec(axisMultiplicity)}); + {HistType::kTH2F, {AxisSpec(100, -1, 1), AxisSpec(axisMultiplicity)}}); registry.add("hPtRecDataPos", "Reconstructed p_{T} (positive);p_{T} (GeV/c);Centrality (%);Counts", - o2::framework::HistType::kTH2F, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}); + {HistType::kTH2F, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}}); registry.add("hPtRecDataNeg", "Reconstructed p_{T} (negative);p_{T} (GeV/c);Centrality (%);Counts", - o2::framework::HistType::kTH2F, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}); + {HistType::kTH2F, {AxisSpec(axisPt), AxisSpec(axisMultiplicity)}}); } - // Initialize histogram labels + // Histogram labels auto h1 = registry.get(HIST("hEventCounterMC")); auto h2 = registry.get(HIST("hEventCounterReco")); @@ -239,7 +301,7 @@ struct JFlucEfficiencyTask { if (p != nullptr) { charge = p->Charge(); } - return std::abs(charge) >= 3.; + return std::abs(charge) >= kChargeThreshold; } // Track selection template @@ -339,6 +401,123 @@ struct JFlucEfficiencyTask { } Preslice perCollision = aod::track::collisionId; + // Common histogram filling function for tracks + template + void fillTrackHistograms(const TrackType& track, float centrality) + { + // Basic pT and eta histograms + registry.fill(HIST("hPtRec"), track.pt(), centrality); + registry.fill(HIST("hEtaRec"), track.eta(), centrality); + + // pT histograms by eta direction + if (track.eta() > 0) { + registry.fill(HIST("hPtRec_Pos"), track.pt(), centrality); + } else if (track.eta() < 0) { + registry.fill(HIST("hPtRec_Neg"), track.pt(), centrality); + } + + // Charge sign specific histograms + if (track.sign() > 0) { // Positive tracks + registry.fill(HIST("hPtRecPos"), track.pt(), centrality); + if (track.eta() > 0) { + registry.fill(HIST("hPtRecPos_Pos"), track.pt(), centrality); + } else if (track.eta() < 0) { + registry.fill(HIST("hPtRecPos_Neg"), track.pt(), centrality); + } + } else if (track.sign() < 0) { // Negative tracks + registry.fill(HIST("hPtRecNeg"), track.pt(), centrality); + if (track.eta() > 0) { + registry.fill(HIST("hPtRecNeg_Pos"), track.pt(), centrality); + } else if (track.eta() < 0) { + registry.fill(HIST("hPtRecNeg_Neg"), track.pt(), centrality); + } + } + + // pT uncertainty histograms + auto ptUncertaintySigma = track.c1Pt21Pt2() * track.pt() * track.pt(); // Variance of pT + auto ptUncertainty = std::sqrt(ptUncertaintySigma); // Standard deviation of pT + registry.fill(HIST("hPtUncertainty"), track.pt(), centrality, ptUncertainty); + + if (track.sign() > 0) { + registry.fill(HIST("hPtUncertaintyPos"), track.pt(), centrality, ptUncertainty); + } else if (track.sign() < 0) { + registry.fill(HIST("hPtUncertaintyNeg"), track.pt(), centrality, ptUncertainty); + } + } + + // Common histogram filling function for MC particles + template + void fillMCParticleHistograms(const ParticleType& particle, float centrality) + { + registry.fill(HIST("hPtGen"), particle.pt(), centrality); + registry.fill(HIST("hEtaGen"), particle.eta(), centrality); + + // pT histograms by eta direction + if (particle.eta() > 0) { + registry.fill(HIST("hPtGen_Pos"), particle.pt(), centrality); + } else if (particle.eta() < 0) { + registry.fill(HIST("hPtGen_Neg"), particle.pt(), centrality); + } + + // Charge sign specific histograms + auto charge = getCharge(particle); + if (charge > 0) { // Positive particles + registry.fill(HIST("hPtGenPos"), particle.pt(), centrality); + if (particle.eta() > 0) { + registry.fill(HIST("hPtGenPos_Pos"), particle.pt(), centrality); + } else if (particle.eta() < 0) { + registry.fill(HIST("hPtGenPos_Neg"), particle.pt(), centrality); + } + } else if (charge < 0) { // Negative particles + registry.fill(HIST("hPtGenNeg"), particle.pt(), centrality); + if (particle.eta() > 0) { + registry.fill(HIST("hPtGenNeg_Pos"), particle.pt(), centrality); + } else if (particle.eta() < 0) { + registry.fill(HIST("hPtGenNeg_Neg"), particle.pt(), centrality); + } + } + } + + // Common event selection function + template + bool selectEvent(const CollisionType& collision, float& centrality) + { + if (!colCuts.isSelected(collision)) { + return false; + } + + if (EventCuts.cfgEvtUseRCTFlagChecker && !rctChecker(collision)) { + return false; + } + + colCuts.fillQA(collision); + centrality = collision.centFT0C(); + + if (centrality < EventCuts.cfgCentMin || centrality > EventCuts.cfgCentMax) { + return false; + } + + return true; + } + + // Common event selection function for Run2 data + template + bool selectEventRun2(const CollisionType& collision, float& centrality) + { + if (!colCuts.isSelected(collision)) { + return false; + } + + colCuts.fillQARun2(collision); + centrality = collision.centRun2V0M(); + + if (centrality < EventCuts.cfgCentMin || centrality > EventCuts.cfgCentMax) { + return false; + } + + return true; + } + void processMC(aod::McCollisions::iterator const& mcCollision, soa::SmallGroups const& collisions, soa::Filtered const& mcTracks, @@ -354,8 +533,9 @@ struct JFlucEfficiencyTask { if (cfgAcceptSplitCollisions == 0 && collisions.size() > 1) { return; } + float centrality = -999; - for (const auto& collision : collisions) { // Anayway only 1 collision per mcCollision will be selected + for (const auto& collision : collisions) { // Anyway only 1 collision per mcCollision will be selected if (!colCuts.isSelected(collision)) // Default event selection return; if (EventCuts.cfgEvtUseRCTFlagChecker && !rctChecker(collision)) { @@ -364,32 +544,32 @@ struct JFlucEfficiencyTask { colCuts.fillQA(collision); centrality = collision.centFT0C(); } + registry.fill(HIST("hEventCounterMC"), 1); registry.fill(HIST("hZVertexMC"), mcCollision.posZ(), centrality); + if (centrality < EventCuts.cfgCentMin || centrality > EventCuts.cfgCentMax) { return; } + + // Fill MC particle histograms for (const auto& particle : mcParticles) { - auto charge = getCharge(particle); if ((!particle.isPhysicalPrimary()) || !isChargedParticle(particle.pdgCode())) { continue; } // pT and eta selections - if (particle.pt() < TrackCuts.cfgMinPt || particle.pt() > TrackCuts.cfgMaxPt || particle.eta() < TrackCuts.cfgEtaMin || particle.eta() > TrackCuts.cfgEtaMax) { + if (particle.pt() < TrackCuts.cfgMinPt || particle.pt() > TrackCuts.cfgMaxPt || + particle.eta() < TrackCuts.cfgEtaMin || particle.eta() > TrackCuts.cfgEtaMax) { continue; } - registry.fill(HIST("hPtGen"), particle.pt(), centrality); - registry.fill(HIST("hEtaGen"), particle.eta(), centrality); - if (charge > 0) { // Positive particles - registry.fill(HIST("hPtGenPos"), particle.pt(), centrality); - } else if (charge < 0) { // Negative particles - registry.fill(HIST("hPtGenNeg"), particle.pt(), centrality); - } + fillMCParticleHistograms(particle, centrality); } - // Reconstruct tracks from MC particles + + // Process reconstructed tracks for (const auto& collision : collisions) { registry.fill(HIST("hZVertexReco"), collision.posZ(), centrality); registry.fill(HIST("hZVertexCorrelation"), mcCollision.posZ(), collision.posZ()); + auto tracks = mcTracks.sliceBy(perCollision, collision.globalIndex()); for (const auto& track : tracks) { if (!track.has_mcParticle()) { @@ -402,13 +582,137 @@ struct JFlucEfficiencyTask { if (!mcPart.isPhysicalPrimary() || !isChargedParticle(mcPart.pdgCode())) { continue; } - registry.fill(HIST("hPtRec"), track.pt(), centrality); - registry.fill(HIST("hEtaRec"), track.eta(), centrality); - if (track.sign() > 0) { // Positive tracks - registry.fill(HIST("hPtRecPos"), track.pt(), centrality); - } else if (track.sign() < 0) { // Negative tracks - registry.fill(HIST("hPtRecNeg"), track.pt(), centrality); + + if (applyMCStudy) { + // Check charge-sign consistency + auto mcCharge = getCharge(mcPart); + auto trackSign = track.sign(); + + if (mcCharge > 0 && trackSign > 0) { + // MC charge + and track sign + + registry.fill(HIST("hChargeSignMatchPos"), track.pt(), centrality); + registry.fill(HIST("hChargeSignMatch"), track.pt(), centrality); + } else if (mcCharge < 0 && trackSign < 0) { + // MC charge - and track sign - + registry.fill(HIST("hChargeSignMatchNeg"), track.pt(), centrality); + registry.fill(HIST("hChargeSignMatch"), track.pt(), centrality); + } else if (mcCharge > 0 && trackSign < 0) { + // MC charge + but track sign - + registry.fill(HIST("hChargeSignMismatchPos"), track.pt(), centrality); + registry.fill(HIST("hChargeSignMismatch"), track.pt(), centrality); + } else if (mcCharge < 0 && trackSign > 0) { + // MC charge - but track sign + + registry.fill(HIST("hChargeSignMismatchNeg"), track.pt(), centrality); + registry.fill(HIST("hChargeSignMismatch"), track.pt(), centrality); + } } + + fillTrackHistograms(track, centrality); + } + } + } + + Preslice perCollisionPID = aod::track::collisionId; + void processMCPID(aod::McCollisions::iterator const& mcCollision, + soa::SmallGroups const& collisions, + soa::Filtered const& mcTracks, + aod::McParticles const& mcParticles) + { + registry.fill(HIST("hEventCounterMC"), 0); + if (!(std::abs(mcCollision.posZ()) < EventCuts.cfgEvtZvtx)) { + return; + } + if (collisions.size() < 1) { + return; + } + if (cfgAcceptSplitCollisions == 0 && collisions.size() > 1) { + return; + } + + float centrality = -999; + for (const auto& collision : collisions) { // Anyway only 1 collision per mcCollision will be selected + if (!colCuts.isSelected(collision)) // Default event selection + return; + if (EventCuts.cfgEvtUseRCTFlagChecker && !rctChecker(collision)) { + return; + } + colCuts.fillQA(collision); + centrality = collision.centFT0C(); + } + + registry.fill(HIST("hEventCounterMC"), 1); + registry.fill(HIST("hZVertexMC"), mcCollision.posZ(), centrality); + + if (centrality < EventCuts.cfgCentMin || centrality > EventCuts.cfgCentMax) { + return; + } + + // Fill MC particle histograms + for (const auto& particle : mcParticles) { + if (!isChargedParticle(particle.pdgCode())) { + continue; + } + // pT and eta selections + if (particle.pt() < TrackCuts.cfgMinPt || particle.pt() > TrackCuts.cfgMaxPt || + particle.eta() < TrackCuts.cfgEtaMin || particle.eta() > TrackCuts.cfgEtaMax) { + continue; + } + // Check if the particle is a pion + if (std::abs(particle.pdgCode()) != std::abs(kPiPlus)) { + continue; + } + fillMCParticleHistograms(particle, centrality); + } + + // Process reconstructed tracks + for (const auto& collision : collisions) { + registry.fill(HIST("hZVertexReco"), collision.posZ(), centrality); + registry.fill(HIST("hZVertexCorrelation"), mcCollision.posZ(), collision.posZ()); + + auto tracks = mcTracks.sliceBy(perCollisionPID, collision.globalIndex()); + for (const auto& track : tracks) { + if (!track.has_mcParticle()) { + continue; + } + if (std::abs(track.tpcNSigmaPi()) > TrackCuts.cfgPIDnSigmaCut) { + continue; + } + if (!trackCut(track)) { + continue; + } + auto mcPart = track.mcParticle(); + if (!isChargedParticle(mcPart.pdgCode())) { + continue; + } + if (std::abs(mcPart.pdgCode()) != kPiPlus) { + continue; + } + + if (applyMCStudy) { + // Check charge-sign consistency + auto mcCharge = getCharge(mcPart); + auto trackSign = track.sign(); + + if (mcCharge > 0 && trackSign > 0) { + // MC charge + and track sign + + registry.fill(HIST("hChargeSignMatchPos"), track.pt(), centrality); + registry.fill(HIST("hChargeSignMatch"), track.pt(), centrality); + } else if (mcCharge < 0 && trackSign < 0) { + // MC charge - and track sign - + registry.fill(HIST("hChargeSignMatchNeg"), track.pt(), centrality); + registry.fill(HIST("hChargeSignMatch"), track.pt(), centrality); + } else if (mcCharge > 0 && trackSign < 0) { + // MC charge + but track sign - + registry.fill(HIST("hChargeSignMismatchPos"), track.pt(), centrality); + registry.fill(HIST("hChargeSignMismatch"), track.pt(), centrality); + } else if (mcCharge < 0 && trackSign > 0) { + // MC charge - but track sign + + registry.fill(HIST("hChargeSignMismatchNeg"), track.pt(), centrality); + registry.fill(HIST("hChargeSignMismatch"), track.pt(), centrality); + } + } + + fillTrackHistograms(track, centrality); } } } @@ -429,39 +733,40 @@ struct JFlucEfficiencyTask { if (cfgAcceptSplitCollisions == 0 && collisions.size() > 1) { return; } + float centrality = -999; - for (const auto& collision : collisions) { // Anayway only 1 collision per mcCollision will be selected + for (const auto& collision : collisions) { // Anyway only 1 collision per mcCollision will be selected if (!colCuts.isSelected(collision)) // Default event selection return; colCuts.fillQARun2(collision); centrality = collision.centRun2V0M(); } + registry.fill(HIST("hEventCounterMC"), 1); registry.fill(HIST("hZVertexMC"), mcCollision.posZ(), centrality); + if (centrality < EventCuts.cfgCentMin || centrality > EventCuts.cfgCentMax) { return; } + + // Fill MC particle histograms for (const auto& particle : mcParticles) { - auto charge = getCharge(particle); if ((!particle.isPhysicalPrimary()) || !isChargedParticle(particle.pdgCode())) { continue; } // pT and eta selections - if (particle.pt() < TrackCuts.cfgMinPt || particle.pt() > TrackCuts.cfgMaxPt || particle.eta() < TrackCuts.cfgEtaMin || particle.eta() > TrackCuts.cfgEtaMax) { + if (particle.pt() < TrackCuts.cfgMinPt || particle.pt() > TrackCuts.cfgMaxPt || + particle.eta() < TrackCuts.cfgEtaMin || particle.eta() > TrackCuts.cfgEtaMax) { continue; } - registry.fill(HIST("hPtGen"), particle.pt(), centrality); - registry.fill(HIST("hEtaGen"), particle.eta(), centrality); - if (charge > 0) { // Positive particles - registry.fill(HIST("hPtGenPos"), particle.pt(), centrality); - } else if (charge < 0) { // Negative particles - registry.fill(HIST("hPtGenNeg"), particle.pt(), centrality); - } + fillMCParticleHistograms(particle, centrality); } - // Reconstruct tracks from MC particles + + // Process reconstructed tracks for (const auto& collision : collisions) { registry.fill(HIST("hZVertexReco"), collision.posZ(), centrality); registry.fill(HIST("hZVertexCorrelation"), mcCollision.posZ(), collision.posZ()); + auto tracks = mcTracks.sliceBy(perCollision, collision.globalIndex()); for (const auto& track : tracks) { if (!track.has_mcParticle()) { @@ -471,71 +776,66 @@ struct JFlucEfficiencyTask { if (!mcPart.isPhysicalPrimary() || !isChargedParticle(mcPart.pdgCode())) { continue; } - // pT and eta selections if (!trackCut(track)) { continue; } - registry.fill(HIST("hPtRec"), track.pt(), centrality); - registry.fill(HIST("hEtaRec"), track.eta(), centrality); - if (track.sign() > 0) { // Positive tracks - registry.fill(HIST("hPtRecPos"), track.pt(), centrality); - } else if (track.sign() < 0) { // Negative tracks - registry.fill(HIST("hPtRecNeg"), track.pt(), centrality); - } + + fillTrackHistograms(track, centrality); } } } void processData(CollisionCandidates::iterator const& collision, soa::Filtered const& tracks) { - if (!colCuts.isSelected(collision)) // Default event selection - return; - if (EventCuts.cfgEvtUseRCTFlagChecker && !rctChecker(collision)) { + float centrality; + if (!selectEvent(collision, centrality)) { return; } - colCuts.fillQA(collision); - auto centrality = collision.centFT0C(); - if (centrality < EventCuts.cfgCentMin || centrality > EventCuts.cfgCentMax) { + + registry.fill(HIST("hZVertexReco"), collision.posZ(), centrality); + + for (const auto& track : tracks) { + if (!trackCut(track)) { + continue; + } + fillTrackHistograms(track, centrality); + } + } + + void processDataPID(CollisionCandidates::iterator const& collision, soa::Filtered const& tracks) + { + float centrality; + if (!selectEvent(collision, centrality)) { return; } + registry.fill(HIST("hZVertexReco"), collision.posZ(), centrality); + for (const auto& track : tracks) { - // pT and eta selections if (!trackCut(track)) { continue; } - registry.fill(HIST("hPtRec"), track.pt(), centrality); - registry.fill(HIST("hEtaRec"), track.eta(), centrality); - if (track.sign() > 0) { // Positive tracks - registry.fill(HIST("hPtRecPos"), track.pt(), centrality); - } else if (track.sign() < 0) { // Negative tracks - registry.fill(HIST("hPtRecNeg"), track.pt(), centrality); + if (std::abs(track.tpcNSigmaPi()) > TrackCuts.cfgPIDnSigmaCut) { + continue; } + fillTrackHistograms(track, centrality); } } void processDataRun2(CollisionRun2Candidates::iterator const& collision, soa::Filtered const& tracks, BCsWithRun2Info const&) { - if (!colCuts.isSelected(collision)) // Default event selection - return; - colCuts.fillQARun2(collision); - auto centrality = collision.centRun2V0M(); - if (centrality < EventCuts.cfgCentMin || centrality > EventCuts.cfgCentMax) { + float centrality; + if (!selectEventRun2(collision, centrality)) { return; } + registry.fill(HIST("hZVertexReco"), collision.posZ(), centrality); + for (const auto& track : tracks) { - // pT and eta selections if (!trackCut(track)) { continue; } - registry.fill(HIST("hPtRec"), track.pt(), centrality); - registry.fill(HIST("hEtaRec"), track.eta(), centrality); - if (track.sign() > 0) { // Positive tracks - registry.fill(HIST("hPtRecPos"), track.pt(), centrality); - } else if (track.sign() < 0) { // Negative tracks - registry.fill(HIST("hPtRecNeg"), track.pt(), centrality); - } + fillTrackHistograms(track, centrality); } } @@ -644,8 +944,10 @@ struct JFlucEfficiencyTask { } PROCESS_SWITCH(JFlucEfficiencyTask, processMC, "Process MC only", false); + PROCESS_SWITCH(JFlucEfficiencyTask, processMCPID, "Process MC with PID only", false); PROCESS_SWITCH(JFlucEfficiencyTask, processMCRun2, "Process Run2 MC only", false); PROCESS_SWITCH(JFlucEfficiencyTask, processData, "Process data only", false); + PROCESS_SWITCH(JFlucEfficiencyTask, processDataPID, "Process data with PID only", false); PROCESS_SWITCH(JFlucEfficiencyTask, processDataRun2, "Process Run2 data only", false); PROCESS_SWITCH(JFlucEfficiencyTask, processDerivedMC, "Process derived MC only", false); PROCESS_SWITCH(JFlucEfficiencyTask, processDerivedData, "Process derived data only", false); diff --git a/PWGCF/JCorran/Tasks/jflucAnalysisTask.cxx b/PWGCF/JCorran/Tasks/jflucAnalysisTask.cxx index 6e0ba68d2df..8f1244661c7 100644 --- a/PWGCF/JCorran/Tasks/jflucAnalysisTask.cxx +++ b/PWGCF/JCorran/Tasks/jflucAnalysisTask.cxx @@ -12,25 +12,27 @@ /// \author Dong Jo Kim (djkim@jyu.fi) /// \since Sep 2022 -#include +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/AnalysisTask.h" #include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" +#include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" - -#include "Common/DataModel/EventSelection.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/Centrality.h" +#include "Framework/RunningWorkflowInfo.h" #include "ReconstructionDataFormats/V0.h" +#include + // #include "CCDB/BasicCCDBManager.h" -#include "PWGCF/JCorran/DataModel/JCatalyst.h" -#include "PWGCF/DataModel/CorrelationsDerived.h" #include "JFFlucAnalysis.h" #include "JFFlucAnalysisO2Hist.h" + +#include "PWGCF/DataModel/CorrelationsDerived.h" +#include "PWGCF/JCorran/DataModel/JCatalyst.h" + #include "Framework/runDataProcessing.h" using namespace o2; @@ -52,6 +54,8 @@ struct jflucAnalysisTask { O2_DEFINE_CONFIGURABLE(etamax, float, 0.8, "Maximum eta for tracks"); O2_DEFINE_CONFIGURABLE(ptmin, float, 0.2, "Minimum pt for tracks"); O2_DEFINE_CONFIGURABLE(ptmax, float, 5.0, "Maximum pt for tracks"); + O2_DEFINE_CONFIGURABLE(cfgCentBinsForMC, int, 0, "0 = OFF and 1 = ON for data like multiplicity/centrality bins for MC process"); + O2_DEFINE_CONFIGURABLE(cfgMultCorrelationsMask, uint16_t, 0, "Selection bitmask for the multiplicity correlations. This should match the filter selection cfgEstimatorBitMask.") ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 100.1}, "multiplicity / centrality axis for histograms"}; ConfigurableAxis phiAxis{"axisPhi", {50, 0.0, o2::constants::math::TwoPI}, "phi axis for histograms"}; @@ -60,8 +64,9 @@ struct jflucAnalysisTask { ConfigurableAxis ptAxis{"axisPt", {60, 0.0, 300.0}, "pt axis for histograms"}; ConfigurableAxis massAxis{"axisMass", {1, 0.0, 10.0}, "mass axis for histograms"}; - Filter jtrackFilter = (aod::jtrack::pt > ptmin) && (aod::jtrack::pt < ptmax); // eta cuts done by jfluc - Filter cftrackFilter = (aod::cftrack::pt > ptmin) && (aod::cftrack::pt < ptmax); // eta cuts done by jfluc + Filter jtrackFilter = (aod::jtrack::pt > ptmin) && (aod::jtrack::pt < ptmax); // eta cuts done by jfluc + Filter cftrackFilter = (aod::cftrack::pt > ptmin) && (aod::cftrack::pt < ptmax); // eta cuts done by jfluc + Filter cfmcparticleFilter = (aod::cfmcparticle::pt > ptmin) && (aod::cfmcparticle::pt < ptmax) && (aod::cfmcparticle::sign != 0); // eta cuts done by jfluc Filter cf2pFilter = (aod::cf2prongtrack::pt > ptmin) && (aod::cf2prongtrack::pt < ptmax); HistogramRegistry registry{"registry"}; @@ -74,15 +79,15 @@ struct jflucAnalysisTask { auto axisSpecZvt = AxisSpec(zvtAxis); auto axisSpecPt = AxisSpec(ptAxis); auto axisSpecMass = AxisSpec(massAxis); - if (doprocessJDerived || doprocessJDerivedCorrected || doprocessCFDerived || doprocessCFDerivedCorrected) { - pcf = new JFFlucAnalysisO2Hist(registry, axisSpecMult, axisSpecPhi, axisSpecEta, axisSpecZvt, axisSpecPt, axisSpecMass, "jfluc"); + if (doprocessJDerived || doprocessJDerivedCorrected || doprocessCFDerived || doprocessCFDerivedCorrected || doprocessCFDerivedMultSet || doprocessCFDerivedMultSetCorrected || doprocessMCCFDerived) { + pcf = new JFFlucAnalysisO2Hist(registry, axisSpecMult, axisSpecPhi, axisSpecEta, axisSpecZvt, axisSpecPt, axisSpecMass, cfgMultCorrelationsMask, "jfluc"); pcf->AddFlags(JFFlucAnalysis::kFlucEbEWeighting); pcf->UserCreateOutputObjects(); } else { pcf = 0; } if (doprocessCF2ProngDerived || doprocessCF2ProngDerivedCorrected) { - pcf2Prong = new JFFlucAnalysisO2Hist(registry, axisSpecMult, axisSpecPhi, axisSpecEta, axisSpecZvt, axisSpecPt, axisSpecMass, "jfluc2prong"); + pcf2Prong = new JFFlucAnalysisO2Hist(registry, axisSpecMult, axisSpecPhi, axisSpecEta, axisSpecZvt, axisSpecPt, axisSpecMass, cfgMultCorrelationsMask, "jfluc2prong"); pcf2Prong->AddFlags(JFFlucAnalysis::kFlucEbEWeighting); pcf2Prong->UserCreateOutputObjects(); @@ -91,6 +96,8 @@ struct jflucAnalysisTask { } else { pcf2Prong = 0; } + if ((doprocessCFDerivedMultSet || doprocessCFDerivedMultSetCorrected) && cfgMultCorrelationsMask == 0) + LOGF(fatal, "cfgMultCorrelationsMask can not be 0 when MultSet process functions are in use."); } template @@ -103,6 +110,7 @@ struct jflucAnalysisTask { pcf->SetEventCentrality(collision.multiplicity()); pcf->SetEventVertex(collision.posZ()); pcf->FillQA(tracks); + pcf->FillMultSet(collision); qvecs.Calculate(tracks, etamin, etamax); pcf->SetJQVectors(&qvecs); pcf->UserExec(""); @@ -154,6 +162,22 @@ struct jflucAnalysisTask { } PROCESS_SWITCH(jflucAnalysisTask, processCFDerivedCorrected, "Process CF derived data with corrections", true); + void processCFDerivedMultSet(soa::Join::iterator const& collision, soa::Filtered const& tracks) + { + if (std::popcount(cfgMultCorrelationsMask.value) != static_cast(collision.multiplicities().size())) + LOGF(fatal, "Multiplicity selections (cfgMultCorrelationsMask = 0x%x) do not match the size of the table column (%ld). The histogram filling relies on the preservation of order.", cfgMultCorrelationsMask.value, collision.multiplicities().size()); + analyze(collision, tracks); + } + PROCESS_SWITCH(jflucAnalysisTask, processCFDerivedMultSet, "Process CF derived data with multiplicity sets", false); + + void processCFDerivedMultSetCorrected(soa::Join::iterator const& collision, soa::Filtered> const& tracks) + { + if (std::popcount(cfgMultCorrelationsMask.value) != static_cast(collision.multiplicities().size())) + LOGF(fatal, "Multiplicity selections (cfgMultCorrelationsMask = 0x%x) do not match the size of the table column (%ld). The histogram filling relies on the preservation of order.", cfgMultCorrelationsMask.value, collision.multiplicities().size()); + analyze(collision, tracks); + } + PROCESS_SWITCH(jflucAnalysisTask, processCFDerivedMultSetCorrected, "Process CF derived data with corrections and multiplicity sets", false); + void processCF2ProngDerived(aod::CFCollision const& collision, soa::Filtered const& tracks, soa::Filtered const& p2tracks) { analyze(collision, p2tracks, tracks); @@ -166,6 +190,27 @@ struct jflucAnalysisTask { } PROCESS_SWITCH(jflucAnalysisTask, processCF2ProngDerivedCorrected, "Process CF derived data with 2-prongs as POI and charged particles as REF with corrections.", false); + void processMCCFDerived(aod::CFMcCollision const& mcCollision, soa::Filtered const& particles, soa::SmallGroups const& collisions) + { + auto multiplicity = mcCollision.multiplicity(); + if (cfgCentBinsForMC > 0) { + if (collisions.size() == 0) { + return; + } + for (const auto& collision : collisions) { + multiplicity = collision.multiplicity(); + } + } + pcf->Init(); + pcf->SetEventCentrality(multiplicity); + pcf->SetEventVertex(mcCollision.posZ()); + pcf->FillQA(particles); + qvecs.Calculate(particles, etamin, etamax); + pcf->SetJQVectors(&qvecs); + pcf->UserExec(""); + } + PROCESS_SWITCH(jflucAnalysisTask, processMCCFDerived, "Process CF derived MC data", false); + JFFlucAnalysis::JQVectorsT qvecs; JFFlucAnalysis::JQVectorsT qvecsRef; JFFlucAnalysisO2Hist* pcf; diff --git a/PWGCF/JCorran/Tasks/jflucWeightsLoader.cxx b/PWGCF/JCorran/Tasks/jflucWeightsLoader.cxx index 244035fd310..7d15d9b2a6d 100644 --- a/PWGCF/JCorran/Tasks/jflucWeightsLoader.cxx +++ b/PWGCF/JCorran/Tasks/jflucWeightsLoader.cxx @@ -12,27 +12,27 @@ /// \since May 2024 // o2-linter: disable='doc/file' -#include -#include -#include -#include - -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/HistogramRegistry.h" +#include "PWGCF/DataModel/CorrelationsDerived.h" +#include "PWGCF/JCorran/DataModel/JCatalyst.h" -#include "Common/DataModel/EventSelection.h" #include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/Centrality.h" -#include "ReconstructionDataFormats/V0.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" #include "CCDB/BasicCCDBManager.h" - -#include "PWGCF/JCorran/DataModel/JCatalyst.h" -#include "PWGCF/DataModel/CorrelationsDerived.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/RunningWorkflowInfo.h" #include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/V0.h" + +#include +#include + +#include +#include using namespace o2; using namespace o2::framework; @@ -50,7 +50,7 @@ struct JflucWeightsLoader { THnF* ph = 0; TFile* pf = 0; - THnD* pheff = 0; + THnF* pheff = 0; TFile* pfeff = 0; int runNumber = 0; int timestamp = 0; @@ -108,7 +108,6 @@ struct JflucWeightsLoader { useCCDB = false; } else { LOGF(info, "Didn't find \"local://\" or \"ccdb\" for non-uniform acceptance corrections."); - return; } if (cfgPathEffWeights.value.substr(0, 8) == "local://") { @@ -118,16 +117,13 @@ struct JflucWeightsLoader { delete pfeff; pfeff = 0; LOGF(fatal, "Efficiency correction weights file not found: %s", cfgPathEffWeights.value.substr(8).c_str()); - } - // - if (!(pheff = pfeff->Get("ccdb_object"))) { + } else if (!(pheff = pfeff->Get("ccdb_object"))) { LOGF(warning, "Efficiency correction histogram not found."); } else { LOGF(info, "Loaded efficiency correction histogram locally."); } } else { LOGF(info, "Didn't find \"local://\" or \"ccdb\" for efficiency corrections."); - return; } } diff --git a/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx b/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx index 5f856d409ca..a64d25c6d67 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/threeParticleCorrelations.cxx @@ -45,7 +45,7 @@ struct ThreeParticleCorrelations { // Track PID parameters double pionID = 0.0, kaonID = 1.0, protonID = 2.0; - float nSigma0 = 0.0, nSigma2 = 2.0, nSigma4 = 4.0, nSigma5 = 5.0; + float nSigma0 = 0.0, nSigma1 = 1.0, nSigma2 = 2.0, nSigma4 = 4.0, nSigma5 = 5.0; // V0 filter parameters float tpcNCrossedRowsMin = 70.0; @@ -55,8 +55,8 @@ struct ThreeParticleCorrelations { int dcaV0DauMax = 1; // Track filter parameters - float pionPtMin = 0.3, pionPtMax = 2.3, kaonPtMin = 0.5, kaonPtMax = 2.5, protonPtMin = 0.5, protonPtMax = 2.5; - float pionPtMid = 1.5, kaonPtMid1 = 1.5, kaonPtMid2 = 2.0, protonPtMid = 0.7; + float pionPtMin = 0.3, pionPtMax = 2.3, kaonPtMin = 0.5, kaonPtMax = 2.3, protonPtMin = 0.6; + float pionPtMid1 = 1.6, pionPtMid2 = 2.0, kaonPtMid1 = 1.5, kaonPtMid2 = 2.0, protonPtMid = 2.3; // RD filter parameters float dEtaMax = 0.05, dEtaMin = 0.023; @@ -179,10 +179,14 @@ struct ThreeParticleCorrelations { rQARegistry.add("hTrackPhi", "hTrackPhi", {HistType::kTH1D, {{100, (-1. / 2) * constants::math::PI, (5. / 2) * constants::math::PI}}}); rQARegistry.add("hTrackNSharedClusters", "hTrackNSharedClusters", {HistType::kTH1D, {{200, 0, 200}}}); - rQARegistry.add("hPtPion", "hPtPion", {HistType::kTH3D, {{trackPtAxis}, {centralityAxis}, {2, -2, 2}}}); - rQARegistry.add("hPtKaon", "hPtKaon", {HistType::kTH3D, {{trackPtAxis}, {centralityAxis}, {2, -2, 2}}}); - rQARegistry.add("hPtProton", "hPtProton", {HistType::kTH3D, {{trackPtAxis}, {centralityAxis}, {2, -2, 2}}}); - rQARegistry.add("hPtV0", "hPtV0", {HistType::kTH3D, {{v0PtAxis}, {centralityAxis}, {2, -2, 2}}}); + rQARegistry.add("hPtPion_Uncorrected", "hPtPion_Uncorrected", {HistType::kTH3D, {{trackPtAxis}, {centralityAxis}, {2, -2, 2}}}); + rQARegistry.add("hPtKaon_Uncorrected", "hPtKaon_Uncorrected", {HistType::kTH3D, {{trackPtAxis}, {centralityAxis}, {2, -2, 2}}}); + rQARegistry.add("hPtProton_Uncorrected", "hPtProton_Uncorrected", {HistType::kTH3D, {{trackPtAxis}, {centralityAxis}, {2, -2, 2}}}); + rQARegistry.add("hPtV0_Uncorrected", "hPtV0_Uncorrected", {HistType::kTH3D, {{v0PtAxis}, {centralityAxis}, {2, -2, 2}}}); + rQARegistry.add("hPtPion_Corrected", "hPtPion_Corrected", {HistType::kTH3D, {{trackPtAxis}, {centralityAxis}, {2, -2, 2}}}); + rQARegistry.add("hPtKaon_Corrected", "hPtKaon_Corrected", {HistType::kTH3D, {{trackPtAxis}, {centralityAxis}, {2, -2, 2}}}); + rQARegistry.add("hPtProton_Corrected", "hPtProton_Corrected", {HistType::kTH3D, {{trackPtAxis}, {centralityAxis}, {2, -2, 2}}}); + rQARegistry.add("hPtV0_Corrected", "hPtV0_Corrected", {HistType::kTH3D, {{v0PtAxis}, {centralityAxis}, {2, -2, 2}}}); rQARegistry.add("hPtPion_MC", "hPtPion_MC", {HistType::kTH3D, {{trackPtAxis}, {centralityAxis}, {2, -2, 2}}}); rQARegistry.add("hPtKaon_MC", "hPtKaon_MC", {HistType::kTH3D, {{trackPtAxis}, {centralityAxis}, {2, -2, 2}}}); rQARegistry.add("hPtProton_MC", "hPtProton_MC", {HistType::kTH3D, {{trackPtAxis}, {centralityAxis}, {2, -2, 2}}}); @@ -197,12 +201,12 @@ struct ThreeParticleCorrelations { rQARegistry.add("hBetaKaon", "hBetaKaon", {HistType::kTH2D, {{56, 0.2, 3.0}, {70, 0.4, 1.1}}}); rQARegistry.add("hBetaProton", "hBetaProton", {HistType::kTH2D, {{56, 0.2, 3.0}, {70, 0.4, 1.1}}}); - rQARegistry.add("hTPCPion", "hTPCPion", {HistType::kTH2D, {{trackPtAxis}, {241, -6, 6}}}); - rQARegistry.add("hTPCKaon", "hTPCKaon", {HistType::kTH2D, {{trackPtAxis}, {241, -6, 6}}}); - rQARegistry.add("hTPCProton", "hTPCProton", {HistType::kTH2D, {{trackPtAxis}, {241, -6, 6}}}); - rQARegistry.add("hTOFPion", "hTOFPion", {HistType::kTH2D, {{trackPtAxis}, {1000, -50, 50}}}); - rQARegistry.add("hTOFKaon", "hTOFKaon", {HistType::kTH2D, {{trackPtAxis}, {1000, -50, 50}}}); - rQARegistry.add("hTOFProton", "hTOFProton", {HistType::kTH2D, {{trackPtAxis}, {1000, -50, 50}}}); + rQARegistry.add("hTPCPion", "hTPCPion", {HistType::kTH2D, {{trackPtAxis}, {1001, -50.05, 50.05}}}); + rQARegistry.add("hTPCKaon", "hTPCKaon", {HistType::kTH2D, {{trackPtAxis}, {1001, -50.05, 50.05}}}); + rQARegistry.add("hTPCProton", "hTPCProton", {HistType::kTH2D, {{trackPtAxis}, {1001, -50.05, 50.05}}}); + rQARegistry.add("hTOFPion", "hTOFPion", {HistType::kTH2D, {{trackPtAxis}, {1001, -50.05, 50.05}}}); + rQARegistry.add("hTOFKaon", "hTOFKaon", {HistType::kTH2D, {{trackPtAxis}, {1001, -50.05, 50.05}}}); + rQARegistry.add("hTOFProton", "hTOFProton", {HistType::kTH2D, {{trackPtAxis}, {1001, -50.05, 50.05}}}); rQARegistry.add("hInvMassLambda", "hInvMassLambda", {HistType::kTH3D, {{lambdaInvMassAxis}, {v0PtAxis}, {centralityAxis}}}); rQARegistry.add("hInvMassAntiLambda", "hInvMassAntiLambda", {HistType::kTH3D, {{lambdaInvMassAxis}, {v0PtAxis}, {centralityAxis}}}); @@ -353,15 +357,18 @@ struct ThreeParticleCorrelations { rQARegistry.fill(HIST("hdEdx"), track.pt(), track.tpcSignal()); rQARegistry.fill(HIST("hBeta"), track.pt(), track.beta()); if (assocPID[0] == pionID) { // Pions - rQARegistry.fill(HIST("hPtPion"), track.pt(), collision.centFT0C(), track.sign(), 1. / trackEff(hEffPions, track, collision.centFT0C())); + rQARegistry.fill(HIST("hPtPion_Uncorrected"), track.pt(), collision.centFT0C(), track.sign()); + rQARegistry.fill(HIST("hPtPion_Corrected"), track.pt(), collision.centFT0C(), track.sign(), 1. / trackEff(hEffPions, track, collision.centFT0C())); rQARegistry.fill(HIST("hdEdxPion"), track.pt(), track.tpcSignal()); rQARegistry.fill(HIST("hBetaPion"), track.pt(), track.beta()); } else if (assocPID[0] == kaonID) { // Kaons - rQARegistry.fill(HIST("hPtKaon"), track.pt(), collision.centFT0C(), track.sign(), 1. / trackEff(hEffKaons, track, collision.centFT0C())); + rQARegistry.fill(HIST("hPtKaon_Uncorrected"), track.pt(), collision.centFT0C(), track.sign()); + rQARegistry.fill(HIST("hPtKaon_Corrected"), track.pt(), collision.centFT0C(), track.sign(), 1. / trackEff(hEffKaons, track, collision.centFT0C())); rQARegistry.fill(HIST("hdEdxKaon"), track.pt(), track.tpcSignal()); rQARegistry.fill(HIST("hBetaKaon"), track.pt(), track.beta()); } else if (assocPID[0] == protonID) { // Protons - rQARegistry.fill(HIST("hPtProton"), track.pt(), collision.centFT0C(), track.sign(), 1. / trackEff(hEffProtons, track, collision.centFT0C())); + rQARegistry.fill(HIST("hPtProton_Uncorrected"), track.pt(), collision.centFT0C(), track.sign()); + rQARegistry.fill(HIST("hPtProton_Corrected"), track.pt(), collision.centFT0C(), track.sign(), 1. / trackEff(hEffProtons, track, collision.centFT0C())); rQARegistry.fill(HIST("hdEdxProton"), track.pt(), track.tpcSignal()); rQARegistry.fill(HIST("hBetaProton"), track.pt(), track.beta()); } @@ -376,7 +383,8 @@ struct ThreeParticleCorrelations { triggSign = v0Sign(trigger); v0Efficiency = v0Eff(hEffLambdas, trigger, collision.centFT0C()); - rQARegistry.fill(HIST("hPtV0"), trigger.pt(), collision.centFT0C(), triggSign, 1. / v0Efficiency); + rQARegistry.fill(HIST("hPtV0_Uncorrected"), trigger.pt(), collision.centFT0C(), triggSign); + rQARegistry.fill(HIST("hPtV0_Corrected"), trigger.pt(), collision.centFT0C(), triggSign, 1. / v0Efficiency); if (triggSign == 1) { candMass = trigger.mLambda(); rQARegistry.fill(HIST("hInvMassLambda"), trigger.mLambda(), trigger.pt(), collision.centFT0C(), 1. / v0Efficiency); @@ -994,11 +1002,15 @@ struct ThreeParticleCorrelations { } if (track.pt() < pionPtMin) { return false; - } else if (track.pt() > pionPtMin && track.pt() < pionPtMid) { + } else if (track.pt() > pionPtMin && track.pt() < pionPtMid1) { if (std::abs(track.tofNSigmaPi()) >= nSigma4) { return false; } - } else if (track.pt() > pionPtMid && track.pt() < pionPtMax) { + } else if (track.pt() > pionPtMid1 && track.pt() < pionPtMid2) { + if (track.tofNSigmaPi() <= -nSigma4 || track.tofNSigmaPi() >= nSigma2) { + return false; + } + } else if (track.pt() > pionPtMid2 && track.pt() < pionPtMax) { if (track.tofNSigmaPi() <= -nSigma4 || track.tofNSigmaPi() >= nSigma0) { return false; } @@ -1017,7 +1029,7 @@ struct ThreeParticleCorrelations { return false; } } else if (track.pt() > kaonPtMid1 && track.pt() < kaonPtMid2) { - if (track.tofNSigmaKa() <= -nSigma2 || track.tofNSigmaKa() >= nSigma4) { + if (track.tofNSigmaKa() <= -nSigma1 || track.tofNSigmaKa() >= nSigma4) { return false; } } else if (track.pt() > kaonPtMid2 && track.pt() < kaonPtMax) { @@ -1035,14 +1047,10 @@ struct ThreeParticleCorrelations { if (track.pt() < protonPtMin) { return false; } else if (track.pt() > protonPtMin && track.pt() < protonPtMid) { - if (track.tofNSigmaPr() <= -nSigma2 || track.tofNSigmaPr() >= nSigma4) { - return false; - } - } else if (track.pt() > protonPtMid && track.pt() < protonPtMax) { if (std::abs(track.tofNSigmaPr()) >= nSigma4) { return false; } - } else if (track.pt() > protonPtMax) { + } else if (track.pt() > protonPtMid) { if (track.tofNSigmaPr() <= -nSigma2 || track.tofNSigmaPr() >= nSigma4) { return false; } diff --git a/PWGCF/TableProducer/dptDptFilter.cxx b/PWGCF/TableProducer/dptDptFilter.cxx index 30f55cf3c3f..2fe925102b8 100644 --- a/PWGCF/TableProducer/dptDptFilter.cxx +++ b/PWGCF/TableProducer/dptDptFilter.cxx @@ -13,40 +13,43 @@ /// \brief Filters collisions and tracks according to selection criteria /// \author victor.gonzalez.sebastian@gmail.com -#include -#include -#include -#include +#include "PWGCF/TableProducer/dptDptFilter.h" + +#include "PWGCF/Core/AnalysisConfigurableCuts.h" +#include "PWGCF/DataModel/DptDptFiltered.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Centrality.h" #include "Common/Core/TableHelper.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponse.h" -#include "PWGCF/Core/AnalysisConfigurableCuts.h" -#include "PWGCF/DataModel/DptDptFiltered.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/CollisionAssociationTables.h" + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" #include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" #include "Framework/RunningWorkflowInfo.h" -#include -#include -#include -#include +#include "Framework/runDataProcessing.h" + #include #include #include #include #include +#include +#include +#include #include +#include -#include "PWGCF/TableProducer/dptDptFilter.h" +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -94,38 +97,70 @@ const char* speciesName[kDptDptNoOfSpecies] = {"h", "e", "mu", "pi", "ka", "p"}; const char* speciesTitle[kDptDptNoOfSpecies] = {"", "e", "#mu", "#pi", "K", "p"}; -const char* eventSelectionSteps[knCollisionSelectionFlags] = { - "IN", - "MB", - "INT7", - "SEL7", - "SEL8", - "NOSAMEBUNCHPUP", - "ISGOODZVTXFT0VSPV", - "ISVERTEXITSTPC", - "ISVERTEXTOFMATCHED", - "ISVERTEXTRDMATCHED", - "NOCOLLINTIMERANGE", - "NOCOLLINROF", - "OCCUPANCY", - "ISGOODITSLAYER3", - "ISGOODITSLAYER0123", - "ISGOODITSLAYERALL", - "CENTRALITY", - "ZVERTEX", - "SELECTED"}; +/// \enum BeforeAfter +/// \brief when filling the histograms +enum BeforeAfter { + BeforeAfterBEFORE = 0, ///< filling the histograms before selections + BeforeAfterAFTER, ///< filling the histograms after selections + BeforeAfterNOOFTIMES ///< how many times fill the histograms +}; + +static const std::vector beforeAfterName = {"before", ""}; +static const std::vector beforeAfterSufix = {"B", "A"}; + +/* helpers for the multiplicity axes definition */ +static constexpr float MultiplicityUpperLimitBase[11][8] = { + /* T0A, T0C, T0M, V0A, V0C, V0M, tracks, PV contr. tracks */ + {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* no system */ + {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* pp Run2 */ + {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* pPb Run2 */ + {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* Pbp Run2 */ + {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* PbPb Run2 */ + {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* XeXe Run2 */ + {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* pp Run3 */ + {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* PbPb Run3 */ + {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* NeNe Run3 */ + {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f}, /* OO Run3 */ + {30e3f, 10e3f, 40e3f, 50e3f, 70e3f, 100e3f, 10e3f, 400.0f} /* pO Run3 */ +}; //============================================================================================ // The DptDptFilter histogram objects // TODO: consider registering in the histogram registry //============================================================================================ +/* event/collision histograms */ TH1D* fhEventSelection = nullptr; +TH1D* fhTriggerSelection = nullptr; +TH2D* fhTriggerSelectionCorrelations = nullptr; TH1F* fhCentMultB = nullptr; TH1F* fhCentMultA = nullptr; TH1F* fhVertexZB = nullptr; TH1F* fhVertexZA = nullptr; TH1F* fhMultB = nullptr; TH1F* fhMultA = nullptr; + +/* multiplicty correlation histograms */ +/* B: before, A: after collision selection */ +/* credits: A. Dobrin team! */ +TH2F* fhMultiplicityVsCentrality[BeforeAfterNOOFTIMES] = {nullptr}; +TH2F* fhMultiplicityVsT0cMultiplicity[BeforeAfterNOOFTIMES] = {nullptr}; +TH2F* fhMultiplicityVsT0aMultiplicity[BeforeAfterNOOFTIMES] = {nullptr}; +TH2F* fhMultiplicityVsV0aMultiplicity[BeforeAfterNOOFTIMES] = {nullptr}; +TH2F* fhMultiplicityVsPvMultiplicity[BeforeAfterNOOFTIMES] = {nullptr}; +TH2F* fhPvMultiplicityVsCentrality[BeforeAfterNOOFTIMES] = {nullptr}; +TH2F* fhPvMultiplicityVsT0cMultiplicity[BeforeAfterNOOFTIMES] = {nullptr}; +TH2F* fhPvMultiplicityVsT0aMultiplicity[BeforeAfterNOOFTIMES] = {nullptr}; +TH2F* fhPvMultiplicityVsV0aMultiplicity[BeforeAfterNOOFTIMES] = {nullptr}; +TH2F* fhV0aMultiplicityVsCentrality[BeforeAfterNOOFTIMES] = {nullptr}; +TH2F* fhV0aMultiplicityVsT0cMultiplicity[BeforeAfterNOOFTIMES] = {nullptr}; +TH2F* fhV0aMultiplicityVsT0aMultiplicity[BeforeAfterNOOFTIMES] = {nullptr}; +TH2F* fhT0cMultiplicityVsCentrality[BeforeAfterNOOFTIMES] = {nullptr}; +TH2F* fhT0cMultiplicityVsT0aMultiplicity[BeforeAfterNOOFTIMES] = {nullptr}; +TH2F* fhT0CentralityVsCentrality[BeforeAfterNOOFTIMES] = {nullptr}; +TH2F* fhV0aCentralityVsCentrality[BeforeAfterNOOFTIMES] = {nullptr}; +TH2F* fhNtpvCentralityVsCentrality[BeforeAfterNOOFTIMES] = {nullptr}; + +/* track histograms */ TH1F* fhPB = nullptr; std::vector fhPA; TH1F* fhPtB = nullptr; @@ -155,11 +190,14 @@ TH2F* fhAmbiguousTrackPt = nullptr; TH2F* fhAmbiguityDegree = nullptr; TH2F* fhCompatibleCollisionsZVtxRms = nullptr; +/* MC generator level event/collision histograms */ TH1F* fhTrueCentMultB = nullptr; TH1F* fhTrueCentMultA = nullptr; TH1F* fhTrueVertexZB = nullptr; TH1F* fhTrueVertexZA = nullptr; TH1F* fhTrueVertexZAA = nullptr; + +/* MC generator level particle histograms */ TH1F* fhTruePB = nullptr; std::vector fhTruePA; TH1F* fhTruePtB = nullptr; @@ -361,27 +399,30 @@ struct Multiplicity { struct DptDptFilter { struct : ConfigurableGroup { - Configurable cfgCCDBUrl{"cfgCCDBUrl", "http://ccdb-test.cern.ch:8080", "The CCDB url for the input file"}; - Configurable cfgCCDBPathName{"cfgCCDBPathName", "", "The CCDB path for the input file. Default \"\", i.e. don't load from CCDB"}; - Configurable cfgCCDBDate{"cfgCCDBDate", "20220307", "The CCDB date for the input file"}; - Configurable cfgCCDBPeriod{"cfgCCDBPeriod", "LHC22o", "The CCDB dataset period for the input file"}; + std::string prefix = "cfgCCDB"; + Configurable url{"url", "http://ccdb-test.cern.ch:8080", "The CCDB url for the input file"}; + Configurable pathName{"pathName", "", "The CCDB path for the input file. Default \"\", i.e. don't load from CCDB"}; + Configurable date{"date", "20220307", "The CCDB date for the input file"}; + Configurable period{"period", "LHC22o", "The CCDB dataset period for the input file"}; } cfginputfile; Configurable cfgFullDerivedData{"cfgFullDerivedData", false, "Produce the full derived data for external storage. Default false"}; Configurable cfgCentMultEstimator{"cfgCentMultEstimator", "V0M", "Centrality/multiplicity estimator detector: V0M,CL0,CL1,FV0A,FT0M,FT0A,FT0C,NTPV,NOCM: none. Default V0M"}; struct : ConfigurableGroup { std::string prefix = "cfgEventSelection"; - Configurable itsDeadMaps{"itsDeadMaps", "", "Level of inactive chips: nocheck(empty), goodIts3, goodIts0123, goodItsAll. Default empty"}; + Configurable fillQc{"fillQc", false, "Fill the quality control histograms. Default: false"}; Configurable minOrbit{"minOrbit", -1, "Lowest orbit to track"}; Configurable maxOrbit{"maxOrbit", INT64_MAX, "Highest orbit to track"}; + Configurable rctSource{"rctSource", "None", "RCT selection source: None,CBT,CBT_hadronPID,CBT_electronPID,CBT_calo,CBT_muon,CBT_muon_glo. Default: None"}; + Configurable> multiplicityUpperLimit{"multiplicityUpperLimit", {&MultiplicityUpperLimitBase[0][0], 11, 8, {systemExternalNamesMap.at(0), systemExternalNamesMap.at(1), systemExternalNamesMap.at(2), systemExternalNamesMap.at(3), systemExternalNamesMap.at(4), systemExternalNamesMap.at(5), systemExternalNamesMap.at(6), systemExternalNamesMap.at(7), systemExternalNamesMap.at(8), systemExternalNamesMap.at(9), systemExternalNamesMap.at(10)}, {multiplicitySourceConfigNamesMap.at(0), multiplicitySourceConfigNamesMap.at(1), multiplicitySourceConfigNamesMap.at(2), multiplicitySourceConfigNamesMap.at(3), multiplicitySourceConfigNamesMap.at(4), multiplicitySourceConfigNamesMap.at(5), multiplicitySourceConfigNamesMap.at(6), multiplicitySourceConfigNamesMap.at(7)}}, "Upper limits for the multiplicity observables"}; struct : ConfigurableGroup { - std::string prefix = "cfgOccupancySelection"; - Configurable cfgOccupancyEstimation{"cfgOccupancyEstimation", "None", "Occupancy estimation: None, Tracks, FT0C. Default None"}; - Configurable cfgMinOccupancy{"cfgMinOccupancy", 0.0f, "Minimum allowed occupancy. Depends on the occupancy estimation"}; - Configurable cfgMaxOccupancy{"cfgMaxOccupancy", 1e6f, "Maximum allowed occupancy. Depends on the occupancy estimation"}; - } cfgOccupancySelection; + std::string prefix = "cfgEventSelection.occupancySelection"; + Configurable occupancyEstimation{"occupancyEstimation", "None", "Occupancy estimation: None, Tracks, FT0C. Default None"}; + Configurable minOccupancy{"minOccupancy", 0.0f, "Minimum allowed occupancy. Depends on the occupancy estimation"}; + Configurable maxOccupancy{"maxOccupancy", 1e6f, "Maximum allowed occupancy. Depends on the occupancy estimation"}; + } occupancySelection; } cfgEventSelection; - Configurable cfgSystem{"cfgSystem", "PbPb", "System: pp, PbPb, Pbp, pPb, XeXe, ppRun3, PbPbRun3. Default PbPb"}; + Configurable cfgSystem{"cfgSystem", "PbPb", "System: Auto, pp, PbPb, Pbp, pPb, XeXe, ppRun3, PbPbRun3. Default PbPb"}; Configurable cfgDataType{"cfgDataType", "data", "Data type: data, datanoevsel, MC, FastMC, OnTheFlyMC. Default data"}; Configurable cfgTriggSel{"cfgTriggSel", "MB", "Trigger selection: MB,VTXTOFMATCHED,VTXTRDMATCHED,VTXTRDTOFMATCHED,None. Default MB"}; Configurable cfgCentSpec{"cfgCentSpec", "00-10,10-20,20-30,30-40,40-50,50-60,60-70,70-80", "Centrality/multiplicity ranges in min-max separated by commas"}; @@ -430,25 +471,33 @@ struct DptDptFilter { /* the track types and combinations */ /* the centrality/multiplicity estimation */ if (doprocessWithoutCent || doprocessWithoutCentDetectorLevel || doprocessWithoutCentGeneratorLevel) { - fCentMultEstimator = kNOCM; + fCentMultEstimator = CentMultNOCM; } else if (doprocessOnTheFlyGeneratorLevel) { - fCentMultEstimator = kFV0A; + fCentMultEstimator = CentMultFV0A; } else { fCentMultEstimator = getCentMultEstimator(cfgCentMultEstimator); } + /* RCT information usage */ + if (cfgEventSelection.rctSource.value == "None") { + useRctInformation = false; + } else { + /* for the time being we don't require ZDC and treat limited acceptance as faulty */ + rctChecker.init(cfgEventSelection.rctSource.value, false, true); + useRctInformation = true; + } + /* the occupancy selection */ - fOccupancyEstimation = getOccupancyEstimator(cfgEventSelection.cfgOccupancySelection.cfgOccupancyEstimation); - fMinOccupancy = cfgEventSelection.cfgOccupancySelection.cfgMinOccupancy; - fMaxOccupancy = cfgEventSelection.cfgOccupancySelection.cfgMaxOccupancy; - /* the ITS dead map check */ - fItsDeadMapCheck = getItsDeadMapCheck(cfgEventSelection.itsDeadMaps); + fOccupancyEstimation = getOccupancyEstimator(cfgEventSelection.occupancySelection.occupancyEstimation); + fMinOccupancy = cfgEventSelection.occupancySelection.minOccupancy; + fMaxOccupancy = cfgEventSelection.occupancySelection.maxOccupancy; /* the trigger selection */ - fTriggerSelection = getTriggerSelection(cfgTriggSel); + triggerSelectionFlags = getTriggerSelection(cfgTriggSel); traceCollId0 = cfgTraceCollId0; /* if the system type is not known at this time, we have to put the initialization somewhere else */ fSystem = getSystemType(cfgSystem); + fLhcRun = multRunForSystemMap.at(fSystem); fDataType = getDataType(cfgDataType); /* create the output list which will own the task histograms */ @@ -458,50 +507,96 @@ struct DptDptFilter { if ((fDataType == kData) || (fDataType == kDataNoEvtSel) || (fDataType == kMC)) { /* create the reconstructed data histograms */ - fhEventSelection = new TH1D("EventSelection", ";;counts", knCollisionSelectionFlags, -0.5f, static_cast(knCollisionSelectionFlags) - 0.5f); - for (int ix = 0; ix < knCollisionSelectionFlags; ++ix) { - fhEventSelection->GetXaxis()->SetBinLabel(ix + 1, eventSelectionSteps[ix]); + fhEventSelection = new TH1D("EventSelection", ";;counts", CollSelNOOFFLAGS, -0.5f, static_cast(CollSelNOOFFLAGS) - 0.5f); + for (int ix = 0; ix < CollSelNOOFFLAGS; ++ix) { + fhEventSelection->GetXaxis()->SetBinLabel(ix + 1, collisionSelectionExternalNamesMap.at(ix).c_str()); } - /* TODO: proper axes and axes titles according to the system; still incomplete */ - std::string multestimator = getCentMultEstimatorName(fCentMultEstimator); - if (fSystem > kPbp) { - fhCentMultB = new TH1F("CentralityB", "Centrality before cut; centrality (%)", 100, 0, 100); - fhCentMultA = new TH1F("CentralityA", "Centrality; centrality (%)", 100, 0, 100); - fhMultB = new TH1F("MultB", TString::Format("%s Multiplicity before cut;%s Multiplicity;Collisions", multestimator.c_str(), multestimator.c_str()), 4001, -0.5, 4000.5); - fhMultA = new TH1F("MultA", TString::Format("%s Multiplicity;%s Multiplicity;Collisions", multestimator.c_str(), multestimator.c_str()), 4001, -0.5, 4000.5); - } else { - /* for pp, pPb and Pbp systems use multiplicity instead */ - fhCentMultB = new TH1F("MultiplicityB", "Multiplicity before cut; multiplicity (%)", 100, 0, 100); - fhCentMultA = new TH1F("MultiplicityA", "Multiplicity; multiplicity (%)", 100, 0, 100); - fhMultB = new TH1F("MultB", TString::Format("%s Multiplicity before cut;%s Multiplicity;Collisions", multestimator.c_str(), multestimator.c_str()), 601, -0.5, 600.5); - fhMultA = new TH1F("MultA", TString::Format("%s Multiplicity;%s Multiplicity;Collisions", multestimator.c_str(), multestimator.c_str()), 601, -0.5, 600.5); + fhTriggerSelection = new TH1D("TriggerSelection", ";;counts", TriggSelNOOFTRIGGERS, -0.5f, static_cast(TriggSelNOOFTRIGGERS) - 0.5f); + for (int ix = 0; ix < TriggSelNOOFTRIGGERS; ++ix) { + fhTriggerSelection->GetXaxis()->SetBinLabel(ix + 1, TString::Format("#color[%d]{%s}", triggerSelectionFlags.test(ix) ? 2 : 1, triggerSelectionExternalNamesMap.at(ix).c_str()).Data()); + } + fhTriggerSelectionCorrelations = new TH2D("TriggerSelectionCorrelations", ";;;counts", + TriggSelNOOFTRIGGERS, -0.5f, static_cast(TriggSelNOOFTRIGGERS) - 0.5f, + TriggSelNOOFTRIGGERS, -0.5f, static_cast(TriggSelNOOFTRIGGERS) - 0.5f); + for (int ixy = 0; ixy < TriggSelNOOFTRIGGERS; ++ixy) { + fhTriggerSelectionCorrelations->GetXaxis()->SetBinLabel(ixy + 1, TString::Format("#color[%d]{%s}", triggerSelectionFlags.test(ixy) ? 2 : 1, triggerSelectionExternalNamesMap.at(ixy).c_str()).Data()); + fhTriggerSelectionCorrelations->GetYaxis()->SetBinLabel(ixy + 1, TString::Format("#color[%d]{%s}", triggerSelectionFlags.test(ixy) ? 2 : 1, triggerSelectionExternalNamesMap.at(ixy).c_str()).Data()); } fhVertexZB = new TH1F("VertexZB", "Vertex Z; z_{vtx}", 60, -15, 15); fhVertexZA = new TH1F("VertexZA", "Vertex Z; z_{vtx}", zvtxbins, zvtxlow, zvtxup); +/* helpers for the multiplicity/centrality axes definition */ +#define DPTDPTCENTRALITYAXIS 105, -0.5f, 104.5f +#define DPTDPTMULTIPLICITYAXIS(est) 1001, -0.5f, cfgEventSelection.multiplicityUpperLimit->getData()[fSystem][est] - 0.5f + + std::string multestimator = getCentMultEstimatorName(fCentMultEstimator); + fhCentMultB = new TH1F("CentralityB", "Centrality before cut; centrality (%)", DPTDPTCENTRALITYAXIS); + fhCentMultA = new TH1F("CentralityA", "Centrality; centrality (%)", DPTDPTCENTRALITYAXIS); + fhMultB = new TH1F("MultB", TString::Format("%s Multiplicity before cut;%s Multiplicity;Collisions", multestimator.c_str(), multestimator.c_str()), DPTDPTMULTIPLICITYAXIS(estimatorMultiplicitySourceMap.at(fCentMultEstimator))); + fhMultA = new TH1F("MultA", TString::Format("%s Multiplicity;%s Multiplicity;Collisions", multestimator.c_str(), multestimator.c_str()), DPTDPTMULTIPLICITYAXIS(estimatorMultiplicitySourceMap.at(fCentMultEstimator))); + + if (cfgEventSelection.fillQc) { + /* the quality control histograms */ + for (int i = 0; i < BeforeAfterNOOFTIMES; ++i) { + fhMultiplicityVsCentrality[i] = new TH2F(TString::Format("MultiplicityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);Number of tracks", beforeAfterName[i].c_str(), multestimator.c_str()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTMULTIPLICITYAXIS(MultSourceNtracks)); + fhMultiplicityVsT0cMultiplicity[i] = new TH2F(TString::Format("MultiplicityVsT0cMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;T0C Multiplicity;Number of tracks", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourceT0C), DPTDPTMULTIPLICITYAXIS(MultSourceNtracks)); + fhMultiplicityVsT0aMultiplicity[i] = new TH2F(TString::Format("MultiplicityVsT0aMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;T0A Multiplicity;Number of tracks", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourceT0A), DPTDPTMULTIPLICITYAXIS(MultSourceNtracks)); + fhMultiplicityVsV0aMultiplicity[i] = new TH2F(TString::Format("MultiplicityVsV0aMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;V0A Multiplicity;Number of tracks", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourceV0A), DPTDPTMULTIPLICITYAXIS(MultSourceNtracks)); + fhMultiplicityVsPvMultiplicity[i] = new TH2F(TString::Format("MultiplicityVsPvMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;PV contributors;Number of tracks", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourcePvContributors), DPTDPTMULTIPLICITYAXIS(MultSourceNtracks)); + fhPvMultiplicityVsCentrality[i] = new TH2F(TString::Format("PvMultiplicityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);PV contributors", beforeAfterName[i].c_str(), multestimator.c_str()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTMULTIPLICITYAXIS(MultSourcePvContributors)); + fhPvMultiplicityVsT0cMultiplicity[i] = new TH2F(TString::Format("PvMultiplicityVsT0cMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;T0C multiplicity;PV contributors", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourceT0C), DPTDPTMULTIPLICITYAXIS(MultSourcePvContributors)); + fhPvMultiplicityVsT0aMultiplicity[i] = new TH2F(TString::Format("PvMultiplicityVsT0aMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;T0A multiplicity;PV contributors", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourceT0A), DPTDPTMULTIPLICITYAXIS(MultSourcePvContributors)); + fhPvMultiplicityVsV0aMultiplicity[i] = new TH2F(TString::Format("PvMultiplicityVsV0aMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;V0A multiplicity;PV contributors", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourceV0A), DPTDPTMULTIPLICITYAXIS(MultSourcePvContributors)); + fhV0aMultiplicityVsCentrality[i] = new TH2F(TString::Format("V0aMultiplicityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);V0A multiplicity", beforeAfterName[i].c_str(), multestimator.c_str()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTMULTIPLICITYAXIS(MultSourceV0A)); + fhV0aMultiplicityVsT0cMultiplicity[i] = new TH2F(TString::Format("V0aMultiplicityVsT0cMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;T0C multiplicity;V0A multiplicity", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourceT0C), DPTDPTMULTIPLICITYAXIS(MultSourceV0A)); + fhV0aMultiplicityVsT0aMultiplicity[i] = new TH2F(TString::Format("V0aMultiplicityVsT0aMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;T0A multiplicity;V0A multiplicity", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourceT0A), DPTDPTMULTIPLICITYAXIS(MultSourceV0A)); + fhT0cMultiplicityVsCentrality[i] = new TH2F(TString::Format("T0cMultiplicityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);T0C multiplicity", beforeAfterName[i].c_str(), multestimator.c_str()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTMULTIPLICITYAXIS(MultSourceT0C)); + fhT0cMultiplicityVsT0aMultiplicity[i] = new TH2F(TString::Format("T0cMultiplicityVsT0aMultiplicity%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;T0A multiplicity;T0C multiplicity", beforeAfterName[i].c_str()).Data(), DPTDPTMULTIPLICITYAXIS(MultSourceT0A), DPTDPTMULTIPLICITYAXIS(MultSourceT0C)); + fhT0CentralityVsCentrality[i] = new TH2F(TString::Format("T0CentralityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);T0 centrality(%%)", beforeAfterName[i].c_str(), multestimator.c_str()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTCENTRALITYAXIS); + fhV0aCentralityVsCentrality[i] = new TH2F(TString::Format("V0aCentralityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);V0A centrality (%%)", beforeAfterName[i].c_str(), multestimator.c_str()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTCENTRALITYAXIS); + fhNtpvCentralityVsCentrality[i] = new TH2F(TString::Format("NtpvCentralityVsCentrality%s", beforeAfterSufix[i].c_str()).Data(), TString::Format("%s;%s centrality (%%);NTPV centrality (%%)", beforeAfterName[i].c_str(), multestimator.c_str()).Data(), DPTDPTCENTRALITYAXIS, DPTDPTCENTRALITYAXIS); + } + } + /* add the hstograms to the output list */ fOutputList->Add(fhEventSelection); + fOutputList->Add(fhTriggerSelection); + fOutputList->Add(fhTriggerSelectionCorrelations); fOutputList->Add(fhCentMultB); fOutputList->Add(fhCentMultA); fOutputList->Add(fhMultB); fOutputList->Add(fhMultA); fOutputList->Add(fhVertexZB); fOutputList->Add(fhVertexZA); + if (cfgEventSelection.fillQc) { + for (int i = 0; i < BeforeAfterNOOFTIMES; ++i) { + /* the quality control histograms */ + fOutputList->Add(fhMultiplicityVsCentrality[i]); + fOutputList->Add(fhMultiplicityVsT0cMultiplicity[i]); + fOutputList->Add(fhMultiplicityVsT0aMultiplicity[i]); + fOutputList->Add(fhMultiplicityVsV0aMultiplicity[i]); + fOutputList->Add(fhMultiplicityVsPvMultiplicity[i]); + fOutputList->Add(fhPvMultiplicityVsCentrality[i]); + fOutputList->Add(fhPvMultiplicityVsT0cMultiplicity[i]); + fOutputList->Add(fhPvMultiplicityVsT0aMultiplicity[i]); + fOutputList->Add(fhPvMultiplicityVsV0aMultiplicity[i]); + fOutputList->Add(fhV0aMultiplicityVsCentrality[i]); + fOutputList->Add(fhV0aMultiplicityVsT0cMultiplicity[i]); + fOutputList->Add(fhV0aMultiplicityVsT0aMultiplicity[i]); + fOutputList->Add(fhT0cMultiplicityVsCentrality[i]); + fOutputList->Add(fhT0cMultiplicityVsT0aMultiplicity[i]); + fOutputList->Add(fhT0CentralityVsCentrality[i]); + fOutputList->Add(fhV0aCentralityVsCentrality[i]); + fOutputList->Add(fhNtpvCentralityVsCentrality[i]); + } + } } if ((fDataType != kData) && (fDataType != kDataNoEvtSel)) { /* create the true data histograms */ - /* TODO: proper axes and axes titles according to the system; still incomplete */ - if (fSystem > kPbp) { - fhTrueCentMultB = new TH1F("TrueCentralityB", "Centrality before (truth); centrality (%)", 100, 0, 100); - fhTrueCentMultA = new TH1F("TrueCentralityA", "Centrality (truth); centrality (%)", 100, 0, 100); - } else { - /* for pp, pPb and Pbp systems use multiplicity instead */ - fhTrueCentMultB = new TH1F("TrueMultiplicityB", "Multiplicity before (truth); multiplicity (%)", 100, 0, 100); - fhTrueCentMultA = new TH1F("TrueMultiplicityA", "Multiplicity (truth); multiplicity (%)", 100, 0, 100); - } - + fhTrueCentMultB = new TH1F("TrueCentralityB", "Centrality before (truth); centrality (%)", 100, 0, 100); + fhTrueCentMultA = new TH1F("TrueCentralityA", "Centrality (truth); centrality (%)", 100, 0, 100); fhTrueVertexZB = new TH1F("TrueVertexZB", "Vertex Z before (truth); z_{vtx}", 60, -15, 15); fhTrueVertexZA = new TH1F("TrueVertexZA", "Vertex Z (truth); z_{vtx}", zvtxbins, zvtxlow, zvtxup); if (!doprocessOnTheFlyGeneratorLevel) { @@ -614,12 +709,56 @@ void DptDptFilter::processReconstructed(CollisionObject const& collision, Tracks collisionsinfo(uint8_t(false), 105.0); } } - /* report the event selection */ - for (int iflag = 0; iflag < knCollisionSelectionFlags; ++iflag) { + /* report the trigger and event selection */ + for (int iflag = 0; iflag < TriggSelNOOFTRIGGERS; ++iflag) { + if (triggerFlags.test(iflag)) { + fhTriggerSelection->Fill(iflag); + for (int jflag = 0; jflag < TriggSelNOOFTRIGGERS; ++jflag) { + if (triggerFlags.test(jflag)) { + fhTriggerSelectionCorrelations->Fill(iflag, jflag); + } + } + } + } + for (int iflag = 0; iflag < CollSelNOOFFLAGS; ++iflag) { if (collisionFlags.test(iflag)) { fhEventSelection->Fill(iflag); + } else { + if (iflag >= CollSelTRIGGSELBIT) { + /* don't report not accepted events */ + break; + } } } + /* report QC information if required */ + if (cfgEventSelection.fillQc) { + [&](bool accepted) { + for (int i = 0; i < BeforeAfterNOOFTIMES; ++i) { + fhMultiplicityVsCentrality[i]->Fill(centormult, ftracks.size()); + fhMultiplicityVsT0cMultiplicity[i]->Fill(collision.multFT0C(), ftracks.size()); + fhMultiplicityVsT0aMultiplicity[i]->Fill(collision.multFT0A(), ftracks.size()); + fhMultiplicityVsV0aMultiplicity[i]->Fill(collision.multFV0A(), ftracks.size()); + fhMultiplicityVsPvMultiplicity[i]->Fill(collision.multNTracksPV(), ftracks.size()); + fhPvMultiplicityVsCentrality[i]->Fill(centormult, collision.multNTracksPV()); + fhPvMultiplicityVsT0cMultiplicity[i]->Fill(collision.multFT0C(), collision.multNTracksPV()); + fhPvMultiplicityVsT0aMultiplicity[i]->Fill(collision.multFT0A(), collision.multNTracksPV()); + fhPvMultiplicityVsV0aMultiplicity[i]->Fill(collision.multFV0A(), collision.multNTracksPV()); + fhV0aMultiplicityVsCentrality[i]->Fill(centormult, collision.multFV0A()); + fhV0aMultiplicityVsT0cMultiplicity[i]->Fill(collision.multFT0C(), collision.multFV0A()); + fhV0aMultiplicityVsT0aMultiplicity[i]->Fill(collision.multFT0A(), collision.multFV0A()); + fhT0cMultiplicityVsCentrality[i]->Fill(centormult, collision.multFT0C()); + fhT0cMultiplicityVsT0aMultiplicity[i]->Fill(collision.multFT0A(), collision.multFT0C()); + if constexpr (framework::has_type_v) { + fhT0CentralityVsCentrality[i]->Fill(centormult, collision.centFT0M()); + fhV0aCentralityVsCentrality[i]->Fill(centormult, collision.centFV0A()); + fhNtpvCentralityVsCentrality[i]->Fill(centormult, collision.centNTPV()); + } + /* if not accepted only before is filled */ + if (!accepted) + break; + } + }(acceptedevent); + } } void DptDptFilter::processWithCent(aod::CollisionEvSelCent const& collision, DptDptFullTracks const& ftracks, aod::BCsWithTimestamps const&) @@ -863,10 +1002,10 @@ struct DptDptFilterTracks { tpcExclude = static_cast(tmpTpcExclude); } /* self configure the CCDB access to the input file */ - getTaskOptionValue(initContext, "dpt-dpt-filter", "cfgCCDBUrl", cfgCCDBUrl, false); - getTaskOptionValue(initContext, "dpt-dpt-filter", "cfgCCDBPathName", cfgCCDBPathName, false); - getTaskOptionValue(initContext, "dpt-dpt-filter", "cfgCCDBDate", cfgCCDBDate, false); - getTaskOptionValue(initContext, "dpt-dpt-filter", "cfgCCDBPeriod", cfgCCDBPeriod, false); + getTaskOptionValue(initContext, "dpt-dpt-filter", "cfgCCDB.url", cfgCCDBUrl, false); + getTaskOptionValue(initContext, "dpt-dpt-filter", "cfgCCDB.pathName", cfgCCDBPathName, false); + getTaskOptionValue(initContext, "dpt-dpt-filter", "cfgCCDB.date", cfgCCDBDate, false); + getTaskOptionValue(initContext, "dpt-dpt-filter", "cfgCCDB.period", cfgCCDBPeriod, false); /* create the output list which will own the task histograms */ TList* fOutputList = new TList(); @@ -1754,10 +1893,8 @@ void DptDptFilterTracks::fillParticleHistosAfterSelection(ParticleObject const& WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - WorkflowSpec workflow{adaptAnalysisTask(cfgc, - SetDefaultProcesses{ - {{"processWithoutCent", true}, - {"processWithoutCentMC", true}}}), + metadataInfo.initMetadata(cfgc); + WorkflowSpec workflow{adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc)}; return workflow; } diff --git a/PWGCF/TableProducer/dptDptFilter.h b/PWGCF/TableProducer/dptDptFilter.h index 18076266f1a..d99ae8951d8 100644 --- a/PWGCF/TableProducer/dptDptFilter.h +++ b/PWGCF/TableProducer/dptDptFilter.h @@ -16,33 +16,38 @@ #ifndef PWGCF_TABLEPRODUCER_DPTDPTFILTER_H_ #define PWGCF_TABLEPRODUCER_DPTDPTFILTER_H_ +#include "PWGCF/Core/AnalysisConfigurableCuts.h" + +#include "Common/CCDB/RCTSelectionFlags.h" +#include "Common/Core/MetadataHelper.h" +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "ReconstructionDataFormats/PID.h" #include -#include -#include + #include #include -#include +#include +#include + #include -#include -#include #include -#include -#include -#include #include +#include +#include #include - -#include "ReconstructionDataFormats/PID.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/Core/RecoDecay.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectionDefaults.h" -#include "PWGCF/Core/AnalysisConfigurableCuts.h" +#include +#include +#include +#include namespace o2 { @@ -63,17 +68,50 @@ namespace dptdptfilter /// \enum SystemType /// \brief The type of the system under analysis enum SystemType { - kNoSystem = 0, ///< no system defined - kpp, ///< **p-p** system - kpPb, ///< **p-Pb** system - kPbp, ///< **Pb-p** system - kPbPb, ///< **Pb-Pb** system - kXeXe, ///< **Xe-Xe** system - kppRun3, ///< **p-p Run 3** system - kPbPbRun3, ///< **Pb-Pb Run 3** system - knSystems ///< number of handled systems + SystemNoSystem = 0, ///< no system defined + SystemPp, ///< **p-p** system + SystemPPb, ///< **p-Pb** system + SystemPbp, ///< **Pb-p** system + SystemPbPb, ///< **Pb-Pb** system + SystemXeXe, ///< **Xe-Xe** system + SystemPpRun3, ///< **p-p Run 3** system + SystemPbPbRun3, ///< **Pb-Pb Run 3** system + SystemNeNeRun3, ///< **Ne-Ne Run 3** system + SystemOORun3, ///< **O-O Run 3** system + SystemPORun3, ///< **p-O Run 3** system + SystemNoOfSystems ///< number of handled systems }; +/// \std::map systemInternalCodesMap +/// \brief maps system names to internal system codes +static const std::map systemInternalCodesMap{ + {"", SystemNoSystem}, + {"pp", SystemPp}, + {"pPb", SystemPPb}, + {"Pbp", SystemPbp}, + {"PbPb", SystemPbPb}, + {"XeXe", SystemXeXe}, + {"ppRun3", SystemPpRun3}, + {"PbPbRun3", SystemPbPbRun3}, + {"NeNeRun3", SystemNeNeRun3}, + {"OORun3", SystemOORun3}, + {"pORun3", SystemPORun3}}; + +/// \std::map systemExternalNamesMap +/// \brief maps system internal codes to system external names +static const std::map systemExternalNamesMap{ + {SystemNoSystem, ""}, + {SystemPp, "pp"}, + {SystemPPb, "pPb"}, + {SystemPbp, "Pbp"}, + {SystemPbPb, "PbPb"}, + {SystemXeXe, "XeXe"}, + {SystemPpRun3, "ppRun3"}, + {SystemPbPbRun3, "PbPbRun3"}, + {SystemNeNeRun3, "NeNeRun3"}, + {SystemOORun3, "OORun3"}, + {SystemPORun3, "pORun3"}}; + /// \enum DataType /// \brief Which kind of data is the task addressing enum DataType { @@ -88,67 +126,232 @@ enum DataType { /// \enum CentMultEstimatorType /// \brief The detector used to estimate centrality/multiplicity enum CentMultEstimatorType { - kNOCM = 0, ///< do not use centrality/multiplicity estimator - kV0M, ///< V0M centrality/multiplicity estimator Run 1/2 - kCL0, ///< CL0 centrality/multiplicity estimator Run 1/2 - kCL1, ///< CL1 centrality/multiplicity estimator Run 1/2 - kFV0A, ///< FV0A centrality/multiplicity estimator Run 3 - kFT0M, ///< FT0M centrality/multiplicity estimator Run 3 - kFT0A, ///< FT0A centrality/multiplicity estimator Run 3 - kFT0C, ///< FT0C centrality/multiplicity estimator Run 3 - kNTPV, ///< NTPV centrality/multiplicity estimator Run 3 - knCentMultEstimators ///< number of centrality/mutiplicity estimator + CentMultNOCM = 0, ///< do not use centrality/multiplicity estimator + CentMultV0M, ///< V0M centrality/multiplicity estimator Run 1/2 + CentMultCL0, ///< CL0 centrality/multiplicity estimator Run 1/2 + CentMultCL1, ///< CL1 centrality/multiplicity estimator Run 1/2 + CentMultFV0A, ///< FV0A centrality/multiplicity estimator Run 3 + CentMultFT0M, ///< FT0M centrality/multiplicity estimator Run 3 + CentMultFT0A, ///< FT0A centrality/multiplicity estimator Run 3 + CentMultFT0C, ///< FT0C centrality/multiplicity estimator Run 3 + CentMultNTPV, ///< NTPV centrality/multiplicity estimator Run 3 + CentMultNOOFESTIMATORS ///< number of centrality/mutiplicity estimator +}; + +/// \std::map estimatorInternalCodesMap +/// \brief maps centrality/multiplicity estimator names to internal estimator codes +static const std::map estimatorInternalCodesMap{ + {"NOCM", CentMultNOCM}, + {"V0M", CentMultV0M}, + {"CL0", CentMultCL0}, + {"CL1", CentMultCL1}, + {"FV0A", CentMultFV0A}, + {"FT0M", CentMultFT0M}, + {"FT0A", CentMultFT0A}, + {"FT0C", CentMultFT0C}, + {"NTPV", CentMultNTPV}}; + +/// \std::map estimatorExternalNamesMap +/// \brief maps internal estimator codes to centrality/multiplicity estimator external names +static const std::map estimatorExternalNamesMap{ + {CentMultNOCM, "NOCM"}, + {CentMultV0M, "V0M"}, + {CentMultCL0, "CL0"}, + {CentMultCL1, "CL1"}, + {CentMultFV0A, "FV0A"}, + {CentMultFT0M, "FT0M"}, + {CentMultFT0A, "FT0A"}, + {CentMultFT0C, "FT0C"}, + {CentMultNTPV, "NTPV"}}; + +/// \enum MultSourceType +/// \brief The multiplicity source +enum MultSourceType { + MultSourceT0A = 0, ///< T0A multiplicity + MultSourceT0C, ///< T0C multiplicity + MultSourceT0M, ///< T0M multiplicity + MultSourceV0A, ///< V0A multiplicity + MultSourceV0C, ///< V0C multiplicity + MultSourceV0M, ///< V0M multiplicity + MultSourceNtracks, ///< number of tracks multiplicity + MultSourcePvContributors, ///< number of primary vertex contributors + MultSourceNOOFSOURCES ///< number multiplicity sources +}; + +/// \enum MultRunType +/// \brief The multiplicity LHC run +enum MultRunType { + MultRunRUN1RUN2 = 0, ///< LHC Run 1 or Run 2 + MultRunRUN3, ///< LHC Run 3 + MultRunNOOFRUNS ///< number of runs for multiplicity }; -/// \enum TriggerSelectionType -/// \brief The type of trigger to apply for event selection -enum TriggerSelectionType { - kNONE = 0, ///< do not use trigger selection - kMB, ///< Minimum bias trigger - kMBEXTRA, ///< Additional Run3 event quality - kVTXTOFMATCHED, ///< at least one vertex contributor is matched to TOF - kVTXTRDMATCHED, ///< at least one vertex contributor is matched to TRD - kVTXTRDTOFMATCHED, ///< at least one vertex contributor is matched to TRD and TOF - kEXTRAVTXTOFMATCHED, ///< Additional Run3 event quality and at least one vertex contributor is matched to TOF - kEXTRAVTXTRDMATCHED, ///< Additional Run3 event quality and at least one vertex contributor is matched to TRD - kEXTRAVTXTRDTOFMATCHED, ///< Additional Run3 event quality and at least one vertex contributor is matched to TRD and TOF - knEventSelection ///< number of triggers for event selection +/// \std::map multRunForSystemMap +/// \brief maps the system to the lhc Run for multiplicity +static const std::map multRunForSystemMap{ + {SystemNoSystem, MultRunRUN1RUN2}, + {SystemPp, MultRunRUN1RUN2}, + {SystemPPb, MultRunRUN1RUN2}, + {SystemPbp, MultRunRUN1RUN2}, + {SystemPbPb, MultRunRUN1RUN2}, + {SystemXeXe, MultRunRUN1RUN2}, + {SystemPpRun3, MultRunRUN3}, + {SystemPbPbRun3, MultRunRUN3}, + {SystemNeNeRun3, MultRunRUN3}, + {SystemOORun3, MultRunRUN3}, + {SystemPORun3, MultRunRUN3}}; + +/// \std::map estimatorMultiplicitySourceMap +/// \brief maps internal estimator codes internal multiplicity sources +static const std::map estimatorMultiplicitySourceMap{ + {CentMultNOCM, MultSourceT0C}, + {CentMultV0M, MultSourceV0M}, + {CentMultCL0, MultSourceT0C}, /* TODO: for Run1,2 */ + {CentMultCL1, MultSourceT0C}, /* TODO: for Run1,2 */ + {CentMultFV0A, MultSourceV0A}, + {CentMultFT0M, MultSourceT0M}, + {CentMultFT0A, MultSourceT0A}, + {CentMultFT0C, MultSourceT0C}, + {CentMultNTPV, MultSourcePvContributors}}; + +/// \std::vector multiplicitySourceExternalNamesMap +/// \brief maps internal multiplicity source to external names for the LHC runs +static const std::vector> multiplicitySourceExternalNamesMap{ + /* Run 1 and Run 2 */ + { + {MultSourceT0A, "T0A multiplicity"}, + {MultSourceT0C, "T0C multiplicity"}, + {MultSourceT0M, "T0M multiplicity"}, + {MultSourceV0A, "V0A multiplicity"}, + {MultSourceV0C, "V0C multiplicity"}, + {MultSourceV0M, "V0M multiplicity"}, + {MultSourceNtracks, "Number of tracks"}, + {MultSourcePvContributors, "PV contributors"}}, + /* Run 3 */ + { + {MultSourceT0A, "FT0A multiplicity"}, + {MultSourceT0C, "FT0C multiplicity"}, + {MultSourceT0M, "FT0M multiplicity"}, + {MultSourceV0A, "FV0A multiplicity"}, + {MultSourceV0C, "WRONG SOURCE"}, + {MultSourceV0M, "FV0M multiplicity"}, + {MultSourceNtracks, "Number of tracks"}, + {MultSourcePvContributors, "PV contributors"}}}; + +/// \std::map multiplicitySourceConfigNamesMap +/// \brief maps internal multiplicity source to external configuration names +/// At configuration time neither the system nor the lhc run is known +static const std::map multiplicitySourceConfigNamesMap{ + {MultSourceT0A, "FT0A"}, + {MultSourceT0C, "FT0C"}, + {MultSourceT0M, "FT0M"}, + {MultSourceV0A, "FV0A"}, + {MultSourceV0C, "V0C"}, + {MultSourceV0M, "FV0M"}, + {MultSourceNtracks, "Number of tracks"}, + {MultSourcePvContributors, "PV contributors"}}; + +/// \enum TriggerSelectionTags +/// \brief The potential trigger tags to apply for event selection +enum TriggerSelectionTags { + TriggSelNONE = 0, ///< do not use trigger selection + TriggSelMB, ///< Minimum bias trigger + TriggSelNOSAMEBUNCHPUP, ///< No same bunch pile up + TriggSelNUMPVCONTRIBUTORS, ///< Number of primary vertex contributors + TriggSelVTXTOFMATCHED, ///< at least one primary vertex contributor is matched to TOF + TriggSelVTXTRDMATCHED, ///< at least one primary vertex contributor is matched to TRD + TriggSelNOCOLLINTRSTD, ///< no other collision in standard time range gap + TriggSelNOCOLLINROFSTD, ///< no other collision in standard readout frame gap + TriggSelISVERTEXITSTPC, ///< primary vertex contributors are matched tracks ITS+TPC + TriggSelISGOODZVTXFT0VSPV, ///< vertex extracted from FT0 is compatible with the one from primary vertex contributors + TriggSelGOODITSLAYER3, ///< good the 3 ITS layer + TriggSelGOODITSLAYER0123, ///< check good the 0,1,2,and 3 ITS layers + TriggSelGOODITSLAYERALL, ///< check good all ITS layers + TriggSelNOGOODITSLAYER3, ///< check no good the 3 ITS layer + TriggSelNOGOODITSLAYER0123, ///< check no good the 0,1,2,and 3 ITS layers + TriggSelNOGOODITSLAYERALL, ///< check no good all ITS layers + TriggSelNOOFTRIGGERS ///< number of triggers for event selection }; +/// \std::map triggerSelectionBitsMap +/// \brief maps trigger selection tags to internal trigger selection bits +static const std::map triggerSelectionBitsMap{ + {"none", TriggSelNONE}, + {"mb", TriggSelMB}, + {"nosamebunchpup", TriggSelNOSAMEBUNCHPUP}, + {"numpvcontr", TriggSelNUMPVCONTRIBUTORS}, + {"vtxtofmatched", TriggSelVTXTOFMATCHED}, + {"vtxtrdmatched", TriggSelVTXTRDMATCHED}, + {"nocollintrstd", TriggSelNOCOLLINTRSTD}, + {"nocollinrofstd", TriggSelNOCOLLINROFSTD}, + {"isvtxitstpc", TriggSelISVERTEXITSTPC}, + {"isgoodvtxft0vspv", TriggSelISGOODZVTXFT0VSPV}, + {"gooditslayer3", TriggSelGOODITSLAYER3}, + {"gooditslayer0123", TriggSelGOODITSLAYER0123}, + {"gooditslayerall", TriggSelGOODITSLAYERALL}, + {"nogooditslayer3", TriggSelNOGOODITSLAYER3}, + {"nogooditslayer0123", TriggSelNOGOODITSLAYER0123}, + {"nogooditslayerall", TriggSelNOGOODITSLAYERALL}}; + +/// \std::map triggerSelectionExternalNamesMap +/// \brief maps trigger selection bits to external names +static const std::map triggerSelectionExternalNamesMap{ + {TriggSelNONE, "none"}, + {TriggSelMB, "Sel8"}, ///< Sel8 includes kIsTriggerTVX, kNoTimeFrameBorder, and kNoITSROFrameBorder + {TriggSelNOSAMEBUNCHPUP, "No same bunch pileup"}, + {TriggSelNUMPVCONTRIBUTORS, "Number PV contributors"}, + {TriggSelVTXTOFMATCHED, "PV contributor TOF matched"}, + {TriggSelVTXTRDMATCHED, "PV contributor TRD matched"}, + {TriggSelNOCOLLINTRSTD, "No coll in TR standard"}, + {TriggSelNOCOLLINROFSTD, "No coll in ROF standard"}, + {TriggSelISVERTEXITSTPC, "Vertex from ITS and TPC"}, + {TriggSelISGOODZVTXFT0VSPV, "Good vtx FT0 vs PV"}, + {TriggSelGOODITSLAYER3, "Good ITS layer 3"}, + {TriggSelGOODITSLAYER0123, "Good ITS layers 0,1,2,3"}, + {TriggSelGOODITSLAYERALL, "Good ITS layer all"}, + {TriggSelNOGOODITSLAYER3, "No good ITS layer 3"}, + {TriggSelNOGOODITSLAYER0123, "No good ITS layer 0,1,2,3"}, + {TriggSelNOGOODITSLAYERALL, "No good ITS layer all"}}; + /// \enum OccupancyEstimationType /// \brief The type of occupancy estimation enum OccupancyEstimationType { - kNOOCC = 0, ///< do not use occupancy estimation - kTRACKSOCC, ///< occupancy estimated using tracks - kFT0COCC, ///< occupancy estimated using the FT0C - knOccupancyEstimators ///< the number of occupancy estimators + OccupancyNOOCC = 0, ///< do not use occupancy estimation + OccupancyTRACKSOCC, ///< occupancy estimated using tracks + OccupancyFT0COCC, ///< occupancy estimated using the FT0C + OccupancyNOOFESTIMATORS ///< the number of occupancy estimators }; /// \enum CollisionSelectionFlags /// \brief The different criteria for selecting/rejecting collisions enum CollisionSelectionFlags { - kIN = 0, ///< new unhandled, yet, event - kMBBIT, ///< minimum bias - kINT7BIT, ///< INT7 Run 1/2 - kSEL7BIT, ///< Sel7 Run 1/2 - kSEL8BIT, ///< Sel8 - kNOSAMEBUNCHPUPBIT, ///< no same bunch pile up - kISGOODZVTXFT0VSPVBIT, ///< good zvtx FT0 vs PV - kISVERTEXITSTPCBIT, ///< is vertex TPC and ITS - kISVERTEXTOFMATCHEDBIT, ///< vertex contributor with TOF matched - kISVERTEXTRDMATCHEDBIT, ///< vertex contributor with TRD matche - kNOCOLLINTIMERANGEBIT, ///< no collision in time range - kNOCOLLINROFBIT, ///< no collision in readout - kOCCUPANCYBIT, ///< occupancy within limits - kISGOODITSLAYER3BIT, ///< right level of inactive chips for ITS layer 3 - kISGOODITSLAYER0123BIT, ///< right level of inactive chips for ITS layers 0,1,2, and 3 - kISGOODITSLAYERALLBIT, ///< right level of inactive chips for all seven ITS layers - kCENTRALITYBIT, ///< centrality cut passed - kZVERTEXBIT, ///< zvtx cut passed - kSELECTED, ///< the event has passed all selections - knCollisionSelectionFlags ///< number of flags + CollSelIN = 0, ///< new unhandled, yet, event + CollSelMBBIT, ///< minimum bias + CollSelINT7BIT, ///< INT7 Run 1/2 + CollSelSEL7BIT, ///< Sel7 Run 1/2 + CollSelTRIGGSELBIT, ///< Accepted by trigger selection + CollSelRCTBIT, ///< Accetped by the RCT information + CollSelOCCUPANCYBIT, ///< occupancy within limits + CollSelCENTRALITYBIT, ///< centrality cut passed + CollSelZVERTEXBIT, ///< zvtx cut passed + CollSelSELECTED, ///< the event has passed all selections + CollSelNOOFFLAGS ///< number of flags }; +/// \std::mag collisionSelectionExternalNamesMap +/// \brief maps collision selection bits to external names +static const std::map collisionSelectionExternalNamesMap{ + {CollSelIN, "In"}, + {CollSelMBBIT, "MB"}, + {CollSelINT7BIT, "INT7"}, + {CollSelSEL7BIT, "Sel7"}, + {CollSelTRIGGSELBIT, "Trigger selection"}, + {CollSelRCTBIT, "RCT accepted"}, + {CollSelOCCUPANCYBIT, "Occupancy"}, + {CollSelCENTRALITYBIT, "Centrality"}, + {CollSelZVERTEXBIT, "z vertex"}, + {CollSelSELECTED, "Selected"}}; + /// \enum StrongDebugging /// \brief Enable a per track information debugging. Only for local analyses enum StrongDebugging { @@ -164,18 +367,6 @@ enum TpcExclusionMethod { kDYNAMIC ///< pT dependent exclusion matching the sector borders a la Alex Dobrin }; -/// \enum ItsDeadMapsCheckType -/// \brief Check for the right level of ITS dead chips -enum ItsDeadMapsCheckType { - kNOCHECK = 0, ///< no check - kGOODITSLAYER3, ///< check good the 3 ITS layer - kGOODITSLAYER0123, ///< check good the 0,1,2,and 3 ITS layers - kGOODITSLAYERALL, ///< check good all ITS layers - kNOGOODITSLAYER3, ///< check no good the 3 ITS layer - kNOGOODITSLAYER0123, ///< check no good the 0,1,2,and 3 ITS layers - kNOGOODITSLAYERALL ///< check no good all ITS layers -}; - //============================================================================================ // The debug output stream //============================================================================================ @@ -187,9 +378,23 @@ std::ofstream debugstream; float overallminp = 0.0f; //============================================================================================ -// The collision selection flags and configuration objects +// The collision selection and trigger selection flags and configuration objects //============================================================================================ std::bitset<32> collisionFlags; +std::bitset<32> collisionSelectionFlags; +std::bitset<32> triggerFlags; +std::bitset<32> triggerSelectionFlags; + +//============================================================================================ +// The input data metadata access helper +//============================================================================================ +o2::common::core::MetadataHelper metadataInfo; + +//============================================================================================ +// The RCT information access +//============================================================================================ +bool useRctInformation = false; +o2::aod::rctsel::RCTFlagsChecker rctChecker; //============================================================================================ // The DptDptFilter configuration objects @@ -514,12 +719,11 @@ inline TList* getCCDBInput(auto& ccdb, const char* ccdbpath, const char* ccdbdat return lst; } -SystemType fSystem = kNoSystem; +SystemType fSystem = SystemNoSystem; +MultRunType fLhcRun = MultRunRUN1RUN2; DataType fDataType = kData; -CentMultEstimatorType fCentMultEstimator = kV0M; -TriggerSelectionType fTriggerSelection = kMB; -OccupancyEstimationType fOccupancyEstimation = kNOOCC; /* the occupancy estimator to use */ -ItsDeadMapsCheckType fItsDeadMapCheck = kNOCHECK; /* the check of the ITS dead maps to use */ +CentMultEstimatorType fCentMultEstimator = CentMultV0M; +OccupancyEstimationType fOccupancyEstimation = OccupancyNOOCC; /* the occupancy estimator to use */ float fMinOccupancy = 0.0f; /* the minimum allowed occupancy */ float fMaxOccupancy = 1e6f; /* the maximum allowed occupancy */ @@ -532,55 +736,71 @@ float particleMaxDCAxy = 999.9f; float particleMaxDCAZ = 999.9f; bool traceCollId0 = false; -inline TriggerSelectionType getTriggerSelection(std::string const& triggstr) +inline std::bitset<32> getTriggerSelection(std::string const& triggstr) { - if (triggstr.empty() || triggstr == "MB") { - return kMB; - } else if (triggstr == "MBEXTRA") { - return kMBEXTRA; - } else if (triggstr == "VTXTOFMATCHED") { - return kVTXTOFMATCHED; - } else if (triggstr == "VTXTRDMATCHED") { - return kVTXTRDMATCHED; - } else if (triggstr == "VTXTRDTOFMATCHED") { - return kVTXTRDTOFMATCHED; - } else if (triggstr == "EXTRAVTXTOFMATCHED") { - return kEXTRAVTXTOFMATCHED; - } else if (triggstr == "EXTRAVTXTRDMATCHED") { - return kEXTRAVTXTRDMATCHED; - } else if (triggstr == "EXTRAVTXTRDTOFMATCHED") { - return kEXTRAVTXTRDTOFMATCHED; - } else if (triggstr == "None") { - return kNONE; + std::bitset<32> flags; + + auto split = [](const auto s) { + std::vector tokens; + std::string token; + + size_t posStart = 0; + size_t posEnd; + while ((posEnd = s.find("+", posStart)) != std::string::npos) { + token = s.substr(posStart, posEnd - posStart); + posStart = posEnd + 1; + tokens.push_back(token); + } + tokens.push_back(s.substr(posStart)); + return tokens; + }; + + std::vector tags = split(triggstr); + + for (const auto& tag : tags) { + if (triggerSelectionBitsMap.contains(tag)) { + flags.set(triggerSelectionBitsMap.at(tag), true); + } else { + LOGF(fatal, "Wrong trigger selection tag: %s", tag.c_str()); + } + } + return flags; +} + +inline SystemType getSytemTypeFromMetaData() +{ + auto period = metadataInfo.get("LPMProductionTag"); + + if (period == "LHC25ad" || period == "LHC25g5") { + LOGF(info, "Configuring for p-O LHC25ad period"); + return SystemPORun3; + } else if (period == "LHC25ae" || period == "LHC25g6") { + LOGF(info, "Configuring for O-O LHC25ae period"); + return SystemOORun3; + } else if (period == "LHC25af" || period == "LHC25g7") { + LOGF(info, "Configuring for Ne-Ne LHC25af period"); + return SystemNeNeRun3; } else { - LOGF(fatal, "Wrong trigger selection: %s", triggstr.c_str()); - return kNONE; + LOGF(fatal, "DptDptCorrelations::getSystemTypeFromMetadata(). No automatic system type configuration for %s period", period.c_str()); } + return SystemPbPb; } inline SystemType getSystemType(std::string const& sysstr) { /* we have to figure out how extract the system type */ - if (sysstr.empty() || (sysstr == "PbPb")) { - return kPbPb; - } else if (sysstr == "pp") { - return kpp; - } else if (sysstr == "pPb") { - return kpPb; - } else if (sysstr == "Pbp") { - return kPbp; - } else if (sysstr == "pPb") { - return kpPb; - } else if (sysstr == "XeXe") { - return kXeXe; - } else if (sysstr == "ppRun3") { - return kppRun3; - } else if (sysstr == "PbPbRun3") { - return kPbPbRun3; + if (sysstr == "Auto") { + /* special treatment for self configuration */ + /* TODO: expand it to all systems */ + return getSytemTypeFromMetaData(); } else { - LOGF(fatal, "DptDptCorrelations::getSystemType(). Wrong system type: %s", sysstr.c_str()); + if (systemInternalCodesMap.contains(sysstr)) { + return static_cast(systemInternalCodesMap.at(sysstr)); + } else { + LOGF(fatal, "DptDptCorrelations::getSystemType(). Wrong system type: %s", sysstr.c_str()); + } } - return kPbPb; + return SystemPbPb; } /// \brief Type of data according to the configuration string @@ -607,100 +827,35 @@ inline DataType getDataType(std::string const& datastr) inline CentMultEstimatorType getCentMultEstimator(std::string const& datastr) { - if (datastr == "V0M") { - return kV0M; - } else if (datastr == "CL0") { - return kCL0; - } else if (datastr == "CL1") { - return kCL1; - } else if (datastr == "FV0A") { - return kFV0A; - } else if (datastr == "FT0M") { - return kFT0M; - } else if (datastr == "FT0A") { - return kFT0A; - } else if (datastr == "FT0C") { - return kFT0C; - } else if (datastr == "NTPV") { - return kNTPV; - } else if (datastr == "NOCM") { - return kNOCM; + if (estimatorInternalCodesMap.contains(datastr)) { + return static_cast(estimatorInternalCodesMap.at(datastr)); } else { LOGF(fatal, "Centrality/Multiplicity estimator %s not supported yet", datastr.c_str()); } - return kNOCM; + return CentMultNOCM; } inline std::string getCentMultEstimatorName(CentMultEstimatorType est) { - switch (est) { - case kV0M: - return "V0M"; - break; - case kCL0: - return "CL0"; - break; - case kCL1: - return "CL1"; - break; - case kFV0A: - return "FV0A"; - break; - case kFT0M: - return "FT0M"; - break; - case kFT0A: - return "FT0A"; - break; - case kFT0C: - return "FT0C"; - break; - case kNTPV: - return "NTPV"; - break; - case kNOCM: - return "NOCM"; - break; - default: - LOGF(fatal, "Centrality/Multiplicity estimator %d not supported yet", (int)est); - return "WRONG"; - break; + if (estimatorExternalNamesMap.contains(est)) { + return estimatorExternalNamesMap.at(est); + } else { + LOGF(fatal, "Centrality/Multiplicity estimator %d not supported yet", static_cast(est)); } + return "WRONG"; } inline OccupancyEstimationType getOccupancyEstimator(const std::string& estimator) { if (estimator == "None") { - return kNOOCC; + return OccupancyNOOCC; } else if (estimator == "Tracks") { - return kTRACKSOCC; + return OccupancyTRACKSOCC; } else if (estimator == "FT0C") { - return kFT0COCC; + return OccupancyFT0COCC; } else { LOGF(fatal, "Occupancy estimator %s not supported yet", estimator.c_str()); - return kNOOCC; - } -} - -inline ItsDeadMapsCheckType getItsDeadMapCheck(const std::string& check) -{ - if (check.length() == 0 || check == "None") { - return kNOCHECK; - } else if (check == "goodIts3") { - return kGOODITSLAYER3; - } else if (check == "goodIts0123") { - return kGOODITSLAYER0123; - } else if (check == "goodItsAll") { - return kGOODITSLAYERALL; - } else if (check == "noGoodIts3") { - return kNOGOODITSLAYER3; - } else if (check == "noGoodIts0123") { - return kNOGOODITSLAYER0123; - } else if (check == "noGoodItsAll") { - return kNOGOODITSLAYERALL; - } else { - LOGF(fatal, "ITS dead map check %s not implemented", check.c_str()); - return kNOCHECK; + return OccupancyNOOCC; } } @@ -714,120 +869,72 @@ inline bool triggerSelectionReco(CollisionObject const& collision) { bool trigsel = false; switch (fSystem) { - case kpp: - case kpPb: - case kPbp: - case kPbPb: - case kXeXe: - switch (fTriggerSelection) { - case kMB: - switch (fDataType) { - case kData: - if (collision.alias_bit(kINT7)) { - collisionFlags.set(kINT7BIT); - if (collision.sel7()) { - trigsel = true; - collisionFlags.set(kSEL7BIT); - } - } - break; - case kMC: + case SystemPp: + case SystemPPb: + case SystemPbp: + case SystemPbPb: + case SystemXeXe: + if (triggerSelectionFlags.test(TriggSelMB)) { + switch (fDataType) { + case kData: + if (collision.alias_bit(kINT7)) { + collisionFlags.set(CollSelINT7BIT); if (collision.sel7()) { trigsel = true; - collisionFlags.set(kSEL7BIT); + collisionFlags.set(CollSelSEL7BIT); } - break; - default: - collisionFlags.set(kMBBIT); + } + break; + case kMC: + if (collision.sel7()) { trigsel = true; - break; - } - break; - case kNONE: - trigsel = true; - break; - default: - break; + collisionFlags.set(CollSelSEL7BIT); + } + break; + default: + collisionFlags.set(CollSelMBBIT); + trigsel = true; + break; + } + } else if (triggerSelectionFlags.test(TriggSelNONE)) { + trigsel = true; } break; - case kppRun3: - case kPbPbRun3: { - auto run3Accepted = [](auto const& coll) { - return coll.sel8() && - coll.selection_bit(aod::evsel::kNoCollInTimeRangeStandard) && - coll.selection_bit(aod::evsel::kNoCollInRofStandard); - }; - auto run3ExtraAccepted = [](auto const& coll) { - return coll.sel8() && - coll.selection_bit(aod::evsel::kNoSameBunchPileup) && - coll.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) && - coll.selection_bit(aod::evsel::kIsVertexITSTPC); + case SystemPpRun3: + case SystemPbPbRun3: + case SystemNeNeRun3: + case SystemPORun3: + case SystemOORun3: { + auto setTriggerFlags = [](auto& flags, auto const& coll) { + flags.set(TriggSelMB, coll.sel8() != 0); + flags.set(TriggSelNOSAMEBUNCHPUP, coll.selection_bit(aod::evsel::kNoSameBunchPileup)); + flags.set(TriggSelNUMPVCONTRIBUTORS, coll.numContrib() > 1); /* TODO: make it configurable */ + flags.set(TriggSelVTXTOFMATCHED, coll.selection_bit(aod::evsel::kIsVertexTOFmatched)); + flags.set(TriggSelVTXTRDMATCHED, coll.selection_bit(aod::evsel::kIsVertexTRDmatched)); + flags.set(TriggSelNOCOLLINTRSTD, coll.selection_bit(aod::evsel::kNoCollInTimeRangeStandard)); + flags.set(TriggSelNOCOLLINROFSTD, coll.selection_bit(aod::evsel::kNoCollInRofStandard)); + flags.set(TriggSelISVERTEXITSTPC, coll.selection_bit(aod::evsel::kIsVertexITSTPC)); + flags.set(TriggSelISGOODZVTXFT0VSPV, coll.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)); + flags.set(TriggSelGOODITSLAYER3, coll.selection_bit(aod::evsel::kIsGoodITSLayer3)); + flags.set(TriggSelGOODITSLAYER0123, coll.selection_bit(aod::evsel::kIsGoodITSLayer0123)); + flags.set(TriggSelGOODITSLAYERALL, coll.selection_bit(aod::evsel::kIsGoodITSLayersAll)); + flags.set(TriggSelNOGOODITSLAYER3, !coll.selection_bit(aod::evsel::kIsGoodITSLayer3)); + flags.set(TriggSelNOGOODITSLAYER0123, !coll.selection_bit(aod::evsel::kIsGoodITSLayer0123)); + flags.set(TriggSelNOGOODITSLAYERALL, !coll.selection_bit(aod::evsel::kIsGoodITSLayersAll)); }; - auto setCollisionFlags = [](auto& flags, auto const& coll) { - flags.set(kSEL8BIT, coll.sel8() != 0); - flags.set(kNOSAMEBUNCHPUPBIT, coll.selection_bit(aod::evsel::kNoSameBunchPileup)); - flags.set(kISGOODZVTXFT0VSPVBIT, coll.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)); - flags.set(kISVERTEXITSTPCBIT, coll.selection_bit(aod::evsel::kIsVertexITSTPC)); - flags.set(kISVERTEXTOFMATCHEDBIT, coll.selection_bit(aod::evsel::kIsVertexTOFmatched)); - flags.set(kISVERTEXTRDMATCHEDBIT, coll.selection_bit(aod::evsel::kIsVertexTRDmatched)); - flags.set(kNOCOLLINTIMERANGEBIT, coll.selection_bit(aod::evsel::kNoCollInTimeRangeStandard)); - flags.set(kNOCOLLINROFBIT, coll.selection_bit(aod::evsel::kNoCollInRofStandard)); - flags.set(kISGOODITSLAYER3BIT, coll.selection_bit(aod::evsel::kIsGoodITSLayer3)); - flags.set(kISGOODITSLAYER0123BIT, coll.selection_bit(aod::evsel::kIsGoodITSLayer0123)); - flags.set(kISGOODITSLAYERALLBIT, coll.selection_bit(aod::evsel::kIsGoodITSLayersAll)); - }; - switch (fTriggerSelection) { - case kMB: - if (run3Accepted(collision)) { - trigsel = true; - } - break; - case kMBEXTRA: - if (run3ExtraAccepted(collision)) { - trigsel = true; - } - break; - case kVTXTOFMATCHED: - if (run3Accepted(collision) && collision.selection_bit(aod::evsel::kIsVertexTOFmatched)) { - trigsel = true; - } - break; - case kVTXTRDMATCHED: - if (run3Accepted(collision) && collision.selection_bit(aod::evsel::kIsVertexTRDmatched)) { - trigsel = true; - } - break; - case kVTXTRDTOFMATCHED: - if (run3Accepted(collision) && collision.selection_bit(aod::evsel::kIsVertexTRDmatched) && collision.selection_bit(aod::evsel::kIsVertexTOFmatched)) { - trigsel = true; - } - break; - case kEXTRAVTXTOFMATCHED: - if (run3ExtraAccepted(collision) && collision.selection_bit(aod::evsel::kIsVertexTOFmatched)) { - trigsel = true; - } - break; - case kEXTRAVTXTRDMATCHED: - if (run3ExtraAccepted(collision) && collision.selection_bit(aod::evsel::kIsVertexTRDmatched)) { - trigsel = true; - } - break; - case kEXTRAVTXTRDTOFMATCHED: - if (run3ExtraAccepted(collision) && collision.selection_bit(aod::evsel::kIsVertexTRDmatched) && collision.selection_bit(aod::evsel::kIsVertexTOFmatched)) { - trigsel = true; - } - break; - case kNONE: - trigsel = true; - break; - default: - break; + setTriggerFlags(triggerFlags, collision); + + /* special treatment for no trigger selection */ + if (triggerSelectionFlags.test(TriggSelNONE)) { + trigsel = true; + } else { + trigsel = ((triggerSelectionFlags & triggerFlags) == triggerSelectionFlags); } - setCollisionFlags(collisionFlags, collision); } break; default: break; } + collisionFlags.set(CollSelTRIGGSELBIT, trigsel); return trigsel; } @@ -899,31 +1006,31 @@ template inline float extractMultiplicity(CollisionObject const& collision, CentMultEstimatorType est) { switch (est) { - case kV0M: + case CentMultV0M: return collision.multFV0M(); break; - case kCL0: + case CentMultCL0: return collision.multTracklets(); break; - case kCL1: + case CentMultCL1: return collision.multTracklets(); break; - case kFV0A: + case CentMultFV0A: return collision.multFV0A(); break; - case kFT0M: + case CentMultFT0M: return collision.multFT0M(); break; - case kFT0A: + case CentMultFT0A: return collision.multFT0A(); break; - case kFT0C: + case CentMultFT0C: return collision.multFT0M(); break; - case kNTPV: + case CentMultNTPV: return collision.multNTracksPV(); break; - case kNOCM: + case CentMultNOCM: return collision.multFT0M(); break; default: @@ -943,11 +1050,11 @@ template float getCentMultPercentile(CollisionObject collision) { switch (fCentMultEstimator) { - case kV0M: + case CentMultV0M: return collision.centRun2V0M(); - case kCL0: + case CentMultCL0: return collision.centRun2CL0(); - case kCL1: + case CentMultCL1: return collision.centRun2CL1(); default: return 105.0; @@ -959,15 +1066,15 @@ template float getCentMultPercentile(CollisionObject collision) { switch (fCentMultEstimator) { - case kFV0A: + case CentMultFV0A: return collision.centFV0A(); - case kFT0M: + case CentMultFT0M: return collision.centFT0M(); - case kFT0A: + case CentMultFT0A: return collision.centFT0A(); - case kFT0C: + case CentMultFT0C: return collision.centFT0C(); - case kNTPV: + case CentMultNTPV: return collision.centNTPV(); default: return 105.0; @@ -981,7 +1088,7 @@ inline bool centralitySelectionMult(CollisionObject collision, float& centmult) float mult = getCentMultPercentile(collision); if (mult < kValidPercentileUpLimit && kValidPercentileLowLimit < mult) { centmult = mult; - collisionFlags.set(kCENTRALITYBIT); + collisionFlags.set(CollSelCENTRALITYBIT); return true; } return false; @@ -993,10 +1100,10 @@ inline bool centralitySelectionNoMult(CollisionObject const&, float& centmult) { bool centmultsel = false; switch (fCentMultEstimator) { - case kNOCM: + case CentMultNOCM: centmult = 50.0; centmultsel = true; - collisionFlags.set(kCENTRALITYBIT); + collisionFlags.set(CollSelCENTRALITYBIT); break; default: break; @@ -1075,19 +1182,19 @@ template inline bool selectOnOccupancy(CollisionObject collision) { switch (fOccupancyEstimation) { - case kNOOCC: - collisionFlags.set(kOCCUPANCYBIT); + case OccupancyNOOCC: + collisionFlags.set(CollSelOCCUPANCYBIT); return true; - case kTRACKSOCC: + case OccupancyTRACKSOCC: if ((fMinOccupancy <= collision.trackOccupancyInTimeRange()) && (collision.trackOccupancyInTimeRange() < fMaxOccupancy)) { - collisionFlags.set(kOCCUPANCYBIT); + collisionFlags.set(CollSelOCCUPANCYBIT); return true; } else { return false; } - case kFT0COCC: + case OccupancyFT0COCC: if ((fMinOccupancy <= collision.ft0cOccupancyInTimeRange()) && (collision.ft0cOccupancyInTimeRange() < fMaxOccupancy)) { - collisionFlags.set(kOCCUPANCYBIT); + collisionFlags.set(CollSelOCCUPANCYBIT); return true; } else { return false; @@ -1154,95 +1261,6 @@ inline bool occupancySelection(aod::McCollision const&) return true; } -////////////////////////////////////////////////////////////////////////////////// -/// ITS dead maps selection -////////////////////////////////////////////////////////////////////////////////// - -/// \brief select on the ITS dead maps -/// \return true if the collision passes the ITS dead maps check false otherwise -template -inline bool selectOnItsDeadMaps(CollisionObject coll) -{ - auto checkFlag = [](auto flag, bool invert = false) { - return invert ? !flag : flag; - }; - switch (fItsDeadMapCheck) { - case kNOCHECK: - return true; - case kGOODITSLAYER3: - return checkFlag(coll.selection_bit(aod::evsel::kIsGoodITSLayer3)); - case kGOODITSLAYER0123: - return checkFlag(coll.selection_bit(aod::evsel::kIsGoodITSLayer0123)); - case kGOODITSLAYERALL: - return checkFlag(coll.selection_bit(aod::evsel::kIsGoodITSLayersAll)); - case kNOGOODITSLAYER3: - return checkFlag(coll.selection_bit(aod::evsel::kIsGoodITSLayer3), true); - case kNOGOODITSLAYER0123: - return checkFlag(coll.selection_bit(aod::evsel::kIsGoodITSLayer0123), true); - case kNOGOODITSLAYERALL: - return checkFlag(coll.selection_bit(aod::evsel::kIsGoodITSLayersAll), true); - default: - return false; - } -} - -/// \brief Occupancy selection by default: unknown subscribed collision table -template -inline bool itsDeadMapsSelection(CollisionObject const&) -{ - LOGF(fatal, "Occupancy selection not implemented for this kind of collisions"); - return false; -} - -/// \brief Occupancy selection for reconstructed and detector level collision tables with centrality/multiplicity information -template <> -inline bool itsDeadMapsSelection(aod::CollisionEvSelCent const& collision) -{ - return selectOnItsDeadMaps(collision); -} - -/// \brief Occupancy selection for reconstructed and detector level collision tables with Run 2 centrality/multiplicity information -template <> -inline bool itsDeadMapsSelection(aod::CollisionEvSelRun2Cent const&) -{ - return true; -} - -/// \brief Occupancy selection for reconstructed and detector level collision tables without centrality/multiplicity information -template <> -inline bool itsDeadMapsSelection(aod::CollisionEvSel const& collision) -{ - return selectOnItsDeadMaps(collision); -} - -/// \brief Occupancy selection for detector level collision tables without centrality/multiplicity -template <> -inline bool itsDeadMapsSelection::iterator>(soa::Join::iterator const& collision) -{ - return selectOnItsDeadMaps(collision); -} - -/// \brief Occupancy selection for detector level collision tables with centrality/multiplicity -template <> -inline bool itsDeadMapsSelection::iterator>(soa::Join::iterator const& collision) -{ - return selectOnItsDeadMaps(collision); -} - -/// \brief Occupancy selection for detector level collision tables with Run 2 centrality/multiplicity -template <> -inline bool itsDeadMapsSelection::iterator>(soa::Join::iterator const&) -{ - return true; -} - -/// \brief Occupancy selection for generator level collision table -template <> -inline bool itsDeadMapsSelection(aod::McCollision const&) -{ - return true; -} - ////////////////////////////////////////////////////////////////////////////////// /// Event selection ////////////////////////////////////////////////////////////////////////////////// @@ -1250,14 +1268,28 @@ inline bool itsDeadMapsSelection(aod::McCollision const&) template inline bool isEventSelected(CollisionObject const& collision, float& centormult) { + triggerFlags.reset(); collisionFlags.reset(); - collisionFlags.set(kIN); + collisionFlags.set(CollSelIN); bool trigsel = triggerSelection(collision); - bool occupancysel = occupancySelection(collision); + bool rctsel = false; + if (useRctInformation) { + if constexpr (framework::has_type_v) { + if (rctChecker.checkTable(collision)) { + rctsel = true; + collisionFlags.set(CollSelRCTBIT); + } + } else { + LOGF(fatal, "RCT check required but the dataset does not have RCT information associated. Please, fix it"); + } + } else { + collisionFlags.set(CollSelRCTBIT); + rctsel = true; + } - bool itsdeadmapssel = itsDeadMapsSelection(collision); + bool occupancysel = occupancySelection(collision); bool zvtxsel = false; /* TODO: vertex quality checks */ @@ -1266,20 +1298,20 @@ inline bool isEventSelected(CollisionObject const& collision, float& centormult) if (collision.posZ() != 0.0) { /* if only one side, we accept collisions which have zvtx different than zero */ zvtxsel = true; - collisionFlags.set(kZVERTEXBIT); + collisionFlags.set(CollSelZVERTEXBIT); } } else { zvtxsel = true; - collisionFlags.set(kZVERTEXBIT); + collisionFlags.set(CollSelZVERTEXBIT); } } bool centmultsel = centralitySelection(collision, centormult); - bool accepted = trigsel && occupancysel && itsdeadmapssel && zvtxsel && centmultsel; + bool accepted = trigsel && rctsel && occupancysel && zvtxsel && centmultsel; if (accepted) { - collisionFlags.set(kSELECTED); + collisionFlags.set(CollSelSELECTED); } return accepted; diff --git a/PWGCF/TableProducer/filter2Prong.cxx b/PWGCF/TableProducer/filter2Prong.cxx index 80f9bb8e038..00f7bb58827 100644 --- a/PWGCF/TableProducer/filter2Prong.cxx +++ b/PWGCF/TableProducer/filter2Prong.cxx @@ -115,9 +115,12 @@ struct Filter2Prong { using HFCandidates = soa::Join; using HFCandidatesML = soa::Join; + using HFCandidatesMCRecoML = soa::Join; template using HasMLProb = decltype(std::declval().mlProbD0()); + template + using HasFlagMcMatchRec = decltype(std::declval().flagMcMatchRec()); using PIDTrack = soa::Join; using ResoV0s = aod::V0Datas; @@ -170,6 +173,10 @@ struct Filter2Prong { continue; if (cfgYMax >= 0.0f && std::abs(hfHelper.yD0(c)) > cfgYMax) continue; + if constexpr (std::experimental::is_detected::value) { + if (std::abs(c.flagMcMatchRec()) != o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) + continue; + } if (c.isSelD0() > 0) { output2ProngTracks(cfcollisions.begin().globalIndex(), @@ -213,6 +220,12 @@ struct Filter2Prong { } PROCESS_SWITCH(Filter2Prong, processData, "Process data D0 candidates", true); + void processMCRecoML(aod::Collisions::iterator const& col, aod::BCsWithTimestamps const& bcs, aod::CFCollRefs const& cfcollisions, aod::CFTrackRefs const& cftracks, HFCandidatesMCRecoML const& candidates) + { + processDataT(col, bcs, cfcollisions, cftracks, candidates); + } + PROCESS_SWITCH(Filter2Prong, processMCRecoML, "Process data D0 candidates together with reco information and ML", false); + using HFMCTrack = soa::Join; void processMC(aod::McCollisions::iterator const&, aod::CFMcParticleRefs const& cfmcparticles, [[maybe_unused]] HFMCTrack const& mcparticles) { @@ -233,11 +246,34 @@ struct Filter2Prong { } } output2ProngMcParts(prongCFId[0], prongCFId[1], - (mcParticle.pdgCode() >= 0 ? aod::cf2prongtrack::D0ToPiK : aod::cf2prongtrack::D0barToKPi) | ((mcParticle.originMcGen() & RecoDecay::OriginType::Prompt) ? aod::cf2prongmcpart::Prompt : 0)); + (mcParticle.pdgCode() >= 0 ? aod::cf2prongtrack::D0ToPiK : aod::cf2prongtrack::D0barToKPi) | ((mcParticle.originMcGen() == RecoDecay::OriginType::Prompt) ? aod::cf2prongmcpart::Prompt : 0)); } } PROCESS_SWITCH(Filter2Prong, processMC, "Process MC 2-prong daughters", false); + void processMCGeneric(aod::McCollisions::iterator const&, aod::CFMcParticleRefs const& cfmcparticles, [[maybe_unused]] aod::McParticles const& mcparticles) + { + // The main filter outputs the primary MC particles. Here we just resolve the daughter indices that are needed for the efficiency matching. + for (const auto& r : cfmcparticles) { + const auto& mcParticle = r.mcParticle(); + if (mcParticle.daughtersIds().size() != 2) { + output2ProngMcParts(-1, -1, aod::cf2prongtrack::Generic2Prong); // not a 2-prong + continue; + } + int prongCFId[2] = {-1, -1}; + for (uint i = 0; i < 2; ++i) { + for (const auto& cfmcpart : cfmcparticles) { + if (mcParticle.daughtersIds()[i] == cfmcpart.mcParticleId()) { + prongCFId[i] = cfmcpart.globalIndex(); + break; + } + } + } + output2ProngMcParts(prongCFId[0], prongCFId[1], aod::cf2prongtrack::Generic2Prong); // the 2-prong Phi, for example, can be checked through its daughters + } + } + PROCESS_SWITCH(Filter2Prong, processMCGeneric, "Process generic MC 2-prong daughters", false); + template bool selectionTrack(const T& candidate) { diff --git a/PWGCF/TableProducer/filterCorrelations.cxx b/PWGCF/TableProducer/filterCorrelations.cxx index 572e4c6c886..70a009346c4 100644 --- a/PWGCF/TableProducer/filterCorrelations.cxx +++ b/PWGCF/TableProducer/filterCorrelations.cxx @@ -55,6 +55,9 @@ struct FilterCF { kTrackSelected = BIT(0), kITS5Clusters = BIT(1), kTPCCrossedRows = BIT(2), + kTPCClusters = BIT(3), + kchi2perTPC = BIT(4), + kchi2perITS = BIT(5), }; enum TrackSelectionCuts2 : uint8_t { @@ -68,7 +71,7 @@ struct FilterCF { O2_DEFINE_CONFIGURABLE(cfgCutMCPt, float, 0.5f, "Minimal pT for particles") O2_DEFINE_CONFIGURABLE(cfgCutMCEta, float, 0.8f, "Eta range for particles") O2_DEFINE_CONFIGURABLE(cfgVerbosity, int, 1, "Verbosity level (0 = major, 1 = per collision)") - O2_DEFINE_CONFIGURABLE(cfgTrigger, int, 7, "Trigger choice: (0 = none, 7 = sel7, 8 = sel8, 9 = sel8 + kNoSameBunchPileup + kIsGoodZvtxFT0vsPV, 10 = sel8 before April, 2024, 11 = sel8 for MC, 12 = sel8 with low occupancy cut)") + O2_DEFINE_CONFIGURABLE(cfgTrigger, int, 7, "Trigger choice: (0 = none, 7 = sel7, 8 = sel8, 9 = sel8 + kNoSameBunchPileup + kIsGoodZvtxFT0vsPV, 10 = sel8 before April, 2024, 11 = sel8 for MC, 12 = sel8 with low occupancy cut, 13 = sel8 + kNoSameBunchPileup + kIsGoodITSLayersAll -- for OO/NeNe) ") O2_DEFINE_CONFIGURABLE(cfgMinOcc, int, 0, "minimum occupancy selection") O2_DEFINE_CONFIGURABLE(cfgMaxOcc, int, 3000, "maximum occupancy selection") O2_DEFINE_CONFIGURABLE(cfgCollisionFlags, uint16_t, aod::collision::CollisionFlagsRun2::Run2VertexerTracks, "Request collision flags if non-zero (0 = off, 1 = Run2VertexerTracks)") @@ -84,6 +87,10 @@ struct FilterCF { O2_DEFINE_CONFIGURABLE(dcazmax, float, 999.f, "maximum dcaz of tracks") O2_DEFINE_CONFIGURABLE(itsnclusters, int, 5, "minimum number of ITS clusters for tracks") O2_DEFINE_CONFIGURABLE(tpcncrossedrows, int, 80, "minimum number of TPC crossed rows for tracks") + O2_DEFINE_CONFIGURABLE(tpcnclusters, int, 50, "minimum number of TPC clusters found") + O2_DEFINE_CONFIGURABLE(chi2pertpccluster, float, 2.5, "maximum Chi2 / cluster for the TPC track segment") + O2_DEFINE_CONFIGURABLE(chi2peritscluster, float, 36, "maximum Chi2 / cluster for the ITS track segment") + O2_DEFINE_CONFIGURABLE(cfgEstimatorBitMask, uint16_t, 0, "BitMask for multiplicity estimators to be included in the CFMultSet tables."); // Filters and input definitions Filter collisionZVtxFilter = nabs(aod::collision::posZ) < cfgCutVertex; @@ -111,6 +118,9 @@ struct FilterCF { Produces outputTrackRefs; Produces outputMcParticleRefs; + Produces outputMultSets; + std::vector multiplicities{}; + // persistent caches std::vector mcReconstructedCache; std::vector mcParticleLabelsCache; @@ -140,6 +150,8 @@ struct FilterCF { return isMultSelected && collision.sel8() && collision.selection_bit(aod::evsel::kNoSameBunchPileup) && collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) && collision.selection_bit(aod::evsel::kNoCollInTimeRangeStandard) && collision.selection_bit(aod::evsel::kIsGoodITSLayersAll); else return false; + } else if (cfgTrigger == 13) { // relevant for OO/NeNe + return isMultSelected && collision.sel8() && collision.selection_bit(aod::evsel::kNoSameBunchPileup) && collision.selection_bit(aod::evsel::kIsGoodITSLayersAll); } return false; } @@ -205,6 +217,15 @@ struct FilterCF { if (track.tpcNClsCrossedRows() >= tpcncrossedrows) { trackType |= kTPCCrossedRows; } + if (track.tpcNClsFound() >= tpcnclusters) { + trackType |= kTPCClusters; + } + if (track.tpcChi2NCl() <= chi2pertpccluster) { + trackType |= kchi2perTPC; + } + if (track.itsChi2NCl() <= chi2peritscluster) { + trackType |= kchi2perITS; + } } return trackType; } else if (cfgTrackSelection == 2) { @@ -221,6 +242,9 @@ struct FilterCF { return 0; } + template + using HasMultTables = decltype(std::declval().multNTracksPV()); + /// \brief Templetized process data for a given collision and its associated tracks /// \param collision The collision object containing information about the collision /// \param tracks The collection of tracks associated with the collision @@ -238,6 +262,19 @@ struct FilterCF { auto bc = collision.template bc_as(); outputCollisions(bc.runNumber(), collision.posZ(), collision.multiplicity(), bc.timestamp()); + if constexpr (std::experimental::is_detected::value) { + multiplicities.clear(); + if (cfgEstimatorBitMask & aod::cfmultset::CentFT0C) + multiplicities.push_back(collision.centFT0C()); + if (cfgEstimatorBitMask & aod::cfmultset::MultFV0A) + multiplicities.push_back(collision.multFV0A()); + if (cfgEstimatorBitMask & aod::cfmultset::MultNTracksPV) + multiplicities.push_back(collision.multNTracksPV()); + if (cfgEstimatorBitMask & aod::cfmultset::MultNTracksGlobal) + multiplicities.push_back(collision.multNTracksGlobal()); + outputMultSets(multiplicities); + } + if (cfgTransientTables) outputCollRefs(collision.globalIndex()); for (auto& track : tracks) { @@ -266,6 +303,12 @@ struct FilterCF { } PROCESS_SWITCH(FilterCF, processDataPid, "Process data with PID", false); + void processDataMults(soa::Filtered>::iterator const& collision, aod::BCsWithTimestamps const&, soa::Filtered> const& tracks) + { + processDataT(collision, tracks); + } + PROCESS_SWITCH(FilterCF, processDataMults, "Process data with multiplicity sets", false); + /// \brief Process MC data for a given set of MC collisions and associated particles and tracks /// \param mcCollisions The collection of MC collisions /// \param allParticles The collection of all MC particles diff --git a/PWGCF/Tasks/correlations.cxx b/PWGCF/Tasks/correlations.cxx index 941f9541612..2a6101a5b9a 100644 --- a/PWGCF/Tasks/correlations.cxx +++ b/PWGCF/Tasks/correlations.cxx @@ -36,13 +36,16 @@ #include #include +#include #include #include #include #include #include +#include #include +#include #include #include @@ -84,7 +87,10 @@ struct CorrelationTask { O2_DEFINE_CONFIGURABLE(cfgTwoTrackCutMinRadius, float, 0.8f, "Two track cut: radius in m from which two track cuts are applied"); O2_DEFINE_CONFIGURABLE(cfgLocalEfficiency, int, 0, "0 = OFF and 1 = ON for local efficiency"); O2_DEFINE_CONFIGURABLE(cfgCentBinsForMC, int, 0, "0 = OFF and 1 = ON for data like multiplicity/centrality bins for MC steps"); - O2_DEFINE_CONFIGURABLE(cfgTrackBitMask, uint8_t, 0, "BitMask for track selection systematics; refer to the enum TrackSelectionCuts in filtering task"); + O2_DEFINE_CONFIGURABLE(cfgTrackBitMask, uint16_t, 0, "BitMask for track selection systematics; refer to the enum TrackSelectionCuts in filtering task"); + O2_DEFINE_CONFIGURABLE(cfgMultCorrelationsMask, uint16_t, 0, "Selection bitmask for the multiplicity correlations. This should match the filter selection cfgEstimatorBitMask.") + O2_DEFINE_CONFIGURABLE(cfgMultCutFormula, std::string, "", "Multiplicity correlations cut formula. A result greater than zero results in accepted event. Parameters: [cFT0C] FT0C centrality, [mFV0A] V0A multiplicity, [mGlob] global track multiplicity, [mPV] PV track multiplicity") + // Suggested values: Photon: 0.004; K0 and Lambda: 0.005 Configurable> cfgPairCut{"cfgPairCut", {kCfgPairCutDefaults[0], 5, {"Photon", "K0", "Lambda", "Phi", "Rho"}}, "Pair cuts on various particles"}; @@ -140,6 +146,9 @@ struct CorrelationTask { std::vector efficiencyAssociatedCache; std::vector p2indexCache; + std::unique_ptr multCutFormula; + std::array multCutFormulaParamIndex; + struct Config { bool mPairCuts = false; THn* mEfficiencyTrigger = nullptr; @@ -175,6 +184,20 @@ struct CorrelationTask { registry.add("invMassTwoPartDPhi", "2D 2-prong invariant mass (GeV/c^2)", {HistType::kTHnSparseF, {axisSpecMass, axisSpecMass, axisPtTrigger, axisPtAssoc, axisDeltaPhi}}); } } + if (doprocessSameDerivedMultSet) { + if (cfgMultCorrelationsMask == 0) + LOGF(fatal, "cfgMultCorrelationsMask can not be 0 when MultSet process functions are in use."); + std::vector multAxes; + if (cfgMultCorrelationsMask & aod::cfmultset::CentFT0C) + multAxes.emplace_back(100, 0, 100, "FT0C centrality"); + if (cfgMultCorrelationsMask & aod::cfmultset::MultFV0A) + multAxes.emplace_back(1000, 0, 100000, "V0A multiplicity"); + if (cfgMultCorrelationsMask & aod::cfmultset::MultNTracksPV) + multAxes.emplace_back(100, 0, 1000, "Nch PV"); + if (cfgMultCorrelationsMask & aod::cfmultset::MultNTracksGlobal) + multAxes.emplace_back(100, 0, 1000, "Nch Global"); + registry.add("multCorrelations", "Multiplicity correlations", {HistType::kTHnSparseF, multAxes}); + } registry.add("multiplicity", "event multiplicity", {HistType::kTH1F, {{1000, 0, 100, "/multiplicity/centrality"}}}); registry.add("yvspt", "y vs pT", {HistType::kTH2F, {{100, -1, 1, "y"}, {100, 0, 20, "p_{T}"}}}); // y vs pT for all tracks (control histogram) @@ -202,6 +225,26 @@ struct CorrelationTask { // --- OBJECT INIT --- + if (!cfgMultCutFormula.value.empty()) { + multCutFormula = std::make_unique("multCutFormula", cfgMultCutFormula.value.c_str()); + std::fill_n(multCutFormulaParamIndex.begin(), std::size(multCutFormulaParamIndex), ~0u); + std::array pars = {"cFT0C", "mFV0A", "mPV", "mGlob"}; // must correspond the order of MultiplicityEstimators + for (uint i = 0, n = multCutFormula->GetNpar(); i < n; ++i) { + auto m = std::find(pars.begin(), pars.end(), multCutFormula->GetParName(i)); + if (m == pars.end()) { + + LOGF(warning, "Unknown parameter in cfgMultCutFormula: %s", multCutFormula->GetParName(i)); + continue; + } + if ((cfgMultCorrelationsMask.value & (1u << i)) == 0) { + LOGF(warning, "The centrality/multiplicity estimator %s is not available to be used in cfgMultCutFormula. Ensure cfgMultCorrelationsMask is correct and matches the CFMultSets in derived data."); + } else { + multCutFormulaParamIndex[std::distance(pars.begin(), m)] = i; + LOGF(info, "Multiplicity cut parameter %s in use.", m->c_str()); + } + } + } + std::vector corrAxis = {{axisDeltaEta, "#Delta#eta"}, {axisPtAssoc, "p_{T} (GeV/c)"}, {axisPtTrigger, "p_{T} (GeV/c)"}, @@ -272,10 +315,20 @@ struct CorrelationTask { return !((track.decay() == 0 && track.mlProbD0()[0] > cfgPtCentDepMLbkgSel->at(idx)) || (track.decay() == 1 && track.mlProbD0bar()[0] > cfgPtCentDepMLbkgSel->at(idx))); } + template + using HasMultSet = decltype(std::declval().multiplicities()); + template - void fillQA(const TCollision& /*collision*/, float multiplicity, const TTracks& tracks) + void fillQA(const TCollision& collision, float multiplicity, const TTracks& tracks) { registry.fill(HIST("multiplicity"), multiplicity); + if constexpr (std::experimental::is_detected::value) { + if (std::popcount(cfgMultCorrelationsMask.value) != static_cast(collision.multiplicities().size())) + LOGF(fatal, "Multiplicity selections (cfgMultCorrelationsMask = 0x%x) do not match the size of the table column (%ld). The histogram filling relies on the preservation of order.", cfgMultCorrelationsMask.value, collision.multiplicities().size()); + // need to convert to vec of doubles since THnSparse has no way to fill vec of floats directly + std::vector v(collision.multiplicities().begin(), collision.multiplicities().end()); + registry.get(HIST("multCorrelations")).get()->Fill(v.data()); + } for (const auto& track1 : tracks) { registry.fill(HIST("yields"), multiplicity, track1.pt(), track1.eta()); registry.fill(HIST("etaphi"), multiplicity, track1.eta(), track1.phi()); @@ -400,9 +453,42 @@ struct CorrelationTask { template using HasPartDaugh1Id = decltype(std::declval().cfParticleDaugh1Id()); + /* + OO outlier cut (requires mask 15): +(567.785+172.715*[mGlob]+0.77888*[mGlob]*[mGlob]+-0.00693466*[mGlob]*[mGlob]*[mGlob]+1.40564e-05*[mGlob]*[mGlob]*[mGlob]*[mGlob] + 3.5*(679.853+66.8068*[mGlob]+-0.444332*[mGlob]*[mGlob]+0.00115002*[mGlob]*[mGlob]*[mGlob]+-4.92064e-07*[mGlob]*[mGlob]*[mGlob]*[mGlob])) > [mFV0A] && (567.785+172.715*[mGlob]+0.77888*[mGlob]*[mGlob]+-0.00693466*[mGlob]*[mGlob]*[mGlob]+1.40564e-05*[mGlob]*[mGlob]*[mGlob]*[mGlob] - 3.0*(679.853+66.8068*[mGlob]+-0.444332*[mGlob]*[mGlob]+0.00115002*[mGlob]*[mGlob]*[mGlob]+-4.92064e-07*[mGlob]*[mGlob]*[mGlob]*[mGlob])) < [mFV0A] && (172.406 + -4.50219*[cFT0C] + 0.0543038*[cFT0C]*[cFT0C] + -0.000373213*[cFT0C]*[cFT0C]*[cFT0C] + 1.15322e-06*[cFT0C]*[cFT0C]*[cFT0C]*[cFT0C] + 4.0*(49.7503 + -1.29008*[cFT0C] + 0.0160059*[cFT0C]*[cFT0C] + -7.86846e-05*[cFT0C]*[cFT0C]*[cFT0C])) > [mPV] && (172.406 + -4.50219*[cFT0C] + 0.0543038*[cFT0C]*[cFT0C] + -0.000373213*[cFT0C]*[cFT0C]*[cFT0C] + 1.15322e-06*[cFT0C]*[cFT0C]*[cFT0C]*[cFT0C] - 2.5*(49.7503 + -1.29008*[cFT0C] + 0.0160059*[cFT0C]*[cFT0C] + -7.86846e-05*[cFT0C]*[cFT0C]*[cFT0C])) < [mPV] && (125.02 + -3.30255*[cFT0C] + 0.0398663*[cFT0C]*[cFT0C] + -0.000271942*[cFT0C]*[cFT0C]*[cFT0C] + 8.34098e-07*[cFT0C]*[cFT0C]*[cFT0C]*[cFT0C] + 4.0*(37.0244 + -0.949883*[cFT0C] + 0.0116622*[cFT0C]*[cFT0C] + -5.71117e-05*[cFT0C]*[cFT0C]*[cFT0C])) > [mGlob] && (125.02 + -3.30255*[cFT0C] + 0.0398663*[cFT0C]*[cFT0C] + -0.000271942*[cFT0C]*[cFT0C]*[cFT0C] + 8.34098e-07*[cFT0C]*[cFT0C]*[cFT0C]*[cFT0C] - 2.5*(37.0244 + -0.949883*[cFT0C] + 0.0116622*[cFT0C]*[cFT0C] + -5.71117e-05*[cFT0C]*[cFT0C]*[cFT0C])) < [mGlob] && (-0.223013 + 0.715849*[mPV] + 3*(0.664242 + 0.0829653*[mPV] + -0.000503733*[mPV]*[mPV] + 1.21185e-06*[mPV]*[mPV]*[mPV])) > [mGlob] +*/ + template + bool passOutlier(CollType const& collision) + { + if (cfgMultCutFormula.value.empty()) + return true; + for (uint i = 0; i < 4; ++i) { + if ((cfgMultCorrelationsMask.value & (1u << i)) == 0 || multCutFormulaParamIndex[i] == ~0u) + continue; + auto estIndex = std::popcount(cfgMultCorrelationsMask.value & ((1u << i) - 1)); + multCutFormula->SetParameter(multCutFormulaParamIndex[i], collision.multiplicities()[estIndex]); + } + return multCutFormula->Eval() > 0.0f; + } + template - float getV0Rapidity(const T& track) + std::tuple getV0Rapidity(const T& track) { + if constexpr (!std::experimental::is_detected::value) + return {false, 0.0f}; // no decay type, return dummy rapidity + const auto decayType = track.decay(); + float mass = 0.f; + + if (decayType == aod::cf2prongtrack::K0stoPiPi) { + mass = o2::constants::physics::MassK0Short; + } else if (decayType == aod::cf2prongtrack::LambdatoPPi || decayType == aod::cf2prongtrack::AntiLambdatoPiP) { + mass = o2::constants::physics::MassLambda; + } else if (decayType == aod::cf2prongtrack::PhiToKK) { + mass = o2::constants::physics::MassPhi; + } else { + return {false, 0.0f}; // unsupported decay type, return dummy rapidity + } + const float pt = track.pt(); const float eta = track.eta(); const float phi = track.phi(); @@ -413,25 +499,8 @@ struct CorrelationTask { const float p2 = px * px + py * py + pz * pz; - if constexpr (std::experimental::is_detected::value) { - const auto decayType = track.decay(); - float mass = 0.f; - - if (decayType == aod::cf2prongtrack::K0stoPiPi) { - mass = o2::constants::physics::MassK0Short; - } else if (decayType == aod::cf2prongtrack::LambdatoPPi || decayType == aod::cf2prongtrack::AntiLambdatoPiP) { - mass = o2::constants::physics::MassLambda; - } else if (decayType == aod::cf2prongtrack::PhiToKK) { - mass = o2::constants::physics::MassPhi; - } else { - return -999.f; // unsupported decay type, return dummy rapidity - } - - const float E = std::sqrt(p2 + mass * mass); - return 0.5f * std::log((E + pz) / (E - pz)); - } - - return -999.f; // no decay type, return dummy rapidity + const float E = std::sqrt(p2 + mass * mass); + return {true, 0.5f * std::log((E + pz) / (E - pz))}; } template @@ -484,10 +553,12 @@ struct CorrelationTask { if (cfgDecayParticleMask != 0 && (cfgDecayParticleMask & (1u << static_cast(track1.decay()))) == 0u) { continue; // skip particles that do not match the decay mask } - if (cfgV0RapidityMax > 0 && std::abs(getV0Rapidity(track1)) > cfgV0RapidityMax) { - continue; // V0s are not allowed to be outside the rapidity range + if (cfgV0RapidityMax > 0) { + auto [t, y] = getV0Rapidity(track1); + if (t && std::abs(y) > cfgV0RapidityMax) + continue; // V0s are not allowed to be outside the rapidity range + registry.fill(HIST("yvspt"), y, track1.pt()); } - registry.fill(HIST("yvspt"), getV0Rapidity(track1), track1.pt()); } if constexpr (std::experimental::is_detected::value) { @@ -565,8 +636,10 @@ struct CorrelationTask { if (cfgDecayParticleMask != 0 && (cfgDecayParticleMask & (1u << static_cast(track2.decay()))) == 0u) { continue; // skip particles that do not match the decay mask } - if (cfgV0RapidityMax > 0 && std::abs(getV0Rapidity(track1)) > cfgV0RapidityMax) { - continue; // V0s are not allowed to be outside the rapidity range + if (cfgV0RapidityMax > 0) { + auto [t, y] = getV0Rapidity(track1); + if (t && std::abs(y) > cfgV0RapidityMax) + continue; // V0s are not allowed to be outside the rapidity range } } @@ -739,9 +812,10 @@ struct CorrelationTask { } PROCESS_SWITCH(CorrelationTask, processSameAOD, "Process same event on AOD", true); - template - void processSameDerivedT(DerivedCollisions::iterator const& collision, TTracks1 const& tracks1, TTracks2 const& tracks2) + template + void processSameDerivedT(CollType const& collision, TTracks1 const& tracks1, TTracks2 const& tracks2) { + using BinningTypeDerived = ColumnBinningPolicy; BinningTypeDerived configurableBinningDerived{{axisVertex, axisMultiplicity}, true}; // true is for 'ignore overflows' (true by default). Underflows and overflows will have bin -1. if (cfgVerbosity > 0) { LOGF(info, "processSameDerivedT: Tracks for collision: %d/%d | Vertex: %.1f | Multiplicity/Centrality: %.1f", tracks1.size(), tracks2.size(), collision.posZ(), collision.multiplicity()); @@ -777,6 +851,14 @@ struct CorrelationTask { } PROCESS_SWITCH(CorrelationTask, processSameDerived, "Process same event on derived data", false); + void processSameDerivedMultSet(soa::Filtered>::iterator const& collision, soa::Filtered const& tracks) + { + if (!passOutlier(collision)) + return; + processSameDerivedT(collision, tracks, tracks); + } + PROCESS_SWITCH(CorrelationTask, processSameDerivedMultSet, "Process same event on derived data with multiplicity sets", false); + void processSame2ProngDerived(DerivedCollisions::iterator const& collision, soa::Filtered const& tracks, soa::Filtered const& p2tracks) { processSameDerivedT(collision, p2tracks, tracks); @@ -844,21 +926,32 @@ struct CorrelationTask { } PROCESS_SWITCH(CorrelationTask, processMixedAOD, "Process mixed events on AOD", false); - using BinningTypeDerived = ColumnBinningPolicy; - - template - void processMixedDerivedT(DerivedCollisions const& collisions, TrackTypes&&... tracks) + template + void processMixedDerivedT(CollType const& collisions, TrackTypes&&... tracks) { - BinningTypeDerived configurableBinningDerived{{axisVertex, axisMultiplicity}, true}; // true is for 'ignore overflows' (true by default). Underflows and overflows will have bin -1. - // Strictly upper categorised collisions, for cfgNoMixedEvents combinations per bin, skipping those in entry -1 + auto getMultiplicity = + [this](auto& col) { + if constexpr (std::experimental::is_detected::value) { + if (!passOutlier(col)) + return -1.0f; + } else { + (void)this; // fix compile error on unused 'this' capture + } + return col.multiplicity(); + }; + + using BinningTypeDerived = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getMultiplicity)>; + BinningTypeDerived configurableBinningDerived{{getMultiplicity}, {axisVertex, axisMultiplicity}, true}; // true is for 'ignore overflows' (true by default). Underflows and overflows will have bin -1. + // Strictly upper categorised collisions, for cfgNoMixedEvents combinations per bin, skipping those in entry -1 auto tracksTuple = std::make_tuple(std::forward(tracks)...); using TA = std::tuple_element<0, decltype(tracksTuple)>::type; using TB = std::tuple_element - 1, decltype(tracksTuple)>::type; - Pair pairs{configurableBinningDerived, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + Pair pairs{configurableBinningDerived, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip for (auto it = pairs.begin(); it != pairs.end(); it++) { auto& [collision1, tracks1, collision2, tracks2] = *it; - int bin = configurableBinningDerived.getBin({collision1.posZ(), collision1.multiplicity()}); + float multiplicity = getMultiplicity(collision1); + int bin = configurableBinningDerived.getBin(std::tuple(collision1.posZ(), multiplicity)); float eventWeight = 1.0f / it.currentWindowNeighbours(); int field = 0; if (cfgTwoTrackCut > 0) { @@ -896,6 +989,12 @@ struct CorrelationTask { } PROCESS_SWITCH(CorrelationTask, processMixedDerived, "Process mixed events on derived data", false); + void processMixedDerivedMultSet(soa::Filtered> const& collisions, DerivedTracks const& tracks) + { + processMixedDerivedT(collisions, tracks); + } + PROCESS_SWITCH(CorrelationTask, processMixedDerivedMultSet, "Process mixed events on derived data with multiplicity sets", false); + void processMixed2ProngDerived(DerivedCollisions const& collisions, DerivedTracks const& tracks, soa::Filtered const& p2tracks) { processMixedDerivedT(collisions, p2tracks, tracks); @@ -1140,7 +1239,7 @@ struct CorrelationTask { } } - if (!(doprocessSameDerived || doprocessSame2ProngDerived || doprocessSame2ProngDerivedML || doprocessSame2Prong2Prong || doprocessSame2Prong2ProngML)) { + if (!(doprocessSameDerived || doprocessSameDerivedMultSet || doprocessSame2ProngDerived || doprocessSame2ProngDerivedML || doprocessSame2Prong2Prong || doprocessSame2Prong2ProngML)) { if constexpr (std::experimental::is_detected::value) fillQA(mcCollision, multiplicity, mcParticles1, mcParticles2); else diff --git a/PWGCF/Tasks/dptDptCorrelations.cxx b/PWGCF/Tasks/dptDptCorrelations.cxx index 065e4be286f..07754ef5316 100644 --- a/PWGCF/Tasks/dptDptCorrelations.cxx +++ b/PWGCF/Tasks/dptDptCorrelations.cxx @@ -13,7 +13,26 @@ /// \brief implements two-particle correlations base data collection /// \author victor.gonzalez.sebastian@gmail.com +#include "PWGCF/Core/AnalysisConfigurableCuts.h" +#include "PWGCF/Core/PairCuts.h" +#include "PWGCF/DataModel/DptDptFiltered.h" +#include "PWGCF/TableProducer/dptDptFilter.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TableHelper.h" +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "DataFormatsParameters/GRPObject.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" #include + #include #include #include @@ -24,28 +43,12 @@ #include #include #include + +#include #include +#include #include #include -#include -#include - -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TableHelper.h" -#include "Common/Core/RecoDecay.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/RunningWorkflowInfo.h" -#include "PWGCF/Core/AnalysisConfigurableCuts.h" -#include "PWGCF/Core/PairCuts.h" -#include "PWGCF/DataModel/DptDptFiltered.h" -#include "PWGCF/TableProducer/dptDptFilter.h" using namespace o2; using namespace o2::framework; @@ -279,15 +282,17 @@ struct DptDptCorrelations { photon = p1+p2; photon.M()*/ - float tantheta1 = 1e10; + constexpr float kLARGETANTHETA = 1e10; + constexpr float kVERYSMALLETA = 1e-10; + float tantheta1 = kLARGETANTHETA; - if (track1.eta() < -1e-10 || track1.eta() > 1e-10) { + if (track1.eta() < -kVERYSMALLETA || track1.eta() > kVERYSMALLETA) { float expTmp = std::exp(-track1.eta()); tantheta1 = 2.0 * expTmp / (1.0 - expTmp * expTmp); } - float tantheta2 = 1e10; - if (track2.eta() < -1e-10 || track2.eta() > 1e-10) { + float tantheta2 = kLARGETANTHETA; + if (track2.eta() < -kVERYSMALLETA || track2.eta() > kVERYSMALLETA) { float expTmp = std::exp(-track2.eta()); tantheta2 = 2.0 * expTmp / (1.0 - expTmp * expTmp); } diff --git a/PWGCF/Tasks/dptDptFilterQa.cxx b/PWGCF/Tasks/dptDptFilterQa.cxx index 85dee751438..876fd8ccb5e 100644 --- a/PWGCF/Tasks/dptDptFilterQa.cxx +++ b/PWGCF/Tasks/dptDptFilterQa.cxx @@ -13,15 +13,16 @@ /// \brief basic checks for the behavior of the filter task /// \author victor.gonzalez.sebastian@gmail.com -#include -#include +#include "PWGCF/DataModel/DptDptFiltered.h" +#include "PWGCF/TableProducer/dptDptFilter.h" #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" -#include "PWGCF/DataModel/DptDptFiltered.h" -#include "PWGCF/TableProducer/dptDptFilter.h" + +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/Tasks/matchRecoGen.cxx b/PWGCF/Tasks/matchRecoGen.cxx index 57ab00301b7..1881b17b268 100644 --- a/PWGCF/Tasks/matchRecoGen.cxx +++ b/PWGCF/Tasks/matchRecoGen.cxx @@ -13,25 +13,24 @@ /// \brief basic check for the matching between generator level and detector level /// \author victor.gonzalez.sebastian@gmail.com -#include -#include -#include +#include "PWGCF/Core/AnalysisConfigurableCuts.h" +#include "PWGCF/DataModel/DptDptFiltered.h" +#include "PWGCF/TableProducer/dptDptFilter.h" +#include "Common/Core/RecoDecay.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" -#include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" + #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" #include "Framework/O2DatabasePDGPlugin.h" #include "Framework/runDataProcessing.h" -#include "PWGCF/Core/AnalysisConfigurableCuts.h" -#include "PWGCF/DataModel/DptDptFiltered.h" -#include "PWGCF/TableProducer/dptDptFilter.h" + #include #include #include @@ -42,6 +41,10 @@ #include #include +#include +#include +#include + using namespace o2; using namespace o2::framework; using namespace o2::soa; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/CMakeLists.txt b/PWGCF/TwoParticleCorrelations/Tasks/CMakeLists.txt index 3ff80210ce2..0b61a13fbb5 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/CMakeLists.txt +++ b/PWGCF/TwoParticleCorrelations/Tasks/CMakeLists.txt @@ -63,6 +63,11 @@ o2physics_add_dpl_workflow(di-hadron-cor PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore O2Physics::AnalysisCCDB O2Physics::GFWCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(pid-di-hadron + SOURCES pidDiHadron.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore O2Physics::AnalysisCCDB O2Physics::GFWCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(longrange-correlation SOURCES longrangeCorrelation.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore diff --git a/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx b/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx index d47aff3c749..7ccd59ed178 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/diHadronCor.cxx @@ -108,13 +108,28 @@ struct DiHadronCor { Configurable> cfgMultT0CCutPars{"cfgMultT0CCutPars", std::vector{143.04, -4.58368, 0.0766055, -0.000727796, 2.86153e-06, 23.3108, -0.36304, 0.00437706, -4.717e-05, 1.98332e-07}, "Global multiplicity vs T0C centrality cut parameter values"}; O2_DEFINE_CONFIGURABLE(cfgMultPVT0CCutEnabled, bool, false, "Enable PV multiplicity vs T0C centrality cut") Configurable> cfgMultPVT0CCutPars{"cfgMultPVT0CCutPars", std::vector{195.357, -6.15194, 0.101313, -0.000955828, 3.74793e-06, 30.0326, -0.43322, 0.00476265, -5.11206e-05, 2.13613e-07}, "PV multiplicity vs T0C centrality cut parameter values"}; - O2_DEFINE_CONFIGURABLE(cfgMultMultHighCutFunction, std::string, "[0]+[1]*x + 5.*([2]+[3]*x)", "Functional for multiplicity correlation cut"); - O2_DEFINE_CONFIGURABLE(cfgMultMultLowCutFunction, std::string, "[0]+[1]*x - 5.*([2]+[3]*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultMultPVHighCutFunction, std::string, "[0]+[1]*x + 5.*([2]+[3]*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultMultPVLowCutFunction, std::string, "[0]+[1]*x - 5.*([2]+[3]*x)", "Functional for multiplicity correlation cut"); O2_DEFINE_CONFIGURABLE(cfgMultGlobalPVCutEnabled, bool, false, "Enable global multiplicity vs PV multiplicity cut") Configurable> cfgMultGlobalPVCutPars{"cfgMultGlobalPVCutPars", std::vector{-0.140809, 0.734344, 2.77495, 0.0165935}, "PV multiplicity vs T0C centrality cut parameter values"}; + O2_DEFINE_CONFIGURABLE(cfgMultMultV0AHighCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x + 4.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultMultV0ALowCutFunction, std::string, "[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x - 3.*([5] + [6]*x + [7]*x*x + [8]*x*x*x + [9]*x*x*x*x)", "Functional for multiplicity correlation cut"); + O2_DEFINE_CONFIGURABLE(cfgMultMultV0ACutEnabled, bool, false, "Enable global multiplicity vs V0A multiplicity cut") + Configurable> cfgMultMultV0ACutPars{"cfgMultMultV0ACutPars", std::vector{534.893, 184.344, 0.423539, -0.00331436, 5.34622e-06, 871.239, 53.3735, -0.203528, 0.000122758, 5.41027e-07}, "Global multiplicity vs V0A multiplicity cut parameter values"}; std::vector multT0CCutPars; std::vector multPVT0CCutPars; std::vector multGlobalPVCutPars; + std::vector multMultV0ACutPars; + TF1* fMultPVT0CCutLow = nullptr; + TF1* fMultPVT0CCutHigh = nullptr; + TF1* fMultT0CCutLow = nullptr; + TF1* fMultT0CCutHigh = nullptr; + TF1* fMultGlobalPVCutLow = nullptr; + TF1* fMultGlobalPVCutHigh = nullptr; + TF1* fMultMultV0ACutLow = nullptr; + TF1* fMultMultV0ACutHigh = nullptr; + TF1* fT0AV0AMean = nullptr; + TF1* fT0AV0ASigma = nullptr; } cfgFuncParas; SliceCache cache; @@ -183,16 +198,6 @@ struct DiHadronCor { // persistent caches std::vector efficiencyAssociatedCache; - // Additional Event selection cuts - Copy from flowGenericFramework.cxx - TF1* fMultPVT0CCutLow = nullptr; - TF1* fMultPVT0CCutHigh = nullptr; - TF1* fMultT0CCutLow = nullptr; - TF1* fMultT0CCutHigh = nullptr; - TF1* fMultGlobalPVCutLow = nullptr; - TF1* fMultGlobalPVCutHigh = nullptr; - TF1* fT0AV0AMean = nullptr; - TF1* fT0AV0ASigma = nullptr; - void init(InitContext&) { if (cfgCentTableUnavailable && !cfgSelCollByNch) { @@ -229,25 +234,31 @@ struct DiHadronCor { cfgFuncParas.multT0CCutPars = cfgFuncParas.cfgMultT0CCutPars; cfgFuncParas.multPVT0CCutPars = cfgFuncParas.cfgMultPVT0CCutPars; cfgFuncParas.multGlobalPVCutPars = cfgFuncParas.cfgMultGlobalPVCutPars; - fMultPVT0CCutLow = new TF1("fMultPVT0CCutLow", cfgFuncParas.cfgMultCentLowCutFunction->c_str(), 0, 100); - fMultPVT0CCutLow->SetParameters(&(cfgFuncParas.multPVT0CCutPars[0])); - fMultPVT0CCutHigh = new TF1("fMultPVT0CCutHigh", cfgFuncParas.cfgMultCentHighCutFunction->c_str(), 0, 100); - fMultPVT0CCutHigh->SetParameters(&(cfgFuncParas.multPVT0CCutPars[0])); - - fMultT0CCutLow = new TF1("fMultT0CCutLow", cfgFuncParas.cfgMultCentLowCutFunction->c_str(), 0, 100); - fMultT0CCutLow->SetParameters(&(cfgFuncParas.multT0CCutPars[0])); - fMultT0CCutHigh = new TF1("fMultT0CCutHigh", cfgFuncParas.cfgMultCentHighCutFunction->c_str(), 0, 100); - fMultT0CCutHigh->SetParameters(&(cfgFuncParas.multT0CCutPars[0])); - - fMultGlobalPVCutLow = new TF1("fMultGlobalPVCutLow", cfgFuncParas.cfgMultMultLowCutFunction->c_str(), 0, 4000); - fMultGlobalPVCutLow->SetParameters(&(cfgFuncParas.multGlobalPVCutPars[0])); - fMultGlobalPVCutHigh = new TF1("fMultGlobalPVCutHigh", cfgFuncParas.cfgMultMultHighCutFunction->c_str(), 0, 4000); - fMultGlobalPVCutHigh->SetParameters(&(cfgFuncParas.multGlobalPVCutPars[0])); - - fT0AV0AMean = new TF1("fT0AV0AMean", "[0]+[1]*x", 0, 200000); - fT0AV0AMean->SetParameters(-1601.0581, 9.417652e-01); - fT0AV0ASigma = new TF1("fT0AV0ASigma", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 200000); - fT0AV0ASigma->SetParameters(463.4144, 6.796509e-02, -9.097136e-07, 7.971088e-12, -2.600581e-17); + cfgFuncParas.multMultV0ACutPars = cfgFuncParas.cfgMultMultV0ACutPars; + cfgFuncParas.fMultPVT0CCutLow = new TF1("fMultPVT0CCutLow", cfgFuncParas.cfgMultCentLowCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultPVT0CCutLow->SetParameters(&(cfgFuncParas.multPVT0CCutPars[0])); + cfgFuncParas.fMultPVT0CCutHigh = new TF1("fMultPVT0CCutHigh", cfgFuncParas.cfgMultCentHighCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultPVT0CCutHigh->SetParameters(&(cfgFuncParas.multPVT0CCutPars[0])); + + cfgFuncParas.fMultT0CCutLow = new TF1("fMultT0CCutLow", cfgFuncParas.cfgMultCentLowCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultT0CCutLow->SetParameters(&(cfgFuncParas.multT0CCutPars[0])); + cfgFuncParas.fMultT0CCutHigh = new TF1("fMultT0CCutHigh", cfgFuncParas.cfgMultCentHighCutFunction->c_str(), 0, 100); + cfgFuncParas.fMultT0CCutHigh->SetParameters(&(cfgFuncParas.multT0CCutPars[0])); + + cfgFuncParas.fMultGlobalPVCutLow = new TF1("fMultGlobalPVCutLow", cfgFuncParas.cfgMultMultPVLowCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultGlobalPVCutLow->SetParameters(&(cfgFuncParas.multGlobalPVCutPars[0])); + cfgFuncParas.fMultGlobalPVCutHigh = new TF1("fMultGlobalPVCutHigh", cfgFuncParas.cfgMultMultPVHighCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultGlobalPVCutHigh->SetParameters(&(cfgFuncParas.multGlobalPVCutPars[0])); + + cfgFuncParas.fMultMultV0ACutLow = new TF1("fMultMultV0ACutLow", cfgFuncParas.cfgMultMultV0ALowCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultMultV0ACutLow->SetParameters(&(cfgFuncParas.multMultV0ACutPars[0])); + cfgFuncParas.fMultMultV0ACutHigh = new TF1("fMultMultV0ACutHigh", cfgFuncParas.cfgMultMultV0AHighCutFunction->c_str(), 0, 4000); + cfgFuncParas.fMultMultV0ACutHigh->SetParameters(&(cfgFuncParas.multMultV0ACutPars[0])); + + cfgFuncParas.fT0AV0AMean = new TF1("fT0AV0AMean", "[0]+[1]*x", 0, 200000); + cfgFuncParas.fT0AV0AMean->SetParameters(-1601.0581, 9.417652e-01); + cfgFuncParas.fT0AV0ASigma = new TF1("fT0AV0ASigma", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 200000); + cfgFuncParas.fT0AV0ASigma->SetParameters(463.4144, 6.796509e-02, -9.097136e-07, 7.971088e-12, -2.600581e-17); } std::string hCentTitle = "Centrality distribution, Estimator " + std::to_string(cfgCentEstimator); @@ -262,8 +273,9 @@ struct DiHadronCor { registry.add("pTCorrected", "pTCorrected", {HistType::kTH1D, {axisPtTrigger}}); registry.add("Nch", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); registry.add("Nch_used", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); // histogram to see how many events are in the same and mixed event - registry.add("Centrality", hCentTitle.c_str(), {HistType::kTH1D, {axisCentrality}}); - registry.add("Centrality_used", hCentTitle.c_str(), {HistType::kTH1D, {axisCentrality}}); // histogram to see how many events are in the same and mixed event + registry.add("Centrality", hCentTitle.c_str(), {HistType::kTH1D, {{100, 0, 100}}}); + registry.add("CentralityWeighted", hCentTitle.c_str(), {HistType::kTH1D, {{100, 0, 100}}}); + registry.add("Centrality_used", hCentTitle.c_str(), {HistType::kTH1D, {{100, 0, 100}}}); // histogram to see how many events are in the same and mixed event registry.add("zVtx", "zVtx", {HistType::kTH1D, {axisVertex}}); registry.add("zVtx_used", "zVtx_used", {HistType::kTH1D, {axisVertex}}); registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); @@ -680,22 +692,28 @@ struct DiHadronCor { auto multNTracksPV = collision.multNTracksPV(); if (cfgEvSelMultCorrelation) { - if (cfgFuncParas.cfgMultPVT0CCutEnabled) { - if (multNTracksPV < fMultPVT0CCutLow->Eval(centrality)) + if (cfgFuncParas.cfgMultPVT0CCutEnabled && !cfgCentTableUnavailable) { + if (multNTracksPV < cfgFuncParas.fMultPVT0CCutLow->Eval(centrality)) return 0; - if (multNTracksPV > fMultPVT0CCutHigh->Eval(centrality)) + if (multNTracksPV > cfgFuncParas.fMultPVT0CCutHigh->Eval(centrality)) return 0; } - if (cfgFuncParas.cfgMultT0CCutEnabled) { - if (multTrk < fMultT0CCutLow->Eval(centrality)) + if (cfgFuncParas.cfgMultT0CCutEnabled && !cfgCentTableUnavailable) { + if (multTrk < cfgFuncParas.fMultT0CCutLow->Eval(centrality)) return 0; - if (multTrk > fMultT0CCutHigh->Eval(centrality)) + if (multTrk > cfgFuncParas.fMultT0CCutHigh->Eval(centrality)) return 0; } if (cfgFuncParas.cfgMultGlobalPVCutEnabled) { - if (multTrk < fMultGlobalPVCutLow->Eval(multNTracksPV)) + if (multTrk < cfgFuncParas.fMultGlobalPVCutLow->Eval(multNTracksPV)) return 0; - if (multTrk > fMultGlobalPVCutHigh->Eval(multNTracksPV)) + if (multTrk > cfgFuncParas.fMultGlobalPVCutHigh->Eval(multNTracksPV)) + return 0; + } + if (cfgFuncParas.cfgMultMultV0ACutEnabled) { + if (collision.multFV0A() < cfgFuncParas.fMultMultV0ACutLow->Eval(multTrk)) + return 0; + if (collision.multFV0A() > cfgFuncParas.fMultMultV0ACutHigh->Eval(multTrk)) return 0; } } @@ -704,7 +722,7 @@ struct DiHadronCor { // V0A T0A 5 sigma cut float sigma = 5.0; - if (cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > sigma * fT0AV0ASigma->Eval(collision.multFT0A()))) + if (cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - cfgFuncParas.fT0AV0AMean->Eval(collision.multFT0A())) > sigma * cfgFuncParas.fT0AV0ASigma->Eval(collision.multFT0A()))) return 0; if (fillCounter && cfgEvSelV0AT0ACut) registry.fill(HIST("hEventCountSpecific"), 11.5); @@ -718,13 +736,18 @@ struct DiHadronCor { return; auto bc = collision.bc_as(); float cent = -1.; - if (!cfgCentTableUnavailable) + float weightCent = 1.0f; + if (!cfgCentTableUnavailable) { cent = getCentrality(collision); + } if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), cent, true)) return; - - if (!cfgCentTableUnavailable) + loadCorrection(bc.timestamp()); + if (!cfgCentTableUnavailable) { + getCentralityWeight(weightCent, cent); registry.fill(HIST("Centrality"), cent); + registry.fill(HIST("CentralityWeighted"), cent, weightCent); + } registry.fill(HIST("Nch"), tracks.size()); registry.fill(HIST("zVtx"), collision.posZ()); @@ -735,12 +758,8 @@ struct DiHadronCor { return; } - loadCorrection(bc.timestamp()); registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin fillYield(collision, tracks); - float weightCent = 1.0f; - if (!cfgCentTableUnavailable) - getCentralityWeight(weightCent, cent); same->fillEvent(tracks.size(), CorrelationContainer::kCFStepReconstructed); fillCorrelations(tracks, tracks, collision.posZ(), SameEvent, getMagneticField(bc.timestamp()), cent, weightCent); diff --git a/PWGCF/TwoParticleCorrelations/Tasks/dptDptEfficiencyAndQc.cxx b/PWGCF/TwoParticleCorrelations/Tasks/dptDptEfficiencyAndQc.cxx index 0fdbca208bf..b561f50af0e 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/dptDptEfficiencyAndQc.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/dptDptEfficiencyAndQc.cxx @@ -13,35 +13,38 @@ /// \brief Provides efficiency extraction and QC for track cuts and PID /// \author victor.gonzalez.sebastian@gmail.com -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ReconstructionDataFormats/PID.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TableHelper.h" +#include "PWGCF/Core/AnalysisConfigurableCuts.h" +#include "PWGCF/DataModel/DptDptFiltered.h" +#include "PWGCF/TableProducer/dptDptFilter.h" + #include "Common/Core/RecoDecay.h" -#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/Core/TableHelper.h" +#include "Common/Core/TrackSelection.h" #include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + #include "Framework/ASoAHelpers.h" -#include "Framework/Expressions.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" +#include "Framework/Expressions.h" #include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/PID.h" +#include + #include "Math/MatrixFunctions.h" #include "Math/SMatrix.h" +#include +#include +#include +#include +#include -#include "PWGCF/Core/AnalysisConfigurableCuts.h" -#include "PWGCF/DataModel/DptDptFiltered.h" -#include "PWGCF/TableProducer/dptDptFilter.h" +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -741,41 +744,41 @@ struct PidDataCollectingEngine { if constexpr (kindOfData == kReco) { /* PID histograms */ std::vector whenname{"Before", "After"}; - constexpr char whenprefix[kNoOfSteps]{'B', 'A'}; + constexpr char kWhenPrefix[kNoOfSteps]{'B', 'A'}; std::vector whentitle{"before", ""}; for (uint ix = 0; ix < kNoOfSteps; ++ix) { fhTPCdEdxSignalVsP[ix] = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "PID", whenname[ix].c_str()), - HNAMESTRING("tpcSignalVsP%c", whenprefix[ix]), + HNAMESTRING("tpcSignalVsP%c", kWhenPrefix[ix]), HTITLESTRING("TPC dE/dx signal %s", whentitle[ix].c_str()), kTH2F, {pidPAxis, dEdxAxis}); fhTOFSignalVsP[ix] = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "PID", whenname[ix].c_str()), - HNAMESTRING("tofSignalVsP%c", whenprefix[ix]), + HNAMESTRING("tofSignalVsP%c", kWhenPrefix[ix]), HTITLESTRING("TOF signal %s", whentitle[ix].c_str()), kTH2F, {pidPAxis, {200, 0.0, 1.1, "#beta"}}); fhPvsTOFSqMass[ix] = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "PID", whenname[ix].c_str()), - HNAMESTRING("tofPvsMassSq%c", whenprefix[ix]), + HNAMESTRING("tofPvsMassSq%c", kWhenPrefix[ix]), HTITLESTRING("Momentum versus #it{m}^{2} %s", whentitle[ix].c_str()), kTH2F, {{140, 0.0, 1.4, "#it{m}^{2} ((GeV/c^{2})^{2})"}, pidPAxis}); for (uint isp = 0; isp < nmainsp; ++isp) { fhTPCdEdxSignalDiffVsP[ix][isp] = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "PID", whenname[ix].c_str()), - HNAMESTRING("tpcSignalDiffVsP%c_%s", whenprefix[ix], mainspnames[isp].c_str()), + HNAMESTRING("tpcSignalDiffVsP%c_%s", kWhenPrefix[ix], mainspnames[isp].c_str()), HTITLESTRING("TPC dE/dx to the %s line %s", mainsptitles[isp].c_str(), whentitle[ix].c_str()), kTH2F, {pidPAxis, {400, -200.0, 200.0, FORMATSTRING("dE/dx - _{%s}", mainsptitles[isp].c_str())}}); fhTOFSignalDiffVsP[ix][isp] = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "PID", whenname[ix].c_str()), - HNAMESTRING("tofSignalDiffVsP%c_%s", whenprefix[ix], mainspnames[isp].c_str()), + HNAMESTRING("tofSignalDiffVsP%c_%s", kWhenPrefix[ix], mainspnames[isp].c_str()), HTITLESTRING("#Delta^{TOF_{%s}} %s", mainsptitles[isp].c_str(), whentitle[ix].c_str()), kTH2F, {pidPAxis, {200, -1000.0, 1000.0, FORMATSTRING("t-t_{ev}-t_{exp_{%s}} (ps)", mainsptitles[isp].c_str())}}); fhTPCTOFSigmaVsP[ix][isp] = ADDHISTOGRAM(TH3, DIRECTORYSTRING("%s/%s/%s", dirname, "PID", whenname[ix].c_str()), - HNAMESTRING("toftpcNSigmasVsP%c_%s", whenprefix[ix], mainspnames[isp].c_str()), + HNAMESTRING("toftpcNSigmasVsP%c_%s", kWhenPrefix[ix], mainspnames[isp].c_str()), HTITLESTRING("n#sigma to the %s line %s", mainsptitles[isp].c_str(), whentitle[ix].c_str()), kTH3F, {pidPAxis, {noOfNSigmaBins, minNSigma, maxNSigma, FORMATSTRING("n#sigma_{TPC}^{%s}", mainsptitles[isp].c_str())}, {120, -6.0, 6.0, FORMATSTRING("n#sigma_{TOF}^{%s}", mainsptitles[isp].c_str())}}); } for (uint isp = 0; isp < nallmainsp; ++isp) { fhTPCnSigmasVsP[ix][isp] = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "PID", whenname[ix].c_str()), - HNAMESTRING("tpcNSigmasVsP%c_%s", whenprefix[ix], allmainspnames[isp].c_str()), + HNAMESTRING("tpcNSigmasVsP%c_%s", kWhenPrefix[ix], allmainspnames[isp].c_str()), HTITLESTRING("TPC n#sigma to the %s line %s", allmainsptitles[isp].c_str(), whentitle[ix].c_str()), kTH2F, {pidPAxis, {noOfNSigmaBins, minNSigma, maxNSigma, FORMATSTRING("n#sigma_{TPC}^{%s}", allmainsptitles[isp].c_str())}}); fhTOFnSigmasVsP[ix][isp] = ADDHISTOGRAM(TH2, DIRECTORYSTRING("%s/%s/%s", dirname, "PID", whenname[ix].c_str()), - HNAMESTRING("tofNSigmasVsP%c_%s", whenprefix[ix], allmainspnames[isp].c_str()), + HNAMESTRING("tofNSigmasVsP%c_%s", kWhenPrefix[ix], allmainspnames[isp].c_str()), HTITLESTRING("TOF n#sigma to the %s line %s", allmainsptitles[isp].c_str(), whentitle[ix].c_str()), kTH2F, {pidPAxis, {noOfNSigmaBins, minNSigma, maxNSigma, FORMATSTRING("n#sigma_{TOF}^{%s}", allmainsptitles[isp].c_str())}}); } diff --git a/PWGCF/TwoParticleCorrelations/Tasks/dptDptPerRunExtraQc.cxx b/PWGCF/TwoParticleCorrelations/Tasks/dptDptPerRunExtraQc.cxx index 8617a65de2f..c9304ec1ef9 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/dptDptPerRunExtraQc.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/dptDptPerRunExtraQc.cxx @@ -13,18 +13,18 @@ /// \brief basic per run check of the per analyzed species p vs TPC IW momentum /// \author victor.gonzalez.sebastian@gmail.com -#include -#include -#include +#include "PWGCF/DataModel/DptDptFiltered.h" +#include "PWGCF/TableProducer/dptDptFilter.h" +#include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "PWGCF/DataModel/DptDptFiltered.h" -#include "PWGCF/TableProducer/dptDptFilter.h" +#include +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/dptDptPerRunQc.cxx b/PWGCF/TwoParticleCorrelations/Tasks/dptDptPerRunQc.cxx index 598d3305539..286641391ea 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/dptDptPerRunQc.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/dptDptPerRunQc.cxx @@ -13,29 +13,28 @@ /// \brief basic per run check of the ITS dead chips and of the hadronic interaction rate /// \author victor.gonzalez.sebastian@gmail.com -#include -#include -#include -#include -#include -#include +#include "PWGCF/DataModel/DptDptFiltered.h" +#include "PWGCF/TableProducer/dptDptFilter.h" -#include "CCDB/BasicCCDBManager.h" #include "Common/CCDB/ctpRateFetcher.h" -#include "DataFormatsParameters/AggregatedRunInfo.h" +#include "CCDB/BasicCCDBManager.h" #include "DataFormatsITSMFT/NoiseMap.h" // missing include in TimeDeadMap.h #include "DataFormatsITSMFT/TimeDeadMap.h" -#include "ITSMFTReconstruction/ChipMappingITS.h" - +#include "DataFormatsParameters/AggregatedRunInfo.h" +#include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" +#include "ITSMFTReconstruction/ChipMappingITS.h" -#include "PWGCF/DataModel/DptDptFiltered.h" -#include "PWGCF/TableProducer/dptDptFilter.h" +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; diff --git a/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx b/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx index 3dd5ec474de..814899e0261 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/lambdaR2Correlation.cxx @@ -19,6 +19,7 @@ #include "Common/DataModel/Centrality.h" #include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "CCDB/BasicCCDBManager.h" @@ -43,9 +44,11 @@ namespace o2::aod namespace lambdacollision { DECLARE_SOA_COLUMN(Cent, cent, float); -} +DECLARE_SOA_COLUMN(Mult, mult, float); +} // namespace lambdacollision DECLARE_SOA_TABLE(LambdaCollisions, "AOD", "LAMBDACOLS", o2::soa::Index<>, lambdacollision::Cent, + lambdacollision::Mult, aod::collision::PosX, aod::collision::PosY, aod::collision::PosZ); @@ -56,6 +59,7 @@ namespace lambdamcgencollision } DECLARE_SOA_TABLE(LambdaMcGenCollisions, "AOD", "LMCGENCOLS", o2::soa::Index<>, lambdacollision::Cent, + lambdacollision::Mult, o2::aod::mccollision::PosX, o2::aod::mccollision::PosY, o2::aod::mccollision::PosZ); @@ -172,6 +176,11 @@ enum TrackLabels { kGenLambdaToPrPi }; +enum CentEstType { + kCentFT0M = 0, + kCentFV0A +}; + enum RunType { kRun3 = 0, kRun2 @@ -229,6 +238,7 @@ struct LambdaTableProducer { Produces lambdaMCGenTrackTable; // Collisions + Configurable cCentEstimator{"cCentEstimator", 0, "Centrality Estimator : 0-FT0M, 1-FV0A"}; Configurable cMinZVtx{"cMinZVtx", -10.0, "Min VtxZ cut"}; Configurable cMaxZVtx{"cMaxZVtx", 10.0, "Max VtxZ cut"}; Configurable cMinMult{"cMinMult", 0., "Minumum Multiplicity"}; @@ -318,9 +328,8 @@ struct LambdaTableProducer { {"hPrimFracVsPtEtaCentLambda", "hPrimFracVsPtEtaCentAntiLambda"}}; // Initialize Global Variables - float cent = 0.; + float cent = 0., mult = 0.; float pt = 0., eta = 0., rap = 0., phi = 0.; - bool bSecondaryLambdaFlag = false; void init(InitContext const&) { @@ -412,9 +421,7 @@ struct LambdaTableProducer { // McReco Histos histos.add("Tracks/h2f_tracks_pid_before_sel", "PIDs", kTH2F, {axisPID, axisV0Pt}); histos.add("Tracks/h2f_tracks_pid_after_sel", "PIDs", kTH2F, {axisPID, axisV0Pt}); - histos.add("Tracks/h2f_lambda_from_sigma", "PIDs", kTH2F, {axisPID, axisV0Pt}); - histos.add("Tracks/h2f_lambda_from_cascade", "PIDs", kTH2F, {axisPID, axisV0Pt}); - histos.add("Tracks/h2f_lambda_from_omega", "PIDs", kTH2F, {axisPID, axisV0Pt}); + histos.add("Tracks/h2f_lambda_mothers_pdg", "PIDs", kTH2F, {axisPID, axisV0Pt}); // McGen Histos histos.add("McGen/h1f_collision_recgen", "# of Reco Collision Associated to One Mc Generator Collision", kTH1F, {axisMult}); @@ -481,7 +488,12 @@ struct LambdaTableProducer { } if constexpr (run == kRun3) { // Run3 Min-Bias Trigger - cent = col.centFT0M(); + // select centrality estimator + if (cCentEstimator == kCentFT0M) { + cent = col.centFT0M(); + } else if (cCentEstimator == kCentFV0A) { + cent = col.centFV0A(); + } if (cSel8Trig && !col.sel8()) { return false; } @@ -495,7 +507,7 @@ struct LambdaTableProducer { } } - if (cent <= cMinMult || cent >= cMaxMult) { // select centrality + if (cent <= cMinMult || cent >= cMaxMult) { // select centrality percentile class return false; } @@ -527,6 +539,9 @@ struct LambdaTableProducer { return false; } + // Set Multiplicity + mult = col.multNTracksPV(); + return true; } @@ -772,7 +787,6 @@ struct LambdaTableProducer { // check for secondary lambda if (!mcpart.isPhysicalPrimary()) { histos.fill(HIST("Tracks/h1f_tracks_info"), kSecondaryLambda); - bSecondaryLambdaFlag = true; return kSecondary; } @@ -817,18 +831,6 @@ struct LambdaTableProducer { } } - // get information about secondary lambdas - if (bSecondaryLambdaFlag) { - auto lambdaMothers = mcpart.template mothers_as(); - if (std::abs(lambdaMothers[0].pdgCode()) == kSigmaMinus || std::abs(lambdaMothers[0].pdgCode()) == kSigma0 || std::abs(lambdaMothers[0].pdgCode()) == kSigmaPlus) { - histos.fill(HIST("Tracks/h2f_lambda_from_sigma"), mcpart.pdgCode(), mcpart.pt()); - } else if (std::abs(lambdaMothers[0].pdgCode()) == kXiMinus || std::abs(lambdaMothers[0].pdgCode()) == kXi0) { - histos.fill(HIST("Tracks/h2f_lambda_from_cascade"), mcpart.pdgCode(), mcpart.pt()); - } else if (std::abs(lambdaMothers[0].pdgCode()) == kOmegaMinus) { - histos.fill(HIST("Tracks/h2f_lambda_from_omega"), mcpart.pdgCode(), mcpart.pt()); - } - } - return true; } @@ -893,6 +895,14 @@ struct LambdaTableProducer { return primFrac * effCorrFact; } + template + void fillLambdaMothers(V const& v0, T const&) + { + auto mcpart = v0.template mcParticle_as(); + auto lambdaMothers = mcpart.template mothers_as(); + histos.fill(HIST("Tracks/h2f_lambda_mothers_pdg"), lambdaMothers[0].pdgCode(), v0.pt()); + } + template void fillLambdaQAHistos(C const& col, V const& v0, T const&) { @@ -973,7 +983,7 @@ struct LambdaTableProducer { histos.fill(HIST("Events/h1f_collision_posZ"), collision.posZ()); // Fill Collision Table - lambdaCollisionTable(cent, collision.posX(), collision.posY(), collision.posZ()); + lambdaCollisionTable(cent, mult, collision.posX(), collision.posY(), collision.posZ()); // initialize v0track objects ParticleType v0Type = kLambda; @@ -1005,9 +1015,11 @@ struct LambdaTableProducer { // we have v0 as lambda histos.fill(HIST("Tracks/h1f_tracks_info"), kAllSelPassed); - // Remove lambda with ambiguous daughters - if (cRemoveAmbiguousTracks && hasAmbiguousDaughters(v0, tracks)) { - continue; + // Remove lambda with ambiguous daughters (Only for run3) + if constexpr (run == kRun3) { + if (cRemoveAmbiguousTracks && hasAmbiguousDaughters(v0, tracks)) { + continue; + } } // Get Lambda mass and kinematic variables @@ -1021,13 +1033,21 @@ struct LambdaTableProducer { if constexpr (dmc == kMC) { histos.fill(HIST("Tracks/h2f_tracks_pid_before_sel"), v0.mcParticle().pdgCode(), v0.pt()); - if (cSelMCPSV0) { // Get Primary/Secondary Lambda + // Get Primary/Secondary Lambda + if (cSelMCPSV0) { v0PrmScdType = isPrimaryV0(v0); } - if (cSelectTrueLambda && !selTrueMcRecLambda(v0, tracks)) { // check for true Lambda/Anti-Lambda + + // check for true Lambda/Anti-Lambda + if (cSelectTrueLambda && !selTrueMcRecLambda(v0, tracks)) { continue; } + // get mothers information + if (v0PrmScdType == kSecondary) { + fillLambdaMothers(v0, tracks); + } + histos.fill(HIST("Tracks/h1f_tracks_info"), kPassTrueLambdaSel); histos.fill(HIST("Tracks/h2f_tracks_pid_after_sel"), v0.mcParticle().pdgCode(), v0.pt()); @@ -1073,7 +1093,7 @@ struct LambdaTableProducer { void fillLambdaMcGenTables(C const& mcCollision, M const& mcParticles) { // Fill McGen Collision Table - lambdaMCGenCollisionTable(cent, mcCollision.posX(), mcCollision.posY(), mcCollision.posZ()); + lambdaMCGenCollisionTable(cent, mult, mcCollision.posX(), mcCollision.posY(), mcCollision.posZ()); // initialize track objects ParticleType v0Type = kLambda; @@ -1203,11 +1223,13 @@ struct LambdaTableProducer { SliceCache cache; Preslice> perCollision = aod::v0data::collisionId; - using CollisionsRun3 = soa::Join; - using CollisionsRun2 = soa::Join; + using CollisionsRun3 = soa::Join; + using CollisionsRun2 = soa::Join; using Tracks = soa::Join; - using McV0Tracks = soa::Join; + using TracksRun2 = soa::Join; using TracksMC = soa::Join; + using TracksMCRun2 = soa::Join; + using McV0Tracks = soa::Join; void processDataRun3(CollisionsRun3::iterator const& collision, aod::V0Datas const& V0s, Tracks const& tracks) { @@ -1216,7 +1238,7 @@ struct LambdaTableProducer { PROCESS_SWITCH(LambdaTableProducer, processDataRun3, "Process for Run3 DATA", true); - void processDataRun2(CollisionsRun2::iterator const& collision, aod::V0Datas const& V0s, Tracks const& tracks) + void processDataRun2(CollisionsRun2::iterator const& collision, aod::V0Datas const& V0s, TracksRun2 const& tracks) { fillLambdaRecoTables(collision, V0s, tracks); } @@ -1236,7 +1258,7 @@ struct LambdaTableProducer { PROCESS_SWITCH(LambdaTableProducer, processMCRecoRun3, "Process for Run3 McReco DATA", false); void processMCRecoRun2(soa::Join::iterator const& collision, aod::McCollisions const&, - McV0Tracks const& V0s, TracksMC const& tracks, aod::McParticles const&) + McV0Tracks const& V0s, TracksMCRun2 const& tracks, aod::McParticles const&) { // check collision if (!selCollision(collision)) { @@ -1259,7 +1281,7 @@ struct LambdaTableProducer { void processMCRun2(aod::McCollisions::iterator const& mcCollision, soa::SmallGroups> const& collisions, - McV0Tracks const& V0s, TracksMC const& tracks, + McV0Tracks const& V0s, TracksMCRun2 const& tracks, aod::McParticles const& mcParticles) { analyzeMcRecoGen(mcCollision, collisions, V0s, tracks, mcParticles); @@ -1483,6 +1505,7 @@ struct LambdaR2Correlation { const AxisSpec axisCheck(1, 0, 1, ""); const AxisSpec axisPosZ(220, -11, 11, "V_{z} (cm)"); const AxisSpec axisCent(cMultBins, "FT0M (%)"); + const AxisSpec axisChMult(200, 0, 200, "N_{ch}"); const AxisSpec axisMult(10, 0, 10, "N_{#Lambda}"); const AxisSpec axisMass(100, 1.06, 1.16, "M_{#Lambda} (GeV/#it{c}^{2})"); const AxisSpec axisPt(cNPtBins, cMinPt, cMaxPt, "p_{T} (GeV/#it{c})"); @@ -1496,8 +1519,9 @@ struct LambdaR2Correlation { // Event histos.add("Event/Reco/h1f_collision_posz", "V_{Z} Distribution", kTH1F, {axisPosZ}); histos.add("Event/Reco/h1f_ft0m_mult_percentile", "FT0M (%)", kTH1F, {axisCent}); - histos.add("Event/Reco/h1i_lambda_mult", "#Lambda - Multiplicity", kTH1I, {axisMult}); - histos.add("Event/Reco/h1i_antilambda_mult", "#bar{#Lambda} - Multiplicity", kTH1I, {axisMult}); + histos.add("Event/Reco/h2f_Mult_vs_Centrality", "N_{ch} vs FT0M(%)", kTH2F, {axisCent, axisChMult}); + histos.add("Event/Reco/h2f_lambda_mult", "#Lambda - Multiplicity", kTH2F, {axisCent, axisMult}); + histos.add("Event/Reco/h2f_antilambda_mult", "#bar{#Lambda} - Multiplicity", kTH2F, {axisCent, axisMult}); // Efficiency Histograms // Single Particle Efficiencies @@ -1510,6 +1534,8 @@ struct LambdaR2Correlation { // Single and Two Particle Densities // 1D Histograms + histos.add("Reco/Primary/h3f_n1_centmasspt_LaP", "#rho_{1}^{#Lambda}", kTH3F, {axisCent, axisMass, axisPt}); + histos.add("Reco/Primary/h3f_n1_centmasspt_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH3F, {axisCent, axisMass, axisPt}); histos.add("Reco/Primary/h2f_n1_pt_LaP", "#rho_{1}^{#Lambda}", kTH2F, {axisCent, axisPt}); histos.add("Reco/Primary/h2f_n1_pt_LaM", "#rho_{1}^{#bar{#Lambda}}", kTH2F, {axisCent, axisPt}); histos.add("Reco/Primary/h2f_n1_eta_LaP", "#rho_{1}^{#Lambda}", kTH2F, {axisCent, axisEta}); @@ -1622,6 +1648,7 @@ struct LambdaR2Correlation { histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("Efficiency/h3f_n1_centptrap_") + HIST(SubDirHist[part]), cent, track.pt(), track.rap()); // QA Plots + histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("h3f_n1_centmasspt_") + HIST(SubDirHist[part]), cent, track.mass(), track.pt()); histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("h2f_n1_pt_") + HIST(SubDirHist[part]), cent, track.pt(), track.corrFact()); histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("h2f_n1_eta_") + HIST(SubDirHist[part]), cent, track.eta(), track.corrFact()); histos.fill(HIST(SubDirRecGen[rec_gen]) + HIST(SubDirPrmScd[pst]) + HIST("h2f_n1_phi_") + HIST(SubDirHist[part]), cent, track.phi(), track.corrFact()); @@ -1637,9 +1664,9 @@ struct LambdaR2Correlation { // fill multiplicity histograms if (ntrk != 0) { if (part == kLambda) { - histos.fill(HIST("Event/") + HIST(SubDirRecGen[rec_gen]) + HIST("h1i_lambda_mult"), ntrk); + histos.fill(HIST("Event/") + HIST(SubDirRecGen[rec_gen]) + HIST("h2f_lambda_mult"), cent, ntrk); } else { - histos.fill(HIST("Event/") + HIST(SubDirRecGen[rec_gen]) + HIST("h1i_antilambda_mult"), ntrk); + histos.fill(HIST("Event/") + HIST(SubDirRecGen[rec_gen]) + HIST("h2f_antilambda_mult"), cent, ntrk); } } } @@ -1671,6 +1698,7 @@ struct LambdaR2Correlation { { histos.fill(HIST("Event/Reco/h1f_collision_posz"), collision.posZ()); histos.fill(HIST("Event/Reco/h1f_ft0m_mult_percentile"), collision.cent()); + histos.fill(HIST("Event/Reco/h2f_Mult_vs_Centrality"), collision.cent(), collision.mult()); cent = collision.cent(); @@ -1723,6 +1751,7 @@ struct LambdaR2Correlation { { histos.fill(HIST("Event/McGen/h1f_collision_posz"), mcgencol.posZ()); histos.fill(HIST("Event/McGen/h1f_ft0m_mult_percentile"), mcgencol.cent()); + histos.fill(HIST("Event/McGen/h2f_Mult_vs_Centrality"), mcgencol.cent(), mcgencol.mult()); cent = mcgencol.cent(); diff --git a/PWGCF/TwoParticleCorrelations/Tasks/longrangeCorrelation.cxx b/PWGCF/TwoParticleCorrelations/Tasks/longrangeCorrelation.cxx index 5fb1bc8e1c8..02cd3ac1d0a 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/longrangeCorrelation.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/longrangeCorrelation.cxx @@ -12,50 +12,54 @@ /// \file longrangeCorrelation.cxx /// /// \brief task for long range correlation analysis -/// \author Abhi Modak (abhi.modak@cern.ch) and Debojit sarkar (debojit.sarkar@cern.ch) +/// \author Abhi Modak (abhi.modak@cern.ch) and Debojit Sarkar (debojit.sarkar@cern.ch) /// \since April 22, 2025 -#include -#include -#include -#include -#include -#include -#include +#include "PWGCF/Core/CorrelationContainer.h" +#include "PWGCF/Core/PairCuts.h" +#include "PWGCF/DataModel/CorrelationsDerived.h" +#include "PWGMM/Mult/DataModel/bestCollisionTable.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/StepTHn.h" -#include "ReconstructionDataFormats/Track.h" -#include "Common/DataModel/PIDResponse.h" -#include "Common/DataModel/Multiplicity.h" +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" #include "Common/DataModel/Centrality.h" -#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" -#include "Common/Core/trackUtilities.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Common/Core/TrackSelection.h" -#include "Framework/ASoAHelpers.h" #include "Common/DataModel/FT0Corrected.h" -#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" #include "CommonConstants/MathConstants.h" +#include "CommonConstants/PhysicsConstants.h" +#include "DetectorsCommonDataFormats/AlignParam.h" #include "FT0Base/Geometry.h" #include "FV0Base/Geometry.h" -#include "PWGCF/DataModel/CorrelationsDerived.h" -#include "Common/DataModel/CollisionAssociationTables.h" -#include "PWGCF/Core/CorrelationContainer.h" -#include "PWGCF/Core/PairCuts.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" -#include "CCDB/CcdbApi.h" -#include "CCDB/BasicCCDBManager.h" -#include "DetectorsCommonDataFormats/AlignParam.h" +#include +#include +#include + +#include +#include +#include +#include using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::aod::track; +using namespace o2::aod::fwdtrack; using namespace o2::aod::evsel; using namespace o2::constants::math; @@ -71,9 +75,23 @@ static constexpr TrackSelectionFlags::flagtype TrackSelectionDca = static constexpr TrackSelectionFlags::flagtype TrackSelectionDcaxyOnly = TrackSelectionFlags::kDCAxy; +enum KindOfEvntType { + kSE, + kME +}; + +enum KindOfCorrType { + kFT0AGLOBAL, + kFT0CGLOBAL, + kFV0GLOBAL, + kMFTGLOBAL, + kFV0MFT +}; + +static constexpr std::string_view kCorrType[] = {"Ft0aGlobal/", "Ft0cGlobal/", "Fv0Global/", "MftGlobal/", "Fv0Mft/"}; +static constexpr std::string_view kEvntType[] = {"SE/", "ME/"}; + AxisSpec axisEvent{10, 0.5, 9.5, "#Event", "EventAxis"}; -AxisSpec amplitudeFT0{5000, 0, 10000, "FT0 amplitude"}; -AxisSpec channelFT0Axis{96, 0.0, 96.0, "FT0 channel"}; struct LongrangeCorrelation { @@ -86,6 +104,7 @@ struct LongrangeCorrelation { Service ccdb; o2::ccdb::CcdbApi ccdbApi; std::vector* offsetFT0; + std::vector* offsetFV0; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; Configurable cfgVtxCut{"cfgVtxCut", 10.0f, "Vertex Z range to consider"}; Configurable cfgEtaCut{"cfgEtaCut", 1.0f, "Eta range to consider"}; @@ -95,7 +114,14 @@ struct LongrangeCorrelation { Configurable mixingParameter{"mixingParameter", 5, "how many events are mixed"}; Configurable cfgMinMult{"cfgMinMult", 0, "Minimum multiplicity for collision"}; Configurable cfgMaxMult{"cfgMaxMult", 10, "Maximum multiplicity for collision"}; + Configurable cfigMftEtaMax{"cfigMftEtaMax", -2.5f, "Maximum MFT eta cut"}; + Configurable cfigMftEtaMin{"cfigMftEtaMin", -3.6f, "Minimum MFT eta cut"}; + Configurable cfigMftDcaxy{"cfigMftDcaxy", 2.0f, "cut on DCA xy for MFT tracks"}; + Configurable cfigMftCluster{"cfigMftCluster", 5, "cut on MFT Cluster"}; Configurable cfgSampleSize{"cfgSampleSize", 10, "Sample size for mixed event"}; + Configurable isApplySameBunchPileup{"isApplySameBunchPileup", false, "Enable SameBunchPileup cut"}; + Configurable isApplyGoodZvtxFT0vsPV{"isApplyGoodZvtxFT0vsPV", false, "Enable GoodZvtxFT0vsPV cut"}; + Configurable isReadoutCenter{"isReadoutCenter", false, "Enable Readout Center"}; ConfigurableAxis axisDeltaPhi{"axisDeltaPhi", {72, -PIHalf, PIHalf * 3}, "delta phi axis for histograms"}; ConfigurableAxis axisDeltaEta{"axisDeltaEta", {40, -6, -2}, "delta eta axis for histograms"}; ConfigurableAxis axisPtTrigger{"axisPtTrigger", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "pt trigger axis for histograms"}; @@ -111,13 +137,45 @@ struct LongrangeCorrelation { ConfigurableAxis axisEtaAssoc{"axisEtaAssoc", {96, 3.5, 4.9}, "#eta assoc axis"}; ConfigurableAxis axisSample{"axisSample", {cfgSampleSize, 0, cfgSampleSize}, "sample axis for histograms"}; ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 80, 100}, "multiplicity / centrality axis for histograms"}; + ConfigurableAxis amplitudeFt0a{"amplitudeFt0a", {5000, 0, 10000}, "FT0A amplitude"}; + ConfigurableAxis channelFt0aAxis{"channelFt0aAxis", {96, 0.0, 96.0}, "FT0A channel"}; using CollTable = soa::Join; using TrksTable = soa::Filtered>; - Preslice perCollision = aod::track::collisionId; - - OutputObj same{Form("sameEvent_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult))}; - OutputObj mixed{Form("mixedEvent_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult))}; + using MftTrkTable = soa::Filtered; + Preslice perColGlobal = aod::track::collisionId; + Preslice perColMft = aod::fwdtrack::collisionId; + + o2::ft0::Geometry ft0Det; + o2::fv0::Geometry* fv0Det; + + OutputObj sameFt0aGlobal{Form("sameEventFt0aGlobal_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult))}; + OutputObj mixedFt0aGlobal{Form("mixedEventFt0aGlobal_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult))}; + OutputObj sameFt0cGlobal{Form("sameEventFt0cGlobal_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult))}; + OutputObj mixedFt0cGlobal{Form("mixedEventFt0cGlobal_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult))}; + OutputObj sameMftGlobal{Form("sameEventMftGlobal_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult))}; + OutputObj mixedMftGlobal{Form("mixedEventMftGlobal_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult))}; + OutputObj sameFv0Global{Form("sameEventFv0Global_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult))}; + OutputObj mixedFv0Global{Form("mixedEventFv0Global_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult))}; + OutputObj sameFv0Mft{Form("sameEventFv0Mft_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult))}; + OutputObj mixedFv0Mft{Form("mixedEventFv0Mft_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult))}; + + template + void addHistos() + { + histos.add(Form("%s%shMult", kCorrType[corrType].data(), kEvntType[evntType].data()), "", kTH1D, {axisMultiplicity}); + histos.add(Form("%s%sTrig_etavsphi", kCorrType[corrType].data(), kEvntType[evntType].data()), "", kTH2D, {axisPhi, axisEtaTrig}); + histos.add(Form("%s%sTrig_eta", kCorrType[corrType].data(), kEvntType[evntType].data()), "", kTH1D, {axisEtaTrig}); + histos.add(Form("%s%sTrig_phi", kCorrType[corrType].data(), kEvntType[evntType].data()), "", kTH1D, {axisPhi}); + histos.add(Form("%s%sTrig_pt", kCorrType[corrType].data(), kEvntType[evntType].data()), "", kTH1D, {axisPtTrigger}); + histos.add(Form("%s%shMult_used", kCorrType[corrType].data(), kEvntType[evntType].data()), "", kTH1F, {axisMultiplicity}); + histos.add(Form("%s%sTrig_hist", kCorrType[corrType].data(), kEvntType[evntType].data()), "", kTHnSparseF, {axisSample, axisVtxZ, axisPtTrigger}); + histos.add(Form("%s%sAssoc_amp", kCorrType[corrType].data(), kEvntType[evntType].data()), "", kTH2D, {channelFt0aAxis, amplitudeFt0a}); + histos.add(Form("%s%sAssoc_eta", kCorrType[corrType].data(), kEvntType[evntType].data()), "", kTH1D, {axisEtaAssoc}); + histos.add(Form("%s%sAssoc_phi", kCorrType[corrType].data(), kEvntType[evntType].data()), "", kTH1D, {axisPhi}); + histos.add(Form("%s%sAssoc_etavsphi", kCorrType[corrType].data(), kEvntType[evntType].data()), "", kTH2D, {axisPhi, axisEtaAssoc}); + histos.add(Form("%s%sdeltaEta_deltaPhi", kCorrType[corrType].data(), kEvntType[evntType].data()), "", kTH2D, {axisDeltaPhi, axisDeltaEta}); + } void init(InitContext const&) { @@ -128,45 +186,11 @@ struct LongrangeCorrelation { ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); LOGF(info, "Getting alignment offsets from the CCDB..."); offsetFT0 = ccdb->getForTimeStamp>("FT0/Calib/Align", cfgCcdbParam.noLaterThan.value); + offsetFV0 = ccdb->getForTimeStamp>("FV0/Calib/Align", cfgCcdbParam.noLaterThan.value); LOGF(info, "Offset for FT0A: x = %.3f y = %.3f z = %.3f\n", (*offsetFT0)[0].getX(), (*offsetFT0)[0].getY(), (*offsetFT0)[0].getZ()); LOGF(info, "Offset for FT0C: x = %.3f y = %.3f z = %.3f\n", (*offsetFT0)[1].getX(), (*offsetFT0)[1].getY(), (*offsetFT0)[1].getZ()); - - // QA histos - histos.add("QA/EventHist", "events", kTH1F, {axisEvent}, false); - histos.add("QA/VtxZHist", "v_{z} (cm)", kTH1F, {axisVtxZ}, false); - histos.add("QA/hMEpvz1", ";pvz;Entries", kTH1F, {{30, -15, 15}}); - histos.add("QA/hMEpvz2", ";pvz;Entries", kTH1F, {{30, -15, 15}}); - histos.add("QA/hMixingQA", "events", kTH1F, {axisEvent}, false); - - auto hstat = histos.get(HIST("QA/EventHist")); - auto* x = hstat->GetXaxis(); - x->SetBinLabel(1, "All events"); - x->SetBinLabel(2, "sel8"); - x->SetBinLabel(3, "|vz|<10"); - - histos.add("SE/hMult", "event multiplicity", kTH1D, {axisMultiplicity}); - histos.add("SE/Trig_etavsphi", ";#eta;#phi", kTH2D, {axisPhi, axisEtaTrig}); - histos.add("SE/Trig_eta", "#eta", kTH1D, {axisEtaTrig}); - histos.add("SE/Trig_phi", "#eta", kTH1D, {axisPhi}); - histos.add("SE/Trig_pt", "p_{T}", kTH1D, {axisPtTrigger}); - histos.add("SE/hMult_used", "event multiplicity", kTH1F, {axisMultiplicity}); - histos.add("SE/Trig_hist", "trig hist", kTHnSparseF, {axisSample, axisVtxZ, axisPtTrigger}); - histos.add("SE/FT0Amp", "ftoamult", kTH2D, {channelFT0Axis, amplitudeFT0}); - histos.add("SE/FT0Aeta", "ft0a;#eta", kTH1D, {axisEtaAssoc}); - histos.add("SE/FT0Aphi", "ft0a;#phi", kTH1D, {axisPhi}); - histos.add("SE/FT0Aetavsphi", ";ft0a;#eta;#phi", kTH2D, {axisPhi, axisEtaAssoc}); - histos.add("SE/deltaEta_deltaPhi", ";#delta#eta;#delta#phi", kTH2D, {axisDeltaPhi, axisDeltaEta}); - - histos.add("ME/hMult", "event multiplicity", kTH1D, {axisMultiplicity}); - histos.add("ME/Trig_etavsphi", ";#eta;#phi", kTH2D, {axisPhi, axisEtaTrig}); - histos.add("ME/Trig_eta", "#eta", kTH1D, {axisEtaTrig}); - histos.add("ME/Trig_phi", "#eta", kTH1D, {axisPhi}); - histos.add("ME/Trig_pt", "p_{T}", kTH1D, {axisPtTrigger}); - histos.add("ME/FT0Amp", "ftoamult", kTH2D, {channelFT0Axis, amplitudeFT0}); - histos.add("ME/FT0Aeta", "ft0a;#eta", kTH1D, {axisEtaAssoc}); - histos.add("ME/FT0Aphi", "ft0a;#phi", kTH1D, {axisPhi}); - histos.add("ME/FT0Aetavsphi", ";ft0a;#eta;#phi", kTH2D, {axisPhi, axisEtaAssoc}); - histos.add("ME/deltaEta_deltaPhi", ";#delta#eta;#delta#phi", kTH2D, {axisDeltaPhi, axisDeltaEta}); + LOGF(info, "Offset for FV0-left: x = %.3f y = %.3f z = %.3f\n", (*offsetFV0)[0].getX(), (*offsetFV0)[0].getY(), (*offsetFV0)[0].getZ()); + LOGF(info, "Offset for FV0-right: x = %.3f y = %.3f z = %.3f\n", (*offsetFV0)[1].getX(), (*offsetFV0)[1].getY(), (*offsetFV0)[1].getZ()); std::vector corrAxis = {{axisSample, "Sample"}, {axisVtxZ, "z-vtx (cm)"}, @@ -180,145 +204,528 @@ struct LongrangeCorrelation { std::vector userAxis; - same.setObject(new CorrelationContainer(Form("sameEvent_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), Form("sameEvent_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), corrAxis, effAxis, userAxis)); - mixed.setObject(new CorrelationContainer(Form("mixedEvent_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), Form("mixedEvent_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), corrAxis, effAxis, userAxis)); + fv0Det = o2::fv0::Geometry::instance(o2::fv0::Geometry::eUninitialized); + + if (doprocessEventStat) { + histos.add("QA/EventHist", "events", kTH1F, {axisEvent}, false); + histos.add("QA/VtxZHist", "v_{z} (cm)", kTH1F, {axisVtxZ}, false); + + auto hstat = histos.get(HIST("QA/EventHist")); + auto* x = hstat->GetXaxis(); + x->SetBinLabel(1, "All events"); + x->SetBinLabel(2, "sel8"); + x->SetBinLabel(3, "kNoSameBunchPileup"); // reject collisions in case of pileup with another collision in the same foundBC + x->SetBinLabel(4, "kIsGoodZvtxFT0vsPV"); // small difference between z-vertex from PV and from FT0 + x->SetBinLabel(5, "|vz|<10"); + } + + if (doprocessFt0aGlobalSE || doprocessFt0aGlobalME) { + addHistos(); + addHistos(); + sameFt0aGlobal.setObject(new CorrelationContainer(Form("sameEventFt0aGlobal_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), Form("sameEventFt0aGlobal_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), corrAxis, effAxis, userAxis)); + mixedFt0aGlobal.setObject(new CorrelationContainer(Form("mixedEventFt0aGlobal_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), Form("mixedEventFt0aGlobal_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), corrAxis, effAxis, userAxis)); + } + + if (doprocessFt0cGlobalSE || doprocessFt0cGlobalME) { + addHistos(); + addHistos(); + sameFt0cGlobal.setObject(new CorrelationContainer(Form("sameEventFt0cGlobal_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), Form("sameEventFt0cGlobal_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), corrAxis, effAxis, userAxis)); + mixedFt0cGlobal.setObject(new CorrelationContainer(Form("mixedEventFt0cGlobal_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), Form("mixedEventFt0cGlobal_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), corrAxis, effAxis, userAxis)); + } + + if (doprocessFv0GlobalSE || doprocessFv0GlobalME) { + addHistos(); + addHistos(); + sameFv0Global.setObject(new CorrelationContainer(Form("sameEventFv0Global_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), Form("sameEventFv0Global_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), corrAxis, effAxis, userAxis)); + mixedFv0Global.setObject(new CorrelationContainer(Form("mixedEventFv0Global_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), Form("mixedEventFv0Global_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), corrAxis, effAxis, userAxis)); + } + + if (doprocessMftGlobalSE || doprocessMftGlobalME) { + addHistos(); + addHistos(); + sameMftGlobal.setObject(new CorrelationContainer(Form("sameEventMftGlobal_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), Form("sameEventMftGlobal_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), corrAxis, effAxis, userAxis)); + mixedMftGlobal.setObject(new CorrelationContainer(Form("mixedEventMftGlobal_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), Form("mixedEventMftGlobal_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), corrAxis, effAxis, userAxis)); + } + + if (doprocessFv0MftSE || doprocessFv0MftME) { + addHistos(); + addHistos(); + sameFv0Mft.setObject(new CorrelationContainer(Form("sameEventFv0Mft_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), Form("sameEventFv0Mft_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), corrAxis, effAxis, userAxis)); + mixedFv0Mft.setObject(new CorrelationContainer(Form("mixedEventFv0Mft_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), Form("mixedEventFv0Mft_%i_%i", static_cast(cfgMinMult), static_cast(cfgMaxMult)), corrAxis, effAxis, userAxis)); + } } - double getPhiFT0(int chno, double offsetX, double offsetY) + Filter fTrackSelectionITS = ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) && + ncheckbit(aod::track::trackCutFlag, TrackSelectionIts); + Filter fTrackSelectionTPC = ifnode(ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::TPC), + ncheckbit(aod::track::trackCutFlag, TrackSelectionTpc), true); + Filter fTrackSelectionDCA = ifnode(dcaZ.node() > 0.f, nabs(aod::track::dcaZ) <= dcaZ && ncheckbit(aod::track::trackCutFlag, TrackSelectionDcaxyOnly), + ncheckbit(aod::track::trackCutFlag, TrackSelectionDca)); + Filter fTracksEta = nabs(aod::track::eta) < cfgEtaCut; + Filter fTracksPt = (aod::track::pt > cfgPtCutMin) && (aod::track::pt < cfgPtCutMax); + + Filter fMftTrackEta = (aod::fwdtrack::eta < cfigMftEtaMax) && (aod::fwdtrack::eta > cfigMftEtaMin); + Filter fMftTrackColID = (aod::fwdtrack::bestCollisionId >= 0); + Filter fMftTrackDca = (nabs(aod::fwdtrack::bestDCAXY) < cfigMftDcaxy); + + double getPhiFT0(UInt_t chno, int i) { - o2::ft0::Geometry ft0Det; ft0Det.calculateChannelCenter(); auto chPos = ft0Det.getChannelCenter(chno); - return RecoDecay::phi(chPos.X() + offsetX, chPos.Y() + offsetY); + return RecoDecay::phi(chPos.X() + (*offsetFT0)[i].getX(), chPos.Y() + (*offsetFT0)[i].getY()); } - double getEtaFT0(int chno, double offsetX, double offsetY, double offsetZ) + double getPhiFV0(UInt_t chno) + { + int cellsInLeft[] = {0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27, 32, 40, 33, 41, 34, 42, 35, 43}; + bool isChnoInLeft = std::find(std::begin(cellsInLeft), std::end(cellsInLeft), chno) != std::end(cellsInLeft); + float offsetX, offsetY; + if (isChnoInLeft) { + offsetX = (*offsetFV0)[0].getX(); + offsetY = (*offsetFV0)[0].getY(); + } else { + offsetX = (*offsetFV0)[1].getX(); + offsetY = (*offsetFV0)[1].getY(); + } + + o2::fv0::Point3Dsimple chPos; + if (isReadoutCenter) + chPos = fv0Det->getReadoutCenter(chno); + else + chPos = fv0Det->getCellCenter(chno); + return RecoDecay::phi(chPos.x + offsetX, chPos.y + offsetY); + } + + double getEtaFT0(UInt_t chno, int i) { - o2::ft0::Geometry ft0Det; ft0Det.calculateChannelCenter(); auto chPos = ft0Det.getChannelCenter(chno); - auto x = chPos.X() + offsetX; - auto y = chPos.Y() + offsetY; - auto z = chPos.Z() + offsetZ; + auto x = chPos.X() + (*offsetFT0)[i].getX(); + auto y = chPos.Y() + (*offsetFT0)[i].getY(); + auto z = chPos.Z() + (*offsetFT0)[i].getZ(); auto r = std::sqrt(x * x + y * y); auto theta = std::atan2(r, z); return -std::log(std::tan(0.5 * theta)); } - Filter fTrackSelectionITS = ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) && - ncheckbit(aod::track::trackCutFlag, TrackSelectionIts); - Filter fTrackSelectionTPC = ifnode(ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::TPC), - ncheckbit(aod::track::trackCutFlag, TrackSelectionTpc), true); - Filter fTrackSelectionDCA = ifnode(dcaZ.node() > 0.f, nabs(aod::track::dcaZ) <= dcaZ && ncheckbit(aod::track::trackCutFlag, TrackSelectionDcaxyOnly), - ncheckbit(aod::track::trackCutFlag, TrackSelectionDca)); - Filter fTracksEta = nabs(aod::track::eta) < cfgEtaCut; - Filter fTracksPt = (aod::track::pt > cfgPtCutMin) && (aod::track::pt < cfgPtCutMax); + double getEtaFV0(UInt_t chno) + { + int cellsInLeft[] = {0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27, 32, 40, 33, 41, 34, 42, 35, 43}; + bool isChnoInLeft = std::find(std::begin(cellsInLeft), std::end(cellsInLeft), chno) != std::end(cellsInLeft); + float offsetX, offsetY, offsetZ; + if (isChnoInLeft) { + offsetX = (*offsetFV0)[0].getX(); + offsetY = (*offsetFV0)[0].getY(); + offsetZ = (*offsetFV0)[0].getZ(); + } else { + offsetX = (*offsetFV0)[1].getX(); + offsetY = (*offsetFV0)[1].getY(); + offsetZ = (*offsetFV0)[1].getZ(); + } + + o2::fv0::Point3Dsimple chPos; + if (isReadoutCenter) + chPos = fv0Det->getReadoutCenter(chno); + else + chPos = fv0Det->getCellCenter(chno); + + auto x = chPos.x + offsetX; + auto y = chPos.y + offsetY; + auto z = chPos.z + offsetZ; + auto r = std::sqrt(x * x + y * y); + auto theta = std::atan2(r, z); + return -std::log(std::tan(0.5 * theta)); + } template bool isEventSelected(CheckCol const& col) { - histos.fill(HIST("QA/EventHist"), 1); if (!col.sel8()) { return false; } - histos.fill(HIST("QA/EventHist"), 2); + if (isApplySameBunchPileup && !col.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + return false; + } + if (isApplyGoodZvtxFT0vsPV && !col.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + return false; + } if (std::abs(col.posZ()) >= cfgVtxCut) { return false; } - histos.fill(HIST("QA/EventHist"), 3); - histos.fill(HIST("QA/VtxZHist"), col.posZ()); return true; } - template - void fillYield(TTracks tracks, bool mixing) + template + bool isMftTrackSelected(CheckMftTrack const& track) { - if (mixing) { - histos.fill(HIST("ME/hMult"), tracks.size()); - for (auto const& triggerTrack : tracks) { - histos.fill(HIST("ME/Trig_etavsphi"), triggerTrack.phi(), triggerTrack.eta()); - histos.fill(HIST("ME/Trig_eta"), triggerTrack.eta()); - histos.fill(HIST("ME/Trig_phi"), triggerTrack.phi()); - histos.fill(HIST("ME/Trig_pt"), triggerTrack.pt()); + if (track.nClusters() < cfigMftCluster) { + return false; + } + return true; + } + + template + void fillYield(TTracks tracks) + { + if (evntType == 1) { + histos.fill(HIST(kCorrType[corrType]) + HIST(kEvntType[evntType]) + HIST("hMult"), tracks.size()); + for (auto const& iTrk : tracks) { + histos.fill(HIST(kCorrType[corrType]) + HIST(kEvntType[evntType]) + HIST("Trig_etavsphi"), iTrk.phi(), iTrk.eta()); + histos.fill(HIST(kCorrType[corrType]) + HIST(kEvntType[evntType]) + HIST("Trig_eta"), iTrk.eta()); + histos.fill(HIST(kCorrType[corrType]) + HIST(kEvntType[evntType]) + HIST("Trig_phi"), iTrk.phi()); + histos.fill(HIST(kCorrType[corrType]) + HIST(kEvntType[evntType]) + HIST("Trig_pt"), iTrk.pt()); } } else { - histos.fill(HIST("SE/hMult"), tracks.size()); - for (auto const& triggerTrack : tracks) { - histos.fill(HIST("SE/Trig_etavsphi"), triggerTrack.phi(), triggerTrack.eta()); - histos.fill(HIST("SE/Trig_eta"), triggerTrack.eta()); - histos.fill(HIST("SE/Trig_phi"), triggerTrack.phi()); - histos.fill(HIST("SE/Trig_pt"), triggerTrack.pt()); + histos.fill(HIST(kCorrType[corrType]) + HIST(kEvntType[evntType]) + HIST("hMult"), tracks.size()); + for (auto const& iTrk : tracks) { + histos.fill(HIST(kCorrType[corrType]) + HIST(kEvntType[evntType]) + HIST("Trig_etavsphi"), iTrk.phi(), iTrk.eta()); + histos.fill(HIST(kCorrType[corrType]) + HIST(kEvntType[evntType]) + HIST("Trig_eta"), iTrk.eta()); + histos.fill(HIST(kCorrType[corrType]) + HIST(kEvntType[evntType]) + HIST("Trig_phi"), iTrk.phi()); + histos.fill(HIST(kCorrType[corrType]) + HIST(kEvntType[evntType]) + HIST("Trig_pt"), iTrk.pt()); } } } template - void fillCorrelation(TTarget target, TTriggers const& triggers, TFT0s const& ft0, bool mixing, float vz) + void fillCorrFt0aGlobal(TTarget target, TTriggers const& triggers, TFT0s const& ft0, bool mixing, float vz) { int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); if (!mixing) - histos.fill(HIST("SE/hMult_used"), triggers.size()); + histos.fill(HIST("Ft0aGlobal/SE/hMult_used"), triggers.size()); for (auto const& triggerTrack : triggers) { if (!mixing) - histos.fill(HIST("SE/Trig_hist"), fSampleIndex, vz, triggerTrack.pt()); - - auto offsetFT0Ax = (*offsetFT0)[0].getX(); - auto offsetFT0Ay = (*offsetFT0)[0].getY(); - auto offsetFT0Az = (*offsetFT0)[0].getZ(); - for (std::size_t iChA = 0; iChA < ft0.channelA().size(); iChA++) { - auto chanelid = ft0.channelA()[iChA]; - float ampl = ft0.amplitudeA()[iChA]; - if (ampl <= 0) - continue; + histos.fill(HIST("Ft0aGlobal/SE/Trig_hist"), fSampleIndex, vz, triggerTrack.pt()); + + for (std::size_t iCh = 0; iCh < ft0.channelA().size(); iCh++) { + auto chanelid = ft0.channelA()[iCh]; + float ampl = ft0.amplitudeA()[iCh]; + if (mixing) - histos.fill(HIST("ME/FT0Amp"), chanelid, ampl); + histos.fill(HIST("Ft0aGlobal/ME/Assoc_amp"), chanelid, ampl); else - histos.fill(HIST("SE/FT0Amp"), chanelid, ampl); + histos.fill(HIST("Ft0aGlobal/SE/Assoc_amp"), chanelid, ampl); - auto phiA = getPhiFT0(chanelid, offsetFT0Ax, offsetFT0Ay); - auto etaA = getEtaFT0(chanelid, offsetFT0Ax, offsetFT0Ay, offsetFT0Az); + auto phi = getPhiFT0(chanelid, 0); + auto eta = getEtaFT0(chanelid, 0); if (mixing) { - histos.fill(HIST("ME/FT0Aeta"), etaA); - histos.fill(HIST("ME/FT0Aphi"), phiA); - histos.fill(HIST("ME/FT0Aetavsphi"), phiA, etaA); + histos.fill(HIST("Ft0aGlobal/ME/Assoc_eta"), eta); + histos.fill(HIST("Ft0aGlobal/ME/Assoc_phi"), phi); + histos.fill(HIST("Ft0aGlobal/ME/Assoc_etavsphi"), phi, eta); } else { - histos.fill(HIST("SE/FT0Aeta"), etaA); - histos.fill(HIST("SE/FT0Aphi"), phiA); - histos.fill(HIST("SE/FT0Aetavsphi"), phiA, etaA); + histos.fill(HIST("Ft0aGlobal/SE/Assoc_eta"), eta); + histos.fill(HIST("Ft0aGlobal/SE/Assoc_phi"), phi); + histos.fill(HIST("Ft0aGlobal/SE/Assoc_etavsphi"), phi, eta); } - float deltaPhi = RecoDecay::constrainAngle(triggerTrack.phi() - phiA, -PIHalf); - float deltaEta = triggerTrack.eta() - etaA; + float deltaPhi = RecoDecay::constrainAngle(triggerTrack.phi() - phi, -PIHalf); + float deltaEta = triggerTrack.eta() - eta; if (mixing) - histos.fill(HIST("ME/deltaEta_deltaPhi"), deltaPhi, deltaEta); + histos.fill(HIST("Ft0aGlobal/ME/deltaEta_deltaPhi"), deltaPhi, deltaEta); else - histos.fill(HIST("SE/deltaEta_deltaPhi"), deltaPhi, deltaEta); + histos.fill(HIST("Ft0aGlobal/SE/deltaEta_deltaPhi"), deltaPhi, deltaEta); target->getPairHist()->Fill(step, fSampleIndex, vz, triggerTrack.pt(), triggerTrack.pt(), deltaPhi, deltaEta); } // associated ft0 tracks } // trigger tracks - } // fillCorrelation + } // fillCorrFt0aGlobal - void processSE(CollTable::iterator const& col, aod::FT0s const&, TrksTable const& tracks) + template + void fillCorrFt0cGlobal(TTarget target, TTriggers const& triggers, TFT0s const& ft0, bool mixing, float vz) + { + int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); + if (!mixing) + histos.fill(HIST("Ft0cGlobal/SE/hMult_used"), triggers.size()); + for (auto const& triggerTrack : triggers) { + if (!mixing) + histos.fill(HIST("Ft0cGlobal/SE/Trig_hist"), fSampleIndex, vz, triggerTrack.pt()); + + for (std::size_t iCh = 0; iCh < ft0.channelC().size(); iCh++) { + auto chanelid = ft0.channelC()[iCh]; + float ampl = ft0.amplitudeC()[iCh]; + + if (mixing) + histos.fill(HIST("Ft0cGlobal/ME/Assoc_amp"), chanelid, ampl); + else + histos.fill(HIST("Ft0cGlobal/SE/Assoc_amp"), chanelid, ampl); + + auto phi = getPhiFT0(chanelid, 1); + auto eta = getEtaFT0(chanelid, 1); + + if (mixing) { + histos.fill(HIST("Ft0cGlobal/ME/Assoc_eta"), eta); + histos.fill(HIST("Ft0cGlobal/ME/Assoc_phi"), phi); + histos.fill(HIST("Ft0cGlobal/ME/Assoc_etavsphi"), phi, eta); + } else { + histos.fill(HIST("Ft0cGlobal/SE/Assoc_eta"), eta); + histos.fill(HIST("Ft0cGlobal/SE/Assoc_phi"), phi); + histos.fill(HIST("Ft0cGlobal/SE/Assoc_etavsphi"), phi, eta); + } + float deltaPhi = RecoDecay::constrainAngle(triggerTrack.phi() - phi, -PIHalf); + float deltaEta = triggerTrack.eta() - eta; + if (mixing) + histos.fill(HIST("Ft0cGlobal/ME/deltaEta_deltaPhi"), deltaPhi, deltaEta); + else + histos.fill(HIST("Ft0cGlobal/SE/deltaEta_deltaPhi"), deltaPhi, deltaEta); + target->getPairHist()->Fill(step, fSampleIndex, vz, triggerTrack.pt(), triggerTrack.pt(), deltaPhi, deltaEta); + } // associated ft0 tracks + } // trigger tracks + } // fillCorrFt0cGlobal + + template + void fillCorrMftGlobal(TTarget target, TTriggers const& triggers, TMFTs const& mft, bool mixing, float vz) + { + int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); + if (!mixing) + histos.fill(HIST("MftGlobal/SE/hMult_used"), triggers.size()); + for (auto const& triggerTrack : triggers) { + if (!mixing) + histos.fill(HIST("MftGlobal/SE/Trig_hist"), fSampleIndex, vz, triggerTrack.pt()); + + for (auto const& assoTrack : mft) { + if (!isMftTrackSelected(assoTrack)) { + continue; + } + auto phi = assoTrack.phi(); + o2::math_utils::bringTo02Pi(phi); + if (mixing) { + histos.fill(HIST("MftGlobal/ME/Assoc_eta"), assoTrack.eta()); + histos.fill(HIST("MftGlobal/ME/Assoc_phi"), phi); + histos.fill(HIST("MftGlobal/ME/Assoc_etavsphi"), phi, assoTrack.eta()); + } else { + histos.fill(HIST("MftGlobal/SE/Assoc_eta"), assoTrack.eta()); + histos.fill(HIST("MftGlobal/SE/Assoc_phi"), phi); + histos.fill(HIST("MftGlobal/SE/Assoc_etavsphi"), phi, assoTrack.eta()); + } + float deltaPhi = RecoDecay::constrainAngle(triggerTrack.phi() - phi, -PIHalf); + float deltaEta = triggerTrack.eta() - assoTrack.eta(); + if (mixing) + histos.fill(HIST("MftGlobal/ME/deltaEta_deltaPhi"), deltaPhi, deltaEta); + else + histos.fill(HIST("MftGlobal/SE/deltaEta_deltaPhi"), deltaPhi, deltaEta); + target->getPairHist()->Fill(step, fSampleIndex, vz, triggerTrack.pt(), assoTrack.pt(), deltaPhi, deltaEta); + } // associated mft tracks + } // trigger tracks + } // fillCorrMftGlobal + + template + void fillCorrFv0Global(TTarget target, TTriggers const& triggers, TFV0s const& fv0, bool mixing, float vz) + { + int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); + if (!mixing) + histos.fill(HIST("Fv0Global/SE/hMult_used"), triggers.size()); + for (auto const& triggerTrack : triggers) { + if (!mixing) + histos.fill(HIST("Fv0Global/SE/Trig_hist"), fSampleIndex, vz, triggerTrack.pt()); + + for (std::size_t iCh = 0; iCh < fv0.channel().size(); iCh++) { + auto chanelid = fv0.channel()[iCh]; + float ampl = fv0.amplitude()[iCh]; + + if (mixing) + histos.fill(HIST("Fv0Global/ME/Assoc_amp"), chanelid, ampl); + else + histos.fill(HIST("Fv0Global/SE/Assoc_amp"), chanelid, ampl); + + auto phi = getPhiFV0(chanelid); + auto eta = getEtaFV0(chanelid); + + if (mixing) { + histos.fill(HIST("Fv0Global/ME/Assoc_eta"), eta); + histos.fill(HIST("Fv0Global/ME/Assoc_phi"), phi); + histos.fill(HIST("Fv0Global/ME/Assoc_etavsphi"), phi, eta); + } else { + histos.fill(HIST("Fv0Global/SE/Assoc_eta"), eta); + histos.fill(HIST("Fv0Global/SE/Assoc_phi"), phi); + histos.fill(HIST("Fv0Global/SE/Assoc_etavsphi"), phi, eta); + } + float deltaPhi = RecoDecay::constrainAngle(triggerTrack.phi() - phi, -PIHalf); + float deltaEta = triggerTrack.eta() - eta; + if (mixing) + histos.fill(HIST("Fv0Global/ME/deltaEta_deltaPhi"), deltaPhi, deltaEta); + else + histos.fill(HIST("Fv0Global/SE/deltaEta_deltaPhi"), deltaPhi, deltaEta); + target->getPairHist()->Fill(step, fSampleIndex, vz, triggerTrack.pt(), triggerTrack.pt(), deltaPhi, deltaEta); + } // associated fv0 tracks + } // trigger tracks + } // fillCorrFv0Global + + template + void fillCorrFv0Mft(TTarget target, TTracks const& tracks, TTriggers const& triggers, TFV0s const& fv0, bool mixing, float vz) + { + int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); + if (!mixing) + histos.fill(HIST("Fv0Mft/SE/hMult_used"), tracks.size()); + for (auto const& triggerTrack : triggers) { + if (!isMftTrackSelected(triggerTrack)) { + continue; + } + if (!mixing) + histos.fill(HIST("Fv0Mft/SE/Trig_hist"), fSampleIndex, vz, triggerTrack.pt()); + + auto trigphi = triggerTrack.phi(); + o2::math_utils::bringTo02Pi(trigphi); + + for (std::size_t iCh = 0; iCh < fv0.channel().size(); iCh++) { + auto chanelid = fv0.channel()[iCh]; + float ampl = fv0.amplitude()[iCh]; + + if (mixing) + histos.fill(HIST("Fv0Mft/ME/Assoc_amp"), chanelid, ampl); + else + histos.fill(HIST("Fv0Mft/SE/Assoc_amp"), chanelid, ampl); + + auto phi = getPhiFV0(chanelid); + auto eta = getEtaFV0(chanelid); + + if (mixing) { + histos.fill(HIST("Fv0Mft/ME/Assoc_eta"), eta); + histos.fill(HIST("Fv0Mft/ME/Assoc_phi"), phi); + histos.fill(HIST("Fv0Mft/ME/Assoc_etavsphi"), phi, eta); + } else { + histos.fill(HIST("Fv0Mft/SE/Assoc_eta"), eta); + histos.fill(HIST("Fv0Mft/SE/Assoc_phi"), phi); + histos.fill(HIST("Fv0Mft/SE/Assoc_etavsphi"), phi, eta); + } + + float deltaPhi = RecoDecay::constrainAngle(trigphi - phi, -PIHalf); + float deltaEta = triggerTrack.eta() - eta; + if (mixing) + histos.fill(HIST("Fv0Mft/ME/deltaEta_deltaPhi"), deltaPhi, deltaEta); + else + histos.fill(HIST("Fv0Mft/SE/deltaEta_deltaPhi"), deltaPhi, deltaEta); + target->getPairHist()->Fill(step, fSampleIndex, vz, triggerTrack.pt(), triggerTrack.pt(), deltaPhi, deltaEta); + } // associated fv0 tracks + } // trigger tracks + } // fillCorrFv0Mft + + void processEventStat(CollTable::iterator const& col) + { + histos.fill(HIST("QA/EventHist"), 1); + if (!col.sel8()) { + return; + } + histos.fill(HIST("QA/EventHist"), 2); + if (isApplySameBunchPileup && !col.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + return; + } + histos.fill(HIST("QA/EventHist"), 3); + if (isApplyGoodZvtxFT0vsPV && !col.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + return; + } + histos.fill(HIST("QA/EventHist"), 4); + if (std::abs(col.posZ()) >= cfgVtxCut) { + return; + } + histos.fill(HIST("QA/EventHist"), 5); + histos.fill(HIST("QA/VtxZHist"), col.posZ()); + } + + void processFt0aGlobalSE(CollTable::iterator const& col, aod::FT0s const&, TrksTable const& tracks) + { + if (!isEventSelected(col)) { + return; + } + if (col.has_foundFT0()) { + fillYield(tracks); + const auto& ft0 = col.foundFT0(); + if (tracks.size() < cfgMinMult || tracks.size() >= cfgMaxMult) { + return; + } + fillCorrFt0aGlobal(sameFt0aGlobal, tracks, ft0, false, col.posZ()); + } + } // same event + + void processFt0cGlobalSE(CollTable::iterator const& col, aod::FT0s const&, TrksTable const& tracks) { if (!isEventSelected(col)) { return; } if (col.has_foundFT0()) { - fillYield(tracks, false); + fillYield(tracks); const auto& ft0 = col.foundFT0(); if (tracks.size() < cfgMinMult || tracks.size() >= cfgMaxMult) { return; } - fillCorrelation(same, tracks, ft0, false, col.posZ()); + fillCorrFt0cGlobal(sameFt0cGlobal, tracks, ft0, false, col.posZ()); + } + } // same event + + void processMftGlobalSE(CollTable::iterator const& col, MftTrkTable const& mfttracks, TrksTable const& tracks) + { + if (!isEventSelected(col)) { + return; + } + fillYield(tracks); + if (tracks.size() < cfgMinMult || tracks.size() >= cfgMaxMult) { + return; + } + fillCorrMftGlobal(sameMftGlobal, tracks, mfttracks, false, col.posZ()); + } // same event + + void processFv0GlobalSE(CollTable::iterator const& col, aod::FV0As const&, TrksTable const& tracks) + { + if (!isEventSelected(col)) { + return; + } + if (col.has_foundFV0()) { + fillYield(tracks); + const auto& fv0 = col.foundFV0(); + if (tracks.size() < cfgMinMult || tracks.size() >= cfgMaxMult) { + return; + } + fillCorrFv0Global(sameFv0Global, tracks, fv0, false, col.posZ()); + } + } // same event + + void processFv0MftSE(CollTable::iterator const& col, aod::FV0As const&, TrksTable const& tracks, MftTrkTable const& mfttracks) + { + if (!isEventSelected(col)) { + return; + } + if (col.has_foundFV0()) { + fillYield(mfttracks); + const auto& fv0 = col.foundFV0(); + if (tracks.size() < cfgMinMult || tracks.size() >= cfgMaxMult) { + return; + } + fillCorrFv0Mft(sameFv0Mft, tracks, mfttracks, fv0, false, col.posZ()); } } // same event - void processME(CollTable const& col, aod::FT0s const&, TrksTable const& tracks) + void processFt0aGlobalME(CollTable const& col, aod::FT0s const&, TrksTable const& tracks) + { + auto getTracksSize = [&tracks, this](CollTable::iterator const& collision) { + auto associatedTracks = tracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache); + return associatedTracks.size(); + }; + + using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; + MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxZME, axisMultME}, true}; + for (auto const& [col1, col2] : soa::selfCombinations(binningOnVtxAndMult, mixingParameter, -1, col, col)) { + if (!isEventSelected(col1) || !isEventSelected(col2)) { + continue; + } + if (col1.globalIndex() == col2.globalIndex()) { + continue; + } + if (col1.has_foundFT0() && col2.has_foundFT0()) { + auto slicedTriggerTracks = tracks.sliceBy(perColGlobal, col1.globalIndex()); + fillYield(slicedTriggerTracks); + const auto& ft0 = col2.foundFT0(); + if (slicedTriggerTracks.size() < cfgMinMult || slicedTriggerTracks.size() >= cfgMaxMult) { + continue; + } + fillCorrFt0aGlobal(mixedFt0aGlobal, slicedTriggerTracks, ft0, true, col1.posZ()); + } + } + } // mixed event + + void processFt0cGlobalME(CollTable const& col, aod::FT0s const&, TrksTable const& tracks) { auto getTracksSize = [&tracks, this](CollTable::iterator const& collision) { auto associatedTracks = tracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache); return associatedTracks.size(); }; + using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxZME, axisMultME}, true}; for (auto const& [col1, col2] : soa::selfCombinations(binningOnVtxAndMult, mixingParameter, -1, col, col)) { @@ -326,25 +733,110 @@ struct LongrangeCorrelation { continue; } if (col1.globalIndex() == col2.globalIndex()) { - histos.fill(HIST("QA/hMixingQA"), 1.0); // same-collision pair counting continue; } if (col1.has_foundFT0() && col2.has_foundFT0()) { - histos.fill(HIST("QA/hMEpvz1"), col1.posZ()); - histos.fill(HIST("QA/hMEpvz2"), col2.posZ()); - auto slicedTriggerTracks = tracks.sliceBy(perCollision, col1.globalIndex()); - fillYield(slicedTriggerTracks, true); + auto slicedTriggerTracks = tracks.sliceBy(perColGlobal, col1.globalIndex()); + fillYield(slicedTriggerTracks); const auto& ft0 = col2.foundFT0(); if (slicedTriggerTracks.size() < cfgMinMult || slicedTriggerTracks.size() >= cfgMaxMult) { continue; } - fillCorrelation(mixed, slicedTriggerTracks, ft0, true, col1.posZ()); + fillCorrFt0cGlobal(mixedFt0cGlobal, slicedTriggerTracks, ft0, true, col1.posZ()); + } + } + } // mixed event + + void processMftGlobalME(CollTable const& col, MftTrkTable const& mfttracks, TrksTable const& tracks) + { + auto getTracksSize = [&tracks, this](CollTable::iterator const& collision) { + auto associatedTracks = tracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache); + return associatedTracks.size(); + }; + + using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; + MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxZME, axisMultME}, true}; + auto tracksTuple = std::make_tuple(tracks, mfttracks); + Pair pairs{binningOnVtxAndMult, mixingParameter, -1, col, tracksTuple, &cache}; + for (auto const& [col1, tracks1, col2, tracks2] : pairs) { + if (!isEventSelected(col1) || !isEventSelected(col2)) { + continue; + } + if ((tracks1.size() < cfgMinMult || tracks1.size() >= cfgMaxMult)) { + continue; + } + fillCorrMftGlobal(mixedMftGlobal, tracks1, tracks2, true, col1.posZ()); + } + } // mixed event + + void processFv0GlobalME(CollTable const& col, aod::FV0As const&, TrksTable const& tracks) + { + auto getTracksSize = [&tracks, this](CollTable::iterator const& collision) { + auto associatedTracks = tracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache); + return associatedTracks.size(); + }; + + using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; + MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxZME, axisMultME}, true}; + for (auto const& [col1, col2] : soa::selfCombinations(binningOnVtxAndMult, mixingParameter, -1, col, col)) { + if (!isEventSelected(col1) || !isEventSelected(col2)) { + continue; + } + if (col1.globalIndex() == col2.globalIndex()) { + continue; + } + if (col1.has_foundFV0() && col2.has_foundFV0()) { + auto slicedTriggerTracks = tracks.sliceBy(perColGlobal, col1.globalIndex()); + fillYield(slicedTriggerTracks); + const auto& fv0 = col2.foundFV0(); + if (slicedTriggerTracks.size() < cfgMinMult || slicedTriggerTracks.size() >= cfgMaxMult) { + continue; + } + fillCorrFv0Global(mixedFv0Global, slicedTriggerTracks, fv0, true, col1.posZ()); + } + } + } // mixed event + + void processFv0MftME(CollTable const& col, aod::FV0As const&, TrksTable const& tracks, MftTrkTable const& mfttracks) + { + auto getTracksSize = [&tracks, this](CollTable::iterator const& collision) { + auto associatedTracks = tracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache); + return associatedTracks.size(); + }; + + using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; + MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxZME, axisMultME}, true}; + for (auto const& [col1, col2] : soa::selfCombinations(binningOnVtxAndMult, mixingParameter, -1, col, col)) { + if (!isEventSelected(col1) || !isEventSelected(col2)) { + continue; + } + if (col1.globalIndex() == col2.globalIndex()) { + continue; + } + if (col1.has_foundFV0() && col2.has_foundFV0()) { + auto slicedGlobalTracks = tracks.sliceBy(perColGlobal, col1.globalIndex()); + auto slicedTriggerMftTracks = mfttracks.sliceBy(perColMft, col1.globalIndex()); + fillYield(slicedTriggerMftTracks); + const auto& fv0 = col2.foundFV0(); + if (slicedGlobalTracks.size() < cfgMinMult || slicedGlobalTracks.size() >= cfgMaxMult) { + continue; + } + fillCorrFv0Mft(mixedFv0Mft, slicedGlobalTracks, slicedTriggerMftTracks, fv0, true, col1.posZ()); } } } // mixed event - PROCESS_SWITCH(LongrangeCorrelation, processSE, "process same event", false); - PROCESS_SWITCH(LongrangeCorrelation, processME, "process mixed event", false); + PROCESS_SWITCH(LongrangeCorrelation, processEventStat, "event stat", false); + PROCESS_SWITCH(LongrangeCorrelation, processFt0aGlobalSE, "same event FT0a vs global", false); + PROCESS_SWITCH(LongrangeCorrelation, processFt0aGlobalME, "mixed event FT0a vs global", false); + PROCESS_SWITCH(LongrangeCorrelation, processFt0cGlobalSE, "same event FT0c vs global", false); + PROCESS_SWITCH(LongrangeCorrelation, processFt0cGlobalME, "mixed event FT0c vs global", false); + PROCESS_SWITCH(LongrangeCorrelation, processMftGlobalSE, "same event MFT vs global", false); + PROCESS_SWITCH(LongrangeCorrelation, processMftGlobalME, "mixed event MFT vs global", false); + PROCESS_SWITCH(LongrangeCorrelation, processFv0GlobalSE, "same event FV0 vs global", false); + PROCESS_SWITCH(LongrangeCorrelation, processFv0GlobalME, "mixed event FV0 vs global", false); + PROCESS_SWITCH(LongrangeCorrelation, processFv0MftSE, "same event FV0 vs MFT", false); + PROCESS_SWITCH(LongrangeCorrelation, processFv0MftME, "mixed event FV0 vs MFT", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/TwoParticleCorrelations/Tasks/neutronProtonCorrZdc.cxx b/PWGCF/TwoParticleCorrelations/Tasks/neutronProtonCorrZdc.cxx index 1870c66da80..772d7c9d288 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/neutronProtonCorrZdc.cxx +++ b/PWGCF/TwoParticleCorrelations/Tasks/neutronProtonCorrZdc.cxx @@ -56,7 +56,10 @@ struct NeutronProtonCorrZdc { Configurable cfgZNmin{"cfgZNmin", -10, "Minimum value for ZN signal"}; Configurable cfgZNmax{"cfgZNmax", 350, "Maximum value for ZN signal"}; Configurable cfgZPmin{"cfgZPmin", -10, "Minimum value for ZP signal"}; - Configurable cfgZPmax{"cfgZPmax", 200, "Maximum value for ZP signal"}; + Configurable cfgZPmax{"cfgZPmax", 150, "Maximum value for ZP signal"}; + Configurable cfgAmplMin{"cfgAmplMin", -50, "Minimum value for sector amplitude"}; + Configurable cfgAmplMax{"cfgAmplMax", 300, "Maximum value for sector amplitude"}; + Configurable cfgNBinsAmpl{"cfgNBinsAmpl", 100, "Number of bins for sector amplitude histograms"}; Configurable cfgDiffZmin{"cfgDiffZmin", -30, "Minimum value for the diffZ signal"}; Configurable cfgDiffZmax{"cfgDiffZmax", 50, "Maximum value for the diffZ signal"}; Configurable cfgNBinsAlpha{"cfgNBinsAlpha", 100, "Number of bins for ZDC asymmetry"}; @@ -87,6 +90,9 @@ struct NeutronProtonCorrZdc { const AxisSpec axisZPCSignal{cfgNBinsZP, cfgZPmin, cfgZPmax, "ZPC (a.u.)"}; const AxisSpec axisZNSignal{2 * cfgNBinsZN, cfgZNmin, 1.5 * cfgZNmax, "ZN (a.u.)"}; const AxisSpec axisZPSignal{2 * cfgNBinsZP, cfgZPmin, 1.5 * cfgZPmax, "ZP (a.u.)"}; + const AxisSpec axisZNAmplitude{cfgNBinsAmpl, cfgAmplMin, cfgAmplMax, "Ampl (a.u.)"}; + const AxisSpec axisZPAmplitude{cfgNBinsAmpl, cfgAmplMin * 0.3, cfgAmplMax * 0.3, "Ampl (a.u.)"}; + const AxisSpec axisTotalAmplitude{cfgNBinsAmpl, 4.0 * cfgAmplMin, 4.0 * cfgAmplMax, "Ampl (a.u.)"}; const AxisSpec axisAlphaZ{cfgNBinsAlpha, cfgAlphaZmin, cfgAlphaZmax, "#alpha_{spec}"}; const AxisSpec axisZDiffSignal{cfgNBinsZN, cfgDiffZmin, cfgDiffZmax, "#Delta E"}; const AxisSpec axisMultiplicityF0A{cfgNBinsMultiplicity, 0, 200000, "F0A"}; @@ -99,6 +105,10 @@ struct NeutronProtonCorrZdc { HistogramConfigSpec defaultTimingHistogram({HistType::kTH2F, {cfgAxisCent, axisZDCTiming}}); HistogramConfigSpec defaultZNSectorHist({HistType::kTH2F, {cfgAxisCent, axisZNSectorSignal}}); HistogramConfigSpec defaultZPSectorHist({HistType::kTH2F, {cfgAxisCent, axisZPSectorSignal}}); + HistogramConfigSpec defaultZNAmplSectorHist({HistType::kTH2F, {cfgAxisCent, axisZNAmplitude}}); + HistogramConfigSpec defaultZPAmplSectorHist({HistType::kTH2F, {cfgAxisCent, axisZPAmplitude}}); + HistogramConfigSpec defaultEnergyZNAmplSectorHist({HistType::kTH2F, {axisZNSignal, axisZNAmplitude}}); + HistogramConfigSpec defaultEnergyZPAmplSectorHist({HistType::kTH2F, {axisZPSignal, axisZPAmplitude}}); HistogramConfigSpec defaultZDCDiffHist({HistType::kTH2F, {cfgAxisCent, axisZDiffSignal}}); // create histograms @@ -132,6 +142,13 @@ struct NeutronProtonCorrZdc { histos.add("ASide/CentvsdiffZNSignal", "CentvsdiffZNSignal", defaultZDCDiffHist); histos.add("ASide/CentvsdiffZPSignal", "CentvsdiffZPSignal", defaultZDCDiffHist); + histos.add("ASide/CentvsZNAmplitude", "CentvsZNAmplitude", defaultZNAmplSectorHist); + histos.add("ASide/CentvsZPAmplitude", "CentvsZPAmplitude", defaultZPAmplSectorHist); + histos.add("ASide/ZNSignalvsZNAmplitudeSum", "ZNSignalvsZNAmplitudeSum", defaultEnergyZNAmplSectorHist); + histos.add("ASide/ZNSignalvsZNAmplitudeCommon", "ZNSignalvsZNAmplitudeCommon", defaultEnergyZNAmplSectorHist); + histos.add("ASide/ZPSignalvsZPAmplitudeSum", "ZPSignalvsZPAmplitudeSum", defaultEnergyZPAmplSectorHist); + histos.add("ASide/ZPSignalvsZPAmplitudeCommon", "ZPSignalvsZPAmplitudeCommon", defaultEnergyZPAmplSectorHist); + // Cloning the folder histos.addClone("ASide/", "CSide/"); @@ -143,6 +160,8 @@ struct NeutronProtonCorrZdc { histos.add("CentvsAlphaZP", "CentvsAlphaZP", kTH2F, {cfgAxisCent, axisAlphaZ}); histos.add("CentvsAlphaZNcommon", "CentvsAlphaZNcommon", kTH2F, {cfgAxisCent, axisAlphaZ}); histos.add("CentvsAlphaZPcommon", "CentvsAlphaZPcommon", kTH2F, {cfgAxisCent, axisAlphaZ}); + histos.add("CentvsAlphaZNAmplitude", "CentvsAlphaZNAmplitude", kTH2F, {cfgAxisCent, axisAlphaZ}); + histos.add("CentvsAlphaZPAmplitude", "CentvsAlphaZPAmplitude", kTH2F, {cfgAxisCent, axisAlphaZ}); histos.add("CentvsDiffZNSignal", "CentvsDiffZNSignal", defaultZDCDiffHist); histos.add("CentvsDiffZPSignal", "CentvsDiffZPSignal", defaultZDCDiffHist); histos.add("CentvsZNAvsZNC", "CentvsZNAvsZNC", kTH3F, {cfgAxisCent, axisZNASignal, axisZNCSignal}); @@ -238,6 +257,8 @@ struct NeutronProtonCorrZdc { std::array, 2> zpEnergyResponse = {zdc.energySectorZPA(), zdc.energySectorZPC()}; std::array znEnergyResponseCommon = {zdc.energyCommonZNA(), zdc.energyCommonZNC()}; std::array zpEnergyResponseCommon = {zdc.energyCommonZPA(), zdc.energyCommonZPC()}; + std::array znAmplitudeResponse = {zdc.amplitudeZNA(), zdc.amplitudeZNC()}; + std::array zpAmplitudeResponse = {zdc.amplitudeZPA(), zdc.amplitudeZPC()}; float sumZN = znEnergyResponse[side][0] + znEnergyResponse[side][1] + znEnergyResponse[side][2] + znEnergyResponse[side][3]; float sumZP = zpEnergyResponse[side][0] + zpEnergyResponse[side][1] + zpEnergyResponse[side][2] + zpEnergyResponse[side][3]; @@ -248,6 +269,13 @@ struct NeutronProtonCorrZdc { histos.fill(HIST(SubDir[side]) + HIST("CentvsZPSignalSum"), centr, sumZP); histos.fill(HIST(SubDir[side]) + HIST("CentvsZPSignalCommon"), centr, zpEnergyResponseCommon[side]); histos.fill(HIST(SubDir[side]) + HIST("CentvsdiffZPSignal"), centr, sumZP - zpEnergyResponseCommon[side]); + histos.fill(HIST(SubDir[side]) + HIST("CentvsZNAmplitude"), centr, znAmplitudeResponse[side]); + histos.fill(HIST(SubDir[side]) + HIST("CentvsZPAmplitude"), centr, zpAmplitudeResponse[side]); + + histos.fill(HIST(SubDir[side]) + HIST("ZNSignalvsZNAmplitudeSum"), sumZN, znAmplitudeResponse[side]); + histos.fill(HIST(SubDir[side]) + HIST("ZNSignalvsZNAmplitudeCommon"), znEnergyResponseCommon[side], znAmplitudeResponse[side]); + histos.fill(HIST(SubDir[side]) + HIST("ZPSignalvsZPAmplitudeSum"), sumZP, zpAmplitudeResponse[side]); + histos.fill(HIST(SubDir[side]) + HIST("ZPSignalvsZPAmplitudeCommon"), zpEnergyResponseCommon[side], zpAmplitudeResponse[side]); } template @@ -332,6 +360,9 @@ struct NeutronProtonCorrZdc { float alphaZN = (sumZNA - sumZNC) / (sumZNA + sumZNC); float alphaZP = (sumZPA - sumZPC) / (sumZPA + sumZPC); + float alphaZNAmplitude = (zdcread.amplitudeZNA() - zdcread.amplitudeZNC()) / (zdcread.amplitudeZNA() + zdcread.amplitudeZNC()); + float alphaZPAmplitude = (zdcread.amplitudeZPA() - zdcread.amplitudeZPC()) / (zdcread.amplitudeZPA() + zdcread.amplitudeZPC()); + histos.fill(HIST("CentvsDiffZNSignal"), cent, (sumZNA + sumZNC) - (zdcread.energyCommonZNA() + zdcread.energyCommonZNC())); histos.fill(HIST("CentvsDiffZPSignal"), cent, (sumZPA + sumZPC) - (zdcread.energyCommonZPA() + zdcread.energyCommonZPC())); histos.fill(HIST("CentvsZNSignalSum"), cent, sumZNA + sumZNC); @@ -342,6 +373,8 @@ struct NeutronProtonCorrZdc { histos.fill(HIST("CentvsAlphaZP"), cent, alphaZP); histos.fill(HIST("CentvsAlphaZNcommon"), cent, (zdcread.energyCommonZNA() - zdcread.energyCommonZNC()) / (zdcread.energyCommonZNA() + zdcread.energyCommonZNC())); histos.fill(HIST("CentvsAlphaZPcommon"), cent, (zdcread.energyCommonZPA() - zdcread.energyCommonZPC()) / (zdcread.energyCommonZPA() + zdcread.energyCommonZPC())); + histos.fill(HIST("CentvsAlphaZNAmplitude"), cent, alphaZNAmplitude); + histos.fill(HIST("CentvsAlphaZPAmplitude"), cent, alphaZPAmplitude); histos.fill(HIST("CentvsZNAvsZNC"), cent, sumZNA, sumZNC); histos.fill(HIST("CentvsZNAvsZPA"), cent, sumZNA, sumZPA); diff --git a/PWGCF/TwoParticleCorrelations/Tasks/pidDiHadron.cxx b/PWGCF/TwoParticleCorrelations/Tasks/pidDiHadron.cxx new file mode 100644 index 00000000000..ac08c333121 --- /dev/null +++ b/PWGCF/TwoParticleCorrelations/Tasks/pidDiHadron.cxx @@ -0,0 +1,718 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file pidDiHadron.cxx +/// \brief di-hadron correlation of PID for O-O, Pb-Pb collisions +/// \author Preet Bhanjan Pati (preet.bhanjan.pati@cern.ch), Zhiyong Lu (zhiyong.lu@cern.ch) +/// \since July/29/2025 + +#include "PWGCF/Core/CorrelationContainer.h" +#include "PWGCF/Core/PairCuts.h" +#include "PWGCF/DataModel/CorrelationsDerived.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/PIDResponseITS.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CommonConstants/MathConstants.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/PID.h" +#include "ReconstructionDataFormats/Track.h" +#include + +#include "TF1.h" +#include "TRandom3.h" +#include + +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +// define the filtered collisions and tracks +#define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; + +struct PidDiHadron { + Service ccdb; + + O2_DEFINE_CONFIGURABLE(cfgCutVtxZ, float, 10.0f, "Accepted z-vertex range") + O2_DEFINE_CONFIGURABLE(cfgCutPtMin, float, 0.2f, "minimum accepted track pT") + O2_DEFINE_CONFIGURABLE(cfgCutPtMax, float, 10.0f, "maximum accepted track pT") + O2_DEFINE_CONFIGURABLE(cfgCutEta, float, 0.8f, "Eta cut") + O2_DEFINE_CONFIGURABLE(cfgCutChi2prTPCcls, float, 2.5f, "max chi2 per TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgCutTPCclu, float, 50.0f, "minimum TPC clusters") + O2_DEFINE_CONFIGURABLE(cfgCutTPCCrossedRows, float, 70.0f, "minimum TPC crossed rows") + O2_DEFINE_CONFIGURABLE(cfgCutITSclu, float, 5.0f, "minimum ITS clusters") + O2_DEFINE_CONFIGURABLE(cfgCutDCAz, float, 2.0f, "max DCA to vertex z") + O2_DEFINE_CONFIGURABLE(cfgCutMerging, float, 0.0, "Merging cut on track merge") + O2_DEFINE_CONFIGURABLE(cfgSelCollByNch, bool, true, "Select collisions by Nch or centrality") + O2_DEFINE_CONFIGURABLE(cfgCutMultMin, int, 0, "Minimum multiplicity for collision") + O2_DEFINE_CONFIGURABLE(cfgCutMultMax, int, 10, "Maximum multiplicity for collision") + O2_DEFINE_CONFIGURABLE(cfgCutCentMin, float, 60.0f, "Minimum centrality for collision") + O2_DEFINE_CONFIGURABLE(cfgCutCentMax, float, 80.0f, "Maximum centrality for collision") + O2_DEFINE_CONFIGURABLE(cfgMixEventNumMin, int, 5, "Minimum number of events to mix") + O2_DEFINE_CONFIGURABLE(cfgRadiusLow, float, 0.8, "Low radius for merging cut") + O2_DEFINE_CONFIGURABLE(cfgRadiusHigh, float, 2.5, "High radius for merging cut") + O2_DEFINE_CONFIGURABLE(cfgSampleSize, double, 10, "Sample size for mixed event") + O2_DEFINE_CONFIGURABLE(cfgCentEstimator, int, 0, "0:FT0C; 1:FT0CVariant1; 2:FT0M; 3:FT0A") + O2_DEFINE_CONFIGURABLE(cfgCentTableUnavailable, bool, false, "if a dataset does not provide centrality information") + O2_DEFINE_CONFIGURABLE(cfgUseAdditionalEventCut, bool, false, "Use additional event cut on mult correlations") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoSameBunchPileup, bool, false, "rejects collisions which are associated with the same found-by-T0 bunch crossing") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoITSROFrameBorder, bool, false, "reject events at ITS ROF border") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoTimeFrameBorder, bool, false, "reject events at TF border") + O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodZvtxFT0vsPV, bool, false, "removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference, use this cut at low multiplicities with caution") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoCollInTimeRangeStandard, bool, false, "no collisions in specified time range") + O2_DEFINE_CONFIGURABLE(cfgEvSelkIsGoodITSLayersAll, bool, true, "cut time intervals with dead ITS staves") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoCollInRofStandard, bool, false, "no other collisions in this Readout Frame with per-collision multiplicity above threshold") + O2_DEFINE_CONFIGURABLE(cfgEvSelkNoHighMultCollInPrevRof, bool, false, "veto an event if FT0C amplitude in previous ITS ROF is above threshold") + O2_DEFINE_CONFIGURABLE(cfgEvSelMultCorrelation, bool, true, "Multiplicity correlation cut") + O2_DEFINE_CONFIGURABLE(cfgEvSelV0AT0ACut, bool, true, "V0A T0A 5 sigma cut") + O2_DEFINE_CONFIGURABLE(cfgEvSelOccupancy, bool, true, "Occupancy cut") + O2_DEFINE_CONFIGURABLE(cfgCutOccupancyHigh, int, 2000, "High cut on TPC occupancy") + O2_DEFINE_CONFIGURABLE(cfgCutOccupancyLow, int, 0, "Low cut on TPC occupancy") + O2_DEFINE_CONFIGURABLE(cfgEfficiency, std::string, "", "CCDB path to efficiency object") + O2_DEFINE_CONFIGURABLE(cfgLocalEfficiency, bool, false, "Use local efficiency object") + O2_DEFINE_CONFIGURABLE(cfgVerbosity, bool, false, "Verbose output") + O2_DEFINE_CONFIGURABLE(cfgUseEventWeights, bool, false, "Use event weights for mixed event") + O2_DEFINE_CONFIGURABLE(cfgUsePtOrder, bool, false, "enable trigger pT < associated pT cut") + O2_DEFINE_CONFIGURABLE(cfgUsePtOrderInMixEvent, bool, false, "enable trigger pT < associated pT cut in mixed event") + O2_DEFINE_CONFIGURABLE(cfgPIDUseITSPID, bool, true, "Use ITS PID for particle identification") + O2_DEFINE_CONFIGURABLE(cfgPIDTofPtCut, float, 0.5f, "Minimum pt to use TOF N-sigma") + O2_DEFINE_CONFIGURABLE(cfgPIDParticle, int, 0, "1 = pion, 2 = kaon, 3 = proton, 0 for no PID") + + SliceCache cache; + + ConfigurableAxis axisVertex{"axisVertex", {10, -10, 10}, "vertex axis for histograms"}; + ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 10, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260}, "multiplicity axis for histograms"}; + ConfigurableAxis axisCentrality{"axisCentrality", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, "centrality axis for histograms"}; + ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.2, 0.5, 1, 1.5, 2, 3, 4, 6, 10}, "pt axis for histograms"}; + ConfigurableAxis axisDeltaPhi{"axisDeltaPhi", {72, -PIHalf, PIHalf * 3}, "delta phi axis for histograms"}; + ConfigurableAxis axisDeltaEta{"axisDeltaEta", {48, -2.4, 2.4}, "delta eta axis for histograms"}; + ConfigurableAxis axisPtTrigger{"axisPtTrigger", {VARIABLE_WIDTH, 0.2, 0.5, 1, 1.5, 2, 3, 4, 6, 10}, "pt trigger axis for histograms"}; + ConfigurableAxis axisPtAssoc{"axisPtAssoc", {VARIABLE_WIDTH, 0.2, 0.5, 1, 1.5, 2, 3, 4, 6, 10}, "pt associated axis for histograms"}; + ConfigurableAxis axisVtxMix{"axisVtxMix", {VARIABLE_WIDTH, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "vertex axis for mixed event histograms"}; + ConfigurableAxis axisMultMix{"axisMultMix", {VARIABLE_WIDTH, 0, 10, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260}, "multiplicity / centrality axis for mixed event histograms"}; + ConfigurableAxis axisSample{"axisSample", {cfgSampleSize, 0, cfgSampleSize}, "sample axis for histograms"}; + Configurable> pidTofNsigmaCut{"pidTofNsigmaCut", std::vector{1.5, 1.5, 1.5, -1.5, -1.5, -1.5}, "TOF n-sigma cut for pions_posNsigma, kaons_posNsigma, protons_posNsigma, pions_negNsigma, kaons_negNsigma, protons_negNsigma"}; + Configurable> pidItsNsigmaCut{"pidItsNsigmaCut", std::vector{3, 3, 3, -3, -3, -3}, "ITS n-sigma cut for pions_posNsigma, kaons_posNsigma, protons_posNsigma, pions_negNsigma, kaons_negNsigma, protons_negNsigma"}; + Configurable> pidTpcNsigmaCut{"pidTpcNsigmaCut", std::vector{10, 10, 10, -10, -10, -10}, "TOF n-sigma cut for pions_posNsigma, kaons_posNsigma, protons_posNsigma, pions_negNsigma, kaons_negNsigma, protons_negNsigma"}; + + ConfigurableAxis axisVertexEfficiency{"axisVertexEfficiency", {10, -10, 10}, "vertex axis for efficiency histograms"}; + ConfigurableAxis axisEtaEfficiency{"axisEtaEfficiency", {20, -1.0, 1.0}, "eta axis for efficiency histograms"}; + ConfigurableAxis axisPtEfficiency{"axisPtEfficiency", {VARIABLE_WIDTH, 0.2, 0.5, 1, 1.5, 2, 3, 4, 6, 10}, "pt axis for efficiency histograms"}; + + // make the filters and cuts. + Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVtxZ); + Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + using FilteredCollisions = soa::Filtered>; + using FilteredTracks = soa::Filtered>; + + Preslice perCollision = aod::track::collisionId; + + // Corrections + TH3D* mEfficiency = nullptr; + bool correctionsLoaded = false; + + // Define the outputs + OutputObj same{"sameEvent"}; + OutputObj mixed{"mixedEvent"}; + HistogramRegistry registry{"registry"}; + + // define global variables + TRandom3* gRandom = new TRandom3(); + enum CentEstimators { + kCentFT0C = 0, + kCentFT0CVariant1, + kCentFT0M, + kCentFV0A, + // Count the total number of enum + kCount_CentEstimators + }; + enum EventType { + SameEvent = 1, + MixedEvent = 3 + }; + std::vector tofNsigmaCut; + std::vector itsNsigmaCut; + std::vector tpcNsigmaCut; + o2::aod::ITSResponse itsResponse; + enum Particles { + PIONS, + KAONS, + PROTONS + }; + + // persistent caches + std::vector efficiencyAssociatedCache; + + TF1* fMultPVCutLow = nullptr; + TF1* fMultPVCutHigh = nullptr; + TF1* fMultCutLow = nullptr; + TF1* fMultCutHigh = nullptr; + TF1* fMultMultPVCut = nullptr; + TF1* fT0AV0AMean = nullptr; + TF1* fT0AV0ASigma = nullptr; + + void init(InitContext&) + { + if (cfgCentTableUnavailable && !cfgSelCollByNch) { + LOGF(fatal, "Centrality table is unavailable, cannot select collisions by centrality"); + } + const AxisSpec axisPhi{72, 0.0, constants::math::TwoPI, "#varphi"}; + const AxisSpec axisEta{40, -1., 1., "#eta"}; + + ccdb->setURL("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + auto now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + ccdb->setCreatedNotAfter(now); + + LOGF(info, "Starting init"); + + // Event Counter + if (doprocessSame && cfgUseAdditionalEventCut) { + registry.add("hEventCount", "Number of Event;; Count", {HistType::kTH1D, {{12, 0, 12}}}); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(1, "after sel8"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(2, "kNoSameBunchPileup"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(3, "kNoITSROFrameBorder"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(4, "kNoTimeFrameBorder"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(5, "kIsGoodZvtxFT0vsPV"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(6, "kNoCollInTimeRangeStandard"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(7, "kIsGoodITSLayersAll"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(8, "kNoCollInRofStandard"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(9, "kNoHighMultCollInPrevRof"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(10, "occupancy"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(11, "MultCorrelation"); + registry.get(HIST("hEventCount"))->GetXaxis()->SetBinLabel(12, "cfgEvSelV0AT0ACut"); + } + + if (cfgUseAdditionalEventCut) { + fMultPVCutLow = new TF1("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x - 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); + fMultPVCutLow->SetParameters(3257.29, -121.848, 1.98492, -0.0172128, 6.47528e-05, 154.756, -1.86072, -0.0274713, 0.000633499, -3.37757e-06); + fMultPVCutHigh = new TF1("fMultPVCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x + 3.5*([5]+[6]*x+[7]*x*x+[8]*x*x*x+[9]*x*x*x*x)", 0, 100); + fMultPVCutHigh->SetParameters(3257.29, -121.848, 1.98492, -0.0172128, 6.47528e-05, 154.756, -1.86072, -0.0274713, 0.000633499, -3.37757e-06); + + fMultCutLow = new TF1("fMultCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); + fMultCutLow->SetParameters(1654.46, -47.2379, 0.449833, -0.0014125, 150.773, -3.67334, 0.0530503, -0.000614061, 3.15956e-06); + fMultCutHigh = new TF1("fMultCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 3.*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); + fMultCutHigh->SetParameters(1654.46, -47.2379, 0.449833, -0.0014125, 150.773, -3.67334, 0.0530503, -0.000614061, 3.15956e-06); + + fT0AV0AMean = new TF1("fT0AV0AMean", "[0]+[1]*x", 0, 200000); + fT0AV0AMean->SetParameters(-1601.0581, 9.417652e-01); + fT0AV0ASigma = new TF1("fT0AV0ASigma", "[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x", 0, 200000); + fT0AV0ASigma->SetParameters(463.4144, 6.796509e-02, -9.097136e-07, 7.971088e-12, -2.600581e-17); + } + + std::string hCentTitle = "Centrality distribution, Estimator " + std::to_string(cfgCentEstimator); + // Make histograms to check the distributions after cuts + if (doprocessSame) { + registry.add("deltaEta_deltaPhi_same", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); // check to see the delta eta and delta phi distribution + registry.add("deltaEta_deltaPhi_mixed", "", {HistType::kTH2D, {axisDeltaPhi, axisDeltaEta}}); + registry.add("Phi", "Phi", {HistType::kTH1D, {axisPhi}}); + registry.add("Eta", "Eta", {HistType::kTH1D, {axisEta}}); + registry.add("EtaCorrected", "EtaCorrected", {HistType::kTH1D, {axisEta}}); + registry.add("pT", "pT", {HistType::kTH1D, {axisPtTrigger}}); + registry.add("pTCorrected", "pTCorrected", {HistType::kTH1D, {axisPtTrigger}}); + registry.add("Nch", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); + registry.add("Nch_used", "N_{ch}", {HistType::kTH1D, {axisMultiplicity}}); // histogram to see how many events are in the same and mixed event + registry.add("Centrality", hCentTitle.c_str(), {HistType::kTH1D, {axisCentrality}}); + registry.add("Centrality_used", hCentTitle.c_str(), {HistType::kTH1D, {axisCentrality}}); // histogram to see how many events are in the same and mixed event + registry.add("zVtx", "zVtx", {HistType::kTH1D, {axisVertex}}); + registry.add("zVtx_used", "zVtx_used", {HistType::kTH1D, {axisVertex}}); + registry.add("Trig_hist", "", {HistType::kTHnSparseF, {{axisSample, axisVertex, axisPtTrigger}}}); + } + + registry.add("eventcount", "bin", {HistType::kTH1F, {{4, 0, 4, "bin"}}}); // histogram to see how many events are in the same and mixed event + + LOGF(info, "Initializing correlation container"); + std::vector corrAxis = {{axisSample, "Sample"}, + {axisVertex, "z-vtx (cm)"}, + {axisPtTrigger, "p_{T} (GeV/c)"}, + {axisPtAssoc, "p_{T} (GeV/c)"}, + {axisDeltaPhi, "#Delta#varphi (rad)"}, + {axisDeltaEta, "#Delta#eta"}}; + std::vector effAxis = { + {axisEtaEfficiency, "#eta"}, + {axisPtEfficiency, "p_{T} (GeV/c)"}, + {axisVertexEfficiency, "z-vtx (cm)"}, + }; + std::vector userAxis; + + same.setObject(new CorrelationContainer("sameEvent", "sameEvent", corrAxis, effAxis, userAxis)); + mixed.setObject(new CorrelationContainer("mixedEvent", "mixedEvent", corrAxis, effAxis, userAxis)); + + tofNsigmaCut = pidTofNsigmaCut; + itsNsigmaCut = pidItsNsigmaCut; + tpcNsigmaCut = pidTpcNsigmaCut; + + LOGF(info, "End of init"); + } + + int getMagneticField(uint64_t timestamp) + { + // Get the magnetic field + static o2::parameters::GRPMagField* grpo = nullptr; + if (grpo == nullptr) { + grpo = ccdb->getForTimeStamp("/GLO/Config/GRPMagField", timestamp); + if (grpo == nullptr) { + LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); + return 0; + } + LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", timestamp, grpo->getNominalL3Field()); + } + return grpo->getNominalL3Field(); + } + + template + float getCentrality(TCollision const& collision) + { + float cent; + switch (cfgCentEstimator) { + case kCentFT0C: + cent = collision.centFT0C(); + break; + case kCentFT0CVariant1: + cent = collision.centFT0CVariant1(); + break; + case kCentFT0M: + cent = collision.centFT0M(); + break; + case kCentFV0A: + cent = collision.centFV0A(); + break; + default: + cent = collision.centFT0C(); + } + return cent; + } + + template + bool trackSelected(TTrack track) + { + return ((track.tpcNClsFound() >= cfgCutTPCclu) && (track.tpcNClsCrossedRows() >= cfgCutTPCCrossedRows) && (track.itsNCls() >= cfgCutITSclu)); + } + + void loadEfficiency(uint64_t timestamp) + { + if (correctionsLoaded) { + return; + } + if (cfgEfficiency.value.empty() == false) { + if (cfgLocalEfficiency > 0) { + TFile* fEfficiencyTrigger = TFile::Open(cfgEfficiency.value.c_str(), "READ"); + mEfficiency = reinterpret_cast(fEfficiencyTrigger->Get("ccdb_object")); + } else { + mEfficiency = ccdb->getForTimeStamp(cfgEfficiency, timestamp); + } + if (mEfficiency == nullptr) { + LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgEfficiency.value.c_str()); + } + LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgEfficiency.value.c_str(), (void*)mEfficiency); + } + correctionsLoaded = true; + } + + bool getEfficiencyCorrection(float& weight_nue, float eta, float pt, float posZ) + { + float eff = 1.; + if (mEfficiency) { + int etaBin = mEfficiency->GetXaxis()->FindBin(eta); + int ptBin = mEfficiency->GetYaxis()->FindBin(pt); + int zBin = mEfficiency->GetZaxis()->FindBin(posZ); + eff = mEfficiency->GetBinContent(etaBin, ptBin, zBin); + } else { + eff = 1.0; + } + if (eff == 0) + return false; + weight_nue = 1. / eff; + return true; + } + + // fill multiple histograms + template + void fillYield(TCollision collision, TTracks tracks) // function to fill the yield and etaphi histograms. + { + float weff1 = 1; + float vtxz = collision.posZ(); + for (auto const& track1 : tracks) { + if (!trackSelected(track1)) + continue; + if (cfgPIDParticle && getNsigmaPID(track1) != cfgPIDParticle) + continue; // if PID is selected, check if the track has the right PID + if (!getEfficiencyCorrection(weff1, track1.eta(), track1.pt(), vtxz)) + continue; + registry.fill(HIST("Phi"), RecoDecay::constrainAngle(track1.phi(), 0.0)); + registry.fill(HIST("Eta"), track1.eta()); + registry.fill(HIST("EtaCorrected"), track1.eta(), weff1); + registry.fill(HIST("pT"), track1.pt()); + registry.fill(HIST("pTCorrected"), track1.pt(), weff1); + } + } + + template + float getDPhiStar(TTrack const& track1, TTrackAssoc const& track2, float radius, int magField) + { + float charge1 = track1.sign(); + float charge2 = track2.sign(); + + float phi1 = track1.phi(); + float phi2 = track2.phi(); + + float pt1 = track1.pt(); + float pt2 = track2.pt(); + + int fbSign = (magField > 0) ? 1 : -1; + + float dPhiStar = phi1 - phi2 - charge1 * fbSign * std::asin(0.075 * radius / pt1) + charge2 * fbSign * std::asin(0.075 * radius / pt2); + + if (dPhiStar > constants::math::PI) + dPhiStar = constants::math::TwoPI - dPhiStar; + if (dPhiStar < -constants::math::PI) + dPhiStar = -constants::math::TwoPI - dPhiStar; + + return dPhiStar; + } + + template + void fillCorrelations(TTracks tracks1, TTracksAssoc tracks2, float posZ, int system, int magneticField, float cent, float eventWeight) // function to fill the Output functions (sparse) and the delta eta and delta phi histograms + { + // Cache efficiency for particles (too many FindBin lookups) + if (mEfficiency) { + efficiencyAssociatedCache.clear(); + efficiencyAssociatedCache.reserve(tracks2.size()); + for (const auto& track2 : tracks2) { + float weff = 1.; + getEfficiencyCorrection(weff, track2.eta(), track2.pt(), posZ); + efficiencyAssociatedCache.push_back(weff); + } + } + + if (system == SameEvent) { + if (!cfgCentTableUnavailable) + registry.fill(HIST("Centrality_used"), cent); + registry.fill(HIST("Nch_used"), tracks1.size()); + } + + int fSampleIndex = gRandom->Uniform(0, cfgSampleSize); + + float triggerWeight = 1.0f; + float associatedWeight = 1.0f; + // loop over all tracks + for (auto const& track1 : tracks1) { + + if (!trackSelected(track1)) + continue; + if (cfgPIDParticle && getNsigmaPID(track1) != cfgPIDParticle) + continue; // if PID is selected, check if the track has the right PID + if (!getEfficiencyCorrection(triggerWeight, track1.eta(), track1.pt(), posZ)) + continue; + if (system == SameEvent) { + registry.fill(HIST("Trig_hist"), fSampleIndex, posZ, track1.pt(), eventWeight * triggerWeight); + } + + for (auto const& track2 : tracks2) { + + if (!trackSelected(track2)) + continue; + if (mEfficiency) { + associatedWeight = efficiencyAssociatedCache[track2.filteredIndex()]; + } + + if (!cfgUsePtOrder && track1.globalIndex() == track2.globalIndex()) + continue; // For pt-differential correlations, skip if the trigger and associate are the same track + if (cfgUsePtOrder && system == SameEvent && track1.pt() <= track2.pt()) + continue; // Without pt-differential correlations, skip if the trigger pt is less than the associate pt + if (cfgUsePtOrder && system == MixedEvent && cfgUsePtOrderInMixEvent && track1.pt() <= track2.pt()) + continue; // For pt-differential correlations in mixed events, skip if the trigger pt is less than the associate pt + + float deltaPhi = RecoDecay::constrainAngle(track1.phi() - track2.phi(), -PIHalf); + float deltaEta = track1.eta() - track2.eta(); + + if (std::abs(deltaEta) < cfgCutMerging) { + + double dPhiStarHigh = getDPhiStar(track1, track2, cfgRadiusHigh, magneticField); + double dPhiStarLow = getDPhiStar(track1, track2, cfgRadiusLow, magneticField); + + const double kLimit = 3.0 * cfgCutMerging; + + bool bIsBelow = false; + + if (std::abs(dPhiStarLow) < kLimit || std::abs(dPhiStarHigh) < kLimit || dPhiStarLow * dPhiStarHigh < 0) { + for (double rad(cfgRadiusLow); rad < cfgRadiusHigh; rad += 0.01) { + double dPhiStar = getDPhiStar(track1, track2, rad, magneticField); + if (std::abs(dPhiStar) < kLimit) { + bIsBelow = true; + break; + } + } + if (bIsBelow) + continue; + } + } + + // fill the right sparse and histograms + if (system == SameEvent) { + + same->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + registry.fill(HIST("deltaEta_deltaPhi_same"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + } else if (system == MixedEvent) { + + mixed->getPairHist()->Fill(step, fSampleIndex, posZ, track1.pt(), track2.pt(), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + registry.fill(HIST("deltaEta_deltaPhi_mixed"), deltaPhi, deltaEta, eventWeight * triggerWeight * associatedWeight); + } + } + } + } + + template + bool eventSelected(TCollision collision, const int multTrk, const float centrality, const bool fillCounter) + { + registry.fill(HIST("hEventCount"), 0.5); + if (cfgEvSelkNoSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + // rejects collisions which are associated with the same "found-by-T0" bunch crossing + // https://indico.cern.ch/event/1396220/#1-event-selection-with-its-rof + return 0; + } + if (fillCounter && cfgEvSelkNoSameBunchPileup) + registry.fill(HIST("hEventCount"), 1.5); + if (cfgEvSelkNoITSROFrameBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { + return 0; + } + if (fillCounter && cfgEvSelkNoITSROFrameBorder) + registry.fill(HIST("hEventCount"), 2.5); + if (cfgEvSelkNoTimeFrameBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { + return 0; + } + if (fillCounter && cfgEvSelkNoTimeFrameBorder) + registry.fill(HIST("hEventCount"), 3.5); + if (cfgEvSelkIsGoodZvtxFT0vsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + // removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference + // use this cut at low multiplicities with caution + return 0; + } + if (fillCounter && cfgEvSelkIsGoodZvtxFT0vsPV) + registry.fill(HIST("hEventCount"), 4.5); + if (cfgEvSelkNoCollInTimeRangeStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + // no collisions in specified time range + return 0; + } + if (fillCounter && cfgEvSelkNoCollInTimeRangeStandard) + registry.fill(HIST("hEventCount"), 5.5); + if (cfgEvSelkIsGoodITSLayersAll && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + // from Jan 9 2025 AOT meeting + // cut time intervals with dead ITS staves + return 0; + } + if (fillCounter && cfgEvSelkIsGoodITSLayersAll) + registry.fill(HIST("hEventCount"), 6.5); + if (cfgEvSelkNoCollInRofStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { + // no other collisions in this Readout Frame with per-collision multiplicity above threshold + return 0; + } + if (fillCounter && cfgEvSelkNoCollInRofStandard) + registry.fill(HIST("hEventCount"), 7.5); + if (cfgEvSelkNoHighMultCollInPrevRof && !collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { + // veto an event if FT0C amplitude in previous ITS ROF is above threshold + return 0; + } + if (fillCounter && cfgEvSelkNoHighMultCollInPrevRof) + registry.fill(HIST("hEventCount"), 8.5); + auto occupancy = collision.trackOccupancyInTimeRange(); + if (cfgEvSelOccupancy && (occupancy < cfgCutOccupancyLow || occupancy > cfgCutOccupancyHigh)) + return 0; + if (fillCounter && cfgEvSelOccupancy) + registry.fill(HIST("hEventCount"), 9.5); + + auto multNTracksPV = collision.multNTracksPV(); + if (cfgEvSelMultCorrelation) { + if (multNTracksPV < fMultPVCutLow->Eval(centrality)) + return 0; + if (multNTracksPV > fMultPVCutHigh->Eval(centrality)) + return 0; + if (multTrk < fMultCutLow->Eval(centrality)) + return 0; + if (multTrk > fMultCutHigh->Eval(centrality)) + return 0; + } + if (fillCounter && cfgEvSelMultCorrelation) + registry.fill(HIST("hEventCount"), 10.5); + + // V0A T0A 5 sigma cut + float sigma = 5.0; + if (cfgEvSelV0AT0ACut && (std::fabs(collision.multFV0A() - fT0AV0AMean->Eval(collision.multFT0A())) > sigma * fT0AV0ASigma->Eval(collision.multFT0A()))) + return 0; + if (fillCounter && cfgEvSelV0AT0ACut) + registry.fill(HIST("hEventCount"), 11.5); + + return 1; + } + + void processSame(FilteredCollisions::iterator const& collision, FilteredTracks const& tracks, aod::BCsWithTimestamps const&) + { + if (!collision.sel8()) + return; + auto bc = collision.bc_as(); + float cent = -1.; + if (!cfgCentTableUnavailable) + cent = getCentrality(collision); + if (cfgUseAdditionalEventCut && !eventSelected(collision, tracks.size(), cent, true)) + return; + + if (!cfgCentTableUnavailable) + registry.fill(HIST("Centrality"), cent); + registry.fill(HIST("Nch"), tracks.size()); + registry.fill(HIST("zVtx"), collision.posZ()); + + if (cfgSelCollByNch && (tracks.size() < cfgCutMultMin || tracks.size() >= cfgCutMultMax)) { + return; + } + if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent < cfgCutCentMin || cent >= cfgCutCentMax)) { + return; + } + + loadEfficiency(bc.timestamp()); + registry.fill(HIST("eventcount"), SameEvent); // because its same event i put it in the 1 bin + fillYield(collision, tracks); + + same->fillEvent(tracks.size(), CorrelationContainer::kCFStepReconstructed); + fillCorrelations(tracks, tracks, collision.posZ(), SameEvent, getMagneticField(bc.timestamp()), cent, 1.0f); + } + PROCESS_SWITCH(PidDiHadron, processSame, "Process same event", true); + + // the process for filling the mixed events + void processMixed(FilteredCollisions const& collisions, FilteredTracks const& tracks, aod::BCsWithTimestamps const&) + { + + auto getTracksSize = [&tracks, this](FilteredCollisions::iterator const& collision) { + auto associatedTracks = tracks.sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), this->cache); + auto mult = associatedTracks.size(); + return mult; + }; + + using MixedBinning = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getTracksSize)>; + + MixedBinning binningOnVtxAndMult{{getTracksSize}, {axisVtxMix, axisMultMix}, true}; + + auto tracksTuple = std::make_tuple(tracks, tracks); + Pair pairs{binningOnVtxAndMult, cfgMixEventNumMin, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto it = pairs.begin(); it != pairs.end(); it++) { + auto& [collision1, tracks1, collision2, tracks2] = *it; + if (!collision1.sel8() || !collision2.sel8()) + continue; + + if (cfgSelCollByNch && (tracks1.size() < cfgCutMultMin || tracks1.size() >= cfgCutMultMax)) + continue; + + if (cfgSelCollByNch && (tracks2.size() < cfgCutMultMin || tracks2.size() >= cfgCutMultMax)) + continue; + + float cent1 = -1; + float cent2 = -1; + if (!cfgCentTableUnavailable) { + cent1 = getCentrality(collision1); + cent2 = getCentrality(collision2); + } + if (cfgUseAdditionalEventCut && !eventSelected(collision1, tracks1.size(), cent1, false)) + continue; + if (cfgUseAdditionalEventCut && !eventSelected(collision2, tracks2.size(), cent2, false)) + continue; + + if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent1 < cfgCutCentMin || cent1 >= cfgCutCentMax)) + continue; + + if (!cfgSelCollByNch && !cfgCentTableUnavailable && (cent2 < cfgCutCentMin || cent2 >= cfgCutCentMax)) + continue; + + registry.fill(HIST("eventcount"), MixedEvent); // fill the mixed event in the 3 bin + auto bc = collision1.bc_as(); + loadEfficiency(bc.timestamp()); + float eventWeight = 1.0f; + if (cfgUseEventWeights) { + eventWeight = 1.0f / it.currentWindowNeighbours(); + } + + fillCorrelations(tracks1, tracks2, collision1.posZ(), MixedEvent, getMagneticField(bc.timestamp()), cent1, eventWeight); + } + } + PROCESS_SWITCH(PidDiHadron, processMixed, "Process mixed events", true); + + template + int getNsigmaPID(TTrack track) + { + // Computing Nsigma arrays for pion, kaon, and protons + std::array nSigmaTPC = {track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr()}; + std::array nSigmaTOF = {track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr()}; + std::array nSigmaITS = {itsResponse.nSigmaITS(track), itsResponse.nSigmaITS(track), itsResponse.nSigmaITS(track)}; + int pid = -1; + + std::array nSigmaToUse = cfgPIDUseITSPID ? nSigmaITS : nSigmaTPC; // Choose which nSigma to use: TPC or ITS + std::vector detectorNsigmaCut = cfgPIDUseITSPID ? itsNsigmaCut : tpcNsigmaCut; // Choose which nSigma to use: TPC or ITS + + bool isPion, isKaon, isProton; + bool isDetectedPion = nSigmaToUse[0] < detectorNsigmaCut[0] && nSigmaToUse[0] > detectorNsigmaCut[0 + 3]; + bool isDetectedKaon = nSigmaToUse[1] < detectorNsigmaCut[1] && nSigmaToUse[1] > detectorNsigmaCut[1 + 3]; + bool isDetectedProton = nSigmaToUse[2] < detectorNsigmaCut[2] && nSigmaToUse[2] > detectorNsigmaCut[2 + 3]; + + bool isTofPion = nSigmaTOF[0] < tofNsigmaCut[0] && nSigmaTOF[0] > tofNsigmaCut[0 + 3]; + bool isTofKaon = nSigmaTOF[1] < tofNsigmaCut[1] && nSigmaTOF[1] > tofNsigmaCut[1 + 3]; + bool isTofProton = nSigmaTOF[2] < tofNsigmaCut[2] && nSigmaTOF[2] > tofNsigmaCut[2 + 3]; + + if (track.pt() > cfgPIDTofPtCut && !track.hasTOF()) { + return 0; + } else if (track.pt() > cfgPIDTofPtCut && track.hasTOF()) { + isPion = isTofPion && isDetectedPion; + isKaon = isTofKaon && isDetectedKaon; + isProton = isTofProton && isDetectedProton; + } else { + isPion = isDetectedPion; + isKaon = isDetectedKaon; + isProton = isDetectedProton; + } + + if ((isPion && isKaon) || (isPion && isProton) || (isKaon && isProton)) { + return 0; // more than one particle satisfy the criteria + } + + if (isPion) { + pid = PIONS; + } else if (isKaon) { + pid = KAONS; + } else if (isProton) { + pid = PROTONS; + } else { + return 0; // no particle satisfies the criteria + } + + return pid + 1; // shift the pid by 1, 1 = pion, 2 = kaon, 3 = proton + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + }; +} diff --git a/PWGDQ/Core/CMakeLists.txt b/PWGDQ/Core/CMakeLists.txt index d19a66a68e6..41ceb661bf9 100644 --- a/PWGDQ/Core/CMakeLists.txt +++ b/PWGDQ/Core/CMakeLists.txt @@ -21,7 +21,7 @@ o2physics_add_library(PWGDQCore AnalysisCompositeCut.cxx MCProng.cxx MCSignal.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2::DCAFitter O2::GlobalTracking O2Physics::AnalysisCore KFParticle::KFParticle) + PUBLIC_LINK_LIBRARIES O2::Framework O2::DCAFitter O2::GlobalTracking O2Physics::AnalysisCore KFParticle::KFParticle O2Physics::MLCore) o2physics_target_root_dictionary(PWGDQCore HEADERS AnalysisCut.h diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index 5cf99d6f22f..20a4c7c548f 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -12,14 +12,19 @@ // Contact: iarsene@cern.ch, i.c.arsene@fys.uio.no // #include "PWGDQ/Core/CutsLibrary.h" -#include -#include -#include -#include -#include + #include "AnalysisCompositeCut.h" #include "VarManager.h" +#include + +#include + +#include +#include +#include +#include + using std::cout; using std::endl; @@ -3948,6 +3953,17 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } + if (!nameStr.compare("eventStandardSel8ppQualityNoVtxZ")) { + cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); + cut->AddCut(VarManager::kIsNoTFBorder, 0.5, 1.5); + cut->AddCut(VarManager::kIsNoITSROFBorder, 0.5, 1.5); + cut->AddCut(VarManager::kIsNoSameBunch, 0.5, 1.5); + cut->AddCut(VarManager::kIsGoodZvtxFT0vsPV, 0.5, 1.5); + cut->AddCut(VarManager::kIsVertexITSTPC, 0.5, 1.5); + cut->AddCut(VarManager::kIsVertexTOFmatched, 0.5, 1.5); + return cut; + } + if (!nameStr.compare("eventStandardSel8multAnalysis")) { cut->AddCut(VarManager::kVtxZ, -10.0, 10.0); cut->AddCut(VarManager::kIsSel8, 0.5, 1.5); @@ -7100,3 +7116,230 @@ AnalysisCompositeCut* o2::aod::dqcuts::ParseJSONAnalysisCompositeCut(T cut, cons return retCut; } + +//________________________________________________________________________________________________ +o2::aod::dqmlcuts::BdtScoreConfig o2::aod::dqmlcuts::GetBdtScoreCutsAndConfigFromJSON(const char* json) +{ + LOG(info) << "========================================== interpreting JSON for ML analysis cuts"; + if (!json) { + LOG(fatal) << "JSON config string is null!"; + return {}; + } + LOG(info) << "JSON string: " << json; + + rapidjson::Document document; + + // Check that the json is parsed correctly + rapidjson::ParseResult ok = document.Parse(json); + if (!ok) { + LOG(fatal) << "JSON parse error: " << rapidjson::GetParseErrorFunc(ok.Code()) << " (" << ok.Offset() << ")"; + return {}; + } + + for (auto it = document.MemberBegin(); it != document.MemberEnd(); ++it) { + const auto& obj = it->value; + + // Classification type + if (!obj.HasMember("type")) { + LOG(fatal) << "Missing type (Binary/MultiClass)"; + return {}; + } + TString typeStr = obj["type"].GetString(); + if (typeStr != "Binary" && typeStr != "MultiClass") { + LOG(fatal) << "Unsupported classification type: " << typeStr; + return {}; + } + + // Input features + if (!obj.HasMember("inputFeatures") || !obj["inputFeatures"].IsArray()) { + LOG(fatal) << "Missing inputFeatures member or array"; + return {}; + } + std::vector namesInputFeatures; + for (const auto& feature : obj["inputFeatures"].GetArray()) { + namesInputFeatures.emplace_back(feature.GetString()); + LOG(debug) << "Input features: " << feature.GetString(); + } + + // Model files + if (!obj.HasMember("modelFiles") || !obj["modelFiles"].IsArray()) { + LOG(fatal) << "Missing modelFiles member or array"; + return {}; + } + std::vector onnxFileNames; + for (const auto& model : obj["modelFiles"].GetArray()) { + onnxFileNames.emplace_back(model.GetString()); + LOG(debug) << "Model Files: " << model.GetString() << " "; + } + + // Centrality estimation type + if (!obj.HasMember("cent") || !obj["cent"].IsString()) { + LOG(fatal) << "Missing cent member"; + return {}; + } + std::string cent = obj["cent"].GetString(); + LOG(debug) << "Centrality type: " << cent; + if (cent != "kCentFT0C" && cent != "kCentFT0A" && cent != "kCentFT0M") { + LOG(fatal) << "Unsupported centrality type: " << cent; + return {}; + } + + // Cut storage + std::vector> centBins; + std::vector> ptBins; + std::vector> cutsMl; + std::vector cutDirs; + std::vector labelsFlatBin; + bool cutDirsFilled = false; + + for (auto centMember = obj.MemberBegin(); centMember != obj.MemberEnd(); ++centMember) { + TString centKey = centMember->name.GetString(); + if (!centKey.Contains("AddCentCut")) + continue; + + const auto& centCut = centMember->value; + + // Centrality info + if (!centCut.HasMember("centMin") || !centCut.HasMember("centMax")) { + LOG(fatal) << "Missing centMin/centMax in " << centKey; + return {}; + } + double centMin = centCut["centMin"].GetDouble(); + double centMax = centCut["centMax"].GetDouble(); + + for (auto ptMember = centCut.MemberBegin(); ptMember != centCut.MemberEnd(); ++ptMember) { + TString ptKey = ptMember->name.GetString(); + if (!ptKey.Contains("AddPtCut")) + continue; + + const auto& ptCut = ptMember->value; + + // Pt info + if (!ptCut.HasMember("pTMin") || !ptCut.HasMember("pTMax")) { + LOG(fatal) << "Missing pTMin/pTMax in " << ptKey; + return {}; + } + + double ptMin = ptCut["pTMin"].GetDouble(); + double ptMax = ptCut["pTMax"].GetDouble(); + + std::vector binCuts; + bool exclude = false; + + for (auto mlMember = ptCut.MemberBegin(); mlMember != ptCut.MemberEnd(); ++mlMember) { + TString mlKey = mlMember->name.GetString(); + if (!mlKey.Contains("AddMLCut")) + continue; + + const auto& mlcut = mlMember->value; + + if (!mlcut.HasMember("cut")) { + LOG(fatal) << "Missing cut (score) in " << mlKey; + return {}; + } + + double cutVal = mlcut["cut"].GetDouble(); + exclude = mlcut.HasMember("exclude") ? mlcut["exclude"].GetBool() : false; + + binCuts.push_back(cutVal); + + if (!cutDirsFilled) { + cutDirs.push_back(exclude ? 0 : 1); + } + } + + if (!cutDirsFilled) { + cutDirsFilled = true; + } + + centBins.emplace_back(centMin, centMax); + ptBins.emplace_back(ptMin, ptMax); + cutsMl.push_back(binCuts); + labelsFlatBin.push_back(Form("%s_cent%.0f_%.0f_pt%.1f_%.1f", cent.c_str(), centMin, centMax, ptMin, ptMax)); + LOG(info) << "Added cut for " << Form("%s_cent%.0f_%.0f_pt%.1f_%.1f", cent.c_str(), centMin, centMax, ptMin, ptMax) << " with cuts: ["; + for (size_t i = 0; i < binCuts.size(); ++i) { + std::cout << binCuts[i]; + if (i != binCuts.size() - 1) + std::cout << ", "; + } + std::cout << "] and direction: " << (exclude ? "CutGreater" : "CutSmaller") << std::endl; + } + } + + if (cutDirs.size() != cutsMl[0].size()) { + LOG(fatal) << "Mismatch the cut size and direction size: cutsMl[0].size() = " << cutsMl[0].size() + << ", cutsMl[0].size() = " << cutDirs.size(); + return {}; + } + + std::vector labelsClass; + for (size_t j = 0; j < cutsMl[0].size(); ++j) { + labelsClass.push_back(Form("score class %d", static_cast(j))); + } + + size_t nFlatBins = cutsMl.size(); + std::vector binsMl(nFlatBins + 1); + std::iota(binsMl.begin(), binsMl.end(), 0); + + // Binary + if (typeStr == "Binary") { + dqmlcuts::BinaryBdtScoreConfig binaryCfg; + binaryCfg.inputFeatures = namesInputFeatures; + binaryCfg.onnxFiles = onnxFileNames; + binaryCfg.binsCent = centBins; + binaryCfg.binsPt = ptBins; + binaryCfg.binsMl = binsMl; + binaryCfg.cutDirs = cutDirs; + binaryCfg.centType = cent; + binaryCfg.cutsMl = makeLabeledCutsMl(cutsMl, labelsFlatBin, labelsClass); + + return binaryCfg; + + // MultiClass + } else if (typeStr == "MultiClass") { + dqmlcuts::MultiClassBdtScoreConfig multiCfg; + multiCfg.inputFeatures = namesInputFeatures; + multiCfg.onnxFiles = onnxFileNames; + multiCfg.binsCent = centBins; + multiCfg.binsPt = ptBins; + multiCfg.binsMl = binsMl; + multiCfg.cutDirs = cutDirs; + multiCfg.centType = cent; + multiCfg.cutsMl = makeLabeledCutsMl(cutsMl, labelsFlatBin, labelsClass); + + return multiCfg; + } + } + + return {}; +} + +o2::framework::LabeledArray o2::aod::dqmlcuts::makeLabeledCutsMl(const std::vector>& cuts, + const std::vector& labelsflatBin, + const std::vector& labelsClass) +{ + const size_t nRows = cuts.size(); + const size_t nCols = cuts.empty() ? 0 : cuts[0].size(); + std::vector flat; + + for (const auto& row : cuts) { + flat.insert(flat.end(), row.begin(), row.end()); + } + + o2::framework::Array2D arr(flat.data(), nRows, nCols); + return o2::framework::LabeledArray(arr, labelsflatBin, labelsClass); +} + +int o2::aod::dqmlcuts::getMlBinIndex(double cent, double pt, + const std::vector>& binsCent, + const std::vector>& binsPt) +{ + LOG(debug) << "Searching for Ml bin index for cent: " << cent << ", pt: " << pt; + for (size_t i = 0; i < binsCent.size(); ++i) { + if (cent >= binsCent[i].first && cent < binsCent[i].second && pt >= binsPt[i].first && pt < binsPt[i].second) { + LOG(debug) << " - Found at index: " << i; + return static_cast(i); + } + } + return -1; // not found +} diff --git a/PWGDQ/Core/CutsLibrary.h b/PWGDQ/Core/CutsLibrary.h index c6ad4caded2..b38577f3c2b 100644 --- a/PWGDQ/Core/CutsLibrary.h +++ b/PWGDQ/Core/CutsLibrary.h @@ -15,12 +15,13 @@ #ifndef PWGDQ_CORE_CUTSLIBRARY_H_ #define PWGDQ_CORE_CUTSLIBRARY_H_ -#include -#include -#include "PWGDQ/Core/AnalysisCut.h" #include "PWGDQ/Core/AnalysisCompositeCut.h" +#include "PWGDQ/Core/AnalysisCut.h" #include "PWGDQ/Core/VarManager.h" +#include +#include + // /////////////////////////////////////////////// // These are the Cuts used in the CEFP Task // // to select tracks in the event selection // @@ -119,6 +120,41 @@ bool ValidateJSONAnalysisCompositeCut(T cut); template AnalysisCompositeCut* ParseJSONAnalysisCompositeCut(T key, const char* cutName); } // namespace dqcuts +namespace dqmlcuts +{ +struct BinaryBdtScoreConfig { + std::vector inputFeatures; + std::vector onnxFiles; + std::vector> binsCent; // bins for centrality + std::vector> binsPt; // bins for pT + std::vector binsMl; // bins for flattened binning + std::string centType; + o2::framework::LabeledArray cutsMl; // BDT score cuts for each bin + std::vector cutDirs; // direction of the cuts on the BDT score +}; + +struct MultiClassBdtScoreConfig { + std::vector inputFeatures; + std::vector onnxFiles; + std::vector> binsCent; + std::vector> binsPt; + std::vector binsMl; + std::string centType; + o2::framework::LabeledArray cutsMl; + std::vector cutDirs; +}; + +using BdtScoreConfig = std::variant; + +BdtScoreConfig GetBdtScoreCutsAndConfigFromJSON(const char* json); + +o2::framework::LabeledArray makeLabeledCutsMl(const std::vector>& cuts, + const std::vector& labelsPt, + const std::vector& labelsClass); +int getMlBinIndex(double cent, double pt, + const std::vector>& binsCent, + const std::vector>& binsPt); +} // namespace dqmlcuts } // namespace o2::aod AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName); diff --git a/PWGDQ/Core/DQMlResponse.h b/PWGDQ/Core/DQMlResponse.h new file mode 100644 index 00000000000..64bfe233cc7 --- /dev/null +++ b/PWGDQ/Core/DQMlResponse.h @@ -0,0 +1,239 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// Contact: jseo@cern.ch +// +// Class to compute the ML response for DQ-analysis selections +// + +#ifndef PWGDQ_CORE_DQMLRESPONSE_H_ +#define PWGDQ_CORE_DQMLRESPONSE_H_ + +#include "Tools/ML/MlResponse.h" + +#include +#include +#include +#include + +namespace o2::analysis +{ + +enum class InputFeatures : uint8_t { // refer to DielectronsAll, TODO: add more features if needed + kMass = 0, + kPt, + kEta, + kPhi, + kPt1, + kITSChi2NCl1, + kTPCNClsCR1, + kTPCNClsFound1, + kTPCChi2NCl1, + kDcaXY1, + kDcaZ1, + kTPCNSigmaEl1, + kTPCNSigmaPi1, + kTPCNSigmaPr1, + kTOFNSigmaEl1, + kTOFNSigmaPi1, + kTOFNSigmaPr1, + kPt2, + kITSChi2NCl2, + kTPCNClsCR2, + kTPCNClsFound2, + kTPCChi2NCl2, + kDcaXY2, + kDcaZ2, + kTPCNSigmaEl2, + kTPCNSigmaPi2, + kTPCNSigmaPr2, + kTOFNSigmaEl2, + kTOFNSigmaPi2, + kTOFNSigmaPr2 +}; + +static const std::map gFeatureNameMap = { + {InputFeatures::kMass, "kMass"}, + {InputFeatures::kPt, "kPt"}, + {InputFeatures::kEta, "kEta"}, + {InputFeatures::kPhi, "kPhi"}, + {InputFeatures::kPt1, "kPt1"}, + {InputFeatures::kITSChi2NCl1, "kITSChi2NCl1"}, + {InputFeatures::kTPCNClsCR1, "kTPCNClsCR1"}, + {InputFeatures::kTPCNClsFound1, "kTPCNClsFound1"}, + {InputFeatures::kTPCChi2NCl1, "kTPCChi2NCl1"}, + {InputFeatures::kDcaXY1, "kDcaXY1"}, + {InputFeatures::kDcaZ1, "kDcaZ1"}, + {InputFeatures::kTPCNSigmaEl1, "kTPCNSigmaEl1"}, + {InputFeatures::kTPCNSigmaPi1, "kTPCNSigmaPi1"}, + {InputFeatures::kTPCNSigmaPr1, "kTPCNSigmaPr1"}, + {InputFeatures::kTOFNSigmaEl1, "kTOFNSigmaEl1"}, + {InputFeatures::kTOFNSigmaPi1, "kTOFNSigmaPi1"}, + {InputFeatures::kTOFNSigmaPr1, "kTOFNSigmaPr1"}, + {InputFeatures::kPt2, "kPt2"}, + {InputFeatures::kITSChi2NCl2, "kITSChi2NCl2"}, + {InputFeatures::kTPCNClsCR2, "kTPCNClsCR2"}, + {InputFeatures::kTPCNClsFound2, "kTPCNClsFound2"}, + {InputFeatures::kTPCChi2NCl2, "kTPCChi2NCl2"}, + {InputFeatures::kDcaXY2, "kDcaXY2"}, + {InputFeatures::kDcaZ2, "kDcaZ2"}, + {InputFeatures::kTPCNSigmaEl2, "kTPCNSigmaEl2"}, + {InputFeatures::kTPCNSigmaPi2, "kTPCNSigmaPi2"}, + {InputFeatures::kTPCNSigmaPr2, "kTPCNSigmaPr2"}, + {InputFeatures::kTOFNSigmaEl2, "kTOFNSigmaEl2"}, + {InputFeatures::kTOFNSigmaPi2, "kTOFNSigmaPi2"}, + {InputFeatures::kTOFNSigmaPr2, "kTOFNSigmaPr2"}}; + +template +class DQMlResponse : public MlResponse +{ + public: + DQMlResponse() = default; + virtual ~DQMlResponse() = default; + + void setBinsCent(const std::vector>& bins) { binsCent = bins; } + void setBinsPt(const std::vector>& bins) { binsPt = bins; } + void setCentType(std::string& type) { centType = type; } + + const std::vector>& getBinsCent() const { return binsCent; } + const std::vector>& getBinsPt() const { return binsPt; } + const std::string& getCentType() const { return centType; } + + /// Method to get the input features vector needed for ML inference + /// \return inputFeatures vector + template + std::vector getInputFeatures(const T1& t1, + const T2& t2, + const TValues& fg) const + { + std::vector dqInputFeatures; + dqInputFeatures.reserve(MlResponse::mCachedIndices.size()); + + for (auto idx : MlResponse::mCachedIndices) { + auto enumIdx = static_cast(idx); + auto mapIdx = gFeatureNameMap.find(enumIdx); + if (mapIdx == gFeatureNameMap.end()) { + LOG(fatal) << "Unknown InputFeatures index: " << static_cast(enumIdx); + } + + const auto& name = mapIdx->second; + if (name == "kMass") { + dqInputFeatures.push_back(fg[VarManager::fgVarNamesMap["kMass"]]); + } else if (name == "kPt") { + dqInputFeatures.push_back(fg[VarManager::fgVarNamesMap["kPt"]]); + } else if (name == "kEta") { + dqInputFeatures.push_back(fg[VarManager::fgVarNamesMap["kEta"]]); + } else if (name == "kPhi") { + dqInputFeatures.push_back(fg[VarManager::fgVarNamesMap["kPhi"]]); + } else if (name == "kPt1") { + dqInputFeatures.push_back(t1.pt()); + } else if (name == "kITSChi2NCl1") { + dqInputFeatures.push_back(t1.itsChi2NCl()); + } else if (name == "kTPCNClsCR1") { + dqInputFeatures.push_back(t1.tpcNClsCrossedRows()); + } else if (name == "kTPCNClsFound1") { + dqInputFeatures.push_back(t1.tpcNClsFound()); + } else if (name == "kTPCChi2NCl1") { + dqInputFeatures.push_back(t1.tpcChi2NCl()); + } else if (name == "kDcaXY1") { + dqInputFeatures.push_back(t1.dcaXY()); + } else if (name == "kDcaZ1") { + dqInputFeatures.push_back(t1.dcaZ()); + } else if (name == "kTPCNSigmaEl1") { + dqInputFeatures.push_back(t1.tpcNSigmaEl()); + } else if (name == "kTPCNSigmaPi1") { + dqInputFeatures.push_back(t1.tpcNSigmaPi()); + } else if (name == "kTPCNSigmaPr1") { + dqInputFeatures.push_back(t1.tpcNSigmaPr()); + } else if (name == "kTOFNSigmaEl1") { + dqInputFeatures.push_back(t1.tofNSigmaEl()); + } else if (name == "kTOFNSigmaPi1") { + dqInputFeatures.push_back(t1.tofNSigmaPi()); + } else if (name == "kTOFNSigmaPr1") { + dqInputFeatures.push_back(t1.tofNSigmaPr()); + } else if (name == "kPt2") { + dqInputFeatures.push_back(t2.pt()); + } else if (name == "kITSChi2NCl2") { + dqInputFeatures.push_back(t2.itsChi2NCl()); + } else if (name == "kTPCNClsCR2") { + dqInputFeatures.push_back(t2.tpcNClsCrossedRows()); + } else if (name == "kTPCNClsFound2") { + dqInputFeatures.push_back(t2.tpcNClsFound()); + } else if (name == "kTPCChi2NCl2") { + dqInputFeatures.push_back(t2.tpcChi2NCl()); + } else if (name == "kDcaXY2") { + dqInputFeatures.push_back(t2.dcaXY()); + } else if (name == "kDcaZ2") { + dqInputFeatures.push_back(t2.dcaZ()); + } else if (name == "kTPCNSigmaEl2") { + dqInputFeatures.push_back(t2.tpcNSigmaEl()); + } else if (name == "kTPCNSigmaPi2") { + dqInputFeatures.push_back(t2.tpcNSigmaPi()); + } else if (name == "kTPCNSigmaPr2") { + dqInputFeatures.push_back(t2.tpcNSigmaPr()); + } else if (name == "kTOFNSigmaEl2") { + dqInputFeatures.push_back(t2.tofNSigmaEl()); + } else if (name == "kTOFNSigmaPi2") { + dqInputFeatures.push_back(t2.tofNSigmaPi()); + } else if (name == "kTOFNSigmaPr2") { + dqInputFeatures.push_back(t2.tofNSigmaPr()); + } else { + LOG(fatal) << "Missing accessor for feature: " << name; + } + } + LOG(debug) << "Total features collected: " << dqInputFeatures.size(); + return dqInputFeatures; + } + + protected: + std::vector> binsCent; + std::vector> binsPt; + std::string centType; + + void setAvailableInputFeatures() + { + MlResponse::mAvailableInputFeatures = { + {"kMass", static_cast(InputFeatures::kMass)}, + {"kPt", static_cast(InputFeatures::kPt)}, + {"kEta", static_cast(InputFeatures::kEta)}, + {"kPhi", static_cast(InputFeatures::kPhi)}, + {"kPt1", static_cast(InputFeatures::kPt1)}, + {"kITSChi2NCl1", static_cast(InputFeatures::kITSChi2NCl1)}, + {"kTPCNClsCR1", static_cast(InputFeatures::kTPCNClsCR1)}, + {"kTPCNClsFound1", static_cast(InputFeatures::kTPCNClsFound1)}, + {"kTPCChi2NCl1", static_cast(InputFeatures::kTPCChi2NCl1)}, + {"kDcaXY1", static_cast(InputFeatures::kDcaXY1)}, + {"kDcaZ1", static_cast(InputFeatures::kDcaZ1)}, + {"kTPCNSigmaEl1", static_cast(InputFeatures::kTPCNSigmaEl1)}, + {"kTPCNSigmaPi1", static_cast(InputFeatures::kTPCNSigmaPi1)}, + {"kTPCNSigmaPr1", static_cast(InputFeatures::kTPCNSigmaPr1)}, + {"kTOFNSigmaEl1", static_cast(InputFeatures::kTOFNSigmaEl1)}, + {"kTOFNSigmaPi1", static_cast(InputFeatures::kTOFNSigmaPi1)}, + {"kTOFNSigmaPr1", static_cast(InputFeatures::kTOFNSigmaPr1)}, + {"kPt2", static_cast(InputFeatures::kPt2)}, + {"kITSChi2NCl2", static_cast(InputFeatures::kITSChi2NCl2)}, + {"kTPCNClsCR2", static_cast(InputFeatures::kTPCNClsCR2)}, + {"kTPCNClsFound2", static_cast(InputFeatures::kTPCNClsFound2)}, + {"kTPCChi2NCl2", static_cast(InputFeatures::kTPCChi2NCl2)}, + {"kDcaXY2", static_cast(InputFeatures::kDcaXY2)}, + {"kDcaZ2", static_cast(InputFeatures::kDcaZ2)}, + {"kTPCNSigmaEl2", static_cast(InputFeatures::kTPCNSigmaEl2)}, + {"kTPCNSigmaPi2", static_cast(InputFeatures::kTPCNSigmaPi2)}, + {"kTPCNSigmaPr2", static_cast(InputFeatures::kTPCNSigmaPr2)}, + {"kTOFNSigmaEl2", static_cast(InputFeatures::kTOFNSigmaEl2)}, + {"kTOFNSigmaPi2", static_cast(InputFeatures::kTOFNSigmaPi2)}, + {"kTOFNSigmaPr2", static_cast(InputFeatures::kTOFNSigmaPr2)}}; + } +}; + +} // namespace o2::analysis + +#endif // PWGDQ_CORE_DQMLRESPONSE_H_ diff --git a/PWGDQ/Core/HistogramsLibrary.cxx b/PWGDQ/Core/HistogramsLibrary.cxx index b9618a4c64e..dd875822000 100644 --- a/PWGDQ/Core/HistogramsLibrary.cxx +++ b/PWGDQ/Core/HistogramsLibrary.cxx @@ -915,12 +915,12 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Rapidity", "", false, 400, -4.0, 4.0, VarManager::kRap); } if (!groupStr.CompareTo("mctruth_pair")) { - hm->AddHistogram(histClass, "Mass_Pt", "", false, 500, 0.0, 5.0, VarManager::kMass, 40, 0.0, 20.0, VarManager::kPt); + hm->AddHistogram(histClass, "Mass_Pt", "", false, 500, 0.0, 15.0, VarManager::kMass, 40, 0.0, 20.0, VarManager::kPt); hm->AddHistogram(histClass, "Pt", "", false, 200, 0.0, 20.0, VarManager::kPt); hm->AddHistogram(histClass, "Pt_Dilepton", "", false, 200, 0.0, 20.0, VarManager::kPairPtDau); hm->AddHistogram(histClass, "Eta_Pt_lepton1", "", false, 100, -2.0, 2.0, VarManager::kEta1, 200, 0.0, 20.0, VarManager::kPt1); hm->AddHistogram(histClass, "Eta_Pt_lepton2", "", false, 100, -2.0, 2.0, VarManager::kEta2, 200, 0.0, 20.0, VarManager::kPt2); - hm->AddHistogram(histClass, "Mass", "", false, 500, 0.0, 5.0, VarManager::kMass); + hm->AddHistogram(histClass, "Mass", "", false, 500, 0.0, 15.0, VarManager::kMass); hm->AddHistogram(histClass, "Eta_Pt", "", false, 40, -2.0, 2.0, VarManager::kEta, 200, 0.0, 20.0, VarManager::kPt); hm->AddHistogram(histClass, "Phi_Eta", "#phi vs #eta distribution", false, 200, -5.0, 5.0, VarManager::kEta, 200, -2. * o2::constants::math::PI, 2. * o2::constants::math::PI, VarManager::kPhi); int varspTHE[3] = {VarManager::kMCPt, VarManager::kMCCosThetaHE, VarManager::kMCPhiHE}; @@ -1621,6 +1621,12 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "MassMult", "", false, 750, 0.0, 15.0, VarManager::kMass, 301, -0.5, 300.5, VarManager::kVtxNcontrib); hm->AddHistogram(histClass, "MassVtxZMult", "", false, 300, 0.0, 6.0, VarManager::kMass, 60, -15.0, 15.0, VarManager::kVtxZ, 100, 0.0, 100.0, VarManager::kVtxNcontrib); } + if (subGroupStr.Contains("dimuon-drellyan")) { + hm->AddHistogram(histClass, "DY_mass", "", false, 5000, 0.0, 50.0, VarManager::kMass); // 10 MeV mass res + hm->AddHistogram(histClass, "DY_pT", "", false, 2000, 0.0, 100.0, VarManager::kPt); // 50 MeV pT res + hm->AddHistogram(histClass, "DY_y", "", false, 20, 2.0, 4.0, VarManager::kRap); + hm->AddHistogram(histClass, "DY_phi", "", false, 180, constants::math::PI, 2 * constants::math::PI, VarManager::kPhi); + } } else if (subGroupStr.Contains("electronmuon")) { hm->AddHistogram(histClass, "Mass", "", false, 750, 0.0, 30.0, VarManager::kMass); hm->AddHistogram(histClass, "Pt", "", false, 120, 0.0, 30.0, VarManager::kPt); @@ -1986,13 +1992,6 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Mass_Pt", "", false, 500, 0.0, 5.0, VarManager::kMassDau, 200, 0.0, 20.0, VarManager::kPt); hm->AddHistogram(histClass, "Rapidity", "", false, 400, -4.0, 4.0, VarManager::kRap); } - - if (subGroupStr.Contains("DY-dimuon")) { - hm->AddHistogram(histClass, "DY_mass", "", false, 5000, 0.0, 50.0, VarManager::kMass); // 10 MeV mass res - hm->AddHistogram(histClass, "DY_pT", "", false, 2000, 0.0, 100.0, VarManager::kPt); // 50 MeV pT res - hm->AddHistogram(histClass, "DY_y", "", false, 20, 2.0, 4.0, VarManager::kRap); - hm->AddHistogram(histClass, "DY_phi", "", false, 180, constants::math::PI, 2 * constants::math::PI, VarManager::kPhi); - } } //__________________________________________________________________ diff --git a/PWGDQ/Core/VarManager.cxx b/PWGDQ/Core/VarManager.cxx index 912dc06740a..4bb8c419ad7 100644 --- a/PWGDQ/Core/VarManager.cxx +++ b/PWGDQ/Core/VarManager.cxx @@ -1131,6 +1131,12 @@ void VarManager::SetDefaultVarNames() fgVariableUnits[kS13] = "GeV^{2}/c^{4}"; fgVariableNames[kS23] = "m_{23}^{2}"; fgVariableUnits[kS23] = "GeV^{2}/c^{4}"; + fgVariableNames[kBdtBackground] = "kBdtBackground"; + fgVariableUnits[kBdtBackground] = " "; + fgVariableNames[kBdtPrompt] = "kBdtPrompt"; + fgVariableUnits[kBdtPrompt] = " "; + fgVariableNames[kBdtNonprompt] = "kBdtNonprompt"; + fgVariableUnits[kBdtNonprompt] = " "; // Set the variables short names map. This is needed for dynamic configuration via JSON files fgVarNamesMap["kNothing"] = kNothing; @@ -1770,4 +1776,7 @@ void VarManager::SetDefaultVarNames() fgVarNamesMap["kV24ME"] = kV24ME; fgVarNamesMap["kWV22ME"] = kWV22ME; fgVarNamesMap["kWV24ME"] = kWV24ME; + fgVarNamesMap["kBdtBackground"] = kBdtBackground; + fgVarNamesMap["kBdtPrompt"] = kBdtPrompt; + fgVarNamesMap["kBdtNonprompt"] = kBdtNonprompt; } diff --git a/PWGDQ/Core/VarManager.h b/PWGDQ/Core/VarManager.h index ec2ec55b83b..d49e71677da 100644 --- a/PWGDQ/Core/VarManager.h +++ b/PWGDQ/Core/VarManager.h @@ -855,6 +855,11 @@ class VarManager : public TObject // deltaMass_jpsi = kPairMass - kPairMassDau +3.096900 kDeltaMass_jpsi, + // BDT score + kBdtBackground, + kBdtPrompt, + kBdtNonprompt, + kNVars }; // end of Variables enumeration @@ -1127,6 +1132,8 @@ class VarManager : public TObject static void FillDileptonTrackTrackVertexing(C const& collision, T1 const& lepton1, T1 const& lepton2, T1 const& track1, T1 const& track2, float* values); template static void FillZDC(const T& zdc, float* values = nullptr); + template + static void FillBdtScore(const T& bdtScore, float* values = nullptr); static void SetCalibrationObject(CalibObjects calib, TObject* obj) { @@ -5524,4 +5531,24 @@ float VarManager::calculatePhiV(T1 const& t1, T2 const& t2) return pairPhiV; } +/// Fill BDT score values. +/// Supports binary (1 output) and multiclass (3 outputs) models. +template +void VarManager::FillBdtScore(T1 const& bdtScore, float* values) +{ + if (!values) { + values = fgValues; + } + + if (bdtScore.size() == 1) { + values[kBdtBackground] = bdtScore[0]; + } else if (bdtScore.size() == 3) { + values[kBdtBackground] = bdtScore[0]; + values[kBdtPrompt] = bdtScore[1]; + values[kBdtNonprompt] = bdtScore[2]; + } else { + LOG(warning) << "Unexpected number of BDT outputs: " << bdtScore.size(); + } +} + #endif // PWGDQ_CORE_VARMANAGER_H_ diff --git a/PWGDQ/Macros/bdtCut.json b/PWGDQ/Macros/bdtCut.json new file mode 100644 index 00000000000..2e015fa8618 --- /dev/null +++ b/PWGDQ/Macros/bdtCut.json @@ -0,0 +1,89 @@ +{ + "TestCut": { + "type": "Binary", + "title": "MyBDTModel", + "inputFeatures": [ + "kMass", + "kPt", + "kEta", + "kPhi", + "kPt1", + "kITSChi2NCl1", + "kTPCNClsCR1", + "kTPCNClsFound1", + "kTPCChi2NCl1", + "kDcaXY1", + "kDcaZ1", + "kTPCNSigmaEl1", + "kTPCNSigmaPi1", + "kTPCNSigmaPr1", + "kTOFNSigmaEl1", + "kTOFNSigmaPi1", + "kTOFNSigmaPr1", + "kPt2", + "kITSChi2NCl2", + "kTPCNClsCR2", + "kTPCNClsFound2", + "kTPCChi2NCl2", + "kDcaXY2", + "kDcaZ2", + "kTPCNSigmaEl2", + "kTPCNSigmaPi2", + "kTPCNSigmaPr2", + "kTOFNSigmaEl2", + "kTOFNSigmaPi2", + "kTOFNSigmaPr2" + ], + "modelFiles": [ + "cent_10_30_pt0_2_onnx.onnx", + "cent_10_30_pt2_20_onnx.onnx", + "cent_30_50_pt0_2_onnx.onnx", + "cent_30_50_pt2_20_onnx.onnx" + ], + "cent": "kCentFT0C", + "AddCentCut-Cent1030": { + "centMin": 10, + "centMax": 30, + "AddPtCut-pTBin1": { + "pTMin": 0, + "pTMax": 2, + "AddMLCut-background": { + "var": "kBdtBackground", + "cut": 0.5, + "exclude": false + } + }, + "AddPtCut-pTBin2": { + "pTMin": 2, + "pTMax": 20, + "AddMLCut-background": { + "var": "kBdtBackground", + "cut": 0.5, + "exclude": false + } + } + }, + "AddCentCut-Cent3050": { + "centMin": 30, + "centMax": 50, + "AddPtCut-pTBin1": { + "pTMin": 0, + "pTMax": 2, + "AddMLCut-background": { + "var": "kBdtBackground", + "cut": 0.5, + "exclude": false + } + }, + "AddPtCut-pTBin2": { + "pTMin": 2, + "pTMax": 20, + "AddMLCut-background": { + "var": "kBdtBackground", + "cut": 0.5, + "exclude": false + } + } + } + } +} diff --git a/PWGDQ/Macros/bdtCutMulti.json b/PWGDQ/Macros/bdtCutMulti.json new file mode 100644 index 00000000000..ba687e36200 --- /dev/null +++ b/PWGDQ/Macros/bdtCutMulti.json @@ -0,0 +1,129 @@ +{ + "TestCut": { + "type": "MultiClass", + "title": "MyBDTModel", + "inputFeatures": [ + "kMass", + "kPt", + "kEta", + "kPhi", + "kPt1", + "kITSChi2NCl1", + "kTPCNClsCR1", + "kTPCNClsFound1", + "kTPCChi2NCl1", + "kDcaXY1", + "kDcaZ1", + "kTPCNSigmaEl1", + "kTPCNSigmaPi1", + "kTPCNSigmaPr1", + "kTOFNSigmaEl1", + "kTOFNSigmaPi1", + "kTOFNSigmaPr1", + "kPt2", + "kITSChi2NCl2", + "kTPCNClsCR2", + "kTPCNClsFound2", + "kTPCChi2NCl2", + "kDcaXY2", + "kDcaZ2", + "kTPCNSigmaEl2", + "kTPCNSigmaPi2", + "kTPCNSigmaPr2", + "kTOFNSigmaEl2", + "kTOFNSigmaPi2", + "kTOFNSigmaPr2" + ], + "modelFiles": [ + "cent_10_30_pt_1_2_onnx.onnx", + "cent_10_30_pt_2_20_onnx.onnx", + "cent_30_50_pt_1_2_onnx.onnx", + "cent_30_50_pt_2_20_onnx.onnx" + ], + "cent": "kCentFT0C", + "AddCentCut-Cent1030": { + "centMin": 10, + "centMax": 30, + "AddPtCut-pTBin1": { + "pTMin": 1, + "pTMax": 2, + "AddMLCut-background": { + "var": "kBdtBackground", + "cut": 0.1, + "exclude": true + }, + "AddMLCut-prompt": { + "var": "kBdtPrompt", + "cut": 0.1, + "exclude": true + }, + "AddMLCut-nonprompt": { + "var": "kBdtNonprompt", + "cut": 0.5, + "exclude": false + } + }, + "AddPtCut-pTBin2": { + "pTMin": 2, + "pTMax": 20, + "AddMLCut-background": { + "var": "kBdtBackground", + "cut": 0.1, + "exclude": true + }, + "AddMLCut-prompt": { + "var": "kBdtPrompt", + "cut": 0.1, + "exclude": true + }, + "AddMLCut-nonprompt": { + "var": "kBdtNonprompt", + "cut": 0.5, + "exclude": false + } + } + }, + "AddCentCut-Cent3050": { + "centMin": 30, + "centMax": 50, + "AddPtCut-pTBin1": { + "pTMin": 1, + "pTMax": 2, + "AddMLCut-background": { + "var": "kBdtBackground", + "cut": 0.1, + "exclude": true + }, + "AddMLCut-prompt": { + "var": "kBdtPrompt", + "cut": 0.1, + "exclude": true + }, + "AddMLCut-nonprompt": { + "var": "kBdtNonprompt", + "cut": 0.5, + "exclude": false + } + }, + "AddPtCut-pTBin2": { + "pTMin": 2, + "pTMax": 20, + "AddMLCut-background": { + "var": "kBdtBackground", + "cut": 0.1, + "exclude": true + }, + "AddMLCut-prompt": { + "var": "kBdtPrompt", + "cut": 0.1, + "exclude": true + }, + "AddMLCut-nonprompt": { + "var": "kBdtNonprompt", + "cut": 0.5, + "exclude": false + } + } + } + } +} diff --git a/PWGDQ/TableProducer/tableMaker.cxx b/PWGDQ/TableProducer/tableMaker.cxx index 87d1183d385..7ebb5876bf5 100644 --- a/PWGDQ/TableProducer/tableMaker.cxx +++ b/PWGDQ/TableProducer/tableMaker.cxx @@ -24,45 +24,48 @@ #include #include // other includes -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/DataTypes.h" -#include "Framework/runDataProcessing.h" -#include "CCDB/BasicCCDBManager.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Centrality.h" +#include "PWGDQ/Core/AnalysisCompositeCut.h" +#include "PWGDQ/Core/AnalysisCut.h" +#include "PWGDQ/Core/CutsLibrary.h" +#include "PWGDQ/Core/HistogramManager.h" +#include "PWGDQ/Core/HistogramsLibrary.h" +#include "PWGDQ/Core/VarManager.h" +#include "PWGDQ/DataModel/ReducedInfoTables.h" + #include "Common/CCDB/TriggerAliases.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/FwdTrackReAlignTables.h" +#include "Common/DataModel/MftmchMatchingML.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/MftmchMatchingML.h" -#include "Common/DataModel/FwdTrackReAlignTables.h" -#include "PWGDQ/DataModel/ReducedInfoTables.h" -#include "PWGDQ/Core/VarManager.h" -#include "PWGDQ/Core/HistogramManager.h" -#include "PWGDQ/Core/AnalysisCut.h" -#include "PWGDQ/Core/AnalysisCompositeCut.h" -#include "PWGDQ/Core/HistogramsLibrary.h" -#include "PWGDQ/Core/CutsLibrary.h" -#include "DataFormatsGlobalTracking/RecoContainerCreateTracksVariadic.h" -#include "DetectorsVertexing/VertexTrackMatcher.h" -#include "ReconstructionDataFormats/PrimaryVertex.h" -#include "ReconstructionDataFormats/VtxTrackIndex.h" -#include "ReconstructionDataFormats/VtxTrackRef.h" -#include "DataFormatsITSMFT/ROFRecord.h" +#include "EventFiltering/Zorro.h" + +#include "CCDB/BasicCCDBManager.h" #include "CommonDataFormat/InteractionRecord.h" -#include "DetectorsVertexing/PVertexerParams.h" -#include "MathUtils/Primitive2D.h" #include "DataFormatsGlobalTracking/RecoContainer.h" -#include "Common/DataModel/CollisionAssociationTables.h" +#include "DataFormatsGlobalTracking/RecoContainerCreateTracksVariadic.h" +#include "DataFormatsITSMFT/ROFRecord.h" #include "DataFormatsParameters/GRPMagField.h" #include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsVertexing/PVertexerParams.h" +#include "DetectorsVertexing/VertexTrackMatcher.h" #include "Field/MagneticField.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/DataTypes.h" +#include "Framework/runDataProcessing.h" +#include "MathUtils/Primitive2D.h" +#include "ReconstructionDataFormats/PrimaryVertex.h" +#include "ReconstructionDataFormats/VtxTrackIndex.h" +#include "ReconstructionDataFormats/VtxTrackRef.h" + #include "TGeoGlobalMagField.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "EventFiltering/Zorro.h" using std::cout; using std::endl; @@ -191,15 +194,15 @@ struct TableMaker { struct : ConfigurableGroup { Configurable fConfigRunZorro{"cfgRunZorro", false, "Enable event selection with zorro"}; - Configurable fConfigZorroTrigMask{"cfgZorroTriggerMask", "fDiMuon", "DQ Trigger masks: fSingleE,fLMeeIMR,fLMeeHMR,fDiElectron,fSingleMuLow,fSingleMuHigh,fDiMuon"}; + Configurable fConfigZorroTrigMask{"cfgZorroTriggerMask", "fDiMuon", "DQ Trigger masks: fSingleE,fLMeeIMR,fLMeeHMR,fDiElectron,fSingleMuLow,fSingleMuHigh,fDiMuon"}; Configurable fConfigRunZorroSel{"cfgRunZorroSel", false, "Select events with trigger mask"}; Configurable fBcTolerance{"cfgBcTolerance", 100, "Number of BCs of margin for software triggers"}; } useZorro; struct : ConfigurableGroup { - Configurable fConfigCcdbUrl{"useCCDBConfigurations.ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable fConfigCcdbPathTPC{"useCCDBConfigurations.ccdb-path-tpc", "Users/z/zhxiong/TPCPID/PostCalib", "base path to the ccdb object"}; - Configurable fConfigCcdbPathZorro{"useCCDBConfigurations.ccdb-path-zorro", "/Users/m/mpuccio/EventFiltering/OTS/", "base path to the ccdb object for zorro"}; + Configurable fConfigCcdbUrl{"useCCDBConfigurations.ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbPathTPC{"useCCDBConfigurations.ccdb-path-tpc", "Users/z/zhxiong/TPCPID/PostCalib", "base path to the ccdb object"}; + Configurable fConfigCcdbPathZorro{"useCCDBConfigurations.ccdb-path-zorro", "/Users/m/mpuccio/EventFiltering/OTS/", "base path to the ccdb object for zorro"}; } useCCDBConfigurations; Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; diff --git a/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx b/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx index 7dc49516e8a..ad48874301e 100644 --- a/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx +++ b/PWGDQ/TableProducer/tableMakerMC_withAssoc.cxx @@ -1112,7 +1112,7 @@ struct TableMakerMC { VarManager::SetupMuonMagField(); } } - std::map metadataRCT, header; + std::map metadataRCT, header; header = fCCDBApi.retrieveHeaders(Form("RCT/Info/RunInformation/%i", bcs.begin().runNumber()), metadataRCT, -1); uint64_t sor = std::atol(header["SOR"].c_str()); uint64_t eor = std::atol(header["EOR"].c_str()); diff --git a/PWGDQ/TableProducer/tableMaker_withAssoc.cxx b/PWGDQ/TableProducer/tableMaker_withAssoc.cxx index 3b3d4c4e0af..60670abfac6 100644 --- a/PWGDQ/TableProducer/tableMaker_withAssoc.cxx +++ b/PWGDQ/TableProducer/tableMaker_withAssoc.cxx @@ -23,46 +23,49 @@ #include #include // other includes -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/DataTypes.h" -#include "Framework/runDataProcessing.h" -#include "CCDB/BasicCCDBManager.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Centrality.h" +#include "PWGDQ/Core/AnalysisCompositeCut.h" +#include "PWGDQ/Core/AnalysisCut.h" +#include "PWGDQ/Core/CutsLibrary.h" +#include "PWGDQ/Core/HistogramManager.h" +#include "PWGDQ/Core/HistogramsLibrary.h" +#include "PWGDQ/Core/VarManager.h" +#include "PWGDQ/DataModel/ReducedInfoTables.h" + #include "Common/CCDB/TriggerAliases.h" +#include "Common/Core/TableHelper.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/FwdTrackReAlignTables.h" +#include "Common/DataModel/MftmchMatchingML.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/MftmchMatchingML.h" -#include "Common/DataModel/FwdTrackReAlignTables.h" -#include "Common/Core/TableHelper.h" -#include "PWGDQ/DataModel/ReducedInfoTables.h" -#include "PWGDQ/Core/VarManager.h" -#include "PWGDQ/Core/HistogramManager.h" -#include "PWGDQ/Core/AnalysisCut.h" -#include "PWGDQ/Core/AnalysisCompositeCut.h" -#include "PWGDQ/Core/HistogramsLibrary.h" -#include "PWGDQ/Core/CutsLibrary.h" -#include "DataFormatsGlobalTracking/RecoContainerCreateTracksVariadic.h" -#include "DetectorsVertexing/VertexTrackMatcher.h" -#include "ReconstructionDataFormats/PrimaryVertex.h" -#include "ReconstructionDataFormats/VtxTrackIndex.h" -#include "ReconstructionDataFormats/VtxTrackRef.h" -#include "DataFormatsITSMFT/ROFRecord.h" +#include "EventFiltering/Zorro.h" + +#include "CCDB/BasicCCDBManager.h" #include "CommonDataFormat/InteractionRecord.h" -#include "DetectorsVertexing/PVertexerParams.h" -#include "MathUtils/Primitive2D.h" #include "DataFormatsGlobalTracking/RecoContainer.h" -#include "Common/DataModel/CollisionAssociationTables.h" +#include "DataFormatsGlobalTracking/RecoContainerCreateTracksVariadic.h" +#include "DataFormatsITSMFT/ROFRecord.h" #include "DataFormatsParameters/GRPMagField.h" #include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsVertexing/PVertexerParams.h" +#include "DetectorsVertexing/VertexTrackMatcher.h" #include "Field/MagneticField.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/DataTypes.h" +#include "Framework/runDataProcessing.h" +#include "MathUtils/Primitive2D.h" +#include "ReconstructionDataFormats/PrimaryVertex.h" +#include "ReconstructionDataFormats/VtxTrackIndex.h" +#include "ReconstructionDataFormats/VtxTrackRef.h" + #include "TGeoGlobalMagField.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "EventFiltering/Zorro.h" using namespace o2; using namespace o2::framework; @@ -225,9 +228,9 @@ struct TableMaker { // CCDB connection configurables struct : ConfigurableGroup { - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/z/zhxiong/TPCPID/PostCalib", "base path to the ccdb object"}; - Configurable fConfigCcdbPathZorro{"ccdb-path-zorro", "/Users/m/mpuccio/EventFiltering/OTS/Chunked/", "base path to the ccdb object for zorro"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/z/zhxiong/TPCPID/PostCalib", "base path to the ccdb object"}; + Configurable fConfigCcdbPathZorro{"ccdb-path-zorro", "/Users/m/mpuccio/EventFiltering/OTS/Chunked/", "base path to the ccdb object for zorro"}; Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable fConfigGeoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; Configurable fConfigGrpMagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; @@ -1317,7 +1320,7 @@ struct TableMaker { VarManager::SetupMuonMagField(); } } - std::map metadataRCT, header; + std::map metadataRCT, header; header = fCCDBApi.retrieveHeaders(Form("RCT/Info/RunInformation/%i", bcs.begin().runNumber()), metadataRCT, -1); uint64_t sor = std::atol(header["SOR"].c_str()); uint64_t eor = std::atol(header["EOR"].c_str()); diff --git a/PWGDQ/Tasks/CMakeLists.txt b/PWGDQ/Tasks/CMakeLists.txt index 5095140a2b8..c3bb38bf955 100644 --- a/PWGDQ/Tasks/CMakeLists.txt +++ b/PWGDQ/Tasks/CMakeLists.txt @@ -11,12 +11,12 @@ o2physics_add_dpl_workflow(table-reader SOURCES tableReader.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGDQCore + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGDQCore O2Physics::MLCore COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(table-reader-with-assoc SOURCES tableReader_withAssoc.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::AnalysisCCDB O2Physics::PWGDQCore + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::AnalysisCCDB O2Physics::PWGDQCore O2Physics::MLCore COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(efficiency @@ -127,4 +127,4 @@ o2physics_add_dpl_workflow(model-converter-event-extended o2physics_add_dpl_workflow(tag-and-probe SOURCES TagAndProbe.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::AnalysisCCDB O2Physics::PWGDQCore - COMPONENT_NAME Analysis) \ No newline at end of file + COMPONENT_NAME Analysis) diff --git a/PWGDQ/Tasks/TagAndProbe.cxx b/PWGDQ/Tasks/TagAndProbe.cxx index 33bfe2ea06c..2a35b33b87e 100644 --- a/PWGDQ/Tasks/TagAndProbe.cxx +++ b/PWGDQ/Tasks/TagAndProbe.cxx @@ -116,7 +116,7 @@ struct AnalysisTagAndProbe { OutputObj fOutputList{"output"}; struct : ConfigurableGroup { - Configurable muon{"cfgMuonCuts", "", "Comma separated list of muon cuts"}; + Configurable muon{"cfgMuonCuts", "", "Comma separated list of muon cuts"}; // TODO: Add pair cuts via JSON } fConfigCuts; @@ -124,7 +124,7 @@ struct AnalysisTagAndProbe { Configurable fConfigQA{"cfgQA", true, "If true, fill output histograms"}; struct : ConfigurableGroup { - Configurable url{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable url{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable grpMagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; diff --git a/PWGDQ/Tasks/dqCorrelation.cxx b/PWGDQ/Tasks/dqCorrelation.cxx index 950e82364cb..ec240fa66fe 100644 --- a/PWGDQ/Tasks/dqCorrelation.cxx +++ b/PWGDQ/Tasks/dqCorrelation.cxx @@ -11,44 +11,45 @@ /// @author Victor Valencia // Contact: iarsene@cern.ch, i.c.arsene@fys.uio.no // -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" #include "PWGCF/GenericFramework/Core/FlowContainer.h" -#include "PWGCF/GenericFramework/Core/GFWCumulant.h" #include "PWGCF/GenericFramework/Core/GFW.h" +#include "PWGCF/GenericFramework/Core/GFWCumulant.h" +#include "PWGCF/GenericFramework/Core/GFWPowerArray.h" #include "PWGCF/GenericFramework/Core/GFWWeights.h" -#include "PWGDQ/DataModel/ReducedInfoTables.h" -#include "PWGDQ/Core/VarManager.h" -#include "PWGDQ/Core/HistogramManager.h" -#include "PWGDQ/Core/MixingHandler.h" -#include "PWGDQ/Core/AnalysisCut.h" #include "PWGDQ/Core/AnalysisCompositeCut.h" -#include "PWGDQ/Core/HistogramsLibrary.h" +#include "PWGDQ/Core/AnalysisCut.h" #include "PWGDQ/Core/CutsLibrary.h" +#include "PWGDQ/Core/HistogramManager.h" +#include "PWGDQ/Core/HistogramsLibrary.h" +#include "PWGDQ/Core/MixingHandler.h" #include "PWGDQ/Core/MixingLibrary.h" +#include "PWGDQ/Core/VarManager.h" +#include "PWGDQ/DataModel/ReducedInfoTables.h" + +#include "CCDB/BasicCCDBManager.h" #include "DataFormatsParameters/GRPMagField.h" -#include "Field/MagneticField.h" -#include "TGeoGlobalMagField.h" -#include "DetectorsBase/Propagator.h" +#include "DataFormatsParameters/GRPObject.h" #include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Field/MagneticField.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" -#include "PWGCF/GenericFramework/Core/GFWPowerArray.h" +#include "TGeoGlobalMagField.h" #include "TProfile.h" +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include using std::cout; using std::endl; @@ -118,7 +119,7 @@ struct DqCumulantFlow { ConfigurableAxis axisMass{"axisMass", {40, 2, 4}, "mass axis for histograms"}; Configurable fConfigNPow{"cfgNPow", 0, "Power of weights for Q vector"}; // Configurables for the reference flow - Configurable fConfigTrackCuts{"cfgLeptonCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; + Configurable fConfigTrackCuts{"cfgLeptonCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; Configurable fConfigCutPtMin{"cfgCutPtMin", 1.0f, "Minimal pT for tracks"}; Configurable fConfigCutPtMax{"cfgCutPtMax", 12.0f, "Maximal pT for tracks"}; Configurable fConfigCutEtaMin{"cfgCutEtaMin", -0.8f, "Eta min range for tracks"}; diff --git a/PWGDQ/Tasks/dqEfficiency.cxx b/PWGDQ/Tasks/dqEfficiency.cxx index 29f7b79392b..bcbaa4fe1bf 100644 --- a/PWGDQ/Tasks/dqEfficiency.cxx +++ b/PWGDQ/Tasks/dqEfficiency.cxx @@ -13,30 +13,33 @@ // // Analysis task for processing O2::DQ MC skimmed AODs // -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "PWGDQ/DataModel/ReducedInfoTables.h" -#include "PWGDQ/Core/VarManager.h" -#include "PWGDQ/Core/HistogramManager.h" -#include "PWGDQ/Core/AnalysisCut.h" #include "PWGDQ/Core/AnalysisCompositeCut.h" -#include "PWGDQ/Core/HistogramsLibrary.h" +#include "PWGDQ/Core/AnalysisCut.h" #include "PWGDQ/Core/CutsLibrary.h" +#include "PWGDQ/Core/HistogramManager.h" +#include "PWGDQ/Core/HistogramsLibrary.h" #include "PWGDQ/Core/MCSignal.h" #include "PWGDQ/Core/MCSignalLibrary.h" +#include "PWGDQ/Core/VarManager.h" +#include "PWGDQ/DataModel/ReducedInfoTables.h" + #include "CCDB/BasicCCDBManager.h" #include "DataFormatsParameters/GRPMagField.h" #include "DetectorsBase/GeometryManager.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include using std::cout; using std::endl; @@ -1040,9 +1043,18 @@ struct AnalysisSameEventPairing { struct AnalysisDileptonTrack { Produces dileptontrackcandidatesList; OutputObj fOutputList{"output"}; + Service ccdb; + o2::base::MatLayerCylSet* lut = nullptr; + // TODO: For now this is only used to determine the position in the filter bit map for the hadron cut - Configurable fConfigTrackCuts{"cfgLeptonCuts", "", "Comma separated list of barrel track cuts"}; + Configurable fConfigTrackCuts{"cfgLeptonCuts", "", "Comma separated list of barrel track cuts"}; Configurable fConfigFillCandidateTable{"cfgFillCandidateTable", false, "Produce a single flat tables with all relevant information dilepton-track candidates"}; + Configurable ccdburl{"ccdburl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fCorrFullGeo{"cfgCorrFullGeo", false, "Use full geometry to correct for MCS effects in track propagation"}; + Configurable fNoCorr{"cfgNoCorrFwdProp", false, "Do not correct for MCS effects in track propagation"}; + Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; + Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; + Filter eventFilter = aod::dqanalysisflags::isEventSelected == 1; // Filter dileptonFilter = aod::reducedpair::mass > 2.92f && aod::reducedpair::mass < 3.16f && aod::reducedpair::sign == 0; // Filter dileptonFilter = aod::reducedpair::mass > 2.6f && aod::reducedpair::mass < 3.5f && aod::reducedpair::sign == 0; @@ -1075,6 +1087,21 @@ struct AnalysisDileptonTrack { return; } + ccdb->setURL(ccdburl.value); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + + if (fNoCorr) { + VarManager::SetupFwdDCAFitterNoCorr(); + } else if (fCorrFullGeo) { + if (!o2::base::GeometryManager::isGeometryLoaded()) { + ccdb->get(geoPath); + } + } else { + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(lutPath)); + VarManager::SetupMatLUTFwdDCAFitter(lut); + } + TString sigNamesStr = fConfigMCRecSignals.value; std::unique_ptr objRecSigArray(sigNamesStr.Tokenize(",")); TString histNames; diff --git a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx index 17ae4e76d22..95243956b78 100644 --- a/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx +++ b/PWGDQ/Tasks/dqEfficiency_withAssoc.cxx @@ -12,43 +12,47 @@ // Contact: iarsene@cern.ch, i.c.arsene@fys.uio.no // Configurable workflow for running several DQ or other PWG analyses -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisHelpers.h" -#include "PWGDQ/DataModel/ReducedInfoTables.h" -#include "PWGDQ/Core/VarManager.h" -#include "PWGDQ/Core/HistogramManager.h" -#include "PWGDQ/Core/MixingHandler.h" -#include "PWGDQ/Core/AnalysisCut.h" #include "PWGDQ/Core/AnalysisCompositeCut.h" -#include "PWGDQ/Core/HistogramsLibrary.h" +#include "PWGDQ/Core/AnalysisCut.h" #include "PWGDQ/Core/CutsLibrary.h" -#include "PWGDQ/Core/MixingLibrary.h" +#include "PWGDQ/Core/HistogramManager.h" +#include "PWGDQ/Core/HistogramsLibrary.h" #include "PWGDQ/Core/MCSignal.h" #include "PWGDQ/Core/MCSignalLibrary.h" +#include "PWGDQ/Core/MixingHandler.h" +#include "PWGDQ/Core/MixingLibrary.h" +#include "PWGDQ/Core/VarManager.h" +#include "PWGDQ/DataModel/ReducedInfoTables.h" + +#include "Common/Core/TableHelper.h" + +#include "CCDB/BasicCCDBManager.h" #include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" #include "Field/MagneticField.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + #include "TGeoGlobalMagField.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "Common/Core/TableHelper.h" +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include using std::cout; using std::endl; @@ -210,8 +214,8 @@ struct AnalysisEventSelection { Produces eventSel; OutputObj fOutputList{"output"}; - Configurable fConfigEventCuts{"cfgEventCuts", "eventStandard", "Event selection"}; - Configurable fConfigEventCutsJSON{"cfgEventCutsJSON", "", "Additional event cuts specified in JSON format"}; + Configurable fConfigEventCuts{"cfgEventCuts", "eventStandard", "Event selection"}; + Configurable fConfigEventCutsJSON{"cfgEventCutsJSON", "", "Additional event cuts specified in JSON format"}; Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; Configurable fConfigAddEventHistogram{"cfgAddEventHistogram", "", "Comma separated list of histograms"}; Configurable fConfigAddEventMCHistogram{"cfgAddEventMCHistogram", "generator", "Comma separated list of histograms"}; @@ -221,7 +225,7 @@ struct AnalysisEventSelection { Configurable fConfigSplitCollisionsDeltaBC{"splitCollisionsDeltaBC", 100, "maximum delta-BC between two collisions to consider them as split candidates; do not apply if value is negative"}; Configurable fConfigCheckSplitCollisions{"checkSplitCollisions", false, "If true, run the split collision check and fill histograms"}; - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; HistogramManager* fHistMan = nullptr; @@ -430,14 +434,14 @@ struct AnalysisTrackSelection { Produces trackAmbiguities; OutputObj fOutputList{"output"}; - Configurable fConfigCuts{"cfgTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; + Configurable fConfigCuts{"cfgTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; Configurable fConfigCutsJSON{"cfgBarrelTrackCutsJSON", "", "Additional list of barrel track cuts in JSON format"}; Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; - Configurable fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"}; + Configurable fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"}; Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format"}; Configurable fConfigPublishAmbiguity{"cfgPublishAmbiguity", true, "If true, publish ambiguity table and fill QA histograms"}; - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/z/zhxiong/TPCPID/PostCalib", "base path to the ccdb object"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/z/zhxiong/TPCPID/PostCalib", "base path to the ccdb object"}; Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable fConfigComputeTPCpostCalib{"cfgTPCpostCalib", false, "If true, compute TPC post-calibrated n-sigmas"}; Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; @@ -534,7 +538,7 @@ struct AnalysisTrackSelection { DefineHistograms(fHistMan, "TrackBarrel_AmbiguityInBunch;TrackBarrel_AmbiguityOutOfBunch;", "ambiguity"); } dqhistograms::AddHistogramsFromJSON(fHistMan, fConfigAddJSONHistograms.value.c_str()); // ad-hoc histograms via JSON - VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill + VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill fOutputList.setObject(fHistMan->GetMainHistogramList()); } @@ -755,13 +759,13 @@ struct AnalysisMuonSelection { Produces muonAmbiguities; OutputObj fOutputList{"output"}; - Configurable fConfigCuts{"cfgMuonCuts", "muonQualityCuts", "Comma separated list of muon cuts"}; + Configurable fConfigCuts{"cfgMuonCuts", "muonQualityCuts", "Comma separated list of muon cuts"}; Configurable fConfigCutsJSON{"cfgMuonCutsJSON", "", "Additional list of muon cuts in JSON format"}; Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; Configurable fConfigAddMuonHistogram{"cfgAddMuonHistogram", "", "Comma separated list of histograms"}; Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format"}; Configurable fConfigPublishAmbiguity{"cfgPublishAmbiguity", true, "If true, publish ambiguity table and fill QA histograms"}; - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable fConfigGeoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; @@ -856,9 +860,9 @@ struct AnalysisMuonSelection { histClasses += "Muon_AmbiguityInBunch;Muon_AmbiguityOutOfBunch;"; } - DefineHistograms(fHistMan, histClasses.Data(), fConfigAddMuonHistogram.value.data()); // define all histograms + DefineHistograms(fHistMan, histClasses.Data(), fConfigAddMuonHistogram.value.data()); // define all histograms dqhistograms::AddHistogramsFromJSON(fHistMan, fConfigAddJSONHistograms.value.c_str()); // ad-hoc histograms via JSON - VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill + VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill fOutputList.setObject(fHistMan->GetMainHistogramList()); } @@ -1247,6 +1251,7 @@ struct AnalysisSameEventPairing { Produces dimuonList; Produces dielectronsExtraList; Produces dielectronInfoList; + Produces dielectronAllList; Produces dimuonsExtraList; Produces dimuonAllList; Produces dileptonMiniTreeGen; @@ -1260,9 +1265,9 @@ struct AnalysisSameEventPairing { OutputObj fOutputList{"output"}; struct : ConfigurableGroup { - Configurable track{"cfgTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; - Configurable muon{"cfgMuonCuts", "", "Comma separated list of muon cuts"}; - Configurable pair{"cfgPairCuts", "", "Comma separated list of pair cuts, !!! Use only if you know what you are doing, otherwise leave empty"}; + Configurable track{"cfgTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; + Configurable muon{"cfgMuonCuts", "", "Comma separated list of muon cuts"}; + Configurable pair{"cfgPairCuts", "", "Comma separated list of pair cuts, !!! Use only if you know what you are doing, otherwise leave empty"}; // TODO: Add pair cuts via JSON } fConfigCuts; @@ -1271,7 +1276,7 @@ struct AnalysisSameEventPairing { Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format"}; struct : ConfigurableGroup { - Configurable url{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable url{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable grpMagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; @@ -1638,9 +1643,9 @@ struct AnalysisSameEventPairing { VarManager::SetCollisionSystem((TString)fConfigOptions.collisionSystem, fConfigOptions.centerMassEnergy); // set collision system and center of mass energy - DefineHistograms(fHistMan, histNames.Data(), fConfigAddSEPHistogram.value.data()); // define all histograms + DefineHistograms(fHistMan, histNames.Data(), fConfigAddSEPHistogram.value.data()); // define all histograms dqhistograms::AddHistogramsFromJSON(fHistMan, fConfigAddJSONHistograms.value.c_str()); // ad-hoc histograms via JSON - VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill + VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill fOutputList.setObject(fHistMan->GetMainHistogramList()); } @@ -1711,6 +1716,7 @@ struct AnalysisSameEventPairing { dielectronInfoList.reserve(1); dileptonInfoList.reserve(1); if (fConfigOptions.flatTables.value) { + dielectronAllList.reserve(1); dimuonAllList.reserve(1); } if (useMiniTree.fConfigMiniTree) { @@ -1798,6 +1804,18 @@ struct AnalysisSameEventPairing { } if constexpr (trackHasCov && TTwoProngFitter) { dielectronsExtraList(t1.globalIndex(), t2.globalIndex(), VarManager::fgValues[VarManager::kVertexingTauzProjected], VarManager::fgValues[VarManager::kVertexingLzProjected], VarManager::fgValues[VarManager::kVertexingLxyProjected]); + if constexpr ((TTrackFillMap & VarManager::ObjTypes::ReducedTrackCollInfo) > 0) { + if (fConfigOptions.flatTables.value && t1.has_reducedMCTrack() && t2.has_reducedMCTrack()) { + dielectronAllList(VarManager::fgValues[VarManager::kMass], VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kEta], VarManager::fgValues[VarManager::kPhi], t1.sign() + t2.sign(), twoTrackFilter, mcDecision, + t1.pt(), t1.eta(), t1.phi(), t1.itsClusterMap(), t1.itsChi2NCl(), t1.tpcNClsCrossedRows(), t1.tpcNClsFound(), t1.tpcChi2NCl(), t1.dcaXY(), t1.dcaZ(), t1.tpcSignal(), t1.tpcNSigmaEl(), t1.tpcNSigmaPi(), t1.tpcNSigmaPr(), t1.beta(), t1.tofNSigmaEl(), t1.tofNSigmaPi(), t1.tofNSigmaPr(), + t2.pt(), t2.eta(), t2.phi(), t2.itsClusterMap(), t2.itsChi2NCl(), t2.tpcNClsCrossedRows(), t2.tpcNClsFound(), t2.tpcChi2NCl(), t2.dcaXY(), t2.dcaZ(), t2.tpcSignal(), t2.tpcNSigmaEl(), t2.tpcNSigmaPi(), t2.tpcNSigmaPr(), t2.beta(), t2.tofNSigmaEl(), t2.tofNSigmaPi(), t2.tofNSigmaPr(), + VarManager::fgValues[VarManager::kKFTrack0DCAxyz], VarManager::fgValues[VarManager::kKFTrack1DCAxyz], VarManager::fgValues[VarManager::kKFDCAxyzBetweenProngs], VarManager::fgValues[VarManager::kKFTrack0DCAxy], VarManager::fgValues[VarManager::kKFTrack1DCAxy], VarManager::fgValues[VarManager::kKFDCAxyBetweenProngs], + VarManager::fgValues[VarManager::kKFTrack0DeviationFromPV], VarManager::fgValues[VarManager::kKFTrack1DeviationFromPV], VarManager::fgValues[VarManager::kKFTrack0DeviationxyFromPV], VarManager::fgValues[VarManager::kKFTrack1DeviationxyFromPV], + VarManager::fgValues[VarManager::kKFMass], VarManager::fgValues[VarManager::kKFChi2OverNDFGeo], VarManager::fgValues[VarManager::kVertexingLxyz], VarManager::fgValues[VarManager::kVertexingLxyzOverErr], VarManager::fgValues[VarManager::kVertexingLxy], VarManager::fgValues[VarManager::kVertexingLxyOverErr], VarManager::fgValues[VarManager::kVertexingTauxy], VarManager::fgValues[VarManager::kVertexingTauxyErr], VarManager::fgValues[VarManager::kKFCosPA], VarManager::fgValues[VarManager::kKFJpsiDCAxyz], VarManager::fgValues[VarManager::kKFJpsiDCAxy], + VarManager::fgValues[VarManager::kKFPairDeviationFromPV], VarManager::fgValues[VarManager::kKFPairDeviationxyFromPV], + VarManager::fgValues[VarManager::kKFMassGeoTop], VarManager::fgValues[VarManager::kKFChi2OverNDFGeoTop]); + } + } } } } @@ -2240,13 +2258,13 @@ struct AnalysisAsymmetricPairing { OutputObj fOutputList{"output"}; // Configurables - Configurable fConfigLegCuts{"cfgLegCuts", "", ":[:],[:[:],...]"}; + Configurable fConfigLegCuts{"cfgLegCuts", "", ":[:],[:[:],...]"}; Configurable fConfigLegAFilterMask{"cfgLegAFilterMask", 0, "Filter mask corresponding to cuts in event-selection"}; Configurable fConfigLegBFilterMask{"cfgLegBFilterMask", 0, "Filter mask corresponding to cuts in event-selection"}; Configurable fConfigLegCFilterMask{"cfgLegCFilterMask", 0, "Filter mask corresponding to cuts in event-selection"}; - Configurable fConfigCommonTrackCuts{"cfgCommonTrackCuts", "", "Comma separated list of cuts to be applied to all legs"}; - Configurable fConfigPairCuts{"cfgPairCuts", "", "Comma separated list of pair cuts"}; - Configurable fConfigPairCutsJSON{"cfgPairCutsJSON", "", "Additional list of pair cuts in JSON format"}; + Configurable fConfigCommonTrackCuts{"cfgCommonTrackCuts", "", "Comma separated list of cuts to be applied to all legs"}; + Configurable fConfigPairCuts{"cfgPairCuts", "", "Comma separated list of pair cuts"}; + Configurable fConfigPairCutsJSON{"cfgPairCutsJSON", "", "Additional list of pair cuts in JSON format"}; Configurable fConfigSkipAmbiguousIdCombinations{"cfgSkipAmbiguousIdCombinations", true, "Choose whether to skip pairs/triples which pass a stricter combination of cuts, e.g. KKPi triplets for D+ -> KPiPi"}; Configurable fConfigHistogramSubgroups{"cfgAsymmetricPairingHistogramsSubgroups", "barrel,vertexing", "Comma separated list of asymmetric-pairing histogram subgroups"}; @@ -2256,7 +2274,7 @@ struct AnalysisAsymmetricPairing { Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format"}; - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable fConfigGRPMagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable fConfigUseRemoteField{"cfgUseRemoteField", false, "Choose whether to fetch the magnetic field from ccdb or set it manually"}; Configurable fConfigMagField{"cfgMagField", 5.0f, "Manually set magnetic field"}; @@ -2660,7 +2678,7 @@ struct AnalysisAsymmetricPairing { VarManager::SetupMatLUTFwdDCAFitter(fLUT); dqhistograms::AddHistogramsFromJSON(fHistMan, fConfigAddJSONHistograms.value.c_str()); // ad-hoc histograms via JSON - VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill + VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill fOutputList.setObject(fHistMan->GetMainHistogramList()); } @@ -2820,7 +2838,7 @@ struct AnalysisAsymmetricPairing { for (int icut = 0; icut < fNLegCuts; icut++) { if (twoTrackFilter & (static_cast(1) << icut)) { isAmbi = (twoTrackFilter & (static_cast(1) << 30)) || (twoTrackFilter & (static_cast(1) << 31)); - if (sign1 * sign2 < 0) { // +- pairs + if (sign1 * sign2 < 0) { // +- pairs fHistMan->FillHistClass(Form("PairsBarrelSEPM_%s", fLegCutNames[icut].Data()), VarManager::fgValues); // reconstructed, unmatched if (isAmbi && fConfigQA) { fHistMan->FillHistClass(Form("PairsBarrelSEPM_ambiguous_%s", fLegCutNames[icut].Data()), VarManager::fgValues); @@ -3239,7 +3257,7 @@ struct AnalysisDileptonTrack { Produces BmesonsTable; OutputObj fOutputList{"output"}; - Configurable fConfigTrackCuts{"cfgTrackCuts", "kaonPID", "Comma separated list of track cuts to be correlated with the dileptons"}; + Configurable fConfigTrackCuts{"cfgTrackCuts", "kaonPID", "Comma separated list of track cuts to be correlated with the dileptons"}; Configurable fConfigDileptonLowMass{"cfgDileptonLowMass", 2.8, "Low mass cut for the dileptons used in analysis"}; Configurable fConfigDileptonHighMass{"cfgDileptonHighMass", 3.2, "High mass cut for the dileptons used in analysis"}; Configurable fConfigDileptonpTCut{"cfgDileptonpTCut", 0.0, "pT cut for dileptons used in the triplet vertexing"}; diff --git a/PWGDQ/Tasks/filterPP.cxx b/PWGDQ/Tasks/filterPP.cxx index c9239f8366d..4f3527f07ca 100644 --- a/PWGDQ/Tasks/filterPP.cxx +++ b/PWGDQ/Tasks/filterPP.cxx @@ -11,35 +11,39 @@ // // Contact: iarsene@cern.ch, i.c.arsene@fys.uio.no // -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/DataTypes.h" -#include "Framework/runDataProcessing.h" -#include "CCDB/BasicCCDBManager.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Centrality.h" +#include "PWGDQ/Core/AnalysisCompositeCut.h" +#include "PWGDQ/Core/AnalysisCut.h" +#include "PWGDQ/Core/CutsLibrary.h" +#include "PWGDQ/Core/HistogramManager.h" +#include "PWGDQ/Core/HistogramsLibrary.h" +#include "PWGDQ/Core/VarManager.h" +#include "PWGDQ/DataModel/ReducedInfoTables.h" + #include "Common/CCDB/TriggerAliases.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" #include "EventFiltering/filterTables.h" -#include "PWGDQ/DataModel/ReducedInfoTables.h" -#include "PWGDQ/Core/VarManager.h" -#include "PWGDQ/Core/HistogramManager.h" -#include "PWGDQ/Core/AnalysisCut.h" -#include "PWGDQ/Core/AnalysisCompositeCut.h" -#include "PWGDQ/Core/HistogramsLibrary.h" -#include "PWGDQ/Core/CutsLibrary.h" + +#include "CCDB/BasicCCDBManager.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/DataTypes.h" +#include "Framework/runDataProcessing.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include using std::cout; using std::endl; @@ -179,8 +183,8 @@ struct DQBarrelTrackSelection { Configurable fConfigCuts{"cfgBarrelTrackCuts", "jpsiPID1", "Comma separated list of barrel track cuts"}; Configurable fConfigQA{"cfgWithQA", false, "If true, fill QA histograms"}; - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/i/iarsene/Calib/TPCpostCalib", "base path to the ccdb object"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/i/iarsene/Calib/TPCpostCalib", "base path to the ccdb object"}; Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable fConfigComputeTPCpostCalib{"cfgTPCpostCalib", false, "If true, compute TPC post-calibrated n-sigmas"}; diff --git a/PWGDQ/Tasks/filterPPwithAssociation.cxx b/PWGDQ/Tasks/filterPPwithAssociation.cxx index 532482e641b..90d1e4942b4 100644 --- a/PWGDQ/Tasks/filterPPwithAssociation.cxx +++ b/PWGDQ/Tasks/filterPPwithAssociation.cxx @@ -11,44 +11,48 @@ // // Contact: iarsene@cern.ch, i.c.arsene@fys.uio.no // -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/DataTypes.h" -#include "Framework/runDataProcessing.h" -#include "CCDB/BasicCCDBManager.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Centrality.h" +#include "PWGDQ/Core/AnalysisCompositeCut.h" +#include "PWGDQ/Core/AnalysisCut.h" +#include "PWGDQ/Core/CutsLibrary.h" +#include "PWGDQ/Core/HistogramManager.h" +#include "PWGDQ/Core/HistogramsLibrary.h" +#include "PWGDQ/Core/VarManager.h" +#include "PWGDQ/DataModel/ReducedInfoTables.h" + #include "Common/CCDB/TriggerAliases.h" +#include "Common/Core/CollisionAssociation.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" #include "EventFiltering/filterTables.h" -#include "PWGDQ/DataModel/ReducedInfoTables.h" -#include "PWGDQ/Core/VarManager.h" -#include "PWGDQ/Core/HistogramManager.h" -#include "PWGDQ/Core/AnalysisCut.h" -#include "PWGDQ/Core/AnalysisCompositeCut.h" -#include "PWGDQ/Core/HistogramsLibrary.h" -#include "PWGDQ/Core/CutsLibrary.h" + +#include "CCDB/BasicCCDBManager.h" #include "CommonConstants/LHCConstants.h" -#include "Common/Core/CollisionAssociation.h" -#include "Common/DataModel/CollisionAssociationTables.h" #include "DataFormatsParameters/GRPMagField.h" #include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" #include "Field/MagneticField.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/DataTypes.h" +#include "Framework/runDataProcessing.h" + #include "TGeoGlobalMagField.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include using std::cout; using std::endl; @@ -83,9 +87,9 @@ DECLARE_SOA_COLUMN(IsDQBarrelSelected, isDQBarrelSelected, uint32_t); DECLARE_SOA_COLUMN(IsDQMuonSelected, isDQMuonSelected, uint32_t); DECLARE_SOA_COLUMN(IsDQEMuBarrelSelected, isDQEMuBarrelSelected, uint32_t); // for electron-muon pair DECLARE_SOA_COLUMN(IsDQEMuMuonSelected, isDQEMuMuonSelected, uint32_t); // for electron-muon pair -DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! Collision index -DECLARE_SOA_INDEX_COLUMN(Track, track); //! Track index -DECLARE_SOA_INDEX_COLUMN(FwdTrack, fwdtrack); //! FwdTrack index +DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! Collision index +DECLARE_SOA_INDEX_COLUMN(Track, track); //! Track index +DECLARE_SOA_INDEX_COLUMN(FwdTrack, fwdtrack); //! FwdTrack index } // namespace dqppfilter DECLARE_SOA_TABLE(DQEventCuts, "AOD", "DQEVENTCUTS", dqppfilter::IsDQEventSelected); @@ -160,7 +164,7 @@ struct DQEventSelectionTask { fHistMan->SetDefaultVarNames(VarManager::fgVariableNames, VarManager::fgVariableUnits); DefineHistograms(fHistMan, "Event_BeforeCuts;Event_AfterCuts;", fConfigHistClasses.value); // define all histograms - VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill + VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill fOutputList.setObject(fHistMan->GetMainHistogramList()); } } @@ -210,8 +214,8 @@ struct DQBarrelTrackSelection { Configurable fConfigQA{"cfgWithQA", false, "If true, fill QA histograms"}; Configurable fConfigHistClasses{"cfgHistClasses", "its,tpcpid,dca", "If true, fill QA histograms"}; Configurable fPropTrack{"cfgPropTrack", true, "Propgate tracks to associated collision to recalculate DCA and momentum vector"}; - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/i/iarsene/Calib/TPCpostCalib", "base path to the ccdb object"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/i/iarsene/Calib/TPCpostCalib", "base path to the ccdb object"}; Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable fConfigComputeTPCpostCalib{"cfgTPCpostCalib", false, "If true, compute TPC post-calibrated n-sigmas"}; @@ -266,7 +270,7 @@ struct DQBarrelTrackSelection { } DefineHistograms(fHistMan, cutNames.Data(), fConfigHistClasses.value); // define all histograms - VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill + VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill fOutputList.setObject(fHistMan->GetMainHistogramList()); // CCDB configuration @@ -384,7 +388,7 @@ struct DQMuonsSelection { Configurable fConfigQA{"cfgWithQA", false, "If true, fill QA histograms"}; Configurable fConfigHistClasses{"cfgHistClasses", "muon", "If true, fill QA histograms"}; Configurable fPropMuon{"cfgPropMuon", false, "Propgate muon tracks through absorber"}; - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; @@ -441,7 +445,7 @@ struct DQMuonsSelection { } DefineHistograms(fHistMan, cutNames.Data(), fConfigHistClasses.value); // define all histograms - VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill + VarManager::SetUseVars(fHistMan->GetUsedVars()); // provide the list of required variables so that VarManager knows what to fill fOutputList.setObject(fHistMan->GetMainHistogramList()); } } @@ -530,7 +534,7 @@ struct DQFilterPPTask { Configurable fConfigFilterLsMuonsPairs{"cfgWithMuonLS", "false", "Comma separated list of booleans for each trigger, If true, also select like sign (--/++) muon pairs"}; Configurable fConfigFilterLsElectronMuonsPairs{"cfgWithElectronMuonLS", "false", "Comma separated list of booleans for each trigger, If true, also select like sign (--/++) muon pairs"}; Configurable fPropMuon{"cfgPropMuon", false, "Propgate muon tracks through absorber"}; - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; @@ -539,21 +543,21 @@ struct DQFilterPPTask { int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. - int fNBarrelCuts; // number of barrel selections - int fNMuonCuts; // number of muon selections - int fNElectronMuonCuts; // number of electron-muon selections - std::vector fBarrelRunPairing; // bit map on whether the selections require pairing (barrel) - std::vector fMuonRunPairing; // bit map on whether the selections require pairing (muon) - std::vector fElectronMuonRunPairing; // bit map on whether the selections require pairing (e-mu) - std::vector fBarrelNreqObjs; // minimal number of tracks/pairs required (barrel) - std::vector fMuonNreqObjs; // minimal number of tracks/pairs required (muon) - std::vector fElectronMuonNreqObjs; // minimal number of electron-muon pairs required - std::map fBarrelPairCuts; // map of barrel pair cuts - std::map fMuonPairCuts; // map of muon pair cuts + int fNBarrelCuts; // number of barrel selections + int fNMuonCuts; // number of muon selections + int fNElectronMuonCuts; // number of electron-muon selections + std::vector fBarrelRunPairing; // bit map on whether the selections require pairing (barrel) + std::vector fMuonRunPairing; // bit map on whether the selections require pairing (muon) + std::vector fElectronMuonRunPairing; // bit map on whether the selections require pairing (e-mu) + std::vector fBarrelNreqObjs; // minimal number of tracks/pairs required (barrel) + std::vector fMuonNreqObjs; // minimal number of tracks/pairs required (muon) + std::vector fElectronMuonNreqObjs; // minimal number of electron-muon pairs required + std::map fBarrelPairCuts; // map of barrel pair cuts + std::map fMuonPairCuts; // map of muon pair cuts std::map fElectronMuonPairCuts; // map of electron-muon pair cuts - std::map fBarrelPairHistNames; // map with names of the barrel pairing histogram directories - std::map fMuonPairHistNames; // map with names of the muon pairing histogram directories - std::map fElectronMuonPairHistNames; // map with names of the electron-muon pairing histogram directories + std::map fBarrelPairHistNames; // map with names of the barrel pairing histogram directories + std::map fMuonPairHistNames; // map with names of the muon pairing histogram directories + std::map fElectronMuonPairHistNames; // map with names of the electron-muon pairing histogram directories std::map fFiltersMap; // map of filters for events that passed at least one filter std::map> fCEFPfilters; // map of CEFP filters for events that passed at least one filter @@ -771,7 +775,7 @@ struct DQFilterPPTask { if (objCountersBarrel[i] > 1) { // pairing has to be enabled and at least two tracks are needed pairingMask |= (static_cast(1) << i); } - objCountersBarrel[i] = 0; // reset counters for selections where pairing is needed (count pairs instead) + objCountersBarrel[i] = 0; // reset counters for selections where pairing is needed (count pairs instead) taggedCollisions[i].clear(); // empty the list of tagged collisions if pairing is needed (so we count just events with pairs or containing selected pair legs) } } @@ -848,7 +852,7 @@ struct DQFilterPPTask { if (objCountersMuon[i] > 1) { pairingMask |= (static_cast(1) << i); } - objCountersMuon[i] = 0; // reset counters for selections where pairing is needed (count pairs instead) + objCountersMuon[i] = 0; // reset counters for selections where pairing is needed (count pairs instead) taggedCollisions[i + fNBarrelCuts].clear(); // empty the list of tagged collisions if pairing is needed (so we count just events with pairs or containing selected pair legs) } } diff --git a/PWGDQ/Tasks/mchAlignRecord.cxx b/PWGDQ/Tasks/mchAlignRecord.cxx index 2f612493b6e..c3dbce0865f 100644 --- a/PWGDQ/Tasks/mchAlignRecord.cxx +++ b/PWGDQ/Tasks/mchAlignRecord.cxx @@ -14,63 +14,61 @@ /// /// \author Chi ZHANG, CEA-Saclay, chi.zhang@cern.ch -#include -#include -#include -#include -#include -#include -#include +#include "PWGDQ/Core/VarManager.h" + +#include "Common/DataModel/EventSelection.h" +#include "CCDB/BasicCCDBManager.h" +#include "CommonConstants/LHCConstants.h" +#include "CommonUtils/NameConf.h" +#include "DataFormatsMCH/Cluster.h" +#include "DataFormatsMCH/TrackMCH.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GRPGeomHelper.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsCommonDataFormats/AlignParam.h" +#include "DetectorsCommonDataFormats/DetID.h" +#include "DetectorsCommonDataFormats/DetectorNameConf.h" #include "Framework/AnalysisTask.h" +#include "Framework/CallbackService.h" +#include "Framework/Logger.h" #include "Framework/runDataProcessing.h" +#include "MCHAlign/Aligner.h" +#include "MCHBase/TrackerParam.h" +#include "MCHGeometryTransformer/Transformations.h" +#include "MCHTracking/Track.h" +#include "MCHTracking/TrackExtrap.h" +#include "MCHTracking/TrackFitter.h" +#include "MCHTracking/TrackParam.h" +#include "ReconstructionDataFormats/TrackMCHMID.h" #include +#include #include #include #include +#include +#include #include #include #include +#include #include #include #include #include #include #include -#include -#include -#include -#include -#include - -#include "CommonConstants/LHCConstants.h" -#include "CommonUtils/NameConf.h" -#include "Common/DataModel/EventSelection.h" -#include "PWGDQ/Core/VarManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DetectorsBase/GeometryManager.h" -#include "DetectorsBase/GRPGeomHelper.h" -#include "DetectorsBase/Propagator.h" -#include "Framework/Logger.h" -#include "Framework/CallbackService.h" -#include "CCDB/BasicCCDBManager.h" - -#include "MCHGeometryTransformer/Transformations.h" -#include "DataFormatsMCH/Cluster.h" -#include "DataFormatsMCH/TrackMCH.h" -#include "MCHTracking/Track.h" -#include "MCHTracking/TrackExtrap.h" -#include "MCHTracking/TrackParam.h" -#include "MCHTracking/TrackFitter.h" -#include "MCHBase/TrackerParam.h" -#include "ReconstructionDataFormats/TrackMCHMID.h" -#include "MCHAlign/Aligner.h" -#include "DetectorsCommonDataFormats/AlignParam.h" -#include "DetectorsCommonDataFormats/DetID.h" -#include "DetectorsCommonDataFormats/DetectorNameConf.h" +#include +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -105,13 +103,13 @@ struct mchAlignRecordTask { map transformNew; mch::geo::TransformationCreator transformation; - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; - Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable fFixChamber{"fix-chamber", "", "Fixing chamber"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; + Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable fFixChamber{"fix-chamber", "", "Fixing chamber"}; Configurable fDoNewGeo{"do-realign", false, "Transform to a given new geometry"}; Configurable fDoEvaluation{"do-evaluation", false, "Enable storage of residuals"}; - Configurable fConfigNewGeoFile{"new-geo", "o2sim_geometry-aligned.root", "New geometry for transformation"}; + Configurable fConfigNewGeoFile{"new-geo", "o2sim_geometry-aligned.root", "New geometry for transformation"}; Configurable fAllowedVarX{"variation-x", 2.0, "Allowed variation for x axis in cm"}; Configurable fAllowedVarY{"variation-y", 0.3, "Allowed variation for y axis in cm"}; Configurable fAllowedVarPhi{"variation-phi", 0.002, "Allowed variation for phi axis in rad"}; diff --git a/PWGDQ/Tasks/muonDCA.cxx b/PWGDQ/Tasks/muonDCA.cxx index b2031418d5c..897ed273322 100644 --- a/PWGDQ/Tasks/muonDCA.cxx +++ b/PWGDQ/Tasks/muonDCA.cxx @@ -13,14 +13,15 @@ /// \brief Task to compute and evaluate DCA quantities /// \author Nicolas Bizé , SUBATECH // -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "GlobalTracking/MatchGlobalFwd.h" +#include "PWGDQ/Core/VarManager.h" +#include "PWGDQ/DataModel/ReducedInfoTables.h" + #include "CCDB/BasicCCDBManager.h" #include "DataFormatsParameters/GRPMagField.h" -#include "PWGDQ/DataModel/ReducedInfoTables.h" -#include "PWGDQ/Core/VarManager.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "GlobalTracking/MatchGlobalFwd.h" using namespace o2; using namespace o2::framework; @@ -44,7 +45,7 @@ struct muonExtrap { Produces dcaTable; Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Service fCCDB; o2::parameters::GRPMagField* grpmag = nullptr; // for run 3, we access GRPMagField from GLO/Config/GRPMagField diff --git a/PWGDQ/Tasks/tableReader.cxx b/PWGDQ/Tasks/tableReader.cxx index ece46047109..102eb26100f 100644 --- a/PWGDQ/Tasks/tableReader.cxx +++ b/PWGDQ/Tasks/tableReader.cxx @@ -11,39 +11,44 @@ // // Contact: iarsene@cern.ch, i.c.arsene@fys.uio.no // -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "PWGDQ/DataModel/ReducedInfoTables.h" -#include "PWGDQ/Core/VarManager.h" -#include "PWGDQ/Core/HistogramManager.h" -#include "PWGDQ/Core/MixingHandler.h" -#include "PWGDQ/Core/AnalysisCut.h" #include "PWGDQ/Core/AnalysisCompositeCut.h" -#include "PWGDQ/Core/HistogramsLibrary.h" +#include "PWGDQ/Core/AnalysisCut.h" #include "PWGDQ/Core/CutsLibrary.h" +#include "PWGDQ/Core/DQMlResponse.h" +#include "PWGDQ/Core/HistogramManager.h" +#include "PWGDQ/Core/HistogramsLibrary.h" +#include "PWGDQ/Core/MixingHandler.h" #include "PWGDQ/Core/MixingLibrary.h" +#include "PWGDQ/Core/VarManager.h" +#include "PWGDQ/DataModel/ReducedInfoTables.h" + +#include "Common/CCDB/EventSelectionParams.h" + +#include "CCDB/BasicCCDBManager.h" #include "DataFormatsParameters/GRPMagField.h" -#include "Field/MagneticField.h" -#include "TGeoGlobalMagField.h" -#include "DetectorsBase/Propagator.h" +#include "DataFormatsParameters/GRPObject.h" #include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Field/MagneticField.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" #include "ITSMFTBase/DPLAlpideParam.h" -#include "Common/CCDB/EventSelectionParams.h" + +#include "TGeoGlobalMagField.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include using std::cout; using std::endl; @@ -157,14 +162,14 @@ struct AnalysisEventSelection { Produces hash; OutputObj fOutputList{"output"}; // TODO: Provide the mixing variables and binning directly via configurables (e.g. vectors of float) - Configurable fConfigMixingVariables{"cfgMixingVars", "", "Mixing configs separated by a comma, default no mixing"}; - Configurable fConfigEventCuts{"cfgEventCuts", "eventStandard", "Event selection"}; + Configurable fConfigMixingVariables{"cfgMixingVars", "", "Mixing configs separated by a comma, default no mixing"}; + Configurable fConfigEventCuts{"cfgEventCuts", "eventStandard", "Event selection"}; Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; Configurable fConfigRunZorro{"cfgRunZorro", false, "Enable event selection with zorro [WARNING: under debug, do not enable!]"}; Configurable fConfigITSROFrameStartBorderMargin{"ITSROFrameStartBorderMargin", -1, "Number of bcs at the start of ITS RO Frame border. Take from CCDB if -1"}; Configurable fConfigITSROFrameEndBorderMargin{"ITSROFrameEndBorderMargin", -1, "Number of bcs at the end of ITS RO Frame border. Take from CCDB if -1"}; Configurable fConfigAddEventHistogram{"cfgAddEventHistogram", "", "Comma separated list of histograms"}; - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; HistogramManager* fHistMan = nullptr; MixingHandler* fMixHandler = nullptr; @@ -318,12 +323,12 @@ struct AnalysisTrackSelection { // for candidate electron selection (+ eventual prefilter cuts) and other needs like quarkonium - hadron correlations // The user must ensure using them properly in the tasks downstream // NOTE: For now, the candidate electron cuts must be provided first, then followed by any other needed selections - Configurable fConfigCuts{"cfgTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; + Configurable fConfigCuts{"cfgTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; - Configurable fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"}; + Configurable fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"}; Configurable fConfigPrefilterCutId{"cfgPrefilterCutId", 32, "Id of the Prefilter track cut (starting at 0)"}; // In order to create another column prefilter (should be temporary before improving cut selection in configurables, then displaced to AnalysisPrefilterSelection) - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/z/zhxiong/TPCPID/PostCalib", "base path to the ccdb object"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/z/zhxiong/TPCPID/PostCalib", "base path to the ccdb object"}; Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable fConfigComputeTPCpostCalib{"cfgTPCpostCalib", false, "If true, compute TPC post-calibrated n-sigmas"}; Configurable fConfigRunPeriods{"cfgRunPeriods", "LHC22f", "run periods for used data"}; @@ -453,7 +458,7 @@ struct AnalysisTrackSelection { struct AnalysisMuonSelection { Produces muonSel; OutputObj fOutputList{"output"}; - Configurable fConfigCuts{"cfgMuonCuts", "muonQualityCuts", "Comma separated list of muon cuts"}; + Configurable fConfigCuts{"cfgMuonCuts", "muonQualityCuts", "Comma separated list of muon cuts"}; Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; Configurable fConfigAddMuonHistogram{"cfgAddMuonHistogram", "", "Comma separated list of histograms"}; @@ -673,14 +678,14 @@ struct AnalysisEventMixing { // single particle selection tasks to preserve the correspondence between the track cut name and its // bit position in the cuts bitmap // TODO: Create a configurable to specify exactly on which of the bits one should run the event mixing - Configurable fConfigTrackCuts{"cfgTrackCuts", "", "Comma separated list of barrel track cuts"}; - Configurable fConfigMuonCuts{"cfgMuonCuts", "", "Comma separated list of muon cuts"}; + Configurable fConfigTrackCuts{"cfgTrackCuts", "", "Comma separated list of barrel track cuts"}; + Configurable fConfigMuonCuts{"cfgMuonCuts", "", "Comma separated list of muon cuts"}; Configurable fConfigMixingDepth{"cfgMixingDepth", 100, "Number of Events stored for event mixing"}; Configurable fConfigAddEventMixingHistogram{"cfgAddEventMixingHistogram", "", "Comma separated list of histograms"}; Configurable ccdburl{"ccdburl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable fConfigAmbiguousHist{"cfgAmbiHist", false, "Enable Ambiguous histograms for time association studies"}; - Configurable ccdbPathFlow{"ccdb-path-flow", "Users/c/chizh/FlowResolution", "path to the ccdb object for flow resolution factors"}; + Configurable ccdbPathFlow{"ccdb-path-flow", "Users/c/chizh/FlowResolution", "path to the ccdb object for flow resolution factors"}; Configurable fConfigFlowReso{"cfgFlowReso", false, "Enable loading of flow resolution factors from CCDB"}; Configurable fConfigSingleMuCumulants{"cfgSingleMuCumulants", false, "Enable loading of flow resolution factors from CCDB"}; Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format"}; @@ -1023,12 +1028,12 @@ struct AnalysisSameEventPairing { int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. OutputObj fOutputList{"output"}; - Configurable fConfigTrackCuts{"cfgTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; - Configurable fConfigMuonCuts{"cfgMuonCuts", "", "Comma separated list of muon cuts"}; - Configurable fConfigPairCuts{"cfgPairCuts", "", "Comma separated list of pair cuts"}; - Configurable url{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable ccdbPath{"ccdb-path", "Users/lm", "base path to the ccdb object"}; - Configurable ccdbPathFlow{"ccdb-path-flow", "Users/c/chizh/FlowResolution", "path to the ccdb object for flow resolution factors"}; + Configurable fConfigTrackCuts{"cfgTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; + Configurable fConfigMuonCuts{"cfgMuonCuts", "", "Comma separated list of muon cuts"}; + Configurable fConfigPairCuts{"cfgPairCuts", "", "Comma separated list of pair cuts"}; + Configurable url{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable ccdbPath{"ccdb-path", "Users/lm", "base path to the ccdb object"}; + Configurable ccdbPathFlow{"ccdb-path-flow", "Users/c/chizh/FlowResolution", "path to the ccdb object for flow resolution factors"}; Configurable fConfigFlowReso{"cfgFlowReso", false, "Enable loading of flow resolution factors from CCDB"}; Configurable nolaterthan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable fConfigAddSEPHistogram{"cfgAddSEPHistogram", "", "Comma separated list of histograms"}; @@ -1050,6 +1055,12 @@ struct AnalysisSameEventPairing { Configurable fCenterMassEnergy{"energy", 13600, "Center of mass energy in GeV"}; Configurable fConfigCumulants{"cfgCumulants", false, "If true, fill Cumulants with Weights different than 0"}; Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format"}; + // ML inference + Configurable applyBDT{"applyBDT", false, "Flag to apply ML selections"}; + Configurable fConfigBdtCutsJSON{"fConfigBdtCutsJSON", "", "Additional list of BDT cuts in JSON format"}; + Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{"Users/j/jseo/ML/PbPbPsi/default/"}, "Paths of models on CCDB"}; + Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB"}; + Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; // Configurables to create output tree (flat tables or minitree) struct : ConfigurableGroup { @@ -1067,6 +1078,10 @@ struct AnalysisSameEventPairing { HistogramManager* fHistMan; + o2::analysis::DQMlResponse fDQMlResponse; + std::vector fOutputMlPsi2ee = {}; // TODO: check this is needed or not + o2::ccdb::CcdbApi ccdbApi; + // NOTE: The track filter produced by the barrel track selection contain a number of electron cut decisions and one last cut for hadrons used in the // dilepton - hadron task downstream. So the bit mask is required to select pairs just based on the electron cuts // TODO: provide as Configurable the list and names of the cuts which should be used in pairing @@ -1117,6 +1132,54 @@ struct AnalysisSameEventPairing { } } + if (applyBDT) { + // BDT cuts via JSON + std::vector binsMl; + o2::framework::LabeledArray cutsMl; + std::vector cutDirMl; + int nClassesMl = 1; + std::vector namesInputFeatures; + std::vector onnxFileNames; + + auto config = o2::aod::dqmlcuts::GetBdtScoreCutsAndConfigFromJSON(fConfigBdtCutsJSON.value.c_str()); + + if (std::holds_alternative(config)) { + auto& cfg = std::get(config); + binsMl = cfg.binsMl; + nClassesMl = 1; + cutsMl = cfg.cutsMl; + cutDirMl = cfg.cutDirs; + namesInputFeatures = cfg.inputFeatures; + onnxFileNames = cfg.onnxFiles; + fDQMlResponse.setBinsCent(cfg.binsCent); + fDQMlResponse.setBinsPt(cfg.binsPt); + fDQMlResponse.setCentType(cfg.centType); + LOG(info) << "Using BDT cuts for binary classification"; + } else { + auto& cfg = std::get(config); + binsMl = cfg.binsMl; + nClassesMl = 3; + cutsMl = cfg.cutsMl; + cutDirMl = cfg.cutDirs; + namesInputFeatures = cfg.inputFeatures; + onnxFileNames = cfg.onnxFiles; + fDQMlResponse.setBinsCent(cfg.binsCent); + fDQMlResponse.setBinsPt(cfg.binsPt); + fDQMlResponse.setCentType(cfg.centType); + LOG(info) << "Using BDT cuts for multiclass classification"; + } + + fDQMlResponse.configure(binsMl, cutsMl, cutDirMl, nClassesMl); + if (loadModelsFromCCDB) { + ccdbApi.init(ccdburl); + fDQMlResponse.setModelPathsCCDB(onnxFileNames, ccdbApi, modelPathsCCDB, timestampCCDB); + } else { + fDQMlResponse.setModelPathsLocal(onnxFileNames); + } + fDQMlResponse.cacheInputFeaturesIndices(namesInputFeatures); + fDQMlResponse.init(); + } + if (context.mOptions.get("processDecayToEESkimmed") || context.mOptions.get("processDecayToEESkimmedNoTwoProngFitter") || context.mOptions.get("processDecayToEESkimmedWithCov") || context.mOptions.get("processDecayToEESkimmedWithCovNoTwoProngFitter") || context.mOptions.get("processDecayToEEVertexingSkimmed") || context.mOptions.get("processVnDecayToEESkimmed") || context.mOptions.get("processDecayToEEPrefilterSkimmed") || context.mOptions.get("processDecayToEEPrefilterSkimmedNoTwoProngFitter") || context.mOptions.get("processDecayToEESkimmedWithColl") || context.mOptions.get("processDecayToEESkimmedWithCollNoTwoProngFitter") || context.mOptions.get("processDecayToPiPiSkimmed") || context.mOptions.get("processAllSkimmed")) { TString cutNames = fConfigTrackCuts.value; if (!cutNames.IsNull()) { // if track cuts @@ -1313,6 +1376,8 @@ struct AnalysisSameEventPairing { dileptonMiniTree.reserve(1); } + bool isSelectedBDT = false; + if (fConfigMultDimuons.value) { uint32_t mult_dimuons = 0; @@ -1391,6 +1456,43 @@ struct AnalysisSameEventPairing { } } if constexpr ((TPairType == pairTypeEE) && (TTrackFillMap & VarManager::ObjTypes::ReducedTrackBarrelPID) > 0) { + if (applyBDT) { + std::vector dqInputFeatures = fDQMlResponse.getInputFeatures(t1, t2, VarManager::fgValues); + + if (dqInputFeatures.empty()) { + LOG(fatal) << "Input features for ML selection are empty! Please check your configuration."; + return; + } + + int modelIndex = -1; + const auto& binsCent = fDQMlResponse.getBinsCent(); + const auto& binsPt = fDQMlResponse.getBinsPt(); + const std::string& centType = fDQMlResponse.getCentType(); + + if ("kCentFT0C" == centType) { + modelIndex = o2::aod::dqmlcuts::getMlBinIndex(VarManager::fgValues[VarManager::kCentFT0C], VarManager::fgValues[VarManager::kPt], binsCent, binsPt); + } else if ("kCentFT0A" == centType) { + modelIndex = o2::aod::dqmlcuts::getMlBinIndex(VarManager::fgValues[VarManager::kCentFT0A], VarManager::fgValues[VarManager::kPt], binsCent, binsPt); + } else if ("kCentFT0M" == centType) { + modelIndex = o2::aod::dqmlcuts::getMlBinIndex(VarManager::fgValues[VarManager::kCentFT0M], VarManager::fgValues[VarManager::kPt], binsCent, binsPt); + } else { + LOG(fatal) << "Unknown centrality estimation type: " << centType; + return; + } + + if (modelIndex < 0) { + LOG(debug) << "Ml index is negative! This means that the centrality/pt is not in the range of the model bins."; + continue; + } + + LOG(debug) << "Model index: " << modelIndex << ", pT: " << VarManager::fgValues[VarManager::kPt] << ", centrality (kCentFT0C): " << VarManager::fgValues[VarManager::kCentFT0C]; + isSelectedBDT = fDQMlResponse.isSelectedMl(dqInputFeatures, modelIndex, fOutputMlPsi2ee); + VarManager::FillBdtScore(fOutputMlPsi2ee); // TODO: check if this is needed or not + } + + if (applyBDT && !isSelectedBDT) + continue; + if (fConfigFlatTables.value) { dielectronAllList(VarManager::fgValues[VarManager::kMass], VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kEta], VarManager::fgValues[VarManager::kPhi], t1.sign() + t2.sign(), dileptonFilterMap, dileptonMcDecision, t1.pt(), t1.eta(), t1.phi(), t1.itsClusterMap(), t1.itsChi2NCl(), t1.tpcNClsCrossedRows(), t1.tpcNClsFound(), t1.tpcChi2NCl(), t1.dcaXY(), t1.dcaZ(), t1.tpcSignal(), t1.tpcNSigmaEl(), t1.tpcNSigmaPi(), t1.tpcNSigmaPr(), t1.beta(), t1.tofNSigmaEl(), t1.tofNSigmaPi(), t1.tofNSigmaPr(), @@ -1464,6 +1566,9 @@ struct AnalysisSameEventPairing { } } + if (applyBDT && !isSelectedBDT) + continue; + int iCut = 0; for (int icut = 0; icut < ncuts; icut++) { if (twoTrackFilter & (static_cast(1) << icut)) { @@ -1738,7 +1843,7 @@ struct AnalysisDileptonHadron { OutputObj fOutputList{"output"}; // TODO: For now this is only used to determine the position in the filter bit map for the hadron cut - Configurable fConfigTrackCuts{"cfgLeptonCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; + Configurable fConfigTrackCuts{"cfgLeptonCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; // comment: add list of subgroups (must define subgroups under ) Configurable fConfigAddDileptonHadHistogram{"cfgAddDileptonHadHistogram", "", "Comma separated list of histograms"}; Configurable fConfigMixingDepth{"cfgMixingDepth", 5, "Event mixing pool depth"}; diff --git a/PWGDQ/Tasks/tableReader_withAssoc.cxx b/PWGDQ/Tasks/tableReader_withAssoc.cxx index d6b29b461d2..ae6c450ac3e 100644 --- a/PWGDQ/Tasks/tableReader_withAssoc.cxx +++ b/PWGDQ/Tasks/tableReader_withAssoc.cxx @@ -12,51 +12,55 @@ // Contact: iarsene@cern.ch, i.c.arsene@fys.uio.no // Configurable workflow for running several DQ or other PWG analyses +#include "PWGDQ/Core/AnalysisCompositeCut.h" +#include "PWGDQ/Core/AnalysisCut.h" +#include "PWGDQ/Core/CutsLibrary.h" +#include "PWGDQ/Core/DQMlResponse.h" +#include "PWGDQ/Core/HistogramManager.h" +#include "PWGDQ/Core/HistogramsLibrary.h" +#include "PWGDQ/Core/MixingHandler.h" +#include "PWGDQ/Core/MixingLibrary.h" +#include "PWGDQ/Core/VarManager.h" +#include "PWGDQ/DataModel/ReducedInfoTables.h" + +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/Core/TableHelper.h" + +#include "CCDB/BasicCCDBManager.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Field/MagneticField.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/Configurable.h" +#include "Framework/OutputObjHeader.h" +#include "Framework/runDataProcessing.h" +#include "ITSMFTBase/DPLAlpideParam.h" + +#include "TGeoGlobalMagField.h" +#include +#include +#include +#include +#include +#include + +#include #include #include #include #include +#include +#include #include -#include -#include -#include #include -#include #include -#include #include -#include -#include -#include -#include -#include -#include -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/AnalysisHelpers.h" -#include "Framework/Configurable.h" -#include "Framework/OutputObjHeader.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "PWGDQ/DataModel/ReducedInfoTables.h" -#include "PWGDQ/Core/VarManager.h" -#include "PWGDQ/Core/HistogramManager.h" -#include "PWGDQ/Core/MixingHandler.h" -#include "PWGDQ/Core/AnalysisCut.h" -#include "PWGDQ/Core/AnalysisCompositeCut.h" -#include "PWGDQ/Core/HistogramsLibrary.h" -#include "PWGDQ/Core/CutsLibrary.h" -#include "PWGDQ/Core/MixingLibrary.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "Field/MagneticField.h" -#include "TGeoGlobalMagField.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "Common/Core/TableHelper.h" -#include "ITSMFTBase/DPLAlpideParam.h" -#include "Common/CCDB/EventSelectionParams.h" +#include using std::cout; using std::endl; @@ -94,6 +98,7 @@ DECLARE_SOA_COLUMN(TauxyBcandidate, tauxyBcandidate, float); DECLARE_SOA_COLUMN(TauzBcandidate, tauzBcandidate, float); DECLARE_SOA_COLUMN(CosPBcandidate, cosPBcandidate, float); DECLARE_SOA_COLUMN(Chi2Bcandidate, chi2Bcandidate, float); +DECLARE_SOA_COLUMN(Ptassoc, ptassoc, float); DECLARE_SOA_COLUMN(PINassoc, pINassoc, float); DECLARE_SOA_COLUMN(Etaassoc, etaassoc, float); DECLARE_SOA_COLUMN(Ptpair, ptpair, float); @@ -139,6 +144,9 @@ DECLARE_SOA_COLUMN(LxyeePoleMass, lxyJPsi2eePoleMass, float); DECLARE_SOA_COLUMN(Lzee, lzJPsi2ee, float); DECLARE_SOA_COLUMN(AmbiguousInBunchPairs, AmbiguousJpsiPairsInBunch, bool); DECLARE_SOA_COLUMN(AmbiguousOutOfBunchPairs, AmbiguousJpsiPairsOutOfBunch, bool); +// Candidate columns for JPsi/muon correlations +DECLARE_SOA_COLUMN(DeltaEta, deltaEta, float); +DECLARE_SOA_COLUMN(DeltaPhi, deltaPhi, float); } // namespace dqanalysisflags DECLARE_SOA_TABLE(EventCuts, "AOD", "DQANAEVCUTSA", dqanalysisflags::IsEventSelected); //! joinable to ReducedEvents @@ -163,12 +171,16 @@ DECLARE_SOA_TABLE(BmesonCandidates, "AOD", "DQBMESONSA", dqanalysisflags::TPCNclsassoc, dqanalysisflags::TPCNclsleg1, dqanalysisflags::TPCNclsleg2, dqanalysisflags::TPCChi2assoc, dqanalysisflags::TPCChi2leg1, dqanalysisflags::TPCChi2leg2, dqanalysisflags::IsJpsiFromBSelected, dqanalysisflags::IsBarrelSelected); +DECLARE_SOA_TABLE(JPsiMuonCandidates, "AOD", "DQJPSIMUONA", + dqanalysisflags::DeltaEta, dqanalysisflags::DeltaPhi, + dqanalysisflags::MassDileptonCandidate, dqanalysisflags::Ptpair, dqanalysisflags::Etapair, dqanalysisflags::Ptassoc, dqanalysisflags::Etaassoc); DECLARE_SOA_TABLE(JPsieeCandidates, "AOD", "DQPSEUDOPROPER", dqanalysisflags::Massee, dqanalysisflags::Ptee, dqanalysisflags::Lxyee, dqanalysisflags::LxyeePoleMass, dqanalysisflags::Lzee, dqanalysisflags::AmbiguousInBunchPairs, dqanalysisflags::AmbiguousOutOfBunchPairs); } // namespace o2::aod // Declarations of various short names using MyEvents = soa::Join; using MyEventsMultExtra = soa::Join; +using MyEventsMultExtraQVector = soa::Join; using MyEventsZdc = soa::Join; using MyEventsMultExtraZdc = soa::Join; using MyEventsSelected = soa::Join; @@ -177,7 +189,8 @@ using MyEventsVtxCovSelectedMultExtra = soa::Join; using MyEventsVtxCov = soa::Join; using MyEventsVtxCovSelected = soa::Join; -using MyEventsVtxCovSelectedQvector = soa::Join; +using MyEventsVtxCovSelectedQvector = soa::Join; +using MyEventsVtxCovSelectedQvectorWithHash = soa::Join; using MyEventsVtxCovZdcSelected = soa::Join; using MyEventsVtxCovZdcSelectedMultExtra = soa::Join; using MyEventsQvector = soa::Join; @@ -202,8 +215,11 @@ using MyMuonTracksSelectedWithColl = soa::Join fOutputList{"output"}; // TODO: Provide the mixing variables and binning directly via configurables (e.g. vectors of float) - Configurable fConfigMixingVariables{"cfgMixingVars", "", "Mixing configs separated by a comma, default no mixing"}; - Configurable fConfigEventCuts{"cfgEventCuts", "eventStandard", "Event selection"}; - Configurable fConfigEventCutsJSON{"cfgEventCutsJSON", "", "Additional event cuts specified in JSON format"}; + Configurable fConfigMixingVariables{"cfgMixingVars", "", "Mixing configs separated by a comma, default no mixing"}; + Configurable fConfigEventCuts{"cfgEventCuts", "eventStandard", "Event selection"}; + Configurable fConfigEventCutsJSON{"cfgEventCutsJSON", "", "Additional event cuts specified in JSON format"}; Configurable fConfigAddEventHistogram{"cfgAddEventHistogram", "", "Comma separated list of histograms"}; Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Add event histograms defined via JSON formatting (see HistogramsLibrary)"}; Configurable fConfigQA{"cfgQA", true, "If true, QA histograms will be created and filled"}; @@ -255,7 +271,7 @@ struct AnalysisEventSelection { Configurable fConfigCheckSplitCollisions{"cfgCheckSplitCollisions", false, "If true, run the split collision check and fill histograms"}; Configurable fConfigRunZorro{"cfgRunZorro", false, "Enable event selection with zorro [WARNING: under debug, do not enable!]"}; - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; HistogramManager* fHistMan = nullptr; @@ -344,7 +360,7 @@ struct AnalysisEventSelection { void runEventSelection(TEvents const& events) { if (events.size() > 0 && events.begin().runNumber() != fCurrentRun) { - std::map metadataRCT, header; + std::map metadataRCT, header; header = fCCDBApi.retrieveHeaders(Form("RCT/Info/RunInformation/%i", events.begin().runNumber()), metadataRCT, -1); uint64_t sor = std::atol(header["SOR"].c_str()); uint64_t eor = std::atol(header["EOR"].c_str()); @@ -535,15 +551,15 @@ struct AnalysisTrackSelection { Produces trackAmbiguities; OutputObj fOutputList{"output"}; - Configurable fConfigCuts{"cfgTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; + Configurable fConfigCuts{"cfgTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; Configurable fConfigCutsJSON{"cfgBarrelTrackCutsJSON", "", "Additional list of barrel track cuts in JSON format"}; - Configurable fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"}; + Configurable fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"}; Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format"}; Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; Configurable fConfigPublishAmbiguity{"cfgPublishAmbiguity", true, "If true, publish ambiguity table and fill QA histograms"}; - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/z/zhxiong/TPCPID/PostCalib", "base path to the ccdb object"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/z/zhxiong/TPCPID/PostCalib", "base path to the ccdb object"}; Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable fConfigComputeTPCpostCalib{"cfgTPCpostCalib", false, "If true, compute TPC post-calibrated n-sigmas"}; @@ -641,7 +657,7 @@ struct AnalysisTrackSelection { LOGF(fatal, "GRP object is not available in CCDB at timestamp=%llu", events.begin().timestamp()); } - std::map metadataRCT, header; + std::map metadataRCT, header; header = fCCDBApi.retrieveHeaders(Form("RCT/Info/RunInformation/%i", events.begin().runNumber()), metadataRCT, -1); uint64_t sor = std::atol(header["SOR"].c_str()); uint64_t eor = std::atol(header["EOR"].c_str()); @@ -787,14 +803,14 @@ struct AnalysisMuonSelection { Produces muonAmbiguities; OutputObj fOutputList{"output"}; - Configurable fConfigCuts{"cfgMuonCuts", "muonQualityCuts", "Comma separated list of muon cuts"}; + Configurable fConfigCuts{"cfgMuonCuts", "muonQualityCuts", "Comma separated list of muon cuts"}; Configurable fConfigCutsJSON{"cfgMuonCutsJSON", "", "Additional list of muon cuts in JSON format"}; Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; Configurable fConfigAddMuonHistogram{"cfgAddMuonHistogram", "", "Comma separated list of histograms"}; Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format"}; Configurable fConfigPublishAmbiguity{"cfgPublishAmbiguity", true, "If true, publish ambiguity table and fill QA histograms"}; - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable fConfigGeoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; @@ -1200,9 +1216,9 @@ struct AnalysisSameEventPairing { OutputObj fOutputList{"output"}; struct : ConfigurableGroup { - Configurable track{"cfgTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; - Configurable muon{"cfgMuonCuts", "", "Comma separated list of muon cuts"}; - Configurable pair{"cfgPairCuts", "", "Comma separated list of pair cuts"}; + Configurable track{"cfgTrackCuts", "jpsiO2MCdebugCuts2", "Comma separated list of barrel track cuts"}; + Configurable muon{"cfgMuonCuts", "", "Comma separated list of muon cuts"}; + Configurable pair{"cfgPairCuts", "", "Comma separated list of pair cuts"}; Configurable event{"cfgRemoveCollSplittingCandidates", false, "If true, remove collision splitting candidates as determined by the event selection task upstream"}; // TODO: Add pair cuts via JSON } fConfigCuts; @@ -1214,7 +1230,7 @@ struct AnalysisSameEventPairing { Configurable fConfigQA{"cfgQA", true, "If true, fill output histograms"}; struct : ConfigurableGroup { - Configurable url{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable url{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable grpMagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; @@ -1236,6 +1252,14 @@ struct AnalysisSameEventPairing { Configurable propTrack{"cfgPropTrack", true, "Propgate tracks to associated collision to recalculate DCA and momentum vector"}; Configurable useRemoteCollisionInfo{"cfgUseRemoteCollisionInfo", false, "Use remote collision information from CCDB"}; } fConfigOptions; + struct : ConfigurableGroup { + Configurable applyBDT{"applyBDT", false, "Flag to apply ML selections"}; + Configurable fConfigBdtCutsJSON{"fConfigBdtCutsJSON", "", "Additional list of BDT cuts in JSON format"}; + + Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{"Users/j/jseo/ML/PbPbPsi/default/"}, "Paths of models on CCDB"}; + Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB"}; + Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; + } fConfigML; Service fCCDB; o2::ccdb::CcdbApi fCCDBApi; @@ -1244,6 +1268,9 @@ struct AnalysisSameEventPairing { HistogramManager* fHistMan; + o2::analysis::DQMlResponse fDQMlResponse; + std::vector fOutputMlPsi2ee = {}; // TODO: check this is needed or not + // keep histogram class names in maps, so we don't have to buld their names in the pair loops std::map> fTrackHistNames; std::map> fMuonHistNames; @@ -1272,7 +1299,7 @@ struct AnalysisSameEventPairing { { LOG(info) << "Starting initialization of AnalysisSameEventPairing (idstoreh)"; fEnableBarrelHistos = context.mOptions.get("processAllSkimmed") || context.mOptions.get("processBarrelOnlySkimmed") || context.mOptions.get("processBarrelOnlyWithCollSkimmed") || context.mOptions.get("processBarrelOnlySkimmedNoCov") || context.mOptions.get("processBarrelOnlySkimmedNoCovWithMultExtra") || context.mOptions.get("processBarrelOnlyWithQvectorCentrSkimmedNoCov"); - fEnableBarrelMixingHistos = context.mOptions.get("processMixingAllSkimmed") || context.mOptions.get("processMixingBarrelSkimmed"); + fEnableBarrelMixingHistos = context.mOptions.get("processMixingAllSkimmed") || context.mOptions.get("processMixingBarrelSkimmed") || context.mOptions.get("processMixingBarrelSkimmedFlow"); fEnableMuonHistos = context.mOptions.get("processAllSkimmed") || context.mOptions.get("processMuonOnlySkimmed") || context.mOptions.get("processMuonOnlySkimmedMultExtra") || context.mOptions.get("processMixingMuonSkimmed"); fEnableMuonMixingHistos = context.mOptions.get("processMixingAllSkimmed") || context.mOptions.get("processMixingMuonSkimmed"); @@ -1311,6 +1338,54 @@ struct AnalysisSameEventPairing { objArrayMuonCuts = muonCutsStr.Tokenize(","); } + if (fConfigML.applyBDT) { + // BDT cuts via JSON + std::vector binsMl; + o2::framework::LabeledArray cutsMl; + std::vector cutDirMl; + int nClassesMl = 1; + std::vector namesInputFeatures; + std::vector onnxFileNames; + + auto config = o2::aod::dqmlcuts::GetBdtScoreCutsAndConfigFromJSON(fConfigML.fConfigBdtCutsJSON.value.c_str()); + + if (std::holds_alternative(config)) { + auto& cfg = std::get(config); + binsMl = cfg.binsMl; + nClassesMl = 1; + cutsMl = cfg.cutsMl; + cutDirMl = cfg.cutDirs; + namesInputFeatures = cfg.inputFeatures; + onnxFileNames = cfg.onnxFiles; + fDQMlResponse.setBinsCent(cfg.binsCent); + fDQMlResponse.setBinsPt(cfg.binsPt); + fDQMlResponse.setCentType(cfg.centType); + LOG(info) << "Using BDT cuts for binary classification"; + } else { + auto& cfg = std::get(config); + binsMl = cfg.binsMl; + nClassesMl = 3; + cutsMl = cfg.cutsMl; + cutDirMl = cfg.cutDirs; + namesInputFeatures = cfg.inputFeatures; + onnxFileNames = cfg.onnxFiles; + fDQMlResponse.setBinsCent(cfg.binsCent); + fDQMlResponse.setBinsPt(cfg.binsPt); + fDQMlResponse.setCentType(cfg.centType); + LOG(info) << "Using BDT cuts for multiclass classification"; + } + + fDQMlResponse.configure(binsMl, cutsMl, cutDirMl, nClassesMl); + if (fConfigML.loadModelsFromCCDB) { + fCCDBApi.init(fConfigCCDB.url); + fDQMlResponse.setModelPathsCCDB(onnxFileNames, fCCDBApi, fConfigML.modelPathsCCDB, fConfigML.timestampCCDB); + } else { + fDQMlResponse.setModelPathsLocal(onnxFileNames); + } + fDQMlResponse.cacheInputFeaturesIndices(namesInputFeatures); + fDQMlResponse.init(); + } + // get the barrel track selection cuts string tempCuts; getTaskOptionValue(context, "analysis-track-selection", "cfgTrackCuts", tempCuts, false); @@ -1617,6 +1692,7 @@ struct AnalysisSameEventPairing { constexpr bool eventHasQvector = ((TEventFillMap & VarManager::ObjTypes::ReducedEventQvector) > 0); constexpr bool eventHasQvectorCentr = ((TEventFillMap & VarManager::ObjTypes::CollisionQvect) > 0); constexpr bool trackHasCov = ((TTrackFillMap & VarManager::ObjTypes::TrackCov) > 0 || (TTrackFillMap & VarManager::ObjTypes::ReducedTrackBarrelCov) > 0); + bool isSelectedBDT = false; for (auto& event : events) { if (!event.isEventSelected_bit(0)) { @@ -1697,6 +1773,43 @@ struct AnalysisSameEventPairing { if constexpr (trackHasCov && TTwoProngFitter) { dielectronsExtraList(t1.globalIndex(), t2.globalIndex(), VarManager::fgValues[VarManager::kVertexingTauzProjected], VarManager::fgValues[VarManager::kVertexingLzProjected], VarManager::fgValues[VarManager::kVertexingLxyProjected]); if constexpr ((TTrackFillMap & VarManager::ObjTypes::ReducedTrackBarrelPID) > 0) { + if (fConfigML.applyBDT) { + std::vector dqInputFeatures = fDQMlResponse.getInputFeatures(t1, t2, VarManager::fgValues); + + if (dqInputFeatures.empty()) { + LOG(fatal) << "Input features for ML selection are empty! Please check your configuration."; + return; + } + + int modelIndex = -1; + const auto& binsCent = fDQMlResponse.getBinsCent(); + const auto& binsPt = fDQMlResponse.getBinsPt(); + const std::string& centType = fDQMlResponse.getCentType(); + + if ("kCentFT0C" == centType) { + modelIndex = o2::aod::dqmlcuts::getMlBinIndex(VarManager::fgValues[VarManager::kCentFT0C], VarManager::fgValues[VarManager::kPt], binsCent, binsPt); + } else if ("kCentFT0A" == centType) { + modelIndex = o2::aod::dqmlcuts::getMlBinIndex(VarManager::fgValues[VarManager::kCentFT0A], VarManager::fgValues[VarManager::kPt], binsCent, binsPt); + } else if ("kCentFT0M" == centType) { + modelIndex = o2::aod::dqmlcuts::getMlBinIndex(VarManager::fgValues[VarManager::kCentFT0M], VarManager::fgValues[VarManager::kPt], binsCent, binsPt); + } else { + LOG(fatal) << "Unknown centrality estimation type: " << centType; + return; + } + + if (modelIndex < 0) { + LOG(info) << "Ml index is negative! This means that the centrality/pt is not in the range of the model bins."; + continue; + } + + LOG(debug) << "Model index: " << modelIndex << ", pT: " << VarManager::fgValues[VarManager::kPt] << ", centrality (kCentFT0C): " << VarManager::fgValues[VarManager::kCentFT0C]; + isSelectedBDT = fDQMlResponse.isSelectedMl(dqInputFeatures, modelIndex, fOutputMlPsi2ee); + VarManager::FillBdtScore(fOutputMlPsi2ee); // TODO: check if this is needed or not + } + + if (fConfigML.applyBDT && !isSelectedBDT) + continue; + if (fConfigOptions.flatTables.value) { dielectronAllList(VarManager::fgValues[VarManager::kMass], VarManager::fgValues[VarManager::kPt], VarManager::fgValues[VarManager::kEta], VarManager::fgValues[VarManager::kPhi], t1.sign() + t2.sign(), twoTrackFilter, dileptonMcDecision, t1.pt(), t1.eta(), t1.phi(), t1.itsClusterMap(), t1.itsChi2NCl(), t1.tpcNClsCrossedRows(), t1.tpcNClsFound(), t1.tpcChi2NCl(), t1.dcaXY(), t1.dcaZ(), t1.tpcSignal(), t1.tpcNSigmaEl(), t1.tpcNSigmaPi(), t1.tpcNSigmaPr(), t1.beta(), t1.tofNSigmaEl(), t1.tofNSigmaPi(), t1.tofNSigmaPr(), @@ -1821,6 +1934,10 @@ struct AnalysisSameEventPairing { bool isLeg1Ambi = false; bool isLeg2Ambi = false; bool isAmbiExtra = false; + + if (fConfigML.applyBDT && !isSelectedBDT) + continue; + for (int icut = 0; icut < ncuts; icut++) { if (twoTrackFilter & (static_cast(1) << icut)) { isAmbiInBunch = (twoTrackFilter & (static_cast(1) << 28)) || (twoTrackFilter & (static_cast(1) << 29)); @@ -2114,6 +2231,13 @@ struct AnalysisSameEventPairing { runSameEventPairing(events, trackAssocsPerCollision, barrelAssocs, barrelTracks); } + void processBarrelOnlySkimmedFlow(MyEventsVtxCovSelectedQvector const& events, + soa::Join const& barrelAssocs, + MyBarrelTracksWithAmbiguities const& barrelTracks) + { + runSameEventPairing(events, trackAssocsPerCollision, barrelAssocs, barrelTracks); + } + void processBarrelOnlySkimmedNoCov(MyEventsSelected const& events, soa::Join const& barrelAssocs, MyBarrelTracksWithAmbiguities const& barrelTracks) @@ -2168,6 +2292,12 @@ struct AnalysisSameEventPairing { runSameSideMixing(events, trackAssocs, tracks, trackAssocsPerCollision); } + void processMixingBarrelSkimmedFlow(soa::Filtered& events, + soa::Join const& trackAssocs, aod::ReducedTracks const& tracks) + { + runSameSideMixing(events, trackAssocs, tracks, trackAssocsPerCollision); + } + void processMixingMuonSkimmed(soa::Filtered& events, soa::Join const& muonAssocs, MyMuonTracksWithCovWithAmbiguities const& muons) { @@ -2185,10 +2315,12 @@ struct AnalysisSameEventPairing { PROCESS_SWITCH(AnalysisSameEventPairing, processBarrelOnlySkimmedNoCov, "Run barrel only pairing (no covariances), with skimmed tracks and with collision information", false); PROCESS_SWITCH(AnalysisSameEventPairing, processBarrelOnlySkimmedNoCovWithMultExtra, "Run barrel only pairing (no covariances), with skimmed tracks, with collision information, with MultsExtra", false); PROCESS_SWITCH(AnalysisSameEventPairing, processBarrelOnlyWithQvectorCentrSkimmedNoCov, "Run barrel only pairing (no covariances), with skimmed tracks, with Qvector from central framework", false); + PROCESS_SWITCH(AnalysisSameEventPairing, processBarrelOnlySkimmedFlow, "Run barrel only pairing, with skimmed tracks and with flow", false); PROCESS_SWITCH(AnalysisSameEventPairing, processMuonOnlySkimmed, "Run muon only pairing, with skimmed tracks", false); PROCESS_SWITCH(AnalysisSameEventPairing, processMuonOnlySkimmedMultExtra, "Run muon only pairing, with skimmed tracks", false); PROCESS_SWITCH(AnalysisSameEventPairing, processMixingAllSkimmed, "Run all types of mixed pairing, with skimmed tracks/muons", false); PROCESS_SWITCH(AnalysisSameEventPairing, processMixingBarrelSkimmed, "Run barrel type mixing pairing, with skimmed tracks", false); + PROCESS_SWITCH(AnalysisSameEventPairing, processMixingBarrelSkimmedFlow, "Run barrel type mixing pairing, with flow, with skimmed tracks", false); PROCESS_SWITCH(AnalysisSameEventPairing, processMixingMuonSkimmed, "Run muon type mixing pairing, with skimmed muons", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDummy, "Dummy function, enabled only if none of the others are enabled", false); }; @@ -2206,13 +2338,13 @@ struct AnalysisAsymmetricPairing { OutputObj fOutputList{"output"}; // Configurables - Configurable fConfigLegCuts{"cfgLegCuts", "", ":[:],[:[:],...]"}; + Configurable fConfigLegCuts{"cfgLegCuts", "", ":[:],[:[:],...]"}; Configurable fConfigLegAFilterMask{"cfgLegAFilterMask", 0, "Filter mask corresponding to cuts in track-selection"}; Configurable fConfigLegBFilterMask{"cfgLegBFilterMask", 0, "Filter mask corresponding to cuts in track-selection"}; Configurable fConfigLegCFilterMask{"cfgLegCFilterMask", 0, "Filter mask corresponding to cuts in track-selection"}; - Configurable fConfigCommonTrackCuts{"cfgCommonTrackCuts", "", "Comma separated list of cuts to be applied to all legs"}; - Configurable fConfigPairCuts{"cfgPairCuts", "", "Comma separated list of pair cuts"}; - Configurable fConfigPairCutsJSON{"cfgPairCutsJSON", "", "Additional list of pair cuts in JSON format"}; + Configurable fConfigCommonTrackCuts{"cfgCommonTrackCuts", "", "Comma separated list of cuts to be applied to all legs"}; + Configurable fConfigPairCuts{"cfgPairCuts", "", "Comma separated list of pair cuts"}; + Configurable fConfigPairCutsJSON{"cfgPairCutsJSON", "", "Additional list of pair cuts in JSON format"}; Configurable fConfigSkipAmbiguousIdCombinations{"cfgSkipAmbiguousIdCombinations", true, "Choose whether to skip pairs/triples which pass a stricter combination of cuts, e.g. KKPi triplets for D+ -> KPiPi"}; Configurable fConfigHistogramSubgroups{"cfgAsymmetricPairingHistogramsSubgroups", "barrel,vertexing", "Comma separated list of asymmetric-pairing histogram subgroups"}; @@ -2221,7 +2353,7 @@ struct AnalysisAsymmetricPairing { Configurable fConfigReflectedHistograms{"cfgReflectedHistograms", false, "Include separate histograms for pairs which are reflections of previously counted pairs"}; Configurable fConfigAddJSONHistograms{"cfgAddJSONHistograms", "", "Histograms in JSON format"}; - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable fConfigGRPMagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable fConfigUseRemoteField{"cfgUseRemoteField", false, "Choose whether to fetch the magnetic field from ccdb or set it manually"}; Configurable fConfigMagField{"cfgMagField", 5.0f, "Manually set magnetic field"}; @@ -2928,9 +3060,10 @@ struct AnalysisAsymmetricPairing { // tracks passing the fConfigTrackCut cut. The dileptons cuts from the same-event pairing task are auto-detected struct AnalysisDileptonTrack { Produces BmesonsTable; + Produces DileptonTrackTable; OutputObj fOutputList{"output"}; - Configurable fConfigTrackCuts{"cfgTrackCuts", "kaonPID", "Comma separated list of cuts for the track to be correlated with the dileptons"}; + Configurable fConfigTrackCuts{"cfgTrackCuts", "kaonPID", "Comma separated list of cuts for the track to be correlated with the dileptons"}; Configurable fConfigDileptonLowMass{"cfgDileptonLowMass", 2.8, "Low mass cut for the dileptons used in analysis"}; Configurable fConfigDileptonHighMass{"cfgDileptonHighMass", 3.2, "High mass cut for the dileptons used in analysis"}; Configurable fConfigDileptonpTCut{"cfgDileptonpTCut", 0.0, "pT cut for dileptons used in the triplet vertexing"}; @@ -2945,7 +3078,7 @@ struct AnalysisDileptonTrack { Configurable fConfigGRPmagPath{"cfgGrpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable fConfigMagField{"cfgMagField", 5.0f, "Manually set magnetic field"}; - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable fConfigGeoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; @@ -3349,6 +3482,8 @@ struct AnalysisDileptonTrack { VarManager::FillDileptonHadron(dilepton, track, fValuesHadron); VarManager::FillDileptonTrackVertexing(event, lepton1, lepton2, track, fValuesHadron); + // Fill table for correlation analysis + DileptonTrackTable(fValuesHadron[VarManager::kDeltaEta], fValuesHadron[VarManager::kDeltaPhi], dilepton.mass(), dilepton.pt(), dilepton.eta(), track.pt(), track.eta()); } // Fill histograms for the triplets diff --git a/PWGDQ/Tasks/taskJpsiHf.cxx b/PWGDQ/Tasks/taskJpsiHf.cxx index 79d9348940a..ef415259a02 100644 --- a/PWGDQ/Tasks/taskJpsiHf.cxx +++ b/PWGDQ/Tasks/taskJpsiHf.cxx @@ -97,15 +97,16 @@ struct taskJPsiHf { float deltaRap = -999; float deltaPhi = -999; - for (auto& dilepton : dileptons) { + for (auto const& dilepton : dileptons) { ptDilepton = RecoDecay::pt(dilepton.px(), dilepton.py()); rapDilepton = RecoDecay::y(std::array{dilepton.px(), dilepton.py(), dilepton.pz()}, constants::physics::MassJPsi); phiDilepton = RecoDecay::phi(dilepton.px(), dilepton.py()); - for (auto& dmeson : dmesons) { + for (auto const& dmeson : dmesons) { ptDmeson = RecoDecay::pt(dmeson.px(), dmeson.py()); phiDmeson = RecoDecay::phi(dmeson.px(), dmeson.py()); - deltaPhi = RecoDecay::constrainAngle(phiDilepton - phiDmeson, -o2::constants::math::PIHalf); + float absDeltaPhiRaw = std::abs(phiDilepton - phiDmeson); + deltaPhi = (absDeltaPhiRaw < o2::constants::math::PI) ? absDeltaPhiRaw : o2::constants::math::TwoPI - absDeltaPhiRaw; auto ptBinDmesForBdt = findBin(binsPtDmesForBdt, ptDmeson); if (ptBinDmesForBdt == -1) { diff --git a/PWGEM/Dilepton/Core/DielectronCut.cxx b/PWGEM/Dilepton/Core/DielectronCut.cxx index f320a801cc2..7f86c7babbe 100644 --- a/PWGEM/Dilepton/Core/DielectronCut.cxx +++ b/PWGEM/Dilepton/Core/DielectronCut.cxx @@ -67,12 +67,13 @@ void DielectronCut::SelectPhotonConversion(bool flag) mSelectPC = flag; LOG(info) << "Dielectron Cut, select photon conversion: " << mSelectPC; } -void DielectronCut::SetMindEtadPhi(bool flag, float min_deta, float min_dphi) +void DielectronCut::SetMindEtadPhi(bool flag1, bool flag2, float min_deta, float min_dphi) { - mApplydEtadPhi = flag; + mApplydEtadPhi = flag1; + mApplydEtadPhiPosition = flag2; mMinDeltaEta = min_deta; mMinDeltaPhi = min_dphi; - LOG(info) << "Dielectron Cut, set apply deta-dphi cut: " << mApplydEtadPhi << " min_deta: " << mMinDeltaEta << " min_dphi: " << mMinDeltaPhi; + LOG(info) << "Dielectron Cut, set apply deta-dphi cut: " << mApplydEtadPhi << " apply deta-dphi* cut: " << mApplydEtadPhiPosition << " min_deta: " << mMinDeltaEta << " min_dphi: " << mMinDeltaPhi; } void DielectronCut::SetRequireDifferentSides(bool flag) { diff --git a/PWGEM/Dilepton/Core/DielectronCut.h b/PWGEM/Dilepton/Core/DielectronCut.h index cd814d7c33e..0dc108b05c5 100644 --- a/PWGEM/Dilepton/Core/DielectronCut.h +++ b/PWGEM/Dilepton/Core/DielectronCut.h @@ -101,7 +101,7 @@ class DielectronCut : public TNamed } template - bool IsSelectedPair(TTrack1 const& t1, TTrack2 const& t2, const float bz) const + bool IsSelectedPair(TTrack1 const& t1, TTrack2 const& t2, const float bz, const float refR) const { ROOT::Math::PtEtaPhiMVector v1(t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassElectron); ROOT::Math::PtEtaPhiMVector v2(t2.pt(), t2.eta(), t2.phi(), o2::constants::physics::MassElectron); @@ -137,6 +137,10 @@ class DielectronCut : public TNamed return false; } + if (mApplydEtadPhi && mApplydEtadPhiPosition) { // applying both cuts is not allowed. + return false; + } + float deta = v1.Eta() - v2.Eta(); float dphi = v1.Phi() - v2.Phi(); o2::math_utils::bringToPMPi(dphi); @@ -144,6 +148,17 @@ class DielectronCut : public TNamed return false; } + float phiPosition1 = t1.phi() + std::asin(t1.sign() * 0.30282 * (bz * 0.1) * refR / (2.f * t1.pt())); + float phiPosition2 = t2.phi() + std::asin(t2.sign() * 0.30282 * (bz * 0.1) * refR / (2.f * t2.pt())); + + phiPosition1 = RecoDecay::constrainAngle(phiPosition1, 0, 1); // 0-2pi + phiPosition2 = RecoDecay::constrainAngle(phiPosition2, 0, 1); // 0-2pi + float dphiPosition = phiPosition1 - phiPosition2; + o2::math_utils::bringToPMPi(dphiPosition); + if (mApplydEtadPhiPosition && std::pow(deta / mMinDeltaEta, 2) + std::pow(dphiPosition / mMinDeltaPhi, 2) < 1.f) { + return false; + } + return true; } @@ -258,14 +273,15 @@ class DielectronCut : public TNamed } template - bool PassPIDML(TTrack const& track, TCollision const& collision) const + bool PassPIDML(TTrack const&, TCollision const&) const { + return false; /*if (!PassTOFif(track)) { // Allows for pre-selection. But potentially dangerous if analyzers are not aware of it return false; }*/ - std::vector inputFeatures = mPIDMlResponse->getInputFeatures(track, collision); - float binningFeature = mPIDMlResponse->getBinningFeature(track, collision); - return mPIDMlResponse->isSelectedMl(inputFeatures, binningFeature); + // std::vector inputFeatures = mPIDMlResponse->getInputFeatures(track, collision); + // float binningFeature = mPIDMlResponse->getBinningFeature(track, collision); + // return mPIDMlResponse->isSelectedMl(inputFeatures, binningFeature); } template @@ -443,7 +459,7 @@ class DielectronCut : public TNamed void SetPairOpAng(float minOpAng = 0.f, float maxOpAng = 1e10f); void SetMaxMeePhiVDep(std::function phivDepCut, float min_phiv, float max_phiv); void SelectPhotonConversion(bool flag); - void SetMindEtadPhi(bool flag, float min_deta, float min_dphi); + void SetMindEtadPhi(bool applydEtadPhi, bool applydEtadPhiPosition, float min_deta, float min_dphi); void SetRequireDifferentSides(bool flag); void SetTrackPtRange(float minPt = 0.f, float maxPt = 1e10f); @@ -516,6 +532,7 @@ class DielectronCut : public TNamed std::function mMaxMeePhiVDep{}; // max mee as a function of phiv bool mSelectPC{false}; // flag to select photon conversion used in mMaxPhivPairMeeDep bool mApplydEtadPhi{false}; // flag to apply deta, dphi cut between 2 tracks + bool mApplydEtadPhiPosition{false}; // flag to apply deta, dphi cut between 2 tracks float mMinDeltaEta{0.f}; float mMinDeltaPhi{0.f}; float mMinOpAng{0.f}, mMaxOpAng{1e10f}; diff --git a/PWGEM/Dilepton/Core/Dilepton.h b/PWGEM/Dilepton/Core/Dilepton.h index 4cfb818e2ce..c928d1cc71f 100644 --- a/PWGEM/Dilepton/Core/Dilepton.h +++ b/PWGEM/Dilepton/Core/Dilepton.h @@ -75,7 +75,7 @@ using MyCollision = MyCollisions::iterator; using MyCollisionsWithSWT = soa::Join; using MyCollisionWithSWT = MyCollisionsWithSWT::iterator; -using MyElectrons = soa::Join; +using MyElectrons = soa::Join; using MyElectron = MyElectrons::iterator; using FilteredMyElectrons = soa::Filtered; using FilteredMyElectron = FilteredMyElectrons::iterator; @@ -85,7 +85,7 @@ using MyMuon = MyMuons::iterator; using FilteredMyMuons = soa::Filtered; using FilteredMyMuon = FilteredMyMuons::iterator; -using MyEMH_electron = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, EMTrackWithCov>; +using MyEMH_electron = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, EMTrack>; using MyEMH_muon = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, EMFwdTrack>; template @@ -106,7 +106,7 @@ struct Dilepton { Configurable cfgQvecEstimator{"cfgQvecEstimator", 0, "FT0M:0, FT0A:1, FT0C:2, BTot:3, BPos:4, BNeg:5"}; Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; Configurable cfgOccupancyEstimator{"cfgOccupancyEstimator", 0, "FT0C:0, Track:1"}; - Configurable cfgCentMin{"cfgCentMin", 0, "min. centrality"}; + Configurable cfgCentMin{"cfgCentMin", -1, "min. centrality"}; Configurable cfgCentMax{"cfgCentMax", 999.f, "max. centrality"}; Configurable cfgDoMix{"cfgDoMix", true, "flag for event mixing"}; Configurable ndepth{"ndepth", 100, "depth for event mixing"}; @@ -178,7 +178,8 @@ struct Dilepton { Configurable cfg_phiv_intercept{"cfg_phiv_intercept", -0.0280, "intercept for m vs. phiv"}; Configurable cfg_min_phiv{"cfg_min_phiv", 0.0, "min phiv (constant)"}; Configurable cfg_max_phiv{"cfg_max_phiv", 3.2, "max phiv (constant)"}; - Configurable cfg_apply_detadphi{"cfg_apply_detadphi", false, "flag to apply deta-dphi elliptic cut"}; + Configurable cfg_apply_detadphi{"cfg_apply_detadphi", false, "flag to apply deta-dphi elliptic cut at PV"}; + Configurable cfg_apply_detadphiposition{"cfg_apply_detadphiposition", false, "flag to apply deta-dphi elliptic cut at certain radius"}; Configurable cfg_min_deta{"cfg_min_deta", 0.02, "min deta between 2 electrons (elliptic cut)"}; Configurable cfg_min_dphi{"cfg_min_dphi", 0.2, "min dphi between 2 electrons (elliptic cut)"}; Configurable cfg_min_opang{"cfg_min_opang", 0.0, "min opening angle"}; @@ -673,7 +674,7 @@ struct Dilepton { fDielectronCut.SetPairDCARange(dielectroncuts.cfg_min_pair_dca3d, dielectroncuts.cfg_max_pair_dca3d); // in sigma fDielectronCut.SetMaxMeePhiVDep([&](float phiv) { return dielectroncuts.cfg_phiv_intercept + phiv * dielectroncuts.cfg_phiv_slope; }, dielectroncuts.cfg_min_phiv, dielectroncuts.cfg_max_phiv); fDielectronCut.ApplyPhiV(dielectroncuts.cfg_apply_phiv); - fDielectronCut.SetMindEtadPhi(dielectroncuts.cfg_apply_detadphi, dielectroncuts.cfg_min_deta, dielectroncuts.cfg_min_dphi); + fDielectronCut.SetMindEtadPhi(dielectroncuts.cfg_apply_detadphi, dielectroncuts.cfg_apply_detadphiposition, dielectroncuts.cfg_min_deta, dielectroncuts.cfg_min_dphi); fDielectronCut.SetPairOpAng(dielectroncuts.cfg_min_opang, dielectroncuts.cfg_max_opang); fDielectronCut.SetRequireDifferentSides(dielectroncuts.cfg_require_diff_sides); @@ -756,7 +757,7 @@ struct Dilepton { fDimuonCut.SetTrackEtaRange(dimuoncuts.cfg_min_eta_track, dimuoncuts.cfg_max_eta_track); fDimuonCut.SetTrackPhiRange(dimuoncuts.cfg_min_phi_track, dimuoncuts.cfg_max_phi_track); fDimuonCut.SetNClustersMFT(dimuoncuts.cfg_min_ncluster_mft, 10); - fDimuonCut.SetNClustersMCHMID(dimuoncuts.cfg_min_ncluster_mch, 16); + fDimuonCut.SetNClustersMCHMID(dimuoncuts.cfg_min_ncluster_mch, 20); fDimuonCut.SetChi2(0.f, dimuoncuts.cfg_max_chi2); fDimuonCut.SetMatchingChi2MCHMFT(0.f, dimuoncuts.cfg_max_matching_chi2_mftmch); fDimuonCut.SetMatchingChi2MCHMID(0.f, dimuoncuts.cfg_max_matching_chi2_mchmid); @@ -858,7 +859,7 @@ struct Dilepton { } if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - if (!cut.IsSelectedPair(t1, t2, d_bz)) { + if (!cut.IsSelectedPair(t1, t2, d_bz, dielectroncuts.cfgRefR)) { return false; } } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { @@ -1081,13 +1082,9 @@ struct Dilepton { used_trackIds.emplace_back(pair_tmp_id1); if (cfgDoMix) { if (t1.sign() > 0) { - emh_pos->AddTrackToEventPool(key_df_collision, EMTrackWithCov(ndf, t1.globalIndex(), collision.globalIndex(), t1.trackId(), t1.pt(), t1.eta(), t1.phi(), leptonM1, t1.sign(), t1.dcaXY(), t1.dcaZ(), possibleIds1, - t1.x(), t1.y(), t1.z(), t1.alpha(), t1.snp(), t1.tgl(), t1.cYY(), t1.cZY(), t1.cZZ(), - t1.cSnpY(), t1.cSnpZ(), t1.cSnpSnp(), t1.cTglY(), t1.cTglZ(), t1.cTglSnp(), t1.cTglTgl(), t1.c1PtY(), t1.c1PtZ(), t1.c1PtSnp(), t1.c1PtTgl(), t1.c1Pt21Pt2())); + emh_pos->AddTrackToEventPool(key_df_collision, EMTrack(ndf, t1.globalIndex(), collision.globalIndex(), t1.trackId(), t1.pt(), t1.eta(), t1.phi(), leptonM1, t1.sign(), t1.dcaXY(), t1.dcaZ(), possibleIds1, t1.cYY(), t1.cZY(), t1.cZZ())); } else { - emh_neg->AddTrackToEventPool(key_df_collision, EMTrackWithCov(ndf, t1.globalIndex(), collision.globalIndex(), t1.trackId(), t1.pt(), t1.eta(), t1.phi(), leptonM1, t1.sign(), t1.dcaXY(), t1.dcaZ(), possibleIds1, - t1.x(), t1.y(), t1.z(), t1.alpha(), t1.snp(), t1.tgl(), t1.cYY(), t1.cZY(), t1.cZZ(), - t1.cSnpY(), t1.cSnpZ(), t1.cSnpSnp(), t1.cTglY(), t1.cTglZ(), t1.cTglSnp(), t1.cTglTgl(), t1.c1PtY(), t1.c1PtZ(), t1.c1PtSnp(), t1.c1PtTgl(), t1.c1Pt21Pt2())); + emh_neg->AddTrackToEventPool(key_df_collision, EMTrack(ndf, t1.globalIndex(), collision.globalIndex(), t1.trackId(), t1.pt(), t1.eta(), t1.phi(), leptonM1, t1.sign(), t1.dcaXY(), t1.dcaZ(), possibleIds1, t1.cYY(), t1.cZY(), t1.cZZ())); } } } @@ -1095,13 +1092,9 @@ struct Dilepton { used_trackIds.emplace_back(pair_tmp_id2); if (cfgDoMix) { if (t2.sign() > 0) { - emh_pos->AddTrackToEventPool(key_df_collision, EMTrackWithCov(ndf, t2.globalIndex(), collision.globalIndex(), t2.trackId(), t2.pt(), t2.eta(), t2.phi(), leptonM2, t2.sign(), t2.dcaXY(), t2.dcaZ(), possibleIds2, - t2.x(), t2.y(), t2.z(), t2.alpha(), t2.snp(), t2.tgl(), t2.cYY(), t2.cZY(), t2.cZZ(), - t2.cSnpY(), t2.cSnpZ(), t2.cSnpSnp(), t2.cTglY(), t2.cTglZ(), t2.cTglSnp(), t2.cTglTgl(), t2.c1PtY(), t2.c1PtZ(), t2.c1PtSnp(), t2.c1PtTgl(), t2.c1Pt21Pt2())); + emh_pos->AddTrackToEventPool(key_df_collision, EMTrack(ndf, t2.globalIndex(), collision.globalIndex(), t2.trackId(), t2.pt(), t2.eta(), t2.phi(), leptonM2, t2.sign(), t2.dcaXY(), t2.dcaZ(), possibleIds2, t2.cYY(), t2.cZY(), t2.cZZ())); } else { - emh_neg->AddTrackToEventPool(key_df_collision, EMTrackWithCov(ndf, t2.globalIndex(), collision.globalIndex(), t2.trackId(), t2.pt(), t2.eta(), t2.phi(), leptonM2, t2.sign(), t2.dcaXY(), t2.dcaZ(), possibleIds2, - t2.x(), t2.y(), t2.z(), t2.alpha(), t2.snp(), t2.tgl(), t2.cYY(), t2.cZY(), t2.cZZ(), - t2.cSnpY(), t2.cSnpZ(), t2.cSnpSnp(), t2.cTglY(), t2.cTglZ(), t2.cTglSnp(), t2.cTglTgl(), t2.c1PtY(), t2.c1PtZ(), t2.c1PtSnp(), t2.c1PtTgl(), t2.c1Pt21Pt2())); + emh_neg->AddTrackToEventPool(key_df_collision, EMTrack(ndf, t2.globalIndex(), collision.globalIndex(), t2.trackId(), t2.pt(), t2.eta(), t2.phi(), leptonM2, t2.sign(), t2.dcaXY(), t2.dcaZ(), possibleIds2, t2.cYY(), t2.cZY(), t2.cZZ())); } } } @@ -1113,10 +1106,10 @@ struct Dilepton { used_trackIds.emplace_back(pair_tmp_id1); if (cfgDoMix) { if (t1.sign() > 0) { - emh_pos->AddTrackToEventPool(key_df_collision, EMFwdTrack(ndf, t1.globalIndex(), collision.globalIndex(), t1.fwdtrackId(), t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassMuon, t1.sign(), t1.fwdDcaX(), t1.fwdDcaY(), possibleIds1, + emh_pos->AddTrackToEventPool(key_df_collision, EMFwdTrack(ndf, t1.globalIndex(), collision.globalIndex(), t1.fwdtrackId(), t1.pt(), t1.eta(), t1.phi(), leptonM1, t1.sign(), t1.fwdDcaX(), t1.fwdDcaY(), possibleIds1, t1.cXXatDCA(), t1.cXYatDCA(), t1.cYYatDCA())); } else { - emh_neg->AddTrackToEventPool(key_df_collision, EMFwdTrack(ndf, t1.globalIndex(), collision.globalIndex(), t1.fwdtrackId(), t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassMuon, t1.sign(), t1.fwdDcaX(), t1.fwdDcaY(), possibleIds1, + emh_neg->AddTrackToEventPool(key_df_collision, EMFwdTrack(ndf, t1.globalIndex(), collision.globalIndex(), t1.fwdtrackId(), t1.pt(), t1.eta(), t1.phi(), leptonM1, t1.sign(), t1.fwdDcaX(), t1.fwdDcaY(), possibleIds1, t1.cXXatDCA(), t1.cXYatDCA(), t1.cYYatDCA())); } } @@ -1125,10 +1118,10 @@ struct Dilepton { used_trackIds.emplace_back(pair_tmp_id2); if (cfgDoMix) { if (t2.sign() > 0) { - emh_pos->AddTrackToEventPool(key_df_collision, EMFwdTrack(ndf, t2.globalIndex(), collision.globalIndex(), t2.fwdtrackId(), t2.pt(), t2.eta(), t2.phi(), o2::constants::physics::MassMuon, t2.sign(), t2.fwdDcaX(), t2.fwdDcaY(), possibleIds2, + emh_pos->AddTrackToEventPool(key_df_collision, EMFwdTrack(ndf, t2.globalIndex(), collision.globalIndex(), t2.fwdtrackId(), t2.pt(), t2.eta(), t2.phi(), leptonM2, t2.sign(), t2.fwdDcaX(), t2.fwdDcaY(), possibleIds2, t2.cXXatDCA(), t2.cXYatDCA(), t2.cYYatDCA())); } else { - emh_neg->AddTrackToEventPool(key_df_collision, EMFwdTrack(ndf, t2.globalIndex(), collision.globalIndex(), t2.fwdtrackId(), t2.pt(), t2.eta(), t2.phi(), o2::constants::physics::MassMuon, t2.sign(), t2.fwdDcaX(), t2.fwdDcaY(), possibleIds2, + emh_neg->AddTrackToEventPool(key_df_collision, EMFwdTrack(ndf, t2.globalIndex(), collision.globalIndex(), t2.fwdtrackId(), t2.pt(), t2.eta(), t2.phi(), leptonM2, t2.sign(), t2.fwdDcaX(), t2.fwdDcaY(), possibleIds2, t2.cXXatDCA(), t2.cXYatDCA(), t2.cYYatDCA())); } } @@ -1146,8 +1139,7 @@ struct Dilepton { SliceCache cache; Preslice perCollision_electron = aod::emprimaryelectron::emeventId; - Filter trackFilter_electron = dielectroncuts.cfg_min_pt_track < o2::aod::track::pt && dielectroncuts.cfg_min_eta_track < o2::aod::track::eta && o2::aod::track::eta < dielectroncuts.cfg_max_eta_track && o2::aod::track::tpcChi2NCl < dielectroncuts.cfg_max_chi2tpc && o2::aod::track::itsChi2NCl < dielectroncuts.cfg_max_chi2its && nabs(o2::aod::track::dcaXY) < dielectroncuts.cfg_max_dcaxy && nabs(o2::aod::track::dcaZ) < dielectroncuts.cfg_max_dcaz; - Filter pidFilter_electron = dielectroncuts.cfg_min_TPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < dielectroncuts.cfg_max_TPCNsigmaEl; + Filter trackFilter_electron = dielectroncuts.cfg_min_pt_track < o2::aod::track::pt && dielectroncuts.cfg_min_eta_track < o2::aod::track::eta && o2::aod::track::eta < dielectroncuts.cfg_max_eta_track && nabs(o2::aod::track::dcaXY) < dielectroncuts.cfg_max_dcaxy && nabs(o2::aod::track::dcaZ) < dielectroncuts.cfg_max_dcaz; Filter ttcaFilter_electron = ifnode(dielectroncuts.enableTTCA.node(), o2::aod::emprimaryelectron::isAssociatedToMPC == true || o2::aod::emprimaryelectron::isAssociatedToMPC == false, o2::aod::emprimaryelectron::isAssociatedToMPC == true); Filter prefilter_derived_electron = ifnode(dielectroncuts.cfg_apply_cuts_from_prefilter_derived.node() && dielectroncuts.cfg_prefilter_bits_derived.node() >= static_cast(1), ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) <= static_cast(0), true) && @@ -1167,7 +1159,7 @@ struct Dilepton { Partition negative_electrons = o2::aod::emprimaryelectron::sign < int8_t(0); Preslice perCollision_muon = aod::emprimarymuon::emeventId; - Filter trackFilter_muon = o2::aod::fwdtrack::trackType == dimuoncuts.cfg_track_type && dimuoncuts.cfg_min_pt_track < o2::aod::fwdtrack::pt && o2::aod::fwdtrack::pt < dimuoncuts.cfg_max_pt_track && dimuoncuts.cfg_min_eta_track < o2::aod::fwdtrack::eta && o2::aod::fwdtrack::eta < dimuoncuts.cfg_max_eta_track && dimuoncuts.cfg_min_phi_track < o2::aod::fwdtrack::phi && o2::aod::fwdtrack::phi < dimuoncuts.cfg_max_phi_track; + Filter trackFilter_muon = o2::aod::fwdtrack::trackType == dimuoncuts.cfg_track_type && dimuoncuts.cfg_min_pt_track < o2::aod::fwdtrack::pt && o2::aod::fwdtrack::pt < dimuoncuts.cfg_max_pt_track && dimuoncuts.cfg_min_eta_track < o2::aod::fwdtrack::eta && o2::aod::fwdtrack::eta < dimuoncuts.cfg_max_eta_track; Filter ttcaFilter_muon = ifnode(dimuoncuts.enableTTCA.node(), o2::aod::emprimarymuon::isAssociatedToMPC == true || o2::aod::emprimarymuon::isAssociatedToMPC == false, o2::aod::emprimarymuon::isAssociatedToMPC == true); Partition positive_muons = o2::aod::emprimarymuon::sign > int8_t(0); Partition negative_muons = o2::aod::emprimarymuon::sign < int8_t(0); @@ -1352,25 +1344,25 @@ struct Dilepton { for (const auto& pos : selected_posTracks_in_this_event) { // ULS mix for (const auto& neg : negTracks_from_event_pool) { - fillPairInfo<1>(collision, pos, neg, cut, tracks); + fillPairInfo<1>(collision, pos, neg, cut, nullptr); } } for (const auto& neg : selected_negTracks_in_this_event) { // ULS mix for (const auto& pos : posTracks_from_event_pool) { - fillPairInfo<1>(collision, neg, pos, cut, tracks); + fillPairInfo<1>(collision, neg, pos, cut, nullptr); } } for (const auto& pos1 : selected_posTracks_in_this_event) { // LS++ mix for (const auto& pos2 : posTracks_from_event_pool) { - fillPairInfo<1>(collision, pos1, pos2, cut, tracks); + fillPairInfo<1>(collision, pos1, pos2, cut, nullptr); } } for (const auto& neg1 : selected_negTracks_in_this_event) { // LS-- mix for (const auto& neg2 : negTracks_from_event_pool) { - fillPairInfo<1>(collision, neg1, neg2, cut, tracks); + fillPairInfo<1>(collision, neg1, neg2, cut, nullptr); } } } // end of loop over mixed event pool @@ -1412,7 +1404,7 @@ struct Dilepton { } if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - if (!cut.IsSelectedPair(t1, t2, d_bz)) { + if (!cut.IsSelectedPair(t1, t2, d_bz, dielectroncuts.cfgRefR)) { return false; } } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { diff --git a/PWGEM/Dilepton/Core/DileptonHadronMPC.h b/PWGEM/Dilepton/Core/DileptonHadronMPC.h index 9a0a2a551d3..11fedd03212 100644 --- a/PWGEM/Dilepton/Core/DileptonHadronMPC.h +++ b/PWGEM/Dilepton/Core/DileptonHadronMPC.h @@ -77,7 +77,7 @@ using MyCollision = MyCollisions::iterator; using MyCollisionsWithSWT = soa::Join; using MyCollisionWithSWT = MyCollisionsWithSWT::iterator; -using MyElectrons = soa::Join; +using MyElectrons = soa::Join; using MyElectron = MyElectrons::iterator; using FilteredMyElectrons = soa::Filtered; using FilteredMyElectron = FilteredMyElectrons::iterator; @@ -87,9 +87,6 @@ using MyMuon = MyMuons::iterator; using FilteredMyMuons = soa::Filtered; using FilteredMyMuon = FilteredMyMuons::iterator; -using MyTracks = soa::Join; -using MyTrack = MyTracks::iterator; - using MyEMH_electron = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, EMTrack>; using MyEMH_muon = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, EMFwdTrack>; using MyEMH_track = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, EMTrack>; // for charged track @@ -111,10 +108,10 @@ struct DileptonHadronMPC { Configurable cfgCentMax{"cfgCentMax", 999.f, "max. centrality"}; Configurable cfgDoMix{"cfgDoMix", true, "flag for event mixing"}; Configurable ndepth_lepton{"ndepth_lepton", 100, "depth for event mixing between lepton-lepton"}; - Configurable ndepth_hadron{"ndepth_hadron", 2, "depth for event mixing between hadron-hadron"}; + Configurable ndepth_hadron{"ndepth_hadron", 1, "depth for event mixing between hadron-hadron"}; Configurable ndiff_bc_mix{"ndiff_bc_mix", 594, "difference in global BC required in mixed events"}; ConfigurableAxis ConfVtxBins{"ConfVtxBins", {VARIABLE_WIDTH, -10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}, "Mixing bins - z-vertex"}; - ConfigurableAxis ConfCentBins{"ConfCentBins", {VARIABLE_WIDTH, 0.0f, 0.1, 1, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.f, 999.f}, "Mixing bins - centrality"}; + ConfigurableAxis ConfCentBins{"ConfCentBins", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.f, 999.f}, "Mixing bins - centrality"}; ConfigurableAxis ConfOccupancyBins{"ConfOccupancyBins", {VARIABLE_WIDTH, -1, 1e+10}, "Mixing bins - occupancy"}; Configurable cfg_swt_name{"cfg_swt_name", "fHighTrackMult", "desired software trigger name"}; // 1 trigger name per 1 task. fHighTrackMult, fHighFt0Mult // Configurable cfgNtracksPV08Min{"cfgNtracksPV08Min", -1, "min. multNTracksPV"}; @@ -122,7 +119,7 @@ struct DileptonHadronMPC { Configurable cfgApplyWeightTTCA{"cfgApplyWeightTTCA", false, "flag to apply weighting by 1/N"}; Configurable cfgDCAType{"cfgDCAType", 0, "type of DCA for output. 0:3D, 1:XY, 2:Z, else:3D"}; - ConfigurableAxis ConfMllBins{"ConfMllBins", {VARIABLE_WIDTH, 0.00, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, 0.11, 0.12, 0.13, 0.14, 0.20, 0.30, 0.40, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.00, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.10, 2.20, 2.30, 2.40, 2.50, 2.60, 2.70, 2.75, 2.80, 2.85, 2.90, 2.95, 3.00, 3.05, 3.10, 3.15, 3.20, 3.25, 3.30, 3.35, 3.40, 3.45, 3.50, 3.55, 3.60, 3.65, 3.70, 3.75, 3.80, 3.85, 3.90, 3.95, 4.00}, "mll bins for output histograms"}; + ConfigurableAxis ConfMllBins{"ConfMllBins", {VARIABLE_WIDTH, 0.00, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.30, 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.40, 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.60, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.70, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.80, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.90, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.00, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.10, 2.20, 2.30, 2.40, 2.50, 2.60, 2.70, 2.75, 2.80, 2.85, 2.90, 2.95, 3.00, 3.05, 3.10, 3.15, 3.20, 3.25, 3.30, 3.35, 3.40, 3.45, 3.50, 3.55, 3.60, 3.65, 3.70, 3.75, 3.80, 3.85, 3.90, 3.95, 4.00}, "mll bins for output histograms"}; ConfigurableAxis ConfPtllBins{"ConfPtllBins", {VARIABLE_WIDTH, 0.00, 0.15, 0.50, 1.00, 1.50, 2.00, 2.50, 3.00, 3.50, 4.00, 4.50, 5.00, 6.00, 7.00, 8.00, 9.00, 10.00}, "pTll bins for output histograms"}; ConfigurableAxis ConfDCAllBins{"ConfDCAllBins", {VARIABLE_WIDTH, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0}, "DCAll bins for output histograms"}; @@ -130,7 +127,7 @@ struct DileptonHadronMPC { ConfigurableAxis ConfPtHadronBins{"ConfPtHadronBins", {VARIABLE_WIDTH, 0.00, 0.15, 0.2, 0.3, 0.4, 0.50, 1.00, 2.00, 3.00, 4.00, 5.00}, "pT,h bins for output histograms"}; ConfigurableAxis ConfRapidityBins{"ConfRapidityBins", {20, -1, 1}, "rapidity bins for output histograms"}; - ConfigurableAxis ConfDEtaBins{"ConfDEtaBins", {60, -3, 3}, "deta bins for output histograms"}; + ConfigurableAxis ConfDEtaBins{"ConfDEtaBins", {120, -6, 6}, "deta bins for output histograms"}; Configurable cfgNbinsDPhi{"cfgNbinsDPhi", 36, "nbins in dphi for output histograms"}; Configurable cfgNbinsCosNDPhi{"cfgNbinsCosNDPhi", 200, "nbins in cos(n(dphi)) for output histograms"}; Configurable cfgNmod{"cfgNmod", 2, "n-th harmonics"}; @@ -183,7 +180,8 @@ struct DileptonHadronMPC { Configurable cfg_phiv_intercept{"cfg_phiv_intercept", -0.0280, "intercept for m vs. phiv"}; Configurable cfg_min_phiv{"cfg_min_phiv", 0.0, "min phiv (constant)"}; Configurable cfg_max_phiv{"cfg_max_phiv", 3.2, "max phiv (constant)"}; - Configurable cfg_apply_detadphi{"cfg_apply_detadphi", false, "flag to apply deta-dphi elliptic cut"}; + Configurable cfg_apply_detadphi{"cfg_apply_detadphi", false, "flag to apply deta-dphi elliptic cut at PV"}; + Configurable cfg_apply_detadphiposition{"cfg_apply_detadphiposition", false, "flag to apply deta-dphi elliptic cut at certain radius"}; Configurable cfg_min_deta{"cfg_min_deta", 0.02, "min deta between 2 electrons (elliptic cut)"}; Configurable cfg_min_dphi{"cfg_min_dphi", 0.2, "min dphi between 2 electrons (elliptic cut)"}; @@ -210,6 +208,7 @@ struct DileptonHadronMPC { Configurable cfg_max_dcaz{"cfg_max_dcaz", 1.0, "max dca Z for single track in cm"}; Configurable cfg_require_itsib_any{"cfg_require_itsib_any", false, "flag to require ITS ib any hits"}; Configurable cfg_require_itsib_1st{"cfg_require_itsib_1st", true, "flag to require ITS ib 1st hit"}; + Configurable cfgRefR{"cfgRefR", 1.2, "reference R (in m) for extrapolation"}; // https://cds.cern.ch/record/1419204 Configurable cfg_pid_scheme{"cfg_pid_scheme", static_cast(DielectronCut::PIDSchemes::kTPChadrejORTOFreq), "pid scheme [kTOFreq : 0, kTPChadrej : 1, kTPChadrejORTOFreq : 2, kTPConly : 3, kTOFif : 4, kPIDML : 5, kTPChadrejORTOFreq_woTOFif : 6]"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; @@ -283,19 +282,11 @@ struct DileptonHadronMPC { Configurable cfg_max_pt_track{"cfg_max_pt_track", 3.0, "max pT for ref. track"}; Configurable cfg_min_eta_track{"cfg_min_eta_track", -0.8, "min eta for ref. track"}; Configurable cfg_max_eta_track{"cfg_max_eta_track", +0.8, "max eta for ref. track"}; - Configurable cfg_min_phi_track{"cfg_min_phi_track", 0.0, "min phi for ref. track"}; - Configurable cfg_max_phi_track{"cfg_max_phi_track", 6.3, "max phi for ref. track"}; - Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 0.5, "max dca XY for single track in cm"}; - Configurable cfg_max_dcaz{"cfg_max_dcaz", 0.5, "max dca Z for single track in cm"}; - Configurable cfg_track_bits{"cfg_track_bits", 645, "required track bits"}; // default:645, loose:0, tight:778 - // Configurable cfg_min_ncluster_its{"cfg_min_ncluster_its", 5, "min ncluster its"}; - // Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; - // Configurable cfg_min_ncrossedrows{"cfg_min_ncrossedrows", 70, "min ncrossed rows"}; - // Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 0.7, "max fraction of shared clusters in TPC"}; - // Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; - // Configurable cfg_max_chi2its{"cfg_max_chi2its", 36.0, "max chi2/NclsITS"}; - // Configurable cfg_require_itsib_any{"cfg_require_itsib_any", true, "flag to require ITS ib any hits"}; - // Configurable cfg_require_itsib_1st{"cfg_require_itsib_1st", false, "flag to require ITS ib 1st hit"}; + // Configurable cfg_min_phi_track{"cfg_min_phi_track", 0.0, "min phi for ref. track"}; + // Configurable cfg_max_phi_track{"cfg_max_phi_track", 6.3, "max phi for ref. track"}; + // Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 0.5, "max dca XY for single track in cm"}; + // Configurable cfg_max_dcaz{"cfg_max_dcaz", 0.5, "max dca Z for single track in cm"}; + Configurable cfg_track_bits{"cfg_track_bits", 5765, "required track bits"}; // default:645, loose:0, tight:778 } trackcuts; o2::aod::rctsel::RCTFlagsChecker rctChecker; @@ -462,8 +453,6 @@ struct DileptonHadronMPC { used_trackIds.clear(); used_trackIds.shrink_to_fit(); - used_refTrackIds.clear(); - used_refTrackIds.shrink_to_fit(); } void addhistograms() @@ -472,7 +461,7 @@ struct DileptonHadronMPC { o2::aod::pwgem::dilepton::utils::eventhistogram::addEventHistograms<-1>(&fRegistry); std::string mass_axis_title = "m_{ll} (GeV/c^{2})"; - std::string pair_pt_axis_title = "p_{T,ll}^{trg} (GeV/c)"; + std::string pair_pt_axis_title = "p_{T,ll} (GeV/c)"; std::string pair_dca_axis_title = "DCA_{ll} (#sigma)"; std::string pair_rapidity_axis_title = "y_{ll}"; std::string deta_axis_title = "#Delta#eta = #eta_{ll} - #eta_{h}"; @@ -509,16 +498,17 @@ struct DileptonHadronMPC { const AxisSpec axis_y{ConfRapidityBins, pair_rapidity_axis_title}; // dilepton-hadron info - const AxisSpec axis_pt_ref{ConfPtHadronBins, "p_{T,h}^{ref} (GeV/c)"}; const AxisSpec axis_deta{ConfDEtaBins, deta_axis_title}; // hadron-hadron info - const AxisSpec axis_deta_hh{ConfDEtaBins, "#Delta#eta = #eta_{h}^{trg} - #eta_{h}^{ref}"}; + const AxisSpec axis_deta_hh{60, -3, +3, "#Delta#eta = #eta_{h}^{ref1} - #eta_{h}^{ref2}"}; const AxisSpec axis_pt_trg{ConfPtHadronBins, "p_{T,h} (GeV/c)"}; const AxisSpec axis_eta_trg{40, -2, +2, "#eta_{h}"}; const AxisSpec axis_phi_trg{36, 0, 2 * M_PI, "#varphi_{h} (rad.)"}; - fRegistry.add("Hadron/hs", "hadron", kTHnSparseD, {axis_pt_trg, axis_eta_trg, axis_phi_trg}, true); + fRegistry.add("Hadron/hs", "hadron", kTHnSparseD, {axis_pt_trg, axis_eta_trg, axis_phi_trg}, false); + fRegistry.add("Hadron/hTrackBit", "track bit", kTH1D, {{65536, -0.5, 65535.5}}, false); + fRegistry.add("Dilepton/same/uls/hs", "dilepton", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y}, true); fRegistry.addClone("Dilepton/same/uls/", "Dilepton/same/lspp/"); fRegistry.addClone("Dilepton/same/uls/", "Dilepton/same/lsmm/"); @@ -526,30 +516,29 @@ struct DileptonHadronMPC { if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kAzimuthalCorrelation)) { const AxisSpec axis_dphi{cfgNbinsDPhi, -M_PI / 2, 3 * M_PI / 2, dphi_axis_title}; - const AxisSpec axis_dphi_hh{cfgNbinsDPhi, -M_PI / 2, 3 * M_PI / 2, "#Delta#varphi = #varphi_{h}^{trg} - #varphi_{h}^{ref} (rad.)"}; // dilepton-hadron - fRegistry.add("DileptonHadron/same/uls/hs", "dilepton-hadron 2PC", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y, axis_pt_ref, axis_deta, axis_dphi}, true); + fRegistry.add("DileptonHadron/same/uls/hs", "dilepton-hadron 2PC", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y, axis_deta, axis_dphi}, true); fRegistry.addClone("DileptonHadron/same/uls/", "DileptonHadron/same/lspp/"); fRegistry.addClone("DileptonHadron/same/uls/", "DileptonHadron/same/lsmm/"); // fRegistry.addClone("DileptonHadron/same/", "DileptonHadron/mix/"); // hadron-hadron - const AxisSpec axis_cosndphi_hh{cfgNbinsCosNDPhi, -1, +1, std::format("cos({0:d}(#varphi_{{h}}^{{trg}} - #varphi_{{h}}^{{ref}}))", cfgNmod.value)}; - fRegistry.add("HadronHadron/same/hs", "hadron-hadron 2PC", kTHnSparseD, {axis_pt_trg, axis_pt_ref, axis_deta_hh, axis_dphi_hh}, true); + const AxisSpec axis_dphi_hh{90, -M_PI / 2, 3 * M_PI / 2, "#Delta#varphi = #varphi_{h}^{ref1} - #varphi_{h}^{ref2} (rad.)"}; + fRegistry.add("HadronHadron/same/hDEtaDPhi", "hadron-hadron 2PC", kTH2D, {axis_dphi_hh, axis_deta_hh}, true); fRegistry.addClone("HadronHadron/same/", "HadronHadron/mix/"); fRegistry.add("HadronHadron/mix/hDiffBC", "diff. global BC in mixed event;|BC_{current} - BC_{mixed}|", kTH1D, {{10001, -0.5, 10000.5}}, true); } else if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kCumulant)) { const AxisSpec axis_cos_ndphi{cfgNbinsCosNDPhi, -1, +1, cosndphi_axis_title}; // dilepton-hadron - fRegistry.add("DileptonHadron/same/uls/hs", "dilepton-hadron 2PC", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y, axis_pt_ref, axis_deta, axis_cos_ndphi}, true); + fRegistry.add("DileptonHadron/same/uls/hs", "dilepton-hadron 2PC", kTHnSparseD, {axis_mass, axis_pt, axis_dca, axis_y, axis_deta, axis_cos_ndphi}, true); fRegistry.addClone("DileptonHadron/same/uls/", "DileptonHadron/same/lspp/"); fRegistry.addClone("DileptonHadron/same/uls/", "DileptonHadron/same/lsmm/"); fRegistry.addClone("DileptonHadron/same/", "DileptonHadron/mix/"); // hadron-hadron - const AxisSpec axis_cosndphi_hh{cfgNbinsCosNDPhi, -1, +1, std::format("cos({0:d}(#varphi_{{h}}^{{trg}} - #varphi_{{h}}^{{ref}}))", cfgNmod.value)}; - fRegistry.add("HadronHadron/same/hs", "hadron-hadron 2PC", kTHnSparseD, {axis_pt_trg, axis_pt_ref, axis_deta_hh, axis_cosndphi_hh}, true); + const AxisSpec axis_cosndphi_hh{cfgNbinsCosNDPhi, -1, +1, std::format("cos({0:d}(#varphi_{{h}}^{{ref1}} - #varphi_{{h}}^{{ref2}}))", cfgNmod.value)}; + fRegistry.add("HadronHadron/same/hDEtaCosNDPhi", "hadron-hadron 2PC", kTH2D, {axis_cosndphi_hh, axis_deta_hh}, true); } fRegistry.add("Dilepton/mix/hDiffBC", "diff. global BC in mixed event;|BC_{current} - BC_{mixed}|", kTH1D, {{10001, -0.5, 10000.5}}, true); } @@ -588,7 +577,7 @@ struct DileptonHadronMPC { fDielectronCut.SetPairDCARange(dielectroncuts.cfg_min_pair_dca3d, dielectroncuts.cfg_max_pair_dca3d); // in sigma fDielectronCut.SetMaxMeePhiVDep([&](float phiv) { return dielectroncuts.cfg_phiv_intercept + phiv * dielectroncuts.cfg_phiv_slope; }, dielectroncuts.cfg_min_phiv, dielectroncuts.cfg_max_phiv); fDielectronCut.ApplyPhiV(dielectroncuts.cfg_apply_phiv); - fDielectronCut.SetMindEtadPhi(dielectroncuts.cfg_apply_detadphi, dielectroncuts.cfg_min_deta, dielectroncuts.cfg_min_dphi); + fDielectronCut.SetMindEtadPhi(dielectroncuts.cfg_apply_detadphi, dielectroncuts.cfg_apply_detadphiposition, dielectroncuts.cfg_min_deta, dielectroncuts.cfg_min_dphi); fDielectronCut.SetPairOpAng(0.f, 6.3); fDielectronCut.SetRequireDifferentSides(false); @@ -666,7 +655,7 @@ struct DileptonHadronMPC { fDimuonCut.SetTrackEtaRange(dimuoncuts.cfg_min_eta_track, dimuoncuts.cfg_max_eta_track); fDimuonCut.SetTrackPhiRange(dimuoncuts.cfg_min_phi_track, dimuoncuts.cfg_max_phi_track); fDimuonCut.SetNClustersMFT(dimuoncuts.cfg_min_ncluster_mft, 10); - fDimuonCut.SetNClustersMCHMID(dimuoncuts.cfg_min_ncluster_mch, 16); + fDimuonCut.SetNClustersMCHMID(dimuoncuts.cfg_min_ncluster_mch, 20); fDimuonCut.SetChi2(0.f, dimuoncuts.cfg_max_chi2); fDimuonCut.SetMatchingChi2MCHMFT(0.f, dimuoncuts.cfg_max_matching_chi2_mftmch); fDimuonCut.SetMatchingChi2MCHMID(0.f, dimuoncuts.cfg_max_matching_chi2_mchmid); @@ -682,19 +671,10 @@ struct DileptonHadronMPC { fEMTrackCut = EMTrackCut("fEMTrackCut", "fEMTrackCut"); fEMTrackCut.SetTrackPtRange(trackcuts.cfg_min_pt_track, trackcuts.cfg_max_pt_track); fEMTrackCut.SetTrackEtaRange(trackcuts.cfg_min_eta_track, trackcuts.cfg_max_eta_track); - fEMTrackCut.SetTrackPhiRange(trackcuts.cfg_min_phi_track, trackcuts.cfg_max_phi_track); - fEMTrackCut.SetTrackMaxDcaXY(trackcuts.cfg_max_dcaxy); - fEMTrackCut.SetTrackMaxDcaZ(trackcuts.cfg_max_dcaz); + // fEMTrackCut.SetTrackPhiRange(trackcuts.cfg_min_phi_track, trackcuts.cfg_max_phi_track); + // fEMTrackCut.SetTrackMaxDcaXY(trackcuts.cfg_max_dcaxy); + // fEMTrackCut.SetTrackMaxDcaZ(trackcuts.cfg_max_dcaz); fEMTrackCut.SetTrackBit(trackcuts.cfg_track_bits); - // fEMTrackCut.SetMinNClustersTPC(trackcuts.cfg_min_ncluster_tpc); - // fEMTrackCut.SetMinNCrossedRowsTPC(trackcuts.cfg_min_ncrossedrows); - // fEMTrackCut.SetMinNCrossedRowsOverFindableClustersTPC(0.8); - // fEMTrackCut.SetMaxFracSharedClustersTPC(trackcuts.cfg_max_frac_shared_clusters_tpc); - // fEMTrackCut.SetChi2PerClusterTPC(0.0, trackcuts.cfg_max_chi2tpc); - // fEMTrackCut.SetChi2PerClusterITS(0.0, trackcuts.cfg_max_chi2its); - // fEMTrackCut.SetNClustersITS(trackcuts.cfg_min_ncluster_its, 7); - // fEMTrackCut.RequireITSibAny(trackcuts.cfg_require_itsib_any); - // fEMTrackCut.RequireITSib1st(trackcuts.cfg_require_itsib_1st); } template @@ -744,7 +724,7 @@ struct DileptonHadronMPC { } if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - if (!cut.IsSelectedPair(t1, t2, d_bz)) { + if (!cut.IsSelectedPair(t1, t2, d_bz, dielectroncuts.cfgRefR)) { return false; } } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { @@ -847,11 +827,6 @@ struct DileptonHadronMPC { } } } - - // possibleIds1.clear(); - // possibleIds1.shrink_to_fit(); - // possibleIds2.clear(); - // possibleIds2.shrink_to_fit(); } return true; } @@ -915,7 +890,7 @@ struct DileptonHadronMPC { } if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - if (!cut.IsSelectedPair(t1, t2, d_bz)) { + if (!cut.IsSelectedPair(t1, t2, d_bz, dielectroncuts.cfgRefR)) { return false; } } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { @@ -955,29 +930,29 @@ struct DileptonHadronMPC { if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kAzimuthalCorrelation)) { dphi = RecoDecay::constrainAngle(dphi, -M_PI / 2, 1U); if (t1.sign() * t2.sign() < 0) { // ULS - fRegistry.fill(HIST("DileptonHadron/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), v3.Pt(), deta, dphi, weight); + fRegistry.fill(HIST("DileptonHadron/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), deta, dphi, weight); } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ - fRegistry.fill(HIST("DileptonHadron/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), v3.Pt(), deta, dphi, weight); + fRegistry.fill(HIST("DileptonHadron/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), deta, dphi, weight); } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- - fRegistry.fill(HIST("DileptonHadron/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), v3.Pt(), deta, dphi, weight); + fRegistry.fill(HIST("DileptonHadron/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), deta, dphi, weight); } } else if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kCumulant)) { o2::math_utils::bringTo02Pi(dphi); float cosndphi = std::cos(cfgNmod * dphi); if (t1.sign() * t2.sign() < 0) { // ULS - fRegistry.fill(HIST("DileptonHadron/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), v3.Pt(), deta, cosndphi, weight); + fRegistry.fill(HIST("DileptonHadron/") + HIST(event_pair_types[ev_id]) + HIST("uls/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), deta, cosndphi, weight); } else if (t1.sign() > 0 && t2.sign() > 0) { // LS++ - fRegistry.fill(HIST("DileptonHadron/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), v3.Pt(), deta, cosndphi, weight); + fRegistry.fill(HIST("DileptonHadron/") + HIST(event_pair_types[ev_id]) + HIST("lspp/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), deta, cosndphi, weight); } else if (t1.sign() < 0 && t2.sign() < 0) { // LS-- - fRegistry.fill(HIST("DileptonHadron/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), v3.Pt(), deta, cosndphi, weight); + fRegistry.fill(HIST("DileptonHadron/") + HIST(event_pair_types[ev_id]) + HIST("lsmm/hs"), v12.M(), v12.Pt(), pair_dca, v12.Rapidity(), deta, cosndphi, weight); } } return true; } - template - bool fillHadronHadron(TCollision const& collision, TRefTrack const& t1, TRefTrack const& t2, TLeptons const& posLeptons, TLeptons const& negLeptons) + template + bool fillHadronHadron(TCollision const& collision, TRefTrack const& t1, TRefTrack const& t2, TLeptons const& posLeptons, TLeptons const& negLeptons, TLeptonCut const& cut) { if constexpr (ev_id == 0) { if (!fEMTrackCut.IsSelected(t1) || !fEMTrackCut.IsSelected(t2)) { // for charged track @@ -987,17 +962,37 @@ struct DileptonHadronMPC { // Leptons should not be in reference track sample. if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { for (const auto& pos : posLeptons) { // leptons per collision + if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { + if (!cut.template IsSelectedTrack(pos, collision)) { + continue; + } + } else { // cut based + if (!cut.template IsSelectedTrack(pos)) { + continue; + } + } if (t1.trackId() == pos.trackId() || t2.trackId() == pos.trackId()) { return false; } - } + } // end of pos lepton loop + for (const auto& neg : negLeptons) { // leptons per collision + if (dielectroncuts.cfg_pid_scheme == static_cast(DielectronCut::PIDSchemes::kPIDML)) { + if (!cut.template IsSelectedTrack(neg, collision)) { + continue; + } + } else { // cut based + if (!cut.template IsSelectedTrack(neg)) { + continue; + } + } if (t1.trackId() == neg.trackId() || t2.trackId() == neg.trackId()) { return false; } - } - } - } + } // end of neg lepton lopp + + } // end of if kDielectron + } // end of if same event if constexpr (ev_id == 1) { if (t1.dfId() == t2.dfId() && t1.globalIndex() == t2.globalIndex()) { @@ -1011,30 +1006,12 @@ struct DileptonHadronMPC { if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kAzimuthalCorrelation)) { dphi = RecoDecay::constrainAngle(dphi, -M_PI / 2, 1U); - fRegistry.fill(HIST("HadronHadron/") + HIST(event_pair_types[ev_id]) + HIST("hs"), t1.pt(), t2.pt(), deta, dphi, weight); + fRegistry.fill(HIST("HadronHadron/") + HIST(event_pair_types[ev_id]) + HIST("hDEtaDPhi"), dphi, deta, weight); } else if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kCumulant)) { o2::math_utils::bringTo02Pi(dphi); float cosndphi = std::cos(cfgNmod * dphi); - fRegistry.fill(HIST("HadronHadron/") + HIST(event_pair_types[ev_id]) + HIST("hs"), t1.pt(), t2.pt(), deta, cosndphi, weight); + fRegistry.fill(HIST("HadronHadron/") + HIST(event_pair_types[ev_id]) + HIST("hDEtaCosNDPhi"), cosndphi, deta, weight); } - - // store ref tracks for mixed event in case of kAzimuthalCorrelation - if constexpr (ev_id == 0) { - if (cfgDoMix && cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kAzimuthalCorrelation)) { - std::pair key_df_collision = std::make_pair(ndf, collision.globalIndex()); - std::pair pair_tmp_id1 = std::make_pair(ndf, t1.globalIndex()); - std::pair pair_tmp_id2 = std::make_pair(ndf, t2.globalIndex()); - if (std::find(used_refTrackIds.begin(), used_refTrackIds.end(), pair_tmp_id1) == used_refTrackIds.end()) { - used_refTrackIds.emplace_back(pair_tmp_id1); - emh_ref->AddTrackToEventPool(key_df_collision, EMTrack(ndf, t1.globalIndex(), collision.globalIndex(), t1.trackId(), t1.pt(), t1.eta(), t1.phi(), 0.139)); - } // store t1 - if (std::find(used_refTrackIds.begin(), used_refTrackIds.end(), pair_tmp_id2) == used_refTrackIds.end()) { - used_refTrackIds.emplace_back(pair_tmp_id2); - emh_ref->AddTrackToEventPool(key_df_collision, EMTrack(ndf, t2.globalIndex(), collision.globalIndex(), t2.trackId(), t2.pt(), t2.eta(), t2.phi(), 0.139)); - } // store t2 - } - } - return true; } @@ -1046,8 +1023,7 @@ struct DileptonHadronMPC { SliceCache cache; Preslice perCollision_electron = aod::emprimaryelectron::emeventId; - Filter trackFilter_electron = dielectroncuts.cfg_min_pt_track < o2::aod::track::pt && dielectroncuts.cfg_min_eta_track < o2::aod::track::eta && o2::aod::track::eta < dielectroncuts.cfg_max_eta_track && o2::aod::track::tpcChi2NCl < dielectroncuts.cfg_max_chi2tpc && o2::aod::track::itsChi2NCl < dielectroncuts.cfg_max_chi2its && nabs(o2::aod::track::dcaXY) < dielectroncuts.cfg_max_dcaxy && nabs(o2::aod::track::dcaZ) < dielectroncuts.cfg_max_dcaz; - Filter pidFilter_electron = dielectroncuts.cfg_min_TPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < dielectroncuts.cfg_max_TPCNsigmaEl; + Filter trackFilter_electron = dielectroncuts.cfg_min_pt_track < o2::aod::track::pt && dielectroncuts.cfg_min_eta_track < o2::aod::track::eta && o2::aod::track::eta < dielectroncuts.cfg_max_eta_track && nabs(o2::aod::track::dcaXY) < dielectroncuts.cfg_max_dcaxy && nabs(o2::aod::track::dcaZ) < dielectroncuts.cfg_max_dcaz; Filter ttcaFilter_electron = ifnode(dielectroncuts.enableTTCA.node(), o2::aod::emprimaryelectron::isAssociatedToMPC == true || o2::aod::emprimaryelectron::isAssociatedToMPC == false, o2::aod::emprimaryelectron::isAssociatedToMPC == true); Filter prefilter_derived_electron = ifnode(dielectroncuts.cfg_apply_cuts_from_prefilter_derived.node() && dielectroncuts.cfg_prefilter_bits_derived.node() >= static_cast(1), ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) <= static_cast(0), true) && @@ -1066,21 +1042,25 @@ struct DileptonHadronMPC { Partition positive_electrons = o2::aod::emprimaryelectron::sign > int8_t(0); Partition negative_electrons = o2::aod::emprimaryelectron::sign < int8_t(0); - Preslice perCollision_track = aod::emprimarytrack::emeventId; - Preslice perCollision_muon = aod::emprimarymuon::emeventId; Filter trackFilter_muon = o2::aod::fwdtrack::trackType == dimuoncuts.cfg_track_type && dimuoncuts.cfg_min_pt_track < o2::aod::fwdtrack::pt && o2::aod::fwdtrack::pt < dimuoncuts.cfg_max_pt_track && dimuoncuts.cfg_min_eta_track < o2::aod::fwdtrack::eta && o2::aod::fwdtrack::eta < dimuoncuts.cfg_max_eta_track && dimuoncuts.cfg_min_phi_track < o2::aod::fwdtrack::phi && o2::aod::fwdtrack::phi < dimuoncuts.cfg_max_phi_track; Filter ttcaFilter_muon = ifnode(dimuoncuts.enableTTCA.node(), o2::aod::emprimarymuon::isAssociatedToMPC == true || o2::aod::emprimarymuon::isAssociatedToMPC == false, o2::aod::emprimarymuon::isAssociatedToMPC == true); Partition positive_muons = o2::aod::emprimarymuon::sign > int8_t(0); Partition negative_muons = o2::aod::emprimarymuon::sign < int8_t(0); + using RefTracks = soa::Join; + using RefTrack = RefTracks::iterator; + Preslice perCollision_track = aod::emprimarytrack::emeventId; + Filter refTrackFilter = trackcuts.cfg_min_pt_track < 1 / nabs(o2::aod::emprimarytrack::signed1Pt) && 1 / nabs(o2::aod::emprimarytrack::signed1Pt) < trackcuts.cfg_max_pt_track && trackcuts.cfg_min_eta_track < o2::aod::emprimarytrack::eta && o2::aod::emprimarytrack::eta < trackcuts.cfg_max_eta_track; + using FilteredRefTracks = soa::Filtered; + using FilteredRefTrack = FilteredRefTracks::iterator; + TEMH* emh_pos = nullptr; TEMH* emh_neg = nullptr; MyEMH_track* emh_ref = nullptr; // for reference flow std::map, uint64_t> map_mixed_eventId_to_globalBC; std::vector> used_trackIds; - std::vector> used_refTrackIds; int ndf = 0; template @@ -1114,11 +1094,6 @@ struct DileptonHadronMPC { fRegistry.fill(HIST("Event/after/hCollisionCounter"), o2::aod::pwgem::dilepton::utils::eventhistogram::nbin_ev); // accepted auto refTracks_per_coll = refTracks.sliceBy(perCollision_track, collision.globalIndex()); - for (const auto& track : refTracks_per_coll) { - if (fEMTrackCut.IsSelected(track)) { - fRegistry.fill(HIST("Hadron/hs"), track.pt(), track.eta(), track.phi()); - } - } auto posTracks_per_coll = posTracks.sliceByCached(perCollision, collision.globalIndex(), cache); auto negTracks_per_coll = negTracks.sliceByCached(perCollision, collision.globalIndex(), cache); @@ -1153,9 +1128,23 @@ struct DileptonHadronMPC { } } + std::pair key_df_collision = std::make_pair(ndf, collision.globalIndex()); + if (nuls > 0 || nlspp > 0 || nlsmm > 0) { // at least 1 pair exists. - for (const auto& [trg, ref] : combinations(CombinationsStrictlyUpperIndexPolicy(refTracks_per_coll, refTracks_per_coll))) { - fillHadronHadron<0>(collision, trg, ref, posTracks_per_coll, negTracks_per_coll); + emh_ref->ReserveNTracksPerCollision(key_df_collision, refTracks_per_coll.size()); + for (const auto& track : refTracks_per_coll) { + if (fEMTrackCut.IsSelected(track)) { + fRegistry.fill(HIST("Hadron/hs"), track.pt(), track.eta(), track.phi()); + fRegistry.fill(HIST("Hadron/hTrackBit"), track.trackBit()); + + // store ref tracks for mixed event in case of kAzimuthalCorrelation + if (cfgDoMix && cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kAzimuthalCorrelation)) { + emh_ref->AddTrackToEventPool(key_df_collision, EMTrack(ndf, track.globalIndex(), collision.globalIndex(), track.trackId(), track.pt(), track.eta(), track.phi(), 0.139)); + } // store ref tracks + } + } + for (const auto& [ref1, ref2] : combinations(CombinationsStrictlyUpperIndexPolicy(refTracks_per_coll, refTracks_per_coll))) { + fillHadronHadron<0>(collision, ref1, ref2, posTracks_per_coll, negTracks_per_coll, cut); } } @@ -1196,7 +1185,6 @@ struct DileptonHadronMPC { } std::tuple key_bin = std::make_tuple(zbin, centbin, epbin, occbin); - std::pair key_df_collision = std::make_pair(ndf, collision.globalIndex()); // make a vector of selected electrons in this collision. auto selected_posTracks_in_this_event = emh_pos->GetTracksPerCollision(key_df_collision); @@ -1204,6 +1192,8 @@ struct DileptonHadronMPC { auto collisionIds_in_mixing_pool = emh_pos->GetCollisionIdsFromEventPool(key_bin); // pos/neg does not matter. + // LOGF(info, "selected_posTracks_in_this_event.size() = %d, selected_negTracks_in_this_event.size() = %d, collisionIds_in_mixing_pool.size() = %d", selected_posTracks_in_this_event.size(), selected_negTracks_in_this_event.size(), collisionIds_in_mixing_pool.size()); + // perform event mixing, only if at least 1 dilepton exists. for (const auto& mix_dfId_collisionId : collisionIds_in_mixing_pool) { @@ -1222,28 +1212,29 @@ struct DileptonHadronMPC { auto posTracks_from_event_pool = emh_pos->GetTracksPerCollision(mix_dfId_collisionId); auto negTracks_from_event_pool = emh_neg->GetTracksPerCollision(mix_dfId_collisionId); + // LOGF(info, "posTracks_from_event_pool.size() = %d, negTracks_from_event_pool.size() = %d", posTracks_from_event_pool.size(), negTracks_from_event_pool.size()); for (const auto& pos : selected_posTracks_in_this_event) { // ULS mix for (const auto& neg : negTracks_from_event_pool) { - fillDilepton<1>(collision, pos, neg, cut, tracks); + fillDilepton<1>(collision, pos, neg, cut, nullptr); } } for (const auto& neg : selected_negTracks_in_this_event) { // ULS mix for (const auto& pos : posTracks_from_event_pool) { - fillDilepton<1>(collision, neg, pos, cut, tracks); + fillDilepton<1>(collision, neg, pos, cut, nullptr); } } for (const auto& pos1 : selected_posTracks_in_this_event) { // LS++ mix for (const auto& pos2 : posTracks_from_event_pool) { - fillDilepton<1>(collision, pos1, pos2, cut, tracks); + fillDilepton<1>(collision, pos1, pos2, cut, nullptr); } } for (const auto& neg1 : selected_negTracks_in_this_event) { // LS-- mix for (const auto& neg2 : negTracks_from_event_pool) { - fillDilepton<1>(collision, neg1, neg2, cut, tracks); + fillDilepton<1>(collision, neg1, neg2, cut, nullptr); } } } // end of loop over mixed event pool for lepton-lepton @@ -1251,6 +1242,7 @@ struct DileptonHadronMPC { if (cfgAnalysisType == static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonHadronAnalysisType::kAzimuthalCorrelation)) { auto selected_refTracks_in_this_event = emh_ref->GetTracksPerCollision(key_df_collision); auto collisionIds_in_mixing_pool_hadron = emh_ref->GetCollisionIdsFromEventPool(key_bin); + for (const auto& mix_dfId_collisionId : collisionIds_in_mixing_pool_hadron) { int mix_dfId = mix_dfId_collisionId.first; int mix_collisionId = mix_dfId_collisionId.second; @@ -1266,12 +1258,14 @@ struct DileptonHadronMPC { } auto refTracks_from_event_pool = emh_ref->GetTracksPerCollision(mix_dfId_collisionId); + // LOGF(info, "selected_refTracks_in_this_event.size() = %d, collisionIds_in_mixing_pool_hadron.size() = %d, refTracks_from_event_pool.size() = %d", selected_refTracks_in_this_event.size(), collisionIds_in_mixing_pool_hadron.size(), refTracks_from_event_pool.size()); for (const auto& ref1 : selected_refTracks_in_this_event) { // ref-ref mix for (const auto& ref2 : refTracks_from_event_pool) { - fillHadronHadron<1>(collision, ref1, ref2, nullptr, nullptr); + // LOGF(info, "ref1.pt() = %f, ref2.pt() = %f", ref1.pt(), ref2.pt()); + fillHadronHadron<1>(collision, ref1, ref2, nullptr, nullptr, nullptr); } } - } // end of loop over mixed event pool for lepton-lepton + } // end of loop over mixed event pool for hadron-hadron } if (nuls > 0 || nlspp > 0 || nlsmm > 0) { @@ -1312,7 +1306,7 @@ struct DileptonHadronMPC { } if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - if (!cut.IsSelectedPair(t1, t2, d_bz)) { + if (!cut.IsSelectedPair(t1, t2, d_bz, dielectroncuts.cfgRefR)) { return false; } } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { @@ -1405,7 +1399,7 @@ struct DileptonHadronMPC { passed_pairIds.shrink_to_fit(); } - void processAnalysis(FilteredMyCollisions const& collisions, MyTracks const& refTracks, Types const&... args) + void processAnalysis(FilteredMyCollisions const& collisions, FilteredRefTracks const& refTracks, Types const&... args) { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { auto electrons = std::get<0>(std::tie(args...)); @@ -1426,7 +1420,7 @@ struct DileptonHadronMPC { PROCESS_SWITCH(DileptonHadronMPC, processAnalysis, "run dilepton analysis", true); using FilteredMyCollisionsWithSWT = soa::Filtered; - void processTriggerAnalysis(FilteredMyCollisionsWithSWT const& collisions, MyTracks const& refTracks, Types const&... args) + void processTriggerAnalysis(FilteredMyCollisionsWithSWT const& collisions, FilteredRefTracks const& refTracks, Types const&... args) { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { auto electrons = std::get<0>(std::tie(args...)); diff --git a/PWGEM/Dilepton/Core/DileptonMC.h b/PWGEM/Dilepton/Core/DileptonMC.h index e5add9f6e63..57beff3f8f1 100644 --- a/PWGEM/Dilepton/Core/DileptonMC.h +++ b/PWGEM/Dilepton/Core/DileptonMC.h @@ -67,7 +67,7 @@ using MyCollision = MyCollisions::iterator; using MyMCCollisions = soa::Join; using MyMCCollision = MyMCCollisions::iterator; -using MyMCElectrons = soa::Join; +using MyMCElectrons = soa::Join; using MyMCElectron = MyMCElectrons::iterator; using FilteredMyMCElectrons = soa::Filtered; using FilteredMyMCElectron = FilteredMyMCElectrons::iterator; @@ -96,7 +96,7 @@ struct DileptonMC { Configurable cfgEventGeneratorType{"cfgEventGeneratorType", -1, "if positive, select event generator type. i.e. gap or signal"}; Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; - Configurable cfgCentMin{"cfgCentMin", 0, "min. centrality"}; + Configurable cfgCentMin{"cfgCentMin", -1, "min. centrality"}; Configurable cfgCentMax{"cfgCentMax", 999.f, "max. centrality"}; // Configurable cfgNtracksPV08Min{"cfgNtracksPV08Min", -1, "min. multNTracksPV"}; // Configurable cfgNtracksPV08Max{"cfgNtracksPV08Max", static_cast(1e+9), "max. multNTracksPV"}; @@ -111,6 +111,7 @@ struct DileptonMC { ConfigurableAxis ConfDPtBins{"ConfDPtBins", {220, -1.0, +10.0}, "dpt bins for output histograms"}; ConfigurableAxis ConfDCAllNarrowBins{"ConfDCAllNarrowBins", {200, 0.0, 10.0}, "narrow DCAll bins for output histograms"}; + ConfigurableAxis ConfTrackDCA{"ConfTrackDCA", {VARIABLE_WIDTH, -10, -9, -8, -7, -6, -5, -4.5, -4, -3.5, -3, -2.5, -2, -1.9, -1.8, -1.7, -1.6, -1.5, -1.4, -1.3, -1.2, -1.1, -1, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.5, 3, 3.5, 4, 4.5, 5, 6, 7, 8, 9, 10}, "DCA binning for single tacks"}; ConfigurableAxis ConfYllBins{"ConfYllBins", {VARIABLE_WIDTH, -10.f, +10.f}, "yll bins for output histograms"}; @@ -172,7 +173,8 @@ struct DileptonMC { Configurable cfg_phiv_intercept{"cfg_phiv_intercept", -0.0280, "intercept for m vs. phiv"}; Configurable cfg_min_phiv{"cfg_min_phiv", 0.0, "min phiv (constant)"}; Configurable cfg_max_phiv{"cfg_max_phiv", 3.2, "max phiv (constant)"}; - Configurable cfg_apply_detadphi{"cfg_apply_detadphi", false, "flag to apply deta-dphi elliptic cut"}; + Configurable cfg_apply_detadphi{"cfg_apply_detadphi", false, "flag to apply deta-dphi elliptic cut at PV"}; + Configurable cfg_apply_detadphiposition{"cfg_apply_detadphiposition", false, "flag to apply deta-dphi elliptic cut at certain radius"}; Configurable cfg_min_deta{"cfg_min_deta", 0.02, "min deta between 2 electrons (elliptic cut)"}; Configurable cfg_min_dphi{"cfg_min_dphi", 0.2, "min dphi between 2 electrons (elliptic cut)"}; Configurable cfg_min_opang{"cfg_min_opang", 0.0, "min opening angle"}; @@ -208,6 +210,7 @@ struct DileptonMC { Configurable cfg_max_its_cluster_size{"cfg_max_its_cluster_size", 16.f, "max ITS cluster size"}; Configurable cfg_min_rel_diff_pin{"cfg_min_rel_diff_pin", -1e+10, "min rel. diff. between pin and ppv"}; Configurable cfg_max_rel_diff_pin{"cfg_max_rel_diff_pin", +1e+10, "max rel. diff. between pin and ppv"}; + Configurable cfgRefR{"cfgRefR", 1.2, "reference R (in m) for extrapolation"}; // https://cds.cern.ch/record/1419204 Configurable cfg_pid_scheme{"cfg_pid_scheme", static_cast(DielectronCut::PIDSchemes::kTPChadrejORTOFreq), "pid scheme [kTOFreq : 0, kTPChadrej : 1, kTPChadrejORTOFreq : 2, kTPConly : 3, kTOFif = 4, kPIDML = 5]"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; @@ -346,6 +349,8 @@ struct DileptonMC { const AxisSpec axis_dca_narrow{ConfDCAllNarrowBins, pair_dca_axis_title}; const AxisSpec axis_dpt{ConfDPtBins, "#Delta p_{T,1}^{gen-rec} + #Delta p_{T,2}^{gen-rec} (GeV/c)"}; + const AxisSpec axis_dca_track1{ConfTrackDCA, "DCA_{e,1}^{Z} (#sigma)"}; + const AxisSpec axis_dca_track2{ConfTrackDCA, "DCA_{e,2}^{Z} (#sigma)"}; const AxisSpec axis_dphi_ee{cfg_nbin_dphi_ee, -M_PI / 2., 3. / 2. * M_PI, "#Delta#varphi = #varphi_{l1} - #varphi_{l2} (rad.)"}; // for kHFll const AxisSpec axis_deta_ee{cfg_nbin_deta_ee, -2., 2., "#Delta#eta = #eta_{l1} - #eta_{l2}"}; // for kHFll @@ -438,6 +443,8 @@ struct DileptonMC { fRegistry.add("Pair/sm/NonPromptPi0/hDeltaPtvsDCA", "#Delta p_{T,1}^{gen-rec} + #Delta p_{T,2}^{gen-rec} vs. DCA_{ee}", kTH2F, {axis_dca_narrow, axis_dpt}, true); fRegistry.add("Pair/sm/PromptJPsi/hDeltaPtvsDCA", "#Delta p_{T,1}^{gen-rec} + #Delta p_{T,2}^{gen-rec} vs. DCA_{ee}", kTH2F, {axis_dca_narrow, axis_dpt}, true); fRegistry.add("Pair/sm/NonPromptJPsi/hDeltaPtvsDCA", "#Delta p_{T,1}^{gen-rec} + #Delta p_{T,2}^{gen-rec} vs. DCA_{ee}", kTH2F, {axis_dca_narrow, axis_dpt}, true); + fRegistry.add("Pair/sm/PromptPi0/hDCAz1vsDCAz2", "DCA_{z,1} vs DCA_{z,2}", kTH2F, {axis_dca_track1, axis_dca_track2}, true); + fRegistry.add("Pair/sm/PromptJPsi/hDCAz1vsDCAz2", "DCA_{z,1} vs DCA_{z,2}", kTH2F, {axis_dca_track1, axis_dca_track2}, true); } fRegistry.add("Pair/ccbar/c2l_c2l/hadron_hadron/hs", "hs pair", kTHnSparseD, {axis_mass, axis_pt, axis_y, axis_dphi_ee, axis_deta_ee, axis_cos_theta_cs, axis_phi_cs, axis_aco, axis_asym_pt, axis_dphi_e_ee, axis_dca}, true); @@ -646,7 +653,7 @@ struct DileptonMC { fDielectronCut.SetPairDCARange(dielectroncuts.cfg_min_pair_dca3d, dielectroncuts.cfg_max_pair_dca3d); // in sigma fDielectronCut.SetMaxMeePhiVDep([&](float phiv) { return dielectroncuts.cfg_phiv_intercept + phiv * dielectroncuts.cfg_phiv_slope; }, dielectroncuts.cfg_min_phiv, dielectroncuts.cfg_max_phiv); fDielectronCut.ApplyPhiV(dielectroncuts.cfg_apply_phiv); - fDielectronCut.SetMindEtadPhi(dielectroncuts.cfg_apply_detadphi, dielectroncuts.cfg_min_deta, dielectroncuts.cfg_min_dphi); + fDielectronCut.SetMindEtadPhi(dielectroncuts.cfg_apply_detadphi, dielectroncuts.cfg_apply_detadphiposition, dielectroncuts.cfg_min_deta, dielectroncuts.cfg_min_dphi); fDielectronCut.SetPairOpAng(dielectroncuts.cfg_min_opang, dielectroncuts.cfg_max_opang); fDielectronCut.SetRequireDifferentSides(dielectroncuts.cfg_require_diff_sides); @@ -729,7 +736,7 @@ struct DileptonMC { fDimuonCut.SetTrackEtaRange(dimuoncuts.cfg_min_eta_track, dimuoncuts.cfg_max_eta_track); fDimuonCut.SetTrackPhiRange(dimuoncuts.cfg_min_phi_track, dimuoncuts.cfg_max_phi_track); fDimuonCut.SetNClustersMFT(dimuoncuts.cfg_min_ncluster_mft, 10); - fDimuonCut.SetNClustersMCHMID(dimuoncuts.cfg_min_ncluster_mch, 16); + fDimuonCut.SetNClustersMCHMID(dimuoncuts.cfg_min_ncluster_mch, 20); fDimuonCut.SetChi2(0.f, dimuoncuts.cfg_max_chi2); fDimuonCut.SetMatchingChi2MCHMFT(0.f, dimuoncuts.cfg_max_matching_chi2_mftmch); fDimuonCut.SetMatchingChi2MCHMID(0.f, dimuoncuts.cfg_max_matching_chi2_mchmid); @@ -823,7 +830,7 @@ struct DileptonMC { return false; } } - if (!cut.IsSelectedPair(t1, t2, d_bz)) { + if (!cut.IsSelectedPair(t1, t2, d_bz, dielectroncuts.cfgRefR)) { return false; } } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { @@ -1003,6 +1010,7 @@ struct DileptonMC { if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.fill(HIST("Pair/sm/PromptPi0/hDeltaPtvsDCA"), pair_dca, deltaPt1 + deltaPt2); fRegistry.fill(HIST("Pair/sm/PromptPi0/hMvsPhiV"), phiv, v12.M()); + fRegistry.fill(HIST("Pair/sm/PromptPi0/hDCAz1vsDCAz2"), dcaZinSigma(t1), dcaZinSigma(t2)); } } else { // non-prompt pi0 fRegistry.fill(HIST("Pair/sm/NonPromptPi0/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), pair_dca, weight); @@ -1043,6 +1051,7 @@ struct DileptonMC { fRegistry.fill(HIST("Pair/sm/PromptJPsi/hs"), v12.M(), v12.Pt(), v12.Rapidity(), dphi, deta, std::fabs(cos_thetaCS), std::fabs(phiCS), aco, asym, std::fabs(dphi_e_ee), pair_dca, weight); if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { fRegistry.fill(HIST("Pair/sm/PromptJPsi/hDeltaPtvsDCA"), pair_dca, deltaPt1 + deltaPt2); + fRegistry.fill(HIST("Pair/sm/PromptJPsi/hDCAz1vsDCAz2"), dcaZinSigma(t1), dcaZinSigma(t2)); } } break; @@ -1224,8 +1233,7 @@ struct DileptonMC { SliceCache cache; Preslice perCollision_electron = aod::emprimaryelectron::emeventId; - Filter trackFilter_electron = o2::aod::track::tpcChi2NCl < dielectroncuts.cfg_max_chi2tpc && o2::aod::track::itsChi2NCl < dielectroncuts.cfg_max_chi2its && nabs(o2::aod::track::dcaXY) < dielectroncuts.cfg_max_dcaxy && nabs(o2::aod::track::dcaZ) < dielectroncuts.cfg_max_dcaz; - Filter pidFilter_electron = dielectroncuts.cfg_min_TPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < dielectroncuts.cfg_max_TPCNsigmaEl; + Filter trackFilter_electron = nabs(o2::aod::track::dcaXY) < dielectroncuts.cfg_max_dcaxy && nabs(o2::aod::track::dcaZ) < dielectroncuts.cfg_max_dcaz; Filter ttcaFilter_electron = ifnode(dielectroncuts.enableTTCA.node(), o2::aod::emprimaryelectron::isAssociatedToMPC == true || o2::aod::emprimaryelectron::isAssociatedToMPC == false, o2::aod::emprimaryelectron::isAssociatedToMPC == true); Filter prefilter_derived_electron = ifnode(dielectroncuts.cfg_apply_cuts_from_prefilter_derived.node() && dielectroncuts.cfg_prefilter_bits_derived.node() >= static_cast(1), ifnode((dielectroncuts.cfg_prefilter_bits_derived.node() & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) > static_cast(0), (o2::aod::emprimaryelectron::pfbderived & static_cast(1 << int(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kMee))) <= static_cast(0), true) && @@ -1242,7 +1250,7 @@ struct DileptonMC { o2::aod::emprimaryelectron::pfb >= static_cast(0)); Preslice perCollision_muon = aod::emprimarymuon::emeventId; - Filter trackFilter_muon = o2::aod::fwdtrack::trackType == dimuoncuts.cfg_track_type && dimuoncuts.cfg_min_phi_track < o2::aod::fwdtrack::phi && o2::aod::fwdtrack::phi < dimuoncuts.cfg_max_phi_track; + Filter trackFilter_muon = o2::aod::fwdtrack::trackType == dimuoncuts.cfg_track_type; Filter ttcaFilter_muon = ifnode(dimuoncuts.enableTTCA.node(), o2::aod::emprimarymuon::isAssociatedToMPC == true || o2::aod::emprimarymuon::isAssociatedToMPC == false, o2::aod::emprimarymuon::isAssociatedToMPC == true); Filter collisionFilter_centrality = (cfgCentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < cfgCentMax) || (cfgCentMin < o2::aod::cent::centFT0A && o2::aod::cent::centFT0A < cfgCentMax) || (cfgCentMin < o2::aod::cent::centFT0C && o2::aod::cent::centFT0C < cfgCentMax); @@ -1889,7 +1897,7 @@ struct DileptonMC { } if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDielectron) { - if (!cut.template IsSelectedPair(t1, t2, d_bz)) { + if (!cut.template IsSelectedPair(t1, t2, d_bz, dielectroncuts.cfgRefR)) { return false; } } else if constexpr (pairtype == o2::aod::pwgem::dilepton::utils::pairutil::DileptonPairType::kDimuon) { diff --git a/PWGEM/Dilepton/Core/DimuonCut.h b/PWGEM/Dilepton/Core/DimuonCut.h index 2895c95f311..1c2ce81010b 100644 --- a/PWGEM/Dilepton/Core/DimuonCut.h +++ b/PWGEM/Dilepton/Core/DimuonCut.h @@ -265,11 +265,11 @@ class DimuonCut : public TNamed // track quality cuts int mTrackType{3}; - int mMinNClustersMFT{0}, mMaxNClustersMFT{10}; // min number of TPC clusters - int mMinNClustersMCHMID{0}, mMaxNClustersMCHMID{16}; // min number of TPC clusters + int mMinNClustersMFT{0}, mMaxNClustersMFT{10}; // min number of MFT clusters + int mMinNClustersMCHMID{0}, mMaxNClustersMCHMID{20}; // min number of MCH-MID clusters float mMinChi2{0.f}, mMaxChi2{1e10f}; // max tpc fit chi2 per TPC cluster - float mMinMatchingChi2MCHMFT{0.f}, mMaxMatchingChi2MCHMFT{1e10f}; // max tpc fit chi2 per TPC cluster - float mMinMatchingChi2MCHMID{0.f}, mMaxMatchingChi2MCHMID{1e10f}; // max tpc fit chi2 per TPC cluster + float mMinMatchingChi2MCHMFT{0.f}, mMaxMatchingChi2MCHMFT{1e10f}; // max matching chi2 between MCH-MFT + float mMinMatchingChi2MCHMID{0.f}, mMaxMatchingChi2MCHMID{1e10f}; // max matching chi2 between MCH-MID std::function mMaxPDCARabsDep{}; // max pdca in xy plane as function of Rabs float mMinRabs{17.6}, mMaxRabs{89.5}; diff --git a/PWGEM/Dilepton/Core/EMEventCut.cxx b/PWGEM/Dilepton/Core/EMEventCut.cxx index 682c496b8e7..58e3c5be4e8 100644 --- a/PWGEM/Dilepton/Core/EMEventCut.cxx +++ b/PWGEM/Dilepton/Core/EMEventCut.cxx @@ -65,7 +65,7 @@ void EMEventCut::SetRequireVertexITSTPC(bool flag) void EMEventCut::SetRequireVertexTOFmatched(bool flag) { mRequireVertexTOFmatched = flag; - LOG(info) << "EM Event Cut, require vertex reconstructed by ITS-TPC matched track: " << mRequireVertexTOFmatched; + LOG(info) << "EM Event Cut, require vertex reconstructed by ITS-TPC-TOF matched track: " << mRequireVertexTOFmatched; } void EMEventCut::SetRequireGoodZvtxFT0vsPV(bool flag) diff --git a/PWGEM/Dilepton/Core/EMTrackCut.h b/PWGEM/Dilepton/Core/EMTrackCut.h index a5d62b45ac0..d70a009aaac 100644 --- a/PWGEM/Dilepton/Core/EMTrackCut.h +++ b/PWGEM/Dilepton/Core/EMTrackCut.h @@ -45,8 +45,8 @@ class EMTrackCut : public TNamed kTrackPtRange, kTrackEtaRange, kTrackPhiRange, - kDCAxy, - kDCAz, + // kDCAxy, + // kDCAz, // kTPCNCls, // kTPCCrossedRows, // kTPCCrossedRowsOverNCls, @@ -75,12 +75,13 @@ class EMTrackCut : public TNamed return false; } - if (!IsSelectedTrack(track, EMTrackCuts::kDCAxy)) { - return false; - } - if (!IsSelectedTrack(track, EMTrackCuts::kDCAz)) { - return false; - } + // if (!IsSelectedTrack(track, EMTrackCuts::kDCAxy)) { + // return false; + // } + // if (!IsSelectedTrack(track, EMTrackCuts::kDCAz)) { + // return false; + // } + if (!IsSelectedTrack(track, EMTrackCuts::kTrackBit)) { return false; } @@ -140,11 +141,11 @@ class EMTrackCut : public TNamed case EMTrackCuts::kTrackPhiRange: return track.phi() > mMinTrackPhi && track.phi() < mMaxTrackPhi; - case EMTrackCuts::kDCAxy: - return std::fabs(track.dcaXY()) < ((mMaxDcaXYPtDep) ? mMaxDcaXYPtDep(track.pt()) : mMaxDcaXY); + // case EMTrackCuts::kDCAxy: + // return std::fabs(track.dcaXY()) < ((mMaxDcaXYPtDep) ? mMaxDcaXYPtDep(track.pt()) : mMaxDcaXY); - case EMTrackCuts::kDCAz: - return std::fabs(track.dcaZ()) < mMaxDcaZ; + // case EMTrackCuts::kDCAz: + // return std::fabs(track.dcaZ()) < mMaxDcaZ; case EMTrackCuts::kTrackBit: { // for (int i = 0; i < 10; i++) { diff --git a/PWGEM/Dilepton/Core/PhotonHBT.h b/PWGEM/Dilepton/Core/PhotonHBT.h index f9c7b46a013..180360e44f3 100644 --- a/PWGEM/Dilepton/Core/PhotonHBT.h +++ b/PWGEM/Dilepton/Core/PhotonHBT.h @@ -80,7 +80,7 @@ using MyCollisionWithSWT = MyCollisionsWithSWT::iterator; using MyV0Photons = soa::Join; using MyV0Photon = MyV0Photons::iterator; -using MyTracks = soa::Join; +using MyTracks = soa::Join; using MyTrack = MyTracks::iterator; using FilteredMyTracks = soa::Filtered; using FilteredMyTrack = FilteredMyTracks::iterator; @@ -99,7 +99,7 @@ struct PhotonHBT { Configurable cfgEP2Estimator_for_Mix{"cfgEP2Estimator_for_Mix", 3, "FT0M:0, FT0A:1, FT0C:2, BTot:3, BPos:4, BNeg:5"}; Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; Configurable cfgOccupancyEstimator{"cfgOccupancyEstimator", 0, "FT0C:0, Track:1"}; - Configurable cfgCentMin{"cfgCentMin", 0, "min. centrality"}; + Configurable cfgCentMin{"cfgCentMin", -1, "min. centrality"}; Configurable cfgCentMax{"cfgCentMax", 999, "max. centrality"}; Configurable maxY{"maxY", 0.8, "maximum rapidity for reconstructed particles"}; Configurable cfgDoMix{"cfgDoMix", true, "flag for event mixing"}; @@ -161,7 +161,6 @@ struct PhotonHBT { Configurable cfg_min_cospa{"cfg_min_cospa", 0.997, "min V0 CosPA"}; Configurable cfg_max_pca{"cfg_max_pca", 3.0, "max distance btween 2 legs"}; Configurable cfg_max_chi2kf{"cfg_max_chi2kf", 1e+10, "max chi2/ndf with KF"}; - Configurable cfg_require_v0_with_correct_xz{"cfg_require_v0_with_correct_xz", true, "flag to select V0s with correct xz"}; Configurable cfg_reject_v0_on_itsib{"cfg_reject_v0_on_itsib", true, "flag to reject V0s on ITSib"}; Configurable cfg_disable_itsonly_track{"cfg_disable_itsonly_track", false, "flag to disable ITSonly tracks"}; @@ -213,6 +212,7 @@ struct PhotonHBT { Configurable cfg_max_rel_diff_pin{"cfg_max_rel_diff_pin", +1e+10, "max rel. diff. between pin and ppv"}; Configurable cfg_require_itsib_any{"cfg_require_itsib_any", false, "flag to require ITS ib any hits"}; Configurable cfg_require_itsib_1st{"cfg_require_itsib_1st", true, "flag to require ITS ib 1st hit"}; + Configurable cfgRefR{"cfgRefR", 1.2, "reference R (in m) for extrapolation"}; // https://cds.cern.ch/record/1419204 Configurable cfg_pid_scheme{"cfg_pid_scheme", static_cast(DielectronCut::PIDSchemes::kTPChadrejORTOFreq), "pid scheme [kTOFreq : 0, kTPChadrej : 1, kTPChadrejORTOFreq : 2, kTPConly : 3, kTOFif = 4, kPIDML = 5]"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; @@ -535,7 +535,6 @@ struct PhotonHBT { fV0PhotonCut.SetDisableTPConly(pcmcuts.cfg_disable_tpconly_track); fV0PhotonCut.SetNClustersITS(0, 7); fV0PhotonCut.SetMeanClusterSizeITSob(0.0, 16.0); - fV0PhotonCut.SetIsWithinBeamPipe(pcmcuts.cfg_require_v0_with_correct_xz); fV0PhotonCut.SetRequireITSTPC(pcmcuts.cfg_require_v0_with_itstpc); fV0PhotonCut.SetRequireITSonly(pcmcuts.cfg_require_v0_with_itsonly); fV0PhotonCut.SetRequireTPConly(pcmcuts.cfg_require_v0_with_tpconly); @@ -849,7 +848,7 @@ struct PhotonHBT { continue; } } - if (!cut1.IsSelectedPair(pos1, ele1, d_bz)) { + if (!cut1.IsSelectedPair(pos1, ele1, d_bz, dielectroncuts.cfgRefR)) { continue; } @@ -877,7 +876,7 @@ struct PhotonHBT { continue; } } - if (!cut2.IsSelectedPair(pos2, ele2, d_bz)) { + if (!cut2.IsSelectedPair(pos2, ele2, d_bz, dielectroncuts.cfgRefR)) { continue; } @@ -995,7 +994,7 @@ struct PhotonHBT { continue; } } - if (!cut2.IsSelectedPair(pos2, ele2, d_bz)) { + if (!cut2.IsSelectedPair(pos2, ele2, d_bz, dielectroncuts.cfgRefR)) { continue; } @@ -1363,7 +1362,7 @@ struct PhotonHBT { continue; } } - if (!cut.IsSelectedPair(pos, ele, d_bz)) { + if (!cut.IsSelectedPair(pos, ele, d_bz, dielectroncuts.cfgRefR)) { continue; } passed_pairIds.emplace_back(std::make_pair(pos.globalIndex(), ele.globalIndex())); diff --git a/PWGEM/Dilepton/Core/SingleTrackQC.h b/PWGEM/Dilepton/Core/SingleTrackQC.h index 0fe4182f96a..4f9744ea769 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQC.h @@ -58,7 +58,7 @@ using MyCollision = MyCollisions::iterator; using MyCollisionsWithSWT = soa::Join; using MyCollisionWithSWT = MyCollisionsWithSWT::iterator; -using MyElectrons = soa::Join; +using MyElectrons = soa::Join; using MyElectron = MyElectrons::iterator; using FilteredMyElectrons = soa::Filtered; using FilteredMyElectron = FilteredMyElectrons::iterator; @@ -75,7 +75,7 @@ struct SingleTrackQC { Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; - Configurable cfgCentMin{"cfgCentMin", 0, "min. centrality"}; + Configurable cfgCentMin{"cfgCentMin", -1, "min. centrality"}; Configurable cfgCentMax{"cfgCentMax", 999.f, "max. centrality"}; Configurable cfg_swt_name{"cfg_swt_name", "fHighTrackMult", "desired software trigger name"}; // 1 trigger name per 1 task. fHighTrackMult, fHighFt0Mult // Configurable cfgNtracksPV08Min{"cfgNtracksPV08Min", -1, "min. multNTracksPV"}; @@ -265,9 +265,9 @@ struct SingleTrackQC { fRegistry.add("Track/positive/hTOFbeta", "TOF #beta;p_{pv} (GeV/c);#beta", kTH2F, {{1000, 0, 10}, {240, 0, 1.2}}, false); fRegistry.add("Track/positive/hTOFNsigmaEl", "TOF n sigma el;p_{pv} (GeV/c);n #sigma_{e}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); // fRegistry.add("Track/positive/hTOFNsigmaMu", "TOF n sigma mu;p_{pv} (GeV/c);n #sigma_{#mu}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/positive/hTOFNsigmaPi", "TOF n sigma pi;p_{pv} (GeV/c);n #sigma_{#pi}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/positive/hTOFNsigmaKa", "TOF n sigma ka;p_{pv} (GeV/c);n #sigma_{K}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/positive/hTOFNsigmaPr", "TOF n sigma pr;p_{pv} (GeV/c);n #sigma_{p}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + // fRegistry.add("Track/positive/hTOFNsigmaPi", "TOF n sigma pi;p_{pv} (GeV/c);n #sigma_{#pi}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + // fRegistry.add("Track/positive/hTOFNsigmaKa", "TOF n sigma ka;p_{pv} (GeV/c);n #sigma_{K}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + // fRegistry.add("Track/positive/hTOFNsigmaPr", "TOF n sigma pr;p_{pv} (GeV/c);n #sigma_{p}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); fRegistry.add("Track/positive/hMeanClusterSizeITS", "mean cluster size ITS;p_{pv} (GeV/c); on ITS #times cos(#lambda);", kTH2F, {{1000, 0.f, 10.f}, {150, 0, 15}}, false); fRegistry.add("Track/positive/hMeanClusterSizeITSib", "mean cluster size ITS inner barrel;p_{pv} (GeV/c); on ITS #times cos(#lambda);", kTH2F, {{1000, 0.f, 10.f}, {150, 0, 15}}, false); @@ -509,9 +509,9 @@ struct SingleTrackQC { fRegistry.fill(HIST("Track/positive/hTPCNsigmaPr"), track.tpcInnerParam(), track.tpcNSigmaPr()); fRegistry.fill(HIST("Track/positive/hTOFNsigmaEl"), track.p(), track.tofNSigmaEl()); // fRegistry.fill(HIST("Track/positive/hTOFNsigmaMu"), track.p(), track.tofNSigmaMu()); - fRegistry.fill(HIST("Track/positive/hTOFNsigmaPi"), track.p(), track.tofNSigmaPi()); - fRegistry.fill(HIST("Track/positive/hTOFNsigmaKa"), track.p(), track.tofNSigmaKa()); - fRegistry.fill(HIST("Track/positive/hTOFNsigmaPr"), track.p(), track.tofNSigmaPr()); + // fRegistry.fill(HIST("Track/positive/hTOFNsigmaPi"), track.p(), track.tofNSigmaPi()); + // fRegistry.fill(HIST("Track/positive/hTOFNsigmaKa"), track.p(), track.tofNSigmaKa()); + // fRegistry.fill(HIST("Track/positive/hTOFNsigmaPr"), track.p(), track.tofNSigmaPr()); // fRegistry.fill(HIST("Track/positive/hITSNsigmaEl"), track.p(), track.itsNSigmaEl()); // fRegistry.fill(HIST("Track/positive/hITSNsigmaMu"), track.p(), track.itsNSigmaMu()); // fRegistry.fill(HIST("Track/positive/hITSNsigmaPi"), track.p(), track.itsNSigmaPi()); @@ -549,9 +549,9 @@ struct SingleTrackQC { fRegistry.fill(HIST("Track/negative/hTPCNsigmaPr"), track.tpcInnerParam(), track.tpcNSigmaPr()); fRegistry.fill(HIST("Track/negative/hTOFNsigmaEl"), track.p(), track.tofNSigmaEl()); // fRegistry.fill(HIST("Track/negative/hTOFNsigmaMu"), track.p(), track.tofNSigmaMu()); - fRegistry.fill(HIST("Track/negative/hTOFNsigmaPi"), track.p(), track.tofNSigmaPi()); - fRegistry.fill(HIST("Track/negative/hTOFNsigmaKa"), track.p(), track.tofNSigmaKa()); - fRegistry.fill(HIST("Track/negative/hTOFNsigmaPr"), track.p(), track.tofNSigmaPr()); + // fRegistry.fill(HIST("Track/negative/hTOFNsigmaPi"), track.p(), track.tofNSigmaPi()); + // fRegistry.fill(HIST("Track/negative/hTOFNsigmaKa"), track.p(), track.tofNSigmaKa()); + // fRegistry.fill(HIST("Track/negative/hTOFNsigmaPr"), track.p(), track.tofNSigmaPr()); // fRegistry.fill(HIST("Track/negative/hITSNsigmaEl"), track.p(), track.itsNSigmaEl()); // fRegistry.fill(HIST("Track/negative/hITSNsigmaMu"), track.p(), track.itsNSigmaMu()); // fRegistry.fill(HIST("Track/negative/hITSNsigmaPi"), track.p(), track.itsNSigmaPi()); diff --git a/PWGEM/Dilepton/Core/SingleTrackQCMC.h b/PWGEM/Dilepton/Core/SingleTrackQCMC.h index ce5496388d6..95e4bc97507 100644 --- a/PWGEM/Dilepton/Core/SingleTrackQCMC.h +++ b/PWGEM/Dilepton/Core/SingleTrackQCMC.h @@ -60,7 +60,7 @@ using MyCollision = MyCollisions::iterator; using MyMCCollisions = soa::Join; using MyMCCollision = MyMCCollisions::iterator; -using MyMCElectrons = soa::Join; +using MyMCElectrons = soa::Join; using MyMCElectron = MyMCElectrons::iterator; using FilteredMyMCElectrons = soa::Filtered; @@ -82,7 +82,7 @@ struct SingleTrackQCMC { Configurable cfgEventGeneratorType{"cfgEventGeneratorType", -1, "if positive, select event generator type. i.e. gap or signal"}; Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; - Configurable cfgCentMin{"cfgCentMin", 0, "min. centrality"}; + Configurable cfgCentMin{"cfgCentMin", -1, "min. centrality"}; Configurable cfgCentMax{"cfgCentMax", 999.f, "max. centrality"}; // Configurable cfgNtracksPV08Min{"cfgNtracksPV08Min", -1, "min. multNTracksPV"}; // Configurable cfgNtracksPV08Max{"cfgNtracksPV08Max", static_cast(1e+9), "max. multNTracksPV"}; @@ -314,9 +314,9 @@ struct SingleTrackQCMC { fRegistry.add("Track/PID/positive/hTOFbeta", "TOF #beta;p_{pv} (GeV/c);#beta", kTH2F, {{1000, 0, 10}, {240, 0, 1.2}}, false); fRegistry.add("Track/PID/positive/hTOFNsigmaEl", "TOF n sigma el;p_{pv} (GeV/c);n #sigma_{e}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); // fRegistry.add("Track/PID/positive/hTOFNsigmaMu", "TOF n sigma mu;p_{pv} (GeV/c);n #sigma_{#mu}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/PID/positive/hTOFNsigmaPi", "TOF n sigma pi;p_{pv} (GeV/c);n #sigma_{#pi}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/PID/positive/hTOFNsigmaKa", "TOF n sigma ka;p_{pv} (GeV/c);n #sigma_{K}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/PID/positive/hTOFNsigmaPr", "TOF n sigma pr;p_{pv} (GeV/c);n #sigma_{p}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + // fRegistry.add("Track/PID/positive/hTOFNsigmaPi", "TOF n sigma pi;p_{pv} (GeV/c);n #sigma_{#pi}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + // fRegistry.add("Track/PID/positive/hTOFNsigmaKa", "TOF n sigma ka;p_{pv} (GeV/c);n #sigma_{K}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + // fRegistry.add("Track/PID/positive/hTOFNsigmaPr", "TOF n sigma pr;p_{pv} (GeV/c);n #sigma_{p}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); fRegistry.add("Track/PID/positive/hMeanClusterSizeITS", "mean cluster size ITS;p_{pv} (GeV/c); on ITS #times cos(#lambda)", kTH2F, {{1000, 0.f, 10.f}, {150, 0, 15}}, false); fRegistry.add("Track/PID/positive/hMeanClusterSizeITSib", "mean cluster size ITS inner barrel;p_{pv} (GeV/c); on ITS #times cos(#lambda)", kTH2F, {{1000, 0.f, 10.f}, {150, 0, 15}}, false); fRegistry.add("Track/PID/positive/hMeanClusterSizeITSob", "mean cluster size ITS outer barrel;p_{pv} (GeV/c); on ITS #times cos(#lambda)", kTH2F, {{1000, 0.f, 10.f}, {150, 0, 15}}, false); @@ -630,9 +630,9 @@ struct SingleTrackQCMC { fRegistry.fill(HIST("Track/PID/positive/hTPCNsigmaPr"), track.tpcInnerParam(), track.tpcNSigmaPr()); fRegistry.fill(HIST("Track/PID/positive/hTOFNsigmaEl"), track.p(), track.tofNSigmaEl()); // fRegistry.fill(HIST("Track/PID/positive/hTOFNsigmaMu"), track.p(), track.tofNSigmaMu()); - fRegistry.fill(HIST("Track/PID/positive/hTOFNsigmaPi"), track.p(), track.tofNSigmaPi()); - fRegistry.fill(HIST("Track/PID/positive/hTOFNsigmaKa"), track.p(), track.tofNSigmaKa()); - fRegistry.fill(HIST("Track/PID/positive/hTOFNsigmaPr"), track.p(), track.tofNSigmaPr()); + // fRegistry.fill(HIST("Track/PID/positive/hTOFNsigmaPi"), track.p(), track.tofNSigmaPi()); + // fRegistry.fill(HIST("Track/PID/positive/hTOFNsigmaKa"), track.p(), track.tofNSigmaKa()); + // fRegistry.fill(HIST("Track/PID/positive/hTOFNsigmaPr"), track.p(), track.tofNSigmaPr()); // fRegistry.fill(HIST("Track/PID/positive/hITSNsigmaEl"), track.p(), track.itsNSigmaEl()); // fRegistry.fill(HIST("Track/PID/positive/hITSNsigmaMu"), track.p(), track.itsNSigmaMu()); // fRegistry.fill(HIST("Track/PID/positive/hITSNsigmaPi"), track.p(), track.itsNSigmaPi()); @@ -678,9 +678,9 @@ struct SingleTrackQCMC { fRegistry.fill(HIST("Track/PID/negative/hTPCNsigmaPr"), track.tpcInnerParam(), track.tpcNSigmaPr()); fRegistry.fill(HIST("Track/PID/negative/hTOFNsigmaEl"), track.p(), track.tofNSigmaEl()); // fRegistry.fill(HIST("Track/PID/negative/hTOFNsigmaMu"), track.p(), track.tofNSigmaMu()); - fRegistry.fill(HIST("Track/PID/negative/hTOFNsigmaPi"), track.p(), track.tofNSigmaPi()); - fRegistry.fill(HIST("Track/PID/negative/hTOFNsigmaKa"), track.p(), track.tofNSigmaKa()); - fRegistry.fill(HIST("Track/PID/negative/hTOFNsigmaPr"), track.p(), track.tofNSigmaPr()); + // fRegistry.fill(HIST("Track/PID/negative/hTOFNsigmaPi"), track.p(), track.tofNSigmaPi()); + // fRegistry.fill(HIST("Track/PID/negative/hTOFNsigmaKa"), track.p(), track.tofNSigmaKa()); + // fRegistry.fill(HIST("Track/PID/negative/hTOFNsigmaPr"), track.p(), track.tofNSigmaPr()); // fRegistry.fill(HIST("Track/PID/negative/hITSNsigmaEl"), track.p(), track.itsNSigmaEl()); // fRegistry.fill(HIST("Track/PID/negative/hITSNsigmaMu"), track.p(), track.itsNSigmaMu()); // fRegistry.fill(HIST("Track/PID/negative/hITSNsigmaPi"), track.p(), track.itsNSigmaPi()); diff --git a/PWGEM/Dilepton/DataModel/dileptonTables.h b/PWGEM/Dilepton/DataModel/dileptonTables.h index a96debb1457..f507a5220ba 100644 --- a/PWGEM/Dilepton/DataModel/dileptonTables.h +++ b/PWGEM/Dilepton/DataModel/dileptonTables.h @@ -41,6 +41,7 @@ enum class swtAliases : int { // software trigger aliases for EM kSingleMuLow, kSingleMuHigh, kDiMuon, + kHighFt0cFv0Mult, kNaliases }; @@ -54,6 +55,7 @@ const std::unordered_map aliasLabels = { {"fSingleMuLow", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kSingleMuLow)}, {"fSingleMuHigh", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kSingleMuHigh)}, {"fDiMuon", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kDiMuon)}, + {"fHighFt0cFv0Mult", static_cast(o2::aod::pwgem::dilepton::swt::swtAliases::kHighFt0cFv0Mult)}, }; } // namespace pwgem::dilepton::swt @@ -122,6 +124,8 @@ DECLARE_SOA_COLUMN(SpherocityPtUnWeighted, spherocity_ptunweighted, float); //! DECLARE_SOA_COLUMN(NtrackSpherocity, ntspherocity, int); DECLARE_SOA_COLUMN(IsSelected, isSelected, bool); //! MB event selection info DECLARE_SOA_COLUMN(IsEoI, isEoI, bool); //! lepton or photon exists in MB event (not for CEFP) +DECLARE_SOA_COLUMN(PosX, posX, float); //! only for treeCreatetorML.cxx +DECLARE_SOA_COLUMN(PosY, posY, float); //! only for treeCreatetorML.cxx DECLARE_SOA_COLUMN(PosZint16, posZint16, int16_t); //! this is only to reduce data size DECLARE_SOA_DYNAMIC_COLUMN(PosZ, posZ, [](int16_t posZint16) -> float { return static_cast(posZint16) * 0.1f; }); @@ -156,9 +160,17 @@ DECLARE_SOA_TABLE_VERSIONED(EMEvents_002, "AOD", "EMEVENT", 2, //! Main event collision::PosX, collision::PosY, collision::PosZ, collision::NumContrib, evsel::NumTracksInTimeRange, evsel::SumAmpFT0CInTimeRange, emevent::Sel8); -using EMEvents = EMEvents_002; +DECLARE_SOA_TABLE_VERSIONED(EMEvents_003, "AOD", "EMEVENT", 3, //! Main event information table + o2::soa::Index<>, emevent::CollisionId, bc::RunNumber, bc::GlobalBC, evsel::Alias, evsel::Selection, evsel::Rct, timestamp::Timestamp, + collision::PosZ, + collision::NumContrib, evsel::NumTracksInTimeRange, evsel::SumAmpFT0CInTimeRange, emevent::Sel8); + +using EMEvents = EMEvents_003; using EMEvent = EMEvents::iterator; +DECLARE_SOA_TABLE(EMEventsXY, "AOD", "EMEVENTXY", emevent::PosX, emevent::PosY); // joinable to EMEvents, only for treeCreatetorML.cxx +using EMEventXY = EMEventsXY::iterator; + DECLARE_SOA_TABLE(EMEventsCov, "AOD", "EMEVENTCOV", //! joinable to EMEvents collision::CovXX, collision::CovXY, collision::CovXZ, collision::CovYY, collision::CovYZ, collision::CovZZ, collision::Chi2, o2::soa::Marker<1>); using EMEventCov = EMEventsCov::iterator; @@ -396,21 +408,25 @@ DECLARE_SOA_COLUMN(CollisionId, collisionId, int); //! DECLARE_SOA_COLUMN(TrackId, trackId, int); //! DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN(AmbiguousElectrons, ambiguousElectrons); DECLARE_SOA_COLUMN(IsAssociatedToMPC, isAssociatedToMPC, bool); //! is associated to most probable collision +DECLARE_SOA_COLUMN(IsAmbiguous, isAmbiguous, bool); //! is ambiguous DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! DECLARE_SOA_COLUMN(PrefilterBit, pfb, uint8_t); //! DECLARE_SOA_COLUMN(PrefilterBitDerived, pfbderived, uint16_t); //! -DECLARE_SOA_COLUMN(ITSNSigmaEl, itsNSigmaEl, float); //! -DECLARE_SOA_COLUMN(ITSNSigmaMu, itsNSigmaMu, float); //! -DECLARE_SOA_COLUMN(ITSNSigmaPi, itsNSigmaPi, float); //! -DECLARE_SOA_COLUMN(ITSNSigmaKa, itsNSigmaKa, float); //! -DECLARE_SOA_COLUMN(ITSNSigmaPr, itsNSigmaPr, float); //! -// DECLARE_SOA_COLUMN(TPCSignalMC, mcTunedtpcSignal, float); //! +DECLARE_SOA_COLUMN(ProbElBDT, probElBDT, float); //! + +DECLARE_SOA_COLUMN(ITSNSigmaEl, itsNSigmaEl, float); //! +DECLARE_SOA_COLUMN(ITSNSigmaMu, itsNSigmaMu, float); //! +DECLARE_SOA_COLUMN(ITSNSigmaPi, itsNSigmaPi, float); //! +DECLARE_SOA_COLUMN(ITSNSigmaKa, itsNSigmaKa, float); //! +DECLARE_SOA_COLUMN(ITSNSigmaPr, itsNSigmaPr, float); //! + DECLARE_SOA_DYNAMIC_COLUMN(Signed1Pt, signed1Pt, [](float pt, int8_t sign) -> float { return sign * 1. / pt; }); DECLARE_SOA_DYNAMIC_COLUMN(P, p, [](float pt, float eta) -> float { return pt * std::cosh(eta); }); DECLARE_SOA_DYNAMIC_COLUMN(Px, px, [](float pt, float phi) -> float { return pt * std::cos(phi); }); DECLARE_SOA_DYNAMIC_COLUMN(Py, py, [](float pt, float phi) -> float { return pt * std::sin(phi); }); DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, [](float pt, float eta) -> float { return pt * std::sinh(eta); }); DECLARE_SOA_DYNAMIC_COLUMN(Theta, theta, [](float tgl) -> float { return M_PI_2 - std::atan(tgl); }); +DECLARE_SOA_DYNAMIC_COLUMN(Tgl, tgl, [](float eta) -> float { return std::tan(M_PI_2 - 2 * std::atan(std::exp(-eta))); }); DECLARE_SOA_DYNAMIC_COLUMN(MeanClusterSizeITS, meanClusterSizeITS, [](uint32_t itsClusterSizes) -> float { int total_cluster_size = 0, nl = 0; for (unsigned int layer = 0; layer < 7; layer++) { @@ -549,11 +565,43 @@ DECLARE_SOA_TABLE_VERSIONED(EMPrimaryElectrons_003, "AOD", "EMPRIMARYEL", 3, //! emprimaryelectron::MeanClusterSizeITSib, emprimaryelectron::MeanClusterSizeITSob); -using EMPrimaryElectrons = EMPrimaryElectrons_003; +DECLARE_SOA_TABLE_VERSIONED(EMPrimaryElectrons_004, "AOD", "EMPRIMARYEL", 4, //! + o2::soa::Index<>, emprimaryelectron::CollisionId, + emprimaryelectron::TrackId, emprimaryelectron::Sign, + track::Pt, track::Eta, track::Phi, + track::DcaXY, track::DcaZ, aod::track::CYY, aod::track::CZY, aod::track::CZZ, + track::TPCNClsFindable, track::TPCNClsFindableMinusFound, track::TPCNClsFindableMinusCrossedRows, track::TPCNClsShared, + track::TPCChi2NCl, track::TPCInnerParam, + track::TPCSignal, pidtpc::TPCNSigmaEl, pidtpc::TPCNSigmaPi, pidtpc::TPCNSigmaKa, pidtpc::TPCNSigmaPr, + pidtofbeta::Beta, pidtof::TOFNSigmaEl, /*pidtof::TOFNSigmaPi, pidtof::TOFNSigmaKa, pidtof::TOFNSigmaPr,*/ + track::ITSClusterSizes, track::ITSChi2NCl, track::TOFChi2, track::DetectorMap, /*track::Tgl,*/ + emprimaryelectron::IsAssociatedToMPC, emprimaryelectron::IsAmbiguous, emprimaryelectron::ProbElBDT, + mcpidtpc::DeDxTunedMc, + + // dynamic column + track::TPCNClsFound, + track::TPCNClsCrossedRows, + track::TPCCrossedRowsOverFindableCls, + track::TPCFoundOverFindableCls, + track::TPCFractionSharedCls, + track::v001::ITSClusterMap, track::v001::ITSNCls, track::v001::ITSNClsInnerBarrel, + track::HasITS, track::HasTPC, track::HasTRD, track::HasTOF, + + emprimaryelectron::Signed1Pt, + emprimaryelectron::P, + emprimaryelectron::Px, + emprimaryelectron::Py, + emprimaryelectron::Pz, + emprimaryelectron::Tgl, + emprimaryelectron::MeanClusterSizeITS, + emprimaryelectron::MeanClusterSizeITSib, + emprimaryelectron::MeanClusterSizeITSob); + +using EMPrimaryElectrons = EMPrimaryElectrons_004; // iterators using EMPrimaryElectron = EMPrimaryElectrons::iterator; -DECLARE_SOA_TABLE(EMPrimaryElectronsCov, "AOD", "EMPRIMARYELCOV", //! +DECLARE_SOA_TABLE(EMPrimaryElectronsCov_000, "AOD", "EMPRIMARYELCOV", //! aod::track::CYY, aod::track::CZY, aod::track::CZZ, @@ -569,9 +617,35 @@ DECLARE_SOA_TABLE(EMPrimaryElectronsCov, "AOD", "EMPRIMARYELCOV", //! aod::track::C1PtSnp, aod::track::C1PtTgl, aod::track::C1Pt21Pt2, o2::soa::Marker<1>); + +DECLARE_SOA_TABLE_VERSIONED(EMPrimaryElectronsCov_001, "AOD", "EMPRIMARYELCOV", 1, //! + aod::track::X, + aod::track::Alpha, + aod::track::Y, + aod::track::Z, + aod::track::Snp, + aod::track::CSnpY, + aod::track::CSnpZ, + aod::track::CSnpSnp, + aod::track::CTglY, + aod::track::CTglZ, + aod::track::CTglSnp, + aod::track::CTglTgl, + aod::track::C1PtY, + aod::track::C1PtZ, + aod::track::C1PtSnp, + aod::track::C1PtTgl, + aod::track::C1Pt21Pt2); // CYY, CZY, CZZ, Tgl are in the main electron table. + +using EMPrimaryElectronsCov = EMPrimaryElectronsCov_001; // iterators using EMPrimaryElectronCov = EMPrimaryElectronsCov::iterator; +DECLARE_SOA_TABLE_VERSIONED(EMPrimaryElectronsDeDxMC_000, "AOD", "EMPRMELDEDXMC", 0, mcpidtpc::DeDxTunedMc, o2::soa::Marker<1>); +using EMPrimaryElectronsDeDxMC = EMPrimaryElectronsDeDxMC_000; +// iterators +using EMPrimaryElectronDeDxMC = EMPrimaryElectronsDeDxMC::iterator; + DECLARE_SOA_TABLE(EMPrimaryElectronEMEventIds, "AOD", "PRMELMEVENTID", emprimaryelectron::EMEventId); // To be joined with EMPrimaryElectrons table at analysis level. // iterators using EMPrimaryElectronEMEventId = EMPrimaryElectronEMEventIds::iterator; @@ -688,46 +762,34 @@ DECLARE_SOA_TABLE(EMGlobalMuonSelfIds, "AOD", "EMGLMUSELFID", emprimarymuon::Glo // iterators using EMGlobalMuonSelfId = EMGlobalMuonSelfIds::iterator; +namespace oldemprimarytrack +{ +DECLARE_SOA_COLUMN(Sign, sign, int8_t); +} // namespace oldemprimarytrack + namespace emprimarytrack { DECLARE_SOA_INDEX_COLUMN(EMEvent, emevent); //! DECLARE_SOA_COLUMN(CollisionId, collisionId, int); //! DECLARE_SOA_COLUMN(TrackId, trackId, int); //! -// DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! -DECLARE_SOA_COLUMN(TrackBit, trackBit, uint16_t); //! -DECLARE_SOA_COLUMN(PtUINT16, ptuint16, uint16_t); //! -DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, [](uint16_t ptuint16) -> float { return static_cast(ptuint16) * 1e-4; }); -// DECLARE_SOA_DYNAMIC_COLUMN(Signed1Pt, signed1Pt, [](float pt, int8_t sign) -> float { return sign * 1. / pt; }); -// DECLARE_SOA_DYNAMIC_COLUMN(P, p, [](float pt, float eta) -> float { return pt * std::cosh(eta); }); -// DECLARE_SOA_DYNAMIC_COLUMN(Px, px, [](float pt, float phi) -> float { return pt * std::cos(phi); }); -// DECLARE_SOA_DYNAMIC_COLUMN(Py, py, [](float pt, float phi) -> float { return pt * std::sin(phi); }); -// DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, [](float pt, float eta) -> float { return pt * std::sinh(eta); }); +DECLARE_SOA_COLUMN(TrackBit, trackBit, uint16_t); //! +DECLARE_SOA_COLUMN(Signed1Pt, signed1Pt, float); //! (sign of charge)/Pt in c/GeV. Use pt() and sign() instead +DECLARE_SOA_COLUMN(Eta, eta, float); //! +DECLARE_SOA_COLUMN(Phi, phi, float); //! +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, [](float signed1Pt) -> float { return 1.f / std::fabs(signed1Pt); }); +DECLARE_SOA_DYNAMIC_COLUMN(Sign, sign, [](float signed1Pt) -> short { return (signed1Pt > 0) ? 1 : -1; }); //! Charge: positive: 1, negative: -1 } // namespace emprimarytrack -DECLARE_SOA_TABLE_VERSIONED(EMPrimaryTracks_000, "AOD", "EMPRIMARYTRACK", 0, //! - o2::soa::Index<>, emprimarytrack::CollisionId, emprimarytrack::TrackId, /* emprimarytrack::Sign,*/ - emprimarytrack::PtUINT16, track::Eta, track::Phi, track::DcaXY, track::DcaZ, emprimarytrack::TrackBit, - - // track::TPCNClsFindable, track::TPCNClsFindableMinusFound, track::TPCNClsFindableMinusCrossedRows, track::TPCNClsShared, track::TPCChi2NCl, - // track::ITSClusterSizes, track::ITSChi2NCl, track::DetectorMap, - - // // dynamic column - // track::TPCNClsFound, - // track::TPCNClsCrossedRows, - // track::TPCCrossedRowsOverFindableCls, - // track::TPCFoundOverFindableCls, - // track::TPCFractionSharedCls, - // track::v001::ITSClusterMap, track::v001::ITSNCls, track::v001::ITSNClsInnerBarrel, - - // track::HasITS, track::HasTPC, track::HasTRD, track::HasTOF, - // emprimarytrack::Signed1Pt, - // emprimarytrack::P, - // emprimarytrack::Px, - // emprimarytrack::Py, - // emprimarytrack::Pz - emprimarytrack::Pt); - -using EMPrimaryTracks = EMPrimaryTracks_000; +DECLARE_SOA_TABLE_VERSIONED(EMPrimaryTracks_000, "AOD", "EMPRIMARYTRACK", 0, //! primary charged track table for 2PC + o2::soa::Index<>, emprimarytrack::CollisionId, emprimarytrack::TrackId, oldemprimarytrack::Sign, track::Pt, track::Eta, track::Phi, emprimarytrack::TrackBit); + +DECLARE_SOA_TABLE_VERSIONED(EMPrimaryTracks_001, "AOD", "EMPRIMARYTRACK", 1, //! primary charged track table for 2PC + o2::soa::Index<>, emprimarytrack::CollisionId, emprimarytrack::TrackId, + emprimarytrack::Signed1Pt, emprimarytrack::Eta, emprimarytrack::Phi, emprimarytrack::TrackBit, + // dynamic column + emprimarytrack::Sign, emprimarytrack::Pt); + +using EMPrimaryTracks = EMPrimaryTracks_001; // iterators using EMPrimaryTrack = EMPrimaryTracks::iterator; @@ -735,9 +797,9 @@ DECLARE_SOA_TABLE(EMPrimaryTrackEMEventIds, "AOD", "PRMTRKEMEVENTID", emprimaryt // iterators using EMPrimaryTrackEMEventId = EMPrimaryTrackEMEventIds::iterator; -// DECLARE_SOA_TABLE(EMPrimaryTrackEMEventIdsTMP, "AOD", "PRMTRKEVIDTMP", track::CollisionId); // To be joined with EMPrimaryTracks in associateDileptonToEMEvent -// // iterators -// using EMPrimaryTrackEMEventIdTMP = EMPrimaryTrackEMEventIdsTMP::iterator; +DECLARE_SOA_TABLE(EMPrimaryTrackEMEventIdsTMP, "AOD", "PRMTRKEVIDTMP", track::CollisionId); // To be joined with EMPrimaryTracks in associateDileptonToEMEvent +// iterators +using EMPrimaryTrackEMEventIdTMP = EMPrimaryTrackEMEventIdsTMP::iterator; // Dummy data for MC namespace emdummydata diff --git a/PWGEM/Dilepton/DataModel/lmeeMLTables.h b/PWGEM/Dilepton/DataModel/lmeeMLTables.h index f2000b0f4a4..04232c50114 100644 --- a/PWGEM/Dilepton/DataModel/lmeeMLTables.h +++ b/PWGEM/Dilepton/DataModel/lmeeMLTables.h @@ -49,6 +49,7 @@ DECLARE_SOA_COLUMN(PIDLabel, pidlabel, uint8_t); //! DECLARE_SOA_COLUMN(TrackType, tracktype, uint8_t); //! DECLARE_SOA_COLUMN(TPCNClsFound, tpcNClsFound, uint8_t); //! DECLARE_SOA_COLUMN(TPCNClsCrossedRows, tpcNClsCrossedRows, uint8_t); //! +DECLARE_SOA_COLUMN(TPCNClsPID, tpcNClsPID, uint8_t); //! DECLARE_SOA_COLUMN(IsForValidation, isForValidation, bool); //! DECLARE_SOA_COLUMN(Sign, sign, short); //! DECLARE_SOA_COLUMN(P, p, float); //! @@ -89,7 +90,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(MeanClusterSizeITSob, meanClusterSizeITSob, [](uint32 DECLARE_SOA_TABLE(EMTracksForMLPID, "AOD", "EMTRACKMLPID", //! o2::soa::Index<>, collision::NumContrib, evsel::NumTracksInTimeRange, evsel::SumAmpFT0CInTimeRange, emmltrack::P, track::Tgl, emmltrack::Sign, - track::TPCNClsFindable, emmltrack::TPCNClsFound, emmltrack::TPCNClsCrossedRows, + track::TPCNClsFindable, emmltrack::TPCNClsFound, emmltrack::TPCNClsCrossedRows, emmltrack::TPCNClsPID, track::TPCChi2NCl, track::TPCInnerParam, track::TPCSignal, pidtpc::TPCNSigmaEl, pidtpc::TPCNSigmaPi, pidtpc::TPCNSigmaKa, pidtpc::TPCNSigmaPr, pidtofbeta::Beta, pidtof::TOFNSigmaEl, pidtof::TOFNSigmaPi, pidtof::TOFNSigmaKa, pidtof::TOFNSigmaPr, diff --git a/PWGEM/Dilepton/TableProducer/CMakeLists.txt b/PWGEM/Dilepton/TableProducer/CMakeLists.txt index fd2d85bb04c..9dbfc1b7d61 100644 --- a/PWGEM/Dilepton/TableProducer/CMakeLists.txt +++ b/PWGEM/Dilepton/TableProducer/CMakeLists.txt @@ -25,6 +25,11 @@ o2physics_add_dpl_workflow(skimmer-primary-electron PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::MLCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(skimmer-primary-electron-qc + SOURCES skimmerPrimaryElectronQC.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::MLCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(skimmer-primary-muon SOURCES skimmerPrimaryMuon.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::GlobalTracking @@ -35,11 +40,6 @@ o2physics_add_dpl_workflow(skimmer-primary-track PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(skimmer-secondary-electron - SOURCES skimmerSecondaryElectron.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(create-emevent-dilepton SOURCES createEMEventDilepton.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore @@ -55,11 +55,6 @@ o2physics_add_dpl_workflow(associate-mc-info-dilepton PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(filter-dielectron-event - SOURCES filterDielectronEvent.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(event-selection SOURCES eventSelection.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore diff --git a/PWGEM/Dilepton/TableProducer/associateMCinfoDilepton.cxx b/PWGEM/Dilepton/TableProducer/associateMCinfoDilepton.cxx index 52867a7609d..6bd004a0e40 100644 --- a/PWGEM/Dilepton/TableProducer/associateMCinfoDilepton.cxx +++ b/PWGEM/Dilepton/TableProducer/associateMCinfoDilepton.cxx @@ -42,7 +42,7 @@ struct AssociateMCInfoDilepton { kPCM = 0x4, }; - using MyCollisionsMC = soa::Join; + using MyCollisionsMC = soa::Join; using TracksMC = soa::Join; using FwdTracksMC = soa::Join; using MFTTracksMC = soa::Join; @@ -172,6 +172,10 @@ struct AssociateMCInfoDilepton { continue; } + if (!collision.isEoI()) { // events with at least 1 lepton for data reduction. + continue; + } + registry.fill(HIST("hEventCounter"), 2); auto mcCollision = collision.mcCollision(); mceventlabels(fEventLabels.find(mcCollision.globalIndex())->second, collision.mcMask()); diff --git a/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx b/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx index a6ab3c9c4c5..b8575494195 100644 --- a/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx +++ b/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx @@ -32,6 +32,7 @@ #include using namespace o2; +using namespace o2::aod; using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::soa; @@ -54,6 +55,7 @@ using MyCollisionsMC_Cent_Qvec = soa::Join; struct CreateEMEventDilepton { Produces embc; Produces event; + Produces eventXY; // Produces eventcov; Produces event_mult; Produces event_cent; @@ -188,9 +190,11 @@ struct CreateEMEventDilepton { registry.fill(HIST("hEventCounter"), 2); event(collision.globalIndex(), bc.runNumber(), bc.globalBC(), collision.alias_raw(), collision.selection_raw(), collision.rct_raw(), bc.timestamp(), - collision.posX(), collision.posY(), collision.posZ(), + collision.posZ(), collision.numContrib(), collision.trackOccupancyInTimeRange(), collision.ft0cOccupancyInTimeRange()); + eventXY(collision.posX(), collision.posY()); + // eventcov(collision.covXX(), collision.covXY(), collision.covXZ(), collision.covYY(), collision.covYZ(), collision.covZZ(), collision.chi2()); event_mult(collision.multFT0A(), collision.multFT0C(), collision.multNTracksPV(), collision.multNTracksPVeta1(), collision.multNTracksPVetaHalf()); @@ -304,6 +308,7 @@ struct AssociateDileptonToEMEvent { PresliceUnsorted perCollision_el = aod::emprimaryelectron::collisionId; PresliceUnsorted perCollision_mu = aod::emprimarymuon::collisionId; Preslice perCollision_track = aod::emprimarytrack::collisionId; + // Preslice perCollision_track = aod::track::collisionId; void init(o2::framework::InitContext&) {} @@ -339,6 +344,7 @@ struct AssociateDileptonToEMEvent { } void processChargedTrack(aod::EMEvents const& collisions, aod::EMPrimaryTracks const& tracks) + // void processChargedTrack(aod::EMEvents const& collisions, aod::EMPrimaryTrackEMEventIdsTMP const& tracks) { fillEventId(collisions, tracks, prmtrackeventid, perCollision_track); } diff --git a/PWGEM/Dilepton/TableProducer/filterDielectronEvent.cxx b/PWGEM/Dilepton/TableProducer/filterDielectronEvent.cxx deleted file mode 100644 index de91b961120..00000000000 --- a/PWGEM/Dilepton/TableProducer/filterDielectronEvent.cxx +++ /dev/null @@ -1,1722 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \brief write relevant information about primary electrons. -/// \author daiki.sekihata@cern.ch - -#include "PWGEM/Dilepton/DataModel/dileptonTables.h" -#include "PWGEM/Dilepton/Utils/EMTrackUtilities.h" -#include "PWGEM/Dilepton/Utils/PairUtilities.h" -#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" - -#include "Common/Core/TableHelper.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/CollisionAssociationTables.h" - -#include "CCDB/BasicCCDBManager.h" -#include "CommonConstants/PhysicsConstants.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DetectorsBase/GeometryManager.h" -#include "DetectorsBase/Propagator.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" - -#include "Math/Vector4D.h" - -#include -#include -#include -#include -#include - -using namespace o2; -using namespace o2::soa; -using namespace o2::framework; -using namespace o2::framework::expressions; -using namespace o2::constants::physics; - -using namespace o2::aod::pwgem::dilepton::utils::emtrackutil; - -using MyTracks = soa::Join; -using MyTrack = MyTracks::iterator; -using MyTracksMC = soa::Join; -using MyTrackMC = MyTracksMC::iterator; - -struct filterDielectronEvent { - using MyCollisions = soa::Join; - using MyCollisionsWithSWT = soa::Join; - - SliceCache cache; - Preslice perCol = o2::aod::track::collisionId; - Produces emprimaryelectrons; - Produces emprimaryelectronscov; - Produces filter; - - // Configurables - Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; - Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable skipGRPOquery{"skipGRPOquery", true, "skip grpo query"}; - - // Operation and minimisation criteria - Configurable fillQAHistogram{"fillQAHistogram", false, "flag to fill QA histograms"}; - Configurable d_bz_input{"d_bz_input", -999, "bz field in kG, -999 is automatic"}; - Configurable min_ncluster_tpc{"min_ncluster_tpc", 0, "min ncluster tpc"}; - Configurable mincrossedrows{"mincrossedrows", 80, "min. crossed rows"}; - Configurable min_tpc_cr_findable_ratio{"min_tpc_cr_findable_ratio", 0.8, "min. TPC Ncr/Nf ratio"}; - Configurable max_pin_for_pion_rejection{"max_pin_for_pion_rejection", 1e+10, "pion rejection is applied below this pin"}; - Configurable max_frac_shared_clusters_tpc{"max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; - Configurable min_ncluster_its{"min_ncluster_its", 4, "min ncluster its"}; - Configurable min_ncluster_itsib{"min_ncluster_itsib", 1, "min ncluster itsib"}; - Configurable maxchi2tpc{"maxchi2tpc", 5.0, "max. chi2/NclsTPC"}; - Configurable maxchi2its{"maxchi2its", 6.0, "max. chi2/NclsITS"}; - Configurable minpt{"minpt", 0.15, "min pt for track"}; - Configurable maxeta{"maxeta", 0.9, "eta acceptance"}; - Configurable dca_xy_max{"dca_xy_max", 0.1f, "max DCAxy in cm"}; - Configurable dca_z_max{"dca_z_max", 0.1f, "max DCAz in cm"}; - Configurable dca_3d_sigma_max{"dca_3d_sigma_max", 1.5, "max DCA 3D in sigma"}; - Configurable minTPCNsigmaEl{"minTPCNsigmaEl", -2.5, "min. TPC n sigma for electron inclusion"}; - Configurable maxTPCNsigmaEl{"maxTPCNsigmaEl", 3.5, "max. TPC n sigma for electron inclusion"}; - Configurable maxTOFNsigmaEl{"maxTOFNsigmaEl", 3.5, "max. TOF n sigma for electron inclusion"}; - Configurable minTPCNsigmaPi{"minTPCNsigmaPi", -1e+10, "min. TPC n sigma for pion exclusion"}; - Configurable maxTPCNsigmaPi{"maxTPCNsigmaPi", 2.0, "max. TPC n sigma for pion exclusion"}; - Configurable minTPCNsigmaKa{"minTPCNsigmaKa", -3.0, "min. TPC n sigma for kaon exclusion"}; - Configurable maxTPCNsigmaKa{"maxTPCNsigmaKa", +3.0, "max. TPC n sigma for kaon exclusion"}; - Configurable minTPCNsigmaPr{"minTPCNsigmaPr", -3.0, "min. TPC n sigma for proton exclusion"}; - Configurable maxTPCNsigmaPr{"maxTPCNsigmaPr", +3.0, "max. TPC n sigma for proton exclusion"}; - Configurable maxMee{"maxMee", 1e+10, "max mee for virtual photon selection"}; - - Configurable apply_phiv{"apply_phiv", true, "flag to apply phiv cut"}; - Configurable slope{"slope", 0.0181, "slope for mee vs. phiv"}; - Configurable intercept{"intercept", -0.0370, "intercept for mee vs. phiv"}; - - HistogramRegistry fRegistry{"output", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; - - int mRunNumber; - float d_bz; - Service ccdb; - o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; - - void init(InitContext&) - { - mRunNumber = 0; - d_bz = 0; - - ccdb->setURL(ccdburl); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - ccdb->setFatalWhenNull(false); - - if (fillQAHistogram) { - fRegistry.add("Track/hPt", "pT;p_{T} (GeV/c)", kTH1F, {{1000, 0.0f, 10}}, false); - fRegistry.add("Track/hQoverPt", "q/pT;q/p_{T} (GeV/c)^{-1}", kTH1F, {{400, -20, 20}}, false); - fRegistry.add("Track/hRelSigma1Pt", "relative p_{T} resolution;p_{T} (GeV/c);#sigma_{1/p_{T}} #times p_{T}", kTH2F, {{1000, 0, 10}, {100, 0, 0.1}}, false); - fRegistry.add("Track/hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2F, {{180, 0, 2 * M_PI}, {20, -1.0f, 1.0f}}, false); - fRegistry.add("Track/hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm)", kTH2F, {{200, -1.0f, 1.0f}, {200, -1.0f, 1.0f}}, false); - fRegistry.add("Track/hDCAxyzSigma", "DCA xy vs. z;DCA_{xy} (#sigma);DCA_{z} (#sigma)", kTH2F, {{200, -10.0f, 10.0f}, {200, -10.0f, 10.0f}}, false); - fRegistry.add("Track/hDCAxyRes_Pt", "DCA_{xy} resolution vs. pT;p_{T} (GeV/c);DCA_{xy} resolution (#mum)", kTH2F, {{1000, 0, 10}, {500, 0., 500}}, false); - fRegistry.add("Track/hDCAzRes_Pt", "DCA_{z} resolution vs. pT;p_{T} (GeV/c);DCA_{z} resolution (#mum)", kTH2F, {{1000, 0, 10}, {500, 0., 500}}, false); - fRegistry.add("Track/hNclsTPC", "number of TPC clusters", kTH1F, {{161, -0.5, 160.5}}, false); - fRegistry.add("Track/hNcrTPC", "number of TPC crossed rows", kTH1F, {{161, -0.5, 160.5}}, false); - fRegistry.add("Track/hChi2TPC", "chi2/number of TPC clusters", kTH1F, {{100, 0, 10}}, false); - fRegistry.add("Track/hTPCdEdx", "TPC dE/dx;p_{in} (GeV/c);TPC dE/dx (a.u.)", kTH2F, {{1000, 0, 10}, {200, 0, 200}}, false); - fRegistry.add("Track/hTPCNsigmaEl", "TPC n sigma el;p_{in} (GeV/c);n #sigma_{e}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTPCNsigmaMu", "TPC n sigma mu;p_{in} (GeV/c);n #sigma_{#mu}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTPCNsigmaPi", "TPC n sigma pi;p_{in} (GeV/c);n #sigma_{#pi}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTPCNsigmaKa", "TPC n sigma ka;p_{in} (GeV/c);n #sigma_{K}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTPCNsigmaPr", "TPC n sigma pr;p_{in} (GeV/c);n #sigma_{p}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTOFbeta", "TOF beta;p_{pv} (GeV/c);#beta", kTH2F, {{1000, 0, 10}, {240, 0, 1.2}}, false); - fRegistry.add("Track/hTOFNsigmaEl", "TOF n sigma el;p_{pv} (GeV/c);n #sigma_{e}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTOFNsigmaMu", "TOF n sigma mu;p_{pv} (GeV/c);n #sigma_{#mu}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTOFNsigmaPi", "TOF n sigma pi;p_{pv} (GeV/c);n #sigma_{#pi}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTOFNsigmaKa", "TOF n sigma ka;p_{pv} (GeV/c);n #sigma_{K}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTOFNsigmaPr", "TOF n sigma pr;p_{pv} (GeV/c);n #sigma_{p}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTPCNcr2Nf", "TPC Ncr/Nfindable", kTH1F, {{200, 0, 2}}, false); - fRegistry.add("Track/hTPCNcls2Nf", "TPC Ncls/Nfindable", kTH1F, {{200, 0, 2}}, false); - fRegistry.add("Track/hTPCNclsShared", "TPC Ncls/Nfindable;p_{T} (GeV/c);N_{cls}^{shared}/N_{cls} in TPC", kTH2F, {{1000, 0, 10}, {100, 0, 1}}, false); - fRegistry.add("Track/hNclsITS", "number of ITS clusters", kTH1F, {{8, -0.5, 7.5}}, false); - fRegistry.add("Track/hChi2ITS", "chi2/number of ITS clusters", kTH1F, {{100, 0, 10}}, false); - fRegistry.add("Track/hITSClusterMap", "ITS cluster map", kTH1F, {{128, -0.5, 127.5}}, false); - fRegistry.add("Track/hMeanClusterSizeITS", "mean cluster size ITS;p_{pv} (GeV/c); on ITS #times cos(#lambda)", kTH2F, {{1000, 0, 10}, {150, 0, 15}}, false); - fRegistry.add("Pair/before/hMvsPt", "m_{ee} vs. p_{T,ee};m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c)", kTH2F, {{400, 0, 4}, {100, 0, 10}}, false); - fRegistry.add("Pair/before/hMvsPhiV", "mee vs. phiv;#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", kTH2F, {{90, 0, M_PI}, {100, 0, 0.1}}, false); - fRegistry.addClone("Pair/before/", "Pair/after/"); - fRegistry.add("Pair/uls/hM", "m_{ee};m_{ee} (GeV/c^{2})", kTH1F, {{100, 0, 0.1}}, false); - fRegistry.add("Pair/lspp/hM", "m_{ee};m_{ee} (GeV/c^{2})", kTH1F, {{100, 0, 0.1}}, false); - fRegistry.add("Pair/lsmm/hM", "m_{ee};m_{ee} (GeV/c^{2})", kTH1F, {{100, 0, 0.1}}, false); - } - } - - void initCCDB(aod::BCsWithTimestamps::iterator const& bc) - { - if (mRunNumber == bc.runNumber()) { - return; - } - - // In case override, don't proceed, please - no CCDB access required - if (d_bz_input > -990) { - d_bz = d_bz_input; - o2::parameters::GRPMagField grpmag; - if (std::fabs(d_bz) > 1e-5) { - grpmag.setL3Current(30000.f / (d_bz / 5.0f)); - } - o2::base::Propagator::initFieldFromGRP(&grpmag); - mRunNumber = bc.runNumber(); - return; - } - - auto run3grp_timestamp = bc.timestamp(); - o2::parameters::GRPObject* grpo = 0x0; - o2::parameters::GRPMagField* grpmag = 0x0; - if (!skipGRPOquery) - grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); - if (grpo) { - o2::base::Propagator::initFieldFromGRP(grpo); - // Fetch magnetic field from ccdb for current collision - d_bz = grpo->getNominalL3Field(); - LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; - } else { - grpmag = ccdb->getForTimeStamp(grpmagPath, run3grp_timestamp); - if (!grpmag) { - LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; - } - o2::base::Propagator::initFieldFromGRP(grpmag); - // Fetch magnetic field from ccdb for current collision - d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); - LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; - } - mRunNumber = bc.runNumber(); - } - - template - bool checkTrack(TCollision const& collision, TTrack const& track) - { - if constexpr (isMC) { - if (!track.has_mcParticle()) { - return false; - } - } - - if (track.tpcChi2NCl() > maxchi2tpc) { - return false; - } - - if (track.itsChi2NCl() > maxchi2its) { - return false; - } - - if (!track.hasITS() || !track.hasTPC()) { - return false; - } - if (track.itsNCls() < min_ncluster_its) { - return false; - } - if (track.itsNClsInnerBarrel() < min_ncluster_itsib) { - return false; - } - - if (track.tpcNClsFound() < min_ncluster_tpc) { - return false; - } - - if (track.tpcNClsCrossedRows() < mincrossedrows) { - return false; - } - - if (track.tpcCrossedRowsOverFindableCls() < min_tpc_cr_findable_ratio) { - return false; - } - - if (track.tpcFractionSharedCls() > max_frac_shared_clusters_tpc) { - return false; - } - - std::array dcaInfo; - auto track_par_cov_recalc = getTrackParCov(track); - track_par_cov_recalc.setPID(o2::track::PID::Electron); - // std::array pVec_recalc = {0, 0, 0}; // px, py, pz - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, track_par_cov_recalc, 2.f, matCorr, &dcaInfo); - // getPxPyPz(track_par_cov_recalc, pVec_recalc); - float dcaXY = dcaInfo[0]; - float dcaZ = dcaInfo[1]; - - if (std::fabs(dcaXY) > dca_xy_max || std::fabs(dcaZ) > dca_z_max) { - return false; - } - - if (track_par_cov_recalc.getPt() < minpt || std::fabs(track_par_cov_recalc.getEta()) > maxeta) { - return false; - } - - float dca_3d = 999.f; - float det = track_par_cov_recalc.getSigmaY2() * track_par_cov_recalc.getSigmaZ2() - track_par_cov_recalc.getSigmaZY() * track_par_cov_recalc.getSigmaZY(); - if (det < 0) { - dca_3d = 999.f; - } else { - float chi2 = (dcaXY * dcaXY * track_par_cov_recalc.getSigmaZ2() + dcaZ * dcaZ * track_par_cov_recalc.getSigmaY2() - 2. * dcaXY * dcaZ * track_par_cov_recalc.getSigmaZY()) / det; - dca_3d = std::sqrt(std::fabs(chi2) / 2.); - } - if (dca_3d > dca_3d_sigma_max) { - return false; - } - - return true; - } - - template - bool isElectron(TTrack const& track) - { - return isElectron_TPChadrej(track) || isElectron_TOFreq(track); - } - - template - bool isElectron_TPChadrej(TTrack const& track) - { - if (track.tpcNSigmaEl() < minTPCNsigmaEl || maxTPCNsigmaEl < track.tpcNSigmaEl()) { - return false; - } - if (minTPCNsigmaPi < track.tpcNSigmaPi() && track.tpcNSigmaPi() < maxTPCNsigmaPi && track.tpcInnerParam() < max_pin_for_pion_rejection) { - return false; - } - if (minTPCNsigmaKa < track.tpcNSigmaKa() && track.tpcNSigmaKa() < maxTPCNsigmaKa) { - return false; - } - if (minTPCNsigmaPr < track.tpcNSigmaPr() && track.tpcNSigmaPr() < maxTPCNsigmaPr) { - return false; - } - if (track.hasTOF() && (maxTOFNsigmaEl < std::fabs(track.tofNSigmaEl()))) { - return false; - } - return true; - } - - template - bool isElectron_TOFreq(TTrack const& track) - { - if (minTPCNsigmaPi < track.tpcNSigmaPi() && track.tpcNSigmaPi() < maxTPCNsigmaPi && track.tpcInnerParam() < max_pin_for_pion_rejection) { - return false; - } - return minTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < maxTPCNsigmaEl && std::fabs(track.tofNSigmaEl()) < maxTOFNsigmaEl; - } - - template - void fillTrackTable(TCollision const& collision, TTrack const& track) - { - if (std::find(stored_trackIds.begin(), stored_trackIds.end(), std::pair{collision.globalIndex(), track.globalIndex()}) == stored_trackIds.end()) { - std::array dcaInfo; - auto track_par_cov_recalc = getTrackParCov(track); - track_par_cov_recalc.setPID(o2::track::PID::Electron); - // std::array pVec_recalc = {0, 0, 0}; // px, py, pz - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, track_par_cov_recalc, 2.f, matCorr, &dcaInfo); - // getPxPyPz(track_par_cov_recalc, pVec_recalc); - float dcaXY = dcaInfo[0]; - float dcaZ = dcaInfo[1]; - - float pt_recalc = track_par_cov_recalc.getPt(); - float eta_recalc = track_par_cov_recalc.getEta(); - float phi_recalc = track_par_cov_recalc.getPhi(); - - bool isAssociatedToMPC = collision.globalIndex() == track.collisionId(); - - emprimaryelectrons(collision.globalIndex(), track.globalIndex(), track.sign(), - pt_recalc, eta_recalc, phi_recalc, dcaXY, dcaZ, - track.tpcNClsFindable(), track.tpcNClsFindableMinusFound(), track.tpcNClsFindableMinusCrossedRows(), track.tpcNClsShared(), - track.tpcChi2NCl(), track.tpcInnerParam(), - track.tpcSignal(), track.tpcNSigmaEl(), /*track.tpcNSigmaMu(),*/ track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), - track.beta(), track.tofNSigmaEl(), /*track.tofNSigmaMu(),*/ track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr(), - track.itsClusterSizes(), - // 0, 0, 0, 0, 0, - track.itsChi2NCl(), track.tofChi2(), track.detectorMap(), - track_par_cov_recalc.getX(), track_par_cov_recalc.getAlpha(), track_par_cov_recalc.getY(), track_par_cov_recalc.getZ(), track_par_cov_recalc.getSnp(), track_par_cov_recalc.getTgl(), isAssociatedToMPC, -1); - - emprimaryelectronscov( - track_par_cov_recalc.getSigmaY2(), - track_par_cov_recalc.getSigmaZY(), - track_par_cov_recalc.getSigmaZ2(), - track_par_cov_recalc.getSigmaSnpY(), - track_par_cov_recalc.getSigmaSnpZ(), - track_par_cov_recalc.getSigmaSnp2(), - track_par_cov_recalc.getSigmaTglY(), - track_par_cov_recalc.getSigmaTglZ(), - track_par_cov_recalc.getSigmaTglSnp(), - track_par_cov_recalc.getSigmaTgl2(), - track_par_cov_recalc.getSigma1PtY(), - track_par_cov_recalc.getSigma1PtZ(), - track_par_cov_recalc.getSigma1PtSnp(), - track_par_cov_recalc.getSigma1PtTgl(), - track_par_cov_recalc.getSigma1Pt2()); - - stored_trackIds.emplace_back(std::pair{collision.globalIndex(), track.globalIndex()}); - - if (fillQAHistogram) { - uint32_t itsClusterSizes = track.itsClusterSizes(); - int total_cluster_size = 0, nl = 0; - for (unsigned int layer = 0; layer < 7; layer++) { - int cluster_size_per_layer = (itsClusterSizes >> (layer * 4)) & 0xf; - if (cluster_size_per_layer > 0) { - nl++; - } - total_cluster_size += cluster_size_per_layer; - } - - fRegistry.fill(HIST("Track/hPt"), pt_recalc); - fRegistry.fill(HIST("Track/hQoverPt"), track.sign() / pt_recalc); - fRegistry.fill(HIST("Track/hRelSigma1Pt"), pt_recalc, std::sqrt(track_par_cov_recalc.getSigma1Pt2()) * pt_recalc); - fRegistry.fill(HIST("Track/hEtaPhi"), phi_recalc, eta_recalc); - fRegistry.fill(HIST("Track/hDCAxyz"), dcaXY, dcaZ); - fRegistry.fill(HIST("Track/hDCAxyzSigma"), dcaXY / std::sqrt(track_par_cov_recalc.getSigmaY2()), dcaZ / std::sqrt(track_par_cov_recalc.getSigmaZ2())); - fRegistry.fill(HIST("Track/hDCAxyRes_Pt"), pt_recalc, std::sqrt(track_par_cov_recalc.getSigmaY2()) * 1e+4); // convert cm to um - fRegistry.fill(HIST("Track/hDCAzRes_Pt"), pt_recalc, std::sqrt(track_par_cov_recalc.getSigmaZ2()) * 1e+4); // convert cm to um - fRegistry.fill(HIST("Track/hNclsITS"), track.itsNCls()); - fRegistry.fill(HIST("Track/hNclsTPC"), track.tpcNClsFound()); - fRegistry.fill(HIST("Track/hNcrTPC"), track.tpcNClsCrossedRows()); - fRegistry.fill(HIST("Track/hTPCNcr2Nf"), track.tpcCrossedRowsOverFindableCls()); - fRegistry.fill(HIST("Track/hTPCNcls2Nf"), track.tpcFoundOverFindableCls()); - fRegistry.fill(HIST("Track/hTPCNclsShared"), track.pt(), track.tpcFractionSharedCls()); - fRegistry.fill(HIST("Track/hChi2TPC"), track.tpcChi2NCl()); - fRegistry.fill(HIST("Track/hChi2ITS"), track.itsChi2NCl()); - fRegistry.fill(HIST("Track/hITSClusterMap"), track.itsClusterMap()); - fRegistry.fill(HIST("Track/hMeanClusterSizeITS"), track.p(), static_cast(total_cluster_size) / static_cast(nl) * std::cos(std::atan(track.tgl()))); - fRegistry.fill(HIST("Track/hTPCdEdx"), track.tpcInnerParam(), track.tpcSignal()); - fRegistry.fill(HIST("Track/hTPCNsigmaEl"), track.tpcInnerParam(), track.tpcNSigmaEl()); - fRegistry.fill(HIST("Track/hTPCNsigmaMu"), track.tpcInnerParam(), track.tpcNSigmaMu()); - fRegistry.fill(HIST("Track/hTPCNsigmaPi"), track.tpcInnerParam(), track.tpcNSigmaPi()); - fRegistry.fill(HIST("Track/hTPCNsigmaKa"), track.tpcInnerParam(), track.tpcNSigmaKa()); - fRegistry.fill(HIST("Track/hTPCNsigmaPr"), track.tpcInnerParam(), track.tpcNSigmaPr()); - fRegistry.fill(HIST("Track/hTOFbeta"), track.p(), track.beta()); - fRegistry.fill(HIST("Track/hTOFNsigmaEl"), track.p(), track.tofNSigmaEl()); - fRegistry.fill(HIST("Track/hTOFNsigmaMu"), track.p(), track.tofNSigmaMu()); - fRegistry.fill(HIST("Track/hTOFNsigmaPi"), track.p(), track.tofNSigmaPi()); - fRegistry.fill(HIST("Track/hTOFNsigmaKa"), track.p(), track.tofNSigmaKa()); - fRegistry.fill(HIST("Track/hTOFNsigmaPr"), track.p(), track.tofNSigmaPr()); - } - } - } - - template - o2::track::TrackParCov propagateTrack(TCollision const& collision, TTrack const& track) - { - std::array dcaInfo; - auto track_par_cov_recalc = getTrackParCov(track); - track_par_cov_recalc.setPID(o2::track::PID::Electron); - // std::array pVec_recalc = {0, 0, 0}; // px, py, pz - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, track_par_cov_recalc, 2.f, matCorr, &dcaInfo); - // getPxPyPz(track_par_cov_recalc, pVec_recalc); - return track_par_cov_recalc; - } - - std::vector> stored_trackIds; - // std::vector> stored_pairIds; - Filter trackFilter = o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& o2::aod::track::tpcChi2NCl < maxchi2tpc&& o2::aod::track::itsChi2NCl < maxchi2its&& ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::TPC) == true; - Filter pidFilter = minTPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < maxTPCNsigmaEl; - using MyFilteredTracks = soa::Filtered; - - Partition posTracks = o2::aod::track::signed1Pt > 0.f; - Partition negTracks = o2::aod::track::signed1Pt < 0.f; - - // ---------- for data ---------- - - void processRec_SA(MyCollisions const& collisions, aod::BCsWithTimestamps const&, MyFilteredTracks const&) - { - stored_trackIds.reserve(posTracks.size() + negTracks.size()); - - for (auto& collision : collisions) { - auto bc = collision.template foundBC_as(); - initCCDB(bc); - - if (!collision.isSelected()) { - filter(0, 0, 0); - continue; - } - - int nee_uls = 0; - auto posTracks_per_coll = posTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); - auto negTracks_per_coll = negTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); - - for (auto& [pos, ele] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { - if (!checkTrack(collision, pos) || !checkTrack(collision, ele)) { - continue; - } - if (!isElectron(pos) || !isElectron(ele)) { - continue; - } - - ROOT::Math::PtEtaPhiMVector v1(pos.pt(), pos.eta(), pos.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(ele.pt(), ele.eta(), ele.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(pos.px(), pos.py(), pos.pz(), ele.px(), ele.py(), ele.pz(), pos.sign(), ele.sign(), d_bz); - - if (fillQAHistogram) { - fRegistry.fill(HIST("Pair/uls/hM"), v12.M()); - fRegistry.fill(HIST("Pair/before/hMvsPt"), v12.M(), v12.Pt()); - fRegistry.fill(HIST("Pair/before/hMvsPhiV"), phiv, v12.M()); - } - if (apply_phiv ? (v12.M() < maxMee && slope * phiv + intercept < v12.M()) : (v12.M() < maxMee)) { - fillTrackTable(collision, pos); - fillTrackTable(collision, ele); - if (fillQAHistogram) { - fRegistry.fill(HIST("Pair/after/hMvsPt"), v12.M(), v12.Pt()); - fRegistry.fill(HIST("Pair/after/hMvsPhiV"), phiv, v12.M()); - } - nee_uls++; - } - - } // end of pairing loop - - if (fillQAHistogram) { - for (auto& [pos1, pos2] : combinations(CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { - if (!checkTrack(collision, pos1) || !checkTrack(collision, pos2)) { - continue; - } - if (!isElectron(pos1) || !isElectron(pos2)) { - continue; - } - - ROOT::Math::PtEtaPhiMVector v1(pos1.pt(), pos1.eta(), pos1.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(pos2.pt(), pos2.eta(), pos2.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - fRegistry.fill(HIST("Pair/lspp/hM"), v12.M()); - } // end of pairing loop - - for (auto& [ele1, ele2] : combinations(CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { - if (!checkTrack(collision, ele1) || !checkTrack(collision, ele2)) { - continue; - } - if (!isElectron(ele1) || !isElectron(ele2)) { - continue; - } - - ROOT::Math::PtEtaPhiMVector v1(ele1.pt(), ele1.eta(), ele1.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(ele2.pt(), ele2.eta(), ele2.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - fRegistry.fill(HIST("Pair/lsmm/hM"), v12.M()); - } // end of pairing loop - } - - if (nee_uls < 1) { - filter(nee_uls, 0, 0); - continue; - } - filter(nee_uls, 0, 0); - - } // end of collision loop - - stored_trackIds.clear(); - stored_trackIds.shrink_to_fit(); - // stored_pairIds.clear(); - // stored_pairIds.shrink_to_fit(); - } - PROCESS_SWITCH(filterDielectronEvent, processRec_SA, "process reconstructed info only", true); // standalone - - Preslice trackIndicesPerCollision = aod::track_association::collisionId; - void processRec_TTCA(MyCollisions const& collisions, aod::BCsWithTimestamps const&, MyTracks const& tracks, aod::TrackAssoc const& trackIndices) - { - stored_trackIds.reserve(tracks.size() * 2); - - for (auto& collision : collisions) { - auto bc = collision.template foundBC_as(); - initCCDB(bc); - - if (!collision.isSelected()) { - filter(0, 0, 0); - continue; - } - - int nee_uls = 0; - auto trackIdsThisCollision = trackIndices.sliceBy(trackIndicesPerCollision, collision.globalIndex()); - std::vector posTracks_per_coll; - std::vector negTracks_per_coll; - posTracks_per_coll.reserve(trackIdsThisCollision.size()); - negTracks_per_coll.reserve(trackIdsThisCollision.size()); - - for (auto& trackId : trackIdsThisCollision) { - auto track = trackId.template track_as(); - if (!checkTrack(collision, track) || !isElectron(track)) { - continue; - } - - if (track.sign() > 0) { - posTracks_per_coll.emplace_back(track); - } else { - negTracks_per_coll.emplace_back(track); - } - } // end of track loop - - for (auto& pos : posTracks_per_coll) { - for (auto& ele : negTracks_per_coll) { - - auto pos_prop = propagateTrack(collision, pos); - auto ele_prop = propagateTrack(collision, ele); - - std::array pVec_pos = {0, 0, 0}; // px, py, pz - getPxPyPz(pos_prop, pVec_pos); - std::array pVec_ele = {0, 0, 0}; // px, py, pz - getPxPyPz(ele_prop, pVec_ele); - - ROOT::Math::PtEtaPhiMVector v1(pos_prop.getPt(), pos_prop.getEta(), pos_prop.getPhi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(ele_prop.getPt(), ele_prop.getEta(), ele_prop.getPhi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(pVec_pos[0], pVec_pos[1], pVec_pos[2], pVec_ele[0], pVec_ele[1], pVec_ele[2], pos.sign(), ele.sign(), d_bz); - - if (fillQAHistogram) { - fRegistry.fill(HIST("Pair/uls/hM"), v12.M()); - fRegistry.fill(HIST("Pair/before/hMvsPt"), v12.M(), v12.Pt()); - fRegistry.fill(HIST("Pair/before/hMvsPhiV"), phiv, v12.M()); - } - if (apply_phiv ? (v12.M() < maxMee && slope * phiv + intercept < v12.M()) : (v12.M() < maxMee)) { - fillTrackTable(collision, pos); - fillTrackTable(collision, ele); - if (fillQAHistogram) { - fRegistry.fill(HIST("Pair/after/hMvsPt"), v12.M(), v12.Pt()); - fRegistry.fill(HIST("Pair/after/hMvsPhiV"), phiv, v12.M()); - } - nee_uls++; - } - - } // end of negative track loop - } // end of postive track loop - - if (fillQAHistogram) { - for (auto& pos1 : posTracks_per_coll) { - for (auto& pos2 : posTracks_per_coll) { - if (pos1.globalIndex() == pos2.globalIndex()) { - continue; - } - - auto pos1_prop = propagateTrack(collision, pos1); - auto pos2_prop = propagateTrack(collision, pos2); - - std::array pVec_pos1 = {0, 0, 0}; // px, py, pz - getPxPyPz(pos1_prop, pVec_pos1); - std::array pVec_pos2 = {0, 0, 0}; // px, py, pz - getPxPyPz(pos2_prop, pVec_pos2); - - ROOT::Math::PtEtaPhiMVector v1(pos1_prop.getPt(), pos1_prop.getEta(), pos1_prop.getPhi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(pos2_prop.getPt(), pos2_prop.getEta(), pos2_prop.getPhi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - fRegistry.fill(HIST("Pair/lspp/hM"), v12.M()); - } // end of positive track loop - } // end of postive track loop - - for (auto& ele1 : negTracks_per_coll) { - for (auto& ele2 : negTracks_per_coll) { - if (ele1.globalIndex() == ele2.globalIndex()) { - continue; - } - - auto ele1_prop = propagateTrack(collision, ele1); - auto ele2_prop = propagateTrack(collision, ele2); - - std::array pVec_ele1 = {0, 0, 0}; // px, py, pz - getPxPyPz(ele1_prop, pVec_ele1); - std::array pVec_ele2 = {0, 0, 0}; // px, py, pz - getPxPyPz(ele2_prop, pVec_ele2); - - ROOT::Math::PtEtaPhiMVector v1(ele1_prop.getPt(), ele1_prop.getEta(), ele1_prop.getPhi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(ele2_prop.getPt(), ele2_prop.getEta(), ele2_prop.getPhi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - fRegistry.fill(HIST("Pair/lsmm/hM"), v12.M()); - } // end of negative track loop - } // end of negative track loop - } - - if (nee_uls < 1) { - filter(nee_uls, 0, 0); - continue; - } - - filter(nee_uls, 0, 0); - - posTracks_per_coll.clear(); - negTracks_per_coll.clear(); - posTracks_per_coll.shrink_to_fit(); - negTracks_per_coll.shrink_to_fit(); - - } // end of collision loop - - stored_trackIds.clear(); - stored_trackIds.shrink_to_fit(); - // stored_pairIds.clear(); - // stored_pairIds.shrink_to_fit(); - } - PROCESS_SWITCH(filterDielectronEvent, processRec_TTCA, "process reconstructed info only", false); // with TTCA - - // ---------- for data ---------- - - void processRec_SA_SWT(MyCollisionsWithSWT const& collisions, aod::BCsWithTimestamps const&, MyFilteredTracks const&) - { - stored_trackIds.reserve(posTracks.size() + negTracks.size()); - - for (auto& collision : collisions) { - auto bc = collision.template foundBC_as(); - initCCDB(bc); - - if (!collision.isSelected()) { - filter(0, 0, 0); - continue; - } - if (collision.swtaliastmp_raw() == 0) { - filter(0, 0, 0); - continue; - } - - int nee_uls = 0; - auto posTracks_per_coll = posTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); - auto negTracks_per_coll = negTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); - - for (auto& [pos, ele] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { - if (!checkTrack(collision, pos) || !checkTrack(collision, ele)) { - continue; - } - if (!isElectron(pos) || !isElectron(ele)) { - continue; - } - - ROOT::Math::PtEtaPhiMVector v1(pos.pt(), pos.eta(), pos.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(ele.pt(), ele.eta(), ele.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(pos.px(), pos.py(), pos.pz(), ele.px(), ele.py(), ele.pz(), pos.sign(), ele.sign(), d_bz); - - if (fillQAHistogram) { - fRegistry.fill(HIST("Pair/uls/hM"), v12.M()); - fRegistry.fill(HIST("Pair/before/hMvsPt"), v12.M(), v12.Pt()); - fRegistry.fill(HIST("Pair/before/hMvsPhiV"), phiv, v12.M()); - } - if (apply_phiv ? (v12.M() < maxMee && slope * phiv + intercept < v12.M()) : (v12.M() < maxMee)) { - fillTrackTable(collision, pos); - fillTrackTable(collision, ele); - if (fillQAHistogram) { - fRegistry.fill(HIST("Pair/after/hMvsPt"), v12.M(), v12.Pt()); - fRegistry.fill(HIST("Pair/after/hMvsPhiV"), phiv, v12.M()); - } - nee_uls++; - } - - } // end of pairing loop - - if (fillQAHistogram) { - for (auto& [pos1, pos2] : combinations(CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { - if (!checkTrack(collision, pos1) || !checkTrack(collision, pos2)) { - continue; - } - if (!isElectron(pos1) || !isElectron(pos2)) { - continue; - } - - ROOT::Math::PtEtaPhiMVector v1(pos1.pt(), pos1.eta(), pos1.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(pos2.pt(), pos2.eta(), pos2.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - fRegistry.fill(HIST("Pair/lspp/hM"), v12.M()); - } // end of pairing loop - - for (auto& [ele1, ele2] : combinations(CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { - if (!checkTrack(collision, ele1) || !checkTrack(collision, ele2)) { - continue; - } - if (!isElectron(ele1) || !isElectron(ele2)) { - continue; - } - - ROOT::Math::PtEtaPhiMVector v1(ele1.pt(), ele1.eta(), ele1.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(ele2.pt(), ele2.eta(), ele2.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - fRegistry.fill(HIST("Pair/lsmm/hM"), v12.M()); - } // end of pairing loop - } - - if (nee_uls < 1) { - filter(nee_uls, 0, 0); - continue; - } - filter(nee_uls, 0, 0); - - } // end of collision loop - - stored_trackIds.clear(); - stored_trackIds.shrink_to_fit(); - // stored_pairIds.clear(); - // stored_pairIds.shrink_to_fit(); - } - PROCESS_SWITCH(filterDielectronEvent, processRec_SA_SWT, "process reconstructed info only", false); // standalone - - void processRec_TTCA_SWT(MyCollisionsWithSWT const& collisions, aod::BCsWithTimestamps const&, MyTracks const& tracks, aod::TrackAssoc const& trackIndices) - { - stored_trackIds.reserve(tracks.size() * 2); - - for (auto& collision : collisions) { - auto bc = collision.template foundBC_as(); - initCCDB(bc); - - if (!collision.isSelected()) { - filter(0, 0, 0); - continue; - } - if (collision.swtaliastmp_raw() == 0) { - filter(0, 0, 0); - continue; - } - - int nee_uls = 0; - auto trackIdsThisCollision = trackIndices.sliceBy(trackIndicesPerCollision, collision.globalIndex()); - std::vector posTracks_per_coll; - std::vector negTracks_per_coll; - posTracks_per_coll.reserve(trackIdsThisCollision.size()); - negTracks_per_coll.reserve(trackIdsThisCollision.size()); - - for (auto& trackId : trackIdsThisCollision) { - auto track = trackId.template track_as(); - if (!checkTrack(collision, track) || !isElectron(track)) { - continue; - } - - if (track.sign() > 0) { - posTracks_per_coll.emplace_back(track); - } else { - negTracks_per_coll.emplace_back(track); - } - } // end of track loop - - for (auto& pos : posTracks_per_coll) { - for (auto& ele : negTracks_per_coll) { - - auto pos_prop = propagateTrack(collision, pos); - auto ele_prop = propagateTrack(collision, ele); - - std::array pVec_pos = {0, 0, 0}; // px, py, pz - getPxPyPz(pos_prop, pVec_pos); - std::array pVec_ele = {0, 0, 0}; // px, py, pz - getPxPyPz(ele_prop, pVec_ele); - - ROOT::Math::PtEtaPhiMVector v1(pos_prop.getPt(), pos_prop.getEta(), pos_prop.getPhi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(ele_prop.getPt(), ele_prop.getEta(), ele_prop.getPhi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(pVec_pos[0], pVec_pos[1], pVec_pos[2], pVec_ele[0], pVec_ele[1], pVec_ele[2], pos.sign(), ele.sign(), d_bz); - - if (fillQAHistogram) { - fRegistry.fill(HIST("Pair/uls/hM"), v12.M()); - fRegistry.fill(HIST("Pair/before/hMvsPt"), v12.M(), v12.Pt()); - fRegistry.fill(HIST("Pair/before/hMvsPhiV"), phiv, v12.M()); - } - if (apply_phiv ? (v12.M() < maxMee && slope * phiv + intercept < v12.M()) : (v12.M() < maxMee)) { - fillTrackTable(collision, pos); - fillTrackTable(collision, ele); - if (fillQAHistogram) { - fRegistry.fill(HIST("Pair/after/hMvsPt"), v12.M(), v12.Pt()); - fRegistry.fill(HIST("Pair/after/hMvsPhiV"), phiv, v12.M()); - } - nee_uls++; - } - - } // end of negative track loop - } // end of postive track loop - - if (fillQAHistogram) { - for (auto& pos1 : posTracks_per_coll) { - for (auto& pos2 : posTracks_per_coll) { - if (pos1.globalIndex() == pos2.globalIndex()) { - continue; - } - - auto pos1_prop = propagateTrack(collision, pos1); - auto pos2_prop = propagateTrack(collision, pos2); - - std::array pVec_pos1 = {0, 0, 0}; // px, py, pz - getPxPyPz(pos1_prop, pVec_pos1); - std::array pVec_pos2 = {0, 0, 0}; // px, py, pz - getPxPyPz(pos2_prop, pVec_pos2); - - ROOT::Math::PtEtaPhiMVector v1(pos1_prop.getPt(), pos1_prop.getEta(), pos1_prop.getPhi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(pos2_prop.getPt(), pos2_prop.getEta(), pos2_prop.getPhi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - fRegistry.fill(HIST("Pair/lspp/hM"), v12.M()); - } // end of positive track loop - } // end of postive track loop - - for (auto& ele1 : negTracks_per_coll) { - for (auto& ele2 : negTracks_per_coll) { - if (ele1.globalIndex() == ele2.globalIndex()) { - continue; - } - - auto ele1_prop = propagateTrack(collision, ele1); - auto ele2_prop = propagateTrack(collision, ele2); - - std::array pVec_ele1 = {0, 0, 0}; // px, py, pz - getPxPyPz(ele1_prop, pVec_ele1); - std::array pVec_ele2 = {0, 0, 0}; // px, py, pz - getPxPyPz(ele2_prop, pVec_ele2); - - ROOT::Math::PtEtaPhiMVector v1(ele1_prop.getPt(), ele1_prop.getEta(), ele1_prop.getPhi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(ele2_prop.getPt(), ele2_prop.getEta(), ele2_prop.getPhi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - fRegistry.fill(HIST("Pair/lsmm/hM"), v12.M()); - } // end of negative track loop - } // end of negative track loop - } - - if (nee_uls < 1) { - filter(nee_uls, 0, 0); - continue; - } - - filter(nee_uls, 0, 0); - - posTracks_per_coll.clear(); - negTracks_per_coll.clear(); - posTracks_per_coll.shrink_to_fit(); - negTracks_per_coll.shrink_to_fit(); - - } // end of collision loop - - stored_trackIds.clear(); - stored_trackIds.shrink_to_fit(); - // stored_pairIds.clear(); - // stored_pairIds.shrink_to_fit(); - } - PROCESS_SWITCH(filterDielectronEvent, processRec_TTCA_SWT, "process reconstructed info only", false); // with TTCA - - // ---------- for MC ---------- - - using MyFilteredTracksMC = soa::Filtered; - Partition posTracksMC = o2::aod::track::signed1Pt > 0.f; - Partition negTracksMC = o2::aod::track::signed1Pt < 0.f; - void processMC_SA(soa::Join const& collisions, aod::McCollisions const&, aod::BCsWithTimestamps const&, MyFilteredTracksMC const& tracks) - { - stored_trackIds.reserve(tracks.size()); - - for (auto& collision : collisions) { - if (!collision.has_mcCollision()) { - continue; - } - auto bc = collision.template foundBC_as(); - initCCDB(bc); - - if (!collision.isSelected()) { - filter(0, 0, 0); - continue; - } - - int nee_uls = 0; - auto posTracks_per_coll = posTracksMC->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); - auto negTracks_per_coll = negTracksMC->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); - - for (auto& [pos, ele] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { - if (!checkTrack(collision, pos) || !checkTrack(collision, ele)) { - continue; - } - if (!isElectron(pos) || !isElectron(ele)) { - continue; - } - - ROOT::Math::PtEtaPhiMVector v1(pos.pt(), pos.eta(), pos.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(ele.pt(), ele.eta(), ele.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(pos.px(), pos.py(), pos.pz(), ele.px(), ele.py(), ele.pz(), pos.sign(), ele.sign(), d_bz); - if (fillQAHistogram) { - fRegistry.fill(HIST("Pair/uls/hM"), v12.M()); - fRegistry.fill(HIST("Pair/before/hMvsPt"), v12.M(), v12.Pt()); - fRegistry.fill(HIST("Pair/before/hMvsPhiV"), phiv, v12.M()); - } - if (apply_phiv ? (v12.M() < maxMee && slope * phiv + intercept < v12.M()) : (v12.M() < maxMee)) { - fillTrackTable(collision, pos); - fillTrackTable(collision, ele); - if (fillQAHistogram) { - fRegistry.fill(HIST("Pair/after/hMvsPt"), v12.M(), v12.Pt()); - fRegistry.fill(HIST("Pair/after/hMvsPhiV"), phiv, v12.M()); - } - nee_uls++; - } - - } // end of pairing loop - - if (fillQAHistogram) { - for (auto& [pos1, pos2] : combinations(CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { - if (!checkTrack(collision, pos1) || !checkTrack(collision, pos2)) { - continue; - } - if (!isElectron(pos1) || !isElectron(pos2)) { - continue; - } - - ROOT::Math::PtEtaPhiMVector v1(pos1.pt(), pos1.eta(), pos1.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(pos2.pt(), pos2.eta(), pos2.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - fRegistry.fill(HIST("Pair/lspp/hM"), v12.M()); - } // end of pairing loop - - for (auto& [ele1, ele2] : combinations(CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { - if (!checkTrack(collision, ele1) || !checkTrack(collision, ele2)) { - continue; - } - if (!isElectron(ele1) || !isElectron(ele2)) { - continue; - } - - ROOT::Math::PtEtaPhiMVector v1(ele1.pt(), ele1.eta(), ele1.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(ele2.pt(), ele2.eta(), ele2.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - fRegistry.fill(HIST("Pair/lsmm/hM"), v12.M()); - } // end of pairing loop - } - - if (nee_uls < 1) { - filter(nee_uls, 0, 0); - continue; - } - filter(nee_uls, 0, 0); - } // end of collision loop - - stored_trackIds.clear(); - stored_trackIds.shrink_to_fit(); - // stored_pairIds.clear(); - // stored_pairIds.shrink_to_fit(); - } - PROCESS_SWITCH(filterDielectronEvent, processMC_SA, "process reconstructed and MC info ", false); - - void processMC_TTCA(soa::Join const& collisions, aod::McCollisions const&, aod::BCsWithTimestamps const&, MyTracksMC const& tracks, aod::TrackAssoc const& trackIndices) - { - stored_trackIds.reserve(tracks.size() * 2); - - for (auto& collision : collisions) { - if (!collision.has_mcCollision()) { - continue; - } - auto bc = collision.template foundBC_as(); - initCCDB(bc); - - if (!collision.isSelected()) { - filter(0, 0, 0); - continue; - } - - int nee_uls = 0; - auto trackIdsThisCollision = trackIndices.sliceBy(trackIndicesPerCollision, collision.globalIndex()); - std::vector posTracks_per_coll; - std::vector negTracks_per_coll; - posTracks_per_coll.reserve(trackIdsThisCollision.size()); - negTracks_per_coll.reserve(trackIdsThisCollision.size()); - - for (auto& trackId : trackIdsThisCollision) { - auto track = trackId.template track_as(); - if (!checkTrack(collision, track) || !isElectron(track)) { - continue; - } - - if (track.sign() > 0) { - posTracks_per_coll.emplace_back(track); - } else { - negTracks_per_coll.emplace_back(track); - } - } // end of track loop - - for (auto& pos : posTracks_per_coll) { - for (auto& ele : negTracks_per_coll) { - auto pos_prop = propagateTrack(collision, pos); - auto ele_prop = propagateTrack(collision, ele); - std::array pVec_pos = {0, 0, 0}; // px, py, pz - getPxPyPz(pos_prop, pVec_pos); - std::array pVec_ele = {0, 0, 0}; // px, py, pz - getPxPyPz(ele_prop, pVec_ele); - - ROOT::Math::PtEtaPhiMVector v1(pos_prop.getPt(), pos_prop.getEta(), pos_prop.getPhi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(ele_prop.getPt(), ele_prop.getEta(), ele_prop.getPhi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(pVec_pos[0], pVec_pos[1], pVec_pos[2], pVec_ele[0], pVec_ele[1], pVec_ele[2], pos.sign(), ele.sign(), d_bz); - if (fillQAHistogram) { - fRegistry.fill(HIST("Pair/uls/hM"), v12.M()); - fRegistry.fill(HIST("Pair/before/hMvsPt"), v12.M(), v12.Pt()); - fRegistry.fill(HIST("Pair/before/hMvsPhiV"), phiv, v12.M()); - } - if (apply_phiv ? (v12.M() < maxMee && slope * phiv + intercept < v12.M()) : (v12.M() < maxMee)) { - fillTrackTable(collision, pos); - fillTrackTable(collision, ele); - if (fillQAHistogram) { - fRegistry.fill(HIST("Pair/after/hMvsPt"), v12.M(), v12.Pt()); - fRegistry.fill(HIST("Pair/after/hMvsPhiV"), phiv, v12.M()); - } - nee_uls++; - } - - } // end of negative track loop - } // end of postive track loop - - if (fillQAHistogram) { - for (auto& pos1 : posTracks_per_coll) { - for (auto& pos2 : posTracks_per_coll) { - if (pos1.globalIndex() == pos2.globalIndex()) { - continue; - } - - auto pos1_prop = propagateTrack(collision, pos1); - auto pos2_prop = propagateTrack(collision, pos2); - - std::array pVec_pos1 = {0, 0, 0}; // px, py, pz - getPxPyPz(pos1_prop, pVec_pos1); - std::array pVec_pos2 = {0, 0, 0}; // px, py, pz - getPxPyPz(pos2_prop, pVec_pos2); - - ROOT::Math::PtEtaPhiMVector v1(pos1_prop.getPt(), pos1_prop.getEta(), pos1_prop.getPhi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(pos2_prop.getPt(), pos2_prop.getEta(), pos2_prop.getPhi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - fRegistry.fill(HIST("Pair/lspp/hM"), v12.M()); - } // end of positive track loop - } // end of postive track loop - - for (auto& ele1 : negTracks_per_coll) { - for (auto& ele2 : negTracks_per_coll) { - if (ele1.globalIndex() == ele2.globalIndex()) { - continue; - } - - auto ele1_prop = propagateTrack(collision, ele1); - auto ele2_prop = propagateTrack(collision, ele2); - - std::array pVec_ele1 = {0, 0, 0}; // px, py, pz - getPxPyPz(ele1_prop, pVec_ele1); - std::array pVec_ele2 = {0, 0, 0}; // px, py, pz - getPxPyPz(ele2_prop, pVec_ele2); - - ROOT::Math::PtEtaPhiMVector v1(ele1_prop.getPt(), ele1_prop.getEta(), ele1_prop.getPhi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(ele2_prop.getPt(), ele2_prop.getEta(), ele2_prop.getPhi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - fRegistry.fill(HIST("Pair/lsmm/hM"), v12.M()); - } // end of negative track loop - } // end of negative track loop - } - - if (nee_uls < 1) { - filter(nee_uls, 0, 0); - continue; - } - filter(nee_uls, 0, 0); - - posTracks_per_coll.clear(); - negTracks_per_coll.clear(); - posTracks_per_coll.shrink_to_fit(); - negTracks_per_coll.shrink_to_fit(); - - } // end of collision loop - - stored_trackIds.clear(); - stored_trackIds.shrink_to_fit(); - // stored_pairIds.clear(); - // stored_pairIds.shrink_to_fit(); - } - PROCESS_SWITCH(filterDielectronEvent, processMC_TTCA, "process reconstructed info only", false); // with TTCA -}; -struct prefilterPrimaryElectron { - using MyCollisions = soa::Join; - using MyCollisionsWithSWT = soa::Join; - - Produces ele_pfb; - - SliceCache cache; - Preslice perCol_track = o2::aod::track::collisionId; - PresliceUnsorted perCol_ele = o2::aod::emprimaryelectron::collisionId; - - // CCDB options - Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; - Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable skipGRPOquery{"skipGRPOquery", true, "skip grpo query"}; - - // Operation and minimisation criteria - Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; - - Configurable max_dcaxy{"max_dcaxy", 0.3, "DCAxy To PV for loose track sample"}; - Configurable max_dcaz{"max_dcaz", 0.3, "DCAz To PV for loose track sample"}; - Configurable minpt{"minpt", 0.1, "min pt for track for loose track sample"}; - Configurable maxeta{"maxeta", 0.9, "eta acceptance for loose track sample"}; - Configurable min_ncluster_tpc{"min_ncluster_tpc", 0, "min ncluster tpc"}; - Configurable mincrossedrows{"mincrossedrows", 70, "min crossed rows"}; - Configurable max_frac_shared_clusters_tpc{"max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; - Configurable min_tpc_cr_findable_ratio{"min_tpc_cr_findable_ratio", 0.8, "min. TPC Ncr/Nf ratio"}; - Configurable maxchi2tpc{"maxchi2tpc", 5.0, "max chi2/NclsTPC"}; - Configurable maxchi2its{"maxchi2its", 6.0, "max chi2/NclsITS"}; - Configurable min_ncluster_its{"min_ncluster_its", 4, "min ncluster its"}; - Configurable min_ncluster_itsib{"min_ncluster_itsib", 1, "min ncluster itsib"}; - Configurable minTPCNsigmaEl{"minTPCNsigmaEl", -3.0, "min. TPC n sigma for electron inclusion"}; - Configurable maxTPCNsigmaEl{"maxTPCNsigmaEl", 3.0, "max. TPC n sigma for electron inclusion"}; - Configurable slope{"slope", 0.0185, "slope for m vs. phiv"}; - Configurable intercept{"intercept", -0.0280, "intercept for m vs. phiv"}; - - Configurable> max_mee_vec{"max_mee_vec", std::vector{0.08, 0.10, 0.12}, "vector fo max mee for prefilter in ULS. Please sort this by increasing order."}; // currently, 3 thoresholds are allowed. - - HistogramRegistry fRegistry{"output", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; - - int mRunNumber; - float d_bz; - Service ccdb; - o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; - - void init(InitContext&) - { - mRunNumber = 0; - d_bz = 0; - - ccdb->setURL(ccdburl); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - ccdb->setFatalWhenNull(false); - - if (!doprocessDummy) { - addHistograms(); - } - } - - void addHistograms() - { - fRegistry.add("Track/hPt", "pT;p_{T} (GeV/c)", kTH1F, {{1000, 0.0f, 10}}, false); - fRegistry.add("Track/hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2F, {{180, 0, 2 * M_PI}, {40, -1.0f, 1.0f}}, false); - fRegistry.add("Track/hTPCNsigmaEl", "loose track TPC PID", kTH2F, {{1000, 0.f, 10}, {100, -5, +5}}); - fRegistry.add("Pair/before/uls/hMvsPt", "mass vs. pT;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c)", kTH2F, {{400, 0, 4}, {100, 0, 10}}); - fRegistry.add("Pair/before/uls/hMvsPhiV", "mass vs. phiv;#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", kTH2F, {{90, 0.f, M_PI}, {100, 0, 1.f}}); - fRegistry.addClone("Pair/before/uls/", "Pair/before/lspp/"); - fRegistry.addClone("Pair/before/uls/", "Pair/before/lsmm/"); - fRegistry.addClone("Pair/before/", "Pair/after/"); - } - - void initCCDB(aod::BCsWithTimestamps::iterator const& bc) - { - if (mRunNumber == bc.runNumber()) { - return; - } - - // In case override, don't proceed, please - no CCDB access required - if (d_bz_input > -990) { - d_bz = d_bz_input; - o2::parameters::GRPMagField grpmag; - if (std::fabs(d_bz) > 1e-5) { - grpmag.setL3Current(30000.f / (d_bz / 5.0f)); - } - o2::base::Propagator::initFieldFromGRP(&grpmag); - mRunNumber = bc.runNumber(); - return; - } - - auto run3grp_timestamp = bc.timestamp(); - o2::parameters::GRPObject* grpo = 0x0; - o2::parameters::GRPMagField* grpmag = 0x0; - if (!skipGRPOquery) - grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); - if (grpo) { - o2::base::Propagator::initFieldFromGRP(grpo); - // Fetch magnetic field from ccdb for current collision - d_bz = grpo->getNominalL3Field(); - LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; - } else { - grpmag = ccdb->getForTimeStamp(grpmagPath, run3grp_timestamp); - if (!grpmag) { - LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; - } - o2::base::Propagator::initFieldFromGRP(grpmag); - // Fetch magnetic field from ccdb for current collision - d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); - LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; - } - mRunNumber = bc.runNumber(); - } - - o2::base::Propagator::MatCorrType noMatCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; - - template - bool checkTrack(TCollision const& collision, TTrack const& track) - { - if (!track.hasITS()) { - return false; - } - if (track.itsChi2NCl() > maxchi2its) { - return false; - } - if (track.itsNCls() < min_ncluster_its) { - return false; - } - if (track.itsNClsInnerBarrel() < min_ncluster_itsib) { - return false; - } - - if (!track.hasTPC()) { - return false; - } - if (track.tpcNSigmaEl() < minTPCNsigmaEl || maxTPCNsigmaEl < track.tpcNSigmaEl()) { - return false; - } - if (track.tpcNClsFound() < min_ncluster_tpc) { - return false; - } - if (track.tpcNClsCrossedRows() < mincrossedrows) { - return false; - } - if (track.tpcCrossedRowsOverFindableCls() < min_tpc_cr_findable_ratio) { - return false; - } - if (track.tpcFractionSharedCls() > max_frac_shared_clusters_tpc) { - return false; - } - if (track.tpcChi2NCl() > maxchi2its) { - return false; - } - - std::array dcaInfo; - auto track_par_cov_recalc = getTrackParCov(track); - // std::array pVec_recalc = {0, 0, 0}; // px, py, pz - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, track_par_cov_recalc, 2.f, matCorr, &dcaInfo); - // getPxPyPz(track_par_cov_recalc, pVec_recalc); - - if (std::fabs(dcaInfo[0]) > max_dcaxy || std::fabs(dcaInfo[1]) > max_dcaz) { - return false; - } - - if (track_par_cov_recalc.getPt() < minpt || std::fabs(track_par_cov_recalc.getEta()) > maxeta) { - return false; - } - - return true; - } - - Preslice trackIndicesPerCollision = aod::track_association::collisionId; - - Filter trackFilter = o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::TPC) == true; - using MyFilteredTracks = soa::Filtered; - Partition posTracks = o2::aod::track::signed1Pt > 0.f; - Partition negTracks = o2::aod::track::signed1Pt < 0.f; - - Partition positrons = o2::aod::emprimaryelectron::sign > int8_t(0); - Partition electrons = o2::aod::emprimaryelectron::sign < int8_t(0); - void processSA(MyCollisions const& collisions, aod::BCsWithTimestamps const&, MyFilteredTracks const&, aod::EMPrimaryElectrons const& primaryelectrons) - { - std::unordered_map pfb_map; // map track.globalIndex -> prefilter bit - - for (auto& collision : collisions) { - auto bc = collision.template foundBC_as(); - initCCDB(bc); - if (!collision.isSelected()) { - continue; - } - - auto posTracks_per_coll = posTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); // loose track sample - auto negTracks_per_coll = negTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); // loose track sample - - auto positrons_per_coll = positrons->sliceByCachedUnsorted(o2::aod::emprimaryelectron::collisionId, collision.globalIndex(), cache); // signal sample - auto electrons_per_coll = electrons->sliceByCachedUnsorted(o2::aod::emprimaryelectron::collisionId, collision.globalIndex(), cache); // signal sample - - for (auto& pos : posTracks_per_coll) { - if (!checkTrack(collision, pos)) { // track cut is applied to loose sample - continue; - } - fRegistry.fill(HIST("Track/hPt"), pos.pt()); - fRegistry.fill(HIST("Track/hEtaPhi"), pos.phi(), pos.eta()); - } - for (auto& neg : negTracks_per_coll) { - if (!checkTrack(collision, neg)) { // track cut is applied to loose sample - continue; - } - fRegistry.fill(HIST("Track/hPt"), neg.pt()); - fRegistry.fill(HIST("Track/hEtaPhi"), neg.phi(), neg.eta()); - } - - for (auto& [ele, empos] : combinations(CombinationsFullIndexPolicy(negTracks_per_coll, positrons_per_coll))) { - // auto pos = tracks.rawIteratorAt(empos.trackId()); // use rawIterator, if the table is filtered. - if (!checkTrack(collision, ele)) { // track cut is applied to loose sample - continue; - } - if (empos.trackId() == ele.globalIndex()) { - continue; - } - - ROOT::Math::PtEtaPhiMVector v1(ele.pt(), ele.eta(), ele.phi(), o2::constants::physics::MassElectron); // loose track - ROOT::Math::PtEtaPhiMVector v2(empos.pt(), empos.eta(), empos.phi(), o2::constants::physics::MassElectron); // signal track - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(empos.px(), empos.py(), empos.pz(), ele.px(), ele.py(), ele.pz(), empos.sign(), ele.sign(), d_bz); - fRegistry.fill(HIST("Pair/before/uls/hMvsPhiV"), phiv, v12.M()); - fRegistry.fill(HIST("Pair/before/uls/hMvsPt"), v12.M(), v12.Pt()); - if (v12.M() < max_mee_vec->at(static_cast(max_mee_vec->size()) - 1)) { - fRegistry.fill(HIST("Track/hTPCNsigmaEl"), ele.tpcInnerParam(), ele.tpcNSigmaEl()); - } - for (int i = 0; i < static_cast(max_mee_vec->size()); i++) { - if (v12.M() < max_mee_vec->at(i)) { - pfb_map[empos.globalIndex()] |= (uint8_t(1) << (static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_1) + i)); - } - } - - if (v12.M() < slope * phiv + intercept) { - pfb_map[empos.globalIndex()] |= (uint8_t(1) << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPC)); - } - - } // end of ULS pairing - - for (auto& [pos, emele] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, electrons_per_coll))) { - // auto ele = tracks.rawIteratorAt(emele.trackId()); // use rawIterator, if the table is filtered. - if (!checkTrack(collision, pos)) { // track cut is applied to loose sample - continue; - } - if (emele.trackId() == pos.globalIndex()) { - continue; - } - - ROOT::Math::PtEtaPhiMVector v1(emele.pt(), emele.eta(), emele.phi(), o2::constants::physics::MassElectron); // signal track - ROOT::Math::PtEtaPhiMVector v2(pos.pt(), pos.eta(), pos.phi(), o2::constants::physics::MassElectron); // loose track - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(pos.px(), pos.py(), pos.pz(), emele.px(), emele.py(), emele.pz(), pos.sign(), emele.sign(), d_bz); - fRegistry.fill(HIST("Pair/before/uls/hMvsPhiV"), phiv, v12.M()); - fRegistry.fill(HIST("Pair/before/uls/hMvsPt"), v12.M(), v12.Pt()); - if (v12.M() < max_mee_vec->at(static_cast(max_mee_vec->size()) - 1)) { - fRegistry.fill(HIST("Track/hTPCNsigmaEl"), pos.tpcInnerParam(), pos.tpcNSigmaEl()); - } - for (int i = 0; i < static_cast(max_mee_vec->size()); i++) { - if (v12.M() < max_mee_vec->at(i)) { - pfb_map[emele.globalIndex()] |= (uint8_t(1) << (static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_1) + i)); - } - } - - if (v12.M() < slope * phiv + intercept) { - pfb_map[emele.globalIndex()] |= (uint8_t(1) << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPC)); - } - - } // end of ULS pairing - - for (auto& [pos, empos] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, positrons_per_coll))) { - // auto pos = tracks.rawIteratorAt(empos.trackId()); // use rawIterator, if the table is filtered. - if (!checkTrack(collision, pos)) { // track cut is applied to loose sample - continue; - } - if (empos.trackId() == pos.globalIndex()) { - continue; - } - - ROOT::Math::PtEtaPhiMVector v1(pos.pt(), pos.eta(), pos.phi(), o2::constants::physics::MassElectron); // loose track - ROOT::Math::PtEtaPhiMVector v2(empos.pt(), empos.eta(), empos.phi(), o2::constants::physics::MassElectron); // signal track - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(empos.px(), empos.py(), empos.pz(), pos.px(), pos.py(), pos.pz(), empos.sign(), pos.sign(), d_bz); - fRegistry.fill(HIST("Pair/before/lspp/hMvsPhiV"), phiv, v12.M()); - fRegistry.fill(HIST("Pair/before/lspp/hMvsPt"), v12.M(), v12.Pt()); - } // end of LS++ pairing - - for (auto& [ele, emele] : combinations(CombinationsFullIndexPolicy(negTracks_per_coll, electrons_per_coll))) { - // auto ele = tracks.rawIteratorAt(emele.trackId()); // use rawIterator, if the table is filtered. - if (!checkTrack(collision, ele)) { // track cut is applied to loose sample - continue; - } - if (emele.trackId() == ele.globalIndex()) { - continue; - } - - ROOT::Math::PtEtaPhiMVector v1(ele.pt(), ele.eta(), ele.phi(), o2::constants::physics::MassElectron); // loose track - ROOT::Math::PtEtaPhiMVector v2(emele.pt(), emele.eta(), emele.phi(), o2::constants::physics::MassElectron); // signal track - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(emele.px(), emele.py(), emele.pz(), ele.px(), ele.py(), ele.pz(), emele.sign(), ele.sign(), d_bz); - fRegistry.fill(HIST("Pair/before/lsmm/hMvsPhiV"), phiv, v12.M()); - fRegistry.fill(HIST("Pair/before/lsmm/hMvsPt"), v12.M(), v12.Pt()); - } // end of LS-- pairing - - } // end of collision loop - - for (auto& ele : primaryelectrons) { - ele_pfb(pfb_map[ele.globalIndex()]); - } - - // check prefilter - for (auto& collision : collisions) { - auto positrons_per_coll = positrons->sliceByCachedUnsorted(o2::aod::emprimaryelectron::collisionId, collision.globalIndex(), cache); // signal sample - auto electrons_per_coll = electrons->sliceByCachedUnsorted(o2::aod::emprimaryelectron::collisionId, collision.globalIndex(), cache); // signal sample - - for (auto& [ele, pos] : combinations(CombinationsFullIndexPolicy(electrons_per_coll, positrons_per_coll))) { - if (pfb_map[ele.globalIndex()] != 0 || pfb_map[pos.globalIndex()] != 0) { - continue; - } - - ROOT::Math::PtEtaPhiMVector v1(ele.pt(), ele.eta(), ele.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(pos.pt(), pos.eta(), pos.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(pos.px(), pos.py(), pos.pz(), ele.px(), ele.py(), ele.pz(), pos.sign(), ele.sign(), d_bz); - fRegistry.fill(HIST("Pair/after/uls/hMvsPhiV"), phiv, v12.M()); - fRegistry.fill(HIST("Pair/after/uls/hMvsPt"), v12.M(), v12.Pt()); - } // end of ULS pairing - } // end of collision loop - - pfb_map.clear(); - } - PROCESS_SWITCH(prefilterPrimaryElectron, processSA, "process SA", false); - - void processDummy(aod::EMPrimaryElectrons const& primaryelectrons) - { - for (int i = 0; i < primaryelectrons.size(); i++) { - ele_pfb(0); - } - } - PROCESS_SWITCH(prefilterPrimaryElectron, processDummy, "processDummy", true); -}; -struct associateAmbiguousElectron { - Produces em_amb_ele_ids; - - SliceCache cache; - PresliceUnsorted perTrack = o2::aod::emprimaryelectron::trackId; - std::vector ambele_self_Ids; - - void process(aod::EMPrimaryElectrons const& electrons) - { - for (auto& electron : electrons) { - auto electrons_with_same_trackId = electrons.sliceBy(perTrack, electron.trackId()); - ambele_self_Ids.reserve(electrons_with_same_trackId.size()); - for (auto& amb_ele : electrons_with_same_trackId) { - if (amb_ele.globalIndex() == electron.globalIndex()) { // don't store myself. - continue; - } - ambele_self_Ids.emplace_back(amb_ele.globalIndex()); - } - em_amb_ele_ids(ambele_self_Ids); - ambele_self_Ids.clear(); - ambele_self_Ids.shrink_to_fit(); - } - } -}; -struct createEMEvent2VP { - using MyBCs = soa::Join; - using MyQvectors = soa::Join; - - using MyCollisions = soa::Join; - using MyCollisions_Cent = soa::Join; // centrality table has dependency on multiplicity table. - using MyCollisions_Cent_Qvec = soa::Join; - - using MyCollisionsWithSWT = soa::Join; - using MyCollisionsWithSWT_Cent = soa::Join; // centrality table has dependency on multiplicity table. - using MyCollisionsWithSWT_Cent_Qvec = soa::Join; - - using MyCollisionsMC = soa::Join; - using MyCollisionsMC_Cent = soa::Join; // centrality table has dependency on multiplicity table. - using MyCollisionsMC_Cent_Qvec = soa::Join; - - Produces event; - // Produces eventcov; - Produces event_mult; - Produces event_cent; - Produces event_qvec; - Produces emswtbit; - - enum class EMEventType : int { - kEvent = 0, - kEvent_Cent = 1, - kEvent_Cent_Qvec = 2, - }; - - HistogramRegistry registry{"registry"}; - void init(o2::framework::InitContext&) - { - auto hEventCounter = registry.add("hEventCounter", "hEventCounter", kTH1I, {{7, 0.5f, 7.5f}}); - hEventCounter->GetXaxis()->SetBinLabel(1, "all"); - hEventCounter->GetXaxis()->SetBinLabel(2, "sel8"); - - registry.add("hNInspectedTVX", "N inspected TVX;run number;N_{TVX}", kTProfile, {{80000, 520000.5, 600000.5}}, true); - } - - ~createEMEvent2VP() - { - swt_names.clear(); - swt_names.shrink_to_fit(); - } - - std::vector mTOIidx; - std::vector swt_names; - uint64_t mNinspectedTVX{0}; - - int mRunNumber; - - template - void skimEvent(TCollisions const& collisions, TBCs const&) - { - for (auto& collision : collisions) { - if constexpr (isMC) { - if (!collision.has_mcCollision()) { - continue; - } - } - - if constexpr (isTriggerAnalysis) { - if (collision.swtaliastmp_raw() == 0) { - continue; - } - } - - auto bc = collision.template foundBC_as(); - - if (!collision.isSelected()) { - continue; - } - - if (!(collision.neeuls() >= 1 || collision.neeuls() + collision.ngpcm() >= 2)) { - continue; - } - - if constexpr (isTriggerAnalysis) { - emswtbit(collision.swtaliastmp_raw(), collision.nInspectedTVX()); - } - - // LOGF(info, "collision.neeuls() = %d, collision.ngpcm() = %d", collision.neeuls(), collision.ngpcm()); - // LOGF(info, "collision.multNTracksPV() = %d, collision.multFT0A() = %f, collision.multFT0C() = %f", collision.multNTracksPV(), collision.multFT0A(), collision.multFT0C()); - - registry.fill(HIST("hEventCounter"), 1); - - event(collision.globalIndex(), bc.runNumber(), bc.globalBC(), collision.alias_raw(), collision.selection_raw(), collision.rct_raw(), bc.timestamp(), - collision.posX(), collision.posY(), collision.posZ(), - collision.numContrib(), collision.trackOccupancyInTimeRange(), collision.ft0cOccupancyInTimeRange()); - - // eventcov(collision.covXX(), collision.covXY(), collision.covXZ(), collision.covYY(), collision.covYZ(), collision.covZZ(), collision.chi2()); - - event_mult(collision.multFT0A(), collision.multFT0C(), collision.multNTracksPV(), collision.multNTracksPVeta1(), collision.multNTracksPVetaHalf()); - - if constexpr (eventype == EMEventType::kEvent) { - event_cent(105.f, 105.f, 105.f); - event_qvec( - 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, - 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f); - } else if constexpr (eventype == EMEventType::kEvent_Cent) { - event_cent(collision.centFT0M(), collision.centFT0A(), collision.centFT0C()); - event_qvec( - 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, - 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f); - } else if constexpr (eventype == EMEventType::kEvent_Cent_Qvec) { - event_cent(collision.centFT0M(), collision.centFT0A(), collision.centFT0C()); - float q2xft0m = 999.f, q2yft0m = 999.f, q2xft0a = 999.f, q2yft0a = 999.f, q2xft0c = 999.f, q2yft0c = 999.f, q2xbpos = 999.f, q2ybpos = 999.f, q2xbneg = 999.f, q2ybneg = 999.f, q2xbtot = 999.f, q2ybtot = 999.f; - float q3xft0m = 999.f, q3yft0m = 999.f, q3xft0a = 999.f, q3yft0a = 999.f, q3xft0c = 999.f, q3yft0c = 999.f, q3xbpos = 999.f, q3ybpos = 999.f, q3xbneg = 999.f, q3ybneg = 999.f, q3xbtot = 999.f, q3ybtot = 999.f; - - if (collision.qvecFT0CReVec().size() >= 2) { // harmonics 2,3 - q2xft0m = collision.qvecFT0MReVec()[0], q2xft0a = collision.qvecFT0AReVec()[0], q2xft0c = collision.qvecFT0CReVec()[0], q2xbpos = collision.qvecBPosReVec()[0], q2xbneg = collision.qvecBNegReVec()[0], q2xbtot = collision.qvecBTotReVec()[0]; - q2yft0m = collision.qvecFT0MImVec()[0], q2yft0a = collision.qvecFT0AImVec()[0], q2yft0c = collision.qvecFT0CImVec()[0], q2ybpos = collision.qvecBPosImVec()[0], q2ybneg = collision.qvecBNegImVec()[0], q2ybtot = collision.qvecBTotImVec()[0]; - q3xft0m = collision.qvecFT0MReVec()[1], q3xft0a = collision.qvecFT0AReVec()[1], q3xft0c = collision.qvecFT0CReVec()[1], q3xbpos = collision.qvecBPosReVec()[1], q3xbneg = collision.qvecBNegReVec()[1], q3xbtot = collision.qvecBTotReVec()[1]; - q3yft0m = collision.qvecFT0MImVec()[1], q3yft0a = collision.qvecFT0AImVec()[1], q3yft0c = collision.qvecFT0CImVec()[1], q3ybpos = collision.qvecBPosImVec()[1], q3ybneg = collision.qvecBNegImVec()[1], q3ybtot = collision.qvecBTotImVec()[1]; - } else if (collision.qvecFT0CReVec().size() >= 1) { // harmonics 2 - q2xft0m = collision.qvecFT0MReVec()[0], q2xft0a = collision.qvecFT0AReVec()[0], q2xft0c = collision.qvecFT0CReVec()[0], q2xbpos = collision.qvecBPosReVec()[0], q2xbneg = collision.qvecBNegReVec()[0], q2xbtot = collision.qvecBTotReVec()[0]; - q2yft0m = collision.qvecFT0MImVec()[0], q2yft0a = collision.qvecFT0AImVec()[0], q2yft0c = collision.qvecFT0CImVec()[0], q2ybpos = collision.qvecBPosImVec()[0], q2ybneg = collision.qvecBNegImVec()[0], q2ybtot = collision.qvecBTotImVec()[0]; - } - event_qvec( - q2xft0m, q2yft0m, q2xft0a, q2yft0a, q2xft0c, q2yft0c, q2xbpos, q2ybpos, q2xbneg, q2ybneg, q2xbtot, q2ybtot, - q3xft0m, q3yft0m, q3xft0a, q3yft0a, q3xft0c, q3yft0c, q3xbpos, q3ybpos, q3xbneg, q3ybneg, q3xbtot, q3ybtot); - } else { - event_cent(105.f, 105.f, 105.f); - event_qvec( - 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, - 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f, 999.f); - } - } // end of collision loop - } // end of skimEvent - - void processEvent(MyCollisions const& collisions, MyBCs const& bcs) - { - skimEvent(collisions, bcs); - } - PROCESS_SWITCH(createEMEvent2VP, processEvent, "process event info", false); - - void processEvent_Cent(MyCollisions_Cent const& collisions, MyBCs const& bcs) - { - skimEvent(collisions, bcs); - } - PROCESS_SWITCH(createEMEvent2VP, processEvent_Cent, "process event info", false); - - void processEvent_Cent_Qvec(MyCollisions_Cent_Qvec const& collisions, MyBCs const& bcs) - { - skimEvent(collisions, bcs); - } - PROCESS_SWITCH(createEMEvent2VP, processEvent_Cent_Qvec, "process event info", false); - - void processEvent_SWT(MyCollisionsWithSWT const& collisions, MyBCs const& bcs) - { - skimEvent(collisions, bcs); - } - PROCESS_SWITCH(createEMEvent2VP, processEvent_SWT, "process event info", false); - - void processEvent_SWT_Cent(MyCollisionsWithSWT_Cent const& collisions, MyBCs const& bcs) - { - skimEvent(collisions, bcs); - } - PROCESS_SWITCH(createEMEvent2VP, processEvent_SWT_Cent, "process event info", false); - - void processEvent_SWT_Cent_Qvec(MyCollisionsWithSWT_Cent_Qvec const& collisions, MyBCs const& bcs) - { - skimEvent(collisions, bcs); - } - PROCESS_SWITCH(createEMEvent2VP, processEvent_SWT_Cent_Qvec, "process event info", false); - - void processEventMC(MyCollisionsMC const& collisions, MyBCs const& bcs) - { - skimEvent(collisions, bcs); - } - PROCESS_SWITCH(createEMEvent2VP, processEventMC, "process event info", false); - - void processEventMC_Cent(MyCollisionsMC_Cent const& collisions, MyBCs const& bcs) - { - skimEvent(collisions, bcs); - } - PROCESS_SWITCH(createEMEvent2VP, processEventMC_Cent, "process event info", false); - - void processEventMC_Cent_Qvec(MyCollisionsMC_Cent_Qvec const& collisions, MyBCs const& bcs) - { - skimEvent(collisions, bcs); - } - PROCESS_SWITCH(createEMEvent2VP, processEventMC_Cent_Qvec, "process event info", false); - - void processDummy(aod::Collisions const&) {} - PROCESS_SWITCH(createEMEvent2VP, processDummy, "processDummy", true); -}; -struct AssociateDileptonToEMEvent2VP { - Produces v0kfeventid; - Produces prmeleventid; - - Preslice perCollision_pcm = aod::v0photonkf::collisionId; - PresliceUnsorted perCollision_el = aod::emprimaryelectron::collisionId; - - void init(o2::framework::InitContext&) {} - - template - void fillEventId(TCollisions const& collisions, TLeptons const& leptons, TEventIds& eventIds, TPreslice const& perCollision) - { - for (auto& collision : collisions) { - auto leptons_coll = leptons.sliceBy(perCollision, collision.collisionId()); - int nl = leptons_coll.size(); - // LOGF(info, "collision.collisionId() = %d , nl = %d", collision.collisionId(), nl); - for (int il = 0; il < nl; il++) { - eventIds(collision.globalIndex()); - } // end of photon loop - } // end of collision loop - } - - // This struct is for both data and MC. - // Note that reconstructed collisions without mc collisions are already rejected in CreateEMEventDilepton in MC. - - void processPCM(aod::EMEvents const& collisions, aod::V0PhotonsKF const& photons) - { - fillEventId(collisions, photons, v0kfeventid, perCollision_pcm); - } - - void processElectron(aod::EMEvents const& collisions, aod::EMPrimaryElectrons const& tracks) - { - fillEventId(collisions, tracks, prmeleventid, perCollision_el); - } - - void processDummy(aod::EMEvents const&) {} - - PROCESS_SWITCH(AssociateDileptonToEMEvent2VP, processPCM, "process pcm-event indexing", false); - PROCESS_SWITCH(AssociateDileptonToEMEvent2VP, processElectron, "process dalitzee-event indexing", false); - PROCESS_SWITCH(AssociateDileptonToEMEvent2VP, processDummy, "process dummy", true); -}; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc, TaskName{"filter-dielectron-event"}), - adaptAnalysisTask(cfgc, TaskName{"prefilter-primary-electron"}), - adaptAnalysisTask(cfgc, TaskName{"associate-ambiguous-electron"}), - adaptAnalysisTask(cfgc, TaskName{"create-emevent-2vp"}), - adaptAnalysisTask(cfgc, TaskName{"associate-dilepton-to-emevent2VP"}), - }; -} diff --git a/PWGEM/Dilepton/TableProducer/filterEoI.cxx b/PWGEM/Dilepton/TableProducer/filterEoI.cxx index 11a3078d501..59dfbf07e0b 100644 --- a/PWGEM/Dilepton/TableProducer/filterEoI.cxx +++ b/PWGEM/Dilepton/TableProducer/filterEoI.cxx @@ -32,11 +32,12 @@ struct filterEoI { kElectron = 0x1, kFwdMuon = 0x2, kPCM = 0x4, + kElectronFromDalitz = 0x8, }; Produces emeoi; - Configurable minNElectrons{"minNElectrons", 1, "min number of e+ or e- at midrapidity"}; - Configurable minNMuons{"minNMuons", 1, "min number of mu+ or mu- at forward rapidity"}; - Configurable minNV0s{"minNV0s", 1, "min number of v0 photons at midrapidity"}; + // Configurable minNElectrons{"minNElectrons", 1, "min number of e+ or e- at midrapidity"}; + // Configurable minNMuons{"minNMuons", 1, "min number of mu+ or mu- at forward rapidity"}; + // Configurable minNV0s{"minNV0s", 1, "min number of v0 photons at midrapidity"}; HistogramRegistry fRegistry{"output"}; void init(o2::framework::InitContext&) @@ -49,44 +50,52 @@ struct filterEoI { hEventCounter->GetXaxis()->SetBinLabel(5, "event with electron or forward muon"); hEventCounter->GetXaxis()->SetBinLabel(6, "event with electron and forward muon"); hEventCounter->GetXaxis()->SetBinLabel(7, "event with electron or forward muon or v0"); - hEventCounter->GetXaxis()->SetBinLabel(8, "event with electron and forward muon and v0"); + hEventCounter->GetXaxis()->SetBinLabel(8, "event with v0 or electrons from dalitz"); } SliceCache cache; Preslice perCollision_el = aod::emprimaryelectron::collisionId; Preslice perCollision_mu = aod::emprimarymuon::collisionId; Preslice perCollision_v0 = aod::v0photonkf::collisionId; + Preslice perCollision_elda = aod::emprimaryelectron::collisionId; - template - void selectEoI(TCollisions const& collisions, TElectrons const& electrons, TMuons const& muons, TV0s const& v0s) + template + void selectEoI(TCollisions const& collisions, TElectrons const& electrons, TMuons const& muons, TV0s const& v0s, TElectronsDA const& electronsda) { for (const auto& collision : collisions) { bool does_electron_exist = false; bool does_fwdmuon_exist = false; bool does_pcm_exist = false; + bool does_electronda_exist = false; fRegistry.fill(HIST("hEventCounter"), 1); if constexpr (static_cast(system & kElectron)) { auto electrons_coll = electrons.sliceBy(perCollision_el, collision.globalIndex()); - if (electrons_coll.size() >= minNElectrons) { + if (electrons_coll.size() >= 1) { does_electron_exist = true; fRegistry.fill(HIST("hEventCounter"), 2); } } if constexpr (static_cast(system & kFwdMuon)) { auto muons_coll = muons.sliceBy(perCollision_mu, collision.globalIndex()); - if (muons_coll.size() >= minNMuons) { + if (muons_coll.size() >= 1) { does_fwdmuon_exist = true; fRegistry.fill(HIST("hEventCounter"), 3); } } if constexpr (static_cast(system & kPCM)) { auto v0s_coll = v0s.sliceBy(perCollision_v0, collision.globalIndex()); - if (v0s_coll.size() >= minNV0s) { + if (v0s_coll.size() >= 1) { does_pcm_exist = true; fRegistry.fill(HIST("hEventCounter"), 4); } } + if constexpr (static_cast(system & kElectronFromDalitz)) { + auto electronsda_coll = electronsda.sliceBy(perCollision_elda, collision.globalIndex()); + if (electronsda_coll.size() >= 2) { + does_electronda_exist = true; + } + } if (does_electron_exist || does_fwdmuon_exist) { fRegistry.fill(HIST("hEventCounter"), 5); @@ -97,11 +106,11 @@ struct filterEoI { if (does_electron_exist || does_fwdmuon_exist || does_pcm_exist) { fRegistry.fill(HIST("hEventCounter"), 7); } - if (does_electron_exist && does_fwdmuon_exist && does_pcm_exist) { + if (does_pcm_exist || does_electronda_exist) { fRegistry.fill(HIST("hEventCounter"), 8); } - emeoi(does_electron_exist || does_fwdmuon_exist || does_pcm_exist); + emeoi(does_electron_exist || does_fwdmuon_exist || does_pcm_exist || does_electronda_exist); } // end of collision loop @@ -110,31 +119,37 @@ struct filterEoI { void process_Electron(aod::Collisions const& collisions, aod::EMPrimaryElectrons const& electrons) { const uint8_t sysflag = kElectron; - selectEoI(collisions, electrons, nullptr, nullptr); + selectEoI(collisions, electrons, nullptr, nullptr, nullptr); } void process_FwdMuon(aod::Collisions const& collisions, aod::EMPrimaryMuons const& muons) { const uint8_t sysflag = kFwdMuon; - selectEoI(collisions, nullptr, muons, nullptr); + selectEoI(collisions, nullptr, muons, nullptr, nullptr); } void process_Electron_FwdMuon(aod::Collisions const& collisions, aod::EMPrimaryElectrons const& electrons, aod::EMPrimaryMuons const& muons) { const uint8_t sysflag = kElectron | kFwdMuon; - selectEoI(collisions, electrons, muons, nullptr); + selectEoI(collisions, electrons, muons, nullptr, nullptr); } void process_PCM(aod::Collisions const& collisions, aod::V0PhotonsKF const& v0s) { const uint8_t sysflag = kPCM; - selectEoI(collisions, nullptr, nullptr, v0s); + selectEoI(collisions, nullptr, nullptr, v0s, nullptr); } void process_Electron_FwdMuon_PCM(aod::Collisions const& collisions, aod::EMPrimaryElectrons const& electrons, aod::EMPrimaryMuons const& muons, aod::V0PhotonsKF const& v0s) { const uint8_t sysflag = kElectron | kFwdMuon | kPCM; - selectEoI(collisions, electrons, muons, v0s); + selectEoI(collisions, electrons, muons, v0s, nullptr); + } + + void process_PCM_ElectronFromDalitz(aod::Collisions const& collisions, aod::V0PhotonsKF const& v0s, aod::EMPrimaryElectronsFromDalitz const& electronsda) + { + const uint8_t sysflag = kPCM | kElectronFromDalitz; + selectEoI(collisions, nullptr, nullptr, v0s, electronsda); } void processDummy(aod::Collisions const& collisions) @@ -149,6 +164,7 @@ struct filterEoI { PROCESS_SWITCH(filterEoI, process_PCM, "create filter bit for PCM", false); PROCESS_SWITCH(filterEoI, process_Electron_FwdMuon, "create filter bit for Electron, FwdMuon", false); PROCESS_SWITCH(filterEoI, process_Electron_FwdMuon_PCM, "create filter bit for Electron, FwdMuon, PCM", false); + PROCESS_SWITCH(filterEoI, process_PCM_ElectronFromDalitz, "create filter bit for PCM, ElectronFromDalitz", false); PROCESS_SWITCH(filterEoI, processDummy, "processDummy", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx b/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx index b4b9db26de5..bf1e2b61505 100644 --- a/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx +++ b/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectron.cxx @@ -51,8 +51,8 @@ using MyCollisions = soa::Join; using MyCollisionsWithSWT = soa::Join; using MyTracks = soa::Join; + aod::pidTPCFullEl, /*aod::pidTPCFullMu,*/ aod::pidTPCFullPi, aod::pidTPCFullKa, aod::pidTPCFullPr, + aod::pidTOFFullEl, /*aod::pidTOFFullMu,*/ aod::pidTOFFullPi, aod::pidTOFFullKa, aod::pidTOFFullPr, aod::pidTOFbeta>; using MyTrack = MyTracks::iterator; using MyTracksMC = soa::Join; using MyTrackMC = MyTracksMC::iterator; @@ -161,13 +161,13 @@ struct skimmerPrimaryElectron { fRegistry.add("Track/hTPCdEdx", "TPC dE/dx;p_{in} (GeV/c);TPC dE/dx (a.u.)", kTH2F, {{1000, 0, 10}, {200, 0, 200}}, false); fRegistry.add("Track/hTPCdEdxMC", "TPC dE/dx;p_{in} (GeV/c);TPC dE/dx (a.u.)", kTH2F, {{1000, 0, 10}, {200, 0, 200}}, false); fRegistry.add("Track/hTPCNsigmaEl", "TPC n sigma el;p_{in} (GeV/c);n #sigma_{e}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTPCNsigmaMu", "TPC n sigma mu;p_{in} (GeV/c);n #sigma_{#mu}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + // fRegistry.add("Track/hTPCNsigmaMu", "TPC n sigma mu;p_{in} (GeV/c);n #sigma_{#mu}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); fRegistry.add("Track/hTPCNsigmaPi", "TPC n sigma pi;p_{in} (GeV/c);n #sigma_{#pi}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); fRegistry.add("Track/hTPCNsigmaKa", "TPC n sigma ka;p_{in} (GeV/c);n #sigma_{K}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); fRegistry.add("Track/hTPCNsigmaPr", "TPC n sigma pr;p_{in} (GeV/c);n #sigma_{p}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); fRegistry.add("Track/hTOFbeta", "TOF beta;p_{pv} (GeV/c);#beta", kTH2F, {{1000, 0, 10}, {240, 0, 1.2}}, false); fRegistry.add("Track/hTOFNsigmaEl", "TOF n sigma el;p_{in} (GeV/c);n #sigma_{e}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTOFNsigmaMu", "TOF n sigma mu;p_{in} (GeV/c);n #sigma_{#mu}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + // fRegistry.add("Track/hTOFNsigmaMu", "TOF n sigma mu;p_{in} (GeV/c);n #sigma_{#mu}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); fRegistry.add("Track/hTOFNsigmaPi", "TOF n sigma pi;p_{in} (GeV/c);n #sigma_{#pi}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); fRegistry.add("Track/hTOFNsigmaKa", "TOF n sigma ka;p_{in} (GeV/c);n #sigma_{K}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); fRegistry.add("Track/hTOFNsigmaPr", "TOF n sigma pr;p_{in} (GeV/c);n #sigma_{p}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); @@ -282,7 +282,7 @@ struct skimmerPrimaryElectron { return false; } - if (track.itsChi2NCl() > maxchi2its) { + if (track.itsChi2NCl() < 0.f || maxchi2its < track.itsChi2NCl()) { return false; } if (track.itsNCls() < min_ncluster_its) { @@ -297,7 +297,7 @@ struct skimmerPrimaryElectron { } if (track.hasTPC()) { - if (track.tpcChi2NCl() > maxchi2tpc) { + if (track.tpcChi2NCl() < 0.f || maxchi2tpc < track.tpcChi2NCl()) { return false; } @@ -328,8 +328,6 @@ struct skimmerPrimaryElectron { float dcaXY = mDcaInfoCov.getY(); float dcaZ = mDcaInfoCov.getZ(); - // LOGF(info, "trackParCov.getSigmaY2() = %.16f, mDcaInfoCov.getSigmaY2() = %.16f, trackParCov.getSigmaZ2() = %.16f, mDcaInfoCov.getSigmaZ2() = %.16f, trackParCov.getSigmaZY() = %.16f, mDcaInfoCov.getSigmaYZ() = %.16f", trackParCov.getSigmaY2(), mDcaInfoCov.getSigmaY2(), trackParCov.getSigmaZ2(), mDcaInfoCov.getSigmaZ2(), trackParCov.getSigmaZY(), mDcaInfoCov.getSigmaYZ()); - if (std::fabs(dcaXY) > dca_xy_max || std::fabs(dcaZ) > dca_z_max) { return false; } @@ -372,33 +370,15 @@ struct skimmerPrimaryElectron { return true; } - template - bool isElectron(TCollision const& collision, TTrack const& track) + template + bool isElectron(TTrack const& track) { if (includeITSsa && (track.hasITS() && !track.hasTPC() && !track.hasTRD() && !track.hasTOF())) { return true; } if (usePIDML) { - if (track.tpcNSigmaEl() < minTPCNsigmaEl || maxTPCNsigmaEl < track.tpcNSigmaEl()) { - return false; - } - if (track.hasTOF() && (maxTOFNsigmaEl < std::fabs(track.tofNSigmaEl()))) { - return false; - } - - // return false; - o2::dataformats::DCA mDcaInfoCov; - mDcaInfoCov.set(999, 999, 999, 999, 999); - auto trackParCov = getTrackParCov(track); - trackParCov.setPID(o2::track::PID::Electron); - mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); - mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); - - std::vector inputFeatures = mlResponseSingleTrack.getInputFeatures(track, trackParCov, collision); - float binningFeature = mlResponseSingleTrack.getBinningFeature(track, trackParCov, collision); - return mlResponseSingleTrack.isSelectedMl(inputFeatures, binningFeature); + return true; } else { return isElectron_TPChadrej(track) || isElectron_TOFreq(track); } @@ -454,26 +434,40 @@ struct skimmerPrimaryElectron { o2::math_utils::bringTo02Pi(phi_recalc); bool isAssociatedToMPC = collision.globalIndex() == track.collisionId(); - float tpcSignalMC = -1; + float mcTunedTPCSignal = 0.f; if constexpr (isMC) { - tpcSignalMC = track.mcTunedTPCSignal(); + mcTunedTPCSignal = track.mcTunedTPCSignal(); + } + + float probaEl = 1.0; + if (usePIDML) { + std::vector inputFeatures = mlResponseSingleTrack.getInputFeatures(track, trackParCov, collision); + float binningFeature = mlResponseSingleTrack.getBinningFeature(track, trackParCov, collision); + probaEl = mlResponseSingleTrack.isSelectedMl(inputFeatures, binningFeature); } emprimaryelectrons(collision.globalIndex(), track.globalIndex(), track.sign(), - pt_recalc, eta_recalc, phi_recalc, dcaXY, dcaZ, + pt_recalc, eta_recalc, phi_recalc, + dcaXY, dcaZ, trackParCov.getSigmaY2(), trackParCov.getSigmaZY(), trackParCov.getSigmaZ2(), track.tpcNClsFindable(), track.tpcNClsFindableMinusFound(), track.tpcNClsFindableMinusCrossedRows(), track.tpcNClsShared(), track.tpcChi2NCl(), track.tpcInnerParam(), - track.tpcSignal(), track.tpcNSigmaEl(), /*track.tpcNSigmaMu(),*/ track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), - track.beta(), track.tofNSigmaEl(), /*track.tofNSigmaMu(),*/ track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr(), + track.tpcSignal(), track.tpcNSigmaEl(), track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), + track.beta(), track.tofNSigmaEl(), /*track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr(),*/ track.itsClusterSizes(), - // track.itsNSigmaEl(), track.itsNSigmaMu(), track.itsNSigmaPi(), track.itsNSigmaKa(), track.itsNSigmaPr(), track.itsChi2NCl(), track.tofChi2(), track.detectorMap(), - trackParCov.getX(), trackParCov.getAlpha(), trackParCov.getY(), trackParCov.getZ(), trackParCov.getSnp(), trackParCov.getTgl(), isAssociatedToMPC, tpcSignalMC); + // trackParCov.getTgl(), + isAssociatedToMPC, false, probaEl, mcTunedTPCSignal); emprimaryelectronscov( - trackParCov.getSigmaY2(), - trackParCov.getSigmaZY(), - trackParCov.getSigmaZ2(), + trackParCov.getX(), + trackParCov.getAlpha(), + trackParCov.getY(), + trackParCov.getZ(), + trackParCov.getSnp(), + // trackParCov.getTgl(), + // trackParCov.getSigmaY2(), + // trackParCov.getSigmaZY(), + // trackParCov.getSigmaZ2(), trackParCov.getSigmaSnpY(), trackParCov.getSigmaSnpZ(), trackParCov.getSigmaSnp2(), @@ -536,15 +530,15 @@ struct skimmerPrimaryElectron { fRegistry.fill(HIST("Track/hChi2TOF"), track.tofChi2()); fRegistry.fill(HIST("Track/hITSClusterMap"), track.itsClusterMap()); fRegistry.fill(HIST("Track/hTPCdEdx"), track.tpcInnerParam(), track.tpcSignal()); - fRegistry.fill(HIST("Track/hTPCdEdxMC"), track.tpcInnerParam(), tpcSignalMC); + fRegistry.fill(HIST("Track/hTPCdEdxMC"), track.tpcInnerParam(), mcTunedTPCSignal); fRegistry.fill(HIST("Track/hTPCNsigmaEl"), track.tpcInnerParam(), track.tpcNSigmaEl()); - fRegistry.fill(HIST("Track/hTPCNsigmaMu"), track.tpcInnerParam(), track.tpcNSigmaMu()); + // fRegistry.fill(HIST("Track/hTPCNsigmaMu"), track.tpcInnerParam(), track.tpcNSigmaMu()); fRegistry.fill(HIST("Track/hTPCNsigmaPi"), track.tpcInnerParam(), track.tpcNSigmaPi()); fRegistry.fill(HIST("Track/hTPCNsigmaKa"), track.tpcInnerParam(), track.tpcNSigmaKa()); fRegistry.fill(HIST("Track/hTPCNsigmaPr"), track.tpcInnerParam(), track.tpcNSigmaPr()); fRegistry.fill(HIST("Track/hTOFbeta"), trackParCov.getP(), track.beta()); fRegistry.fill(HIST("Track/hTOFNsigmaEl"), track.tpcInnerParam(), track.tofNSigmaEl()); - fRegistry.fill(HIST("Track/hTOFNsigmaMu"), track.tpcInnerParam(), track.tofNSigmaMu()); + // fRegistry.fill(HIST("Track/hTOFNsigmaMu"), track.tpcInnerParam(), track.tofNSigmaMu()); fRegistry.fill(HIST("Track/hTOFNsigmaPi"), track.tpcInnerParam(), track.tofNSigmaPi()); fRegistry.fill(HIST("Track/hTOFNsigmaKa"), track.tpcInnerParam(), track.tofNSigmaKa()); fRegistry.fill(HIST("Track/hTOFNsigmaPr"), track.tpcInnerParam(), track.tofNSigmaPr()); @@ -579,7 +573,7 @@ struct skimmerPrimaryElectron { auto tracks_per_coll = tracks.sliceBy(perCol, collision.globalIndex()); for (const auto& track : tracks_per_coll) { - if (!checkTrack(collision, track) || !isElectron(collision, track)) { + if (!checkTrack(collision, track) || !isElectron(track)) { continue; } fillTrackTable(collision, track); @@ -608,7 +602,7 @@ struct skimmerPrimaryElectron { for (const auto& trackId : trackIdsThisCollision) { auto track = trackId.template track_as(); - if (!checkTrack(collision, track) || !isElectron(collision, track)) { + if (!checkTrack(collision, track) || !isElectron(track)) { continue; } fillTrackTable(collision, track); @@ -638,7 +632,7 @@ struct skimmerPrimaryElectron { auto tracks_per_coll = tracks.sliceBy(perCol, collision.globalIndex()); for (const auto& track : tracks_per_coll) { - if (!checkTrack(collision, track) || !isElectron(collision, track)) { + if (!checkTrack(collision, track) || !isElectron(track)) { continue; } fillTrackTable(collision, track); @@ -670,7 +664,7 @@ struct skimmerPrimaryElectron { for (const auto& trackId : trackIdsThisCollision) { auto track = trackId.template track_as(); - if (!checkTrack(collision, track) || !isElectron(collision, track)) { + if (!checkTrack(collision, track) || !isElectron(track)) { continue; } fillTrackTable(collision, track); @@ -704,7 +698,7 @@ struct skimmerPrimaryElectron { auto tracks_per_coll = tracks.sliceBy(perCol, collision.globalIndex()); for (const auto& track : tracks_per_coll) { - if (!checkTrack(collision, track) || !isElectron(collision, track)) { + if (!checkTrack(collision, track) || !isElectron(track)) { continue; } fillTrackTable(collision, track); @@ -735,7 +729,7 @@ struct skimmerPrimaryElectron { for (const auto& trackId : trackIdsThisCollision) { auto track = trackId.template track_as(); - if (!checkTrack(collision, track) || !isElectron(collision, track)) { + if (!checkTrack(collision, track) || !isElectron(track)) { continue; } fillTrackTable(collision, track); @@ -977,6 +971,7 @@ struct prefilterPrimaryElectron { if constexpr (loose_track_sign > 0) { // positive track is loose track auto trackParCov = getTrackParCov(pos); + trackParCov.setPID(o2::track::PID::Electron); o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); getPxPyPz(trackParCov, pVec_recalc); @@ -987,6 +982,7 @@ struct prefilterPrimaryElectron { phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(pVec_recalc[0], pVec_recalc[1], pVec_recalc[2], ele.px(), ele.py(), ele.pz(), pos.sign(), ele.sign(), d_bz); } else { auto trackParCov = getTrackParCov(ele); + trackParCov.setPID(o2::track::PID::Electron); o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); getPxPyPz(trackParCov, pVec_recalc); diff --git a/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectronQC.cxx b/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectronQC.cxx new file mode 100644 index 00000000000..68b0fad8593 --- /dev/null +++ b/PWGEM/Dilepton/TableProducer/skimmerPrimaryElectronQC.cxx @@ -0,0 +1,806 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \brief write relevant information about primary electrons. +/// \author daiki.sekihata@cern.ch + +#include "PWGEM/Dilepton/DataModel/dileptonTables.h" +#include "PWGEM/Dilepton/Utils/MlResponseO2Track.h" +#include "PWGEM/Dilepton/Utils/PairUtilities.h" + +#include "Common/Core/TableHelper.h" +#include "Common/Core/trackUtilities.h" +// #include "Common/DataModel/CollisionAssociationTables.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/PIDResponseITS.h" +#include "Tools/ML/MlResponse.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CommonConstants/PhysicsConstants.h" +#include "DataFormatsCalibration/MeanVertexObject.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "Math/Vector4D.h" + +#include +#include +#include +#include + +using namespace o2; +using namespace o2::soa; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::constants::physics; + +using MyCollisions = soa::Join; +using MyCollisionsWithSWT = soa::Join; + +using MyTracks = soa::Join; +using MyTrack = MyTracks::iterator; +using MyTracksMC = soa::Join; +using MyTrackMC = MyTracksMC::iterator; + +struct skimmerPrimaryElectronQC { + SliceCache cache; + Preslice perCol = o2::aod::track::collisionId; + Produces emprimaryelectrons; + Produces emprimaryelectronscov; + + // Configurables + Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; + Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; + Configurable mVtxPath{"mVtxPath", "GLO/Calib/MeanVertex", "Path of the mean vertex file"}; + Configurable skipGRPOquery{"skipGRPOquery", true, "skip grpo query"}; + + // Operation and minimisation criteria + Configurable fillQAHistogram{"fillQAHistogram", false, "flag to fill QA histograms"}; + Configurable d_bz_input{"d_bz_input", -999, "bz field in kG, -999 is automatic"}; + + struct : ConfigurableGroup { + std::string prefix = "trackcut"; + Configurable min_ncluster_tpc{"min_ncluster_tpc", 0, "min ncluster tpc"}; + Configurable mincrossedrows{"mincrossedrows", 40, "min. crossed rows"}; + Configurable min_ncluster_its{"min_ncluster_its", 2, "min ncluster its"}; + Configurable min_ncluster_itsib{"min_ncluster_itsib", 0, "min ncluster itsib"}; + Configurable min_tpc_cr_findable_ratio{"min_tpc_cr_findable_ratio", 0.8, "min. TPC Ncr/Nf ratio"}; + Configurable max_frac_shared_clusters_tpc{"max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; + Configurable maxchi2tpc{"maxchi2tpc", 5.0, "max. chi2/NclsTPC"}; + Configurable maxchi2its{"maxchi2its", 36.0, "max. chi2/NclsITS"}; + Configurable minpt{"minpt", 0.05, "min pt for ITS-TPC track"}; + Configurable maxeta{"maxeta", 0.9, "eta acceptance"}; + Configurable dca_xy_max{"dca_xy_max", 1.0, "max DCAxy in cm"}; + Configurable dca_z_max{"dca_z_max", 1.0, "max DCAz in cm"}; + Configurable minTPCNsigmaEl{"minTPCNsigmaEl", -3.5, "min. TPC n sigma for electron inclusion"}; + Configurable maxTPCNsigmaEl{"maxTPCNsigmaEl", +3.5, "max. TPC n sigma for electron inclusion"}; + } trackcut; + + struct : ConfigurableGroup { + std::string prefix = "tighttrackcut"; + Configurable min_ncluster_tpc_pid{"min_ncluster_tpc_pid", 60, "min ncluster tpc used for PID"}; + Configurable min_ncluster_tpc{"min_ncluster_tpc", 0, "min ncluster tpc"}; + Configurable mincrossedrows{"mincrossedrows", 100, "min. crossed rows"}; + Configurable min_ncluster_its{"min_ncluster_its", 5, "min ncluster its"}; + Configurable min_ncluster_itsib{"min_ncluster_itsib", 3, "min ncluster itsib"}; + Configurable min_tpc_cr_findable_ratio{"min_tpc_cr_findable_ratio", 0.8, "min. TPC Ncr/Nf ratio"}; + Configurable max_frac_shared_clusters_tpc{"max_frac_shared_clusters_tpc", 0.7, "max fraction of shared clusters in TPC"}; + Configurable maxchi2tpc{"maxchi2tpc", 4.0, "max. chi2/NclsTPC"}; + Configurable maxchi2its{"maxchi2its", 5.0, "max. chi2/NclsITS"}; + Configurable dca_xy_max{"dca_xy_max", 0.2, "max DCAxy in cm"}; + Configurable dca_z_max{"dca_z_max", 0.2, "max DCAz in cm"}; + Configurable minTPCNsigmaEl{"minTPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; // Don't change. + Configurable maxTPCNsigmaEl{"maxTPCNsigmaEl", +2.0, "max. TPC n sigma for electron inclusion"}; // Don't change. + Configurable minTOFNsigmaEl{"minTOFNsigmaEl", -2.0, "min. TOF n sigma for electron inclusion"}; // Don't change. + Configurable maxTOFNsigmaEl{"maxTOFNsigmaEl", +2.0, "max. TOF n sigma for electron inclusion"}; // Don't change. + } tighttrackcut; + + Configurable storeOnlyTrueElectronMC{"storeOnlyTrueElectronMC", false, "Flag to store only true electron in MC"}; + Configurable maxMee{"maxMee", 0.005, "max mee for pi0 -> ee"}; + Configurable maxPhiV{"maxPhiV", M_PI / 2, "max phiv for pi0 -> ee"}; + + // configuration for PID ML + Configurable usePIDML{"usePIDML", false, "Flag to use PID ML"}; + Configurable> onnxFileNames{"onnxFileNames", std::vector{"filename"}, "ONNX file names for each bin (if not from CCDB full path)"}; + Configurable> onnxPathsCCDB{"onnxPathsCCDB", std::vector{"path"}, "Paths of models on CCDB"}; + Configurable> binsMl{"binsMl", std::vector{-999999., 999999.}, "Bin limits for ML application"}; + Configurable> cutsMl{"cutsMl", std::vector{0.95}, "ML cuts per bin"}; + Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature"}, "Names of ML model input features"}; + Configurable nameBinningFeature{"nameBinningFeature", "pt", "Names of ML model binning feature"}; + Configurable timestampCCDB{"timestampCCDB", -1, "timestamp of the ONNX file for ML model used to query in CCDB. Exceptions: > 0 for the specific timestamp, 0 gets the run dependent timestamp"}; + Configurable loadModelsFromCCDB{"loadModelsFromCCDB", false, "Flag to enable or disable the loading of models from CCDB"}; + Configurable enableOptimizations{"enableOptimizations", false, "Enables the ONNX extended model-optimization: sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED)"}; + + HistogramRegistry fRegistry{"output", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; + o2::analysis::MlResponseO2Track mlResponseSingleTrack; + + int mRunNumber; + float d_bz; + Service ccdb; + // o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + + o2::dataformats::VertexBase mVtx; + o2::dataformats::DCA mDcaInfoCov; + + const o2::dataformats::MeanVertexObject* mMeanVtx = nullptr; + o2::base::MatLayerCylSet* lut = nullptr; + o2::ccdb::CcdbApi ccdbApi; + + void init(InitContext&) + { + mRunNumber = 0; + d_bz = 0; + + ccdb->setURL(ccdburl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(false); + ccdbApi.init(ccdburl); + + if (fillQAHistogram) { + fRegistry.add("Track/hPt", "pT;p_{T} (GeV/c)", kTH1F, {{1000, 0.0f, 10}}, false); + fRegistry.add("Track/hQoverPt", "q/pT;q/p_{T} (GeV/c)^{-1}", kTH1F, {{400, -20, 20}}, false); + fRegistry.add("Track/hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2F, {{180, 0, 2 * M_PI}, {20, -1.0f, 1.0f}}, false); + fRegistry.add("Track/hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm)", kTH2F, {{200, -1.0f, 1.0f}, {200, -1.0f, 1.0f}}, false); + fRegistry.add("Track/hDCAxyzSigma", "DCA xy vs. z;DCA_{xy} (#sigma);DCA_{z} (#sigma)", kTH2F, {{200, -10.0f, 10.0f}, {200, -10.0f, 10.0f}}, false); + fRegistry.add("Track/hDCAxyRes_Pt", "DCA_{xy} resolution vs. pT;p_{T} (GeV/c);DCA_{xy} resolution (#mum)", kTH2F, {{1000, 0, 10}, {500, 0., 500}}, false); + fRegistry.add("Track/hDCAzRes_Pt", "DCA_{z} resolution vs. pT;p_{T} (GeV/c);DCA_{z} resolution (#mum)", kTH2F, {{1000, 0, 10}, {500, 0., 500}}, false); + fRegistry.add("Track/hNclsTPC", "number of TPC clusters", kTH1F, {{161, -0.5, 160.5}}, false); + fRegistry.add("Track/hNcrTPC", "number of TPC crossed rows", kTH1F, {{161, -0.5, 160.5}}, false); + fRegistry.add("Track/hChi2TPC", "chi2/number of TPC clusters", kTH1F, {{100, 0, 10}}, false); + fRegistry.add("Track/hChi2TOF", "chi2 of TOF", kTH1F, {{100, 0, 10}}, false); + fRegistry.add("Track/hTPCNcr2Nf", "TPC Ncr/Nfindable", kTH1F, {{200, 0, 2}}, false); + fRegistry.add("Track/hTPCNcls2Nf", "TPC Ncls/Nfindable", kTH1F, {{200, 0, 2}}, false); + fRegistry.add("Track/hTPCNclsShared", "TPC Ncls shared/Ncls;p_{T} (GeV/c);N_{cls}^{shared}/N_{cls} in TPC", kTH2F, {{1000, 0, 10}, {100, 0, 1}}, false); + fRegistry.add("Track/hNclsITS", "number of ITS clusters", kTH1F, {{8, -0.5, 7.5}}, false); + fRegistry.add("Track/hChi2ITS", "chi2/number of ITS clusters", kTH1F, {{400, 0, 40}}, false); + fRegistry.add("Track/hITSClusterMap", "ITS cluster map", kTH1F, {{128, -0.5, 127.5}}, false); + fRegistry.add("Track/hTPCdEdx", "TPC dE/dx;p_{in} (GeV/c);TPC dE/dx (a.u.)", kTH2F, {{1000, 0, 10}, {200, 0, 200}}, false); + fRegistry.add("Track/hTPCdEdxMC", "TPC dE/dx;p_{in} (GeV/c);TPC dE/dx (a.u.)", kTH2F, {{1000, 0, 10}, {200, 0, 200}}, false); + fRegistry.add("Track/hTPCNsigmaEl", "TPC n sigma el;p_{in} (GeV/c);n #sigma_{e}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + fRegistry.add("Track/hTPCNsigmaPi", "TPC n sigma pi;p_{in} (GeV/c);n #sigma_{#pi}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + fRegistry.add("Track/hTPCNsigmaKa", "TPC n sigma ka;p_{in} (GeV/c);n #sigma_{K}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + fRegistry.add("Track/hTPCNsigmaPr", "TPC n sigma pr;p_{in} (GeV/c);n #sigma_{p}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + fRegistry.add("Track/hTOFbeta", "TOF beta;p_{pv} (GeV/c);#beta", kTH2F, {{1000, 0, 10}, {240, 0, 1.2}}, false); + fRegistry.add("Track/hTOFNsigmaEl", "TOF n sigma el;p_{in} (GeV/c);n #sigma_{e}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + fRegistry.add("Track/hTOFNsigmaPi", "TOF n sigma pi;p_{in} (GeV/c);n #sigma_{#pi}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + fRegistry.add("Track/hTOFNsigmaKa", "TOF n sigma ka;p_{in} (GeV/c);n #sigma_{K}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + fRegistry.add("Track/hTOFNsigmaPr", "TOF n sigma pr;p_{in} (GeV/c);n #sigma_{p}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + fRegistry.add("Track/hMeanClusterSizeITS", "mean cluster size ITS;p_{pv} (GeV/c); #times cos(#lambda)", kTH2F, {{1000, 0, 10}, {150, 0, 15}}, false); + fRegistry.add("Track/hMeanClusterSizeITSib", "mean cluster size ITSib;p_{pv} (GeV/c); #times cos(#lambda)", kTH2F, {{1000, 0, 10}, {150, 0, 15}}, false); + fRegistry.add("Track/hMeanClusterSizeITSob", "mean cluster size ITSob;p_{pv} (GeV/c); #times cos(#lambda)", kTH2F, {{1000, 0, 10}, {150, 0, 15}}, false); + fRegistry.add("Pair/hMvsPhiV", "m_{ee} vs. #varphi_{V} ULS;#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", kTH2F, {{180, 0.f, M_PI}, {100, 0, 0.1}}); + } + + if (usePIDML) { + static constexpr int nClassesMl = 2; + const std::vector cutDirMl = {o2::cuts_ml::CutNot, o2::cuts_ml::CutSmaller}; + const std::vector labelsClasses = {"Background", "Signal"}; + const uint32_t nBinsMl = binsMl.value.size() - 1; + const std::vector labelsBins(nBinsMl, "bin"); + double cutsMlArr[nBinsMl][nClassesMl]; + for (uint32_t i = 0; i < nBinsMl; i++) { + cutsMlArr[i][0] = 0.0; + cutsMlArr[i][1] = cutsMl.value[i]; + } + o2::framework::LabeledArray cutsMl = {cutsMlArr[0], nBinsMl, nClassesMl, labelsBins, labelsClasses}; + + mlResponseSingleTrack.configure(binsMl.value, cutsMl, cutDirMl, nClassesMl); + if (loadModelsFromCCDB) { + ccdbApi.init(ccdburl); + mlResponseSingleTrack.setModelPathsCCDB(onnxFileNames.value, ccdbApi, onnxPathsCCDB.value, timestampCCDB.value); + } else { + mlResponseSingleTrack.setModelPathsLocal(onnxFileNames.value); + } + mlResponseSingleTrack.cacheInputFeaturesIndices(namesInputFeatures); + mlResponseSingleTrack.cacheBinningIndex(nameBinningFeature); + mlResponseSingleTrack.init(enableOptimizations.value); + } // end of PID ML + } + + void initCCDB(aod::BCsWithTimestamps::iterator const& bc) + { + if (mRunNumber == bc.runNumber()) { + return; + } + + // load matLUT for this timestamp + if (!lut) { + LOG(info) << "Loading material look-up table for timestamp: " << bc.timestamp(); + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->getForTimeStamp(lutPath, bc.timestamp())); + } else { + LOG(info) << "Material look-up table already in place. Not reloading."; + } + + // In case override, don't proceed, please - no CCDB access required + if (d_bz_input > -990) { + d_bz = d_bz_input; + o2::parameters::GRPMagField grpmag; + if (std::fabs(d_bz) > 1e-5) { + grpmag.setL3Current(30000.f / (d_bz / 5.0f)); + } + o2::base::Propagator::initFieldFromGRP(&grpmag); + o2::base::Propagator::Instance()->setMatLUT(lut); + mMeanVtx = ccdb->getForTimeStamp(mVtxPath, bc.timestamp()); + mRunNumber = bc.runNumber(); + return; + } + + auto run3grp_timestamp = bc.timestamp(); + o2::parameters::GRPObject* grpo = 0x0; + o2::parameters::GRPMagField* grpmag = 0x0; + if (!skipGRPOquery) { + grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); + } + if (grpo) { + o2::base::Propagator::initFieldFromGRP(grpo); + o2::base::Propagator::Instance()->setMatLUT(lut); + mMeanVtx = ccdb->getForTimeStamp(mVtxPath, bc.timestamp()); + // Fetch magnetic field from ccdb for current collision + d_bz = grpo->getNominalL3Field(); + LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; + } else { + grpmag = ccdb->getForTimeStamp(grpmagPath, run3grp_timestamp); + if (!grpmag) { + LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; + } + o2::base::Propagator::initFieldFromGRP(grpmag); + o2::base::Propagator::Instance()->setMatLUT(lut); + mMeanVtx = ccdb->getForTimeStamp(mVtxPath, bc.timestamp()); + + // Fetch magnetic field from ccdb for current collision + d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); + LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; + } + mRunNumber = bc.runNumber(); + } + + template + bool checkTrack(TCollision const& collision, TTrack const& track) + { + if constexpr (isMC) { + if (!track.has_mcParticle()) { + return false; + } + if (storeOnlyTrueElectronMC) { + const auto& mcParticle = track.template mcParticle_as(); + if (std::abs(mcParticle.pdgCode()) != 11) { + return false; + } + } + } + + if (!track.hasITS()) { + return false; + } + + if (trackcut.maxchi2its < track.itsChi2NCl()) { // accept ITS afterburner (itsChi2NCl = -999) + return false; + } + if (track.itsNCls() < trackcut.min_ncluster_its) { + return false; + } + if (track.itsNClsInnerBarrel() < trackcut.min_ncluster_itsib) { + return false; + } + + if (track.hasTPC()) { + if (track.tpcChi2NCl() < 0.f || trackcut.maxchi2tpc < track.tpcChi2NCl()) { + return false; + } + + if (track.tpcNClsFound() < trackcut.min_ncluster_tpc) { + return false; + } + + if (track.tpcNClsCrossedRows() < trackcut.mincrossedrows) { + return false; + } + + if (track.tpcCrossedRowsOverFindableCls() < trackcut.min_tpc_cr_findable_ratio) { + return false; + } + + if (track.tpcFractionSharedCls() > trackcut.max_frac_shared_clusters_tpc) { + return false; + } + } + + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto trackParCov = getTrackParCov(track); + trackParCov.setPID(o2::track::PID::Electron); + mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); + mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); + float dcaXY = mDcaInfoCov.getY(); + float dcaZ = mDcaInfoCov.getZ(); + + if (std::fabs(dcaXY) > trackcut.dca_xy_max || std::fabs(dcaZ) > trackcut.dca_z_max) { + return false; + } + + if (trackParCov.getPt() < trackcut.minpt || std::fabs(trackParCov.getEta()) > trackcut.maxeta) { + return false; + } + + return true; + } + + template + bool checkTrackTight(TCollision const& collision, TTrack const& track) + { + if constexpr (isMC) { + if (!track.has_mcParticle()) { + return false; + } + if (storeOnlyTrueElectronMC) { + const auto& mcParticle = track.template mcParticle_as(); + if (std::abs(mcParticle.pdgCode()) != 11) { + return false; + } + } + } + + if (!track.hasITS() || !track.hasTPC()) { + return false; + } + + if (track.itsChi2NCl() < 0.f || tighttrackcut.maxchi2its < track.itsChi2NCl()) { + return false; + } + if (track.itsNCls() < tighttrackcut.min_ncluster_its) { + return false; + } + if (track.itsNClsInnerBarrel() < tighttrackcut.min_ncluster_itsib) { + return false; + } + + if (track.tpcChi2NCl() < 0.f || tighttrackcut.maxchi2tpc < track.tpcChi2NCl()) { + return false; + } + + if (track.tpcNClsFound() < tighttrackcut.min_ncluster_tpc) { + return false; + } + + if (track.tpcNClsCrossedRows() < tighttrackcut.mincrossedrows) { + return false; + } + + if (track.tpcCrossedRowsOverFindableCls() < tighttrackcut.min_tpc_cr_findable_ratio) { + return false; + } + + if (track.tpcFractionSharedCls() > tighttrackcut.max_frac_shared_clusters_tpc) { + return false; + } + + if (track.tpcNClsPID() < tighttrackcut.min_ncluster_tpc_pid) { + return false; + } + + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto trackParCov = getTrackParCov(track); + trackParCov.setPID(o2::track::PID::Electron); + mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); + mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); + float dcaXY = mDcaInfoCov.getY(); + float dcaZ = mDcaInfoCov.getZ(); + + if (std::fabs(dcaXY) > tighttrackcut.dca_xy_max || std::fabs(dcaZ) > tighttrackcut.dca_z_max) { + return false; + } + + if (trackParCov.getPt() < trackcut.minpt || std::fabs(trackParCov.getEta()) > trackcut.maxeta) { + return false; + } + + return true; + } + + template + bool isElectron(TTrack const& track) + { + if (track.hasTPC()) { + if (trackcut.minTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < trackcut.maxTPCNsigmaEl) { + return true; + } else { + return false; + } + } else { // accept ITSsa too + return true; + } + } + + template + bool isElectronTight(TTrack const& track) + { + bool is_El_TPC = tighttrackcut.minTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < tighttrackcut.maxTPCNsigmaEl; + bool is_El_TOF = tighttrackcut.minTOFNsigmaEl < track.tofNSigmaEl() && track.tofNSigmaEl() < tighttrackcut.maxTOFNsigmaEl; + return is_El_TPC && is_El_TOF; + } + + template + void fillTrackTable(TCollision const& collision, TTrack const& track) + { + if (std::find(stored_trackIds.begin(), stored_trackIds.end(), std::pair{collision.globalIndex(), track.globalIndex()}) == stored_trackIds.end()) { + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto trackParCov = getTrackParCov(track); + trackParCov.setPID(o2::track::PID::Electron); + mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); + mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); + float dcaXY = mDcaInfoCov.getY(); + float dcaZ = mDcaInfoCov.getZ(); + + float pt_recalc = trackParCov.getPt(); + float eta_recalc = trackParCov.getEta(); + float phi_recalc = trackParCov.getPhi(); + o2::math_utils::bringTo02Pi(phi_recalc); + + bool isAssociatedToMPC = collision.globalIndex() == track.collisionId(); + float mcTunedTPCSignal = 0.f; + if constexpr (isMC) { + mcTunedTPCSignal = track.mcTunedTPCSignal(); + } + + float probaEl = 1.0; + if (usePIDML) { + std::vector inputFeatures = mlResponseSingleTrack.getInputFeatures(track, trackParCov, collision); + float binningFeature = mlResponseSingleTrack.getBinningFeature(track, trackParCov, collision); + probaEl = mlResponseSingleTrack.isSelectedMl(inputFeatures, binningFeature); + } + + emprimaryelectrons(collision.globalIndex(), track.globalIndex(), track.sign(), + pt_recalc, eta_recalc, phi_recalc, + dcaXY, dcaZ, trackParCov.getSigmaY2(), trackParCov.getSigmaZY(), trackParCov.getSigmaZ2(), + track.tpcNClsFindable(), track.tpcNClsFindableMinusFound(), track.tpcNClsFindableMinusCrossedRows(), track.tpcNClsShared(), + track.tpcChi2NCl(), track.tpcInnerParam(), + track.tpcSignal(), track.tpcNSigmaEl(), track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), + track.beta(), track.tofNSigmaEl(), /*track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr(),*/ + track.itsClusterSizes(), + track.itsChi2NCl(), track.tofChi2(), track.detectorMap(), + // trackParCov.getTgl(), + isAssociatedToMPC, false, probaEl, mcTunedTPCSignal); + + emprimaryelectronscov( + trackParCov.getX(), + trackParCov.getAlpha(), + trackParCov.getY(), + trackParCov.getZ(), + trackParCov.getSnp(), + // trackParCov.getTgl(), + // trackParCov.getSigmaY2(), + // trackParCov.getSigmaZY(), + // trackParCov.getSigmaZ2(), + trackParCov.getSigmaSnpY(), + trackParCov.getSigmaSnpZ(), + trackParCov.getSigmaSnp2(), + trackParCov.getSigmaTglY(), + trackParCov.getSigmaTglZ(), + trackParCov.getSigmaTglSnp(), + trackParCov.getSigmaTgl2(), + trackParCov.getSigma1PtY(), + trackParCov.getSigma1PtZ(), + trackParCov.getSigma1PtSnp(), + trackParCov.getSigma1PtTgl(), + trackParCov.getSigma1Pt2()); + + stored_trackIds.emplace_back(std::pair{collision.globalIndex(), track.globalIndex()}); + + if (fillQAHistogram) { + int total_cluster_size = 0, nl = 0; + for (unsigned int layer = 0; layer < 7; layer++) { + int cluster_size_per_layer = track.itsClsSizeInLayer(layer); + if (cluster_size_per_layer > 0) { + nl++; + } + total_cluster_size += cluster_size_per_layer; + } + + int total_cluster_size_ib = 0, nl_ib = 0; + for (unsigned int layer = 0; layer < 3; layer++) { + int cluster_size_per_layer = track.itsClsSizeInLayer(layer); + if (cluster_size_per_layer > 0) { + nl_ib++; + } + total_cluster_size_ib += cluster_size_per_layer; + } + + int total_cluster_size_ob = 0, nl_ob = 0; + for (unsigned int layer = 3; layer < 7; layer++) { + int cluster_size_per_layer = track.itsClsSizeInLayer(layer); + if (cluster_size_per_layer > 0) { + nl_ob++; + } + total_cluster_size_ob += cluster_size_per_layer; + } + + fRegistry.fill(HIST("Track/hPt"), pt_recalc); + fRegistry.fill(HIST("Track/hQoverPt"), track.sign() / pt_recalc); + fRegistry.fill(HIST("Track/hEtaPhi"), phi_recalc, eta_recalc); + fRegistry.fill(HIST("Track/hDCAxyz"), dcaXY, dcaZ); + fRegistry.fill(HIST("Track/hDCAxyzSigma"), dcaXY / std::sqrt(trackParCov.getSigmaY2()), dcaZ / std::sqrt(trackParCov.getSigmaZ2())); + fRegistry.fill(HIST("Track/hDCAxyRes_Pt"), pt_recalc, std::sqrt(trackParCov.getSigmaY2()) * 1e+4); // convert cm to um + fRegistry.fill(HIST("Track/hDCAzRes_Pt"), pt_recalc, std::sqrt(trackParCov.getSigmaZ2()) * 1e+4); // convert cm to um + fRegistry.fill(HIST("Track/hNclsITS"), track.itsNCls()); + fRegistry.fill(HIST("Track/hNclsTPC"), track.tpcNClsFound()); + fRegistry.fill(HIST("Track/hNcrTPC"), track.tpcNClsCrossedRows()); + fRegistry.fill(HIST("Track/hTPCNcr2Nf"), track.tpcCrossedRowsOverFindableCls()); + fRegistry.fill(HIST("Track/hTPCNcls2Nf"), track.tpcFoundOverFindableCls()); + fRegistry.fill(HIST("Track/hTPCNclsShared"), track.pt(), track.tpcFractionSharedCls()); + fRegistry.fill(HIST("Track/hChi2TPC"), track.tpcChi2NCl()); + fRegistry.fill(HIST("Track/hChi2ITS"), track.itsChi2NCl()); + fRegistry.fill(HIST("Track/hChi2TOF"), track.tofChi2()); + fRegistry.fill(HIST("Track/hITSClusterMap"), track.itsClusterMap()); + fRegistry.fill(HIST("Track/hTPCdEdx"), track.tpcInnerParam(), track.tpcSignal()); + fRegistry.fill(HIST("Track/hTPCdEdxMC"), track.tpcInnerParam(), mcTunedTPCSignal); + fRegistry.fill(HIST("Track/hTPCNsigmaEl"), track.tpcInnerParam(), track.tpcNSigmaEl()); + fRegistry.fill(HIST("Track/hTPCNsigmaPi"), track.tpcInnerParam(), track.tpcNSigmaPi()); + fRegistry.fill(HIST("Track/hTPCNsigmaKa"), track.tpcInnerParam(), track.tpcNSigmaKa()); + fRegistry.fill(HIST("Track/hTPCNsigmaPr"), track.tpcInnerParam(), track.tpcNSigmaPr()); + fRegistry.fill(HIST("Track/hTOFbeta"), trackParCov.getP(), track.beta()); + fRegistry.fill(HIST("Track/hTOFNsigmaEl"), track.tpcInnerParam(), track.tofNSigmaEl()); + fRegistry.fill(HIST("Track/hTOFNsigmaPi"), track.tpcInnerParam(), track.tofNSigmaPi()); + fRegistry.fill(HIST("Track/hTOFNsigmaKa"), track.tpcInnerParam(), track.tofNSigmaKa()); + fRegistry.fill(HIST("Track/hTOFNsigmaPr"), track.tpcInnerParam(), track.tofNSigmaPr()); + fRegistry.fill(HIST("Track/hMeanClusterSizeITS"), trackParCov.getP(), static_cast(total_cluster_size) / static_cast(nl) * std::cos(std::atan(trackParCov.getTgl()))); + fRegistry.fill(HIST("Track/hMeanClusterSizeITSib"), trackParCov.getP(), static_cast(total_cluster_size_ib) / static_cast(nl_ib) * std::cos(std::atan(trackParCov.getTgl()))); + fRegistry.fill(HIST("Track/hMeanClusterSizeITSob"), trackParCov.getP(), static_cast(total_cluster_size_ob) / static_cast(nl_ob) * std::cos(std::atan(trackParCov.getTgl()))); + } + } + } + + template + bool isDielectronFromPi0(TCollision const& collision, TTrack const& t1, TTrack const& t2) + { + mDcaInfoCov.set(999, 999, 999, 999, 999); + std::array pVec1 = {0, 0, 0}; // px, py, pz + std::array pVec2 = {0, 0, 0}; // px, py, pz + mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); + mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + + auto t1ParCov = getTrackParCov(t1); + t1ParCov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, t1ParCov, 2.f, matCorr, &mDcaInfoCov); + getPxPyPz(t1ParCov, pVec1); + + auto t2ParCov = getTrackParCov(t2); + t2ParCov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, t2ParCov, 2.f, matCorr, &mDcaInfoCov); + getPxPyPz(t2ParCov, pVec2); + + ROOT::Math::PtEtaPhiMVector v1(t1ParCov.getPt(), t1ParCov.getEta(), t1ParCov.getPhi(), o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v2(t2ParCov.getPt(), t2ParCov.getEta(), t2ParCov.getPhi(), o2::constants::physics::MassElectron); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + float mee = v12.M(); + float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(pVec1[0], pVec1[1], pVec1[2], pVec2[0], pVec2[1], pVec2[2], t1.sign(), t2.sign(), d_bz); + + if (fillQAHistogram) { + fRegistry.fill(HIST("Pair/hMvsPhiV"), phiv, mee); + } + if (mee < maxMee && phiv < maxPhiV) { + return true; + } else { + return false; + } + } + + std::vector> stored_trackIds; + Filter trackFilter = trackcut.minpt < o2::aod::track::pt && nabs(o2::aod::track::eta) < trackcut.maxeta && o2::aod::track::itsChi2NCl < trackcut.maxchi2its && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true; + Filter pidFilter = trackcut.minTPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < trackcut.maxTPCNsigmaEl; + using MyFilteredTracks = soa::Filtered; + + Partition posTracks = o2::aod::track::signed1Pt > 0.f; + Partition negTracks = o2::aod::track::signed1Pt < 0.f; + + // ---------- for data ---------- + + void processRec(MyCollisions const& collisions, aod::BCsWithTimestamps const&, MyFilteredTracks const& tracks) + { + stored_trackIds.reserve(tracks.size()); + + for (const auto& collision : collisions) { + auto bc = collision.template foundBC_as(); + initCCDB(bc); + + if (!collision.isSelected()) { + continue; + } + + const auto& posTracks_per_coll = posTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); + const auto& negTracks_per_coll = negTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); + + for (const auto& [pos, ele] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { + if ((checkTrackTight(collision, pos) && isElectronTight(pos)) && (checkTrack(collision, ele) && isElectron(ele))) { + if (isDielectronFromPi0(collision, pos, ele)) { + fillTrackTable(collision, ele); + } + } + if ((checkTrackTight(collision, ele) && isElectronTight(ele)) && (checkTrack(collision, pos) && isElectron(pos))) { + if (isDielectronFromPi0(collision, pos, ele)) { + fillTrackTable(collision, pos); + } + } + + // if (isDielectronFromPi0(collision, pos, ele)) { + // if ((checkTrackTight(collision, pos) && isElectronTight(pos)) && (checkTrack(collision, ele) && isElectron(ele)) ) { + // fillTrackTable(collision, ele); + // } + // if ((checkTrackTight(collision, ele) && isElectronTight(ele)) && (checkTrack(collision, pos) && isElectron(pos)) ) { + // fillTrackTable(collision, pos); + // } + // } + + } // end of ULS pairing + } // end of collision loop + + stored_trackIds.clear(); + stored_trackIds.shrink_to_fit(); + } + PROCESS_SWITCH(skimmerPrimaryElectronQC, processRec, "process reconstructed info only", true); // standalone + + void processRec_SWT(MyCollisionsWithSWT const& collisions, aod::BCsWithTimestamps const&, MyFilteredTracks const& tracks) + { + stored_trackIds.reserve(tracks.size()); + + for (const auto& collision : collisions) { + auto bc = collision.template foundBC_as(); + initCCDB(bc); + + if (!collision.isSelected()) { + continue; + } + + if (collision.swtaliastmp_raw() == 0) { + continue; + } + + const auto& posTracks_per_coll = posTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); + const auto& negTracks_per_coll = negTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); + + for (const auto& [pos, ele] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { + if ((checkTrackTight(collision, pos) && isElectronTight(pos)) && (checkTrack(collision, ele) && isElectron(ele))) { + if (isDielectronFromPi0(collision, pos, ele)) { + fillTrackTable(collision, ele); + } + } + if ((checkTrackTight(collision, ele) && isElectronTight(ele)) && (checkTrack(collision, pos) && isElectron(pos))) { + if (isDielectronFromPi0(collision, pos, ele)) { + fillTrackTable(collision, pos); + } + } + + // if (isDielectronFromPi0(collision, pos, ele)) { + // if ((checkTrackTight(collision, pos) && isElectronTight(pos)) && (checkTrack(collision, ele) && isElectron(ele)) ) { + // fillTrackTable(collision, ele); + // } + // if ((checkTrackTight(collision, ele) && isElectronTight(ele)) && (checkTrack(collision, pos) && isElectron(pos)) ) { + // fillTrackTable(collision, pos); + // } + // } + + } // end of ULS pairing + + } // end of collision loop + + stored_trackIds.clear(); + stored_trackIds.shrink_to_fit(); + } + PROCESS_SWITCH(skimmerPrimaryElectronQC, processRec_SWT, "process reconstructed info only", false); // standalone with swt + + // ---------- for MC ---------- + using MyFilteredTracksMC = soa::Filtered; + Partition posTracksMC = o2::aod::track::signed1Pt > 0.f; + Partition negTracksMC = o2::aod::track::signed1Pt < 0.f; + void processMC(soa::Join const& collisions, aod::McCollisions const&, aod::BCsWithTimestamps const&, MyFilteredTracksMC const& tracks, aod::McParticles const&) + { + stored_trackIds.reserve(tracks.size()); + + for (const auto& collision : collisions) { + if (!collision.has_mcCollision()) { + continue; + } + auto bc = collision.template foundBC_as(); + initCCDB(bc); + + if (!collision.isSelected()) { + continue; + } + const auto& posTracks_per_coll = posTracksMC->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); + const auto& negTracks_per_coll = negTracksMC->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); + + for (const auto& [pos, ele] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { + if ((checkTrackTight(collision, pos) && isElectronTight(pos)) && (checkTrack(collision, ele) && isElectron(ele))) { + if (isDielectronFromPi0(collision, pos, ele)) { + fillTrackTable(collision, ele); + } + } + if ((checkTrackTight(collision, ele) && isElectronTight(ele)) && (checkTrack(collision, pos) && isElectron(pos))) { + if (isDielectronFromPi0(collision, pos, ele)) { + fillTrackTable(collision, pos); + } + } + + // if (isDielectronFromPi0(collision, pos, ele)) { + // if ((checkTrackTight(collision, pos) && isElectronTight(pos)) && (checkTrack(collision, ele) && isElectron(ele)) ) { + // fillTrackTable(collision, ele); + // } + // if ((checkTrackTight(collision, ele) && isElectronTight(ele)) && (checkTrack(collision, pos) && isElectron(pos)) ) { + // fillTrackTable(collision, pos); + // } + // } + + } // end of ULS pairing + + } // end of collision loop + + stored_trackIds.clear(); + stored_trackIds.shrink_to_fit(); + } + PROCESS_SWITCH(skimmerPrimaryElectronQC, processMC, "process reconstructed and MC info ", false); +}; + +struct prefilterPrimaryElectron { + Produces ele_pfb; + + void init(InitContext&) {} + + void process(aod::EMPrimaryElectrons const& primaryelectrons) + { + for (int i = 0; i < primaryelectrons.size(); i++) { + ele_pfb(0); + } + } +}; + +struct associateAmbiguousElectron { + Produces em_amb_ele_ids; + + SliceCache cache; + PresliceUnsorted perTrack = o2::aod::emprimaryelectron::trackId; + std::vector ambele_self_Ids; + + void process(aod::EMPrimaryElectrons const& electrons) + { + for (const auto& electron : electrons) { + auto electrons_with_same_trackId = electrons.sliceBy(perTrack, electron.trackId()); + ambele_self_Ids.reserve(electrons_with_same_trackId.size()); + for (const auto& amb_ele : electrons_with_same_trackId) { + if (amb_ele.globalIndex() == electron.globalIndex()) { // don't store myself. + continue; + } + ambele_self_Ids.emplace_back(amb_ele.globalIndex()); + } + em_amb_ele_ids(ambele_self_Ids); + ambele_self_Ids.clear(); + ambele_self_Ids.shrink_to_fit(); + } + } +}; +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc, TaskName{"skimmer-primary-electron-qc"}), + adaptAnalysisTask(cfgc, TaskName{"prefilter-primary-electron"}), + adaptAnalysisTask(cfgc, TaskName{"associate-ambiguous-electron"})}; +} diff --git a/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuon.cxx b/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuon.cxx index aaeddaadb27..1f9456e9c96 100644 --- a/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuon.cxx +++ b/PWGEM/Dilepton/TableProducer/skimmerPrimaryMuon.cxx @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -116,7 +117,7 @@ struct skimmerPrimaryMuon { } mRunNumber = bc.runNumber(); - std::map metadata; + std::map metadata; auto soreor = o2::ccdb::BasicCCDBManager::getRunDuration(ccdbApi, mRunNumber); auto ts = soreor.first; auto grpmag = ccdbApi.retrieveFromTFileAny(grpmagPath, metadata, ts); @@ -399,14 +400,46 @@ struct skimmerPrimaryMuon { } } - SliceCache cache; + // std::map, float> mCandidates; // std::pair -> chi2MatchMCHMFT; + std::vector> vec_min_chi2MatchMCHMFT; // std::pair -> chi2MatchMCHMFT; + template + void findBestMatchPerMCHMID(TMuons const& muons) + { + vec_min_chi2MatchMCHMFT.reserve(muons.size()); + for (const auto& muon : muons) { + if (muon.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { + const auto& muons_per_MCHMID = muons.sliceBy(fwdtracksPerMCHTrack, muon.globalIndex()); + // LOGF(info, "stanadalone: muon.globalIndex() = %d, muon.chi2MatchMCHMFT() = %f", muon.globalIndex(), muon.chi2MatchMCHMFT()); + // LOGF(info, "muons_per_MCHMID.size() = %d", muons_per_MCHMID.size()); + + float min_chi2MatchMCHMFT = 1e+10; + std::tuple tupleIds_at_min; + for (const auto& muon_tmp : muons_per_MCHMID) { + if (muon_tmp.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack) { + // LOGF(info, "muon_tmp.globalIndex() = %d, muon_tmp.matchMCHTrackId() = %d, muon_tmp.matchMFTTrackId() = %d, muon_tmp.chi2MatchMCHMFT() = %f", muon_tmp.globalIndex(), muon_tmp.matchMCHTrackId(), muon_tmp.matchMFTTrackId(), muon_tmp.chi2MatchMCHMFT()); + if (0.f < muon_tmp.chi2MatchMCHMFT() && muon_tmp.chi2MatchMCHMFT() < min_chi2MatchMCHMFT) { + min_chi2MatchMCHMFT = muon_tmp.chi2MatchMCHMFT(); + tupleIds_at_min = std::make_tuple(muon_tmp.globalIndex(), muon_tmp.matchMCHTrackId(), muon_tmp.matchMFTTrackId()); + } + } + } + vec_min_chi2MatchMCHMFT.emplace_back(tupleIds_at_min); + // mCandidates[tupleIds_at_min] = min_chi2MatchMCHMFT; + // LOGF(info, "min: muon_tmp.globalIndex() = %d, muon_tmp.matchMCHTrackId() = %d, muon_tmp.matchMFTTrackId() = %d, muon_tmp.chi2MatchMCHMFT() = %f", std::get<0>(tupleIds_at_min), std::get<1>(tupleIds_at_min), std::get<2>(tupleIds_at_min), min_chi2MatchMCHMFT); + } + } // end of muon loop + } + SliceCache cache; Preslice perCollision = o2::aod::fwdtrack::collisionId; Preslice fwdtrackIndicesPerCollision = aod::track_association::collisionId; PresliceUnsorted fwdtrackIndicesPerFwdTrack = aod::track_association::fwdtrackId; + PresliceUnsorted fwdtracksPerMCHTrack = aod::fwdtrack::matchMCHTrackId; void processRec_SA(MyCollisions const& collisions, MyFwdTracks const& fwdtracks, aod::MFTTracks const&, aod::BCsWithTimestamps const&) { + findBestMatchPerMCHMID(fwdtracks); + for (const auto& collision : collisions) { const auto& bc = collision.template bc_as(); initCCDB(bc); @@ -420,14 +453,24 @@ struct skimmerPrimaryMuon { if (fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { continue; } + + if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { + continue; + } + fillFwdTrackTable(collision, fwdtrack, false); } // end of fwdtrack loop } // end of collision loop + + vec_min_chi2MatchMCHMFT.clear(); + vec_min_chi2MatchMCHMFT.shrink_to_fit(); } PROCESS_SWITCH(skimmerPrimaryMuon, processRec_SA, "process reconstructed info", false); void processRec_TTCA(MyCollisions const& collisions, MyFwdTracks const& fwdtracks, aod::MFTTracks const&, aod::BCsWithTimestamps const&, aod::FwdTrackAssoc const& fwdtrackIndices) { + findBestMatchPerMCHMID(fwdtracks); + std::unordered_map mapAmb; // fwdtrack.globalIndex() -> bool isAmb; for (const auto& fwdtrack : fwdtracks) { const auto& fwdtrackIdsPerFwdTrack = fwdtrackIndices.sliceBy(fwdtrackIndicesPerFwdTrack, fwdtrack.globalIndex()); @@ -449,15 +492,23 @@ struct skimmerPrimaryMuon { if (fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { continue; } + if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { + continue; + } + fillFwdTrackTable(collision, fwdtrack, mapAmb[fwdtrack.globalIndex()]); } // end of fwdtrack loop } // end of collision loop mapAmb.clear(); + vec_min_chi2MatchMCHMFT.clear(); + vec_min_chi2MatchMCHMFT.shrink_to_fit(); } PROCESS_SWITCH(skimmerPrimaryMuon, processRec_TTCA, "process reconstructed info", false); void processRec_SA_SWT(MyCollisionsWithSWT const& collisions, MyFwdTracks const& fwdtracks, aod::MFTTracks const&, aod::BCsWithTimestamps const&) { + findBestMatchPerMCHMID(fwdtracks); + for (const auto& collision : collisions) { const auto& bc = collision.template bc_as(); initCCDB(bc); @@ -475,14 +526,22 @@ struct skimmerPrimaryMuon { if (fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { continue; } + if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { + continue; + } + fillFwdTrackTable(collision, fwdtrack, false); } // end of fwdtrack loop } // end of collision loop + vec_min_chi2MatchMCHMFT.clear(); + vec_min_chi2MatchMCHMFT.shrink_to_fit(); } PROCESS_SWITCH(skimmerPrimaryMuon, processRec_SA_SWT, "process reconstructed info only with standalone", false); void processRec_TTCA_SWT(MyCollisionsWithSWT const& collisions, MyFwdTracks const& fwdtracks, aod::MFTTracks const&, aod::BCsWithTimestamps const&, aod::FwdTrackAssoc const& fwdtrackIndices) { + findBestMatchPerMCHMID(fwdtracks); + std::unordered_map mapAmb; // fwdtrack.globalIndex() -> bool isAmb; for (const auto& fwdtrack : fwdtracks) { const auto& fwdtrackIdsPerFwdTrack = fwdtrackIndices.sliceBy(fwdtrackIndicesPerFwdTrack, fwdtrack.globalIndex()); @@ -506,15 +565,23 @@ struct skimmerPrimaryMuon { if (fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { continue; } + if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { + continue; + } + fillFwdTrackTable(collision, fwdtrack, mapAmb[fwdtrack.globalIndex()]); } // end of fwdtrack loop } // end of collision loop mapAmb.clear(); + vec_min_chi2MatchMCHMFT.clear(); + vec_min_chi2MatchMCHMFT.shrink_to_fit(); } PROCESS_SWITCH(skimmerPrimaryMuon, processRec_TTCA_SWT, "process reconstructed info", false); void processMC_SA(soa::Join const& collisions, MyFwdTracksMC const& fwdtracks, MFTTracksMC const&, aod::BCsWithTimestamps const&) { + findBestMatchPerMCHMID(fwdtracks); + for (const auto& collision : collisions) { const auto& bc = collision.template bc_as(); initCCDB(bc); @@ -533,14 +600,22 @@ struct skimmerPrimaryMuon { if (fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { continue; } + if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { + continue; + } + fillFwdTrackTable(collision, fwdtrack, false); } // end of fwdtrack loop } // end of collision loop + vec_min_chi2MatchMCHMFT.clear(); + vec_min_chi2MatchMCHMFT.shrink_to_fit(); } PROCESS_SWITCH(skimmerPrimaryMuon, processMC_SA, "process reconstructed and MC info", false); void processMC_TTCA(soa::Join const& collisions, MyFwdTracksMC const& fwdtracks, MFTTracksMC const&, aod::BCsWithTimestamps const&, aod::FwdTrackAssoc const& fwdtrackIndices) { + findBestMatchPerMCHMID(fwdtracks); + std::unordered_map mapAmb; // fwdtrack.globalIndex() -> bool isAmb; for (const auto& fwdtrack : fwdtracks) { const auto& fwdtrackIdsPerFwdTrack = fwdtrackIndices.sliceBy(fwdtrackIndicesPerFwdTrack, fwdtrack.globalIndex()); @@ -567,10 +642,16 @@ struct skimmerPrimaryMuon { if (fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && fwdtrack.trackType() != o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack) { continue; } + if (fwdtrack.trackType() == o2::aod::fwdtrack::ForwardTrackTypeEnum::GlobalMuonTrack && std::find(vec_min_chi2MatchMCHMFT.begin(), vec_min_chi2MatchMCHMFT.end(), std::make_tuple(fwdtrack.globalIndex(), fwdtrack.matchMCHTrackId(), fwdtrack.matchMFTTrackId())) == vec_min_chi2MatchMCHMFT.end()) { + continue; + } + fillFwdTrackTable(collision, fwdtrack, mapAmb[fwdtrack.globalIndex()]); } // end of fwdtrack loop } // end of collision loop mapAmb.clear(); + vec_min_chi2MatchMCHMFT.clear(); + vec_min_chi2MatchMCHMFT.shrink_to_fit(); } PROCESS_SWITCH(skimmerPrimaryMuon, processMC_TTCA, "process reconstructed and MC info", false); diff --git a/PWGEM/Dilepton/TableProducer/skimmerPrimaryTrack.cxx b/PWGEM/Dilepton/TableProducer/skimmerPrimaryTrack.cxx index 7e05accb739..094065b6256 100644 --- a/PWGEM/Dilepton/TableProducer/skimmerPrimaryTrack.cxx +++ b/PWGEM/Dilepton/TableProducer/skimmerPrimaryTrack.cxx @@ -73,15 +73,15 @@ struct skimmerPrimaryTrack { Configurable d_bz_input{"d_bz_input", -999, "bz field in kG, -999 is automatic"}; Configurable minpt{"minpt", 0.2, "min pt for ITS-TPC track"}; - Configurable maxpt{"maxpt", 3.0, "max pt for ITS-TPC track"}; - Configurable maxeta{"maxeta", 1.4, "eta acceptance"}; - Configurable dca_xy_max{"dca_xy_max", 0.5, "max DCAxy in cm"}; - Configurable dca_z_max{"dca_z_max", 0.5, "max DCAz in cm"}; + Configurable maxpt{"maxpt", 5.0, "max pt for ITS-TPC track"}; + Configurable maxeta{"maxeta", 0.8, "eta acceptance"}; + Configurable dca_xy_max{"dca_xy_max", 1.0, "max DCAxy in cm"}; + Configurable dca_z_max{"dca_z_max", 1.0, "max DCAz in cm"}; + Configurable max_frac_shared_clusters_tpc{"max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; // Configurable min_ncluster_tpc{"min_ncluster_tpc", 0, "min ncluster tpc"}; // Configurable mincrossedrows{"mincrossedrows", 70, "min. crossed rows"}; // Configurable min_tpc_cr_findable_ratio{"min_tpc_cr_findable_ratio", 0.8, "min. TPC Ncr/Nf ratio"}; - // Configurable max_frac_shared_clusters_tpc{"max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; // Configurable min_ncluster_its{"min_ncluster_its", 4, "min ncluster its"}; // Configurable min_ncluster_itsib{"min_ncluster_itsib", 1, "min ncluster itsib"}; // Configurable maxchi2tpc{"maxchi2tpc", 5.0, "max. chi2/NclsTPC"}; @@ -225,9 +225,9 @@ struct skimmerPrimaryTrack { return false; } - // if (track.tpcFractionSharedCls() > max_frac_shared_clusters_tpc) { - // return false; - // } + if (track.tpcFractionSharedCls() > max_frac_shared_clusters_tpc) { + return false; + } o2::dataformats::DCA mDcaInfoCov; mDcaInfoCov.set(999, 999, 999, 999, 999); @@ -242,6 +242,9 @@ struct skimmerPrimaryTrack { if (std::fabs(dcaXY) > dca_xy_max || std::fabs(dcaZ) > dca_z_max) { return false; } + if (std::fabs(dcaZ) > 3.f) { + return false; + } if (std::fabs(trackParCov.getEta()) > maxeta || trackParCov.getPt() < minpt || maxpt < trackParCov.getPt()) { return false; @@ -304,17 +307,31 @@ struct skimmerPrimaryTrack { if (track.tpcNClsFound() >= 90) { trackBit |= static_cast(RefTrackBit::kNclsTPC90); } - if (track.tpcChi2NCl() < 4) { + if (track.tpcChi2NCl() < 4.f) { trackBit |= static_cast(RefTrackBit::kChi2TPC4); } - if (track.tpcChi2NCl() < 3) { + if (track.tpcChi2NCl() < 3.f) { trackBit |= static_cast(RefTrackBit::kChi2TPC3); } if (track.tpcFractionSharedCls() < 0.7) { trackBit |= static_cast(RefTrackBit::kFracSharedTPC07); } - emprimarytracks(collision.globalIndex(), track.globalIndex(), /*track.sign(),*/ static_cast(pt * 1e+4), eta, phi, dcaXY, dcaZ, trackBit); + if (std::fabs(dcaZ) < 0.5) { + trackBit |= static_cast(RefTrackBit::kDCAz05cm); + } + if (std::fabs(dcaZ) < 0.3) { + trackBit |= static_cast(RefTrackBit::kDCAz03cm); + } + + if (std::fabs(dcaXY) < 0.5) { + trackBit |= static_cast(RefTrackBit::kDCAxy05cm); + } + if (std::fabs(dcaXY) < 0.3) { + trackBit |= static_cast(RefTrackBit::kDCAxy03cm); + } + + emprimarytracks(collision.globalIndex(), track.globalIndex(), track.sign() / pt, eta, phi, trackBit); // prmtrackeventidtmp(collision.globalIndex()); stored_trackIds.emplace_back(std::pair{collision.globalIndex(), track.globalIndex()}); diff --git a/PWGEM/Dilepton/TableProducer/skimmerSecondaryElectron.cxx b/PWGEM/Dilepton/TableProducer/skimmerSecondaryElectron.cxx deleted file mode 100644 index 15b99dc7349..00000000000 --- a/PWGEM/Dilepton/TableProducer/skimmerSecondaryElectron.cxx +++ /dev/null @@ -1,631 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \brief write relevant information about primary electrons. -/// \author daiki.sekihata@cern.ch - -#include "PWGEM/Dilepton/DataModel/dileptonTables.h" -#include "PWGEM/Dilepton/Utils/PairUtilities.h" - -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/CollisionAssociationTables.h" - -#include "CCDB/BasicCCDBManager.h" -#include "CommonConstants/PhysicsConstants.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DetectorsBase/GeometryManager.h" -#include "DetectorsBase/Propagator.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" - -#include "Math/Vector4D.h" - -#include -#include -#include -#include -#include -#include - -using namespace o2; -using namespace o2::soa; -using namespace o2::framework; -using namespace o2::framework::expressions; -using namespace o2::constants::physics; - -using MyCollisions = soa::Join; -using MyCollisionsMC = soa::Join; - -using MyTracks = soa::Join; -using MyTrack = MyTracks::iterator; -using MyTracksMC = soa::Join; -using MyTrackMC = MyTracksMC::iterator; - -struct skimmerSecondaryElectron { - // enum class EM_EEPairType : int { - // kULS = 0, - // kLSpp = +1, - // kLSmm = -1, - // }; - - SliceCache cache; - Preslice perCol = o2::aod::track::collisionId; - Produces emprimaryelectrons; - Produces emprimaryelectronscov; - Produces event; - Produces event_mult; - Produces event_cent; - - // Configurables - Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; - Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable skipGRPOquery{"skipGRPOquery", true, "skip grpo query"}; - - // Operation and minimisation criteria - Configurable fillQAHistogram{"fillQAHistogram", false, "flag to fill QA histograms"}; - Configurable d_bz_input{"d_bz_input", -999, "bz field in kG, -999 is automatic"}; - Configurable min_ncluster_tpc{"min_ncluster_tpc", 10, "min ncluster tpc"}; - Configurable mincrossedrows{"mincrossedrows", 70, "min. crossed rows"}; - Configurable min_tpc_cr_findable_ratio{"min_tpc_cr_findable_ratio", 0.8, "min. TPC Ncr/Nf ratio"}; - Configurable minitsncls{"minitsncls", 4, "min. number of ITS clusters"}; - Configurable maxchi2tpc{"maxchi2tpc", 5.0, "max. chi2/NclsTPC"}; - Configurable maxchi2its{"maxchi2its", 6.0, "max. chi2/NclsITS"}; - Configurable minpt{"minpt", 0.15, "min pt for track"}; - Configurable maxeta{"maxeta", 0.9, "eta acceptance"}; - Configurable dca_xy_max{"dca_xy_max", 1.0f, "max DCAxy in cm"}; - Configurable dca_z_max{"dca_z_max", 1.0f, "max DCAz in cm"}; - Configurable dca_3d_sigma_max{"dca_3d_sigma_max", 1e+10, "max DCA 3D in sigma"}; - Configurable minTPCNsigmaEl{"minTPCNsigmaEl", -3.0, "min. TPC n sigma for electron inclusion"}; - Configurable maxTPCNsigmaEl{"maxTPCNsigmaEl", +4.0, "max. TPC n sigma for electron inclusion"}; - Configurable slope{"slope", 0.0185, "slope for m vs. phiv"}; - Configurable intercept{"intercept", -0.0280, "intercept for m vs. phiv"}; - Configurable mee_min{"mee_min", 0.0f, "minimum mee to distinguish photon conversion and dalitz decay"}; - - HistogramRegistry fRegistry{"output", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; - - std::pair> itsRequirement = {1, {0, 1, 2}}; // any hits on 3 ITS ib layers. - - int mRunNumber; - float d_bz; - Service ccdb; - o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; - - void init(InitContext&) - { - mRunNumber = 0; - d_bz = 0; - - ccdb->setURL(ccdburl); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - ccdb->setFatalWhenNull(false); - - if (fillQAHistogram) { - fRegistry.add("Track/hPt", "pT;p_{T} (GeV/c)", kTH1F, {{1000, 0.0f, 10}}, false); - fRegistry.add("Track/hQoverPt", "q/pT;q/p_{T} (GeV/c)^{-1}", kTH1F, {{400, -20, 20}}, false); - fRegistry.add("Track/hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2F, {{180, 0, 2 * M_PI}, {20, -1.0f, 1.0f}}, false); - fRegistry.add("Track/hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm)", kTH2F, {{200, -1.0f, 1.0f}, {200, -1.0f, 1.0f}}, false); - fRegistry.add("Track/hDCAxyzSigma", "DCA xy vs. z;DCA_{xy} (#sigma);DCA_{z} (#sigma)", kTH2F, {{200, -10.0f, 10.0f}, {200, -10.0f, 10.0f}}, false); - fRegistry.add("Track/hDCAxyRes_Pt", "DCA_{xy} resolution vs. pT;p_{T} (GeV/c);DCA_{xy} resolution (#mum)", kTH2F, {{1000, 0, 10}, {500, 0., 500}}, false); - fRegistry.add("Track/hDCAzRes_Pt", "DCA_{z} resolution vs. pT;p_{T} (GeV/c);DCA_{z} resolution (#mum)", kTH2F, {{1000, 0, 10}, {500, 0., 500}}, false); - fRegistry.add("Track/hNclsTPC", "number of TPC clusters", kTH1F, {{161, -0.5, 160.5}}, false); - fRegistry.add("Track/hNcrTPC", "number of TPC crossed rows", kTH1F, {{161, -0.5, 160.5}}, false); - fRegistry.add("Track/hChi2TPC", "chi2/number of TPC clusters", kTH1F, {{100, 0, 10}}, false); - fRegistry.add("Track/hTPCdEdx", "TPC dE/dx;p_{in} (GeV/c);TPC dE/dx (a.u.)", kTH2F, {{1000, 0, 10}, {200, 0, 200}}, false); - fRegistry.add("Track/hTPCNsigmaEl", "TPC n sigma el;p_{in} (GeV/c);n #sigma_{e}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTPCNsigmaMu", "TPC n sigma mu;p_{in} (GeV/c);n #sigma_{#mu}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTPCNsigmaPi", "TPC n sigma pi;p_{in} (GeV/c);n #sigma_{#pi}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTPCNsigmaKa", "TPC n sigma ka;p_{in} (GeV/c);n #sigma_{K}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTPCNsigmaPr", "TPC n sigma pr;p_{in} (GeV/c);n #sigma_{p}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTOFbeta", "TOF beta;p_{in} (GeV/c);#beta", kTH2F, {{1000, 0, 10}, {600, 0, 1.2}}, false); - fRegistry.add("Track/h1overTOFbeta", "TOF beta;p_{in} (GeV/c);1/#beta", kTH2F, {{1000, 0, 10}, {1000, 0.8, 1.8}}, false); - fRegistry.add("Track/hTOFNsigmaEl", "TOF n sigma el;p_{in} (GeV/c);n #sigma_{e}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTOFNsigmaMu", "TOF n sigma mu;p_{in} (GeV/c);n #sigma_{#mu}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTOFNsigmaPi", "TOF n sigma pi;p_{in} (GeV/c);n #sigma_{#pi}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTOFNsigmaKa", "TOF n sigma ka;p_{in} (GeV/c);n #sigma_{K}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTOFNsigmaPr", "TOF n sigma pr;p_{in} (GeV/c);n #sigma_{p}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTPCNcr2Nf", "TPC Ncr/Nfindable", kTH1F, {{200, 0, 2}}, false); - fRegistry.add("Track/hTPCNcls2Nf", "TPC Ncls/Nfindable", kTH1F, {{200, 0, 2}}, false); - fRegistry.add("Track/hNclsITS", "number of ITS clusters", kTH1F, {{8, -0.5, 7.5}}, false); - fRegistry.add("Track/hChi2ITS", "chi2/number of ITS clusters", kTH1F, {{100, 0, 10}}, false); - fRegistry.add("Track/hITSClusterMap", "ITS cluster map", kTH1F, {{128, -0.5, 127.5}}, false); - fRegistry.add("Track/hMeanClusterSizeITS", "mean cluster size ITS;p_{pv} (GeV/c); on ITS #times cos(#lambda)", kTH2F, {{1000, 0, 10}, {32, 0, 16}}, false); - fRegistry.add("Pair/hMvsPhiV", "mee vs. phiv;#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", kTH2F, {{90, 0, M_PI}, {100, 0, 0.1}}, false); - } - } - - void initCCDB(aod::BCsWithTimestamps::iterator const& bc) - { - if (mRunNumber == bc.runNumber()) { - return; - } - - // In case override, don't proceed, please - no CCDB access required - if (d_bz_input > -990) { - d_bz = d_bz_input; - o2::parameters::GRPMagField grpmag; - if (fabs(d_bz) > 1e-5) { - grpmag.setL3Current(30000.f / (d_bz / 5.0f)); - } - o2::base::Propagator::initFieldFromGRP(&grpmag); - mRunNumber = bc.runNumber(); - return; - } - - auto run3grp_timestamp = bc.timestamp(); - o2::parameters::GRPObject* grpo = 0x0; - o2::parameters::GRPMagField* grpmag = 0x0; - if (!skipGRPOquery) - grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); - if (grpo) { - o2::base::Propagator::initFieldFromGRP(grpo); - // Fetch magnetic field from ccdb for current collision - d_bz = grpo->getNominalL3Field(); - LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; - } else { - grpmag = ccdb->getForTimeStamp(grpmagPath, run3grp_timestamp); - if (!grpmag) { - LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; - } - o2::base::Propagator::initFieldFromGRP(grpmag); - // Fetch magnetic field from ccdb for current collision - d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); - LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG"; - } - mRunNumber = bc.runNumber(); - } - - template - bool checkTrack(TTrack const& track) - { - if constexpr (isMC) { - if (!track.has_mcParticle()) { - return false; - } - } - - if (track.tpcChi2NCl() > maxchi2tpc) { - return false; - } - - if (track.itsChi2NCl() > maxchi2its) { - return false; - } - - if (!track.hasITS() || !track.hasTPC()) { - return false; - } - if (track.itsNCls() < minitsncls) { - return false; - } - - auto hits = std::count_if(itsRequirement.second.begin(), itsRequirement.second.end(), [&](auto&& requiredLayer) { return track.itsClusterMap() & (1 << requiredLayer); }); - if (hits < itsRequirement.first) { - return false; - } - - if (track.tpcNClsFound() < min_ncluster_tpc) { - return false; - } - - if (track.tpcNClsCrossedRows() < mincrossedrows) { - return false; - } - - if (track.tpcCrossedRowsOverFindableCls() < min_tpc_cr_findable_ratio) { - return false; - } - - if (abs(track.dcaXY()) > dca_xy_max || abs(track.dcaZ()) > dca_z_max) { - return false; - } - - if (track.pt() < minpt || abs(track.eta()) > maxeta) { - return false; - } - - return true; - } - - template - void fillTrackTable(TCollision const& collision, TTrack const& track) - { - if (std::find(stored_trackIds.begin(), stored_trackIds.end(), std::pair{collision.globalIndex(), track.globalIndex()}) == stored_trackIds.end()) { - std::array dcaInfo; - auto track_par_cov_recalc = getTrackParCov(track); - track_par_cov_recalc.setPID(o2::track::PID::Electron); - std::array pVec_recalc = {0, 0, 0}; // px, py, pz - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, track_par_cov_recalc, 2.f, matCorr, &dcaInfo); - getPxPyPz(track_par_cov_recalc, pVec_recalc); - float dcaXY = dcaInfo[0]; - float dcaZ = dcaInfo[1]; - - float pt_recalc = track_par_cov_recalc.getPt(); - float eta_recalc = track_par_cov_recalc.getEta(); - float phi_recalc = track_par_cov_recalc.getPhi(); - - bool isAssociatedToMPC = collision.globalIndex() == track.collisionId(); - - emprimaryelectrons(collision.globalIndex(), track.globalIndex(), track.sign(), - pt_recalc, eta_recalc, phi_recalc, dcaXY, dcaZ, - track.tpcNClsFindable(), track.tpcNClsFindableMinusFound(), track.tpcNClsFindableMinusCrossedRows(), track.tpcNClsShared(), - track.tpcChi2NCl(), track.tpcInnerParam(), - track.tpcSignal(), track.tpcNSigmaEl(), /*track.tpcNSigmaMu(),*/ track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), - track.beta(), track.tofNSigmaEl(), /*track.tofNSigmaMu(),*/ track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr(), - track.itsClusterSizes(), - // 0, 0, 0, 0, 0, - track.itsChi2NCl(), track.tofChi2(), track.detectorMap(), - track_par_cov_recalc.getX(), track_par_cov_recalc.getAlpha(), track_par_cov_recalc.getY(), track_par_cov_recalc.getZ(), track_par_cov_recalc.getSnp(), track_par_cov_recalc.getTgl(), isAssociatedToMPC, -1); - - emprimaryelectronscov( - track_par_cov_recalc.getSigmaY2(), - track_par_cov_recalc.getSigmaZY(), - track_par_cov_recalc.getSigmaZ2(), - track_par_cov_recalc.getSigmaSnpY(), - track_par_cov_recalc.getSigmaSnpZ(), - track_par_cov_recalc.getSigmaSnp2(), - track_par_cov_recalc.getSigmaTglY(), - track_par_cov_recalc.getSigmaTglZ(), - track_par_cov_recalc.getSigmaTglSnp(), - track_par_cov_recalc.getSigmaTgl2(), - track_par_cov_recalc.getSigma1PtY(), - track_par_cov_recalc.getSigma1PtZ(), - track_par_cov_recalc.getSigma1PtSnp(), - track_par_cov_recalc.getSigma1PtTgl(), - track_par_cov_recalc.getSigma1Pt2()); - - stored_trackIds.emplace_back(std::pair{collision.globalIndex(), track.globalIndex()}); - - if (fillQAHistogram) { - uint32_t itsClusterSizes = track.itsClusterSizes(); - int total_cluster_size = 0, nl = 0; - for (unsigned int layer = 3; layer < 7; layer++) { - int cluster_size_per_layer = (itsClusterSizes >> (layer * 4)) & 0xf; - if (cluster_size_per_layer > 0) { - nl++; - } - total_cluster_size += cluster_size_per_layer; - } - - fRegistry.fill(HIST("Track/hPt"), pt_recalc); - fRegistry.fill(HIST("Track/hQoverPt"), track.sign() / pt_recalc); - fRegistry.fill(HIST("Track/hEtaPhi"), phi_recalc, eta_recalc); - fRegistry.fill(HIST("Track/hDCAxyz"), dcaXY, dcaZ); - fRegistry.fill(HIST("Track/hDCAxyzSigma"), dcaXY / sqrt(track_par_cov_recalc.getSigmaY2()), dcaZ / sqrt(track_par_cov_recalc.getSigmaZ2())); - fRegistry.fill(HIST("Track/hDCAxyRes_Pt"), pt_recalc, sqrt(track_par_cov_recalc.getSigmaY2()) * 1e+4); // convert cm to um - fRegistry.fill(HIST("Track/hDCAzRes_Pt"), pt_recalc, sqrt(track_par_cov_recalc.getSigmaZ2()) * 1e+4); // convert cm to um - fRegistry.fill(HIST("Track/hNclsITS"), track.itsNCls()); - fRegistry.fill(HIST("Track/hNclsTPC"), track.tpcNClsFound()); - fRegistry.fill(HIST("Track/hNcrTPC"), track.tpcNClsCrossedRows()); - fRegistry.fill(HIST("Track/hTPCNcr2Nf"), track.tpcCrossedRowsOverFindableCls()); - fRegistry.fill(HIST("Track/hTPCNcls2Nf"), track.tpcFoundOverFindableCls()); - fRegistry.fill(HIST("Track/hChi2TPC"), track.tpcChi2NCl()); - fRegistry.fill(HIST("Track/hChi2ITS"), track.itsChi2NCl()); - fRegistry.fill(HIST("Track/hITSClusterMap"), track.itsClusterMap()); - fRegistry.fill(HIST("Track/hMeanClusterSizeITS"), track.p(), static_cast(total_cluster_size) / static_cast(nl) * std::cos(std::atan(track.tgl()))); - fRegistry.fill(HIST("Track/hTPCdEdx"), track.tpcInnerParam(), track.tpcSignal()); - fRegistry.fill(HIST("Track/hTPCNsigmaEl"), track.tpcInnerParam(), track.tpcNSigmaEl()); - fRegistry.fill(HIST("Track/hTPCNsigmaMu"), track.tpcInnerParam(), track.tpcNSigmaMu()); - fRegistry.fill(HIST("Track/hTPCNsigmaPi"), track.tpcInnerParam(), track.tpcNSigmaPi()); - fRegistry.fill(HIST("Track/hTPCNsigmaKa"), track.tpcInnerParam(), track.tpcNSigmaKa()); - fRegistry.fill(HIST("Track/hTPCNsigmaPr"), track.tpcInnerParam(), track.tpcNSigmaPr()); - fRegistry.fill(HIST("Track/hTOFbeta"), track.tpcInnerParam(), track.beta()); - fRegistry.fill(HIST("Track/h1overTOFbeta"), track.tpcInnerParam(), 1. / track.beta()); - fRegistry.fill(HIST("Track/hTOFNsigmaEl"), track.tpcInnerParam(), track.tofNSigmaEl()); - fRegistry.fill(HIST("Track/hTOFNsigmaMu"), track.tpcInnerParam(), track.tofNSigmaMu()); - fRegistry.fill(HIST("Track/hTOFNsigmaPi"), track.tpcInnerParam(), track.tofNSigmaPi()); - fRegistry.fill(HIST("Track/hTOFNsigmaKa"), track.tpcInnerParam(), track.tofNSigmaKa()); - fRegistry.fill(HIST("Track/hTOFNsigmaPr"), track.tpcInnerParam(), track.tofNSigmaPr()); - } - } - } - - std::vector> stored_trackIds; - Filter trackFilter = o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& o2::aod::track::tpcChi2NCl < maxchi2tpc&& o2::aod::track::itsChi2NCl < maxchi2its&& ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::TPC) == true && nabs(o2::aod::track::dcaXY) < dca_xy_max&& nabs(o2::aod::track::dcaZ) < dca_z_max; - Filter pidFilter = minTPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < maxTPCNsigmaEl; - using MyFilteredTracks = soa::Filtered; - - Partition posTracks = o2::aod::track::signed1Pt > 0.f; - Partition negTracks = o2::aod::track::signed1Pt < 0.f; - - // ---------- for data ---------- - - void processRec(MyCollisions const& collisions, aod::BCsWithTimestamps const&, MyFilteredTracks const& tracks) - { - stored_trackIds.reserve(tracks.size()); - - for (auto& collision : collisions) { - auto bc = collision.bc_as(); - initCCDB(bc); - - if (!collision.selection_bit(o2::aod::evsel::kIsTriggerTVX) || !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder) || !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { - continue; - } - - auto posTracks_per_coll = posTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); // loose track sample - auto negTracks_per_coll = negTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); // loose track sample - - int npair = 0; - for (auto& [pos, neg] : combinations(CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS - - if (!checkTrack(pos) || !checkTrack(neg)) { - continue; - } - - ROOT::Math::PtEtaPhiMVector v1(pos.pt(), pos.eta(), pos.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(neg.pt(), neg.eta(), neg.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - float mee = v12.M(); - float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(pos.px(), pos.py(), pos.pz(), neg.px(), neg.py(), neg.pz(), pos.sign(), neg.sign(), d_bz); - - if (mee < mee_min || slope * phiv + intercept < mee) { // select phocon conversions - continue; - } - if (fillQAHistogram) { - fRegistry.fill(HIST("Pair/hMvsPhiV"), phiv, mee); - } - fillTrackTable(collision, pos); - fillTrackTable(collision, neg); - npair++; - } - - if (npair < 0.5) { - continue; - } - - event(collision.globalIndex(), bc.runNumber(), bc.globalBC(), collision.alias_raw(), collision.selection_raw(), collision.rct_raw(), bc.timestamp(), - collision.posX(), collision.posY(), collision.posZ(), - collision.numContrib(), collision.trackOccupancyInTimeRange(), collision.ft0cOccupancyInTimeRange()); - event_mult(collision.multFT0A(), collision.multFT0C(), collision.multNTracksPV(), collision.multNTracksPVeta1(), collision.multNTracksPVetaHalf()); - event_cent(collision.centFT0M(), collision.centFT0A(), collision.centFT0C()); - } // end of collision loop - - stored_trackIds.clear(); - stored_trackIds.shrink_to_fit(); - } - PROCESS_SWITCH(skimmerSecondaryElectron, processRec, "process reconstructed info only", true); // standalone - - // ---------- for MC ---------- - using MyFilteredTracksMC = soa::Filtered; - Partition posTracksMC = o2::aod::track::signed1Pt > 0.f; - Partition negTracksMC = o2::aod::track::signed1Pt < 0.f; - void processMC(MyCollisionsMC const& collisions, aod::McCollisions const&, aod::BCsWithTimestamps const&, MyFilteredTracksMC const& tracks) - { - stored_trackIds.reserve(tracks.size()); - - for (auto& collision : collisions) { - if (!collision.has_mcCollision()) { - continue; - } - auto bc = collision.bc_as(); - initCCDB(bc); - - if (!collision.selection_bit(o2::aod::evsel::kIsTriggerTVX) || !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder) || !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { - continue; - } - - auto posTracks_per_coll = posTracksMC->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); // loose track sample - auto negTracks_per_coll = negTracksMC->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); // loose track sample - - int npair = 0; - for (auto& [pos, neg] : combinations(CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, negTracks_per_coll))) { // ULS - if (!checkTrack(pos) || !checkTrack(neg)) { - continue; - } - - ROOT::Math::PtEtaPhiMVector v1(pos.pt(), pos.eta(), pos.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v2(neg.pt(), neg.eta(), neg.phi(), o2::constants::physics::MassElectron); - ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - float mee = v12.M(); - float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(pos.px(), pos.py(), pos.pz(), neg.px(), neg.py(), neg.pz(), pos.sign(), neg.sign(), d_bz); - - if (mee < mee_min || slope * phiv + intercept < mee) { // select phocon conversions - continue; - } - if (fillQAHistogram) { - fRegistry.fill(HIST("Pair/hMvsPhiV"), phiv, mee); - } - fillTrackTable(collision, pos); - fillTrackTable(collision, neg); - npair++; - } - - if (npair < 0.5) { - continue; - } - - event(collision.globalIndex(), bc.runNumber(), bc.globalBC(), collision.alias_raw(), collision.selection_raw(), collision.rct_raw(), bc.timestamp(), - collision.posX(), collision.posY(), collision.posZ(), - collision.numContrib(), collision.trackOccupancyInTimeRange(), collision.ft0cOccupancyInTimeRange()); - event_mult(collision.multFT0A(), collision.multFT0C(), collision.multNTracksPV(), collision.multNTracksPVeta1(), collision.multNTracksPVetaHalf()); - event_cent(collision.centFT0M(), collision.centFT0A(), collision.centFT0C()); - } // end of collision loop - - stored_trackIds.clear(); - stored_trackIds.shrink_to_fit(); - } - PROCESS_SWITCH(skimmerSecondaryElectron, processMC, "process reconstructed and MC info ", false); -}; - -struct AssociateMCInfoSecondaryElectron { - Produces mcevents; - Produces mceventlabels; - Produces emmcparticles; - Produces emprimaryelectronmclabels; - - HistogramRegistry registry{"EMMCEvent"}; - void init(o2::framework::InitContext&) - { - auto hEventCounter = registry.add("hEventCounter", "hEventCounter", kTH1I, {{6, 0.5f, 6.5f}}); - hEventCounter->GetXaxis()->SetBinLabel(1, "all"); - hEventCounter->GetXaxis()->SetBinLabel(2, "has mc collision"); - } - - void processMC(MyCollisionsMC const& collisions, aod::McCollisions const&, aod::McParticles const& mcTracks, MyTracksMC const& o2tracks, aod::EMEvents const& emevents, aod::EMPrimaryElectrons const& emprimaryelectrons) - { - // temporary variables used for the indexing of the skimmed MC stack - std::map fNewLabels; - std::map fNewLabelsReversed; - // std::map fMCFlags; - std::map fEventIdx; - std::map fEventLabels; - int fCounters[2] = {0, 0}; //! [0] - particle counter, [1] - event counter - - for (auto& emevent : emevents) { - registry.fill(HIST("hEventCounter"), 1); - auto collision = collisions.iteratorAt(emevent.collisionId()); - auto mcCollision = collision.mcCollision(); - - if (!(fEventLabels.find(mcCollision.globalIndex()) != fEventLabels.end())) { - mcevents(mcCollision.globalIndex(), mcCollision.generatorsID(), mcCollision.posX(), mcCollision.posY(), mcCollision.posZ(), mcCollision.impactParameter(), mcCollision.eventPlaneAngle()); - fEventLabels[mcCollision.globalIndex()] = fCounters[1]; - fCounters[1]++; - } - - mceventlabels(fEventLabels.find(mcCollision.globalIndex())->second, collision.mcMask()); - } // end of reconstructed collision loop - - for (auto& emprimaryelectron : emprimaryelectrons) { - auto collision_from_el = collisions.iteratorAt(emprimaryelectron.collisionId()); - if (!collision_from_el.has_mcCollision()) { - continue; - } - auto mcCollision_from_el = collision_from_el.mcCollision(); - - auto o2track = o2tracks.iteratorAt(emprimaryelectron.trackId()); - if (!o2track.has_mcParticle()) { - continue; // If no MC particle is found, skip the dilepton - } - auto mctrack = o2track.template mcParticle_as(); - - // if the MC truth particle corresponding to this reconstructed track which is not already written, add it to the skimmed MC stack - if (!(fNewLabels.find(mctrack.globalIndex()) != fNewLabels.end())) { - fNewLabels[mctrack.globalIndex()] = fCounters[0]; - fNewLabelsReversed[fCounters[0]] = mctrack.globalIndex(); - // fMCFlags[mctrack.globalIndex()] = mcflags; - fEventIdx[mctrack.globalIndex()] = fEventLabels.find(mcCollision_from_el.globalIndex())->second; - fCounters[0]++; - } - emprimaryelectronmclabels(fNewLabels.find(mctrack.index())->second, o2track.mcMask()); - - // Next, store mother-chain of this reconstructed track. - int motherid = -999; // first mother index - if (mctrack.has_mothers()) { - motherid = mctrack.mothersIds()[0]; // first mother index - } - while (motherid > -1) { - if (motherid < mcTracks.size()) { // protect against bad mother indices. why is this needed? - auto mp = mcTracks.iteratorAt(motherid); - - // if the MC truth particle corresponding to this reconstructed track which is not already written, add it to the skimmed MC stack - if (!(fNewLabels.find(mp.globalIndex()) != fNewLabels.end())) { - fNewLabels[mp.globalIndex()] = fCounters[0]; - fNewLabelsReversed[fCounters[0]] = mp.globalIndex(); - // fMCFlags[mp.globalIndex()] = mcflags; - fEventIdx[mp.globalIndex()] = fEventLabels.find(mcCollision_from_el.globalIndex())->second; - fCounters[0]++; - } - - if (mp.has_mothers()) { - motherid = mp.mothersIds()[0]; // first mother index - } else { - motherid = -999; - } - } else { - motherid = -999; - } - } // end of mother chain loop - - } // end of em primary electron loop - - // Loop over the label map, create the mother/daughter relationships if these exist and write the skimmed MC stack - for (const auto& [newLabel, oldLabel] : fNewLabelsReversed) { - auto mctrack = mcTracks.iteratorAt(oldLabel); - // uint16_t mcflags = fMCFlags.find(oldLabel)->second; - - std::vector mothers; - if (mctrack.has_mothers()) { - for (auto& m : mctrack.mothersIds()) { - if (m < mcTracks.size()) { // protect against bad mother indices - if (fNewLabels.find(m) != fNewLabels.end()) { - mothers.push_back(fNewLabels.find(m)->second); - } - } else { - std::cout << "Mother label (" << m << ") exceeds the McParticles size (" << mcTracks.size() << ")" << std::endl; - std::cout << " Check the MC generator" << std::endl; - } - } - } - - // Note that not all daughters from the original table are preserved in the skimmed MC stack - std::vector daughters; - if (mctrack.has_daughters()) { - // int ndau = mctrack.daughtersIds()[1] - mctrack.daughtersIds()[0] + 1; - // LOGF(info, "daughter range in original MC stack pdg = %d | %d - %d , n dau = %d", mctrack.pdgCode(), mctrack.daughtersIds()[0], mctrack.daughtersIds()[1], mctrack.daughtersIds()[1] -mctrack.daughtersIds()[0] +1); - for (int d = mctrack.daughtersIds()[0]; d <= mctrack.daughtersIds()[1]; ++d) { - // TODO: remove this check as soon as issues with MC production are fixed - if (d < mcTracks.size()) { // protect against bad daughter indices - // auto dau_tmp = mcTracks.iteratorAt(d); - // // LOGF(info, "daughter pdg = %d", dau_tmp.pdgCode()); - // if ((mctrack.pdgCode() == 223 || mctrack.pdgCode() == 333) && (mctrack.isPhysicalPrimary() || mctrack.producedByGenerator())) { - // if (fNewLabels.find(d) == fNewLabels.end() && (abs(dau_tmp.pdgCode()) == 11 || abs(dau_tmp.pdgCode()) == 13)) { - // LOGF(info, "daughter lepton is not found mctrack.globalIndex() = %d, mctrack.producedByGenerator() == %d, ndau = %d | dau_tmp.globalIndex() = %d, dau_tmp.pdgCode() = %d, dau_tmp.producedByGenerator() = %d, dau_tmp.pt() = %f, dau_tmp.eta() = %f, dau_tmp.phi() = %f", mctrack.globalIndex(), mctrack.producedByGenerator(), ndau, dau_tmp.globalIndex(), dau_tmp.pdgCode(), dau_tmp.producedByGenerator(), dau_tmp.pt(), dau_tmp.eta(), dau_tmp.phi()); - // } - // } - - if (fNewLabels.find(d) != fNewLabels.end()) { - daughters.push_back(fNewLabels.find(d)->second); - } - } else { - std::cout << "Daughter label (" << d << ") exceeds the McParticles size (" << mcTracks.size() << ")" << std::endl; - std::cout << " Check the MC generator" << std::endl; - } - } - } - - emmcparticles(fEventIdx.find(oldLabel)->second, mctrack.pdgCode(), mctrack.flags(), - mothers, daughters, - mctrack.px(), mctrack.py(), mctrack.pz(), mctrack.e(), - mctrack.vx(), mctrack.vy(), mctrack.vz()); - - mothers.clear(); - mothers.shrink_to_fit(); - daughters.clear(); - daughters.shrink_to_fit(); - } // end loop over labels - - fNewLabels.clear(); - fNewLabelsReversed.clear(); - // fMCFlags.clear(); - fEventIdx.clear(); - fEventLabels.clear(); - fCounters[0] = 0; - fCounters[1] = 0; - } - - void processDummy(MyCollisions const&) {} - - PROCESS_SWITCH(AssociateMCInfoSecondaryElectron, processMC, "create em mc event table for Electron", false); - PROCESS_SWITCH(AssociateMCInfoSecondaryElectron, processDummy, "processDummy", true); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc, TaskName{"skimmer-secondary-electron"}), - adaptAnalysisTask(cfgc, TaskName{"associate-mc-info-secondary-electron"}), - }; -} diff --git a/PWGEM/Dilepton/TableProducer/treeCreatorElectronML.cxx b/PWGEM/Dilepton/TableProducer/treeCreatorElectronML.cxx index 1874e953269..51b21a6439c 100644 --- a/PWGEM/Dilepton/TableProducer/treeCreatorElectronML.cxx +++ b/PWGEM/Dilepton/TableProducer/treeCreatorElectronML.cxx @@ -551,7 +551,7 @@ struct TreeCreatorElectronML { } } - template + template void doSingleTrack(TTrack& track, TMCParticle& mctrack, TMCParticles& mctracks, uint64_t collisionId, std::vector& collisions_old_labels, int& collisions_counter, bool use_downsample = true) { if (!IsSelected(track)) { @@ -584,15 +584,28 @@ struct TreeCreatorElectronML { collisions_counter++; collisions_old_labels.push_back(collisionId); } - mytrack(collisions_counter, - track.sign(), track.pt(), track.eta(), track.phi(), track.tgl(), track.dcaXY(), track.dcaZ(), sqrt(track.cYY()), sqrt(track.cZZ()), track.cZY(), - track.tpcNClsFindable(), track.tpcNClsFound(), track.tpcNClsCrossedRows(), - track.tpcChi2NCl(), track.tpcInnerParam(), - track.tpcSignal(), track.tpcNSigmaEl(), /*track.tpcNSigmaMu(),*/ track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), - track.beta(), track.tofNSigmaEl(), /*track.tofNSigmaMu(),*/ track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr(), - track.tofChi2(), track.itsChi2NCl(), track.itsClusterSizes(), - mctrack.vx(), mctrack.vy(), mctrack.vz(), - mctrack.pdgCode(), mctrack.isPhysicalPrimary(), mothers_id, mothers_pdg); + + if constexpr (isDerived) { + mytrack(collisions_counter, + track.sign(), track.pt(), track.eta(), track.phi(), track.tgl(), track.dcaXY(), track.dcaZ(), sqrt(track.cYY()), sqrt(track.cZZ()), track.cZY(), + track.tpcNClsFindable(), track.tpcNClsFound(), track.tpcNClsCrossedRows(), + track.tpcChi2NCl(), track.tpcInnerParam(), + track.tpcSignal(), track.tpcNSigmaEl(), /*track.tpcNSigmaMu(),*/ track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), + track.beta(), track.tofNSigmaEl(), /*track.tofNSigmaMu(),*/ 0, 0, 0, + track.tofChi2(), track.itsChi2NCl(), track.itsClusterSizes(), + mctrack.vx(), mctrack.vy(), mctrack.vz(), + mctrack.pdgCode(), mctrack.isPhysicalPrimary(), mothers_id, mothers_pdg); + } else { + mytrack(collisions_counter, + track.sign(), track.pt(), track.eta(), track.phi(), track.tgl(), track.dcaXY(), track.dcaZ(), sqrt(track.cYY()), sqrt(track.cZZ()), track.cZY(), + track.tpcNClsFindable(), track.tpcNClsFound(), track.tpcNClsCrossedRows(), + track.tpcChi2NCl(), track.tpcInnerParam(), + track.tpcSignal(), track.tpcNSigmaEl(), /*track.tpcNSigmaMu(),*/ track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), + track.beta(), track.tofNSigmaEl(), /*track.tofNSigmaMu(),*/ track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr(), + track.tofChi2(), track.itsChi2NCl(), track.itsClusterSizes(), + mctrack.vx(), mctrack.vy(), mctrack.vz(), + mctrack.pdgCode(), mctrack.isPhysicalPrimary(), mothers_id, mothers_pdg); + } mothers_id.shrink_to_fit(); mothers_pdg.shrink_to_fit(); @@ -638,7 +651,7 @@ struct TreeCreatorElectronML { continue; } auto mctrack = track.mcParticle_as(); - doSingleTrack(track, mctrack, mctracks, collision.globalIndex(), collisions_old_labels, collisions_counter); + doSingleTrack(track, mctrack, mctracks, collision.globalIndex(), collisions_old_labels, collisions_counter); } } @@ -651,7 +664,7 @@ struct TreeCreatorElectronML { } PROCESS_SWITCH(TreeCreatorElectronML, processSingleTrack, "produce ML input for single track level", false); - using MyFilteredCollisionsSkimmed = soa::Filtered>; + using MyFilteredCollisionsSkimmed = soa::Filtered>; using MyFilteredTracksMCSkimmed = soa::Filtered>; Preslice perCollisionSkimmed = aod::emprimaryelectron::emeventId; @@ -672,7 +685,7 @@ struct TreeCreatorElectronML { continue; } auto mctrack = track.emmcparticle_as(); - doSingleTrack(track, mctrack, mctracks, collision.globalIndex(), collisions_old_labels, collisions_counter); + doSingleTrack(track, mctrack, mctracks, collision.globalIndex(), collisions_old_labels, collisions_counter); } } @@ -736,7 +749,7 @@ struct TreeCreatorElectronML { auto track = tracks.rawIteratorAt(track_label); auto mctrack = track.mcParticle_as(); - doSingleTrack(track, mctrack, mctracks, collision.globalIndex(), collisions_old_labels, collisions_counter, false); + doSingleTrack(track, mctrack, mctracks, collision.globalIndex(), collisions_old_labels, collisions_counter, false); } // end of track loop @@ -808,7 +821,7 @@ struct TreeCreatorElectronML { auto track = tracks.rawIteratorAt(track_label); auto mctrack = track.emmcparticle_as(); - doSingleTrack(track, mctrack, mctracks, collision.globalIndex(), collisions_old_labels_track, collisions_counter_track, false); + doSingleTrack(track, mctrack, mctracks, collision.globalIndex(), collisions_old_labels_track, collisions_counter_track, false); } // end of track loop diff --git a/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx b/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx index 0a5527d1428..b35d73698e7 100644 --- a/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx +++ b/PWGEM/Dilepton/TableProducer/treeCreatorElectronMLDDA.cxx @@ -119,10 +119,19 @@ struct TreeCreatorElectronMLDDA { Configurable d_bz_input{"d_bz_input", -999, "bz field, -999 is automatic"}; Configurable useMatCorrType{"useMatCorrType", 2, "0: none, 1: TGeo, 2: LUT"}; - Configurable downscaling_electron{"downscaling_electron", 0.01, "down scaling factor to store electron"}; - Configurable downscaling_pion{"downscaling_pion", 0.01, "down scaling factor to store pion"}; - Configurable downscaling_kaon{"downscaling_kaon", 1.1, "down scaling factor to store kaon"}; - Configurable downscaling_proton{"downscaling_proton", 0.01, "down scaling factor to store proton"}; + Configurable downscaling_electron_highP{"downscaling_electron_highP", 1.1, "down scaling factor to store electron at high p"}; + Configurable downscaling_pion_highP{"downscaling_pion_highP", 1.1, "down scaling factor to store pion at high p"}; + Configurable downscaling_kaon_highP{"downscaling_kaon_highP", 1.1, "down scaling factor to store kaon at high p"}; + Configurable downscaling_proton_highP{"downscaling_proton_highP", 1.1, "down scaling factor to store proton at high p"}; + + Configurable downscaling_electron_midP{"downscaling_electron_midP", 0.1, "down scaling factor to store electron at intermediate p"}; + + Configurable downscaling_electron_lowP{"downscaling_electron_lowP", 0.01, "down scaling factor to store electron at low p"}; + Configurable downscaling_pion_lowP{"downscaling_pion_lowP", 0.01, "down scaling factor to store pion at low p"}; + Configurable downscaling_kaon_lowP{"downscaling_kaon_lowP", 1.1, "down scaling factor to store kaon at low p"}; + Configurable downscaling_proton_lowP{"downscaling_proton_lowP", 0.01, "down scaling factor to store proton at low p"}; + + Configurable mid_p_for_downscaling_electron{"mid_p_for_downscaling_electron", 0.8, "intermediate p to apply down scaling factor to store electron"}; Configurable max_p_for_downscaling_electron{"max_p_for_downscaling_electron", 2.0, "max p to apply down scaling factor to store electron"}; Configurable max_p_for_downscaling_pion{"max_p_for_downscaling_pion", 2.0, "max p to apply down scaling factor to store pion"}; @@ -156,22 +165,6 @@ struct TreeCreatorElectronMLDDA { Configurable cfgRequireGoodITSLayersAll{"cfgRequireGoodITSLayersAll", false, "number of inactive chips on all ITS layers are below threshold "}; } eventcuts; - struct : ConfigurableGroup { - std::string prefix = "trackcut_group"; - Configurable cfg_min_pt{"cfg_min_pt", 0.05, "min pt for v0 legs"}; - Configurable cfg_max_eta{"cfg_max_eta", 0.9, "max. eta for v0 legs"}; - Configurable cfg_min_cr2findable_ratio_tpc{"cfg_min_cr2findable_ratio_tpc", 0.8, "min. TPC Ncr/Nf ratio"}; - Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 0.7, "max fraction of shared clusters in TPC"}; - Configurable cfg_min_ncrossedrows_tpc{"cfg_min_ncrossedrows_tpc", 70, "min ncrossed rows"}; - Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; - Configurable cfg_min_ncluster_its{"cfg_min_ncluster_its", 4, "min ncluster its"}; - Configurable cfg_min_ncluster_itsib{"cfg_min_ncluster_itsib", 1, "min ncluster itsib"}; - Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 5.0, "max chi2/NclsTPC"}; // comment - Configurable cfg_max_chi2its{"cfg_max_chi2its", 36.0, "max chi2/NclsITS"}; - Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 1.0, "max dca XY in cm"}; - Configurable cfg_max_dcaz{"cfg_max_dcaz", 1.0, "max dca Z in cm"}; - } trackcuts; - struct : ConfigurableGroup { std::string prefix = "v0cut_group"; Configurable cfg_min_pt{"cfg_min_pt", 0.05, "min pt for v0 legs"}; @@ -190,9 +183,12 @@ struct TreeCreatorElectronMLDDA { Configurable cfg_min_cospa{"cfg_min_cospa", 0.9998, "min cospa for v0"}; Configurable cfg_max_dcadau{"cfg_max_dcadau", 0.1, "max distance between 2 legs for v0"}; + Configurable cfg_min_qt_strangeness{"cfg_min_qt_strangeness", 0.015, "min qt for Lambda and K0S"}; + Configurable cfg_min_cr2findable_ratio_tpc{"cfg_min_cr2findable_ratio_tpc", 0.8, "min. TPC Ncr/Nf ratio"}; Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 0.7, "max fraction of shared clusters in TPC"}; Configurable cfg_min_ncrossedrows_tpc{"cfg_min_ncrossedrows_tpc", 70, "min ncrossed rows"}; + Configurable cfg_min_ncluster_tpc_pid{"cfg_min_ncluster_tpc_pid", 0, "min ncluster tpc"}; Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; Configurable cfg_min_ncluster_its{"cfg_min_ncluster_its", 2, "min ncluster its"}; Configurable cfg_min_ncluster_itsib{"cfg_min_ncluster_itsib", 0, "min ncluster itsib"}; @@ -201,7 +197,6 @@ struct TreeCreatorElectronMLDDA { Configurable cfg_min_dcaxy_v0leg{"cfg_min_dcaxy_v0leg", 0.1, "min dca XY to PV for v0 legs in cm"}; Configurable cfg_includeITSsa{"cfg_includeITSsa", false, "Flag to include ITSsa tracks"}; Configurable cfg_max_pt_itssa{"cfg_max_pt_itssa", 0.15, "mix pt for ITSsa track"}; - Configurable cfg_min_qt_strangeness{"cfg_min_qt_strangeness", 0.015, "min qt for Lambda and K0S"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -5, "min n sigma e in TPC"}; Configurable cfg_max_TPCNsigmaEl{"cfg_max_TPCNsigmaEl", +5, "max n sigma e in TPC"}; @@ -220,23 +215,37 @@ struct TreeCreatorElectronMLDDA { Configurable cfg_max_TOFNsigmaKa{"cfg_max_TOFNsigmaKa", +5, "max n sigma ka in TOF"}; Configurable cfg_min_TOFNsigmaPr{"cfg_min_TOFNsigmaPr", -5, "min n sigma pr in TOF"}; Configurable cfg_max_TOFNsigmaPr{"cfg_max_TOFNsigmaPr", +5, "max n sigma pr in TOF"}; - - Configurable cfg_min_TPCNsigmaEl_tight{"cfg_min_TPCNsigmaEl_tight", -2, "min n sigma e in TPC for pi0->eeg"}; - Configurable cfg_max_TPCNsigmaEl_tight{"cfg_max_TPCNsigmaEl_tight", +2, "max n sigma e in TPC for pi0->eeg"}; - Configurable cfg_min_TOFNsigmaEl_tight{"cfg_min_TOFNsigmaEl_tight", -2, "min n sigma e in TOF for pi0->eeg"}; - Configurable cfg_max_TOFNsigmaEl_tight{"cfg_max_TOFNsigmaEl_tight", +2, "max n sigma e in TOF for pi0->eeg"}; - - Configurable cfg_min_TPCNsigmaPi_tight{"cfg_min_TPCNsigmaPi_tight", -2, "min n sigma pi in TPC for Lambda and cascade"}; - Configurable cfg_max_TPCNsigmaPi_tight{"cfg_max_TPCNsigmaPi_tight", +2, "max n sigma pi in TPC for Lambda and cascade"}; - Configurable cfg_min_TPCNsigmaPr_tight{"cfg_min_TPCNsigmaPr_tight", -2, "min n sigma pr in TPC for cascade"}; - Configurable cfg_max_TPCNsigmaPr_tight{"cfg_max_TPCNsigmaPr_tight", +2, "max n sigma pr in TPC for cascade"}; - - Configurable cfg_min_TOFNsigmaPi_tight{"cfg_min_TOFNsigmaPi_tight", -2, "min n sigma pi in TOF for Lambda and cascade"}; - Configurable cfg_max_TOFNsigmaPi_tight{"cfg_max_TOFNsigmaPi_tight", +2, "max n sigma pi in TOF for Lambda and cascade"}; - Configurable cfg_min_TOFNsigmaPr_tight{"cfg_min_TOFNsigmaPr_tight", -2, "min n sigma pr in TOF for cascade"}; - Configurable cfg_max_TOFNsigmaPr_tight{"cfg_max_TOFNsigmaPr_tight", +2, "max n sigma pr in TOF for cascade"}; } v0cuts; + struct : ConfigurableGroup { + std::string prefix = "tightv0cut_group"; + Configurable cfg_min_cr2findable_ratio_tpc{"cfg_min_cr2findable_ratio_tpc", 0.8, "min. TPC Ncr/Nf ratio"}; + Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 0.7, "max fraction of shared clusters in TPC"}; + Configurable cfg_min_ncrossedrows_tpc{"cfg_min_ncrossedrows_tpc", 80, "min ncrossed rows"}; + Configurable cfg_min_ncluster_tpc_pid{"cfg_min_ncluster_tpc_pid", 60, "min ncluster tpc"}; + Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; + Configurable cfg_min_ncluster_its{"cfg_min_ncluster_its", 2, "min ncluster its"}; + Configurable cfg_min_ncluster_itsib{"cfg_min_ncluster_itsib", 0, "min ncluster itsib"}; + Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; + Configurable cfg_max_chi2its{"cfg_max_chi2its", 5.0, "max chi2/NclsITS"}; + Configurable requireTOF_for_tagging{"requireTOF_for_tagging", false, "flag to require TOF for tagging 1 leg from V0"}; + + Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2, "min n sigma e in TPC for pc->ee"}; + Configurable cfg_max_TPCNsigmaEl{"cfg_max_TPCNsigmaEl", +2, "max n sigma e in TPC for pc->ee"}; + Configurable cfg_min_TOFNsigmaEl{"cfg_min_TOFNsigmaEl", -2, "min n sigma e in TOF for pc->ee"}; + Configurable cfg_max_TOFNsigmaEl{"cfg_max_TOFNsigmaEl", +2, "max n sigma e in TOF for pc->ee"}; + + Configurable cfg_min_TPCNsigmaPi{"cfg_min_TPCNsigmaPi", -2, "min n sigma pi in TPC for Lambda and cascade"}; + Configurable cfg_max_TPCNsigmaPi{"cfg_max_TPCNsigmaPi", +2, "max n sigma pi in TPC for Lambda and cascade"}; + Configurable cfg_min_TPCNsigmaPr{"cfg_min_TPCNsigmaPr", -2, "min n sigma pr in TPC for cascade"}; + Configurable cfg_max_TPCNsigmaPr{"cfg_max_TPCNsigmaPr", +2, "max n sigma pr in TPC for cascade"}; + + Configurable cfg_min_TOFNsigmaPi{"cfg_min_TOFNsigmaPi", -2, "min n sigma pi in TOF for Lambda and cascade"}; + Configurable cfg_max_TOFNsigmaPi{"cfg_max_TOFNsigmaPi", +2, "max n sigma pi in TOF for Lambda and cascade"}; + Configurable cfg_min_TOFNsigmaPr{"cfg_min_TOFNsigmaPr", -2, "min n sigma pr in TOF for cascade"}; + Configurable cfg_max_TOFNsigmaPr{"cfg_max_TOFNsigmaPr", +2, "max n sigma pr in TOF for cascade"}; + } tightv0cuts; + struct : ConfigurableGroup { std::string prefix = "cascadecut_group"; Configurable cfg_min_mass_lambda{"cfg_min_mass_lambda", 1.11, "min mass for lambda in cascade"}; @@ -252,7 +261,9 @@ struct TreeCreatorElectronMLDDA { Configurable cfg_min_rxy_v0{"cfg_min_rxy_v0", 1.2, "minimum V0 rxy in cascade"}; Configurable cfg_min_rxy{"cfg_min_rxy", 0.5, "minimum V0 rxy in cascade"}; Configurable cfg_min_dcaxy_v0leg{"cfg_min_dcaxy_v0leg", 0.1, "min dca XY for v0 legs in cm"}; - Configurable cfg_min_dcaxy_bachelor{"cfg_min_dcaxy_bachelor", 0.1, "min dca XY for bachelor in cm"}; + Configurable cfg_min_dcaxy_bachelor{"cfg_min_dcaxy_bachelor", 0.05, "min dca XY for bachelor in cm"}; + Configurable cfg_min_dcaxy_v0{"cfg_min_dcaxy_v0", 0.05, "min dca XY for V0 in cm"}; + Configurable requireTOF_for_tagging{"requireTOF_for_tagging", false, "flag to require TOF for tagging 1 leg from V0"}; } cascadecuts; // for RCT @@ -376,19 +387,19 @@ struct TreeCreatorElectronMLDDA { } template - bool isSelectedTrack(TCollision const& collision, TTrack const& track) + bool isSelectedV0Leg(TCollision const& collision, TTrack const& track) { if (!track.hasITS()) { return false; } - if (track.itsNCls() < trackcuts.cfg_min_ncluster_its) { + if (track.itsNCls() < v0cuts.cfg_min_ncluster_its) { return false; } - if (track.itsNClsInnerBarrel() < trackcuts.cfg_min_ncluster_itsib) { + if (track.itsNClsInnerBarrel() < v0cuts.cfg_min_ncluster_itsib) { return false; } - if (track.itsChi2NCl() > trackcuts.cfg_max_chi2its) { + if (track.itsChi2NCl() > v0cuts.cfg_max_chi2its) { return false; } @@ -397,19 +408,22 @@ struct TreeCreatorElectronMLDDA { } if (track.hasTPC()) { - if (track.tpcNClsCrossedRows() < trackcuts.cfg_min_ncrossedrows_tpc) { + if (track.tpcNClsCrossedRows() < v0cuts.cfg_min_ncrossedrows_tpc) { return false; } - if (track.tpcNClsFound() < trackcuts.cfg_min_ncluster_tpc) { + if (track.tpcNClsFound() < v0cuts.cfg_min_ncluster_tpc) { + return false; + } + if (track.tpcChi2NCl() > v0cuts.cfg_max_chi2tpc) { return false; } - if (track.tpcChi2NCl() > trackcuts.cfg_max_chi2tpc) { + if (track.tpcCrossedRowsOverFindableCls() < v0cuts.cfg_min_cr2findable_ratio_tpc) { return false; } - if (track.tpcCrossedRowsOverFindableCls() < trackcuts.cfg_min_cr2findable_ratio_tpc) { + if (track.tpcFractionSharedCls() > v0cuts.cfg_max_frac_shared_clusters_tpc) { return false; } - if (track.tpcFractionSharedCls() > trackcuts.cfg_max_frac_shared_clusters_tpc) { + if (track.tpcNClsPID() < v0cuts.cfg_min_ncluster_tpc_pid) { return false; } } @@ -420,20 +434,18 @@ struct TreeCreatorElectronMLDDA { mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); - float dcaXY = mDcaInfoCov.getY(); - float dcaZ = mDcaInfoCov.getZ(); + // float dcaXY = mDcaInfoCov.getY(); + // float dcaZ = mDcaInfoCov.getZ(); - if (std::fabs(dcaXY) > trackcuts.cfg_max_dcaxy) { - return false; - } - if (std::fabs(dcaZ) > trackcuts.cfg_max_dcaz) { - return false; - } + // if (std::fabs(dcaXY) < v0cuts.cfg_min_dcaxy_v0leg) { // this is applied in filter. + // return false; + // } - if (std::fabs(trackParCov.getEta()) > trackcuts.cfg_max_eta || trackParCov.getPt() < trackcuts.cfg_min_pt) { + if (std::fabs(trackParCov.getEta()) > v0cuts.cfg_max_eta || trackParCov.getPt() < v0cuts.cfg_min_pt) { return false; } - if ((track.hasITS() && !track.hasTPC() && !track.hasTRD() && !track.hasTOF()) && v0cuts.cfg_max_pt_itssa < trackParCov.getPt()) { + + if ((track.hasITS() && !track.hasTPC() && !track.hasTRD() && !track.hasTOF()) && v0cuts.cfg_max_pt_itssa < track.pt()) { return true; } @@ -441,42 +453,39 @@ struct TreeCreatorElectronMLDDA { } template - bool isSelectedV0Leg(TCollision const& collision, TTrack const& track) + bool isSelectedV0LegTight(TCollision const& collision, TTrack const& track) { - if (!track.hasITS()) { + if (!track.hasITS() || !track.hasTPC()) { return false; } - if (track.itsNCls() < v0cuts.cfg_min_ncluster_its) { + if (track.itsNCls() < tightv0cuts.cfg_min_ncluster_its) { return false; } - if (track.itsNClsInnerBarrel() < v0cuts.cfg_min_ncluster_itsib) { + if (track.itsNClsInnerBarrel() < tightv0cuts.cfg_min_ncluster_itsib) { return false; } - if (track.itsChi2NCl() > v0cuts.cfg_max_chi2its) { + if (tightv0cuts.cfg_max_chi2its < track.itsChi2NCl()) { return false; } - if (!v0cuts.cfg_includeITSsa && (!track.hasITS() || !track.hasTPC())) { + if (track.tpcNClsCrossedRows() < tightv0cuts.cfg_min_ncrossedrows_tpc) { return false; } - - if (track.hasTPC()) { - if (track.tpcNClsCrossedRows() < v0cuts.cfg_min_ncrossedrows_tpc) { - return false; - } - if (track.tpcNClsFound() < v0cuts.cfg_min_ncluster_tpc) { - return false; - } - if (track.tpcChi2NCl() > v0cuts.cfg_max_chi2tpc) { - return false; - } - if (track.tpcCrossedRowsOverFindableCls() < v0cuts.cfg_min_cr2findable_ratio_tpc) { - return false; - } - if (track.tpcFractionSharedCls() > v0cuts.cfg_max_frac_shared_clusters_tpc) { - return false; - } + if (track.tpcNClsFound() < tightv0cuts.cfg_min_ncluster_tpc) { + return false; + } + if (track.tpcChi2NCl() < 0.f || tightv0cuts.cfg_max_chi2tpc < track.tpcChi2NCl()) { + return false; + } + if (track.tpcCrossedRowsOverFindableCls() < tightv0cuts.cfg_min_cr2findable_ratio_tpc) { + return false; + } + if (track.tpcFractionSharedCls() > tightv0cuts.cfg_max_frac_shared_clusters_tpc) { + return false; + } + if (track.tpcNClsPID() < tightv0cuts.cfg_min_ncluster_tpc_pid) { + return false; } mDcaInfoCov.set(999, 999, 999, 999, 999); @@ -485,21 +494,17 @@ struct TreeCreatorElectronMLDDA { mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); - float dcaXY = mDcaInfoCov.getY(); + // float dcaXY = mDcaInfoCov.getY(); // float dcaZ = mDcaInfoCov.getZ(); - if (std::fabs(dcaXY) < v0cuts.cfg_min_dcaxy_v0leg) { // this is applied in filter. - return false; - } + // if (std::fabs(dcaXY) < v0cuts.cfg_min_dcaxy_v0leg) { // this is applied in filter. + // return false; + // } if (std::fabs(trackParCov.getEta()) > v0cuts.cfg_max_eta || trackParCov.getPt() < v0cuts.cfg_min_pt) { return false; } - if ((track.hasITS() && !track.hasTPC() && !track.hasTRD() && !track.hasTOF()) && v0cuts.cfg_max_pt_itssa < track.pt()) { - return true; - } - return true; } @@ -550,24 +555,24 @@ struct TreeCreatorElectronMLDDA { template bool isElectronTight(TTrack const& track) { - bool is_El_TPC = v0cuts.cfg_min_TPCNsigmaEl_tight < track.tpcNSigmaEl() && track.tpcNSigmaEl() < v0cuts.cfg_max_TPCNsigmaEl_tight; - bool is_El_TOF = track.hasTOF() ? v0cuts.cfg_min_TOFNsigmaEl_tight < track.tofNSigmaEl() && track.tofNSigmaEl() < v0cuts.cfg_max_TOFNsigmaEl_tight : true; // TOFif + bool is_El_TPC = tightv0cuts.cfg_min_TPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < tightv0cuts.cfg_max_TPCNsigmaEl; + bool is_El_TOF = track.hasTOF() ? tightv0cuts.cfg_min_TOFNsigmaEl < track.tofNSigmaEl() && track.tofNSigmaEl() < tightv0cuts.cfg_max_TOFNsigmaEl : true; // TOFif return is_El_TPC && is_El_TOF; } template bool isPionTight(TTrack const& track) { - bool is_Pi_TPC = v0cuts.cfg_min_TPCNsigmaPi_tight < track.tpcNSigmaPi() && track.tpcNSigmaPi() < v0cuts.cfg_max_TPCNsigmaPi_tight; - bool is_Pi_TOF = track.hasTOF() ? v0cuts.cfg_min_TOFNsigmaPi_tight < track.tofNSigmaPi() && track.tofNSigmaPi() < v0cuts.cfg_max_TOFNsigmaPi_tight : true; // TOFif + bool is_Pi_TPC = tightv0cuts.cfg_min_TPCNsigmaPi < track.tpcNSigmaPi() && track.tpcNSigmaPi() < tightv0cuts.cfg_max_TPCNsigmaPi; + bool is_Pi_TOF = track.hasTOF() ? tightv0cuts.cfg_min_TOFNsigmaPi < track.tofNSigmaPi() && track.tofNSigmaPi() < tightv0cuts.cfg_max_TOFNsigmaPi : true; // TOFif return is_Pi_TPC && is_Pi_TOF; } template bool isProtonTight(TTrack const& track) { - bool is_Pr_TPC = v0cuts.cfg_min_TPCNsigmaPr_tight < track.tpcNSigmaPr() && track.tpcNSigmaPr() < v0cuts.cfg_max_TPCNsigmaPr_tight; - bool is_Pr_TOF = track.hasTOF() ? v0cuts.cfg_min_TOFNsigmaPr_tight < track.tofNSigmaPr() && track.tofNSigmaPr() < v0cuts.cfg_max_TOFNsigmaPr_tight : true; // TOFif + bool is_Pr_TPC = tightv0cuts.cfg_min_TPCNsigmaPr < track.tpcNSigmaPr() && track.tpcNSigmaPr() < tightv0cuts.cfg_max_TPCNsigmaPr; + bool is_Pr_TOF = track.hasTOF() ? tightv0cuts.cfg_min_TOFNsigmaPr < track.tofNSigmaPr() && track.tofNSigmaPr() < tightv0cuts.cfg_max_TOFNsigmaPr : true; // TOFif return is_Pr_TPC && is_Pr_TOF; } @@ -588,27 +593,55 @@ struct TreeCreatorElectronMLDDA { // float dcaZ = mDcaInfoCov.getZ(); if (pidlabel == static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kElectron)) { - if (dist01(engine) > downscaling_electron && trackParCov.getP() < max_p_for_downscaling_electron) { - return; + if (track.tpcInnerParam() < mid_p_for_downscaling_electron) { + if (dist01(engine) > downscaling_electron_lowP) { + return; + } + } else if (track.tpcInnerParam() < max_p_for_downscaling_electron) { + if (dist01(engine) > downscaling_electron_midP) { + return; + } + } else { + if (dist01(engine) > downscaling_electron_highP) { + return; + } } } else if (pidlabel == static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kPion)) { - if (dist01(engine) > downscaling_pion && trackParCov.getP() < max_p_for_downscaling_pion) { - return; + if (track.tpcInnerParam() < max_p_for_downscaling_pion) { + if (dist01(engine) > downscaling_pion_lowP) { + return; + } + } else { + if (dist01(engine) > downscaling_pion_highP) { + return; + } } } else if (pidlabel == static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kKaon)) { - if (dist01(engine) > downscaling_kaon && trackParCov.getP() < max_p_for_downscaling_kaon) { - return; + if (track.tpcInnerParam() < max_p_for_downscaling_kaon) { + if (dist01(engine) > downscaling_kaon_lowP) { + return; + } + } else { + if (dist01(engine) > downscaling_kaon_highP) { + return; + } } } else if (pidlabel == static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kProton)) { - if (dist01(engine) > downscaling_proton && trackParCov.getP() < max_p_for_downscaling_proton) { - return; + if (track.tpcInnerParam() < max_p_for_downscaling_proton) { + if (dist01(engine) > downscaling_proton_lowP) { + return; + } + } else { + if (dist01(engine) > downscaling_proton_highP) { + return; + } } } if (std::find(stored_trackIds.begin(), stored_trackIds.end(), track.globalIndex()) == stored_trackIds.end()) { emprimarytracks(collision.numContrib(), collision.trackOccupancyInTimeRange(), collision.ft0cOccupancyInTimeRange(), trackParCov.getP(), trackParCov.getTgl(), track.sign(), - track.tpcNClsFindable(), track.tpcNClsFound(), track.tpcNClsCrossedRows(), + track.tpcNClsFindable(), track.tpcNClsFound(), track.tpcNClsCrossedRows(), track.tpcNClsPID(), track.tpcChi2NCl(), track.tpcInnerParam(), track.tpcSignal(), track.tpcNSigmaEl(), /*track.tpcNSigmaMu(),*/ track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), track.beta(), track.tofNSigmaEl(), /*track.tofNSigmaMu(),*/ track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr(), @@ -700,10 +733,10 @@ struct TreeCreatorElectronMLDDA { } //! type of V0. 0: built solely for cascades (does not pass standard V0 cuts), 1: standard 2, 3: photon-like with TPC-only use. Regular analysis should always use type 1. - Filter v0Filter = o2::aod::v0data::v0Type == uint8_t(1) && o2::aod::v0data::v0cosPA > v0cuts.cfg_min_cospa.value&& o2::aod::v0data::dcaV0daughters v0cuts.cfg_min_dcaxy_v0leg&& nabs(o2::aod::v0data::dcanegtopv) > v0cuts.cfg_min_dcaxy_v0leg; + Filter v0Filter = o2::aod::v0data::v0Type == uint8_t(1) && o2::aod::v0data::v0cosPA > v0cuts.cfg_min_cospa&& o2::aod::v0data::dcaV0daughters v0cuts.cfg_min_dcaxy_v0leg&& nabs(o2::aod::v0data::dcanegtopv) > v0cuts.cfg_min_dcaxy_v0leg; using filteredV0s = soa::Filtered; - Filter cascadeFilter = o2::aod::cascdata::dcacascdaughters < cascadecuts.cfg_max_dcadau.value && nabs(o2::aod::cascdata::dcanegtopv) > cascadecuts.cfg_min_dcaxy_v0leg&& nabs(o2::aod::cascdata::dcanegtopv) > cascadecuts.cfg_min_dcaxy_v0leg&& nabs(o2::aod::cascdata::dcabachtopv) > cascadecuts.cfg_min_dcaxy_bachelor; + Filter cascadeFilter = o2::aod::cascdata::dcacascdaughters < cascadecuts.cfg_max_dcadau && nabs(o2::aod::cascdata::dcanegtopv) > cascadecuts.cfg_min_dcaxy_v0leg&& nabs(o2::aod::cascdata::dcanegtopv) > cascadecuts.cfg_min_dcaxy_v0leg&& nabs(o2::aod::cascdata::dcabachtopv) > cascadecuts.cfg_min_dcaxy_bachelor; using filteredCascades = soa::Filtered; Filter collisionFilter_track_occupancy = eventcuts.cfgTrackOccupancyMin <= o2::aod::evsel::trackOccupancyInTimeRange && o2::aod::evsel::trackOccupancyInTimeRange < eventcuts.cfgTrackOccupancyMax; @@ -739,6 +772,7 @@ struct TreeCreatorElectronMLDDA { auto v0s_coll = v0s.sliceBy(perCollision_v0, collision.globalIndex()); for (const auto& v0 : v0s_coll) { + // auto o2v0 = v0.template v0_as(); auto pos = v0.template posTrack_as(); auto neg = v0.template negTrack_as(); // LOGF(info, "v0.globalIndex() = %d, v0.collisionId() = %d, v0.posTrackId() = %d, v0.negTrackId() = %d", v0.globalIndex(), v0.collisionId(), v0.posTrackId(), v0.negTrackId()); @@ -764,65 +798,77 @@ struct TreeCreatorElectronMLDDA { if (v0cuts.cfg_min_qt_strangeness < v0.qtarm()) { if (!(v0cuts.cfg_min_mass_lambda_veto < v0.mLambda() && v0.mLambda() < v0cuts.cfg_max_mass_lambda_veto) && !(v0cuts.cfg_min_mass_lambda_veto < v0.mAntiLambda() && v0.mAntiLambda() < v0cuts.cfg_max_mass_lambda_veto)) { - if (isPionTight(pos) && isPion(neg)) { - registry.fill(HIST("V0/hMassK0Short"), v0.mK0Short()); - if (v0cuts.cfg_min_mass_k0s < v0.mK0Short() && v0.mK0Short() < v0cuts.cfg_max_mass_k0s) { - registry.fill(HIST("V0/hTPCdEdx_P_Pi"), neg.tpcInnerParam(), neg.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_Pi"), neg.tpcInnerParam(), neg.beta()); - fillTrackTable(collision, neg, static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kPion)); + if ((isPionTight(pos) && isSelectedV0LegTight(collision, pos)) && (isPion(neg) && isSelectedV0Leg(collision, neg))) { + if (!tightv0cuts.requireTOF_for_tagging || pos.hasTOF()) { + registry.fill(HIST("V0/hMassK0Short"), v0.mK0Short()); + if (v0cuts.cfg_min_mass_k0s < v0.mK0Short() && v0.mK0Short() < v0cuts.cfg_max_mass_k0s) { + registry.fill(HIST("V0/hTPCdEdx_P_Pi"), neg.tpcInnerParam(), neg.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_Pi"), neg.tpcInnerParam(), neg.beta()); + fillTrackTable(collision, neg, static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kPion)); + } } } - if (isPion(pos) && isPionTight(neg)) { - registry.fill(HIST("V0/hMassK0Short"), v0.mK0Short()); - if (v0cuts.cfg_min_mass_k0s < v0.mK0Short() && v0.mK0Short() < v0cuts.cfg_max_mass_k0s) { - registry.fill(HIST("V0/hTPCdEdx_P_Pi"), pos.tpcInnerParam(), pos.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_Pi"), pos.tpcInnerParam(), pos.beta()); - fillTrackTable(collision, pos, static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kPion)); + if (isPion(pos) && isSelectedV0Leg(collision, pos) && isPionTight(neg) && isSelectedV0LegTight(collision, neg)) { + if (!tightv0cuts.requireTOF_for_tagging || neg.hasTOF()) { + registry.fill(HIST("V0/hMassK0Short"), v0.mK0Short()); + if (v0cuts.cfg_min_mass_k0s < v0.mK0Short() && v0.mK0Short() < v0cuts.cfg_max_mass_k0s) { + registry.fill(HIST("V0/hTPCdEdx_P_Pi"), pos.tpcInnerParam(), pos.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_Pi"), pos.tpcInnerParam(), pos.beta()); + fillTrackTable(collision, pos, static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kPion)); + } } } - } + } // end of K0S if (!(v0cuts.cfg_min_mass_k0s_veto < v0.mK0Short() && v0.mK0Short() < v0cuts.cfg_max_mass_k0s_veto)) { - if (isProton(pos) && isPionTight(neg)) { - registry.fill(HIST("V0/hMassLambda"), v0.mLambda()); - if (v0cuts.cfg_min_mass_lambda < v0.mLambda() && v0.mLambda() < v0cuts.cfg_max_mass_lambda) { - fillTrackTable(collision, pos, static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kProton)); - registry.fill(HIST("V0/hTPCdEdx_P_Pr"), pos.tpcInnerParam(), pos.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_Pr"), pos.tpcInnerParam(), pos.beta()); + if (isProton(pos) && isSelectedV0Leg(collision, pos) && isPionTight(neg) && isSelectedV0LegTight(collision, neg)) { + if (!tightv0cuts.requireTOF_for_tagging || (neg.hasTOF() || neg.tpcInnerParam() < 0.4)) { + registry.fill(HIST("V0/hMassLambda"), v0.mLambda()); + if (v0cuts.cfg_min_mass_lambda < v0.mLambda() && v0.mLambda() < v0cuts.cfg_max_mass_lambda) { + fillTrackTable(collision, pos, static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kProton)); + registry.fill(HIST("V0/hTPCdEdx_P_Pr"), pos.tpcInnerParam(), pos.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_Pr"), pos.tpcInnerParam(), pos.beta()); + } } - } - if (isPionTight(pos) && isProton(neg)) { - registry.fill(HIST("V0/hMassAntiLambda"), v0.mAntiLambda()); - if (v0cuts.cfg_min_mass_lambda < v0.mAntiLambda() && v0.mAntiLambda() < v0cuts.cfg_max_mass_lambda) { - fillTrackTable(collision, neg, static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kProton)); - registry.fill(HIST("V0/hTPCdEdx_P_Pr"), neg.tpcInnerParam(), neg.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_Pr"), neg.tpcInnerParam(), neg.beta()); + } // end of Lambda + if (isPionTight(pos) && isSelectedV0LegTight(collision, pos) && isProton(neg) && isSelectedV0Leg(collision, neg)) { + if (!tightv0cuts.requireTOF_for_tagging || (pos.hasTOF() || pos.tpcInnerParam() < 0.4)) { + registry.fill(HIST("V0/hMassAntiLambda"), v0.mAntiLambda()); + if (v0cuts.cfg_min_mass_lambda < v0.mAntiLambda() && v0.mAntiLambda() < v0cuts.cfg_max_mass_lambda) { + fillTrackTable(collision, neg, static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kProton)); + registry.fill(HIST("V0/hTPCdEdx_P_Pr"), neg.tpcInnerParam(), neg.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_Pr"), neg.tpcInnerParam(), neg.beta()); + } } - } + } // end of AntiLambda } } // end of stangeness - if (isElectronTight(pos) && isElectron(neg)) { - registry.fill(HIST("V0/hMassGamma"), v0.mGamma()); - registry.fill(HIST("V0/hMassGamma_Rxy"), v0.v0radius(), v0.mGamma()); - if (v0cuts.cfg_min_mass_photon < v0.mGamma() && v0.mGamma() < v0cuts.cfg_max_mass_photon) { - registry.fill(HIST("V0/hXY_Gamma"), v0.x(), v0.y()); - fillTrackTable(collision, neg, static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kElectron)); - registry.fill(HIST("V0/hTPCdEdx_P_El"), neg.tpcInnerParam(), neg.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_El"), neg.tpcInnerParam(), neg.beta()); + if (isElectronTight(pos) && isSelectedV0LegTight(collision, pos) && isElectron(neg) && isSelectedV0Leg(collision, neg)) { + if (!tightv0cuts.requireTOF_for_tagging || pos.hasTOF()) { + registry.fill(HIST("V0/hMassGamma"), v0.mGamma()); + registry.fill(HIST("V0/hMassGamma_Rxy"), v0.v0radius(), v0.mGamma()); + if (v0cuts.cfg_min_mass_photon < v0.mGamma() && v0.mGamma() < v0cuts.cfg_max_mass_photon) { + registry.fill(HIST("V0/hXY_Gamma"), v0.x(), v0.y()); + fillTrackTable(collision, neg, static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kElectron)); + registry.fill(HIST("V0/hTPCdEdx_P_El"), neg.tpcInnerParam(), neg.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_El"), neg.tpcInnerParam(), neg.beta()); + } } - } - - if (isElectron(pos) && isElectronTight(neg)) { - registry.fill(HIST("V0/hMassGamma"), v0.mGamma()); - registry.fill(HIST("V0/hMassGamma_Rxy"), v0.v0radius(), v0.mGamma()); - if (v0cuts.cfg_min_mass_photon < v0.mGamma() && v0.mGamma() < v0cuts.cfg_max_mass_photon) { - registry.fill(HIST("V0/hXY_Gamma"), v0.x(), v0.y()); - fillTrackTable(collision, pos, static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kElectron)); - registry.fill(HIST("V0/hTPCdEdx_P_El"), pos.tpcInnerParam(), pos.tpcSignal()); - registry.fill(HIST("V0/hTOFbeta_P_El"), pos.tpcInnerParam(), pos.beta()); + } // end of photon conversion + + if (isElectron(pos) && isSelectedV0Leg(collision, pos) && isElectronTight(neg) && isSelectedV0LegTight(collision, neg)) { + if (!tightv0cuts.requireTOF_for_tagging || neg.hasTOF()) { + registry.fill(HIST("V0/hMassGamma"), v0.mGamma()); + registry.fill(HIST("V0/hMassGamma_Rxy"), v0.v0radius(), v0.mGamma()); + if (v0cuts.cfg_min_mass_photon < v0.mGamma() && v0.mGamma() < v0cuts.cfg_max_mass_photon) { + registry.fill(HIST("V0/hXY_Gamma"), v0.x(), v0.y()); + fillTrackTable(collision, pos, static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kElectron)); + registry.fill(HIST("V0/hTPCdEdx_P_El"), pos.tpcInnerParam(), pos.tpcSignal()); + registry.fill(HIST("V0/hTOFbeta_P_El"), pos.tpcInnerParam(), pos.beta()); + } } - } + } // end of photon conversion } // end of v0 loop @@ -840,10 +886,16 @@ struct TreeCreatorElectronMLDDA { if (!isProtonTight(pos) || !isPionTight(neg)) { continue; } + if (cascadecuts.requireTOF_for_tagging && (!pos.hasTOF() && !neg.hasTOF())) { // require TOF to proton candidates. // pion from L is soft. Don't require TOF for soft pions. + continue; + } } else { // Omegabar+ -> Lbar + K+ -> pbar + pi+ + K+ if (!isProtonTight(neg) || !isPionTight(pos)) { continue; } + if (cascadecuts.requireTOF_for_tagging && (!pos.hasTOF() && !neg.hasTOF())) { // require TOF to anti-proton candidates. // pion from L is soft. Don't require TOF for soft pions. + continue; + } } if (!(cascadecuts.cfg_min_mass_lambda < cascade.mLambda() && cascade.mLambda() < cascadecuts.cfg_max_mass_lambda)) { @@ -875,7 +927,11 @@ struct TreeCreatorElectronMLDDA { continue; } - if (!isSelectedV0Leg(collision, pos) || !isSelectedV0Leg(collision, neg) || !isSelectedV0Leg(collision, bachelor)) { + if (cascade.dcav0topv(collision.posX(), collision.posY(), collision.posZ()) < cascadecuts.cfg_min_dcaxy_v0) { + continue; + } + + if (!isSelectedV0LegTight(collision, pos) || !isSelectedV0LegTight(collision, neg) || !isSelectedV0Leg(collision, bachelor)) { continue; } @@ -916,8 +972,8 @@ struct TreeCreatorElectronMLDDA { // please choose only 1 process function. void processDummy(filteredMyCollisions const&) {} - PROCESS_SWITCH(TreeCreatorElectronMLDDA, processPID, "produce ML input for single track level", false); // this is for eID with ITSsa. e/pi/k/p are selected by TOF, and these can be used for ITS-TPC PID. - PROCESS_SWITCH(TreeCreatorElectronMLDDA, processDummy, "process dummy", true); + PROCESS_SWITCH(TreeCreatorElectronMLDDA, processPID, "produce ML input for single track level", true); // this is for eID with ITSsa. e/pi/k/p are selected by TOF, and these can be used for ITS-TPC PID. + PROCESS_SWITCH(TreeCreatorElectronMLDDA, processDummy, "process dummy", false); }; struct MLTrackQC { @@ -925,63 +981,63 @@ struct MLTrackQC { HistogramRegistry registry{ "registry", { - {"hTPCdEdx_P_All", "TPC dE/dx vs. p;p_{pv} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0.f, 5.f}, {200, 0, 200}}}}, - {"hTOFbeta_P_All", "TOF beta vs. p;p_{pv} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0.f, 5.f}, {220, 0.0, 1.1}}}}, - {"hITSobClusterSize_P_All", "mean ITSob cluster size vs. p;p_{pv} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {150, 0.0, 15}}}}, - {"hTPCdEdx_P_Electron", "TPC dE/dx vs. p;p_{pv} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0.f, 5.f}, {200, 0, 200}}}}, - {"hTOFbeta_P_Electron", "TOF beta vs. p;p_{pv} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0.f, 5.f}, {220, 0.0, 1.1}}}}, - {"hITSobClusterSize_P_Electron", "mean ITSob cluster size vs. p;p_{pv} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {150, 0.0, 15}}}}, - {"hTPCdEdx_P_Pion", "TPC dE/dx vs. p;p_{pv} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0.f, 5.f}, {200, 0, 200}}}}, - {"hTOFbeta_P_Pion", "TOF beta vs. p;p_{pv} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0.f, 5.f}, {220, 0.0, 1.1}}}}, - {"hITSobClusterSize_P_Pion", "mean ITSob cluster size vs. p;p_{pv} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {150, 0.0, 15}}}}, - {"hTPCdEdx_P_Kaon", "TPC dE/dx vs. p;p_{pv} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0.f, 5.f}, {200, 0, 200}}}}, - {"hTOFbeta_P_Kaon", "TOF beta vs. p;p_{pv} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0.f, 5.f}, {220, 0.0, 1.1}}}}, - {"hITSobClusterSize_P_Kaon", "mean ITSob cluster size vs. p;p_{pv} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {150, 0.0, 15}}}}, - {"hTPCdEdx_P_Proton", "TPC dE/dx vs. p;p_{pv} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{500, 0.f, 5.f}, {200, 0, 200}}}}, - {"hTOFbeta_P_Proton", "TOF beta vs. p;p_{pv} (GeV/c);TOF #beta", {HistType::kTH2F, {{500, 0.f, 5.f}, {220, 0.0, 1.1}}}}, - {"hITSobClusterSize_P_Proton", "mean ITSob cluster size vs. p;p_{pv} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{500, 0.f, 5.f}, {150, 0.0, 15}}}}, - - {"hTPCNsigmaEl_P", "TPC n#sigma_{e} vs. p;p_{pv} (GeV/c);n #sigma_{e}^{TPC}", {HistType::kTH2F, {{500, 0.f, 5.f}, {100, -5, +5}}}}, - {"hTPCNsigmaPi_P", "TPC n#sigma_{#pi} vs. p;p_{pv} (GeV/c);n #sigma_{#pi}^{TPC}", {HistType::kTH2F, {{500, 0.f, 5.f}, {100, -5, +5}}}}, - {"hTPCNsigmaKa_P", "TPC n#sigma_{K} vs. p;p_{pv} (GeV/c);n #sigma_{K}^{TPC}", {HistType::kTH2F, {{500, 0.f, 5.f}, {100, -5, +5}}}}, - {"hTPCNsigmaPr_P", "TPC n#sigma_{p} vs. p;p_{pv} (GeV/c);n #sigma_{p}^{TPC}", {HistType::kTH2F, {{500, 0.f, 5.f}, {100, -5, +5}}}}, - {"hTOFNsigmaEl_P", "TOF n#sigma_{e} vs. p;p_{pv} (GeV/c);n #sigma_{e}^{TOF}", {HistType::kTH2F, {{500, 0.f, 5.f}, {100, -5, +5}}}}, - {"hTOFNsigmaPi_P", "TOF n#sigma_{#pi} vs. p;p_{pv} (GeV/c);n #sigma_{#pi}^{TOF}", {HistType::kTH2F, {{500, 0.f, 5.f}, {100, -5, +5}}}}, - {"hTOFNsigmaKa_P", "TOF n#sigma_{K} vs. p;p_{pv} (GeV/c);n #sigma_{K}^{TOF}", {HistType::kTH2F, {{500, 0.f, 5.f}, {100, -5, +5}}}}, - {"hTOFNsigmaPr_P", "TOF n#sigma_{p} vs. p;p_{pv} (GeV/c);n #sigma_{p}^{TOF}", {HistType::kTH2F, {{500, 0.f, 5.f}, {100, -5, +5}}}}, + {"hTPCdEdx_P_All", "TPC dE/dx vs. p;p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{1000, 0.f, 10.f}, {200, 0, 200}}}}, + {"hTOFbeta_P_All", "TOF beta vs. p;p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{1000, 0.f, 10.f}, {220, 0.0, 1.1}}}}, + {"hITSobClusterSize_P_All", "mean ITSob cluster size vs. p;p_{in} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{1000, 0.f, 10.f}, {150, 0.0, 15}}}}, + {"hTPCdEdx_P_Electron", "TPC dE/dx vs. p;p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{1000, 0.f, 10.f}, {200, 0, 200}}}}, + {"hTOFbeta_P_Electron", "TOF beta vs. p;p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{1000, 0.f, 10.f}, {220, 0.0, 1.1}}}}, + {"hITSobClusterSize_P_Electron", "mean ITSob cluster size vs. p;p_{in} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{1000, 0.f, 10.f}, {150, 0.0, 15}}}}, + {"hTPCdEdx_P_Pion", "TPC dE/dx vs. p;p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{1000, 0.f, 10.f}, {200, 0, 200}}}}, + {"hTOFbeta_P_Pion", "TOF beta vs. p;p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{1000, 0.f, 10.f}, {220, 0.0, 1.1}}}}, + {"hITSobClusterSize_P_Pion", "mean ITSob cluster size vs. p;p_{in} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{1000, 0.f, 10.f}, {150, 0.0, 15}}}}, + {"hTPCdEdx_P_Kaon", "TPC dE/dx vs. p;p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{1000, 0.f, 10.f}, {200, 0, 200}}}}, + {"hTOFbeta_P_Kaon", "TOF beta vs. p;p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{1000, 0.f, 10.f}, {220, 0.0, 1.1}}}}, + {"hITSobClusterSize_P_Kaon", "mean ITSob cluster size vs. p;p_{in} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{1000, 0.f, 10.f}, {150, 0.0, 15}}}}, + {"hTPCdEdx_P_Proton", "TPC dE/dx vs. p;p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{1000, 0.f, 10.f}, {200, 0, 200}}}}, + {"hTOFbeta_P_Proton", "TOF beta vs. p;p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{1000, 0.f, 10.f}, {220, 0.0, 1.1}}}}, + {"hITSobClusterSize_P_Proton", "mean ITSob cluster size vs. p;p_{in} (GeV/c); #times cos(#lambda)", {HistType::kTH2F, {{1000, 0.f, 10.f}, {150, 0.0, 15}}}}, + + {"hTPCNsigmaEl_P", "TPC n#sigma_{e} vs. p;p_{in} (GeV/c);n #sigma_{e}^{TPC}", {HistType::kTH2F, {{1000, 0.f, 10.f}, {100, -5, +5}}}}, + {"hTPCNsigmaPi_P", "TPC n#sigma_{#pi} vs. p;p_{in} (GeV/c);n #sigma_{#pi}^{TPC}", {HistType::kTH2F, {{1000, 0.f, 10.f}, {100, -5, +5}}}}, + {"hTPCNsigmaKa_P", "TPC n#sigma_{K} vs. p;p_{in} (GeV/c);n #sigma_{K}^{TPC}", {HistType::kTH2F, {{1000, 0.f, 10.f}, {100, -5, +5}}}}, + {"hTPCNsigmaPr_P", "TPC n#sigma_{p} vs. p;p_{in} (GeV/c);n #sigma_{p}^{TPC}", {HistType::kTH2F, {{1000, 0.f, 10.f}, {100, -5, +5}}}}, + {"hTOFNsigmaEl_P", "TOF n#sigma_{e} vs. p;p_{in} (GeV/c);n #sigma_{e}^{TOF}", {HistType::kTH2F, {{1000, 0.f, 10.f}, {100, -5, +5}}}}, + {"hTOFNsigmaPi_P", "TOF n#sigma_{#pi} vs. p;p_{in} (GeV/c);n #sigma_{#pi}^{TOF}", {HistType::kTH2F, {{1000, 0.f, 10.f}, {100, -5, +5}}}}, + {"hTOFNsigmaKa_P", "TOF n#sigma_{K} vs. p;p_{in} (GeV/c);n #sigma_{K}^{TOF}", {HistType::kTH2F, {{1000, 0.f, 10.f}, {100, -5, +5}}}}, + {"hTOFNsigmaPr_P", "TOF n#sigma_{p} vs. p;p_{in} (GeV/c);n #sigma_{p}^{TOF}", {HistType::kTH2F, {{1000, 0.f, 10.f}, {100, -5, +5}}}}, }, }; void processQC(aod::EMTracksForMLPID const& tracks) { for (const auto& track : tracks) { - registry.fill(HIST("hTPCdEdx_P_All"), track.p(), track.tpcSignal()); - registry.fill(HIST("hTOFbeta_P_All"), track.p(), track.beta()); - registry.fill(HIST("hITSobClusterSize_P_All"), track.p(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); + registry.fill(HIST("hTPCdEdx_P_All"), track.tpcInnerParam(), track.tpcSignal()); + registry.fill(HIST("hTOFbeta_P_All"), track.tpcInnerParam(), track.beta()); + registry.fill(HIST("hITSobClusterSize_P_All"), track.tpcInnerParam(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); if (track.pidlabel() == static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kElectron)) { - registry.fill(HIST("hTPCdEdx_P_Electron"), track.p(), track.tpcSignal()); - registry.fill(HIST("hTOFbeta_P_Electron"), track.p(), track.beta()); - registry.fill(HIST("hITSobClusterSize_P_Electron"), track.p(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); - registry.fill(HIST("hTPCNsigmaEl_P"), track.p(), track.tpcNSigmaEl()); - registry.fill(HIST("hTOFNsigmaEl_P"), track.p(), track.tofNSigmaEl()); + registry.fill(HIST("hTPCdEdx_P_Electron"), track.tpcInnerParam(), track.tpcSignal()); + registry.fill(HIST("hTOFbeta_P_Electron"), track.tpcInnerParam(), track.beta()); + registry.fill(HIST("hITSobClusterSize_P_Electron"), track.tpcInnerParam(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); + registry.fill(HIST("hTPCNsigmaEl_P"), track.tpcInnerParam(), track.tpcNSigmaEl()); + registry.fill(HIST("hTOFNsigmaEl_P"), track.tpcInnerParam(), track.tofNSigmaEl()); } else if (track.pidlabel() == static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kPion)) { - registry.fill(HIST("hTPCdEdx_P_Pion"), track.p(), track.tpcSignal()); - registry.fill(HIST("hTOFbeta_P_Pion"), track.p(), track.beta()); - registry.fill(HIST("hITSobClusterSize_P_Pion"), track.p(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); - registry.fill(HIST("hTPCNsigmaPi_P"), track.p(), track.tpcNSigmaPi()); - registry.fill(HIST("hTOFNsigmaPi_P"), track.p(), track.tofNSigmaPi()); + registry.fill(HIST("hTPCdEdx_P_Pion"), track.tpcInnerParam(), track.tpcSignal()); + registry.fill(HIST("hTOFbeta_P_Pion"), track.tpcInnerParam(), track.beta()); + registry.fill(HIST("hITSobClusterSize_P_Pion"), track.tpcInnerParam(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); + registry.fill(HIST("hTPCNsigmaPi_P"), track.tpcInnerParam(), track.tpcNSigmaPi()); + registry.fill(HIST("hTOFNsigmaPi_P"), track.tpcInnerParam(), track.tofNSigmaPi()); } else if (track.pidlabel() == static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kKaon)) { - registry.fill(HIST("hTPCdEdx_P_Kaon"), track.p(), track.tpcSignal()); - registry.fill(HIST("hTOFbeta_P_Kaon"), track.p(), track.beta()); - registry.fill(HIST("hITSobClusterSize_P_Kaon"), track.p(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); - registry.fill(HIST("hTPCNsigmaKa_P"), track.p(), track.tpcNSigmaKa()); - registry.fill(HIST("hTOFNsigmaKa_P"), track.p(), track.tofNSigmaKa()); + registry.fill(HIST("hTPCdEdx_P_Kaon"), track.tpcInnerParam(), track.tpcSignal()); + registry.fill(HIST("hTOFbeta_P_Kaon"), track.tpcInnerParam(), track.beta()); + registry.fill(HIST("hITSobClusterSize_P_Kaon"), track.tpcInnerParam(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); + registry.fill(HIST("hTPCNsigmaKa_P"), track.tpcInnerParam(), track.tpcNSigmaKa()); + registry.fill(HIST("hTOFNsigmaKa_P"), track.tpcInnerParam(), track.tofNSigmaKa()); } else if (track.pidlabel() == static_cast(o2::aod::pwgem::dilepton::ml::PID_Label::kProton)) { - registry.fill(HIST("hTPCdEdx_P_Proton"), track.p(), track.tpcSignal()); - registry.fill(HIST("hTOFbeta_P_Proton"), track.p(), track.beta()); - registry.fill(HIST("hITSobClusterSize_P_Proton"), track.p(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); - registry.fill(HIST("hTPCNsigmaPr_P"), track.p(), track.tpcNSigmaPr()); - registry.fill(HIST("hTOFNsigmaPr_P"), track.p(), track.tofNSigmaPr()); + registry.fill(HIST("hTPCdEdx_P_Proton"), track.tpcInnerParam(), track.tpcSignal()); + registry.fill(HIST("hTOFbeta_P_Proton"), track.tpcInnerParam(), track.beta()); + registry.fill(HIST("hITSobClusterSize_P_Proton"), track.tpcInnerParam(), track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl()))); + registry.fill(HIST("hTPCNsigmaPr_P"), track.tpcInnerParam(), track.tpcNSigmaPr()); + registry.fill(HIST("hTOFNsigmaPr_P"), track.tpcInnerParam(), track.tofNSigmaPr()); } } // end of track loop } diff --git a/PWGEM/Dilepton/Tasks/CMakeLists.txt b/PWGEM/Dilepton/Tasks/CMakeLists.txt index 94ccb5f2ea4..fb0fb81fbcc 100644 --- a/PWGEM/Dilepton/Tasks/CMakeLists.txt +++ b/PWGEM/Dilepton/Tasks/CMakeLists.txt @@ -161,3 +161,7 @@ o2physics_add_dpl_workflow(dimuon-hadron-mpc PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore O2Physics::MLCore O2Physics::PWGEMDileptonCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(mc-particle-predictions-otf + SOURCES mcParticlePredictionsOTF.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGEM/Dilepton/Tasks/Converters/CMakeLists.txt b/PWGEM/Dilepton/Tasks/Converters/CMakeLists.txt index 7e02c208968..f5f41c009cd 100644 --- a/PWGEM/Dilepton/Tasks/Converters/CMakeLists.txt +++ b/PWGEM/Dilepton/Tasks/Converters/CMakeLists.txt @@ -15,6 +15,11 @@ o2physics_add_dpl_workflow(event-converter2 PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(event-converter3 + SOURCES eventConverter3.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(electron-converter2 SOURCES electronConverter2.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore @@ -25,3 +30,13 @@ o2physics_add_dpl_workflow(electron-converter3 PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(electron-converter4 + SOURCES electronConverter4.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(track-converter1 + SOURCES trackConverter1.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + diff --git a/PWGEM/Dilepton/Tasks/Converters/electronConverter4.cxx b/PWGEM/Dilepton/Tasks/Converters/electronConverter4.cxx new file mode 100644 index 00000000000..dcca6b5edc1 --- /dev/null +++ b/PWGEM/Dilepton/Tasks/Converters/electronConverter4.cxx @@ -0,0 +1,124 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// ======================== +// +// This code runs loop over ULS ee pars for virtual photon QC. +// Please write to: daiki.sekihata@cern.ch + +#include "PWGEM/Dilepton/DataModel/dileptonTables.h" + +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +using namespace o2; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +struct electronConverter4 { + Produces track_004; + + using MyElectrons002 = soa::Join; + void process002to004(MyElectrons002 const& tracks) + { + for (const auto& track : tracks) { + track_004(track.collisionId(), + track.trackId(), + track.sign(), + track.pt(), + track.eta(), + track.phi(), + track.dcaXY(), + track.dcaZ(), + track.cYY(), + track.cZY(), + track.cZZ(), + track.tpcNClsFindable(), + track.tpcNClsFindableMinusFound(), + track.tpcNClsFindableMinusCrossedRows(), + track.tpcNClsShared(), + track.tpcChi2NCl(), + track.tpcInnerParam(), + track.tpcSignal(), + track.tpcNSigmaEl(), + track.tpcNSigmaPi(), + track.tpcNSigmaKa(), + track.tpcNSigmaPr(), + track.beta(), + track.tofNSigmaEl(), + // track.tofNSigmaPi(), + // track.tofNSigmaKa(), + // track.tofNSigmaPr(), + track.itsClusterSizes(), + track.itsChi2NCl(), + track.tofChi2(), + track.detectorMap(), + // track.tgl(), + track.isAssociatedToMPC(), + false, + 0.f, + 0.f); + } // end of track loop + } + PROCESS_SWITCH(electronConverter4, process002to004, "convert from 002 into 004", false); + + using MyElectrons003 = soa::Join; + void process003to004(MyElectrons003 const& tracks) + { + for (const auto& track : tracks) { + track_004(track.collisionId(), + track.trackId(), + track.sign(), + track.pt(), + track.eta(), + track.phi(), + track.dcaXY(), + track.dcaZ(), + track.cYY(), + track.cZY(), + track.cZZ(), + track.tpcNClsFindable(), + track.tpcNClsFindableMinusFound(), + track.tpcNClsFindableMinusCrossedRows(), + track.tpcNClsShared(), + track.tpcChi2NCl(), + track.tpcInnerParam(), + track.tpcSignal(), + track.tpcNSigmaEl(), + track.tpcNSigmaPi(), + track.tpcNSigmaKa(), + track.tpcNSigmaPr(), + track.beta(), + track.tofNSigmaEl(), + // track.tofNSigmaPi(), + // track.tofNSigmaKa(), + // track.tofNSigmaPr(), + track.itsClusterSizes(), + track.itsChi2NCl(), + track.tofChi2(), + track.detectorMap(), + // track.tgl(), + track.isAssociatedToMPC(), + false, + 0.f, + track.mcTunedTPCSignal()); + } // end of track loop + } + PROCESS_SWITCH(electronConverter4, process003to004, "convert from 003 into 004", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"electron-converter4"})}; +} diff --git a/PWGEM/Dilepton/Tasks/Converters/eventConverter3.cxx b/PWGEM/Dilepton/Tasks/Converters/eventConverter3.cxx new file mode 100644 index 00000000000..fe22e18f859 --- /dev/null +++ b/PWGEM/Dilepton/Tasks/Converters/eventConverter3.cxx @@ -0,0 +1,54 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// ======================== +// +// This code runs loop over ULS ee pars for virtual photon QC. +// Please write to: daiki.sekihata@cern.ch + +#include "PWGEM/Dilepton/DataModel/dileptonTables.h" + +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +using namespace o2; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +struct eventConverter3 { + Produces event_003; + + void process(aod::EMEvents_002 const& collisions) + { + for (auto& collision : collisions) { + event_003( + collision.globalIndex(), + collision.runNumber(), + collision.globalBC(), + collision.alias_raw(), + collision.selection_raw(), + collision.rct_raw(), + collision.timestamp(), + collision.posZ(), + collision.numContrib(), + collision.trackOccupancyInTimeRange(), + collision.ft0cOccupancyInTimeRange()); + } // end of collision loop + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"event-converter3"})}; +} diff --git a/PWGEM/Dilepton/Tasks/Converters/trackConverter1.cxx b/PWGEM/Dilepton/Tasks/Converters/trackConverter1.cxx new file mode 100644 index 00000000000..fda87265b3c --- /dev/null +++ b/PWGEM/Dilepton/Tasks/Converters/trackConverter1.cxx @@ -0,0 +1,48 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// ======================== +// +// This code runs loop over ULS ee pars for virtual photon QC. +// Please write to: daiki.sekihata@cern.ch + +#include "PWGEM/Dilepton/DataModel/dileptonTables.h" + +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +using namespace o2; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +struct trackConverter1 { + Produces track_001; + + void process(aod::EMPrimaryTracks_000 const& tracks) + { + for (auto& track : tracks) { + track_001(track.collisionId(), + track.trackId(), + track.sign() / track.pt(), + track.eta(), + track.phi(), + track.trackBit()); + } // end of track loop + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"track-converter1"})}; +} diff --git a/PWGEM/Dilepton/Tasks/emEfficiencyEE.cxx b/PWGEM/Dilepton/Tasks/emEfficiencyEE.cxx index 7cc41a190d2..76b523ec64c 100644 --- a/PWGEM/Dilepton/Tasks/emEfficiencyEE.cxx +++ b/PWGEM/Dilepton/Tasks/emEfficiencyEE.cxx @@ -12,41 +12,45 @@ // // Analysis task for calculating single electron and dielectron efficiency // -#include -#include -#include -#include -#include -#include -#include -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/ASoA.h" -#include "Framework/DataTypes.h" -#include "Framework/HistogramRegistry.h" -#include "PWGDQ/Core/VarManager.h" -#include "PWGDQ/Core/HistogramManager.h" -#include "PWGDQ/Core/AnalysisCut.h" #include "PWGDQ/Core/AnalysisCompositeCut.h" -#include "PWGDQ/Core/HistogramsLibrary.h" +#include "PWGDQ/Core/AnalysisCut.h" #include "PWGDQ/Core/CutsLibrary.h" +#include "PWGDQ/Core/HistogramManager.h" +#include "PWGDQ/Core/HistogramsLibrary.h" #include "PWGDQ/Core/MCSignal.h" #include "PWGDQ/Core/MCSignalLibrary.h" +#include "PWGDQ/Core/VarManager.h" #include "PWGDQ/DataModel/ReducedInfoTables.h" +#include "PWGEM/Dilepton/DataModel/dileptonTables.h" + +#include "Common/CCDB/TriggerAliases.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Centrality.h" -#include "Common/CCDB/TriggerAliases.h" + +#include "CCDB/BasicCCDBManager.h" #include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" #include "Field/MagneticField.h" +#include "Framework/ASoA.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/DataTypes.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + #include "TGeoGlobalMagField.h" -#include "PWGEM/Dilepton/DataModel/dileptonTables.h" +#include +#include +#include +#include +#include + +#include +#include using std::cout; using std::endl; @@ -457,7 +461,7 @@ struct AnalysisTrackSelection { ConfigurableAxis deltaphiResBins{"deltaphiResBins", {500, -0.5f, 0.5f}, "DeltaPhi binning for resolution"}; Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; - Configurable fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"}; + Configurable fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"}; // output lists OutputObj fOutputQA{"SingleElectronQA"}; @@ -1027,8 +1031,8 @@ struct AnalysisTrackSelection { fHistManQA->FillHistClass(fHistNamesMCMatchedQA[j][i].Data(), VarManager::fgValues); } } // end loop over cuts - } // end loop over MC signals - } // end loop over reconstructed track belonging to the events + } // end loop over MC signals + } // end loop over reconstructed track belonging to the events } template @@ -1275,8 +1279,8 @@ struct AnalysisTrackSelection { fHistManQA->FillHistClass(fHistNamesMCMatchedQA[j][i].Data(), VarManager::fgValues); } } // end loop over cuts - } // end loop over MC signals - } // end loop over reconstructed track belonging to the events + } // end loop over MC signals + } // end loop over reconstructed track belonging to the events } void processSkimmed(soa::Filtered const& events, MyBarrelTracks const& tracks, ReducedMCEvents const& eventsMC, ReducedMCTracks const& tracksMC) @@ -1601,7 +1605,7 @@ struct AnalysisSameEventPairing { runRecPair(groupedTracks, tracksMC); } } // end loop over reconstructed event - } // end loop pairing function + } // end loop pairing function template void runMCPairing(TEventMC const& /*eventMC*/, TTracksMC const& tracksMC) @@ -1716,7 +1720,7 @@ struct AnalysisSameEventPairing { } } } // end of true pairing loop - } // end runMCGen + } // end runMCGen template void runRecPair(TTracks const& tracks, TTracksMC const& /*tracksMC*/) diff --git a/PWGEM/Dilepton/Tasks/eventQC.cxx b/PWGEM/Dilepton/Tasks/eventQC.cxx index 60ff83b2da1..eb46e057ace 100644 --- a/PWGEM/Dilepton/Tasks/eventQC.cxx +++ b/PWGEM/Dilepton/Tasks/eventQC.cxx @@ -69,7 +69,7 @@ struct eventQC { Configurable> cfgnMods{"cfgnMods", {2, 3}, "Modulation of interest. Please keep increasing order"}; Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; Configurable cfgQvecEstimator{"cfgQvecEstimator", 0, "FT0M:0, FT0A:1, FT0C:2, BTot:3, BPos:4, BNeg:5"}; - Configurable cfgCentMin{"cfgCentMin", 0, "min. centrality"}; + Configurable cfgCentMin{"cfgCentMin", -1.f, "min. centrality"}; Configurable cfgCentMax{"cfgCentMax", 999.f, "max. centrality"}; Configurable cfgNtracksPV08Min{"cfgNtracksPV08Min", -1, "min. multNTracksPV"}; Configurable cfgNtracksPV08Max{"cfgNtracksPV08Max", 1000000000, "max. multNTracksPV"}; @@ -77,6 +77,12 @@ struct eventQC { Configurable cfgNbinsEta{"cfgNbinsEta", 20, "number of eta bins for output histograms"}; Configurable cfgNbinsPhi{"cfgNbinsPhi", 36, "number of phi bins for output histograms"}; + ConfigurableAxis ConfFT0AMultBins{"ConfFT0AMultBins", {200, 0, 200e+3}, "FT0A multiplicity bins for output histograms"}; + ConfigurableAxis ConfFT0CMultBins{"ConfFT0CMultBins", {600, 0, 60e+3}, "FT0C multiplicity bins for output histograms"}; + ConfigurableAxis ConfFV0AMultBins{"ConfFV0AMultBins", {200, 0, 200e+3}, "FV0A multiplicity bins for output histograms"}; + ConfigurableAxis ConfTrackMultBins{"ConfTrackMultBins", {6001, -0.5, 6e+3 + 0.5}, "Track multiplicity bins for output histograms"}; + ConfigurableAxis ConfCentBins{"ConfCentBins", {110, 0, 110}, "centrality bins for output histograms"}; + struct : ConfigurableGroup { std::string prefix = "eventcut_group"; Configurable cfgZvtxMin{"cfgZvtxMin", -10.f, "min. Zvtx"}; @@ -181,8 +187,30 @@ struct eventQC { void addhistograms() { - // event info + const AxisSpec axis_cent_ft0m{ConfCentBins, "centrality FT0M (%)"}; + const AxisSpec axis_cent_ft0a{ConfCentBins, "centrality FT0A (%)"}; + const AxisSpec axis_cent_ft0c{ConfCentBins, "centrality FT0C (%)"}; + + const AxisSpec axis_mult_ft0a{ConfFT0AMultBins, "FT0A multiplicity"}; + const AxisSpec axis_mult_ft0c{ConfFT0CMultBins, "FT0C multiplicity"}; + const AxisSpec axis_mult_fv0a{ConfFV0AMultBins, "FV0A multiplicity"}; + const AxisSpec axis_mult_ncontrib{ConfTrackMultBins, "N_{track} to PV"}; + const AxisSpec axis_mult_ncontrib08{ConfTrackMultBins, "N_{track} to PV in |#eta| < 0.8"}; + const AxisSpec axis_mult_global_ncontrib08{ConfTrackMultBins, "N_{track}^{global} to PV in |#eta| < 0.8"}; + const AxisSpec axis_mult_globalTrack{ConfTrackMultBins, "N_{track}^{global} in |#eta| < 0.8"}; + + if (doprocessEventQC_SWT) { + fRegistry.add("BC/hNcoll", "Number of collisions per triggered BC;N_{collision} per triggered BC", kTH1F, {{11, -0.5, +10.5}}, false); + fRegistry.add("BC/hDeltaT", "diff. in collision time per BC;#DeltaT_{coll} (ns)", kTH1F, {{500, -25, +25}}, false); + fRegistry.add("BC/hDeltaZ", "diff. in collision Z_{vtx} per BC;#DeltaZ_{vtx} (cm)", kTH1F, {{1000, -5, +5}}, false); + fRegistry.add("BC/hCorrNcontrib", "hMultNTracksPV;", kTH2F, {{axis_mult_ncontrib}, {axis_mult_ncontrib}}, false); + fRegistry.add("BC/Collision/hMultNTracksPV", "hMultNTracksPV;N_{track} to PV in |#eta| < 0.8", kTH1F, {{axis_mult_ncontrib08}}, false); + fRegistry.add("BC/Collision/hMultFT0AFT0C", "hMultFT0AFT0C;mult. FT0A;mult. FT0C", kTH2F, {{axis_mult_ft0a}, {axis_mult_ft0c}}, false); + fRegistry.add("BC/Collision/hMultFT0AFV0A", "hMultFT0AFV0A;mult. FT0A;mult. FV0A", kTH2F, {{axis_mult_ft0a}, {axis_mult_fv0a}}, false); + fRegistry.add("BC/Collision/hMultFT0CFV0A", "hMultFT0CFV0A;mult. FT0C;mult. FV0A", kTH2F, {{axis_mult_ft0c}, {axis_mult_fv0a}}, false); + } + // event info const int nbin_ev = 20; auto hCollisionCounter = fRegistry.add("Event/before/hCollisionCounter", "collision counter;;Number of events", kTH1F, {{nbin_ev, 0.5, nbin_ev + 0.5}}, false); hCollisionCounter->GetXaxis()->SetBinLabel(1, "all"); @@ -208,52 +236,33 @@ struct eventQC { fRegistry.add("hNInspectedTVX", "N inspected TVX;run number;N_{TVX}", kTProfile, {{80000, 520000.5, 600000.5}}, true); - const AxisSpec axis_cent_ft0m{{0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110}, - "centrality FT0M (%)"}; - - const AxisSpec axis_cent_ft0a{{0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110}, - "centrality FT0A (%)"}; - - const AxisSpec axis_cent_ft0c{{0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110}, - "centrality FT0C (%)"}; - if (cfgFillEvent) { fRegistry.add("Event/before/hZvtx", "vertex z; Z_{vtx} (cm)", kTH1F, {{100, -50, +50}}, false); - fRegistry.add("Event/before/hMultNTracksPV", "hMultNTracksPV; N_{track} to PV", kTH1F, {{6001, -0.5, 6000.5}}, false); - fRegistry.add("Event/before/hMultNTracksPVeta1", "hMultNTracksPVeta1; N_{track} to PV", kTH1F, {{6001, -0.5, 6000.5}}, false); - fRegistry.add("Event/before/hMultFT0", "hMultFT0;mult. FT0A;mult. FT0C", kTH2F, {{200, 0, 200000}, {60, 0, 60000}}, false); + fRegistry.add("Event/before/hMultNTracksPV", "hMultNTracksPV; N_{track} to PV in |#eta| < 0.8", kTH1F, {{axis_mult_ncontrib08}}, false); + fRegistry.add("Event/before/hMultFT0AFT0C", "hMultFT0AFT0C;mult. FT0A;mult. FT0C", kTH2F, {{axis_mult_ft0a}, {axis_mult_ft0c}}, false); + fRegistry.add("Event/before/hMultFT0AFV0A", "hMultFT0AFV0A;mult. FT0A;mult. FV0A", kTH2F, {{axis_mult_ft0a}, {axis_mult_fv0a}}, false); + fRegistry.add("Event/before/hMultFT0CFV0A", "hMultFT0CFV0A;mult. FT0C;mult. FV0A", kTH2F, {{axis_mult_ft0c}, {axis_mult_fv0a}}, false); fRegistry.add("Event/before/hCentFT0A", "hCentFT0A;centrality FT0A (%)", kTH1F, {{axis_cent_ft0a}}, false); fRegistry.add("Event/before/hCentFT0C", "hCentFT0C;centrality FT0C (%)", kTH1F, {{axis_cent_ft0c}}, false); fRegistry.add("Event/before/hCentFT0M", "hCentFT0M;centrality FT0M (%)", kTH1F, {{axis_cent_ft0m}}, false); - fRegistry.add("Event/before/hCentFT0CvsMultNTracksPV", "hCentFT0CvsMultNTracksPV;centrality FT0C (%);N_{track} to PV", kTH2F, {{100, 0, 100}, {600, 0, 6000}}, false); - fRegistry.add("Event/before/hMultFT0CvsMultNTracksPV", "hMultFT0CvsMultNTracksPV;mult. FT0C;N_{track} to PV", kTH2F, {{60, 0, 60000}, {600, 0, 6000}}, false); - fRegistry.add("Event/before/hMultFT0CvsOccupancy", "hMultFT0CvsOccupancy;mult. FT0C;N_{track} in time range", kTH2F, {{60, 0, 60000}, {200, 0, 20000}}, false); - fRegistry.add("Event/before/hNTracksPVvsOccupancy", "hNTracksPVvsOccupancy;N_{track} to PV;N_{track} in time range", kTH2F, {{600, 0, 6000}, {200, 0, 20000}}, false); - fRegistry.add("Event/before/hNGlobalTracksvsOccupancy", "hNGlobalTracksvsOccupancy;N_{track}^{global};N_{track} in time range", kTH2F, {{600, 0, 6000}, {200, 0, 20000}}, false); - fRegistry.add("Event/before/hNGlobalTracksPVvsOccupancy", "hNGlobalTracksPVvsOccupancy;N_{track}^{global} to PV;N_{track} in time range", kTH2F, {{600, 0, 6000}, {200, 0, 20000}}, false); + fRegistry.add("Event/before/hCentFT0CvsMultNTracksPV", "hCentFT0CvsMultNTracksPV;centrality FT0C (%);N_{track} to PV in |#eta| < 0.8", kTH2F, {{axis_cent_ft0c}, {axis_mult_ncontrib08}}, false); + fRegistry.add("Event/before/hMultFT0CvsMultNTracksPV", "hMultFT0CvsMultNTracksPV;mult. FT0C;N_{track} to PV in |#eta| < 0.8", kTH2F, {{axis_mult_ft0c}, {axis_mult_ncontrib08}}, false); + fRegistry.add("Event/before/hMultFT0CvsTrackOccupancy", "hMultFT0CvsTrackOccupancy;mult. FT0C;N_{track} in time range", kTH2F, {{axis_mult_ft0c}, {200, 0, 20000}}, false); + fRegistry.add("Event/before/hMultFV0AvsMultNTracksPV", "hMultFV0AvsMultNTracksPV;mult. FV0A;N_{track} to PV in |#eta| < 0.8", kTH2F, {{axis_mult_fv0a}, {axis_mult_ncontrib08}}, false); + fRegistry.add("Event/before/hNTracksPVvsTrackOccupancy", "hNTracksPVvsTrackOccupancy;N_{track} to PV in |#eta| < 0.8;N_{track} in time range", kTH2F, {{axis_mult_ncontrib08}, {200, 0, 20000}}, false); + fRegistry.add("Event/before/hNGlobalTracksvsTrackOccupancy", "hNGlobalTracksvsTrackOccupancy;N_{track}^{global} in |#eta| < 0.8;N_{track} in time range", kTH2F, {{axis_mult_globalTrack}, {200, 0, 20000}}, false); + fRegistry.add("Event/before/hNGlobalTracksPVvsTrackOccupancy", "hNGlobalTracksPVvsTrackOccupancy;N_{track}^{global} to PV in |#eta| < 0.8;N_{track} in time range", kTH2F, {{axis_mult_global_ncontrib08}, {200, 0, 20000}}, false); fRegistry.add("Event/before/hCorrOccupancy", "occupancy correlation;FT0C occupancy;track-based occupancy", kTH2F, {{200, 0, 200000}, {200, 0, 20000}}, false); } fRegistry.addClone("Event/before/", "Event/after/"); if (cfgFillEvent) { - fRegistry.add("Event/after/hMultNGlobalTracks", "hMultNGlobalTracks; N_{track}^{global}", kTH1F, {{6001, -0.5, 6000.5}}, false); - fRegistry.add("Event/after/hCentFT0CvsMultNGlobalTracks", "hCentFT0CvsMultNGlobalTracks;centrality FT0C (%);N_{track}^{global}", kTH2F, {{100, 0, 100}, {600, 0, 6000}}, false); - fRegistry.add("Event/after/hMultFT0CvsMultNGlobalTracks", "hMultFT0CvsMultNGlobalTracks;mult. FT0C;N_{track}^{global}", kTH2F, {{60, 0, 60000}, {600, 0, 6000}}, false); - fRegistry.add("Event/after/hMultNGlobalTracksPV", "hMultNGlobalTracksPV; N_{track}^{global} to PV", kTH1F, {{6001, -0.5, 6000.5}}, false); - fRegistry.add("Event/after/hCentFT0CvsMultNGlobalTracksPV", "hCentFT0CvsMultNGlobalTracksPV;centrality FT0C (%);N_{track}^{global} to PV", kTH2F, {{100, 0, 100}, {600, 0, 6000}}, false); - fRegistry.add("Event/after/hMultFT0CvsMultNGlobalTracksPV", "hMultFT0CvsMultNGlobalTracksPV;mult. FT0C;N_{track}^{global} to PV", kTH2F, {{60, 0, 60000}, {600, 0, 6000}}, false); + fRegistry.add("Event/after/hMultNGlobalTracks", "hMultNGlobalTracks; N_{track}^{global} in |#eta| < 0.8", kTH1F, {{axis_mult_globalTrack}}, false); + fRegistry.add("Event/after/hCentFT0CvsMultNGlobalTracks", "hCentFT0CvsMultNGlobalTracks;centrality FT0C (%);N_{track}^{global} in |#eta| < 0.8", kTH2F, {{axis_cent_ft0c}, {axis_mult_globalTrack}}, false); + fRegistry.add("Event/after/hMultFT0CvsMultNGlobalTracks", "hMultFT0CvsMultNGlobalTracks;mult. FT0C;N_{track}^{global} in |#eta| < 0.8", kTH2F, {{axis_mult_ft0c}, {axis_mult_globalTrack}}, false); + fRegistry.add("Event/after/hMultNGlobalTracksPV", "hMultNGlobalTracksPV; N_{track}^{global} to PV in |#eta| < 0.8", kTH1F, {{axis_mult_global_ncontrib08}}, false); + fRegistry.add("Event/after/hCentFT0CvsMultNGlobalTracksPV", "hCentFT0CvsMultNGlobalTracksPV;centrality FT0C (%);N_{track}^{global} to PV in |#eta| < 0.8", kTH2F, {{axis_cent_ft0c}, {axis_mult_global_ncontrib08}}, false); + fRegistry.add("Event/after/hMultFT0CvsMultNGlobalTracksPV", "hMultFT0CvsMultNGlobalTracksPV;mult. FT0C;N_{track}^{global} to PV in |#eta| < 0.8", kTH2F, {{axis_mult_ft0c}, {axis_mult_global_ncontrib08}}, false); } std::vector tmp_ptbins; @@ -471,11 +480,13 @@ struct eventQC { fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hZvtx"), collision.posZ()); fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hMultNTracksPV"), collision.multNTracksPV()); - fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hMultNTracksPVeta1"), collision.multNTracksPVeta1()); - fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hMultFT0"), collision.multFT0A(), collision.multFT0C()); + fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hMultFT0AFT0C"), collision.multFT0A(), collision.multFT0C()); + fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hMultFT0AFV0A"), collision.multFT0A(), collision.multFV0A()); + fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hMultFT0CFV0A"), collision.multFT0C(), collision.multFV0A()); fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hMultFT0CvsMultNTracksPV"), collision.multFT0C(), collision.multNTracksPV()); - fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hMultFT0CvsOccupancy"), collision.multFT0C(), collision.trackOccupancyInTimeRange()); - fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hNTracksPVvsOccupancy"), collision.multNTracksPV(), collision.trackOccupancyInTimeRange()); + fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hMultFV0AvsMultNTracksPV"), collision.multFV0A(), collision.multNTracksPV()); + fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hMultFT0CvsTrackOccupancy"), collision.multFT0C(), collision.trackOccupancyInTimeRange()); + fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hNTracksPVvsTrackOccupancy"), collision.multNTracksPV(), collision.trackOccupancyInTimeRange()); fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hCorrOccupancy"), collision.ft0cOccupancyInTimeRange(), collision.trackOccupancyInTimeRange()); fRegistry.fill(HIST("Event/") + HIST(event_types[ev_id]) + HIST("hCentFT0A"), collision.centFT0A()); @@ -810,7 +821,8 @@ struct eventQC { return true; } - Filter collisionFilter_evsel = o2::aod::evsel::sel8 == true && (eventcuts.cfgZvtxMin < o2::aod::collision::posZ && o2::aod::collision::posZ < eventcuts.cfgZvtxMax); + Filter collisionFilter_evsel = ifnode(eventcuts.cfgRequireSel8.node(), o2::aod::evsel::sel8 == true, true); + Filter collisionFilter_zvtx = eventcuts.cfgZvtxMin < o2::aod::collision::posZ && o2::aod::collision::posZ < eventcuts.cfgZvtxMax; Filter collisionFilter_centrality = (cfgCentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < cfgCentMax) || (cfgCentMin < o2::aod::cent::centFT0A && o2::aod::cent::centFT0A < cfgCentMax) || (cfgCentMin < o2::aod::cent::centFT0C && o2::aod::cent::centFT0C < cfgCentMax); Filter collisionFilter_multiplicity = cfgNtracksPV08Min <= o2::aod::mult::multNTracksPV && o2::aod::mult::multNTracksPV < cfgNtracksPV08Max; Filter collisionFilter_track_occupancy = eventcuts.cfgTrackOccupancyMin <= o2::aod::evsel::trackOccupancyInTimeRange && o2::aod::evsel::trackOccupancyInTimeRange < eventcuts.cfgTrackOccupancyMax; @@ -826,11 +838,40 @@ struct eventQC { SliceCache cache; Preslice perCol = o2::aod::track::collisionId; + Preslice perBC = o2::aod::collision::bcId; template - void runQC(TBCs const&, TCollisions const& collisions, TTracks const& tracks) + void runQC(TBCs const& bcs, TCollisions const& collisions, TTracks const& tracks) { - for (auto& collision : collisions) { + if constexpr (isTriggerAnalysis) { + for (const auto& bc : bcs) { + initCCDB(bc); + if (!zorro.isSelected(bc.globalBC())) { // triggered BC + continue; + } + + // if (!bc.selection_bit(o2::aod::evsel::kIsTriggerTVX)) { + // continue; + // } + + const auto& collisions_per_bc = collisions.sliceBy(perBC, bc.globalIndex()); + fRegistry.fill(HIST("BC/hNcoll"), collisions_per_bc.size()); + for (const auto& collision : collisions_per_bc) { + fRegistry.fill(HIST("BC/Collision/hMultNTracksPV"), collision.multNTracksPV()); + fRegistry.fill(HIST("BC/Collision/hMultFT0AFT0C"), collision.multFT0A(), collision.multFT0C()); + fRegistry.fill(HIST("BC/Collision/hMultFT0AFV0A"), collision.multFT0A(), collision.multFV0A()); + fRegistry.fill(HIST("BC/Collision/hMultFT0CFV0A"), collision.multFT0C(), collision.multFV0A()); + } + + for (const auto& [col1, col2] : combinations(CombinationsStrictlyUpperIndexPolicy(collisions_per_bc, collisions_per_bc))) { + fRegistry.fill(HIST("BC/hDeltaZ"), col1.posZ() - col2.posZ()); + fRegistry.fill(HIST("BC/hDeltaT"), col1.collisionTime() - col2.collisionTime()); + fRegistry.fill(HIST("BC/hCorrNcontrib"), col1.numContrib(), col2.numContrib()); + } // end of pairing + } // end of bc loop + } + + for (const auto& collision : collisions) { if constexpr (isTriggerAnalysis) { const auto& bc = collision.template bc_as(); // don't use foundBC for CEFP. initCCDB(bc); @@ -862,7 +903,7 @@ struct eventQC { int nGlobalTracks = 0, nGlobalTracksPV = 0; auto tracks_per_coll = tracks.sliceBy(perCol, collision.globalIndex()); - for (auto& track : tracks_per_coll) { + for (const auto& track : tracks_per_coll) { if (!isSelectedTrack(track)) { continue; } @@ -893,8 +934,8 @@ struct eventQC { fRegistry.fill(HIST("Event/after/hMultNGlobalTracksPV"), nGlobalTracksPV); fRegistry.fill(HIST("Event/after/hMultFT0CvsMultNGlobalTracks"), collision.multFT0C(), nGlobalTracks); fRegistry.fill(HIST("Event/after/hMultFT0CvsMultNGlobalTracksPV"), collision.multFT0C(), nGlobalTracksPV); - fRegistry.fill(HIST("Event/after/hNGlobalTracksvsOccupancy"), nGlobalTracks, collision.trackOccupancyInTimeRange()); - fRegistry.fill(HIST("Event/after/hNGlobalTracksPVvsOccupancy"), nGlobalTracksPV, collision.trackOccupancyInTimeRange()); + fRegistry.fill(HIST("Event/after/hNGlobalTracksvsTrackOccupancy"), nGlobalTracks, collision.trackOccupancyInTimeRange()); + fRegistry.fill(HIST("Event/after/hNGlobalTracksPVvsTrackOccupancy"), nGlobalTracksPV, collision.trackOccupancyInTimeRange()); fRegistry.fill(HIST("Event/after/hCentFT0CvsMultNGlobalTracks"), collision.centFT0C(), nGlobalTracks); fRegistry.fill(HIST("Event/after/hCentFT0CvsMultNGlobalTracksPV"), collision.centFT0C(), nGlobalTracksPV); } diff --git a/PWGEM/Dilepton/Tasks/matchingMFT.cxx b/PWGEM/Dilepton/Tasks/matchingMFT.cxx index c1deb69e52a..99a0db783e2 100644 --- a/PWGEM/Dilepton/Tasks/matchingMFT.cxx +++ b/PWGEM/Dilepton/Tasks/matchingMFT.cxx @@ -126,7 +126,7 @@ struct matchingMFT { } mRunNumber = bc.runNumber(); LOGF(info, "mRunNumber = %d", mRunNumber); - std::map metadata; + std::map metadata; auto soreor = o2::ccdb::BasicCCDBManager::getRunDuration(ccdbApi, mRunNumber); auto ts = soreor.first; auto grpmag = ccdbApi.retrieveFromTFileAny(grpmagPath, metadata, ts); diff --git a/PWGEM/Dilepton/Tasks/mcParticlePredictionsOTF.cxx b/PWGEM/Dilepton/Tasks/mcParticlePredictionsOTF.cxx new file mode 100644 index 00000000000..9ec7f079712 --- /dev/null +++ b/PWGEM/Dilepton/Tasks/mcParticlePredictionsOTF.cxx @@ -0,0 +1,100 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// \file mcParticlePrediction.cxx +/// \author Sebastian Scheid, s.scheid@cern.ch +/// \brief Task to build the predictions from the models based on the generated particles +/// + +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +using namespace o2; +using namespace o2::framework; + +struct otfParticlePrediction { + // histogram registry + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + // define configurables + ConfigurableAxis binsEta{"binsEta", {100, -5, 5}, "Binning of the Eta axis"}; + ConfigurableAxis binsPt{"binsPt", {100, 0, 10}, "Binning of the Pt axis"}; + + Configurable maxYParticle{"maxYParticle", 5.f, "Max rapidity of particles considered"}; + + // init function + void init(InitContext&) + { + + const AxisSpec axisEta{binsEta, "#eta"}; + const AxisSpec axisPt{binsPt, "#it{p}_{T} (GeV/#it{c})"}; + + histos.add("collisions/generated", "collisions", kTH1D, {{2, -0.5, 1.5}}); + histos.add("particles/generated/pi0", "pi0", kTH2D, {axisPt, axisEta}); + histos.add("particles/generated/eta", "eta", kTH2D, {axisPt, axisEta}); + histos.add("particles/generated/etaP", "etaP", kTH2D, {axisPt, axisEta}); + histos.add("particles/generated/rho", "rho", kTH2D, {axisPt, axisEta}); + histos.add("particles/generated/omega", "omega", kTH2D, {axisPt, axisEta}); + histos.add("particles/generated/phi", "phi", kTH2D, {axisPt, axisEta}); + } + + void process(aod::McCollisions const& mcCollisions, + aod::McParticles const& mcParticles) + { + + histos.fill(HIST("collisions/generated"), 0, mcCollisions.size()); + + for (const auto& particle : mcParticles) { + auto pdg = std::abs(particle.pdgCode()); + if (std::abs(particle.y()) > maxYParticle) { + continue; + } + // if (!(particle.isPhysicalPrimary())) { + // continue; + // } + if (pdg < 100) { + continue; + } + if (pdg > 1000) { + continue; + } + switch (pdg) { + case 111: + histos.fill(HIST("particles/generated/pi0"), particle.pt(), particle.y()); + break; + case 221: + histos.fill(HIST("particles/generated/eta"), particle.pt(), particle.y()); + break; + case 331: + histos.fill(HIST("particles/generated/etaP"), particle.pt(), particle.y()); + break; + case 223: + histos.fill(HIST("particles/generated/omega"), particle.pt(), particle.y()); + break; + case 113: + histos.fill(HIST("particles/generated/rho"), particle.pt(), particle.y()); + break; + case 333: + histos.fill(HIST("particles/generated/phi"), particle.pt(), particle.y()); + break; + default: + break; + } + } + } +}; + +WorkflowSpec + defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGEM/Dilepton/Tasks/prefilterDielectron.cxx b/PWGEM/Dilepton/Tasks/prefilterDielectron.cxx index d1c15942c5e..d3a12ec6481 100644 --- a/PWGEM/Dilepton/Tasks/prefilterDielectron.cxx +++ b/PWGEM/Dilepton/Tasks/prefilterDielectron.cxx @@ -14,32 +14,33 @@ // This code produces information on prefilter for dielectron. // Please write to: daiki.sekihata@cern.ch -#include -#include -#include -#include -#include +#include "PWGEM/Dilepton/Core/DielectronCut.h" +#include "PWGEM/Dilepton/Core/EMEventCut.h" +#include "PWGEM/Dilepton/DataModel/dileptonTables.h" +#include "PWGEM/Dilepton/Utils/EMTrack.h" +#include "PWGEM/Dilepton/Utils/EventHistograms.h" +#include "PWGEM/Dilepton/Utils/PairUtilities.h" -#include "TString.h" -#include "Math/Vector4D.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" #include "Common/Core/RecoDecay.h" #include "Common/Core/trackUtilities.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" #include "CCDB/BasicCCDBManager.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" -#include "PWGEM/Dilepton/DataModel/dileptonTables.h" -#include "PWGEM/Dilepton/Core/DielectronCut.h" -#include "PWGEM/Dilepton/Core/EMEventCut.h" -#include "PWGEM/Dilepton/Utils/EMTrack.h" -#include "PWGEM/Dilepton/Utils/EventHistograms.h" -#include "PWGEM/Dilepton/Utils/PairUtilities.h" +#include "Math/Vector4D.h" +#include "TString.h" + +#include +#include +#include +#include +#include using namespace o2; using namespace o2::aod; @@ -52,7 +53,7 @@ using namespace o2::aod::pwgem::dilepton::utils::pairutil; using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; -using MyTracks = soa::Join; +using MyTracks = soa::Join; using MyTrack = MyTracks::iterator; struct prefilterDielectron { @@ -101,12 +102,14 @@ struct prefilterDielectron { Configurable cfg_max_phiv{"cfg_max_phiv", 3.2, "max phiv"}; // region to be rejected // for deta-dphi prefilter - Configurable cfg_apply_detadphi_uls{"cfg_apply_detadphi_uls", false, "flag to apply generator deta-dphi elliptic cut in ULS"}; // region to be rejected - Configurable cfg_apply_detadphi_ls{"cfg_apply_detadphi_ls", false, "flag to apply generator deta-dphi elliptic cut in LS"}; // region to be rejected - Configurable cfg_min_deta_ls{"cfg_min_deta_ls", 0.04, "deta between 2 electrons (elliptic cut)"}; // region to be rejected - Configurable cfg_min_dphi_ls{"cfg_min_dphi_ls", 0.2, "dphi between 2 electrons (elliptic cut)"}; // region to be rejected - Configurable cfg_min_deta_uls{"cfg_min_deta_uls", 0.04, "deta between 2 electrons (elliptic cut)"}; // region to be rejected - Configurable cfg_min_dphi_uls{"cfg_min_dphi_uls", 0.2, "dphi between 2 electrons (elliptic cut)"}; // region to be rejected + Configurable cfg_apply_detadphi_uls{"cfg_apply_detadphi_uls", false, "flag to apply generator deta-dphi elliptic cut in ULS"}; // region to be rejected + Configurable cfg_apply_detadphi_ls{"cfg_apply_detadphi_ls", false, "flag to apply generator deta-dphi elliptic cut in LS"}; // region to be rejected + Configurable cfg_apply_detadphiposition_uls{"cfg_apply_detadphiposition_uls", false, "flag to apply generator deta-dphi elliptic cut in ULS"}; // region to be rejected + Configurable cfg_apply_detadphiposition_ls{"cfg_apply_detadphiposition_ls", false, "flag to apply generator deta-dphi elliptic cut in LS"}; // region to be rejected + Configurable cfg_min_deta_ls{"cfg_min_deta_ls", 0.04, "deta between 2 electrons (elliptic cut)"}; // region to be rejected + Configurable cfg_min_dphi_ls{"cfg_min_dphi_ls", 0.2, "dphi between 2 electrons (elliptic cut)"}; // region to be rejected + Configurable cfg_min_deta_uls{"cfg_min_deta_uls", 0.04, "deta between 2 electrons (elliptic cut)"}; // region to be rejected + Configurable cfg_min_dphi_uls{"cfg_min_dphi_uls", 0.2, "dphi between 2 electrons (elliptic cut)"}; // region to be rejected Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.2, "min pT for single track"}; Configurable cfg_max_pt_track{"cfg_max_pt_track", 1e+10, "max pT for single track"}; @@ -170,6 +173,19 @@ struct prefilterDielectron { void init(InitContext& /*context*/) { + if (dielectroncuts.cfg_apply_detadphi_ls && dielectroncuts.cfg_apply_detadphiposition_ls) { + LOG(fatal) << "Please choose deta-dphi prefiter either at PV or certain radius"; + } + if (dielectroncuts.cfg_apply_detadphi_uls && dielectroncuts.cfg_apply_detadphiposition_uls) { + LOG(fatal) << "Please choose deta-dphi prefiter either at PV or certain radius"; + } + if (dielectroncuts.cfg_apply_detadphi_uls && dielectroncuts.cfg_apply_detadphiposition_ls) { + LOG(fatal) << "Please choose deta-dphi prefiter either at PV or certain radius"; + } + if (dielectroncuts.cfg_apply_detadphi_ls && dielectroncuts.cfg_apply_detadphiposition_uls) { + LOG(fatal) << "Please choose deta-dphi prefiter either at PV or certain radius"; + } + DefineEMEventCut(); DefineDielectronCut(); addhistograms(); @@ -267,7 +283,7 @@ struct prefilterDielectron { fDielectronCut.SetPairDCARange(0.f, 1e+10); // in sigma fDielectronCut.ApplyPhiV(false); fDielectronCut.ApplyPrefilter(false); - fDielectronCut.SetMindEtadPhi(false, 1.f, 1.f); + fDielectronCut.SetMindEtadPhi(false, false, 1.f, 1.f); fDielectronCut.SetPairOpAng(0.f, 3.2f); fDielectronCut.SetRequireDifferentSides(false); @@ -407,11 +423,18 @@ struct prefilterDielectron { map_pfb[ele.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kPhiV); } - if (dielectroncuts.cfg_apply_detadphi_uls && std::pow(deta / dielectroncuts.cfg_min_deta_uls, 2) + std::pow(dphi / dielectroncuts.cfg_min_dphi_uls, 2) < 1.f) { - map_pfb[pos.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS); - map_pfb[ele.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS); + if (dielectroncuts.cfg_apply_detadphiposition_uls) { + if (std::pow(deta / dielectroncuts.cfg_min_deta_uls, 2) + std::pow(dphiPosition / dielectroncuts.cfg_min_dphi_uls, 2) < 1.f) { + map_pfb[pos.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS); + map_pfb[ele.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS); + } + } else if (dielectroncuts.cfg_apply_detadphi_uls) { + if (std::pow(deta / dielectroncuts.cfg_min_deta_uls, 2) + std::pow(dphi / dielectroncuts.cfg_min_dphi_uls, 2) < 1.f) { + map_pfb[pos.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS); + map_pfb[ele.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackULS); + } } - } + } // end of ULS pairing for (auto& [pos1, pos2] : combinations(CombinationsStrictlyUpperIndexPolicy(posTracks_per_coll, posTracks_per_coll))) { // LS++ if (!fDielectronCut.IsSelectedTrack(pos1) || !fDielectronCut.IsSelectedTrack(pos2)) { @@ -440,11 +463,18 @@ struct prefilterDielectron { fRegistry.fill(HIST("Pair/before/lspp/hDeltaEtaDeltaPhi"), dphi, deta); fRegistry.fill(HIST("Pair/before/lspp/hDeltaEtaDeltaPhiPosition"), dphiPosition, deta); - if (dielectroncuts.cfg_apply_detadphi_ls && std::pow(deta / dielectroncuts.cfg_min_deta_ls, 2) + std::pow(dphi / dielectroncuts.cfg_min_dphi_ls, 2) < 1.f) { - map_pfb[pos1.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS); - map_pfb[pos2.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS); + if (dielectroncuts.cfg_apply_detadphiposition_ls) { + if (std::pow(deta / dielectroncuts.cfg_min_deta_ls, 2) + std::pow(dphiPosition / dielectroncuts.cfg_min_dphi_ls, 2) < 1.f) { + map_pfb[pos1.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS); + map_pfb[pos2.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS); + } + } else if (dielectroncuts.cfg_apply_detadphi_ls) { + if (std::pow(deta / dielectroncuts.cfg_min_deta_ls, 2) + std::pow(dphi / dielectroncuts.cfg_min_dphi_ls, 2) < 1.f) { + map_pfb[pos1.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS); + map_pfb[pos2.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS); + } } - } + } // end of LS++ pairing for (auto& [ele1, ele2] : combinations(CombinationsStrictlyUpperIndexPolicy(negTracks_per_coll, negTracks_per_coll))) { // LS-- if (!fDielectronCut.IsSelectedTrack(ele1) || !fDielectronCut.IsSelectedTrack(ele2)) { @@ -473,11 +503,18 @@ struct prefilterDielectron { fRegistry.fill(HIST("Pair/before/lsmm/hDeltaEtaDeltaPhi"), dphi, deta); fRegistry.fill(HIST("Pair/before/lsmm/hDeltaEtaDeltaPhiPosition"), dphiPosition, deta); - if (dielectroncuts.cfg_apply_detadphi_ls && std::pow(deta / dielectroncuts.cfg_min_deta_ls, 2) + std::pow(dphi / dielectroncuts.cfg_min_dphi_ls, 2) < 1.f) { - map_pfb[ele1.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS); - map_pfb[ele2.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS); + if (dielectroncuts.cfg_apply_detadphiposition_ls) { + if (std::pow(deta / dielectroncuts.cfg_min_deta_ls, 2) + std::pow(dphiPosition / dielectroncuts.cfg_min_dphi_ls, 2) < 1.f) { + map_pfb[ele1.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS); + map_pfb[ele2.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS); + } + } else if (dielectroncuts.cfg_apply_detadphi_ls) { + if (std::pow(deta / dielectroncuts.cfg_min_deta_ls, 2) + std::pow(dphi / dielectroncuts.cfg_min_dphi_ls, 2) < 1.f) { + map_pfb[ele1.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS); + map_pfb[ele2.globalIndex()] |= 1 << static_cast(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBitDerived::kSplitOrMergedTrackLS); + } } - } + } // end of LS-- pairing } // end of collision loop diff --git a/PWGEM/Dilepton/Tasks/smearing.cxx b/PWGEM/Dilepton/Tasks/smearing.cxx index 7d2404645ca..03d0b272f46 100644 --- a/PWGEM/Dilepton/Tasks/smearing.cxx +++ b/PWGEM/Dilepton/Tasks/smearing.cxx @@ -13,21 +13,21 @@ // Analysis task to produce smeared pt, eta, phi for electrons/muons in dilepton analysis // Please write to: daiki.sekihata@cern.ch -#include -#include -#include +#include "PWGEM/Dilepton/DataModel/dileptonTables.h" +#include "PWGEM/Dilepton/Utils/MomentumSmearer.h" #include "CCDB/BasicCCDBManager.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" #include "Framework/ASoA.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" #include "Framework/DataTypes.h" #include "Framework/HistogramRegistry.h" -// #include "PWGDQ/DataModel/ReducedInfoTables.h" // remove this later, because 2 data tables (covariant matrix) in this header confilict against EM tables. -#include "PWGEM/Dilepton/Utils/MomentumSmearer.h" -#include "PWGEM/Dilepton/DataModel/dileptonTables.h" +#include "Framework/runDataProcessing.h" + +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -292,20 +292,16 @@ struct ApplySmearing { } void processDummyMCanalysisEM(aod::EMMCParticles const&) {} - // void processDummyMCanalysisDQ(ReducedMCTracks const&) {} PROCESS_SWITCH(ApplySmearing, processMCanalysisEM, "Run for MC analysis which uses skimmed EM data format", false); - // PROCESS_SWITCH(ApplySmearing, processMCanalysisDQ, "Run for MC analysis which uses skimmed DQ data format", false); PROCESS_SWITCH(ApplySmearing, processCocktail, "Run for cocktail analysis", false); PROCESS_SWITCH(ApplySmearing, processDummyMCanalysisEM, "Dummy process function", false); - // PROCESS_SWITCH(ApplySmearing, processDummyMCanalysisDQ, "Dummy process function", false); PROCESS_SWITCH(ApplySmearing, processDummyCocktail, "Dummy process function", true); }; struct CheckSmearing { - using EMMCParticlesWithSmearing = soa::Join; // this is only for electrons - // using MyReducedTracks = soa::Join; // this is only for electrons - using MyCocktailTracks = soa::Join; // this is only for electrons + using EMMCParticlesWithSmearing = soa::Join; + using MyCocktailTracks = soa::Join; // Run for electrons or muons Configurable fPdgCode{"cfgPdgCode", 11, "Set the type of particle to be checked"}; @@ -322,9 +318,9 @@ struct CheckSmearing { void init(o2::framework::InitContext&) { - registry.add("hCorrelation_Pt", "pT correlation;p_{T,l}^{gen} (GeV/c);p_{T,l}^{smeared} (GeV/c)", {HistType::kTH2F, {{1000, 0.0f, 10.0f}, {1000, 0.0f, 10.0f}}}); - registry.add("hCorrelation_Eta", "eta correlation;#eta_{l}^{gen};#eta_{l}^{smeared}", {HistType::kTH2F, {{200, -1.0f, +1.0f}, {200, -1.0f, +1.0f}}}); - registry.add("hCorrelation_Phi", "phi correlation;#varphi_{l}^{gen} (rad.);#varphi_{l}^{smeared} (rad.)", {HistType::kTH2F, {{100, 0.0f, TMath::TwoPi()}, {100, 0.0f, TMath::TwoPi()}}}); + registry.add("Electron/hCorrelation_Pt", "pT correlation;p_{T,l}^{gen} (GeV/c);p_{T,l}^{smeared} (GeV/c)", {HistType::kTH2F, {{1000, 0.0f, 10.0f}, {1000, 0.0f, 10.0f}}}); + registry.add("Electron/hCorrelation_Eta", "eta correlation;#eta_{l}^{gen};#eta_{l}^{smeared}", {HistType::kTH2F, {{200, -1.0f, +1.0f}, {200, -1.0f, +1.0f}}}); + registry.add("Electron/hCorrelation_Phi", "phi correlation;#varphi_{l}^{gen} (rad.);#varphi_{l}^{smeared} (rad.)", {HistType::kTH2F, {{100, 0.0f, TMath::TwoPi()}, {100, 0.0f, TMath::TwoPi()}}}); // Binning for resolution AxisSpec axisPtRes{ptResBins, "#it{p}^{gen}_{T,l} (GeV/#it{c})"}; @@ -333,16 +329,19 @@ struct CheckSmearing { AxisSpec axisDeltaphiRes{deltaphiResBins, "#varphi^{gen} - #varphi^{rec} (rad.)"}; if (!fConfigUsePtVecRes) { - registry.add("PtGen_DeltaPtOverPtGen", "", HistType::kTH2D, {axisPtRes, axisDeltaptRes}, true); - registry.add("PtGen_DeltaEta", "", HistType::kTH2D, {axisPtRes, axisDeltaetaRes}, true); - registry.add("PtGen_DeltaPhi_Neg", "", HistType::kTH2D, {axisPtRes, axisDeltaphiRes}, true); - registry.add("PtGen_DeltaPhi_Pos", "", HistType::kTH2D, {axisPtRes, axisDeltaphiRes}, true); + registry.add("Electron/PtGen_DeltaPtOverPtGen", "", HistType::kTH2D, {axisPtRes, axisDeltaptRes}, true); + registry.add("Electron/PtGen_DeltaEta", "", HistType::kTH2D, {axisPtRes, axisDeltaetaRes}, true); + registry.add("Electron/PtGen_DeltaPhi_Neg", "", HistType::kTH2D, {axisPtRes, axisDeltaphiRes}, true); + registry.add("Electron/PtGen_DeltaPhi_Pos", "", HistType::kTH2D, {axisPtRes, axisDeltaphiRes}, true); } else { - registry.add("PtGen_DeltaPtOverPtGen", "", HistType::kTH2D, {{ptResBinsVec, "#it{p}^{gen}_{T,l} (GeV/#it{c})"}, axisDeltaptRes}, true); - registry.add("PtGen_DeltaEta", "", HistType::kTH2D, {{ptResBinsVec, "#it{p}^{gen}_{T,l} (GeV/#it{c})"}, axisDeltaetaRes}, true); - registry.add("PtGen_DeltaPhi_Neg", "", HistType::kTH2D, {{ptResBinsVec, "#it{p}^{gen}_{T,l} (GeV/#it{c})"}, axisDeltaphiRes}, true); - registry.add("PtGen_DeltaPhi_Pos", "", HistType::kTH2D, {{ptResBinsVec, "#it{p}^{gen}_{T,l} (GeV/#it{c})"}, axisDeltaphiRes}, true); + registry.add("Electron/PtGen_DeltaPtOverPtGen", "", HistType::kTH2D, {{ptResBinsVec, "#it{p}^{gen}_{T,l} (GeV/#it{c})"}, axisDeltaptRes}, true); + registry.add("Electron/PtGen_DeltaEta", "", HistType::kTH2D, {{ptResBinsVec, "#it{p}^{gen}_{T,l} (GeV/#it{c})"}, axisDeltaetaRes}, true); + registry.add("Electron/PtGen_DeltaPhi_Neg", "", HistType::kTH2D, {{ptResBinsVec, "#it{p}^{gen}_{T,l} (GeV/#it{c})"}, axisDeltaphiRes}, true); + registry.add("Electron/PtGen_DeltaPhi_Pos", "", HistType::kTH2D, {{ptResBinsVec, "#it{p}^{gen}_{T,l} (GeV/#it{c})"}, axisDeltaphiRes}, true); } + + registry.addClone("Electron/", "GlobalMuon/"); + registry.addClone("Electron/", "StandaloneMuon/"); } template @@ -360,21 +359,59 @@ struct CheckSmearing { } } - float deltaptoverpt = -1000.; - if (mctrack.pt() > 0.) - deltaptoverpt = (mctrack.pt() - mctrack.ptSmeared()) / mctrack.pt(); - float deltaeta = mctrack.eta() - mctrack.etaSmeared(); - float deltaphi = mctrack.phi() - mctrack.phiSmeared(); - registry.fill(HIST("PtGen_DeltaPtOverPtGen"), mctrack.pt(), deltaptoverpt); - registry.fill(HIST("PtGen_DeltaEta"), mctrack.pt(), deltaeta); - if (mctrack.pdgCode() < 0) { - registry.fill(HIST("PtGen_DeltaPhi_Neg"), mctrack.pt(), deltaphi); - } else { - registry.fill(HIST("PtGen_DeltaPhi_Pos"), mctrack.pt(), deltaphi); + if (std::abs(mctrack.pdgCode()) == 11) { // for electrons + float deltaptoverpt = -1000.f; + if (mctrack.pt() > 0.f) { + deltaptoverpt = (mctrack.pt() - mctrack.ptSmeared()) / mctrack.pt(); + } + float deltaeta = mctrack.eta() - mctrack.etaSmeared(); + float deltaphi = mctrack.phi() - mctrack.phiSmeared(); + registry.fill(HIST("Electron/PtGen_DeltaPtOverPtGen"), mctrack.pt(), deltaptoverpt); + registry.fill(HIST("Electron/PtGen_DeltaEta"), mctrack.pt(), deltaeta); + if (mctrack.pdgCode() < 0) { // e+ + registry.fill(HIST("Electron/PtGen_DeltaPhi_Pos"), mctrack.pt(), deltaphi); + } else { // e- + registry.fill(HIST("Electron/PtGen_DeltaPhi_Neg"), mctrack.pt(), deltaphi); + } + registry.fill(HIST("Electron/hCorrelation_Pt"), mctrack.pt(), mctrack.ptSmeared()); + registry.fill(HIST("Electron/hCorrelation_Eta"), mctrack.eta(), mctrack.etaSmeared()); + registry.fill(HIST("Electron/hCorrelation_Phi"), mctrack.phi(), mctrack.phiSmeared()); + } else if (std::abs(mctrack.pdgCode()) == 13) { // for muons + float deltaptoverpt = -1000.f; + // for standalone muons + if (mctrack.pt() > 0.f) { + deltaptoverpt = (mctrack.pt() - mctrack.ptSmeared_sa_muon()) / mctrack.pt(); + } + float deltaeta = mctrack.eta() - mctrack.etaSmeared_sa_muon(); + float deltaphi = mctrack.phi() - mctrack.phiSmeared_sa_muon(); + registry.fill(HIST("StandaloneMuon/PtGen_DeltaPtOverPtGen"), mctrack.pt(), deltaptoverpt); + registry.fill(HIST("StandaloneMuon/PtGen_DeltaEta"), mctrack.pt(), deltaeta); + if (mctrack.pdgCode() < 0) { // mu+ + registry.fill(HIST("StandaloneMuon/PtGen_DeltaPhi_Pos"), mctrack.pt(), deltaphi); + } else { // mu- + registry.fill(HIST("StandaloneMuon/PtGen_DeltaPhi_Neg"), mctrack.pt(), deltaphi); + } + registry.fill(HIST("StandaloneMuon/hCorrelation_Pt"), mctrack.pt(), mctrack.ptSmeared_sa_muon()); + registry.fill(HIST("StandaloneMuon/hCorrelation_Eta"), mctrack.eta(), mctrack.etaSmeared_sa_muon()); + registry.fill(HIST("StandaloneMuon/hCorrelation_Phi"), mctrack.phi(), mctrack.phiSmeared_sa_muon()); + + // for global muons + if (mctrack.pt() > 0.f) { + deltaptoverpt = (mctrack.pt() - mctrack.ptSmeared_gl_muon()) / mctrack.pt(); + } + deltaeta = mctrack.eta() - mctrack.etaSmeared_gl_muon(); + deltaphi = mctrack.phi() - mctrack.phiSmeared_gl_muon(); + registry.fill(HIST("GlobalMuon/PtGen_DeltaPtOverPtGen"), mctrack.pt(), deltaptoverpt); + registry.fill(HIST("GlobalMuon/PtGen_DeltaEta"), mctrack.pt(), deltaeta); + if (mctrack.pdgCode() < 0) { // mu+ + registry.fill(HIST("GlobalMuon/PtGen_DeltaPhi_Pos"), mctrack.pt(), deltaphi); + } else { // mu- + registry.fill(HIST("GlobalMuon/PtGen_DeltaPhi_Neg"), mctrack.pt(), deltaphi); + } + registry.fill(HIST("GlobalMuon/hCorrelation_Pt"), mctrack.pt(), mctrack.ptSmeared_gl_muon()); + registry.fill(HIST("GlobalMuon/hCorrelation_Eta"), mctrack.eta(), mctrack.etaSmeared_gl_muon()); + registry.fill(HIST("GlobalMuon/hCorrelation_Phi"), mctrack.phi(), mctrack.phiSmeared_gl_muon()); } - registry.fill(HIST("hCorrelation_Pt"), mctrack.pt(), mctrack.ptSmeared()); - registry.fill(HIST("hCorrelation_Eta"), mctrack.eta(), mctrack.etaSmeared()); - registry.fill(HIST("hCorrelation_Phi"), mctrack.phi(), mctrack.phiSmeared()); } // end of mctrack loop } @@ -383,25 +420,17 @@ struct CheckSmearing { Check(tracksMC, mccollisions); } - // void processCheckMCanalysisDQ(MyReducedTracks const& tracksMC) - // { - // Check(tracksMC); - // } - void processCheckCocktail(MyCocktailTracks const& tracksMC) { Check(tracksMC, nullptr); } void processDummyMCanalysisEM(aod::EMMCParticles const&) {} - // void processDummyMCanalysisDQ(ReducedMCTracks const&) {} void processDummyCocktail(aod::McParticles const&) {} PROCESS_SWITCH(CheckSmearing, processCheckMCanalysisEM, "Run for MC analysis", false); - // PROCESS_SWITCH(CheckSmearing, processCheckMCanalysisDQ, "Run for MC analysis", false); PROCESS_SWITCH(CheckSmearing, processCheckCocktail, "Run for cocktail analysis", false); PROCESS_SWITCH(CheckSmearing, processDummyMCanalysisEM, "Dummy process function", false); - // PROCESS_SWITCH(CheckSmearing, processDummyMCanalysisDQ, "Dummy process function", false); PROCESS_SWITCH(CheckSmearing, processDummyCocktail, "Dummy process function", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGEM/Dilepton/Tasks/tableReaderBarrel.cxx b/PWGEM/Dilepton/Tasks/tableReaderBarrel.cxx index 819a85efe65..9787a5bae04 100644 --- a/PWGEM/Dilepton/Tasks/tableReaderBarrel.cxx +++ b/PWGEM/Dilepton/Tasks/tableReaderBarrel.cxx @@ -12,39 +12,43 @@ // Contact: iarsene@cern.ch, i.c.arsene@fys.uio.no // -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "PWGDQ/DataModel/ReducedInfoTables.h" -#include "PWGDQ/Core/VarManager.h" -#include "PWGDQ/Core/HistogramManager.h" -#include "PWGDQ/Core/MixingHandler.h" -#include "PWGDQ/Core/AnalysisCut.h" #include "PWGDQ/Core/AnalysisCompositeCut.h" -#include "PWGDQ/Core/HistogramsLibrary.h" +#include "PWGDQ/Core/AnalysisCut.h" #include "PWGDQ/Core/CutsLibrary.h" +#include "PWGDQ/Core/HistogramManager.h" +#include "PWGDQ/Core/HistogramsLibrary.h" +#include "PWGDQ/Core/MixingHandler.h" #include "PWGDQ/Core/MixingLibrary.h" +#include "PWGDQ/Core/VarManager.h" +#include "PWGDQ/DataModel/ReducedInfoTables.h" + +#include "Common/CCDB/EventSelectionParams.h" + +#include "CCDB/BasicCCDBManager.h" #include "DataFormatsParameters/GRPMagField.h" -#include "Field/MagneticField.h" -#include "TGeoGlobalMagField.h" -#include "DetectorsBase/Propagator.h" +#include "DataFormatsParameters/GRPObject.h" #include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Field/MagneticField.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" #include "ITSMFTBase/DPLAlpideParam.h" -#include "Common/CCDB/EventSelectionParams.h" + +#include "TGeoGlobalMagField.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include using std::cout; using std::endl; @@ -123,12 +127,12 @@ struct AnalysisEventSelection { Produces hash; OutputObj fOutputList{"output"}; // TODO: Provide the mixing variables and binning directly via configurables (e.g. vectors of float) - Configurable fConfigMixingVariables{"cfgMixingVars", "", "Mixing configs separated by a comma, default no mixing"}; + Configurable fConfigMixingVariables{"cfgMixingVars", "", "Mixing configs separated by a comma, default no mixing"}; Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; Configurable fConfigITSROFrameStartBorderMargin{"ITSROFrameStartBorderMargin", -1, "Number of bcs at the start of ITS RO Frame border. Take from CCDB if -1"}; Configurable fConfigITSROFrameEndBorderMargin{"ITSROFrameEndBorderMargin", -1, "Number of bcs at the end of ITS RO Frame border. Take from CCDB if -1"}; Configurable fConfigAddEventHistogram{"cfgAddEventHistogram", "", "Comma separated list of histograms"}; - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; AnalysisCompositeCut* fEventCut; struct : ConfigurableGroup { @@ -284,10 +288,10 @@ struct AnalysisTrackSelection { // NOTE: For now, the candidate electron cuts must be provided first, then followed by any other needed selections Configurable fConfigQA{"cfgQA", false, "If true, fill QA histograms"}; Configurable fConfigQAIfSelEvt{"cfgQAIfSelEvt", true, "If true, fill QA only for selected events"}; - Configurable fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"}; + Configurable fConfigAddTrackHistogram{"cfgAddTrackHistogram", "", "Comma separated list of histograms"}; Configurable fConfigPrefilterCutId{"cfgPrefilterCutId", 32, "Id of the Prefilter track cut (starting at 0)"}; // In order to create another column prefilter (should be temporary before improving cut selection in configurables, then displaced to AnalysisPrefilterSelection) - Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/z/zhxiong/TPCPID/PostCalib", "base path to the ccdb object"}; + Configurable fConfigCcdbUrl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable fConfigCcdbPathTPC{"ccdb-path-tpc", "Users/z/zhxiong/TPCPID/PostCalib", "base path to the ccdb object"}; Configurable fConfigNoLaterThan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable fConfigComputeTPCpostCalib{"cfgTPCpostCalib", false, "If true, compute TPC post-calibrated n-sigmas"}; Configurable fConfigRunPeriods{"cfgRunPeriods", "LHC22f", "run periods for used data"}; @@ -948,8 +952,8 @@ struct AnalysisSameEventPairing { OutputObj fOutputList{"output"}; Configurable fConfigNbTrackCut{"cfgNbTrackCut", 1, "Number of track cuts without prefilter cut, need to be consistent with the track selection"}; Configurable fConfigNbPairCut{"cfgNbPairCut", 1, "Number of pair cuts, need to be below 4 right now"}; - Configurable url{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable ccdbPath{"ccdb-path", "Users/lm", "base path to the ccdb object"}; + Configurable url{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable ccdbPath{"ccdb-path", "Users/lm", "base path to the ccdb object"}; Configurable nolaterthan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; Configurable fConfigAddSEPHistogram{"cfgAddSEPHistogram", "", "Comma separated list of histograms"}; Configurable ccdburl{"ccdburl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; @@ -1072,7 +1076,7 @@ struct AnalysisSameEventPairing { } } - if (fConfigNbTrackCut > 0 && fConfigNbTrackCut < 31) { // if track cuts + if (fConfigNbTrackCut > 0 && fConfigNbTrackCut < 31) { // if track cuts for (std::size_t icut = 0; icut < fConfigNbTrackCut; ++icut) { // loop over track cuts fTwoTrackFilterMask |= (static_cast(1) << icut); // no pair cuts diff --git a/PWGEM/Dilepton/Tasks/taggingHFE.cxx b/PWGEM/Dilepton/Tasks/taggingHFE.cxx index f843b20819a..b3098ef9774 100644 --- a/PWGEM/Dilepton/Tasks/taggingHFE.cxx +++ b/PWGEM/Dilepton/Tasks/taggingHFE.cxx @@ -13,52 +13,68 @@ /// \brief a task to study tagging e from charm hadron decays in MC /// \author daiki.sekihata@cern.ch -#include -#include -#include -#include -#include - -#include "Math/Vector4D.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsCalibration/MeanVertexObject.h" -#include "CCDB/BasicCCDBManager.h" -#include "Common/Core/trackUtilities.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Common/Core/TableHelper.h" -#include "Common/Core/RecoDecay.h" -#include "DCAFitter/DCAFitterN.h" +#include "PWGEM/Dilepton/Utils/MCUtilities.h" #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TableHelper.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/PIDResponse.h" -#include "PWGEM/Dilepton/Utils/MCUtilities.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CommonConstants/PhysicsConstants.h" +#include "DCAFitter/DCAFitterN.h" +#include "DataFormatsCalibration/MeanVertexObject.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "Math/Vector4D.h" + +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::soa; using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::constants::physics; +using namespace o2::aod::pwgem::dilepton::utils::mcutil; struct taggingHFE { - using MyCollisions = soa::Join; + using MyCollisions = soa::Join; + using MyCollisionsWithMCLabel = soa::Join; - using MyTracks = soa::Join; + using MyTracks = soa::Join; + using MyTracksWithMCLabel = soa::Join; using MyV0s = soa::Join; + using MyCascades = soa::Join; + + struct EBPair { // electron-baryon pair + float mass{-999.f}; + float dca2legs{-999.f}; + float cospa{-999.f}; + float lxy{-999.f}; + float lz{-999.f}; + float ptepv{-999.f}; + float dca3dinsigma{-999.f}; + }; // Configurables Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; @@ -72,7 +88,7 @@ struct taggingHFE { Configurable d_UseWeightedPCA{"d_UseWeightedPCA", false, "Vertices use cov matrices"}; struct : ConfigurableGroup { - std::string prefix = "electroncut_group"; + std::string prefix = "electroncut"; Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.05, "min pT for single track"}; Configurable cfg_max_pt_track{"cfg_max_pt_track", 1e+10, "max pT for single track"}; Configurable cfg_min_eta_track{"cfg_min_eta_track", -0.9, "min eta for single track"}; @@ -82,16 +98,41 @@ struct taggingHFE { Configurable cfg_min_ncrossedrows_tpc{"cfg_min_ncrossedrows_tpc", 70, "min ncrossed rows"}; Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; Configurable cfg_min_ncluster_its{"cfg_min_ncluster_its", 5, "min ncluster its"}; - Configurable cfg_min_ncluster_itsib{"cfg_min_ncluster_itsib", 1, "min ncluster itsib"}; + Configurable cfg_min_ncluster_itsib{"cfg_min_ncluster_itsib", 3, "min ncluster itsib"}; Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; Configurable cfg_max_chi2its{"cfg_max_chi2its", 5.0, "max chi2/NclsITS"}; - Configurable cfg_max_chi2tof{"cfg_max_chi2tof", 1e+10, "max chi2/NclsTOF"}; - Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 0.3, "max dca XY for single track in cm"}; - Configurable cfg_max_dcaz{"cfg_max_dcaz", 0.3, "max dca Z for single track in cm"}; - } electroncuts; + Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 1.0, "max dca XY for single track in cm"}; + Configurable cfg_max_dcaz{"cfg_max_dcaz", 1.0, "max dca Z for single track in cm"}; + Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2, "min n sigma el in TPC"}; + Configurable cfg_max_TPCNsigmaEl{"cfg_max_TPCNsigmaEl", +3, "max n sigma el in TPC"}; + Configurable cfg_min_TOFNsigmaEl{"cfg_min_TOFNsigmaEl", -3, "min n sigma el in TOF"}; + Configurable cfg_max_TOFNsigmaEl{"cfg_max_TOFNsigmaEl", +3, "max n sigma el in TOF"}; + } electroncut; struct : ConfigurableGroup { - std::string prefix = "kaoncut_group"; + std::string prefix = "loose_electroncut"; + Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.05, "min pT for single track"}; + Configurable cfg_max_pt_track{"cfg_max_pt_track", 1e+10, "max pT for single track"}; + Configurable cfg_min_eta_track{"cfg_min_eta_track", -1.2, "min eta for single track"}; + Configurable cfg_max_eta_track{"cfg_max_eta_track", +1.2, "max eta for single track"}; + Configurable cfg_min_cr2findable_ratio_tpc{"cfg_min_cr2findable_ratio_tpc", 0.8, "min. TPC Ncr/Nf ratio"}; + Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; + Configurable cfg_min_ncrossedrows_tpc{"cfg_min_ncrossedrows_tpc", 40, "min ncrossed rows"}; + Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; + Configurable cfg_min_ncluster_its{"cfg_min_ncluster_its", 2, "min ncluster its"}; + Configurable cfg_min_ncluster_itsib{"cfg_min_ncluster_itsib", 0, "min ncluster itsib"}; + Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; + Configurable cfg_max_chi2its{"cfg_max_chi2its", 36.0, "max chi2/NclsITS"}; + Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 1.0, "max dca XY for single track in cm"}; + Configurable cfg_max_dcaz{"cfg_max_dcaz", 1.0, "max dca Z for single track in cm"}; + Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2, "min n sigma el in TPC"}; + Configurable cfg_max_TPCNsigmaEl{"cfg_max_TPCNsigmaEl", +3, "max n sigma el in TPC"}; + Configurable cfg_min_TOFNsigmaEl{"cfg_min_TOFNsigmaEl", -3, "min n sigma el in TOF"}; + Configurable cfg_max_TOFNsigmaEl{"cfg_max_TOFNsigmaEl", +3, "max n sigma el in TOF"}; + } loose_electroncut; + + struct : ConfigurableGroup { + std::string prefix = "kaoncut"; Configurable cfg_min_pt_track{"cfg_min_pt_track", 0.05, "min pT for single track"}; Configurable cfg_max_pt_track{"cfg_max_pt_track", 1e+10, "max pT for single track"}; Configurable cfg_min_eta_track{"cfg_min_eta_track", -1.2, "min eta for single track"}; @@ -104,62 +145,77 @@ struct taggingHFE { Configurable cfg_min_ncluster_itsib{"cfg_min_ncluster_itsib", 1, "min ncluster itsib"}; Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; Configurable cfg_max_chi2its{"cfg_max_chi2its", 36.0, "max chi2/NclsITS"}; - Configurable cfg_max_chi2tof{"cfg_max_chi2tof", 1e+10, "max chi2/NclsTOF"}; Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 0.5, "max dca XY for single track in cm"}; Configurable cfg_max_dcaz{"cfg_max_dcaz", 0.5, "max dca Z for single track in cm"}; Configurable cfg_min_TPCNsigmaKa{"cfg_min_TPCNsigmaKa", -3, "min n sigma ka in TPC"}; Configurable cfg_max_TPCNsigmaKa{"cfg_max_TPCNsigmaKa", +3, "max n sigma ka in TPC"}; Configurable cfg_min_TOFNsigmaKa{"cfg_min_TOFNsigmaKa", -3, "min n sigma ka in TOF"}; Configurable cfg_max_TOFNsigmaKa{"cfg_max_TOFNsigmaKa", +3, "max n sigma ka in TOF"}; - } kaoncuts; + } kaoncut; struct : ConfigurableGroup { - std::string prefix = "svcut_group"; - Configurable cfg_min_cospa{"cfg_min_cospa", 0.8, "min cospa"}; - Configurable cfg_min_cospaXY{"cfg_min_cospaXY", 0.8, "min cospaXY"}; - Configurable cfg_max_dca2legs{"cfg_max_dca2legs", 1.0, "max distance between 2 legs"}; - Configurable cfg_min_lxy{"cfg_min_lxy", -1, "min lxy for charm hadron candidate"}; - Configurable cfg_max_mass_eK{"cfg_max_mass_eK", 2.0, "max mass for eK pair"}; - Configurable cfg_max_mass_eL{"cfg_max_mass_eL", 2.3, "max mass for eL pair"}; - } svcuts; - - struct : ConfigurableGroup { - std::string prefix = "v0cut_group"; - Configurable cfg_min_mass_k0s{"cfg_min_mass_k0s", 0.485, "min mass for K0S"}; - Configurable cfg_max_mass_k0s{"cfg_max_mass_k0s", 0.510, "max mass for K0S"}; - Configurable cfg_min_mass_lambda{"cfg_min_mass_lambda", 1.11, "min mass for Lambda rejection"}; - Configurable cfg_max_mass_lambda{"cfg_max_mass_lambda", 1.12, "max mass for Lambda rejection"}; - Configurable cfg_min_cospa{"cfg_min_cospa", 0.95, "min cospa for v0hadron"}; - Configurable cfg_max_dca2legs{"cfg_max_dca2legs", 0.2, "max distance between 2 legs for v0hadron"}; + std::string prefix = "v0cut"; + Configurable cfg_min_mass_k0s_veto{"cfg_min_mass_k0s_veto", 0.47, "min mass for K0S veto"}; + Configurable cfg_max_mass_k0s_veto{"cfg_max_mass_k0s_veto", 0.52, "max mass for K0S veto"}; + Configurable cfg_min_mass_lambda{"cfg_min_mass_lambda", 1.113, "min mass for Lambda"}; + Configurable cfg_max_mass_lambda{"cfg_max_mass_lambda", 1.118, "max mass for Lambda"}; + Configurable cfg_min_cospa{"cfg_min_cospa", 0.999, "min cospa for v0hadron"}; + Configurable cfg_max_dca2legs{"cfg_max_dca2legs", 0.1, "max distance between 2 legs for v0hadron"}; // Configurable cfg_min_radius{"cfg_min_radius", 0.1, "min rxy for v0hadron"}; Configurable cfg_min_cr2findable_ratio_tpc{"cfg_min_cr2findable_ratio_tpc", 0.8, "min. TPC Ncr/Nf ratio"}; - Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; - Configurable cfg_min_ncrossedrows_tpc{"cfg_min_ncrossedrows_tpc", 40, "min ncrossed rows"}; + Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 0.7, "max fraction of shared clusters in TPC"}; + Configurable cfg_min_ncrossedrows_tpc{"cfg_min_ncrossedrows_tpc", 70, "min ncrossed rows"}; Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; Configurable cfg_max_chi2its{"cfg_max_chi2its", 36.0, "max chi2/NclsITS"}; Configurable cfg_min_ncluster_its{"cfg_min_ncluster_its", 2, "min ncluster its"}; Configurable cfg_min_ncluster_itsib{"cfg_min_ncluster_itsib", 0, "min ncluster itsib"}; - Configurable cfg_max_chi2tof{"cfg_max_chi2tof", 1e+10, "max chi2 for TOF"}; Configurable cfg_min_dcaxy{"cfg_min_dcaxy", 0.1, "min dca XY for v0 legs in cm"}; - Configurable cfg_min_TPCNsigmaPi{"cfg_min_TPCNsigmaPi", -3, "min n sigma pi in TPC"}; - Configurable cfg_max_TPCNsigmaPi{"cfg_max_TPCNsigmaPi", +3, "max n sigma pi in TPC"}; - Configurable cfg_min_TPCNsigmaPr{"cfg_min_TPCNsigmaPr", -3, "min n sigma pr in TPC"}; - Configurable cfg_max_TPCNsigmaPr{"cfg_max_TPCNsigmaPr", +3, "max n sigma pr in TPC"}; - Configurable cfg_min_TOFNsigmaPi{"cfg_min_TOFNsigmaPi", -3, "min n sigma pi in TOF"}; - Configurable cfg_max_TOFNsigmaPi{"cfg_max_TOFNsigmaPi", +3, "max n sigma pi in TOF"}; - Configurable cfg_min_TOFNsigmaPr{"cfg_min_TOFNsigmaPr", -3, "min n sigma pr in TOF"}; - Configurable cfg_max_TOFNsigmaPr{"cfg_max_TOFNsigmaPr", +3, "max n sigma pr in TOF"}; - } v0cuts; + Configurable cfg_min_TPCNsigmaPi{"cfg_min_TPCNsigmaPi", -2, "min n sigma pi in TPC"}; + Configurable cfg_max_TPCNsigmaPi{"cfg_max_TPCNsigmaPi", +2, "max n sigma pi in TPC"}; + Configurable cfg_min_TPCNsigmaPr{"cfg_min_TPCNsigmaPr", -2, "min n sigma pr in TPC"}; + Configurable cfg_max_TPCNsigmaPr{"cfg_max_TPCNsigmaPr", +2, "max n sigma pr in TPC"}; + Configurable cfg_min_TOFNsigmaPi{"cfg_min_TOFNsigmaPi", -2, "min n sigma pi in TOF"}; + Configurable cfg_max_TOFNsigmaPi{"cfg_max_TOFNsigmaPi", +2, "max n sigma pi in TOF"}; + Configurable cfg_min_TOFNsigmaPr{"cfg_min_TOFNsigmaPr", -2, "min n sigma pr in TOF"}; + Configurable cfg_max_TOFNsigmaPr{"cfg_max_TOFNsigmaPr", +2, "max n sigma pr in TOF"}; + } v0cut; - Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; - Configurable cfgCentMin{"cfgCentMin", -1.f, "min. centrality"}; - Configurable cfgCentMax{"cfgCentMax", 999.f, "max. centrality"}; - Configurable cfgZvtxMin{"cfgZvtxMin", -10.f, "min. Zvtx"}; - Configurable cfgZvtxMax{"cfgZvtxMax", 10.f, "max. Zvtx"}; + struct : ConfigurableGroup { + std::string prefix = "cascadecut"; + Configurable cfg_min_mass_lambda{"cfg_min_mass_lambda", 1.11, "min mass for lambda in cascade"}; + Configurable cfg_max_mass_lambda{"cfg_max_mass_lambda", 1.12, "max mass for lambda in cascade"}; + Configurable cfg_min_mass_Xi{"cfg_min_mass_Xi", 1.316, "min mass for Xi"}; + Configurable cfg_max_mass_Xi{"cfg_max_mass_Xi", 1.326, "max mass for Xi"}; + Configurable cfg_min_mass_Xi_veto{"cfg_min_mass_Xi_veto", 1.31, "min mass for Xi veto"}; + Configurable cfg_max_mass_Xi_veto{"cfg_max_mass_Xi_veto", 1.33, "max mass for Xi veto"}; + Configurable cfg_min_mass_Omega{"cfg_min_mass_Omega", 1.669, "min mass for Omega"}; + Configurable cfg_max_mass_Omega{"cfg_max_mass_Omega", 1.675, "max mass for Omega"}; + Configurable cfg_min_mass_Omega_veto{"cfg_min_mass_Omega_veto", 1.66, "min mass for Omega veto"}; + Configurable cfg_max_mass_Omega_veto{"cfg_max_mass_Omega_veto", 1.68, "max mass for Omega veto"}; + Configurable cfg_min_cospa_v0{"cfg_min_cospa_v0", 0.995, "minimum V0 CosPA in cascade"}; + Configurable cfg_max_dcadau_v0{"cfg_max_dcadau_v0", 0.1, "max distance between V0 Daughters in cascade"}; + Configurable cfg_min_cospa{"cfg_min_cospa", 0.9998, "minimum cascade CosPA"}; + Configurable cfg_max_dcadau{"cfg_max_dcadau", 0.1, "max distance between bachelor and V0"}; + Configurable cfg_min_rxy_v0{"cfg_min_rxy_v0", 1.2, "minimum V0 rxy in cascade"}; + Configurable cfg_min_rxy{"cfg_min_rxy", 0.5, "minimum V0 rxy in cascade"}; + Configurable cfg_min_dcaxy_v0leg{"cfg_min_dcaxy_v0leg", 0.1, "min dca XY for v0 legs in cm"}; + Configurable cfg_min_dcaxy_bachelor{"cfg_min_dcaxy_bachelor", 0.05, "min dca XY for bachelor in cm"}; + Configurable cfg_min_dcaxy_v0{"cfg_min_dcaxy_v0", 0.05, "min dca XY for V0 in cm"}; + } cascadecut; - Configurable cfgEventGeneratorType{"cfgEventGeneratorType", -1, "if positive, select event generator type. i.e. gap or signal"}; + struct : ConfigurableGroup { + std::string prefix = "eventcut"; + Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; + Configurable cfgCentMin{"cfgCentMin", -1.f, "min. centrality"}; + Configurable cfgCentMax{"cfgCentMax", 999.f, "max. centrality"}; + Configurable cfgZvtxMin{"cfgZvtxMin", -10.f, "min. Zvtx"}; + Configurable cfgZvtxMax{"cfgZvtxMax", 10.f, "max. Zvtx"}; + Configurable cfgEventGeneratorType{"cfgEventGeneratorType", -1, "if positive, select event generator type. i.e. gap or signal"}; + } eventcut; + + Configurable cfgMeeMaxPF{"cfgMeeMaxPF", 0.08, "max mee for prefilter to reject pi0->ee and gamma->ee in LMR"}; HistogramRegistry fRegistry{"fRegistry"}; static constexpr std::string_view hadron_names[6] = {"LF/", "Jpsi/", "D0/", "Dpm/", "Ds/", "Lc/"}; @@ -169,9 +225,9 @@ struct taggingHFE { void init(o2::framework::InitContext&) { - if (doprocessSA && doprocessTTCA) { - LOGF(fatal, "Cannot enable doprocessWithoutFTTCA and doprocessWithFTTCA at the same time. Please choose one."); - } + // if (doprocessSA && doprocessTTCA) { + // LOGF(fatal, "Cannot enable doprocessWithoutFTTCA and doprocessWithFTTCA at the same time. Please choose one."); + // } ccdb->setURL(ccdburl); ccdb->setCaching(true); @@ -276,80 +332,97 @@ struct taggingHFE { fRegistry.add("Event/hCentFT0CvsMultNTracksPV", "hCentFT0CvsMultNTracksPV;centrality FT0C (%);N_{track} to PV", kTH2F, {{110, 0, 110}, {600, 0, 6000}}, false); fRegistry.add("Event/hMultFT0CvsMultNTracksPV", "hMultFT0CvsMultNTracksPV;mult. FT0C;N_{track} to PV", kTH2F, {{60, 0, 60000}, {600, 0, 6000}}, false); - // for charm hadrons - fRegistry.add("e_Kpm/all/hLxy", "decay length XY from PV;L_{xy} (cm)", kTH1F, {{500, 0, 0.5}}, false); - fRegistry.add("e_Kpm/all/hLz", "decay length Z from PV;L_{z} (cm)", kTH1F, {{500, 0, 0.5}}, false); - fRegistry.add("e_Kpm/all/hCosPA", "cosPA;cosine of pointing angle", kTH1F, {{200, 0.8, 1}}, false); - fRegistry.add("e_Kpm/all/hCosPAXY", "cosPA in XY;cosine of pointing angle in XY", kTH1F, {{200, 0.8, 1}}, false); - fRegistry.add("e_Kpm/all/hDCA2Legs", "distance between 2 legs;distance between 2 legs (cm)", kTH1F, {{500, 0, 0.5}}, false); - fRegistry.add("e_Kpm/all/hMass", "mass;mass (GeV/c^{2})", kTH1F, {{200, 0.5, 2.5}}, false); - fRegistry.add("e_Kpm/all/hMass_CosPA", "mass vs. cosPA;mass (GeV/c^{2});cosine of pointing angle", kTH2F, {{200, 0.5, 2.5}, {200, 0.8, 1.0}}, false); - fRegistry.add("e_Kpm/all/hDeltaEtaDeltaPhi", "#Delta#varphi vs. #Delta#eta;#Delta#varphi = #varphi_{h} - #varphi_{e} (rad.);#Delta#eta = #eta_{h} - #eta_{e}", kTH2F, {{180, -M_PI, M_PI}, {200, -2, +2}}, false); - fRegistry.add("e_Kpm/all/hRelDeltaPt", "rel delta pT;(p_{T,h} - p_{T,e})/p_{T,e}", kTH1F, {{80, -2, +2}}, false); - fRegistry.add("e_Kpm/all/hProdDCAxy", "product of DCAxy;d_{xy}^{e} #times d_{xy}^{h} (#sigma)^{2}", kTH1F, {{200, -100, +100}}, false); - fRegistry.add("e_Kpm/all/hCorrelationDCAxy", "correlation of DCAxy;DCA^{xy}_{e} (#sigma);DCA^{xy}_{h} (#sigma)", kTH2F, {{200, -10, +10}, {200, -10, +10}}, false); - fRegistry.add("e_Kpm/all/hCorrelationDCAz", "correlation of DCAz;DCA^{z}_{e} (#sigma);DCA^{z}_{h} (#sigma)", kTH2F, {{200, -10, +10}, {200, -10, +10}}, false); - - fRegistry.addClone("e_Kpm/all/", "e_Kpm/D0/"); - fRegistry.addClone("e_Kpm/all/", "e_Kpm/Dpm/"); - fRegistry.addClone("e_Kpm/all/", "e_Kpm/Ds/"); - fRegistry.addClone("e_Kpm/all/", "e_Kpm/fake/"); - - fRegistry.addClone("e_Kpm/all/", "e_K0S/all/"); - fRegistry.addClone("e_Kpm/all/", "e_K0S/D0/"); - fRegistry.addClone("e_Kpm/all/", "e_K0S/Dpm/"); - fRegistry.addClone("e_Kpm/all/", "e_K0S/Ds/"); - fRegistry.addClone("e_Kpm/all/", "e_K0S/fake/"); - - fRegistry.addClone("e_Kpm/all/", "e_Lambda/all/"); - fRegistry.addClone("e_Kpm/all/", "e_Lambda/Lc/"); - fRegistry.addClone("e_Kpm/all/", "e_Lambda/fake/"); - - // for V0s - fRegistry.add("V0/K0S/hPt", "pT of V0;p_{T} (GeV/c)", kTH1F, {{100, 0, 10}}, false); - fRegistry.add("V0/K0S/hYPhi", "Y vs. #varphi of V0;#varphi (rad.);rapidity", kTH2F, {{36, 0, 2 * M_PI}, {80, -2, +2}}, false); - fRegistry.add("V0/K0S/hAP", "Ap plot;#alpha;q_{T} (GeV/c)", kTH2F, {{200, -1, 1}, {250, 0, 0.25}}, false); - fRegistry.add("V0/K0S/hLxy", "decay length from PV;L_{xy} (cm)", kTH1F, {{100, 0, 10}}, false); - fRegistry.add("V0/K0S/hCosPA", "cosPA;cosine of pointing angle", kTH1F, {{100, 0.9, 1}}, false); - fRegistry.add("V0/K0S/hDCA2Legs", "distance between 2 legs;distance between 2 legs (cm)", kTH1F, {{100, 0, 1}}, false); - fRegistry.addClone("V0/K0S/", "V0/Lambda/"); - fRegistry.addClone("V0/K0S/", "V0/AntiLambda/"); - fRegistry.add("V0/K0S/hMassK0S", "K0S mass;m_{#pi#pi} (GeV/c^{2})", kTH1F, {{100, 0.45, 0.55}}, false); - fRegistry.add("V0/Lambda/hMassLambda", "Lambda mass;m_{p#pi} (GeV/c^{2})", kTH1F, {{100, 1.08, 1.18}}, false); - fRegistry.add("V0/AntiLambda/hMassAntiLambda", "Anti-Lambda mass;m_{p#pi} (GeV/c^{2})", kTH1F, {{100, 1.08, 1.18}}, false); - - const AxisSpec axis_pt{{0, 0.05, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 6, 7, 8, 9, 10}, "p_{T,e} (GeV/c)"}; - const AxisSpec axis_dca_sigma{{0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9, 9.5, 10}, "DCA_{e}^{3D} (#sigma)"}; - - // for tracks - fRegistry.add("LF/electron/prompt/findable/hs", "electron;p_{T,e} (GeV/c);#eta_{e};#varphi_{e} (rad.);DCA_{e}^{3D} (#sigma)", kTHnSparseF, {{axis_pt}, {80, -2, +2}, {36, 0, 2 * M_PI}, {axis_dca_sigma}}, false); - fRegistry.add("LF/electron/prompt/findable/hTPCdEdx", "TPC dE/dx;p_{in} (GeV/c);TPC dE/dx (a.u.)", kTH2F, {{1000, 0, 10}, {200, 0, 200}}, false); - fRegistry.add("LF/electron/prompt/findable/hTOFbeta", "TOF #beta;p_{pv} (GeV/c);#beta", kTH2F, {{1000, 0, 10}, {240, 0, 1.2}}, false); - - fRegistry.addClone("LF/electron/prompt/findable/", "LF/electron/prompt/correct/"); - fRegistry.addClone("LF/electron/prompt/findable/", "LF/electron/prompt/fake/"); - fRegistry.addClone("LF/electron/prompt/", "LF/electron/nonprompt/"); - fRegistry.addClone("LF/electron/", "Jpsi/electron/"); - - fRegistry.addClone("LF/electron/", "D0/electron/"); // D0 -> K- e+ nu, Br = 0.03549 | D0 -> K- e+ pi0 nu, Br = 0.016 | D0 -> K*(892)- e+ nu, Br = 0.0215 // D0 -> anti-K0S e+ pi- nu, Br = 0.0144 - fRegistry.addClone("LF/electron/", "Dpm/electron/"); // D+ -> K- pi+ e+ nu, Br = 0.0402 | D+ -> anti-K*(892)0 e+ nu, Br = 0.0540 // D+ -> anti-K0S e+ nu, Br = 0.0872 - fRegistry.addClone("LF/electron/", "Ds/electron/"); // Ds+ -> K0S e+ nu, Br = 0.0034 // Ds+ -> phi e+ nu, Br = 0.0239 - fRegistry.addClone("LF/electron/", "Lc/electron/"); // Lc+ -> L e+ nu, Br = 0.0356 - - fRegistry.addClone("D0/electron/", "D0/kaon/"); // D0 -> K- e+ nu, Br = 0.03549 | D0 -> K- e+ pi0 nu, Br = 0.016 | D0 -> K*(892)- e+ nu, Br = 0.0215 // D0 -> anti-K0S e+ pi- nu, Br = 0.0144 - fRegistry.addClone("Dpm/electron/", "Dpm/kaon/"); // D+ -> K- pi+ e+ nu, Br = 0.0402 | D+ -> anti-K*(892)0 e+ nu, Br = 0.0540 // D+ -> anti-K0S e+ nu, Br = 0.0872 - fRegistry.addClone("Ds/electron/", "Ds/kaon/"); // Ds+ -> K0S e+ nu, Br = 0.0034 // Ds+ -> phi e+ nu, Br = 0.0239 - - fRegistry.add("Generated/D0/prompt/hs", "#eta correlation from charm hadron;p_{T,e} (GeV/c);p_{T,K} (GeV/c);#eta_{e};#eta_{K};", kTHnSparseF, {{100, 0, 10}, {100, 0, 10}, {200, -10, +10}, {200, -10, 10}}, false); - fRegistry.addClone("Generated/D0/prompt/", "Generated/D0/nonprompt/"); + fRegistry.add("Prefilter/before/uls/hMee", "hMee;m_{ee} (GeV/c^{2});", kTH1F, {{500, 0, 5}}, false); + fRegistry.addClone("Prefilter/before/uls/", "Prefilter/before/lspp/"); + fRegistry.addClone("Prefilter/before/uls/", "Prefilter/before/lsmm/"); + fRegistry.addClone("Prefilter/before/", "Prefilter/after/"); + + // electron-related histograms + fRegistry.add("Data/electron/hs", "hs;p_{T,e} (GeV/c);#eta_{e};#varphi_{e} (rad.);DCA_{e}^{3D} (#sigma);", kTHnSparseF, {{100, 0, 10}, {20, -1, +1}, {90, 0, 2 * M_PI}, {100, 0, 10}}, false); + fRegistry.addClone("Data/electron/", "MC/eFromPromptLF/"); + fRegistry.addClone("Data/electron/", "MC/eFromNonPromptLF/"); + fRegistry.addClone("Data/electron/", "MC/eFromPromptJpsi/"); + fRegistry.addClone("Data/electron/", "MC/eFromNonPromptJpsi/"); + fRegistry.addClone("Data/electron/", "MC/eFromPromptD0/"); + fRegistry.addClone("Data/electron/", "MC/eFromPromptDpm/"); + fRegistry.addClone("Data/electron/", "MC/eFromPromptDs/"); + fRegistry.addClone("Data/electron/", "MC/eFromPromptLcpm/"); + fRegistry.addClone("Data/electron/", "MC/eFromPromptXic0/"); + // fRegistry.addClone("Data/electron/", "MC/eFromPromptXicpm/"); // cannot be detected + fRegistry.addClone("Data/electron/", "MC/eFromPromptOmegac0/"); + fRegistry.addClone("Data/electron/", "MC/eFromNonPromptD0/"); + fRegistry.addClone("Data/electron/", "MC/eFromNonPromptDpm/"); + fRegistry.addClone("Data/electron/", "MC/eFromNonPromptDs/"); + fRegistry.addClone("Data/electron/", "MC/eFromNonPromptLcpm/"); + fRegistry.addClone("Data/electron/", "MC/eFromNonPromptXic0/"); + // fRegistry.addClone("Data/electron/", "MC/eFromNonPromptXicpm/"); // cannot be detected + fRegistry.addClone("Data/electron/", "MC/eFromNonPromptOmegac0/"); + fRegistry.addClone("Data/electron/", "MC/eFromB0/"); + fRegistry.addClone("Data/electron/", "MC/eFromBpm/"); + fRegistry.addClone("Data/electron/", "MC/eFromBs/"); + fRegistry.addClone("Data/electron/", "MC/eFromBc/"); + fRegistry.addClone("Data/electron/", "MC/eFromLb0/"); + + // for V0 (Lambda) + fRegistry.add("Data/V0/hPt", "pT of V0;p_{T} (GeV/c)", kTH1F, {{100, 0, 10}}, false); + fRegistry.add("Data/V0/hYPhi", "rapidity vs. #varphi of V0;#varphi (rad.);rapidity_{#Lambda}", kTH2F, {{90, 0, 2 * M_PI}, {80, -2, +2}}, false); + fRegistry.add("Data/V0/hAP", "Ap plot;#alpha;q_{T} (GeV/c)", kTH2F, {{200, -1, 1}, {250, 0, 0.25}}, false); + fRegistry.add("Data/V0/hLxy", "decay length from PV;L_{xy} (cm)", kTH1F, {{100, 0, 10}}, false); + fRegistry.add("Data/V0/hCosPA", "cosPA;cosine of pointing angle", kTH1F, {{100, 0.99, 1}}, false); + fRegistry.add("Data/V0/hDCA2Legs", "distance between 2 legs at PCA;distance between 2 legs (cm)", kTH1F, {{100, 0, 1}}, false); + fRegistry.add("Data/V0/hMassK0S", "K0S mass;m_{#pi#pi} (GeV/c^{2})", kTH1F, {{100, 0.45, 0.55}}, false); + fRegistry.add("Data/V0/hMassLambda", "Lambda mass;m_{p#pi^{-}} (GeV/c^{2})", kTH1F, {{100, 1.08, 1.18}}, false); + fRegistry.add("Data/V0/hMassAntiLambda", "Anti-Lambda mass;m_{#bar{p}#pi^{+}} (GeV/c^{2})", kTH1F, {{100, 1.08, 1.18}}, false); + + // for cascade + fRegistry.add("Data/Cascade/hPt", "pT of V0;p_{T} (GeV/c)", kTH1F, {{100, 0, 10}}, false); + fRegistry.add("Data/Cascade/hYPhi", "rapidity vs. #varphi of V0;#varphi (rad.);rapidity_{#Lambda}", kTH2F, {{90, 0, 2 * M_PI}, {80, -2, +2}}, false); + fRegistry.add("Data/Cascade/hCosPA", "cosPA;cosine of pointing angle", kTH1F, {{100, 0.99, 1}}, false); + fRegistry.add("Data/Cascade/hDCA2Legs", "distance between 2 legs at PCA;distance between 2 legs (cm)", kTH1F, {{100, 0, 1}}, false); + fRegistry.add("Data/Cascade/hV0CosPA", "cosPA of V0 in cascade;cosine of pointing angle", kTH1F, {{100, 0.99, 1}}, false); + fRegistry.add("Data/Cascade/hV0DCA2Legs", "distance between 2 legs at PCA of V0 in cascade;distance between 2 legs (cm)", kTH1F, {{100, 0, 1}}, false); + + fRegistry.add("Data/Cascade/hMassLambda", "Lambda mass;m_{p#pi^{-}} (GeV/c^{2})", kTH1F, {{100, 1.08, 1.18}}, false); + fRegistry.add("Data/Cascade/hMassXi", "#Xi mass;m_{#Lambda#pi} (GeV/c^{2})", kTH1F, {{100, 1.27, 1.37}}, false); + fRegistry.add("Data/Cascade/hMassOmega", "#Omega mass;m_{#LambdaK} (GeV/c^{2})", kTH1F, {{100, 1.62, 1.72}}, false); + + // for e-L pair + fRegistry.add("Data/eL/RS/hs", "hs;m_{e#Lambda} (GeV/c^{2});p_{T,e} (GeV/c);DCA_{e}^{3D} (#sigma);L_{xy} (cm);", kTHnSparseF, {{20, 1.1, 3.1}, {100, 0, 10}, {100, 0, 10}, {500, 0, 0.5}}, false); + fRegistry.add("Data/eL/RS/hCosPA", "cos PA;cosPA", kTH1F, {{100, 0.99, 1.0}}, false); + fRegistry.add("Data/eL/RS/hDCA2Legs", "distance between 2 legs at PCA;distance between 2 legs at PCA (cm)", kTH1F, {{500, 0.0, 0.5}}, false); + fRegistry.add("Data/eL/RS/hLxy", "distance between PV and SV in XY;L_{xy} (cm)", kTH1F, {{500, 0.0, 0.5}}, false); + fRegistry.add("Data/eL/RS/hLz", "distance between PV and SV in Z;L_{z} (cm)", kTH1F, {{500, 0.0, 0.5}}, false); + fRegistry.addClone("Data/eL/RS/", "Data/eL/WS/"); // right and wrong sign + fRegistry.addClone("Data/eL/RS/", "MC/eLfromPromptLcpm/"); + fRegistry.addClone("Data/eL/RS/", "MC/eLfromNonPromptLcpm/"); + + // for e-Xi pair + fRegistry.add("Data/eXi/RS/hs", "hs;m_{e#Xi} (GeV/c^{2});p_{T,e} (GeV/c);DCA_{e}^{3D} (#sigma);L_{xy} (cm);", kTHnSparseF, {{20, 1.1, 3.1}, {100, 0, 10}, {100, 0, 10}, {500, 0, 0.5}}, false); + fRegistry.add("Data/eXi/RS/hCosPA", "cos PA;cosPA", kTH1F, {{100, 0.99, 1.0}}, false); + fRegistry.add("Data/eXi/RS/hDCA2Legs", "distance between 2 legs at PCA;distance between 2 legs at PCA (cm)", kTH1F, {{500, 0.0, 0.5}}, false); + fRegistry.add("Data/eXi/RS/hLxy", "distance between PV and SV in XY;L_{xy} (cm)", kTH1F, {{500, 0.0, 0.5}}, false); + fRegistry.add("Data/eXi/RS/hLz", "distance between PV and SV in Z;L_{z} (cm)", kTH1F, {{500, 0.0, 0.5}}, false); + fRegistry.addClone("Data/eXi/RS/", "Data/eXi/WS/"); // right and wrong sign + fRegistry.addClone("Data/eXi/RS/", "MC/eXifromPromptXic0/"); + fRegistry.addClone("Data/eXi/RS/", "MC/eXifromNonPromptXic0/"); + + // for e-Omega pair + fRegistry.add("Data/eOmega/RS/hs", "hs;m_{e#Omega} (GeV/c^{2});p_{T,e} (GeV/c);DCA_{e}^{3D} (#sigma);L_{xy} (cm);", kTHnSparseF, {{20, 1.1, 3.1}, {100, 0, 10}, {100, 0, 10}, {500, 0, 0.5}}, false); + fRegistry.add("Data/eOmega/RS/hCosPA", "cos PA;cosPA", kTH1F, {{100, 0.99, 1.0}}, false); + fRegistry.add("Data/eOmega/RS/hDCA2Legs", "distance between 2 legs at PCA;distance between 2 legs at PCA (cm)", kTH1F, {{500, 0.0, 0.5}}, false); + fRegistry.add("Data/eOmega/RS/hLxy", "distance between PV and SV in XY;L_{xy} (cm)", kTH1F, {{500, 0.0, 0.5}}, false); + fRegistry.add("Data/eOmega/RS/hLz", "distance between PV and SV in Z;L_{z} (cm)", kTH1F, {{500, 0.0, 0.5}}, false); + fRegistry.addClone("Data/eOmega/RS/", "Data/eOmega/WS/"); // right and wrong sign + fRegistry.addClone("Data/eOmega/RS/", "MC/eOmegafromPromptOmegac0/"); + fRegistry.addClone("Data/eOmega/RS/", "MC/eOmegafromNonPromptOmegac0/"); } template bool isKaon(TTrack const& track) { // TOFif - bool is_ka_included_TPC = kaoncuts.cfg_min_TPCNsigmaKa < track.tpcNSigmaKa() && track.tpcNSigmaKa() < kaoncuts.cfg_max_TPCNsigmaKa; - bool is_ka_included_TOF = track.hasTOF() ? (kaoncuts.cfg_min_TOFNsigmaKa < track.tofNSigmaKa() && track.tofNSigmaKa() < kaoncuts.cfg_max_TOFNsigmaKa && track.tofChi2() < kaoncuts.cfg_max_chi2tof) : true; + bool is_ka_included_TPC = kaoncut.cfg_min_TPCNsigmaKa < track.tpcNSigmaKa() && track.tpcNSigmaKa() < kaoncut.cfg_max_TPCNsigmaKa; + bool is_ka_included_TOF = track.hasTOF() ? (kaoncut.cfg_min_TOFNsigmaKa < track.tofNSigmaKa() && track.tofNSigmaKa() < kaoncut.cfg_max_TOFNsigmaKa) : true; return is_ka_included_TPC && is_ka_included_TOF; } @@ -357,8 +430,8 @@ struct taggingHFE { bool isPion(TTrack const& track) { // TOFif - bool is_pi_included_TPC = v0cuts.cfg_min_TPCNsigmaPi < track.tpcNSigmaPi() && track.tpcNSigmaPi() < v0cuts.cfg_max_TPCNsigmaPi; - bool is_pi_included_TOF = track.hasTOF() ? (v0cuts.cfg_min_TOFNsigmaPi < track.tofNSigmaPi() && track.tofNSigmaPi() < v0cuts.cfg_max_TOFNsigmaPi && track.tofChi2() < v0cuts.cfg_max_chi2tof) : true; + bool is_pi_included_TPC = v0cut.cfg_min_TPCNsigmaPi < track.tpcNSigmaPi() && track.tpcNSigmaPi() < v0cut.cfg_max_TPCNsigmaPi; + bool is_pi_included_TOF = track.hasTOF() ? (v0cut.cfg_min_TOFNsigmaPi < track.tofNSigmaPi() && track.tofNSigmaPi() < v0cut.cfg_max_TOFNsigmaPi) : true; return is_pi_included_TPC && is_pi_included_TOF; } @@ -366,63 +439,76 @@ struct taggingHFE { bool isProton(TTrack const& track) { // TOFif - bool is_pr_included_TPC = v0cuts.cfg_min_TPCNsigmaPr < track.tpcNSigmaPr() && track.tpcNSigmaPr() < v0cuts.cfg_max_TPCNsigmaPr; - bool is_pr_included_TOF = track.hasTOF() ? (v0cuts.cfg_min_TOFNsigmaPr < track.tofNSigmaPr() && track.tofNSigmaPr() < v0cuts.cfg_max_TOFNsigmaPr && track.tofChi2() < v0cuts.cfg_max_chi2tof) : true; + bool is_pr_included_TPC = v0cut.cfg_min_TPCNsigmaPr < track.tpcNSigmaPr() && track.tpcNSigmaPr() < v0cut.cfg_max_TPCNsigmaPr; + bool is_pr_included_TOF = track.hasTOF() ? (v0cut.cfg_min_TOFNsigmaPr < track.tofNSigmaPr() && track.tofNSigmaPr() < v0cut.cfg_max_TOFNsigmaPr) : true; return is_pr_included_TPC && is_pr_included_TOF; } + template + bool isElectron(TTrack const& track) + { + // TOFif + bool is_el_included_TPC = electroncut.cfg_min_TPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < electroncut.cfg_max_TPCNsigmaEl; + bool is_el_included_TOF = track.hasTOF() ? (electroncut.cfg_min_TOFNsigmaEl < track.tofNSigmaEl() && track.tofNSigmaEl() < electroncut.cfg_max_TOFNsigmaEl) : true; + return is_el_included_TPC && is_el_included_TOF; + } + template - bool isSelectedTrackForElectron(TTrack const& track, TTrackParCov const& trackParCov, const float dcaXY, const float dcaZ) + bool isSelectedElectron(TTrack const& track, TTrackParCov const& trackParCov, const float dcaXY, const float dcaZ) { if (!track.hasITS() || !track.hasTPC()) { return false; } - if (trackParCov.getPt() < electroncuts.cfg_min_pt_track || electroncuts.cfg_max_pt_track < trackParCov.getPt()) { + if (trackParCov.getPt() < electroncut.cfg_min_pt_track || electroncut.cfg_max_pt_track < trackParCov.getPt()) { return false; } - if (trackParCov.getEta() < electroncuts.cfg_min_eta_track || electroncuts.cfg_max_eta_track < trackParCov.getEta()) { + if (trackParCov.getEta() < electroncut.cfg_min_eta_track || electroncut.cfg_max_eta_track < trackParCov.getEta()) { return false; } - if (std::fabs(dcaXY) > electroncuts.cfg_max_dcaxy) { + if (std::fabs(dcaXY) > electroncut.cfg_max_dcaxy) { return false; } - if (std::fabs(dcaZ) > electroncuts.cfg_max_dcaz) { + if (std::fabs(dcaZ) > electroncut.cfg_max_dcaz) { return false; } - if (track.itsChi2NCl() > electroncuts.cfg_max_chi2its) { + if (track.itsChi2NCl() < 0.f || electroncut.cfg_max_chi2its < track.itsChi2NCl()) { return false; } - if (track.itsNCls() < electroncuts.cfg_min_ncluster_its) { + if (track.itsNCls() < electroncut.cfg_min_ncluster_its) { return false; } - if (track.itsNClsInnerBarrel() < electroncuts.cfg_min_ncluster_itsib) { + if (track.itsNClsInnerBarrel() < electroncut.cfg_min_ncluster_itsib) { return false; } - if (track.tpcChi2NCl() > electroncuts.cfg_max_chi2tpc) { + if (track.tpcChi2NCl() < 0.f || electroncut.cfg_max_chi2tpc < track.tpcChi2NCl()) { return false; } - if (track.tpcNClsFound() < electroncuts.cfg_min_ncluster_tpc) { + if (track.tpcNClsFound() < electroncut.cfg_min_ncluster_tpc) { return false; } - if (track.tpcNClsCrossedRows() < electroncuts.cfg_min_ncrossedrows_tpc) { + if (track.tpcNClsCrossedRows() < electroncut.cfg_min_ncrossedrows_tpc) { return false; } - if (track.tpcCrossedRowsOverFindableCls() < electroncuts.cfg_min_cr2findable_ratio_tpc) { + if (track.tpcCrossedRowsOverFindableCls() < electroncut.cfg_min_cr2findable_ratio_tpc) { return false; } - if (track.tpcFractionSharedCls() > electroncuts.cfg_max_frac_shared_clusters_tpc) { + if (track.tpcFractionSharedCls() > electroncut.cfg_max_frac_shared_clusters_tpc) { + return false; + } + + if (!isElectron(track)) { return false; } @@ -430,103 +516,135 @@ struct taggingHFE { } template - bool isSelectedTrackForKaon(TTrack const& track, TTrackParCov const& trackParCov, const float dcaXY, const float dcaZ) + bool isSelectedElectronLoose(TTrack const& track, TTrackParCov const& trackParCov, const float dcaXY, const float dcaZ) { - if (!track.hasITS() || !track.hasTPC()) { + if (!track.hasITS()) { return false; } - if (trackParCov.getPt() < kaoncuts.cfg_min_pt_track || kaoncuts.cfg_max_pt_track < trackParCov.getPt()) { + if (trackParCov.getPt() < loose_electroncut.cfg_min_pt_track || loose_electroncut.cfg_max_pt_track < trackParCov.getPt()) { return false; } - if (trackParCov.getEta() < kaoncuts.cfg_min_eta_track || kaoncuts.cfg_max_eta_track < trackParCov.getEta()) { + if (trackParCov.getEta() < loose_electroncut.cfg_min_eta_track || loose_electroncut.cfg_max_eta_track < trackParCov.getEta()) { return false; } - if (std::fabs(dcaXY) > kaoncuts.cfg_max_dcaxy) { + if (std::fabs(dcaXY) > loose_electroncut.cfg_max_dcaxy) { return false; } - if (std::fabs(dcaZ) > kaoncuts.cfg_max_dcaz) { + if (std::fabs(dcaZ) > loose_electroncut.cfg_max_dcaz) { return false; } - if (track.itsChi2NCl() > kaoncuts.cfg_max_chi2its) { + if (loose_electroncut.cfg_max_chi2its < track.itsChi2NCl()) { return false; } - if (track.itsNCls() < kaoncuts.cfg_min_ncluster_its) { + if (track.itsNCls() < loose_electroncut.cfg_min_ncluster_its) { return false; } - if (track.itsNClsInnerBarrel() < kaoncuts.cfg_min_ncluster_itsib) { + if (track.itsNClsInnerBarrel() < loose_electroncut.cfg_min_ncluster_itsib) { return false; } - if (track.tpcChi2NCl() > kaoncuts.cfg_max_chi2tpc) { - return false; - } + if (track.hasTPC()) { + if (loose_electroncut.cfg_max_chi2tpc < track.tpcChi2NCl()) { + return false; + } - if (track.tpcNClsFound() < kaoncuts.cfg_min_ncluster_tpc) { - return false; - } + if (track.tpcNClsFound() < loose_electroncut.cfg_min_ncluster_tpc) { + return false; + } - if (track.tpcNClsCrossedRows() < kaoncuts.cfg_min_ncrossedrows_tpc) { - return false; - } + if (track.tpcNClsCrossedRows() < loose_electroncut.cfg_min_ncrossedrows_tpc) { + return false; + } - if (track.tpcCrossedRowsOverFindableCls() < kaoncuts.cfg_min_cr2findable_ratio_tpc) { - return false; - } + if (track.tpcCrossedRowsOverFindableCls() < loose_electroncut.cfg_min_cr2findable_ratio_tpc) { + return false; + } - if (track.tpcFractionSharedCls() > kaoncuts.cfg_max_frac_shared_clusters_tpc) { - return false; + if (track.tpcFractionSharedCls() > loose_electroncut.cfg_max_frac_shared_clusters_tpc) { + return false; + } + + if (!isElectron(track)) { + return false; + } } return true; } - template - bool isSelectedV0Leg(TTrack const& track, const float dcaXY) + template + bool isLambda(TV0 const& v0) { - if (!track.hasITS() || !track.hasTPC()) { - return false; + return (v0cut.cfg_min_mass_lambda < v0.mLambda() && v0.mLambda() < v0cut.cfg_max_mass_lambda) && (v0.mK0Short() < v0cut.cfg_min_mass_k0s_veto || v0cut.cfg_max_mass_k0s_veto < v0.mK0Short()); + } + + template + bool isAntiLambda(TV0 const& v0) + { + return (v0cut.cfg_min_mass_lambda < v0.mAntiLambda() && v0.mAntiLambda() < v0cut.cfg_max_mass_lambda) && (v0.mK0Short() < v0cut.cfg_min_mass_k0s_veto || v0cut.cfg_max_mass_k0s_veto < v0.mK0Short()); + } + + template + bool isXi(TCascade const& cascade) + { + return (cascadecut.cfg_min_mass_Xi < cascade.mXi() && cascade.mXi() < cascadecut.cfg_max_mass_Xi) && (cascade.mOmega() < cascadecut.cfg_min_mass_Omega_veto || cascadecut.cfg_max_mass_Omega_veto < cascade.mOmega()); + } + + template + bool isOmega(TCascade const& cascade) + { + return (cascadecut.cfg_min_mass_Omega < cascade.mOmega() && cascade.mOmega() < cascadecut.cfg_max_mass_Omega) && (cascade.mXi() < cascadecut.cfg_min_mass_Xi || cascadecut.cfg_max_mass_Xi < cascade.mXi()); + } + + template + bool isSelectedV0Leg(TTrack const& track) + { + if constexpr (isMC) { + if (!track.has_mcParticle()) { + return false; + } } - if (std::fabs(dcaXY) < v0cuts.cfg_min_dcaxy) { + if (!track.hasITS() || !track.hasTPC()) { return false; } - if (track.itsChi2NCl() > v0cuts.cfg_max_chi2its) { + if (track.itsChi2NCl() > v0cut.cfg_max_chi2its) { return false; } - if (track.itsNCls() < v0cuts.cfg_min_ncluster_its) { + if (track.itsNCls() < v0cut.cfg_min_ncluster_its) { return false; } - if (track.itsNClsInnerBarrel() < v0cuts.cfg_min_ncluster_itsib) { + if (track.itsNClsInnerBarrel() < v0cut.cfg_min_ncluster_itsib) { return false; } - if (track.tpcChi2NCl() > v0cuts.cfg_max_chi2tpc) { + if (track.tpcChi2NCl() > v0cut.cfg_max_chi2tpc) { return false; } - if (track.tpcNClsFound() < v0cuts.cfg_min_ncluster_tpc) { + if (track.tpcNClsFound() < v0cut.cfg_min_ncluster_tpc) { return false; } - if (track.tpcNClsCrossedRows() < v0cuts.cfg_min_ncrossedrows_tpc) { + if (track.tpcNClsCrossedRows() < v0cut.cfg_min_ncrossedrows_tpc) { return false; } - if (track.tpcCrossedRowsOverFindableCls() < v0cuts.cfg_min_cr2findable_ratio_tpc) { + if (track.tpcCrossedRowsOverFindableCls() < v0cut.cfg_min_cr2findable_ratio_tpc) { return false; } - if (track.tpcFractionSharedCls() > v0cuts.cfg_max_frac_shared_clusters_tpc) { + if (track.tpcFractionSharedCls() > v0cut.cfg_max_frac_shared_clusters_tpc) { return false; } @@ -547,777 +665,906 @@ struct taggingHFE { fRegistry.fill(HIST("Event/hMultFT0CvsMultNTracksPV"), collision.multFT0C(), collision.multNTracksPV()); } - template - void fillElectronHistograms(TTrack const& track, TTrackParCov const& trackParCov, const float dcaXY, const float dcaZ) + template + void fillV0Histograms(TV0 const& v0) { - if (std::find(used_electronIds.begin(), used_electronIds.end(), std::make_pair(findId, track.globalIndex())) == used_electronIds.end()) { - float dca3DinSigma = dca3DinSigmaOTF(dcaXY, dcaZ, trackParCov.getSigmaY2(), trackParCov.getSigmaZ2(), trackParCov.getSigmaZY()); - fRegistry.fill(HIST(hadron_names[charmHadronId]) + HIST("electron/") + HIST(promptTypes[promptId]) + HIST(hTypes[findId]) + HIST("hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); - fRegistry.fill(HIST(hadron_names[charmHadronId]) + HIST("electron/") + HIST(promptTypes[promptId]) + HIST(hTypes[findId]) + HIST("hTPCdEdx"), track.tpcInnerParam(), track.tpcSignal()); - fRegistry.fill(HIST(hadron_names[charmHadronId]) + HIST("electron/") + HIST(promptTypes[promptId]) + HIST(hTypes[findId]) + HIST("hTOFbeta"), trackParCov.getP(), track.beta()); - used_electronIds.emplace_back(std::make_pair(findId, track.globalIndex())); - } + fRegistry.fill(HIST("Data/V0/hPt"), v0.pt()); + fRegistry.fill(HIST("Data/V0/hYPhi"), v0.phi(), v0.yLambda()); + fRegistry.fill(HIST("Data/V0/hAP"), v0.alpha(), v0.qtarm()); + fRegistry.fill(HIST("Data/V0/hCosPA"), v0.v0cosPA()); + fRegistry.fill(HIST("Data/V0/hLxy"), v0.v0radius()); + fRegistry.fill(HIST("Data/V0/hDCA2Legs"), v0.dcaV0daughters()); + fRegistry.fill(HIST("Data/V0/hMassK0S"), v0.mK0Short()); + fRegistry.fill(HIST("Data/V0/hMassLambda"), v0.mLambda()); + fRegistry.fill(HIST("Data/V0/hMassAntiLambda"), v0.mAntiLambda()); } - template - void fillKaonHistograms(TTrack const& track, TTrackParCov const& trackParCov, const float dcaXY, const float dcaZ) + template + void fillCascadeHistograms(TCollision const& collision, TCascade const& cascade) { - float dca3DinSigma = dca3DinSigmaOTF(dcaXY, dcaZ, trackParCov.getSigmaY2(), trackParCov.getSigmaZ2(), trackParCov.getSigmaZY()); - fRegistry.fill(HIST(hadron_names[charmHadronId]) + HIST("kaon/") + HIST(promptTypes[promptId]) + HIST(hTypes[findId]) + HIST("hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); - fRegistry.fill(HIST(hadron_names[charmHadronId]) + HIST("kaon/") + HIST(promptTypes[promptId]) + HIST(hTypes[findId]) + HIST("hTPCdEdx"), track.tpcInnerParam(), track.tpcSignal()); - fRegistry.fill(HIST(hadron_names[charmHadronId]) + HIST("kaon/") + HIST(promptTypes[promptId]) + HIST(hTypes[findId]) + HIST("hTOFbeta"), trackParCov.getP(), track.beta()); + fRegistry.fill(HIST("Data/Cascade/hPt"), cascade.pt()); + fRegistry.fill(HIST("Data/Cascade/hMassLambda"), cascade.mLambda()); + fRegistry.fill(HIST("Data/Cascade/hCosPA"), cascade.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + fRegistry.fill(HIST("Data/Cascade/hDCA2Legs"), cascade.dcacascdaughters()); + fRegistry.fill(HIST("Data/Cascade/hV0CosPA"), cascade.v0cosPA(collision.posX(), collision.posY(), collision.posZ())); + fRegistry.fill(HIST("Data/Cascade/hV0DCA2Legs"), cascade.dcaV0daughters()); + fRegistry.fill(HIST("Data/Cascade/hMassXi"), cascade.mXi()); + fRegistry.fill(HIST("Data/Cascade/hMassOmega"), cascade.mOmega()); } - float dca3DinSigmaOTF(const float dcaXY, const float dcaZ, const float cYY, const float cZZ, const float cZY) + template + void fillElectronHistograms(TTrack const& track, TMCParticles const& mcParticles) { - float det = cYY * cZZ - cZY * cZY; // determinant - if (det < 0) { - return 999.f; - } else { - return std::sqrt(std::fabs((dcaXY * dcaXY * cZZ + dcaZ * dcaZ * cYY - 2. * dcaXY * dcaZ * cZY) / det / 2.)); // dca 3d in sigma - } - } - - template - void runPairEandTrack(TCollision const& collision, TElectron const& ele, TTrackIds const& trackIds, TTracks const& tracks, TMCParticles const& mcParticles, TMCCollisions const&) - { - std::array pVtx = {collision.posX(), collision.posY(), collision.posZ()}; - const auto& mcele = ele.template mcParticle_as(); - const auto& mcCollision1 = mcele.template mcCollision_as(); - - if (cfgEventGeneratorType >= 0 && mcCollision1.getSubGeneratorId() != cfgEventGeneratorType) { - return; - } - - // o2::dataformats::DCA mDcaInfoCov; mDcaInfoCov.set(999, 999, 999, 999, 999); - auto eleParCov = getTrackParCov(ele); - eleParCov.setPID(o2::track::PID::Electron); - // mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); - // mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, eleParCov, 2.f, matCorr, &mDcaInfoCov); + auto trackParCov = getTrackParCov(track); + trackParCov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); float dcaXY = mDcaInfoCov.getY(); float dcaZ = mDcaInfoCov.getZ(); + float dca3DinSigma = dca3DinSigmaOTF(dcaXY, dcaZ, trackParCov.getSigmaY2(), trackParCov.getSigmaZ2(), trackParCov.getSigmaZY()); - for (const auto& trackId : trackIds) { - if (trackId == ele.globalIndex()) { - continue; - } + if (isSelectedElectron(track, trackParCov, dcaXY, dcaZ)) { + return; + } - const auto& track = tracks.rawIteratorAt(trackId); + if constexpr (isMC) { const auto& mctrack = track.template mcParticle_as(); - const auto& mcCollision2 = mctrack.template mcCollision_as(); - - auto trackParCov = getTrackParCov(track); - trackParCov.setPID(o2::track::PID::Kaon); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); - float dcaXY_h = mDcaInfoCov.getY(); - float dcaZ_h = mDcaInfoCov.getZ(); - std::array svpos = {0.}; // secondary vertex position - std::array pvec0 = {0.}; - std::array pvec1 = {0.}; - - int nCand = 0; - try { - nCand = fitter.process(eleParCov, trackParCov); - } catch (...) { - LOG(error) << "Exception caught in DCA fitter process call!"; - continue; - } - if (nCand == 0) { - continue; + if (std::abs(mctrack.pdgCode()) != 11) { + return; } - - fitter.propagateTracksToVertex(); // propagate e and K to D vertex - const auto& vtx = fitter.getPCACandidate(); - for (int i = 0; i < 3; i++) { - svpos[i] = vtx[i]; - } - fitter.getTrack(0).getPxPyPzGlo(pvec0); // electron - fitter.getTrack(1).getPxPyPzGlo(pvec1); // strange hadron - std::array pvecSum = {pvec0[0] + pvec1[0], pvec0[1] + pvec1[1], pvec0[2] + pvec1[2]}; - - float dca2legs = std::sqrt(fitter.getChi2AtPCACandidate()); - float lxy = std::sqrt(std::pow(svpos[0] - collision.posX(), 2) + std::pow(svpos[1] - collision.posY(), 2)); - float lz = std::fabs(svpos[2] - collision.posZ()); - float mEK = RecoDecay::m(std::array{pvec0, pvec1}, std::array{o2::constants::physics::MassElectron, o2::constants::physics::MassKaonCharged}); - float cpa = RecoDecay::cpa(pVtx, svpos, pvecSum); - float cpaXY = RecoDecay::cpaXY(pVtx, svpos, pvecSum); - // float ptEK = RecoDecay::sqrtSumOfSquares(pvec0[0] + pvec1[0], pvec0[1] + pvec1[1]); - - float deta = RecoDecay::eta(pvec1) - RecoDecay::eta(pvec0); - float dphi = RecoDecay::phi(pvec1[0], pvec1[1]) - RecoDecay::phi(pvec0[0], pvec0[1]); - o2::math_utils::bringToPMPi(dphi); - float reldpt = (RecoDecay::sqrtSumOfSquares(pvec1[0], pvec1[1]) - RecoDecay::sqrtSumOfSquares(pvec0[0], pvec0[1])) / RecoDecay::sqrtSumOfSquares(pvec0[0], pvec0[1]); - - if (cpa < svcuts.cfg_min_cospa || cpaXY < svcuts.cfg_min_cospaXY || svcuts.cfg_max_mass_eK < mEK || lxy < svcuts.cfg_min_lxy || svcuts.cfg_max_dca2legs < dca2legs) { - continue; + if (!(mctrack.isPhysicalPrimary() || mctrack.producedByGenerator())) { + return; } + const auto& mcmother = mctrack.template mothers_first_as(); // mother particle of electron + int pdg_mother = std::abs(mcmother.pdgCode()); - fRegistry.fill(HIST("e_Kpm/all/hDCA2Legs"), dca2legs); - fRegistry.fill(HIST("e_Kpm/all/hLxy"), lxy); - fRegistry.fill(HIST("e_Kpm/all/hLz"), lz); - fRegistry.fill(HIST("e_Kpm/all/hCosPAXY"), cpaXY); - fRegistry.fill(HIST("e_Kpm/all/hCosPA"), cpa); - fRegistry.fill(HIST("e_Kpm/all/hMass"), mEK); - fRegistry.fill(HIST("e_Kpm/all/hMass_CosPA"), mEK, cpa); - fRegistry.fill(HIST("e_Kpm/all/hDeltaEtaDeltaPhi"), dphi, deta); - fRegistry.fill(HIST("e_Kpm/all/hRelDeltaPt"), reldpt); - fRegistry.fill(HIST("e_Kpm/all/hProdDCAxy"), dcaXY / std::sqrt(eleParCov.getSigmaY2()) * dcaXY_h / std::sqrt(trackParCov.getSigmaY2())); - fRegistry.fill(HIST("e_Kpm/all/hCorrelationDCAxy"), dcaXY / std::sqrt(eleParCov.getSigmaY2()), dcaXY_h / std::sqrt(trackParCov.getSigmaY2())); - fRegistry.fill(HIST("e_Kpm/all/hCorrelationDCAz"), dcaZ / std::sqrt(eleParCov.getSigmaZ2()), dcaZ_h / std::sqrt(trackParCov.getSigmaZ2())); - - int commonMotherId = o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2ProngsWithoutPDG(mcele, mctrack); // e and K+/- - if (commonMotherId < 0 && mctrack.has_mothers()) { - const auto& mctrack_mother = mctrack.template mothers_first_as(); // mother particle of Kaon. For example K*(892)+ -> K+ pi0 or K*(892)0 -> K+ pi- and CC, or phi->K+K- - if (std::abs(mctrack_mother.pdgCode()) == 313 || std::abs(mctrack_mother.pdgCode()) == 323 || std::abs(mctrack_mother.pdgCode()) == 333) { - commonMotherId = o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2ProngsWithoutPDG(mcele, mctrack_mother); // e and K*(892)0 or K*(892)+/- or phi(1019) + if (pdg_mother == 111 || pdg_mother == 221 || pdg_mother == 331 || pdg_mother == 113 || pdg_mother == 223 || pdg_mother == 333) { // LF + if (IsFromCharm(mcmother, mcParticles) < 0 && IsFromBeauty(mcmother, mcParticles) < 0) { + fRegistry.fill(HIST("MC/eFromPromptLF/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + } else { + fRegistry.fill(HIST("MC/eFromNonPromptLF/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); } - } - if (commonMotherId >= 0) { // common mother is correctly found by DCAFitterN. - if (std::abs(mctrack.pdgCode()) == 321 && mcCollision1.globalIndex() == mcCollision2.globalIndex()) { // common mother is correctly found by DCAFitterN. - const auto& cmp = mcParticles.rawIteratorAt(commonMotherId); - if (std::abs(cmp.pdgCode()) == 421) { // D0 - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(cmp, mcParticles) < 0) { - fillElectronHistograms<2, 1, 0>(ele, eleParCov, dcaXY, dcaZ); // nprompt charm - } else { - fillElectronHistograms<2, 1, 1>(ele, eleParCov, dcaXY, dcaZ); // nonprompt charm - } - - fRegistry.fill(HIST("e_Kpm/D0/hDCA2Legs"), dca2legs); - fRegistry.fill(HIST("e_Kpm/D0/hLxy"), lxy); - fRegistry.fill(HIST("e_Kpm/D0/hLz"), lz); - fRegistry.fill(HIST("e_Kpm/D0/hCosPAXY"), cpaXY); - fRegistry.fill(HIST("e_Kpm/D0/hCosPA"), cpa); - fRegistry.fill(HIST("e_Kpm/D0/hMass"), mEK); - fRegistry.fill(HIST("e_Kpm/D0/hMass_CosPA"), mEK, cpa); - fRegistry.fill(HIST("e_Kpm/D0/hDeltaEtaDeltaPhi"), dphi, deta); - fRegistry.fill(HIST("e_Kpm/D0/hRelDeltaPt"), reldpt); - fRegistry.fill(HIST("e_Kpm/D0/hProdDCAxy"), dcaXY / std::sqrt(eleParCov.getSigmaY2()) * dcaXY_h / std::sqrt(trackParCov.getSigmaY2())); - fRegistry.fill(HIST("e_Kpm/D0/hCorrelationDCAxy"), dcaXY / std::sqrt(eleParCov.getSigmaY2()), dcaXY_h / std::sqrt(trackParCov.getSigmaY2())); - fRegistry.fill(HIST("e_Kpm/D0/hCorrelationDCAz"), dcaZ / std::sqrt(eleParCov.getSigmaZ2()), dcaZ_h / std::sqrt(trackParCov.getSigmaZ2())); - } else if (std::abs(cmp.pdgCode()) == 411) { // Dpm - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(cmp, mcParticles) < 0) { - fillElectronHistograms<3, 1, 0>(ele, eleParCov, dcaXY, dcaZ); // prompt charm - } else { - fillElectronHistograms<3, 1, 1>(ele, eleParCov, dcaXY, dcaZ); // nonprompt charm - } - fRegistry.fill(HIST("e_Kpm/Dpm/hDCA2Legs"), dca2legs); - fRegistry.fill(HIST("e_Kpm/Dpm/hLxy"), lxy); - fRegistry.fill(HIST("e_Kpm/Dpm/hLz"), lz); - fRegistry.fill(HIST("e_Kpm/Dpm/hCosPAXY"), cpaXY); - fRegistry.fill(HIST("e_Kpm/Dpm/hCosPA"), cpa); - fRegistry.fill(HIST("e_Kpm/Dpm/hMass"), mEK); - fRegistry.fill(HIST("e_Kpm/Dpm/hMass_CosPA"), mEK, cpa); - fRegistry.fill(HIST("e_Kpm/Dpm/hDeltaEtaDeltaPhi"), dphi, deta); - fRegistry.fill(HIST("e_Kpm/Dpm/hRelDeltaPt"), reldpt); - fRegistry.fill(HIST("e_Kpm/Dpm/hProdDCAxy"), dcaXY / std::sqrt(eleParCov.getSigmaY2()) * dcaXY_h / std::sqrt(trackParCov.getSigmaY2())); - fRegistry.fill(HIST("e_Kpm/Dpm/hCorrelationDCAxy"), dcaXY / std::sqrt(eleParCov.getSigmaY2()), dcaXY_h / std::sqrt(trackParCov.getSigmaY2())); - fRegistry.fill(HIST("e_Kpm/Dpm/hCorrelationDCAz"), dcaZ / std::sqrt(eleParCov.getSigmaZ2()), dcaZ_h / std::sqrt(trackParCov.getSigmaZ2())); - } else if (std::abs(cmp.pdgCode()) == 431) { // Ds - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(cmp, mcParticles) < 0) { - fillElectronHistograms<4, 1, 0>(ele, eleParCov, dcaXY, dcaZ); // prompt charm - } else { - fillElectronHistograms<4, 1, 1>(ele, eleParCov, dcaXY, dcaZ); // nonprompt charm - } - fRegistry.fill(HIST("e_Kpm/Ds/hDCA2Legs"), dca2legs); - fRegistry.fill(HIST("e_Kpm/Ds/hLxy"), lxy); - fRegistry.fill(HIST("e_Kpm/Ds/hLz"), lz); - fRegistry.fill(HIST("e_Kpm/Ds/hCosPAXY"), cpaXY); - fRegistry.fill(HIST("e_Kpm/Ds/hCosPA"), cpa); - fRegistry.fill(HIST("e_Kpm/Ds/hMass"), mEK); - fRegistry.fill(HIST("e_Kpm/Ds/hMass_CosPA"), mEK, cpa); - fRegistry.fill(HIST("e_Kpm/Ds/hDeltaEtaDeltaPhi"), dphi, deta); - fRegistry.fill(HIST("e_Kpm/Ds/hRelDeltaPt"), reldpt); - fRegistry.fill(HIST("e_Kpm/Ds/hProdDCAxy"), dcaXY / std::sqrt(eleParCov.getSigmaY2()) * dcaXY_h / std::sqrt(trackParCov.getSigmaY2())); - fRegistry.fill(HIST("e_Kpm/Ds/hCorrelationDCAxy"), dcaXY / std::sqrt(eleParCov.getSigmaY2()), dcaXY_h / std::sqrt(trackParCov.getSigmaY2())); - fRegistry.fill(HIST("e_Kpm/Ds/hCorrelationDCAz"), dcaZ / std::sqrt(eleParCov.getSigmaZ2()), dcaZ_h / std::sqrt(trackParCov.getSigmaZ2())); - } + } else if (pdg_mother == 443) { // Jpsi + if (IsFromBeauty(mcmother, mcParticles) < 0) { + fRegistry.fill(HIST("MC/eFromPromptJpsi/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + } else { + fRegistry.fill(HIST("MC/eFromNonPromptJpsi/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); } - } else { // common mother does not exist, but DCAFitterN found something. i.e. fake - const auto& mp = mcele.template mothers_first_as(); - if ((mcele.isPhysicalPrimary() || mcele.producedByGenerator()) && (std::abs(mp.pdgCode()) == 111 || std::abs(mp.pdgCode()) == 221 || std::abs(mp.pdgCode()) == 331 || std::abs(mp.pdgCode()) == 113 || std::abs(mp.pdgCode()) == 223 || std::abs(mp.pdgCode()) == 333)) { // LF - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromCharm(mcele, mcParticles) < 0 && o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(mcele, mcParticles) < 0) { - fillElectronHistograms<0, 2, 0>(ele, eleParCov, dcaXY, dcaZ); - } else { - fillElectronHistograms<0, 2, 1>(ele, eleParCov, dcaXY, dcaZ); - } + } else if (pdg_mother == 411) { // D+/- + if (IsFromBeauty(mcmother, mcParticles) < 0) { + fRegistry.fill(HIST("MC/eFromPromptDpm/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + } else { + fRegistry.fill(HIST("MC/eFromNonPromptDpm/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + } + } else if (pdg_mother == 421) { // D0 + if (IsFromBeauty(mcmother, mcParticles) < 0) { + fRegistry.fill(HIST("MC/eFromPromptD0/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + } else { + fRegistry.fill(HIST("MC/eFromNonPromptD0/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + } + } else if (pdg_mother == 431) { // Ds+/- + if (IsFromBeauty(mcmother, mcParticles) < 0) { + fRegistry.fill(HIST("MC/eFromPromptDs/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + } else { + fRegistry.fill(HIST("MC/eFromNonPromptDs/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + } + } else if (pdg_mother == 4122) { // Lc+/- + if (IsFromBeauty(mcmother, mcParticles) < 0) { + fRegistry.fill(HIST("MC/eFromPromptLcpm/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + } else { + fRegistry.fill(HIST("MC/eFromNonPromptLcpm/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + } + } else if (pdg_mother == 4132) { // Xic0 + if (IsFromBeauty(mcmother, mcParticles) < 0) { + fRegistry.fill(HIST("MC/eFromPromptXic0/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + } else { + fRegistry.fill(HIST("MC/eFromNonPromptXic0/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); } - fRegistry.fill(HIST("e_Kpm/fake/hDCA2Legs"), dca2legs); - fRegistry.fill(HIST("e_Kpm/fake/hLxy"), lxy); - fRegistry.fill(HIST("e_Kpm/fake/hLz"), lz); - fRegistry.fill(HIST("e_Kpm/fake/hCosPAXY"), cpaXY); - fRegistry.fill(HIST("e_Kpm/fake/hCosPA"), cpa); - fRegistry.fill(HIST("e_Kpm/fake/hMass"), mEK); - fRegistry.fill(HIST("e_Kpm/fake/hMass_CosPA"), mEK, cpa); - fRegistry.fill(HIST("e_Kpm/fake/hDeltaEtaDeltaPhi"), dphi, deta); - fRegistry.fill(HIST("e_Kpm/fake/hRelDeltaPt"), reldpt); - fRegistry.fill(HIST("e_Kpm/fake/hProdDCAxy"), dcaXY / std::sqrt(eleParCov.getSigmaY2()) * dcaXY_h / std::sqrt(trackParCov.getSigmaY2())); - fRegistry.fill(HIST("e_Kpm/fake/hCorrelationDCAxy"), dcaXY / std::sqrt(eleParCov.getSigmaY2()), dcaXY_h / std::sqrt(trackParCov.getSigmaY2())); - fRegistry.fill(HIST("e_Kpm/fake/hCorrelationDCAz"), dcaZ / std::sqrt(eleParCov.getSigmaZ2()), dcaZ_h / std::sqrt(trackParCov.getSigmaZ2())); + } else if (pdg_mother == 4332) { // Omegac0 + if (IsFromBeauty(mcmother, mcParticles) < 0) { + fRegistry.fill(HIST("MC/eFromPromptOmegac0/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + } else { + fRegistry.fill(HIST("MC/eFromNonPromptOmegac0/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + } + } else if (pdg_mother == 511) { // B0 + fRegistry.fill(HIST("MC/eFromB0/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + } else if (pdg_mother == 521) { // B+/- + fRegistry.fill(HIST("MC/eFromBpm/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + } else if (pdg_mother == 531) { // Bs0 + fRegistry.fill(HIST("MC/eFromBs/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + } else if (pdg_mother == 541) { // Bc+/- + fRegistry.fill(HIST("MC/eFromBc/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + } else if (pdg_mother == 5122) { // Lb0 + fRegistry.fill(HIST("MC/eFromLb0/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); } - } // end of kaon loop + } else { + fRegistry.fill(HIST("Data/electron/hs"), trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), dca3DinSigma); + } } - template - void runPairEandV0(TCollision const& collision, TElectron const& ele, TV0Ids const& v0Ids, TV0s const& v0s, TMCParticles const& mcParticles, TMCCollisions const&) + float dca3DinSigmaOTF(const float dcaXY, const float dcaZ, const float cYY, const float cZZ, const float cZY) { - std::array pVtx = {collision.posX(), collision.posY(), collision.posZ()}; - const auto& mcele = ele.template mcParticle_as(); - const auto& mcCollision1 = mcele.template mcCollision_as(); - if (cfgEventGeneratorType >= 0 && mcCollision1.getSubGeneratorId() != cfgEventGeneratorType) { - return; + float det = cYY * cZZ - cZY * cZY; // determinant + if (det < 0) { + return 999.f; + } else { + return std::sqrt(std::fabs((dcaXY * dcaXY * cZZ + dcaZ * dcaZ * cYY - 2. * dcaXY * dcaZ * cZY) / det / 2.)); // dca 3d in sigma } + } - // o2::dataformats::DCA mDcaInfoCov; + template + bool isSemiLeptonic(TMCParticle const& mcParticle, TMCParticles const& mcParticles) + { + if (!mcParticle.has_daughters()) { + return false; + } + bool is_lepton_involved = false; + bool is_neutrino_involved = false; + for (int d = mcParticle.daughtersIds()[0]; d <= mcParticle.daughtersIds()[1]; ++d) { + if (d < mcParticles.size()) { // protect against bad daughter indices + const auto& daughter = mcParticles.rawIteratorAt(d); + if (daughter.pdgCode() == pdgLepton) { + is_lepton_involved = true; + } else if (daughter.pdgCode() == pdgNeutrino) { + is_neutrino_involved = true; + } + } else { + std::cout << "Daughter label (" << d << ") exceeds the McParticles size (" << mcParticles.size() << ")" << std::endl; + std::cout << " Check the MC generator" << std::endl; + return false; + } + } + + if (is_lepton_involved && is_neutrino_involved) { + return true; + } else { + return false; + } + } + + template + EBPair makeELPair(TCollision const& collision, TTrack const& track, TV0 const& v0) + { mDcaInfoCov.set(999, 999, 999, 999, 999); - auto eleParCov = getTrackParCov(ele); - eleParCov.setPID(o2::track::PID::Electron); - // mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); - // mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, eleParCov, 2.f, matCorr, &mDcaInfoCov); + auto trackParCov = getTrackParCov(track); + trackParCov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); float dcaXY = mDcaInfoCov.getY(); float dcaZ = mDcaInfoCov.getZ(); + float dca3DinSigma = dca3DinSigmaOTF(dcaXY, dcaZ, trackParCov.getSigmaY2(), trackParCov.getSigmaZ2(), trackParCov.getSigmaZY()); - for (const auto& v0Id : v0Ids) { - const auto& v0 = v0s.rawIteratorAt(v0Id); - auto pos = v0.template posTrack_as(); - // auto neg = v0.template negTrack_as(); - - const auto& mcpos = pos.template mcParticle_as(); - // const auto& mcneg = neg.template mcParticle_as(); - const auto& mcv0 = mcpos.template mothers_first_as(); // check mother of K0S. namely, K0 [311 or -311]. - const auto& mcCollision2 = mcv0.template mcCollision_as(); - - const std::array vertex = {v0.x(), v0.y(), v0.z()}; - const std::array momentum = {v0.px(), v0.py(), v0.pz()}; - std::array covV0 = {0.f}; - - constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component - for (int i = 0; i < 6; i++) { - covV0[MomInd[i]] = v0.momentumCovMat()[i]; - covV0[i] = v0.positionCovMat()[i]; - } - - auto tV0 = o2::track::TrackParCov(vertex, momentum, covV0, 0, true); - tV0.setAbsCharge(0); - tV0.setPID(o2::track::PID::K0); - - std::array svpos = {0.}; // secondary vertex position - std::array pvec0 = {0.}; - std::array pvec1 = {0.}; + EBPair eLpair; + eLpair.ptepv = trackParCov.getPt(); + eLpair.dca3dinsigma = dca3DinSigma; - int nCand = 0; - try { - nCand = fitter.process(eleParCov, tV0); - } catch (...) { - LOG(error) << "Exception caught in DCA fitter process call!"; - continue; - } - if (nCand == 0) { - continue; - } + const std::array vertex = {v0.x(), v0.y(), v0.z()}; + const std::array momentum = {v0.px(), v0.py(), v0.pz()}; + std::array covV0 = {0.f}; - fitter.propagateTracksToVertex(); // propagate e and K to D vertex - const auto& vtx = fitter.getPCACandidate(); - for (int i = 0; i < 3; i++) { - svpos[i] = vtx[i]; - } - fitter.getTrack(0).getPxPyPzGlo(pvec0); // electron - fitter.getTrack(1).getPxPyPzGlo(pvec1); // v0 - std::array pvecSum = {pvec0[0] + pvec1[0], pvec0[1] + pvec1[1], pvec0[2] + pvec1[2]}; - - float dca2legs = std::sqrt(fitter.getChi2AtPCACandidate()); - float lxy = std::sqrt(std::pow(svpos[0] - collision.posX(), 2) + std::pow(svpos[1] - collision.posY(), 2)); - float lz = std::fabs(svpos[2] - collision.posZ()); - // float ptEK = RecoDecay::sqrtSumOfSquares(pvec0[0] + pvec1[0], pvec0[1] + pvec1[1]); - - float deta = RecoDecay::eta(pvec1) - RecoDecay::eta(pvec0); - float dphi = RecoDecay::phi(pvec1[0], pvec1[1]) - RecoDecay::phi(pvec0[0], pvec0[1]); - o2::math_utils::bringToPMPi(dphi); - float reldpt = (RecoDecay::sqrtSumOfSquares(pvec1[0], pvec1[1]) - RecoDecay::sqrtSumOfSquares(pvec0[0], pvec0[1])) / RecoDecay::sqrtSumOfSquares(pvec0[0], pvec0[1]); - - float mEK = 0; - if constexpr (pairId == 1) { - mEK = RecoDecay::m(std::array{pvec0, pvec1}, std::array{o2::constants::physics::MassElectron, o2::constants::physics::MassK0Short}); - if (svcuts.cfg_max_mass_eK < mEK) { - continue; - } - } else if constexpr (pairId == 2) { - mEK = RecoDecay::m(std::array{pvec0, pvec1}, std::array{o2::constants::physics::MassElectron, o2::constants::physics::MassLambda}); - if (svcuts.cfg_max_mass_eL < mEK) { - continue; - } - } - float cpa = RecoDecay::cpa(pVtx, svpos, pvecSum); - float cpaXY = RecoDecay::cpaXY(pVtx, svpos, pvecSum); + constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component + for (int i = 0; i < 6; i++) { + covV0[MomInd[i]] = v0.momentumCovMat()[i]; + covV0[i] = v0.positionCovMat()[i]; + } - if (cpa < svcuts.cfg_min_cospa || cpaXY < svcuts.cfg_min_cospaXY || lxy < svcuts.cfg_min_lxy || svcuts.cfg_max_dca2legs < dca2legs) { - continue; - } + auto v0ParCov = o2::track::TrackParCov(vertex, momentum, covV0, 0, true); + v0ParCov.setAbsCharge(0); + v0ParCov.setPID(o2::track::PID::Lambda); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("all/hDCA2Legs"), dca2legs); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("all/hLxy"), lxy); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("all/hLz"), lz); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("all/hCosPAXY"), cpaXY); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("all/hCosPA"), cpa); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("all/hMass"), mEK); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("all/hMass_CosPA"), mEK, cpa); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("all/hDeltaEtaDeltaPhi"), dphi, deta); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("all/hRelDeltaPt"), reldpt); - - int commonMotherId = -1; - if constexpr (pairId == 1) { - const auto& mcv0_mother = mcv0.template mothers_first_as(); // mother particle of K0S. - commonMotherId = o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2ProngsWithoutPDG(mcele, mcv0_mother); // K0, not K0S - } else if constexpr (pairId == 2) { - commonMotherId = o2::aod::pwgem::dilepton::utils::mcutil::FindCommonMotherFrom2ProngsWithoutPDG(mcele, mcv0); // lambda - } + std::array svpos = {0.}; // secondary vertex position + std::array pvec0 = {0.}; + std::array pvec1 = {0.}; - if (commonMotherId >= 0) { // common mother is correctly found by DCAFitterN. - const auto& cmp = mcParticles.rawIteratorAt(commonMotherId); - if constexpr (pairId == 1) { - if (std::abs(mcv0.pdgCode()) == 310 && mcCollision1.globalIndex() == mcCollision2.globalIndex()) { - if (std::abs(cmp.pdgCode()) == 421) { // D0 - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(cmp, mcParticles) < 0) { - fillElectronHistograms<2, 1, 0>(ele, eleParCov, dcaXY, dcaZ); // prompt charm - } else { - fillElectronHistograms<2, 1, 1>(ele, eleParCov, dcaXY, dcaZ); // nonprompt charm - } - fRegistry.fill(HIST(pair_names[pairId]) + HIST("D0/hDCA2Legs"), dca2legs); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("D0/hLxy"), lxy); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("D0/hLz"), lz); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("D0/hCosPAXY"), cpaXY); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("D0/hCosPA"), cpa); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("D0/hMass"), mEK); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("D0/hMass_CosPA"), mEK, cpa); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("D0/hDeltaEtaDeltaPhi"), dphi, deta); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("D0/hRelDeltaPt"), reldpt); - } else if (std::abs(cmp.pdgCode()) == 411) { // Dpm - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(cmp, mcParticles) < 0) { - fillElectronHistograms<3, 1, 0>(ele, eleParCov, dcaXY, dcaZ); // prompt charm - } else { - fillElectronHistograms<3, 1, 1>(ele, eleParCov, dcaXY, dcaZ); // nonprompt charm - } - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Dpm/hDCA2Legs"), dca2legs); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Dpm/hLxy"), lxy); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Dpm/hLz"), lz); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Dpm/hCosPAXY"), cpaXY); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Dpm/hCosPA"), cpa); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Dpm/hMass"), mEK); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Dpm/hMass_CosPA"), mEK, cpa); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Dpm/hDeltaEtaDeltaPhi"), dphi, deta); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Dpm/hRelDeltaPt"), reldpt); - } else if (std::abs(cmp.pdgCode()) == 431) { // Ds - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(cmp, mcParticles) < 0) { - fillElectronHistograms<4, 1, 0>(ele, eleParCov, dcaXY, dcaZ); // prompt charm - } else { - fillElectronHistograms<4, 1, 1>(ele, eleParCov, dcaXY, dcaZ); // nonprompt charm - } - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Ds/hDCA2Legs"), dca2legs); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Ds/hLxy"), lxy); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Ds/hLz"), lz); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Ds/hCosPAXY"), cpaXY); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Ds/hCosPA"), cpa); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Ds/hMass"), mEK); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Ds/hMass_CosPA"), mEK, cpa); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Ds/hDeltaEtaDeltaPhi"), dphi, deta); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Ds/hRelDeltaPt"), reldpt); - } - } - } else if constexpr (pairId == 2) { - if (std::abs(mcv0.pdgCode()) == 3122 && mcCollision1.globalIndex() == mcCollision2.globalIndex()) { - if (std::abs(cmp.pdgCode()) == 4122) { // Lc - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(cmp, mcParticles) < 0) { - fillElectronHistograms<5, 1, 0>(ele, eleParCov, dcaXY, dcaZ); // prompt charm - } else { - fillElectronHistograms<5, 1, 1>(ele, eleParCov, dcaXY, dcaZ); // nonprompt charm - } - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Lc/hDCA2Legs"), dca2legs); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Lc/hLxy"), lxy); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Lc/hLz"), lz); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Lc/hCosPAXY"), cpaXY); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Lc/hCosPA"), cpa); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Lc/hMass"), mEK); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Lc/hMass_CosPA"), mEK, cpa); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Lc/hDeltaEtaDeltaPhi"), dphi, deta); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("Lc/hRelDeltaPt"), reldpt); - } - } - } - } else { // common mother does not exist, but DCAFitterN found something. i.e. fake - const auto& mp = mcele.template mothers_first_as(); - if ((mcele.isPhysicalPrimary() || mcele.producedByGenerator()) && (std::abs(mp.pdgCode()) == 111 || std::abs(mp.pdgCode()) == 221 || std::abs(mp.pdgCode()) == 331 || std::abs(mp.pdgCode()) == 113 || std::abs(mp.pdgCode()) == 223 || std::abs(mp.pdgCode()) == 333)) { // LF - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromCharm(mcele, mcParticles) < 0 && o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(mcele, mcParticles) < 0) { - fillElectronHistograms<0, 2, 0>(ele, eleParCov, dcaXY, dcaZ); - } else { - fillElectronHistograms<0, 2, 1>(ele, eleParCov, dcaXY, dcaZ); - } - } - fRegistry.fill(HIST(pair_names[pairId]) + HIST("fake/hDCA2Legs"), dca2legs); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("fake/hLxy"), lxy); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("fake/hLz"), lz); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("fake/hCosPAXY"), cpaXY); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("fake/hCosPA"), cpa); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("fake/hMass"), mEK); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("fake/hMass_CosPA"), mEK, cpa); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("fake/hDeltaEtaDeltaPhi"), dphi, deta); - fRegistry.fill(HIST(pair_names[pairId]) + HIST("fake/hRelDeltaPt"), reldpt); - } + int nCand = 0; + try { + nCand = fitter.process(trackParCov, v0ParCov); + } catch (...) { + LOG(error) << "Exception caught in DCA fitter process call!"; + return eLpair; + } + if (nCand == 0) { + return eLpair; + } - } // end of v0 loop + fitter.propagateTracksToVertex(); // propagate e and K to D vertex + const auto& vtx = fitter.getPCACandidate(); + for (int i = 0; i < 3; i++) { + svpos[i] = vtx[i]; + } + fitter.getTrack(0).getPxPyPzGlo(pvec0); // electron + fitter.getTrack(1).getPxPyPzGlo(pvec1); // v0 + std::array pvecSum = {pvec0[0] + pvec1[0], pvec0[1] + pvec1[1], pvec0[2] + pvec1[2]}; + + float cospa = RecoDecay::cpa(vertex, svpos, pvecSum); + float dca2legs = std::sqrt(fitter.getChi2AtPCACandidate()); + float lxy = std::sqrt(std::pow(svpos[0] - collision.posX(), 2) + std::pow(svpos[1] - collision.posY(), 2)); + float lz = std::fabs(svpos[2] - collision.posZ()); + ROOT::Math::PxPyPzMVector v1(pvec0[0], pvec0[1], pvec0[2], o2::constants::physics::MassElectron); + ROOT::Math::PxPyPzMVector v2(pvec1[0], pvec1[1], pvec1[2], o2::constants::physics::MassLambda); + ROOT::Math::PxPyPzMVector v12 = v1 + v2; + + eLpair.mass = v12.M(); + eLpair.dca2legs = dca2legs; + eLpair.cospa = cospa; + eLpair.lxy = lxy; + eLpair.lz = lz; + return eLpair; } - SliceCache cache; - Preslice perCol = o2::aod::track::collisionId; - Preslice perCol_v0 = o2::aod::v0data::collisionId; - - Filter collisionFilter_evsel = o2::aod::evsel::sel8 == true && (cfgZvtxMin < o2::aod::collision::posZ && o2::aod::collision::posZ < cfgZvtxMax); - Filter collisionFilter_centrality = (cfgCentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < cfgCentMax) || (cfgCentMin < o2::aod::cent::centFT0A && o2::aod::cent::centFT0A < cfgCentMax) || (cfgCentMin < o2::aod::cent::centFT0C && o2::aod::cent::centFT0C < cfgCentMax); - using FilteredMyCollisions = soa::Filtered; - - Preslice trackIndicesPerCollision = aod::track_association::collisionId; - std::vector> stored_trackIds; - Filter trackFilter = ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::TPC) == true; - using MyFilteredTracks = soa::Filtered; - - Partition posTracks = o2::aod::track::signed1Pt > 0.f; - Partition negTracks = o2::aod::track::signed1Pt < 0.f; + template + EBPair makeECascadePair(TCollision const& collision, TTrack const& track, TCascade const& cascade) + { + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto trackParCov = getTrackParCov(track); + trackParCov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); + float dcaXY = mDcaInfoCov.getY(); + float dcaZ = mDcaInfoCov.getZ(); + float dca3DinSigma = dca3DinSigmaOTF(dcaXY, dcaZ, trackParCov.getSigmaY2(), trackParCov.getSigmaZ2(), trackParCov.getSigmaZY()); - //! type of V0. 0: built solely for cascades (does not pass standard V0 cuts), 1: standard 2, 3: photon-like with TPC-only use. Regular analysis should always use type 1. - Filter v0Filter = o2::aod::v0data::v0Type == uint8_t(1) && o2::aod::v0data::v0cosPA > v0cuts.cfg_min_cospa&& o2::aod::v0data::dcaV0daughters < v0cuts.cfg_max_dca2legs; - using filteredV0s = soa::Filtered; + EBPair eCascPair; + eCascPair.ptepv = trackParCov.getPt(); + eCascPair.dca3dinsigma = dca3DinSigma; - std::vector electronIds; - std::vector positronIds; - std::vector negKaonIds; - std::vector posKaonIds; + const std::array vertex = {cascade.x(), cascade.y(), cascade.z()}; + const std::array momentum = {cascade.px(), cascade.py(), cascade.pz()}; - std::vector k0sIds; - std::vector lambdaIds; - std::vector antilambdaIds; + std::array covCasc = {0.}; + constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component + for (int i = 0; i < 6; i++) { + covCasc[MomInd[i]] = cascade.momentumCovMat()[i]; + covCasc[i] = cascade.positionCovMat()[i]; + } - std::vector> used_electronIds; // pair of hTypeId and electronId + auto cascParCov = o2::track::TrackParCov(vertex, momentum, covCasc, cascade.sign(), true); + cascParCov.setAbsCharge(1); + if constexpr (cascType == 0) { + cascParCov.setPID(o2::track::PID::XiMinus); + } else if constexpr (cascType == 1) { + cascParCov.setPID(o2::track::PID::OmegaMinus); + } + std::array svpos = {0.}; // secondary vertex position + std::array pvec0 = {0.}; + std::array pvec1 = {0.}; + + int nCand = 0; + try { + nCand = fitter.process(trackParCov, cascParCov); + } catch (...) { + LOG(error) << "Exception caught in DCA fitter process call!"; + return eCascPair; + } + if (nCand == 0) { + return eCascPair; + } - void processSA(FilteredMyCollisions const&, aod::BCsWithTimestamps const&, MyTracks const&, filteredV0s const&, aod::McParticles const&, aod::McCollisions const&) {} - PROCESS_SWITCH(taggingHFE, processSA, "process without TTCA", false); + fitter.propagateTracksToVertex(); // propagate e and Xi/Omega to decay vertex of charm baryon + const auto& vtx = fitter.getPCACandidate(); + for (int i = 0; i < 3; i++) { + svpos[i] = vtx[i]; + } + fitter.getTrack(0).getPxPyPzGlo(pvec0); // electron + fitter.getTrack(1).getPxPyPzGlo(pvec1); // v0 + std::array pvecSum = {pvec0[0] + pvec1[0], pvec0[1] + pvec1[1], pvec0[2] + pvec1[2]}; + + float cospa = RecoDecay::cpa(vertex, svpos, pvecSum); + float dca2legs = std::sqrt(fitter.getChi2AtPCACandidate()); + float lxy = std::sqrt(std::pow(svpos[0] - collision.posX(), 2) + std::pow(svpos[1] - collision.posY(), 2)); + float lz = std::fabs(svpos[2] - collision.posZ()); + ROOT::Math::PxPyPzMVector v1(pvec0[0], pvec0[1], pvec0[2], o2::constants::physics::MassElectron); + ROOT::Math::PxPyPzMVector v2(pvec1[0], pvec1[1], pvec1[2], o2::constants::physics::MassXiMinus); + if constexpr (cascType == 0) { + v2.SetM(o2::constants::physics::MassXiMinus); + } else if constexpr (cascType == 1) { + v2.SetM(o2::constants::physics::MassOmegaMinus); + } + ROOT::Math::PxPyPzMVector v12 = v1 + v2; + + eCascPair.mass = v12.M(); + eCascPair.dca2legs = dca2legs; + eCascPair.cospa = cospa; + eCascPair.lxy = lxy; + eCascPair.lz = lz; + return eCascPair; + } - void processTTCA(FilteredMyCollisions const& collisions, aod::BCsWithTimestamps const&, MyTracks const& tracks, aod::TrackAssoc const& trackIndices, filteredV0s const& v0s, aod::McParticles const& mcParticles, aod::McCollisions const& mcCollisions) + template + void runPairing(TBCs const&, TCollisions const& collisions, TTracks const& tracks, TTrackAssoc const& trackIndices, TV0s const& v0s, TCascades const& cascades, TMCCollisions const&, TMCParticles const& mcParticles) { used_electronIds.reserve(tracks.size()); for (const auto& collision : collisions) { - const auto& bc = collision.template foundBC_as(); + const auto& bc = collision.template foundBC_as(); initCCDB(bc); fRegistry.fill(HIST("Event/hCollisionCounter"), 0); if (!collision.has_mcCollision()) { continue; } const float centralities[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}; - if (centralities[cfgCentEstimator] < cfgCentMin || cfgCentMax < centralities[cfgCentEstimator]) { + if (centralities[eventcut.cfgCentEstimator] < eventcut.cfgCentMin || eventcut.cfgCentMax < centralities[eventcut.cfgCentEstimator]) { continue; } fRegistry.fill(HIST("Event/hCollisionCounter"), 1); const auto& mcCollision = collision.template mcCollision_as(); - if (cfgEventGeneratorType < 0 || mcCollision.getSubGeneratorId() == cfgEventGeneratorType) { + if (eventcut.cfgEventGeneratorType < 0 || mcCollision.getSubGeneratorId() == eventcut.cfgEventGeneratorType) { fillEventHistograms(collision); } + mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); + mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + const auto& trackIdsThisCollision = trackIndices.sliceBy(trackIndicesPerCollision, collision.globalIndex()); electronIds.reserve(trackIdsThisCollision.size()); positronIds.reserve(trackIdsThisCollision.size()); negKaonIds.reserve(trackIdsThisCollision.size()); posKaonIds.reserve(trackIdsThisCollision.size()); - mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); - mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); for (const auto& trackId : trackIdsThisCollision) { - const auto& track = trackId.template track_as(); + const auto& track = trackId.template track_as(); if (!track.hasITS() || !track.hasTPC()) { continue; } - if (!track.has_mcParticle()) { - continue; - } - const auto& mctrack = track.template mcParticle_as(); - if (std::abs(mctrack.pdgCode()) != 11) { - continue; - } - const auto& mcCollision1 = mctrack.template mcCollision_as(); - if (cfgEventGeneratorType >= 0 && mcCollision1.getSubGeneratorId() != cfgEventGeneratorType) { - continue; - } - if (!mctrack.has_mothers() || !(mctrack.isPhysicalPrimary() || mctrack.producedByGenerator())) { - continue; - } - const auto& mp = mctrack.template mothers_first_as(); // mother particle of electron - - // o2::dataformats::DCA mDcaInfoCov; - mDcaInfoCov.set(999, 999, 999, 999, 999); - auto track_par_cov_recalc = getTrackParCov(track); - track_par_cov_recalc.setPID(o2::track::PID::Electron); - // mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); - // mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, track_par_cov_recalc, 2.f, matCorr, &mDcaInfoCov); - float dcaXY = mDcaInfoCov.getY(); - float dcaZ = mDcaInfoCov.getZ(); - - if (!isSelectedTrackForElectron(track, track_par_cov_recalc, dcaXY, dcaZ)) { - continue; - } - if (std::abs(mp.pdgCode()) == 111 || std::abs(mp.pdgCode()) == 221 || std::abs(mp.pdgCode()) == 331 || std::abs(mp.pdgCode()) == 113 || std::abs(mp.pdgCode()) == 223 || std::abs(mp.pdgCode()) == 333) { // LF - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromCharm(mp, mcParticles) < 0 && o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(mp, mcParticles) < 0) { - fillElectronHistograms<0, 0, 0>(track, track_par_cov_recalc, dcaXY, dcaZ); // prompt LF - } else { - fillElectronHistograms<0, 0, 1>(track, track_par_cov_recalc, dcaXY, dcaZ); // nonprompt LF + if constexpr (isMC) { + if (!track.has_mcParticle()) { + continue; } - } else if (std::abs(mp.pdgCode()) == 443) { // Jpsi - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(mp, mcParticles) < 0) { - fillElectronHistograms<1, 0, 0>(track, track_par_cov_recalc, dcaXY, dcaZ); // prompt Jpsi - } else { - fillElectronHistograms<1, 0, 1>(track, track_par_cov_recalc, dcaXY, dcaZ); // nonprompt Jpsi + const auto& mctrack = track.template mcParticle_as(); + const auto& mcCollision = mctrack.template mcCollision_as(); + if (eventcut.cfgEventGeneratorType >= 0 && mcCollision.getSubGeneratorId() != eventcut.cfgEventGeneratorType) { + continue; } - } else if (std::abs(mp.pdgCode()) == 421) { // D0 - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(mp, mcParticles) < 0) { - fillElectronHistograms<2, 0, 0>(track, track_par_cov_recalc, dcaXY, dcaZ); - } else { - fillElectronHistograms<2, 0, 1>(track, track_par_cov_recalc, dcaXY, dcaZ); + if (!mctrack.has_mothers() || !(mctrack.isPhysicalPrimary() || mctrack.producedByGenerator())) { + continue; } - } else if (std::abs(mp.pdgCode()) == 411) { // Dpm - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(mp, mcParticles) < 0) { - fillElectronHistograms<3, 0, 0>(track, track_par_cov_recalc, dcaXY, dcaZ); - } else { - fillElectronHistograms<3, 0, 1>(track, track_par_cov_recalc, dcaXY, dcaZ); - } - } else if (std::abs(mp.pdgCode()) == 431) { // Ds - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(mp, mcParticles) < 0) { - fillElectronHistograms<4, 0, 0>(track, track_par_cov_recalc, dcaXY, dcaZ); - } else { - fillElectronHistograms<4, 0, 1>(track, track_par_cov_recalc, dcaXY, dcaZ); - } - } else if (std::abs(mp.pdgCode()) == 4122) { // Lc - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(mp, mcParticles) < 0) { - fillElectronHistograms<5, 0, 0>(track, track_par_cov_recalc, dcaXY, dcaZ); - } else { - fillElectronHistograms<5, 0, 1>(track, track_par_cov_recalc, dcaXY, dcaZ); - } + fillElectronHistograms(track, mcParticles); } - if (track.sign() > 0) { // positron - positronIds.emplace_back(trackId.trackId()); - } else { // electron - electronIds.emplace_back(trackId.trackId()); - } - } // end of track loop for electron selection - - for (const auto& trackId : trackIdsThisCollision) { - const auto& track = trackId.template track_as(); - if (!track.hasITS() || !track.hasTPC()) { - continue; - } - if (!track.has_mcParticle()) { - continue; - } - - const auto& mctrack = track.template mcParticle_as(); - const auto& mcCollision1 = mctrack.template mcCollision_as(); - - // o2::dataformats::DCA mDcaInfoCov; mDcaInfoCov.set(999, 999, 999, 999, 999); - auto track_par_cov_recalc = getTrackParCov(track); - track_par_cov_recalc.setPID(o2::track::PID::Kaon); - // mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); - // mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, track_par_cov_recalc, 2.f, matCorr, &mDcaInfoCov); + auto trackParCov = getTrackParCov(track); + trackParCov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, trackParCov, 2.f, matCorr, &mDcaInfoCov); float dcaXY = mDcaInfoCov.getY(); float dcaZ = mDcaInfoCov.getZ(); - if (!isSelectedTrackForKaon(track, track_par_cov_recalc, dcaXY, dcaZ)) { - continue; + if (isSelectedElectron(track, trackParCov, dcaXY, dcaZ)) { + if (track.sign() > 0) { // positron + positronIds.emplace_back(trackId.trackId()); + } else { // electron + electronIds.emplace_back(trackId.trackId()); + } } - if (isKaon(track)) { - if (track.sign() > 0) { // positive kaon - posKaonIds.emplace_back(trackId.trackId()); - } else { // negative kaon - negKaonIds.emplace_back(trackId.trackId()); - } - if (std::abs(mctrack.pdgCode()) == 321) { - if (!mctrack.has_mothers() || !(mctrack.isPhysicalPrimary() || mctrack.producedByGenerator())) { - continue; - } - const auto& mp = mctrack.template mothers_first_as(); // mother particle of electron - if (cfgEventGeneratorType < 0 || mcCollision1.getSubGeneratorId() == cfgEventGeneratorType) { - if (std::abs(mp.pdgCode()) == 421) { // D0 - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(mp, mcParticles) < 0) { - fillKaonHistograms<2, 0, 0>(track, track_par_cov_recalc, dcaXY, dcaZ); - } else { - fillKaonHistograms<2, 0, 1>(track, track_par_cov_recalc, dcaXY, dcaZ); - } - } else if (std::abs(mp.pdgCode()) == 411) { // Dpm - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(mp, mcParticles) < 0) { - fillKaonHistograms<3, 0, 0>(track, track_par_cov_recalc, dcaXY, dcaZ); - } else { - fillKaonHistograms<3, 0, 1>(track, track_par_cov_recalc, dcaXY, dcaZ); - } - } else if (std::abs(mp.pdgCode()) == 431) { // Ds - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(mp, mcParticles) < 0) { - fillKaonHistograms<4, 0, 0>(track, track_par_cov_recalc, dcaXY, dcaZ); - } else { - fillKaonHistograms<4, 0, 1>(track, track_par_cov_recalc, dcaXY, dcaZ); - } - } - } + if (isSelectedElectronLoose(track, trackParCov, dcaXY, dcaZ)) { + if (track.sign() > 0) { // positron + positronIdsLoose.emplace_back(trackId.trackId()); + } else { // electron + electronIdsLoose.emplace_back(trackId.trackId()); } } - } // end of track loop for kaon selection - - const auto& v0s_per_coll = v0s.sliceBy(perCol_v0, collision.globalIndex()); - k0sIds.reserve(v0s_per_coll.size()); - lambdaIds.reserve(v0s_per_coll.size()); - antilambdaIds.reserve(v0s_per_coll.size()); + } // end of track loop for electron selection - for (const auto& v0 : v0s_per_coll) { - if (v0cuts.cfg_min_mass_k0s < v0.mK0Short() && v0.mK0Short() < v0cuts.cfg_max_mass_k0s) { - auto pos = v0.template posTrack_as(); - auto neg = v0.template negTrack_as(); + // First, apply pi0 prefilter to imporove S/B + std::vector vec_eFromPi0; + vec_eFromPi0.reserve(electronIds.size() + positronIds.size()); - if (!isPion(pos) || !isPion(neg)) { - continue; - } + for (const auto& positronId : positronIds) { + const auto& pos = tracks.rawIteratorAt(positronId); + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto posParCov = getTrackParCov(pos); + posParCov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, posParCov, 2.f, matCorr, &mDcaInfoCov); + ROOT::Math::PtEtaPhiMVector v1(posParCov.getPt(), posParCov.getEta(), posParCov.getPhi(), o2::constants::physics::MassElectron); - float dcaXY = 999.f; - // o2::dataformats::DCA mDcaInfoCov; + for (const auto& electronId : electronIdsLoose) { + const auto& ele = tracks.rawIteratorAt(electronId); mDcaInfoCov.set(999, 999, 999, 999, 999); - auto track_par_cov_recalc_pos = getTrackParCov(pos); - track_par_cov_recalc_pos.setPID(o2::track::PID::Pion); - // mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); - // mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, track_par_cov_recalc_pos, 2.f, matCorr, &mDcaInfoCov); - dcaXY = mDcaInfoCov.getY(); - if (!isSelectedV0Leg(pos, dcaXY)) { - continue; + auto eleParCov = getTrackParCov(ele); + eleParCov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, eleParCov, 2.f, matCorr, &mDcaInfoCov); + ROOT::Math::PtEtaPhiMVector v2(eleParCov.getPt(), eleParCov.getEta(), eleParCov.getPhi(), o2::constants::physics::MassElectron); + + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + float mee = v12.M(); + fRegistry.fill(HIST("Prefilter/before/uls/hMee"), mee); + if (mee < cfgMeeMaxPF) { + vec_eFromPi0.emplace_back(positronId); } + } // end of loose electron sample + } // end of main positron sample + for (const auto& electronId : electronIds) { + const auto& ele = tracks.rawIteratorAt(electronId); + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto eleParCov = getTrackParCov(ele); + eleParCov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, eleParCov, 2.f, matCorr, &mDcaInfoCov); + ROOT::Math::PtEtaPhiMVector v1(eleParCov.getPt(), eleParCov.getEta(), eleParCov.getPhi(), o2::constants::physics::MassElectron); + + for (const auto& positronId : positronIdsLoose) { + const auto& pos = tracks.rawIteratorAt(positronId); mDcaInfoCov.set(999, 999, 999, 999, 999); - auto track_par_cov_recalc_neg = getTrackParCov(neg); - track_par_cov_recalc_neg.setPID(o2::track::PID::Pion); - // mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); - // mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, track_par_cov_recalc_neg, 2.f, matCorr, &mDcaInfoCov); - dcaXY = mDcaInfoCov.getY(); - if (!isSelectedV0Leg(neg, dcaXY)) { - continue; + auto posParCov = getTrackParCov(pos); + posParCov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, posParCov, 2.f, matCorr, &mDcaInfoCov); + ROOT::Math::PtEtaPhiMVector v2(posParCov.getPt(), posParCov.getEta(), posParCov.getPhi(), o2::constants::physics::MassElectron); + + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + float mee = v12.M(); + fRegistry.fill(HIST("Prefilter/before/uls/hMee"), mee); + if (mee < cfgMeeMaxPF) { + vec_eFromPi0.emplace_back(electronId); } + } // end of loose positron sample + } // end of main electron sample - fRegistry.fill(HIST("V0/K0S/hPt"), v0.pt()); - fRegistry.fill(HIST("V0/K0S/hYPhi"), v0.phi(), v0.yK0Short()); - fRegistry.fill(HIST("V0/K0S/hCosPA"), v0.v0cosPA()); - fRegistry.fill(HIST("V0/K0S/hLxy"), v0.v0radius()); - fRegistry.fill(HIST("V0/K0S/hDCA2Legs"), v0.dcaV0daughters()); - fRegistry.fill(HIST("V0/K0S/hAP"), v0.alpha(), v0.qtarm()); - fRegistry.fill(HIST("V0/K0S/hMassK0S"), v0.mK0Short()); - k0sIds.emplace_back(v0.globalIndex()); - - } else if (v0cuts.cfg_min_mass_lambda < v0.mLambda() && v0.mLambda() < v0cuts.cfg_max_mass_lambda) { - auto pos = v0.template posTrack_as(); - auto neg = v0.template negTrack_as(); - - if (!isProton(pos) || !isPion(neg)) { + for (const auto& positronId1 : positronIds) { + const auto& pos1 = tracks.rawIteratorAt(positronId1); + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto pos1ParCov = getTrackParCov(pos1); + pos1ParCov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, pos1ParCov, 2.f, matCorr, &mDcaInfoCov); + ROOT::Math::PtEtaPhiMVector v1(pos1ParCov.getPt(), pos1ParCov.getEta(), pos1ParCov.getPhi(), o2::constants::physics::MassElectron); + + for (const auto& positronId2 : positronIdsLoose) { + const auto& pos2 = tracks.rawIteratorAt(positronId2); + if (positronId1 == positronId2) { continue; } - - float dcaXY = 999.f; - // o2::dataformats::DCA mDcaInfoCov; mDcaInfoCov.set(999, 999, 999, 999, 999); - auto track_par_cov_recalc_pos = getTrackParCov(pos); - track_par_cov_recalc_pos.setPID(o2::track::PID::Proton); - // mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); - // mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, track_par_cov_recalc_pos, 2.f, matCorr, &mDcaInfoCov); - dcaXY = mDcaInfoCov.getY(); - if (!isSelectedV0Leg(pos, dcaXY)) { + auto pos2ParCov = getTrackParCov(pos2); + pos2ParCov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, pos2ParCov, 2.f, matCorr, &mDcaInfoCov); + ROOT::Math::PtEtaPhiMVector v2(pos2ParCov.getPt(), pos2ParCov.getEta(), pos2ParCov.getPhi(), o2::constants::physics::MassElectron); + + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + float mee = v12.M(); + fRegistry.fill(HIST("Prefilter/before/lspp/hMee"), mee); + } // end of loose positron sample + } // end of main positron sample + + for (const auto& electronId1 : electronIds) { + const auto& ele1 = tracks.rawIteratorAt(electronId1); + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto ele1ParCov = getTrackParCov(ele1); + ele1ParCov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, ele1ParCov, 2.f, matCorr, &mDcaInfoCov); + ROOT::Math::PtEtaPhiMVector v1(ele1ParCov.getPt(), ele1ParCov.getEta(), ele1ParCov.getPhi(), o2::constants::physics::MassElectron); + + for (const auto& electronId2 : electronIdsLoose) { + const auto& ele2 = tracks.rawIteratorAt(electronId2); + if (electronId1 == electronId2) { continue; } + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto ele2ParCov = getTrackParCov(ele2); + ele2ParCov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, ele2ParCov, 2.f, matCorr, &mDcaInfoCov); + ROOT::Math::PtEtaPhiMVector v2(ele2ParCov.getPt(), ele2ParCov.getEta(), ele2ParCov.getPhi(), o2::constants::physics::MassElectron); + + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + float mee = v12.M(); + fRegistry.fill(HIST("Prefilter/before/lsmm/hMee"), mee); + } // end of loose electron sample + } // end of main electron sample + + std::vector vec_diff_pos; + std::set_difference(positronIds.begin(), positronIds.end(), vec_eFromPi0.begin(), vec_eFromPi0.end(), std::back_inserter(vec_diff_pos)); + positronIds = vec_diff_pos; + + std::vector vec_diff_ele; + std::set_difference(electronIds.begin(), electronIds.end(), vec_eFromPi0.begin(), vec_eFromPi0.end(), std::back_inserter(vec_diff_ele)); + electronIds = vec_diff_ele; + + vec_eFromPi0.clear(); + vec_eFromPi0.shrink_to_fit(); + + for (const auto& electronId : electronIds) { + const auto& ele = tracks.rawIteratorAt(electronId); + mDcaInfoCov.set(999, 999, 999, 999, 999); + auto eleParCov = getTrackParCov(ele); + eleParCov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, eleParCov, 2.f, matCorr, &mDcaInfoCov); + ROOT::Math::PtEtaPhiMVector v1(eleParCov.getPt(), eleParCov.getEta(), eleParCov.getPhi(), o2::constants::physics::MassElectron); + for (const auto& positronId : positronIds) { + const auto& pos = tracks.rawIteratorAt(positronId); mDcaInfoCov.set(999, 999, 999, 999, 999); - auto track_par_cov_recalc_neg = getTrackParCov(neg); - track_par_cov_recalc_neg.setPID(o2::track::PID::Pion); - // mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); - // mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, track_par_cov_recalc_neg, 2.f, matCorr, &mDcaInfoCov); - dcaXY = mDcaInfoCov.getY(); - if (!isSelectedV0Leg(neg, dcaXY)) { - continue; - } + auto posParCov = getTrackParCov(pos); + posParCov.setPID(o2::track::PID::Electron); + o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, posParCov, 2.f, matCorr, &mDcaInfoCov); + ROOT::Math::PtEtaPhiMVector v2(posParCov.getPt(), posParCov.getEta(), posParCov.getPhi(), o2::constants::physics::MassElectron); + + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + float mee = v12.M(); + fRegistry.fill(HIST("Prefilter/after/uls/hMee"), mee); + } // end of main positron sample + } // end of main electron sample - fRegistry.fill(HIST("V0/Lambda/hPt"), v0.pt()); - fRegistry.fill(HIST("V0/Lambda/hYPhi"), v0.phi(), v0.yLambda()); - fRegistry.fill(HIST("V0/Lambda/hCosPA"), v0.v0cosPA()); - fRegistry.fill(HIST("V0/Lambda/hLxy"), v0.v0radius()); - fRegistry.fill(HIST("V0/Lambda/hDCA2Legs"), v0.dcaV0daughters()); - fRegistry.fill(HIST("V0/Lambda/hAP"), v0.alpha(), v0.qtarm()); - fRegistry.fill(HIST("V0/Lambda/hMassLambda"), v0.mLambda()); + const auto& v0s_per_coll = v0s.sliceBy(perCol_v0, collision.globalIndex()); + lambdaIds.reserve(v0s_per_coll.size()); + lambdaIds.reserve(v0s_per_coll.size()); + antilambdaIds.reserve(v0s_per_coll.size()); + antilambdaIds.reserve(v0s_per_coll.size()); + for (const auto& v0 : v0s_per_coll) { + auto pos = v0.template posTrack_as(); + auto neg = v0.template negTrack_as(); + if (!isSelectedV0Leg(pos) || !isSelectedV0Leg(neg)) { + continue; + } + fillV0Histograms(v0); + if (isLambda(v0) && isProton(pos) && isPion(neg)) { lambdaIds.emplace_back(v0.globalIndex()); - } else if (v0cuts.cfg_min_mass_lambda < v0.mAntiLambda() && v0.mAntiLambda() < v0cuts.cfg_max_mass_lambda) { - auto pos = v0.template posTrack_as(); - auto neg = v0.template negTrack_as(); + } else if (isAntiLambda(v0) && isProton(neg) && isPion(pos)) { + antilambdaIds.emplace_back(v0.globalIndex()); + } + } // end of V0 loop + + const auto& cascades_per_coll = cascades.sliceBy(perCol_casc, collision.globalIndex()); + xiPlusIds.reserve(cascades_per_coll.size()); + xiPlusIds.reserve(cascades_per_coll.size()); + xiMinusIds.reserve(cascades_per_coll.size()); + xiMinusIds.reserve(cascades_per_coll.size()); + omegaPlusIds.reserve(cascades_per_coll.size()); + omegaPlusIds.reserve(cascades_per_coll.size()); + omegaMinusIds.reserve(cascades_per_coll.size()); + omegaMinusIds.reserve(cascades_per_coll.size()); + for (const auto& cascade : cascades_per_coll) { + auto pos = cascade.template posTrack_as(); + auto neg = cascade.template negTrack_as(); + auto bachelor = cascade.template bachelor_as(); + if (pos.sign() * neg.sign() > 0) { + continue; + } + if (cascade.mLambda() < cascadecut.cfg_min_mass_lambda || cascadecut.cfg_max_mass_lambda < cascade.mLambda()) { + continue; + } - if (!isPion(pos) || !isProton(neg)) { - continue; - } - float dcaXY = 999.f; - // o2::dataformats::DCA mDcaInfoCov; - mDcaInfoCov.set(999, 999, 999, 999, 999); - auto track_par_cov_recalc_pos = getTrackParCov(pos); - track_par_cov_recalc_pos.setPID(o2::track::PID::Pion); - // mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); - // mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, track_par_cov_recalc_pos, 2.f, matCorr, &mDcaInfoCov); - dcaXY = mDcaInfoCov.getY(); - if (!isSelectedV0Leg(pos, dcaXY)) { + if (!isSelectedV0Leg(pos) || !isSelectedV0Leg(neg) || !isSelectedV0Leg(bachelor)) { + continue; + } + + if (cascade.sign() < 0) { // L-> p pi- + if (!isProton(pos) || !isPion(neg)) { continue; } - - mDcaInfoCov.set(999, 999, 999, 999, 999); - auto track_par_cov_recalc_neg = getTrackParCov(neg); - track_par_cov_recalc_neg.setPID(o2::track::PID::Proton); - // mVtx.setPos({collision.posX(), collision.posY(), collision.posZ()}); - // mVtx.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - o2::base::Propagator::Instance()->propagateToDCABxByBz(mVtx, track_par_cov_recalc_neg, 2.f, matCorr, &mDcaInfoCov); - dcaXY = mDcaInfoCov.getY(); - if (!isSelectedV0Leg(neg, dcaXY)) { + } else { // Lbar-> pbar pi+ + if (!isProton(neg) || !isPion(pos)) { continue; } - fRegistry.fill(HIST("V0/AntiLambda/hPt"), v0.pt()); - fRegistry.fill(HIST("V0/AntiLambda/hYPhi"), v0.phi(), v0.yLambda()); - fRegistry.fill(HIST("V0/AntiLambda/hCosPA"), v0.v0cosPA()); - fRegistry.fill(HIST("V0/AntiLambda/hLxy"), v0.v0radius()); - fRegistry.fill(HIST("V0/AntiLambda/hDCA2Legs"), v0.dcaV0daughters()); - fRegistry.fill(HIST("V0/AntiLambda/hAP"), v0.alpha(), v0.qtarm()); - fRegistry.fill(HIST("V0/AntiLambda/hMassAntiLambda"), v0.mAntiLambda()); - antilambdaIds.emplace_back(v0.globalIndex()); } - } // end of v0 loop + if (cascade.casccosPA(collision.posX(), collision.posY(), collision.posZ()) < cascadecut.cfg_min_cospa) { + continue; + } + if (cascade.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) < cascadecut.cfg_min_cospa_v0) { + continue; + } - for (const auto& trackId : electronIds) { - const auto& ele = tracks.rawIteratorAt(trackId); - runPairEandTrack<0>(collision, ele, posKaonIds, tracks, mcParticles, mcCollisions); - runPairEandTrack<0>(collision, ele, negKaonIds, tracks, mcParticles, mcCollisions); // only for Ds - runPairEandV0<1>(collision, ele, k0sIds, v0s, mcParticles, mcCollisions); - runPairEandV0<2>(collision, ele, antilambdaIds, v0s, mcParticles, mcCollisions); - } // end of electron loop + fillCascadeHistograms(collision, cascade); + if (cascade.sign() < 0) { // Xi- or Omega- + if (isXi(cascade) && isPion(bachelor)) { + xiMinusIds.emplace_back(cascade.globalIndex()); + } else if (isOmega(cascade) && isKaon(bachelor)) { + omegaMinusIds.emplace_back(cascade.globalIndex()); + } + } else { // Xi+ or Omega+ + if (isXi(cascade) && isPion(bachelor)) { + xiPlusIds.emplace_back(cascade.globalIndex()); + } else if (isOmega(cascade) && isKaon(bachelor)) { + omegaPlusIds.emplace_back(cascade.globalIndex()); + } + } + } // end of cascade loop + + // Lc+ -> e+ Lambda nu_e, br = 0.0356, ctau = 60.75 um, m = 2286 MeV/c2 + for (const auto& positronId : positronIds) { + const auto& pos = tracks.rawIteratorAt(positronId); + + for (const auto& lambdaId : lambdaIds) { + const auto& lambda = v0s.rawIteratorAt(lambdaId); + const auto& eLpair = makeELPair(collision, pos, lambda); // RS + fRegistry.fill(HIST("Data/eL/RS/hs"), eLpair.mass, eLpair.ptepv, eLpair.dca3dinsigma, eLpair.lxy); + fRegistry.fill(HIST("Data/eL/RS/hCosPA"), eLpair.cospa); + fRegistry.fill(HIST("Data/eL/RS/hDCA2Legs"), eLpair.dca2legs); + fRegistry.fill(HIST("Data/eL/RS/hLxy"), eLpair.lxy); + fRegistry.fill(HIST("Data/eL/RS/hLz"), eLpair.lz); + + if constexpr (isMC) { + const auto& mcpos = pos.template mcParticle_as(); + auto posLeg = lambda.template posTrack_as(); + auto negLeg = lambda.template negTrack_as(); + const auto& mcposLeg = posLeg.template mcParticle_as(); + const auto& mcnegLeg = negLeg.template mcParticle_as(); + int mcLambdaId = FindCommonMotherFrom2Prongs(mcposLeg, mcnegLeg, 2212, -211, 3122, mcParticles); + if (mcLambdaId > 0) { // true lambda + const auto& mcLambda = mcParticles.rawIteratorAt(mcLambdaId); + int mcLambdacId = FindCommonMotherFrom2Prongs(mcpos, mcLambda, -11, 3122, 4122, mcParticles); + if (mcLambdacId > 0) { // true Lc0 + const auto& mcLambdac0 = mcParticles.rawIteratorAt(mcLambdacId); + if (IsFromBeauty(mcLambdac0, mcParticles) < 0) { + fRegistry.fill(HIST("MC/eLfromPromptLcpm/hs"), eLpair.mass, eLpair.ptepv, eLpair.dca3dinsigma, eLpair.lxy); + } else { + fRegistry.fill(HIST("MC/eLfromNonPromptLcpm/hs"), eLpair.mass, eLpair.ptepv, eLpair.dca3dinsigma, eLpair.lxy); + } + } + } + } // end of MC truth + } // end of Lambda loop + + for (const auto& antilambdaId : antilambdaIds) { + const auto& antilambda = v0s.rawIteratorAt(antilambdaId); + const auto& eLpair = makeELPair(collision, pos, antilambda); // WS + fRegistry.fill(HIST("Data/eL/WS/hs"), eLpair.mass, eLpair.ptepv, eLpair.dca3dinsigma, eLpair.lxy); + fRegistry.fill(HIST("Data/eL/WS/hCosPA"), eLpair.cospa); + fRegistry.fill(HIST("Data/eL/WS/hDCA2Legs"), eLpair.dca2legs); + fRegistry.fill(HIST("Data/eL/WS/hLxy"), eLpair.lxy); + fRegistry.fill(HIST("Data/eL/WS/hLz"), eLpair.lz); + } // end of AntiLambda loop + + } // end of main positron sample + + for (const auto& electronId : electronIds) { + const auto& ele = tracks.rawIteratorAt(electronId); + + for (const auto& lambdaId : lambdaIds) { + const auto& lambda = v0s.rawIteratorAt(lambdaId); + const auto& eLpair = makeELPair(collision, ele, lambda); // WS + fRegistry.fill(HIST("Data/eL/WS/hs"), eLpair.mass, eLpair.ptepv, eLpair.dca3dinsigma, eLpair.lxy); + fRegistry.fill(HIST("Data/eL/WS/hCosPA"), eLpair.cospa); + fRegistry.fill(HIST("Data/eL/WS/hDCA2Legs"), eLpair.dca2legs); + fRegistry.fill(HIST("Data/eL/WS/hLxy"), eLpair.lxy); + fRegistry.fill(HIST("Data/eL/WS/hLz"), eLpair.lz); + } // end of Lambda loop + + for (const auto& antilambdaId : antilambdaIds) { + const auto& antilambda = v0s.rawIteratorAt(antilambdaId); + const auto& eLpair = makeELPair(collision, ele, antilambda); // RS + fRegistry.fill(HIST("Data/eL/RS/hs"), eLpair.mass, eLpair.ptepv, eLpair.dca3dinsigma, eLpair.lxy); + fRegistry.fill(HIST("Data/eL/RS/hCosPA"), eLpair.cospa); + fRegistry.fill(HIST("Data/eL/RS/hDCA2Legs"), eLpair.dca2legs); + fRegistry.fill(HIST("Data/eL/RS/hLxy"), eLpair.lxy); + fRegistry.fill(HIST("Data/eL/RS/hLz"), eLpair.lz); + + if constexpr (isMC) { + const auto& mcele = ele.template mcParticle_as(); + auto posLeg = antilambda.template posTrack_as(); + auto negLeg = antilambda.template negTrack_as(); + const auto& mcposLeg = posLeg.template mcParticle_as(); + const auto& mcnegLeg = negLeg.template mcParticle_as(); + int mcLambdaId = FindCommonMotherFrom2Prongs(mcposLeg, mcnegLeg, 221, -2212, -3122, mcParticles); + if (mcLambdaId > 0) { // true lambda + const auto& mcLambda = mcParticles.rawIteratorAt(mcLambdaId); + int mcLambdacId = FindCommonMotherFrom2Prongs(mcele, mcLambda, 11, -3122, -4122, mcParticles); + if (mcLambdacId > 0) { // true Lc0 + const auto& mcLambdac0 = mcParticles.rawIteratorAt(mcLambdacId); + if (IsFromBeauty(mcLambdac0, mcParticles) < 0) { + fRegistry.fill(HIST("MC/eLfromPromptLcpm/hs"), eLpair.mass, eLpair.ptepv, eLpair.dca3dinsigma, eLpair.lxy); + } else { + fRegistry.fill(HIST("MC/eLfromNonPromptLcpm/hs"), eLpair.mass, eLpair.ptepv, eLpair.dca3dinsigma, eLpair.lxy); + } + } + } + } // end of MC truth + + } // end of AntiLambda loop + + } // end of main electron sample + + // Xic0 -> e+ Xi- nu_e, br = 0.0105, ctau = 45.1 um, m = 2470 MeV/c2 + for (const auto& positronId : positronIds) { + const auto& pos = tracks.rawIteratorAt(positronId); + + for (const auto& xiMinusId : xiMinusIds) { + const auto& xiMinus = cascades.rawIteratorAt(xiMinusId); + const auto& eXipair = makeECascadePair<0>(collision, pos, xiMinus); // RS + fRegistry.fill(HIST("Data/eXi/RS/hs"), eXipair.mass, eXipair.ptepv, eXipair.dca3dinsigma, eXipair.lxy); + fRegistry.fill(HIST("Data/eXi/RS/hCosPA"), eXipair.cospa); + fRegistry.fill(HIST("Data/eXi/RS/hDCA2Legs"), eXipair.dca2legs); + fRegistry.fill(HIST("Data/eXi/RS/hLxy"), eXipair.lxy); + fRegistry.fill(HIST("Data/eXi/RS/hLz"), eXipair.lz); + + if constexpr (isMC) { + const auto& mcpos = pos.template mcParticle_as(); + auto posLeg = xiMinus.template posTrack_as(); + auto negLeg = xiMinus.template negTrack_as(); + auto bachelor = xiMinus.template bachelor_as(); + const auto& mcposLeg = posLeg.template mcParticle_as(); + const auto& mcnegLeg = negLeg.template mcParticle_as(); + const auto& mcbachelor = bachelor.template mcParticle_as(); + int mcLambdaId = FindCommonMotherFrom2Prongs(mcposLeg, mcnegLeg, 2212, -211, 3122, mcParticles); + if (mcLambdaId > 0) { // true Lambda + const auto& mcLambda = mcParticles.rawIteratorAt(mcLambdaId); + int mcXiId = FindCommonMotherFrom2Prongs(mcLambda, mcbachelor, 3122, -211, 3312, mcParticles); + if (mcXiId > 0) { // true xiMinus + const auto& mcXi = mcParticles.rawIteratorAt(mcXiId); + int mcXic0Id = FindCommonMotherFrom2Prongs(mcpos, mcXi, -11, 3312, 4132, mcParticles); + if (mcXic0Id > 0) { // true Xic0 + const auto& mcXic0 = mcParticles.rawIteratorAt(mcXic0Id); + if (IsFromBeauty(mcXic0, mcParticles) < 0) { + fRegistry.fill(HIST("MC/eXifromPromptXic0/hs"), eXipair.mass, eXipair.ptepv, eXipair.dca3dinsigma, eXipair.lxy); + } else { + fRegistry.fill(HIST("MC/eXifromNonPromptXic0/hs"), eXipair.mass, eXipair.ptepv, eXipair.dca3dinsigma, eXipair.lxy); + } + } + } + } + } // end of MC truth + } // end of Lambda loop + + for (const auto& xiPlusId : xiPlusIds) { + const auto& xiPlus = cascades.rawIteratorAt(xiPlusId); + const auto& eXipair = makeECascadePair<0>(collision, pos, xiPlus); // WS + fRegistry.fill(HIST("Data/eXi/WS/hs"), eXipair.mass, eXipair.ptepv, eXipair.dca3dinsigma, eXipair.lxy); + fRegistry.fill(HIST("Data/eXi/WS/hCosPA"), eXipair.cospa); + fRegistry.fill(HIST("Data/eXi/WS/hDCA2Legs"), eXipair.dca2legs); + fRegistry.fill(HIST("Data/eXi/WS/hLxy"), eXipair.lxy); + fRegistry.fill(HIST("Data/eXi/WS/hLz"), eXipair.lz); + } // end of AntiLambda loop + } // end of main positron sample + + for (const auto& electronId : electronIds) { + const auto& ele = tracks.rawIteratorAt(electronId); + + for (const auto& xiMinusId : xiMinusIds) { + const auto& xiMinus = cascades.rawIteratorAt(xiMinusId); + const auto& eXipair = makeECascadePair<0>(collision, ele, xiMinus); // WS + fRegistry.fill(HIST("Data/eXi/WS/hs"), eXipair.mass, eXipair.ptepv, eXipair.dca3dinsigma, eXipair.lxy); + fRegistry.fill(HIST("Data/eXi/WS/hCosPA"), eXipair.cospa); + fRegistry.fill(HIST("Data/eXi/WS/hDCA2Legs"), eXipair.dca2legs); + fRegistry.fill(HIST("Data/eXi/WS/hLxy"), eXipair.lxy); + fRegistry.fill(HIST("Data/eXi/WS/hLz"), eXipair.lz); + + } // end of Xi- loop + + for (const auto& xiPlusId : xiPlusIds) { + const auto& xiPlus = cascades.rawIteratorAt(xiPlusId); + const auto& eXipair = makeECascadePair<0>(collision, ele, xiPlus); // RS + fRegistry.fill(HIST("Data/eXi/RS/hs"), eXipair.mass, eXipair.ptepv, eXipair.dca3dinsigma, eXipair.lxy); + fRegistry.fill(HIST("Data/eXi/RS/hCosPA"), eXipair.cospa); + fRegistry.fill(HIST("Data/eXi/RS/hDCA2Legs"), eXipair.dca2legs); + fRegistry.fill(HIST("Data/eXi/RS/hLxy"), eXipair.lxy); + fRegistry.fill(HIST("Data/eXi/RS/hLz"), eXipair.lz); + + if constexpr (isMC) { + const auto& mcele = ele.template mcParticle_as(); + auto posLeg = xiPlus.template posTrack_as(); + auto negLeg = xiPlus.template negTrack_as(); + auto bachelor = xiPlus.template bachelor_as(); + const auto& mcposLeg = posLeg.template mcParticle_as(); + const auto& mcnegLeg = negLeg.template mcParticle_as(); + const auto& mcbachelor = bachelor.template mcParticle_as(); + int mcLambdaId = FindCommonMotherFrom2Prongs(mcposLeg, mcnegLeg, 211, -2212, -3122, mcParticles); + if (mcLambdaId > 0) { // true AntiLambda + const auto& mcLambda = mcParticles.rawIteratorAt(mcLambdaId); + int mcXiId = FindCommonMotherFrom2Prongs(mcLambda, mcbachelor, -3122, 211, -3312, mcParticles); + if (mcXiId > 0) { // true xiPlus + const auto& mcXi = mcParticles.rawIteratorAt(mcXiId); + int mcXic0Id = FindCommonMotherFrom2Prongs(mcele, mcXi, 11, -3312, 4132, mcParticles); + if (mcXic0Id > 0) { // true Xic0 + const auto& mcXic0 = mcParticles.rawIteratorAt(mcXic0Id); + if (IsFromBeauty(mcXic0, mcParticles) < 0) { + fRegistry.fill(HIST("MC/eXifromPromptXic0/hs"), eXipair.mass, eXipair.ptepv, eXipair.dca3dinsigma, eXipair.lxy); + } else { + fRegistry.fill(HIST("MC/eXifromNonPromptXic0/hs"), eXipair.mass, eXipair.ptepv, eXipair.dca3dinsigma, eXipair.lxy); + } + } + } + } + } // end of MC truth + + } // end of Xi+ loop + } // end of main electron sample + + // Omegac0 -> e+ Omega- nu_e, br(Omegac0 -> e+ Omega- nu_e) / br(Omegac0 -> Omega- pi+) = 1.98, ctau = 82 um, m = 2695 MeV/c2 + for (const auto& positronId : positronIds) { + const auto& pos = tracks.rawIteratorAt(positronId); + + for (const auto& omegaMinusId : omegaMinusIds) { + const auto& omegaMinus = cascades.rawIteratorAt(omegaMinusId); + const auto& eOmegapair = makeECascadePair<1>(collision, pos, omegaMinus); // RS + fRegistry.fill(HIST("Data/eOmega/RS/hs"), eOmegapair.mass, eOmegapair.ptepv, eOmegapair.dca3dinsigma, eOmegapair.lxy); + fRegistry.fill(HIST("Data/eOmega/RS/hCosPA"), eOmegapair.cospa); + fRegistry.fill(HIST("Data/eOmega/RS/hDCA2Legs"), eOmegapair.dca2legs); + fRegistry.fill(HIST("Data/eOmega/RS/hLxy"), eOmegapair.lxy); + fRegistry.fill(HIST("Data/eOmega/RS/hLz"), eOmegapair.lz); + + if constexpr (isMC) { + const auto& mcpos = pos.template mcParticle_as(); + auto posLeg = omegaMinus.template posTrack_as(); + auto negLeg = omegaMinus.template negTrack_as(); + auto bachelor = omegaMinus.template bachelor_as(); + const auto& mcposLeg = posLeg.template mcParticle_as(); + const auto& mcnegLeg = negLeg.template mcParticle_as(); + const auto& mcbachelor = bachelor.template mcParticle_as(); + int mcLambdaId = FindCommonMotherFrom2Prongs(mcposLeg, mcnegLeg, 2212, -211, 3122, mcParticles); + if (mcLambdaId > 0) { // true Lambda + const auto& mcLambda = mcParticles.rawIteratorAt(mcLambdaId); + int mcOmegaId = FindCommonMotherFrom2Prongs(mcLambda, mcbachelor, 3122, -211, 3312, mcParticles); + if (mcOmegaId > 0) { // true omegaMinus + const auto& mcOmega = mcParticles.rawIteratorAt(mcOmegaId); + int mcOmegac0Id = FindCommonMotherFrom2Prongs(mcpos, mcOmega, -11, 3312, 4132, mcParticles); + if (mcOmegac0Id > 0) { // true Omegac0 + const auto& mcOmegac0 = mcParticles.rawIteratorAt(mcOmegac0Id); + if (IsFromBeauty(mcOmegac0, mcParticles) < 0) { + fRegistry.fill(HIST("MC/eOmegafromPromptOmegac0/hs"), eOmegapair.mass, eOmegapair.ptepv, eOmegapair.dca3dinsigma, eOmegapair.lxy); + } else { + fRegistry.fill(HIST("MC/eOmegafromNonPromptOmegac0/hs"), eOmegapair.mass, eOmegapair.ptepv, eOmegapair.dca3dinsigma, eOmegapair.lxy); + } + } + } + } + } // end of MC truth + } // end of Lambda loop + + for (const auto& omegaPlusId : omegaPlusIds) { + const auto& omegaPlus = cascades.rawIteratorAt(omegaPlusId); + const auto& eOmegapair = makeECascadePair<1>(collision, pos, omegaPlus); // WS + fRegistry.fill(HIST("Data/eOmega/WS/hs"), eOmegapair.mass, eOmegapair.ptepv, eOmegapair.dca3dinsigma, eOmegapair.lxy); + fRegistry.fill(HIST("Data/eOmega/WS/hCosPA"), eOmegapair.cospa); + fRegistry.fill(HIST("Data/eOmega/WS/hDCA2Legs"), eOmegapair.dca2legs); + fRegistry.fill(HIST("Data/eOmega/WS/hLxy"), eOmegapair.lxy); + fRegistry.fill(HIST("Data/eOmega/WS/hLz"), eOmegapair.lz); + } // end of AntiLambda loop + } // end of main positron sample + + for (const auto& electronId : electronIds) { + const auto& ele = tracks.rawIteratorAt(electronId); + + for (const auto& omegaMinusId : omegaMinusIds) { + const auto& omegaMinus = cascades.rawIteratorAt(omegaMinusId); + const auto& eOmegapair = makeECascadePair<1>(collision, ele, omegaMinus); // WS + fRegistry.fill(HIST("Data/eOmega/WS/hs"), eOmegapair.mass, eOmegapair.ptepv, eOmegapair.dca3dinsigma, eOmegapair.lxy); + fRegistry.fill(HIST("Data/eOmega/WS/hCosPA"), eOmegapair.cospa); + fRegistry.fill(HIST("Data/eOmega/WS/hDCA2Legs"), eOmegapair.dca2legs); + fRegistry.fill(HIST("Data/eOmega/WS/hLxy"), eOmegapair.lxy); + fRegistry.fill(HIST("Data/eOmega/WS/hLz"), eOmegapair.lz); + + } // end of Omega- loop + + for (const auto& omegaPlusId : omegaPlusIds) { + const auto& omegaPlus = cascades.rawIteratorAt(omegaPlusId); + const auto& eOmegapair = makeECascadePair<1>(collision, ele, omegaPlus); // RS + fRegistry.fill(HIST("Data/eOmega/RS/hs"), eOmegapair.mass, eOmegapair.ptepv, eOmegapair.dca3dinsigma, eOmegapair.lxy); + fRegistry.fill(HIST("Data/eOmega/RS/hCosPA"), eOmegapair.cospa); + fRegistry.fill(HIST("Data/eOmega/RS/hDCA2Legs"), eOmegapair.dca2legs); + fRegistry.fill(HIST("Data/eOmega/RS/hLxy"), eOmegapair.lxy); + fRegistry.fill(HIST("Data/eOmega/RS/hLz"), eOmegapair.lz); + + if constexpr (isMC) { + const auto& mcele = ele.template mcParticle_as(); + auto posLeg = omegaPlus.template posTrack_as(); + auto negLeg = omegaPlus.template negTrack_as(); + auto bachelor = omegaPlus.template bachelor_as(); + const auto& mcposLeg = posLeg.template mcParticle_as(); + const auto& mcnegLeg = negLeg.template mcParticle_as(); + const auto& mcbachelor = bachelor.template mcParticle_as(); + int mcLambdaId = FindCommonMotherFrom2Prongs(mcposLeg, mcnegLeg, 211, -2212, -3122, mcParticles); + if (mcLambdaId > 0) { // true AntiLambda + const auto& mcLambda = mcParticles.rawIteratorAt(mcLambdaId); + int mcOmegaId = FindCommonMotherFrom2Prongs(mcLambda, mcbachelor, -3122, 211, -3312, mcParticles); + if (mcOmegaId > 0) { // true omegaPlus + const auto& mcOmega = mcParticles.rawIteratorAt(mcOmegaId); + int mcOmegac0Id = FindCommonMotherFrom2Prongs(mcele, mcOmega, 11, -3312, 4132, mcParticles); + if (mcOmegac0Id > 0) { // true Omegac0 + const auto& mcOmegac0 = mcParticles.rawIteratorAt(mcOmegac0Id); + if (IsFromBeauty(mcOmegac0, mcParticles) < 0) { + fRegistry.fill(HIST("MC/eOmegafromPromptOmegac0/hs"), eOmegapair.mass, eOmegapair.ptepv, eOmegapair.dca3dinsigma, eOmegapair.lxy); + } else { + fRegistry.fill(HIST("MC/eOmegafromNonPromptOmegac0/hs"), eOmegapair.mass, eOmegapair.ptepv, eOmegapair.dca3dinsigma, eOmegapair.lxy); + } + } + } + } + } // end of MC truth - for (const auto& trackId : positronIds) { - const auto& pos = tracks.rawIteratorAt(trackId); - runPairEandTrack<0>(collision, pos, negKaonIds, tracks, mcParticles, mcCollisions); - runPairEandTrack<0>(collision, pos, posKaonIds, tracks, mcParticles, mcCollisions); // only for Ds - runPairEandV0<1>(collision, pos, k0sIds, v0s, mcParticles, mcCollisions); // only for Ds - runPairEandV0<2>(collision, pos, lambdaIds, v0s, mcParticles, mcCollisions); - } // end of positron loop + } // end of Omega+ loop + } // end of main electron sample + electronIdsLoose.clear(); + electronIdsLoose.shrink_to_fit(); + positronIdsLoose.clear(); + positronIdsLoose.shrink_to_fit(); electronIds.clear(); electronIds.shrink_to_fit(); positronIds.clear(); @@ -1327,87 +1574,75 @@ struct taggingHFE { posKaonIds.clear(); posKaonIds.shrink_to_fit(); - k0sIds.clear(); - k0sIds.shrink_to_fit(); lambdaIds.clear(); lambdaIds.shrink_to_fit(); antilambdaIds.clear(); antilambdaIds.shrink_to_fit(); + + xiPlusIds.clear(); + xiPlusIds.shrink_to_fit(); + xiMinusIds.clear(); + xiMinusIds.shrink_to_fit(); + + omegaPlusIds.clear(); + omegaPlusIds.shrink_to_fit(); + omegaMinusIds.clear(); + omegaMinusIds.shrink_to_fit(); } // end of collision loop used_electronIds.clear(); used_electronIds.shrink_to_fit(); } - PROCESS_SWITCH(taggingHFE, processTTCA, "process with TTCA", true); - template - bool isSemiLeptonic(TMCParticle const& mcParticle, TMCParticles const& mcParticles) - { - if (!mcParticle.has_daughters()) { - return false; - } - bool is_lepton_involved = false; - bool is_neutrino_involved = false; - for (int d = mcParticle.daughtersIds()[0]; d <= mcParticle.daughtersIds()[1]; ++d) { - if (d < mcParticles.size()) { // protect against bad daughter indices - const auto& daughter = mcParticles.rawIteratorAt(d); - if (daughter.pdgCode() == pdgLepton) { - is_lepton_involved = true; - } else if (daughter.pdgCode() == pdgNeutrino) { - is_neutrino_involved = true; - } - } else { - std::cout << "Daughter label (" << d << ") exceeds the McParticles size (" << mcParticles.size() << ")" << std::endl; - std::cout << " Check the MC generator" << std::endl; - return false; - } - } + SliceCache cache; + Preslice perCol = o2::aod::track::collisionId; + Preslice perCol_v0 = o2::aod::v0data::collisionId; + Preslice perCol_casc = o2::aod::cascdata::collisionId; - if (is_lepton_involved && is_neutrino_involved) { - return true; - } else { - return false; - } - } + Filter collisionFilter_evsel = o2::aod::evsel::sel8 == true && (eventcut.cfgZvtxMin < o2::aod::collision::posZ && o2::aod::collision::posZ < eventcut.cfgZvtxMax); + Filter collisionFilter_centrality = (eventcut.cfgCentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < eventcut.cfgCentMax) || (eventcut.cfgCentMin < o2::aod::cent::centFT0A && o2::aod::cent::centFT0A < eventcut.cfgCentMax) || (eventcut.cfgCentMin < o2::aod::cent::centFT0C && o2::aod::cent::centFT0C < eventcut.cfgCentMax); + using FilteredMyCollisions = soa::Filtered; + using FilteredMyCollisionsWithMCLabel = soa::Filtered; - Partition genDpms = nabs(o2::aod::mcparticle::pdgCode) == 411; - Partition genD0s = nabs(o2::aod::mcparticle::pdgCode) == 421; - Partition genDss = nabs(o2::aod::mcparticle::pdgCode) == 431; - Partition genLcs = nabs(o2::aod::mcparticle::pdgCode) == 4122; + Preslice trackIndicesPerCollision = aod::track_association::collisionId; + std::vector> stored_trackIds; - void processGen(aod::McCollisions const&, aod::McParticles const& mcParticles) - { - for (const auto& genD0 : genD0s) { - const auto& mcCollision = genD0.template mcCollision_as(); - if (cfgEventGeneratorType >= 0 && mcCollision.getSubGeneratorId() != cfgEventGeneratorType) { - continue; - } - if (!(genD0.isPhysicalPrimary() || genD0.producedByGenerator())) { - continue; - } - if ((isSemiLeptonic<11, -12>(genD0, mcParticles) || isSemiLeptonic<-11, 12>(genD0, mcParticles))) { - float ptE = 999.f, ptK = 999.f; - float etaE = 999.f, etaK = 999.f; - for (int d = genD0.daughtersIds()[0]; d <= genD0.daughtersIds()[1]; ++d) { - const auto& daughter = mcParticles.rawIteratorAt(d); - if (std::abs(daughter.pdgCode()) == 11) { - ptE = daughter.pt(); - etaE = daughter.eta(); - } else if (std::abs(daughter.pdgCode()) == 321) { - ptK = daughter.pt(); - etaK = daughter.eta(); - } - } - if (o2::aod::pwgem::dilepton::utils::mcutil::IsFromBeauty(genD0, mcParticles) < 0) { - fRegistry.fill(HIST("Generated/D0/prompt/hs"), ptE, ptK, etaE, etaK); - } else { - fRegistry.fill(HIST("Generated/D0/nonprompt/hs"), ptE, ptK, etaE, etaK); - } - } + // Filter trackFilter = ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::TPC) == true; + // using MyFilteredTracks = soa::Filtered; + // using MyFilteredTracksWithMCLabel = soa::Filtered; + // Partition posTracks = o2::aod::track::signed1Pt > 0.f; + // Partition negTracks = o2::aod::track::signed1Pt < 0.f; + + //! type of V0. 0: built solely for cascades (does not pass standard V0 cut), 1: standard 2, 3: photon-like with TPC-only use. Regular analysis should always use type 1. + Filter v0Filter = o2::aod::v0data::v0Type == uint8_t(1) && o2::aod::v0data::v0cosPA > v0cut.cfg_min_cospa&& o2::aod::v0data::dcaV0daughters v0cut.cfg_min_dcaxy&& nabs(o2::aod::v0data::dcanegtopv) > v0cut.cfg_min_dcaxy; + using filteredV0s = soa::Filtered; + + Filter cascadeFilter = nabs(o2::aod::cascdata::dcanegtopv) > cascadecut.cfg_min_dcaxy_v0leg&& nabs(o2::aod::cascdata::dcanegtopv) > cascadecut.cfg_min_dcaxy_v0leg&& nabs(o2::aod::cascdata::dcabachtopv) > cascadecut.cfg_min_dcaxy_bachelor; + Filter cascadeFilter_dca = o2::aod::cascdata::dcacascdaughters < cascadecut.cfg_max_dcadau && o2::aod::cascdata::dcaV0daughters < cascadecut.cfg_max_dcadau_v0; + using filteredMyCascades = soa::Filtered; + + std::vector electronIdsLoose; + std::vector positronIdsLoose; + std::vector electronIds; + std::vector positronIds; + std::vector negKaonIds; + std::vector posKaonIds; - } // end of gen. D0 loop + std::vector lambdaIds; + std::vector antilambdaIds; + + std::vector xiPlusIds; + std::vector xiMinusIds; + std::vector omegaPlusIds; + std::vector omegaMinusIds; + + std::vector> used_electronIds; // pair of hTypeId and electronId + + void processMC(FilteredMyCollisionsWithMCLabel const& collisions, aod::BCsWithTimestamps const& bcs, MyTracksWithMCLabel const& tracks, aod::TrackAssoc const& trackIndices, filteredV0s const& v0s, filteredMyCascades const& cascades, aod::McCollisions const& mcCollisions, aod::McParticles const& mcParticles) + { + runPairing(bcs, collisions, tracks, trackIndices, v0s, cascades, mcCollisions, mcParticles); } - PROCESS_SWITCH(taggingHFE, processGen, "process gen. info", true); + PROCESS_SWITCH(taggingHFE, processMC, "process with TTCA", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { diff --git a/PWGEM/Dilepton/Tasks/vpPairQC.cxx b/PWGEM/Dilepton/Tasks/vpPairQC.cxx index 098403d7ea4..ffa82e3c3e5 100644 --- a/PWGEM/Dilepton/Tasks/vpPairQC.cxx +++ b/PWGEM/Dilepton/Tasks/vpPairQC.cxx @@ -50,7 +50,7 @@ using namespace o2::aod::pwgem::dilepton::utils::emtrackutil; using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; -using MyTracks = soa::Join; +using MyTracks = soa::Join; using MyTrack = MyTracks::iterator; struct vpPairQC { @@ -126,6 +126,7 @@ struct vpPairQC { Configurable cfg_max_its_cluster_size{"cfg_max_its_cluster_size", 16.f, "max ITS cluster size"}; Configurable cfg_min_rel_diff_pin{"cfg_min_rel_diff_pin", -1e+10, "min rel. diff. between pin and ppv"}; Configurable cfg_max_rel_diff_pin{"cfg_max_rel_diff_pin", +1e+10, "max rel. diff. between pin and ppv"}; + Configurable cfgRefR{"cfgRefR", 1.2, "reference R (in m) for extrapolation"}; // https://cds.cern.ch/record/1419204 Configurable cfg_pid_scheme{"cfg_pid_scheme", static_cast(DielectronCut::PIDSchemes::kTOFif), "pid scheme [kTOFreq : 0, kTPChadrej : 1, kTPChadrejORTOFreq : 2, kTPConly : 3, kTOFif : 4, kPIDML : 5]"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; @@ -263,9 +264,9 @@ struct vpPairQC { fRegistry.add("Track/positive/hTPCNsigmaPr", "TPC n sigma pr;p_{in} (GeV/c);n #sigma_{p}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); fRegistry.add("Track/positive/hTOFNsigmaEl", "TOF n sigma el;p_{pv} (GeV/c);n #sigma_{e}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); // fRegistry.add("Track/positive/hTOFNsigmaMu", "TOF n sigma mu;p_{pv} (GeV/c);n #sigma_{#mu}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/positive/hTOFNsigmaPi", "TOF n sigma pi;p_{pv} (GeV/c);n #sigma_{#pi}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/positive/hTOFNsigmaKa", "TOF n sigma ka;p_{pv} (GeV/c);n #sigma_{K}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/positive/hTOFNsigmaPr", "TOF n sigma pr;p_{pv} (GeV/c);n #sigma_{p}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + // fRegistry.add("Track/positive/hTOFNsigmaPi", "TOF n sigma pi;p_{pv} (GeV/c);n #sigma_{#pi}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + // fRegistry.add("Track/positive/hTOFNsigmaKa", "TOF n sigma ka;p_{pv} (GeV/c);n #sigma_{K}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); + // fRegistry.add("Track/positive/hTOFNsigmaPr", "TOF n sigma pr;p_{pv} (GeV/c);n #sigma_{p}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); fRegistry.addClone("Track/positive/", "Track/negative/"); const AxisSpec axis_mass{50, 0, 0.05, "m_{ee} (GeV/c^{2})"}; @@ -381,7 +382,7 @@ struct vpPairQC { return false; } - if (!fDielectronCut.IsSelectedPair(t1, t2, d_bz)) { + if (!fDielectronCut.IsSelectedPair(t1, t2, d_bz, dielectroncuts.cfgRefR)) { return false; } @@ -420,11 +421,6 @@ struct vpPairQC { if (track.sign() > 0) { fRegistry.fill(HIST("Track/positive/hs"), track.pt(), track.eta(), track.phi(), dca_3d, weight); fRegistry.fill(HIST("Track/positive/hQoverPt"), track.sign() / track.pt()); - fRegistry.fill(HIST("Track/positive/hPResolution"), track.p(), sigmaP(track) / track.p()); - fRegistry.fill(HIST("Track/positive/hPtResolution"), track.p(), sigmaPt(track) / track.pt()); - fRegistry.fill(HIST("Track/positive/hThetaResolution"), track.p(), sigmaTheta(track)); - fRegistry.fill(HIST("Track/positive/hEtaResolution"), track.p(), sigmaEta(track)); - fRegistry.fill(HIST("Track/positive/hPhiResolution"), track.p(), sigmaPhi(track)); fRegistry.fill(HIST("Track/positive/hDCAxyz"), track.dcaXY(), track.dcaZ()); fRegistry.fill(HIST("Track/positive/hDCAxyzSigma"), track.dcaXY() / sqrt(track.cYY()), track.dcaZ() / sqrt(track.cZZ())); fRegistry.fill(HIST("Track/positive/hDCAxyRes_Pt"), track.pt(), sqrt(track.cYY()) * 1e+4); // convert cm to um @@ -451,17 +447,12 @@ struct vpPairQC { fRegistry.fill(HIST("Track/positive/hTPCNsigmaPr"), track.tpcInnerParam(), track.tpcNSigmaPr()); fRegistry.fill(HIST("Track/positive/hTOFNsigmaEl"), track.p(), track.tofNSigmaEl()); // fRegistry.fill(HIST("Track/positive/hTOFNsigmaMu"), track.p(), track.tofNSigmaMu()); - fRegistry.fill(HIST("Track/positive/hTOFNsigmaPi"), track.p(), track.tofNSigmaPi()); - fRegistry.fill(HIST("Track/positive/hTOFNsigmaKa"), track.p(), track.tofNSigmaKa()); - fRegistry.fill(HIST("Track/positive/hTOFNsigmaPr"), track.p(), track.tofNSigmaPr()); + // fRegistry.fill(HIST("Track/positive/hTOFNsigmaPi"), track.p(), track.tofNSigmaPi()); + // fRegistry.fill(HIST("Track/positive/hTOFNsigmaKa"), track.p(), track.tofNSigmaKa()); + // fRegistry.fill(HIST("Track/positive/hTOFNsigmaPr"), track.p(), track.tofNSigmaPr()); } else { fRegistry.fill(HIST("Track/negative/hs"), track.pt(), track.eta(), track.phi(), dca_3d, weight); fRegistry.fill(HIST("Track/negative/hQoverPt"), track.sign() / track.pt()); - fRegistry.fill(HIST("Track/negative/hPResolution"), track.p(), sigmaP(track) / track.p()); - fRegistry.fill(HIST("Track/negative/hPtResolution"), track.p(), sigmaPt(track) / track.pt()); - fRegistry.fill(HIST("Track/negative/hThetaResolution"), track.p(), sigmaTheta(track)); - fRegistry.fill(HIST("Track/negative/hEtaResolution"), track.p(), sigmaEta(track)); - fRegistry.fill(HIST("Track/negative/hPhiResolution"), track.p(), sigmaPhi(track)); fRegistry.fill(HIST("Track/negative/hDCAxyz"), track.dcaXY(), track.dcaZ()); fRegistry.fill(HIST("Track/negative/hDCAxyzSigma"), track.dcaXY() / sqrt(track.cYY()), track.dcaZ() / sqrt(track.cZZ())); fRegistry.fill(HIST("Track/negative/hDCAxyRes_Pt"), track.pt(), sqrt(track.cYY()) * 1e+4); // convert cm to um @@ -488,9 +479,9 @@ struct vpPairQC { fRegistry.fill(HIST("Track/negative/hTPCNsigmaPr"), track.tpcInnerParam(), track.tpcNSigmaPr()); fRegistry.fill(HIST("Track/negative/hTOFNsigmaEl"), track.p(), track.tofNSigmaEl()); // fRegistry.fill(HIST("Track/negative/hTOFNsigmaMu"), track.p(), track.tofNSigmaMu()); - fRegistry.fill(HIST("Track/negative/hTOFNsigmaPi"), track.p(), track.tofNSigmaPi()); - fRegistry.fill(HIST("Track/negative/hTOFNsigmaKa"), track.p(), track.tofNSigmaKa()); - fRegistry.fill(HIST("Track/negative/hTOFNsigmaPr"), track.p(), track.tofNSigmaPr()); + // fRegistry.fill(HIST("Track/negative/hTOFNsigmaPi"), track.p(), track.tofNSigmaPi()); + // fRegistry.fill(HIST("Track/negative/hTOFNsigmaKa"), track.p(), track.tofNSigmaKa()); + // fRegistry.fill(HIST("Track/negative/hTOFNsigmaPr"), track.p(), track.tofNSigmaPr()); } } diff --git a/PWGEM/Dilepton/Tasks/vpPairQCMC.cxx b/PWGEM/Dilepton/Tasks/vpPairQCMC.cxx index 9cc2c6cb77f..d470a92afa2 100644 --- a/PWGEM/Dilepton/Tasks/vpPairQCMC.cxx +++ b/PWGEM/Dilepton/Tasks/vpPairQCMC.cxx @@ -50,7 +50,7 @@ using namespace o2::aod::pwgem::dilepton::utils::mcutil; using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; -using MyMCTracks = soa::Join; +using MyMCTracks = soa::Join; using MyMCTrack = MyMCTracks::iterator; struct vpPairQCMC { @@ -126,6 +126,7 @@ struct vpPairQCMC { Configurable cfg_max_its_cluster_size{"cfg_max_its_cluster_size", 16.f, "max ITS cluster size"}; Configurable cfg_min_rel_diff_pin{"cfg_min_rel_diff_pin", -1e+10, "min rel. diff. between pin and ppv"}; Configurable cfg_max_rel_diff_pin{"cfg_max_rel_diff_pin", +1e+10, "max rel. diff. between pin and ppv"}; + Configurable cfgRefR{"cfgRefR", 1.2, "reference R (in m) for extrapolation"}; // https://cds.cern.ch/record/1419204 Configurable cfg_pid_scheme{"cfg_pid_scheme", static_cast(DielectronCut::PIDSchemes::kTOFif), "pid scheme [kTOFreq : 0, kTPChadrej : 1, kTPChadrejORTOFreq : 2, kTPConly : 3, kTOFif : 4, kPIDML : 5]"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; @@ -411,7 +412,7 @@ struct vpPairQCMC { return false; } - if (!fDielectronCut.IsSelectedPair(t1, t2, d_bz)) { + if (!fDielectronCut.IsSelectedPair(t1, t2, d_bz, dielectroncuts.cfgRefR)) { return false; } diff --git a/PWGEM/Dilepton/Utils/EMTrackUtilities.h b/PWGEM/Dilepton/Utils/EMTrackUtilities.h index 087ee38d60b..5c5b21e6ea0 100644 --- a/PWGEM/Dilepton/Utils/EMTrackUtilities.h +++ b/PWGEM/Dilepton/Utils/EMTrackUtilities.h @@ -27,7 +27,7 @@ namespace o2::aod::pwgem::dilepton::utils::emtrackutil { -enum class RefTrackBit : uint16_t { // This is not for leptons, but charged particles for ref. flow. +enum class RefTrackBit : uint16_t { // This is not for leptons, but charged tracks for reference flow. kNclsITS5 = 1, kNclsITS6 = 2, kNcrTPC70 = 4, @@ -38,6 +38,10 @@ enum class RefTrackBit : uint16_t { // This is not for leptons, but charged part kChi2TPC4 = 128, kChi2TPC3 = 256, kFracSharedTPC07 = 512, + kDCAxy05cm = 1024, // default is 1 cm + kDCAxy03cm = 2048, + kDCAz05cm = 4096, // default is 1cm + kDCAz03cm = 8192, }; //_______________________________________________________________________ @@ -146,36 +150,36 @@ bool isBestMatch(TTrack const& track, TCut const& cut, TTracks const& tracks) } } //_______________________________________________________________________ -template -float sigmaPt(T const& track) -{ - return std::sqrt(track.c1Pt21Pt2()) / std::pow(track.signed1Pt(), 2); // pT resolution -} -//_______________________________________________________________________ -template -float sigmaPhi(T const& track) -{ - return std::sqrt(track.cSnpSnp()) / std::sqrt(1.f - std::pow(track.snp(), 2)); // phi resolution -} -//_______________________________________________________________________ -template -float sigmaTheta(T const& track) -{ - return std::sqrt(track.cTglTgl()) / (1.f + std::pow(track.tgl(), 2)); // theta resolution = lambda resolution. // lambda = pi/2 - theta. theta is polar angle. -} -//_______________________________________________________________________ -template -float sigmaEta(T const& track) -{ - return std::sqrt(track.cTglTgl()) / std::sqrt(1.f + std::pow(track.tgl(), 2)); -} -//_______________________________________________________________________ -template -float sigmaP(T const& track) -{ - // p = 1/1/pT x 1/cos(lambda); - return std::sqrt(std::pow(1.f / track.signed1Pt(), 4) * ((1.f + std::pow(track.tgl(), 2)) * track.c1Pt21Pt2() + 1.f / (1.f + std::pow(track.tgl(), 2)) * std::pow(track.signed1Pt() * track.tgl(), 2) * track.cTglTgl() - 2.f * track.signed1Pt() * track.tgl() * track.c1PtTgl())); -} +// template +// float sigmaPt(T const& track) +// { +// return std::sqrt(track.c1Pt21Pt2()) / std::pow(track.signed1Pt(), 2); // pT resolution +// } +// //_______________________________________________________________________ +// template +// float sigmaPhi(T const& track) +// { +// return std::sqrt(track.cSnpSnp()) / std::sqrt(1.f - std::pow(track.snp(), 2)); // phi resolution +// } +// //_______________________________________________________________________ +// template +// float sigmaTheta(T const& track) +// { +// return std::sqrt(track.cTglTgl()) / (1.f + std::pow(track.tgl(), 2)); // theta resolution = lambda resolution. // lambda = pi/2 - theta. theta is polar angle. +// } +// //_______________________________________________________________________ +// template +// float sigmaEta(T const& track) +// { +// return std::sqrt(track.cTglTgl()) / std::sqrt(1.f + std::pow(track.tgl(), 2)); +// } +// //_______________________________________________________________________ +// template +// float sigmaP(T const& track) +// { +// // p = 1/1/pT x 1/cos(lambda); +// return std::sqrt(std::pow(1.f / track.signed1Pt(), 4) * ((1.f + std::pow(track.tgl(), 2)) * track.c1Pt21Pt2() + 1.f / (1.f + std::pow(track.tgl(), 2)) * std::pow(track.signed1Pt() * track.tgl(), 2) * track.cTglTgl() - 2.f * track.signed1Pt() * track.tgl() * track.c1PtTgl())); +// } //_______________________________________________________________________ } // namespace o2::aod::pwgem::dilepton::utils::emtrackutil #endif // PWGEM_DILEPTON_UTILS_EMTRACKUTILITIES_H_ diff --git a/PWGEM/Dilepton/Utils/EventMixingHandler.h b/PWGEM/Dilepton/Utils/EventMixingHandler.h index 1fa83c60240..20b38399979 100644 --- a/PWGEM/Dilepton/Utils/EventMixingHandler.h +++ b/PWGEM/Dilepton/Utils/EventMixingHandler.h @@ -47,6 +47,11 @@ class EventMixingHandler void SetNdepth(int ndepth) { fNdepth = ndepth; } + void ReserveNTracksPerCollision(U key_df_collision, int ntrack) + { + fMap_Tracks_per_collision[key_df_collision].reserve(ntrack); + } + void AddTrackToEventPool(U key_df_collision, V obj) { fMap_Tracks_per_collision[key_df_collision].emplace_back(obj); diff --git a/PWGEM/Dilepton/Utils/MlResponseO2Track.h b/PWGEM/Dilepton/Utils/MlResponseO2Track.h index cd9be049af6..ae0c17096fb 100644 --- a/PWGEM/Dilepton/Utils/MlResponseO2Track.h +++ b/PWGEM/Dilepton/Utils/MlResponseO2Track.h @@ -144,18 +144,18 @@ enum class InputFeaturesO2Track : uint8_t { reldiffp, tpcSignal, tpcNSigmaEl, - tpcNSigmaMu, + // tpcNSigmaMu, tpcNSigmaPi, tpcNSigmaKa, tpcNSigmaPr, beta, tofNSigmaEl, - tofNSigmaMu, + // tofNSigmaMu, tofNSigmaPi, tofNSigmaKa, tofNSigmaPr, tpctofNSigmaEl, - tpctofNSigmaMu, + // tpctofNSigmaMu, tpctofNSigmaPi, tpctofNSigmaKa, tpctofNSigmaPr, @@ -198,18 +198,18 @@ class MlResponseO2Track : public MlResponse CHECK_AND_FILL_O2_TRACK_RELDIFF(reldiffp, getP, tpcInnerParam); CHECK_AND_FILL_O2_TRACK(tpcSignal); CHECK_AND_FILL_O2_TRACK(tpcNSigmaEl); - CHECK_AND_FILL_O2_TRACK(tpcNSigmaMu); + // CHECK_AND_FILL_O2_TRACK(tpcNSigmaMu); CHECK_AND_FILL_O2_TRACK(tpcNSigmaPi); CHECK_AND_FILL_O2_TRACK(tpcNSigmaKa); CHECK_AND_FILL_O2_TRACK(tpcNSigmaPr); CHECK_AND_FILL_O2_TRACK(beta); CHECK_AND_FILL_O2_TRACK(tofNSigmaEl); - CHECK_AND_FILL_O2_TRACK(tofNSigmaMu); + // CHECK_AND_FILL_O2_TRACK(tofNSigmaMu); CHECK_AND_FILL_O2_TRACK(tofNSigmaPi); CHECK_AND_FILL_O2_TRACK(tofNSigmaKa); CHECK_AND_FILL_O2_TRACK(tofNSigmaPr); CHECK_AND_FILL_O2_TRACK_TPCTOF(tpctofNSigmaEl, tpcNSigmaEl, tofNSigmaEl, hasTOF); - CHECK_AND_FILL_O2_TRACK_TPCTOF(tpctofNSigmaMu, tpcNSigmaMu, tofNSigmaMu, hasTOF); + // CHECK_AND_FILL_O2_TRACK_TPCTOF(tpctofNSigmaMu, tpcNSigmaMu, tofNSigmaMu, hasTOF); CHECK_AND_FILL_O2_TRACK_TPCTOF(tpctofNSigmaPi, tpcNSigmaPi, tofNSigmaPi, hasTOF); CHECK_AND_FILL_O2_TRACK_TPCTOF(tpctofNSigmaKa, tpcNSigmaKa, tofNSigmaKa, hasTOF); CHECK_AND_FILL_O2_TRACK_TPCTOF(tpctofNSigmaPr, tpcNSigmaPr, tofNSigmaPr, hasTOF); @@ -278,18 +278,18 @@ class MlResponseO2Track : public MlResponse FILL_MAP_O2_TRACK(reldiffp), FILL_MAP_O2_TRACK(tpcSignal), FILL_MAP_O2_TRACK(tpcNSigmaEl), - FILL_MAP_O2_TRACK(tpcNSigmaMu), + // FILL_MAP_O2_TRACK(tpcNSigmaMu), FILL_MAP_O2_TRACK(tpcNSigmaPi), FILL_MAP_O2_TRACK(tpcNSigmaKa), FILL_MAP_O2_TRACK(tpcNSigmaPr), FILL_MAP_O2_TRACK(beta), FILL_MAP_O2_TRACK(tofNSigmaEl), - FILL_MAP_O2_TRACK(tofNSigmaMu), + // FILL_MAP_O2_TRACK(tofNSigmaMu), FILL_MAP_O2_TRACK(tofNSigmaPi), FILL_MAP_O2_TRACK(tofNSigmaKa), FILL_MAP_O2_TRACK(tofNSigmaPr), FILL_MAP_O2_TRACK(tpctofNSigmaEl), - FILL_MAP_O2_TRACK(tpctofNSigmaMu), + // FILL_MAP_O2_TRACK(tpctofNSigmaMu), FILL_MAP_O2_TRACK(tpctofNSigmaPi), FILL_MAP_O2_TRACK(tpctofNSigmaKa), FILL_MAP_O2_TRACK(tpctofNSigmaPr), diff --git a/PWGEM/Dilepton/Utils/MomentumSmearer.h b/PWGEM/Dilepton/Utils/MomentumSmearer.h index 7e36dcfed0f..10699e4c2a0 100644 --- a/PWGEM/Dilepton/Utils/MomentumSmearer.h +++ b/PWGEM/Dilepton/Utils/MomentumSmearer.h @@ -15,22 +15,27 @@ #ifndef PWGEM_DILEPTON_UTILS_MOMENTUMSMEARER_H_ #define PWGEM_DILEPTON_UTILS_MOMENTUMSMEARER_H_ -#include +#include "CCDB/BasicCCDBManager.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/Logger.h" +#include "Framework/runDataProcessing.h" +#include +#include #include #include #include #include -#include -#include -#include #include +#include -#include "CCDB/BasicCCDBManager.h" -#include "Framework/Logger.h" +#include -using namespace o2::framework; using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; class MomentumSmearer { diff --git a/PWGEM/PhotonMeson/Core/CutsLibrary.cxx b/PWGEM/PhotonMeson/Core/CutsLibrary.cxx index c2f313e6e62..d8475e550e9 100644 --- a/PWGEM/PhotonMeson/Core/CutsLibrary.cxx +++ b/PWGEM/PhotonMeson/Core/CutsLibrary.cxx @@ -132,7 +132,7 @@ V0PhotonCut* o2::aod::pwgem::photon::pcmcuts::GetCut(const char* cutName) cut->SetChi2PerClusterITS(-1e+10, 5.0); cut->SetNClustersITS(2, 4); cut->SetMeanClusterSizeITSob(0.0, 16.0); - cut->SetIsWithinBeamPipe(true); + // cut->SetIsWithinBeamPipe(true); // for v0 cut->SetMinCosPA(0.99); cut->SetMaxPCA(3.0); @@ -201,7 +201,7 @@ V0PhotonCut* o2::aod::pwgem::photon::pcmcuts::GetCut(const char* cutName) cut->SetChi2PerClusterITS(-1e+10, 5.0); cut->SetNClustersITS(2, 4); cut->SetMeanClusterSizeITSob(0.0, 16.0); - cut->SetIsWithinBeamPipe(true); + // cut->SetIsWithinBeamPipe(true); // for v0 cut->SetMinCosPA(0.995); cut->SetMaxPCA(0.5); @@ -216,7 +216,7 @@ V0PhotonCut* o2::aod::pwgem::photon::pcmcuts::GetCut(const char* cutName) cut->SetChi2PerClusterITS(-1e+10, 5.0); cut->SetNClustersITS(2, 4); cut->SetMeanClusterSizeITSob(0.0, 16.0); - cut->SetIsWithinBeamPipe(true); + // cut->SetIsWithinBeamPipe(true); cut->SetRequireITSTPC(true); // for v0 cut->SetMinCosPA(0.99); @@ -232,7 +232,7 @@ V0PhotonCut* o2::aod::pwgem::photon::pcmcuts::GetCut(const char* cutName) cut->SetChi2PerClusterITS(-1e+10, 5.0); cut->SetNClustersITS(2, 4); cut->SetMeanClusterSizeITSob(0.0, 16.0); - cut->SetIsWithinBeamPipe(true); + // cut->SetIsWithinBeamPipe(true); // for v0 cut->SetMinCosPA(0.99); cut->SetMaxPCA(3.0); @@ -249,7 +249,7 @@ V0PhotonCut* o2::aod::pwgem::photon::pcmcuts::GetCut(const char* cutName) cut->SetChi2PerClusterITS(-1e+10, 5.0); cut->SetNClustersITS(2, 4); cut->SetMeanClusterSizeITSob(0.0, 16.0); - cut->SetIsWithinBeamPipe(false); + // cut->SetIsWithinBeamPipe(false); // for v0 cut->SetMinCosPA(0.95); cut->SetMaxPCA(3.0); @@ -265,7 +265,7 @@ V0PhotonCut* o2::aod::pwgem::photon::pcmcuts::GetCut(const char* cutName) cut->SetChi2PerClusterITS(-1e+10, 5.0); cut->SetNClustersITS(2, 4); cut->SetMeanClusterSizeITSob(0.0, 16.0); - cut->SetIsWithinBeamPipe(false); + // cut->SetIsWithinBeamPipe(false); // for v0 cut->SetMinCosPA(0.95); cut->SetMaxPCA(3.0); diff --git a/PWGEM/PhotonMeson/Core/DalitzEECut.h b/PWGEM/PhotonMeson/Core/DalitzEECut.h index ee94b84c19c..ddc1da18340 100644 --- a/PWGEM/PhotonMeson/Core/DalitzEECut.h +++ b/PWGEM/PhotonMeson/Core/DalitzEECut.h @@ -240,10 +240,10 @@ class DalitzEECut : public TNamed { switch (cut) { case DalitzEECuts::kTrackPtRange: - return track.pt() >= mMinTrackPt && track.pt() <= mMaxTrackPt; + return track.pt() > mMinTrackPt && track.pt() < mMaxTrackPt; case DalitzEECuts::kTrackEtaRange: - return track.eta() >= mMinTrackEta && track.eta() <= mMaxTrackEta; + return track.eta() > mMinTrackEta && track.eta() < mMaxTrackEta; case DalitzEECuts::kTPCNCls: return track.tpcNClsFound() >= mMinNClustersTPC; @@ -255,19 +255,19 @@ class DalitzEECut : public TNamed return track.tpcCrossedRowsOverFindableCls() >= mMinNCrossedRowsOverFindableClustersTPC; case DalitzEECuts::kTPCFracSharedClusters: - return track.tpcFractionSharedCls() <= mMaxFracSharedClustersTPC; + return track.tpcFractionSharedCls() < mMaxFracSharedClustersTPC; case DalitzEECuts::kTPCChi2NDF: return mMinChi2PerClusterTPC < track.tpcChi2NCl() && track.tpcChi2NCl() < mMaxChi2PerClusterTPC; case DalitzEECuts::kDCA3Dsigma: - return mMinDca3D <= dca3DinSigma(track) && dca3DinSigma(track) <= mMaxDca3D; // in sigma for single leg + return mMinDca3D < dca3DinSigma(track) && dca3DinSigma(track) < mMaxDca3D; // in sigma for single leg case DalitzEECuts::kDCAxy: - return std::fabs(track.dcaXY()) <= ((mMaxDcaXYPtDep) ? mMaxDcaXYPtDep(track.pt()) : mMaxDcaXY); + return std::fabs(track.dcaXY()) < ((mMaxDcaXYPtDep) ? mMaxDcaXYPtDep(track.pt()) : mMaxDcaXY); case DalitzEECuts::kDCAz: - return std::fabs(track.dcaZ()) <= mMaxDcaZ; + return std::fabs(track.dcaZ()) < mMaxDcaZ; case DalitzEECuts::kITSNCls: return mMinNClustersITS <= track.itsNCls() && track.itsNCls() <= mMaxNClustersITS; @@ -283,7 +283,7 @@ class DalitzEECut : public TNamed // Setters void SetPairPtRange(float minPt = 0.f, float maxPt = 1e10f); void SetPairYRange(float minY = -1e10f, float maxY = 1e10f); - void SetMeeRange(float min = 0.f, float max = 0.5); + void SetMeeRange(float min = 0.f, float max = 0.04); void SetMaxPhivPairMeeDep(std::function meeDepCut); void SelectPhotonConversion(bool flag); diff --git a/PWGEM/PhotonMeson/Core/DiphotonHadronMPC.h b/PWGEM/PhotonMeson/Core/DiphotonHadronMPC.h index a0811629c32..7478a70a764 100644 --- a/PWGEM/PhotonMeson/Core/DiphotonHadronMPC.h +++ b/PWGEM/PhotonMeson/Core/DiphotonHadronMPC.h @@ -78,9 +78,6 @@ using MyV0Photon = MyV0Photons::iterator; using MyPrimaryElectrons = soa::Filtered>; using MyPrimaryElectron = MyPrimaryElectrons::iterator; -using MyTracks = soa::Join; -using MyTrack = MyTracks::iterator; - template struct DiphotonHadronMPC { @@ -108,7 +105,7 @@ struct DiphotonHadronMPC { ConfigurableAxis ConfPtggBins{"ConfPtggBins", {VARIABLE_WIDTH, 0.0, 0.1, 0.2, 0.3, 0.4, 0.50, 1.00, 1.50, 2.00, 2.50, 3.00, 3.50, 4.00, 4.50, 5.00, 6.00, 7.00, 8.00, 9.00, 10.00}, "pTgg bins for output histograms"}; ConfigurableAxis ConfPtHadronBins{"ConfPtHadronBins", {VARIABLE_WIDTH, 0.00, 0.15, 0.2, 0.3, 0.4, 0.50, 1.00, 2.00, 3.00, 4.00, 5.00}, "pT,h bins for output histograms"}; - ConfigurableAxis ConfDEtaBins{"ConfDEtaBins", {60, -3, 3}, "deta bins for output histograms"}; + ConfigurableAxis ConfDEtaBins{"ConfDEtaBins", {120, -6, 6}, "deta bins for output histograms"}; Configurable cfgNbinsDPhi{"cfgNbinsDPhi", 36, "nbins in dphi for output histograms"}; // Configurable cfgNbinsCosNDPhi{"cfgNbinsCosNDPhi", 100, "nbins in cos(n(dphi)) for output histograms"}; // Configurable cfgNmod{"cfgNmod", 2, "n-th harmonics"}; @@ -152,7 +149,6 @@ struct DiphotonHadronMPC { Configurable cfg_min_cospa{"cfg_min_cospa", 0.997, "min V0 CosPA"}; Configurable cfg_max_pca{"cfg_max_pca", 3.0, "max distance btween 2 legs"}; Configurable cfg_max_chi2kf{"cfg_max_chi2kf", 1e+10, "max chi2/ndf with KF"}; - Configurable cfg_require_v0_with_correct_xz{"cfg_require_v0_with_correct_xz", false, "flag to select V0s with correct xz"}; Configurable cfg_reject_v0_on_itsib{"cfg_reject_v0_on_itsib", true, "flag to reject V0s on ITSib"}; Configurable cfg_apply_cuts_from_prefilter_derived{"cfg_apply_cuts_from_prefilter_derived", false, "flag to apply prefilter to V0"}; @@ -207,19 +203,11 @@ struct DiphotonHadronMPC { Configurable cfg_max_pt_track{"cfg_max_pt_track", 3.0, "max pT for ref. track"}; Configurable cfg_min_eta_track{"cfg_min_eta_track", -0.8, "min eta for ref. track"}; Configurable cfg_max_eta_track{"cfg_max_eta_track", +0.8, "max eta for ref. track"}; - Configurable cfg_min_phi_track{"cfg_min_phi_track", 0.0, "min phi for ref. track"}; - Configurable cfg_max_phi_track{"cfg_max_phi_track", 6.3, "max phi for ref. track"}; - Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 0.5, "max dca XY for single track in cm"}; - Configurable cfg_max_dcaz{"cfg_max_dcaz", 0.5, "max dca Z for single track in cm"}; + // Configurable cfg_min_phi_track{"cfg_min_phi_track", 0.0, "min phi for ref. track"}; + // Configurable cfg_max_phi_track{"cfg_max_phi_track", 6.3, "max phi for ref. track"}; + // Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 0.5, "max dca XY for single track in cm"}; + // Configurable cfg_max_dcaz{"cfg_max_dcaz", 0.5, "max dca Z for single track in cm"}; Configurable cfg_track_bits{"cfg_track_bits", 645, "required track bits"}; // default:645, loose:0, tight:778 - // Configurable cfg_min_ncluster_its{"cfg_min_ncluster_its", 5, "min ncluster its"}; - // Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; - // Configurable cfg_min_ncrossedrows{"cfg_min_ncrossedrows", 70, "min ncrossed rows"}; - // Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 0.7, "max fraction of shared clusters in TPC"}; - // Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; - // Configurable cfg_max_chi2its{"cfg_max_chi2its", 36.0, "max chi2/NclsITS"}; - // Configurable cfg_require_itsib_any{"cfg_require_itsib_any", true, "flag to require ITS ib any hits"}; - // Configurable cfg_require_itsib_1st{"cfg_require_itsib_1st", false, "flag to require ITS ib 1st hit"}; } trackcuts; o2::aod::rctsel::RCTFlagsChecker rctChecker; @@ -337,8 +325,6 @@ struct DiphotonHadronMPC { used_photonIds.shrink_to_fit(); used_dileptonIds.clear(); used_dileptonIds.shrink_to_fit(); - used_refTrackIds.clear(); - used_refTrackIds.shrink_to_fit(); map_mixed_eventId_to_globalBC.clear(); } @@ -359,20 +345,11 @@ struct DiphotonHadronMPC { // cosndphi_axis_title = std::format("cos({0:d}(#varphi_{{ee#gamma}} - #varphi_{{h}}))", cfgNmod.value); } - // photon info - const AxisSpec axis_pt_single{ConfPtggBins, "p_{T,#gamma} (GeV/c)"}; - const AxisSpec axis_eta_single{20, -1, +1, "#eta_{#gamma}"}; - const AxisSpec axis_phi_single{36, 0, 2 * M_PI, "#varphi_{#gamma} (rad.)"}; - const AxisSpec axis_deta_single{ConfDEtaBins, "#Delta#eta = #eta_{#gamma} - #eta_{h}"}; - const AxisSpec axis_dphi_single{cfgNbinsDPhi, -M_PI / 2, +3 * M_PI / 2, "#Delta#varphi = #varphi_{#gamma} - #varphi_{h} (rad.)"}; - // const AxisSpec axis_cos_ndphi_single{cfgNbinsCosNDPhi, -1, +1, std::format("cos({0:d}(#varphi_{{#gamma}} - #varphi_{{h}}))", cfgNmod.value)}; - // diphoton info const AxisSpec axis_mass{ConfMggBins, mass_axis_title}; const AxisSpec axis_pt{ConfPtggBins, pair_pt_axis_title}; // diphoton-hadron info - const AxisSpec axis_pt_ref{ConfPtHadronBins, "p_{T,h}^{ref} (GeV/c)"}; const AxisSpec axis_deta{ConfDEtaBins, deta_axis_title}; const AxisSpec axis_dphi{cfgNbinsDPhi, -M_PI / 2, +3 * M_PI / 2, dphi_axis_title}; @@ -380,19 +357,20 @@ struct DiphotonHadronMPC { const AxisSpec axis_eta_hadron{40, -2, +2, "#eta_{h}"}; const AxisSpec axis_phi_hadron{36, 0, 2 * M_PI, "#varphi_{h} (rad.)"}; - fRegistry.add("Hadron/hs", "hadron", kTHnSparseD, {axis_pt_hadron, axis_eta_hadron, axis_phi_hadron}, true); + fRegistry.add("Hadron/hs", "hadron", kTHnSparseD, {axis_pt_hadron, axis_eta_hadron, axis_phi_hadron}, false); + fRegistry.add("Hadron/hTrackBit", "track bit", kTH1D, {{65536, -0.5, 65535.5}}, false); fRegistry.add("Diphoton/same/hs", "diphoton", kTHnSparseD, {axis_mass, axis_pt}, true); fRegistry.addClone("Diphoton/same/", "Diphoton/mix/"); - fRegistry.add("DiphotonHadron/same/hs", "diphoton-hadron 2PC", kTHnSparseD, {axis_mass, axis_pt, axis_pt_ref, axis_deta, axis_dphi}, true); + fRegistry.add("DiphotonHadron/same/hs", "diphoton-hadron 2PC", kTHnSparseD, {axis_mass, axis_pt, axis_deta, axis_dphi}, true); fRegistry.addClone("DiphotonHadron/same/", "DiphotonHadron/mix/"); // hadron-hadron - const AxisSpec axis_deta_hh{ConfDEtaBins, "#Delta#eta = #eta_{h}^{ref1} - #eta_{h}^{ref2}"}; - const AxisSpec axis_dphi_hh{cfgNbinsDPhi, -M_PI / 2, +3 * M_PI / 2, "#Delta#varphi = #varphi_{h}^{ref1} - #varphi_{h}^{ref2} (rad.)"}; + const AxisSpec axis_deta_hh{60, -3, +3, "#Delta#eta = #eta_{h}^{ref1} - #eta_{h}^{ref2}"}; + const AxisSpec axis_dphi_hh{90, -M_PI / 2, +3 * M_PI / 2, "#Delta#varphi = #varphi_{h}^{ref1} - #varphi_{h}^{ref2} (rad.)"}; // const AxisSpec axis_cosndphi_hh{cfgNbinsCosNDPhi, -1, +1, std::format("cos({0:d}(#varphi_{{h}}^{{ref1}} - #varphi_{{h}}^{{ref2}}))", cfgNmod.value)}; - fRegistry.add("HadronHadron/same/hs", "hadron-hadron 2PC", kTHnSparseD, {axis_pt_hadron, axis_pt_ref, axis_deta_hh, axis_dphi_hh}, true); + fRegistry.add("HadronHadron/same/hDEtaDPhi", "hadron-hadron 2PC", kTH2D, {axis_dphi_hh, axis_deta_hh}, true); fRegistry.addClone("HadronHadron/same/", "HadronHadron/mix/"); } @@ -432,7 +410,6 @@ struct DiphotonHadronMPC { fV0PhotonCut.SetChi2PerClusterITS(-1e+10, pcmcuts.cfg_max_chi2its); fV0PhotonCut.SetNClustersITS(0, 7); fV0PhotonCut.SetMeanClusterSizeITSob(0.0, 16.0); - fV0PhotonCut.SetIsWithinBeamPipe(pcmcuts.cfg_require_v0_with_correct_xz); fV0PhotonCut.SetDisableITSonly(pcmcuts.cfg_disable_itsonly_track); fV0PhotonCut.SetDisableTPConly(pcmcuts.cfg_disable_tpconly_track); fV0PhotonCut.SetRequireITSTPC(pcmcuts.cfg_require_v0_with_itstpc); @@ -478,29 +455,26 @@ struct DiphotonHadronMPC { fEMTrackCut = EMTrackCut("fEMTrackCut", "fEMTrackCut"); fEMTrackCut.SetTrackPtRange(trackcuts.cfg_min_pt_track, trackcuts.cfg_max_pt_track); fEMTrackCut.SetTrackEtaRange(trackcuts.cfg_min_eta_track, trackcuts.cfg_max_eta_track); - fEMTrackCut.SetTrackPhiRange(trackcuts.cfg_min_phi_track, trackcuts.cfg_max_phi_track); - fEMTrackCut.SetTrackMaxDcaXY(trackcuts.cfg_max_dcaxy); - fEMTrackCut.SetTrackMaxDcaZ(trackcuts.cfg_max_dcaz); + // fEMTrackCut.SetTrackPhiRange(trackcuts.cfg_min_phi_track, trackcuts.cfg_max_phi_track); + // fEMTrackCut.SetTrackMaxDcaXY(trackcuts.cfg_max_dcaxy); + // fEMTrackCut.SetTrackMaxDcaZ(trackcuts.cfg_max_dcaz); fEMTrackCut.SetTrackBit(trackcuts.cfg_track_bits); - // fEMTrackCut.SetMinNClustersTPC(trackcuts.cfg_min_ncluster_tpc); - // fEMTrackCut.SetMinNCrossedRowsTPC(trackcuts.cfg_min_ncrossedrows); - // fEMTrackCut.SetMinNCrossedRowsOverFindableClustersTPC(0.8); - // fEMTrackCut.SetMaxFracSharedClustersTPC(trackcuts.cfg_max_frac_shared_clusters_tpc); - // fEMTrackCut.SetChi2PerClusterTPC(0.0, trackcuts.cfg_max_chi2tpc); - // fEMTrackCut.SetChi2PerClusterITS(0.0, trackcuts.cfg_max_chi2its); - // fEMTrackCut.SetNClustersITS(trackcuts.cfg_min_ncluster_its, 7); - // fEMTrackCut.RequireITSibAny(trackcuts.cfg_require_itsib_any); - // fEMTrackCut.RequireITSib1st(trackcuts.cfg_require_itsib_1st); } SliceCache cache; Preslice perCollision_pcm = aod::v0photonkf::emeventId; - Preslice perCollision_track = aod::emprimarytrack::emeventId; Preslice perCollision_electron = aod::emprimaryelectron::emeventId; Partition positrons = o2::aod::emprimaryelectron::sign > int8_t(0) && static_cast(dileptoncuts.cfg_min_pt_track) < o2::aod::track::pt&& nabs(o2::aod::track::eta) < static_cast(dileptoncuts.cfg_max_eta_track) && static_cast(dileptoncuts.cfg_min_TPCNsigmaEl) < o2::aod::pidtpc::tpcNSigmaEl&& o2::aod::pidtpc::tpcNSigmaEl < static_cast(dileptoncuts.cfg_max_TPCNsigmaEl); Partition electrons = o2::aod::emprimaryelectron::sign < int8_t(0) && static_cast(dileptoncuts.cfg_min_pt_track) < o2::aod::track::pt && nabs(o2::aod::track::eta) < static_cast(dileptoncuts.cfg_max_eta_track) && static_cast(dileptoncuts.cfg_min_TPCNsigmaEl) < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < static_cast(dileptoncuts.cfg_max_TPCNsigmaEl); + using RefTracks = soa::Join; + using RefTrack = RefTracks::iterator; + Preslice perCollision_track = aod::emprimarytrack::emeventId; + Filter refTrackFilter = trackcuts.cfg_min_pt_track < 1 / nabs(o2::aod::emprimarytrack::signed1Pt) && 1 / nabs(o2::aod::emprimarytrack::signed1Pt) < trackcuts.cfg_max_pt_track && trackcuts.cfg_min_eta_track < o2::aod::emprimarytrack::eta && o2::aod::emprimarytrack::eta < trackcuts.cfg_max_eta_track; + using FilteredRefTracks = soa::Filtered; + using FilteredRefTrack = FilteredRefTracks::iterator; + using MyEMH = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, EMTrack>; MyEMH* emh1 = nullptr; MyEMH* emh2 = nullptr; @@ -510,7 +484,6 @@ struct DiphotonHadronMPC { std::vector> used_photonIds; // std::vector> used_dileptonIds; // - std::vector> used_refTrackIds; // std::vector> used_diphotonIds; // std::map, uint64_t> map_mixed_eventId_to_globalBC; @@ -580,11 +553,6 @@ struct DiphotonHadronMPC { // LOGF(info, "collision.globalIndex() = %d, collision.posZ() = %f, centrality = %f, ep2 = %f, collision.trackOccupancyInTimeRange() = %d, zbin = %d, centbin = %d, epbin = %d, occbin = %d", collision.globalIndex(), collision.posZ(), centrality, ep2, collision.trackOccupancyInTimeRange(), zbin, centbin, epbin, occbin); auto refTracks_per_collision = refTracks.sliceBy(perCollision_track, collision.globalIndex()); - for (const auto& track : refTracks_per_collision) { - if (fEMTrackCut.IsSelected(track)) { - fRegistry.fill(HIST("Hadron/hs"), track.pt(), track.eta(), track.phi()); - } - } std::tuple key_bin = std::make_tuple(zbin, centbin, epbin, occbin); std::pair key_df_collision = std::make_pair(ndf, collision.globalIndex()); @@ -610,7 +578,7 @@ struct DiphotonHadronMPC { auto pos2 = g2.template posTrack_as(); auto ele2 = g2.template negTrack_as(); - int npair = 0; + int npair = 0; // the number of diphoton-h pairs for (const auto& track : refTracks_per_collision) { if (pos1.trackId() == track.trackId() || ele1.trackId() == track.trackId()) { continue; @@ -625,13 +593,8 @@ struct DiphotonHadronMPC { float dphi = v12.Phi() - v3.Phi(); // o2::math_utils::bringTo02Pi(dphi); dphi = RecoDecay::constrainAngle(dphi, -M_PI / 2, 1U); - fRegistry.fill(HIST("DiphotonHadron/same/hs"), v12.M(), v12.Pt(), v3.Pt(), deta, dphi); + fRegistry.fill(HIST("DiphotonHadron/same/hs"), v12.M(), v12.Pt(), deta, dphi); npair++; - std::pair pair_tmp_ref = std::make_pair(ndf, track.globalIndex()); - if (std::find(used_refTrackIds.begin(), used_refTrackIds.end(), pair_tmp_ref) == used_refTrackIds.end()) { // add a ref track in mixing pool - emh_ref->AddTrackToEventPool(key_df_collision, EMTrack(ndf, track.globalIndex(), collision.globalIndex(), track.globalIndex(), track.pt(), track.eta(), track.phi(), 0.139)); - used_refTrackIds.emplace_back(pair_tmp_ref); - } } } // end of ref track loop @@ -694,7 +657,7 @@ struct DiphotonHadronMPC { } fRegistry.fill(HIST("Diphoton/same/hs"), veeg.M(), veeg.Pt()); - int npair = 0; + int npair = 0; // the number of diphoton-h pairs for (const auto& track : refTracks_per_collision) { if (pos1.trackId() == track.trackId() || ele1.trackId() == track.trackId()) { continue; @@ -708,14 +671,9 @@ struct DiphotonHadronMPC { float dphi = veeg.Phi() - v3.Phi(); // o2::math_utils::bringTo02Pi(dphi); dphi = RecoDecay::constrainAngle(dphi, -M_PI / 2, 1U); - fRegistry.fill(HIST("DiphotonHadron/same/hs"), veeg.M(), veeg.Pt(), v3.Pt(), deta, dphi); + fRegistry.fill(HIST("DiphotonHadron/same/hs"), veeg.M(), veeg.Pt(), deta, dphi); npair++; - std::pair pair_tmp_ref = std::make_pair(ndf, track.globalIndex()); - if (std::find(used_refTrackIds.begin(), used_refTrackIds.end(), pair_tmp_ref) == used_refTrackIds.end()) { // add a ref track in mixing pool - emh_ref->AddTrackToEventPool(key_df_collision, EMTrack(ndf, track.globalIndex(), collision.globalIndex(), track.globalIndex(), track.pt(), track.eta(), track.phi(), 0.139)); - used_refTrackIds.emplace_back(pair_tmp_ref); - } } // end of ref track loop if (npair > 0) { @@ -742,13 +700,22 @@ struct DiphotonHadronMPC { } // end of pairing in same event if (ndiphoton > 0) { + emh_ref->ReserveNTracksPerCollision(key_df_collision, refTracks_per_collision.size()); + for (const auto& track : refTracks_per_collision) { + if (fEMTrackCut.IsSelected(track)) { + fRegistry.fill(HIST("Hadron/hs"), track.pt(), track.eta(), track.phi()); + fRegistry.fill(HIST("Hadron/hTrackBit"), track.trackBit()); + emh_ref->AddTrackToEventPool(key_df_collision, EMTrack(ndf, track.globalIndex(), collision.globalIndex(), track.globalIndex(), track.pt(), track.eta(), track.phi(), 0.139)); + } + } + for (const auto& [ref1, ref2] : combinations(CombinationsStrictlyUpperIndexPolicy(refTracks_per_collision, refTracks_per_collision))) { if (fEMTrackCut.IsSelected(ref1) && fEMTrackCut.IsSelected(ref2)) { float deta = ref1.eta() - ref2.eta(); float dphi = ref1.phi() - ref2.phi(); // o2::math_utils::bringTo02Pi(dphi); dphi = RecoDecay::constrainAngle(dphi, -M_PI / 2, 1U); - fRegistry.fill(HIST("HadronHadron/same/hs"), ref1.pt(), ref2.pt(), deta, dphi); + fRegistry.fill(HIST("HadronHadron/same/hDEtaDPhi"), dphi, deta); } } } @@ -822,7 +789,7 @@ struct DiphotonHadronMPC { float dphi = trg.phi() - ref.phi(); // o2::math_utils::bringTo02Pi(dphi); dphi = RecoDecay::constrainAngle(dphi, -M_PI / 2, 1U); - fRegistry.fill(HIST("DiphotonHadron/mix/hs"), trg.mass(), trg.pt(), ref.pt(), deta, dphi); + fRegistry.fill(HIST("DiphotonHadron/mix/hs"), trg.mass(), trg.pt(), deta, dphi); } } } // end of loop over mixed event pool between diphoton-hadron @@ -917,7 +884,7 @@ struct DiphotonHadronMPC { float dphi = trg.phi() - ref.phi(); // o2::math_utils::bringTo02Pi(dphi); dphi = RecoDecay::constrainAngle(dphi, -M_PI / 2, 1U); - fRegistry.fill(HIST("DiphotonHadron/mix/hs"), trg.mass(), trg.pt(), ref.pt(), deta, dphi); + fRegistry.fill(HIST("DiphotonHadron/mix/hs"), trg.mass(), trg.pt(), deta, dphi); } } } // end of loop over mixed event pool between diphoton-hadron @@ -945,7 +912,7 @@ struct DiphotonHadronMPC { float dphi = ref1.phi() - ref2.phi(); // o2::math_utils::bringTo02Pi(dphi); dphi = RecoDecay::constrainAngle(dphi, -M_PI / 2, 1U); - fRegistry.fill(HIST("HadronHadron/mix/hs"), ref1.pt(), ref2.pt(), deta, dphi); + fRegistry.fill(HIST("HadronHadron/mix/hDEtaDPhi"), dphi, deta); } } } // end of loop over mixed event pool between hadron-hadron @@ -970,7 +937,7 @@ struct DiphotonHadronMPC { Filter prefilter_primaryelectron = ifnode(dileptoncuts.cfg_apply_cuts_from_prefilter_derived.node(), o2::aod::emprimaryelectron::pfbderived == static_cast(0), true); int ndf = 0; - void processAnalysis(FilteredMyCollisions const& collisions, MyTracks const& refTracks, Types const&... args) + void processAnalysis(FilteredMyCollisions const& collisions, FilteredRefTracks const& refTracks, Types const&... args) { // LOGF(info, "ndf = %d", ndf); if constexpr (pairtype == PairType::kPCMPCM) { @@ -989,7 +956,7 @@ struct DiphotonHadronMPC { PROCESS_SWITCH(DiphotonHadronMPC, processAnalysis, "process pair analysis", true); using FilteredMyCollisionsWithSWT = soa::Filtered; - void processTriggerAnalysis(FilteredMyCollisionsWithSWT const& collisions, MyTracks const& refTracks, Types const&... args) + void processTriggerAnalysis(FilteredMyCollisionsWithSWT const& collisions, FilteredRefTracks const& refTracks, Types const&... args) { // LOGF(info, "ndf = %d", ndf); if constexpr (pairtype == PairType::kPCMPCM) { diff --git a/PWGEM/PhotonMeson/Core/EMCPhotonCut.cxx b/PWGEM/PhotonMeson/Core/EMCPhotonCut.cxx index 582b9754057..199da171c11 100644 --- a/PWGEM/PhotonMeson/Core/EMCPhotonCut.cxx +++ b/PWGEM/PhotonMeson/Core/EMCPhotonCut.cxx @@ -13,11 +13,17 @@ // Class for EMCal cluster selection // -#include -#include "Framework/Logger.h" #include "PWGEM/PhotonMeson/Core/EMCPhotonCut.h" + #include "PWGJE/DataModel/EMCALClusters.h" +#include "Framework/Logger.h" + +#include + +#include +#include + ClassImp(EMCPhotonCut); const char* EMCPhotonCut::mCutNames[static_cast(EMCPhotonCut::EMCPhotonCuts::kNCuts)] = {"Definition", "Energy", "NCell", "M02", "Timing", "TrackMatching", "Exotic"}; diff --git a/PWGEM/PhotonMeson/Core/EMCPhotonCut.h b/PWGEM/PhotonMeson/Core/EMCPhotonCut.h index 8bfd8ca630f..1e3ac74f6cd 100644 --- a/PWGEM/PhotonMeson/Core/EMCPhotonCut.h +++ b/PWGEM/PhotonMeson/Core/EMCPhotonCut.h @@ -9,22 +9,19 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -// -// Class for emcal photon selection -// +/// \file EMCPhotonCut.h +/// \brief Header of class for emcal photon selection. +/// \author M. Hemmer, marvin.hemmer@cern.ch; N. Strangmann, nicolas.strangmann@cern.ch #ifndef PWGEM_PHOTONMESON_CORE_EMCPHOTONCUT_H_ #define PWGEM_PHOTONMESON_CORE_EMCPHOTONCUT_H_ -#include -#include -#include +#include + +#include + +#include #include -#include -#include "Framework/Logger.h" -#include "Framework/DataTypes.h" -#include "Rtypes.h" -#include "TNamed.h" class EMCPhotonCut : public TNamed { @@ -95,14 +92,14 @@ class EMCPhotonCut : public TNamed return mMinTime <= cluster.time() && cluster.time() <= mMaxTime; case EMCPhotonCuts::kTM: { - auto trackseta = cluster.tracketa(); // std:vector - auto tracksphi = cluster.trackphi(); // std:vector - auto trackspt = cluster.trackpt(); // std:vector - auto tracksp = cluster.trackp(); // std:vector + auto dEtas = cluster.deltaEta(); // std:vector + auto dPhis = cluster.deltaPhi(); // std:vector + auto trackspt = cluster.trackpt(); // std:vector + auto tracksp = cluster.trackp(); // std:vector int ntrack = tracksp.size(); for (int itr = 0; itr < ntrack; itr++) { - float dEta = fabs(trackseta[itr] - cluster.eta()); - float dPhi = fabs(tracksphi[itr] - cluster.phi()); + float dEta = std::fabs(dEtas[itr]); + float dPhi = std::fabs(dPhis[itr]); bool result = (dEta > mTrackMatchingEta(trackspt[itr])) || (dPhi > mTrackMatchingPhi(trackspt[itr])) || (cluster.e() / tracksp[itr] >= mMinEoverP); if (!result) { return false; diff --git a/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx b/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx index 50174ab9e08..e54a462e9dc 100644 --- a/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx +++ b/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx @@ -9,28 +9,25 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. // -// Contact: daiki.sekihata@cern.ch -// -#include -#include -#include -using namespace std; +/// \file HistogramsLibrary.cxx +/// \brief Small histogram library for photon and meson analysis. +/// \author D. Sekihata, daiki.sekihata@cern.ch + +#include "PWGEM/PhotonMeson/Core/HistogramsLibrary.h" + +#include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include "Framework/Logger.h" -#include "PWGEM/PhotonMeson/Core/HistogramsLibrary.h" +#include + +#include + +#include + +using namespace std; void o2::aod::pwgem::photon::histogram::DefineHistograms(THashList* list, const char* histClass, const char* subGroup) { @@ -184,7 +181,7 @@ void o2::aod::pwgem::photon::histogram::DefineHistograms(THashList* list, const list->Add(new TH2F("hEtaRec_DeltaEta", "photon #eta resolution;#eta^{rec} of conversion point;#eta^{rec} - #eta^{gen}", 400, -2, +2, 400, -1.0f, 1.0f)); list->Add(new TH2F("hEtaRec_DeltaPhi", "photon #varphi resolution;#eta^{rec} of conversion point;#varphi^{rec} - #varphi^{gen} (rad.)", 400, -2, +2, 400, -1.0f, 1.0f)); } // end of mc - } // end of V0 + } // end of V0 if (TString(histClass).Contains("Dalitz")) { THnSparseF* hs_dilepton_uls_same = nullptr; @@ -576,7 +573,7 @@ void o2::aod::pwgem::photon::histogram::DefineHistograms(THashList* list, const hs_conv_point_mix->Sumw2(); list->Add(hs_conv_point_mix); } // end of pair - } // end of material budget study + } // end of material budget study if (TString(histClass) == "Generated") { list->Add(new TH1F("hCollisionCounter", "hCollisionCounter", 5, 0.5f, 5.5f)); diff --git a/PWGEM/PhotonMeson/Core/HistogramsLibrary.h b/PWGEM/PhotonMeson/Core/HistogramsLibrary.h index 324718a663e..368acef59ce 100644 --- a/PWGEM/PhotonMeson/Core/HistogramsLibrary.h +++ b/PWGEM/PhotonMeson/Core/HistogramsLibrary.h @@ -8,34 +8,25 @@ // In applying this license CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -// -// Contact: daiki.sekihata@cern.ch -// + +/// \file HistogramsLibrary.h +/// \brief Small histogram library for photon and meson analysis. +/// \author D. Sekihata, daiki.sekihata@cern.ch #ifndef PWGEM_PHOTONMESON_CORE_HISTOGRAMSLIBRARY_H_ #define PWGEM_PHOTONMESON_CORE_HISTOGRAMSLIBRARY_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" +#include +#include +#include + +#include +#include +#include + enum EMHistType { kEvent = 0, kEvent_Cent = 1, @@ -48,6 +39,8 @@ enum EMHistType { kEMCCluster = 8, }; +const float maxZ = 10.f; + namespace o2::aod { namespace pwgem::photon::histogram @@ -81,7 +74,7 @@ void FillHistClass(THashList* list, const char* subGroup, T1 const& obj1 /*, con if (obj1.sel8()) { reinterpret_cast(list->FindObject("hCollisionCounter"))->Fill("sel8", 1.f); } - if (abs(obj1.posZ()) < 10.0) { + if (std::abs(obj1.posZ()) < maxZ) { reinterpret_cast(list->FindObject("hCollisionCounter"))->Fill("|Z_{vtx}| < 10 cm", 1.f); } @@ -176,9 +169,9 @@ void FillHistClass(THashList* list, const char* subGroup, T1 const& obj1 /*, con reinterpret_cast(list->FindObject("hQoverPt"))->Fill(obj1.sign() / obj1.pt()); reinterpret_cast(list->FindObject("hEtaPhi"))->Fill(obj1.phi(), obj1.eta()); reinterpret_cast(list->FindObject("hDCAxyz"))->Fill(obj1.dcaXY(), obj1.dcaZ()); - reinterpret_cast(list->FindObject("hDCAxyzSigma"))->Fill(obj1.dcaXY() / sqrt(obj1.cYY()), obj1.dcaZ() / sqrt(obj1.cZZ())); - reinterpret_cast(list->FindObject("hDCAxyRes_Pt"))->Fill(obj1.pt(), sqrt(obj1.cYY()) * 1e+4); // convert cm to um - reinterpret_cast(list->FindObject("hDCAzRes_Pt"))->Fill(obj1.pt(), sqrt(obj1.cZZ()) * 1e+4); // convert cm to um + reinterpret_cast(list->FindObject("hDCAxyzSigma"))->Fill(obj1.dcaXY() / std::sqrt(obj1.cYY()), obj1.dcaZ() / std::sqrt(obj1.cZZ())); + reinterpret_cast(list->FindObject("hDCAxyRes_Pt"))->Fill(obj1.pt(), std::sqrt(obj1.cYY()) * 1e+4); // convert cm to um + reinterpret_cast(list->FindObject("hDCAzRes_Pt"))->Fill(obj1.pt(), std::sqrt(obj1.cZZ()) * 1e+4); // convert cm to um reinterpret_cast(list->FindObject("hNclsITS"))->Fill(obj1.itsNCls()); reinterpret_cast(list->FindObject("hNclsTPC"))->Fill(obj1.tpcNClsFound()); reinterpret_cast(list->FindObject("hNcrTPC"))->Fill(obj1.tpcNClsCrossedRows()); @@ -225,8 +218,8 @@ void FillHistClass(THashList* list, const char* subGroup, T1 const& obj1 /*, con reinterpret_cast(list->FindObject("hPt"))->Fill(obj1.pt()); reinterpret_cast(list->FindObject("hE"))->Fill(obj1.e()); reinterpret_cast(list->FindObject("hEtaPhi"))->Fill(obj1.phi(), obj1.eta()); - for (size_t itrack = 0; itrack < obj1.tracketa().size(); itrack++) { // Fill TrackEtaPhi histogram with delta phi and delta eta of all tracks saved in the vectors in skimmerGammaCalo.cxx - reinterpret_cast(list->FindObject("hTrackEtaPhi"))->Fill(obj1.trackphi()[itrack] - obj1.phi(), obj1.tracketa()[itrack] - obj1.eta()); + for (size_t itrack = 0; itrack < obj1.deltaEta().size(); itrack++) { // Fill TrackEtaPhi histogram with delta phi and delta eta of all tracks saved in the vectors in skimmerGammaCalo.cxx + reinterpret_cast(list->FindObject("hTrackEtaPhi"))->Fill(obj1.deltaPhi()[itrack], obj1.deltaEta()[itrack]); } } } diff --git a/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGamma.h b/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGamma.h index 4b37b306f95..8d2f16d34f6 100644 --- a/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGamma.h +++ b/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGamma.h @@ -71,9 +71,12 @@ using namespace o2::aod::pwgem::photon; using namespace o2::aod::pwgem::dilepton::utils::emtrackutil; using namespace o2::aod::pwgem::dilepton::utils; -using MyCollisions = soa::Join; +using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; +using MyCollisionsWithJJMC = soa::Join; +using MyCollisionWithJJMC = MyCollisionsWithJJMC::iterator; + using MyV0Photons = soa::Filtered>; using MyV0Photon = MyV0Photons::iterator; @@ -111,7 +114,8 @@ struct Pi0EtaToGammaGamma { EMPhotonEventCut fEMEventCut; struct : ConfigurableGroup { std::string prefix = "eventcut_group"; - Configurable cfgZvtxMax{"cfgZvtxMax", 10.f, "max. Zvtx"}; + Configurable cfgZvtxMin{"cfgZvtxMin", -10.f, "min. Zvtx"}; + Configurable cfgZvtxMax{"cfgZvtxMax", +10.f, "max. Zvtx"}; Configurable cfgRequireSel8{"cfgRequireSel8", true, "require sel8 in event cut"}; Configurable cfgRequireFT0AND{"cfgRequireFT0AND", true, "require FT0AND in event cut"}; Configurable cfgRequireNoTFB{"cfgRequireNoTFB", false, "require No time frame border in event cut"}; @@ -142,18 +146,17 @@ struct Pi0EtaToGammaGamma { Configurable cfg_max_v0radius{"cfg_max_v0radius", 90.0, "max v0 radius"}; Configurable cfg_max_alpha_ap{"cfg_max_alpha_ap", 0.95, "max alpha for AP cut"}; Configurable cfg_max_qt_ap{"cfg_max_qt_ap", 0.01, "max qT for AP cut"}; - Configurable cfg_min_cospa{"cfg_min_cospa", 0.997, "min V0 CosPA"}; - Configurable cfg_max_pca{"cfg_max_pca", 3.0, "max distance btween 2 legs"}; + Configurable cfg_min_cospa{"cfg_min_cospa", 0.999, "min V0 CosPA"}; + Configurable cfg_max_pca{"cfg_max_pca", 1.5, "max distance btween 2 legs"}; Configurable cfg_max_chi2kf{"cfg_max_chi2kf", 1e+10, "max chi2/ndf with KF"}; - Configurable cfg_require_v0_with_correct_xz{"cfg_require_v0_with_correct_xz", true, "flag to select V0s with correct xz"}; Configurable cfg_reject_v0_on_itsib{"cfg_reject_v0_on_itsib", true, "flag to reject V0s on ITSib"}; Configurable cfg_apply_cuts_from_prefilter_derived{"cfg_apply_cuts_from_prefilter_derived", false, "flag to apply prefilter to V0"}; - Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 10, "min ncluster tpc"}; + Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; Configurable cfg_min_ncrossedrows{"cfg_min_ncrossedrows", 40, "min ncrossed rows"}; Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; - Configurable cfg_max_chi2its{"cfg_max_chi2its", 5.0, "max chi2/NclsITS"}; + Configurable cfg_max_chi2its{"cfg_max_chi2its", 36.0, "max chi2/NclsITS"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -3.0, "min. TPC n sigma for electron"}; Configurable cfg_max_TPCNsigmaEl{"cfg_max_TPCNsigmaEl", +3.0, "max. TPC n sigma for electron"}; Configurable cfg_disable_itsonly_track{"cfg_disable_itsonly_track", false, "flag to disable ITSonly tracks"}; @@ -177,7 +180,7 @@ struct Pi0EtaToGammaGamma { Configurable cfg_min_ncluster_its{"cfg_min_ncluster_its", 5, "min ncluster its"}; Configurable cfg_min_ncrossedrows{"cfg_min_ncrossedrows", 70, "min ncrossed rows"}; Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; - Configurable cfg_max_chi2its{"cfg_max_chi2its", 5.0, "max chi2/NclsITS"}; + Configurable cfg_max_chi2its{"cfg_max_chi2its", 36.0, "max chi2/NclsITS"}; Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 0.05, "max dca XY for single track in cm"}; Configurable cfg_max_dcaz{"cfg_max_dcaz", 0.05, "max dca Z for single track in cm"}; Configurable cfg_max_dca3dsigma_track{"cfg_max_dca3dsigma_track", 1.5, "max DCA 3D in sigma"}; @@ -337,7 +340,7 @@ struct Pi0EtaToGammaGamma { fEMEventCut = EMPhotonEventCut("fEMEventCut", "fEMEventCut"); fEMEventCut.SetRequireSel8(eventcuts.cfgRequireSel8); fEMEventCut.SetRequireFT0AND(eventcuts.cfgRequireFT0AND); - fEMEventCut.SetZvtxRange(-eventcuts.cfgZvtxMax, +eventcuts.cfgZvtxMax); + fEMEventCut.SetZvtxRange(eventcuts.cfgZvtxMin, eventcuts.cfgZvtxMax); fEMEventCut.SetRequireNoTFB(eventcuts.cfgRequireNoTFB); fEMEventCut.SetRequireNoITSROFB(eventcuts.cfgRequireNoITSROFB); fEMEventCut.SetRequireNoSameBunchPileup(eventcuts.cfgRequireNoSameBunchPileup); @@ -371,7 +374,6 @@ struct Pi0EtaToGammaGamma { fV0PhotonCut.SetChi2PerClusterITS(-1e+10, pcmcuts.cfg_max_chi2its); fV0PhotonCut.SetNClustersITS(0, 7); fV0PhotonCut.SetMeanClusterSizeITSob(0.0, 16.0); - fV0PhotonCut.SetIsWithinBeamPipe(pcmcuts.cfg_require_v0_with_correct_xz); fV0PhotonCut.SetDisableITSonly(pcmcuts.cfg_disable_itsonly_track); fV0PhotonCut.SetDisableTPConly(pcmcuts.cfg_disable_tpconly_track); fV0PhotonCut.SetRequireITSTPC(pcmcuts.cfg_require_v0_with_itstpc); @@ -548,8 +550,8 @@ struct Pi0EtaToGammaGamma { Preslice perCollision_phos = aod::phoscluster::emeventId; Preslice perCollision_electron = aod::emprimaryelectron::emeventId; - Partition positrons = o2::aod::emprimaryelectron::sign > int8_t(0) && static_cast(dileptoncuts.cfg_min_pt_track) < o2::aod::track::pt&& nabs(o2::aod::track::eta) < static_cast(dileptoncuts.cfg_max_eta_track) && static_cast(dileptoncuts.cfg_min_TPCNsigmaEl) < o2::aod::pidtpc::tpcNSigmaEl&& o2::aod::pidtpc::tpcNSigmaEl < static_cast(dileptoncuts.cfg_max_TPCNsigmaEl); - Partition electrons = o2::aod::emprimaryelectron::sign < int8_t(0) && static_cast(dileptoncuts.cfg_min_pt_track) < o2::aod::track::pt && nabs(o2::aod::track::eta) < static_cast(dileptoncuts.cfg_max_eta_track) && static_cast(dileptoncuts.cfg_min_TPCNsigmaEl) < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < static_cast(dileptoncuts.cfg_max_TPCNsigmaEl); + Partition positrons = o2::aod::emprimaryelectron::sign > int8_t(0) && dileptoncuts.cfg_min_pt_track < o2::aod::track::pt&& nabs(o2::aod::track::eta) < dileptoncuts.cfg_max_eta_track; + Partition electrons = o2::aod::emprimaryelectron::sign < int8_t(0) && dileptoncuts.cfg_min_pt_track < o2::aod::track::pt && nabs(o2::aod::track::eta) < dileptoncuts.cfg_max_eta_track; using MyEMH = o2::aod::pwgem::dilepton::utils::EventMixingHandler, std::pair, EMTrack>; MyEMH* emh1 = nullptr; @@ -572,7 +574,12 @@ struct Pi0EtaToGammaGamma { continue; } - if (eventcuts.onlyKeepWeightedEvents && std::fabs(collision.weight() - 1.) < 1E-10) { + float weight = 1.f; + if constexpr (std::is_same_v, FilteredMyCollisionsWithJJMC>) { + weight = collision.weight(); + } + + if (eventcuts.onlyKeepWeightedEvents && std::fabs(weight - 1.f) < 1E-10) { continue; } @@ -581,13 +588,13 @@ struct Pi0EtaToGammaGamma { continue; } - o2::aod::pwgem::photonmeson::utils::eventhistogram::fillEventInfo<0>(&fRegistry, collision, collision.weight()); + o2::aod::pwgem::photonmeson::utils::eventhistogram::fillEventInfo<0>(&fRegistry, collision, weight); if (!fEMEventCut.IsSelected(collision)) { continue; } - o2::aod::pwgem::photonmeson::utils::eventhistogram::fillEventInfo<1>(&fRegistry, collision, collision.weight()); - fRegistry.fill(HIST("Event/before/hCollisionCounter"), 12.0, collision.weight()); // accepted - fRegistry.fill(HIST("Event/after/hCollisionCounter"), 12.0, collision.weight()); // accepted + o2::aod::pwgem::photonmeson::utils::eventhistogram::fillEventInfo<1>(&fRegistry, collision, weight); + fRegistry.fill(HIST("Event/before/hCollisionCounter"), 12.0, weight); // accepted + fRegistry.fill(HIST("Event/after/hCollisionCounter"), 12.0, weight); // accepted int zbin = lower_bound(zvtx_bin_edges.begin(), zvtx_bin_edges.end(), collision.posZ()) - zvtx_bin_edges.begin() - 1; if (zbin < 0) { @@ -655,10 +662,10 @@ struct Pi0EtaToGammaGamma { } } - fRegistry.fill(HIST("Pair/same/hs"), v12.M(), v12.Pt(), collision.weight()); + fRegistry.fill(HIST("Pair/same/hs"), v12.M(), v12.Pt(), weight); if constexpr (pairtype == PairType::kEMCEMC) { - RotationBackground(v12, v1, v2, photons2_per_collision, g1.globalIndex(), g2.globalIndex(), collision.weight()); + RotationBackground(v12, v1, v2, photons2_per_collision, g1.globalIndex(), g2.globalIndex(), weight); } std::pair pair_tmp_id1 = std::make_pair(ndf, g1.globalIndex()); @@ -712,7 +719,7 @@ struct Pi0EtaToGammaGamma { continue; } - fRegistry.fill(HIST("Pair/same/hs"), veeg.M(), veeg.Pt(), collision.weight()); + fRegistry.fill(HIST("Pair/same/hs"), veeg.M(), veeg.Pt(), weight); std::pair pair_tmp_id1 = std::make_pair(ndf, g1.globalIndex()); std::tuple tuple_tmp_id2 = std::make_tuple(ndf, collision.globalIndex(), pos2.trackId(), ele2.trackId()); @@ -742,7 +749,7 @@ struct Pi0EtaToGammaGamma { continue; } - fRegistry.fill(HIST("Pair/same/hs"), v12.M(), v12.Pt(), collision.weight()); + fRegistry.fill(HIST("Pair/same/hs"), v12.M(), v12.Pt(), weight); std::pair pair_tmp_id1 = std::make_pair(ndf, g1.globalIndex()); std::pair pair_tmp_id2 = std::make_pair(ndf, g2.globalIndex()); @@ -799,7 +806,7 @@ struct Pi0EtaToGammaGamma { continue; } - fRegistry.fill(HIST("Pair/mix/hs"), v12.M(), v12.Pt(), collision.weight()); + fRegistry.fill(HIST("Pair/mix/hs"), v12.M(), v12.Pt(), weight); } } } // end of loop over mixed event pool @@ -834,7 +841,7 @@ struct Pi0EtaToGammaGamma { if (std::fabs(v12.Rapidity()) > maxY) { continue; } - fRegistry.fill(HIST("Pair/mix/hs"), v12.M(), v12.Pt(), collision.weight()); + fRegistry.fill(HIST("Pair/mix/hs"), v12.M(), v12.Pt(), weight); } } } // end of loop over mixed event pool @@ -867,7 +874,7 @@ struct Pi0EtaToGammaGamma { if (std::fabs(v12.Rapidity()) > maxY) { continue; } - fRegistry.fill(HIST("Pair/mix/hs"), v12.M(), v12.Pt(), collision.weight()); + fRegistry.fill(HIST("Pair/mix/hs"), v12.M(), v12.Pt(), weight); } } } // end of loop over mixed event pool @@ -925,9 +932,46 @@ struct Pi0EtaToGammaGamma { // } ndf++; } - PROCESS_SWITCH(Pi0EtaToGammaGamma, processAnalysis, "process pair analysis", false); + PROCESS_SWITCH(Pi0EtaToGammaGamma, processAnalysis, "process pair analysis", true); + + using FilteredMyCollisionsWithJJMC = soa::Filtered; + void processAnalysisJJMC(FilteredMyCollisionsWithJJMC const& collisions, Types const&... args) + { + // LOGF(info, "ndf = %d", ndf); + if constexpr (pairtype == PairType::kPCMPCM) { + auto v0photons = std::get<0>(std::tie(args...)); + auto v0legs = std::get<1>(std::tie(args...)); + runPairing(collisions, v0photons, v0photons, v0legs, v0legs, perCollision_pcm, perCollision_pcm, fV0PhotonCut, fV0PhotonCut); + } else if constexpr (pairtype == PairType::kPCMDalitzEE) { + auto v0photons = std::get<0>(std::tie(args...)); + auto v0legs = std::get<1>(std::tie(args...)); + auto emprimaryelectrons = std::get<2>(std::tie(args...)); + // LOGF(info, "electrons.size() = %d, positrons.size() = %d", electrons.size(), positrons.size()); + runPairing(collisions, v0photons, emprimaryelectrons, v0legs, emprimaryelectrons, perCollision_pcm, perCollision_electron, fV0PhotonCut, fDileptonCut); + } else if constexpr (pairtype == PairType::kEMCEMC) { + auto emcclusters = std::get<0>(std::tie(args...)); + runPairing(collisions, emcclusters, emcclusters, nullptr, nullptr, perCollision_emc, perCollision_emc, fEMCCut, fEMCCut); + } else if constexpr (pairtype == PairType::kPHOSPHOS) { + auto phosclusters = std::get<0>(std::tie(args...)); + runPairing(collisions, phosclusters, phosclusters, nullptr, nullptr, perCollision_phos, perCollision_phos, fPHOSCut, fPHOSCut); + } + // else if constexpr (pairtype == PairType::kPCMEMC) { + // auto v0photons = std::get<0>(std::tie(args...)); + // auto v0legs = std::get<1>(std::tie(args...)); + // auto emcclusters = std::get<2>(std::tie(args...)); + // auto emcmatchedtracks = std::get<3>(std::tie(args...)); + // runPairing(collisions, v0photons, emcclusters, v0legs, nullptr, perCollision_pcm, perCollision_emc, fV0PhotonCut, fEMCCut, emcmatchedtracks, nullptr); + // } else if constexpr (pairtype == PairType::kPCMPHOS) { + // auto v0photons = std::get<0>(std::tie(args...)); + // auto v0legs = std::get<1>(std::tie(args...)); + // auto phosclusters = std::get<2>(std::tie(args...)); + // runPairing(collisions, v0photons, phosclusters, v0legs, nullptr, perCollision_pcm, perCollision_phos, fV0PhotonCut, fPHOSCut, nullptr, nullptr); + // } + ndf++; + } + PROCESS_SWITCH(Pi0EtaToGammaGamma, processAnalysisJJMC, "process pair analysis", false); void processDummy(MyCollisions const&) {} - PROCESS_SWITCH(Pi0EtaToGammaGamma, processDummy, "Dummy function", true); + PROCESS_SWITCH(Pi0EtaToGammaGamma, processDummy, "Dummy function", false); }; #endif // PWGEM_PHOTONMESON_CORE_PI0ETATOGAMMAGAMMA_H_ diff --git a/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGammaMC.h b/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGammaMC.h index bb83f7aa0ea..16cd3054172 100644 --- a/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGammaMC.h +++ b/PWGEM/PhotonMeson/Core/Pi0EtaToGammaGammaMC.h @@ -57,9 +57,12 @@ using namespace o2::aod::pwgem::photonmeson::photonpair; using namespace o2::aod::pwgem::photonmeson::utils::mcutil; using namespace o2::aod::pwgem::dilepton::utils::mcutil; -using MyCollisions = soa::Join; +using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; +using MyCollisionsWithJJMC = soa::Join; +using MyCollisionWithJJMC = MyCollisionsWithJJMC::iterator; + using MyMCCollisions = soa::Join; using MyMCCollision = MyMCCollisions::iterator; @@ -88,7 +91,7 @@ struct Pi0EtaToGammaGammaMC { Configurable cfgQvecEstimator{"cfgQvecEstimator", 0, "FT0M:0, FT0A:1, FT0C:2"}; Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; - Configurable cfgCentMin{"cfgCentMin", 0, "min. centrality"}; + Configurable cfgCentMin{"cfgCentMin", -1, "min. centrality"}; Configurable cfgCentMax{"cfgCentMax", 999, "max. centrality"}; Configurable maxY_rec{"maxY_rec", 0.9, "maximum rapidity for reconstructed particles"}; Configurable fd_k0s_to_pi0{"fd_k0s_pi0", "1.0", "feed down correction to pi0"}; @@ -97,10 +100,11 @@ struct Pi0EtaToGammaGammaMC { EMPhotonEventCut fEMEventCut; struct : ConfigurableGroup { std::string prefix = "eventcut_group"; - Configurable cfgZvtxMax{"cfgZvtxMax", 10.f, "max. Zvtx"}; - Configurable cfgRequireSel8{"cfgRequireSel8", true, "require sel8 in event cut"}; + Configurable cfgZvtxMin{"cfgZvtxMin", -10.f, "min. Zvtx"}; + Configurable cfgZvtxMax{"cfgZvtxMax", +10.f, "max. Zvtx"}; + Configurable cfgRequireSel8{"cfgRequireSel8", false, "require sel8 in event cut"}; Configurable cfgRequireFT0AND{"cfgRequireFT0AND", true, "require FT0AND in event cut"}; - Configurable cfgRequireNoTFB{"cfgRequireNoTFB", false, "require No time frame border in event cut"}; + Configurable cfgRequireNoTFB{"cfgRequireNoTFB", true, "require No time frame border in event cut"}; Configurable cfgRequireNoITSROFB{"cfgRequireNoITSROFB", false, "require no ITS readout frame border in event cut"}; Configurable cfgRequireNoSameBunchPileup{"cfgRequireNoSameBunchPileup", false, "require no same bunch pileup in event cut"}; Configurable cfgRequireVertexITSTPC{"cfgRequireVertexITSTPC", false, "require Vertex ITSTPC in event cut"}; // ITS-TPC matched track contributes PV. @@ -128,17 +132,16 @@ struct Pi0EtaToGammaGammaMC { Configurable cfg_max_v0radius{"cfg_max_v0radius", 90.0, "max v0 radius"}; Configurable cfg_max_alpha_ap{"cfg_max_alpha_ap", 0.95, "max alpha for AP cut"}; Configurable cfg_max_qt_ap{"cfg_max_qt_ap", 0.01, "max qT for AP cut"}; - Configurable cfg_min_cospa{"cfg_min_cospa", 0.997, "min V0 CosPA"}; - Configurable cfg_max_pca{"cfg_max_pca", 3.0, "max distance btween 2 legs"}; + Configurable cfg_min_cospa{"cfg_min_cospa", 0.999, "min V0 CosPA"}; + Configurable cfg_max_pca{"cfg_max_pca", 1.5, "max distance btween 2 legs"}; Configurable cfg_max_chi2kf{"cfg_max_chi2kf", 1e+10, "max chi2/ndf with KF"}; - Configurable cfg_require_v0_with_correct_xz{"cfg_require_v0_with_correct_xz", true, "flag to select V0s with correct xz"}; Configurable cfg_reject_v0_on_itsib{"cfg_reject_v0_on_itsib", true, "flag to reject V0s on ITSib"}; Configurable cfg_apply_cuts_from_prefilter_derived{"cfg_apply_cuts_from_prefilter_derived", false, "flag to apply prefilter to V0"}; - Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 10, "min ncluster tpc"}; + Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; Configurable cfg_min_ncrossedrows{"cfg_min_ncrossedrows", 40, "min ncrossed rows"}; Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; - Configurable cfg_max_chi2its{"cfg_max_chi2its", 5.0, "max chi2/NclsITS"}; + Configurable cfg_max_chi2its{"cfg_max_chi2its", 36.0, "max chi2/NclsITS"}; Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -3.0, "min. TPC n sigma for electron"}; Configurable cfg_max_TPCNsigmaEl{"cfg_max_TPCNsigmaEl", +3.0, "max. TPC n sigma for electron"}; @@ -164,7 +167,7 @@ struct Pi0EtaToGammaGammaMC { Configurable cfg_min_ncrossedrows{"cfg_min_ncrossedrows", 70, "min ncrossed rows"}; Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; - Configurable cfg_max_chi2its{"cfg_max_chi2its", 5.0, "max chi2/NclsITS"}; + Configurable cfg_max_chi2its{"cfg_max_chi2its", 36.0, "max chi2/NclsITS"}; Configurable cfg_max_dcaxy{"cfg_max_dcaxy", 0.05, "max dca XY for single track in cm"}; Configurable cfg_max_dcaz{"cfg_max_dcaz", 0.05, "max dca Z for single track in cm"}; Configurable cfg_max_dca3dsigma_track{"cfg_max_dca3dsigma_track", 1.5, "max DCA 3D in sigma"}; @@ -296,7 +299,7 @@ struct Pi0EtaToGammaGammaMC { fEMEventCut = EMPhotonEventCut("fEMEventCut", "fEMEventCut"); fEMEventCut.SetRequireSel8(eventcuts.cfgRequireSel8); fEMEventCut.SetRequireFT0AND(eventcuts.cfgRequireFT0AND); - fEMEventCut.SetZvtxRange(-eventcuts.cfgZvtxMax, +eventcuts.cfgZvtxMax); + fEMEventCut.SetZvtxRange(eventcuts.cfgZvtxMin, eventcuts.cfgZvtxMax); fEMEventCut.SetRequireNoTFB(eventcuts.cfgRequireNoTFB); fEMEventCut.SetRequireNoITSROFB(eventcuts.cfgRequireNoITSROFB); fEMEventCut.SetRequireNoSameBunchPileup(eventcuts.cfgRequireNoSameBunchPileup); @@ -330,7 +333,6 @@ struct Pi0EtaToGammaGammaMC { fV0PhotonCut.SetChi2PerClusterITS(-1e+10, pcmcuts.cfg_max_chi2its); fV0PhotonCut.SetNClustersITS(0, 7); fV0PhotonCut.SetMeanClusterSizeITSob(0.0, 16.0); - fV0PhotonCut.SetIsWithinBeamPipe(pcmcuts.cfg_require_v0_with_correct_xz); fV0PhotonCut.SetDisableITSonly(pcmcuts.cfg_disable_itsonly_track); fV0PhotonCut.SetDisableTPConly(pcmcuts.cfg_disable_tpconly_track); fV0PhotonCut.SetRequireITSTPC(pcmcuts.cfg_require_v0_with_itstpc); @@ -408,8 +410,8 @@ struct Pi0EtaToGammaGammaMC { Preslice perCollision_phos = aod::phoscluster::emeventId; Preslice perCollision_electron = aod::emprimaryelectron::emeventId; - Partition positrons = o2::aod::emprimaryelectron::sign > int8_t(0) && static_cast(dileptoncuts.cfg_min_pt_track) < o2::aod::track::pt&& nabs(o2::aod::track::eta) < static_cast(dileptoncuts.cfg_max_eta_track) && static_cast(dileptoncuts.cfg_min_TPCNsigmaEl) < o2::aod::pidtpc::tpcNSigmaEl&& o2::aod::pidtpc::tpcNSigmaEl < static_cast(dileptoncuts.cfg_max_TPCNsigmaEl); - Partition electrons = o2::aod::emprimaryelectron::sign < int8_t(0) && static_cast(dileptoncuts.cfg_min_pt_track) < o2::aod::track::pt && nabs(o2::aod::track::eta) < static_cast(dileptoncuts.cfg_max_eta_track) && static_cast(dileptoncuts.cfg_min_TPCNsigmaEl) < o2::aod::pidtpc::tpcNSigmaEl && o2::aod::pidtpc::tpcNSigmaEl < static_cast(dileptoncuts.cfg_max_TPCNsigmaEl); + Partition positrons = o2::aod::emprimaryelectron::sign > int8_t(0) && dileptoncuts.cfg_min_pt_track < o2::aod::track::pt&& nabs(o2::aod::track::eta) < dileptoncuts.cfg_max_eta_track; + Partition electrons = o2::aod::emprimaryelectron::sign < int8_t(0) && dileptoncuts.cfg_min_pt_track < o2::aod::track::pt && nabs(o2::aod::track::eta) < dileptoncuts.cfg_max_eta_track; template void runTruePairing(TCollisions const& collisions, @@ -426,7 +428,12 @@ struct Pi0EtaToGammaGammaMC { continue; } - if (eventcuts.onlyKeepWeightedEvents && std::fabs(collision.weight() - 1.) < 1E-10) { + float weight = 1.f; + if constexpr (std::is_same_v, FilteredMyCollisionsWithJJMC>) { + weight = collision.weight(); + } + + if (eventcuts.onlyKeepWeightedEvents && std::fabs(weight - 1.0) < 1e-10) { continue; } @@ -435,13 +442,13 @@ struct Pi0EtaToGammaGammaMC { continue; } - o2::aod::pwgem::photonmeson::utils::eventhistogram::fillEventInfo<0>(&fRegistry, collision, collision.weight()); + o2::aod::pwgem::photonmeson::utils::eventhistogram::fillEventInfo<0>(&fRegistry, collision, weight); if (!fEMEventCut.IsSelected(collision)) { continue; } - o2::aod::pwgem::photonmeson::utils::eventhistogram::fillEventInfo<1>(&fRegistry, collision, collision.weight()); - fRegistry.fill(HIST("Event/before/hCollisionCounter"), 12.0, collision.weight()); // accepted - fRegistry.fill(HIST("Event/after/hCollisionCounter"), 12.0, collision.weight()); // accepted + o2::aod::pwgem::photonmeson::utils::eventhistogram::fillEventInfo<1>(&fRegistry, collision, weight); + fRegistry.fill(HIST("Event/before/hCollisionCounter"), 12.0, weight); // accepted + fRegistry.fill(HIST("Event/after/hCollisionCounter"), 12.0, weight); // accepted int photonid1 = -1, photonid2 = -1, pi0id = -1, etaid = -1; if constexpr (pairtype == PairType::kPCMPCM || pairtype == PairType::kPHOSPHOS || pairtype == PairType::kEMCEMC) { // same kinds pairing @@ -512,9 +519,9 @@ struct Pi0EtaToGammaGammaMC { if (g1mc.globalIndex() == g2mc.globalIndex()) { if (getMotherPDGCode(g1mc, mcparticles) == 111) - fRegistry.fill(HIST("Pair/Pi0/hs_FromSameGamma"), v12.M(), v12.Pt(), collision.weight()); + fRegistry.fill(HIST("Pair/Pi0/hs_FromSameGamma"), v12.M(), v12.Pt(), weight); else if (getMotherPDGCode(g1mc, mcparticles) == 221) - fRegistry.fill(HIST("Pair/Eta/hs_FromSameGamma"), v12.M(), v12.Pt(), collision.weight()); + fRegistry.fill(HIST("Pair/Eta/hs_FromSameGamma"), v12.M(), v12.Pt(), weight); continue; } @@ -523,13 +530,13 @@ struct Pi0EtaToGammaGammaMC { if (cfgRequireTrueAssociation && (pi0mc.emmceventId() != collision.emmceventId())) { continue; } - o2::aod::pwgem::photonmeson::utils::nmhistogram::fillTruePairInfo(&fRegistry, v12, pi0mc, mcparticles, mccollisions, f1fd_k0s_to_pi0, collision.weight()); + o2::aod::pwgem::photonmeson::utils::nmhistogram::fillTruePairInfo(&fRegistry, v12, pi0mc, mcparticles, mccollisions, f1fd_k0s_to_pi0, weight); } else if (etaid > 0) { auto etamc = mcparticles.iteratorAt(etaid); if (cfgRequireTrueAssociation && (etamc.emmceventId() != collision.emmceventId())) { continue; } - o2::aod::pwgem::photonmeson::utils::nmhistogram::fillTruePairInfo(&fRegistry, v12, etamc, mcparticles, mccollisions, f1fd_k0s_to_pi0, collision.weight()); + o2::aod::pwgem::photonmeson::utils::nmhistogram::fillTruePairInfo(&fRegistry, v12, etamc, mcparticles, mccollisions, f1fd_k0s_to_pi0, weight); } } // end of pairing loop } else if constexpr (pairtype == PairType::kPCMDalitzEE) { @@ -589,13 +596,13 @@ struct Pi0EtaToGammaGammaMC { if (cfgRequireTrueAssociation && (pi0mc.emmceventId() != collision.emmceventId())) { continue; } - o2::aod::pwgem::photonmeson::utils::nmhistogram::fillTruePairInfo(&fRegistry, veeg, pi0mc, mcparticles, mccollisions, f1fd_k0s_to_pi0, collision.weight()); + o2::aod::pwgem::photonmeson::utils::nmhistogram::fillTruePairInfo(&fRegistry, veeg, pi0mc, mcparticles, mccollisions, f1fd_k0s_to_pi0, weight); } else if (etaid > 0) { auto etamc = mcparticles.iteratorAt(etaid); if (cfgRequireTrueAssociation && (etamc.emmceventId() != collision.emmceventId())) { continue; } - o2::aod::pwgem::photonmeson::utils::nmhistogram::fillTruePairInfo(&fRegistry, veeg, etamc, mcparticles, mccollisions, f1fd_k0s_to_pi0, collision.weight()); + o2::aod::pwgem::photonmeson::utils::nmhistogram::fillTruePairInfo(&fRegistry, veeg, etamc, mcparticles, mccollisions, f1fd_k0s_to_pi0, weight); } } // end of dielectron loop } // end of pcm loop @@ -615,10 +622,10 @@ struct Pi0EtaToGammaGammaMC { } // if (pi0id > 0) { // auto pi0mc = mcparticles.iteratorAt(pi0id); - // o2::aod::pwgem::photonmeson::utils::nmhistogram::fillTruePairInfo(&fRegistry, v12, pi0mc, mcparticles, mccollisions, f1fd_k0s_to_pi0, collision.weight()); + // o2::aod::pwgem::photonmeson::utils::nmhistogram::fillTruePairInfo(&fRegistry, v12, pi0mc, mcparticles, mccollisions, f1fd_k0s_to_pi0, weight); // } else if (etaid > 0) { // auto etamc = mcparticles.iteratorAt(etaid); - // o2::aod::pwgem::photonmeson::utils::nmhistogram::fillTruePairInfo(&fRegistry, v12, etamc, mcparticles, mccollisions, f1fd_k0s_to_pi0, collision.weight()); + // o2::aod::pwgem::photonmeson::utils::nmhistogram::fillTruePairInfo(&fRegistry, v12, etamc, mcparticles, mccollisions, f1fd_k0s_to_pi0, weight); // } } // end of pairing loop } // end of pairing in same event @@ -668,7 +675,12 @@ struct Pi0EtaToGammaGammaMC { continue; // I don't know why this is necessary in simulation. } - if (eventcuts.onlyKeepWeightedEvents && std::fabs(collision.weight() - 1.) < 1E-10) { + float weight = 1.f; + if constexpr (std::is_same_v, FilteredMyCollisionsWithJJMC>) { + weight = collision.weight(); + } + + if (eventcuts.onlyKeepWeightedEvents && std::fabs(weight - 1.0) < 1e-10) { continue; } @@ -684,8 +696,8 @@ struct Pi0EtaToGammaGammaMC { auto mccollision = collision.template emmcevent_as(); auto binned_data_pi0_gen = mccollision.generatedPi0(); auto binned_data_eta_gen = mccollision.generatedEta(); - fillBinnedData<0>(binned_data_pi0_gen, collision.weight()); - fillBinnedData<1>(binned_data_eta_gen, collision.weight()); + fillBinnedData<0>(binned_data_pi0_gen, weight); + fillBinnedData<1>(binned_data_eta_gen, weight); } // end of collision loop } @@ -734,9 +746,49 @@ struct Pi0EtaToGammaGammaMC { // runPairing(collisions, v0photons, phosclusters, v0legs, nullptr, perCollision_pcm, perCollision_phos, fV0PhotonCut, fPHOSCut, nullptr, nullptr); // } } - PROCESS_SWITCH(Pi0EtaToGammaGammaMC, processAnalysis, "process pair analysis", false); + PROCESS_SWITCH(Pi0EtaToGammaGammaMC, processAnalysis, "process pair analysis", true); + + using FilteredMyCollisionsWithJJMC = soa::Filtered; + void processAnalysisJJMC(FilteredMyCollisionsWithJJMC const& collisions, MyMCCollisions const& mccollisions, aod::EMMCParticles const& mcparticles, Types const&... args) + { + if constexpr (pairtype == PairType::kPCMPCM) { + auto v0photons = std::get<0>(std::tie(args...)); + auto v0legs = std::get<1>(std::tie(args...)); + runTruePairing(collisions, v0photons, v0photons, v0legs, v0legs, perCollision_pcm, perCollision_pcm, fV0PhotonCut, fV0PhotonCut, mccollisions, mcparticles); + runGenInfo(collisions, mccollisions, mcparticles); + } else if constexpr (pairtype == PairType::kPCMDalitzEE) { + auto v0photons = std::get<0>(std::tie(args...)); + auto v0legs = std::get<1>(std::tie(args...)); + auto emprimaryelectrons = std::get<2>(std::tie(args...)); + // LOGF(info, "electrons.size() = %d, positrons.size() = %d", electrons.size(), positrons.size()); + runTruePairing(collisions, v0photons, emprimaryelectrons, v0legs, emprimaryelectrons, perCollision_pcm, perCollision_electron, fV0PhotonCut, fDileptonCut, mccollisions, mcparticles); + runGenInfo(collisions, mccollisions, mcparticles); + } else if constexpr (pairtype == PairType::kEMCEMC) { + auto emcclusters = std::get<0>(std::tie(args...)); + runTruePairing(collisions, emcclusters, emcclusters, nullptr, nullptr, perCollision_emc, perCollision_emc, fEMCCut, fEMCCut, mccollisions, mcparticles); + runGenInfo(collisions, mccollisions, mcparticles); + } + + // else if constexpr (pairtype == PairType::kPHOSPHOS) { + // auto phosclusters = std::get<0>(std::tie(args...)); + // runPairing(collisions, phosclusters, phosclusters, nullptr, nullptr, perCollision_phos, perCollision_phos, fPHOSCut, fPHOSCut, nullptr, nullptr); + // } + // else if constexpr (pairtype == PairType::kPCMEMC) { + // auto v0photons = std::get<0>(std::tie(args...)); + // auto v0legs = std::get<1>(std::tie(args...)); + // auto emcclusters = std::get<2>(std::tie(args...)); + // auto emcmatchedtracks = std::get<3>(std::tie(args...)); + // runPairing(collisions, v0photons, emcclusters, v0legs, nullptr, perCollision_pcm, perCollision_emc, fV0PhotonCut, fEMCCut, emcmatchedtracks, nullptr); + // } else if constexpr (pairtype == PairType::kPCMPHOS) { + // auto v0photons = std::get<0>(std::tie(args...)); + // auto v0legs = std::get<1>(std::tie(args...)); + // auto phosclusters = std::get<2>(std::tie(args...)); + // runPairing(collisions, v0photons, phosclusters, v0legs, nullptr, perCollision_pcm, perCollision_phos, fV0PhotonCut, fPHOSCut, nullptr, nullptr); + // } + } + PROCESS_SWITCH(Pi0EtaToGammaGammaMC, processAnalysisJJMC, "process pair analysis", false); void processDummy(MyCollisions const&) {} - PROCESS_SWITCH(Pi0EtaToGammaGammaMC, processDummy, "Dummy function", true); + PROCESS_SWITCH(Pi0EtaToGammaGammaMC, processDummy, "Dummy function", false); }; #endif // PWGEM_PHOTONMESON_CORE_PI0ETATOGAMMAGAMMAMC_H_ diff --git a/PWGEM/PhotonMeson/Core/TaggingPi0.h b/PWGEM/PhotonMeson/Core/TaggingPi0.h index d74af2ceb0c..5f37d60d277 100644 --- a/PWGEM/PhotonMeson/Core/TaggingPi0.h +++ b/PWGEM/PhotonMeson/Core/TaggingPi0.h @@ -138,7 +138,6 @@ struct TaggingPi0 { Configurable cfg_min_cospa{"cfg_min_cospa", 0.997, "min V0 CosPA"}; Configurable cfg_max_pca{"cfg_max_pca", 3.0, "max distance btween 2 legs"}; Configurable cfg_max_chi2kf{"cfg_max_chi2kf", 1e+10, "max chi2/ndf with KF"}; - Configurable cfg_require_v0_with_correct_xz{"cfg_require_v0_with_correct_xz", true, "flag to select V0s with correct xz"}; Configurable cfg_reject_v0_on_itsib{"cfg_reject_v0_on_itsib", true, "flag to reject V0s on ITSib"}; Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 10, "min ncluster tpc"}; @@ -369,7 +368,6 @@ struct TaggingPi0 { fV0PhotonCut.SetChi2PerClusterITS(-1e+10, pcmcuts.cfg_max_chi2its); fV0PhotonCut.SetNClustersITS(0, 7); fV0PhotonCut.SetMeanClusterSizeITSob(0.0, 16.0); - fV0PhotonCut.SetIsWithinBeamPipe(pcmcuts.cfg_require_v0_with_correct_xz); fV0PhotonCut.SetDisableITSonly(pcmcuts.cfg_disable_itsonly_track); fV0PhotonCut.SetDisableTPConly(pcmcuts.cfg_disable_tpconly_track); fV0PhotonCut.SetRequireITSTPC(pcmcuts.cfg_require_v0_with_itstpc); diff --git a/PWGEM/PhotonMeson/Core/TaggingPi0MC.h b/PWGEM/PhotonMeson/Core/TaggingPi0MC.h index 56c6274a141..faf777d0185 100644 --- a/PWGEM/PhotonMeson/Core/TaggingPi0MC.h +++ b/PWGEM/PhotonMeson/Core/TaggingPi0MC.h @@ -56,7 +56,7 @@ using namespace o2::aod::pwgem::photonmeson::photonpair; using namespace o2::aod::pwgem::photonmeson::utils::mcutil; using namespace o2::aod::pwgem::dilepton::utils::mcutil; -using MyCollisions = soa::Join; +using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; using MyMCCollisions = soa::Join; @@ -87,7 +87,7 @@ struct TaggingPi0MC { Configurable cfgQvecEstimator{"cfgQvecEstimator", 0, "FT0M:0, FT0A:1, FT0C:2"}; Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; - Configurable cfgCentMin{"cfgCentMin", 0, "min. centrality"}; + Configurable cfgCentMin{"cfgCentMin", -1, "min. centrality"}; Configurable cfgCentMax{"cfgCentMax", 999, "max. centrality"}; Configurable fd_k0s_to_pi0{"fd_k0s_pi0", "1.0", "feed down correction to pi0"}; Configurable cfgRequireTrueAssociation{"cfgRequireTrueAssociation", false, "flag to require true mc collision association"}; @@ -96,6 +96,7 @@ struct TaggingPi0MC { EMPhotonEventCut fEMEventCut; struct : ConfigurableGroup { std::string prefix = "eventcut_group"; + Configurable cfgZvtxMin{"cfgZvtxMin", -10.f, "min. Zvtx"}; Configurable cfgZvtxMax{"cfgZvtxMax", 10.f, "max. Zvtx"}; Configurable cfgRequireSel8{"cfgRequireSel8", true, "require sel8 in event cut"}; Configurable cfgRequireFT0AND{"cfgRequireFT0AND", true, "require FT0AND in event cut"}; @@ -130,7 +131,6 @@ struct TaggingPi0MC { Configurable cfg_min_cospa{"cfg_min_cospa", 0.997, "min V0 CosPA"}; Configurable cfg_max_pca{"cfg_max_pca", 3.0, "max distance btween 2 legs"}; Configurable cfg_max_chi2kf{"cfg_max_chi2kf", 1e+10, "max chi2/ndf with KF"}; - Configurable cfg_require_v0_with_correct_xz{"cfg_require_v0_with_correct_xz", true, "flag to select V0s with correct xz"}; Configurable cfg_reject_v0_on_itsib{"cfg_reject_v0_on_itsib", true, "flag to reject V0s on ITSib"}; Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 10, "min ncluster tpc"}; @@ -305,7 +305,7 @@ struct TaggingPi0MC { fEMEventCut = EMPhotonEventCut("fEMEventCut", "fEMEventCut"); fEMEventCut.SetRequireSel8(eventcuts.cfgRequireSel8); fEMEventCut.SetRequireFT0AND(eventcuts.cfgRequireFT0AND); - fEMEventCut.SetZvtxRange(-eventcuts.cfgZvtxMax, +eventcuts.cfgZvtxMax); + fEMEventCut.SetZvtxRange(eventcuts.cfgZvtxMin, eventcuts.cfgZvtxMax); fEMEventCut.SetRequireNoTFB(eventcuts.cfgRequireNoTFB); fEMEventCut.SetRequireNoITSROFB(eventcuts.cfgRequireNoITSROFB); fEMEventCut.SetRequireNoSameBunchPileup(eventcuts.cfgRequireNoSameBunchPileup); @@ -339,7 +339,6 @@ struct TaggingPi0MC { fV0PhotonCut.SetChi2PerClusterITS(-1e+10, pcmcuts.cfg_max_chi2its); fV0PhotonCut.SetNClustersITS(0, 7); fV0PhotonCut.SetMeanClusterSizeITSob(0.0, 16.0); - fV0PhotonCut.SetIsWithinBeamPipe(pcmcuts.cfg_require_v0_with_correct_xz); fV0PhotonCut.SetDisableITSonly(pcmcuts.cfg_disable_itsonly_track); fV0PhotonCut.SetDisableTPConly(pcmcuts.cfg_disable_tpconly_track); fV0PhotonCut.SetRequireITSTPC(pcmcuts.cfg_require_v0_with_itstpc); diff --git a/PWGEM/PhotonMeson/Core/V0PhotonCut.cxx b/PWGEM/PhotonMeson/Core/V0PhotonCut.cxx index 07d805fa291..4c149b7fd20 100644 --- a/PWGEM/PhotonMeson/Core/V0PhotonCut.cxx +++ b/PWGEM/PhotonMeson/Core/V0PhotonCut.cxx @@ -193,12 +193,6 @@ void V0PhotonCut::SetMeanClusterSizeITSob(float min, float max) LOG(info) << "V0 Photon Cut, set mean cluster size ITS range: " << mMinMeanClusterSizeITS << " - " << mMaxMeanClusterSizeITS; } -void V0PhotonCut::SetIsWithinBeamPipe(bool flag) -{ - mIsWithinBP = flag; - LOG(info) << "V0 Photon Cut, propagated to within beam pipe: " << mIsWithinBP; -} - void V0PhotonCut::SetRequireITSTPC(bool flag) { mRequireITSTPC = flag; diff --git a/PWGEM/PhotonMeson/Core/V0PhotonCut.h b/PWGEM/PhotonMeson/Core/V0PhotonCut.h index d6064ab8786..dcd9cd2c5ce 100644 --- a/PWGEM/PhotonMeson/Core/V0PhotonCut.h +++ b/PWGEM/PhotonMeson/Core/V0PhotonCut.h @@ -16,16 +16,18 @@ #ifndef PWGEM_PHOTONMESON_CORE_V0PHOTONCUT_H_ #define PWGEM_PHOTONMESON_CORE_V0PHOTONCUT_H_ -#include -#include -#include -#include -#include #include "Rtypes.h" -#include "TNamed.h" -#include "TMath.h" #include "PWGEM/PhotonMeson/Utils/TrackSelection.h" + +#include "TMath.h" +#include "TNamed.h" + +#include +#include +#include +#include +#include using namespace o2::pwgem::photonmeson; class V0PhotonCut : public TNamed @@ -64,7 +66,6 @@ class V0PhotonCut : public TNamed kITSNCls, kITSChi2NDF, kITSClusterSize, - kIsWithinBeamPipe, kRequireITSTPC, kRequireITSonly, kRequireTPConly, @@ -140,9 +141,6 @@ class V0PhotonCut : public TNamed if (!IsSelectedTrack(track, V0PhotonCuts::kDCAz)) { return false; } - if (mIsWithinBP && !IsSelectedTrack(track, V0PhotonCuts::kIsWithinBeamPipe)) { - return false; - } if (!track.hasITS() && !track.hasTPC()) { // track has to be ITSonly or TPConly or ITS-TPC return false; } @@ -269,11 +267,6 @@ class V0PhotonCut : public TNamed if (v0.v0radius() < mMinRxy || mMaxRxy < v0.v0radius()) { return false; } - if (mRejectITSib) { - if (v0.v0radius() < 4.f || v0.pca() < -0.05 * v0.v0radius() + 0.3) { - return false; - } - } return true; } @@ -343,10 +336,10 @@ class V0PhotonCut : public TNamed { switch (cut) { case V0PhotonCuts::kTrackPtRange: - return track.pt() >= mMinTrackPt && track.pt() <= mMaxTrackPt; + return track.pt() > mMinTrackPt && track.pt() < mMaxTrackPt; case V0PhotonCuts::kTrackEtaRange: - return track.eta() >= mMinTrackEta && track.eta() <= mMaxTrackEta; + return track.eta() > mMinTrackEta && track.eta() < mMaxTrackEta; case V0PhotonCuts::kTPCNCls: return track.tpcNClsFound() >= mMinNClustersTPC; @@ -358,22 +351,22 @@ class V0PhotonCut : public TNamed return track.tpcCrossedRowsOverFindableCls() >= mMinNCrossedRowsOverFindableClustersTPC; case V0PhotonCuts::kTPCFracSharedClusters: - return track.tpcFractionSharedCls() <= mMaxFracSharedClustersTPC; + return track.tpcFractionSharedCls() < mMaxFracSharedClustersTPC; case V0PhotonCuts::kTPCChi2NDF: return mMinChi2PerClusterTPC < track.tpcChi2NCl() && track.tpcChi2NCl() < mMaxChi2PerClusterTPC; case V0PhotonCuts::kTPCNsigmaEl: - return track.tpcNSigmaEl() >= mMinTPCNsigmaEl && track.tpcNSigmaEl() <= mMaxTPCNsigmaEl; + return track.tpcNSigmaEl() > mMinTPCNsigmaEl && track.tpcNSigmaEl() < mMaxTPCNsigmaEl; case V0PhotonCuts::kTPCNsigmaPi: - return track.tpcNSigmaPi() >= mMinTPCNsigmaPi && track.tpcNSigmaPi() <= mMaxTPCNsigmaPi; + return track.tpcNSigmaPi() > mMinTPCNsigmaPi && track.tpcNSigmaPi() < mMaxTPCNsigmaPi; case V0PhotonCuts::kDCAxy: - return std::fabs(track.dcaXY()) <= ((mMaxDcaXYPtDep) ? mMaxDcaXYPtDep(track.pt()) : mMaxDcaXY); + return std::fabs(track.dcaXY()) < ((mMaxDcaXYPtDep) ? mMaxDcaXYPtDep(track.pt()) : mMaxDcaXY); case V0PhotonCuts::kDCAz: - return std::fabs(track.dcaZ()) <= mMaxDcaZ; + return std::fabs(track.dcaZ()) < mMaxDcaZ; case V0PhotonCuts::kITSNCls: return mMinNClustersITS <= track.itsNCls() && track.itsNCls() <= mMaxNClustersITS; @@ -388,28 +381,6 @@ class V0PhotonCut : public TNamed return mMinMeanClusterSizeITS < track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl())) && track.meanClusterSizeITSob() * std::cos(std::atan(track.tgl())) < mMaxMeanClusterSizeITS; } - case V0PhotonCuts::kIsWithinBeamPipe: { - if (!isTPConlyTrack(track)) { // TPC-TRD, TPC-TOF, TPC-TRD-TOF are constrained. - return true; - } - - // if (abs(track.y()) > abs(track.x() * TMath::Tan(10.f * TMath::DegToRad())) + 15.f) { - // return false; - // } - if (track.x() < 0.1 && std::fabs(track.y()) > 15.f) { - return false; - } - if (track.x() > 82.9 && std::fabs(track.y()) > std::fabs(track.x() * std::tan(10.f * TMath::DegToRad())) + 5.f) { - return false; - } - if (track.x() > 82.9 && std::fabs(track.y()) < 15.0 && abs(abs(track.z()) - 44.5) < 2.5) { - return false; - } - return true; - // const float slope = TMath::Tan(2 * TMath::ATan(TMath::Exp(-0.5))); - // return !(track.x() > 82.9 && abs(track.y()) < 15.f && abs(abs(track.z()) - track.x() / slope) < 3.f && 15.f < abs(track.dcaXY())); - //// return !(track.x() > 82.9 && abs(track.y()) < 40.f && abs(abs(track.z()) - 47.f) < 3.f && 15.f < abs(track.dcaXY())); - } case V0PhotonCuts::kRequireITSTPC: return isITSTPCTrack(track); @@ -515,7 +486,6 @@ class V0PhotonCut : public TNamed float mMaxDcaXY{1e10f}; // max dca in xy plane float mMaxDcaZ{1e10f}; // max dca in z direction std::function mMaxDcaXYPtDep{}; // max dca in xy plane as function of pT - bool mIsWithinBP{false}; bool mRequireITSTPC{false}; bool mRequireITSonly{false}; bool mRequireTPConly{false}; diff --git a/PWGEM/PhotonMeson/DataModel/gammaTables.h b/PWGEM/PhotonMeson/DataModel/gammaTables.h index 0abbc3bfe76..a6b7017f550 100644 --- a/PWGEM/PhotonMeson/DataModel/gammaTables.h +++ b/PWGEM/PhotonMeson/DataModel/gammaTables.h @@ -9,15 +9,21 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -#include -#include +#include "PWGEM/Dilepton/DataModel/dileptonTables.h" #include "Common/Core/RecoDecay.h" #include "Common/DataModel/CaloClusters.h" +#include "Common/DataModel/PIDResponseTOF.h" +#include "Common/DataModel/PIDResponseTPC.h" +#include "Common/DataModel/TrackSelectionTables.h" -#include "PWGEM/Dilepton/DataModel/dileptonTables.h" +#include +#include -#include "PWGJE/DataModel/EMCALClusters.h" +#include +#include +#include +#include #ifndef PWGEM_PHOTONMESON_DATAMODEL_GAMMATABLES_H_ #define PWGEM_PHOTONMESON_DATAMODEL_GAMMATABLES_H_ @@ -117,10 +123,12 @@ DECLARE_SOA_COLUMN(IsMoved, isMoved, bool); //! moved by drift manager. r DECLARE_SOA_COLUMN(Px, px, float); //! Px at SV DECLARE_SOA_COLUMN(Py, py, float); //! Py at SV DECLARE_SOA_COLUMN(Pz, pz, float); //! Pz at SV + DECLARE_SOA_DYNAMIC_COLUMN(P, p, [](float px, float py, float pz) -> float { return RecoDecay::sqrtSumOfSquares(px, py, pz); }); DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, [](float px, float py) -> float { return RecoDecay::sqrtSumOfSquares(px, py); }); DECLARE_SOA_DYNAMIC_COLUMN(Eta, eta, [](float px, float py, float pz) -> float { return RecoDecay::eta(std::array{px, py, pz}); }); DECLARE_SOA_DYNAMIC_COLUMN(Phi, phi, [](float px, float py) -> float { return RecoDecay::phi(px, py); }); +DECLARE_SOA_DYNAMIC_COLUMN(Tgl, tgl, [](float px, float py, float pz) -> float { return std::tan(M_PI_2 - 2 * std::atan(std::exp(-RecoDecay::eta(std::array{px, py, pz})))); }); DECLARE_SOA_DYNAMIC_COLUMN(MeanClusterSizeITS, meanClusterSizeITS, [](uint32_t itsClusterSizes) -> float { int total_cluster_size = 0, nl = 0; for (unsigned int layer = 0; layer < 7; layer++) { @@ -167,7 +175,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(MeanClusterSizeITSob, meanClusterSizeITSob, [](uint32 } }); } // namespace v0leg -DECLARE_SOA_TABLE(V0Legs, "AOD", "V0LEG", //! +DECLARE_SOA_TABLE(V0Legs_000, "AOD", "V0LEG", //! o2::soa::Index<>, v0leg::CollisionId, v0leg::TrackId, v0leg::Sign, v0leg::Px, v0leg::Py, v0leg::Pz, track::DcaXY, track::DcaZ, @@ -188,15 +196,52 @@ DECLARE_SOA_TABLE(V0Legs, "AOD", "V0LEG", //! track::TPCFoundOverFindableCls, track::TPCFractionSharedCls, track::v001::ITSClusterMap, track::v001::ITSNCls, track::v001::ITSNClsInnerBarrel, - track::HasITS, track::HasTPC, - track::HasTRD, track::HasTOF, + track::HasITS, track::HasTPC, track::HasTRD, track::HasTOF, v0leg::MeanClusterSizeITS, v0leg::MeanClusterSizeITSib, v0leg::MeanClusterSizeITSob); +DECLARE_SOA_TABLE_VERSIONED(V0Legs_001, "AOD", "V0LEG", 1, //! + o2::soa::Index<>, v0leg::CollisionId, v0leg::TrackId, v0leg::Sign, + v0leg::Px, v0leg::Py, v0leg::Pz, + track::DcaXY, track::DcaZ, + track::TPCNClsFindable, track::TPCNClsFindableMinusFound, track::TPCNClsFindableMinusCrossedRows, track::TPCNClsShared, + track::TPCChi2NCl, track::TPCInnerParam, + track::TPCSignal, pidtpc::TPCNSigmaEl, pidtpc::TPCNSigmaPi, + track::ITSClusterSizes, track::ITSChi2NCl, track::DetectorMap, + + // dynamic column + v0leg::P, + v0leg::Pt, + v0leg::Eta, + v0leg::Phi, + v0leg::Tgl, + + track::TPCNClsFound, + track::TPCNClsCrossedRows, + track::TPCCrossedRowsOverFindableCls, + track::TPCFoundOverFindableCls, + track::TPCFractionSharedCls, + track::v001::ITSClusterMap, track::v001::ITSNCls, track::v001::ITSNClsInnerBarrel, + track::HasITS, track::HasTPC, track::HasTRD, track::HasTOF, + v0leg::MeanClusterSizeITS, + v0leg::MeanClusterSizeITSib, + v0leg::MeanClusterSizeITSob); + +using V0Legs = V0Legs_001; // iterators using V0Leg = V0Legs::iterator; +DECLARE_SOA_TABLE_VERSIONED(V0LegsXYZ_000, "AOD", "V0LEGXYZ", 0, track::X, track::Y, track::Z); +using V0LegsXYZ = V0LegsXYZ_000; +// iterators +using V0LegXYZ = V0LegsXYZ::iterator; + +DECLARE_SOA_TABLE_VERSIONED(V0LegsDeDxMC_000, "AOD", "V0LEGDEDXMC", 0, mcpidtpc::DeDxTunedMc, o2::soa::Marker<2>); +using V0LegsDeDxMC = V0LegsDeDxMC_000; +// iterators +using V0LegDeDxMC = V0LegsDeDxMC::iterator; + namespace emevent { DECLARE_SOA_COLUMN(NgPCM, ngpcm, int); @@ -223,23 +268,25 @@ DECLARE_SOA_COLUMN(Vz, vz, float); //! seco DECLARE_SOA_COLUMN(Px, px, float); //! px for photon kf DECLARE_SOA_COLUMN(Py, py, float); //! py for photon kf DECLARE_SOA_COLUMN(Pz, pz, float); //! pz for photon kf -DECLARE_SOA_COLUMN(MGamma, mGamma, float); //! invariant mass of dielectron at SV -DECLARE_SOA_COLUMN(DCAxyToPV, dcaXYtopv, float); //! DCAxy of V0 to PV -DECLARE_SOA_COLUMN(DCAzToPV, dcaZtopv, float); //! DCAz of V0 to PV -DECLARE_SOA_COLUMN(CosPA, cospa, float); //! -DECLARE_SOA_COLUMN(CosPAXY, cospaXY, float); //! -DECLARE_SOA_COLUMN(CosPARZ, cospaRZ, float); //! -DECLARE_SOA_COLUMN(PCA, pca, float); //! -DECLARE_SOA_COLUMN(Alpha, alpha, float); //! -DECLARE_SOA_COLUMN(QtArm, qtarm, float); //! -DECLARE_SOA_COLUMN(ChiSquareNDF, chiSquareNDF, float); //! Chi2 / NDF of the reconstructed V0 -DECLARE_SOA_COLUMN(SigmaPx2, sigmaPx2, float); //! error^2 of px in covariant matrix -DECLARE_SOA_COLUMN(SigmaPy2, sigmaPy2, float); //! error^2 of py in covariant matrix -DECLARE_SOA_COLUMN(SigmaPz2, sigmaPz2, float); //! error^2 of pz in covariant matrix -DECLARE_SOA_COLUMN(SigmaPxPy, sigmaPxPy, float); //! error of px x py in covariant matrix -DECLARE_SOA_COLUMN(SigmaPyPz, sigmaPyPz, float); //! error of py x pz in covariant matrix -DECLARE_SOA_COLUMN(SigmaPzPx, sigmaPzPx, float); //! error of pz x px in covariant matrix -DECLARE_SOA_COLUMN(PrefilterBitDerived, pfbderived, uint16_t); //! + +DECLARE_SOA_COLUMN(MGamma, mGamma, float); //! invariant mass of dielectron at SV +DECLARE_SOA_COLUMN(DCAxyToPV, dcaXYtopv, float); //! DCAxy of V0 to PV +DECLARE_SOA_COLUMN(DCAzToPV, dcaZtopv, float); //! DCAz of V0 to PV +DECLARE_SOA_COLUMN(CosPA, cospa, float); //! +DECLARE_SOA_COLUMN(CosPAXY, cospaXY, float); //! +DECLARE_SOA_COLUMN(CosPARZ, cospaRZ, float); //! +DECLARE_SOA_COLUMN(PCA, pca, float); //! +DECLARE_SOA_COLUMN(Alpha, alpha, float); //! +DECLARE_SOA_COLUMN(QtArm, qtarm, float); //! +DECLARE_SOA_COLUMN(ChiSquareNDF, chiSquareNDF, float); //! Chi2 / NDF of the reconstructed V0 + +DECLARE_SOA_COLUMN(SigmaPx2, sigmaPx2, float); //! error^2 of px in covariant matrix +DECLARE_SOA_COLUMN(SigmaPy2, sigmaPy2, float); //! error^2 of py in covariant matrix +DECLARE_SOA_COLUMN(SigmaPz2, sigmaPz2, float); //! error^2 of pz in covariant matrix +DECLARE_SOA_COLUMN(SigmaPxPy, sigmaPxPy, float); //! error of px x py in covariant matrix +DECLARE_SOA_COLUMN(SigmaPyPz, sigmaPyPz, float); //! error of py x pz in covariant matrix +DECLARE_SOA_COLUMN(SigmaPzPx, sigmaPzPx, float); //! error of pz x px in covariant matrix +DECLARE_SOA_COLUMN(PrefilterBitDerived, pfbderived, uint16_t); //! DECLARE_SOA_DYNAMIC_COLUMN(E, e, [](float px, float py, float pz, float m = 0) -> float { return RecoDecay::sqrtSumOfSquares(px, py, pz, m); }); //! energy of v0 photn, mass to be given as argument when getter is called! DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, [](float px, float py) -> float { return RecoDecay::sqrtSumOfSquares(px, py); }); @@ -248,7 +295,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(Phi, phi, [](float px, float py) -> float { return Re DECLARE_SOA_DYNAMIC_COLUMN(P, p, [](float px, float py, float pz) -> float { return RecoDecay::sqrtSumOfSquares(px, py, pz); }); DECLARE_SOA_DYNAMIC_COLUMN(V0Radius, v0radius, [](float vx, float vy) -> float { return RecoDecay::sqrtSumOfSquares(vx, vy); }); } // namespace v0photonkf -DECLARE_SOA_TABLE(V0PhotonsKF, "AOD", "V0PHOTONKF", //! +DECLARE_SOA_TABLE(V0PhotonsKF_000, "AOD", "V0PHOTONKF", //! o2::soa::Index<>, v0photonkf::CollisionId, v0photonkf::V0Id, v0photonkf::PosTrackId, v0photonkf::NegTrackId, v0photonkf::Vx, v0photonkf::Vy, v0photonkf::Vz, v0photonkf::Px, v0photonkf::Py, v0photonkf::Pz, @@ -265,6 +312,27 @@ DECLARE_SOA_TABLE(V0PhotonsKF, "AOD", "V0PHOTONKF", //! v0photonkf::Phi, v0photonkf::P, v0photonkf::V0Radius); + +DECLARE_SOA_TABLE_VERSIONED(V0PhotonsKF_001, "AOD", "V0PHOTONKF", 1, //! + o2::soa::Index<>, v0photonkf::CollisionId, v0photonkf::V0Id, v0photonkf::PosTrackId, v0photonkf::NegTrackId, + v0photonkf::Vx, v0photonkf::Vy, v0photonkf::Vz, + v0photonkf::Px, v0photonkf::Py, v0photonkf::Pz, + v0photonkf::MGamma, + v0photonkf::DCAxyToPV, v0photonkf::DCAzToPV, + v0photonkf::CosPA, v0photonkf::CosPAXY, v0photonkf::CosPARZ, v0photonkf::PCA, + v0photonkf::Alpha, v0photonkf::QtArm, + v0photonkf::ChiSquareNDF, + + // dynamic column + v0photonkf::E, + v0photonkf::Pt, + v0photonkf::Eta, + v0photonkf::Phi, + v0photonkf::P, + v0photonkf::V0Radius); + +using V0PhotonsKF = V0PhotonsKF_001; + // iterators using V0PhotonKF = V0PhotonsKF::iterator; @@ -281,7 +349,7 @@ DECLARE_SOA_TABLE(V0PhotonsKFPrefilterBitDerived, "AOD", "V0PHOTONKFPFBPI0", v0p // iterators using V0PhotonKFPrefilterBitDerived = V0PhotonsKFPrefilterBitDerived::iterator; -DECLARE_SOA_TABLE(EMPrimaryElectronsFromDalitz, "AOD", "EMPRIMARYELDA", //! +DECLARE_SOA_TABLE(EMPrimaryElectronsFromDalitz_000, "AOD", "EMPRIMARYELDA", //! o2::soa::Index<>, emprimaryelectron::CollisionId, emprimaryelectron::TrackId, emprimaryelectron::Sign, track::Pt, track::Eta, track::Phi, track::DcaXY, track::DcaZ, track::CYY, track::CZY, track::CZZ, @@ -308,6 +376,38 @@ DECLARE_SOA_TABLE(EMPrimaryElectronsFromDalitz, "AOD", "EMPRIMARYELDA", //! emprimaryelectron::MeanClusterSizeITS, emprimaryelectron::MeanClusterSizeITSib, emprimaryelectron::MeanClusterSizeITSob); + +DECLARE_SOA_TABLE_VERSIONED(EMPrimaryElectronsFromDalitz_001, "AOD", "EMPRIMARYELDA", 1, //! + o2::soa::Index<>, emprimaryelectron::CollisionId, + emprimaryelectron::TrackId, emprimaryelectron::Sign, + track::Pt, track::Eta, track::Phi, track::DcaXY, track::DcaZ, track::CYY, track::CZY, track::CZZ, + track::TPCNClsFindable, track::TPCNClsFindableMinusFound, track::TPCNClsFindableMinusCrossedRows, track::TPCNClsShared, + track::TPCChi2NCl, track::TPCInnerParam, + track::TPCSignal, pidtpc::TPCNSigmaEl, pidtpc::TPCNSigmaPi, + pidtofbeta::Beta, pidtof::TOFNSigmaEl, + track::ITSClusterSizes, track::ITSChi2NCl, track::TOFChi2, track::DetectorMap, + + // dynamic column + track::TPCNClsFound, + track::TPCNClsCrossedRows, + track::TPCCrossedRowsOverFindableCls, + track::TPCFoundOverFindableCls, + track::v001::ITSClusterMap, track::v001::ITSNCls, track::v001::ITSNClsInnerBarrel, + track::TPCFractionSharedCls, + track::HasITS, track::HasTPC, track::HasTRD, track::HasTOF, + + emprimaryelectron::Signed1Pt, + emprimaryelectron::P, + emprimaryelectron::Px, + emprimaryelectron::Py, + emprimaryelectron::Pz, + emprimaryelectron::Tgl, + emprimaryelectron::MeanClusterSizeITS, + emprimaryelectron::MeanClusterSizeITSib, + emprimaryelectron::MeanClusterSizeITSob); + +using EMPrimaryElectronsFromDalitz = EMPrimaryElectronsFromDalitz_001; + // iterators using EMPrimaryElectronFromDalitz = EMPrimaryElectronsFromDalitz::iterator; @@ -462,16 +562,16 @@ DECLARE_SOA_COLUMN(Time, time, float); DECLARE_SOA_COLUMN(IsExotic, isExotic, bool); //! flag to mark cluster as exotic DECLARE_SOA_COLUMN(Definition, definition, int); //! cluster definition, see EMCALClusterDefinition.h DECLARE_SOA_ARRAY_INDEX_COLUMN(Track, track); //! TrackIds -DECLARE_SOA_COLUMN(TrackEta, tracketa, std::vector); //! eta values of the matched tracks -DECLARE_SOA_COLUMN(TrackPhi, trackphi, std::vector); //! phi values of the matched tracks +DECLARE_SOA_COLUMN(DeltaPhi, deltaPhi, std::vector); //! phi values of the matched tracks +DECLARE_SOA_COLUMN(DeltaEta, deltaEta, std::vector); //! eta values of the matched tracks DECLARE_SOA_COLUMN(TrackP, trackp, std::vector); //! momentum values of the matched tracks DECLARE_SOA_COLUMN(TrackPt, trackpt, std::vector); //! pt values of the matched tracks DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, [](float e, float eta, float m = 0) -> float { return sqrt(e * e - m * m) / cosh(eta); }); //! cluster pt, mass to be given as argument when getter is called! } // namespace emccluster -DECLARE_SOA_TABLE(SkimEMCClusters, "AOD", "SKIMEMCCLUSTERS", //! table of skimmed EMCal clusters +DECLARE_SOA_TABLE(SkimEMCClusters, "AOD", "SKIMEMCCLUSTER", //! table of skimmed EMCal clusters o2::soa::Index<>, skimmedcluster::CollisionId, emccluster::Definition, skimmedcluster::E, skimmedcluster::Eta, skimmedcluster::Phi, - skimmedcluster::M02, skimmedcluster::NCells, skimmedcluster::Time, emccluster::IsExotic, emccluster::TrackEta, - emccluster::TrackPhi, emccluster::TrackP, emccluster::TrackPt, emccluster::Pt); + skimmedcluster::M02, skimmedcluster::NCells, skimmedcluster::Time, emccluster::IsExotic, emccluster::DeltaPhi, + emccluster::DeltaEta, emccluster::TrackP, emccluster::TrackPt, emccluster::Pt); using SkimEMCCluster = SkimEMCClusters::iterator; DECLARE_SOA_TABLE(EMCEMEventIds, "AOD", "EMCEMEVENTID", emccluster::EMEventId); // To be joined with SkimEMCClusters table at analysis level. @@ -523,42 +623,11 @@ namespace caloextra { DECLARE_SOA_INDEX_COLUMN_FULL(Cluster, cluster, int, SkimEMCClusters, ""); //! reference to the gamma in the skimmed EMCal table DECLARE_SOA_INDEX_COLUMN_FULL(Cell, cell, int, Calos, ""); //! reference to the gamma in the skimmed EMCal table -// DECLARE_SOA_INDEX_COLUMN(Track, track); //! TrackID -DECLARE_SOA_COLUMN(TrackEta, tracketa, float); //! eta of the matched track -DECLARE_SOA_COLUMN(TrackPhi, trackphi, float); //! phi of the matched track -DECLARE_SOA_COLUMN(TrackP, trackp, float); //! momentum of the matched track -DECLARE_SOA_COLUMN(TrackPt, trackpt, float); //! pt of the matched track } // namespace caloextra DECLARE_SOA_TABLE(SkimEMCCells, "AOD", "SKIMEMCCELLS", //! table of link between skimmed EMCal clusters and their cells o2::soa::Index<>, caloextra::ClusterId, caloextra::CellId); //! using SkimEMCCell = SkimEMCCells::iterator; - -DECLARE_SOA_TABLE(SkimEMCMTs, "AOD", "SKIMEMCMTS", //! table of link between skimmed EMCal clusters and their matched tracks - o2::soa::Index<>, caloextra::ClusterId, caloextra::TrackEta, - caloextra::TrackPhi, caloextra::TrackP, caloextra::TrackPt); -using SkimEMCMT = SkimEMCMTs::iterator; - -namespace gammareco -{ -DECLARE_SOA_COLUMN(Method, method, int); //! cut bit for PCM photon candidates -DECLARE_SOA_INDEX_COLUMN_FULL(SkimmedPCM, skimmedPCM, int, V0PhotonsKF, ""); //! reference to the gamma in the skimmed PCM table -DECLARE_SOA_INDEX_COLUMN_FULL(SkimmedPHOS, skimmedPHOS, int, PHOSClusters, ""); //! reference to the gamma in the skimmed PHOS table -DECLARE_SOA_INDEX_COLUMN_FULL(SkimmedEMC, skimmedEMC, int, SkimEMCClusters, ""); //! reference to the gamma in the skimmed EMCal table -DECLARE_SOA_COLUMN(PCMCutBit, pcmcutbit, uint64_t); //! cut bit for PCM photon candidates -DECLARE_SOA_COLUMN(PHOSCutBit, phoscutbit, uint64_t); //! cut bit for PHOS photon candidates -DECLARE_SOA_COLUMN(EMCCutBit, emccutbit, uint64_t); //! cut bit for EMCal photon candidates -} // namespace gammareco -DECLARE_SOA_TABLE(SkimGammas, "AOD", "SKIMGAMMAS", //! table of all gamma candidates (PCM, EMCal and PHOS) after cuts - o2::soa::Index<>, skimmedcluster::CollisionId, gammareco::Method, - skimmedcluster::E, skimmedcluster::Eta, skimmedcluster::Phi, - gammareco::SkimmedEMCId, gammareco::SkimmedPHOSId); -DECLARE_SOA_TABLE(SkimPCMCuts, "AOD", "SKIMPCMCUTS", //! table of link between skimmed PCM photon candidates and their cuts - o2::soa::Index<>, gammareco::SkimmedPCMId, gammareco::PCMCutBit); //! -DECLARE_SOA_TABLE(SkimPHOSCuts, "AOD", "SKIMPHOSCUTS", //! table of link between skimmed PHOS photon candidates and their cuts - o2::soa::Index<>, gammareco::SkimmedPHOSId, gammareco::PHOSCutBit); //! -DECLARE_SOA_TABLE(SkimEMCCuts, "AOD", "SKIMEMCCUTS", //! table of link between skimmed EMCal photon candidates and their cuts - o2::soa::Index<>, gammareco::SkimmedEMCId, gammareco::EMCCutBit); //! } // namespace o2::aod #endif // PWGEM_PHOTONMESON_DATAMODEL_GAMMATABLES_H_ diff --git a/PWGEM/PhotonMeson/TableProducer/CMakeLists.txt b/PWGEM/PhotonMeson/TableProducer/CMakeLists.txt index 511fb699611..a4cf2e6b566 100644 --- a/PWGEM/PhotonMeson/TableProducer/CMakeLists.txt +++ b/PWGEM/PhotonMeson/TableProducer/CMakeLists.txt @@ -63,13 +63,3 @@ o2physics_add_dpl_workflow(skimmer-dalitz-ee SOURCES skimmerDalitzEE.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(gamma-table-producer - SOURCES gammaSelection.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(produce-meson-calo - SOURCES produceMesonCalo.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) diff --git a/PWGEM/PhotonMeson/TableProducer/createEMEventPhoton.cxx b/PWGEM/PhotonMeson/TableProducer/createEMEventPhoton.cxx index 871bd62f35d..724b6347fa6 100644 --- a/PWGEM/PhotonMeson/TableProducer/createEMEventPhoton.cxx +++ b/PWGEM/PhotonMeson/TableProducer/createEMEventPhoton.cxx @@ -193,7 +193,7 @@ struct CreateEMEventPhoton { } event(collision.globalIndex(), bc.runNumber(), bc.globalBC(), collision.alias_raw(), collision.selection_raw(), collision.rct_raw(), bc.timestamp(), - collision.posX(), collision.posY(), collision.posZ(), + collision.posZ(), collision.numContrib(), collision.trackOccupancyInTimeRange(), collision.ft0cOccupancyInTimeRange()); // eventCov(collision.covXX(), collision.covXY(), collision.covXZ(), collision.covYY(), collision.covYZ(), collision.covZZ(), collision.chi2()); diff --git a/PWGEM/PhotonMeson/TableProducer/gammaSelection.cxx b/PWGEM/PhotonMeson/TableProducer/gammaSelection.cxx deleted file mode 100644 index 7a3708d480b..00000000000 --- a/PWGEM/PhotonMeson/TableProducer/gammaSelection.cxx +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \brief skim cluster information to write photon cluster table in AO2D.root -/// dependencies: skimmergammacalo, skimmergammaconversions, skimmer-phos -/// \author marvin.hemmer@cern.ch - -// TODO: add PCM table -#include - -#include "PWGEM/PhotonMeson/Utils/gammaSelectionCuts.h" - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" - -// includes for the R recalculation -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "CCDB/BasicCCDBManager.h" - -#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" -#include "PWGEM/PhotonMeson/Utils/emcalHistoDefinitions.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; - -struct gammaSelection { - - uint64_t EMC_CutModeBit; - - Preslice perEMCClusterMT = o2::aod::caloextra::clusterId; - - Produces tableGammaReco; - Produces tableEMCCuts; - - // Configurable for filter/cuts - Configurable EMC_minTime{"EMC_minTime", -20., "Minimum cluster time for EMCal time cut"}; - Configurable EMC_maxTime{"EMC_maxTime", +25., "Maximum cluster time for EMCal time cut"}; - Configurable EMC_minM02{"EMC_minM02", 0.1, "Minimum M02 for EMCal M02 cut"}; - Configurable EMC_maxM02{"EMC_maxM02", 0.7, "Maximum M02 for EMCal M02 cut"}; - Configurable EMC_minE{"EMC_minE", 0.7, "Minimum cluster energy for EMCal energy cut"}; - Configurable EMC_minNCell{"EMC_minNCell", 1, "Minimum number of cells per cluster for EMCal NCell cut"}; - Configurable> EMC_TM_Eta{"EMC_TM_Eta", {0.01f, 4.07f, -2.5f}, "|eta| <= [0]+(pT+[1])^[2] for EMCal track matching"}; - Configurable> EMC_TM_Phi{"EMC_TM_Phi", {0.015f, 3.65f, -2.f}, "|phi| <= [0]+(pT+[1])^[2] for EMCal track matching"}; - Configurable EMC_Eoverp{"EMC_Eoverp", 1.75, "Minimum cluster energy over track momentum for EMCal track matching"}; - Configurable EMC_CutMode{"EMC_CutMode", "0", "Cut Mode that is run. Each bit is a different setting. The first bit will use the cuts from the configurables."}; - - Configurable PHOS_minTime{"PHOS_minTime", -30., "Minimum cluster time for PHOS time cut"}; - Configurable PHOS_maxTime{"PHOS_maxTime", +30., "Maximum cluster time for PHOS time cut"}; - Configurable PHOS_minM02{"PHOS_minM02", 0.1, "Minimum M02 for PHOS M02 cut"}; - Configurable PHOS_minE{"PHOS_minE", 0.3, "Minimum cluster energy for PHOS energy cut"}; - Configurable PHOS_minENCell{"PHOS_minENCell", 0.1, "Threshold cluster energy for switch for PHOS NCell and M02 cut"}; - Configurable PHOS_minNCell{"PHOS_minNCell", 1, "Minimum number of cells per cluster for PHOS NCell cut"}; - Configurable PHOS_TM_Eta{"PHOS_TM_Eta", 0.02f, "|eta| <= value for PHOS track matching"}; - Configurable PHOS_TM_Phi{"PHOS_TM_Phi", 0.08f, "|phi| <= value for PHOS track matching"}; - - Configurable PHOS_QA{"PHOS_QA", 0b0, "Flag to enable PHOS related QA plots. 1st bit for TM QA."}; - - HistogramRegistry EMCHistos{ - "EMCHistos", - {}, - OutputObjHandlingPolicy::QAObject, - true, - true}; - - HistogramRegistry PHOSHistos{ - "PHOSHistos", - {}, - OutputObjHandlingPolicy::QAObject, - true, - true}; - - void init(o2::framework::InitContext&) - { - EMC_CutModeBit = stoi(EMC_CutMode, 0, 2); - std::bitset<64> EMC_CutModeBitSet(EMC_CutModeBit); - // EMCal - EMCHistos.add("hClusterEIn", "hClusterEIn", gHistoSpec_clusterECuts); - EMCHistos.add("hClusterEOut", "hClusterEOut", gHistoSpec_clusterECuts); - auto hCaloCuts_EMC = EMCHistos.add("hCaloCuts_EMC", "hCaloCuts_EMC", kTH2I, {{7, -0.5, 6.5}, {64, -0.5, 63.5}}); - hCaloCuts_EMC->GetXaxis()->SetBinLabel(1, "in"); - hCaloCuts_EMC->GetXaxis()->SetBinLabel(2, "#it{t}_{cluster} cut"); - hCaloCuts_EMC->GetXaxis()->SetBinLabel(3, "#it{M}_{02} cut"); - hCaloCuts_EMC->GetXaxis()->SetBinLabel(4, "#it{E} cut"); - hCaloCuts_EMC->GetXaxis()->SetBinLabel(5, "#it{N}_{cell} cut"); - hCaloCuts_EMC->GetXaxis()->SetBinLabel(6, "TM"); - hCaloCuts_EMC->GetXaxis()->SetBinLabel(7, "out"); - - LOG(info) << "| ECMal cluster cut settings:"; - LOG(info) << "|\t Timing cut: " << EMC_minTime << " < t < " << EMC_maxTime; - LOG(info) << "|\t M02 cut: " << EMC_minM02 << " < M02 < " << EMC_maxM02; - LOG(info) << "|\t E_min cut: E_cluster > " << EMC_minE; - LOG(info) << "|\t N_cell cut: N_cell > " << EMC_minNCell; - LOG(info) << "|\t TM |eta|: |eta| <= " << EMC_TM_Eta->at(0) << " + (pT + " << EMC_TM_Eta->at(1) << ")^" << EMC_TM_Eta->at(2); - LOG(info) << "|\t TM |phi|: |phi| <= " << EMC_TM_Phi->at(0) << " + (pT + " << EMC_TM_Phi->at(1) << ")^" << EMC_TM_Phi->at(2); - LOG(info) << "|\t TM E/p: E/p < " << EMC_Eoverp; - LOG(info) << "|\t Cut bit is set to: " << EMC_CutModeBitSet << std::endl; - - gatherCutsEMC(EMC_minTime, EMC_maxTime, EMC_minM02, EMC_maxM02, EMC_minE, EMC_minNCell, EMC_TM_Eta, EMC_TM_Phi, EMC_Eoverp); - - // PHOS - PHOSHistos.add("hClusterEIn", "hClusterEIn", gHistoSpec_clusterECuts); - PHOSHistos.add("hClusterEOut", "hClusterEOut", gHistoSpec_clusterECuts); - auto hCaloCuts_PHOS = PHOSHistos.add("hCaloCuts_PHOS", "hCaloCuts_PHOS", kTH1I, {{7, -0.5, 6.5}}); - hCaloCuts_PHOS->GetXaxis()->SetBinLabel(1, "in"); - hCaloCuts_PHOS->GetXaxis()->SetBinLabel(2, "#it{t}_{cluster} cut"); - hCaloCuts_PHOS->GetXaxis()->SetBinLabel(3, "#it{M}_{02} cut"); - hCaloCuts_PHOS->GetXaxis()->SetBinLabel(4, "#it{E} cut"); - hCaloCuts_PHOS->GetXaxis()->SetBinLabel(5, "#it{N}_{cell} cut"); - hCaloCuts_PHOS->GetXaxis()->SetBinLabel(6, "TM"); - hCaloCuts_PHOS->GetXaxis()->SetBinLabel(7, "out"); - if (PHOS_QA & 0b1) { - PHOSHistos.add("clusterTM_dEtadPhi", "cluster trackmatching dEta/dPhi;d#it{#eta};d#it{#varphi} (rad)", kTH2F, {{100, -0.2, 0.2}, {100, -0.2, 0.2}}); // dEta dPhi map of matched tracks - } - - LOG(info) << "| PHOS cluster cut settings:"; - LOG(info) << "|\t Timing cut: " << PHOS_minTime << " < t < " << PHOS_maxTime; - LOG(info) << "|\t NCell cut: " << PHOS_minNCell << " <= NCell for E >= " << PHOS_minENCell; - LOG(info) << "|\t M02 cut: " << PHOS_minM02 << " < M02 for E >= " << PHOS_minENCell; - LOG(info) << "|\t E_min cut: E_cluster > " << PHOS_minE; - LOG(info) << "|\t TM |eta|: |eta| <= " << PHOS_TM_Eta; - LOG(info) << "|\t TM |phi|: |phi| <= " << PHOS_TM_Phi << std::endl; - } - - void processRec(aod::EMEvents const&, aod::SkimEMCClusters const& emcclusters, aod::SkimEMCMTs const& matchedtracks, aod::PHOSClusters const& phosclusters) - { - for (const auto& emccluster : emcclusters) { // loop of EMC clusters - uint64_t EMC_CutBit = doPhotonCutsEMC(EMC_CutModeBit, emccluster, matchedtracks, perEMCClusterMT, EMCHistos); - tableEMCCuts(emccluster.globalIndex(), EMC_CutBit); - } // end loop of EMC clusters - - for (const auto& phoscluster : phosclusters) { // loop over PHOS clusters - PHOSHistos.fill(HIST("hClusterEIn"), phoscluster.e(), 0); - PHOSHistos.fill(HIST("hCaloCuts_PHOS"), 0); - - if (phoscluster.time() > PHOS_maxTime || phoscluster.time() < PHOS_minTime) { - PHOSHistos.fill(HIST("hCaloCuts_PHOS"), 1); - continue; - } - if (!(phoscluster.e() >= PHOS_minENCell && phoscluster.m02() > PHOS_minM02)) { - PHOSHistos.fill(HIST("hCaloCuts_PHOS"), 2); - continue; - } - if (phoscluster.e() <= PHOS_minE) { - PHOSHistos.fill(HIST("hCaloCuts_PHOS"), 3); - continue; - } - if (!(phoscluster.e() >= PHOS_minENCell && phoscluster.nCells() > PHOS_minNCell)) { - PHOSHistos.fill(HIST("hCaloCuts_PHOS"), 4); - continue; - } - - // TODO: add track matching for PHOS when available! - // track matching - bool hasMatchedTrack_PHOS = false; - // double dEta_PHOS, dPhi_PHOS; - // // only consider closest match - // dEta_PHOS = phoscluster.tracketa() - phoscluster.eta(); - // dPhi_PHOS = phoscluster.trackphi() - phoscluster.phi(); - // if ((fabs(dEta_PHOS) < PHOS_TM_Eta) && (fabs(dPhi_PHOS) < PHOS_TM_Phi)) { - // hasMatchedTrack_PHOS = true; - // if (PHOS_QA & 0b1) { - // EMCHistos.fill(HIST("clusterTM_dEtadPhi"), dEta_PHOS, dPhi_PHOS); - // } - // } - if (hasMatchedTrack_PHOS) { - PHOSHistos.fill(HIST("hCaloCuts_PHOS"), 5); - } else { - PHOSHistos.fill(HIST("hClusterEOut"), phoscluster.e(), 0); - PHOSHistos.fill(HIST("hCaloCuts_PHOS"), 6); - tableGammaReco(phoscluster.collisionId(), 2, - phoscluster.e(), phoscluster.eta(), phoscluster.phi(), 0, phoscluster.globalIndex()); - } - } // end loop of PHOS clusters - } - PROCESS_SWITCH(gammaSelection, processRec, "process only reconstructed info", true); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; - return workflow; -} diff --git a/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx b/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx index a3521b5fa4c..c0eeeba224f 100644 --- a/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx +++ b/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx @@ -15,43 +15,43 @@ // // \author Daiki Sekihata , Tokyo -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Math/Vector4D.h" +#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" +#include "PWGEM/PhotonMeson/Utils/PCMUtilities.h" +#include "PWGEM/PhotonMeson/Utils/TrackSelection.h" -#include "Framework/runDataProcessing.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" #include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" +#include "Common/Core/TPCVDriftManager.h" +#include "Common/Core/TableHelper.h" #include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" +#include "Tools/KFparticle/KFUtilities.h" + #include "CCDB/BasicCCDBManager.h" -#include "Common/Core/TableHelper.h" -#include "Common/Core/TPCVDriftManager.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" -#include "Tools/KFparticle/KFUtilities.h" +#include "Math/Vector4D.h" -#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" -#include "PWGEM/PhotonMeson/Utils/PCMUtilities.h" -#include "PWGEM/PhotonMeson/Utils/TrackSelection.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::soa; @@ -65,14 +65,16 @@ using MyCollisions = soa::Join; using MyCollisionsWithSWT = soa::Join; using MyCollisionsMC = soa::Join; -using MyTracksIU = soa::Join; -using MyTracksIUMC = soa::Join; +using MyTracksIU = soa::Join; +using MyTracksIUMC = soa::Join; struct PhotonConversionBuilder { Produces v0photonskf; - // Produces v0photonskfcov; Produces v0legs; - Produces events_ngpcm; + Produces v0legsXYZ; + Produces v0legsDeDxMC; + // Produces v0photonskfcov; + // Produces events_ngpcm; // CCDB options Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; @@ -337,10 +339,10 @@ struct PhotonConversionBuilder { float px = kfp.GetPx(); float py = kfp.GetPy(); float cospaXY = RecoDecay::dotProd(std::array{lx, ly}, std::array{px, py}) / (RecoDecay::sqrtSumOfSquares(lx, ly) * RecoDecay::sqrtSumOfSquares(px, py)); - if (cospaXY < -1.) { - return -1.; - } else if (cospaXY > 1.) { - return 1.; + if (cospaXY < -1.f) { + return -1.f; + } else if (cospaXY > 1.f) { + return 1.f; } return cospaXY; } @@ -356,15 +358,15 @@ struct PhotonConversionBuilder { float pz = kfp.GetPz(); float cospaRZ = RecoDecay::dotProd(std::array{lt, lz}, std::array{pt, pz}) / (RecoDecay::sqrtSumOfSquares(lt, lz) * RecoDecay::sqrtSumOfSquares(pt, pz)); - if (cospaRZ < -1.) { - return -1.; - } else if (cospaRZ > 1.) { - return 1.; + if (cospaRZ < -1.f) { + return -1.f; + } else if (cospaRZ > 1.f) { + return 1.f; } return cospaRZ; } - template + template void fillTrackTable(TTrack const& track, TShiftedTrack const& shiftedtrack, TKFParticle const& kfp, const float dcaXY, const float dcaZ) { v0legs(track.collisionId(), track.globalIndex(), track.sign(), @@ -372,8 +374,13 @@ struct PhotonConversionBuilder { track.tpcNClsFindable(), track.tpcNClsFindableMinusFound(), track.tpcNClsFindableMinusCrossedRows(), track.tpcNClsShared(), track.tpcChi2NCl(), track.tpcInnerParam(), track.tpcSignal(), track.tpcNSigmaEl(), track.tpcNSigmaPi(), - track.itsClusterSizes(), track.itsChi2NCl(), track.detectorMap(), - shiftedtrack.getX(), shiftedtrack.getY(), shiftedtrack.getZ(), shiftedtrack.getTgl()); + track.itsClusterSizes(), track.itsChi2NCl(), track.detectorMap()); + + v0legsXYZ(shiftedtrack.getX(), shiftedtrack.getY(), shiftedtrack.getZ()); + + if constexpr (isMC) { + v0legsDeDxMC(track.mcTunedTPCSignal()); + } } template @@ -599,6 +606,11 @@ struct PhotonConversionBuilder { return; } + float chi2kf = gammaKF_DecayVtx.GetChi2() / gammaKF_DecayVtx.GetNDF(); + if (chi2kf > 6e+3) { // protection for uint16. + return; + } + // calculate DCAxy,z to PV float v0mom = RecoDecay::sqrtSumOfSquares(gammaKF_DecayVtx.GetPx(), gammaKF_DecayVtx.GetPy(), gammaKF_DecayVtx.GetPz()); float length = RecoDecay::sqrtSumOfSquares(gammaKF_DecayVtx.GetX() - collision.posX(), gammaKF_DecayVtx.GetY() - collision.posY(), gammaKF_DecayVtx.GetZ() - collision.posZ()); @@ -639,8 +651,6 @@ struct PhotonConversionBuilder { registry.fill(HIST("V0/hCosPAXY_Rxy"), rxy, cospaXY_kf); registry.fill(HIST("V0/hCosPARZ_Rxy"), rxy, cospaRZ_kf); - float chi2kf = gammaKF_DecayVtx.GetChi2() / gammaKF_DecayVtx.GetNDF(); - for (auto& leg : {kfp_pos_DecayVtx, kfp_ele_DecayVtx}) { float legpt = RecoDecay::sqrtSumOfSquares(leg.GetPx(), leg.GetPy()); float legeta = RecoDecay::eta(std::array{leg.GetPx(), leg.GetPy(), leg.GetPz()}); @@ -668,12 +678,13 @@ struct PhotonConversionBuilder { gammaKF_DecayVtx.GetX(), gammaKF_DecayVtx.GetY(), gammaKF_DecayVtx.GetZ(), gammaKF_PV.GetPx(), gammaKF_PV.GetPy(), gammaKF_PV.GetPz(), v0_sv.M(), dca_xy_v0_to_pv, dca_z_v0_to_pv, - cospa_kf, cospaXY_kf, cospaRZ_kf, pca_kf, alpha, qt, chi2kf); + cospa_kf, cospaXY_kf, cospaRZ_kf, + pca_kf, alpha, qt, chi2kf); // v0photonskfcov(gammaKF_PV.GetCovariance(9), gammaKF_PV.GetCovariance(14), gammaKF_PV.GetCovariance(20), gammaKF_PV.GetCovariance(13), gammaKF_PV.GetCovariance(19), gammaKF_PV.GetCovariance(18)); - fillTrackTable(pos, pTrack, kfp_pos_DecayVtx, posdcaXY, posdcaZ); // positive leg first - fillTrackTable(ele, nTrack, kfp_ele_DecayVtx, eledcaXY, eledcaZ); // negative leg second + fillTrackTable(pos, pTrack, kfp_pos_DecayVtx, posdcaXY, posdcaZ); // positive leg first + fillTrackTable(ele, nTrack, kfp_ele_DecayVtx, eledcaXY, eledcaZ); // negative leg second } // end of fill table } @@ -800,7 +811,7 @@ struct PhotonConversionBuilder { continue; } } - events_ngpcm(nv0_map[collision.globalIndex()]); + // events_ngpcm(nv0_map[collision.globalIndex()]); } // end of collision loop pca_map.clear(); diff --git a/PWGEM/PhotonMeson/TableProducer/produceMesonCalo.cxx b/PWGEM/PhotonMeson/TableProducer/produceMesonCalo.cxx deleted file mode 100644 index 7fd19416d3d..00000000000 --- a/PWGEM/PhotonMeson/TableProducer/produceMesonCalo.cxx +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \brief perform calo photon analysis on calo photons from skimmergammacalo task -/// dependencies: skimmergammacalo -/// \author marvin.hemmer@cern.ch - -#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" -#include "PWGEM/PhotonMeson/DataModel/mesonTables.h" - -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" - -// includes for the R recalculation -#include "DataFormatsParameters/GRPObject.h" -#include "DetectorsBase/GeometryManager.h" -#include "CCDB/BasicCCDBManager.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; - -struct produceMesonCalo { - - Produces tableCaloMeson; - - HistogramRegistry spectra = { - "spectra", - {}, - OutputObjHandlingPolicy::AnalysisObject, - true, - true}; - - // Configurable for histograms - Configurable nBinsMinv{"nBinsMinv", 800, "N bins for minv axis"}; - Configurable minMinv{"minMinv", 0.0, "Minimum value for minv axis"}; - Configurable maxMinv{"maxMinv", 0.8, "Maximum value for minv axis"}; - Configurable nBinsPt{"nBinsPt", 180, "N bins for pT axis"}; - Configurable minPt{"minPt", 0., "Minimum value for pT axis"}; - Configurable maxPt{"maxPt", 60., "Maximum value for pT axis"}; - - void init(o2::framework::InitContext&) - { - std::vector ptBinning(nBinsPt, 0); - - for (int i = 0; i < nBinsPt; i++) { - if (i < 100) { - ptBinning.at(i) = 0.10 * i; - } else if (i < 140) { - ptBinning.at(i) = 10. + 0.25 * (i - 100); - } else if (i < 180) { - ptBinning.at(i) = 20. + 1.00 * (i - 140); - } else { - ptBinning.at(i) = maxPt; - } - } - - AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec minvAxis = {nBinsMinv, minMinv, maxMinv, - "#it{m}_{inv} (GeV/#it{c}^{2})"}; - AxisSpec etaAxis = {100, -0.8, 0.8, "#eta"}; - AxisSpec phiAxis = {360, 0, 2 * M_PI, "#varphi (rad)"}; - AxisSpec alphaAxis = {200, -1, +1, "#alpha"}; - AxisSpec oaAxis = {180, 0, M_PI, "#vartheta_{#gamma#gamma} (rad)"}; - - HistogramConfigSpec defaultPtMinvHist( - {HistType::kTH2F, {minvAxis, ptAxis}}); - - HistogramConfigSpec defaultEtaPhiHist( - {HistType::kTH2F, {etaAxis, phiAxis}}); - - HistogramConfigSpec defaultPtMotherPtGammaHist( - {HistType::kTH2F, {ptAxis, ptAxis}}); - - HistogramConfigSpec defaultPtAlpha( - {HistType::kTH2F, {ptAxis, alphaAxis}}); - - HistogramConfigSpec defaultPtOA( - {HistType::kTH2F, {ptAxis, oaAxis}}); - - spectra.add("SameEvent_Minv_Pt", "SameEvent_Minv_Pt", defaultPtMinvHist, true); - spectra.add("SameEvent_Eta_Phi", "SameEvent_Eta_Phi", defaultEtaPhiHist, true); - spectra.add("SameEvent_Pt_Alpha", "SameEvent_Pt_Alpha", defaultPtAlpha, true); - spectra.add("SameEvent_Pt_OA", "SameEvent_Pt_OA", defaultPtOA, true); - spectra.add("SameEvent_PtMother_PtGamma", "SameEvent_PtMother_PtGamma", defaultPtMotherPtGammaHist, true); - - spectra.add("Photon_Eta_Phi", "Photon_Eta_Phi", defaultEtaPhiHist, true); - } - - void - processRec(aod::Collision const&, - aod::SkimGammas const& skimgammas) - { - for (auto& [gamma0, gamma1] : // EMC-EMC - combinations(o2::soa::CombinationsStrictlyUpperIndexPolicy(skimgammas, - skimgammas))) { - float openingAngle = acos((cos(gamma0.phi() - gamma1.phi()) + - sinh(gamma0.eta()) * sinh(gamma1.eta())) / - (cosh(gamma0.eta()) * cosh(gamma1.eta()))); - float E = gamma0.e() + gamma1.e(); - float pt0 = gamma0.e() / cosh(gamma0.eta()); - float pt1 = gamma1.e() / cosh(gamma1.eta()); - float px = - pt0 * cos(gamma0.phi()) + pt1 * cos(gamma1.phi()); - float py = - pt0 * sin(gamma0.phi()) + pt1 * sin(gamma1.phi()); - float pz = - pt0 * sinh(gamma0.eta()) + pt1 * sinh(gamma1.eta()); - float alpha = (gamma0.e() - gamma1.e()) != 0. - ? (gamma0.e() - gamma1.e()) / (gamma0.e() + gamma1.e()) - : 0.; - float Pt = sqrt(pt0 * pt0 + pt1 * pt1 + - 2. * pt0 * pt1 * - cos(gamma0.phi() - gamma1.phi())); - float minv = - sqrt(2. * gamma0.e() * gamma1.e() * (1. - cos(openingAngle))); - float eta = asinh(pz / Pt); - float phi = atan2(py, px); - phi = (phi < 0) ? phi + 2. * M_PI : phi; - tableCaloMeson(gamma0.collisionId(), gamma0.globalIndex(), gamma1.globalIndex(), - openingAngle, px, py, pz, E, alpha, minv, eta, phi, - Pt); - spectra.get(HIST("SameEvent_Minv_Pt"))->Fill(minv, Pt); - spectra.get(HIST("SameEvent_Eta_Phi"))->Fill(eta, phi); - spectra.get(HIST("SameEvent_Pt_Alpha"))->Fill(Pt, alpha); - spectra.get(HIST("SameEvent_Pt_OA"))->Fill(Pt, openingAngle); - spectra.get(HIST("SameEvent_PtMother_PtGamma"))->Fill(Pt, pt0); - spectra.get(HIST("SameEvent_PtMother_PtGamma"))->Fill(Pt, pt1); - - spectra.get(HIST("Photon_Eta_Phi"))->Fill(gamma0.eta(), gamma0.phi()); - spectra.get(HIST("Photon_Eta_Phi"))->Fill(gamma1.eta(), gamma1.phi()); - } - } - PROCESS_SWITCH(produceMesonCalo, processRec, - "process only reconstructed info", true); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; - return workflow; -} diff --git a/PWGEM/PhotonMeson/TableProducer/skimmerGammaCalo.cxx b/PWGEM/PhotonMeson/TableProducer/skimmerGammaCalo.cxx index f5dbdad1c28..731a9ed9331 100644 --- a/PWGEM/PhotonMeson/TableProducer/skimmerGammaCalo.cxx +++ b/PWGEM/PhotonMeson/TableProducer/skimmerGammaCalo.cxx @@ -51,7 +51,6 @@ struct SkimmerGammaCalo { Produces tableGammaEMCReco; Produces tableEMCClusterMCLabels; Produces tableCellEMCReco; - Produces tableTrackEMCReco; // Configurable for filter/cuts Configurable minTime{"minTime", -200., "Minimum cluster time for time cut"}; @@ -155,21 +154,19 @@ struct SkimmerGammaCalo { vP.reserve(groupedMTs.size()); vPt.reserve(groupedMTs.size()); for (const auto& emcmatchedtrack : groupedMTs) { - if (std::abs(emccluster.eta() - emcmatchedtrack.track_as().trackEtaEmcal()) >= maxdEta || std::abs(emccluster.phi() - emcmatchedtrack.track_as().trackPhiEmcal()) >= maxdPhi) { + if (std::abs(emcmatchedtrack.deltaEta()) >= maxdEta || std::abs(emcmatchedtrack.deltaPhi()) >= maxdPhi) { continue; } historeg.fill(HIST("MTEtaPhi"), emccluster.eta() - emcmatchedtrack.track_as().trackEtaEmcal(), emccluster.phi() - emcmatchedtrack.track_as().trackPhiEmcal()); vTrackIds.emplace_back(emcmatchedtrack.trackId()); - vEta.emplace_back(emcmatchedtrack.track_as().trackEtaEmcal()); - vPhi.emplace_back(emcmatchedtrack.track_as().trackPhiEmcal()); + vEta.emplace_back(emcmatchedtrack.deltaEta()); + vPhi.emplace_back(emcmatchedtrack.deltaPhi()); vP.emplace_back(emcmatchedtrack.track_as().p()); vPt.emplace_back(emcmatchedtrack.track_as().pt()); - tableTrackEMCReco(emcmatchedtrack.emcalclusterId(), emcmatchedtrack.track_as().trackEtaEmcal(), emcmatchedtrack.track_as().trackPhiEmcal(), - emcmatchedtrack.track_as().p(), emcmatchedtrack.track_as().pt()); } tableGammaEMCReco(emccluster.collisionId(), emccluster.definition(), emccluster.energy(), emccluster.eta(), emccluster.phi(), emccluster.m02(), - emccluster.nCells(), emccluster.time(), emccluster.isExotic(), vEta, vPhi, vP, vPt); + emccluster.nCells(), emccluster.time(), emccluster.isExotic(), vPhi, vEta, vP, vPt); } } void processMC(soa::Join::iterator const& collision, soa::Join const& emcclusters, aod::McParticles const&) @@ -178,6 +175,10 @@ struct SkimmerGammaCalo { return; } + if (needEMCTrigger.value && !collision.alias_bit(kTVXinEMC)) { + return; + } + for (const auto& emccluster : emcclusters) { // Definition cut diff --git a/PWGEM/PhotonMeson/TableProducer/skimmerGammaConversion.cxx b/PWGEM/PhotonMeson/TableProducer/skimmerGammaConversion.cxx index 6a39aea8881..fa843d22f54 100644 --- a/PWGEM/PhotonMeson/TableProducer/skimmerGammaConversion.cxx +++ b/PWGEM/PhotonMeson/TableProducer/skimmerGammaConversion.cxx @@ -23,38 +23,37 @@ // runme like: o2-analysis-trackselection -b --aod-file ${sourceFile} --aod-writer-json ${writerFile} | o2-analysis-timestamp -b | o2-analysis-trackextension -b | o2-analysis-lf-lambdakzerobuilder -b | o2-analysis-pid-tpc -b | o2-analysis-em-skimmermc -b -#include #include +#include #include #include // todo: remove reduantant information in GammaConversionsInfoTrue #include "PWGEM/PhotonMeson/DataModel/gammaTables.h" -#include "PWGEM/PhotonMeson/Utils/gammaConvDefinitions.h" #include "PWGEM/PhotonMeson/Utils/PCMUtilities.h" +#include "PWGEM/PhotonMeson/Utils/gammaConvDefinitions.h" #include "PWGLF/DataModel/LFStrangenessTables.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" // includes for the R recalculation -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "CCDB/BasicCCDBManager.h" +#include "Common/Core/trackUtilities.h" +#include "Tools/KFparticle/KFUtilities.h" +#include "CCDB/BasicCCDBManager.h" +#include "CommonConstants/PhysicsConstants.h" #include "DCAFitter/HelixHelper.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" #include "ReconstructionDataFormats/TrackFwd.h" -#include "Common/Core/trackUtilities.h" -#include "CommonConstants/PhysicsConstants.h" +#include "Math/Vector4D.h" #include #include -#include "Math/Vector4D.h" - -#include "Tools/KFparticle/KFUtilities.h" using namespace o2; using namespace o2::framework; @@ -189,8 +188,7 @@ struct skimmerGammaConversion { theTrack.tpcNClsFindable(), theTrack.tpcNClsFindableMinusFound(), theTrack.tpcNClsFindableMinusCrossedRows(), theTrack.tpcNClsShared(), theTrack.tpcChi2NCl(), theTrack.tpcInnerParam(), theTrack.tpcSignal(), theTrack.tpcNSigmaEl(), theTrack.tpcNSigmaPi(), - theTrack.itsClusterSizes(), theTrack.itsChi2NCl(), theTrack.detectorMap(), - theTrack.x(), theTrack.y(), theTrack.z(), theTrack.tgl()); + theTrack.itsClusterSizes(), theTrack.itsChi2NCl(), theTrack.detectorMap()); } template diff --git a/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryElectronFromDalitzEE.cxx b/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryElectronFromDalitzEE.cxx index b773c43cea6..435e9451a83 100644 --- a/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryElectronFromDalitzEE.cxx +++ b/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryElectronFromDalitzEE.cxx @@ -42,20 +42,21 @@ using namespace o2::framework::expressions; using namespace o2::constants::physics; using namespace o2::pwgem::photonmeson; -// using MyCollisions = soa::Join; using MyCollisions = soa::Join; using MyCollisionsWithSWT = soa::Join; using MyCollisionsMC = soa::Join; using MyTracks = soa::Join; using MyTrack = MyTracks::iterator; -using MyTracksMC = soa::Join; +using MyTracksMC = soa::Join; using MyTrackMC = MyTracksMC::iterator; struct skimmerPrimaryElectronFromDalitzEE { SliceCache cache; Preslice perCol = o2::aod::track::collisionId; + Preslice perCol_pcm = o2::aod::v0photonkf::collisionId; Produces emprimaryelectrons; + Produces emprimaryelectronsDeDxMC; // Configurables Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; @@ -89,6 +90,8 @@ struct skimmerPrimaryElectronFromDalitzEE { Configurable includeITSsa{"includeITSsa", false, "Flag to include ITSsa tracks"}; Configurable maxpt_itssa{"maxpt_itssa", 0.15, "max pt for ITSsa track"}; Configurable maxMeanITSClusterSize{"maxMeanITSClusterSize", 16, "max x cos(lambda)"}; + Configurable slope{"slope", 0.0185, "slope for m vs. phiv"}; + Configurable intercept{"intercept", -0.0380, "intercept for m vs. phiv"}; HistogramRegistry fRegistry{"output", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; static constexpr std::string_view dileptonSigns[3] = {"uls/", "lspp/", "lsmm/"}; @@ -115,7 +118,7 @@ struct skimmerPrimaryElectronFromDalitzEE { fRegistry.add("Track/hPt", "pT;p_{T} (GeV/c)", kTH1F, {{1000, 0.0f, 10}}, false); fRegistry.add("Track/hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2F, {{180, 0, 2 * M_PI}, {400, -2.0f, 2.0f}}, false); fRegistry.add("Track/hQoverPt", "q/pT;q/p_{T} (GeV/c)^{-1}", kTH1F, {{400, -20, 20}}, false); - fRegistry.add("Track/hRelDeltaPt", "pT resolution;p_{T} (GeV/c);#Deltap_{T}/p_{T}", kTH2F, {{1000, 0, 10}, {100, 0, 1}}, false); + fRegistry.add("Track/hRelDeltaPt", "pT resolution;p_{T} (GeV/c);#Deltap_{T}/p_{T}", kTH2F, {{1000, 0, 10}, {100, 0, 0.1}}, false); fRegistry.add("Track/hDCAxyz", "DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm)", kTH2F, {{200, -1.0f, 1.0f}, {200, -1.0f, 1.0f}}, false); fRegistry.add("Track/hDCAxy_Pt", "DCA_{xy} vs. pT;p_{T} (GeV/c);DCA_{xy} (cm)", kTH2F, {{200, 0, 10}, {200, -1, 1}}, false); fRegistry.add("Track/hDCAz_Pt", "DCA_{z} vs. pT;p_{T} (GeV/c);DCA_{z} (cm)", kTH2F, {{200, 0, 10}, {200, -1, 1}}, false); @@ -131,12 +134,13 @@ struct skimmerPrimaryElectronFromDalitzEE { fRegistry.add("Track/hTPCNcls2Nf", "TPC Ncls/Nfindable", kTH1F, {{200, 0, 2}}, false); fRegistry.add("Track/hTPCNclsShared", "TPC Ncls shared/Ncls;p_{T} (GeV/c);N_{cls}^{shared}/N_{cls} in TPC", kTH2F, {{1000, 0, 10}, {100, 0, 1}}, false); fRegistry.add("Track/hTPCdEdx", "TPC dE/dx;p_{in} (GeV/c);TPC dE/dx (a.u.)", kTH2F, {{1000, 0, 10}, {200, 0, 200}}, false); + fRegistry.add("Track/hTPCdEdxMC", "TPC dE/dx;p_{in} (GeV/c);TPC dE/dx (a.u.)", kTH2F, {{1000, 0, 10}, {200, 0, 200}}, false); fRegistry.add("Track/hTPCNsigmaEl", "TPC n sigma el;p_{in} (GeV/c);n #sigma_{e}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); fRegistry.add("Track/hTPCNsigmaPi", "TPC n sigma pi;p_{in} (GeV/c);n #sigma_{#pi}^{TPC}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); // ITS fRegistry.add("Track/hNclsITS", "number of ITS clusters", kTH1F, {{8, -0.5, 7.5}}, false); - fRegistry.add("Track/hChi2ITS", "chi2/number of ITS clusters", kTH1F, {{100, 0, 10}}, false); + fRegistry.add("Track/hChi2ITS", "chi2/number of ITS clusters", kTH1F, {{400, 0, 40}}, false); fRegistry.add("Track/hITSClusterMap", "ITS cluster map", kTH1F, {{128, -0.5, 127.5}}, false); fRegistry.add("Track/hMeanClusterSizeITS", "mean cluster size ITS;p_{pv} (GeV/c); #times cos(#lambda)", kTH2F, {{1000, 0, 10}, {150, 0, 15}}, false); fRegistry.add("Track/hMeanClusterSizeITSib", "mean cluster size ITSib;p_{pv} (GeV/c); #times cos(#lambda)", kTH2F, {{1000, 0, 10}, {150, 0, 15}}, false); @@ -209,7 +213,7 @@ struct skimmerPrimaryElectronFromDalitzEE { return false; } - if (track.itsChi2NCl() > maxchi2its) { + if (track.itsChi2NCl() < 0.f || maxchi2its < track.itsChi2NCl()) { return false; } @@ -225,7 +229,7 @@ struct skimmerPrimaryElectronFromDalitzEE { } if (track.hasTPC()) { - if (track.tpcChi2NCl() > maxchi2tpc) { + if (track.tpcChi2NCl() < 0.f || maxchi2tpc < track.tpcChi2NCl()) { return false; } @@ -307,80 +311,90 @@ struct skimmerPrimaryElectronFromDalitzEE { return true; } - template + template void fillTrackTable(TCollision const& collision, TTrack const& track) { - if (std::find(stored_trackIds.begin(), stored_trackIds.end(), std::make_pair(collision.globalIndex(), track.globalIndex())) == stored_trackIds.end()) { - emprimaryelectrons(collision.globalIndex(), track.globalIndex(), track.sign(), - track.pt(), track.eta(), track.phi(), track.dcaXY(), track.dcaZ(), track.cYY(), track.cZY(), track.cZZ(), - track.tpcNClsFindable(), track.tpcNClsFindableMinusFound(), track.tpcNClsFindableMinusCrossedRows(), track.tpcNClsShared(), - track.tpcChi2NCl(), track.tpcInnerParam(), - track.tpcSignal(), track.tpcNSigmaEl(), track.tpcNSigmaPi(), - track.beta(), track.tofNSigmaEl(), track.tofNSigmaPi(), - track.itsClusterSizes(), track.itsChi2NCl(), track.tofChi2(), track.detectorMap(), track.tgl()); - - fRegistry.fill(HIST("Track/hPt"), track.pt()); - fRegistry.fill(HIST("Track/hEtaPhi"), track.phi(), track.eta()); - fRegistry.fill(HIST("Track/hQoverPt"), track.sign() / track.pt()); - fRegistry.fill(HIST("Track/hRelDeltaPt"), track.pt(), track.sigma1Pt() * track.pt()); - fRegistry.fill(HIST("Track/hDCAxyz"), track.dcaXY(), track.dcaZ()); - fRegistry.fill(HIST("Track/hDCAxy_Pt"), track.pt(), track.dcaXY()); - fRegistry.fill(HIST("Track/hDCAz_Pt"), track.pt(), track.dcaZ()); - fRegistry.fill(HIST("Track/hDCAxyzSigma"), track.dcaXY() / std::sqrt(track.cYY()), track.dcaZ() / std::sqrt(track.cZZ())); - fRegistry.fill(HIST("Track/hDCAxyRes_Pt"), track.pt(), std::sqrt(track.cYY()) * 1e+4); // convert cm to um - fRegistry.fill(HIST("Track/hDCAzRes_Pt"), track.pt(), std::sqrt(track.cZZ()) * 1e+4); // convert cm to um - - fRegistry.fill(HIST("Track/hNclsTPC"), track.tpcNClsFound()); - fRegistry.fill(HIST("Track/hNcrTPC"), track.tpcNClsCrossedRows()); - fRegistry.fill(HIST("Track/hChi2TPC"), track.tpcChi2NCl()); - fRegistry.fill(HIST("Track/hTPCNcr2Nf"), track.tpcCrossedRowsOverFindableCls()); - fRegistry.fill(HIST("Track/hTPCNcls2Nf"), track.tpcFoundOverFindableCls()); - fRegistry.fill(HIST("Track/hTPCNclsShared"), track.pt(), track.tpcFractionSharedCls()); - fRegistry.fill(HIST("Track/hTPCdEdx"), track.tpcInnerParam(), track.tpcSignal()); - fRegistry.fill(HIST("Track/hTPCNsigmaEl"), track.tpcInnerParam(), track.tpcNSigmaEl()); - fRegistry.fill(HIST("Track/hTPCNsigmaPi"), track.tpcInnerParam(), track.tpcNSigmaPi()); - - fRegistry.fill(HIST("Track/hChi2TOF"), track.tofChi2()); - fRegistry.fill(HIST("Track/hTOFbeta"), track.p(), track.beta()); - fRegistry.fill(HIST("Track/hTOFNsigmaEl"), track.p(), track.tofNSigmaEl()); - fRegistry.fill(HIST("Track/hTOFNsigmaPi"), track.p(), track.tofNSigmaPi()); - - fRegistry.fill(HIST("Track/hNclsITS"), track.itsNCls()); - fRegistry.fill(HIST("Track/hChi2ITS"), track.itsChi2NCl()); - fRegistry.fill(HIST("Track/hITSClusterMap"), track.itsClusterMap()); + emprimaryelectrons(collision.globalIndex(), track.globalIndex(), track.sign(), + track.pt(), track.eta(), track.phi(), track.dcaXY(), track.dcaZ(), track.cYY(), track.cZY(), track.cZZ(), + track.tpcNClsFindable(), track.tpcNClsFindableMinusFound(), track.tpcNClsFindableMinusCrossedRows(), track.tpcNClsShared(), + track.tpcChi2NCl(), track.tpcInnerParam(), + track.tpcSignal(), track.tpcNSigmaEl(), track.tpcNSigmaPi(), + track.beta(), track.tofNSigmaEl(), + track.itsClusterSizes(), track.itsChi2NCl(), track.tofChi2(), track.detectorMap()); - int total_cluster_size = 0, nl = 0; - for (unsigned int layer = 0; layer < 7; layer++) { - int cluster_size_per_layer = track.itsClsSizeInLayer(layer); - if (cluster_size_per_layer > 0) { - nl++; - } - total_cluster_size += cluster_size_per_layer; - } + if constexpr (isMC) { + emprimaryelectronsDeDxMC(track.mcTunedTPCSignal()); + } + } - int total_cluster_size_ib = 0, nl_ib = 0; - for (unsigned int layer = 0; layer < 3; layer++) { - int cluster_size_per_layer = track.itsClsSizeInLayer(layer); - if (cluster_size_per_layer > 0) { - nl_ib++; - } - total_cluster_size_ib += cluster_size_per_layer; + template + void fillTrackHistograms(TTrack const& track) + { + float mcTunedTPCSignal = 0.f; + if constexpr (isMC) { + mcTunedTPCSignal = track.mcTunedTPCSignal(); + } + + fRegistry.fill(HIST("Track/hPt"), track.pt()); + fRegistry.fill(HIST("Track/hEtaPhi"), track.phi(), track.eta()); + fRegistry.fill(HIST("Track/hQoverPt"), track.sign() / track.pt()); + fRegistry.fill(HIST("Track/hRelDeltaPt"), track.pt(), track.sigma1Pt() * track.pt()); + fRegistry.fill(HIST("Track/hDCAxyz"), track.dcaXY(), track.dcaZ()); + fRegistry.fill(HIST("Track/hDCAxy_Pt"), track.pt(), track.dcaXY()); + fRegistry.fill(HIST("Track/hDCAz_Pt"), track.pt(), track.dcaZ()); + fRegistry.fill(HIST("Track/hDCAxyzSigma"), track.dcaXY() / std::sqrt(track.cYY()), track.dcaZ() / std::sqrt(track.cZZ())); + fRegistry.fill(HIST("Track/hDCAxyRes_Pt"), track.pt(), std::sqrt(track.cYY()) * 1e+4); // convert cm to um + fRegistry.fill(HIST("Track/hDCAzRes_Pt"), track.pt(), std::sqrt(track.cZZ()) * 1e+4); // convert cm to um + + fRegistry.fill(HIST("Track/hNclsTPC"), track.tpcNClsFound()); + fRegistry.fill(HIST("Track/hNcrTPC"), track.tpcNClsCrossedRows()); + fRegistry.fill(HIST("Track/hChi2TPC"), track.tpcChi2NCl()); + fRegistry.fill(HIST("Track/hTPCNcr2Nf"), track.tpcCrossedRowsOverFindableCls()); + fRegistry.fill(HIST("Track/hTPCNcls2Nf"), track.tpcFoundOverFindableCls()); + fRegistry.fill(HIST("Track/hTPCNclsShared"), track.pt(), track.tpcFractionSharedCls()); + fRegistry.fill(HIST("Track/hTPCdEdx"), track.tpcInnerParam(), track.tpcSignal()); + fRegistry.fill(HIST("Track/hTPCdEdxMC"), track.tpcInnerParam(), mcTunedTPCSignal); + fRegistry.fill(HIST("Track/hTPCNsigmaEl"), track.tpcInnerParam(), track.tpcNSigmaEl()); + fRegistry.fill(HIST("Track/hTPCNsigmaPi"), track.tpcInnerParam(), track.tpcNSigmaPi()); + + fRegistry.fill(HIST("Track/hChi2TOF"), track.tofChi2()); + fRegistry.fill(HIST("Track/hTOFbeta"), track.p(), track.beta()); + fRegistry.fill(HIST("Track/hTOFNsigmaEl"), track.p(), track.tofNSigmaEl()); + fRegistry.fill(HIST("Track/hTOFNsigmaPi"), track.p(), track.tofNSigmaPi()); + + fRegistry.fill(HIST("Track/hNclsITS"), track.itsNCls()); + fRegistry.fill(HIST("Track/hChi2ITS"), track.itsChi2NCl()); + fRegistry.fill(HIST("Track/hITSClusterMap"), track.itsClusterMap()); + + int total_cluster_size = 0, nl = 0; + for (unsigned int layer = 0; layer < 7; layer++) { + int cluster_size_per_layer = track.itsClsSizeInLayer(layer); + if (cluster_size_per_layer > 0) { + nl++; } + total_cluster_size += cluster_size_per_layer; + } - int total_cluster_size_ob = 0, nl_ob = 0; - for (unsigned int layer = 3; layer < 7; layer++) { - int cluster_size_per_layer = track.itsClsSizeInLayer(layer); - if (cluster_size_per_layer > 0) { - nl_ob++; - } - total_cluster_size_ob += cluster_size_per_layer; + int total_cluster_size_ib = 0, nl_ib = 0; + for (unsigned int layer = 0; layer < 3; layer++) { + int cluster_size_per_layer = track.itsClsSizeInLayer(layer); + if (cluster_size_per_layer > 0) { + nl_ib++; } - fRegistry.fill(HIST("Track/hMeanClusterSizeITS"), track.p(), static_cast(total_cluster_size) / static_cast(nl) * std::cos(std::atan(track.tgl()))); - fRegistry.fill(HIST("Track/hMeanClusterSizeITSib"), track.p(), static_cast(total_cluster_size_ib) / static_cast(nl_ib) * std::cos(std::atan(track.tgl()))); - fRegistry.fill(HIST("Track/hMeanClusterSizeITSob"), track.p(), static_cast(total_cluster_size_ob) / static_cast(nl_ob) * std::cos(std::atan(track.tgl()))); + total_cluster_size_ib += cluster_size_per_layer; + } - stored_trackIds.emplace_back(std::make_pair(collision.globalIndex(), track.globalIndex())); + int total_cluster_size_ob = 0, nl_ob = 0; + for (unsigned int layer = 3; layer < 7; layer++) { + int cluster_size_per_layer = track.itsClsSizeInLayer(layer); + if (cluster_size_per_layer > 0) { + nl_ob++; + } + total_cluster_size_ob += cluster_size_per_layer; } + fRegistry.fill(HIST("Track/hMeanClusterSizeITS"), track.p(), static_cast(total_cluster_size) / static_cast(nl) * std::cos(std::atan(track.tgl()))); + fRegistry.fill(HIST("Track/hMeanClusterSizeITSib"), track.p(), static_cast(total_cluster_size_ib) / static_cast(nl_ib) * std::cos(std::atan(track.tgl()))); + fRegistry.fill(HIST("Track/hMeanClusterSizeITSob"), track.p(), static_cast(total_cluster_size_ob) / static_cast(nl_ob) * std::cos(std::atan(track.tgl()))); } template @@ -405,9 +419,35 @@ struct skimmerPrimaryElectronFromDalitzEE { if (v12.M() > maxMee) { // don't store continue; } - fillTrackTable(collision, t1); - fillTrackTable(collision, t2); - } // end of pairing + + if (v12.M() < slope * phiv + intercept) { + continue; + } + + if (t1.sign() > 0) { // for positron + if (std::find(acceptedPosTrackIds_per_collision.begin(), acceptedPosTrackIds_per_collision.end(), t1.globalIndex()) == acceptedPosTrackIds_per_collision.end()) { + fillTrackHistograms(t1); + acceptedPosTrackIds_per_collision.emplace_back(t1.globalIndex()); + } + } else { // for electron + if (std::find(acceptedNegTrackIds_per_collision.begin(), acceptedNegTrackIds_per_collision.end(), t1.globalIndex()) == acceptedNegTrackIds_per_collision.end()) { + fillTrackHistograms(t1); + acceptedNegTrackIds_per_collision.emplace_back(t1.globalIndex()); + } + } + + if (t2.sign() > 0) { // for positron + if (std::find(acceptedPosTrackIds_per_collision.begin(), acceptedPosTrackIds_per_collision.end(), t2.globalIndex()) == acceptedPosTrackIds_per_collision.end()) { + fillTrackHistograms(t2); + acceptedPosTrackIds_per_collision.emplace_back(t2.globalIndex()); + } + } else { // for electron + if (std::find(acceptedNegTrackIds_per_collision.begin(), acceptedNegTrackIds_per_collision.end(), t2.globalIndex()) == acceptedNegTrackIds_per_collision.end()) { + fillTrackHistograms(t2); + acceptedNegTrackIds_per_collision.emplace_back(t2.globalIndex()); + } + } + } // end of ULS pairing } else { // LS for (auto& [t1, t2] : combinations(CombinationsStrictlyUpperIndexPolicy(tracks1, tracks2))) { if (!checkTrack(collision, t1) || !checkTrack(collision, t2)) { @@ -423,18 +463,20 @@ struct skimmerPrimaryElectronFromDalitzEE { float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz(), t1.sign(), t2.sign(), d_bz); fRegistry.fill(HIST("Pair/") + HIST(dileptonSigns[pairtype]) + HIST("hMvsPt"), v12.M(), v12.Pt()); fRegistry.fill(HIST("Pair/") + HIST(dileptonSigns[pairtype]) + HIST("hMvsPhiV"), phiv, v12.M()); - } // end of pairing + } // end of LS pairing } } - std::vector> stored_trackIds; - Filter trackFilter = o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& o2::aod::track::itsChi2NCl < maxchi2its&& ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true && nabs(o2::aod::track::dcaXY) < dca_xy_max&& nabs(o2::aod::track::dcaZ) < dca_z_max; + std::vector acceptedPosTrackIds_per_collision; + std::vector acceptedNegTrackIds_per_collision; + std::vector> stored_trackIds; + Filter trackFilter = minpt < o2::aod::track::pt && nabs(o2::aod::track::eta) < maxeta && o2::aod::track::itsChi2NCl < maxchi2its && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true && nabs(o2::aod::track::dcaXY) < dca_xy_max && nabs(o2::aod::track::dcaZ) < dca_z_max; using MyFilteredTracks = soa::Filtered; Partition posTracks = o2::aod::track::signed1Pt > 0.f; Partition negTracks = o2::aod::track::signed1Pt < 0.f; // ---------- for data ---------- - void processRec(MyCollisions const& collisions, aod::BCsWithTimestamps const&, MyFilteredTracks const& tracks) + void processRec(MyCollisions const& collisions, aod::BCsWithTimestamps const&, MyFilteredTracks const& tracks, aod::V0PhotonsKF const& v0photons) { stored_trackIds.reserve(tracks.size()); @@ -445,18 +487,34 @@ struct skimmerPrimaryElectronFromDalitzEE { continue; } - // if (collision.ngpcm() < 1) { - // continue; - // } - - auto posTracks_per_coll = posTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); - auto negTracks_per_coll = negTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); + const auto& v0photons_per_coll = v0photons.sliceBy(perCol_pcm, collision.globalIndex()); + const auto& posTracks_per_coll = posTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); + const auto& negTracks_per_coll = negTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); + acceptedPosTrackIds_per_collision.reserve(posTracks_per_coll.size()); + acceptedNegTrackIds_per_collision.reserve(negTracks_per_coll.size()); fillPairInfo(collision, posTracks_per_coll, negTracks_per_coll); // ULS if (fillLS) { fillPairInfo(collision, posTracks_per_coll, posTracks_per_coll); // LS++ fillPairInfo(collision, negTracks_per_coll, negTracks_per_coll); // LS-- } + + if ((v0photons_per_coll.size() >= 1 && acceptedPosTrackIds_per_collision.size() >= 1 && acceptedNegTrackIds_per_collision.size() >= 1) || (acceptedPosTrackIds_per_collision.size() >= 2 && acceptedNegTrackIds_per_collision.size() >= 2)) { + // LOGF(info, "v0photons_per_coll.size() = %d, acceptedPosTrackIds_per_collision.size() = %d, acceptedNegTrackIds_per_collision.size() = %d", v0photons_per_coll.size(), acceptedPosTrackIds_per_collision.size(), acceptedNegTrackIds_per_collision.size()); + for (const auto& posId : acceptedPosTrackIds_per_collision) { + const auto& pos = tracks.rawIteratorAt(posId); + fillTrackTable(collision, pos); + } + for (const auto& eleId : acceptedNegTrackIds_per_collision) { + const auto& ele = tracks.rawIteratorAt(eleId); + fillTrackTable(collision, ele); + } + } + + acceptedPosTrackIds_per_collision.clear(); + acceptedPosTrackIds_per_collision.shrink_to_fit(); + acceptedNegTrackIds_per_collision.clear(); + acceptedNegTrackIds_per_collision.shrink_to_fit(); } // end of collision loop stored_trackIds.clear(); @@ -464,7 +522,7 @@ struct skimmerPrimaryElectronFromDalitzEE { } PROCESS_SWITCH(skimmerPrimaryElectronFromDalitzEE, processRec, "process reconstructed info only", true); // standalone - void processRec_SWT(MyCollisionsWithSWT const& collisions, aod::BCsWithTimestamps const&, MyFilteredTracks const& tracks) + void processRec_SWT(MyCollisionsWithSWT const& collisions, aod::BCsWithTimestamps const&, MyFilteredTracks const& tracks, aod::V0PhotonsKF const& v0photons) { stored_trackIds.reserve(tracks.size()); @@ -475,22 +533,38 @@ struct skimmerPrimaryElectronFromDalitzEE { continue; } - // if (collision.ngpcm() < 1) { - // continue; - // } - if (collision.swtaliastmp_raw() == 0) { continue; } - auto posTracks_per_coll = posTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); - auto negTracks_per_coll = negTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); + const auto& v0photons_per_coll = v0photons.sliceBy(perCol_pcm, collision.globalIndex()); + const auto& posTracks_per_coll = posTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); + const auto& negTracks_per_coll = negTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); + acceptedPosTrackIds_per_collision.reserve(posTracks_per_coll.size()); + acceptedNegTrackIds_per_collision.reserve(negTracks_per_coll.size()); fillPairInfo(collision, posTracks_per_coll, negTracks_per_coll); // ULS if (fillLS) { fillPairInfo(collision, posTracks_per_coll, posTracks_per_coll); // LS++ fillPairInfo(collision, negTracks_per_coll, negTracks_per_coll); // LS-- } + + if ((v0photons_per_coll.size() >= 1 && acceptedPosTrackIds_per_collision.size() >= 1 && acceptedNegTrackIds_per_collision.size() >= 1) || (acceptedPosTrackIds_per_collision.size() >= 2 && acceptedNegTrackIds_per_collision.size() >= 2)) { + // LOGF(info, "v0photons_per_coll.size() = %d, acceptedPosTrackIds_per_collision.size() = %d, acceptedNegTrackIds_per_collision.size() = %d", v0photons_per_coll.size(), acceptedPosTrackIds_per_collision.size(), acceptedNegTrackIds_per_collision.size()); + for (const auto& posId : acceptedPosTrackIds_per_collision) { + const auto& pos = tracks.rawIteratorAt(posId); + fillTrackTable(collision, pos); + } + for (const auto& eleId : acceptedNegTrackIds_per_collision) { + const auto& ele = tracks.rawIteratorAt(eleId); + fillTrackTable(collision, ele); + } + } + + acceptedPosTrackIds_per_collision.clear(); + acceptedPosTrackIds_per_collision.shrink_to_fit(); + acceptedNegTrackIds_per_collision.clear(); + acceptedNegTrackIds_per_collision.shrink_to_fit(); } // end of collision loop stored_trackIds.clear(); @@ -502,32 +576,47 @@ struct skimmerPrimaryElectronFromDalitzEE { Partition posTracksMC = o2::aod::track::signed1Pt > 0.f; Partition negTracksMC = o2::aod::track::signed1Pt < 0.f; // ---------- for MC ---------- - void processMC(MyCollisionsMC const& collisions, aod::McCollisions const&, aod::BCsWithTimestamps const&, MyFilteredTracksMC const& tracks) + void processMC(MyCollisionsMC const& collisions, aod::McCollisions const&, aod::BCsWithTimestamps const&, MyFilteredTracksMC const& tracks, aod::V0PhotonsKF const& v0photons) { stored_trackIds.reserve(tracks.size()); for (const auto& collision : collisions) { + auto bc = collision.template foundBC_as(); + initCCDB(bc); if (!collision.has_mcCollision()) { continue; } if (!collision.isSelected()) { continue; } - auto bc = collision.template foundBC_as(); - initCCDB(bc); - - // if (collision.ngpcm() < 1) { - // continue; - // } - auto posTracks_per_coll = posTracksMC->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); - auto negTracks_per_coll = negTracksMC->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); + const auto& v0photons_per_coll = v0photons.sliceBy(perCol_pcm, collision.globalIndex()); + const auto& posTracks_per_coll = posTracksMC->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); + const auto& negTracks_per_coll = negTracksMC->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); + acceptedPosTrackIds_per_collision.reserve(posTracks_per_coll.size()); + acceptedNegTrackIds_per_collision.reserve(negTracks_per_coll.size()); fillPairInfo(collision, posTracks_per_coll, negTracks_per_coll); // ULS if (fillLS) { fillPairInfo(collision, posTracks_per_coll, posTracks_per_coll); // LS++ fillPairInfo(collision, negTracks_per_coll, negTracks_per_coll); // LS-- } + if ((v0photons_per_coll.size() >= 1 && acceptedPosTrackIds_per_collision.size() >= 1 && acceptedNegTrackIds_per_collision.size() >= 1) || (acceptedPosTrackIds_per_collision.size() >= 2 && acceptedNegTrackIds_per_collision.size() >= 2)) { + // LOGF(info, "v0photons_per_coll.size() = %d, acceptedPosTrackIds_per_collision.size() = %d, acceptedNegTrackIds_per_collision.size() = %d", v0photons_per_coll.size(), acceptedPosTrackIds_per_collision.size(), acceptedNegTrackIds_per_collision.size()); + for (const auto& posId : acceptedPosTrackIds_per_collision) { + const auto& pos = tracks.rawIteratorAt(posId); + fillTrackTable(collision, pos); + } + for (const auto& eleId : acceptedNegTrackIds_per_collision) { + const auto& ele = tracks.rawIteratorAt(eleId); + fillTrackTable(collision, ele); + } + } + + acceptedPosTrackIds_per_collision.clear(); + acceptedPosTrackIds_per_collision.shrink_to_fit(); + acceptedNegTrackIds_per_collision.clear(); + acceptedNegTrackIds_per_collision.shrink_to_fit(); } // end of collision loop stored_trackIds.clear(); diff --git a/PWGEM/PhotonMeson/Tasks/CMakeLists.txt b/PWGEM/PhotonMeson/Tasks/CMakeLists.txt index e839592246a..332cafc0795 100644 --- a/PWGEM/PhotonMeson/Tasks/CMakeLists.txt +++ b/PWGEM/PhotonMeson/Tasks/CMakeLists.txt @@ -9,6 +9,8 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. +add_subdirectory(Converters) + o2physics_add_dpl_workflow(gammaconversions SOURCES gammaConversions.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore @@ -159,6 +161,12 @@ o2physics_add_dpl_workflow(diphoton-hadron-mpc-pcmpcm PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGEMPhotonMesonCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(compconvbuilder + SOURCES compconvbuilder.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGEMPhotonMesonCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(diphoton-hadron-mpc-pcmdalitzee SOURCES diphotonHadronMPCPCMDalitzEE.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGEMPhotonMesonCore diff --git a/PWGEM/PhotonMeson/Tasks/Converters/CMakeLists.txt b/PWGEM/PhotonMeson/Tasks/Converters/CMakeLists.txt new file mode 100644 index 00000000000..89aceb70f98 --- /dev/null +++ b/PWGEM/PhotonMeson/Tasks/Converters/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. + +o2physics_add_dpl_workflow(pcm-converter1 + SOURCES pcmConverter1.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(electron-from-dalitz-converter1 + SOURCES electronFromDalitzConverter1.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGEM/PhotonMeson/Tasks/Converters/electronFromDalitzConverter1.cxx b/PWGEM/PhotonMeson/Tasks/Converters/electronFromDalitzConverter1.cxx new file mode 100644 index 00000000000..961f8b0dfe7 --- /dev/null +++ b/PWGEM/PhotonMeson/Tasks/Converters/electronFromDalitzConverter1.cxx @@ -0,0 +1,69 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// ======================== +// +// This code runs loop over ULS ee pars for virtual photon QC. +// Please write to: daiki.sekihata@cern.ch + +#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" + +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +using namespace o2; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +struct electronFromDalitzConverter1 { + Produces electron_001; + + void process(aod::EMPrimaryElectronsFromDalitz_000 const& tracks) + { + for (const auto& track : tracks) { + electron_001(track.collisionId(), + track.trackId(), + track.sign(), + track.pt(), + track.eta(), + track.phi(), + track.dcaXY(), + track.dcaZ(), + track.cYY(), + track.cZY(), + track.cZZ(), + track.tpcNClsFindable(), + track.tpcNClsFindableMinusFound(), + track.tpcNClsFindableMinusCrossedRows(), + track.tpcNClsShared(), + track.tpcChi2NCl(), + track.tpcInnerParam(), + track.tpcSignal(), + track.tpcNSigmaEl(), + track.tpcNSigmaPi(), + track.beta(), + track.tofNSigmaEl(), + track.itsClusterSizes(), + track.itsChi2NCl(), + track.tofChi2(), + track.detectorMap()); + + } // end of track loop + } // end of process +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"electronFromDalitz-converter1"})}; +} diff --git a/PWGEM/PhotonMeson/Tasks/Converters/pcmConverter1.cxx b/PWGEM/PhotonMeson/Tasks/Converters/pcmConverter1.cxx new file mode 100644 index 00000000000..1607c30b94a --- /dev/null +++ b/PWGEM/PhotonMeson/Tasks/Converters/pcmConverter1.cxx @@ -0,0 +1,88 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// ======================== +// +// This code runs loop over ULS ee pars for virtual photon QC. +// Please write to: daiki.sekihata@cern.ch + +#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" + +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +using namespace o2; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +struct pcmConverter1 { + Produces v0photon_001; + Produces v0leg_001; + + void process(aod::V0PhotonsKF_000 const& v0s, aod::V0Legs_000 const& v0legs) + { + for (auto& v0 : v0s) { + v0photon_001( + v0.collisionId(), + v0.v0Id(), + v0.posTrackId(), + v0.negTrackId(), + v0.vx(), + v0.vy(), + v0.vz(), + v0.px(), + v0.py(), + v0.pz(), + v0.mGamma(), + v0.dcaXYtopv(), + v0.dcaZtopv(), + v0.cospa(), + v0.cospaXY(), + v0.cospaRZ(), + v0.pca(), + v0.alpha(), + v0.qtarm(), + v0.chiSquareNDF()); + } // end of v0 loop + + for (auto& v0leg : v0legs) { + v0leg_001( + v0leg.collisionId(), + v0leg.trackId(), + v0leg.sign(), + v0leg.px(), + v0leg.py(), + v0leg.pz(), + v0leg.dcaXY(), + v0leg.dcaZ(), + v0leg.tpcNClsFindable(), + v0leg.tpcNClsFindableMinusFound(), + v0leg.tpcNClsFindableMinusCrossedRows(), + v0leg.tpcNClsShared(), + v0leg.tpcChi2NCl(), + v0leg.tpcInnerParam(), + v0leg.tpcSignal(), + v0leg.tpcNSigmaEl(), + v0leg.tpcNSigmaPi(), + v0leg.itsClusterSizes(), + v0leg.itsChi2NCl(), + v0leg.detectorMap()); + } // end of v0leg loop + } // end of process +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"pcm-converter1"})}; +} diff --git a/PWGEM/PhotonMeson/Tasks/OmegaMesonEMC.cxx b/PWGEM/PhotonMeson/Tasks/OmegaMesonEMC.cxx index 6ac2788f549..d113fb5720b 100644 --- a/PWGEM/PhotonMeson/Tasks/OmegaMesonEMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/OmegaMesonEMC.cxx @@ -85,6 +85,9 @@ struct OmegaMesonEMC { Configurable confEvtZvtx{"confEvtZvtx", 10.f, "Evt sel: Max. z-Vertex (cm)"}; Configurable confEvtRequireSel8{"confEvtRequireSel8", true, "Evt sel: check for sel8 trigger bit"}; Configurable confEvtRequirekTVXinEMC{"confEvtRequirekTVXinEMC", false, "Evt sel: check for EMCal MB trigger kTVXinEMC"}; + Configurable confEvtRequireL0{"confEvtRequireL0", false, "Evt sel: check for EMCal L0 trigger"}; + Configurable confEvtRequireGoodZVertex{"confEvtRequireGoodZVertex", false, "Evt sel: check for EMCal good z-vertex"}; + Configurable confEvtRequireNoSameBunchPileUp{"confEvtRequireNoSameBunchPileUp", false, "Evt sel: check for no same bunch pile-up"}; // ---> Track selection Configurable> cfgChargedPionCuts{"cfgChargedPionCuts", {hnm::chargedPionCutsTable[0], 3, 2, hnm::chargedPionCutsName, hnm::chargedPionMinMaxName}, "Charged pion track cuts"}; @@ -224,6 +227,12 @@ struct OmegaMesonEMC { return; // Skip this collision if sel8 trigger bit is not set if (confEvtRequirekTVXinEMC && !iskTVXinEMC) return; // Skip this collision if kTVXinEMC trigger bit is not set + if (confEvtRequireL0 && !isL0Triggered) + return; // Skip this collision if L0 trigger bit is not set + if (confEvtRequireGoodZVertex && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + return; // Skip this collision if good z-vertex condition is not met + if (confEvtRequireNoSameBunchPileUp && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + return; // Skip this collision if no same bunch pileup condition is not met if (bcHasEMCCells && iskTVXinEMC) mHistManager.fill(HIST("Event/nEMCalEvents"), 0); diff --git a/PWGEM/PhotonMeson/Tasks/SinglePhoton.cxx b/PWGEM/PhotonMeson/Tasks/SinglePhoton.cxx index 9c82fa7b09a..d00c2e9732f 100644 --- a/PWGEM/PhotonMeson/Tasks/SinglePhoton.cxx +++ b/PWGEM/PhotonMeson/Tasks/SinglePhoton.cxx @@ -14,29 +14,37 @@ // This code loops over photon candidate and fill histograms // Please write to: daiki.sekihata@cern.ch -#include -#include - -#include "TString.h" -#include "Math/Vector4D.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" -#include "Common/Core/trackUtilities.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/PIDResponse.h" -#include "Common/Core/RecoDecay.h" -#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" -#include "PWGEM/PhotonMeson/Core/V0PhotonCut.h" -#include "PWGEM/PhotonMeson/Core/PHOSPhotonCut.h" -#include "PWGEM/PhotonMeson/Core/EMCPhotonCut.h" +#include "EMPhotonEventCut.h" + #include "PWGEM/PhotonMeson/Core/CutsLibrary.h" +#include "PWGEM/PhotonMeson/Core/EMCPhotonCut.h" #include "PWGEM/PhotonMeson/Core/HistogramsLibrary.h" +#include "PWGEM/PhotonMeson/Core/PHOSPhotonCut.h" +#include "PWGEM/PhotonMeson/Core/V0PhotonCut.h" +#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" + +#include "Common/CCDB/TriggerAliases.h" +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Centrality.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::aod; @@ -266,8 +274,8 @@ struct SinglePhoton { return is_selected; } - template - void FillPhoton(TEvents const& collisions, TPhotons1 const& photons1, TPreslice1 const& perCollision1, TCuts1 const& cuts1, TV0Legs const&, TEMCMatchedTracks const&) + template + void FillPhoton(TEvents const& collisions, TPhotons1 const& photons1, TPreslice1 const& perCollision1, TCuts1 const& cuts1, TV0Legs const&) { THashList* list_ev_before = static_cast(fMainList->FindObject("Event")->FindObject(detnames[photontype].data())->FindObject(event_types[0].data())); THashList* list_ev_after = static_cast(fMainList->FindObject("Event")->FindObject(detnames[photontype].data())->FindObject(event_types[1].data())); @@ -339,17 +347,17 @@ struct SinglePhoton { void processPCM(MyCollisions const&, MyV0Photons const& v0photons, aod::V0Legs const& legs) { - FillPhoton(grouped_collisions, v0photons, perCollision, fPCMCuts, legs, nullptr); + FillPhoton(grouped_collisions, v0photons, perCollision, fPCMCuts, legs); } // void processPHOS(MyCollisions const& collisions, aod::PHOSClusters const& phosclusters) // { - // FillPhoton(grouped_collisions, phosclusters, perCollision_phos, fPHOSCuts, nullptr, nullptr); + // FillPhoton(grouped_collisions, phosclusters, perCollision_phos, fPHOSCuts, nullptr); // } - // void processEMC(MyCollisions const& collisions, aod::SkimEMCClusters const& emcclusters, aod::SkimEMCMTs const& emcmatchedtracks) + // void processEMC(MyCollisions const& collisions, aod::SkimEMCClusters const& emcclusters) // { - // FillPhoton(grouped_collisions, emcclusters, perCollision_emc, fEMCCuts, nullptr, emcmatchedtracks); + // FillPhoton(grouped_collisions, emcclusters, perCollision_emc, fEMCCuts, nullptr); // } void processDummy(MyCollisions::iterator const&) {} diff --git a/PWGEM/PhotonMeson/Tasks/SinglePhotonMC.cxx b/PWGEM/PhotonMeson/Tasks/SinglePhotonMC.cxx index ccb33db7f3a..dd09bc17c4a 100644 --- a/PWGEM/PhotonMeson/Tasks/SinglePhotonMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/SinglePhotonMC.cxx @@ -14,32 +14,35 @@ // This code loops over photon candidate and fill histograms // Please write to: daiki.sekihata@cern.ch -#include -#include - -#include "TString.h" -#include "TMath.h" -#include "Math/Vector4D.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" -#include "Common/Core/trackUtilities.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/PIDResponse.h" -#include "Common/Core/RecoDecay.h" -#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" -#include "PWGEM/PhotonMeson/Utils/MCUtilities.h" -#include "PWGEM/PhotonMeson/Core/V0PhotonCut.h" -#include "PWGEM/PhotonMeson/Core/PHOSPhotonCut.h" -#include "PWGEM/PhotonMeson/Core/EMCPhotonCut.h" +#include "EMPhotonEventCut.h" + +#include "PWGEM/Dilepton/Utils/MCUtilities.h" #include "PWGEM/PhotonMeson/Core/CutsLibrary.h" +#include "PWGEM/PhotonMeson/Core/EMCPhotonCut.h" #include "PWGEM/PhotonMeson/Core/HistogramsLibrary.h" -#include "PWGEM/Dilepton/Utils/MCUtilities.h" +#include "PWGEM/PhotonMeson/Core/PHOSPhotonCut.h" +#include "PWGEM/PhotonMeson/Core/V0PhotonCut.h" +#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" +#include "PWGEM/PhotonMeson/Utils/MCUtilities.h" + +#include "Common/CCDB/TriggerAliases.h" +#include "Common/DataModel/Centrality.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include using namespace o2; using namespace o2::aod; @@ -272,8 +275,8 @@ struct SinglePhotonMC { return is_selected; } - template - void FillTruePhoton(TEvents const& collisions, TPhotons1 const& photons1, TPreslice1 const& perCollision1, TCuts1 const& cuts1, TV0Legs const&, TEMCMatchedTracks const&, TMCParticles const& mcparticles, TMCEvents const&) + template + void FillTruePhoton(TEvents const& collisions, TPhotons1 const& photons1, TPreslice1 const& perCollision1, TCuts1 const& cuts1, TV0Legs const&, TMCParticles const& mcparticles, TMCEvents const&) { THashList* list_ev_before = static_cast(fMainList->FindObject("Event")->FindObject(detnames[photontype].data())->FindObject(event_types[0].data())); THashList* list_ev_after = static_cast(fMainList->FindObject("Event")->FindObject(detnames[photontype].data())->FindObject(event_types[1].data())); @@ -351,25 +354,25 @@ struct SinglePhotonMC { } } // end of photon loop - } // end of cut loop - } // end of collision loop + } // end of cut loop + } // end of collision loop } Partition grouped_collisions = (cfgCentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < cfgCentMax) || (cfgCentMin < o2::aod::cent::centFT0A && o2::aod::cent::centFT0A < cfgCentMax) || (cfgCentMin < o2::aod::cent::centFT0C && o2::aod::cent::centFT0C < cfgCentMax); // this goes to same event. void processPCM(MyCollisions const&, MyV0Photons const& v0photons, MyMCV0Legs const& legs, aod::EMMCParticles const& mcparticles, aod::EMMCEvents const& mccollisions) { - FillTruePhoton(grouped_collisions, v0photons, perCollision, fPCMCuts, legs, nullptr, mcparticles, mccollisions); + FillTruePhoton(grouped_collisions, v0photons, perCollision, fPCMCuts, legs, mcparticles, mccollisions); } // void processPHOS(MyCollisions const& collisions, aod::PHOSClusters const& phosclusters, aod::EMMCParticles const& mcparticles, aod::EMMCEvents const& mccollisions) // { - // FillTruePhoton(grouped_collisions, phosclusters, perCollision_phos, fPHOSCuts, nullptr, nullptr, mcparticles, mccollisions); + // FillTruePhoton(grouped_collisions, phosclusters, perCollision_phos, fPHOSCuts, nullptr, mcparticles, mccollisions); // } - // void processEMC(MyCollisions const& collisions, aod::SkimEMCClusters const& emcclusters, aod::SkimEMCMTs const& emcmatchedtracks, aod::EMMCParticles const& mcparticles, aod::EMMCEvents const& mccollisions) + // void processEMC(MyCollisions const& collisions, aod::SkimEMCClusters const& emcclusters, aod::EMMCParticles const& mcparticles, aod::EMMCEvents const& mccollisions) // { - // FillTruePhoton(grouped_collisions, emcclusters, perCollision_emc, fEMCCuts, nullptr, emcmatchedtracks, mcparticles, mccollisions); + // FillTruePhoton(grouped_collisions, emcclusters, perCollision_emc, fEMCCuts, nullptr, mcparticles, mccollisions); // } PresliceUnsorted perMcCollision = aod::emmcparticle::emmceventId; diff --git a/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx b/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx index 2f91a62dc43..17989065391 100644 --- a/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx +++ b/PWGEM/PhotonMeson/Tasks/TagAndProbe.cxx @@ -14,28 +14,47 @@ // This code is for data-driven efficiency for photon analyses. tag and probe method // Please write to: daiki.sekihata@cern.ch -#include -#include - -#include "TString.h" -#include "Math/Vector4D.h" -#include "Math/Vector3D.h" -#include "Math/LorentzRotation.h" -#include "Math/Rotation3D.h" -#include "Math/AxisAngle.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "Common/Core/RecoDecay.h" -#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" -#include "PWGEM/PhotonMeson/Utils/PairUtilities.h" -#include "PWGEM/PhotonMeson/Core/V0PhotonCut.h" -#include "PWGEM/PhotonMeson/Core/PHOSPhotonCut.h" -#include "PWGEM/PhotonMeson/Core/EMCPhotonCut.h" -#include "PWGEM/PhotonMeson/Core/PairCut.h" +#include "EMPhotonEventCut.h" + #include "PWGEM/PhotonMeson/Core/CutsLibrary.h" +#include "PWGEM/PhotonMeson/Core/EMCPhotonCut.h" #include "PWGEM/PhotonMeson/Core/HistogramsLibrary.h" +#include "PWGEM/PhotonMeson/Core/PHOSPhotonCut.h" +#include "PWGEM/PhotonMeson/Core/PairCut.h" +#include "PWGEM/PhotonMeson/Core/V0PhotonCut.h" +#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" +#include "PWGEM/PhotonMeson/Utils/PairUtilities.h" + +#include "Common/CCDB/TriggerAliases.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include using namespace o2; using namespace o2::aod; @@ -126,7 +145,7 @@ struct TagAndProbe { THashList* list_pair_subsys_paircut = reinterpret_cast(list_pair_subsys_photoncut->FindObject(pair_cut_name.data())); o2::aod::pwgem::photon::histogram::DefineHistograms(list_pair_subsys_paircut, "tag_and_probe", pairname.data()); } // end of cut3 loop pair cut - } // end of cut2 loop + } // end of cut2 loop } static constexpr std::string_view pairnames[6] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PHOSEMC"}; @@ -232,8 +251,8 @@ struct TagAndProbe { Preslice perCollision_phos = aod::skimmedcluster::collisionId; Preslice perCollision_emc = aod::skimmedcluster::collisionId; - template - void SameEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TTagCut const& tagcut, TProbeCuts const& probecuts, TPairCuts const& paircuts, TLegs const& /*legs*/, TEMCMTs const& emcmatchedtracks) + template + void SameEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TTagCut const& tagcut, TProbeCuts const& probecuts, TPairCuts const& paircuts, TLegs const& /*legs*/) { THashList* list_ev_pair_before = static_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject(event_types[0].data())); THashList* list_ev_pair_after = static_cast(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject(event_types[1].data())); @@ -315,13 +334,13 @@ struct TagAndProbe { reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", tagcut.GetName(), probecut.GetName()))->FindObject(paircut.GetName())->FindObject("hMggPt_PassingProbe_Same"))->Fill(v12.M(), v2.Pt()); if constexpr (pairtype == PairType::kEMCEMC) { - RotationBackground(v12, v1, v2, photons2_coll, g1.globalIndex(), g2.globalIndex(), probecut, paircut, emcmatchedtracks); + RotationBackground(v12, v1, v2, photons2_coll, g1.globalIndex(), g2.globalIndex(), probecut, paircut); } } // end of probe cut loop - } // end of pair cut loop - } // end of g2 loop - } // end of g1 loop - } // end of collision loop + } // end of pair cut loop + } // end of g2 loop + } // end of g1 loop + } // end of collision loop } Configurable ndepth{"ndepth", 10, "depth for event mixing"}; @@ -334,8 +353,8 @@ struct TagAndProbe { BinningType_A colBinning_A{{ConfVtxBins, ConfCentBins}, true}; BinningType_C colBinning_C{{ConfVtxBins, ConfCentBins}, true}; - template - void MixedEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TTagCut const& tagcut, TProbeCuts const& probecuts, TPairCuts const& paircuts, TLegs const& /*legs*/, TEMCMTs const& /*emcmatchedtracks*/, TMixedBinning const& colBinning) + template + void MixedEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TTagCut const& tagcut, TProbeCuts const& probecuts, TPairCuts const& paircuts, TLegs const& /*legs*/, TMixedBinning const& colBinning) { THashList* list_pair_ss = static_cast(fMainList->FindObject("Pair")->FindObject(pairnames[pairtype].data())); @@ -406,15 +425,15 @@ struct TagAndProbe { reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", tagcut.GetName(), probecut.GetName()))->FindObject(paircut.GetName())->FindObject("hMggPt_PassingProbe_Mixed"))->Fill(v12.M(), v2.Pt()); } // end of probe cut loop - } // end of pair cut loop - } // end of g2 loop - } // end of g1 loop - } // end of different collision combinations + } // end of pair cut loop + } // end of g2 loop + } // end of g1 loop + } // end of different collision combinations } /// \brief Calculate background (using rotation background method only for EMCal!) template - void RotationBackground(const ROOT::Math::PtEtaPhiMVector& meson, ROOT::Math::PtEtaPhiMVector photon1, ROOT::Math::PtEtaPhiMVector photon2, TPhotons const& photons_coll, unsigned int ig1, unsigned int ig2, EMCPhotonCut const& cut, PairCut const& paircut, SkimEMCMTs const& /*emcmatchedtracks*/) + void RotationBackground(const ROOT::Math::PtEtaPhiMVector& meson, ROOT::Math::PtEtaPhiMVector photon1, ROOT::Math::PtEtaPhiMVector photon2, TPhotons const& photons_coll, unsigned int ig1, unsigned int ig2, EMCPhotonCut const& cut, PairCut const& paircut) { // if less than 3 clusters are present skip event since we need at least 3 clusters if (photons_coll.size() < 3) { @@ -442,7 +461,7 @@ struct TagAndProbe { // only combine rotated photons with other photons continue; } - if (!cut.template IsSelected(photon)) { + if (!cut.template IsSelected(photon)) { continue; } @@ -474,32 +493,32 @@ struct TagAndProbe { } Partition grouped_collisions = cfgCentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < cfgCentMax; // this goes to same event. - Filter collisionFilter_common = nabs(o2::aod::collision::posZ) < 10.f && o2::aod::collision::numContrib > (uint16_t)0 && o2::aod::evsel::sel8 == true; + Filter collisionFilter_common = nabs(o2::aod::collision::posZ) < 10.f && o2::aod::collision::numContrib > static_cast(0) && o2::aod::evsel::sel8 == true; Filter collisionFilter_centrality = (cfgCentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < cfgCentMax) || (cfgCentMin < o2::aod::cent::centFT0A && o2::aod::cent::centFT0A < cfgCentMax) || (cfgCentMin < o2::aod::cent::centFT0C && o2::aod::cent::centFT0C < cfgCentMax); using MyFilteredCollisions = soa::Filtered; // this goes to mixed event. void processPCMPCM(MyCollisions const&, MyFilteredCollisions const& filtered_collisions, MyV0Photons const& v0photons, aod::V0Legs const& legs) { - SameEventPairing(grouped_collisions, v0photons, v0photons, perCollision, perCollision, fTagPCMCut, fProbePCMCuts, fPairCuts, legs, nullptr); + SameEventPairing(grouped_collisions, v0photons, v0photons, perCollision, perCollision, fTagPCMCut, fProbePCMCuts, fPairCuts, legs); if (cfgCentEstimator == 0) { - MixedEventPairing(filtered_collisions, v0photons, v0photons, perCollision, perCollision, fTagPCMCut, fProbePCMCuts, fPairCuts, legs, nullptr, colBinning_M); + MixedEventPairing(filtered_collisions, v0photons, v0photons, perCollision, perCollision, fTagPCMCut, fProbePCMCuts, fPairCuts, legs, colBinning_M); } else if (cfgCentEstimator == 1) { - MixedEventPairing(filtered_collisions, v0photons, v0photons, perCollision, perCollision, fTagPCMCut, fProbePCMCuts, fPairCuts, legs, nullptr, colBinning_A); + MixedEventPairing(filtered_collisions, v0photons, v0photons, perCollision, perCollision, fTagPCMCut, fProbePCMCuts, fPairCuts, legs, colBinning_A); } else if (cfgCentEstimator == 2) { - MixedEventPairing(filtered_collisions, v0photons, v0photons, perCollision, perCollision, fTagPCMCut, fProbePCMCuts, fPairCuts, legs, nullptr, colBinning_C); + MixedEventPairing(filtered_collisions, v0photons, v0photons, perCollision, perCollision, fTagPCMCut, fProbePCMCuts, fPairCuts, legs, colBinning_C); } } void processPHOSPHOS(MyCollisions const&, MyFilteredCollisions const& filtered_collisions, aod::PHOSClusters const& phosclusters) { - SameEventPairing(grouped_collisions, phosclusters, phosclusters, perCollision_phos, perCollision_phos, fTagPHOSCut, fProbePHOSCuts, fPairCuts, nullptr, nullptr); - MixedEventPairing(filtered_collisions, phosclusters, phosclusters, perCollision_phos, perCollision_phos, fTagPHOSCut, fProbePHOSCuts, fPairCuts, nullptr, nullptr, colBinning_C); + SameEventPairing(grouped_collisions, phosclusters, phosclusters, perCollision_phos, perCollision_phos, fTagPHOSCut, fProbePHOSCuts, fPairCuts, nullptr); + MixedEventPairing(filtered_collisions, phosclusters, phosclusters, perCollision_phos, perCollision_phos, fTagPHOSCut, fProbePHOSCuts, fPairCuts, nullptr, colBinning_C); } - void processEMCEMC(MyCollisions const&, MyFilteredCollisions const& filtered_collisions, aod::SkimEMCClusters const& emcclusters, aod::SkimEMCMTs const& emcmatchedtracks) + void processEMCEMC(MyCollisions const&, MyFilteredCollisions const& filtered_collisions, aod::SkimEMCClusters const& emcclusters) { - SameEventPairing(grouped_collisions, emcclusters, emcclusters, perCollision_emc, perCollision_emc, fTagEMCCut, fProbeEMCCuts, fPairCuts, nullptr, emcmatchedtracks); - MixedEventPairing(filtered_collisions, emcclusters, emcclusters, perCollision_emc, perCollision_emc, fTagEMCCut, fProbeEMCCuts, fPairCuts, nullptr, emcmatchedtracks, colBinning_C); + SameEventPairing(grouped_collisions, emcclusters, emcclusters, perCollision_emc, perCollision_emc, fTagEMCCut, fProbeEMCCuts, fPairCuts, nullptr); + MixedEventPairing(filtered_collisions, emcclusters, emcclusters, perCollision_emc, perCollision_emc, fTagEMCCut, fProbeEMCCuts, fPairCuts, nullptr, colBinning_C); } void processDummy(MyCollisions const&) {} diff --git a/PWGEM/PhotonMeson/Tasks/compconvbuilder.cxx b/PWGEM/PhotonMeson/Tasks/compconvbuilder.cxx new file mode 100644 index 00000000000..d2aafe07b2f --- /dev/null +++ b/PWGEM/PhotonMeson/Tasks/compconvbuilder.cxx @@ -0,0 +1,876 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file compconvbuilder.cxx +/// \brief QA task for photons in the EM and LF builder +/// \author S. Mrozinski, smrozins@cern.ch + +#include "PWGEM/Dilepton/Utils/MCUtilities.h" +#include "PWGEM/PhotonMeson/Core/EMPhotonEventCut.h" +#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" +#include "PWGLF/DataModel/LFStrangenessMLTables.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/Core/RecoDecay.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::aod; +using namespace o2::soa; +using namespace o2::constants; + +using namespace o2::aod::pwgem::dilepton::utils::mcutil; + +using MyV0Photons = soa::Join; +using MyMCV0Legs = soa::Join; +using MyMCV0Leg = MyMCV0Legs::iterator; + +using MyCollisions = soa::Join; +using MyCollision = MyCollisions::iterator; + +using MyMCCollisions = soa::Join; +using MyMCCollision = MyMCCollisions::iterator; + +using MyStraCollisions = soa::Join; +using MyStraCollision = MyStraCollisions::iterator; + +using MyTracksIUMC = soa::Join; + +using V0DerivedMCDatas = soa::Join; + +using DauTracks = soa::Join; + +struct Compconvbuilder { + HistogramRegistry registry{"Compconvbuilder"}; + + enum ConversionBuilderID { + EMBuilder = 0, + LFBuilder = 1, + EMOnly = 2, + LFOnly = 3, + Common = 4, + NConversionBuilder + }; + + static constexpr std::string_view kConversionBuilder[NConversionBuilder] = {"EMBuilder/", "LFBuilder/", "EMOnly/", "LFOnly/", "Common/"}; + static constexpr std::string_view kEventTypes[2] = {"before/", "after/"}; + + EMPhotonEventCut fEMEventCut; + struct : ConfigurableGroup { + std::string prefix = "eventcut_group"; + Configurable cfgZvtxMax{"cfgZvtxMax", 10.f, "max. Zvtx"}; + Configurable cfgRequireSel8{"cfgRequireSel8", true, "require sel8 in event cut"}; + Configurable cfgRequireFT0AND{"cfgRequireFT0AND", true, "require FT0AND in event cut"}; + Configurable cfgRequireNoTFB{"cfgRequireNoTFB", true, "require No time frame border in event cut"}; + Configurable cfgRequireNoITSROFB{"cfgRequireNoITSROFB", true, "require no ITS readout frame border in event cut"}; + Configurable cfgRequireNoSameBunchPileup{"cfgRequireNoSameBunchPileup", false, "require no same bunch pileup in event cut"}; + Configurable cfgRequireVertexITSTPC{"cfgRequireVertexITSTPC", false, "require Vertex ITSTPC in event cut"}; // ITS-TPC matched track contributes PV. + Configurable cfgRequireGoodZvtxFT0vsPV{"cfgRequireGoodZvtxFT0vsPV", false, "require good Zvtx between FT0 vs. PV in event cut"}; + Configurable cfgTrackOccupancyMin{"cfgTrackOccupancyMin", -2, "min. occupancy"}; + Configurable cfgTrackOccupancyMax{"cfgTrackOccupancyMax", 1000000000, "max. occupancy"}; + Configurable cfgFT0COccupancyMin{"cfgFT0COccupancyMin", -2, "min. FT0C occupancy"}; + Configurable cfgFT0COccupancyMax{"cfgFT0COccupancyMax", 1000000000, "max. FT0C occupancy"}; + Configurable cfgRequireNoCollInTimeRangeStandard{"cfgRequireNoCollInTimeRangeStandard", false, "require no collision in time range standard"}; + Configurable cfgRequireNoCollInTimeRangeStrict{"cfgRequireNoCollInTimeRangeStrict", false, "require no collision in time range strict"}; + Configurable cfgRequireNoCollInITSROFStandard{"cfgRequireNoCollInITSROFStandard", false, "require no collision in time range standard"}; + Configurable cfgRequireNoCollInITSROFStrict{"cfgRequireNoCollInITSROFStrict", false, "require no collision in time range strict"}; + Configurable cfgRequireNoHighMultCollInPrevRof{"cfgRequireNoHighMultCollInPrevRof", false, "require no HM collision in previous ITS ROF"}; + } eventcuts; + + void defineEMEventCut() + { + fEMEventCut = EMPhotonEventCut("fEMEventCut", "fEMEventCut"); + fEMEventCut.SetRequireSel8(eventcuts.cfgRequireSel8); + fEMEventCut.SetRequireFT0AND(eventcuts.cfgRequireFT0AND); + fEMEventCut.SetZvtxRange(-eventcuts.cfgZvtxMax, +eventcuts.cfgZvtxMax); + fEMEventCut.SetRequireNoTFB(eventcuts.cfgRequireNoTFB); + fEMEventCut.SetRequireNoITSROFB(eventcuts.cfgRequireNoITSROFB); + fEMEventCut.SetRequireNoSameBunchPileup(eventcuts.cfgRequireNoSameBunchPileup); + fEMEventCut.SetRequireVertexITSTPC(eventcuts.cfgRequireVertexITSTPC); + fEMEventCut.SetRequireGoodZvtxFT0vsPV(eventcuts.cfgRequireGoodZvtxFT0vsPV); + fEMEventCut.SetRequireNoCollInTimeRangeStandard(eventcuts.cfgRequireNoCollInTimeRangeStandard); + fEMEventCut.SetRequireNoCollInTimeRangeStrict(eventcuts.cfgRequireNoCollInTimeRangeStrict); + fEMEventCut.SetRequireNoCollInITSROFStandard(eventcuts.cfgRequireNoCollInITSROFStandard); + fEMEventCut.SetRequireNoCollInITSROFStrict(eventcuts.cfgRequireNoCollInITSROFStrict); + fEMEventCut.SetRequireNoHighMultCollInPrevRof(eventcuts.cfgRequireNoHighMultCollInPrevRof); + } + + // Link V0-photons to their collision + Preslice perV0PhotonCollision = aod::v0photonkf::emeventId; + + void init(InitContext const& /*ctx*/) + { + + defineEMEventCut(); + + for (int i = 0; i < NConversionBuilder; ++i) { + + registry.add(string(kConversionBuilder[i]) + "hPt", ";p_{T} (GeV/c); Counts", kTH1F, {{1000, 0., 10.}}); + registry.add(string(kConversionBuilder[i]) + "hR", ";R_{conv} (cm); Counts", kTH1F, {{100, 0., 100.}}); + + registry.add(string(kConversionBuilder[i]) + "hEta", ";#eta; Counts", kTH1F, {{200, -1.0f, 1.0f}}); + + registry.add(string(kConversionBuilder[i]) + "hcosPA", ";R_{conv} (cm); Counts", kTH1F, {{100, 0.99f, 1.0f}}); + + registry.add(string(kConversionBuilder[i]) + "MatchedDeltaRec", ";#Delta colID_{rec};Counts", kTH1F, {{21, -10.5, 10.5}}); + + registry.add(string(kConversionBuilder[i]) + "hZ", ";z (cm);Counts", kTH1F, {{200, -100, 100}}); + + registry.add(string(kConversionBuilder[i]) + "hZR", "conversion point in RZ;Z (cm);R_{xy} (cm)", kTH2F, {{200, -100, 100}, {200, 0.0f, 100.0f}}); + + registry.add(string(kConversionBuilder[i]) + "hAP", "AP plot;#alpha;q_{T} (GeV/c)", kTH2F, {{200, -1.0f, +1.0f}, {250, 0.0f, 0.25f}}); + + registry.add(string(kConversionBuilder[i]) + "ResolutionGen/Z_res", "Conversion radius resolution;z_{conv, gen} (cm);R_{conv, gen} (cm);#varphi_{gen} (rad.);#eta_{gen};p_{T, gen};z_{conv, rec} - z_{conv, gen} (cm);", + kTHnSparseF, + {{200, -100, 100}, + {200, 0, 100}, + {90, 0, math::TwoPI}, + {200, -1.0f, 1.0f}, + {500, 0, 10}, + {120, -30, 30} + + }, + false); + + registry.add(string(kConversionBuilder[i]) + "ResolutionGen/R_res", "Conversion radius resolution;z_{conv, gen} (cm);R_{conv, gen} (cm);#varphi_{gen} (rad.);#eta_{gen};p_{T, gen};R_{conv, rec} - R_{conv, gen} (cm);", + kTHnSparseF, + {{200, -100, 100}, + {200, 0, 100}, + {90, 0, math::TwoPI}, + {200, -1.0f, 1.0f}, + {500, 0, 10}, + {120, -30, 30} + + }, + false); + + registry.add(string(kConversionBuilder[i]) + "ResolutionGen/Phi_res", "#varphi resolution;z_{conv, gen} (cm);R_{conv, gen} (cm);#varphi_{gen} (rad.);#eta_{gen};p_{T, gen};#varphi_{conv, rec} - #varphi_{conv, gen} (cm);", + kTHnSparseF, + {{200, -100, 100}, + {200, 0, 100}, + {90, 0, math::TwoPI}, + {200, -1.0f, 1.0f}, + {500, 0, 10}, + {100, -0.2f, 0.2f} + + }, + false); + + registry.add(string(kConversionBuilder[i]) + "ResolutionGen/Pt_res", "Conversion radius resolution;z_{conv, gen} (cm);R_{conv, gen} (cm);#varphi_{gen} (rad.);#eta_{gen};p_{T, gen};p_{T, rec} - p_{T, gen}/p_{T, gen};", + kTHnSparseF, + {{200, -100, 100}, + {200, 0, 100}, + {90, 0, math::TwoPI}, + {200, -1.0f, 1.0f}, + {500, 0, 10}, + {200, -1.0f, 1.0f} + + }, + false); + + registry.add(string(kConversionBuilder[i]) + "ResolutionGen/Eta_res", "Conversion radius resolution;z_{conv, gen} (cm);R_{conv, gen} (cm);#varphi_{gen} (rad.);#eta_{gen};p_{T, gen};#eta_{conv, rec} - #eta_{conv, gen} (cm);", + kTHnSparseF, + {{200, -100, 100}, + {200, 0, 100}, + {90, 0, math::TwoPI}, + {200, -1.0f, 1.0f}, + {500, 0, 10}, + {100, -0.5f, 0.5f} + + }, + false); + + registry.add(string(kConversionBuilder[i]) + "ResolutionRec/Z_res", "Conversion radius resolution;z_{conv, rec} (cm);R_{conv, rec} (cm);#varphi_{rec} (rad.);#eta_{rec};p_{T, rec};z_{conv, rec} - z_{conv, gen} (cm);", + kTHnSparseF, + {{200, -100, 100}, + {200, 0, 100}, + {90, 0, math::TwoPI}, + {200, -1.0f, 1.0f}, + {500, 0, 10}, + {120, -30, 30} + + }, + false); + + registry.add(string(kConversionBuilder[i]) + "ResolutionRec/R_res", "Conversion radius resolution;z_{conv, rec} (cm);R_{conv, rec} (cm);#varphi_{rec} (rad.);#eta_{rec};p_{T, rec};R_{conv, rec} - R_{conv, gen} (cm);", + kTHnSparseF, + {{200, -100, 100}, + {200, 0, 100}, + {90, 0, math::TwoPI}, + {200, -1.0f, 1.0f}, + {500, 0, 10}, + {120, -30, 30} + + }, + false); + + registry.add(string(kConversionBuilder[i]) + "ResolutionRec/Phi_res", "#varphi resolution;z_{conv, rec} (cm);R_{conv, rec} (cm);#varphi_{rec} (rad.);#eta_{rec};p_{T, rec};#varphi_{conv, rec} - #varphi_{conv, gen} (cm);", + kTHnSparseF, + {{200, -100, 100}, + {200, 0, 100}, + {90, 0, math::TwoPI}, + {200, -1.0f, 1.0f}, + {500, 0, 10}, + {100, -0.2f, 0.2f} + + }, + false); + + registry.add(string(kConversionBuilder[i]) + "ResolutionRec/Pt_res", "Conversion radius resolution;z_{conv, rec} (cm);R_{conv, rec} (cm);#varphi_{rec} (rad.);#eta_{rec};p_{T, rec};p_{T, rec} - p_{T, gen}/p_{T, gen};", + kTHnSparseF, + {{200, -100, 100}, + {200, 0, 100}, + {90, 0, math::TwoPI}, + {200, -1.0f, 1.0f}, + {500, 0, 10}, + {200, -1.0f, 1.0f} + + }, + false); + + registry.add(string(kConversionBuilder[i]) + "ResolutionRec/Eta_res", "Conversion radius resolution;z_{conv, rec} (cm);R_{conv, rec} (cm);#varphi_{rec} (rad.);#eta_{rec};p_{T, rec};#eta_{conv, rec} - #eta_{conv, gen} (cm);", + kTHnSparseF, + {{200, -100, 100}, + {200, 0, 100}, + {90, 0, math::TwoPI}, + {200, -1.0f, 1.0f}, + {500, 0, 10}, + {100, -0.5f, 0.5f} + + }, + false); + registry.add(string(kConversionBuilder[i]) + "ConvInfo", "Conversion radius resolution;x_{conv} (cm);y_{conv} (cm);z_{conv} (cm);R_{conv} (cm);#varphi (rad.);#eta;p_{T, gen};", + kTHnSparseF, + { + {200, -100, 100}, + {200, -100, 100}, + {200, -100, 100}, + {200, 0, 100}, + {90, 0, math::TwoPI}, + {200, -1.0f, 1.0f}, + {500, 0, 10}, + + }, + false); + + registry.add(string(kConversionBuilder[i]) + "V0Leg/Asymmetry", "", kTH1F, {{100, 0, 1}}); + + auto hCollisionCounter = registry.add(string(kConversionBuilder[i]) + "Event/before/hCollisionCounter", "collision counter;;Number of events", kTH1F, {{10, 0.5, 10.5}}, false); + hCollisionCounter->GetXaxis()->SetBinLabel(1, "all"); + hCollisionCounter->GetXaxis()->SetBinLabel(2, "No TF border"); + hCollisionCounter->GetXaxis()->SetBinLabel(3, "No ITS ROF border"); + hCollisionCounter->GetXaxis()->SetBinLabel(4, "No Same Bunch Pileup"); + hCollisionCounter->GetXaxis()->SetBinLabel(5, "Is Vertex ITSTPC"); + hCollisionCounter->GetXaxis()->SetBinLabel(6, "Is Good Zvtx FT0vsPV"); + hCollisionCounter->GetXaxis()->SetBinLabel(7, "FT0AND"); + hCollisionCounter->GetXaxis()->SetBinLabel(8, "sel8"); + hCollisionCounter->GetXaxis()->SetBinLabel(9, "|Z_{vtx}| < 10 cm"); + hCollisionCounter->GetXaxis()->SetBinLabel(10, "accepted"); + + registry.add(string(kConversionBuilder[i]) + "Event/before/hZvtx", "vertex z; Z_{vtx} (cm)", kTH1F, {{100, -50, +50}}, false); + registry.add(string(kConversionBuilder[i]) + "Event/before/hMultNTracksPV", "hMultNTracksPV; N_{track} to PV", kTH1F, {{6001, -0.5, 6000.5}}, false); + registry.add(string(kConversionBuilder[i]) + "Event/before/hMultNTracksPVeta1", "hMultNTracksPVeta1; N_{track} to PV", kTH1F, {{6001, -0.5, 6000.5}}, false); + registry.add(string(kConversionBuilder[i]) + "Event/before/hMultFT0", "hMultFT0;mult. FT0A;mult. FT0C", kTH2F, {{300, 0, 6000}, {300, 0, 6000}}, false); + registry.add(string(kConversionBuilder[i]) + "Event/before/hCentFT0A", "hCentFT0A;centrality FT0A (%)", kTH1F, {{110, 0, 110}}, false); + registry.add(string(kConversionBuilder[i]) + "Event/before/hCentFT0C", "hCentFT0C;centrality FT0C (%)", kTH1F, {{110, 0, 110}}, false); + registry.add(string(kConversionBuilder[i]) + "Event/before/hCentFT0M", "hCentFT0M;centrality FT0M (%)", kTH1F, {{110, 0, 110}}, false); + registry.add(string(kConversionBuilder[i]) + "Event/before/hCentFT0MvsMultNTracksPV", "hCentFT0MvsMultNTracksPV;centrality FT0M (%);N_{track} to PV", kTH2F, {{110, 0, 110}, {600, 0, 6000}}, false); + registry.add(string(kConversionBuilder[i]) + "Event/before/hMultFT0MvsMultNTracksPV", "hMultFT0MvsMultNTracksPV;mult. FT0M;N_{track} to PV", kTH2F, {{600, 0, 6000}, {600, 0, 6000}}, false); + registry.addClone(string(kConversionBuilder[i]) + "Event/before/", string(kConversionBuilder[i]) + "Event/after/"); + } + + registry.add("truePhotons/hPt_Converted", "Converted Photons; p_{T} (GeV/c); Counts", kTH1F, {{100, 0., 10.}}); + registry.add("truePhotons/hR_Converted", "Converted Photons; R (cm); Counts", kTH1F, {{100, 0., 100.}}); + + registry.add("truePhotons/Sparse_Converted", "Conversion radius resolution;x_{conv} (cm);z_{conv} (cm);y_{conv} (cm);R_{conv} (cm);#varphi (rad.);#eta;p_{T, gen};", + kTHnSparseF, + {{200, -100, 100}, + {200, -100, 100}, + {200, -100, 100}, + {200, 0, 100}, + {90, 0, math::TwoPI}, + {200, -1.0f, 1.0f}, + {500, 0, 10}}, + false); + + auto h = registry.add("EMBuilder/hV0SignType", "Crosscheck", kTH1F, {{3, 0.5, 4.5}}, false); + h->GetXaxis()->SetBinLabel(1, "Same-sign"); + h->GetXaxis()->SetBinLabel(2, "Opposite-sign"); + h->GetXaxis()->SetBinLabel(3, "Zero-sign"); + + auto h2 = registry.add("EMBuilder/hV0ElectronPositronTrue", "pair in MC truth;;counts", kTH1F, {{2, -0.5, 1.5}}); + h2->GetXaxis()->SetBinLabel(1, "Mismatch"); + h2->GetXaxis()->SetBinLabel(2, "Good"); + } + + template + void fillEventInfo(TCollision const& collision, const float /*weight*/ = 1.f) + { + registry.fill(HIST(kConversionBuilder[type]) + HIST("Event/") + HIST(kEventTypes[ev_id]) + HIST("hCollisionCounter"), 1.0); + + if (collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { + registry.fill(HIST(kConversionBuilder[type]) + HIST("Event/") + HIST(kEventTypes[ev_id]) + HIST("hCollisionCounter"), 2.0); + } + if (collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { + registry.fill(HIST(kConversionBuilder[type]) + HIST("Event/") + HIST(kEventTypes[ev_id]) + HIST("hCollisionCounter"), 3.0); + } + if (collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + registry.fill(HIST(kConversionBuilder[type]) + HIST("Event/") + HIST(kEventTypes[ev_id]) + HIST("hCollisionCounter"), 4.0); + } + if (collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { + registry.fill(HIST(kConversionBuilder[type]) + HIST("Event/") + HIST(kEventTypes[ev_id]) + HIST("hCollisionCounter"), 5.0); + } + if (collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + registry.fill(HIST(kConversionBuilder[type]) + HIST("Event/") + HIST(kEventTypes[ev_id]) + HIST("hCollisionCounter"), 6.0); + } + + if (collision.selection_bit(o2::aod::evsel::kIsTriggerTVX)) { + registry.fill(HIST(kConversionBuilder[type]) + HIST("Event/") + HIST(kEventTypes[ev_id]) + HIST("hCollisionCounter"), 7.0); + } + + if (collision.sel8()) { + registry.fill(HIST(kConversionBuilder[type]) + HIST("Event/") + HIST(kEventTypes[ev_id]) + HIST("hCollisionCounter"), 8.0); + } + if (std::fabs(collision.posZ()) < eventcuts.cfgZvtxMax) { + registry.fill(HIST(kConversionBuilder[type]) + HIST("Event/") + HIST(kEventTypes[ev_id]) + HIST("hCollisionCounter"), 9.0); + } + + registry.fill(HIST(kConversionBuilder[type]) + HIST("Event/") + HIST(kEventTypes[ev_id]) + HIST("hMultNTracksPVeta1"), collision.multNTracksPVeta1()); + } + + template + void fillLegInfo(auto& v0, auto& posleg, auto& negleg) + { + if constexpr (type == 0) { + + float ptPos = posleg.pt(); + float ptNeg = negleg.pt(); + float asym = (ptPos - ptNeg) / (ptPos + ptNeg); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("V0Leg/Asymmetry"), asym); + + } else { + + float ptPos = v0.postrackpt(); + float ptNeg = negleg.negtrackpt(); + float asym = (ptPos - ptNeg) / (ptPos + ptNeg); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("V0Leg/Asymmetry"), asym); + } + } + + template + void fillV0Info(auto& v0, auto& v0MC, auto& mcleg) + { + registry.fill(HIST(kConversionBuilder[type]) + HIST("hPt"), v0.pt()); + registry.fill(HIST(kConversionBuilder[type]) + HIST("hEta"), v0.eta()); + registry.fill(HIST(kConversionBuilder[type]) + HIST("hAP"), v0.alpha(), v0.qtarm()); + + if constexpr (type == EMBuilder || type == EMOnly) { + registry.fill(HIST(kConversionBuilder[type]) + HIST("hZ"), v0.vz()); + registry.fill(HIST(kConversionBuilder[type]) + HIST("hcosPA"), v0.cospa()); + registry.fill(HIST(kConversionBuilder[type]) + HIST("hZR"), v0.vz(), v0.v0radius()); + + float deltapT = v0.pt() - v0MC.pt(); + float deltaZ = v0.vz() - mcleg.vz(); + float deltaPhi = v0.phi() - v0MC.phi(); + float deltaEta = v0.eta() - v0MC.eta(); + float deltaR = v0.v0radius() - std::sqrt(std::pow(mcleg.vx(), 2) + std::pow(mcleg.vy(), 2)); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionGen/Z_res"), + mcleg.vz(), + std::sqrt(std::pow(mcleg.vx(), 2) + std::pow(mcleg.vy(), 2)), + v0MC.phi(), + v0MC.eta(), + v0MC.pt(), + deltaZ); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionGen/R_res"), + mcleg.vz(), + std::sqrt(std::pow(mcleg.vx(), 2) + std::pow(mcleg.vy(), 2)), + v0MC.phi(), + v0MC.eta(), + v0MC.pt(), + deltaR); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionGen/Phi_res"), + mcleg.vz(), + std::sqrt(std::pow(mcleg.vx(), 2) + std::pow(mcleg.vy(), 2)), + v0MC.phi(), + v0MC.eta(), + v0MC.pt(), + deltaPhi); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionGen/Pt_res"), + mcleg.vz(), + std::sqrt(std::pow(mcleg.vx(), 2) + std::pow(mcleg.vy(), 2)), + v0MC.phi(), + v0MC.eta(), + v0MC.pt(), + deltapT); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionGen/Eta_res"), + mcleg.vz(), + std::sqrt(std::pow(mcleg.vx(), 2) + std::pow(mcleg.vy(), 2)), + v0MC.phi(), + v0MC.eta(), + v0MC.pt(), + deltaEta); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionRec/Z_res"), + v0.vz(), + v0.v0radius(), + v0.phi(), + v0.eta(), + v0.pt(), + deltaZ); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionRec/R_res"), + v0.vz(), + v0.v0radius(), + v0.phi(), + v0.eta(), + v0.pt(), + deltaR); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionRec/Phi_res"), + v0.vz(), + v0.v0radius(), + v0.phi(), + v0.eta(), + v0.pt(), + deltaPhi); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionRec/Pt_res"), + v0.vz(), + v0.v0radius(), + v0.phi(), + v0.eta(), + v0.pt(), + deltapT); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionRec/Eta_res"), + v0.vz(), + v0.v0radius(), + v0.phi(), + v0.eta(), + v0.pt(), + deltaEta); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ConvInfo"), + v0.vx(), // 0 + v0.vy(), // 1 + v0.vz(), // 2 + v0.v0radius(), // 3 + v0.phi(), // 4 + v0.eta(), // 5 + v0.pt()); // 6 + + } else { + registry.fill(HIST(kConversionBuilder[type]) + HIST("hZ"), v0.z()); + registry.fill(HIST(kConversionBuilder[type]) + HIST("hcosPA"), v0.v0cosPA()); + registry.fill(HIST(kConversionBuilder[type]) + HIST("hZR"), v0.z(), v0.v0radius()); + + float deltaR = v0.v0radius() - std::hypot(v0MC.xMC(), v0MC.yMC()); + + float phiRec = v0.phi(); + RecoDecay::constrainAngle(phiRec); + + float phiMC = std::atan2(v0MC.pyMC(), v0MC.pxMC()); + RecoDecay::constrainAngle(phiMC); + + float deltaPhi = phiRec - phiMC; + RecoDecay::constrainAngle(deltaPhi); + + float etaGen = 0.5f * std::log((std::hypot(v0MC.pxMC(), v0MC.pyMC(), v0MC.pzMC()) + v0MC.pzMC()) / (std::hypot(v0MC.pxMC(), v0MC.pyMC(), v0MC.pzMC()) - v0MC.pzMC())); + + float etaRec = 0.5f * std::log((std::hypot(v0.px(), v0.py(), v0.pz()) + v0.pz()) / (std::hypot(v0.px(), v0.py(), v0.pz()) - v0.pz())); + + float deltapT = v0.pt() - v0MC.ptMC(); + float deltaEta = etaRec - etaGen; + float deltaZ = v0.z() - v0MC.zMC(); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionGen/Z_res"), + v0MC.zMC(), + std::hypot(v0MC.xMC(), v0MC.yMC()), + phiMC, + etaGen, + v0MC.ptMC(), + deltaZ); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionGen/R_res"), + v0MC.zMC(), + std::hypot(v0MC.xMC(), v0MC.yMC()), + phiMC, + etaGen, + v0MC.ptMC(), + deltaR); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionGen/Phi_res"), + v0MC.zMC(), + std::hypot(v0MC.xMC(), v0MC.yMC()), + phiMC, + etaGen, + v0MC.ptMC(), + deltaPhi); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionGen/Pt_res"), + v0MC.zMC(), + std::hypot(v0MC.xMC(), v0MC.yMC()), + phiMC, + etaGen, + v0MC.ptMC(), + deltapT); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionGen/Eta_res"), + v0MC.zMC(), + std::hypot(v0MC.xMC(), v0MC.yMC()), + phiMC, + etaGen, + v0MC.ptMC(), + deltaEta); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionRec/Z_res"), + v0.z(), + v0.v0radius(), + phiRec, + v0.eta(), + v0.pt(), + deltaZ); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionRec/R_res"), + v0.z(), + v0.v0radius(), + phiRec, + v0.eta(), + v0.pt(), + deltaR); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionRec/Phi_res"), + v0.z(), + v0.v0radius(), + phiRec, + v0.eta(), + v0.pt(), + deltaPhi); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionRec/Eta_res"), + v0.z(), + v0.v0radius(), + phiRec, + v0.eta(), + v0.pt(), + deltaEta); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ResolutionRec/Pt_res"), + v0.z(), + v0.v0radius(), + phiRec, + v0.eta(), + v0.pt(), + deltapT); + + registry.fill(HIST(kConversionBuilder[type]) + HIST("ConvInfo"), + v0.x(), + v0.y(), + v0.z(), + v0.v0radius(), + phiRec, + v0.eta(), + v0.pt()); + } + + registry.fill(HIST(kConversionBuilder[type]) + HIST("hR"), v0.v0radius()); + } + + Preslice perCollisionMCDerived = o2::aod::v0data::straCollisionId; + + void processLFV0sMC(MyStraCollisions const& stracollisions, + soa::Join const&, + V0DerivedMCDatas const& strangeV0s, + DauTracks const&) + { + + for (const auto& collision : stracollisions) { + + fillEventInfo<0, LFBuilder>(collision); + + if (!fEMEventCut.IsSelected(collision)) { + continue; + } + + fillEventInfo<1, LFBuilder>(collision); + + registry.fill(HIST((kConversionBuilder[1])) + HIST("Event/before/hCollisionCounter"), 10.0); + registry.fill(HIST((kConversionBuilder[1])) + HIST("Event/after/hCollisionCounter"), 10.0); // accepted + + auto myV0s = strangeV0s.sliceBy(perCollisionMCDerived, collision.globalIndex()); + + for (auto const& v0 : myV0s) { + if (!v0.has_v0MCCore()) { + continue; + } + + auto v0MC = v0.v0MCCore_as>(); + + if (v0MC.pdgCode() != kGamma || !v0MC.isPhysicalPrimary()) { + continue; + } + + auto posTrack = v0.template posTrackExtra_as(); + + fillV0Info(v0, v0MC, posTrack); + } + } + } + + Preslice perCollision = aod::v0photonkf::emeventId; + + void processEMV0sMC(MyV0Photons const& v0s, aod::EMMCParticles const& mcparticles, MyMCV0Legs const&, MyCollisions const& collisions) + { + + for (const auto& collision : collisions) { + + fillEventInfo<0, EMBuilder>(collision); + + if (!fEMEventCut.IsSelected(collision)) { + continue; + } + fillEventInfo<1, EMBuilder>(collision); + + registry.fill(HIST((kConversionBuilder[0])) + HIST("Event/before/hCollisionCounter"), 10.0); // accepted + registry.fill(HIST((kConversionBuilder[0])) + HIST("Event/after/hCollisionCounter"), 10.0); // accepted + + auto v0PhotonsColl = v0s.sliceBy(perCollision, collision.globalIndex()); + + for (auto const& v0 : v0PhotonsColl) { + + auto pos = v0.posTrack_as(); + auto ele = v0.negTrack_as(); + auto posmc = pos.template emmcparticle_as(); + auto elemc = ele.template emmcparticle_as(); + + int photonid = FindCommonMotherFrom2Prongs(posmc, elemc, kPositron, kElectron, kGamma, mcparticles); + + auto mcphoton = mcparticles.iteratorAt(photonid); + + if (mcphoton.isPhysicalPrimary()) { + + fillV0Info(v0, mcphoton, elemc); + } + + if (pos.sign() * ele.sign() > 0) { + registry.fill(HIST("EMBuilder/hV0SignType"), 1); // same-sign + } else if (pos.sign() * ele.sign() < 0) { + registry.fill(HIST("EMBuilder/hV0SignType"), 2); // opposite-sign + } else { + registry.fill(HIST("EMBuilder/hV0SignType"), 3); // zero or undefined + } + + if ((posmc.pdgCode() == kElectron && elemc.pdgCode() == kPositron) || (posmc.pdgCode() == kPositron && elemc.pdgCode() == kElectron)) { + registry.fill(HIST("EMBuilder/hV0ElectronPositronTrue"), 1); // good + } else { + registry.fill(HIST("EMBuilder/hV0ElectronPositronTrue"), 0); // mismatch + } + } + } + } + + PresliceUnsorted perMcCollision = aod::emmcparticle::emmceventId; + + void processConvV0s(MyCollisions const& collisions, + MyMCCollisions const&, + aod::EMMCParticles const& mcparticles, + MyTracksIUMC const& tracks) + { + for (const auto& collision : collisions) { + + const float minR = 5.0f; + const float maxR = 90.f; + + if (!fEMEventCut.IsSelected(collision)) { + continue; + } + + auto mccollision = collision.template emmcevent_as(); + + auto mcstack = mcparticles.sliceBy(perMcCollision, mccollision.globalIndex()); + auto mcTracksColl = mcparticles.sliceBy(perMcCollision, mccollision.globalIndex()); + + std::unordered_map mc2trk; + for (const auto& trk : tracks) { + if (trk.mcParticleId() >= 0) { + mc2trk[trk.mcParticleId()] = trk.globalIndex(); + } + } + + for (const auto& mc : mcTracksColl) { + if (mc.pdgCode() != kGamma || !mc.isPhysicalPrimary()) { + continue; + } + + auto daughters = mc.daughtersIds(); + if (daughters.size() != 2) { // o2-linter: disable=magic-number (this is pretty clear and not magic) + continue; + } + + auto d1 = mcparticles.iteratorAt(daughters[0]); + auto d2 = mcparticles.iteratorAt(daughters[1]); + + if (std::abs(d1.pdgCode()) != kElectron || std::abs(d2.pdgCode()) != kElectron) { + continue; + } + + float r = std::hypot(d1.vx(), d1.vy()); + if (r < minR || r > maxR) { + continue; + } + + registry.fill(HIST("truePhotons/hPt_Converted"), mc.pt()); + registry.fill(HIST("truePhotons/hR_Converted"), r); + + registry.fill(HIST("truePhotons/Sparse_Converted"), d1.vx(), mc.y(), d1.vz(), r, mc.phi(), mc.eta(), mc.pt()); + + int id1 = mc2trk.count(d1.globalIndex()) ? mc2trk[d1.globalIndex()] : -1; + int id2 = mc2trk.count(d2.globalIndex()) ? mc2trk[d2.globalIndex()] : -1; + if (id1 < 0 || id2 < 0) { + continue; + } + } + } + } + + void processMatchCategories( + MyCollisions const& collisions, + aod::EMMCEvents const&, + MyTracksIUMC const& tracksgen, + MyV0Photons const& emV0s, + soa::Join const&, + V0DerivedMCDatas const& lfV0s, + MyMCV0Legs const&, + aod::EMMCParticles const&, + aod::McParticles const& mcparticles, + DauTracks const&) + { + std::unordered_map trackToMcLabel; + for (auto const& t : tracksgen) { + int label = t.mcParticleId(); + if (label >= 0) { + trackToMcLabel[t.globalIndex()] = label; + } + } + + for (const auto& collision : collisions) { + if (!fEMEventCut.IsSelected(collision)) + continue; + + fillEventInfo<1, EMBuilder>(collision); + + auto emSlice = emV0s.sliceBy(perCollision, collision.globalIndex()); + auto lfSlice = lfV0s.sliceBy(perCollisionMCDerived, collision.globalIndex()); + + using EMIt = decltype(emSlice.begin()); + using LFIt = decltype(lfSlice.begin()); + struct Entry { + std::optional emIt; + std::optional lfIt; + }; + std::unordered_map table; + + for (EMIt it = emSlice.begin(); it != emSlice.end(); ++it) { + auto posmc = it.posTrack_as() + .emmcparticle_as(); + auto negmc = it.negTrack_as() + .emmcparticle_as(); + int pid = FindCommonMotherFrom2Prongs(posmc, negmc, + kPositron, kElectron, kGamma, mcparticles); + if (pid >= 0) + table[pid].emIt = it; + } + + for (LFIt it = lfSlice.begin(); it != lfSlice.end(); ++it) { + int posTrackIndex = it.posTrackId(); + auto negTrackIndex = it.negTrackId(); + + if (!trackToMcLabel.count(posTrackIndex) || !trackToMcLabel.count(negTrackIndex)) + continue; + auto posmc = mcparticles.iteratorAt(trackToMcLabel[posTrackIndex]); + auto negmc = mcparticles.iteratorAt(trackToMcLabel[negTrackIndex]); + int pid = FindCommonMotherFrom2Prongs(posmc, negmc, + kPositron, kElectron, kGamma, mcparticles); + if (pid >= 0) + table[pid].lfIt = it; + } + + for (auto const& [pid, entry] : table) { + auto mcphoton = mcparticles.iteratorAt(pid); + + if (entry.emIt.has_value() && entry.lfIt.has_value()) { + // --- Common V0 --- + auto& lfV0 = *entry.lfIt.value(); + auto v0MC = lfV0.template v0MCCore_as< + soa::Join>(); + auto posTrack = lfV0.template posTrackExtra_as(); + fillV0Info(lfV0, v0MC, posTrack); + + } else if (entry.emIt.has_value()) { + // --- EM-only V0 --- + auto& emV0 = *entry.emIt.value(); + auto negmc = emV0.negTrack_as() + .emmcparticle_as(); + fillV0Info(emV0, mcphoton, negmc); + + } else if (entry.lfIt.has_value()) { + // --- LF-only V0 --- + auto& lfV0 = *entry.lfIt.value(); + auto v0MC = lfV0.template v0MCCore_as< + soa::Join>(); + auto posTrack = lfV0.template posTrackExtra_as(); + fillV0Info(lfV0, v0MC, posTrack); + } + } + } + } + + PROCESS_SWITCH(Compconvbuilder, processMatchCategories, "Process V0s matched via MC photon", false); + PROCESS_SWITCH(Compconvbuilder, processLFV0sMC, "Process LF Builder V0s", true); + PROCESS_SWITCH(Compconvbuilder, processEMV0sMC, "Process EM Builder V0s", false); + PROCESS_SWITCH(Compconvbuilder, processConvV0s, "Process generated converted V0s", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfg) +{ + return WorkflowSpec{adaptAnalysisTask(cfg)}; +} diff --git a/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx b/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx index 552d5b711d4..376d4ca043a 100644 --- a/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx +++ b/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx @@ -213,7 +213,6 @@ struct DalitzEEQC { fRegistry.add("Track/hChi2TOF", "chi2 of TOF", kTH1F, {{100, 0, 10}}, false); fRegistry.add("Track/hTOFbeta", "TOF beta;p_{pv} (GeV/c);#beta", kTH2F, {{1000, 0, 10}, {240, 0, 1.2}}, false); fRegistry.add("Track/hTOFNsigmaEl", "TOF n sigma el;p_{pv} (GeV/c);n #sigma_{e}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/hTOFNsigmaPi", "TOF n sigma pi;p_{pv} (GeV/c);n #sigma_{#pi}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); } void DefineEMEventCut() @@ -325,7 +324,6 @@ struct DalitzEEQC { fRegistry.fill(HIST("Track/hTPCNsigmaEl"), track.tpcInnerParam(), track.tpcNSigmaEl()); fRegistry.fill(HIST("Track/hTPCNsigmaPi"), track.tpcInnerParam(), track.tpcNSigmaPi()); fRegistry.fill(HIST("Track/hTOFNsigmaEl"), track.p(), track.tofNSigmaEl()); - fRegistry.fill(HIST("Track/hTOFNsigmaPi"), track.p(), track.tofNSigmaPi()); fRegistry.fill(HIST("Track/hTOFbeta"), track.p(), track.beta()); fRegistry.fill(HIST("Track/hMeanClusterSizeITS"), track.p(), track.meanClusterSizeITS() * std::cos(std::atan(track.tgl()))); } diff --git a/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx b/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx index adc556bf78d..3b84310b761 100644 --- a/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx @@ -187,7 +187,6 @@ struct DalitzEEQCMC { fRegistry.add("Track/primary/hChi2TOF", "chi2 of TOF", kTH1F, {{100, 0, 10}}, false); fRegistry.add("Track/primary/hTOFbeta", "TOF beta;p_{pv} (GeV/c);#beta", kTH2F, {{1000, 0, 10}, {240, 0, 1.2}}, false); fRegistry.add("Track/primary/hTOFNsigmaEl", "TOF n sigma el;p_{pv} (GeV/c);n #sigma_{e}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); - fRegistry.add("Track/primary/hTOFNsigmaPi", "TOF n sigma pi;p_{pv} (GeV/c);n #sigma_{#pi}^{TOF}", kTH2F, {{1000, 0, 10}, {100, -5, +5}}, false); fRegistry.add("Track/primary/hPtGen_DeltaPtOverPtGen", "electron p_{T} resolution;p_{T}^{gen} (GeV/c);(p_{T}^{rec} - p_{T}^{gen})/p_{T}^{gen}", kTH2F, {{1000, 0, 10}, {200, -1.0f, 1.0f}}, true); fRegistry.add("Track/primary/hPtGen_DeltaEta", "electron #eta resolution;p_{T}^{gen} (GeV/c);#eta^{rec} - #eta^{gen}", kTH2F, {{1000, 0, 10}, {100, -0.5f, 0.5f}}, true); fRegistry.add("Track/primary/hPtGen_DeltaPhi", "electron #varphi resolution;p_{T}^{gen} (GeV/c);#varphi^{rec} - #varphi^{gen} (rad.)", kTH2F, {{1000, 0, 10}, {100, -0.5f, 0.5f}}, true); @@ -480,7 +479,6 @@ struct DalitzEEQCMC { fRegistry.fill(HIST("Track/") + HIST(track_types[tracktype]) + HIST("hTPCNsigmaEl"), track.tpcInnerParam(), track.tpcNSigmaEl()); fRegistry.fill(HIST("Track/") + HIST(track_types[tracktype]) + HIST("hTPCNsigmaPi"), track.tpcInnerParam(), track.tpcNSigmaPi()); fRegistry.fill(HIST("Track/") + HIST(track_types[tracktype]) + HIST("hTOFNsigmaEl"), track.p(), track.tofNSigmaEl()); - fRegistry.fill(HIST("Track/") + HIST(track_types[tracktype]) + HIST("hTOFNsigmaPi"), track.p(), track.tofNSigmaPi()); fRegistry.fill(HIST("Track/") + HIST(track_types[tracktype]) + HIST("hTOFbeta"), track.p(), track.beta()); fRegistry.fill(HIST("Track/") + HIST(track_types[tracktype]) + HIST("hPtGen_DeltaPtOverPtGen"), mctrack.pt(), (track.pt() - mctrack.pt()) / mctrack.pt()); fRegistry.fill(HIST("Track/") + HIST(track_types[tracktype]) + HIST("hPtGen_DeltaEta"), mctrack.pt(), track.eta() - mctrack.eta()); diff --git a/PWGEM/PhotonMeson/Tasks/emcalQC.cxx b/PWGEM/PhotonMeson/Tasks/emcalQC.cxx index 4173c26eccf..6f298546c30 100644 --- a/PWGEM/PhotonMeson/Tasks/emcalQC.cxx +++ b/PWGEM/PhotonMeson/Tasks/emcalQC.cxx @@ -18,28 +18,31 @@ /// \author Nicolas Strangmann (nicolas.strangmann@cern.ch) Goethe University Frankfurt /// -#include -#include -#include -#include "TString.h" -#include "THashList.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" -#include "Common/Core/trackUtilities.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/PIDResponse.h" -#include "Common/Core/RecoDecay.h" -#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" +#include "EMPhotonEventCut.h" + #include "PWGEM/PhotonMeson/Core/EMCPhotonCut.h" -#include "PWGEM/PhotonMeson/Core/CutsLibrary.h" -#include "PWGEM/PhotonMeson/Utils/EventHistograms.h" +#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" #include "PWGEM/PhotonMeson/Utils/ClusterHistograms.h" +#include "PWGEM/PhotonMeson/Utils/EventHistograms.h" + +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include using namespace o2; using namespace o2::aod; diff --git a/PWGEM/PhotonMeson/Tasks/pcmQC.cxx b/PWGEM/PhotonMeson/Tasks/pcmQC.cxx index 077a1be9f7d..1b784b5cb18 100644 --- a/PWGEM/PhotonMeson/Tasks/pcmQC.cxx +++ b/PWGEM/PhotonMeson/Tasks/pcmQC.cxx @@ -14,18 +14,18 @@ // This code runs loop over v0 photons for PCM QC. // Please write to: daiki.sekihata@cern.ch -#include -#include +#include "PWGEM/PhotonMeson/Core/EMPhotonEventCut.h" +#include "PWGEM/PhotonMeson/Core/V0PhotonCut.h" +#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" +#include "PWGEM/PhotonMeson/Utils/PCMUtilities.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" #include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" -#include "PWGEM/PhotonMeson/Utils/PCMUtilities.h" -#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" -#include "PWGEM/PhotonMeson/Core/V0PhotonCut.h" -#include "PWGEM/PhotonMeson/Core/EMPhotonEventCut.h" +#include +#include using namespace o2; using namespace o2::aod; @@ -81,16 +81,15 @@ struct PCMQC { Configurable cfg_max_v0radius{"cfg_max_v0radius", 90.0, "max v0 radius"}; Configurable cfg_max_alpha_ap{"cfg_max_alpha_ap", 0.95, "max alpha for AP cut"}; Configurable cfg_max_qt_ap{"cfg_max_qt_ap", 0.01, "max qT for AP cut"}; - Configurable cfg_min_cospa{"cfg_min_cospa", 0.997, "min V0 CosPA"}; - Configurable cfg_max_pca{"cfg_max_pca", 3.0, "max distance btween 2 legs"}; + Configurable cfg_min_cospa{"cfg_min_cospa", 0.999, "min V0 CosPA"}; + Configurable cfg_max_pca{"cfg_max_pca", 1.5, "max distance btween 2 legs"}; Configurable cfg_max_chi2kf{"cfg_max_chi2kf", 1e+10, "max chi2/ndf with KF"}; - Configurable cfg_require_v0_with_correct_xz{"cfg_require_v0_with_correct_xz", true, "flag to select V0s with correct xz"}; Configurable cfg_reject_v0_on_itsib{"cfg_reject_v0_on_itsib", true, "flag to reject V0s on ITSib"}; Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; Configurable cfg_min_ncrossedrows{"cfg_min_ncrossedrows", 40, "min ncrossed rows"}; Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; - Configurable cfg_max_chi2its{"cfg_max_chi2its", 5.0, "max chi2/NclsITS"}; + Configurable cfg_max_chi2its{"cfg_max_chi2its", 36.0, "max chi2/NclsITS"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -3.0, "min. TPC n sigma for electron"}; Configurable cfg_max_TPCNsigmaEl{"cfg_max_TPCNsigmaEl", +3.0, "max. TPC n sigma for electron"}; Configurable cfg_disable_itsonly_track{"cfg_disable_itsonly_track", false, "flag to disable ITSonly tracks"}; @@ -172,9 +171,9 @@ struct PCMQC { fRegistry.add("V0Leg/hChi2ITS", "chi2/number of ITS clusters", kTH1F, {{100, 0, 10}}, false); fRegistry.add("V0Leg/hITSClusterMap", "ITS cluster map", kTH1F, {{128, -0.5, 127.5}}, false); fRegistry.add("V0Leg/hMeanClusterSizeITS", "mean cluster size ITS; on ITS #times cos(#lambda)", kTH2F, {{1000, 0, 10}, {160, 0, 16}}, false); - fRegistry.add("V0Leg/hXY", "X vs. Y;X (cm);Y (cm)", kTH2F, {{100, 0, 100}, {80, -20, 20}}, false); - fRegistry.add("V0Leg/hZX", "Z vs. X;Z (cm);X (cm)", kTH2F, {{200, -100, 100}, {100, 0, 100}}, false); - fRegistry.add("V0Leg/hZY", "Z vs. Y;Z (cm);Y (cm)", kTH2F, {{200, -100, 100}, {80, -20, 20}}, false); + // fRegistry.add("V0Leg/hXY", "X vs. Y;X (cm);Y (cm)", kTH2F, {{100, 0, 100}, {80, -20, 20}}, false); + // fRegistry.add("V0Leg/hZX", "Z vs. X;Z (cm);X (cm)", kTH2F, {{200, -100, 100}, {100, 0, 100}}, false); + // fRegistry.add("V0Leg/hZY", "Z vs. Y;Z (cm);Y (cm)", kTH2F, {{200, -100, 100}, {80, -20, 20}}, false); } void DefineEMEventCut() @@ -219,7 +218,6 @@ struct PCMQC { fV0PhotonCut.SetChi2PerClusterITS(-1e+10, pcmcuts.cfg_max_chi2its); fV0PhotonCut.SetNClustersITS(0, 7); fV0PhotonCut.SetMeanClusterSizeITSob(0.0, 16.0); - fV0PhotonCut.SetIsWithinBeamPipe(pcmcuts.cfg_require_v0_with_correct_xz); fV0PhotonCut.SetDisableITSonly(pcmcuts.cfg_disable_itsonly_track); fV0PhotonCut.SetDisableTPConly(pcmcuts.cfg_disable_tpconly_track); fV0PhotonCut.SetRequireITSTPC(pcmcuts.cfg_require_v0_with_itstpc); @@ -316,9 +314,9 @@ struct PCMQC { fRegistry.fill(HIST("V0Leg/hTPCdEdx"), leg.tpcInnerParam(), leg.tpcSignal()); fRegistry.fill(HIST("V0Leg/hTPCNsigmaEl"), leg.tpcInnerParam(), leg.tpcNSigmaEl()); fRegistry.fill(HIST("V0Leg/hTPCNsigmaPi"), leg.tpcInnerParam(), leg.tpcNSigmaPi()); - fRegistry.fill(HIST("V0Leg/hXY"), leg.x(), leg.y()); - fRegistry.fill(HIST("V0Leg/hZX"), leg.z(), leg.x()); - fRegistry.fill(HIST("V0Leg/hZY"), leg.z(), leg.y()); + // fRegistry.fill(HIST("V0Leg/hXY"), leg.x(), leg.y()); + // fRegistry.fill(HIST("V0Leg/hZX"), leg.z(), leg.x()); + // fRegistry.fill(HIST("V0Leg/hZY"), leg.z(), leg.y()); } Preslice perCollision = aod::v0photonkf::emeventId; diff --git a/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx b/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx index 0587fe75138..1b2590a33cd 100644 --- a/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx @@ -14,20 +14,20 @@ // This code runs loop over v0 photons for PCM QC. // Please write to: daiki.sekihata@cern.ch -#include -#include +#include "PWGEM/Dilepton/Utils/MCUtilities.h" +#include "PWGEM/PhotonMeson/Core/EMPhotonEventCut.h" +#include "PWGEM/PhotonMeson/Core/V0PhotonCut.h" +#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" +#include "PWGEM/PhotonMeson/Utils/MCUtilities.h" +#include "PWGEM/PhotonMeson/Utils/PCMUtilities.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" #include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" -#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" -#include "PWGEM/PhotonMeson/Utils/PCMUtilities.h" -#include "PWGEM/PhotonMeson/Utils/MCUtilities.h" -#include "PWGEM/Dilepton/Utils/MCUtilities.h" -#include "PWGEM/PhotonMeson/Core/V0PhotonCut.h" -#include "PWGEM/PhotonMeson/Core/EMPhotonEventCut.h" +#include +#include using namespace o2; using namespace o2::aod; @@ -59,7 +59,6 @@ struct PCMQCMC { Configurable maxRgen{"maxRgen", 90.f, "maximum radius for generated particles"}; Configurable margin_z_mc{"margin_z_mc", 7.0, "margin for z cut in cm for MC"}; Configurable cfgRequireTrueAssociation{"cfgRequireTrueAssociation", false, "flag to require true mc collision association"}; - Configurable cfg_fill_resolution{"cfg_fill_resoltion", false, "flag to fill resolution histogram"}; EMPhotonEventCut fEMEventCut; struct : ConfigurableGroup { @@ -97,16 +96,15 @@ struct PCMQCMC { Configurable cfg_max_v0radius{"cfg_max_v0radius", 90.0, "max v0 radius"}; Configurable cfg_max_alpha_ap{"cfg_max_alpha_ap", 0.95, "max alpha for AP cut"}; Configurable cfg_max_qt_ap{"cfg_max_qt_ap", 0.01, "max qT for AP cut"}; - Configurable cfg_min_cospa{"cfg_min_cospa", 0.997, "min V0 CosPA"}; + Configurable cfg_min_cospa{"cfg_min_cospa", 0.999, "min V0 CosPA"}; Configurable cfg_max_pca{"cfg_max_pca", 3.0, "max distance btween 2 legs"}; Configurable cfg_max_chi2kf{"cfg_max_chi2kf", 1e+10, "max chi2/ndf with KF"}; - Configurable cfg_require_v0_with_correct_xz{"cfg_require_v0_with_correct_xz", true, "flag to select V0s with correct xz"}; Configurable cfg_reject_v0_on_itsib{"cfg_reject_v0_on_itsib", true, "flag to reject V0s on ITSib"}; Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; Configurable cfg_min_ncrossedrows{"cfg_min_ncrossedrows", 40, "min ncrossed rows"}; Configurable cfg_max_frac_shared_clusters_tpc{"cfg_max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"}; Configurable cfg_max_chi2tpc{"cfg_max_chi2tpc", 4.0, "max chi2/NclsTPC"}; - Configurable cfg_max_chi2its{"cfg_max_chi2its", 5.0, "max chi2/NclsITS"}; + Configurable cfg_max_chi2its{"cfg_max_chi2its", 36.0, "max chi2/NclsITS"}; Configurable cfg_min_TPCNsigmaEl{"cfg_min_TPCNsigmaEl", -3.0, "min. TPC n sigma for electron"}; Configurable cfg_max_TPCNsigmaEl{"cfg_max_TPCNsigmaEl", +3.0, "max. TPC n sigma for electron"}; Configurable cfg_disable_itsonly_track{"cfg_disable_itsonly_track", false, "flag to disable ITSonly tracks"}; @@ -204,22 +202,9 @@ struct PCMQCMC { fRegistry.add("V0/primary/hPtGen_DeltaEta", "photon #eta resolution;p_{T}^{gen} (GeV/c);#eta^{rec} - #eta^{gen}", kTH2F, {{1000, 0, 10}, {100, -0.5f, 0.5f}}, true); fRegistry.add("V0/primary/hPtGen_DeltaPhi", "photon #varphi resolution;p_{T}^{gen} (GeV/c);#varphi^{rec} - #varphi^{gen} (rad.)", kTH2F, {{1000, 0, 10}, {100, -0.5f, 0.5f}}, true); fRegistry.add("V0/primary/hRxyGen_DeltaPtOverPtGen", "photon p_{T} resolution; R_{xy}^{gen} (cm);(p_{T}^{rec} - p_{T}^{gen})/p_{T}^{gen}", kTH2F, {{100, 0, 100}, {200, -1.0f, 1.0f}}, true); - fRegistry.add("V0/primary/hsPhotonResolution", - "Photon resolution;p_{T};#eta;R_{xy};Z_{conv};Z_{vtx};#Deltap_{T}/p_{T};#Delta#eta;#Delta#phi", - kTHnSparseF, - {{100, 0, 10}, - {80, -1.6, 1.6}, - {100, 0, 100}, - {100, -50, 50}, - {100, -50, 50}, - {200, -1, 1}, - {100, -0.5, 0.5}, - {100, -0.5, 0.5}}, - false); fRegistry.add("V0/primary/hRxyGen_DeltaEta", "photon #eta resolution;R_{xy}^{gen} (cm);#eta^{rec} - #eta^{gen}", kTH2F, {{100, 0, 100}, {100, -0.5f, 0.5f}}, true); fRegistry.add("V0/primary/hRxyGen_DeltaPhi", "photon #varphi resolution;R_{xy}^{gen} (cm);#varphi^{rec} - #varphi^{gen} (rad.)", kTH2F, {{100, 0, 100}, {100, -0.5f, 0.5f}}, true); fRegistry.add("V0/primary/hRxyGen_DeltaR", "photon #varphi resolution;R_{xy}^{gen} (cm);#varphi^{rec} - #varphi^{gen} (rad.)", kTH2F, {{100, 0, 100}, {100, 0, 100}}, true); - fRegistry.add("V0/primary/hsConvVtxZPtR", "z_{vtx} vs p_{T} vs R_{xy};z_{vtx} (cm);p_{T} (GeV/c);R_{xy} (cm)", kTHnSparseF, {{100, -20.0f, +20.0f}, {100, 0.0f, 10.0f}, {100, 0, 100}}, false); fRegistry.add("V0/primary/hXY_MC", "X vs. Y of true photon conversion point.;X (cm);Y (cm)", kTH2F, {{400, -100.0f, +100}, {400, -100, +100}}, true); fRegistry.add("V0/primary/hRZ_MC", "R vs. Z of true photon conversion point;Z (cm);R_{xy} (cm)", kTH2F, {{200, -100.0f, +100}, {200, 0, 100}}, true); fRegistry.add("V0/primary/hsConvPoint", "photon conversion point;r_{xy} (cm);#varphi (rad.);#eta;", kTHnSparseF, {{100, 0.0f, 100}, {90, 0, 2 * M_PI}, {80, -2, +2}}, false); @@ -248,26 +233,11 @@ struct PCMQCMC { fRegistry.add("V0Leg/primary/hChi2ITS", "chi2/number of ITS clusters", kTH1F, {{100, 0, 10}}, false); fRegistry.add("V0Leg/primary/hITSClusterMap", "ITS cluster map", kTH1F, {{128, -0.5, 127.5}}, false); fRegistry.add("V0Leg/primary/hMeanClusterSizeITS", "mean cluster size ITS; on ITS #times cos(#lambda)", kTH2F, {{1000, 0, 10}, {160, 0, 16}}, false); - fRegistry.add("V0Leg/primary/hXY", "X vs. Y;X (cm);Y (cm)", kTH2F, {{100, 0, 100}, {40, -20, 20}}, false); - fRegistry.add("V0Leg/primary/hZX", "Z vs. X;Z (cm);X (cm)", kTH2F, {{200, -100, 100}, {100, 0, 100}}, false); - fRegistry.add("V0Leg/primary/hZY", "Z vs. Y;Z (cm);Y (cm)", kTH2F, {{200, -100, 100}, {40, -20, 20}}, false); + // fRegistry.add("V0Leg/primary/hXY", "X vs. Y;X (cm);Y (cm)", kTH2F, {{100, 0, 100}, {40, -20, 20}}, false); + // fRegistry.add("V0Leg/primary/hZX", "Z vs. X;Z (cm);X (cm)", kTH2F, {{200, -100, 100}, {100, 0, 100}}, false); + // fRegistry.add("V0Leg/primary/hZY", "Z vs. Y;Z (cm);Y (cm)", kTH2F, {{200, -100, 100}, {40, -20, 20}}, false); fRegistry.add("V0Leg/primary/hPtGen_DeltaPtOverPtGen", "electron p_{T} resolution;p_{T}^{gen} (GeV/c);(p_{T}^{rec} - p_{T}^{gen})/p_{T}^{gen}", kTH2F, {{1000, 0, 10}, {200, -1.0f, 1.0f}}, true); fRegistry.add("V0Leg/primary/hPtGen_DeltaEta", "electron #eta resolution;p_{T}^{gen} (GeV/c);#eta^{rec} - #eta^{gen}", kTH2F, {{1000, 0, 10}, {100, -0.5f, 0.5f}}, true); - if (cfg_fill_resolution) { - fRegistry.add("V0Leg/primary/hsPhotonResolution", - "Photon resolution;p_{T};#eta;R_{xy};Z_{conv};Z_{vtx};#Deltap_{T}/p_{T};#Delta#eta;#Delta#phi", - kTHnSparseF, - {{100, 0, 10}, - {80, -1.6, 1.6}, - {100, 0, 100}, - {100, -50, 50}, - {100, -50, 50}, - {200, -1, 1}, - {100, -0.5, 0.5}, - {100, -0.5, 0.5}}, - false); - } - fRegistry.add("V0Leg/primary/hPtGen_DeltaPhi", "electron #varphi resolution;p_{T}^{gen} (GeV/c);#varphi^{rec} - #varphi^{gen} (rad.)", kTH2F, {{1000, 0, 10}, {100, -0.5f, 0.5f}}, true); fRegistry.add("V0Leg/primary/hRxyGen_DeltaPtOverPtGen", "photon p_{T} resolution; R_{xy}^{gen} (cm);(p_{T}^{rec} - p_{T}^{gen})/p_{T}^{gen}", kTH2F, {{100, 0, 100}, {200, -1.0f, 1.0f}}, true); fRegistry.add("V0Leg/primary/hRxyGen_DeltaEta", "photon #eta resolution;R_{xy}^{gen} (cm);#eta^{rec} - #eta^{gen}", kTH2F, {{100, 0, 100}, {100, -0.5f, 0.5f}}, true); @@ -325,7 +295,6 @@ struct PCMQCMC { fV0PhotonCut.SetChi2PerClusterITS(-1e+10, pcmcuts.cfg_max_chi2its); fV0PhotonCut.SetNClustersITS(0, 7); fV0PhotonCut.SetMeanClusterSizeITSob(0.0, 16.0); - fV0PhotonCut.SetIsWithinBeamPipe(pcmcuts.cfg_require_v0_with_correct_xz); fV0PhotonCut.SetDisableITSonly(pcmcuts.cfg_disable_itsonly_track); fV0PhotonCut.SetDisableTPConly(pcmcuts.cfg_disable_tpconly_track); fV0PhotonCut.SetRequireITSTPC(pcmcuts.cfg_require_v0_with_itstpc); @@ -391,9 +360,6 @@ struct PCMQCMC { fRegistry.fill(HIST("V0/") + HIST(mcphoton_types[mctype]) + HIST("hMassGamma"), v0.v0radius(), v0.mGamma()); fRegistry.fill(HIST("V0/") + HIST(mcphoton_types[mctype]) + HIST("hKFChi2vsM"), v0.mGamma(), v0.chiSquareNDF()); fRegistry.fill(HIST("V0/") + HIST(mcphoton_types[mctype]) + HIST("hKFChi2vsR"), v0.v0radius(), v0.chiSquareNDF()); - fRegistry.fill(HIST("V0/") + HIST(mcphoton_types[mctype]) + HIST("hsConvVtxZPtR"), - v0.vz(), v0.pt(), v0.v0radius()); - fRegistry.fill(HIST("V0/") + HIST(mcphoton_types[mctype]) + HIST("hKFChi2vsX"), v0.vx(), v0.chiSquareNDF()); fRegistry.fill(HIST("V0/") + HIST(mcphoton_types[mctype]) + HIST("hKFChi2vsY"), v0.vy(), v0.chiSquareNDF()); fRegistry.fill(HIST("V0/") + HIST(mcphoton_types[mctype]) + HIST("hKFChi2vsZ"), v0.vz(), v0.chiSquareNDF()); @@ -402,17 +368,6 @@ struct PCMQCMC { fRegistry.fill(HIST("V0/") + HIST(mcphoton_types[mctype]) + HIST("hPtGen_DeltaPhi"), mcphoton.pt(), v0.phi() - mcphoton.phi()); fRegistry.fill(HIST("V0/") + HIST(mcphoton_types[mctype]) + HIST("hRxyGen_DeltaPtOverPtGen"), std::sqrt(std::pow(mcleg.vx(), 2) + std::pow(mcleg.vy(), 2)), (v0.pt() - mcphoton.pt()) / mcphoton.pt()); fRegistry.fill(HIST("V0/") + HIST(mcphoton_types[mctype]) + HIST("hRxyGen_DeltaEta"), std::sqrt(std::pow(mcleg.vx(), 2) + std::pow(mcleg.vy(), 2)), v0.eta() - mcphoton.eta()); - if (cfg_fill_resolution) { - fRegistry.fill(HIST("V0/") + HIST(mcphoton_types[mctype]) + HIST("hsPhotonResolution"), - mcphoton.pt(), - mcphoton.eta(), - std::sqrt(mcleg.vx() * mcleg.vx() + mcleg.vy() * mcleg.vy()), - mcleg.vz(), - v0.vz(), - (v0.pt() - mcphoton.pt()) / mcphoton.pt(), - v0.eta() - mcphoton.eta(), - TVector2::Phi_mpi_pi(v0.phi() - mcphoton.phi())); - } fRegistry.fill(HIST("V0/") + HIST(mcphoton_types[mctype]) + HIST("hRxyGen_DeltaPhi"), std::sqrt(std::pow(mcleg.vx(), 2) + std::pow(mcleg.vy(), 2)), v0.phi() - mcphoton.phi()); fRegistry.fill(HIST("V0/") + HIST(mcphoton_types[mctype]) + HIST("hRxyGen_DeltaR"), std::sqrt(std::pow(mcleg.vx(), 2) + std::pow(mcleg.vy(), 2)), v0.v0radius() - std::sqrt(std::pow(mcleg.vx(), 2) + std::pow(mcleg.vy(), 2))); fRegistry.fill(HIST("V0/") + HIST(mcphoton_types[mctype]) + HIST("hConvPoint_diffX"), mcleg.vx(), v0.vx() - mcleg.vx()); @@ -449,25 +404,14 @@ struct PCMQCMC { fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hTPCdEdx"), leg.tpcInnerParam(), leg.tpcSignal()); fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hTPCNsigmaEl"), leg.tpcInnerParam(), leg.tpcNSigmaEl()); fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hTPCNsigmaPi"), leg.tpcInnerParam(), leg.tpcNSigmaPi()); - fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hXY"), leg.x(), leg.y()); - fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hZX"), leg.z(), leg.x()); - fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hZY"), leg.z(), leg.y()); + // fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hXY"), leg.x(), leg.y()); + // fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hZX"), leg.z(), leg.x()); + // fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hZY"), leg.z(), leg.y()); auto mcleg = leg.template emmcparticle_as(); fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hPtGen_DeltaPtOverPtGen"), mcleg.pt(), (leg.pt() - mcleg.pt()) / mcleg.pt()); fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hPtGen_DeltaEta"), mcleg.pt(), leg.eta() - mcleg.eta()); fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hPtGen_DeltaPhi"), mcleg.pt(), leg.phi() - mcleg.phi()); fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hRxyGen_DeltaPtOverPtGen"), std::sqrt(std::pow(mcleg.vx(), 2) + std::pow(mcleg.vy(), 2)), (leg.pt() - mcleg.pt()) / mcleg.pt()); - if (cfg_fill_resolution) { - fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hsPhotonResolution"), - mcleg.pt(), - mcleg.eta(), - std::sqrt(mcleg.vx() * mcleg.vx() + mcleg.vy() * mcleg.vy()), - mcleg.vz(), - leg.z(), - (leg.pt() - mcleg.pt()) / mcleg.pt(), - leg.eta() - mcleg.eta(), - TVector2::Phi_mpi_pi(leg.phi() - mcleg.phi())); - } fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hRxyGen_DeltaEta"), std::sqrt(std::pow(mcleg.vx(), 2) + std::pow(mcleg.vy(), 2)), leg.eta() - mcleg.eta()); fRegistry.fill(HIST("V0Leg/") + HIST(mcphoton_types[mctype]) + HIST("hRxyGen_DeltaPhi"), std::sqrt(std::pow(mcleg.vx(), 2) + std::pow(mcleg.vy(), 2)), leg.phi() - mcleg.phi()); } diff --git a/PWGEM/PhotonMeson/Tasks/prefilterPhoton.cxx b/PWGEM/PhotonMeson/Tasks/prefilterPhoton.cxx index ecc1eb34329..ea3dfd23dc1 100644 --- a/PWGEM/PhotonMeson/Tasks/prefilterPhoton.cxx +++ b/PWGEM/PhotonMeson/Tasks/prefilterPhoton.cxx @@ -104,7 +104,6 @@ struct prefilterPhoton { Configurable cfg_min_cospa{"cfg_min_cospa", 0.99, "min V0 CosPA"}; Configurable cfg_max_pca{"cfg_max_pca", 1.5, "max distance btween 2 legs"}; Configurable cfg_max_chi2kf{"cfg_max_chi2kf", 1e+10, "max chi2/ndf with KF"}; - Configurable cfg_require_v0_with_correct_xz{"cfg_require_v0_with_correct_xz", false, "flag to select V0s with correct xz"}; Configurable cfg_reject_v0_on_itsib{"cfg_reject_v0_on_itsib", true, "flag to reject V0s on ITSib"}; Configurable cfg_min_ncluster_tpc{"cfg_min_ncluster_tpc", 0, "min ncluster tpc"}; Configurable cfg_min_ncrossedrows{"cfg_min_ncrossedrows", 40, "min ncrossed rows"}; @@ -281,7 +280,6 @@ struct prefilterPhoton { fV0PhotonCut.SetNClustersITS(0, 7); fV0PhotonCut.SetMeanClusterSizeITSob(0.0, 16.0); - fV0PhotonCut.SetIsWithinBeamPipe(pcmcuts.cfg_require_v0_with_correct_xz); } void DefineDileptonCut() diff --git a/PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx b/PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx index 2e64bd6ebe2..aa837b02233 100644 --- a/PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/taskPi0FlowEMC.cxx @@ -14,72 +14,96 @@ /// /// \author M. Hemmer, marvin.hemmer@cern.ch -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Math/Vector4D.h" -#include "Math/Vector3D.h" -#include "Math/LorentzRotation.h" -#include "Math/Rotation3D.h" -#include "Math/AxisAngle.h" - -#include "CCDB/BasicCCDBManager.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/runDataProcessing.h" - -#include "Common/Core/EventPlaneHelper.h" -#include "Common/Core/RecoDecay.h" -#include "Common/DataModel/Qvectors.h" -#include "CommonConstants/MathConstants.h" - -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsEMCAL/Constants.h" -#include "EMCALBase/Geometry.h" -#include "EMCALCalib/BadChannelMap.h" - -#include "PWGEM/Dilepton/Utils/EMTrackUtilities.h" #include "PWGEM/PhotonMeson/Core/EMCPhotonCut.h" #include "PWGEM/PhotonMeson/Core/EMPhotonEventCut.h" #include "PWGEM/PhotonMeson/DataModel/gammaTables.h" -#include "PWGEM/PhotonMeson/Utils/emcalHistoDefinitions.h" -#include "PWGEM/PhotonMeson/Utils/PairUtilities.h" #include "PWGEM/PhotonMeson/Utils/EventHistograms.h" -#include "PWGEM/PhotonMeson/Utils/NMHistograms.h" +#include "PWGEM/PhotonMeson/Utils/emcalHistoDefinitions.h" + +#include "Common/CCDB/TriggerAliases.h" +#include "Common/Core/EventPlaneHelper.h" +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include // IWYU pragma: keep +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::aod; using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::soa; -using namespace o2::aod::pwgem::photonmeson::photonpair; using namespace o2::aod::pwgem::photon; -using namespace o2::aod::pwgem::dilepton::utils; - -enum QvecEstimator { FT0M = 0, - FT0A = 1, - FT0C, - TPCPos, - TPCNeg, - TPCTot }; - -enum CentralityEstimator { None = 0, - CFT0A = 1, - CFT0C, - CFT0M, - NCentralityEstimators + +enum QvecEstimator { + FT0M = 0, + FT0A = 1, + FT0C, + TPCPos, + TPCNeg, + TPCTot +}; + +enum CentralityEstimator { + None = 0, + CFT0A = 1, + CFT0C, + CFT0M, + NCentralityEstimators +}; + +enum Harmonics { + kNone = 0, + kDirect = 1, + kElliptic = 2, + kTriangluar = 3, + kQuadrangular = 4, + kPentagonal = 5, + kHexagonal = 6, + kHeptagonal = 7, + kOctagonal = 8 }; struct TaskPi0FlowEMC { + static constexpr float MinEnergy = 0.7f; + // configurable for flow Configurable harmonic{"harmonic", 2, "harmonic number"}; Configurable qvecDetector{"qvecDetector", 0, "Detector for Q vector estimation (FT0M: 0, FT0A: 1, FT0C: 2, TPC Pos: 3, TPC Neg: 4, TPC Tot: 5)"}; @@ -98,6 +122,8 @@ struct TaskPi0FlowEMC { Configurable cfgDoM02{"cfgDoM02", false, "Flag to enable flow vs M02 for single photons"}; Configurable cfgDoReverseScaling{"cfgDoReverseScaling", false, "Flag to reverse the scaling that is possibly applied during NonLin"}; Configurable cfgDoPlaneQA{"cfgDoPlaneQA", false, "Flag to enable QA plots comparing in and out of plane"}; + Configurable cfgMaxQVector{"cfgMaxQVector", 20.f, "Maximum allowed absolute QVector value."}; + Configurable cfgMaxAsymmetry{"cfgMaxAsymmetry", 0.1f, "Maximum allowed asymmetry for photon pairs used in calibration."}; // configurable axis ConfigurableAxis thnConfigAxisInvMass{"thnConfigAxisInvMass", {400, 0.0, 0.8}, ""}; @@ -107,6 +133,7 @@ struct TaskPi0FlowEMC { ConfigurableAxis thnConfigAxisCosDeltaPhi{"thnConfigAxisCosDeltaPhi", {8, -1., 1.}, ""}; ConfigurableAxis thnConfigAxisScalarProd{"thnConfigAxisScalarProd", {100, -5., 5.}, ""}; ConfigurableAxis thnConfigAxisM02{"thnConfigAxisM02", {200, 0., 5.}, ""}; + ConfigurableAxis thnConfigAxisEnergyCalib{"thnConfigAxisEnergyCalib", {200, 0., 20.}, ""}; EMPhotonEventCut fEMEventCut; struct : ConfigurableGroup { @@ -173,6 +200,7 @@ struct TaskPi0FlowEMC { Configurable cfgSpresoPath{"cfgSpresoPath", "Users/m/mhemmer/EM/Flow/Resolution", "Path to SP resolution file"}; Configurable cfgApplySPresolution{"cfgApplySPresolution", 0, "Apply resolution correction"}; Configurable doEMCalCalib{"doEMCalCalib", 0, "Produce output for EMCal calibration"}; + Configurable cfgEnableNonLin{"cfgEnableNonLin", false, "flag to turn extra non linear energy calibration on/off"}; } correctionConfig; SliceCache cache; @@ -187,6 +215,7 @@ struct TaskPi0FlowEMC { using EMCalPhotons = soa::Join; using FilteredCollsWithQvecs = soa::Filtered>; using CollsWithQvecs = soa::Join; + using Colls = soa::Join; Preslice perCollisionEMC = aod::emccluster::emeventId; @@ -205,6 +234,12 @@ struct TaskPi0FlowEMC { std::vector lookupTable1D; float epsilon = 1.e-8; + // static constexpr + static constexpr int64_t NMinPhotonRotBkg = 3; + + // Usage when cfgEnableNonLin is enabled + std::unique_ptr fEMCalCorrectionFactor; // ("fEMCalCorrectionFactor","(1 + [0]/x + [1]/x^2) / (1 + [2]/x)", 0.3, 100.); + // To access the 1D array inline int getIndex(int iEta, int iPhi) { @@ -265,7 +300,7 @@ struct TaskPi0FlowEMC { void init(InitContext&) { - if (harmonic != 2 && harmonic != 3) { + if (harmonic != kElliptic && harmonic != kTriangluar) { LOG(info) << "Harmonic was set to " << harmonic << " but can only be 2 or 3!"; } @@ -283,10 +318,10 @@ struct TaskPi0FlowEMC { const AxisSpec thnAxisM02{thnConfigAxisM02, "M_{02}"}; const AxisSpec thAxisTanThetaPhi{mesonConfig.thConfigAxisTanThetaPhi, "atan(#Delta#theta/#Delta#varphi)"}; const AxisSpec thAxisClusterEnergy{thnConfigAxisPt, "#it{E} (GeV)"}; + const AxisSpec thAxisEnergyCalib{thnConfigAxisEnergyCalib, "#it{E}_{clus} (GeV)"}; const AxisSpec thAxisAlpha{100, -1., +1, "#alpha"}; const AxisSpec thAxisMult{1000, 0., +1000, "#it{N}_{ch}"}; const AxisSpec thAxisEnergy{1000, 0., 100., "#it{E}_{clus} (GeV)"}; - const AxisSpec thAxisEnergyCalib{100, 0., 20., "#it{E}_{clus} (GeV)"}; const AxisSpec thAxisTime{1500, -600, 900, "#it{t}_{cl} (ns)"}; const AxisSpec thAxisEta{320, -0.8, 0.8, "#eta"}; const AxisSpec thAxisPhi{500, 0, 2 * 3.14159, "phi"}; @@ -414,6 +449,9 @@ struct TaskPi0FlowEMC { LOG(info) << "thnConfigAxisInvMass.value[1] = " << thnConfigAxisInvMass.value[1] << " thnConfigAxisInvMass.value.back() = " << thnConfigAxisInvMass.value.back(); LOG(info) << "thnConfigAxisPt.value[1] = " << thnConfigAxisPt.value[1] << " thnConfigAxisPt.value.back() = " << thnConfigAxisPt.value.back(); + + fEMCalCorrectionFactor = std::make_unique("fEMCalCorrectionFactor", "(1 + [0]/x + [1]/x^2) / (1 + [2]/x)", 0.3, 100.); + fEMCalCorrectionFactor->SetParameters(-5.33426e-01, 1.40144e-02, -5.24434e-01); }; // end init /// Change radians to degree @@ -450,7 +488,8 @@ struct TaskPi0FlowEMC { /// Get the centrality /// \param collision is the collision with the centrality information - float getCentrality(CollsWithQvecs::iterator const& collision) + template + float getCentrality(TCollision const& collision) { float cent = -999.; switch (centEstimator) { @@ -492,65 +531,65 @@ struct TaskPi0FlowEMC { switch (detector) { case QvecEstimator::FT0M: - if (harmonic == 2) { + if (harmonic == kElliptic) { xQVec = collision.q2xft0m(); yQVec = collision.q2yft0m(); - } else if (harmonic == 3) { + } else if (harmonic == kTriangluar) { xQVec = collision.q3xft0m(); yQVec = collision.q3yft0m(); } break; case QvecEstimator::FT0A: - if (harmonic == 2) { + if (harmonic == kElliptic) { xQVec = collision.q2xft0a(); yQVec = collision.q2yft0a(); - } else if (harmonic == 3) { + } else if (harmonic == kTriangluar) { xQVec = collision.q3xft0a(); yQVec = collision.q3yft0a(); } break; case QvecEstimator::FT0C: - if (harmonic == 2) { + if (harmonic == kElliptic) { xQVec = collision.q2xft0c(); yQVec = collision.q2yft0c(); - } else if (harmonic == 3) { + } else if (harmonic == kTriangluar) { xQVec = collision.q3xft0c(); yQVec = collision.q3yft0c(); } break; case QvecEstimator::TPCPos: - if (harmonic == 2) { + if (harmonic == kElliptic) { xQVec = collision.q2xbpos(); yQVec = collision.q2ybpos(); - } else if (harmonic == 3) { + } else if (harmonic == kTriangluar) { xQVec = collision.q3xbpos(); yQVec = collision.q3ybpos(); } break; case QvecEstimator::TPCNeg: - if (harmonic == 2) { + if (harmonic == kElliptic) { xQVec = collision.q2xbneg(); yQVec = collision.q2ybneg(); - } else if (harmonic == 3) { + } else if (harmonic == kTriangluar) { xQVec = collision.q3xbneg(); yQVec = collision.q3ybneg(); } break; case QvecEstimator::TPCTot: - if (harmonic == 2) { + if (harmonic == kElliptic) { xQVec = collision.q2xbtot(); yQVec = collision.q2ybtot(); - } else if (harmonic == 3) { + } else if (harmonic == kTriangluar) { xQVec = collision.q3xbtot(); yQVec = collision.q3ybtot(); } break; default: LOG(warning) << "Q vector estimator not valid. Falling back to FT0M"; - if (harmonic == 2) { + if (harmonic == kElliptic) { xQVec = collision.q2xft0m(); yQVec = collision.q2yft0m(); - } else if (harmonic == 3) { + } else if (harmonic == kTriangluar) { xQVec = collision.q3xft0m(); yQVec = collision.q3yft0m(); } @@ -565,7 +604,7 @@ struct TaskPi0FlowEMC { { bool isgood = true; for (const auto& QVec : QVecs) { - if (std::fabs(QVec) > 20.f) { + if (std::fabs(QVec) > cfgMaxQVector) { isgood = false; break; } @@ -660,7 +699,7 @@ struct TaskPi0FlowEMC { void rotationBackground(const ROOT::Math::PtEtaPhiMVector& meson, ROOT::Math::PtEtaPhiMVector photon1, ROOT::Math::PtEtaPhiMVector photon2, TPhotons const& photons_coll, unsigned int ig1, unsigned int ig2, CollsWithQvecs::iterator const& collision) { // if less than 3 clusters are present skip event since we need at least 3 clusters - if (photons_coll.size() < 3) { + if (photons_coll.size() < NMinPhotonRotBkg) { return; } @@ -703,7 +742,11 @@ struct TaskPi0FlowEMC { if (checkEtaPhi1D(photon.eta(), RecoDecay::constrainAngle(photon.phi())) >= cfgEMCalMapLevelBackground.value) { continue; } - ROOT::Math::PtEtaPhiMVector photon3(photon.pt(), photon.eta(), photon.phi(), 0.); + float energyCorrectionFactor = 1.f; + if (correctionConfig.cfgEnableNonLin.value) { + energyCorrectionFactor = fEMCalCorrectionFactor->Eval(photon.e() > MinEnergy ? photon.e() : MinEnergy); + } + ROOT::Math::PtEtaPhiMVector photon3(energyCorrectionFactor * photon.pt(), photon.eta(), photon.phi(), 0.); if (iCellIDPhoton1 >= 0) { ROOT::Math::PtEtaPhiMVector mother1 = photon1 + photon3; float openingAngle1 = std::acos(photon1.Vect().Dot(photon3.Vect()) / (photon1.P() * photon3.P())); @@ -755,11 +798,11 @@ struct TaskPi0FlowEMC { } /// \brief Calculate background using rotation background method for calib - template - void rotationBackgroundCalib(const ROOT::Math::PtEtaPhiMVector& meson, ROOT::Math::PtEtaPhiMVector photon1, ROOT::Math::PtEtaPhiMVector photon2, TPhotons const& photons_coll, unsigned int ig1, unsigned int ig2, CollsWithQvecs::iterator const& collision) + template + void rotationBackgroundCalib(const ROOT::Math::PtEtaPhiMVector& meson, ROOT::Math::PtEtaPhiMVector photon1, ROOT::Math::PtEtaPhiMVector photon2, TPhotons const& photons_coll, unsigned int ig1, unsigned int ig2, TCollision const& collision) { // if less than 3 clusters are present skip event since we need at least 3 clusters - if (photons_coll.size() < 3) { + if (photons_coll.size() < NMinPhotonRotBkg) { return; } float cent = getCentrality(collision); @@ -792,9 +835,13 @@ struct TaskPi0FlowEMC { if (checkEtaPhi1D(photon.eta(), RecoDecay::constrainAngle(photon.phi())) >= cfgEMCalMapLevelBackground.value) { continue; } - ROOT::Math::PtEtaPhiMVector photon3(photon.pt(), photon.eta(), photon.phi(), 0.); + float energyCorrectionFactor = 1.f; + if (correctionConfig.cfgEnableNonLin.value) { + energyCorrectionFactor = fEMCalCorrectionFactor->Eval(photon.e() > MinEnergy ? photon.e() : MinEnergy); + } + ROOT::Math::PtEtaPhiMVector photon3(energyCorrectionFactor * photon.pt(), photon.eta(), photon.phi(), 0.); if (iCellIDPhoton1 >= 0) { - if (std::fabs((photon1.E() - photon3.E()) / (photon1.E() + photon3.E()) < 0.1)) { // only use symmetric decays + if (std::fabs((photon1.E() - photon3.E()) / (photon1.E() + photon3.E()) < cfgMaxAsymmetry)) { // only use symmetric decays ROOT::Math::PtEtaPhiMVector mother1 = photon1 + photon3; float openingAngle1 = std::acos(photon1.Vect().Dot(photon3.Vect()) / (photon1.P() * photon3.P())); @@ -812,7 +859,7 @@ struct TaskPi0FlowEMC { } } if (iCellIDPhoton2 >= 0) { - if (std::fabs((photon2.E() - photon3.E()) / (photon2.E() + photon3.E()) < 0.1)) { // only use symmetric decays + if (std::fabs((photon2.E() - photon3.E()) / (photon2.E() + photon3.E()) < cfgMaxAsymmetry)) { // only use symmetric decays ROOT::Math::PtEtaPhiMVector mother2 = photon2 + photon3; float openingAngle2 = std::acos(photon2.Vect().Dot(photon3.Vect()) / (photon2.P() * photon3.P())); @@ -868,6 +915,10 @@ struct TaskPi0FlowEMC { void processEMCal(CollsWithQvecs const& collisions, EMCalPhotons const& clusters) { int nColl = 1; + float energyCorrectionFactor = 1.f; + if (cfgDoReverseScaling.value) { + energyCorrectionFactor = 1.0505f; + } for (const auto& collision : collisions) { auto photonsPerCollision = clusters.sliceBy(perCollisionEMC, collision.globalIndex()); @@ -946,18 +997,14 @@ struct TaskPi0FlowEMC { continue; } } - - ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); - ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); - if (cfgDoReverseScaling.value) { - // Convert to PxPyPzEVector to modify energy - ROOT::Math::PxPyPzEVector v1Mod(v1); - v1Mod.SetE(v1Mod.E() * 1.0505); - v1 = ROOT::Math::PtEtaPhiMVector(v1Mod.Pt(), v1Mod.Eta(), v1Mod.Phi(), 0.); - ROOT::Math::PxPyPzEVector v2Mod(v2); - v2Mod.SetE(v2Mod.E() * 1.0505); - v2 = ROOT::Math::PtEtaPhiMVector(v2Mod.Pt(), v2Mod.Eta(), v2Mod.Phi(), 0.); + if (correctionConfig.cfgEnableNonLin.value) { + energyCorrectionFactor = fEMCalCorrectionFactor->Eval(g1.e() > MinEnergy ? g1.e() : MinEnergy); } + ROOT::Math::PtEtaPhiMVector v1(energyCorrectionFactor * g1.pt(), g1.eta(), g1.phi(), 0.); + if (correctionConfig.cfgEnableNonLin.value) { + energyCorrectionFactor = fEMCalCorrectionFactor->Eval(g2.e() > MinEnergy ? g2.e() : MinEnergy); + } + ROOT::Math::PtEtaPhiMVector v2(energyCorrectionFactor * g2.pt(), g2.eta(), g2.phi(), 0.); ROOT::Math::PtEtaPhiMVector vMeson = v1 + v2; float dTheta = v1.Theta() - v2.Theta(); float dPhi = v1.Phi() - v2.Phi(); @@ -1006,6 +1053,10 @@ struct TaskPi0FlowEMC { // Pi0 from EMCal void processEMCalMixed(FilteredCollsWithQvecs const& collisions, FilteredEMCalPhotons const& clusters) { + float energyCorrectionFactor = 1.f; + if (cfgDoReverseScaling.value) { + energyCorrectionFactor = 1.0505f; + } auto getClustersSize = [&clusters, this](FilteredCollsWithQvecs::iterator const& col) { auto associatedClusters = clusters.sliceByCached(emccluster::emeventId, col.globalIndex(), this->cache); // it's cached, so slicing/grouping happens only once @@ -1054,18 +1105,14 @@ struct TaskPi0FlowEMC { continue; } } - ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); - ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); - - if (cfgDoReverseScaling.value) { - // Convert to PxPyPzEVector to modify energy - ROOT::Math::PxPyPzEVector v1Mod(v1); - v1Mod.SetE(v1Mod.E() * 1.0505); - v1 = ROOT::Math::PtEtaPhiMVector(v1Mod.Pt(), v1Mod.Eta(), v1Mod.Phi(), 0.); - ROOT::Math::PxPyPzEVector v2Mod(v2); - v2Mod.SetE(v2Mod.E() * 1.0505); - v2 = ROOT::Math::PtEtaPhiMVector(v2Mod.Pt(), v2Mod.Eta(), v2Mod.Phi(), 0.); + if (correctionConfig.cfgEnableNonLin.value) { + energyCorrectionFactor = fEMCalCorrectionFactor->Eval(g1.e() > MinEnergy ? g1.e() : MinEnergy); + } + ROOT::Math::PtEtaPhiMVector v1(energyCorrectionFactor * g1.pt(), g1.eta(), g1.phi(), 0.); + if (correctionConfig.cfgEnableNonLin.value) { + energyCorrectionFactor = fEMCalCorrectionFactor->Eval(g2.e() > MinEnergy ? g2.e() : MinEnergy); } + ROOT::Math::PtEtaPhiMVector v2(energyCorrectionFactor * g2.pt(), g2.eta(), g2.phi(), 0.); ROOT::Math::PtEtaPhiMVector vMeson = v1 + v2; float dTheta = v1.Theta() - v2.Theta(); @@ -1138,7 +1185,7 @@ struct TaskPi0FlowEMC { float yQVecBNeg = -999.f; float xQVecBTot = -999.f; float yQVecBTot = -999.f; - if (harmonic == 2) { + if (harmonic == kElliptic) { xQVecFT0a = collision.q2xft0a(); yQVecFT0a = collision.q2yft0a(); xQVecFT0c = collision.q2xft0c(); @@ -1151,7 +1198,7 @@ struct TaskPi0FlowEMC { yQVecBNeg = collision.q2ybneg(); xQVecBTot = collision.q2xbtot(); yQVecBTot = collision.q2ybtot(); - } else if (harmonic == 3) { + } else if (harmonic == kTriangluar) { xQVecFT0a = collision.q3xft0a(); yQVecFT0a = collision.q3yft0a(); xQVecFT0c = collision.q3xft0c(); @@ -1203,7 +1250,7 @@ struct TaskPi0FlowEMC { registry.fill(HIST("epReso/hEpResoFT0mTPCneg"), centrality, std::cos(harmonic * getDeltaPsiInRange(epFT0m, epBNegs))); registry.fill(HIST("epReso/hEpResoFT0mTPCtot"), centrality, std::cos(harmonic * getDeltaPsiInRange(epFT0m, epBTots))); registry.fill(HIST("epReso/hEpResoTPCposTPCneg"), centrality, std::cos(harmonic * getDeltaPsiInRange(epBPoss, epBNegs))); - for (int n = 1; n <= 8; n++) { + for (int n = 1; n <= kOctagonal; n++) { registry.fill(HIST("epReso/hEpCosCoefficientsFT0c"), centrality, n, std::cos(n * epFT0c)); registry.fill(HIST("epReso/hEpSinCoefficientsFT0c"), centrality, n, std::sin(n * epFT0c)); registry.fill(HIST("epReso/hEpCosCoefficientsFT0a"), centrality, n, std::cos(n * epFT0a)); @@ -1222,8 +1269,9 @@ struct TaskPi0FlowEMC { PROCESS_SWITCH(TaskPi0FlowEMC, processResolution, "Process resolution", false); // EMCal calibration - void processEMCalCalib(CollsWithQvecs const& collisions, EMCalPhotons const& clusters) + void processEMCalCalib(Colls const& collisions, EMCalPhotons const& clusters) { + float energyCorrectionFactor = 1.f; if (!correctionConfig.doEMCalCalib) { return; } @@ -1244,10 +1292,6 @@ struct TaskPi0FlowEMC { // event selection continue; } - if (!isQvecGood(getAllQvec(collision))) { - // selection based on QVector - continue; - } runNow = collision.runNumber(); if (runNow != runBefore) { initCCDB(collision); @@ -1281,18 +1325,16 @@ struct TaskPi0FlowEMC { } } - ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); - ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); - if (cfgDoReverseScaling.value) { - // Convert to PxPyPzEVector to modify energy - ROOT::Math::PxPyPzEVector v1Mod(v1); - v1Mod.SetE(v1Mod.E() * 1.0505); - v1 = ROOT::Math::PtEtaPhiMVector(v1Mod.Pt(), v1Mod.Eta(), v1Mod.Phi(), 0.); - ROOT::Math::PxPyPzEVector v2Mod(v2); - v2Mod.SetE(v2Mod.E() * 1.0505); - v2 = ROOT::Math::PtEtaPhiMVector(v2Mod.Pt(), v2Mod.Eta(), v2Mod.Phi(), 0.); + if (correctionConfig.cfgEnableNonLin.value) { + energyCorrectionFactor = fEMCalCorrectionFactor->Eval(g1.e() > MinEnergy ? g1.e() : MinEnergy); + } + ROOT::Math::PtEtaPhiMVector v1(energyCorrectionFactor * g1.pt(), g1.eta(), g1.phi(), 0.); + if (correctionConfig.cfgEnableNonLin.value) { + energyCorrectionFactor = fEMCalCorrectionFactor->Eval(g2.e() > MinEnergy ? g2.e() : MinEnergy); } + ROOT::Math::PtEtaPhiMVector v2(energyCorrectionFactor * g2.pt(), g2.eta(), g2.phi(), 0.); ROOT::Math::PtEtaPhiMVector vMeson = v1 + v2; + float dTheta = v1.Theta() - v2.Theta(); float dPhi = v1.Phi() - v2.Phi(); float openingAngle = std::acos(v1.Vect().Dot(v2.Vect()) / (v1.P() * v2.P())); @@ -1323,7 +1365,7 @@ struct TaskPi0FlowEMC { registry.fill(HIST("hClusterCuts"), 5); continue; } - if (std::fabs((v1.E() - v2.E()) / (v1.E() + v2.E()) < 0.1)) { // only use symmetric decays + if (std::fabs((v1.E() - v2.E()) / (v1.E() + v2.E()) < cfgMaxAsymmetry)) { // only use symmetric decays registry.fill(HIST("hClusterCuts"), 6); registry.fill(HIST("hSparseCalibSE"), vMeson.M(), vMeson.E() / 2., getCentrality(collision)); } diff --git a/PWGEM/PhotonMeson/Utils/ClusterHistograms.h b/PWGEM/PhotonMeson/Utils/ClusterHistograms.h index bb1a641bbfe..b5f0eb6db85 100644 --- a/PWGEM/PhotonMeson/Utils/ClusterHistograms.h +++ b/PWGEM/PhotonMeson/Utils/ClusterHistograms.h @@ -9,40 +9,51 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// Header file for histograms used in EMC cluster QA -/// \author nicolas.strangmann@cern.ch +/// \file ClusterHistograms.h +/// \brief Header file for histograms used in EMC cluster QA +/// \author N. Strangmann, nicolas.strangmann@cern.ch #ifndef PWGEM_PHOTONMESON_UTILS_CLUSTERHISTOGRAMS_H_ #define PWGEM_PHOTONMESON_UTILS_CLUSTERHISTOGRAMS_H_ +#include +#include + +#include + +#include +#include + +#include + using namespace o2::framework; namespace o2::aod::pwgem::photonmeson::utils::clusterhistogram { -void addClusterHistograms(HistogramRegistry* fRegistry, bool do2DQA) +inline void addClusterHistograms(HistogramRegistry* fRegistry, bool do2DQA) { - fRegistry->add("Cluster/before/hE", "E_{cluster};#it{E}_{cluster} (GeV);#it{N}_{cluster}", kTH1F, {{500, 0.0f, 50}}, true); - fRegistry->add("Cluster/before/hPt", "Transverse momenta of clusters;#it{p}_{T} (GeV/c);#it{N}_{cluster}", kTH1F, {{500, 0.0f, 50}}, true); - fRegistry->add("Cluster/before/hNgamma", "Number of #gamma candidates per collision;#it{N}_{#gamma} per collision;#it{N}_{collisions}", kTH1F, {{51, -0.5f, 50.5f}}, true); - fRegistry->add("Cluster/before/hEtaPhi", "#eta vs #varphi;#eta;#varphi (rad.)", kTH2F, {{280, -0.7f, 0.7f}, {180, 0, 2 * M_PI}}, true); - fRegistry->add("Cluster/before/hNTracks", "Number of tracks considered for TM;#it{N}_{tracks};#it{N}_{cluster}", kTH1F, {{20, -0.5f, 19.5}}, true); - fRegistry->add("Cluster/before/hTrackdEtadPhi", "d#eta vs. d#varphi of matched tracks;d#eta;d#varphi (rad.)", kTH2F, {{200, -0.2f, 0.2f}, {200, -0.2f, 0.2f}}, true); + fRegistry->add("Cluster/before/hE", "E_{cluster};#it{E}_{cluster} (GeV);#it{N}_{cluster}", o2::framework::kTH1F, {{500, 0.0f, 50}}, true); + fRegistry->add("Cluster/before/hPt", "Transverse momenta of clusters;#it{p}_{T} (GeV/c);#it{N}_{cluster}", o2::framework::kTH1F, {{500, 0.0f, 50}}, true); + fRegistry->add("Cluster/before/hNgamma", "Number of #gamma candidates per collision;#it{N}_{#gamma} per collision;#it{N}_{collisions}", o2::framework::kTH1F, {{51, -0.5f, 50.5f}}, true); + fRegistry->add("Cluster/before/hEtaPhi", "#eta vs #varphi;#eta;#varphi (rad.)", o2::framework::kTH2F, {{280, -0.7f, 0.7f}, {180, 0, 2 * M_PI}}, true); + fRegistry->add("Cluster/before/hNTracks", "Number of tracks considered for TM;#it{N}_{tracks};#it{N}_{cluster}", o2::framework::kTH1F, {{20, -0.5f, 19.5}}, true); + fRegistry->add("Cluster/before/hTrackdEtadPhi", "d#eta vs. d#varphi of matched tracks;d#eta;d#varphi (rad.)", o2::framework::kTH2F, {{200, -0.2f, 0.2f}, {200, -0.2f, 0.2f}}, true); if (do2DQA) { // Check if 2D QA histograms were selected in em-qc task - fRegistry->add("Cluster/before/hNCell", "#it{N}_{cells};N_{cells} (GeV);#it{E}_{cluster} (GeV)", kTH2F, {{26, -0.5, 25.5}, {200, 0, 20}}, true); - fRegistry->add("Cluster/before/hM02", "Long ellipse axis;#it{M}_{02} (cm);#it{E}_{cluster} (GeV)", kTH2F, {{200, 0, 2}, {200, 0, 20}}, true); - fRegistry->add("Cluster/before/hTime", "Cluster time;#it{t}_{cls} (ns);#it{E}_{cluster} (GeV)", kTH2F, {{300, -150, 150}, {200, 0, 20}}, true); - fRegistry->add("Cluster/before/hTrackdEta", "d#eta vs. E of matched tracks;d#eta;#it{E}_{cluster} (GeV)", kTH2F, {{200, -0.2f, 0.2f}, {200, 0, 20}}, true); - fRegistry->add("Cluster/before/hTrackdPhi", "d#phi vs. E of matched tracks;d#varphi (rad.);#it{E}_{cluster} (GeV)", kTH2F, {{200, -0.2f, 0.2f}, {200, 0, 20}}, true); - fRegistry->add("Cluster/before/hTrackEOverP", "Energy of cluster divided by momentum of matched tracks;#it{E}_{cluster}/#it{p}_{track} (#it{c});#it{E}_{cluster} (GeV)", kTH2F, {{200, 0., 5.}, {200, 0, 20}}, true); + fRegistry->add("Cluster/before/hNCell", "#it{N}_{cells};N_{cells} (GeV);#it{E}_{cluster} (GeV)", o2::framework::kTH2F, {{26, -0.5, 25.5}, {200, 0, 20}}, true); + fRegistry->add("Cluster/before/hM02", "Long ellipse axis;#it{M}_{02} (cm);#it{E}_{cluster} (GeV)", o2::framework::kTH2F, {{200, 0, 2}, {200, 0, 20}}, true); + fRegistry->add("Cluster/before/hTime", "Cluster time;#it{t}_{cls} (ns);#it{E}_{cluster} (GeV)", o2::framework::kTH2F, {{300, -150, 150}, {200, 0, 20}}, true); + fRegistry->add("Cluster/before/hTrackdEta", "d#eta vs. E of matched tracks;d#eta;#it{E}_{cluster} (GeV)", o2::framework::kTH2F, {{200, -0.2f, 0.2f}, {200, 0, 20}}, true); + fRegistry->add("Cluster/before/hTrackdPhi", "d#phi vs. E of matched tracks;d#varphi (rad.);#it{E}_{cluster} (GeV)", o2::framework::kTH2F, {{200, -0.2f, 0.2f}, {200, 0, 20}}, true); + fRegistry->add("Cluster/before/hTrackEOverP", "Energy of cluster divided by momentum of matched tracks;#it{E}_{cluster}/#it{p}_{track} (#it{c});#it{E}_{cluster} (GeV)", o2::framework::kTH2F, {{200, 0., 5.}, {200, 0, 20}}, true); } else { - fRegistry->add("Cluster/before/hNCell", "#it{N}_{cells};N_{cells} (GeV);#it{N}_{cluster}", kTH1F, {{26, -0.5, 25.5}}, true); - fRegistry->add("Cluster/before/hM02", "Long ellipse axis;#it{M}_{02} (cm);#it{N}_{cluster}", kTH1F, {{400, 0, 2}}, true); - fRegistry->add("Cluster/before/hTime", "Cluster time;#it{t}_{cls} (ns);#it{N}_{cluster}", kTH1F, {{600, -150, 150}}, true); - fRegistry->add("Cluster/before/hTrackEOverP", "Energy of cluster divided by momentum of matched tracks;#it{E}_{cluster}/#it{p}_{track} (#it{c})", kTH1F, {{200, 0., 5.}}, true); + fRegistry->add("Cluster/before/hNCell", "#it{N}_{cells};N_{cells} (GeV);#it{N}_{cluster}", o2::framework::kTH1F, {{26, -0.5, 25.5}}, true); + fRegistry->add("Cluster/before/hM02", "Long ellipse axis;#it{M}_{02} (cm);#it{N}_{cluster}", o2::framework::kTH1F, {{400, 0, 2}}, true); + fRegistry->add("Cluster/before/hTime", "Cluster time;#it{t}_{cls} (ns);#it{N}_{cluster}", o2::framework::kTH1F, {{600, -150, 150}}, true); + fRegistry->add("Cluster/before/hTrackEOverP", "Energy of cluster divided by momentum of matched tracks;#it{E}_{cluster}/#it{p}_{track} (#it{c})", o2::framework::kTH1F, {{200, 0., 5.}}, true); } - auto hClusterQualityCuts = fRegistry->add("Cluster/hClusterQualityCuts", "Energy at which clusters are removed by a given cut;;#it{E} (GeV)", kTH2F, {{8, -0.5, 7.5}, {500, 0, 50}}, true); + auto hClusterQualityCuts = fRegistry->add("Cluster/hClusterQualityCuts", "Energy at which clusters are removed by a given cut;;#it{E} (GeV)", o2::framework::kTH2F, {{8, -0.5, 7.5}, {500, 0, 50}}, true); hClusterQualityCuts->GetXaxis()->SetBinLabel(1, "In"); hClusterQualityCuts->GetXaxis()->SetBinLabel(2, "Energy"); hClusterQualityCuts->GetXaxis()->SetBinLabel(3, "NCell"); @@ -56,30 +67,30 @@ void addClusterHistograms(HistogramRegistry* fRegistry, bool do2DQA) } template -void fillClusterHistograms(HistogramRegistry* fRegistry, TCluster cluster, bool do2DQA, float weight = 1.f) +inline void fillClusterHistograms(HistogramRegistry* fRegistry, TCluster cluster, bool do2DQA, float weight = 1.f) { static constexpr std::string_view cluster_types[2] = {"before/", "after/"}; fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hE"), cluster.e(), weight); fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hPt"), cluster.pt(), weight); fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hEtaPhi"), cluster.eta(), cluster.phi(), weight); - fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hNTracks"), cluster.tracketa().size(), weight); - for (size_t itrack = 0; itrack < cluster.tracketa().size(); itrack++) { // Fill TrackEtaPhi histogram with delta phi and delta eta of all tracks saved in the vectors in skimmerGammaCalo.cxx - fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hTrackdEtadPhi"), cluster.tracketa()[itrack] - cluster.eta(), cluster.trackphi()[itrack] - cluster.phi(), weight); + fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hNTracks"), cluster.deltaEta().size(), weight); + for (size_t itrack = 0; itrack < cluster.deltaEta().size(); itrack++) { // Fill TrackEtaPhi histogram with delta phi and delta eta of all tracks saved in the vectors in skimmerGammaCalo.cxx + fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hTrackdEtadPhi"), cluster.deltaEta()[itrack], cluster.deltaPhi()[itrack], weight); } if (do2DQA) { fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hNCell"), cluster.nCells(), cluster.e(), weight); fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hM02"), cluster.m02(), cluster.e(), weight); fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hTime"), cluster.time(), cluster.e(), weight); - for (size_t itrack = 0; itrack < cluster.tracketa().size(); itrack++) { + for (size_t itrack = 0; itrack < cluster.deltaEta().size(); itrack++) { fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hTrackEOverP"), cluster.e() / cluster.trackp()[itrack], cluster.e(), weight); - fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hTrackdEta"), cluster.tracketa()[itrack] - cluster.eta(), cluster.e(), weight); - fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hTrackdPhi"), cluster.trackphi()[itrack] - cluster.phi(), cluster.e(), weight); + fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hTrackdEta"), cluster.deltaEta()[itrack], cluster.e(), weight); + fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hTrackdPhi"), cluster.deltaPhi()[itrack], cluster.e(), weight); } } else { fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hNCell"), cluster.nCells(), weight); fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hM02"), cluster.m02(), weight); fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hTime"), cluster.time(), weight); - for (size_t itrack = 0; itrack < cluster.tracketa().size(); itrack++) { + for (size_t itrack = 0; itrack < cluster.deltaEta().size(); itrack++) { fRegistry->fill(HIST("Cluster/") + HIST(cluster_types[cls_id]) + HIST("hTrackEOverP"), cluster.e() / cluster.trackp()[itrack], weight); } } diff --git a/PWGEM/PhotonMeson/Utils/emcalHistoDefinitions.h b/PWGEM/PhotonMeson/Utils/emcalHistoDefinitions.h index 6ce678e9c35..f3eac77ca04 100644 --- a/PWGEM/PhotonMeson/Utils/emcalHistoDefinitions.h +++ b/PWGEM/PhotonMeson/Utils/emcalHistoDefinitions.h @@ -12,9 +12,9 @@ /// \brief commonly used histogram (axis) definitions for emcal in PWGEM /// \author marvin.hemmer@cern.ch -#include +#include -#include "Framework/AnalysisTask.h" +#include #ifndef PWGEM_PHOTONMESON_UTILS_EMCALHISTODEFINITIONS_H_ #define PWGEM_PHOTONMESON_UTILS_EMCALHISTODEFINITIONS_H_ diff --git a/PWGEM/PhotonMeson/Utils/gammaSelectionCuts.h b/PWGEM/PhotonMeson/Utils/gammaSelectionCuts.h deleted file mode 100644 index 341a6c95e38..00000000000 --- a/PWGEM/PhotonMeson/Utils/gammaSelectionCuts.h +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \brief cut selection and cut functions for photon candidates -/// \author marvin.hemmer@cern.ch - -#include - -#include "Framework/AnalysisTask.h" -#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" - -#ifndef PWGEM_PHOTONMESON_UTILS_GAMMASELECTIONCUTS_H_ -#define PWGEM_PHOTONMESON_UTILS_GAMMASELECTIONCUTS_H_ - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; -namespace emccuts -{ -// set the standard cuts -std::vector EMC_minTime = {-20.f}; -std::vector EMC_maxTime = {+25.f}; -std::vector EMC_minM02 = {0.1f}; -std::vector EMC_maxM02 = {0.7f}; -std::vector EMC_minE = {0.7f}; -std::vector EMC_minNCell = {1}; -std::vector> EMC_TM_Eta = {{0.01f, 4.07f, -2.5f}}; -std::vector> EMC_TM_Phi = {{0.015f, 3.65f, -2.f}}; -std::vector EMC_Eoverp = {1.75f}; -} // namespace emccuts -void gatherCutsEMC(float minTime, float maxTime, float minM02, float maxM02, float minE, int minNCell, std::vector TM_Eta, std::vector TM_Phi, float Eoverp) -{ - // insert the configurable values in first position - emccuts::EMC_minTime.insert(emccuts::EMC_minTime.begin(), minTime); - emccuts::EMC_maxTime.insert(emccuts::EMC_maxTime.begin(), maxTime); - emccuts::EMC_minM02.insert(emccuts::EMC_minM02.begin(), minM02); - emccuts::EMC_maxM02.insert(emccuts::EMC_maxM02.begin(), maxM02); - emccuts::EMC_minE.insert(emccuts::EMC_minE.begin(), minE); - emccuts::EMC_minNCell.insert(emccuts::EMC_minNCell.begin(), minNCell); - emccuts::EMC_TM_Eta.insert(emccuts::EMC_TM_Eta.begin(), TM_Eta); - emccuts::EMC_TM_Phi.insert(emccuts::EMC_TM_Phi.begin(), TM_Phi); - emccuts::EMC_Eoverp.insert(emccuts::EMC_Eoverp.begin(), Eoverp); - - // fill up the rest of the vectors to size 64 to ensure no crashes can happen - emccuts::EMC_minTime.resize(64, 0); - emccuts::EMC_maxTime.resize(64, 0); - emccuts::EMC_minM02.resize(64, 0); - emccuts::EMC_maxM02.resize(64, 0); - emccuts::EMC_minE.resize(64, 0); - emccuts::EMC_minNCell.resize(64, 0); - emccuts::EMC_TM_Eta.resize(64, {0, 0, 0}); - emccuts::EMC_TM_Phi.resize(64, {0, 0, 0}); - emccuts::EMC_Eoverp.resize(64, 0); -} - -uint64_t doTimeCutEMC(int iCut, uint64_t cutbit, aod::SkimEMCCluster const& cluster, HistogramRegistry& registry) -{ - uint64_t cut_return = 0; - if (cutbit & ((uint64_t)1 << (uint64_t)iCut)) { // check if current cut should be applied - if (cluster.time() <= emccuts::EMC_maxTime.at(iCut) && cluster.time() >= emccuts::EMC_minTime.at(iCut)) { // check cut itself - cut_return |= (1 << iCut); // set bit of current cut to 1 for passing the cut - } else { - registry.fill(HIST("hCaloCuts_EMC"), 1, iCut); - } - } - return cut_return; -} - -uint64_t doM02CutEMC(int iCut, uint64_t cutbit, aod::SkimEMCCluster const& cluster, HistogramRegistry& registry) -{ - uint64_t cut_return = 0; - if (cutbit & ((uint64_t)1 << (uint64_t)iCut)) { // check if current cut should be applied - if (cluster.m02() <= emccuts::EMC_maxM02.at(iCut) && cluster.m02() >= emccuts::EMC_minM02.at(iCut)) { // check cut itself - cut_return |= (1 << iCut); // set bit of current cut to 1 for passing the cut - } else { - registry.fill(HIST("hCaloCuts_EMC"), 2, iCut); - } - } - return cut_return; -} - -uint64_t doMinECutEMC(int iCut, uint64_t cutbit, aod::SkimEMCCluster const& cluster, HistogramRegistry& registry) -{ - uint64_t cut_return = 0; - if (cutbit & ((uint64_t)1 << (uint64_t)iCut)) { // check if current cut should be applied - if (cluster.e() > emccuts::EMC_minE.at(iCut)) { // check cut itself - cut_return |= (1 << iCut); // set bit of current cut to 1 for passing the cut - } else { - registry.fill(HIST("hCaloCuts_EMC"), 3, iCut); - } - } - return cut_return; -} - -uint64_t doNCellCutEMC(int iCut, uint64_t cutbit, aod::SkimEMCCluster const& cluster, HistogramRegistry& registry) -{ - uint64_t cut_return = 0; - if (cutbit & ((uint64_t)1 << (uint64_t)iCut)) { // check if current cut should be applied - if (cluster.nCells() >= emccuts::EMC_minNCell.at(iCut)) { // check cut itself - cut_return |= (1 << iCut); // set bit of current cut to 1 for passing the cut - } else { - registry.fill(HIST("hCaloCuts_EMC"), 4, iCut); - } - } - return cut_return; -} - -uint64_t doTrackMatchingEMC(int iCut, uint64_t cutbit, aod::SkimEMCCluster const& cluster, aod::SkimEMCMTs const& tracks, HistogramRegistry& registry) -{ - uint64_t cut_return = 0; - double dEta, dPhi; - if (cutbit & ((uint64_t)1 << (uint64_t)iCut)) { // check if current cut should be applied - bool hasMatchedTrack_EMC = false; - for (const auto& track : tracks) { - dEta = track.tracketa() - cluster.eta(); - dPhi = track.trackphi() - cluster.phi(); - if ((fabs(dEta) <= emccuts::EMC_TM_Eta.at(iCut).at(0) + pow(track.trackpt() + emccuts::EMC_TM_Eta.at(iCut).at(1), emccuts::EMC_TM_Eta.at(iCut).at(2))) && - (fabs(dPhi) <= emccuts::EMC_TM_Phi.at(iCut).at(0) + pow(track.trackpt() + emccuts::EMC_TM_Phi.at(iCut).at(1), emccuts::EMC_TM_Phi.at(iCut).at(2))) && - cluster.e() / track.trackp() < emccuts::EMC_Eoverp.at(iCut)) { // check cut itself - hasMatchedTrack_EMC = true; // set bit of current cut to 1 for passing the cut - } - } - if (hasMatchedTrack_EMC) { - registry.fill(HIST("hCaloCuts_EMC"), 5, iCut); - } else { - cut_return |= (1 << iCut); - } - } - return cut_return; -} - -uint64_t doPhotonCutsEMC(uint64_t cutbit, aod::SkimEMCCluster const& cluster, aod::SkimEMCMTs const& tracks, Preslice perEMCClusterMT, HistogramRegistry& registry) -{ - uint64_t cut_return = 0; - auto tracksMatchedEMC = tracks.sliceBy(perEMCClusterMT, cluster.globalIndex()); - for (int iCut = 0; iCut < 64; iCut++) { // loop over max number of cut settings - if (cutbit & ((uint64_t)1 << (uint64_t)iCut)) { // check each cut setting if it is selected - registry.fill(HIST("hClusterEIn"), cluster.e(), iCut); - cut_return = doTimeCutEMC(iCut, cutbit, cluster, registry); - // use cut_return instead of cutbit from here on to only check cut settings that we want to look at - // where the cluster did not fail in the previous cut(s) - cut_return = doM02CutEMC(iCut, cut_return, cluster, registry); - cut_return = doMinECutEMC(iCut, cut_return, cluster, registry); - cut_return = doNCellCutEMC(iCut, cut_return, cluster, registry); - cut_return = doTrackMatchingEMC(iCut, cut_return, cluster, tracksMatchedEMC, registry); - - registry.fill(HIST("hCaloCuts_EMC"), 0, iCut); - if (cut_return & ((uint64_t)1 << (uint64_t)iCut)) { - registry.fill(HIST("hClusterEOut"), cluster.e(), iCut); - registry.fill(HIST("hCaloCuts_EMC"), 6, iCut); - } - } - } - return cut_return; -} - -#endif // PWGEM_PHOTONMESON_UTILS_GAMMASELECTIONCUTS_H_ diff --git a/PWGEM/Tasks/phosPi0.cxx b/PWGEM/Tasks/phosPi0.cxx index a47aaa0d485..d9eca400242 100644 --- a/PWGEM/Tasks/phosPi0.cxx +++ b/PWGEM/Tasks/phosPi0.cxx @@ -14,34 +14,35 @@ /// \author Dmitri Peresunko /// -#include -#include -#include -#include -#include -#include -#include - #include "Common/DataModel/CaloClusters.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" +#include "EventFiltering/Zorro.h" +#include "EventFiltering/ZorroSummary.h" -#include "Framework/ConfigParamSpec.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" +#include "CCDB/BasicCCDBManager.h" +#include "CommonDataFormat/InteractionRecord.h" +#include "DataFormatsParameters/GRPLHCIFData.h" #include "Framework/ASoA.h" #include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/ConfigParamSpec.h" #include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" +#include "PHOSBase/Geometry.h" -#include "EventFiltering/Zorro.h" -#include "EventFiltering/ZorroSummary.h" +#include -#include "PHOSBase/Geometry.h" -#include "CommonDataFormat/InteractionRecord.h" -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsParameters/GRPLHCIFData.h" +#include +#include +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::aod::evsel; @@ -52,7 +53,7 @@ struct PhosPi0 { Configurable skimmedProcessing{"skimmedProcessing", false, "Skimmed dataset processing"}; Configurable trigName{"trigName", "fPHOSPhoton", "name of offline trigger"}; Configurable zorroCCDBpath{"zorroCCDBpath", "/Users/m/mpuccio/EventFiltering/OTS/", "path to the zorro ccdb objects"}; - Configurable evSelTrig{"evSelTrig", aod::evsel::kIsTriggerTVX, "Select events with this trigger"}; + Configurable evSelTrig{"evSelTrig", kTVXinPHOS, "Select events with this trigger"}; Configurable isMC{"isMC", false, "to fill MC histograms"}; Configurable minCluE{"minCluE", 0.3, "Minimum cluster energy for analysis"}; Configurable minCluTime{"minCluTime", -25.e-9, "Min. cluster time"}; @@ -107,14 +108,19 @@ struct PhosPi0 { int mRunNumber = 0; // Current run number int mixedEventBin = 0; // Which list of Mixed use for mixing std::vector mCurEvent; - static constexpr int kMaxMixBins = 20; // maximal number of kinds of events for mixing + static constexpr int kMixBinsZ = 20; + static constexpr int kMixBinsPhi = 6; + static constexpr int kMaxMixBins = kMixBinsZ * kMixBinsPhi + 1; // maximal number of bins of events for mixing: vtx*event plane + hard + static constexpr double kEmixCut = 10.; // minimal clu energy for special hard mixing bin + static constexpr int kHardMixBin = kMaxMixBins - 1; // special hard mixing bin + std::array>, kMaxMixBins> mMixedEvents; std::array>, kMaxMixBins> mAmbMixedEvents; int mPrevMCColId = -1; // mark MC collissions already scanned // fast access to histos TH1* hColl; - TH3 *hReMod, *hMiMod; + TH3 *hReMod, *hMiMod, *hReAsym, *hMiAsym; TH2 *hReAll, *hReDisp, *hReCPV, *hReBoth, *hSignalAll, *hPi0SignalAll, *hPi0SignalCPV, *hPi0SignalDisp, *hPi0SignalBoth, *hMiAll, *hMiDisp, *hMiCPV, *hMiBoth; TH2 *hReOneAll, *hReOneDisp, *hReOneCPV, *hReOneBoth, *hMiOneAll, *hMiOneDisp, *hMiOneCPV, *hMiOneBoth; @@ -154,8 +160,8 @@ struct PhosPi0 { hColl->GetXaxis()->SetBinLabel(4, "T0a&&T0c"); hColl->GetXaxis()->SetBinLabel(5, "kTVXinPHOS"); hColl->GetXaxis()->SetBinLabel(6, "kIsTriggerTVX"); - hColl->GetXaxis()->SetBinLabel(7, "PHOSClu"); - hColl->GetXaxis()->SetBinLabel(8, "PHOSClu&&kTVXinPHOS"); + hColl->GetXaxis()->SetBinLabel(7, "kPHOS"); + hColl->GetXaxis()->SetBinLabel(8, "kPHOS&&kTVXinPHOS"); hColl->GetXaxis()->SetBinLabel(9, "Accepted"); auto h2{std::get>(mHistManager.add("eventsBC", "Number of events per trigger", HistType::kTH1F, {{8, 0., 8.}}))}; @@ -186,6 +192,7 @@ struct PhosPi0 { mHistManager.add("cluCPVOcc", "Cluster with CPV occupancy", HistType::kTH3F, {phiAxis, zAxis, modAxis}); mHistManager.add("cluDispOcc", "Cluster with Disp occupancy", HistType::kTH3F, {phiAxis, zAxis, modAxis}); mHistManager.add("cluBothOcc", "Cluster with Both occupancy", HistType::kTH3F, {phiAxis, zAxis, modAxis}); + mHistManager.add("qvec", "qvector", HistType::kTH2F, {{10, 0, o2::constants::math::PI, "#phi", "#phi (rad)"}, {10, 0., 1., "|q|", "|q|"}}); } hReMod = std::get>(mHistManager.add("mggReModComb", "inv mass per module", @@ -203,6 +210,9 @@ struct PhosPi0 { hReBoth = std::get>(mHistManager.add("mggReBoth", "inv mass for centrality", HistType::kTH2F, {mggAxis, ptAxis})) .get(); + hReAsym = std::get>(mHistManager.add("mggReAsym", "inv mass vs pt vs asym", + HistType::kTH3F, {mggAxis, ptAxis, {10, 0., 1., "asym", "a"}})) + .get(); hReOneAll = std::get>(mHistManager.add("mggReOneAll", "inv mass for centrality", HistType::kTH2F, {mggAxis, ptAxis})) .get(); @@ -262,6 +272,9 @@ struct PhosPi0 { hMiBoth = std::get>(mHistManager.add("mggMiBoth", "inv mass for centrality", HistType::kTH2F, {mggAxis, ptAxis})) .get(); + hMiAsym = std::get>(mHistManager.add("mggMiAsym", "inv mass vs pt vs asym", + HistType::kTH3F, {mggAxis, ptAxis, {10, 0., 1., "asym", "a"}})) + .get(); hMiOneAll = std::get>(mHistManager.add("mggMiOneAll", "inv mass for centrality", HistType::kTH2F, {mggAxis, ptAxis})) .get(); @@ -306,25 +319,28 @@ struct PhosPi0 { /// \brief Process PHOS data void processData(SelCollisions::iterator const& col, aod::CaloClusters const& clusters, + aod::FullTracks const& tracks, aod::BCsWithTimestamps const&) { aod::McParticles const* mcPart = nullptr; - scanAll(col, clusters, mcPart); + scanAll(col, clusters, tracks, mcPart); } PROCESS_SWITCH(PhosPi0, processData, "processData", true); void processMC(SelCollisionsMC::iterator const& col, McClusters const& clusters, + aod::FullTracks const& tracks, aod::McParticles const& mcPart, aod::McCollisions const& /*mcCol*/, aod::BCsWithTimestamps const&) { - scanAll(col, clusters, &mcPart); + scanAll(col, clusters, tracks, &mcPart); } PROCESS_SWITCH(PhosPi0, processMC, "processMC", false); template void scanAll(TCollision& col, TClusters& clusters, + aod::FullTracks const& tracks, aod::McParticles const* mcPart) { mixedEventBin = 0; @@ -341,7 +357,7 @@ struct PhosPi0 { return; /// } } else { - if (!col.selection_bit(evSelTrig)) { + if (!col.alias_bit(evSelTrig)) { return; } } @@ -350,13 +366,14 @@ struct PhosPi0 { const double vtxCut = 10.; double vtxZ = col.posZ(); mHistManager.fill(HIST("vertex"), vtxZ); - bool isColSelected = false; - if constexpr (isMC) { - isColSelected = (col.selection_bit(kIsTriggerTVX) && (clusters.size() > 0)); - } else { - isColSelected = col.selection_bit(evSelTrig) && std::abs(vtxZ) < vtxCut; // col.alias_bit(evSelTrig) - // collision.selection_bit(aod::evsel::kNoTimeFrameBorder); - } + bool isColSelected = col.alias_bit(evSelTrig) && std::abs(vtxZ) < vtxCut; + ; + // if constexpr (isMC) { + // isColSelected = (col.selection_bit(kIsTriggerTVX) && (clusters.size() > 0)); + // } else { + // isColSelected = col.alias_bit(evSelTrig) && std::abs(vtxZ) < vtxCut; // + // // collision.selection_bit(aod::evsel::kNoTimeFrameBorder); + // } if (col.selection_bit(kIsBBT0A) || col.selection_bit(kIsBBT0C)) { hColl->Fill(2.5); @@ -367,58 +384,33 @@ struct PhosPi0 { if (col.alias_bit(kTVXinPHOS)) { hColl->Fill(4.5); } - if (col.selection_bit(kIsTriggerTVX)) { + if (col.alias_bit(kIsTriggerTVX)) { hColl->Fill(5.5); } - if (clusters.size() > 0) { + if (col.alias_bit(kPHOS)) { hColl->Fill(6.5); if (col.alias_bit(kTVXinPHOS)) { hColl->Fill(7.5); } } - // //Event Plane| jet orientation - // if (flag & (kProton | kDeuteron | kTriton | kHe3 | kHe4) || doprocessMC) { /// ignore PID pre-selections for the MC - // if constexpr (std::is_same::value) { - // nuclei::candidates_flow.emplace_back(NucleusCandidateFlow{ - // collision.centFV0A(), - // collision.centFT0M(), - // collision.centFT0A(), - // collision.centFT0C(), - // collision.psiFT0A(), - // collision.multFT0A(), - // collision.psiFT0C(), - // collision.multFT0C(), - // collision.psiTPC(), - // collision.psiTPCL(), - // collision.psiTPCR(), - // collision.multTPC()}); - // } else if constexpr (std::is_same::value) { - // nuclei::candidates_flow.emplace_back(NucleusCandidateFlow{ - // collision.centFV0A(), - // collision.centFT0M(), - // collision.centFT0A(), - // collision.centFT0C(), - // 0.5 * std::atan2(collision.qvecFT0AIm(), collision.qvecFT0ARe()), - // collision.multFT0A(), - // 0.5 * std::atan2(collision.qvecFT0CIm(), collision.qvecFT0CRe()), - // collision.multFT0C(), - // -999., - // 0.5 * std::atan2(collision.qvecBNegIm(), collision.qvecBNegRe()), - // 0.5 * std::atan2(collision.qvecBPosIm(), collision.qvecBPosRe()), - // collision.multTPC()}); - // } - - int mult = 1.; // multiplicity TODO!!! - mixedEventBin = findMixedEventBin(vtxZ, mult); if (!isColSelected) { return; } hColl->Fill(8.5); + int mult = 1.; // multiplicity TODO!!! + std::pair q = evalQvec(tracks); + + // find proper event for mixing + // note, that if one find hard cluster in PHOS later, it will change bin to special one + mixedEventBin = findMixedEventBin(vtxZ, mult, q); + // Fill MC distributions // pion rapidity, pt, phi // secondary pi0s + const double rMax = 0.5; // consider pi0s within this radius as primary + const double yMax = 0.5; // rapidity range if constexpr (isMC) { // check current collision Id for clusters int cluMcBCId = -1; @@ -444,16 +436,16 @@ struct PhosPi0 { if (part.mcCollision().bcId() != col.bcId()) { continue; } - if (part.pdgCode() == 111) { + if (part.pdgCode() == PDG_t::kPi0) { double r = std::sqrt(std::pow(part.vx(), 2) + std::pow(part.vy(), 2)); - if (r < 0.5) { + if (r < rMax) { mHistManager.fill(HIST("hMCPi0RapPrim"), part.y()); } - if (std::abs(part.y()) < .5) { + if (std::abs(part.y()) < yMax) { double pt = part.pt(); mHistManager.fill(HIST("hMCPi0SpAll"), pt); double phiVtx = std::atan2(part.vy(), part.vx()); - if (r > 0.5) { + if (r > rMax) { mHistManager.fill(HIST("hMCPi0SecVtx"), r, phiVtx); } else { mHistManager.fill(HIST("hMCPi0SpPrim"), pt); @@ -482,11 +474,14 @@ struct PhosPi0 { clu.m02() < minM02) { continue; } + if (clu.e() > kEmixCut) { + mixedEventBin = kHardMixBin; + } if (fillQC) { mHistManager.fill(HIST("cluSp"), clu.e(), clu.mod()); if (clu.e() > minOccE) { mHistManager.fill(HIST("cluOcc"), clu.x(), clu.z(), clu.mod()); - if (clu.trackdist() > 2.) { + if (clu.trackdist() > cpvCut) { mHistManager.fill(HIST("cluCPVOcc"), clu.x(), clu.z(), clu.mod()); mHistManager.fill(HIST("cluSpCPV"), clu.e(), clu.mod()); if (testLambda(clu.e(), clu.m02(), clu.m20())) { @@ -529,6 +524,7 @@ struct PhosPi0 { } hReMod->Fill(m, pt, modComb, w); hReAll->Fill(m, pt, w); + hReAsym->Fill(m, pt, std::abs((ph1.e - ph2.e) / (ph1.e + ph2.e)), w); hReOneAll->Fill(m, ph1.pt(), w); hReOneAll->Fill(m, ph2.pt(), w); if (ph1.isCPVOK()) { @@ -550,28 +546,32 @@ struct PhosPi0 { } } // Test time eff - if (std::abs(ph1.time - timeOffset) < 12.5e-9) { // strict cut on first photon - if (std::abs(ph2.time - timeOffset) < 100.e-9) { + const double tofCut1 = 12.5e-9; + const double tofCut2 = 30.e-9; + const double tofCut3 = 50.e-9; + const double tofCut4 = 100.e-9; + if (std::abs(ph1.time - timeOffset) < tofCut1) { // strict cut on first photon + if (std::abs(ph2.time - timeOffset) < tofCut4) { hReTime100->Fill(m, ph2.pt()); - if (std::abs(ph2.time - timeOffset) < 50.e-9) { + if (std::abs(ph2.time - timeOffset) < tofCut3) { hReTime50->Fill(m, ph2.pt()); - if (std::abs(ph2.time - timeOffset) < 30.e-9) { + if (std::abs(ph2.time - timeOffset) < tofCut2) { hReTime30->Fill(m, ph2.pt()); - if (std::abs(ph2.time - timeOffset) < 12.5e-9) { + if (std::abs(ph2.time - timeOffset) < tofCut1) { hReTime12->Fill(m, ph2.pt()); } } } } } - if (std::abs(ph2.time - timeOffset) < 12.5e-9) { // strict cut on first photon - if (std::abs(ph1.time - timeOffset) < 100.e-9) { + if (std::abs(ph2.time - timeOffset) < tofCut1) { // strict cut on first photon + if (std::abs(ph1.time - timeOffset) < tofCut4) { hReTime100->Fill(m, ph1.pt()); - if (std::abs(ph1.time - timeOffset) < 50.e-9) { + if (std::abs(ph1.time - timeOffset) < tofCut3) { hReTime50->Fill(m, ph1.pt()); - if (std::abs(ph1.time - timeOffset) < 30.e-9) { + if (std::abs(ph1.time - timeOffset) < tofCut2) { hReTime30->Fill(m, ph1.pt()); - if (std::abs(ph1.time - timeOffset) < 12.5e-9) { + if (std::abs(ph1.time - timeOffset) < tofCut1) { hReTime12->Fill(m, ph1.pt()); } } @@ -584,7 +584,7 @@ struct PhosPi0 { int cp = commonParentPDG(ph1.label, ph2.label, mcPart); if (cp != 0) { hSignalAll->Fill(m, pt, w); - if (cp == 111) { + if (cp == PDG_t::kPi0) { isPi0 = true; hPi0SignalAll->Fill(m, pt, w); } @@ -633,6 +633,7 @@ struct PhosPi0 { } hMiMod->Fill(m, pt, modComb, w); hMiAll->Fill(m, pt, w); + hMiAsym->Fill(m, pt, std::abs((ph1.e - ph2.e) / (ph1.e + ph2.e)), w); hMiOneAll->Fill(m, ph1.pt(), w); hMiOneAll->Fill(m, ph2.pt(), w); if (ph1.isCPVOK()) { @@ -681,9 +682,10 @@ struct PhosPi0 { mixedEventBin = 0; mHistManager.fill(HIST("eventsBC"), 0.); - double vtxZ = 0; // no vtx info - int mult = 1.; // multiplicity TODO!!! - mixedEventBin = findMixedEventBin(vtxZ, mult); + double vtxZ = 0; // no vtx info + int mult = 1.; // multiplicity TODO!!! + std::pair q{0, 0}; // fake q-vector as no tracks + mixedEventBin = findMixedEventBin(vtxZ, mult, q); if (!isSelected) { return; @@ -709,7 +711,7 @@ struct PhosPi0 { mHistManager.fill(HIST("cluSp"), clu.e(), clu.mod()); if (clu.e() > minOccE) { mHistManager.fill(HIST("cluOcc"), clu.x(), clu.z(), clu.mod()); - if (clu.trackdist() > 2.) { + if (clu.trackdist() > cpvCut) { mHistManager.fill(HIST("cluCPVOcc"), clu.x(), clu.z(), clu.mod()); mHistManager.fill(HIST("cluSpCPV"), clu.e(), clu.mod()); if (testLambda(clu.e(), clu.m02(), clu.m20())) { @@ -809,7 +811,7 @@ struct PhosPi0 { if (d == 1) { return 3 + std::min(m1, m2); } - if (d == 2) { + if (d == 2) { // o2-linter: disable=magic-number (algoritm value) return 6 + std::min(m1, m2); } return 9; @@ -819,11 +821,11 @@ struct PhosPi0 { { // Parameterization for full dispersion // Parameterizatino for full dispersion - float l2Mean = 1.53126 + 9.50835e+06 / (1. + 1.08728e+07 * pt + 1.73420e+06 * pt * pt); - float l1Mean = 1.12365 + 0.123770 * std::exp(-pt * 0.246551) + 5.30000e-03 * pt; - float l2Sigma = 6.48260e-02 + 7.60261e+10 / (1. + 1.53012e+11 * pt + 5.01265e+05 * pt * pt) + 9.00000e-03 * pt; - float l1Sigma = 4.44719e-04 + 6.99839e-01 / (1. + 1.22497e+00 * pt + 6.78604e-07 * pt * pt) + 9.00000e-03 * pt; - float c = -0.35 - 0.550 * std::exp(-0.390730 * pt); + float l2Mean = 1.53126 + 9.50835e+06 / (1. + 1.08728e+07 * pt + 1.73420e+06 * pt * pt); // o2-linter: disable=magic-number (fixed parameterization) + float l1Mean = 1.12365 + 0.123770 * std::exp(-pt * 0.246551) + 5.30000e-03 * pt; // o2-linter: disable=magic-number (fixed parameterization) + float l2Sigma = 6.48260e-02 + 7.60261e+10 / (1. + 1.53012e+11 * pt + 5.01265e+05 * pt * pt) + 9.00000e-03 * pt; // o2-linter: disable=magic-number (fixed parameterization) + float l1Sigma = 4.44719e-04 + 6.99839e-01 / (1. + 1.22497e+00 * pt + 6.78604e-07 * pt * pt) + 9.00000e-03 * pt; // o2-linter: disable=magic-number (fixed parameterization) + float c = -0.35 - 0.550 * std::exp(-0.390730 * pt); // o2-linter: disable=magic-number (fixed parameterization) return 0.5 * (l1 - l1Mean) * (l1 - l1Mean) / l1Sigma / l1Sigma + 0.5 * (l2 - l2Mean) * (l2 - l2Mean) / l2Sigma / l2Sigma + @@ -831,17 +833,27 @@ struct PhosPi0 { 4.; } //_____________________________________________________________________________ - int findMixedEventBin(double vtxZ, double /*mult */) + int findMixedEventBin(double vtxZ, double /*mult*/, std::pair& q) { // calculate index for event mixing const double zwidth = 1.; // Width of zvtx bin - int res = static_cast((vtxZ + 10.) / zwidth); - - if (res < 0) - return 0; - if (res >= kMaxMixBins) - return kMaxMixBins - 1; - return res; + int iz = static_cast((vtxZ + 10.) / zwidth); + + if (iz < 0) + iz = 0; + if (iz >= kMixBinsZ) + iz = kMixBinsZ - 1; + + // event plane orientation + double phi = 0.5 * std::atan2(q.second, q.first); // 1/2 due to second order flow harmonic + while (phi < 0) + phi += o2::constants::math::PI; + while (phi > o2::constants::math::PI) + phi -= o2::constants::math::PI; + int iphi = static_cast(kMixBinsPhi * phi / o2::constants::math::PI); + mHistManager.fill(HIST("qvec"), phi, std::sqrt(q.first * q.first + q.second * q.second)); + + return iz * iphi; } //---------------------------------------- int commonParentPDG(int lab1, int lab2, aod::McParticles const* mcParticles) @@ -857,13 +869,16 @@ struct PhosPi0 { return mcParticles->iteratorAt(iparent1).pdgCode(); } auto parent2 = mcParticles->iteratorAt(iparent2); - if (parent2.mothersIds().size() == 0 || parent2.pdgCode() == 21 || std::abs(parent2.pdgCode()) < 11 || std::abs(parent2.pdgCode()) > 5000) { // no parents, parent not quark/gluon, strings + // no parents, parent not quark/gluon, strings + if (parent2.mothersIds().size() == 0 || parent2.pdgCode() == 21 || // o2-linter: disable=pdg/explicit-code (no code) o2-linter: disable=magic-number (pdg value) + std::abs(parent2.pdgCode()) < 11 || std::abs(parent2.pdgCode()) > 5000) { // o2-linter: disable=pdg/explicit-code (no code) o2-linter: disable=magic-number (pdg value) break; } iparent2 = parent2.mothersIds()[0]; } auto parent1 = mcParticles->iteratorAt(iparent1); - if (parent1.mothersIds().size() == 0 || parent1.pdgCode() == 21 || std::abs(parent1.pdgCode()) < 11 || std::abs(parent1.pdgCode()) > 5000) { // no parents, parent not quark/gluon, strings + // no parents, parent not quark/gluon, strings + if (parent1.mothersIds().size() == 0 || parent1.pdgCode() == 21 || std::abs(parent1.pdgCode()) < 11 || std::abs(parent1.pdgCode()) > 5000) { // o2-linter: disable=pdg/explicit-code (no code) o2-linter: disable=magic-number (pdg value) return 0; } iparent1 = parent1.mothersIds()[0]; @@ -879,24 +894,24 @@ struct PhosPi0 { if (tofEffParam == 0) { return 1.; } - if (tofEffParam == 1) { // Run2 100 ns + if (tofEffParam == 1) { // Run2 100 ns //o2-linter: disable=magic-number (local parameterization) // parameterization 01.08.2020 - if (en > 1.1) + if (en > 1.1) // o2-linter: disable=magic-number (local parameterization) en = 1.1; - if (en < 0.11) + if (en < 0.11) // o2-linter: disable=magic-number (local parameterization) en = 0.11; - return std::exp((-1.15295e+05 + 2.26754e+05 * en - 1.26063e+05 * en * en + en * en * en) / - (1. - 3.16443e+05 * en + 3.68044e+06 * en * en + en * en * en)); + return std::exp((-1.15295e+05 + 2.26754e+05 * en - 1.26063e+05 * en * en + en * en * en) / // o2-linter: disable=magic-number (local parameterization) + (1. - 3.16443e+05 * en + 3.68044e+06 * en * en + en * en * en)); // o2-linter: disable=magic-number (local parameterization) } - if (tofEffParam == 2) { // Run2 30 ns - if (en > 1.6) + if (tofEffParam == 2) { // Run2 30 ns //o2-linter: disable=magic-number (kind of TOF parameterization) + if (en > 1.6) // o2-linter: disable=magic-number (local parameterization) en = 1.6; - return 1. / (1. + std::exp((4.83230e+01 - 8.89758e+01 * en + 1.10897e+03 * en * en - 5.73755e+03 * en * en * en - - 1.43777e+03 * en * en * en * en) / - (1. - 1.23667e+02 * en + 1.07255e+03 * en * en + 5.87221e+02 * en * en * en))); + return 1. / (1. + std::exp((4.83230e+01 - 8.89758e+01 * en + 1.10897e+03 * en * en - 5.73755e+03 * en * en * en - // o2-linter: disable=magic-number (local parameterization) + 1.43777e+03 * en * en * en * en) / // o2-linter: disable=magic-number (local parameterization) + (1. - 1.23667e+02 * en + 1.07255e+03 * en * en + 5.87221e+02 * en * en * en))); // o2-linter: disable=magic-number (local parameterization) } - if (tofEffParam == 2) { // Run2 12.5 ns - if (en < 4.6) { + if (tofEffParam == 3) { // Run2 12.5 ns //o2-linter: disable=magic-number (local parameterization) + if (en < 4.6) { // o2-linter: disable=magic-number (local parameterization) return std::exp(3.64952e-03 * (-5.80032e+01 - 1.53442e+02 * en + 1.30994e+02 * en * en + -3.53094e+01 * en * en * en + en * en * en * en) / (-7.75638e-02 + 8.64761e-01 * en + 1.22320e+00 * en * en - 1.00177e+00 * en * en * en + en * en * en * en)); @@ -907,6 +922,30 @@ struct PhosPi0 { } return 1.; } + //_____________________________________________________________________________ + std::pair evalQvec(aod::FullTracks const& tracks) + { + // calculate approximate q-vector for event + const int ord = 2; // flow order + std::pair q{0, 0}; + int ntr = 0; + for (const auto& track : tracks) { + if (!track.has_collision()) { // ignore orphan tracks without collision + continue; + } + // if (!track.isGlobalTrack()) { // only global tracks + // continue; + // } + q.first += std::cos(ord * track.phi()); + q.second += std::sin(ord * track.phi()); + ntr++; + } + if (ntr > 0) { + q.first /= ntr; + q.second /= ntr; + } + return q; + } }; o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) diff --git a/PWGHF/Core/CentralityEstimation.h b/PWGHF/Core/CentralityEstimation.h index bd1746c4604..fbe18d28d89 100644 --- a/PWGHF/Core/CentralityEstimation.h +++ b/PWGHF/Core/CentralityEstimation.h @@ -59,8 +59,8 @@ concept hasNTracksPVCent = requires(T collision) { /// Evaluate centrality/multiplicity percentile using FT0A estimator /// \param candidate is candidate /// \return centrality/multiplicity percentile of the collision -template -float getCentralityColl(const Coll& collision) +template +float getCentralityColl(const TCollision& collision) { return collision.centFT0A(); } @@ -68,8 +68,8 @@ float getCentralityColl(const Coll& collision) /// Evaluate centrality/multiplicity percentile using FT0C estimator /// \param candidate is candidate /// \return centrality/multiplicity percentile of the collision -template -float getCentralityColl(const Coll& collision) +template +float getCentralityColl(const TCollision& collision) { return collision.centFT0C(); } @@ -77,8 +77,8 @@ float getCentralityColl(const Coll& collision) /// Evaluate centrality/multiplicity percentile using FT0M estimator /// \param candidate is candidate /// \return centrality/multiplicity percentile of the collision -template -float getCentralityColl(const Coll& collision) +template +float getCentralityColl(const TCollision& collision) { return collision.centFT0M(); } @@ -86,8 +86,8 @@ float getCentralityColl(const Coll& collision) /// Evaluate centrality/multiplicity percentile using FV0A estimator /// \param candidate is candidate /// \return centrality/multiplicity percentile of the collision -template -float getCentralityColl(const Coll& collision) +template +float getCentralityColl(const TCollision& collision) { return collision.centFV0A(); } @@ -95,8 +95,8 @@ float getCentralityColl(const Coll& collision) /// Evaluate centrality/multiplicity percentile using NTracksPV estimator /// \param candidate is candidate /// \return centrality/multiplicity percentile of the collision -template -float getCentralityColl(const Coll& collision) +template +float getCentralityColl(const TCollision& collision) { return collision.centNTPV(); } @@ -104,8 +104,8 @@ float getCentralityColl(const Coll& collision) /// Default case if no centrality/multiplicity estimator is provided /// \param candidate is candidate /// \return dummy value for centrality/multiplicity percentile of the collision -template -float getCentralityColl(const Coll&) +template +float getCentralityColl(const TCollision&) { return 105.0f; } @@ -114,36 +114,36 @@ float getCentralityColl(const Coll&) /// \param collision is the collision with the centrality information /// \param centEstimator integer to select the centrality estimator /// \return collision centrality -template -float getCentralityColl(const Coll& collision, int centEstimator) +template +float getCentralityColl(const TCollision& collision, const int centEstimator) { switch (centEstimator) { case CentralityEstimator::FT0A: - if constexpr (hasFT0ACent) { + if constexpr (hasFT0ACent) { return collision.centFT0A(); } LOG(fatal) << "Collision does not have centFT0A()."; break; case CentralityEstimator::FT0C: - if constexpr (hasFT0CCent) { + if constexpr (hasFT0CCent) { return collision.centFT0C(); } LOG(fatal) << "Collision does not have centFT0C()."; break; case CentralityEstimator::FT0M: - if constexpr (hasFT0MCent) { + if constexpr (hasFT0MCent) { return collision.centFT0M(); } LOG(fatal) << "Collision does not have centFT0M()."; break; case CentralityEstimator::FV0A: - if constexpr (hasFV0ACent) { + if constexpr (hasFV0ACent) { return collision.centFV0A(); } LOG(fatal) << "Collision does not have centFV0A()."; break; default: - LOG(fatal) << "Centrality estimator not valid. Possible values are V0A, T0M, T0A, T0C."; + LOG(fatal) << "Centrality estimator not valid. See CentralityEstimator for valid values."; break; } return -999.f; @@ -152,13 +152,14 @@ float getCentralityColl(const Coll& collision, int centEstimator) /// \brief Function to get MC collision centrality /// \param collSlice collection of reconstructed collisions associated to a generated one /// \return generated MC collision centrality -template -float getCentralityGenColl(CCs const& collSlice) +template +float getCentralityGenColl(TCollisions const& collSlice) { - float centrality{-1}; - float multiplicity{0.f}; + using TMult = uint16_t; // type of numContrib + float centrality{-1.f}; + TMult multiplicity{}; for (const auto& collision : collSlice) { - float collMult = collision.numContrib(); + const TMult collMult = collision.numContrib(); if (collMult > multiplicity) { centrality = getCentralityColl(collision); multiplicity = collMult; @@ -171,13 +172,14 @@ float getCentralityGenColl(CCs const& collSlice) /// \param collSlice collection of reconstructed collisions associated to a generated one /// \param centEstimator integer to select the centrality estimator /// \return generated MC collision centrality -template -float getCentralityGenColl(CCs const& collSlice, int centEstimator) +template +float getCentralityGenColl(TCollisions const& collSlice, const int centEstimator) { - float centrality{-1}; - float multiplicity{0.f}; + using TMult = uint16_t; // type of numContrib + float centrality{-1.f}; + TMult multiplicity{}; for (const auto& collision : collSlice) { - float collMult = collision.numContrib(); + const TMult collMult = collision.numContrib(); if (collMult > multiplicity) { centrality = getCentralityColl(collision, centEstimator); multiplicity = collMult; diff --git a/PWGHF/Core/DecayChannels.h b/PWGHF/Core/DecayChannels.h index abc8ac291a6..0c0392d99e2 100644 --- a/PWGHF/Core/DecayChannels.h +++ b/PWGHF/Core/DecayChannels.h @@ -30,10 +30,12 @@ namespace o2::hf_decay // - HF cascades to LF cascades (Ωc0/Ξc0 → Ξ+ π−, Ξc+ → Ξ+ π− π+) // - Σc +using HfDecayChannel = int8_t; + namespace hf_cand_2prong { /// @brief 2-prong candidates: main channels -enum DecayChannelMain : int8_t { +enum DecayChannelMain : HfDecayChannel { // D0 D0ToPiK = 1, // π+ K− D0ToPiKPi0 = 2, // π+ K− π0 @@ -47,7 +49,7 @@ enum DecayChannelMain : int8_t { NChannelsMain = JpsiToMuMu // last channel }; /// @brief 2-prong candidates: resonant channels -enum DecayChannelResonant : int8_t { +enum DecayChannelResonant : HfDecayChannel { // D0 D0ToRhoplusPi = 1, // ρ+ π− D0ToRhoplusK = 2, // ρ+ K− @@ -61,7 +63,7 @@ enum DecayChannelResonant : int8_t { namespace hf_cand_3prong { /// @brief 3-prong candidates: main channels -enum DecayChannelMain : int8_t { +enum DecayChannelMain : HfDecayChannel { // D+ DplusToPiKPi = 1, // π+ K− π+ DplusToPiKPiPi0 = 2, // π+ K− π+ π0 @@ -94,7 +96,7 @@ enum DecayChannelMain : int8_t { NChannelsMain = XicToSPiPi // last channel }; /// @brief 3-prong candidates: resonant channels -enum DecayChannelResonant : int8_t { +enum DecayChannelResonant : HfDecayChannel { // D+ DplusToPhiPi = 1, // φ π+ DplusToKstar0K = 2, // anti-K*0 K+ @@ -136,7 +138,7 @@ enum DecayChannelResonant : int8_t { namespace hf_cand_dstar { /// @brief D*+ candidates: main channels -enum DecayChannelMain : int8_t { +enum DecayChannelMain : HfDecayChannel { // D*+ DstarToPiKPi = 1, // π+ K− π+ (from [(D0 → π+ K−) π+]) DstarToPiKPiPi0 = 2, // π+ K− π+ π0 (from [(D0 → π+ K− π0) π+] or [(D+ → π+ K− π+) π0]) @@ -148,7 +150,7 @@ enum DecayChannelMain : int8_t { namespace hf_cand_beauty { /// @brief beauty candidates: main channels -enum DecayChannelMain : int8_t { +enum DecayChannelMain : HfDecayChannel { // B0 B0ToDminusPi = 1, // D− π+ B0ToDminusPiPi0 = 2, // D− π+ π0 @@ -176,7 +178,7 @@ enum DecayChannelMain : int8_t { NChannelsMain = B0ToDsPi // last channel }; /// @brief beauty candidates: resonant channels -enum DecayChannelResonant : int8_t { +enum DecayChannelResonant : HfDecayChannel { // B0 B0ToDminusRhoplus = 1, // D− ρ+ B0ToDstarminusPi = 2, // D*− π+ @@ -195,7 +197,7 @@ enum DecayChannelResonant : int8_t { NChannelsResonant = BplusToDstar0Pi // last channel }; /// @brief beauty candidates: beauty to J/ψ decay channels -enum DecayChannelToJpsiMain : int8_t { +enum DecayChannelToJpsiMain : HfDecayChannel { // B0 B0ToJpsiPiK = 1, // J/ψ π− K+ // Bs0 @@ -210,7 +212,7 @@ enum DecayChannelToJpsiMain : int8_t { NChannelsToJpsiMain = BcToJpsiPi // last channel }; /// @brief beauty candidates: beauty to J/ψ resonant decay channels -enum DecayChannelToJpsiResonant : int8_t { +enum DecayChannelToJpsiResonant : HfDecayChannel { // B0 B0ToJpsiKstar0 = 1, // J/ψ K*0(892) // Bs0 @@ -223,7 +225,7 @@ enum DecayChannelToJpsiResonant : int8_t { namespace hf_cand_reso { /// @brief resonance candidates: main channels -enum DecayChannelMain : int8_t { +enum DecayChannelMain : HfDecayChannel { // D1(2420)0 D1zeroToDstarPi = 1, // D*+ π- // D2*(2460)0 @@ -250,7 +252,10 @@ enum DecayChannelMain : int8_t { // Xic(3080)0 Xic3080zeroToD0Lambda = 14, // D0 Λ // Xic(3080)+ - Xic3080plusToDplusLambda = 15 // D+ Λ + Xic3080plusToDplusLambda = 15, // D+ Λ + // D*+ + DstarToD0Pi = 16, // D0 π+ + NChannelsMain = DstarToD0Pi // last channel }; } // namespace hf_cand_reso } // namespace o2::hf_decay diff --git a/PWGHF/Core/HfHelper.h b/PWGHF/Core/HfHelper.h index 41239c48179..37798045914 100644 --- a/PWGHF/Core/HfHelper.h +++ b/PWGHF/Core/HfHelper.h @@ -33,6 +33,11 @@ #include #include +template +concept IsB0ToDstarPiChannel = requires(T candidate) { + candidate.prongD0Id(); +}; + class HfHelper { public: @@ -634,6 +639,12 @@ class HfHelper return candidate.m(std::array{o2::constants::physics::MassDMinus, o2::constants::physics::MassPiPlus}); } + template + auto invMassB0ToDPi(const T& candidate) + { + return candidate.m(std::array{o2::constants::physics::MassD0, o2::constants::physics::MassPiPlus, o2::constants::physics::MassPiPlus}); + } + template auto cosThetaStarB0(const T& candidate) { diff --git a/PWGHF/Core/HfMlResponseB0ToDPi.h b/PWGHF/Core/HfMlResponseB0ToDPi.h index 1f6d4940b7f..4874b56543b 100644 --- a/PWGHF/Core/HfMlResponseB0ToDPi.h +++ b/PWGHF/Core/HfMlResponseB0ToDPi.h @@ -75,9 +75,12 @@ namespace o2::analysis enum class InputFeaturesB0ToDPi : uint8_t { ptProng0 = 0, ptProng1, + ptProng2, impactParameter0, impactParameter1, + impactParameter2, impactParameterProduct, + impactParameterProngSqSum, chi2PCA, decayLength, decayLengthXY, @@ -91,7 +94,13 @@ enum class InputFeaturesB0ToDPi : uint8_t { prong0MlScoreNonprompt, tpcNSigmaPi1, tofNSigmaPi1, - tpcTofNSigmaPi1 + tpcTofNSigmaPi1, + tpcNSigmaPiBachPi, + tofNSigmaPiBachPi, + tpcTofNSigmaPiBachPi, + tpcNSigmaPiSoftPi, + tofNSigmaPiSoftPi, + tpcTofNSigmaPiSoftPi }; template @@ -109,7 +118,7 @@ class HfMlResponseB0ToDPi : public HfMlResponse /// \return inputFeatures vector template std::vector getInputFeatures(T1 const& candidate, - T2 const& prong1, + T2 const& prongBachPi, const std::vector* mlScoresD = nullptr) { std::vector inputFeatures; @@ -130,11 +139,77 @@ class HfMlResponseB0ToDPi : public HfMlResponse CHECK_AND_FILL_VEC_B0(cpaXY); CHECK_AND_FILL_VEC_B0(maxNormalisedDeltaIP); // TPC PID variable - CHECK_AND_FILL_VEC_B0_FULL(prong1, tpcNSigmaPi1, tpcNSigmaPi); + CHECK_AND_FILL_VEC_B0_FULL(prongBachPi, tpcNSigmaPi1, tpcNSigmaPi); // TOF PID variable - CHECK_AND_FILL_VEC_B0_FULL(prong1, tofNSigmaPi1, tofNSigmaPi); + CHECK_AND_FILL_VEC_B0_FULL(prongBachPi, tofNSigmaPi1, tofNSigmaPi); // Combined PID variables - CHECK_AND_FILL_VEC_B0_FUNC(prong1, tpcTofNSigmaPi1, o2::pid_tpc_tof_utils::getTpcTofNSigmaPi1); + CHECK_AND_FILL_VEC_B0_FUNC(prongBachPi, tpcTofNSigmaPi1, o2::pid_tpc_tof_utils::getTpcTofNSigmaPi1); + } + if constexpr (withDmesMl) { + if constexpr (reduced) { + switch (idx) { + CHECK_AND_FILL_VEC_B0(prong0MlScoreBkg); + CHECK_AND_FILL_VEC_B0(prong0MlScorePrompt); + CHECK_AND_FILL_VEC_B0(prong0MlScoreNonprompt); + } + } else { + if (mlScoresD) { + switch (idx) { + CHECK_AND_FILL_VEC_B0_INDEX(prong0MlScoreBkg, *mlScoresD, 0); + CHECK_AND_FILL_VEC_B0_INDEX(prong0MlScorePrompt, *mlScoresD, 1); + CHECK_AND_FILL_VEC_B0_INDEX(prong0MlScoreNonprompt, *mlScoresD, 2); + } + } else { + LOG(fatal) << "ML scores of D not provided"; + } + } + } + } + + return inputFeatures; + } + + /// Method to get the input features vector needed for ML inference + /// \param candidate is the B0 candidate + /// \param prongBachPi is the candidate's bachelor pion prong + /// \param prongSoftPi is the candidate's soft pion prong + /// \param mlScoresD is the vector of ML scores for the D meson (if available) + /// \note this method is used for B0 → D*∓ π± candidates with D meson ML scores + /// \return inputFeatures vector + template + std::vector getInputFeaturesDStarPi(T1 const& candidate, + T2 const& prongBachPi, + T3 const& prongSoftPi, + const std::vector* mlScoresD = nullptr) + { + std::vector inputFeatures; + + for (const auto& idx : MlResponse::mCachedIndices) { + switch (idx) { + CHECK_AND_FILL_VEC_B0(ptProng0); + CHECK_AND_FILL_VEC_B0(ptProng1); + CHECK_AND_FILL_VEC_B0(ptProng2); + CHECK_AND_FILL_VEC_B0(impactParameter0); + CHECK_AND_FILL_VEC_B0(impactParameter1); + CHECK_AND_FILL_VEC_B0(impactParameter2); + CHECK_AND_FILL_VEC_B0(impactParameterProngSqSum); + CHECK_AND_FILL_VEC_B0(chi2PCA); + CHECK_AND_FILL_VEC_B0(decayLength); + CHECK_AND_FILL_VEC_B0(decayLengthXY); + CHECK_AND_FILL_VEC_B0(decayLengthNormalised); + CHECK_AND_FILL_VEC_B0(decayLengthXYNormalised); + CHECK_AND_FILL_VEC_B0(cpa); + CHECK_AND_FILL_VEC_B0(cpaXY); + CHECK_AND_FILL_VEC_B0(maxNormalisedDeltaIP); + // TPC PID variable + CHECK_AND_FILL_VEC_B0_FULL(prongBachPi, tpcNSigmaPiBachPi, tpcNSigmaPi); + CHECK_AND_FILL_VEC_B0_FULL(prongSoftPi, tpcNSigmaPiSoftPi, tpcNSigmaPiSoftPi); + // TOF PID variable + CHECK_AND_FILL_VEC_B0_FULL(prongBachPi, tofNSigmaPiBachPi, tofNSigmaPi); + CHECK_AND_FILL_VEC_B0_FULL(prongSoftPi, tofNSigmaPiSoftPi, tofNSigmaPiSoftPi); + // Combined PID variables + CHECK_AND_FILL_VEC_B0_FUNC(prongBachPi, tpcTofNSigmaPiBachPi, o2::pid_tpc_tof_utils::getTpcTofNSigmaPi1); + CHECK_AND_FILL_VEC_B0_FUNC(prongSoftPi, tpcTofNSigmaPiSoftPi, o2::pid_tpc_tof_utils::getTpcTofNSigmaSoftPi); } if constexpr (withDmesMl) { if constexpr (reduced) { @@ -167,9 +242,12 @@ class HfMlResponseB0ToDPi : public HfMlResponse MlResponse::mAvailableInputFeatures = { FILL_MAP_B0(ptProng0), FILL_MAP_B0(ptProng1), + FILL_MAP_B0(ptProng2), FILL_MAP_B0(impactParameter0), FILL_MAP_B0(impactParameter1), + FILL_MAP_B0(impactParameter2), FILL_MAP_B0(impactParameterProduct), + FILL_MAP_B0(impactParameterProngSqSum), FILL_MAP_B0(chi2PCA), FILL_MAP_B0(decayLength), FILL_MAP_B0(decayLengthXY), @@ -183,10 +261,16 @@ class HfMlResponseB0ToDPi : public HfMlResponse FILL_MAP_B0(prong0MlScoreNonprompt), // TPC PID variable FILL_MAP_B0(tpcNSigmaPi1), + FILL_MAP_B0(tpcNSigmaPiSoftPi), + FILL_MAP_B0(tpcNSigmaPiBachPi), // TOF PID variable FILL_MAP_B0(tofNSigmaPi1), + FILL_MAP_B0(tofNSigmaPiSoftPi), + FILL_MAP_B0(tofNSigmaPiBachPi), // Combined PID variable - FILL_MAP_B0(tpcTofNSigmaPi1)}; + FILL_MAP_B0(tpcTofNSigmaPi1), + FILL_MAP_B0(tpcTofNSigmaPiSoftPi), + FILL_MAP_B0(tpcTofNSigmaPiBachPi)}; } }; diff --git a/PWGHF/D2H/DataModel/ReducedDataModel.h b/PWGHF/D2H/DataModel/ReducedDataModel.h index 82df09123da..3473321a0a5 100644 --- a/PWGHF/D2H/DataModel/ReducedDataModel.h +++ b/PWGHF/D2H/DataModel/ReducedDataModel.h @@ -50,8 +50,8 @@ namespace aod { namespace hf_reduced_collision { -DECLARE_SOA_COLUMN(Bz, bz, float); //! Magnetic field in z-direction -DECLARE_SOA_COLUMN(HfCollisionRejectionMap, hfCollisionRejectionMap, uint32_t); //! Bitmask with failed selection criteria +DECLARE_SOA_COLUMN(Bz, bz, float); //! Magnetic field in z-direction +DECLARE_SOA_COLUMN(HfCollisionRejectionMap, hfCollisionRejectionMap, o2::hf_evsel::HfCollisionRejectionMask); //! Bitmask with failed selection criteria // keep track of the number of studied events (for normalization purposes) DECLARE_SOA_COLUMN(OriginalCollisionCount, originalCollisionCount, int); //! Size of COLLISION table processed DECLARE_SOA_COLUMN(ZvtxSelectedCollisionCount, zvtxSelectedCollisionCount, int); //! Number of COLLISIONS with |zvtx| < zvtxMax @@ -293,24 +293,12 @@ DECLARE_SOA_TABLE(HfRedTracksCov, "AOD", "HFREDTRACKCOV", //! Table with track c HFTRACKPARCOV_COLUMNS, o2::soa::Marker<1>); -DECLARE_SOA_TABLE(HfRedSoftPiBases, "AOD", "HFREDSOFTPIBASE", //! Table with track information for reduced workflow - soa::Index<>, - hf_track_index_reduced::TrackId, - hf_track_index_reduced::HfRedCollisionId, - HFTRACKPAR_COLUMNS, - hf_track_vars_reduced::ItsNCls, - hf_track_vars_reduced::TpcNClsCrossedRows, - hf_track_vars_reduced::TpcChi2NCl, - aod::track::Px, - aod::track::Py, - aod::track::Pz, - aod::track::PVector, - o2::soa::Marker<2>); - -DECLARE_SOA_TABLE(HfRedSoftPiCov, "AOD", "HFREDSOFTPICOV", //! Table with track covariance information for reduced workflow +DECLARE_SOA_TABLE(HfRedTracksMom, "AOD", "HFREDTRACKMOM", //! Table with track momentum information for reduced workflow soa::Index<>, - HFTRACKPARCOV_COLUMNS, - o2::soa::Marker<2>); + hf_track_vars_reduced::Px, + hf_track_vars_reduced::Py, + hf_track_vars_reduced::Pz, + hf_track_vars_reduced::Sign); // CAREFUL: need to follow convention [Name = Description + 's'] in DECLARE_SOA_TABLE(Name, "AOD", Description) // to call DECLARE_SOA_INDEX_COLUMN_FULL later on @@ -546,6 +534,39 @@ DECLARE_SOA_TABLE(HfRed2ProngsMl, "AOD", "HFRED2PRONGML", //! Table with 2prong hf_charm_cand_reduced::MlScorePromptMassHypo1, hf_charm_cand_reduced::MlScoreNonpromptMassHypo1); +// CAREFUL: need to follow convention [Name = Description + 's'] in DECLARE_SOA_TABLE(Name, "AOD", Description) +// to call DECLARE_SOA_INDEX_COLUMN_FULL later on +DECLARE_SOA_TABLE(HfRedSoftPiBases, "AOD", "HFREDSOFTPIBASE", //! Table with track information for reduced workflow + soa::Index<>, + hf_track_index_reduced::TrackId, + hf_track_index_reduced::HfRedCollisionId, + HFTRACKPAR_COLUMNS, + hf_track_vars_reduced::ItsNCls, + hf_track_vars_reduced::TpcNClsCrossedRows, + hf_track_vars_reduced::TpcChi2NCl, + aod::track::Px, + aod::track::Py, + aod::track::Pz, + aod::track::PVector); + +DECLARE_SOA_TABLE(HfRedSoftPiCov, "AOD", "HFREDSOFTPICOV", //! Table with track covariance information for reduced workflow + soa::Index<>, + HFTRACKPARCOV_COLUMNS, + o2::soa::Marker<2>); + +DECLARE_SOA_TABLE(HfRedSoftPiPid, "AOD", "HFREDSOFTPIPID", + soa::Index<>, + hf_cand_dstar::TPCNSigmaPiSoftPi, + hf_cand_dstar::TOFNSigmaPiSoftPi, + hf_track_vars_reduced::HasTOF, + hf_track_vars_reduced::HasTPC, + hf_cand_dstar::TPCTOFNSigmaPiSoftPi) + +namespace hf_track_index_reduced +{ +DECLARE_SOA_INDEX_COLUMN_FULL(SoftPi, softPi, int, HfRedSoftPiBases, ""); //! ReducedCollision index +}; // namespace hf_track_index_reduced + // CAREFUL: need to follow convention [Name = Description + 's'] in DECLARE_SOA_TABLE(Name, "AOD", Description) // to call DECLARE_SOA_INDEX_COLUMN_FULL later on DECLARE_SOA_TABLE(HfRed3Prongs, "AOD", "HFRED3PRONG", //! Table with 3prong candidate information for reduced workflow @@ -583,6 +604,17 @@ DECLARE_SOA_TABLE_VERSIONED(HfRed3ProngsMl_001, "AOD", "HFRED3PRONGML", 1, //! T using HfRed3ProngsMl = HfRed3ProngsMl_001; +DECLARE_SOA_TABLE(HfRedMomDDaugs, "AOD", "HFREDMOMDDAUGS", //! Table with 2prong candidate ML scores + hf_cand::PxProng0, + hf_cand::PyProng0, + hf_cand::PzProng0, + hf_cand::PxProng1, + hf_cand::PyProng1, + hf_cand::PzProng1, + hf_cand::PxProng2, + hf_cand::PyProng2, + hf_cand::PzProng2); + // CAREFUL: need to follow convention [Name = Description + 's'] in DECLARE_SOA_TABLE(Name, "AOD", Description) // to call DECLARE_SOA_INDEX_COLUMN_FULL later on DECLARE_SOA_TABLE(HfRedJpsis, "AOD", "HFREDJPSI", //! Table with J/Psi candidate information for reduced workflow @@ -711,11 +743,15 @@ using HfRedPidDau2s = HfRedPidDau2s_001; using HfRedPidDau0 = HfRedPidDau0s::iterator; using HfRedPidDau1 = HfRedPidDau1s::iterator; using HfRedPidDau2 = HfRedPidDau2s::iterator; + // Beauty candidates prongs namespace hf_cand_b0_reduced { DECLARE_SOA_INDEX_COLUMN_FULL(Prong0, prong0, int, HfRed3Prongs, "_0"); //! Prong0 index DECLARE_SOA_INDEX_COLUMN_FULL(Prong1, prong1, int, HfRedTrackBases, "_1"); //! Prong1 index +DECLARE_SOA_INDEX_COLUMN_FULL(ProngD0, prongD0, int, HfRed2Prongs, "_0"); //! ProngD0 index +DECLARE_SOA_INDEX_COLUMN_FULL(ProngBachPi, prongBachPi, int, HfRedTrackBases, "_1"); //! ProngBachPi index +DECLARE_SOA_INDEX_COLUMN_FULL(ProngSoftPi, prongSoftPi, int, HfRedSoftPiBases, "_2"); //! ProngSoftPi index DECLARE_SOA_COLUMN(Prong0MlScoreBkg, prong0MlScoreBkg, float); //! Bkg ML score of the D daughter DECLARE_SOA_COLUMN(Prong0MlScorePrompt, prong0MlScorePrompt, float); //! Prompt ML score of the D daughter DECLARE_SOA_COLUMN(Prong0MlScoreNonprompt, prong0MlScoreNonprompt, float); //! Nonprompt ML score of the D daughter @@ -724,6 +760,9 @@ DECLARE_SOA_COLUMN(Prong0MlScoreNonprompt, prong0MlScoreNonprompt, float); //! N DECLARE_SOA_TABLE(HfRedB0Prongs, "AOD", "HFREDB0PRONG", //! Table with B0 daughter indices hf_cand_b0_reduced::Prong0Id, hf_cand_b0_reduced::Prong1Id); +DECLARE_SOA_TABLE(HfRedB0ProngDStars, "AOD", "HFREDB0PRONGDST", //! Table with B0 daughter indices + hf_cand_b0_reduced::ProngD0Id, hf_cand_b0_reduced::ProngBachPiId, hf_cand_b0_reduced::ProngSoftPiId); + DECLARE_SOA_TABLE(HfRedB0DpMls, "AOD", "HFREDB0DPML", //! Table with ML scores for the D+ daughter hf_cand_b0_reduced::Prong0MlScoreBkg, hf_cand_b0_reduced::Prong0MlScorePrompt, @@ -731,6 +770,7 @@ DECLARE_SOA_TABLE(HfRedB0DpMls, "AOD", "HFREDB0DPML", //! Table with ML scores f o2::soa::Marker<1>); using HfRedCandB0 = soa::Join; +using HfRedCandB0DStar = soa::Join; namespace hf_cand_bplus_reduced { @@ -848,6 +888,15 @@ DECLARE_SOA_TABLE(HfMcCheckDpPis, "AOD", "HFMCCHECKDPPI", //! Table with reconst hf_b0_mc::PdgCodeProng3, o2::soa::Marker<1>); +// table with results of reconstruction level MC matching +DECLARE_SOA_TABLE(HfMcRecRedDStarPis, "AOD", "HFMCRECREDDSTPI", //! Table with reconstructed MC information on DStarPi pairs for reduced workflow + hf_cand_b0_reduced::ProngD0Id, + hf_cand_b0_reduced::ProngBachPiId, + hf_cand_b0::FlagMcMatchRec, + hf_cand_b0::FlagWrongCollision, + hf_cand_b0::DebugMcRec, + hf_b0_mc::PtMother); + // Table with same size as HFCANDB0 DECLARE_SOA_TABLE(HfMcRecRedB0s, "AOD", "HFMCRECREDB0", //! Reconstruction-level MC information on B0 candidates for reduced workflow hf_cand_b0::FlagMcMatchRec, @@ -1186,7 +1235,7 @@ DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! DECLARE_SOA_COLUMN(ItsNClsSoftPi, itsNClsSoftPi, int); //! minimum value of number of ITS clusters for the decay daughter tracks DECLARE_SOA_COLUMN(TpcNClsCrossedRowsSoftPi, tpcNClsCrossedRowsSoftPi, int); //! minimum value of number of TPC crossed rows for the decay daughter tracks DECLARE_SOA_COLUMN(TpcChi2NClSoftPi, tpcChi2NClSoftPi, float); //! maximum value of TPC chi2 for the decay daughter tracks -DECLARE_SOA_DYNAMIC_COLUMN(Px, px, //! +DECLARE_SOA_DYNAMIC_COLUMN(Px, px, //! [](float pxProng0, float pxProng1, float pxProng2) -> float { return 1.f * pxProng0 + 1.f * pxProng1 + 1.f * pxProng2; }); DECLARE_SOA_DYNAMIC_COLUMN(Py, py, //! [](float pyProng0, float pyProng1, float pyProng2) -> float { return 1.f * pyProng0 + 1.f * pyProng1 + 1.f * pyProng2; }); @@ -1274,6 +1323,7 @@ DECLARE_SOA_TABLE(HfRedVzeros, "AOD", "HFREDVZERO", //! Table with V0 candidate DECLARE_SOA_TABLE(HfRedTrkNoParams, "AOD", "HFREDTRKNOPARAM", //! Table with tracks without track parameters for resonances reduced workflow o2::soa::Index<>, // Indices + hf_track_index_reduced::TrackId, hf_track_index_reduced::HfRedCollisionId, // Static hf_track_vars_reduced::Px, @@ -1397,16 +1447,16 @@ DECLARE_SOA_COLUMN(InvMassProng1, invMassProng1, float); //! Invariant Mass of V DECLARE_SOA_COLUMN(Sign, sign, int8_t); //! Sign of the Resonance candidate DECLARE_SOA_COLUMN(IsWrongSign, isWrongSign, int8_t); //! Flag for wrong sign of the Resonance candidate, 1 = wrong sign, 0 = right sign -DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); // flag for resonance decay channel classification reconstruction level -DECLARE_SOA_COLUMN(FlagMcMatchRecD, flagMcMatchRecD, int8_t); // flag for D meson bachelor decay channel classification reconstruction level -DECLARE_SOA_COLUMN(FlagMcMatchChanD, flagMcMatchChanD, int8_t); // flag for D meson resonant channel classification reconstruction level -DECLARE_SOA_COLUMN(FlagMcMatchGen, flagMcMatchGen, int8_t); // flag for decay channel classification generator level -DECLARE_SOA_COLUMN(DebugMcRec, debugMcRec, uint16_t); // debug flag for mis-association at reconstruction level -DECLARE_SOA_COLUMN(Origin, origin, int8_t); // Flag for origin of MC particle 1=promt, 2=FD -DECLARE_SOA_COLUMN(SignD0, signD0, int8_t); // Sign of the D0 in the channels with D* -> D0 pi, needed in case of non-matched D* -DECLARE_SOA_COLUMN(PtGen, ptGen, float); // Pt at generation level in GeV/c -DECLARE_SOA_COLUMN(InvMassGen, invMassGen, float); //! Invariant mass at generation level in GeV/c2 -DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! +DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); // flag for resonance decay channel classification reconstruction level +DECLARE_SOA_COLUMN(FlagMcMatchRecD, flagMcMatchRecD, int8_t); // flag for D meson bachelor decay channel classification reconstruction level +DECLARE_SOA_COLUMN(FlagMcMatchChanD, flagMcMatchChanD, int8_t); // flag for D meson resonant channel classification reconstruction level +DECLARE_SOA_COLUMN(FlagMcMatchGen, flagMcMatchGen, int8_t); // flag for decay channel classification generator level +DECLARE_SOA_COLUMN(DebugMcRec, debugMcRec, uint16_t); // debug flag for mis-association at reconstruction level +DECLARE_SOA_COLUMN(Origin, origin, int8_t); // Flag for origin of MC particle 1=promt, 2=FD +DECLARE_SOA_COLUMN(SignD0, signD0, int8_t); // Sign of the D0 in the channels with D* -> D0 pi, needed in case of non-matched D* +DECLARE_SOA_COLUMN(PtGen, ptGen, float); // Pt at generation level in GeV/c +DECLARE_SOA_COLUMN(InvMassGen, invMassGen, float); //! Invariant mass at generation level in GeV/c2 +DECLARE_SOA_DYNAMIC_COLUMN(Pt, pt, //! [](float pxProng0, float pxProng1, float pyProng0, float pyProng1) -> float { return RecoDecay::pt((1.f * pxProng0 + 1.f * pxProng1), (1.f * pyProng0 + 1.f * pyProng1)); }); DECLARE_SOA_DYNAMIC_COLUMN(PtProng0, ptProng0, //! [](float pxProng0, float pyProng0) -> float { return RecoDecay::pt(pxProng0, pyProng0); }); diff --git a/PWGHF/D2H/TableProducer/candidateCreatorB0Reduced.cxx b/PWGHF/D2H/TableProducer/candidateCreatorB0Reduced.cxx index a5815359f4b..fd6a2b4098c 100644 --- a/PWGHF/D2H/TableProducer/candidateCreatorB0Reduced.cxx +++ b/PWGHF/D2H/TableProducer/candidateCreatorB0Reduced.cxx @@ -51,9 +51,11 @@ using namespace o2::hf_trkcandsel; /// Reconstruction of B0 candidates struct HfCandidateCreatorB0Reduced { - Produces rowCandidateBase; // table defined in CandidateReconstructionTables.h - Produces rowCandidateProngs; // table defined in ReducedDataModel.h - Produces rowCandidateDmesMlScores; // table defined in ReducedDataModel.h + Produces rowCandidateBase; // table defined in CandidateReconstructionTables.h + Produces rowCandidateB0DStar; // table defined in CandidateReconstructionTables.h + Produces rowCandidateProngs; // table defined in ReducedDataModel.h + Produces rowCandidateProngsDStar; // table defined in ReducedDataModel.h + Produces rowCandidateDmesMlScores; // table defined in ReducedDataModel.h // vertexing Configurable propagateToPCA{"propagateToPCA", true, "create tracks version propagated to PCA"}; @@ -67,17 +69,18 @@ struct HfCandidateCreatorB0Reduced { Configurable invMassWindowDPiTolerance{"invMassWindowDPiTolerance", 0.01, "invariant-mass window tolerance for DPi pair preselections (GeV/c2)"}; float myInvMassWindowDPi{1.}; // variable that will store the value of invMassWindowDPi (defined in dataCreatorDplusPiReduced.cxx) - float massPi{0.}; - float massD{0.}; - float massB0{0.}; float bz{0.}; - o2::vertexing::DCAFitterN<2> df2; // fitter for B vertex (2-prong vertex fitter) + o2::vertexing::DCAFitterN<2> df2; // fitter for B vertex (2-prong vertex fitter for DpPi candidates) + o2::vertexing::DCAFitterN<3> df3; // fitter for B vertex (3-prong vertex fitter for DstarPi candidates) using HfRedCollisionsWithExtras = soa::Join; + using HfSoftPiWCovAndPid = soa::Join; - Preslice> candsDPerCollision = hf_track_index_reduced::hfRedCollisionId; - Preslice> candsDWithMlPerCollision = hf_track_index_reduced::hfRedCollisionId; + Preslice> candsDplusPerCollision = hf_track_index_reduced::hfRedCollisionId; + Preslice> candsDplusWithMlPerCollision = hf_track_index_reduced::hfRedCollisionId; + Preslice> candsDstarPerCollision = hf_track_index_reduced::hfRedCollisionId; + Preslice> candsDstarWithMlPerCollision = hf_track_index_reduced::hfRedCollisionId; Preslice> tracksPionPerCollision = hf_track_index_reduced::hfRedCollisionId; std::shared_ptr hCandidates; @@ -85,16 +88,11 @@ struct HfCandidateCreatorB0Reduced { void init(InitContext const&) { - std::array doprocess{doprocessData, doprocessDataWithDmesMl}; + std::array doprocess{doprocessDataDplusPi, doprocessDataDplusPiWithDmesMl, doprocessDataDstarPi, doprocessDataDstarPiWithDmesMl}; if ((std::accumulate(doprocess.begin(), doprocess.end(), 0)) != 1) { LOGP(fatal, "Only one process function for data should be enabled at a time."); } - // invariant-mass window cut - massPi = o2::constants::physics::MassPiPlus; - massD = o2::constants::physics::MassDMinus; - massB0 = o2::constants::physics::MassB0; - // Initialize fitter df2.setPropagateToPCA(propagateToPCA); df2.setMaxR(maxR); @@ -104,8 +102,20 @@ struct HfCandidateCreatorB0Reduced { df2.setUseAbsDCA(useAbsDCA); df2.setWeightedFinalPCA(useWeightedFinalPCA); + df3.setPropagateToPCA(propagateToPCA); + df3.setMaxR(maxR); + df3.setMaxDZIni(maxDZIni); + df3.setMinParamChange(minParamChange); + df3.setMinRelChi2Change(minRelChi2Change); + df3.setUseAbsDCA(useAbsDCA); + df3.setWeightedFinalPCA(useWeightedFinalPCA); + // histograms - registry.add("hMassB0ToDPi", "2-prong candidates;inv. mass (B^{0} #rightarrow D^{#minus}#pi^{#plus} #rightarrow #pi^{#minus}K^{#plus}#pi^{#minus}#pi^{#plus}) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 3., 8.}}}); + if (doprocessDataDplusPi || doprocessDataDplusPiWithDmesMl) { + registry.add("hMassB0ToDPi", "2-prong candidates;inv. mass (B^{0} #rightarrow D^{#minus}#pi^{#plus} #rightarrow #pi^{#minus}K^{#plus}#pi^{#minus}#pi^{#plus}) (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{500, 3., 8.}}}); + } else if (doprocessDataDstarPi || doprocessDataDstarPiWithDmesMl) { + registry.add("hMassB0ToDPi", "3-prong candidates;inv. mass (B^{0} #rightarrow D^{0}#pi^{#plus}#pi^{#plus} #rightarrow #pi^{#minus}K^{#plus}#pi^{#minus}#pi^{#plus}) (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{500, 3., 8.}}}); + } registry.add("hCovPVXX", "2-prong candidates;XX element of cov. matrix of prim. vtx. position (cm^{2});entries", {HistType::kTH1F, {{100, 0., 1.e-4}}}); registry.add("hCovSVXX", "2-prong candidates;XX element of cov. matrix of sec. vtx. position (cm^{2});entries", {HistType::kTH1F, {{100, 0., 0.2}}}); registry.add("hEvents", "Events;;entries", HistType::kTH1F, {{1, 0.5, 1.5}}); @@ -115,6 +125,118 @@ struct HfCandidateCreatorB0Reduced { setLabelHistoCands(hCandidates); } + /// Main function to perform B0 candidate creation + /// \param withDmesMl is the flag to use the table with ML scores for the D- daughter (only possible if present in the derived data) + /// \param collision the collision + /// \param candsDThisColl B0 candidates in this collision + /// \param tracksPionThisCollision pion tracks in this collision + /// \param invMass2DPiMin minimum B0 invariant-mass + /// \param invMass2DPiMax maximum B0 invariant-mass + template + void runCandidateCreationDStar(Coll const& collision, + Cands const& candsDThisColl, + SoftPions const& softPions, + Pions const& tracksPionThisCollision, + const float invMass2DPiMin, + const float invMass2DPiMax) + { + auto primaryVertex = getPrimaryVertex(collision); + auto covMatrixPV = primaryVertex.getCov(); + + // Set the magnetic field from ccdb + bz = collision.bz(); + df3.setBz(bz); + + for (const auto& candD : candsDThisColl) { + auto trackParCovD = getTrackParCov(candD); + std::array pVecD0 = candD.pVector(); + auto trackSoftPion = softPions.rawIteratorAt(candD.globalIndex()); + std::array pVecSoftPion = trackSoftPion.pVector(); + auto trackParCovSoftPi = getTrackParCov(trackSoftPion); + + for (const auto& trackBachPion : tracksPionThisCollision) { + // this track is among daughters + if (trackBachPion.trackId() == candD.prong0Id() || trackBachPion.trackId() == candD.prong1Id() || trackBachPion.trackId() == trackSoftPion.trackId()) { + continue; + } + + auto trackParCovPi = getTrackParCov(trackBachPion); + std::array pVecBachPion = trackBachPion.pVector(); + + // compute invariant mass square and apply selection + auto invMass2DPi = RecoDecay::m2(std::array{pVecD0, pVecSoftPion, pVecBachPion}, std::array{o2::constants::physics::MassD0, o2::constants::physics::MassPiPlus, o2::constants::physics::MassPiPlus}); + if ((invMass2DPi < invMass2DPiMin) || (invMass2DPi > invMass2DPiMax)) { + continue; + } + + // --------------------------------- + // reconstruct the 3-prong B0 vertex + hCandidates->Fill(SVFitting::BeforeFit); + try { + if (df3.process(trackParCovD, trackParCovSoftPi, trackParCovPi) == 0) { + continue; + } + } catch (const std::runtime_error& error) { + LOG(info) << "Run time error found: " << error.what() << ". DCAFitterN cannot work, skipping the candidate."; + hCandidates->Fill(SVFitting::Fail); + continue; + } + hCandidates->Fill(SVFitting::FitOk); + + // DPi passed B0 reconstruction + + // calculate relevant properties + const auto& secondaryVertexB0 = df3.getPCACandidate(); + auto chi2PCA = df3.getChi2AtPCACandidate(); + auto covMatrixPCA = df3.calcPCACovMatrixFlat(); + registry.fill(HIST("hCovSVXX"), covMatrixPCA[0]); + registry.fill(HIST("hCovPVXX"), covMatrixPV[0]); + + // propagate D and Pi to the B0 vertex + df3.propagateTracksToVertex(); + // track.getPxPyPzGlo(pVec) modifies pVec of track + df3.getTrack(0).getPxPyPzGlo(pVecD0); // momentum of D at the B0 vertex + df3.getTrack(1).getPxPyPzGlo(pVecSoftPion); // momentum of SoftPi at the B0 vertex + df3.getTrack(2).getPxPyPzGlo(pVecBachPion); // momentum of Pi at the B0 vertex + + registry.fill(HIST("hMassB0ToDPi"), std::sqrt(invMass2DPi)); + + // compute impact parameters of D and Pi + o2::dataformats::DCA dcaD; + o2::dataformats::DCA dcaSoftPion; + o2::dataformats::DCA dcaBachPion; + trackParCovD.propagateToDCA(primaryVertex, bz, &dcaD); + trackParCovSoftPi.propagateToDCA(primaryVertex, bz, &dcaSoftPion); + trackParCovPi.propagateToDCA(primaryVertex, bz, &dcaBachPion); + + // get uncertainty of the decay length + float phi, theta; + // getPointDirection modifies phi and theta + getPointDirection(std::array{collision.posX(), collision.posY(), collision.posZ()}, secondaryVertexB0, phi, theta); + auto errorDecayLength = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, theta) + getRotatedCovMatrixXX(covMatrixPCA, phi, theta)); + auto errorDecayLengthXY = std::sqrt(getRotatedCovMatrixXX(covMatrixPV, phi, 0.) + getRotatedCovMatrixXX(covMatrixPCA, phi, 0.)); + + // fill the candidate table for the B0 here: + rowCandidateB0DStar(collision.globalIndex(), + collision.posX(), collision.posY(), collision.posZ(), + secondaryVertexB0[0], secondaryVertexB0[1], secondaryVertexB0[2], + errorDecayLength, errorDecayLengthXY, + chi2PCA, + pVecD0[0], pVecD0[1], pVecD0[2], + pVecSoftPion[0], pVecSoftPion[1], pVecSoftPion[2], + pVecBachPion[0], pVecBachPion[1], pVecBachPion[2], + dcaD.getY(), dcaSoftPion.getY(), dcaBachPion.getY(), + std::sqrt(dcaD.getSigmaY2()), std::sqrt(dcaSoftPion.getSigmaY2()), std::sqrt(dcaBachPion.getSigmaY2())); + + rowCandidateProngsDStar(candD.globalIndex(), trackBachPion.globalIndex(), trackSoftPion.globalIndex()); + + if constexpr (withDmesMl) { + rowCandidateDmesMlScores(candD.mlScoreBkgMassHypo0(), candD.mlScorePromptMassHypo0(), candD.mlScoreNonpromptMassHypo0()); + } + } // pi loop + } // D loop + } + /// Main function to perform B0 candidate creation /// \param withDmesMl is the flag to use the table with ML scores for the D- daughter (only possible if present in the derived data) /// \param collision the collision @@ -126,8 +248,8 @@ struct HfCandidateCreatorB0Reduced { void runCandidateCreation(Coll const& collision, Cands const& candsDThisColl, Pions const& tracksPionThisCollision, - const float& invMass2DPiMin, - const float& invMass2DPiMax) + const float invMass2DPiMin, + const float invMass2DPiMax) { auto primaryVertex = getPrimaryVertex(collision); auto covMatrixPV = primaryVertex.getCov(); @@ -150,7 +272,7 @@ struct HfCandidateCreatorB0Reduced { std::array pVecPion = trackPion.pVector(); // compute invariant mass square and apply selection - auto invMass2DPi = RecoDecay::m2(std::array{pVecD, pVecPion}, std::array{massD, massPi}); + auto invMass2DPi = RecoDecay::m2(std::array{pVecD, pVecPion}, std::array{o2::constants::physics::MassDMinus, o2::constants::physics::MassPiPlus}); if ((invMass2DPi < invMass2DPiMin) || (invMass2DPi > invMass2DPiMax)) { continue; } @@ -218,11 +340,11 @@ struct HfCandidateCreatorB0Reduced { } // D loop } - void processData(HfRedCollisionsWithExtras const& collisions, - soa::Join const& candsD, - soa::Join const& tracksPion, - aod::HfOrigColCounts const& collisionsCounter, - aod::HfCandB0Configs const& configs) + void processDataDplusPi(HfRedCollisionsWithExtras const& collisions, + soa::Join const& candsD, + soa::Join const& tracksPion, + aod::HfOrigColCounts const& collisionsCounter, + aod::HfCandB0Configs const& configs) { // DPi invariant-mass window cut for (const auto& config : configs) { @@ -230,8 +352,8 @@ struct HfCandidateCreatorB0Reduced { } // invMassWindowDPiTolerance is used to apply a slightly tighter cut than in DPi pair preselection // to avoid accepting DPi pairs that were not formed in DPi pair creator - float invMass2DPiMin = (massB0 - myInvMassWindowDPi + invMassWindowDPiTolerance) * (massB0 - myInvMassWindowDPi + invMassWindowDPiTolerance); - float invMass2DPiMax = (massB0 + myInvMassWindowDPi - invMassWindowDPiTolerance) * (massB0 + myInvMassWindowDPi - invMassWindowDPiTolerance); + float invMass2DPiMin = (o2::constants::physics::MassB0 - myInvMassWindowDPi + invMassWindowDPiTolerance) * (o2::constants::physics::MassB0 - myInvMassWindowDPi + invMassWindowDPiTolerance); + float invMass2DPiMax = (o2::constants::physics::MassB0 + myInvMassWindowDPi - invMassWindowDPiTolerance) * (o2::constants::physics::MassB0 + myInvMassWindowDPi - invMassWindowDPiTolerance); for (const auto& collisionCounter : collisionsCounter) { registry.fill(HIST("hEvents"), 1, collisionCounter.originalCollisionCount()); @@ -240,7 +362,7 @@ struct HfCandidateCreatorB0Reduced { static int ncol = 0; for (const auto& collision : collisions) { auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsD.sliceBy(candsDPerCollision, thisCollId); + auto candsDThisColl = candsD.sliceBy(candsDplusPerCollision, thisCollId); auto tracksPionThisCollision = tracksPion.sliceBy(tracksPionPerCollision, thisCollId); runCandidateCreation(collision, candsDThisColl, tracksPionThisCollision, invMass2DPiMin, invMass2DPiMax); if (ncol % 10000 == 0) { @@ -248,15 +370,15 @@ struct HfCandidateCreatorB0Reduced { } ncol++; } - } // processData + } // processDataDplusPi - PROCESS_SWITCH(HfCandidateCreatorB0Reduced, processData, "Process data without any ML score", true); + PROCESS_SWITCH(HfCandidateCreatorB0Reduced, processDataDplusPi, "Process data D-pi without any ML score", true); - void processDataWithDmesMl(HfRedCollisionsWithExtras const& collisions, - soa::Join const& candsD, - soa::Join const& tracksPion, - aod::HfOrigColCounts const& collisionsCounter, - aod::HfCandB0Configs const& configs) + void processDataDplusPiWithDmesMl(HfRedCollisionsWithExtras const& collisions, + soa::Join const& candsD, + soa::Join const& tracksPion, + aod::HfOrigColCounts const& collisionsCounter, + aod::HfCandB0Configs const& configs) { // DPi invariant-mass window cut for (const auto& config : configs) { @@ -264,8 +386,8 @@ struct HfCandidateCreatorB0Reduced { } // invMassWindowDPiTolerance is used to apply a slightly tighter cut than in DPi pair preselection // to avoid accepting DPi pairs that were not formed in DPi pair creator - float invMass2DPiMin = (massB0 - myInvMassWindowDPi + invMassWindowDPiTolerance) * (massB0 - myInvMassWindowDPi + invMassWindowDPiTolerance); - float invMass2DPiMax = (massB0 + myInvMassWindowDPi - invMassWindowDPiTolerance) * (massB0 + myInvMassWindowDPi - invMassWindowDPiTolerance); + float invMass2DPiMin = (o2::constants::physics::MassB0 - myInvMassWindowDPi + invMassWindowDPiTolerance) * (o2::constants::physics::MassB0 - myInvMassWindowDPi + invMassWindowDPiTolerance); + float invMass2DPiMax = (o2::constants::physics::MassB0 + myInvMassWindowDPi - invMassWindowDPiTolerance) * (o2::constants::physics::MassB0 + myInvMassWindowDPi - invMassWindowDPiTolerance); for (const auto& collisionCounter : collisionsCounter) { registry.fill(HIST("hEvents"), 1, collisionCounter.originalCollisionCount()); @@ -274,7 +396,7 @@ struct HfCandidateCreatorB0Reduced { static int ncol = 0; for (const auto& collision : collisions) { auto thisCollId = collision.globalIndex(); - auto candsDThisColl = candsD.sliceBy(candsDPerCollision, thisCollId); + auto candsDThisColl = candsD.sliceBy(candsDplusPerCollision, thisCollId); auto tracksPionThisCollision = tracksPion.sliceBy(tracksPionPerCollision, thisCollId); runCandidateCreation(collision, candsDThisColl, tracksPionThisCollision, invMass2DPiMin, invMass2DPiMax); if (ncol % 10000 == 0) { @@ -282,14 +404,86 @@ struct HfCandidateCreatorB0Reduced { } ncol++; } - } // processDataWithDmesMl + } // processDataDplusPiWithDmesMl + + PROCESS_SWITCH(HfCandidateCreatorB0Reduced, processDataDplusPiWithDmesMl, "Process data D-pi with ML scores of D mesons", false); + + void processDataDstarPi(HfRedCollisionsWithExtras const& collisions, + soa::Join const& candsD, + HfSoftPiWCovAndPid const& softPions, + soa::Join const& tracksPion, + aod::HfOrigColCounts const& collisionsCounter, + aod::HfCandB0Configs const& configs) + { + // DPi invariant-mass window cut + for (const auto& config : configs) { + myInvMassWindowDPi = config.myInvMassWindowDPi(); + } + // invMassWindowDPiTolerance is used to apply a slightly tighter cut than in DPi pair preselection + // to avoid accepting DPi pairs that were not formed in DPi pair creator + float invMass2DPiMin = (o2::constants::physics::MassB0 - myInvMassWindowDPi + invMassWindowDPiTolerance) * (o2::constants::physics::MassB0 - myInvMassWindowDPi + invMassWindowDPiTolerance); + float invMass2DPiMax = (o2::constants::physics::MassB0 + myInvMassWindowDPi - invMassWindowDPiTolerance) * (o2::constants::physics::MassB0 + myInvMassWindowDPi - invMassWindowDPiTolerance); + + for (const auto& collisionCounter : collisionsCounter) { + registry.fill(HIST("hEvents"), 1, collisionCounter.originalCollisionCount()); + } + + static int ncol = 0; + for (const auto& collision : collisions) { + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD.sliceBy(candsDstarPerCollision, thisCollId); + auto tracksPionThisCollision = tracksPion.sliceBy(tracksPionPerCollision, thisCollId); + runCandidateCreationDStar(collision, candsDThisColl, softPions, tracksPionThisCollision, invMass2DPiMin, invMass2DPiMax); + if (ncol % 10000 == 0) { + LOGP(debug, "collisions parsed {}", ncol); + } + ncol++; + } + } // processDataDstarPi + + PROCESS_SWITCH(HfCandidateCreatorB0Reduced, processDataDstarPi, "Process data D*pi without any ML score", false); + + void processDataDstarPiWithDmesMl(HfRedCollisionsWithExtras const& collisions, + soa::Join const& candsD, + HfSoftPiWCovAndPid const& softPions, + soa::Join const& tracksPion, + aod::HfOrigColCounts const& collisionsCounter, + aod::HfCandB0Configs const& configs) + { + // DPi invariant-mass window cut + for (const auto& config : configs) { + myInvMassWindowDPi = config.myInvMassWindowDPi(); + } + // invMassWindowDPiTolerance is used to apply a slightly tighter cut than in DPi pair preselection + // to avoid accepting DPi pairs that were not formed in DPi pair creator + float invMass2DPiMin = (o2::constants::physics::MassB0 - myInvMassWindowDPi + invMassWindowDPiTolerance) * (o2::constants::physics::MassB0 - myInvMassWindowDPi + invMassWindowDPiTolerance); + float invMass2DPiMax = (o2::constants::physics::MassB0 + myInvMassWindowDPi - invMassWindowDPiTolerance) * (o2::constants::physics::MassB0 + myInvMassWindowDPi - invMassWindowDPiTolerance); + + for (const auto& collisionCounter : collisionsCounter) { + registry.fill(HIST("hEvents"), 1, collisionCounter.originalCollisionCount()); + } + + static int ncol = 0; + for (const auto& collision : collisions) { + auto thisCollId = collision.globalIndex(); + auto candsDThisColl = candsD.sliceBy(candsDstarWithMlPerCollision, thisCollId); + auto tracksPionThisCollision = tracksPion.sliceBy(tracksPionPerCollision, thisCollId); + runCandidateCreationDStar(collision, candsDThisColl, softPions, tracksPionThisCollision, invMass2DPiMin, invMass2DPiMax); + if (ncol % 10000 == 0) { + LOGP(debug, "collisions parsed {}", ncol); + } + ncol++; + } + } // processDataDstarPiWithDmesMl + + PROCESS_SWITCH(HfCandidateCreatorB0Reduced, processDataDstarPiWithDmesMl, "Process data D*pi with ML scores of D mesons", false); - PROCESS_SWITCH(HfCandidateCreatorB0Reduced, processDataWithDmesMl, "Process data with ML scores of D mesons", false); }; // struct /// Extends the table base with expression columns and performs MC matching. struct HfCandidateCreatorB0ReducedExpressions { Spawns rowCandidateB0; + Spawns rowCandidateB0DSt; Spawns rowTracksExt; Produces rowB0McRec; Produces rowB0McCheck; @@ -298,14 +492,20 @@ struct HfCandidateCreatorB0ReducedExpressions { /// \param checkDecayTypeMc /// \param rowsDPiMcRec MC reco information on DPi pairs /// \param candsB0 prong global indices of B0 candidates - template - void fillB0McRec(McRec const& rowsDPiMcRec, HfRedB0Prongs const& candsB0) + template + void fillB0McRec(McRec const& rowsDPiMcRec, B0Prongs const& candsB0) { for (const auto& candB0 : candsB0) { bool filledMcInfo{false}; for (const auto& rowDPiMcRec : rowsDPiMcRec) { - if ((rowDPiMcRec.prong0Id() != candB0.prong0Id()) || (rowDPiMcRec.prong1Id() != candB0.prong1Id())) { - continue; + if constexpr (std::is_same_v) { + if ((rowDPiMcRec.prong0Id() != candB0.prong0Id()) || (rowDPiMcRec.prong1Id() != candB0.prong1Id())) { + continue; + } + } else if constexpr (std::is_same_v) { // No need to check ID of soft pion, it is the same as D0 + if ((rowDPiMcRec.prongD0Id() != candB0.prongD0Id()) || (rowDPiMcRec.prongBachPiId() != candB0.prongBachPiId())) { + continue; + } } rowB0McRec(rowDPiMcRec.flagMcMatchRec(), -1 /*channel*/, rowDPiMcRec.flagWrongCollision(), rowDPiMcRec.debugMcRec(), rowDPiMcRec.ptMother()); filledMcInfo = true; @@ -328,17 +528,29 @@ struct HfCandidateCreatorB0ReducedExpressions { } } - void processMc(HfMcRecRedDpPis const& rowsDPiMcRec, HfRedB0Prongs const& candsB0) + void processMcDplusPi(HfMcRecRedDpPis const& rowsDPiMcRec, HfRedB0Prongs const& candsB0) + { + fillB0McRec(rowsDPiMcRec, candsB0); + } + PROCESS_SWITCH(HfCandidateCreatorB0ReducedExpressions, processMcDplusPi, "Process MC for DplusPi", false); + + void processMcDplusPiWithDecayTypeCheck(soa::Join const& rowsDPiMcRec, HfRedB0Prongs const& candsB0) + { + fillB0McRec(rowsDPiMcRec, candsB0); + } + PROCESS_SWITCH(HfCandidateCreatorB0ReducedExpressions, processMcDplusPiWithDecayTypeCheck, "Process MC with decay type checks for DplusPi", false); + + void processMcDstarPi(HfMcRecRedDStarPis const& rowsDPiMcRec, HfRedB0ProngDStars const& candsB0) { fillB0McRec(rowsDPiMcRec, candsB0); } - PROCESS_SWITCH(HfCandidateCreatorB0ReducedExpressions, processMc, "Process MC", false); + PROCESS_SWITCH(HfCandidateCreatorB0ReducedExpressions, processMcDstarPi, "Process MC for DstarPi", false); - void processMcWithDecayTypeCheck(soa::Join const& rowsDPiMcRec, HfRedB0Prongs const& candsB0) + void processMcDstarPiWithDecayTypeCheck(soa::Join const& rowsDPiMcRec, HfRedB0ProngDStars const& candsB0) { fillB0McRec(rowsDPiMcRec, candsB0); } - PROCESS_SWITCH(HfCandidateCreatorB0ReducedExpressions, processMcWithDecayTypeCheck, "Process MC with decay type checks", false); + PROCESS_SWITCH(HfCandidateCreatorB0ReducedExpressions, processMcDstarPiWithDecayTypeCheck, "Process MC with decay type checks for DstarPi", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx b/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx index 55ba9628f9a..f5f8734c652 100644 --- a/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx +++ b/PWGHF/D2H/TableProducer/candidateCreatorCharmResoReduced.cxx @@ -102,23 +102,27 @@ struct HfCandidateCreatorCharmResoReduced { Produces rowCandidateResoIndices2PrTrks; // D Configurables struct : ConfigurableGroup { + std::string prefix = "dmesonsCuts"; Configurable> binsPtD{"binsPtD", std::vector{hf_cuts_d_daughter::vecBinsPt}, "pT bin limits for D daughter cuts"}; Configurable> cutsD{"cutsD", {hf_cuts_d_daughter::Cuts[0], hf_cuts_d_daughter::NBinsPt, hf_cuts_d_daughter::NCutVars, hf_cuts_d_daughter::labelsPt, hf_cuts_d_daughter::labelsCutVar}, "D daughter selections"}; Configurable keepSideBands{"keepSideBands", false, "flag to keep events from D meson sidebands for backgorund estimation"}; } cfgDmesCuts; // V0 cuts configurables struct : ConfigurableGroup { + std::string prefix = "v0Cuts"; Configurable> cutsV0{"cutsV0", {hf_cuts_v0_daughter::Cuts[0], hf_cuts_v0_daughter::NBinsPt, hf_cuts_v0_daughter::NCutVars, hf_cuts_v0_daughter::labelsPt, hf_cuts_v0_daughter::labelsCutVar}, "V0 daughter selections"}; Configurable> binsPtV0{"binsPtV0", std::vector{hf_cuts_v0_daughter::vecBinsPt}, "pT bin limits for V0 daughter cuts"}; Configurable v0Type{"v0Type", 0, "V0 type to be selected (0: K0s, 1: Lambda"}; } cfgV0Cuts; // Track cuts configurables struct : ConfigurableGroup { + std::string prefix = "trackCuts"; Configurable> cutsTrk{"cutsTrk", {hf_cuts_track_daughter::Cuts[0], hf_cuts_track_daughter::NCutVars, hf_cuts_track_daughter::labelsCutVar}, "Track daughter selections, set to -1 to disable cuts"}; Configurable massHypo{"massHypo", 1, "Mass Hypothesis for the track daughters (0: pion, 1: kaon, 2: proton)"}; } cfgTrackCuts; // Mixed Event configurables struct : ConfigurableGroup { + std::string prefix = "mixedEvent"; Configurable numberEventsMixed{"numberEventsMixed", 5, "Number of events mixed in ME process"}; Configurable numberEventsToSkip{"numberEventsToSkip", -1, "Number of events to Skip in ME process"}; ConfigurableAxis multPoolBins{"multPoolBins", {VARIABLE_WIDTH, 0., 45., 60., 75., 95, 250}, "event multiplicity pools (PV contributors for now)"}; @@ -126,6 +130,7 @@ struct HfCandidateCreatorCharmResoReduced { } cfgMixedEvent; // Histogram axes configurables struct : ConfigurableGroup { + std::string prefix = "histAxes"; ConfigurableAxis axisPtD{"axisPtD", {100, 0., 50}, "#it{p}_{T} (GeV/#it{c})"}; ConfigurableAxis axisPtV0{"axisPtV0", {100, 0., 50}, "#it{p}_{T} (GeV/#it{c})"}; ConfigurableAxis axisPtReso{"axisPtReso", {100, 0., 50}, "#it{p}_{T} (GeV/#it{c})"}; @@ -691,10 +696,8 @@ struct HfCandidateCreatorCharmResoReduced { bool alreadyCounted{false}; for (const auto& candV0Tr : candsV0Tr) { if constexpr (bachType == BachelorType::V0) { // Case: V0 - if (rejectPairsWithCommonDaughter) { - if (std::find(dDaughtersIDs.begin(), dDaughtersIDs.end(), candV0Tr.prong0Id()) != dDaughtersIDs.end() || std::find(dDaughtersIDs.begin(), dDaughtersIDs.end(), candV0Tr.prong1Id()) != dDaughtersIDs.end()) { - continue; - } + if (rejectPairsWithCommonDaughter && (std::find(dDaughtersIDs.begin(), dDaughtersIDs.end(), candV0Tr.prong0Id()) != dDaughtersIDs.end() || std::find(dDaughtersIDs.begin(), dDaughtersIDs.end(), candV0Tr.prong1Id()) != dDaughtersIDs.end())) { + continue; } if (!isV0Selected(candV0Tr)) { continue; @@ -704,10 +707,8 @@ struct HfCandidateCreatorCharmResoReduced { alreadyCounted = true; } } else if constexpr (bachType == BachelorType::Track) { // Case: Track - if (rejectPairsWithCommonDaughter) { - if (std::find(dDaughtersIDs.begin(), dDaughtersIDs.end(), candV0Tr.globalIndex()) != dDaughtersIDs.end()) { - continue; - } + if (rejectPairsWithCommonDaughter && std::find(dDaughtersIDs.begin(), dDaughtersIDs.end(), candV0Tr.trackId()) != dDaughtersIDs.end()) { + continue; } if (!isTrackSelected(candV0Tr)) { continue; diff --git a/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx b/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx index 53609fc66c9..51ba23c8511 100644 --- a/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx +++ b/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx @@ -103,13 +103,14 @@ struct HfCandidateSelectorB0ToDPiReduced { TrackSelectorPi selectorPion; HfHelper hfHelper; - using TracksPion = soa::Join; + using TracksBachPion = soa::Join; + using TracksSoftPions = soa::Join; HistogramRegistry registry{"registry"}; void init(InitContext const&) { - std::array doprocess{doprocessSelection, doprocessSelectionWithDmesMl}; + std::array doprocess{doprocessSelectionDplusPi, doprocessSelectionDplusPiWithDmesMl, doprocessSelectionDstarPi, doprocessSelectionDstarPiWithDmesMl}; if ((std::accumulate(doprocess.begin(), doprocess.end(), 0)) != 1) { LOGP(fatal, "Only one process function for data should be enabled at a time."); } @@ -155,6 +156,55 @@ struct HfCandidateSelectorB0ToDPiReduced { } } + /// Utility function to retrieve the bach pion track + /// from the B0 candidate in the D*-pi decay channel + /// \param candidate is the B0 candidate + /// \return bach pion track + template + auto getTrackBachPi(const T1& candidate) + { + return candidate.template prongBachPi_as(); + } + + /// Method to get the input features vector needed for ML inference + /// \param candidate is the B0 candidate + /// \param prongBachPi is the candidate's bachelor pion prong + /// \note this method is used for B0 → D*- π+ candidates with D meson ML scores + template + auto getMlInputFeatures(const T1& candB0, const T2& prongBachPi) + { + auto prongSoftPi = candB0.template prongSoftPi_as(); + if constexpr (withDmesMl) { + return hfMlResponse.getInputFeaturesDStarPi(candB0, prongBachPi, prongSoftPi); + } else { + return hfMlResponse.getInputFeaturesDStarPi(candB0, prongBachPi, prongSoftPi); + } + } + + /// Utility function to retrieve the bach pion track + /// from the B0 candidate in the D-pi decay channel + /// \param candidate is the B0 candidate + /// \return bach pion track + template + auto getTrackBachPi(const T1& candidate) + { + return candidate.template prong1_as(); + } + + /// Method to get the input features vector needed for ML inference + /// \param candB0 is the B0 candidate + /// \param prongBachPi is the candidate's bachelor pion prong + /// \note this method is used for B0 → D- π+ candidates with D meson ML scores + template + auto getMlInputFeatures(const T1& candB0, const T2& prongBachPi) + { + if constexpr (withDmesMl) { + return hfMlResponse.getInputFeatures(candB0, prongBachPi); + } else { + return hfMlResponse.getInputFeatures(candB0, prongBachPi); + } + } + /// Main function to perform B0 candidate creation /// \param withDmesMl is the flag to use the table with ML scores for the D- daughter (only possible if present in the derived data) /// \param hfCandsB0 B0 candidates @@ -162,7 +212,7 @@ struct HfCandidateSelectorB0ToDPiReduced { /// \param configs config inherited from the Dpi data creator template void runSelection(Cands const& hfCandsB0, - TracksPion const&, + TracksBachPion const&, HfCandB0Configs const& configs) { // get DplusPi creator configurable @@ -205,16 +255,15 @@ struct HfCandidateSelectorB0ToDPiReduced { registry.fill(HIST("hSelections"), 2 + SelectionStep::RecoTopol, ptCandB0); } - // track-level PID selection - auto trackPi = hfCandB0.template prong1_as(); + auto trackBachPi = getTrackBachPi(hfCandB0); if (pionPidMethod == PidMethod::TpcOrTof || pionPidMethod == PidMethod::TpcAndTof) { - int pidTrackPi{TrackSelectorPID::Status::NotApplicable}; + int pidTrackBachPi{TrackSelectorPID::Status::NotApplicable}; if (pionPidMethod == PidMethod::TpcOrTof) { - pidTrackPi = selectorPion.statusTpcOrTof(trackPi); + pidTrackBachPi = selectorPion.statusTpcOrTof(trackBachPi); } else if (pionPidMethod == PidMethod::TpcAndTof) { - pidTrackPi = selectorPion.statusTpcAndTof(trackPi); + pidTrackBachPi = selectorPion.statusTpcAndTof(trackBachPi); } - if (!hfHelper.selectionB0ToDPiPid(pidTrackPi, acceptPIDNotApplicable.value)) { + if (!hfHelper.selectionB0ToDPiPid(pidTrackBachPi, acceptPIDNotApplicable.value)) { // LOGF(info, "B0 candidate selection failed at PID selection"); hfSelB0ToDPiCandidate(statusB0ToDPi); if (applyB0Ml) { @@ -227,10 +276,9 @@ struct HfCandidateSelectorB0ToDPiReduced { registry.fill(HIST("hSelections"), 2 + SelectionStep::RecoPID, ptCandB0); } } - if (applyB0Ml) { // B0 ML selections - std::vector inputFeatures = hfMlResponse.getInputFeatures(hfCandB0, trackPi); + std::vector inputFeatures = getMlInputFeatures(hfCandB0, trackBachPi); bool isSelectedMl = hfMlResponse.isSelectedMl(inputFeatures, ptCandB0, outputMl); hfMlB0ToDPiCandidate(outputMl[1]); // storing ML score for signal class @@ -249,23 +297,43 @@ struct HfCandidateSelectorB0ToDPiReduced { } } - void processSelection(HfRedCandB0 const& hfCandsB0, - TracksPion const& pionTracks, - HfCandB0Configs const& configs) + void processSelectionDplusPi(HfRedCandB0 const& hfCandsB0, + TracksBachPion const& pionTracks, + HfCandB0Configs const& configs) + { + runSelection(hfCandsB0, pionTracks, configs); + } // processSelectionDplusPi + + PROCESS_SWITCH(HfCandidateSelectorB0ToDPiReduced, processSelectionDplusPi, "Process selection DplusPi without ML scores of D mesons", true); + + void processSelectionDplusPiWithDmesMl(soa::Join const& hfCandsB0, + TracksBachPion const& pionTracks, + HfCandB0Configs const& configs) + { + runSelection(hfCandsB0, pionTracks, configs); + } // processSelectionDplusPiWithDmesMl + + PROCESS_SWITCH(HfCandidateSelectorB0ToDPiReduced, processSelectionDplusPiWithDmesMl, "Process selection DplusPi with ML scores of D mesons", false); + + void processSelectionDstarPi(HfRedCandB0DStar const& hfCandsB0, + TracksBachPion const& pionTracks, + HfCandB0Configs const& configs, + TracksSoftPions const& /*softPions*/) { runSelection(hfCandsB0, pionTracks, configs); - } // processSelection + } // processSelectionDstarPi - PROCESS_SWITCH(HfCandidateSelectorB0ToDPiReduced, processSelection, "Process selection without ML scores of D mesons", true); + PROCESS_SWITCH(HfCandidateSelectorB0ToDPiReduced, processSelectionDstarPi, "Process selection DstarPi without ML scores of D mesons", false); - void processSelectionWithDmesMl(soa::Join const& hfCandsB0, - TracksPion const& pionTracks, - HfCandB0Configs const& configs) + void processSelectionDstarPiWithDmesMl(soa::Join const& hfCandsB0, + TracksBachPion const& pionTracks, + HfCandB0Configs const& configs, + TracksSoftPions const& /*softPions*/) { runSelection(hfCandsB0, pionTracks, configs); - } // processSelectionWithDmesMl + } // processSelectionDstarPiWithDmesMl - PROCESS_SWITCH(HfCandidateSelectorB0ToDPiReduced, processSelectionWithDmesMl, "Process selection with ML scores of D mesons", false); + PROCESS_SWITCH(HfCandidateSelectorB0ToDPiReduced, processSelectionDstarPiWithDmesMl, "Process selection DstarPi with ML scores of D mesons", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx index 0b73b385893..8b38982c477 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmHadPiReduced.cxx @@ -122,6 +122,7 @@ struct HfDataCreatorCharmHadPiReduced { Produces hfTrackPion; Produces hfTrackCovPion; Produces hfTrackPidPion; + Produces hfTrackMomPion; // charm hadron related tables Produces hfCand2Prong; Produces hfCand2ProngCov; @@ -129,9 +130,11 @@ struct HfDataCreatorCharmHadPiReduced { Produces hfCand3Prong; Produces hfCand3ProngCov; Produces hfCand3ProngMl; - // D* soft pion related tables + Produces hfMomDMesDaugs; + // D* related tables Produces hfTrackSoftPion; Produces hfTrackCovSoftPion; + Produces hfTrackPidSoftPion; // PID tables for charm-hadron candidate daughter tracks Produces hfCandPidProng0; Produces hfCandPidProng1; @@ -141,6 +144,7 @@ struct HfDataCreatorCharmHadPiReduced { Produces rowCandidateConfigB0; Produces rowHfDPiMcRecReduced; Produces rowHfDPiMcCheckReduced; + Produces rowHfDStarPiMcRecReduced; Produces rowHfB0McGenReduced; Produces rowCandidateConfigBplus; @@ -266,7 +270,7 @@ struct HfDataCreatorCharmHadPiReduced { PresliceUnsorted colPerMcCollision = aod::mccollisionlabel::mcCollisionId; } preslices; - std::shared_ptr hCandidatesD0, hCandidatesDPlus, hCandidatesDs, hCandidatesLc, hCandidatesDstar; + std::shared_ptr hCandidatesD0, hCandidatesDPlus, hCandidatesDs, hCandidatesLc, hCandidatesD0FromDstar; HistogramRegistry registry{"registry"}; std::array arrPDGResonantDsPhiPi = {kPhi, kPiPlus}; // Ds± → Phi π± @@ -306,8 +310,7 @@ struct HfDataCreatorCharmHadPiReduced { // Initialize fitter if (doprocessDplusPiData || doprocessDplusPiDataWithMl || doprocessDplusPiDataWithQvec || doprocessDplusPiDataWithMlAndQvec || doprocessDplusPiMc || doprocessDplusPiMcWithMl || doprocessDsPiData || doprocessDsPiDataWithMl || doprocessDsPiDataWithQvec || doprocessDsPiDataWithMlAndQvec || doprocessDsPiMc || doprocessDsPiMcWithMl || - doprocessLcPiData || doprocessLcPiDataWithMl || doprocessLcPiMc || doprocessLcPiMcWithMl || - doprocessDstarPiData || doprocessDstarPiDataWithMl || doprocessDstarPiDataWithQvec || doprocessDstarPiDataWithMlAndQvec || doprocessDstarPiMc || doprocessDstarPiMcWithMl) { + doprocessLcPiData || doprocessLcPiDataWithMl || doprocessLcPiMc || doprocessLcPiMcWithMl) { df3.setPropagateToPCA(vertexConfigurations.propagateToPCA); df3.setMaxR(vertexConfigurations.maxR); df3.setMaxDZIni(vertexConfigurations.maxDZIni); @@ -316,7 +319,8 @@ struct HfDataCreatorCharmHadPiReduced { df3.setUseAbsDCA(vertexConfigurations.useAbsDCA); df3.setWeightedFinalPCA(vertexConfigurations.useWeightedFinalPCA); df3.setMatCorrType(noMatCorr); - } else if (doprocessD0PiData || doprocessD0PiDataWithMl || doprocessD0PiDataWithQvec || doprocessD0PiDataWithMlAndQvec || doprocessD0PiMc || doprocessD0PiMcWithMl) { + } else if (doprocessD0PiData || doprocessD0PiDataWithMl || doprocessD0PiDataWithQvec || doprocessD0PiDataWithMlAndQvec || doprocessD0PiMc || doprocessD0PiMcWithMl || + doprocessDstarPiData || doprocessDstarPiDataWithMl || doprocessDstarPiDataWithQvec || doprocessDstarPiDataWithMlAndQvec || doprocessDstarPiMc || doprocessDstarPiMcWithMl) { df2.setPropagateToPCA(vertexConfigurations.propagateToPCA); df2.setMaxR(vertexConfigurations.maxR); df2.setMaxDZIni(vertexConfigurations.maxDZIni); @@ -381,13 +385,13 @@ struct HfDataCreatorCharmHadPiReduced { hCandidatesDPlus = registry.add("hCandidatesDPlus", "Dplus candidate counter", {HistType::kTH1D, {axisCands}}); hCandidatesDs = registry.add("hCandidatesDs", "Ds candidate counter", {HistType::kTH1D, {axisCands}}); hCandidatesLc = registry.add("hCandidatesLc", "Lc candidate counter", {HistType::kTH1D, {axisCands}}); - hCandidatesDstar = registry.add("hCandidatesDstar", "Dstar candidate counter", {HistType::kTH1D, {axisCands}}); + hCandidatesD0FromDstar = registry.add("hCandidatesD0FromDstar", "D0 from D* candidate counter", {HistType::kTH1D, {axisCands}}); setLabelHistoCands(hCandidatesD0); setLabelHistoCands(hCandidatesDPlus); setLabelHistoCands(hCandidatesDs); setLabelHistoCands(hCandidatesLc); - setLabelHistoCands(hCandidatesDstar); + setLabelHistoCands(hCandidatesD0FromDstar); // init HF event selection helper hfEvSel.init(registry); @@ -1006,7 +1010,7 @@ struct HfDataCreatorCharmHadPiReduced { checkWrongCollision(particleMother, collision, indexCollisionMaxNumContrib, flagWrongCollision); } } - tables.rowHfDPiMcRecReduced(indexHfCandCharm, selectedTracksPion[vecDaughtersB.back().globalIndex()], flag, flagWrongCollision, debug, motherPt); + tables.rowHfDStarPiMcRecReduced(indexHfCandCharm, selectedTracksPion[vecDaughtersB.back().globalIndex()], flag, flagWrongCollision, debug, motherPt); } } @@ -1021,7 +1025,7 @@ struct HfDataCreatorCharmHadPiReduced { { registry.fill(HIST("hEvents"), 1 + Event::Processed); float centrality = -1.f; - auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); if (configs.skipRejectedCollisions && hfRejMap != 0) { return; } @@ -1050,6 +1054,7 @@ struct HfDataCreatorCharmHadPiReduced { LOG(info) << ">>>>>>>>>>>> Magnetic field: " << bz; runNumber = bc.runNumber(); } + df2.setBz(bz); df3.setBz(bz); auto thisCollId = collision.globalIndex(); @@ -1099,7 +1104,7 @@ struct HfDataCreatorCharmHadPiReduced { registry.fill(HIST("hPtLc"), candC.pt()); registry.fill(HIST("hCpaLc"), candC.cpa()); } else if constexpr (decChannel == DecayChannel::B0ToDstarPi) { - indexHfCandCharm = tables.hfCand3Prong.lastIndex() + 1; + indexHfCandCharm = tables.hfCand2Prong.lastIndex() + 1; if (candC.signSoftPi() > 0) { invMassC0 = candC.invMassDstar() - candC.invMassD0(); } else { @@ -1219,7 +1224,7 @@ struct HfDataCreatorCharmHadPiReduced { trackParCovCharmHad.setAbsCharge(0); // to be sure } else if constexpr (decChannel == DecayChannel::B0ToDstarPi) { - hCandidatesDstar->Fill(SVFitting::BeforeFit); + hCandidatesD0FromDstar->Fill(SVFitting::BeforeFit); try { // D0 vertex if (df2.process(trackParCov0, trackParCov1) == 0) { @@ -1227,10 +1232,10 @@ struct HfDataCreatorCharmHadPiReduced { } } catch (const std::runtime_error& error) { LOG(info) << "Run time error found: " << error.what() << ". DCAFitterN cannot work, skipping the candidate."; - hCandidatesDstar->Fill(SVFitting::Fail); + hCandidatesD0FromDstar->Fill(SVFitting::Fail); continue; } - hCandidatesDstar->Fill(SVFitting::FitOk); + hCandidatesD0FromDstar->Fill(SVFitting::FitOk); auto secondaryVertexCharm = df2.getPCACandidate(); trackParCov0.propagateTo(secondaryVertexCharm[0], bz); trackParCov1.propagateTo(secondaryVertexCharm[0], bz); @@ -1312,6 +1317,7 @@ struct HfDataCreatorCharmHadPiReduced { trackParCovPion.getSigma1PtTgl(), trackParCovPion.getSigma1Pt2()); tables.hfTrackPidPion(trackPion.hasTPC(), trackPion.hasTOF(), trackPion.tpcNSigmaPi(), trackPion.tofNSigmaPi()); + tables.hfTrackMomPion(pVecPion[0], pVecPion[1], pVecPion[2], trackPion.sign()); // add trackPion.globalIndex() to a list // to keep memory of the pions filled in the table and avoid refilling them if they are paired to another D candidate // and keep track of their index in tables.hfTrackPion for McRec purposes @@ -1445,13 +1451,18 @@ struct HfDataCreatorCharmHadPiReduced { trackParCovSoftPion.getSigmaTglSnp(), trackParCovSoftPion.getSigmaTgl2(), trackParCovSoftPion.getSigma1PtY(), trackParCovSoftPion.getSigma1PtZ(), trackParCovSoftPion.getSigma1PtSnp(), trackParCovSoftPion.getSigma1PtTgl(), trackParCovSoftPion.getSigma1Pt2()); + tables.hfTrackPidSoftPion(candC.nSigTpcPi2(), candC.nSigTofPi2(), charmHadDauTracks[2].hasTOF(), charmHadDauTracks[2].hasTPC()); if constexpr (withMl) { std::array mlScores = {-1.f, -1.f, -1.f, -1.f, -1.f, -1.f}; if (candC.mlProbDstarToD0Pi().size() == NSizeMLScore) { std::copy(candC.mlProbDstarToD0Pi().begin(), candC.mlProbDstarToD0Pi().end(), mlScores.begin()); } - tables.hfCand3ProngMl(mlScores[0], mlScores[1], mlScores[2], -1.f, -1.f, -1.f); + tables.hfCand3ProngMl(mlScores[0], mlScores[1], mlScores[2], mlScores[3], mlScores[4], mlScores[5]); } + + tables.hfMomDMesDaugs(pVec0[0], pVec0[1], pVec0[2], + pVec1[0], pVec1[1], pVec1[2], + pVecSoftPion[0], pVecSoftPion[1], pVecSoftPion[2]); } fillHfReducedCollision = true; } @@ -1487,15 +1498,16 @@ struct HfDataCreatorCharmHadPiReduced { // Check event selection float centDummy{-1.f}, centFT0C{-1.f}, centFT0M{-1.f}; const auto collSlice = collisions.sliceBy(preslices.colPerMcCollision, mcCollision.globalIndex()); - auto hfRejMap = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, collSlice, centDummy); + const auto hfRejMap = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, collSlice, centDummy); if (configs.skipRejectedCollisions && hfRejMap != 0) { return; } // get centrality - float multiplicity{0.f}; + using TMult = uint16_t; // type of numContrib + TMult multiplicity{}; for (const auto& collision : collSlice) { - float collMult = collision.numContrib(); + const TMult collMult = collision.numContrib(); if (collMult > multiplicity) { centFT0C = collision.centFT0C(); centFT0M = collision.centFT0M(); diff --git a/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx index a2584dc5b06..c2d7d6f3047 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorCharmResoReduced.cxx @@ -162,7 +162,7 @@ struct HfDataCreatorCharmResoReduced { // selection single tracks struct : ConfigurableGroup { - std::string prefix = "single_tracks"; + std::string prefix = "singleTracks"; Configurable setTrackSelections{"setTrackSelections", 2, "flag to apply track selections: 0=none; 1=global track w/o DCA selection; 2=global track; 3=only ITS quality"}; Configurable maxEta{"maxEta", 0.8, "maximum pseudorapidity for single tracks to be paired with D mesons"}; Configurable minPt{"minPt", 0.1, "minimum pT for single tracks to be paired with D mesons"}; @@ -173,6 +173,7 @@ struct HfDataCreatorCharmResoReduced { // QA histograms struct : ConfigurableGroup { + std::string prefix = "qaPlots"; Configurable applyCutsForQaHistograms{"applyCutsForQaHistograms", true, "flag to apply cuts to QA histograms"}; Configurable cutMassDstarMin{"cutMassDstarMin", 0.143, "minimum mass for Dstar candidates"}; Configurable cutMassDstarMax{"cutMassDstarMax", 0.155, "maximum mass for Dstar candidates"}; @@ -349,7 +350,8 @@ struct HfDataCreatorCharmResoReduced { doprocessDstarV0MC || doprocessDstarTrackMC || doprocessDstarV0AndTrackMC || doprocessDstarV0MCWithMl || doprocessDstarTrackMCWithMl || doprocessDstarV0AndTrackMCWithMl || doprocessDplusV0MC || doprocessDplusTrackMC || doprocessDplusV0AndTrackMC || doprocessDplusV0MCWithMl || doprocessDplusTrackMCWithMl || doprocessDplusV0AndTrackMCWithMl) { // MC Rec - registry.add("hMCRecCounter", "Number of Reconstructed MC Matched candidates per channel", {HistType::kTH1D, {{31, -15.5, 15.5}}}); + int nChannels = hf_decay::hf_cand_reso::DecayChannelMain::NChannelsMain; + registry.add("hMCRecCounter", "Number of Reconstructed MC Matched candidates per channel", {HistType::kTH1D, {{2 * nChannels + 1, -(nChannels + 0.5), nChannels + 0.5}}}); registry.add("hMCRecDebug", "Debug of MC Reco", {HistType::kTH1D, {{551, -0.5, 550.5}}}); registry.add("hMCRecOrigin", "Origin of Matched particles", {HistType::kTH1D, {{3, -0.5, 2.5}}}); registry.add("hMCRecMassGen", "Generated inv. mass of resoncances", {HistType::kTH1D, {{2000, 1.8, 3.8}}}); @@ -644,24 +646,24 @@ struct HfDataCreatorCharmResoReduced { vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prongPiId())); // Check if D* is matched flagCharmBach = candCharmBach.flagMcMatchRec(); - if (std::abs(flagCharmBach) > 0) { + if (flagCharmBach != 0) { SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DstarMatched); origin = candCharmBach.originMcRec(); } // Check if D0 is matched flagCharmBachInterm = candCharmBach.flagMcMatchRecD0(); - if (std::abs(flagCharmBachInterm) > 0) { + if (flagCharmBachInterm != 0) { SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); } // Check if V0 is matched vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.posTrackId())); vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.negTrackId())); flagV0 = getMatchingFlagV0(particlesMc, std::array{vecDaughtersReso[3], vecDaughtersReso[4]}); - if (std::abs(flagV0) > 0) { + if (flagV0 != 0) { SETBIT(debugMcRec, std::abs(flagV0)); } // If both D* and K0s are matched, try to match resonance - if (std::abs(flagCharmBach) > 0 && flagV0 == hf_decay::hf_cand_reso::PartialMatchMc::K0Matched) { + if (flagCharmBach != 0 && flagV0 == hf_decay::hf_cand_reso::PartialMatchMc::K0Matched) { std::array pdgCodesDaughters = {+kPiPlus, -kKPlus, +kPiPlus, +kPiPlus, -kPiPlus}; auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], vecDaughtersReso[3], vecDaughtersReso[4]}; for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarK0s) { @@ -671,7 +673,7 @@ struct HfDataCreatorCharmResoReduced { break; } } - } else if (std::abs(flagCharmBachInterm) > 0 && flagV0 == hf_decay::hf_cand_reso::PartialMatchMc::K0Matched) { + } else if (flagCharmBachInterm != 0 && flagV0 == hf_decay::hf_cand_reso::PartialMatchMc::K0Matched) { std::array pdgCodesDaughters = {+kPiPlus, -kKPlus, +kPiPlus, -kPiPlus}; auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[3], vecDaughtersReso[4]}; // Peaking background of D0K0s <- Ds* with spurious soft pion @@ -702,7 +704,7 @@ struct HfDataCreatorCharmResoReduced { // Check if D+ is matched flagCharmBach = candCharmBach.flagMcMatchRec(); flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); - if (std::abs(flagCharmBach) > 0) { + if (flagCharmBach != 0) { SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DplusMatched); origin = candCharmBach.originMcRec(); } @@ -710,7 +712,7 @@ struct HfDataCreatorCharmResoReduced { vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.posTrackId())); vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.negTrackId())); flagV0 = getMatchingFlagV0(particlesMc, std::array{vecDaughtersReso[3], vecDaughtersReso[4]}); - if (std::abs(flagV0) > 0) { + if (flagV0 != 0) { SETBIT(debugMcRec, std::abs(flagV0)); } // If both D+ and K0s are matched, try to match resonance @@ -754,7 +756,7 @@ struct HfDataCreatorCharmResoReduced { // Check if D0 is matched flagCharmBach = candCharmBach.flagMcMatchRec(); flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); - if (std::abs(flagCharmBach) > 0) { + if (flagCharmBach != 0) { SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); origin = candCharmBach.originMcRec(); } @@ -762,7 +764,7 @@ struct HfDataCreatorCharmResoReduced { vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.posTrackId())); vecDaughtersReso.push_back(tracks.rawIteratorAt(bachelorV0.negTrackId())); flagV0 = getMatchingFlagV0(particlesMc, std::array{vecDaughtersReso[2], vecDaughtersReso[3]}); - if (std::abs(flagV0) > 0) { + if (flagV0 != 0) { SETBIT(debugMcRec, std::abs(flagV0)); } // No physical channel expected in D0 K0s @@ -796,7 +798,7 @@ struct HfDataCreatorCharmResoReduced { registry.fill(HIST("hMCRecOrigin"), origin); registry.fill(HIST("hMCRecMassGen"), invMassGen); } - if (std::abs(flagCharmBach) > 0) { + if (flagCharmBach != 0) { registry.fill(HIST("hMCRecCharmDau"), flagCharmBach); } } @@ -828,8 +830,8 @@ struct HfDataCreatorCharmResoReduced { CCand const& candCharmBach, BBachTr const& bachelorTrack, Tr const& tracks, - int& indexHfCandCharm, - int64_t& indexCandTrBach) + const int64_t indexHfCandCharm, + const int64_t indexCandTrBach) { std::vector vecDaughtersReso{}; int8_t sign{0}, nKinkedTracks{0}, origin{0}, flagCharmBach{0}, flagCharmBachInterm{0}, flagTrack{0}, flagReso{0}; @@ -842,22 +844,22 @@ struct HfDataCreatorCharmResoReduced { vecDaughtersReso.push_back(tracks.rawIteratorAt(candCharmBach.prongPiId())); // Check if D* is matched flagCharmBach = candCharmBach.flagMcMatchRec(); - if (std::abs(flagCharmBach) > 0) { + if (flagCharmBach != 0) { SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DstarMatched); origin = candCharmBach.originMcRec(); } // Check if D0 is matched flagCharmBachInterm = candCharmBach.flagMcMatchRecD0(); - if (std::abs(flagCharmBachInterm) > 0) { + if (flagCharmBachInterm != 0) { SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); } // Check if Track is matched flagTrack = getMatchingFlagTrack(bachelorTrack); - if (std::abs(flagTrack) > 0) { + if (flagTrack != 0) { SETBIT(debugMcRec, flagTrack); } // If both D* and Track are matched, try to match resonance - if (std::abs(flagCharmBach) > 0 && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::PionMatched) { + if (flagCharmBach != 0 && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::PionMatched) { auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], vecDaughtersReso[2], bachelorTrack}; auto pdgCodesDaughters = std::array{+kPiPlus, -kKPlus, +kPiPlus, -kPiPlus}; for (const auto& [decayChannelFlag, pdgCodeReso] : hf_decay::hf_cand_reso::particlesToDstarPi) { @@ -886,13 +888,13 @@ struct HfDataCreatorCharmResoReduced { // Check if D+ is matched flagCharmBach = candCharmBach.flagMcMatchRec(); flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); - if (std::abs(flagCharmBach) > 0) { + if (flagCharmBach != 0) { SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::DplusMatched); origin = candCharmBach.originMcRec(); } // Check if Track is matched flagTrack = getMatchingFlagTrack(bachelorTrack); - if (std::abs(flagTrack) > 0) { + if (flagTrack != 0) { SETBIT(debugMcRec, flagTrack); } // If both D+ and Track are matched, try to match resonance @@ -925,10 +927,14 @@ struct HfDataCreatorCharmResoReduced { // Check if D0 is matched flagCharmBach = candCharmBach.flagMcMatchRec(); flagCharmBachInterm = candCharmBach.flagMcDecayChanRec(); - if (std::abs(flagCharmBach) > 0) { + if (flagCharmBach != 0) { SETBIT(debugMcRec, hf_decay::hf_cand_reso::PartialMatchMc::D0Matched); origin = candCharmBach.originMcRec(); } + flagTrack = getMatchingFlagTrack(bachelorTrack); + if (flagTrack != 0) { + SETBIT(debugMcRec, flagTrack); + } if (hf_decay::hf_cand_2prong::daughtersD0Main.contains(static_cast(std::abs(flagCharmBach))) && flagTrack == hf_decay::hf_cand_reso::PartialMatchMc::PionMatched) { auto arrDaughtersReso = std::array{vecDaughtersReso[0], vecDaughtersReso[1], bachelorTrack}; auto pdgCodesDzeroDaughters = hf_decay::hf_cand_2prong::daughtersD0Main.at(static_cast(std::abs(flagCharmBach))); @@ -969,7 +975,7 @@ struct HfDataCreatorCharmResoReduced { registry.fill(HIST("hMCRecOrigin"), origin); registry.fill(HIST("hMCRecMassGen"), invMassGen); } - if (std::abs(flagCharmBach) > 0) { + if (flagCharmBach != 0) { registry.fill(HIST("hMCRecCharmDau"), flagCharmBach); } } // fillMcRecoInfoDTrack @@ -986,7 +992,7 @@ struct HfDataCreatorCharmResoReduced { { // helpers for ReducedTables filling float centrality = -1.f; - uint16_t hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); if (rejectCollisionsWithBadEvSel && hfRejMap != 0) { return; } @@ -1436,7 +1442,8 @@ struct HfDataCreatorCharmResoReduced { } // end of DType switch // fill track table if (!selectedTracks.count(track.globalIndex())) { - hfTrackNoParam(indexHfReducedCollision, + hfTrackNoParam(track.globalIndex(), + indexHfReducedCollision, track.px(), track.py(), track.pz(), track.sign(), track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr(), track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr(), @@ -1539,7 +1546,7 @@ struct HfDataCreatorCharmResoReduced { const auto mcParticlesPerMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, mcCollision.globalIndex()); // Slice the collisions table to get the collision info for the current MC collision float centrality{-1.f}; - uint16_t rejectionMask{0}; + o2::hf_evsel::HfCollisionRejectionMask rejectionMask{}; int nSplitColl = 0; const auto collSlice = collInfos.sliceBy(colPerMcCollision, mcCollision.globalIndex()); rejectionMask = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, collSlice, centrality); diff --git a/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx b/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx index cf6785d286c..41ee2790334 100644 --- a/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx +++ b/PWGHF/D2H/TableProducer/dataCreatorJpsiHadReduced.cxx @@ -511,10 +511,10 @@ struct HfDataCreatorJpsiHadReduced { /// \param indexHfCandJpsi is the index of the Jpsi candidate /// \param selectedTracksBach is the map with the indices of selected bachelor pion tracks template - void fillMcRecoInfo(const CColl& collision, - const PParticles& particlesMc, - const std::vector& vecDaughtersB, - int& indexHfCandJpsi, + void fillMcRecoInfo(CColl const& collision, + PParticles const& particlesMc, + std::vector const& vecDaughtersB, + const int64_t indexHfCandJpsi, std::array, 2> selectedTracksBach, const int64_t indexCollisionMaxNumContrib) { @@ -728,13 +728,13 @@ struct HfDataCreatorJpsiHadReduced { registry.fill(HIST("hEvents"), 1 + Event::Processed); float centrality = -1.f; - auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + const auto hfRejMap = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); if (skipRejectedCollisions && hfRejMap != 0) { return; } // helpers for ReducedTables filling - int indexHfReducedCollision = hfReducedCollision.lastIndex() + 1; + int const indexHfReducedCollision = hfReducedCollision.lastIndex() + 1; // std::map where the key is the track.globalIndex() and // the value is the track index in the table of the selected tracks std::map selectedTracksBach; @@ -797,8 +797,8 @@ struct HfDataCreatorJpsiHadReduced { // --------------------------------- // reconstruct J/Psi candidate secondary vertex - o2::track::TrackParCov trackParCovJpsi{}; - std::array pVecJpsi{}; + o2::track::TrackParCov trackParCovJpsi{}; // FIXME: unused + std::array pVecJpsi{}; // FIXME: unused registry.fill(HIST("hFitCandidatesJpsi"), SVFitting::BeforeFit); try { if (df2.process(trackPosParCov, trackNegParCov) == 0) { @@ -823,8 +823,8 @@ struct HfDataCreatorJpsiHadReduced { } registry.fill(HIST("hSelectionsJpsi"), 2 + aod::SelectionStep::RecoPID, candidate.pt()); - int indexHfCandJpsi = hfJpsi.lastIndex() + 1; - float invMassJpsi = runJpsiToee ? hfHelper.invMassJpsiToEE(candidate) : hfHelper.invMassJpsiToMuMu(candidate); + int const indexHfCandJpsi = hfJpsi.lastIndex() + 1; + float const invMassJpsi = runJpsiToee ? hfHelper.invMassJpsiToEE(candidate) : hfHelper.invMassJpsiToMuMu(candidate); registry.fill(HIST("hMassJpsi"), invMassJpsi); registry.fill(HIST("hPtJpsi"), candidate.pt()); registry.fill(HIST("hCpaJpsi"), candidate.cpa()); @@ -1189,7 +1189,7 @@ struct HfDataCreatorJpsiHadReduced { auto candsJpsiThisColl = candsJpsi.sliceBy(candsJpsiPerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); auto collsSameMcCollision = collisions.sliceBy(colPerMcCollision, collision.mcCollisionId()); - int64_t indexCollisionMaxNumContrib = getIndexCollisionMaxNumContrib(collsSameMcCollision); + int64_t const indexCollisionMaxNumContrib = getIndexCollisionMaxNumContrib(collsSameMcCollision); runDataCreation(collision, candsJpsiThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs); } // handle normalization by the right number of collisions @@ -1226,7 +1226,7 @@ struct HfDataCreatorJpsiHadReduced { auto candsJpsiThisColl = candsJpsi.sliceBy(candsJpsiPerCollision, thisCollId); auto trackIdsThisCollision = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); auto collsSameMcCollision = collisions.sliceBy(colPerMcCollision, collision.mcCollisionId()); - int64_t indexCollisionMaxNumContrib = getIndexCollisionMaxNumContrib(collsSameMcCollision); + int64_t const indexCollisionMaxNumContrib = getIndexCollisionMaxNumContrib(collsSameMcCollision); runDataCreation(collision, candsJpsiThisColl, trackIdsThisCollision, tracks, particlesMc, indexCollisionMaxNumContrib, bcs); } // handle normalization by the right number of collisions diff --git a/PWGHF/D2H/Tasks/taskB0Reduced.cxx b/PWGHF/D2H/Tasks/taskB0Reduced.cxx index e1e30490f18..169e4fcd834 100644 --- a/PWGHF/D2H/Tasks/taskB0Reduced.cxx +++ b/PWGHF/D2H/Tasks/taskB0Reduced.cxx @@ -40,6 +40,7 @@ #include #include #include +#include using namespace o2; using namespace o2::aod; @@ -191,8 +192,10 @@ struct HfTaskB0Reduced { HfHelper hfHelper; - using TracksPion = soa::Join; + using TracksBachPions = soa::Join; using CandsDplus = soa::Join; + using CandsDstar = soa::Join; + using TracksSoftPions = soa::Join; Filter filterSelectCandidates = (aod::hf_sel_candidate_b0::isSelB0ToDPi >= selectionFlagB0); @@ -200,11 +203,13 @@ struct HfTaskB0Reduced { void init(InitContext&) { - std::array processFuncData{doprocessData, doprocessDataWithDmesMl, doprocessDataWithB0Ml}; + std::array processFuncData{doprocessDataDplusPi, doprocessDataDplusPiWithDmesMl, doprocessDataDplusPiWithB0Ml, + doprocessDataDstarPi, doprocessDataDstarPiWithDmesMl}; if ((std::accumulate(processFuncData.begin(), processFuncData.end(), 0)) > 1) { LOGP(fatal, "Only one process function for data can be enabled at a time."); } - std::array processFuncMc{doprocessMc, doprocessMcWithDecayTypeCheck, doprocessMcWithDmesMl, doprocessMcWithDmesMlAndDecayTypeCheck, doprocessMcWithB0Ml, doprocessMcWithB0MlAndDecayTypeCheck}; + std::array processFuncMc{doprocessMcDplusPi, doprocessMcDplusPiWithDecayTypeCheck, doprocessMcDplusPiWithDmesMl, doprocessMcDplusPiWithDmesMlAndDecayTypeCheck, doprocessMcDplusPiWithB0Ml, doprocessMcDplusPiWithB0MlAndDecayTypeCheck, + doprocessMcDstarPi, doprocessMcDstarPiWithDmesMl}; if ((std::accumulate(processFuncMc.begin(), processFuncMc.end(), 0)) > 1) { LOGP(fatal, "Only one process function for MC can be enabled at a time."); } @@ -212,6 +217,7 @@ struct HfTaskB0Reduced { const AxisSpec axisMlScore{100, 0.f, 1.f}; const AxisSpec axisMassB0{300, 4.5f, 6.0f}; const AxisSpec axisMassDminus{300, 1.75f, 2.05f}; + const AxisSpec axisMassDeltaMassDStar{300, 0.05f, 0.3f}; const AxisSpec axisDecayLength{200, 0.f, 0.4f}; const AxisSpec axisNormDecayLength{100, 0.f, 50.f}; const AxisSpec axisDca{100, -0.05f, 0.05f}; @@ -219,63 +225,94 @@ struct HfTaskB0Reduced { const AxisSpec axisEta{30, -1.5f, 1.5f}; const AxisSpec axisError{100, 0.f, 1.f}; const AxisSpec axisImpParProd{100, -1.e-3, 1.e-3}; + const AxisSpec axisImpParProngSqSum{100, 0, 1.e-3}; const AxisSpec axisPtB0{100, 0.f, 50.f}; const AxisSpec axisPtDminus{100, 0.f, 50.f}; const AxisSpec axisPtPi{100, 0.f, 10.f}; + const AxisSpec axisPtSoftPi{100, 0.f, 1.f}; - if (doprocessData || doprocessDataWithDmesMl || doprocessDataWithB0Ml) { + std::array processFuncDplusPi = {doprocessDataDplusPi, doprocessDataDplusPiWithDmesMl, doprocessDataDplusPiWithB0Ml, + doprocessMcDplusPi, doprocessMcDplusPiWithDecayTypeCheck, doprocessMcDplusPiWithDmesMl, + doprocessMcDplusPiWithDmesMlAndDecayTypeCheck, doprocessMcDplusPiWithB0Ml, + doprocessMcDplusPiWithB0MlAndDecayTypeCheck}; + const AxisSpec axisMass = ((std::accumulate(processFuncDplusPi.begin(), processFuncDplusPi.end(), 0)) > 0) ? axisMassDminus : axisMassDeltaMassDStar; + std::string dMesSpecie{""}; + if ((std::accumulate(processFuncDplusPi.begin(), processFuncDplusPi.end(), 0)) > 0) { + dMesSpecie += "D^{#minus}"; + } else { + dMesSpecie += "D^{0}#pi^{#minus}"; + } + + if (doprocessDataDplusPi || doprocessDataDplusPiWithDmesMl || doprocessDataDplusPiWithB0Ml || doprocessDataDstarPi || doprocessDataDstarPiWithDmesMl) { if (fillHistograms) { registry.add("hMass", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});#it{M} (D#pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPtB0, axisMassB0}}); registry.add("hDecLength", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);entries", {HistType::kTH2F, {axisPtB0, axisDecayLength}}); registry.add("hDecLengthXy", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});decay length XY (cm);entries", {HistType::kTH2F, {axisPtB0, axisDecayLength}}); registry.add("hNormDecLengthXy", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate norm. decay length XY (cm);entries", {HistType::kTH2F, {axisPtB0, axisNormDecayLength}}); - registry.add("hDcaProng0", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});prong 0 (D^{#minus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {axisPtB0, axisDca}}); + registry.add("hDcaProng0", Form("B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});prong 0 (%s) DCAxy to prim. vertex (cm);entries", dMesSpecie.c_str()), {HistType::kTH2F, {axisPtB0, axisDca}}); registry.add("hDcaProng1", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});prong 1 (#pi^{#plus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {axisPtB0, axisDca}}); - registry.add("hPtProng0", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(D^{#minus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtDminus}}); - registry.add("hPtProng1", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(#pi^{#plus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtPi}}); registry.add("hCosp", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate cos(#vartheta_{P});entries", {HistType::kTH2F, {axisPtB0, axisCosp}}); registry.add("hCospXy", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate cos(#vartheta_{P}^{XY});entries", {HistType::kTH2F, {axisPtB0, axisCosp}}); registry.add("hEta", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate #it{#eta};entries", {HistType::kTH2F, {axisPtB0, axisEta}}); registry.add("hRapidity", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate #it{y};entries", {HistType::kTH2F, {axisPtB0, axisEta}}); - registry.add("hImpParProd", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate impact parameter product;entries", {HistType::kTH2F, {axisPtB0, axisImpParProd}}); - registry.add("hInvMassD", "B^{0} candidates;#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, #it{M}(K#pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPtDminus, axisMassDminus}}); - registry.add("hDecLengthD", "B^{0} candidates;#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate decay length (cm);entries", {HistType::kTH2F, {axisPtDminus, axisDecayLength}}); - registry.add("hDecLengthXyD", "B^{0} candidates;#it{p}_{T}(D^{#minus}) (GeV/#it{c});decay length XY (cm);entries", {HistType::kTH2F, {axisPtDminus, axisDecayLength}}); - registry.add("hCospD", "B^{0} candidates;#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate cos(#vartheta_{P});entries", {HistType::kTH2F, {axisPtDminus, axisCosp}}); - registry.add("hCospXyD", "B^{0} candidates;#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate cos(#vartheta_{P}^{XY});entries", {HistType::kTH2F, {axisPtDminus, axisCosp}}); + registry.add("hInvMassD", Form("B^{0} candidates;#it{p}_{T}(%s) (GeV/#it{c});prong0, #it{M}(K#pi) (GeV/#it{c}^{2});entries", dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisMass}}); + registry.add("hDecLengthD", Form("B^{0} candidates;#it{p}_{T}(%s) (GeV/#it{c});%s candidate decay length (cm);entries", dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisDecayLength}}); + registry.add("hDecLengthXyD", Form("B^{0} candidates;#it{p}_{T}(%s) (GeV/#it{c});decay length XY (cm);entries", dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisDecayLength}}); + registry.add("hCospD", Form("B^{0} candidates;#it{p}_{T}(%s) (GeV/#it{c});%s candidate cos(#vartheta_{P});entries", dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisCosp}}); + registry.add("hCospXyD", Form("B^{0} candidates;#it{p}_{T}(%s) (GeV/#it{c});%s candidate cos(#vartheta_{P}^{XY});entries", dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisCosp}}); + if ((std::accumulate(processFuncDplusPi.begin(), processFuncDplusPi.end(), 0)) > 0) { + registry.add("hImpParProd", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate impact parameter product;entries", {HistType::kTH2F, {axisPtB0, axisImpParProd}}); + registry.add("hPtProng0", Form("B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(%s) (GeV/#it{c});entries", dMesSpecie.c_str()), {HistType::kTH2F, {axisPtB0, axisPtDminus}}); + registry.add("hPtProng1", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(#pi^{#plus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtPi}}); + } else { + registry.add("hImpParProngSqSum", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate impact parameter sum;entries", {HistType::kTH2F, {axisPtB0, axisImpParProngSqSum}}); + registry.add("hPtProngD0", Form("B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(%s) (GeV/#it{c});entries", dMesSpecie.c_str()), {HistType::kTH2F, {axisPtB0, axisPtDminus}}); + registry.add("hPtProngSoftPi", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(#pi^{#plus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtSoftPi}}); + registry.add("hPtProngBachPi", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(#pi^{#plus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtPi}}); + registry.add("hDcaProng2", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});prong 2 (#pi^{#plus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {axisPtB0, axisDca}}); + } // ML scores of D- daughter - if (doprocessDataWithDmesMl) { - registry.add("hMlScoreBkgD", "B^{0} candidates;#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, D^{#minus} ML background score;entries", {HistType::kTH2F, {axisPtDminus, axisMlScore}}); - registry.add("hMlScorePromptD", "B^{0} candidates;#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, D^{#minus} ML prompt score;entries", {HistType::kTH2F, {axisPtDminus, axisMlScore}}); - registry.add("hMlScoreNonPromptD", "B^{0} candidates;#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, D^{#minus} ML nonprompt score;entries", {HistType::kTH2F, {axisPtDminus, axisMlScore}}); + if (doprocessDataDplusPiWithDmesMl || doprocessDataDstarPiWithDmesMl) { + registry.add("hMlScoreBkgD", Form("B^{0} candidates;#it{p}_{T}(%s) (GeV/#it{c});prong0, %s ML background score;entries", dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisMlScore}}); + registry.add("hMlScorePromptD", Form("B^{0} candidates;#it{p}_{T}(%s) (GeV/#it{c});prong0, %s ML prompt score;entries", dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisMlScore}}); + registry.add("hMlScoreNonPromptD", Form("B^{0} candidates;#it{p}_{T}(%s) (GeV/#it{c});prong0, %s ML nonprompt score;entries", dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisMlScore}}); } // ML scores of B0 candidate - if (doprocessDataWithB0Ml) { + if (doprocessDataDplusPiWithB0Ml) { registry.add("hMlScoreSigB0", "B^{0} candidates;#it{p}_{T}(B^{0}) (GeV/#it{c});prong0, B^{0} ML signal score;entries", {HistType::kTH2F, {axisPtB0, axisMlScore}}); } } if (fillSparses) { - if (!(doprocessDataWithDmesMl || doprocessDataWithB0Ml)) { - registry.add("hMassPtCutVars", "B^{0} candidates;#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate decay length (cm);D^{#minus} candidate cos(#vartheta_{P})", {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProd, axisCosp, axisMassDminus, axisPtDminus, axisDecayLength, axisCosp}}); + if (!(doprocessDataDplusPiWithDmesMl || doprocessDataDplusPiWithB0Ml || doprocessDataDstarPiWithDmesMl)) { + if ((std::accumulate(processFuncDplusPi.begin(), processFuncDplusPi.end(), 0)) > 0) { + registry.add("hMassPtCutVars", "B^{0} candidates;#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(%s) (GeV/#it{c});%s candidate decay length (cm);%s candidate cos(#vartheta_{P})", {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProd, axisCosp, axisMass, axisPtDminus, axisDecayLength, axisCosp}}); + } else { + registry.add("hMassPtCutVars", "B^{0} candidates;#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(%s) (GeV/#it{c});%s candidate decay length (cm);%s candidate cos(#vartheta_{P})", {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProngSqSum, axisCosp, axisMass, axisPtDminus, axisDecayLength, axisCosp}}); + } } else { - registry.add("hMassPtCutVars", "B^{0} candidates;#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate ML score bkg;D^{#minus} candidate ML score nonprompt", {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProd, axisCosp, axisMassDminus, axisPtDminus, axisMlScore, axisMlScore}}); + if ((std::accumulate(processFuncDplusPi.begin(), processFuncDplusPi.end(), 0)) > 0) { + registry.add("hMassPtCutVars", "B^{0} candidates;#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(%s) (GeV/#it{c});%s candidate ML score bkg;%s candidate ML score nonprompt", {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProd, axisCosp, axisMass, axisPtDminus, axisMlScore, axisMlScore}}); + } else { + registry.add("hMassPtCutVars", "B^{0} candidates;#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(%s) (GeV/#it{c});%s candidate ML score bkg;%s candidate ML score nonprompt", {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProngSqSum, axisCosp, axisMass, axisPtDminus, axisMlScore, axisMlScore}}); + } } } } - if (doprocessMc || doprocessMcWithDecayTypeCheck || doprocessMcWithDmesMl || doprocessMcWithDmesMlAndDecayTypeCheck || doprocessMcWithB0Ml || doprocessMcWithB0MlAndDecayTypeCheck) { + if (doprocessMcDplusPi || doprocessMcDplusPiWithDecayTypeCheck || doprocessMcDplusPiWithDmesMl || doprocessMcDplusPiWithDmesMlAndDecayTypeCheck || doprocessMcDplusPiWithB0Ml || doprocessMcDplusPiWithB0MlAndDecayTypeCheck || + doprocessMcDstarPi || doprocessMcDstarPiWithDmesMl) { if (fillHistograms) { // gen histos registry.add("hEtaGen", "B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{#eta}^{gen}(B^{0});entries", {HistType::kTH2F, {axisPtB0, axisEta}}); registry.add("hYGen", "B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{y}^{gen}(B^{0});entries", {HistType::kTH2F, {axisPtB0, axisEta}}); registry.add("hYGenWithProngsInAcceptance", "MC particles (generated-daughters in acceptance);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{y}^{gen}(B^{0});entries", {HistType::kTH2F, {axisPtB0, axisEta}}); - registry.add("hPtProng0Gen", "B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{p}_{T}^{gen}(D^{#minus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtDminus}}); + registry.add("hPtProng0Gen", Form("B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{p}_{T}^{gen}(%s) (GeV/#it{c});entries", dMesSpecie.c_str()), {HistType::kTH2F, {axisPtB0, axisPtDminus}}); registry.add("hPtProng1Gen", "B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{p}_{T}^{gen}(#pi^{#plus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtPi}}); - registry.add("hYProng0Gen", "B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{y}^{gen}(D^{#minus});entries", {HistType::kTH2F, {axisPtB0, axisEta}}); + registry.add("hYProng0Gen", Form("B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{y}^{gen}(%s);entries", dMesSpecie.c_str()), {HistType::kTH2F, {axisPtB0, axisEta}}); registry.add("hYProng1Gen", "B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{y}^{gen}(#pi^{#plus});entries", {HistType::kTH2F, {axisPtB0, axisEta}}); - registry.add("hEtaProng0Gen", "B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{#eta}^{gen}(D^{#minus});entries", {HistType::kTH2F, {axisPtB0, axisEta}}); + registry.add("hEtaProng0Gen", Form("B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{#eta}^{gen}(%s);entries", dMesSpecie.c_str()), {HistType::kTH2F, {axisPtB0, axisEta}}); registry.add("hEtaProng1Gen", "B^{0} particles (generated);#it{p}_{T}^{gen}(B^{0}) (GeV/#it{c});#it{#eta}^{gen}(#pi^{#plus});entries", {HistType::kTH2F, {axisPtB0, axisEta}}); // reco histos @@ -284,49 +321,68 @@ struct HfTaskB0Reduced { registry.add("hDecLengthRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);entries", {HistType::kTH2F, {axisPtB0, axisDecayLength}}); registry.add("hDecLengthXyRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});decay length XY (cm);entries", {HistType::kTH2F, {axisPtB0, axisDecayLength}}); registry.add("hNormDecLengthXyRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate norm. decay length XY (cm);entries", {HistType::kTH2F, {axisPtB0, axisNormDecayLength}}); - registry.add("hDcaProng0RecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});prong 0 (D^{#minus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {axisPtB0, axisDca}}); + registry.add("hDcaProng0RecSig", Form("B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});prong 0 (%s) DCAxy to prim. vertex (cm);entries", dMesSpecie.c_str()), {HistType::kTH2F, {axisPtB0, axisDca}}); registry.add("hDcaProng1RecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});prong 1 (#pi^{#plus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {axisPtB0, axisDca}}); - registry.add("hPtProng0RecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(D^{#minus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtDminus}}); - registry.add("hPtProng1RecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(#pi^{#plus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtPi}}); registry.add("hCospRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate cos(#vartheta_{P});entries", {HistType::kTH2F, {axisPtB0, axisCosp}}); registry.add("hCospXyRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate cos(#vartheta_{P}^{XY});entries", {HistType::kTH2F, {axisPtB0, axisCosp}}); registry.add("hEtaRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate #it{#eta};entries", {HistType::kTH2F, {axisPtB0, axisEta}}); registry.add("hRapidityRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate #it{y};entries", {HistType::kTH2F, {axisPtB0, axisEta}}); - registry.add("hImpParProdRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate impact parameter product;entries", {HistType::kTH2F, {axisPtB0, axisImpParProd}}); - registry.add("hInvMassDRecSig", "B^{0} candidates (matched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, #it{M}(K#pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPtDminus, axisMassDminus}}); - registry.add("hDecLengthDRecSig", "B^{0} candidates (matched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate decay length (cm);entries", {HistType::kTH2F, {axisPtDminus, axisDecayLength}}); - registry.add("hDecLengthXyDRecSig", "B^{0} candidates (matched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});decay length XY (cm);entries", {HistType::kTH2F, {axisPtDminus, axisDecayLength}}); - registry.add("hCospDRecSig", "B^{0} candidates (matched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate cos(#vartheta_{P});entries", {HistType::kTH2F, {axisPtDminus, axisCosp}}); - registry.add("hCospXyDRecSig", "B^{0} candidates (matched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate cos(#vartheta_{P}^{XY});entries", {HistType::kTH2F, {axisPtDminus, axisCosp}}); + registry.add("hInvMassDRecSig", Form("B^{0} candidates (matched);#it{p}_{T}(%s) (GeV/#it{c});prong0, #it{M}(K#pi) (GeV/#it{c}^{2});entries", dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisMass}}); + registry.add("hDecLengthDRecSig", Form("B^{0} candidates (matched);#it{p}_{T}(%s) (GeV/#it{c});%s candidate decay length (cm);entries", dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisDecayLength}}); + registry.add("hDecLengthXyDRecSig", Form("B^{0} candidates (matched);#it{p}_{T}(%s) (GeV/#it{c});decay length XY (cm);entries", dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisDecayLength}}); + registry.add("hCospDRecSig", Form("B^{0} candidates (matched);#it{p}_{T}(%s) (GeV/#it{c});%s candidate cos(#vartheta_{P});entries", dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisCosp}}); + registry.add("hCospXyDRecSig", Form("B^{0} candidates (matched);#it{p}_{T}(%s) (GeV/#it{c});%s candidate cos(#vartheta_{P}^{XY});entries", dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisCosp}}); + + if ((std::accumulate(processFuncDplusPi.begin(), processFuncDplusPi.end(), 0)) > 0) { + registry.add("hPtProng0RecSig", Form("B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(%s) (GeV/#it{c});entries", dMesSpecie.c_str()), {HistType::kTH2F, {axisPtB0, axisPtDminus}}); + registry.add("hPtProng1RecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(#pi^{#plus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtPi}}); + registry.add("hImpParProdRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate impact parameter product;entries", {HistType::kTH2F, {axisPtB0, axisImpParProd}}); + } else { + registry.add("hPtProngD0RecSig", Form("B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(%s) (GeV/#it{c});entries", dMesSpecie.c_str()), {HistType::kTH2F, {axisPtB0, axisPtDminus}}); + registry.add("hPtProngSoftPiRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(#pi^{#plus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtSoftPi}}); + registry.add("hPtProngBachPiRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(#pi^{#plus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtPi}}); + registry.add("hDcaProng2RecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});prong 2 (#pi^{#minus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {axisPtB0, axisDca}}); + registry.add("hImpParProngSqSumRecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate impact parameter product;entries", {HistType::kTH2F, {axisPtB0, axisImpParProngSqSum}}); + } + // background if (fillBackground) { registry.add("hMassRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{M} (D#pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPtB0, axisMassB0}}); registry.add("hDecLengthRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);entries", {HistType::kTH2F, {axisPtB0, axisDecayLength}}); registry.add("hDecLengthXyRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});decay length XY (cm);entries", {HistType::kTH2F, {axisPtB0, axisDecayLength}}); registry.add("hNormDecLengthXyRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate norm. decay length XY (cm);entries", {HistType::kTH2F, {axisPtB0, axisNormDecayLength}}); - registry.add("hDcaProng0RecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});prong 0 (D^{#minus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {axisPtB0, axisDca}}); + registry.add("hDcaProng0RecBg", Form("B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});prong 0 (%s) DCAxy to prim. vertex (cm);entries", dMesSpecie.c_str()), {HistType::kTH2F, {axisPtB0, axisDca}}); registry.add("hDcaProng1RecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});prong 1 (#pi^{#plus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {axisPtB0, axisDca}}); - registry.add("hPtProng0RecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(D^{#minus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtDminus}}); - registry.add("hPtProng1RecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(#pi^{#plus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtPi}}); registry.add("hCospRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate cos(#vartheta_{P});entries", {HistType::kTH2F, {axisPtB0, axisCosp}}); registry.add("hCospXyRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate cos(#vartheta_{P}^{XY});entries", {HistType::kTH2F, {axisPtB0, axisCosp}}); registry.add("hEtaRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate #it{#eta};entries", {HistType::kTH2F, {axisPtB0, axisEta}}); registry.add("hRapidityRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate #it{y};entries", {HistType::kTH2F, {axisPtB0, axisEta}}); - registry.add("hImpParProdRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate impact parameter product;entries", {HistType::kTH2F, {axisPtB0, axisImpParProd}}); - registry.add("hInvMassDRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, #it{M}(K#pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisPtDminus, axisMassDminus}}); - registry.add("hDecLengthDRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate decay length (cm);entries", {HistType::kTH2F, {axisPtDminus, axisDecayLength}}); - registry.add("hDecLengthXyDRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});decay length XY (cm);entries", {HistType::kTH2F, {axisPtDminus, axisDecayLength}}); - registry.add("hCospDRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate cos(#vartheta_{P});entries", {HistType::kTH2F, {axisPtDminus, axisCosp}}); - registry.add("hCospXyDRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate cos(#vartheta_{P}^{XY});entries", {HistType::kTH2F, {axisPtDminus, axisCosp}}); + registry.add("hInvMassDRecBg", Form("B^{0} candidates (unmatched);#it{p}_{T}(%s) (GeV/#it{c});prong0, #it{M}(K#pi) (GeV/#it{c}^{2});entries", dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisMass}}); + registry.add("hDecLengthDRecBg", Form("B^{0} candidates (unmatched);#it{p}_{T}(%s) (GeV/#it{c});%s candidate decay length (cm);entries", dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisDecayLength}}); + registry.add("hDecLengthXyDRecBg", Form("B^{0} candidates (unmatched);#it{p}_{T}(%s) (GeV/#it{c});decay length XY (cm);entries", dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisDecayLength}}); + registry.add("hCospDRecBg", Form("B^{0} candidates (unmatched);#it{p}_{T}(%s) (GeV/#it{c});%s candidate cos(#vartheta_{P});entries", dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisCosp}}); + registry.add("hCospXyDRecBg", Form("B^{0} candidates (unmatched);#it{p}_{T}(%s) (GeV/#it{c});%s candidate cos(#vartheta_{P}^{XY});entries", dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisCosp}}); + + if ((std::accumulate(processFuncDplusPi.begin(), processFuncDplusPi.end(), 0)) > 0) { + registry.add("hPtProng0RecBg", Form("B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(%s) (GeV/#it{c});entries", dMesSpecie.c_str()), {HistType::kTH2F, {axisPtB0, axisPtDminus}}); + registry.add("hPtProng1RecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(#pi^{#plus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtPi}}); + registry.add("hImpParProdRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate impact parameter product;entries", {HistType::kTH2F, {axisPtB0, axisImpParProd}}); + } else { + registry.add("hPtProngD0RecBg", Form("B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(%s) (GeV/#it{c});entries", dMesSpecie.c_str()), {HistType::kTH2F, {axisPtB0, axisPtDminus}}); + registry.add("hPtProngSoftPiRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(#pi^{#plus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtSoftPi}}); + registry.add("hPtProngBachPiRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{p}_{T}(#pi^{#plus}) (GeV/#it{c});entries", {HistType::kTH2F, {axisPtB0, axisPtPi}}); + registry.add("hImpParProngSqSumRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate impact parameter product;entries", {HistType::kTH2F, {axisPtB0, axisImpParProngSqSum}}); + registry.add("hDcaProng2RecBg", "B^{0} candidates (unmatched);#it{p}_{T}(B^{0}) (GeV/#it{c});prong 2 (#pi^{#plus}) DCAxy to prim. vertex (cm);entries", {HistType::kTH2F, {axisPtB0, axisDca}}); + } } // MC checks - if (doprocessMcWithDecayTypeCheck || doprocessMcWithB0MlAndDecayTypeCheck || doprocessMcWithDmesMlAndDecayTypeCheck) { + if (doprocessMcDplusPiWithDecayTypeCheck || doprocessMcDplusPiWithB0MlAndDecayTypeCheck || doprocessMcDplusPiWithDmesMlAndDecayTypeCheck) { constexpr uint8_t kNBinsDecayTypeMc = hf_cand_b0::DecayTypeMc::NDecayTypeMc; TString labels[kNBinsDecayTypeMc]; - labels[hf_cand_b0::DecayTypeMc::B0ToDplusPiToPiKPiPi] = "B^{0} #rightarrow (D^{#minus} #rightarrow #pi^{#minus} K^{#plus} #pi^{#minus}) #pi^{#plus}"; - labels[hf_cand_b0::DecayTypeMc::B0ToDsPiToKKPiPi] = "B^{0} #rightarrow (D^{#minus}_{s} #rightarrow K^{#minus} K^{#plus} #pi^{#minus}) #pi^{#plus}"; - labels[hf_cand_b0::DecayTypeMc::BsToDsPiToKKPiPi] = "B_{s}^{0} #rightarrow (D^{#minus}_{s} #rightarrow K^{#minus} K^{#plus} #pi^{#minus}) #pi^{#plus}"; - labels[hf_cand_b0::DecayTypeMc::B0ToDplusKToPiKPiK] = "B^{0} #rightarrow (D^{#minus} #rightarrow #pi^{#minus} K^{#plus} #pi^{#minus}) K^{#plus}"; + labels[hf_cand_b0::DecayTypeMc::B0ToDplusPiToPiKPiPi] = Form("B^{0} #rightarrow (%s #rightarrow #pi^{#minus} K^{#plus} #pi^{#minus}) #pi^{#plus}", dMesSpecie.c_str()); + labels[hf_cand_b0::DecayTypeMc::B0ToDsPiToKKPiPi] = Form("B^{0} #rightarrow (%s_{s} #rightarrow K^{#minus} K^{#plus} #pi^{#minus}) #pi^{#plus}", dMesSpecie.c_str()); + labels[hf_cand_b0::DecayTypeMc::BsToDsPiToKKPiPi] = Form("B_{s}^{0} #rightarrow (%s_{s} #rightarrow K^{#minus} K^{#plus} #pi^{#minus}) #pi^{#plus}", dMesSpecie.c_str()); + labels[hf_cand_b0::DecayTypeMc::B0ToDplusKToPiKPiK] = Form("B^{0} #rightarrow (%s #rightarrow #pi^{#minus} K^{#plus} #pi^{#minus}) K^{#plus}", dMesSpecie.c_str()); labels[hf_cand_b0::DecayTypeMc::PartlyRecoDecay] = "Partly reconstructed decay channel"; labels[hf_cand_b0::DecayTypeMc::OtherDecay] = "Other decays"; static const AxisSpec axisDecayType = {kNBinsDecayTypeMc, 0.5, kNBinsDecayTypeMc + 0.5, ""}; @@ -336,18 +392,18 @@ struct HfTaskB0Reduced { } } // ML scores of D- daughter - if (doprocessMcWithDmesMl || doprocessMcWithDmesMlAndDecayTypeCheck) { + if (doprocessMcDplusPiWithDmesMl || doprocessMcDplusPiWithDmesMlAndDecayTypeCheck || doprocessMcDstarPiWithDmesMl) { // signal - registry.add("hMlScoreBkgDRecSig", "B^{0} candidates (matched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, D^{#minus} ML background score;entries", {HistType::kTH2F, {axisPtDminus, axisMlScore}}); - registry.add("hMlScorePromptDRecSig", "B^{0} candidates (matched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, D^{#minus} ML prompt score;entries", {HistType::kTH2F, {axisPtDminus, axisMlScore}}); - registry.add("hMlScoreNonPromptDRecSig", "B^{0} candidates (matched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, D^{#minus} ML nonprompt score;entries", {HistType::kTH2F, {axisPtDminus, axisMlScore}}); + registry.add("hMlScoreBkgDRecSig", Form("B^{0} candidates (matched);#it{p}_{T}(%s) (GeV/#it{c});prong0, %s ML background score;entries", dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisMlScore}}); + registry.add("hMlScorePromptDRecSig", Form("B^{0} candidates (matched);#it{p}_{T}(%s) (GeV/#it{c});prong0, %s ML prompt score;entries", dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisMlScore}}); + registry.add("hMlScoreNonPromptDRecSig", Form("B^{0} candidates (matched);#it{p}_{T}(%s) (GeV/#it{c});prong0, %s ML nonprompt score;entries", dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisMlScore}}); // background - registry.add("hMlScoreBkgDRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, D^{#minus} ML background score;entries", {HistType::kTH2F, {axisPtDminus, axisMlScore}}); - registry.add("hMlScorePromptDRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, D^{#minus} ML prompt score;entries", {HistType::kTH2F, {axisPtDminus, axisMlScore}}); - registry.add("hMlScoreNonPromptDRecBg", "B^{0} candidates (unmatched);#it{p}_{T}(D^{#minus}) (GeV/#it{c});prong0, D^{#minus} ML nonprompt score;entries", {HistType::kTH2F, {axisPtDminus, axisMlScore}}); + registry.add("hMlScoreBkgDRecBg", Form("B^{0} candidates (unmatched);#it{p}_{T}(%s) (GeV/#it{c});prong0, %s ML background score;entries", dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisMlScore}}); + registry.add("hMlScorePromptDRecBg", Form("B^{0} candidates (unmatched);#it{p}_{T}(%s) (GeV/#it{c});prong0, %s ML prompt score;entries", dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisMlScore}}); + registry.add("hMlScoreNonPromptDRecBg", Form("B^{0} candidates (unmatched);#it{p}_{T}(%s) (GeV/#it{c});prong0, %s ML nonprompt score;entries", dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTH2F, {axisPtDminus, axisMlScore}}); } // ML scores of B0 candidate - if (doprocessMcWithB0Ml || doprocessMcWithB0MlAndDecayTypeCheck) { + if (doprocessMcDplusPiWithB0Ml || doprocessMcDplusPiWithB0MlAndDecayTypeCheck) { // signal registry.add("hMlScoreSigB0RecSig", "B^{0} candidates (matched);#it{p}_{T}(B^{0}) (GeV/#it{c});prong0, B^{0} ML signal score;entries", {HistType::kTH2F, {axisPtB0, axisMlScore}}); // background @@ -360,15 +416,15 @@ struct HfTaskB0Reduced { registry.add("hPtYWithProngsInAccepanceGenSig", "B^{0} particles (generated-daughters in acceptance);#it{p}_{T}(B^{0}) (GeV/#it{c});#it{y}(B^{0})", {HistType::kTHnSparseF, {axisPtB0, axisEta}}); // reco sparses - if (!(doprocessDataWithDmesMl || doprocessDataWithB0Ml)) { - registry.add("hMassPtCutVarsRecSig", "B^{0} candidates (matched);#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate decay length (cm);D^{#minus} candidate cos(#vartheta_{P})", {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProd, axisCosp, axisMassDminus, axisPtDminus, axisDecayLength, axisCosp}}); + if (!(doprocessDataDplusPiWithDmesMl || doprocessDataDplusPiWithB0Ml || doprocessDataDstarPiWithDmesMl)) { + registry.add("hMassPtCutVarsRecSig", Form("B^{0} candidates (matched);#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(%s) (GeV/#it{c});%s candidate decay length (cm);%s candidate cos(#vartheta_{P})", dMesSpecie.c_str(), dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProd, axisCosp, axisMass, axisPtDminus, axisDecayLength, axisCosp}}); if (fillBackground) { - registry.add("hMassPtCutVarsRecBg", "B^{0} candidates (unmatched);#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate decay length (cm);D^{#minus} candidate cos(#vartheta_{P})", {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProd, axisCosp, axisMassDminus, axisPtDminus, axisDecayLength, axisCosp}}); + registry.add("hMassPtCutVarsRecBg", Form("B^{0} candidates (unmatched);#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(%s) (GeV/#it{c});%s candidate decay length (cm);%s candidate cos(#vartheta_{P})", dMesSpecie.c_str(), dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProd, axisCosp, axisMass, axisPtDminus, axisDecayLength, axisCosp}}); } } else { - registry.add("hMassPtCutVarsRecSig", "B^{0} candidates (matched);#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate ML score bkg;D^{#minus} candidate ML score nonprompt", {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProd, axisCosp, axisMassDminus, axisPtDminus, axisMlScore, axisMlScore}}); + registry.add("hMassPtCutVarsRecSig", Form("B^{0} candidates (matched);#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(%s) (GeV/#it{c});%s candidate ML score bkg;%s candidate ML score nonprompt", dMesSpecie.c_str(), dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProd, axisCosp, axisMass, axisPtDminus, axisMlScore, axisMlScore}}); if (fillBackground) { - registry.add("hMassPtCutVarsRecBg", "B^{0} candidates (unmatched);#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(D^{#minus}) (GeV/#it{c});D^{#minus} candidate ML score bkg;D^{#minus} candidate ML score nonprompt", {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProd, axisCosp, axisMassDminus, axisPtDminus, axisMlScore, axisMlScore}}); + registry.add("hMassPtCutVarsRecBg", Form("B^{0} candidates (unmatched);#it{M} (D#pi) (GeV/#it{c}^{2});#it{p}_{T}(B^{0}) (GeV/#it{c});B^{0} candidate decay length (cm);B^{0} candidate norm. decay length XY (cm);B^{0} candidate impact parameter product (cm);B^{0} candidate cos(#vartheta_{P});#it{M} (K#pi) (GeV/#it{c}^{2});#it{p}_{T}(%s) (GeV/#it{c});%s candidate ML score bkg;%s candidate ML score nonprompt", dMesSpecie.c_str(), dMesSpecie.c_str(), dMesSpecie.c_str()), {HistType::kTHnSparseF, {axisMassB0, axisPtB0, axisDecayLength, axisNormDecayLength, axisImpParProd, axisCosp, axisMass, axisPtDminus, axisMlScore, axisMlScore}}); } } } @@ -385,6 +441,244 @@ struct HfTaskB0Reduced { return std::abs(etaProng) <= etaTrackMax && ptProng >= ptTrackMin; } + /// Fill candidate information at reconstruction level + /// \param doMc is the flag to enable the filling with MC information + /// \param withDecayTypeCheck is the flag to enable MC with decay type check + /// \param withDmesMl is the flag to enable the filling with ML scores for the D- daughter + /// \param withB0Ml is the flag to enable the filling with ML scores for the B0 candidate + /// \param candidate is the B0 candidate + /// \param candidatesD is the table with D- candidates + template + void fillCandDStarPi(Cand const& candidate, + SoftPions const& softPions, + CandsDmes const&) + { + auto ptCandB0 = candidate.pt(); + auto invMassB0 = hfHelper.invMassB0ToDPi(candidate); + auto candD = candidate.template prongD0_as(); + auto ptD = candidate.ptProng0(); + auto invMassD = candD.invMassHypo0(); + auto softPi = softPions.rawIteratorAt(candD.globalIndex()); + std::array posPv{candidate.posX(), candidate.posY(), candidate.posZ()}; + std::array posSvD{candD.xSecondaryVertex(), candD.ySecondaryVertex(), candD.zSecondaryVertex()}; + std::array momD{candD.pVector()}; + auto cospD = RecoDecay::cpa(posPv, posSvD, momD); + auto cospXyD = RecoDecay::cpaXY(posPv, posSvD, momD); + auto decLenD = RecoDecay::distance(posPv, posSvD); + auto decLenXyD = RecoDecay::distanceXY(posPv, posSvD); + + int8_t flagMcMatchRec = 0; + int8_t flagWrongCollision = 0; + bool isSignal = false; + if constexpr (doMc) { + flagMcMatchRec = candidate.flagMcMatchRec(); + flagWrongCollision = candidate.flagWrongCollision(); + isSignal = TESTBIT(std::abs(flagMcMatchRec), hf_cand_b0::DecayTypeMc::B0ToDstarPiToD0PiPiToKPiPiPi); + } + + if (fillHistograms) { + if constexpr (doMc) { + if (isSignal) { + registry.fill(HIST("hMassRecSig"), ptCandB0, hfHelper.invMassB0ToDPi(candidate)); + registry.fill(HIST("hPtProngD0RecSig"), ptCandB0, candidate.ptProng0()); + registry.fill(HIST("hPtProngSoftPiRecSig"), ptCandB0, candidate.ptProng1()); + registry.fill(HIST("hPtProngBachPiRecSig"), ptCandB0, candidate.ptProng2()); + registry.fill(HIST("hImpParProngSqSumRecSig"), ptCandB0, candidate.impactParameterProngSqSum()); + registry.fill(HIST("hDecLengthRecSig"), ptCandB0, candidate.decayLength()); + registry.fill(HIST("hDecLengthXyRecSig"), ptCandB0, candidate.decayLengthXY()); + registry.fill(HIST("hNormDecLengthXyRecSig"), ptCandB0, candidate.decayLengthXY() / candidate.errorDecayLengthXY()); + registry.fill(HIST("hDcaProng0RecSig"), ptCandB0, candidate.impactParameter0()); + registry.fill(HIST("hDcaProng1RecSig"), ptCandB0, candidate.impactParameter1()); + registry.fill(HIST("hDcaProng2RecSig"), ptCandB0, candidate.impactParameter2()); + registry.fill(HIST("hCospRecSig"), ptCandB0, candidate.cpa()); + registry.fill(HIST("hCospXyRecSig"), ptCandB0, candidate.cpaXY()); + registry.fill(HIST("hEtaRecSig"), ptCandB0, candidate.eta()); + registry.fill(HIST("hRapidityRecSig"), ptCandB0, hfHelper.yB0(candidate)); + registry.fill(HIST("hInvMassDRecSig"), ptD, invMassD); + registry.fill(HIST("hDecLengthDRecSig"), ptD, decLenD); + registry.fill(HIST("hDecLengthXyDRecSig"), ptD, decLenXyD); + registry.fill(HIST("hCospDRecSig"), ptD, cospD); + registry.fill(HIST("hCospXyDRecSig"), ptD, cospXyD); + if constexpr (withDmesMl) { + registry.fill(HIST("hMlScoreBkgDRecSig"), ptD, candidate.prong0MlScoreBkg()); + registry.fill(HIST("hMlScorePromptDRecSig"), ptD, candidate.prong0MlScorePrompt()); + registry.fill(HIST("hMlScoreNonPromptDRecSig"), ptD, candidate.prong0MlScoreNonprompt()); + } + } else if (fillBackground) { + registry.fill(HIST("hMassRecBg"), ptCandB0, hfHelper.invMassB0ToDPi(candidate)); + registry.fill(HIST("hPtProngD0RecBg"), ptCandB0, candidate.ptProng0()); + registry.fill(HIST("hPtProngSoftPiRecBg"), ptCandB0, candidate.ptProng1()); + registry.fill(HIST("hPtProngBachPiRecBg"), ptCandB0, candidate.ptProng2()); + registry.fill(HIST("hImpParProngSqSumRecBg"), ptCandB0, candidate.impactParameterProngSqSum()); + registry.fill(HIST("hDecLengthRecBg"), ptCandB0, candidate.decayLength()); + registry.fill(HIST("hDecLengthXyRecBg"), ptCandB0, candidate.decayLengthXY()); + registry.fill(HIST("hNormDecLengthXyRecBg"), ptCandB0, candidate.decayLengthXY() / candidate.errorDecayLengthXY()); + registry.fill(HIST("hDcaProng0RecBg"), ptCandB0, candidate.impactParameter0()); + registry.fill(HIST("hDcaProng1RecBg"), ptCandB0, candidate.impactParameter1()); + registry.fill(HIST("hDcaProng2RecBg"), ptCandB0, candidate.impactParameter2()); + registry.fill(HIST("hCospRecBg"), ptCandB0, candidate.cpa()); + registry.fill(HIST("hCospXyRecBg"), ptCandB0, candidate.cpaXY()); + registry.fill(HIST("hEtaRecBg"), ptCandB0, candidate.eta()); + registry.fill(HIST("hRapidityRecBg"), ptCandB0, hfHelper.yB0(candidate)); + registry.fill(HIST("hInvMassDRecBg"), ptD, invMassD); + registry.fill(HIST("hDecLengthDRecBg"), ptD, decLenD); + registry.fill(HIST("hDecLengthXyDRecBg"), ptD, decLenXyD); + registry.fill(HIST("hCospDRecBg"), ptD, cospD); + registry.fill(HIST("hCospXyDRecBg"), ptD, cospXyD); + if constexpr (withDmesMl) { + registry.fill(HIST("hMlScoreBkgDRecBg"), ptD, candidate.prong0MlScoreBkg()); + registry.fill(HIST("hMlScorePromptDRecBg"), ptD, candidate.prong0MlScorePrompt()); + registry.fill(HIST("hMlScoreNonPromptDRecBg"), ptD, candidate.prong0MlScoreNonprompt()); + } + } + } else { + registry.fill(HIST("hMass"), ptCandB0, invMassB0); + registry.fill(HIST("hPtProngD0"), ptCandB0, candidate.ptProng0()); + registry.fill(HIST("hPtProngSoftPi"), ptCandB0, candidate.ptProng1()); + registry.fill(HIST("hPtProngBachPi"), ptCandB0, candidate.ptProng2()); + registry.fill(HIST("hDecLength"), ptCandB0, candidate.decayLength()); + registry.fill(HIST("hDecLengthXy"), ptCandB0, candidate.decayLengthXY()); + registry.fill(HIST("hNormDecLengthXy"), ptCandB0, candidate.decayLengthXY() / candidate.errorDecayLengthXY()); + registry.fill(HIST("hImpParProngSqSum"), ptCandB0, candidate.impactParameterProngSqSum()); + registry.fill(HIST("hDcaProng0"), ptCandB0, candidate.impactParameter0()); + registry.fill(HIST("hDcaProng1"), ptCandB0, candidate.impactParameter1()); + registry.fill(HIST("hDcaProng2"), ptCandB0, candidate.impactParameter2()); + registry.fill(HIST("hCosp"), ptCandB0, candidate.cpa()); + registry.fill(HIST("hCospXy"), ptCandB0, candidate.cpaXY()); + registry.fill(HIST("hEta"), ptCandB0, candidate.eta()); + registry.fill(HIST("hRapidity"), ptCandB0, hfHelper.yB0(candidate)); + registry.fill(HIST("hInvMassD"), ptD, invMassD); + registry.fill(HIST("hDecLengthD"), ptD, decLenD); + registry.fill(HIST("hDecLengthXyD"), ptD, decLenXyD); + registry.fill(HIST("hCospD"), ptD, cospD); + registry.fill(HIST("hCospXyD"), ptD, cospXyD); + + if constexpr (withDmesMl) { + registry.fill(HIST("hMlScoreBkgD"), ptD, candidate.prong0MlScoreBkg()); + registry.fill(HIST("hMlScorePromptD"), ptD, candidate.prong0MlScorePrompt()); + registry.fill(HIST("hMlScoreNonPromptD"), ptD, candidate.prong0MlScoreNonprompt()); + } + } + } + if (fillSparses) { + if constexpr (doMc) { + if (isSignal) { + if constexpr (withDmesMl) { + registry.fill(HIST("hMassPtCutVarsRecSig"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProngSqSum(), candidate.cpa(), invMassD, ptD, candidate.prong0MlScoreBkg(), candidate.prong0MlScoreNonprompt()); + } else { + registry.fill(HIST("hMassPtCutVarsRecSig"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProngSqSum(), candidate.cpa(), invMassD, ptD, decLenD, cospD); + } + } else if (fillBackground) { + if constexpr (withDmesMl) { + registry.fill(HIST("hMassPtCutVarsRecBg"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProngSqSum(), candidate.cpa(), invMassD, ptD, candidate.prong0MlScoreBkg(), candidate.prong0MlScoreNonprompt()); + } else { + registry.fill(HIST("hMassPtCutVarsRecBg"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProngSqSum(), candidate.cpa(), invMassD, ptD, decLenD, cospD); + } + } + } else { + if constexpr (withDmesMl) { + registry.fill(HIST("hMassPtCutVars"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProngSqSum(), candidate.cpa(), invMassD, ptD, candidate.prong0MlScoreBkg(), candidate.prong0MlScoreNonprompt()); + } else { + registry.fill(HIST("hMassPtCutVars"), invMassB0, ptCandB0, candidate.decayLength(), candidate.decayLengthXY() / candidate.errorDecayLengthXY(), candidate.impactParameterProngSqSum(), candidate.cpa(), invMassD, ptD, decLenD, cospD); + } + } + } + if (fillTree) { + float pseudoRndm = ptD * 1000. - static_cast(ptD * 1000); + if (flagMcMatchRec != 0 || (((doMc && fillBackground) || !doMc) && (ptCandB0 >= ptMaxForDownSample || pseudoRndm < downSampleBkgFactor))) { + float prong0MlScoreBkg = -1.; + float prong0MlScorePrompt = -1.; + float prong0MlScoreNonprompt = -1.; + float candidateMlScoreSig = -1; + if constexpr (withDmesMl) { + prong0MlScoreBkg = candidate.prong0MlScoreBkg(); + prong0MlScorePrompt = candidate.prong0MlScorePrompt(); + prong0MlScoreNonprompt = candidate.prong0MlScoreNonprompt(); + } + auto prongBachPi = candidate.template prongBachPi_as(); + + float ptMother = -1.; + if constexpr (doMc) { + ptMother = candidate.ptMother(); + } + + hfRedCandB0Lite( + // B-meson features + invMassB0, + ptCandB0, + candidate.eta(), + candidate.phi(), + hfHelper.yB0(candidate), + candidate.cpa(), + candidate.cpaXY(), + candidate.chi2PCA(), + candidate.decayLength(), + candidate.decayLengthXY(), + candidate.decayLengthNormalised(), + candidate.decayLengthXYNormalised(), + candidate.impactParameterProngSqSum(), + candidate.maxNormalisedDeltaIP(), + candidateMlScoreSig, + candidate.isSelB0ToDPi(), + // D-meson features + invMassD, + ptD, + decLenD, + decLenXyD, + candidate.impactParameter0(), + candD.ptProngMin(), + candD.absEtaProngMin(), + candD.itsNClsProngMin(), + candD.tpcNClsCrossedRowsProngMin(), + candD.tpcChi2NClProngMax(), + candD.tpcNSigmaPiProng0(), + candD.tofNSigmaPiProng0(), + candD.tpcTofNSigmaPiProng0(), + candD.tpcNSigmaKaProng1(), + candD.tofNSigmaKaProng1(), + candD.tpcTofNSigmaKaProng1(), + softPi.tpcNSigmaPiSoftPi(), + softPi.tofNSigmaPiSoftPi(), + softPi.tpcTofNSigmaPiSoftPi(), + prong0MlScoreBkg, + prong0MlScorePrompt, + prong0MlScoreNonprompt, + // pion features + candidate.ptProng1(), + std::abs(RecoDecay::eta(prongBachPi.pVector())), + prongBachPi.itsNCls(), + prongBachPi.tpcNClsCrossedRows(), + prongBachPi.tpcChi2NCl(), + candidate.impactParameter1(), + prongBachPi.tpcNSigmaPi(), + prongBachPi.tofNSigmaPi(), + prongBachPi.tpcTofNSigmaPi(), + // MC truth + flagMcMatchRec, + isSignal, + flagWrongCollision, + ptMother); + + if constexpr (withDecayTypeCheck) { + hfRedB0McCheck( + flagMcMatchRec, + flagWrongCollision, + invMassD, + ptD, + invMassB0, + ptCandB0, + candidateMlScoreSig, + candidate.pdgCodeBeautyMother(), + candidate.pdgCodeCharmMother(), + candidate.pdgCodeProng0(), + candidate.pdgCodeProng1(), + candidate.pdgCodeProng2(), + candidate.pdgCodeProng3()); + } + } + } + } + /// Fill candidate information at reconstruction level /// \param doMc is the flag to enable the filling with MC information /// \param withDecayTypeCheck is the flag to enable MC with decay type check @@ -558,7 +852,7 @@ struct HfTaskB0Reduced { if constexpr (withB0Ml) { candidateMlScoreSig = candidate.mlProbB0ToDPi(); } - auto prong1 = candidate.template prong1_as(); + auto prong1 = candidate.template prong1_as(); float ptMother = -1.; if constexpr (doMc) { @@ -681,9 +975,9 @@ struct HfTaskB0Reduced { } // Process functions - void processData(soa::Filtered> const& candidates, - CandsDplus const& candidatesD, - TracksPion const&) + void processDataDplusPi(soa::Filtered> const& candidates, + CandsDplus const& candidatesD, + TracksBachPions const&) { for (const auto& candidate : candidates) { if (yCandRecoMax >= 0. && std::abs(hfHelper.yB0(candidate)) > yCandRecoMax) { @@ -691,12 +985,12 @@ struct HfTaskB0Reduced { } fillCand(candidate, candidatesD); } // candidate loop - } // processData - PROCESS_SWITCH(HfTaskB0Reduced, processData, "Process data without ML scores for B0 and D daughter", true); + } // processDataDplusPi + PROCESS_SWITCH(HfTaskB0Reduced, processDataDplusPi, "Process data without ML scores for B0 and Dplus daughter", true); - void processDataWithDmesMl(soa::Filtered> const& candidates, - CandsDplus const& candidatesD, - TracksPion const&) + void processDataDplusPiWithDmesMl(soa::Filtered> const& candidates, + CandsDplus const& candidatesD, + TracksBachPions const&) { for (const auto& candidate : candidates) { if (yCandRecoMax >= 0. && std::abs(hfHelper.yB0(candidate)) > yCandRecoMax) { @@ -704,12 +998,12 @@ struct HfTaskB0Reduced { } fillCand(candidate, candidatesD); } // candidate loop - } // processDataWithDmesMl - PROCESS_SWITCH(HfTaskB0Reduced, processDataWithDmesMl, "Process data with(out) ML scores for D daughter (B0)", false); + } // processDataDplusPiWithDmesMl + PROCESS_SWITCH(HfTaskB0Reduced, processDataDplusPiWithDmesMl, "Process data with(out) ML scores for Dplus daughter (B0)", false); - void processDataWithB0Ml(soa::Filtered> const& candidates, - CandsDplus const& candidatesD, - TracksPion const&) + void processDataDplusPiWithB0Ml(soa::Filtered> const& candidates, + CandsDplus const& candidatesD, + TracksBachPions const&) { for (const auto& candidate : candidates) { if (yCandRecoMax >= 0. && std::abs(hfHelper.yB0(candidate)) > yCandRecoMax) { @@ -717,13 +1011,42 @@ struct HfTaskB0Reduced { } fillCand(candidate, candidatesD); } // candidate loop - } // processDataWithB0Ml - PROCESS_SWITCH(HfTaskB0Reduced, processDataWithB0Ml, "Process data with(out) ML scores for B0 (D daughter)", false); + } // processDataDplusPiWithB0Ml + PROCESS_SWITCH(HfTaskB0Reduced, processDataDplusPiWithB0Ml, "Process data with(out) ML scores for B0 (Dplus daughter)", false); + + // Process functions + void processDataDstarPi(soa::Filtered> const& candidates, + CandsDstar const& candidatesD, + TracksSoftPions const& softPions, + TracksBachPions const&) + { + for (const auto& candidate : candidates) { + if (yCandRecoMax >= 0. && std::abs(hfHelper.yB0(candidate)) > yCandRecoMax) { + continue; + } + fillCandDStarPi(candidate, softPions, candidatesD); + } // candidate loop + } // processDataDstarPi + PROCESS_SWITCH(HfTaskB0Reduced, processDataDstarPi, "Process data without ML scores for B0 and Dstar daughter", false); + + void processDataDstarPiWithDmesMl(soa::Filtered> const& candidates, + CandsDstar const& candidatesD, + TracksSoftPions const& softPions, + TracksBachPions const&) + { + for (const auto& candidate : candidates) { + if (yCandRecoMax >= 0. && std::abs(hfHelper.yB0(candidate)) > yCandRecoMax) { + continue; + } + fillCandDStarPi(candidate, softPions, candidatesD); + } // candidate loop + } // processDataDstarPiWithDmesMl + PROCESS_SWITCH(HfTaskB0Reduced, processDataDstarPiWithDmesMl, "Process data with(out) ML scores for Dstar daughter (B0)", false); - void processMc(soa::Filtered> const& candidates, - aod::HfMcGenRedB0s const& mcParticles, - CandsDplus const& candidatesD, - TracksPion const&) + void processMcDplusPi(soa::Filtered> const& candidates, + aod::HfMcGenRedB0s const& mcParticles, + CandsDplus const& candidatesD, + TracksBachPions const&) { // MC rec for (const auto& candidate : candidates) { @@ -737,13 +1060,13 @@ struct HfTaskB0Reduced { for (const auto& particle : mcParticles) { fillCandMcGen(particle); } // gen - } // processMc - PROCESS_SWITCH(HfTaskB0Reduced, processMc, "Process MC without ML scores for B0 and D daughter", false); + } // processMcDplusPi + PROCESS_SWITCH(HfTaskB0Reduced, processMcDplusPi, "Process MC without ML scores for B0 and Dplus daughter", false); - void processMcWithDecayTypeCheck(soa::Filtered> const& candidates, - aod::HfMcGenRedB0s const& mcParticles, - CandsDplus const& candidatesD, - TracksPion const&) + void processMcDplusPiWithDecayTypeCheck(soa::Filtered> const& candidates, + aod::HfMcGenRedB0s const& mcParticles, + CandsDplus const& candidatesD, + TracksBachPions const&) { // MC rec for (const auto& candidate : candidates) { @@ -757,13 +1080,13 @@ struct HfTaskB0Reduced { for (const auto& particle : mcParticles) { fillCandMcGen(particle); } // gen - } // processMc - PROCESS_SWITCH(HfTaskB0Reduced, processMcWithDecayTypeCheck, "Process MC with decay type check and without ML scores for B0 and D daughter", false); + } // processMcDplusPi + PROCESS_SWITCH(HfTaskB0Reduced, processMcDplusPiWithDecayTypeCheck, "Process MC with decay type check and without ML scores for B0 and Dplus daughter", false); - void processMcWithDmesMl(soa::Filtered> const& candidates, - aod::HfMcGenRedB0s const& mcParticles, - CandsDplus const& candidatesD, - TracksPion const&) + void processMcDplusPiWithDmesMl(soa::Filtered> const& candidates, + aod::HfMcGenRedB0s const& mcParticles, + CandsDplus const& candidatesD, + TracksBachPions const&) { // MC rec for (const auto& candidate : candidates) { @@ -777,13 +1100,13 @@ struct HfTaskB0Reduced { for (const auto& particle : mcParticles) { fillCandMcGen(particle); } // gen - } // processMcWithDmesMl - PROCESS_SWITCH(HfTaskB0Reduced, processMcWithDmesMl, "Process MC with(out) ML scores for D daughter (B0)", false); + } // processMcDplusPiWithDmesMl + PROCESS_SWITCH(HfTaskB0Reduced, processMcDplusPiWithDmesMl, "Process MC with(out) ML scores for Dplus daughter (B0)", false); - void processMcWithDmesMlAndDecayTypeCheck(soa::Filtered> const& candidates, - aod::HfMcGenRedB0s const& mcParticles, - CandsDplus const& candidatesD, - TracksPion const&) + void processMcDplusPiWithDmesMlAndDecayTypeCheck(soa::Filtered> const& candidates, + aod::HfMcGenRedB0s const& mcParticles, + CandsDplus const& candidatesD, + TracksBachPions const&) { // MC rec for (const auto& candidate : candidates) { @@ -797,13 +1120,13 @@ struct HfTaskB0Reduced { for (const auto& particle : mcParticles) { fillCandMcGen(particle); } // gen - } // processMc - PROCESS_SWITCH(HfTaskB0Reduced, processMcWithDmesMlAndDecayTypeCheck, "Process MC with decay type check and with(out) ML scores for B0 (D daughter)", false); + } // processMcDplusPi + PROCESS_SWITCH(HfTaskB0Reduced, processMcDplusPiWithDmesMlAndDecayTypeCheck, "Process MC with decay type check and with(out) ML scores for B0 (Dplus daughter)", false); - void processMcWithB0Ml(soa::Filtered> const& candidates, - aod::HfMcGenRedB0s const& mcParticles, - CandsDplus const& candidatesD, - TracksPion const&) + void processMcDplusPiWithB0Ml(soa::Filtered> const& candidates, + aod::HfMcGenRedB0s const& mcParticles, + CandsDplus const& candidatesD, + TracksBachPions const&) { // MC rec for (const auto& candidate : candidates) { @@ -817,13 +1140,13 @@ struct HfTaskB0Reduced { for (const auto& particle : mcParticles) { fillCandMcGen(particle); } // gen - } // processMcWithB0Ml - PROCESS_SWITCH(HfTaskB0Reduced, processMcWithB0Ml, "Process MC with(out) ML scores for B0 (D daughter)", false); + } // processMcDplusPiWithB0Ml + PROCESS_SWITCH(HfTaskB0Reduced, processMcDplusPiWithB0Ml, "Process MC with(out) ML scores for B0 (Dplus daughter)", false); - void processMcWithB0MlAndDecayTypeCheck(soa::Filtered> const& candidates, - aod::HfMcGenRedB0s const& mcParticles, - CandsDplus const& candidatesD, - TracksPion const&) + void processMcDplusPiWithB0MlAndDecayTypeCheck(soa::Filtered> const& candidates, + aod::HfMcGenRedB0s const& mcParticles, + CandsDplus const& candidatesD, + TracksBachPions const&) { // MC rec for (const auto& candidate : candidates) { @@ -837,8 +1160,51 @@ struct HfTaskB0Reduced { for (const auto& particle : mcParticles) { fillCandMcGen(particle); } // gen - } // processMc - PROCESS_SWITCH(HfTaskB0Reduced, processMcWithB0MlAndDecayTypeCheck, "Process MC with decay type check and with(out) ML scores for B0 (D daughter)", false); + } // processMcDplusPi + PROCESS_SWITCH(HfTaskB0Reduced, processMcDplusPiWithB0MlAndDecayTypeCheck, "Process MC with decay type check and with(out) ML scores for B0 (Dplus daughter)", false); + + void processMcDstarPi(soa::Filtered> const& candidates, + aod::HfMcGenRedB0s const& mcParticles, + CandsDstar const& candidatesD, + TracksSoftPions const& softPions, + TracksBachPions const&) + { + // MC rec + for (const auto& candidate : candidates) { + if (yCandRecoMax >= 0. && std::abs(hfHelper.yB0(candidate)) > yCandRecoMax) { + continue; + } + fillCandDStarPi(candidate, softPions, candidatesD); + } // rec + + // MC gen. level + for (const auto& particle : mcParticles) { + fillCandMcGen(particle); + } // gen + } // processMcDstarPi + PROCESS_SWITCH(HfTaskB0Reduced, processMcDstarPi, "Process MC without ML scores for B0 and Dstar daughter", false); + + void processMcDstarPiWithDmesMl(soa::Filtered> const& candidates, + aod::HfMcGenRedB0s const& mcParticles, + CandsDstar const& candidatesD, + TracksSoftPions const& softPions, + TracksBachPions const&) + { + // MC rec + for (const auto& candidate : candidates) { + if (yCandRecoMax >= 0. && std::abs(hfHelper.yB0(candidate)) > yCandRecoMax) { + continue; + } + fillCandDStarPi(candidate, softPions, candidatesD); + } // rec + + // MC gen. level + for (const auto& particle : mcParticles) { + fillCandMcGen(particle); + } // gen + } // processMcDstarPiWithDmesMl + PROCESS_SWITCH(HfTaskB0Reduced, processMcDstarPiWithDmesMl, "Process MC with(out) ML scores for Dstar daughter (B0)", false); + }; // struct WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/D2H/Tasks/taskD0.cxx b/PWGHF/D2H/Tasks/taskD0.cxx index 30bc3787e24..3e4be3ca15c 100644 --- a/PWGHF/D2H/Tasks/taskD0.cxx +++ b/PWGHF/D2H/Tasks/taskD0.cxx @@ -391,7 +391,7 @@ struct HfTaskD0 { cent = getCentralityColl(collision, centEstimator); } if (storeOccupancy && occEstimator != OccupancyEstimator::None) { - occ = getOccupancyColl(collision, occEstimator); + occ = o2::hf_occupancy::getOccupancyColl(collision, occEstimator); } } @@ -558,7 +558,7 @@ struct HfTaskD0 { cent = getCentralityColl(collision, centEstimator); } if (storeOccupancy && occEstimator != OccupancyEstimator::None) { - occ = getOccupancyColl(collision, occEstimator); + occ = o2::hf_occupancy::getOccupancyColl(collision, occEstimator); } float massD0, massD0bar; if constexpr (reconstructionType == aod::hf_cand::VertexerType::KfParticle) { @@ -844,7 +844,7 @@ struct HfTaskD0 { cent = getCentralityGenColl(recoCollsPerMcCollCent, centEstimator); } if (storeOccupancy && occEstimator != OccupancyEstimator::None) { - occ = getOccupancyGenColl(recoCollsPerMcCollCent, occEstimator); + occ = o2::hf_occupancy::getOccupancyGenColl(recoCollsPerMcCollCent, occEstimator); } } else { const auto& recoCollsPerMcColl = collisions.sliceBy(colPerMcCollision, particle.mcCollision().globalIndex()); diff --git a/PWGHF/D2H/Tasks/taskDplus.cxx b/PWGHF/D2H/Tasks/taskDplus.cxx index 30734322e9d..9740516e91c 100644 --- a/PWGHF/D2H/Tasks/taskDplus.cxx +++ b/PWGHF/D2H/Tasks/taskDplus.cxx @@ -44,6 +44,7 @@ #include +#include #include #include #include @@ -69,6 +70,7 @@ struct HfTaskDplus { Configurable> classMl{"classMl", {0, 1, 2}, "Indexes of ML scores to be stored. Three indexes max."}; Configurable storeCentrality{"storeCentrality", false, "Flag to store centrality information"}; Configurable storeOccupancy{"storeOccupancy", false, "Flag to store occupancy information"}; + Configurable storePvContributors{"storePvContributors", false, "Flag to store number of PV contributors information"}; Configurable fillMcBkgHistos{"fillMcBkgHistos", false, "Flag to fill and store histograms for MC background"}; HfHelper hfHelper; @@ -102,6 +104,7 @@ struct HfTaskDplus { ConfigurableAxis thnConfigAxisY{"thnConfigAxisY", {40, -1, 1}, "Cand. rapidity bins"}; ConfigurableAxis thnConfigAxisCent{"thnConfigAxisCent", {110, 0., 110.}, "axis for centrality"}; ConfigurableAxis thnConfigAxisOccupancy{"thnConfigAxisOccupancy", {14, 0, 14000}, "axis for occupancy"}; + ConfigurableAxis thnConfigAxisPvContributors{"thnConfigAxisPvContributors", {100, 0., 100.}, "axis for PV contributors"}; ConfigurableAxis thnConfigAxisPtBHad{"thnConfigAxisPtBHad", {25, 0., 50}, "axis for pt of B hadron decayed into D candidate"}; ConfigurableAxis thnConfigAxisFlagBHad{"thnConfigAxisFlagBHad", {5, 0., 5}, "axis for PDG of B hadron"}; ConfigurableAxis thnConfigAxisMlScore0{"thnConfigAxisMlScore0", {100, 0., 1.}, "axis for ML output score 0"}; @@ -137,6 +140,7 @@ struct HfTaskDplus { AxisSpec thnAxisFlagBHad{thnConfigAxisFlagBHad, "B Hadron flag"}; AxisSpec thnAxisCent{thnConfigAxisCent, "Centrality"}; AxisSpec thnAxisOccupancy{thnConfigAxisOccupancy, "Occupancy"}; + AxisSpec thnAxisPvContributors{thnConfigAxisPvContributors, "PV contributors"}; registry.add("hMass", "3-prong candidates;inv. mass (#pi K #pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{350, 1.7, 2.05}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); registry.add("hEta", "3-prong candidates;candidate #it{#eta};entries", {HistType::kTH2F, {{100, -2., 2.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); @@ -180,13 +184,15 @@ struct HfTaskDplus { std::vector axes = {thnAxisMass, thnAxisPt}; if (doprocessDataWithMl) { - axes.insert(axes.end(), {thnAxisMlScore0, thnAxisMlScore1, thnAxisMlScore2}); + axes.push_back(thnAxisMlScore0); + axes.push_back(thnAxisMlScore1); + axes.push_back(thnAxisMlScore2); } if (storeCentrality) { - axes.insert(axes.end(), {thnAxisCent}); + axes.push_back(thnAxisCent); } if (storeOccupancy) { - axes.insert(axes.end(), {thnAxisOccupancy}); + axes.push_back(thnAxisOccupancy); } registry.add("hSparseMass", "THn for Dplus", HistType::kTHnSparseF, axes); @@ -202,22 +208,28 @@ struct HfTaskDplus { axesFD.insert(axesFD.end(), {thnAxisMlScore0, thnAxisMlScore1, thnAxisMlScore2}); } if (storeCentrality) { - axes.insert(axes.end(), {thnAxisCent}); - axesFD.insert(axesFD.end(), {thnAxisCent}); - axesGenPrompt.insert(axesGenPrompt.end(), {thnAxisCent}); - axesGenFD.insert(axesGenFD.end(), {thnAxisCent}); + axes.push_back(thnAxisCent); + axesFD.push_back(thnAxisCent); + axesGenPrompt.push_back(thnAxisCent); + axesGenFD.push_back(thnAxisCent); } if (storeOccupancy) { - axes.insert(axes.end(), {thnAxisOccupancy}); - axesFD.insert(axesFD.end(), {thnAxisOccupancy}); - axesGenPrompt.insert(axesGenPrompt.end(), {thnAxisOccupancy}); - axesGenFD.insert(axesGenFD.end(), {thnAxisOccupancy}); + axes.push_back(thnAxisOccupancy); + axesFD.push_back(thnAxisOccupancy); + axesGenPrompt.push_back(thnAxisOccupancy); + axesGenFD.push_back(thnAxisOccupancy); + } + if (storePvContributors) { + axes.push_back(thnAxisPvContributors); + axesFD.push_back(thnAxisPvContributors); + axesGenPrompt.push_back(thnAxisPvContributors); + axesGenFD.push_back(thnAxisPvContributors); } - axesFD.insert(axesFD.end(), {thnAxisPtBHad}); - axesFD.insert(axesFD.end(), {thnAxisFlagBHad}); - axesGenFD.insert(axesGenFD.end(), {thnAxisPtBHad}); - axesGenFD.insert(axesGenFD.end(), {thnAxisFlagBHad}); + axesFD.push_back(thnAxisPtBHad); + axesFD.push_back(thnAxisFlagBHad); + axesGenFD.push_back(thnAxisPtBHad); + axesGenFD.push_back(thnAxisFlagBHad); registry.add("hSparseMassPrompt", "THn for Dplus Prompt", HistType::kTHnSparseF, axes); registry.add("hSparseMassFD", "THn for Dplus FD", HistType::kTHnSparseF, axesFD); @@ -267,12 +279,14 @@ struct HfTaskDplus { /// \param flagBHad transverse momentum of beauty mother for nonprompt candidates /// \param centrality collision centrality /// \param occupancy collision occupancy + /// \param numPvContributors contributors to the PV template void fillSparseML(const T1& candidate, float ptbhad, int flagBHad, float centrality, - float occupancy) + float occupancy, + float numPvContributors) { std::vector outputMl = {-999., -999., -999.}; for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { @@ -288,6 +302,8 @@ struct HfTaskDplus { registry.fill(HIST("hSparseMassPrompt"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2], centrality); } else if (!storeCentrality && storeOccupancy) { registry.fill(HIST("hSparseMassPrompt"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2], occupancy); + } else if (!storeCentrality && !storeOccupancy && storePvContributors) { + registry.fill(HIST("hSparseMassPrompt"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2], numPvContributors); } else { registry.fill(HIST("hSparseMassPrompt"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2]); } @@ -300,6 +316,8 @@ struct HfTaskDplus { registry.fill(HIST("hSparseMassFD"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2], centrality, ptbhad, flagBHad); } else if (!storeCentrality && storeOccupancy) { registry.fill(HIST("hSparseMassFD"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2], occupancy, ptbhad, flagBHad); + } else if (!storeCentrality && !storeOccupancy && storePvContributors) { + registry.fill(HIST("hSparseMassFD"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2], numPvContributors); } else { registry.fill(HIST("hSparseMassFD"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2], ptbhad, flagBHad); } @@ -312,6 +330,8 @@ struct HfTaskDplus { registry.fill(HIST("hSparseMassBkg"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2], centrality); } else if (!storeCentrality && storeOccupancy) { registry.fill(HIST("hSparseMassBkg"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2], occupancy); + } else if (!storeCentrality && !storeOccupancy && storePvContributors) { + registry.fill(HIST("hSparseMassBkg"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2], numPvContributors); } else { registry.fill(HIST("hSparseMassBkg"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2]); } @@ -324,6 +344,8 @@ struct HfTaskDplus { registry.fill(HIST("hSparseMassNotMatched"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2], centrality); } else if (!storeCentrality && storeOccupancy) { registry.fill(HIST("hSparseMassNotMatched"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2], occupancy); + } else if (!storeCentrality && !storeOccupancy && storePvContributors) { + registry.fill(HIST("hSparseMassNotMatched"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2], numPvContributors); } else { registry.fill(HIST("hSparseMassNotMatched"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2]); } @@ -335,6 +357,8 @@ struct HfTaskDplus { registry.fill(HIST("hSparseMass"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2], centrality); } else if (!storeCentrality && storeOccupancy) { registry.fill(HIST("hSparseMass"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2], occupancy); + } else if (!storeCentrality && !storeOccupancy && storePvContributors) { + registry.fill(HIST("hSparseMass"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2], numPvContributors); } else { registry.fill(HIST("hSparseMass"), hfHelper.invMassDplusToPiKPi(candidate), candidate.pt(), outputMl[0], outputMl[1], outputMl[2]); } @@ -416,12 +440,14 @@ struct HfTaskDplus { /// \param flagGenB transverse momentum of beauty mother for nonprompt candidates /// \param centrality collision centrality /// \param occupancy collision occupancy + /// \param numPvContributors contributors to the PV template void fillSparseMcGen(const T1& particle, float ptGenB, int flagGenB, float centrality, - float occupancy) + float occupancy, + float numPvContributors) { auto yGen = RecoDecay::y(particle.pVector(), o2::constants::physics::MassDPlus); if (particle.originMcGen() == RecoDecay::OriginType::Prompt) { @@ -431,6 +457,8 @@ struct HfTaskDplus { registry.fill(HIST("hSparseMassGenPrompt"), particle.pt(), yGen, centrality); } else if (!storeCentrality && storeOccupancy) { registry.fill(HIST("hSparseMassGenPrompt"), particle.pt(), yGen, occupancy); + } else if (!storeCentrality && !storeOccupancy && storePvContributors) { + registry.fill(HIST("hSparseMassGenPrompt"), particle.pt(), yGen, numPvContributors); } else { registry.fill(HIST("hSparseMassGenPrompt"), particle.pt(), yGen); } @@ -441,6 +469,8 @@ struct HfTaskDplus { registry.fill(HIST("hSparseMassGenFD"), particle.pt(), yGen, centrality, ptGenB, flagGenB); } else if (!storeCentrality && storeOccupancy) { registry.fill(HIST("hSparseMassGenFD"), particle.pt(), yGen, occupancy, ptGenB, flagGenB); + } else if (!storeCentrality && !storeOccupancy && storePvContributors) { + registry.fill(HIST("hSparseMassGenFD"), particle.pt(), yGen, numPvContributors, ptGenB, flagGenB); } else { registry.fill(HIST("hSparseMassGenFD"), particle.pt(), yGen, ptGenB, flagGenB); } @@ -454,6 +484,7 @@ struct HfTaskDplus { { float cent{-1.f}; float occ{-1.f}; + float numPvContr{-1.f}; float ptBhad{-1.f}; int flagBHad{-1}; if constexpr (!fillMl) { @@ -475,12 +506,15 @@ struct HfTaskDplus { cent = getCentralityColl(collision, centEstimator); } if (storeOccupancy && occEstimator != OccupancyEstimator::None) { - occ = getOccupancyColl(collision, occEstimator); + occ = o2::hf_occupancy::getOccupancyColl(collision, occEstimator); + } + if (storePvContributors) { + numPvContr = collision.numContrib(); } } fillHisto(candidate); - fillSparseML(candidate, ptBhad, flagBHad, cent, occ); + fillSparseML(candidate, ptBhad, flagBHad, cent, occ, numPvContr); } } } @@ -493,6 +527,7 @@ struct HfTaskDplus { { float cent{-1}; float occ{-1}; + float numPvContr{-1}; float ptBhad{-1}; int flagBHad{-1}; @@ -528,13 +563,16 @@ struct HfTaskDplus { cent = getCentralityColl(collision, centEstimator); } if (storeOccupancy && occEstimator != OccupancyEstimator::None) { - occ = getOccupancyColl(collision, occEstimator); + occ = o2::hf_occupancy::getOccupancyColl(collision, occEstimator); + } + if (storePvContributors) { + numPvContr = collision.numContrib(); } } fillHisto(candidate); fillHistoMCRec(candidate); - fillSparseML(candidate, ptBhad, flagBHad, cent, occ); + fillSparseML(candidate, ptBhad, flagBHad, cent, occ, numPvContr); } // Bkg ptBhad = -1; @@ -549,10 +587,13 @@ struct HfTaskDplus { cent = getCentralityColl(collision, centEstimator); } if (storeOccupancy && occEstimator != OccupancyEstimator::None) { - occ = getOccupancyColl(collision, occEstimator); + occ = o2::hf_occupancy::getOccupancyColl(collision, occEstimator); + } + if (storePvContributors) { + numPvContr = collision.numContrib(); } fillHistoMCRec(candidate); - fillSparseML(candidate, ptBhad, flagBHad, cent, occ); + fillSparseML(candidate, ptBhad, flagBHad, cent, occ, numPvContr); } } } @@ -570,6 +611,7 @@ struct HfTaskDplus { // MC gen. float cent{-1.}; float occ{-1.}; + float numPvContr{-1.}; float ptGenB{-1.}; int flagGenB{-1}; @@ -580,12 +622,13 @@ struct HfTaskDplus { cent = getCentralityGenColl(recoCollsPerGenMcColl, centEstimator); } if (storeOccupancy && occEstimator != OccupancyEstimator::None) { - occ = getOccupancyGenColl(recoCollsPerGenMcColl, occEstimator); + occ = o2::hf_occupancy::getOccupancyGenColl(recoCollsPerGenMcColl, occEstimator); } for (const auto& particle : mcParticlesPerGenMcColl) { ptGenB = -1; flagGenB = -1; + numPvContr = -1; auto yGen = RecoDecay::y(particle.pVector(), o2::constants::physics::MassDPlus); if ((yCandGenMax >= 0. && std::abs(yGen) > yCandGenMax) || (std::abs(particle.flagMcMatchGen()) != hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi)) { continue; @@ -595,9 +638,12 @@ struct HfTaskDplus { flagGenB = getBHadMotherFlag(bHadMother.pdgCode()); ptGenB = bHadMother.pt(); } + for (const auto& recCol : mcRecoCollisions) { + numPvContr = std::max(numPvContr, recCol.numContrib()); + } fillHistoMCGen(particle); if constexpr (fillMl) { - fillSparseMcGen(particle, ptGenB, flagGenB, cent, occ); + fillSparseMcGen(particle, ptGenB, flagGenB, cent, occ, numPvContr); } } } diff --git a/PWGHF/D2H/Tasks/taskDstarToD0Pi.cxx b/PWGHF/D2H/Tasks/taskDstarToD0Pi.cxx index 3175b472a0c..801e25e3460 100644 --- a/PWGHF/D2H/Tasks/taskDstarToD0Pi.cxx +++ b/PWGHF/D2H/Tasks/taskDstarToD0Pi.cxx @@ -25,6 +25,7 @@ #include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" +#include #include #include #include @@ -40,6 +41,8 @@ #include #include +#include +#include #include #include @@ -52,12 +55,31 @@ using namespace o2::soa; /// Dstar analysis task struct HfTaskDstarToD0Pi { Configurable selectionFlagDstarToD0Pi{"selectionFlagDstarToD0Pi", true, "Selection Flag for D* decay to D0 & Pi"}; + Configurable isCentStudy{"isCentStudy", true, "Flag to select centrality study"}; + Configurable qaEnabled{"qaEnabled", true, "Flag to enable QA histograms"}; + + // CCDB configuration + Configurable useWeight{"useWeight", true, "Flag to use weights from CCDB"}; + Configurable nWeights{"nWeights", 6, "Number of weights to be used from CCDB"}; + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable ccdbPathForWeight{"ccdbPathForWeight", "Users/d/desharma/weights", "CCDB path for PVContrib weights"}; + Configurable timestampCCDB{"timestampCCDB", -1, "CCDB timestamp for the weights"}; + Configurable weightFileName{"weightFileName", "Weights.root", "Name of the weight file to be used for PVContrib"}; + Configurable> centRangesForWeights{"centRangesForWeights", {0.0, 5.0, 10.0, 30.0, 50.0, 70.0, 100.0}, "Centrality ranges for weights. Size of ranges should be equal to nWeights + 1"}; + Configurable yCandDstarRecoMax{"yCandDstarRecoMax", 0.8, "max. candidate Dstar rapidity"}; Configurable yCandDstarGenMax{"yCandDstarGenMax", 0.5, "max. rapidity of Generator level Particle"}; Configurable selectionFlagHfD0ToPiK{"selectionFlagHfD0ToPiK", true, "Selection Flag for HF flagged candidates"}; Configurable> ptBins{"ptBins", std::vector{hf_cuts_dstar_to_d0_pi::vecBinsPt}, "pT bin limits for Dstar"}; + Configurable deltaMassMin{"deltaMassMin", 0.142, "Lower bound of the signal region for Delta Invariant MassDstar"}; + Configurable deltaMassMax{"deltaMassMax", 0.15, "Upper bound of the signal region for Delta Invariant MassDstar"}; + o2::ccdb::CcdbApi ccdbApi; SliceCache cache; + std::vector hWeights; + std::vector axesPtVsCentVsBDTVsPvContrib; + std::vector axesPtVsCentVsPvContrib; + std::vector axesPtVsBDT; using CandDstarWSelFlag = soa::Join; using CandDstarWSelFlagWMl = soa::Join; @@ -86,17 +108,9 @@ struct HfTaskDstarToD0Pi { ConfigurableAxis binningDeltaInvMass{"binningDeltaInvMass", {100, 0.13, 0.16}, "Bins of Delta InvMass of Dstar"}; ConfigurableAxis binningBkgBDTScore{"binningBkgBDTScore", {100, 0.0f, 1.0f}, "Bins for background BDT Score"}; ConfigurableAxis binningSigBDTScore{"binningSigBDTScore", {100, 0.0f, 1.0f}, "Bins for Signal (Prompts + Non Prompt) BDT Score"}; + ConfigurableAxis binningPvContrib{"binningPvContrib", {100, 0.0f, 300.0f}, "Bins for PVContrib"}; - HistogramRegistry registry{ - "registry", - {{"QA/hPtDstar", "Dstar Candidates; Dstar candidate #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}}, - {"QA/hPtD0", "D0 Candiades; D0 Candidate #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}}, - {"QA/hPtProng0D0", "Prong0 of D0 Candidates; Prong0 #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}}, - {"QA/hPtProng1D0", "Prong1 of D0 Candidates; Prong1 #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}}, - {"QA/hPtProng0D0Bar", "Prong0 of D0Bar Candidates; Prong0 #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}}, - {"QA/hPtProng1D0Bar", "Prong1 of D0Bar Candidates; Prong1 #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}}, - {"QA/hPtSoftPi", "Soft Pi ; Soft Pi #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{100, 0., 1.}}}}, - {"QA/hDeltaCentGen", "#{Delta}Cent % distribution of Collisions having same MC Collision;FT0M #{Delta}Cent %; Counts", {HistType::kTH1F, {{100, 0.0, 100.0}}}}}}; + HistogramRegistry registry{"registry", {}}; void init(InitContext&) { @@ -113,84 +127,173 @@ struct HfTaskDstarToD0Pi { AxisSpec axisBDTScorePrompt = {binningSigBDTScore, "BDT Score for Prompt Cand"}; AxisSpec axisBDTScoreNonPrompt = {binningSigBDTScore, "BDT Score for Non-Prompt Cand"}; AxisSpec axisBDTScoreBackground = {binningBkgBDTScore, "BDT Score for Background Cand"}; + AxisSpec axisPvContrib = {binningPvContrib, "PV Contribution"}; + AxisSpec axisPt = {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}; + + axesPtVsCentVsBDTVsPvContrib = {axisPt, axisCentrality, axisBDTScoreBackground, axisBDTScorePrompt, axisBDTScoreNonPrompt, axisPvContrib}; + axesPtVsCentVsPvContrib = {axisPt, axisCentrality, axisPvContrib}; + axesPtVsBDT = {axisPt, axisBDTScoreBackground, axisBDTScorePrompt, axisBDTScoreNonPrompt}; + + if (qaEnabled) { + // only QA + registry.add("QA/hPtDstar", "Dstar Candidates; Dstar candidate #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}); + registry.add("QA/hPtD0", "D0 Candiades; D0 Candidate #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}); + registry.add("QA/hPtProng0D0", "Prong0 of D0 Candidates; Prong0 #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}); + registry.add("QA/hPtProng1D0", "Prong1 of D0 Candidates; Prong1 #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}); + registry.add("QA/hPtProng0D0Bar", "Prong0 of D0Bar Candidates; Prong0 #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}); + registry.add("QA/hPtProng1D0Bar", "Prong1 of D0Bar Candidates; Prong1 #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}); + registry.add("QA/hPtSoftPi", "Soft Pi ; Soft Pi #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{100, 0., 1.}}}); + registry.add("QA/hDeltaCentGen", "#{Delta}Cent % distribution of Collisions having same MC Collision;FT0M #{Delta}Cent %; Counts", {HistType::kTH1F, {{100, 0.0, 100.0}}}); + + registry.add("QA/hEtaDstar", "D* Candidate; D* Candidate #it{#eta};entries", {HistType::kTH2F, {{100, -2., 2.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hCtD0", "D0 Candidate; D0 Candidate's proper life time #it{c}#tau (cm) ; entries ", {HistType::kTH2F, {{1000, -0.1, 14.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hDecayLengthD0", "D0 Candidate; D0 Candidate's decay length (cm); entries", {HistType::kTH2F, {axisDecayLength, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hDecayLengthXYD0", "D0 Candidate; D0 Candidate's decay length xy (cm); entries", {HistType::kTH2F, {axisDecayLength, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hDecayLengthNormalisedD0", "D0 Candidates;Do Candidate's normalised decay length (cm); entries", {HistType::kTH2F, {axisNormDecayLength, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hDecayLengthXYNormalisedD0", "D0 candidate; D0 Candidate's normalised decay length xy (cm); entries", {HistType::kTH2F, {axisNormDecayLength, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hCPAD0", "D0 Candidates; D0 Candidate's cosine pointing angle; entries", {HistType::kTH2F, {{110, -1., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hCPAxyD0", "D0 candidates; D0 Candidate's cosine of pointing angle xy; entries", {HistType::kTH2F, {{110, -1., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hImpactParameterXYD0", "D0 Candidates; D0 Candidate's reconstructed impact parameter xy (cm); entries", {HistType::kTH2F, {axisImpactParam, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hDeltaIPMaxNormalisedD0", "D0 Candidate; D0 Candidate's Norm. Delta IP; entries", {HistType::kTH2F, {{1000, -20., 20.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hSqSumProngsImpactParameterD0", "D0 Candidates; Sqr Sum of Impact params of D0 Prongs; entries ", {HistType::kTH2F, {{1000, 0., 0.25}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hDecayLengthErrorD0", "D0 Candidates; D0 Candidate's Decay Length Error (cm); entries", {HistType::kTH2F, {axisDecayLength, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hDecayLengthXYErrorD0", "D0 Candidates; D0 Candidate's Decay Length Error XY (cm); entries", {HistType::kTH2F, {axisDecayLength, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hImpactParameterError", "D0 Prongs; Impact param error of different D0 Prongs (cm); entries", {HistType::kTH2F, {axisImpactParam, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hd0Prong0", "Prong0; DCAxy of Prong0 (cm); entries", {HistType::kTH2F, {axisImpactParam, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hd0Prong1", "Prong1; DCAxy of Prong1 (cm); entries", {HistType::kTH2F, {axisImpactParam, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hd0ProngSoftPi", "ProngSoftPi; DCAxy of Prong Soft Pi (cm); entries", {HistType::kTH2F, {axisImpactParam, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + + // MC Matching at Reconstruction Level Successful + registry.add("QA/hCPASkimD0RecSig", "MC Matched Skimed D* Candidates at Reconstruction Level; cosine of pointing angle", {HistType::kTH1F, {{110, -1.1, 1.1}}}); + registry.add("QA/hEtaSkimD0RecSig", "MC Matched Skimed D* Candidates at Reconstruction Level; #it{#eta} of D0 Prong", {HistType::kTH1F, {{100, -2., 2.}}}); + registry.add("QA/hEtaSkimDstarRecSig", "MC Matched Skimed D* Candidates at Reconstruction Level; #it{#eta} of D* Candidate", {HistType::kTH1F, {{100, -2., 2.}}}); + + // pt vs y + registry.add("QA/hPtSkimDstarGenSig", "MC Matched Skimed D* Reconstructed Candidates at Generator Level; #it{p}_{T} of D* at Generator Level (GeV/#it{c})", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}, true); + registry.add("QA/hPtVsCentSkimDstarGenSig", "MC Matched Skimed D* Reconstructed Candidates at Generator Level; #it{p}_{T} of D* at Generator Level (GeV/#it{c}); Centrality (%)", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {axisCentrality}}}, true); + registry.add("QA/hPtVsYSkimDstarRecSig", "MC Matched Skimed D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("QA/hPtVsYRecoTopolDstarRecSig", "MC Matched RecoTopol D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("QA/hPtVsYRecoPidDstarRecSig", "MC Matched RecoPid D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("QA/hPtFullRecoDstarRecSig", "MC Matched FullReco D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c})", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + + // Only Prompt RecSig + registry.add("QA/hPtVsYSkimPromptDstarRecSig", "MC Matched Skimed Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}; #it{y})", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("QA/hPtVsYRecoTopolPromptDstarRecSig", "MC Matched RecoTopol Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("QA/hPtVsYRecoPidPromptDstarRecSig", "MC Matched RecoPid Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("QA/hPtFullRecoPromptDstarRecSig", "MC Matched FullReco Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c})", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + // Only Non-Prompt RecSig + registry.add("QA/hPtVsYSkimNonPromptDstarRecSig", "MC Matched Skimed Non-Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("QA/hPtVsYRecoTopolNonPromptDstarRecSig", "MC Matched RecoTopol Non-Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("QA/hPtVsYRecoPidNonPromptDstarRecSig", "MC Matched RecoPid Non-Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("QA/hPtFullRecoNonPromptDstarRecSig", "MC Matched FullReco Non-Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c})", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + // MC Matching UnSuccessful + registry.add("QA/hCPASkimD0RecBg", "MC UnMatched Skimmed D0 Candidates at Reconstruction Level; cosine of pointing angle", {HistType::kTH1F, {{110, -1., 1.}}}); + registry.add("QA/hEtaSkimD0RecBg", "MC UnMatched Skimmed D0 Candidates at Reconstruction Level; #it{#eta} of D0 Prong", {HistType::kTH1F, {{100, -2., 2.}}}); + registry.add("QA/hEtaSkimDstarRecBg", "MC UnMatched Skimmed D* Candidates at Reconstruction Level; #it{#eta} of D* Candidate", {HistType::kTH1F, {{100, -2., 2.}}}); + // registry.add("QA/hPtSkimD0RecBg", "MC UnMatched Skimmed D0 Candidates at Reconstruction Level; #it{p}_{T} of D0", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + registry.add("QA/hPtSkimDstarRecBg", "MC UnMatched Skimmed D* Candidates at Reconstruction Level; #it{p}_{T} of D*", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + + // MC Matching at Generator level Successful + registry.add("QA/hEtaDstarGen", "MC Matched D* Candidates at Generator Level; #it{#eta}", {HistType::kTH1F, {{100, -2., 2.}}}); + registry.add("QA/hPtDstarGen", "MC Matched D* Candidates at Generator Level; #it{p}_{T} of D*", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); + } - registry.add("Yield/hDeltaInvMassDstar3D", "#Delta #it{M}_{inv} D* Candidate; inv. mass ((#pi #pi k) - (#pi k)) (GeV/#it{c}^{2});#it{p}_{T} (GeV/#it{c}); FT0M centrality", {HistType::kTH3F, {{axisDeltaInvMass}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {axisCentrality}}}, true); - registry.add("Yield/hDeltaInvMassDstar2D", "#Delta #it{M}_{inv} D* Candidate; inv. mass ((#pi #pi k) - (#pi k)) (GeV/#it{c}^{2});#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{axisDeltaInvMass}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}, true); registry.add("Yield/hDeltaInvMassDstar1D", "#Delta #it{M}_{inv} D* Candidate; inv. mass ((#pi #pi k) - (#pi k)) (GeV/#it{c}^{2}); entries", {HistType::kTH1F, {{axisDeltaInvMass}}}, true); registry.add("Yield/hInvMassDstar", "#Delta #it{M}_{inv} D* Candidate; inv. mass (#pi #pi k) (GeV/#it{c}^{2}); entries", {HistType::kTH1F, {{500, 0., 5.0}}}, true); registry.add("Yield/hInvMassD0", "#it{M}_{inv}D^{0} candidate;#it{M}_{inv} D^{0} (GeV/#it{c});#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{500, 0., 5.0}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}, true); - // only QA - registry.add("QA/hEtaDstar", "D* Candidate; D* Candidate #it{#eta};entries", {HistType::kTH2F, {{100, -2., 2.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hCtD0", "D0 Candidate; D0 Candidate's proper life time #it{c}#tau (cm) ; entries ", {HistType::kTH2F, {{1000, -0.1, 14.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hDecayLengthD0", "D0 Candidate; D0 Candidate's decay length (cm); entries", {HistType::kTH2F, {axisDecayLength, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hDecayLengthXYD0", "D0 Candidate; D0 Candidate's decay length xy (cm); entries", {HistType::kTH2F, {axisDecayLength, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hDecayLengthNormalisedD0", "D0 Candidates;Do Candidate's normalised decay length (cm); entries", {HistType::kTH2F, {axisNormDecayLength, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hDecayLengthXYNormalisedD0", "D0 candidate; D0 Candidate's normalised decay length xy (cm); entries", {HistType::kTH2F, {axisNormDecayLength, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hCPAD0", "D0 Candidates; D0 Candidate's cosine pointing angle; entries", {HistType::kTH2F, {{110, -1., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hCPAxyD0", "D0 candidates; D0 Candidate's cosine of pointing angle xy; entries", {HistType::kTH2F, {{110, -1., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hImpactParameterXYD0", "D0 Candidates; D0 Candidate's reconstructed impact parameter xy (cm); entries", {HistType::kTH2F, {axisImpactParam, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hDeltaIPMaxNormalisedD0", "D0 Candidate; D0 Candidate's Norm. Delta IP; entries", {HistType::kTH2F, {{1000, -20., 20.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hSqSumProngsImpactParameterD0", "D0 Candidates; Sqr Sum of Impact params of D0 Prongs; entries ", {HistType::kTH2F, {{1000, 0., 0.25}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hDecayLengthErrorD0", "D0 Candidates; D0 Candidate's Decay Length Error (cm); entries", {HistType::kTH2F, {axisDecayLength, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hDecayLengthXYErrorD0", "D0 Candidates; D0 Candidate's Decay Length Error XY (cm); entries", {HistType::kTH2F, {axisDecayLength, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hImpactParameterError", "D0 Prongs; Impact param error of different D0 Prongs (cm); entries", {HistType::kTH2F, {axisImpactParam, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hd0Prong0", "Prong0; DCAxy of Prong0 (cm); entries", {HistType::kTH2F, {axisImpactParam, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hd0Prong1", "Prong1; DCAxy of Prong1 (cm); entries", {HistType::kTH2F, {axisImpactParam, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hd0ProngSoftPi", "ProngSoftPi; DCAxy of Prong Soft Pi (cm); entries", {HistType::kTH2F, {axisImpactParam, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - // MC Matching at Reconstruction Level Successful - registry.add("QA/hCPASkimD0RecSig", "MC Matched Skimed D* Candidates at Reconstruction Level; cosine of pointing angle", {HistType::kTH1F, {{110, -1.1, 1.1}}}); - registry.add("QA/hEtaSkimD0RecSig", "MC Matched Skimed D* Candidates at Reconstruction Level; #it{#eta} of D0 Prong", {HistType::kTH1F, {{100, -2., 2.}}}); - registry.add("QA/hEtaSkimDstarRecSig", "MC Matched Skimed D* Candidates at Reconstruction Level; #it{#eta} of D* Candidate", {HistType::kTH1F, {{100, -2., 2.}}}); + + // BDT Score (axisBDTScoreBackground, axisBDTScorePrompt, axisBDTScoreNonPrompt) + if (doprocessDataWML) { + registry.add("Yield/hDeltaInvMassVsPtVsCentVsBDTScore", "#Delta #it{M}_{inv} Vs Pt Vs Cent Vs BDTScore", {HistType::kTHnSparseF, {{axisDeltaInvMass}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {axisCentrality}, {axisBDTScoreBackground}, {axisBDTScorePrompt}, {axisBDTScoreNonPrompt}}}, true); + } else if (doprocessDataWoML) { + registry.add("Yield/hDeltaInvMassDstar2D", "#Delta #it{M}_{inv} D* Candidate; inv. mass ((#pi #pi k) - (#pi k)) (GeV/#it{c}^{2});#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{axisDeltaInvMass}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}, true); + registry.add("Yield/hDeltaInvMassDstar3D", "#Delta #it{M}_{inv} D* Candidate; inv. mass ((#pi #pi k) - (#pi k)) (GeV/#it{c}^{2});#it{p}_{T} (GeV/#it{c}); FT0M centrality", {HistType::kTH3F, {{axisDeltaInvMass}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {axisCentrality}}}, true); + } + // pt vs y - registry.add("QA/hPtSkimDstarGenSig", "MC Matched Skimed D* Reconstructed Candidates at Generator Level; #it{p}_{T} of D* at Generator Level (GeV/#it{c})", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}, true); - registry.add("Efficiency/hPtVsCentSkimDstarGenSig", "MC Matched Skimed D* Reconstructed Candidates at Generator Level; #it{p}_{T} of D* at Generator Level (GeV/#it{c}); Centrality (%)", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {axisCentrality}}}, true); - registry.add("QA/hPtVsYSkimDstarRecSig", "MC Matched Skimed D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("QA/hPtVsYRecoTopolDstarRecSig", "MC Matched RecoTopol D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("QA/hPtVsYRecoPidDstarRecSig", "MC Matched RecoPid D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("QA/hPtFullRecoDstarRecSig", "MC Matched FullReco D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c})", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("Efficiency/hPtVsCentFullRecoDstarRecSig", "MC Matched FullReco D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); Centrality (%)", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {axisCentrality}}}, true); - // Only Prompt RecSig - registry.add("QA/hPtVsYSkimPromptDstarRecSig", "MC Matched Skimed Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}; #it{y})", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("QA/hPtVsYRecoTopolPromptDstarRecSig", "MC Matched RecoTopol Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("QA/hPtVsYRecoPidPromptDstarRecSig", "MC Matched RecoPid Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("QA/hPtFullRecoPromptDstarRecSig", "MC Matched FullReco Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c})", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - // Only Non-Prompt RecSig - registry.add("QA/hPtVsYSkimNonPromptDstarRecSig", "MC Matched Skimed Non-Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("QA/hPtVsYRecoTopolNonPromptDstarRecSig", "MC Matched RecoTopol Non-Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("QA/hPtVsYRecoPidNonPromptDstarRecSig", "MC Matched RecoPid Non-Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c}); #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); - registry.add("QA/hPtFullRecoNonPromptDstarRecSig", "MC Matched FullReco Non-Prompt D* Candidates at Reconstruction Level; #it{p}_{T} of D* at Reconstruction Level (GeV/#it{c})", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - // MC Matching UnSuccessful - registry.add("QA/hCPASkimD0RecBg", "MC UnMatched Skimmed D0 Candidates at Reconstruction Level; cosine of pointing angle", {HistType::kTH1F, {{110, -1., 1.}}}); - registry.add("QA/hEtaSkimD0RecBg", "MC UnMatched Skimmed D0 Candidates at Reconstruction Level; #it{#eta} of D0 Prong", {HistType::kTH1F, {{100, -2., 2.}}}); - registry.add("QA/hEtaSkimDstarRecBg", "MC UnMatched Skimmed D* Candidates at Reconstruction Level; #it{#eta} of D* Candidate", {HistType::kTH1F, {{100, -2., 2.}}}); - registry.add("QA/hPtSkimD0RecBg", "MC UnMatched Skimmed D0 Candidates at Reconstruction Level; #it{p}_{T} of D0", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hPtSkimDstarRecBg", "MC UnMatched Skimmed D* Candidates at Reconstruction Level; #it{p}_{T} of D*", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - // MC Matching at Generator level Successful - registry.add("QA/hEtaDstarGen", "MC Matched D* Candidates at Generator Level; #it{#eta}", {HistType::kTH1F, {{100, -2., 2.}}}); - registry.add("QA/hPtDstarGen", "MC Matched D* Candidates at Generator Level; #it{p}_{T} of D*", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("Efficiency/hPtVsCentDstarGen", "MC Matched D* Candidates at Generator Level; #it{p}_{T} of D*;Centrality (%) ", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {axisCentrality}}}, true); - registry.add("QA/hPtVsYDstarGen", "MC Matched D* Candidates at Generator Level; #it{p}_{T} of D*; #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("Efficiency/hPtVsYDstarGen", "MC Matched D* Candidates at Generator Level; #it{p}_{T} of D*; #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}, true); // Prompt Gen - registry.add("QA/hPtPromptDstarGen", "MC Matched Prompt D* Candidates at Generator Level; #it{p}_{T} of D*", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hPtVsYPromptDstarGen", "MC Matched Prompt D* Candidates at Generator Level; #it{p}_{T} of D*; #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("Efficiency/hPtVsYPromptDstarGen", "MC Matched Prompt D* Candidates at Generator Level; #it{p}_{T} of D*; #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}, true); // Non Prmpt Gen - registry.add("QA/hPtNonPromptDstarGen", "MC Matched Non-Prompt D* Candidates at Generator Level; #it{p}_{T} of D*", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hPtVsYNonPromptDstarGen", "MC Matched Non-Prompt D* Candidates at Generator Level; #it{p}_{T} of D*; #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}); + registry.add("Efficiency/hPtVsYNonPromptDstarGen", "MC Matched Non-Prompt D* Candidates at Generator Level; #it{p}_{T} of D*; #it{y}", {HistType::kTH2F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {100, -5., 5.}}}, true); - // Checking PV contributors from Data as well MC rec - registry.add("Efficiency/hNumPvContributorsAll", "PV Contributors; PV Contributor; FT0M Centrality", {HistType::kTH2F, {{100, 0, 300}, {axisCentrality}}}, true); - registry.add("Efficiency/hNumPvContributorsCand", "PV Contributors; PV Contributor; FT0M Centrality", {HistType::kTH2F, {{100, 0, 300}, {axisCentrality}}}, true); - registry.add("Efficiency/hNumPvContributorsCandInMass", "PV Contributors; PV Contributor; FT0M Centrality", {HistType::kTH2F, {{100, 0, 300}, {axisCentrality}}}, true); + // Checking PV contributors from Data as well MC rec for calculation weights offline + if (isCentStudy) { + registry.add("Efficiency/hNumPvContributorsAll", "PV Contributors; PV Contributor; FT0M Centrality", {HistType::kTH2F, {{axisPvContrib}, {axisCentrality}}}, true); + registry.add("Efficiency/hNumPvContributorsCand", "PV Contributors; PV Contributor; FT0M Centrality", {HistType::kTH2F, {{axisPvContrib}, {axisCentrality}}}, true); + registry.add("Efficiency/hNumPvContributorsCandInMass", "PV Contributors; PV Contributor; FT0M Centrality", {HistType::kTH2F, {{axisPvContrib}, {axisCentrality}}}, true); + } - // BDT Score (axisBDTScoreBackground, axisBDTScorePrompt, axisBDTScoreNonPrompt) - if (doprocessDataWML) { - registry.add("Yield/hDeltaInvMassVsPtVsCentVsBDTScore", "#Delta #it{M}_{inv} Vs Pt Vs Cent Vs BDTScore", {HistType::kTHnSparseF, {{axisDeltaInvMass}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {axisCentrality}, {axisBDTScoreBackground}, {axisBDTScorePrompt}, {axisBDTScoreNonPrompt}}}); + // Hists at Reco level W/O ML usefull for efficiency calculation + if (doprocessMcWoMl && isCentStudy) { + registry.add("Efficiency/hPtVsCentVsPvContribRecSig", "Pt Vs Cent Vs PvContrib", {HistType::kTHnSparseF, axesPtVsCentVsPvContrib}, true); + registry.add("Efficiency/hPtPromptVsCentVsPvContribRecSig", "Pt Vs Cent Vs PvContrib", {HistType::kTHnSparseF, axesPtVsCentVsPvContrib}, true); + registry.add("Efficiency/hPtNonPromptVsCentVsPvContribRecSig", "Pt Vs Cent Vs PvContrib", {HistType::kTHnSparseF, axesPtVsCentVsPvContrib}, true); + } else if (doprocessMcWoMl && !isCentStudy) { + registry.add("Efficiency/hPtVsPvContribRecSig", "Pt Vs PvContrib", {HistType::kTHnSparseF, axesPtVsBDT}, true); + registry.add("Efficiency/hPtPromptVsPvContribRecSig", "Pt Vs PvContrib", {HistType::kTHnSparseF, axesPtVsBDT}, true); + registry.add("Efficiency/hPtNonPromptVsPvContribRecSig", "Pt Vs PvContrib", {HistType::kTHnSparseF, axesPtVsBDT}, true); } - if (doprocessMcWML) { - registry.add("Efficiency/hPtVsCentVsBDTScore", "Pt Vs Cent Vs BDTScore", {HistType::kTHnSparseF, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {axisCentrality}, {axisBDTScoreBackground}, {axisBDTScorePrompt}, {axisBDTScoreNonPrompt}}}); - registry.add("Efficiency/hPtPromptVsCentVsBDTScore", "Pt Vs Cent Vs BDTScore", {HistType::kTHnSparseF, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {axisCentrality}, {axisBDTScoreBackground}, {axisBDTScorePrompt}, {axisBDTScoreNonPrompt}}}); - registry.add("Efficiency/hPtNonPromptVsCentVsBDTScore", "Pt Vs Cent Vs BDTScore", {HistType::kTHnSparseF, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {axisCentrality}, {axisBDTScoreBackground}, {axisBDTScorePrompt}, {axisBDTScoreNonPrompt}}}); + + // Hists at Reco level W/ ML usefull for efficiency calculation + if (doprocessMcWML && isCentStudy) { + registry.add("Efficiency/hPtVsCentVsBDTScoreVsPvContribRecSig", "Pt Vs Cent Vs BDTScore Vs PvContrib", {HistType::kTHnSparseF, axesPtVsCentVsBDTVsPvContrib}, true); + registry.add("Efficiency/hPtPromptVsCentVsBDTScorePvContribRecSig", "Pt Vs Cent Vs BDTScore Vs PvContrib", {HistType::kTHnSparseF, axesPtVsCentVsBDTVsPvContrib}, true); + registry.add("Efficiency/hPtNonPrompRectVsCentVsBDTScorePvContribRecSig", "Pt Vs Cent Vs BDTScore", {HistType::kTHnSparseF, axesPtVsCentVsBDTVsPvContrib}, true); // registry.add("Efficiency/hPtBkgVsCentVsBDTScore", "Pt Vs Cent Vs BDTScore", {HistType::kTHnSparseF, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}, {axisCentrality}, {axisBDTScoreBackground}, {axisBDTScorePrompt}, {axisBDTScoreNonPrompt}}}); + } else if (doprocessMcWML && !isCentStudy) { + registry.add("Efficiency/hPtVsBDTScoreRecSig", "Pt Vs BDTScore", {HistType::kTHnSparseF, axesPtVsBDT}, true); + registry.add("Efficiency/hPtPromptVsBDTScoreRecSig", "Pt Vs BDTScore", {HistType::kTHnSparseF, axesPtVsBDT}, true); + registry.add("Efficiency/hPtNonPromptVsBDTScoreRecSig", "Pt Vs BDTScore", {HistType::kTHnSparseF, axesPtVsBDT}, true); + } + + // Hists at Gen level usefull for efficiency calculation + if (doprocessMcWoMl || doprocessMcWML) { + if (isCentStudy) { + registry.add("Efficiency/hPtVsCentVsPvContribGen", "Pt Vs Cent Vs PvContrib", {HistType::kTHnSparseF, axesPtVsCentVsPvContrib}, true); + registry.add("Efficiency/hPtPromptVsCentVsPvContribGen", "Pt Vs Cent Vs PvContrib", {HistType::kTHnSparseF, axesPtVsCentVsPvContrib}, true); + registry.add("Efficiency/hPtNonPromptVsCentVsPvContribGen", "Pt Vs Cent Vs PvContrib", {HistType::kTHnSparseF, axesPtVsCentVsPvContrib}, true); + } else { + registry.add("Efficiency/hPtGen", "MC Matched D* Candidates at Generator Level", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}, true); + registry.add("Efficiency/hPtPromptVsGen", "MC Matched Prompt D* Candidates at Generator Level", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}, true); + registry.add("Efficiency/hPtNonPromptVsGen", "MC Matched Non-Prompt D* Candidates at Generator Level", {HistType::kTH1F, {{vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}, true); + } + } + + // if weights to be applied + if (useWeight) { + ccdbApi.init(ccdbUrl); + std::map metadata; + // Retrieve the file from CCDB + bool isFileAvailable = ccdbApi.retrieveBlob(ccdbPathForWeight, ".", metadata, timestampCCDB, false, weightFileName); + if (!isFileAvailable) { + LOGF(fatal, "Failed to retrieve weight file from CCDB: %s", ccdbPathForWeight.value.c_str()); + return; + } + + if (isCentStudy) { + // Open the ROOT file + TFile* weightFile = TFile::Open(weightFileName.value.c_str(), "READ"); + if (weightFile && !weightFile->IsZombie()) { + // Ensure hWeights is properly sized + hWeights.resize(nWeights); + for (int ithWeight = 0; ithWeight < nWeights; ++ithWeight) { + std::string histName = "hMult" + std::to_string(ithWeight + 1) + "_Weight"; + hWeights[ithWeight] = reinterpret_cast(weightFile->Get(histName.c_str())); + if (!hWeights[ithWeight]) { + LOGF(fatal, "Histogram %s not found in weight file!", histName.c_str()); + return; + } + hWeights[ithWeight]->SetDirectory(0); + hWeights[ithWeight]->SetName(("hWeight" + std::to_string(ithWeight + 1)).c_str()); + } + weightFile->Close(); + delete weightFile; + } else { + LOGF(fatal, "Failed to open weight file from CCDB: %s", weightFileName.value.c_str()); + return; + } + } } } @@ -220,7 +323,6 @@ struct HfTaskDstarToD0Pi { auto nCandsCurrentCol = selectedCandsCurrentCol.size(); if (nCandsCurrentCol > 0) { - // LOGF(debug, "size of selectedCandsCurrentCol: %d", nCandsCurrentCol); registry.fill(HIST("Efficiency/hNumPvContributorsCand"), nPVContributors, centrality); } @@ -231,28 +333,30 @@ struct HfTaskDstarToD0Pi { continue; } - registry.fill(HIST("QA/hPtDstar"), candDstar.pt()); - registry.fill(HIST("QA/hPtD0"), candDstar.ptD0()); - registry.fill(HIST("QA/hPtSoftPi"), candDstar.ptSoftPi()); - registry.fill(HIST("QA/hEtaDstar"), candDstar.eta(), candDstar.pt()); - registry.fill(HIST("QA/hCtD0"), candDstar.ctD0(), candDstar.pt()); - registry.fill(HIST("QA/hDecayLengthD0"), candDstar.decayLengthD0(), candDstar.pt()); - registry.fill(HIST("QA/hDecayLengthXYD0"), candDstar.decayLengthXYD0(), candDstar.pt()); - registry.fill(HIST("QA/hDecayLengthNormalisedD0"), candDstar.decayLengthNormalisedD0(), candDstar.pt()); - registry.fill(HIST("QA/hDecayLengthXYNormalisedD0"), candDstar.decayLengthXYNormalisedD0(), candDstar.pt()); - registry.fill(HIST("QA/hCPAD0"), candDstar.cpaD0(), candDstar.pt()); - registry.fill(HIST("QA/hCPAxyD0"), candDstar.cpaXYD0(), candDstar.pt()); - registry.fill(HIST("QA/hImpactParameterXYD0"), candDstar.impactParameterXYD0(), candDstar.pt()); - registry.fill(HIST("QA/hDeltaIPMaxNormalisedD0"), candDstar.deltaIPNormalisedMaxD0(), candDstar.pt()); - registry.fill(HIST("QA/hSqSumProngsImpactParameterD0"), candDstar.impactParameterProngSqSumD0(), candDstar.pt()); - registry.fill(HIST("QA/hDecayLengthErrorD0"), candDstar.errorDecayLengthD0(), candDstar.pt()); - registry.fill(HIST("QA/hDecayLengthXYErrorD0"), candDstar.errorDecayLengthXYD0(), candDstar.pt()); - registry.fill(HIST("QA/hImpactParameterError"), candDstar.errorImpactParameter0(), candDstar.pt()); - registry.fill(HIST("QA/hImpactParameterError"), candDstar.errorImpactParameter1(), candDstar.pt()); - registry.fill(HIST("QA/hImpactParameterError"), candDstar.errorImpParamSoftPi(), candDstar.pt()); - registry.fill(HIST("QA/hd0Prong0"), candDstar.impactParameter0(), candDstar.pt()); - registry.fill(HIST("QA/hd0Prong1"), candDstar.impactParameter1(), candDstar.pt()); - registry.fill(HIST("QA/hd0ProngSoftPi"), candDstar.impParamSoftPi(), candDstar.pt()); + if (qaEnabled) { + registry.fill(HIST("QA/hPtDstar"), candDstar.pt()); + registry.fill(HIST("QA/hPtD0"), candDstar.ptD0()); + registry.fill(HIST("QA/hPtSoftPi"), candDstar.ptSoftPi()); + registry.fill(HIST("QA/hEtaDstar"), candDstar.eta(), candDstar.pt()); + registry.fill(HIST("QA/hCtD0"), candDstar.ctD0(), candDstar.pt()); + registry.fill(HIST("QA/hDecayLengthD0"), candDstar.decayLengthD0(), candDstar.pt()); + registry.fill(HIST("QA/hDecayLengthXYD0"), candDstar.decayLengthXYD0(), candDstar.pt()); + registry.fill(HIST("QA/hDecayLengthNormalisedD0"), candDstar.decayLengthNormalisedD0(), candDstar.pt()); + registry.fill(HIST("QA/hDecayLengthXYNormalisedD0"), candDstar.decayLengthXYNormalisedD0(), candDstar.pt()); + registry.fill(HIST("QA/hCPAD0"), candDstar.cpaD0(), candDstar.pt()); + registry.fill(HIST("QA/hCPAxyD0"), candDstar.cpaXYD0(), candDstar.pt()); + registry.fill(HIST("QA/hImpactParameterXYD0"), candDstar.impactParameterXYD0(), candDstar.pt()); + registry.fill(HIST("QA/hDeltaIPMaxNormalisedD0"), candDstar.deltaIPNormalisedMaxD0(), candDstar.pt()); + registry.fill(HIST("QA/hSqSumProngsImpactParameterD0"), candDstar.impactParameterProngSqSumD0(), candDstar.pt()); + registry.fill(HIST("QA/hDecayLengthErrorD0"), candDstar.errorDecayLengthD0(), candDstar.pt()); + registry.fill(HIST("QA/hDecayLengthXYErrorD0"), candDstar.errorDecayLengthXYD0(), candDstar.pt()); + registry.fill(HIST("QA/hImpactParameterError"), candDstar.errorImpactParameter0(), candDstar.pt()); + registry.fill(HIST("QA/hImpactParameterError"), candDstar.errorImpactParameter1(), candDstar.pt()); + registry.fill(HIST("QA/hImpactParameterError"), candDstar.errorImpParamSoftPi(), candDstar.pt()); + registry.fill(HIST("QA/hd0Prong0"), candDstar.impactParameter0(), candDstar.pt()); + registry.fill(HIST("QA/hd0Prong1"), candDstar.impactParameter1(), candDstar.pt()); + registry.fill(HIST("QA/hd0ProngSoftPi"), candDstar.impParamSoftPi(), candDstar.pt()); + } auto invDstar = candDstar.invMassDstar(); auto invAntiDstar = candDstar.invMassAntiDstar(); @@ -262,7 +366,7 @@ struct HfTaskDstarToD0Pi { auto signDstar = candDstar.signSoftPi(); if (signDstar > 0) { auto deltaMDstar = std::abs(invDstar - invD0); - if (0.142f < deltaMDstar && deltaMDstar < 0.15f) { + if (deltaMassMin < deltaMDstar && deltaMDstar < deltaMassMax) { nCandsSignalRegion++; } @@ -271,17 +375,21 @@ struct HfTaskDstarToD0Pi { registry.fill(HIST("Yield/hDeltaInvMassVsPtVsCentVsBDTScore"), deltaMDstar, candDstar.pt(), centrality, mlBdtScore[0], mlBdtScore[1], mlBdtScore[2]); } - registry.fill(HIST("Yield/hDeltaInvMassDstar3D"), deltaMDstar, candDstar.pt(), centrality); - registry.fill(HIST("Yield/hDeltaInvMassDstar2D"), deltaMDstar, candDstar.pt()); + if (doprocessDataWoML) { + registry.fill(HIST("Yield/hDeltaInvMassDstar3D"), deltaMDstar, candDstar.pt(), centrality); + registry.fill(HIST("Yield/hDeltaInvMassDstar2D"), deltaMDstar, candDstar.pt()); + } registry.fill(HIST("Yield/hInvMassD0"), invD0, candDstar.ptD0()); registry.fill(HIST("Yield/hDeltaInvMassDstar1D"), deltaMDstar); registry.fill(HIST("Yield/hInvMassDstar"), invDstar); // filling pt of two pronges of D0 - registry.fill(HIST("QA/hPtProng0D0"), candDstar.ptProng0()); - registry.fill(HIST("QA/hPtProng1D0"), candDstar.ptProng1()); + if (qaEnabled) { + registry.fill(HIST("QA/hPtProng0D0"), candDstar.ptProng0()); + registry.fill(HIST("QA/hPtProng1D0"), candDstar.ptProng1()); + } } else if (signDstar < 0) { auto deltaMAntiDstar = std::abs(invAntiDstar - invD0Bar); - if (0.142f < deltaMAntiDstar && deltaMAntiDstar < 0.15f) { + if (deltaMassMin < deltaMAntiDstar && deltaMAntiDstar < deltaMassMax) { nCandsSignalRegion++; } @@ -290,14 +398,19 @@ struct HfTaskDstarToD0Pi { registry.fill(HIST("Yield/hDeltaInvMassVsPtVsCentVsBDTScore"), deltaMAntiDstar, candDstar.pt(), centrality, mlBdtScore[0], mlBdtScore[1], mlBdtScore[2]); } - registry.fill(HIST("Yield/hDeltaInvMassDstar3D"), deltaMAntiDstar, candDstar.pt(), centrality); - registry.fill(HIST("Yield/hDeltaInvMassDstar2D"), deltaMAntiDstar, candDstar.pt()); + if (doprocessDataWoML) { + registry.fill(HIST("Yield/hDeltaInvMassDstar3D"), deltaMAntiDstar, candDstar.pt(), centrality); + registry.fill(HIST("Yield/hDeltaInvMassDstar2D"), deltaMAntiDstar, candDstar.pt()); + } + registry.fill(HIST("Yield/hInvMassD0"), invD0Bar, candDstar.ptD0()); registry.fill(HIST("Yield/hDeltaInvMassDstar1D"), deltaMAntiDstar); registry.fill(HIST("Yield/hInvMassDstar"), invAntiDstar); // filling pt of two pronges of D0Bar - registry.fill(HIST("QA/hPtProng0D0Bar"), candDstar.ptProng0()); - registry.fill(HIST("QA/hPtProng1D0Bar"), candDstar.ptProng1()); + if (qaEnabled) { + registry.fill(HIST("QA/hPtProng0D0Bar"), candDstar.ptProng0()); + registry.fill(HIST("QA/hPtProng1D0Bar"), candDstar.ptProng1()); + } } } // candidate loop for current collision ends @@ -315,11 +428,9 @@ struct HfTaskDstarToD0Pi { template void runMcRecTaskDstar(T1 const& candsMcRecSel, CandDstarMcGen const& rowsMcPartilces) { - // LOGF(info, "Running MC Rec Task Dstar"); int8_t signDstar = 0; // MC at Reconstruction level for (const auto& candDstarMcRec : candsMcRecSel) { - // LOGF(info, "MC Rec Dstar loop"); auto ptDstarRecSig = candDstarMcRec.pt(); auto yDstarRecSig = candDstarMcRec.y(constants::physics::MassDStar); if (yCandDstarRecoMax >= 0. && std::abs(yDstarRecSig) > yCandDstarRecoMax) { @@ -327,72 +438,115 @@ struct HfTaskDstarToD0Pi { } auto collision = candDstarMcRec.template collision_as(); auto centrality = collision.centFT0M(); // 0-100% + auto nPVContributors = collision.numContrib(); // number of PV contributors if (std::abs(candDstarMcRec.flagMcMatchRec()) == hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi) { // if MC matching is successful at Reconstruction Level - // LOGF(info, "MC Rec Dstar loop MC Matched"); // get MC Mother particle auto prong0 = candDstarMcRec.template prong0_as(); auto indexMother = RecoDecay::getMother(rowsMcPartilces, prong0.template mcParticle_as(), o2::constants::physics::Pdg::kDStar, true, &signDstar, 2); - auto particleMother = rowsMcPartilces.rawIteratorAt(indexMother); // What is difference between rawIterator() or iteratorAt() methods? - registry.fill(HIST("QA/hPtSkimDstarGenSig"), particleMother.pt()); // generator level pt - registry.fill(HIST("Efficiency/hPtVsCentSkimDstarGenSig"), particleMother.pt(), centrality); - - registry.fill(HIST("QA/hPtVsYSkimDstarRecSig"), ptDstarRecSig, yDstarRecSig); // Skimed at level of trackIndexSkimCreator - if (candDstarMcRec.isRecoTopol()) { // if Topological selection are passed - registry.fill(HIST("QA/hPtVsYRecoTopolDstarRecSig"), ptDstarRecSig, yDstarRecSig); - } - if (candDstarMcRec.isRecoPid()) { // if PID selection is passed - registry.fill(HIST("QA/hPtVsYRecoPidDstarRecSig"), ptDstarRecSig, yDstarRecSig); - } - if (candDstarMcRec.isSelDstarToD0Pi()) { // if all selection passed - registry.fill(HIST("QA/hPtFullRecoDstarRecSig"), ptDstarRecSig); - registry.fill(HIST("Efficiency/hPtVsCentFullRecoDstarRecSig"), ptDstarRecSig, centrality); - if constexpr (applyMl) { - auto bdtScore = candDstarMcRec.mlProbDstarToD0Pi(); - registry.fill(HIST("Efficiency/hPtVsCentVsBDTScore"), ptDstarRecSig, centrality, bdtScore[0], bdtScore[1], bdtScore[2]); - } - } - registry.fill(HIST("QA/hCPASkimD0RecSig"), candDstarMcRec.cpaD0()); - registry.fill(HIST("QA/hEtaSkimD0RecSig"), candDstarMcRec.etaD0()); - registry.fill(HIST("QA/hEtaSkimDstarRecSig"), candDstarMcRec.eta()); - - // only prompt signal at reconstruction level - if (candDstarMcRec.originMcRec() == RecoDecay::OriginType::Prompt) { - registry.fill(HIST("QA/hPtVsYSkimPromptDstarRecSig"), ptDstarRecSig, yDstarRecSig); // Skimed at level of trackIndexSkimCreator - if (candDstarMcRec.isRecoTopol()) { // if Topological selection are passed - registry.fill(HIST("QA/hPtVsYRecoTopolPromptDstarRecSig"), ptDstarRecSig, yDstarRecSig); + auto particleMother = rowsMcPartilces.rawIteratorAt(indexMother); // What is difference between rawIterator() or iteratorAt() methods? + if (qaEnabled) { + registry.fill(HIST("QA/hPtSkimDstarGenSig"), particleMother.pt()); // generator level pt + registry.fill(HIST("QA/hPtVsCentSkimDstarGenSig"), particleMother.pt(), centrality); + registry.fill(HIST("QA/hPtVsYSkimDstarRecSig"), ptDstarRecSig, yDstarRecSig); // Skimed at level of trackIndexSkimCreator + if (candDstarMcRec.isRecoTopol()) { // if Topological selection are passed + registry.fill(HIST("QA/hPtVsYRecoTopolDstarRecSig"), ptDstarRecSig, yDstarRecSig); } if (candDstarMcRec.isRecoPid()) { // if PID selection is passed - registry.fill(HIST("QA/hPtVsYRecoPidPromptDstarRecSig"), ptDstarRecSig, yDstarRecSig); + registry.fill(HIST("QA/hPtVsYRecoPidDstarRecSig"), ptDstarRecSig, yDstarRecSig); } - if (candDstarMcRec.isSelDstarToD0Pi()) { // if all selection passed - registry.fill(HIST("QA/hPtFullRecoPromptDstarRecSig"), ptDstarRecSig); - if constexpr (applyMl) { - auto bdtScore = candDstarMcRec.mlProbDstarToD0Pi(); - registry.fill(HIST("Efficiency/hPtPromptVsCentVsBDTScore"), ptDstarRecSig, centrality, bdtScore[0], bdtScore[1], bdtScore[2]); + } + + if (candDstarMcRec.isSelDstarToD0Pi()) { // if all selection passed + float weightValue = 1.0; + if (useWeight && (hWeights.size() < 1 || hWeights[0] == nullptr)) { + LOGF(fatal, "Weight histograms are not initialized or empty. Check CCDB path or weight file."); + return; + } else if (useWeight && isCentStudy) { + for (int ithWeight = 0; ithWeight < nWeights; ++ithWeight) { + if (centrality > centRangesForWeights.value[ithWeight] && centrality <= centRangesForWeights.value[ithWeight + 1]) { + weightValue = hWeights[ithWeight]->GetBinContent(hWeights[ithWeight]->FindBin(nPVContributors)); + break; + } } } - } else if (candDstarMcRec.originMcRec() == RecoDecay::OriginType::NonPrompt) { // only non-prompt signal at reconstruction level - registry.fill(HIST("QA/hPtVsYSkimNonPromptDstarRecSig"), ptDstarRecSig, yDstarRecSig); - if (candDstarMcRec.isRecoTopol()) { // if Topological selection are passed - registry.fill(HIST("QA/hPtVsYRecoTopolNonPromptDstarRecSig"), ptDstarRecSig, yDstarRecSig); - } - if (candDstarMcRec.isRecoPid()) { // if PID selection is passed - registry.fill(HIST("QA/hPtVsYRecoPidNonPromptDstarRecSig"), ptDstarRecSig, yDstarRecSig); + if (qaEnabled) { + registry.fill(HIST("QA/hPtFullRecoDstarRecSig"), ptDstarRecSig); } - if (candDstarMcRec.isSelDstarToD0Pi()) { // if all selection passed - registry.fill(HIST("QA/hPtFullRecoNonPromptDstarRecSig"), ptDstarRecSig); - if constexpr (applyMl) { + + if constexpr (applyMl) { // All efficiency histograms at reconstruction level w/ ml + if (isCentStudy) { auto bdtScore = candDstarMcRec.mlProbDstarToD0Pi(); - registry.fill(HIST("Efficiency/hPtNonPromptVsCentVsBDTScore"), ptDstarRecSig, centrality, bdtScore[0], bdtScore[1], bdtScore[2]); + registry.fill(HIST("Efficiency/hPtVsCentVsBDTScoreVsPvContribRecSig"), ptDstarRecSig, centrality, bdtScore[0], bdtScore[1], bdtScore[2], nPVContributors, weightValue); + if (candDstarMcRec.originMcRec() == RecoDecay::OriginType::Prompt) { + registry.fill(HIST("Efficiency/hPtPromptVsCentVsBDTScorePvContribRecSig"), ptDstarRecSig, centrality, bdtScore[0], bdtScore[1], bdtScore[2], nPVContributors, weightValue); + } else if (candDstarMcRec.originMcRec() == RecoDecay::OriginType::NonPrompt) { + registry.fill(HIST("Efficiency/hPtNonPrompRectVsCentVsBDTScorePvContribRecSig"), ptDstarRecSig, centrality, bdtScore[0], bdtScore[1], bdtScore[2], nPVContributors, weightValue); + } + } else { + auto bdtScore = candDstarMcRec.mlProbDstarToD0Pi(); + registry.fill(HIST("Efficiency/hPtVsBDTScoreRecSig"), ptDstarRecSig, bdtScore[0], bdtScore[1], bdtScore[2], weightValue); + if (candDstarMcRec.originMcRec() == RecoDecay::OriginType::Prompt) { + registry.fill(HIST("Efficiency/hPtPromptVsBDTScoreRecSig"), ptDstarRecSig, bdtScore[0], bdtScore[1], bdtScore[2], weightValue); + } else if (candDstarMcRec.originMcRec() == RecoDecay::OriginType::NonPrompt) { + registry.fill(HIST("Efficiency/hPtNonPromptVsBDTScoreRecSig"), ptDstarRecSig, bdtScore[0], bdtScore[1], bdtScore[2], weightValue); + } + } + } else { // All efficiency histograms at reconstruction level w/o ml + if (isCentStudy) { + registry.fill(HIST("Efficiency/hPtVsCentVsPvContribRecSig"), ptDstarRecSig, centrality, nPVContributors, weightValue); + if (candDstarMcRec.originMcRec() == RecoDecay::OriginType::Prompt) { + registry.fill(HIST("Efficiency/hPtPromptVsCentVsPvContribRecSig"), ptDstarRecSig, centrality, nPVContributors, weightValue); + } else if (candDstarMcRec.originMcRec() == RecoDecay::OriginType::NonPrompt) { + registry.fill(HIST("Efficiency/hPtNonPromptVsCentVsPvContribRecSig"), ptDstarRecSig, centrality, nPVContributors, weightValue); + } + } else { + registry.fill(HIST("Efficiency/hPtVsPvContribRecSig"), ptDstarRecSig, nPVContributors, weightValue); + if (candDstarMcRec.originMcRec() == RecoDecay::OriginType::Prompt) { + registry.fill(HIST("Efficiency/hPtPromptVsPvContribRecSig"), ptDstarRecSig, nPVContributors, weightValue); + } else if (candDstarMcRec.originMcRec() == RecoDecay::OriginType::NonPrompt) { + registry.fill(HIST("Efficiency/hPtNonPromptVsPvContribRecSig"), ptDstarRecSig, nPVContributors, weightValue); + } + } + } + } + if (qaEnabled) { + registry.fill(HIST("QA/hCPASkimD0RecSig"), candDstarMcRec.cpaD0()); + registry.fill(HIST("QA/hEtaSkimD0RecSig"), candDstarMcRec.etaD0()); + registry.fill(HIST("QA/hEtaSkimDstarRecSig"), candDstarMcRec.eta()); + + // only prompt signal at reconstruction level + if (candDstarMcRec.originMcRec() == RecoDecay::OriginType::Prompt) { + registry.fill(HIST("QA/hPtVsYSkimPromptDstarRecSig"), ptDstarRecSig, yDstarRecSig); // Skimed at level of trackIndexSkimCreator + if (candDstarMcRec.isRecoTopol()) { // if Topological selection are passed + registry.fill(HIST("QA/hPtVsYRecoTopolPromptDstarRecSig"), ptDstarRecSig, yDstarRecSig); + } + if (candDstarMcRec.isRecoPid()) { // if PID selection is passed + registry.fill(HIST("QA/hPtVsYRecoPidPromptDstarRecSig"), ptDstarRecSig, yDstarRecSig); + } + if (candDstarMcRec.isSelDstarToD0Pi()) { // if all selection passed + registry.fill(HIST("QA/hPtFullRecoPromptDstarRecSig"), ptDstarRecSig); + } + } else if (candDstarMcRec.originMcRec() == RecoDecay::OriginType::NonPrompt) { // only non-prompt signal at reconstruction level + registry.fill(HIST("QA/hPtVsYSkimNonPromptDstarRecSig"), ptDstarRecSig, yDstarRecSig); + if (candDstarMcRec.isRecoTopol()) { // if Topological selection are passed + registry.fill(HIST("QA/hPtVsYRecoTopolNonPromptDstarRecSig"), ptDstarRecSig, yDstarRecSig); + } + if (candDstarMcRec.isRecoPid()) { // if PID selection is passed + registry.fill(HIST("QA/hPtVsYRecoPidNonPromptDstarRecSig"), ptDstarRecSig, yDstarRecSig); + } + if (candDstarMcRec.isSelDstarToD0Pi()) { // if all selection passed + registry.fill(HIST("QA/hPtFullRecoNonPromptDstarRecSig"), ptDstarRecSig); } } } } else { // MC Unmatched (Baground at Reconstruction Level) - registry.fill(HIST("QA/hCPASkimD0RecBg"), candDstarMcRec.cpaD0()); - registry.fill(HIST("QA/hEtaSkimD0RecBg"), candDstarMcRec.etaD0()); - registry.fill(HIST("QA/hEtaSkimDstarRecBg"), candDstarMcRec.eta()); - if (candDstarMcRec.isSelDstarToD0Pi()) { - registry.fill(HIST("QA/hPtSkimDstarRecBg"), candDstarMcRec.pt()); + if (qaEnabled) { + registry.fill(HIST("QA/hCPASkimD0RecBg"), candDstarMcRec.cpaD0()); + registry.fill(HIST("QA/hEtaSkimD0RecBg"), candDstarMcRec.etaD0()); + registry.fill(HIST("QA/hEtaSkimDstarRecBg"), candDstarMcRec.eta()); + if (candDstarMcRec.isSelDstarToD0Pi()) { + registry.fill(HIST("QA/hPtSkimDstarRecBg"), candDstarMcRec.pt()); + } } } } // candidate loop ends @@ -411,16 +565,24 @@ struct HfTaskDstarToD0Pi { if (yCandDstarGenMax >= 0. && std::abs(yGen) > yCandDstarGenMax) { continue; } + auto mcCollision = mcParticle.template mcCollision_as(); auto recCollisions = collisions.sliceBy(colsPerMcCollision, mcCollision.globalIndex()); - // looking if a generated collision reconstructed more than a times. - if (recCollisions.size() > 1) { - for (const auto& [c1, c2] : combinations(CombinationsStrictlyUpperIndexPolicy(recCollisions, recCollisions))) { - auto deltaCent = std::abs(c1.centFT0M() - c2.centFT0M()); - registry.fill(HIST("QA/hDeltaCentGen"), deltaCent); + if (qaEnabled) { + registry.fill(HIST("QA/hEtaDstarGen"), mcParticle.eta()); + registry.fill(HIST("QA/hPtDstarGen"), ptGen); + + // looking if a generated collision reconstructed more than a times. + if (recCollisions.size() > 1) { + for (const auto& [c1, c2] : combinations(CombinationsStrictlyUpperIndexPolicy(recCollisions, recCollisions))) { + auto deltaCent = std::abs(c1.centFT0M() - c2.centFT0M()); + registry.fill(HIST("QA/hDeltaCentGen"), deltaCent); + } } } + float centFT0MGen; + float pvContributors; // assigning centrality to MC Collision using max FT0M amplitute from Reconstructed collisions if (recCollisions.size()) { std::vector::iterator, int>> tempRecCols; @@ -429,20 +591,49 @@ struct HfTaskDstarToD0Pi { } std::sort(tempRecCols.begin(), tempRecCols.end(), compare); centFT0MGen = tempRecCols.at(0).first.centFT0M(); + pvContributors = tempRecCols.at(0).second; } else { centFT0MGen = -999.; + pvContributors = -999.; + } + + float weightValue = 1.0; + if (useWeight && (hWeights.size() < 1 || hWeights[0] == nullptr)) { + LOGF(fatal, "Weight histograms are not initialized or empty. Check CCDB path or weight file."); + return; + } else if (useWeight && isCentStudy) { + for (int ithWeight = 0; ithWeight < nWeights; ++ithWeight) { + if (centFT0MGen > centRangesForWeights.value[ithWeight] && centFT0MGen <= centRangesForWeights.value[ithWeight + 1]) { + weightValue = hWeights[ithWeight]->GetBinContent(hWeights[ithWeight]->FindBin(centFT0MGen, pvContributors)); + break; + } + } + } + + registry.fill(HIST("Efficiency/hPtVsYDstarGen"), ptGen, yGen, weightValue); + if (isCentStudy) { + registry.fill(HIST("Efficiency/hPtVsCentVsPvContribGen"), ptGen, centFT0MGen, pvContributors, weightValue); + } else { + registry.fill(HIST("Efficiency/hPtGen"), ptGen, weightValue); } - registry.fill(HIST("QA/hEtaDstarGen"), mcParticle.eta()); - registry.fill(HIST("QA/hPtDstarGen"), ptGen); - registry.fill(HIST("QA/hPtVsYDstarGen"), ptGen, yGen); - registry.fill(HIST("Efficiency/hPtVsCentDstarGen"), ptGen, centFT0MGen); - // only promt Dstar candidate at Generator level + + // Prompt if (mcParticle.originMcGen() == RecoDecay::OriginType::Prompt) { - registry.fill(HIST("QA/hPtPromptDstarGen"), ptGen); - registry.fill(HIST("QA/hPtVsYPromptDstarGen"), ptGen, yGen); - } else if (mcParticle.originMcGen() == RecoDecay::OriginType::NonPrompt) { // only non-prompt Dstar candidate at Generator level - registry.fill(HIST("QA/hPtNonPromptDstarGen"), ptGen); - registry.fill(HIST("QA/hPtVsYNonPromptDstarGen"), ptGen, yGen); + registry.fill(HIST("Efficiency/hPtVsYPromptDstarGen"), ptGen, yGen, weightValue); + if (isCentStudy) { + registry.fill(HIST("Efficiency/hPtPromptVsCentVsPvContribGen"), ptGen, centFT0MGen, pvContributors, weightValue); + } else { + registry.fill(HIST("Efficiency/hPtPromptVsGen"), ptGen, weightValue); + } + // Non-Prompt + } else if (mcParticle.originMcGen() == RecoDecay::OriginType::NonPrompt) { + registry.fill(HIST("Efficiency/hPtVsYNonPromptDstarGen"), ptGen, yGen, weightValue); + if (isCentStudy) { + registry.fill(HIST("Efficiency/hPtNonPromptVsCentVsPvContribGen"), ptGen, centFT0MGen, pvContributors, weightValue); + + } else { + registry.fill(HIST("Efficiency/hPtNonPromptVsGen"), ptGen, weightValue); + } } } } // MC Particle loop ends diff --git a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx index 7960aeb7f4f..5666daeaacb 100644 --- a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx +++ b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx @@ -317,10 +317,10 @@ struct HfTaskFlowCharmHadrons { /// \param tracksQy is the Y component of the Q vector for the tracks /// \param channel is the decay channel template - void getQvecDtracks(const T1& cand, + void getQvecDtracks(T1 const& cand, std::vector& tracksQx, std::vector& tracksQy, - float& ampl) + const float ampl) { // TODO: add possibility to consider different weights for the tracks, at the moment only pT is considered; float pXTrack0 = cand.pxProng0(); @@ -398,7 +398,7 @@ struct HfTaskFlowCharmHadrons { /// Get the event selection flags /// \param hfevselflag is the event selection flag - std::vector getEventSelectionFlags(uint32_t hfevselflag) + std::vector getEventSelectionFlags(const o2::hf_evsel::HfCollisionRejectionMask hfevselflag) { return { TESTBIT(hfevselflag, o2::hf_evsel::EventRejection::NoSameBunchPileup), @@ -419,16 +419,16 @@ struct HfTaskFlowCharmHadrons { /// \param outputMl are the ML scores /// \param occupancy is the occupancy of the collision using the track estimator /// \param hfevselflag flag of the collision associated to utilsEvSelHf.h - void fillThn(float& mass, - float& pt, - float& cent, - float& cosNPhi, - float& sinNPhi, - float& cosDeltaPhi, - float& sp, - std::vector& outputMl, - float& occupancy, - uint32_t& hfevselflag) + void fillThn(const float mass, + const float pt, + const float cent, + const float cosNPhi, + const float sinNPhi, + const float cosDeltaPhi, + const float sp, + const std::vector& outputMl, + const float occupancy, + const o2::hf_evsel::HfCollisionRejectionMask hfevselflag) { if (occEstimator != 0) { std::vector evtSelFlags = getEventSelectionFlags(hfevselflag); @@ -476,7 +476,7 @@ struct HfTaskFlowCharmHadrons { aod::BCsWithTimestamps const&, float& centrality) { - float occupancy = getOccupancyColl(collision, occEstimator); + const auto occupancy = o2::hf_occupancy::getOccupancyColl(collision, occEstimator); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); centrality = o2::hf_centrality::getCentralityColl(collision, centEstimator); @@ -546,9 +546,9 @@ struct HfTaskFlowCharmHadrons { return; } float occupancy = 0.; - uint32_t hfevflag{}; + o2::hf_evsel::HfCollisionRejectionMask hfevflag{}; if (occEstimator != 0) { - occupancy = getOccupancyColl(collision, occEstimator); + occupancy = o2::hf_occupancy::getOccupancyColl(collision, occEstimator); registry.fill(HIST("trackOccVsFT0COcc"), collision.trackOccupancyInTimeRange(), collision.ft0cOccupancyInTimeRange()); hfevflag = hfEvSel.getHfCollisionRejectionMask(collision, cent, ccdb, registry); } @@ -668,7 +668,7 @@ struct HfTaskFlowCharmHadrons { // If TPC is used for the SP estimation, the tracks of the hadron candidate must be removed from the TPC Q vector to avoid double counting if (qvecDetector == QvecEstimator::TPCNeg || qvecDetector == QvecEstimator::TPCPos) { - float ampl = amplQVec - static_cast(nProngs); + float const ampl = amplQVec - static_cast(nProngs); std::vector tracksQx = {}; std::vector tracksQy = {}; if constexpr (std::is_same_v || std::is_same_v) { @@ -846,11 +846,10 @@ struct HfTaskFlowCharmHadrons { centrality = o2::hf_centrality::getCentralityColl(collision, o2::hf_centrality::CentralityEstimator::FT0C); if (storeResoOccu) { - float occupancy{-1.f}; - occupancy = getOccupancyColl(collision, occEstimator); + const auto occupancy = o2::hf_occupancy::getOccupancyColl(collision, occEstimator); registry.fill(HIST("trackOccVsFT0COcc"), collision.trackOccupancyInTimeRange(), collision.ft0cOccupancyInTimeRange()); - uint32_t hfevflag = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); - std::vector evtSelFlags = getEventSelectionFlags(hfevflag); + const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + std::vector evtSelFlags = getEventSelectionFlags(rejectionMask); registry.fill(HIST("spReso/hSparseReso"), centrality, xQVecFT0c * xQVecFV0a + yQVecFT0c * yQVecFV0a, xQVecFT0c * xQVecBTot + yQVecFT0c * yQVecBTot, xQVecFV0a * xQVecBTot + yQVecFV0a * yQVecBTot, diff --git a/PWGHF/D2H/Utils/utilsRedDataFormat.h b/PWGHF/D2H/Utils/utilsRedDataFormat.h index 4e4bc2b9b3c..f5115e59ac0 100644 --- a/PWGHF/D2H/Utils/utilsRedDataFormat.h +++ b/PWGHF/D2H/Utils/utilsRedDataFormat.h @@ -82,6 +82,30 @@ float getTpcTofNSigmaPi1(const T1& prong1) return defaultNSigma; } +/// Helper function to retrive PID information of bachelor pion from b-hadron decay +/// \param prongSoftPi soft pion track +template +float getTpcTofNSigmaSoftPi(const T1& prongSoftPi) +{ + float defaultNSigma = -999.f; // -999.f is the default value set in TPCPIDResponse.h and PIDTOF.h + + bool hasTpc = prongSoftPi.hasTPC(); + bool hasTof = prongSoftPi.hasTOF(); + + if (hasTpc && hasTof) { + float tpcNSigma = prongSoftPi.tpcNSigmaPiSoftPi(); + float tofNSigma = prongSoftPi.tofNSigmaPiSoftPi(); + return std::sqrt(.5f * tpcNSigma * tpcNSigma + .5f * tofNSigma * tofNSigma); + } + if (hasTpc) { + return std::abs(prongSoftPi.tpcNSigmaPiSoftPi()); + } + if (hasTof) { + return std::abs(prongSoftPi.tofNSigmaPiSoftPi()); + } + return defaultNSigma; +} + /// Helper function to retrive PID information of bachelor kaon from b-hadron decay /// \param prong1 kaon track from reduced data format, aod::HfRedBachProng0Tracks /// \return the combined TPC and TOF n-sigma for kaon diff --git a/PWGHF/DataModel/CandidateReconstructionTables.h b/PWGHF/DataModel/CandidateReconstructionTables.h index 8af9f18162d..9fddeb3551d 100644 --- a/PWGHF/DataModel/CandidateReconstructionTables.h +++ b/PWGHF/DataModel/CandidateReconstructionTables.h @@ -18,7 +18,9 @@ #ifndef PWGHF_DATAMODEL_CANDIDATERECONSTRUCTIONTABLES_H_ #define PWGHF_DATAMODEL_CANDIDATERECONSTRUCTIONTABLES_H_ +#include "PWGHF/Utils/utilsEvSelHf.h" #include "PWGHF/Utils/utilsPid.h" +// #include "PWGLF/DataModel/LFStrangenessTables.h" #include "ALICE3/DataModel/ECAL.h" @@ -192,7 +194,7 @@ DECLARE_SOA_TABLE(PidTpcTofTinyPr, "AOD", "PIDTPCTOFTINYPR", //! Table of the TP namespace hf_sel_collision { -DECLARE_SOA_COLUMN(WhyRejectColl, whyRejectColl, uint32_t); //! +DECLARE_SOA_COLUMN(WhyRejectColl, whyRejectColl, o2::hf_evsel::HfCollisionRejectionMask); //! } // namespace hf_sel_collision DECLARE_SOA_TABLE(HfSelCollision, "AOD", "HFSELCOLLISION", //! @@ -720,36 +722,21 @@ DECLARE_SOA_TABLE(HfCand2ProngBase, "AOD", "HFCAND2PBASE", //! DECLARE_SOA_EXTENDED_TABLE_USER(HfCand2ProngExt, HfCand2ProngBase, "HFCAND2PEXT", //! hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand_2prong::Pz); -DECLARE_SOA_TABLE(HfProng0PidPi, "AOD", "HFP0PIDPI", //! +DECLARE_SOA_TABLE(HfCand2Prong0PidPi, "AOD", "HFCAND2P0PIDPI", //! hf_cand::NSigTpcPi0, hf_cand::NSigTofPi0, hf_cand::TpcTofNSigmaPi0); -DECLARE_SOA_TABLE(HfProng1PidPi, "AOD", "HFP1PIDPI", //! +DECLARE_SOA_TABLE(HfCand2Prong1PidPi, "AOD", "HFCAND2P1PIDPI", //! hf_cand::NSigTpcPi1, hf_cand::NSigTofPi1, hf_cand::TpcTofNSigmaPi1); -DECLARE_SOA_TABLE(HfProng2PidPi, "AOD", "HFP2PIDPI", //! - hf_cand::NSigTpcPi2, hf_cand::NSigTofPi2, - hf_cand::TpcTofNSigmaPi2); -DECLARE_SOA_TABLE(HfProng0PidKa, "AOD", "HFP0PIDKA", //! +DECLARE_SOA_TABLE(HfCand2Prong0PidKa, "AOD", "HFCAND2P0PIDKA", //! hf_cand::NSigTpcKa0, hf_cand::NSigTofKa0, hf_cand::TpcTofNSigmaKa0); -DECLARE_SOA_TABLE(HfProng1PidKa, "AOD", "HFP1PIDKA", //! +DECLARE_SOA_TABLE(HfCand2Prong1PidKa, "AOD", "HFCAND2P1PIDKA", //! hf_cand::NSigTpcKa1, hf_cand::NSigTofKa1, hf_cand::TpcTofNSigmaKa1); -DECLARE_SOA_TABLE(HfProng2PidKa, "AOD", "HFP2PIDKA", //! - hf_cand::NSigTpcKa2, hf_cand::NSigTofKa2, - hf_cand::TpcTofNSigmaKa2); -DECLARE_SOA_TABLE(HfProng0PidPr, "AOD", "HFP0PIDPR", //! - hf_cand::NSigTpcPr0, hf_cand::NSigTofPr0, - hf_cand::TpcTofNSigmaPr0); -DECLARE_SOA_TABLE(HfProng1PidPr, "AOD", "HFP1PIDPR", //! - hf_cand::NSigTpcPr1, hf_cand::NSigTofPr1, - hf_cand::TpcTofNSigmaPr1); -DECLARE_SOA_TABLE(HfProng2PidPr, "AOD", "HFP2PIDPR", //! - hf_cand::NSigTpcPr2, hf_cand::NSigTofPr2, - hf_cand::TpcTofNSigmaPr2); using HfCand2Prong = HfCand2ProngExt; -using HfCand2ProngWPid = soa::Join; +using HfCand2ProngWPid = soa::Join; DECLARE_SOA_TABLE(HfCand2ProngKF, "AOD", "HFCAND2PKF", hf_cand::KfTopolChi2OverNdf, @@ -842,9 +829,9 @@ DECLARE_SOA_TABLE(HfCandCascBase, "AOD", "HFCANDCASCBASE", //! hf_cand_casc::PtV0Pos, // pT of positive V0 daughter hf_cand_casc::PtV0Neg, // pT of negative V0 daughter v0data::V0Radius, - v0data::MLambda, - v0data::MAntiLambda, - v0data::MK0Short, + v0data::legacy::MLambda, + v0data::legacy::MAntiLambda, + v0data::legacy::MK0Short, v0data::MGamma, hf_cand_casc::CtV0); // , @@ -1087,9 +1074,37 @@ DECLARE_SOA_TABLE(HfCand3ProngBase, "AOD", "HFCAND3PBASE", //! DECLARE_SOA_EXTENDED_TABLE_USER(HfCand3ProngExt, HfCand3ProngBase, "HFCAND3PEXT", //! hf_cand_3prong::Px, hf_cand_3prong::Py, hf_cand_3prong::Pz); +DECLARE_SOA_TABLE(HfCand3Prong0PidPi, "AOD", "HFCAND3P0PIDPI", //! + hf_cand::NSigTpcPi0, hf_cand::NSigTofPi0, + hf_cand::TpcTofNSigmaPi0); +DECLARE_SOA_TABLE(HfCand3Prong1PidPi, "AOD", "HFCAND3P1PIDPI", //! + hf_cand::NSigTpcPi1, hf_cand::NSigTofPi1, + hf_cand::TpcTofNSigmaPi1); +DECLARE_SOA_TABLE(HfCand3Prong2PidPi, "AOD", "HFCAND3P2PIDPI", //! + hf_cand::NSigTpcPi2, hf_cand::NSigTofPi2, + hf_cand::TpcTofNSigmaPi2); +DECLARE_SOA_TABLE(HfCand3Prong0PidKa, "AOD", "HFCAND3P0PIDKA", //! + hf_cand::NSigTpcKa0, hf_cand::NSigTofKa0, + hf_cand::TpcTofNSigmaKa0); +DECLARE_SOA_TABLE(HfCand3Prong1PidKa, "AOD", "HFCAND3P1PIDKA", //! + hf_cand::NSigTpcKa1, hf_cand::NSigTofKa1, + hf_cand::TpcTofNSigmaKa1); +DECLARE_SOA_TABLE(HfCand3Prong2PidKa, "AOD", "HFCAND3P2PIDKA", //! + hf_cand::NSigTpcKa2, hf_cand::NSigTofKa2, + hf_cand::TpcTofNSigmaKa2); +DECLARE_SOA_TABLE(HfCand3Prong0PidPr, "AOD", "HFCAND3P0PIDPR", //! + hf_cand::NSigTpcPr0, hf_cand::NSigTofPr0, + hf_cand::TpcTofNSigmaPr0); +DECLARE_SOA_TABLE(HfCand3Prong1PidPr, "AOD", "HFCAND3P1PIDPR", //! + hf_cand::NSigTpcPr1, hf_cand::NSigTofPr1, + hf_cand::TpcTofNSigmaPr1); +DECLARE_SOA_TABLE(HfCand3Prong2PidPr, "AOD", "HFCAND3P2PIDPR", //! + hf_cand::NSigTpcPr2, hf_cand::NSigTofPr2, + hf_cand::TpcTofNSigmaPr2); + using HfCand3Prong = HfCand3ProngExt; -using HfCand3ProngWPidPiKaPr = soa::Join; -using HfCand3ProngWPidPiKa = soa::Join; +using HfCand3ProngWPidPiKaPr = soa::Join; +using HfCand3ProngWPidPiKa = soa::Join; DECLARE_SOA_TABLE(HfCand3ProngKF, "AOD", "HFCAND3PKF", hf_cand_3prong::KfXError, hf_cand_3prong::KfYError, hf_cand_3prong::KfZError, @@ -1903,6 +1918,7 @@ DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); // reconstruction le DECLARE_SOA_COLUMN(FlagMcMatchGen, flagMcMatchGen, int8_t); // generator level DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int8_t); DECLARE_SOA_COLUMN(OriginMcGen, originMcGen, int8_t); +DECLARE_SOA_COLUMN(DecayLengthMcGen, decayLengthMcGen, float); // Residuals and pulls DECLARE_SOA_COLUMN(PtResidual, ptResidual, float); DECLARE_SOA_COLUMN(PResidual, pResidual, float); @@ -2010,7 +2026,8 @@ DECLARE_SOA_TABLE(HfCandXicMcRec, "AOD", "HFCANDXICMCREC", DECLARE_SOA_TABLE(HfCandXicMcGen, "AOD", "HFCANDXICMCGEN", hf_cand_xic_to_xi_pi_pi::FlagMcMatchGen, hf_cand_xic_to_xi_pi_pi::OriginMcGen, - hf_cand::PdgBhadMotherPart); + hf_cand::PdgBhadMotherPart, + hf_cand_xic_to_xi_pi_pi::DecayLengthMcGen); // table with residuals and pulls of PV DECLARE_SOA_TABLE(HfCandXicResid, "AOD", "HFCANDXICRESID", @@ -2237,6 +2254,40 @@ DECLARE_SOA_TABLE(HfCandB0Base, "AOD", "HFCANDB0BASE", hf_cand::E, hf_cand::E2); +DECLARE_SOA_TABLE(HfCandB0DStar, "AOD", "HFCANDB0DSTAR", + // general columns + HFCAND_COLUMNS, + /* prong 2 */ hf_cand::ImpactParameterNormalised2, + hf_cand::PtProng2, + hf_cand::Pt2Prong2, + hf_cand::PVectorProng2, + // 3-prong specific columns + hf_cand::PxProng0, hf_cand::PyProng0, hf_cand::PzProng0, + hf_cand::PxProng1, hf_cand::PyProng1, hf_cand::PzProng1, + hf_cand::PxProng2, hf_cand::PyProng2, hf_cand::PzProng2, + hf_cand::ImpactParameter0, hf_cand::ImpactParameter1, hf_cand::ImpactParameter2, + hf_cand::ErrorImpactParameter0, hf_cand::ErrorImpactParameter1, hf_cand::ErrorImpactParameter2, + /* dynamic columns */ + hf_cand_3prong::M, + hf_cand_3prong::M2, + hf_cand_3prong::ImpactParameterProngSqSum, + /* dynamic columns that use candidate momentum components */ + hf_cand::Pt, + hf_cand::Pt2, + hf_cand::P, + hf_cand::P2, + hf_cand::PVector, + hf_cand::Cpa, + hf_cand::CpaXY, + hf_cand::Ct, + hf_cand::ImpactParameterXY, + hf_cand_3prong::MaxNormalisedDeltaIP, + hf_cand::Eta, + hf_cand::Phi, + hf_cand::Y, + hf_cand::E, + hf_cand::E2); + // extended table with expression columns that can be used as arguments of dynamic columns DECLARE_SOA_EXTENDED_TABLE_USER(HfCandB0Ext, HfCandB0Base, "HFCANDB0EXT", hf_cand_2prong::Px, hf_cand_2prong::Py, hf_cand_2prong::Pz); @@ -2246,6 +2297,10 @@ DECLARE_SOA_TABLE(HfCandB0Prongs, "AOD", "HFCANDB0PRONGS", using HfCandB0 = soa::Join; +// extended table with expression columns that can be used as arguments of dynamic columns +DECLARE_SOA_EXTENDED_TABLE_USER(HfCandB0DStExt, HfCandB0DStar, "HFCANDB0DSTEXT", + hf_cand_3prong::Px, hf_cand_3prong::Py, hf_cand_3prong::Pz); + // table with results of reconstruction level MC matching DECLARE_SOA_TABLE(HfCandB0McRec, "AOD", "HFCANDB0MCREC", hf_cand_b0::FlagMcMatchRec, @@ -2678,7 +2733,11 @@ DECLARE_SOA_DYNAMIC_COLUMN(NormalisedImpParamZSoftPi, normalisedImpParamZSoftPi, DECLARE_SOA_COLUMN(PxSoftPi, pxSoftPi, float); DECLARE_SOA_COLUMN(PySoftPi, pySoftPi, float); DECLARE_SOA_COLUMN(PzSoftPi, pzSoftPi, float); +DECLARE_SOA_COLUMN(DcaYSoftPi, dcaYSoftPi, float); +DECLARE_SOA_COLUMN(SigmaYSoftPi, sigmaYSoftPi, float); DECLARE_SOA_COLUMN(SignSoftPi, signSoftPi, int8_t); +DECLARE_SOA_COLUMN(TPCNSigmaPiSoftPi, tpcNSigmaPiSoftPi, float); //! NsigmaTPCPi for soft pi, o2-linter: disable=name/o2-column (written to disk) +DECLARE_SOA_COLUMN(TOFNSigmaPiSoftPi, tofNSigmaPiSoftPi, float); //! NsigmaTOFPi for soft pi, o2-linter: disable=name/o2-column (written to disk) // Dstar momenta DECLARE_SOA_EXPRESSION_COLUMN(PxDstar, pxDstar, float, 1.f * aod::hf_cand::pxProng0 + 1.f * aod::hf_cand::pxProng1 + 1.f * aod::hf_cand_dstar::pxSoftPi); DECLARE_SOA_EXPRESSION_COLUMN(PyDstar, pyDstar, float, 1.f * aod::hf_cand::pyProng0 + 1.f * aod::hf_cand::pyProng1 + 1.f * aod::hf_cand_dstar::pySoftPi); @@ -2694,7 +2753,8 @@ DECLARE_SOA_DYNAMIC_COLUMN(InvMassAntiDstar, invMassAntiDstar, DECLARE_SOA_DYNAMIC_COLUMN(PtSoftPi, ptSoftPi, [](float pxSoftPi, float pySoftPi) -> float { return RecoDecay::pt(pxSoftPi, pySoftPi); }); DECLARE_SOA_DYNAMIC_COLUMN(PVecSoftPi, pVecSoftPi, [](float px, float py, float pz) -> std::array { return std::array{px, py, pz}; }); - +DECLARE_SOA_DYNAMIC_COLUMN(TPCTOFNSigmaPiSoftPi, tpcTofNSigmaPiSoftPi, //! Combination of NsigmaTPC and NsigmaTOF, o2-linter: disable=name/o2-column (written to disk) + [](float tpcNSigmaPiSoftPi, float TOFNSigmaPiSoftPi) -> float { return pid_tpc_tof_utils::combineNSigma(tpcNSigmaPiSoftPi, TOFNSigmaPiSoftPi); }); // MC matching result: DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); //! reconstruction level DECLARE_SOA_COLUMN(FlagMcMatchGen, flagMcMatchGen, int8_t); //! generator level @@ -2767,8 +2827,27 @@ DECLARE_SOA_TABLE(HfD0FromDstarBase, "AOD", "HFD0FRMDSTR", DECLARE_SOA_EXTENDED_TABLE_USER(HfD0FromDstarExt, HfD0FromDstarBase, "HFD0FRMDSTREXT", hf_cand_dstar::PxD0, hf_cand_dstar::PyD0, hf_cand_dstar::PzD0); +DECLARE_SOA_TABLE(HfCandDstarProng0PidPi, "AOD", "HFDSTRP0PIDPI", //! + hf_cand::NSigTpcPi0, hf_cand::NSigTofPi0, + hf_cand::TpcTofNSigmaPi0); +DECLARE_SOA_TABLE(HfCandDstarProng1PidPi, "AOD", "HFDSTRP1PIDPI", //! + hf_cand::NSigTpcPi1, hf_cand::NSigTofPi1, + hf_cand::TpcTofNSigmaPi1); +DECLARE_SOA_TABLE(HfCandDstarProng2PidPi, "AOD", "HFDSTRP2PIDPI", //! + hf_cand::NSigTpcPi2, hf_cand::NSigTofPi2, + hf_cand::TpcTofNSigmaPi2); +DECLARE_SOA_TABLE(HfCandDstarProng0PidKa, "AOD", "HFDSTRP0PIDKA", //! + hf_cand::NSigTpcKa0, hf_cand::NSigTofKa0, + hf_cand::TpcTofNSigmaKa0); +DECLARE_SOA_TABLE(HfCandDstarProng1PidKa, "AOD", "HFDSTRP1PIDKA", //! + hf_cand::NSigTpcKa1, hf_cand::NSigTofKa1, + hf_cand::TpcTofNSigmaKa1); +DECLARE_SOA_TABLE(HfCandDstarProng2PidKa, "AOD", "HFDSTRP2PIDKA", //! + hf_cand::NSigTpcKa2, hf_cand::NSigTofKa2, + hf_cand::TpcTofNSigmaKa2); + using HfD0FromDstar = HfD0FromDstarExt; -using HfD0FromDstarWPid = soa::Join; +using HfD0FromDstarWPid = soa::Join; DECLARE_SOA_TABLE(HfCandDstarBase, "AOD", "HFCANDDSTRBASE", o2::soa::Index<>, @@ -2819,7 +2898,7 @@ DECLARE_SOA_EXTENDED_TABLE_USER(HfCandDstarExt, HfCandDstarBase, "HFCANDDSTREXT" using HfCandDstars = HfCandDstarExt; using HfCandDstar = HfCandDstars::iterator; -using HfCandDstarsWPid = soa::Join; +using HfCandDstarsWPid = soa::Join; // table with results of reconstruction level MC matching DECLARE_SOA_TABLE(HfCandDstarMcRec, "AOD", "HFCANDDSTRMCREC", diff --git a/PWGHF/HFC/DataModel/CorrelationTables.h b/PWGHF/HFC/DataModel/CorrelationTables.h index a77035b7f3f..d453d894978 100644 --- a/PWGHF/HFC/DataModel/CorrelationTables.h +++ b/PWGHF/HFC/DataModel/CorrelationTables.h @@ -161,6 +161,7 @@ DECLARE_SOA_COLUMN(IsSignal, isSignal, bool); //! U DECLARE_SOA_COLUMN(IsPrompt, isPrompt, bool); //! Used in MC-Rec, Lc Prompt or Non-Prompt DECLARE_SOA_COLUMN(IsPhysicalPrimary, isPhysicalPrimary, bool); //! Used in MC-Rec, primary associated particles DECLARE_SOA_COLUMN(IsAutoCorrelated, isAutoCorrelated, bool); //! Correlation Status +DECLARE_SOA_COLUMN(Cent, cent, float); //! Centrality of Collision DECLARE_SOA_COLUMN(PrNsigmTPC, prNsigmTPC, float); //! Associated Particle TPC nSigma proton DECLARE_SOA_COLUMN(KaNsigmTPC, kaNsigmTPC, float); //! Associated Particle TPC nSigma Kaon DECLARE_SOA_COLUMN(PiNsigmTPC, piNsigmTPC, float); //! Associated Particle TPC nSigma Pion @@ -175,7 +176,8 @@ DECLARE_SOA_TABLE(LcHadronPair, "AOD", "LCHPAIR", //! Lc-Hadrons pairs Informati aod::hf_correlation_lc_hadron::PtLc, aod::hf_correlation_lc_hadron::PtHadron, aod::hf_correlation_lc_hadron::PoolBin, - aod::hf_correlation_lc_hadron::IsAutoCorrelated); + aod::hf_correlation_lc_hadron::IsAutoCorrelated, + aod::hf_correlation_lc_hadron::Cent); DECLARE_SOA_TABLE(LcHadronRecoInfo, "AOD", "LCHRECOINFO", //! Lc-Hadrons pairs Reconstructed Informations aod::hf_correlation_lc_hadron::MLc, diff --git a/PWGHF/HFC/TableProducer/correlatorHfeHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorHfeHadrons.cxx index 30989581962..0a824c1e9b5 100644 --- a/PWGHF/HFC/TableProducer/correlatorHfeHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorHfeHadrons.cxx @@ -152,12 +152,20 @@ struct HfCorrelatorHfeHadrons { int gCollisionId = collision.globalIndex(); int64_t timeStamp = bc.timestamp(); + // Add hadron Table For Mix Event Electron Hadron correlation + for (const auto& hTrack : tracks) { + if (!selAssoHadron(hTrack)) { + continue; + } + registry.fill(HIST("hTracksBin"), poolBin); + entryHadron(hTrack.phi(), hTrack.eta(), hTrack.pt(), poolBin, gCollisionId, timeStamp); + } + // Construct Deta Phi between electrons and hadrons double ptElectron = -999; double phiElectron = -999; double etaElectron = -999; - int nElectron = 0; for (const auto& eTrack : electron) { ptElectron = eTrack.ptTrack(); @@ -209,10 +217,7 @@ struct HfCorrelatorHfeHadrons { if (ptCondition && (ptElectron < ptHadron)) { continue; } - if (nElectron == 0) { - registry.fill(HIST("hTracksBin"), poolBin); - entryHadron(phiHadron, etaHadron, ptHadron, poolBin, gCollisionId, timeStamp); - } + deltaPhi = RecoDecay::constrainAngle(phiElectron - phiHadron, -o2::constants::math::PIHalf); deltaEta = etaElectron - etaHadron; registry.fill(HIST("hInclusiveEHCorrel"), ptElectron, ptHadron, deltaPhi, deltaEta); @@ -236,7 +241,7 @@ struct HfCorrelatorHfeHadrons { entryElectronHadronPair(deltaPhi, deltaEta, ptElectron, ptHadron, poolBin, nElHadLSCorr, nElHadUSCorr); } // end Hadron Track loop - nElectron++; + } // end Electron loop } diff --git a/PWGHF/HFC/TableProducer/correlatorLcHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorLcHadrons.cxx index 22770502878..98d2728572a 100644 --- a/PWGHF/HFC/TableProducer/correlatorLcHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorLcHadrons.cxx @@ -27,6 +27,7 @@ #include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTOF.h" @@ -65,7 +66,6 @@ using namespace o2::constants::math; using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::analysis::hf_correlations; - /// /// Returns deltaPhi values in range [-pi/2., 3.*pi/2.], typically used for correlation studies /// @@ -88,11 +88,14 @@ struct HfCorrelatorLcHadronsSelection { Configurable selectionFlagLc{"selectionFlagLc", 1, "Selection Flag for Lc"}; Configurable yCandMax{"yCandMax", 0.8, "max. cand. rapidity"}; Configurable ptCandMin{"ptCandMin", 1., "min. cand. pT"}; + Configurable centMin{"centMin", 0., "Minimum Centrality"}; + Configurable centMax{"centMax", 100., "Maximum Centrality"}; + Configurable useCentrality{"useCentrality", false, "Flag for centrality dependent analyses"}; HfHelper hfHelper; SliceCache cache; - using SelCollisions = soa::Join; + using SelCollisions = soa::Join; using CandidatesLcData = soa::Filtered>; using CandidatesLcMcRec = soa::Filtered>; using CandidatesLcMcGen = soa::Join; @@ -108,6 +111,7 @@ struct HfCorrelatorLcHadronsSelection { bool isLcFound = true; bool isSel8 = true; bool isNosameBunchPileUp = true; + bool isCentInRange = false; if (doSelLcCollision) { for (const auto& candidate : candidates) { if (std::abs(hfHelper.yLc(candidate)) > yCandMax || candidate.pt() < ptCandMin) { @@ -118,13 +122,21 @@ struct HfCorrelatorLcHadronsSelection { break; } } + + float cent = 0.; + if (useCentrality) { + cent = collision.centFT0M(); + } + if (useSel8) { isSel8 = collision.sel8(); } if (selNoSameBunchPileUpColl) { isNosameBunchPileUp = static_cast(collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)); } - isSelColl = isLcFound && isSel8 && isNosameBunchPileUp; + + isCentInRange = (cent >= centMin && cent < centMax); + isSelColl = isLcFound && isSel8 && isNosameBunchPileUp && isCentInRange; lcSel(isSelColl); } PROCESS_SWITCH(HfCorrelatorLcHadronsSelection, processLcSelectionData, "Process Lc Collision Selection Data", true); @@ -226,6 +238,7 @@ struct HfCorrelatorLcHadrons { Configurable isRecTrkPhyPrimary{"isRecTrkPhyPrimary", true, "Calculate the efficiency of reconstructed primary physical tracks"}; Configurable calEffLcEvent{"calEffLcEvent", true, "Calculate the efficiency of Lc candidate"}; Configurable eventFractionToAnalyze{"eventFractionToAnalyze", -1, "Fraction of events to analyze (use only for ME offline on very large samples)"}; + Configurable useCentrality{"useCentrality", false, "Flag for centrality dependent analyses"}; HfHelper hfHelper; SliceCache cache; @@ -236,7 +249,7 @@ struct HfCorrelatorLcHadrons { TRandom3* rnd = new TRandom3(0); // Event Mixing for the Data Mode - using SelCollisionsWithLc = soa::Filtered>; + using SelCollisionsWithLc = soa::Filtered>; using SelCollisionsWithLcMc = soa::Filtered>; // collisionFilter applied using CandidatesLcData = soa::Filtered>; // Event Mixing for the MCRec Mode @@ -267,6 +280,7 @@ struct HfCorrelatorLcHadrons { ConfigurableAxis binsPoolBin{"binsPoolBin", {9, 0., 9.}, "PoolBin"}; ConfigurableAxis binsMultFT0M{"binsMultFT0M", {600, 0., 6000.}, "Multiplicity as FT0M signal amplitude"}; ConfigurableAxis binsMassLc{"binsMassLc", {200, 1.98, 2.58}, "inv. mass (p K #pi) (GeV/#it{c}^{2})"}; + ConfigurableAxis binsCentFt0m{"binsCentFt0m", {100, 0., 100.}, "Centrality percentile (FT0M)"}; BinningType corrBinning{{binsZVtx, binsMultiplicity}, true}; @@ -286,49 +300,51 @@ struct HfCorrelatorLcHadrons { AxisSpec axisPoolBin = {binsPoolBin, "PoolBin"}; AxisSpec axisRapidity = {100, -2, 2, "Rapidity"}; AxisSpec axisSign = {2, -1, 1, "Sign"}; - - registry.add("hPtCand", "Lc,Hadron candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPtLc}}); - registry.add("hPtProng0", "Lc,Hadron candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPtLc}}); - registry.add("hPtProng1", "Lc,Hadron candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPtLc}}); - registry.add("hPtProng2", "Lc,Hadron candidates;prong 2 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPtLc}}); - registry.add("hSelectionStatusLcToPKPi", "Lc,Hadron candidates;selection status;entries", {HistType::kTH1F, {{8, -0.5, 7.5}}}); - registry.add("hSelectionStatusLcToPiKP", "Lc,Hadron candidates;selection status;entries", {HistType::kTH1F, {{8, -0.5, 7.5}}}); - registry.add("hEta", "Lc,Hadron candidates;candidate #it{#eta};entries", {HistType::kTH1F, {axisEta}}); - registry.add("hPhi", "Lc,Hadron candidates;candidate #it{#varphi};entries", {HistType::kTH1F, {axisPhi}}); - registry.add("hY", "Lc,Hadron candidates;candidate #it{#y};entries", {HistType::kTH1F, {axisRapidity}}); - registry.add("hCountLcHadronPerEvent", "Lc,Hadron particles - MC gen;Number per event;entries", {HistType::kTH1F, {{21, -0.5, 20.5}}}); - registry.add("hMultiplicityPreSelection", "multiplicity prior to selection;multiplicity;entries", {HistType::kTH1F, {{10000, 0., 10000.}}}); - registry.add("hMultiplicity", "multiplicity;multiplicity;entries", {HistType::kTH1F, {{10000, 0., 10000.}}}); - registry.add("hMultFT0M", "multiplicity;multiplicity;entries", {HistType::kTH1F, {{10000, 0., 10000.}}}); - registry.add("hZvtx", "z vertex;z vertex;entries", {HistType::kTH1F, {{200, -20., 20.}}}); - registry.add("hLcBin", "Lc selected in pool Bin;pool Bin;entries", {HistType::kTH1F, {{9, 0., 9.}}}); - registry.add("hTracksBin", "Tracks selected in pool Bin;pool Bin;entries", {HistType::kTH1F, {{9, 0., 9.}}}); - registry.add("hMassLcVsPt", "Lc candidates;inv. mass (p K #pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{axisMassLc}, {axisPtLc}}}); - registry.add("hMassLcData", "Lc candidates;inv. mass (p K #pi) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{axisMassLc}}}); - registry.add("hLcPoolBin", "Lc candidates pool bin", {HistType::kTH1F, {axisPoolBin}}); - registry.add("hTracksPoolBin", "Particles associated pool bin", {HistType::kTH1F, {axisPoolBin}}); + AxisSpec axisCent = {binsCentFt0m, "Centrality"}; + + registry.add("hPtCand", "Lc,Hadron candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {axisPtLc}}); + registry.add("hPtProng0", "Lc,Hadron candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {axisPtLc}}); + registry.add("hPtProng1", "Lc,Hadron candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {axisPtLc}}); + registry.add("hPtProng2", "Lc,Hadron candidates;prong 2 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {axisPtLc}}); + registry.add("hSelectionStatusLcToPKPi", "Lc,Hadron candidates;selection status;entries", {HistType::kTH1D, {{8, -0.5, 7.5}}}); + registry.add("hSelectionStatusLcToPiKP", "Lc,Hadron candidates;selection status;entries", {HistType::kTH1D, {{8, -0.5, 7.5}}}); + registry.add("hEta", "Lc,Hadron candidates;candidate #it{#eta};entries", {HistType::kTH1D, {axisEta}}); + registry.add("hPhi", "Lc,Hadron candidates;candidate #it{#varphi};entries", {HistType::kTH1D, {axisPhi}}); + registry.add("hY", "Lc,Hadron candidates;candidate #it{#y};entries", {HistType::kTH1D, {axisRapidity}}); + registry.add("hCountLcHadronPerEvent", "Lc,Hadron particles - MC gen;Number per event;entries", {HistType::kTH1D, {{21, -0.5, 20.5}}}); + registry.add("hMultiplicityPreSelection", "multiplicity prior to selection;multiplicity;entries", {HistType::kTH1D, {{10000, 0., 10000.}}}); + registry.add("hMultiplicity", "multiplicity;multiplicity;entries", {HistType::kTH1D, {{10000, 0., 10000.}}}); + registry.add("hMultFT0M", "multiplicity;multiplicity;entries", {HistType::kTH1D, {{10000, 0., 10000.}}}); + registry.add("hZvtx", "z vertex;z vertex;entries", {HistType::kTH1D, {{200, -20., 20.}}}); + registry.add("hCentFT0M", "Centrality FT0M; Centrality;entries", {HistType::kTH1D, {{100, 0., 100.}}}); + registry.add("hLcBin", "Lc selected in pool Bin;pool Bin;entries", {HistType::kTH1D, {{9, 0., 9.}}}); + registry.add("hTracksBin", "Tracks selected in pool Bin;pool Bin;entries", {HistType::kTH1D, {{9, 0., 9.}}}); + registry.add("hMassLcVsPtVsCent", "Lc candidates;inv. mass (p K #pi) (GeV/#it{c}^{2});entries", {HistType::kTH3F, {{axisMassLc}, {axisPtLc}, {axisCent}}}); + registry.add("hMassLcData", "Lc candidates;inv. mass (p K #pi) (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{axisMassLc}}}); + registry.add("hLcPoolBin", "Lc candidates pool bin", {HistType::kTH1D, {axisPoolBin}}); + registry.add("hTracksPoolBin", "Particles associated pool bin", {HistType::kTH1D, {axisPoolBin}}); // Histograms for MC Reco analysis - registry.add("hSelectionStatusLcToPKPiMcRec", "Lc,Hadron candidates - MC reco;selection status;entries", {HistType::kTH1F, {{8, -0.5, 7.5}}}); - registry.add("hSelectionStatusLcToPiKPMcRec", "Lc,Hadron candidates - MC reco;selection status;entries", {HistType::kTH1F, {{8, -0.5, 7.5}}}); - registry.add("hMcEvtCount", "Event counter - MC gen;;entries", {HistType::kTH1F, {{1, -0.5, 0.5}}}); - registry.add("hPtProng0McRec", "Lc,Hadron candidates - MC reco;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPtLc}}); - registry.add("hPtProng1McRec", "Lc,Hadron candidates - MC reco;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPtLc}}); - registry.add("hPtProng2McRec", "Lc,Hadron candidates - MC reco;prong 2 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPtLc}}); - registry.add("hMassLcMcRec", "Lc candidates;inv. mass (P K #pi) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{axisMassLc}}}); + registry.add("hSelectionStatusLcToPKPiMcRec", "Lc,Hadron candidates - MC reco;selection status;entries", {HistType::kTH1D, {{8, -0.5, 7.5}}}); + registry.add("hSelectionStatusLcToPiKPMcRec", "Lc,Hadron candidates - MC reco;selection status;entries", {HistType::kTH1D, {{8, -0.5, 7.5}}}); + registry.add("hMcEvtCount", "Event counter - MC gen;;entries", {HistType::kTH1D, {{1, -0.5, 0.5}}}); + registry.add("hPtProng0McRec", "Lc,Hadron candidates - MC reco;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {axisPtLc}}); + registry.add("hPtProng1McRec", "Lc,Hadron candidates - MC reco;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {axisPtLc}}); + registry.add("hPtProng2McRec", "Lc,Hadron candidates - MC reco;prong 2 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {axisPtLc}}); + registry.add("hMassLcMcRec", "Lc candidates;inv. mass (P K #pi) (GeV/#it{c}^{2});entries", {HistType::kTH1D, {{axisMassLc}}}); registry.add("hMassLcVsPtMcRec", "Lc candidates - MC Reco", {HistType::kTH2F, {{axisMassLc}, {axisPtLc}}}); registry.add("hMassLcMcRecSig", "Lc signal candidates - MC reco;inv. mass (p K #pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{axisMassLc}, {axisPtLc}}}); registry.add("hMassLcMcRecBkg", "Lc background candidates - MC reco;inv. mass (p K #pi) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{axisMassLc}, {axisPtLc}}}); - registry.add("hPtCandMcRecSig", "Lc,Hadron candidates - MC Reco", {HistType::kTH1F, {axisPtLc}}); - registry.add("hPtCandMcRecSigPrompt", "Lc,Hadron candidates Prompt - MC Reco", {HistType::kTH1F, {axisPtLc}}); - registry.add("hPtCandMcRecSigNonPrompt", "Lc,Hadron candidates Non Prompt - MC Reco", {HistType::kTH1F, {axisPtLc}}); - registry.add("hPtCandMcRecBkg", "Lc,Hadron candidates - MC Reco", {HistType::kTH1F, {axisPtLc}}); - registry.add("hEtaMcRecSig", "Lc,Hadron candidates - MC Reco", {HistType::kTH1F, {axisEta}}); - registry.add("hPhiMcRecSig", "Lc,Hadron candidates - MC Reco", {HistType::kTH1F, {axisPhi}}); - registry.add("hYMcRecSig", "Lc,Hadron candidates - MC reco;candidate #it{#y};entries", {HistType::kTH1F, {axisRapidity}}); - registry.add("hEtaMcRecBkg", "Lc,Hadron candidates - MC Reco", {HistType::kTH1F, {axisEta}}); - registry.add("hPhiMcRecBkg", "Lc,Hadron candidates - MC Reco", {HistType::kTH1F, {axisPhi}}); - registry.add("hYMcRecBkg", "Lc,Hadron candidates - MC reco;candidate #it{#y};entries", {HistType::kTH1F, {axisRapidity}}); - registry.add("hFakeTracksMcRec", "Fake tracks - MC Rec", {HistType::kTH1F, {axisPtHadron}}); + registry.add("hPtCandMcRecSig", "Lc,Hadron candidates - MC Reco", {HistType::kTH1D, {axisPtLc}}); + registry.add("hPtCandMcRecSigPrompt", "Lc,Hadron candidates Prompt - MC Reco", {HistType::kTH1D, {axisPtLc}}); + registry.add("hPtCandMcRecSigNonPrompt", "Lc,Hadron candidates Non Prompt - MC Reco", {HistType::kTH1D, {axisPtLc}}); + registry.add("hPtCandMcRecBkg", "Lc,Hadron candidates - MC Reco", {HistType::kTH1D, {axisPtLc}}); + registry.add("hEtaMcRecSig", "Lc,Hadron candidates - MC Reco", {HistType::kTH1D, {axisEta}}); + registry.add("hPhiMcRecSig", "Lc,Hadron candidates - MC Reco", {HistType::kTH1D, {axisPhi}}); + registry.add("hYMcRecSig", "Lc,Hadron candidates - MC reco;candidate #it{#y};entries", {HistType::kTH1D, {axisRapidity}}); + registry.add("hEtaMcRecBkg", "Lc,Hadron candidates - MC Reco", {HistType::kTH1D, {axisEta}}); + registry.add("hPhiMcRecBkg", "Lc,Hadron candidates - MC Reco", {HistType::kTH1D, {axisPhi}}); + registry.add("hYMcRecBkg", "Lc,Hadron candidates - MC reco;candidate #it{#y};entries", {HistType::kTH1D, {axisRapidity}}); + registry.add("hFakeTracksMcRec", "Fake tracks - MC Rec", {HistType::kTH1D, {axisPtHadron}}); registry.add("hPtParticleAssocVsCandMcRec", "Associated Particle - MC Rec", {HistType::kTH2F, {{axisPtHadron}, {axisPtLc}}}); registry.add("hPtTracksVsSignRec", "Associated Particle - MC Rec", {HistType::kTH2F, {{axisPtTrack}, {axisSign}}}); registry.add("hPtTracksVsSignRecTrue", "Associated Particle - MC Rec (True)", {HistType::kTH2F, {{axisPtTrack}, {axisSign}}}); @@ -338,15 +354,14 @@ struct HfCorrelatorLcHadrons { registry.add("hPtVsMultiplicityMcRecNonPrompt", "Multiplicity FT0M - MC Rec Non Prompt", {HistType::kTH2F, {{axisPtLc}, {axisMultFT0M}}}); // Histograms for MC Gen analysis registry.add("hcountLctriggersMcGen", "Lc trigger particles - MC gen;;N of trigger Lc", {HistType::kTH2F, {{1, -0.5, 0.5}, {axisPtLc}}}); - registry.add("hPtCandMcGen", "Lc,Hadron particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPtLc}}); - registry.add("hYMcGen", "Lc,Hadron candidates - MC gen;candidate #it{#y};entries", {HistType::kTH1F, {axisRapidity}}); - registry.add("hPtCandMcGenPrompt", "Lc,Hadron particles - MC Gen Prompt", {HistType::kTH1F, {axisPtLc}}); - registry.add("hPtCandMcGenNonPrompt", "Lc,Hadron particles - MC Gen Non Prompt", {HistType::kTH1F, {axisPtLc}}); - registry.add("hPtParticleAssocMcGen", "Associated Particle - MC Gen", {HistType::kTH1F, {axisPtHadron}}); - registry.add("hEtaMcGen", "Lc,Hadron particles - MC Gen", {HistType::kTH1F, {axisEta}}); - registry.add("hPhiMcGen", "Lc,Hadron particles - MC Gen", {HistType::kTH1F, {axisPhi}}); - registry.add("hMultFT0AMcGen", "Lc,Hadron multiplicity FT0A - MC Gen", {HistType::kTH1F, {axisMultiplicity}}); - + registry.add("hPtCandMcGen", "Lc,Hadron particles - MC gen;particle #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1D, {axisPtLc}}); + registry.add("hYMcGen", "Lc,Hadron candidates - MC gen;candidate #it{#y};entries", {HistType::kTH1D, {axisRapidity}}); + registry.add("hPtCandMcGenPrompt", "Lc,Hadron particles - MC Gen Prompt", {HistType::kTH1D, {axisPtLc}}); + registry.add("hPtCandMcGenNonPrompt", "Lc,Hadron particles - MC Gen Non Prompt", {HistType::kTH1D, {axisPtLc}}); + registry.add("hPtParticleAssocMcGen", "Associated Particle - MC Gen", {HistType::kTH1D, {axisPtHadron}}); + registry.add("hEtaMcGen", "Lc,Hadron particles - MC Gen", {HistType::kTH1D, {axisEta}}); + registry.add("hPhiMcGen", "Lc,Hadron particles - MC Gen", {HistType::kTH1D, {axisPhi}}); + registry.add("hMultFT0AMcGen", "Lc,Hadron multiplicity FT0A - MC Gen", {HistType::kTH1D, {axisMultiplicity}}); corrBinning = {{binsZVtx, binsMultiplicity}, true}; } @@ -374,6 +389,10 @@ struct HfCorrelatorLcHadrons { int gCollisionId = collision.globalIndex(); int64_t timeStamp = bc.timestamp(); + float cent = 0.; + if (useCentrality) { + cent = collision.centFT0M(); + } int poolBin = corrBinning.getBin(std::make_tuple(collision.posZ(), collision.multFT0M())); int nTracks = 0; if (collision.numContrib() > 1) { @@ -412,8 +431,9 @@ struct HfCorrelatorLcHadrons { registry.fill(HIST("hPhi"), RecoDecay::constrainAngle(candidate.phi(), -PIHalf)); registry.fill(HIST("hY"), hfHelper.yLc(candidate)); registry.fill(HIST("hLcBin"), poolBin); + if (candidate.isSelLcToPKPi() >= selectionFlagLc) { - registry.fill(HIST("hMassLcVsPt"), hfHelper.invMassLcToPKPi(candidate), candidate.pt(), efficiencyWeightLc); + registry.fill(HIST("hMassLcVsPtVsCent"), hfHelper.invMassLcToPKPi(candidate), candidate.pt(), cent, efficiencyWeightLc); registry.fill(HIST("hMassLcData"), hfHelper.invMassLcToPKPi(candidate), efficiencyWeightLc); registry.fill(HIST("hSelectionStatusLcToPKPi"), candidate.isSelLcToPKPi()); for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { @@ -423,7 +443,7 @@ struct HfCorrelatorLcHadrons { entryLc(candidate.phi(), candidate.eta(), candidate.pt() * chargeLc, hfHelper.invMassLcToPKPi(candidate), poolBin, gCollisionId, timeStamp); } if (candidate.isSelLcToPiKP() >= selectionFlagLc) { - registry.fill(HIST("hMassLcVsPt"), hfHelper.invMassLcToPiKP(candidate), candidate.pt(), efficiencyWeightLc); + registry.fill(HIST("hMassLcVsPtVsCent"), hfHelper.invMassLcToPiKP(candidate), candidate.pt(), cent, efficiencyWeightLc); registry.fill(HIST("hMassLcData"), hfHelper.invMassLcToPiKP(candidate), efficiencyWeightLc); registry.fill(HIST("hSelectionStatusLcToPiKP"), candidate.isSelLcToPiKP()); for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) { @@ -463,7 +483,8 @@ struct HfCorrelatorLcHadrons { candidate.pt() * chargeLc, track.pt() * track.sign(), poolBin, - correlationStatus); + correlationStatus, + cent); entryLcHadronPairY(track.rapidity(MassProton) - hfHelper.yLc(candidate)); // only for proton as of now entryLcHadronRecoInfo(hfHelper.invMassLcToPKPi(candidate), false); entryLcHadronGenInfo(false, false, 0); @@ -479,7 +500,8 @@ struct HfCorrelatorLcHadrons { candidate.pt() * chargeLc, track.pt() * track.sign(), poolBin, - correlationStatus); + correlationStatus, + cent); entryLcHadronPairY(track.rapidity(MassProton) - hfHelper.yLc(candidate)); // only for proton as of now entryLcHadronRecoInfo(hfHelper.invMassLcToPiKP(candidate), false); entryLcHadronGenInfo(false, false, 0); @@ -503,6 +525,7 @@ struct HfCorrelatorLcHadrons { } // end outer Lc loop registry.fill(HIST("hZvtx"), collision.posZ()); registry.fill(HIST("hMultFT0M"), collision.multFT0M()); + registry.fill(HIST("hCentFT0M"), cent); } PROCESS_SWITCH(HfCorrelatorLcHadrons, processData, "Process data", true); @@ -667,6 +690,7 @@ struct HfCorrelatorLcHadrons { } //} } + float cent = 100.0; // will be updated later // Lc-Hadron correlation dedicated section // if the candidate is selected as Lc, search for Hadron ad evaluate correlations @@ -716,7 +740,8 @@ struct HfCorrelatorLcHadrons { candidate.pt() * chargeLc, track.pt() * track.sign(), poolBin, - correlationStatus); + correlationStatus, + cent); entryLcHadronPairY(track.rapidity(MassProton) - hfHelper.yLc(candidate)); // only for proton as of now entryLcHadronRecoInfo(hfHelper.invMassLcToPKPi(candidate), isLcSignal); if (fillTrkPID) { @@ -746,7 +771,8 @@ struct HfCorrelatorLcHadrons { candidate.pt() * chargeLc, track.pt() * track.sign(), poolBin, - correlationStatus); + correlationStatus, + cent); entryLcHadronPairY(track.rapidity(MassProton) - hfHelper.yLc(candidate)); // only for proton as of now entryLcHadronRecoInfo(hfHelper.invMassLcToPiKP(candidate), isLcSignal); if (fillTrkPID) { @@ -790,6 +816,7 @@ struct HfCorrelatorLcHadrons { bool isLcPrompt = false; bool isLcNonPrompt = false; + float cent = 100.0; // will be updated later // find leading particle if (correlateLcWithLeadingParticle) { @@ -878,7 +905,8 @@ struct HfCorrelatorLcHadrons { particle.pt() * chargeLc / std::abs(chargeLc), particleAssoc.pt() * chargeAssoc / std::abs(chargeAssoc), poolBin, - correlationStatus); + correlationStatus, + cent); entryLcHadronPairY(particleAssoc.y() - yL); entryLcHadronRecoInfo(MassLambdaCPlus, true); entryLcHadronGenInfo(isLcPrompt, particleAssoc.isPhysicalPrimary(), trackOrigin); @@ -911,6 +939,8 @@ struct HfCorrelatorLcHadrons { auto trackPos1 = trigLc.template prong0_as(); // positive daughter (negative for the antiparticles) int8_t chargeLc = trackPos1.sign(); // charge of 1st prong will be the charge of Lc candidate + float cent = 100.0; // will be updated later + std::vector outputMl = {-1., -1., -1.}; // LcToPKPi and LcToPiKP division if (trigLc.isSelLcToPKPi() >= selectionFlagLc) { @@ -919,7 +949,8 @@ struct HfCorrelatorLcHadrons { trigLc.pt() * chargeLc, assocParticle.pt() * assocParticle.sign(), poolBin, - correlationStatus); + correlationStatus, + cent); entryLcHadronPairY(assocParticle.y() - hfHelper.yLc(trigLc)); entryLcHadronRecoInfo(hfHelper.invMassLcToPKPi(trigLc), false); entryLcHadronGenInfo(false, false, 0); @@ -938,7 +969,8 @@ struct HfCorrelatorLcHadrons { trigLc.pt() * chargeLc, assocParticle.pt() * assocParticle.sign(), poolBin, - correlationStatus); + correlationStatus, + cent); entryLcHadronPairY(assocParticle.y() - hfHelper.yLc(trigLc)); entryLcHadronRecoInfo(hfHelper.invMassLcToPiKP(trigLc), false); entryLcHadronGenInfo(false, false, 0); @@ -1006,6 +1038,7 @@ struct HfCorrelatorLcHadrons { registry.fill(HIST("hZvtx"), c1.posZ()); registry.fill(HIST("hTracksPoolBin"), poolBin); registry.fill(HIST("hLcPoolBin"), poolBinLc); + float cent = 100.0; // will be updated later for (const auto& [candidate, pAssoc] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { if (std::abs(hfHelper.yLc(candidate)) > yCandMax || candidate.pt() < ptCandMin || candidate.pt() > ptCandMax) { continue; @@ -1038,7 +1071,8 @@ struct HfCorrelatorLcHadrons { candidate.pt() * chargeLc, pAssoc.pt() * pAssoc.sign(), poolBin, - correlationStatus); + correlationStatus, + cent); entryLcHadronPairY(pAssoc.y() - hfHelper.yLc(candidate)); entryLcHadronRecoInfo(hfHelper.invMassLcToPKPi(candidate), isLcSignal); entryLcHadronGenInfo(isLcPrompt, isPhysicalPrimary, trackOrigin); @@ -1057,7 +1091,8 @@ struct HfCorrelatorLcHadrons { candidate.pt() * chargeLc, pAssoc.pt() * pAssoc.sign(), poolBin, - correlationStatus); + correlationStatus, + cent); entryLcHadronPairY(pAssoc.y() - hfHelper.yLc(candidate)); entryLcHadronRecoInfo(hfHelper.invMassLcToPiKP(candidate), isLcSignal); entryLcHadronGenInfo(isLcPrompt, isPhysicalPrimary, trackOrigin); @@ -1105,6 +1140,7 @@ struct HfCorrelatorLcHadrons { } int8_t chargeLc = pdg->GetParticle(candidate.pdgCode())->Charge(); // Retrieve charge int8_t chargeAssoc = pdg->GetParticle(particleAssoc.pdgCode())->Charge(); // Retrieve charge + float cent = 100.0; // will be updated later int trackOrigin = RecoDecay::getCharmHadronOrigin(mcParticles, particleAssoc, true); bool isLcPrompt = candidate.originMcGen() == RecoDecay::OriginType::Prompt; @@ -1113,7 +1149,8 @@ struct HfCorrelatorLcHadrons { candidate.pt() * chargeLc / std::abs(chargeLc), particleAssoc.pt() * chargeAssoc / std::abs(chargeAssoc), poolBin, - correlationStatus); + correlationStatus, + cent); entryLcHadronPairY(particleAssoc.y() - yL); entryLcHadronRecoInfo(MassLambdaCPlus, true); entryLcHadronGenInfo(isLcPrompt, particleAssoc.isPhysicalPrimary(), trackOrigin); diff --git a/PWGHF/HFC/TableProducer/correlatorLcScHadrons.cxx b/PWGHF/HFC/TableProducer/correlatorLcScHadrons.cxx index b06f67990a9..7ce63015c54 100644 --- a/PWGHF/HFC/TableProducer/correlatorLcScHadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorLcScHadrons.cxx @@ -476,13 +476,15 @@ struct HfCorrelatorLcScHadrons { { bool isPhysicalPrimary = false; int trackOrigin = -1; + float cent = 100.0; // will be updated later entryCandHadronPair(getDeltaPhi(track.phi(), candidate.phi()), track.eta() - candidate.eta(), candidate.pt(), track.pt() * track.sign(), binPool, - correlStatus); + correlStatus, + cent); entryCandHadronPairY(track.rapidity(MassProton) - yCand); entryCandHadronMlInfo(outMl[0], outMl[1]); entryTrackRecoInfo(track.dcaXY(), track.dcaZ(), track.tpcNClsCrossedRows()); @@ -1020,12 +1022,15 @@ struct HfCorrelatorLcScHadrons { int8_t chargeAssoc = pdg->GetParticle(particleAssoc.pdgCode())->Charge(); // Retrieve charge chargeAssoc = chargeAssoc / std::abs(chargeAssoc); registry.fill(HIST("hPtParticleAssocMcGen"), particleAssoc.pt()); + float cent = 100.0; // will be updated later + entryCandHadronPair(getDeltaPhi(particleAssoc.phi(), particle.phi()), particleAssoc.eta() - particle.eta(), particle.pt(), particleAssoc.pt() * chargeAssoc, poolBin, - correlationStatus); + correlationStatus, + cent); entryCandHadronPairY(particleAssoc.y() - yCand); entryCandHadronRecoInfo(massCand, true); entryCandHadronGenInfo(isPrompt, particleAssoc.isPhysicalPrimary(), trackOrigin); @@ -1166,6 +1171,7 @@ struct HfCorrelatorLcScHadrons { } int8_t chargeLc = pdg->GetParticle(candidate.pdgCode())->Charge(); // Retrieve charge int8_t chargeAssoc = pdg->GetParticle(particleAssoc.pdgCode())->Charge(); // Retrieve charge + float cent = 100.0; // will be updated later int trackOrigin = RecoDecay::getCharmHadronOrigin(mcParticles, particleAssoc, true); bool isPrompt = candidate.originMcGen() == RecoDecay::OriginType::Prompt; @@ -1174,7 +1180,8 @@ struct HfCorrelatorLcScHadrons { candidate.pt() * chargeLc / std::abs(chargeLc), particleAssoc.pt() * chargeAssoc / std::abs(chargeAssoc), poolBin, - correlationStatus); + correlationStatus, + cent); entryCandHadronPairY(particleAssoc.y() - yL); entryCandHadronRecoInfo(MassLambdaCPlus, true); entryCandHadronGenInfo(isPrompt, particleAssoc.isPhysicalPrimary(), trackOrigin); diff --git a/PWGHF/HFC/TableProducer/femtoDreamProducer.cxx b/PWGHF/HFC/TableProducer/femtoDreamProducer.cxx index a605bc74f6c..1255781f2b0 100644 --- a/PWGHF/HFC/TableProducer/femtoDreamProducer.cxx +++ b/PWGHF/HFC/TableProducer/femtoDreamProducer.cxx @@ -13,6 +13,7 @@ /// \brief Tasks that produces the track tables used for the pairing /// \author Ravindra Singh, GSI, ravindra.singh@cern.ch /// \author Biao Zhang, Heidelberg University, biao.zhang@cern.ch +/// \author Yunfan Liu, Central China Normal University, yunfan.l@cern.ch #include "PWGCF/DataModel/FemtoDerived.h" #include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" @@ -21,6 +22,7 @@ #include "PWGHF/Core/CentralityEstimation.h" #include "PWGHF/Core/DecayChannels.h" #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/HfMlResponseDplusToPiKPi.h" #include "PWGHF/Core/HfMlResponseLcToPKPi.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" @@ -87,6 +89,11 @@ enum MlMode : uint8_t { FillMlFromNewBDT }; +// decay channels +enum DecayChannel { DplusToPiKPi = 0, + LcToPKPi +}; + struct HfFemtoDreamProducer { Produces outputCollision; @@ -95,6 +102,7 @@ struct HfFemtoDreamProducer { Produces rowCandMcCharmHad; Produces rowCandCharmHadGen; Produces outputPartsIndex; + Produces outputPartsTime; Produces outputMcCollision; Produces outputCollsMcLabels; Produces outputParts; @@ -119,16 +127,16 @@ struct HfFemtoDreamProducer { Configurable isDebug{"isDebug", true, "Enable Debug tables"}; Configurable isRun3{"isRun3", true, "Running on Run3 or pilot"}; - /// Lc table - Configurable selectionFlagLc{"selectionFlagLc", 1, "Selection Flag for Lc"}; - Configurable useCent{"useCent", false, "Enable centrality for lc"}; + /// Charm hadron table + Configurable selectionFlagHadron{"selectionFlagHadron", 1, "Selection Flag for Charm Hadron: 1 for Lc, 7 for Dplus (Topologic and PID cuts)"}; + Configurable useCent{"useCent", false, "Enable centrality for Charm Hadron"}; Configurable trkPDGCode{"trkPDGCode", 2212, "PDG code of the selected track for Monte Carlo truth"}; Configurable> trkCharge{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kSign, "trk"), std::vector{-1, 1}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kSign, "Track selection: ")}; Configurable> trkDCAxyMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAxyMax, "trk"), std::vector{0.1f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAxyMax, "Track selection: ")}; Configurable> trkDCAzMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kDCAzMax, "trk"), std::vector{0.2f, 3.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kDCAzMax, "Track selection: ")}; Configurable> trkEta{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kEtaMax, "trk"), std::vector{0.8f, 0.7f, 0.9f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kEtaMax, "Track selection: ")}; - Configurable> trkPIDspecies{"trkPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton}, "Trk sel: Particles species for PID"}; + Configurable> trkPIDspecies{"trkPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, "Trk sel: Particles species for PID"}; Configurable> trkPIDnSigmaMax{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kPIDnSigmaMax, "trk"), std::vector{3.5f, 3.f, 2.5f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kPIDnSigmaMax, "Track selection: ")}; Configurable trkPIDnSigmaOffsetTPC{"trkPIDnSigmaOffsetTPC", 0., "Offset for TPC nSigma because of bad calibration"}; Configurable trkPIDnSigmaOffsetTOF{"trkPIDnSigmaOffsetTOF", 0., "Offset for TOF nSigma because of bad calibration"}; @@ -141,7 +149,7 @@ struct HfFemtoDreamProducer { Configurable> trkITSnclsIbMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsIbMin, "trk"), std::vector{-1.f, 1.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsIbMin, "Track selection: ")}; Configurable> trkITSnclsMin{FemtoDreamTrackSelection::getSelectionName(femtoDreamTrackSelection::kITSnClsMin, "trk"), std::vector{-1.f, 2.f, 4.f}, FemtoDreamTrackSelection::getSelectionHelper(femtoDreamTrackSelection::kITSnClsMin, "Track selection: ")}; // ML inference - Configurable applyMlMode{"applyMlMode", 1, "None: 0, BDT model from Lc selector: 1, New BDT model on Top of Lc selector: 2"}; + Configurable applyMlMode{"applyMlMode", 1, "None: 0, BDT model from candidate selector: 1, New BDT model on Top of candidate selector: 2"}; Configurable> binsPtMl{"binsPtMl", std::vector{hf_cuts_ml::vecBinsPt}, "pT bin limits for ML application"}; Configurable> cutDirMl{"cutDirMl", std::vector{hf_cuts_ml::vecCutDir}, "Whether to reject score values greater or smaller than the threshold"}; Configurable> cutsMl{"cutsMl", {hf_cuts_ml::Cuts[0], hf_cuts_ml::NBinsPt, hf_cuts_ml::NCutScores, hf_cuts_ml::labelsPt, hf_cuts_ml::labelsCutScore}, "ML selections per pT bin"}; @@ -152,6 +160,8 @@ struct HfFemtoDreamProducer { HfHelper hfHelper; o2::analysis::HfMlResponseLcToPKPi hfMlResponse; + o2::analysis::HfMlResponseDplusToPiKPi hfMlResponseDplus; + std::vector outputMlDplus = {}; std::vector outputMlPKPi = {}; std::vector outputMlPiKP = {}; o2::ccdb::CcdbApi ccdbApi; @@ -162,6 +172,8 @@ struct HfFemtoDreamProducer { float magField; int runNumber; + using CandidateDplus = soa::Join; + using CandidateDplusMc = soa::Join; using CandidateLc = soa::Join; using CandidateLcMc = soa::Join; @@ -176,14 +188,16 @@ struct HfFemtoDreamProducer { using GeneratedMc = soa::Filtered>; - Filter filterSelectCandidateLc = (aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlagLc || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlagLc); + Filter filterSelectCandidateDplus = (aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagHadron || aod::hf_sel_candidate_dplus::isSelDplusToPiKPi >= selectionFlagHadron); + Filter filterSelectCandidateLc = (aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlagHadron || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlagHadron); HistogramRegistry qaRegistry{"QAHistos", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry trackRegistry{"Tracks", {}, OutputObjHandlingPolicy::AnalysisObject}; void init(InitContext&) { - std::array processes = {doprocessDataCharmHad, doprocessMcCharmHad, doprocessDataCharmHadWithML, doprocessMcCharmHadWithML, doprocessMcCharmHadGen}; + std::array processes = {doprocessDataDplusToPiKPi, doprocessMcDplusToPiKPi, doprocessDataDplusToPiKPiWithML, doprocessMcDplusToPiKPiWithML, doprocessMcDplusToPiKPiGen, + doprocessDataLcToPKPi, doprocessMcLcToPKPi, doprocessDataLcToPKPiWithML, doprocessMcLcToPKPiWithML, doprocessMcLcToPKPiGen}; if (std::accumulate(processes.begin(), processes.end(), 0) != 1) { LOGP(fatal, "One and only one process function must be enabled at a time."); } @@ -378,9 +392,11 @@ struct HfFemtoDreamProducer { trackCuts.fillQA(track); // the bit-wise container of the systematic variations is obtained auto cutContainer = trackCuts.getCutContainer(track, track.pt(), track.eta(), sqrtf(powf(track.dcaXY(), 2.f) + powf(track.dcaZ(), 2.f))); - + auto bc = col.template bc_as(); + int64_t timeStamp = bc.timestamp(); // track global index outputPartsIndex(track.globalIndex()); + outputPartsTime(timeStamp); // now the table is filled outputParts(outputCollision.lastIndex(), @@ -404,7 +420,7 @@ struct HfFemtoDreamProducer { return fIsTrackFilled; } - template + template void fillCharmHadronTable(CollisionType const& col, TrackType const& tracks, CandType const& candidates) { const auto vtxZ = col.posZ(); @@ -451,44 +467,15 @@ struct HfFemtoDreamProducer { bool isTrackFilled = false; bool isSelectedMlLcToPKPi = true; bool isSelectedMlLcToPiKP = true; + bool isSelectedMlDplusToPiKPi = true; for (const auto& candidate : candidates) { + outputMlDplus = {-1.0f, -1.0f, -1.0f}; outputMlPKPi = {-1.0f, -1.0f, -1.0f}; outputMlPiKP = {-1.0f, -1.0f, -1.0f}; auto trackPos1 = candidate.template prong0_as(); // positive daughter (negative for the antiparticles) auto trackNeg = candidate.template prong1_as(); // negative daughter (positive for the antiparticles) auto trackPos2 = candidate.template prong2_as(); // positive daughter (negative for the antiparticles) - if constexpr (useCharmMl) { - /// fill with ML information - /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score - if (applyMlMode == FillMlFromSelector) { - if (candidate.mlProbLcToPKPi().size() > 0) { - outputMlPKPi.at(0) = candidate.mlProbLcToPKPi()[0]; /// bkg score - outputMlPKPi.at(1) = candidate.mlProbLcToPKPi()[1]; /// prompt score - outputMlPKPi.at(2) = candidate.mlProbLcToPKPi()[2]; /// non-prompt score - } - if (candidate.mlProbLcToPiKP().size() > 0) { - outputMlPiKP.at(0) = candidate.mlProbLcToPiKP()[0]; /// bkg score - outputMlPiKP.at(1) = candidate.mlProbLcToPiKP()[1]; /// prompt score - outputMlPiKP.at(2) = candidate.mlProbLcToPiKP()[2]; /// non-prompt score - } - } else if (applyMlMode == FillMlFromNewBDT) { - isSelectedMlLcToPKPi = false; - isSelectedMlLcToPiKP = false; - if (candidate.mlProbLcToPKPi().size() > 0) { - std::vector inputFeaturesLcToPKPi = hfMlResponse.getInputFeatures(candidate, true); - isSelectedMlLcToPKPi = hfMlResponse.isSelectedMl(inputFeaturesLcToPKPi, candidate.pt(), outputMlPKPi); - } - if (candidate.mlProbLcToPiKP().size() > 0) { - std::vector inputFeaturesLcToPiKP = hfMlResponse.getInputFeatures(candidate, false); - isSelectedMlLcToPiKP = hfMlResponse.isSelectedMl(inputFeaturesLcToPiKP, candidate.pt(), outputMlPKPi); - } - if (!isSelectedMlLcToPKPi && !isSelectedMlLcToPiKP) - continue; - } else { - LOGF(fatal, "Please check your Ml configuration!!"); - } - } auto bc = col.template bc_as(); int64_t timeStamp = bc.timestamp(); auto fillTable = [&](int CandFlag, @@ -526,8 +513,65 @@ struct HfFemtoDreamProducer { } } }; - fillTable(0, candidate.isSelLcToPKPi(), outputMlPKPi.at(0), outputMlPKPi.at(1), outputMlPKPi.at(2)); - fillTable(1, candidate.isSelLcToPiKP(), outputMlPiKP.at(0), outputMlPiKP.at(1), outputMlPiKP.at(2)); + if constexpr (channel == DecayChannel::DplusToPiKPi) { + if constexpr (useCharmMl) { + /// fill with ML information + /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score + if (applyMlMode == FillMlFromSelector) { + if (candidate.mlProbDplusToPiKPi().size() > 0) { + outputMlDplus.at(0) = candidate.mlProbDplusToPiKPi()[0]; /// bkg score + outputMlDplus.at(1) = candidate.mlProbDplusToPiKPi()[1]; /// prompt score + outputMlDplus.at(2) = candidate.mlProbDplusToPiKPi()[2]; /// non-prompt score + } + } else if (applyMlMode == FillMlFromNewBDT) { + isSelectedMlDplusToPiKPi = false; + if (candidate.mlProbDplusToPiKPi().size() > 0) { + std::vector inputFeaturesDplusToPiKPi = hfMlResponseDplus.getInputFeatures(candidate); + isSelectedMlDplusToPiKPi = hfMlResponseDplus.isSelectedMl(inputFeaturesDplusToPiKPi, candidate.pt(), outputMlDplus); + } + if (!isSelectedMlDplusToPiKPi) + continue; + } else { + LOGF(fatal, "Please check your Ml configuration!!"); + } + } + fillTable(2, candidate.isSelDplusToPiKPi(), outputMlDplus.at(0), outputMlDplus.at(1), outputMlDplus.at(2)); + + } else if constexpr (channel == DecayChannel::LcToPKPi) { + if constexpr (useCharmMl) { + /// fill with ML information + /// BDT index 0: bkg score; BDT index 1: prompt score; BDT index 2: non-prompt score + if (applyMlMode == FillMlFromSelector) { + if (candidate.mlProbLcToPKPi().size() > 0) { + outputMlPKPi.at(0) = candidate.mlProbLcToPKPi()[0]; /// bkg score + outputMlPKPi.at(1) = candidate.mlProbLcToPKPi()[1]; /// prompt score + outputMlPKPi.at(2) = candidate.mlProbLcToPKPi()[2]; /// non-prompt score + } + if (candidate.mlProbLcToPiKP().size() > 0) { + outputMlPiKP.at(0) = candidate.mlProbLcToPiKP()[0]; /// bkg score + outputMlPiKP.at(1) = candidate.mlProbLcToPiKP()[1]; /// prompt score + outputMlPiKP.at(2) = candidate.mlProbLcToPiKP()[2]; /// non-prompt score + } + } else if (applyMlMode == FillMlFromNewBDT) { + isSelectedMlLcToPKPi = false; + isSelectedMlLcToPiKP = false; + if (candidate.mlProbLcToPKPi().size() > 0) { + std::vector inputFeaturesLcToPKPi = hfMlResponse.getInputFeatures(candidate, true); + isSelectedMlLcToPKPi = hfMlResponse.isSelectedMl(inputFeaturesLcToPKPi, candidate.pt(), outputMlPKPi); + } + if (candidate.mlProbLcToPiKP().size() > 0) { + std::vector inputFeaturesLcToPiKP = hfMlResponse.getInputFeatures(candidate, false); + isSelectedMlLcToPiKP = hfMlResponse.isSelectedMl(inputFeaturesLcToPiKP, candidate.pt(), outputMlPKPi); + } + if (!isSelectedMlLcToPKPi && !isSelectedMlLcToPiKP) + continue; + } else { + LOGF(fatal, "Please check your Ml configuration!!"); + } + } + fillTable(0, candidate.isSelLcToPKPi(), outputMlPKPi.at(0), outputMlPKPi.at(1), outputMlPKPi.at(2)); + fillTable(1, candidate.isSelLcToPiKP(), outputMlPiKP.at(0), outputMlPiKP.at(1), outputMlPiKP.at(2)); + } } if (!isTrackFilled) { @@ -571,22 +615,97 @@ struct HfFemtoDreamProducer { return true; } - template + template void fillCharmHadMcGen(ParticleType particles) { // Filling particle properties rowCandCharmHadGen.reserve(particles.size()); - for (const auto& particle : particles) { - if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { - rowCandCharmHadGen( - particle.mcCollisionId(), - particle.flagMcMatchGen(), - particle.originMcGen()); + if constexpr (channel == DecayChannel::DplusToPiKPi) { + for (const auto& particle : particles) { + if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::DplusToPiKPi) { + rowCandCharmHadGen( + particle.mcCollisionId(), + particle.flagMcMatchGen(), + particle.originMcGen()); + } + } + } else if constexpr (channel == DecayChannel::LcToPKPi) { + for (const auto& particle : particles) { + if (std::abs(particle.flagMcMatchGen()) == hf_decay::hf_cand_3prong::DecayChannelMain::LcToPKPi) { + rowCandCharmHadGen( + particle.mcCollisionId(), + particle.flagMcMatchGen(), + particle.originMcGen()); + } } } } - void processDataCharmHad(FemtoFullCollision const& col, + /// DplusToPiKPi + void processDataDplusToPiKPi(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + soa::Filtered const& candidates) + { + // get magnetic field for run + getMagneticFieldTesla(col.bc_as()); + + fillCharmHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfFemtoDreamProducer, processDataDplusToPiKPi, + "Provide experimental data for DplusToPiKPi femto", false); + + void processDataDplusToPiKPiWithML(FemtoFullCollision const& col, + aod::BCsWithTimestamps const&, + FemtoHFTracks const& tracks, + soa::Filtered> const& candidates) + { + + // get magnetic field for run + getMagneticFieldTesla(col.bc_as()); + + fillCharmHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfFemtoDreamProducer, processDataDplusToPiKPiWithML, + "Provide experimental data for DplusToPiKPi with ml", false); + + void processMcDplusToPiKPi(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::McParticles const&, + CandidateDplusMc const& candidates) + { + // get magnetic field for run + getMagneticFieldTesla(col.bc_as()); + + fillCharmHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfFemtoDreamProducer, processMcDplusToPiKPi, "Provide Mc for DplusToPiKPi", false); + + void processMcDplusToPiKPiWithML(FemtoFullCollisionMc const& col, + aod::BCsWithTimestamps const&, + FemtoHFMcTracks const& tracks, + aod::McParticles const&, + soa::Join const& candidates) + { + // get magnetic field for run + getMagneticFieldTesla(col.bc_as()); + + fillCharmHadronTable(col, tracks, candidates); + } + PROCESS_SWITCH(HfFemtoDreamProducer, processMcDplusToPiKPiWithML, "Provide Mc for DplusToPiKPi with ml", false); + + void processMcDplusToPiKPiGen(GeneratedMc const& particles) + { + + fillCharmHadMcGen(particles); + } + PROCESS_SWITCH(HfFemtoDreamProducer, processMcDplusToPiKPiGen, "Provide Mc Generated DplusToPiKPi", false); + + /// LcToPKPi + void processDataLcToPKPi(FemtoFullCollision const& col, aod::BCsWithTimestamps const&, FemtoHFTracks const& tracks, soa::Filtered const& candidates) @@ -594,12 +713,12 @@ struct HfFemtoDreamProducer { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); - fillCharmHadronTable(col, tracks, candidates); + fillCharmHadronTable(col, tracks, candidates); } - PROCESS_SWITCH(HfFemtoDreamProducer, processDataCharmHad, - "Provide experimental data for charm hadron femto", false); + PROCESS_SWITCH(HfFemtoDreamProducer, processDataLcToPKPi, + "Provide experimental data for Lc(PKPi)-proton femto", false); - void processDataCharmHadWithML(FemtoFullCollision const& col, + void processDataLcToPKPiWithML(FemtoFullCollision const& col, aod::BCsWithTimestamps const&, FemtoHFTracks const& tracks, soa::Filtered()); - fillCharmHadronTable(col, tracks, candidates); + fillCharmHadronTable(col, tracks, candidates); } - PROCESS_SWITCH(HfFemtoDreamProducer, processDataCharmHadWithML, - "Provide experimental data for charm hadron femto with ml", false); + PROCESS_SWITCH(HfFemtoDreamProducer, processDataLcToPKPiWithML, + "Provide experimental data for Lc(PKPi)-proton femto with ml", false); - void processMcCharmHad(FemtoFullCollisionMc const& col, + void processMcLcToPKPi(FemtoFullCollisionMc const& col, aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, aod::McParticles const&, @@ -623,11 +742,11 @@ struct HfFemtoDreamProducer { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); - fillCharmHadronTable(col, tracks, candidates); + fillCharmHadronTable(col, tracks, candidates); } - PROCESS_SWITCH(HfFemtoDreamProducer, processMcCharmHad, "Provide Mc for charm hadron", false); + PROCESS_SWITCH(HfFemtoDreamProducer, processMcLcToPKPi, "Provide Mc for lctopkpi", false); - void processMcCharmHadWithML(FemtoFullCollisionMc const& col, + void processMcLcToPKPiWithML(FemtoFullCollisionMc const& col, aod::BCsWithTimestamps const&, FemtoHFMcTracks const& tracks, aod::McParticles const&, @@ -637,16 +756,16 @@ struct HfFemtoDreamProducer { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); - fillCharmHadronTable(col, tracks, candidates); + fillCharmHadronTable(col, tracks, candidates); } - PROCESS_SWITCH(HfFemtoDreamProducer, processMcCharmHadWithML, "Provide Mc for charm hadron with ml", false); + PROCESS_SWITCH(HfFemtoDreamProducer, processMcLcToPKPiWithML, "Provide Mc for lctopkpi with ml", false); - void processMcCharmHadGen(GeneratedMc const& particles) + void processMcLcToPKPiGen(GeneratedMc const& particles) { - fillCharmHadMcGen(particles); + fillCharmHadMcGen(particles); } - PROCESS_SWITCH(HfFemtoDreamProducer, processMcCharmHadGen, "Provide Mc Generated charm hadron", false); + PROCESS_SWITCH(HfFemtoDreamProducer, processMcLcToPKPiGen, "Provide Mc Generated lctopkpi", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/HFC/Tasks/taskCharmHadronsFemtoDream.cxx b/PWGHF/HFC/Tasks/taskCharmHadronsFemtoDream.cxx index bd9c2679ff5..5632f7eefe8 100644 --- a/PWGHF/HFC/Tasks/taskCharmHadronsFemtoDream.cxx +++ b/PWGHF/HFC/Tasks/taskCharmHadronsFemtoDream.cxx @@ -9,10 +9,11 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file taskCharmHadronsFemtoDream.cxx.cxx +/// \file taskCharmHadronsFemtoDream.cxx /// \brief Tasks that reads the track tables used for the pairing and builds pairs of two tracks /// \author Ravindra SIngh, GSI, ravindra.singh@cern.ch /// \author Biao Zhang, Heidelberg University, biao.zhang@cern.ch +/// \author Yunfan Liu, Central China Normal University, yunfan.l@cern.ch #include "PWGCF/DataModel/FemtoDerived.h" #include "PWGCF/FemtoDream/Core/femtoDreamContainer.h" @@ -43,6 +44,7 @@ #include #include #include +#include using namespace o2; using namespace o2::aod; @@ -51,6 +53,11 @@ using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::analysis::femtoDream; +inline o2::framework::expressions::Node coshEta(o2::framework::expressions::Node&& eta) +{ + return (nexp(std::move(eta)) + nexp(0.0f - std::move(eta))) * 0.5f; +} + struct HfTaskCharmHadronsFemtoDream { enum TrackCharge { @@ -58,27 +65,22 @@ struct HfTaskCharmHadronsFemtoDream { NegativeCharge = -1 }; - /// Binning configurables - ConfigurableAxis bin4Dkstar{"bin4Dkstar", {1500, 0., 6.}, "binning kstar for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; - ConfigurableAxis bin4DMult{"bin4Dmult", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f}, "multiplicity Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; - ConfigurableAxis bin4DmT{"bin4DmT", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; - ConfigurableAxis bin4DmultPercentile{"bin4DmultPercentile", {10, 0.0f, 100.0f}, "multiplicity percentile Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; - ConfigurableAxis binInvMass{"binInvMass", {400, 2.10, 2.50}, "InvMass binning"}; - ConfigurableAxis binpTCharm{"binpTCharm", {360, 0, 36}, "pT binning of charm hadron"}; - ConfigurableAxis binTempFitVarTrack{"binTempFitVarTrack", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot (Track)"}; - ConfigurableAxis binmT{"binmT", {225, 0., 7.5}, "binning mT"}; - ConfigurableAxis binmultTempFit{"binmultTempFit", {1, 0, 1}, "multiplicity Binning for the TempFitVar plot"}; - ConfigurableAxis binMulPercentile{"binMulPercentile", {10, 0.0f, 100.0f}, "multiplicity percentile Binning"}; - ConfigurableAxis binpTTrack{"binpTTrack", {50, 0.5, 10.05}, "pT binning of the pT vs. TempFitVar plot (Track)"}; - ConfigurableAxis binEta{"binEta", {{200, -1.5, 1.5}}, "eta binning"}; - ConfigurableAxis binPhi{"binPhi", {{200, 0, TMath::TwoPi()}}, "phi binning"}; - ConfigurableAxis binkT{"binkT", {150, 0., 9.}, "binning kT"}; - ConfigurableAxis binkstar{"binkstar", {1500, 0., 6.}, "binning kstar"}; - ConfigurableAxis binNSigmaTPC{"binNSigmaTPC", {1600, -8, 8}, "Binning of Nsigma TPC plot"}; - ConfigurableAxis binNSigmaTOF{"binNSigmaTOF", {3000, -15, 15}, "Binning of the Nsigma TOF plot"}; - ConfigurableAxis binNSigmaTPCTOF{"binNSigmaTPCTOF", {3000, -15, 15}, "Binning of the Nsigma TPC+TOF plot"}; - ConfigurableAxis binTPCClusters{"binTPCClusters", {163, -0.5, 162.5}, "Binning of TPC found clusters plot"}; - Configurable ConfTempFitVarMomentum{"ConfTempFitVarMomentum", 0, "Momentum used for binning: 0 -> pt; 1 -> preco; 2 -> ptpc"}; + enum PairSign { + PairNotDefined = 0, + LikeSignPair = 1, + UnLikeSignPair = 2 + }; + + constexpr static int OriginRecPrompt = 1; + constexpr static int OriginRecFD = 2; + constexpr static int CutBitChargePositive = 2; + + Produces rowFemtoResultPairs; + Produces rowFemtoResultCharm; + Produces rowFemtoResultTrk; + Produces rowFemtoResultColl; + + Configurable confTempFitVarMomentum{"confTempFitVarMomentum", 0, "Momentum used for binning: 0 -> pt; 1 -> preco; 2 -> ptpc"}; /// Particle 2 (Charm Hadrons) Configurable charmHadBkgBDTmax{"charmHadBkgBDTmax", 1., "Maximum background bdt score for Charm Hadron (particle 2)"}; @@ -104,14 +106,10 @@ struct HfTaskCharmHadronsFemtoDream { Configurable smearingByOrigin{"smearingByOrigin", false, "Obtain the smearing matrix differential in the MC origin of particle 1 and particle 2. High memory consumption. Use with care!"}; Configurable use4D{"use4D", false, "Enable four dimensional histogramms (to be used only for analysis with high statistics): k* vs multiplicity vs multiplicity percentil vs mT"}; Configurable useCPR{"useCPR", false, "Close Pair Rejection"}; - ConfigurableAxis dummy{"dummy", {1, 0, 1}, "dummy axis"}; // Mixing configurables - ConfigurableAxis mixingBinMult{"mixingBinMult", {VARIABLE_WIDTH, 0.0f, 20.0f, 60.0f, 200.0f}, "Mixing bins - multiplicity"}; - ConfigurableAxis mixingBinMultPercentile{"mixingBinMultPercentile", {VARIABLE_WIDTH, 0.0f, 100.f}, "Mixing bins - multiplicity percentile"}; - ConfigurableAxis mixingBinVztx{"mixingBinVztx", {VARIABLE_WIDTH, -10.0f, -4.f, 0.f, 4.f, 10.f}, "Mixing bins - z-vertex"}; - Configurable mixingDepth{"mixingDepth", 5, "Number of events for mixing"}; Configurable mixingBinPolicy{"mixingBinPolicy", 0, "Binning policy for mixing - 0: multiplicity, 1: multipliciy percentile, 2: both"}; + Configurable mixingDepth{"mixingDepth", 5, "Number of events for mixing"}; /// Event selection struct : ConfigurableGroup { @@ -133,23 +131,7 @@ struct HfTaskCharmHadronsFemtoDream { Configurable etaTrack1Min{"etaTrack1Min", -10., "Minimum eta of partricle 1 (Track)"}; Configurable ptTrack1Min{"ptTrack1Min", 0., "Minimum pT of partricle 1 (Track)"}; - ColumnBinningPolicy colBinningMult{{mixingBinVztx, mixingBinMult}, true}; - ColumnBinningPolicy colBinningMultPercentile{{mixingBinVztx, mixingBinMultPercentile}, true}; - ColumnBinningPolicy colBinningMultMultPercentile{{mixingBinVztx, mixingBinMult, mixingBinMultPercentile}, true}; - - FemtoDreamContainer sameEventCont; - FemtoDreamContainer mixedEventCont; - FemtoDreamPairCleaner pairCleaner; - FemtoDreamDetaDphiStar pairCloseRejectionSE; - FemtoDreamDetaDphiStar pairCloseRejectionME; - Filter eventMultiplicity = aod::femtodreamcollision::multNtr >= eventSel.multMin && aod::femtodreamcollision::multNtr <= eventSel.multMax; - Filter eventMultiplicityPercentile = aod::femtodreamcollision::multV0M >= eventSel.multPercentileMin && aod::femtodreamcollision::multV0M <= eventSel.multPercentileMax; - Filter hfCandSelFilter = aod::fdhf::candidateSelFlag >= static_cast(charmHadCandSel.value); - Filter hfMcSelFilter = nabs(aod::fdhf::flagMc) == static_cast(charmHadMcSel.value); - Filter trackEtaFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::eta < etaTrack1Max, true); - Filter trackEtaFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::eta > etaTrack1Min, true); - Filter trackPtFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt < ptTrack1Max, true); - Filter trackPtFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt > ptTrack1Min, true); + SliceCache cache; using FilteredCharmCands = soa::Filtered; using FilteredCharmCand = FilteredCharmCands::iterator; @@ -166,10 +148,70 @@ struct HfTaskCharmHadronsFemtoDream { using FilteredFDMcParts = soa::Filtered>; using FilteredFDMcPart = FilteredFDMcParts::iterator; - using FilteredFDParticles = soa::Filtered>; + using FilteredFDParticles = soa::Filtered>; using FilteredFDParticle = FilteredFDParticles::iterator; - femtodreamcollision::BitMaskType BitMask = 1 << 0; + Filter eventMultiplicity = aod::femtodreamcollision::multNtr >= eventSel.multMin && aod::femtodreamcollision::multNtr <= eventSel.multMax; + Filter eventMultiplicityPercentile = aod::femtodreamcollision::multV0M >= eventSel.multPercentileMin && aod::femtodreamcollision::multV0M <= eventSel.multPercentileMax; + Filter hfCandSelFilter = aod::fdhf::candidateSelFlag >= static_cast(charmHadCandSel.value); + Filter hfMcSelFilter = nabs(aod::fdhf::flagMc) == static_cast(charmHadMcSel.value); + Filter trackEtaFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::eta < etaTrack1Max, true); + Filter trackEtaFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::eta > etaTrack1Min, true); + Filter trackPtFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt < ptTrack1Max, true); + Filter trackPtFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt > ptTrack1Min, true); + + Preslice perCol = aod::femtodreamparticle::fdCollisionId; + Preslice perHfByCol = aod::femtodreamparticle::fdCollisionId; + + /// Partition for particle 1 + Partition partitionTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && (ncheckbit(aod::femtodreamparticle::cut, cutBitTrack1)) && ifnode(aod::femtodreamparticle::pt * coshEta(aod::femtodreamparticle::eta) <= pidThresTrack1, ncheckbit(aod::femtodreamparticle::pidcut, tpcBitTrack1), ncheckbit(aod::femtodreamparticle::pidcut, tpcTofBitTrack1)); + + Partition partitionMcTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && + (ncheckbit(aod::femtodreamparticle::cut, cutBitTrack1)) && + ifnode(aod::femtodreamparticle::pt * coshEta(aod::femtodreamparticle::eta) <= pidThresTrack1, ncheckbit(aod::femtodreamparticle::pidcut, tpcBitTrack1), ncheckbit(aod::femtodreamparticle::pidcut, tpcTofBitTrack1)); + + /// Partition for particle 2 + Partition partitionCharmHadron = aod::fdhf::bdtBkg < charmHadBkgBDTmax && aod::fdhf::bdtFD < charmHadFdBDTmax && aod::fdhf::bdtFD > charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmHadPromptBDTmin; + Partition partitionMcCharmHadron = aod::fdhf::originMcRec == OriginRecPrompt || aod::fdhf::originMcRec == OriginRecFD; + + /// Axis configurables + ConfigurableAxis dummy{"dummy", {1, 0, 1}, "dummy axis"}; + /// Binning configurables + ConfigurableAxis bin4Dkstar{"bin4Dkstar", {1500, 0., 6.}, "binning kstar for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; + ConfigurableAxis bin4DMult{"bin4DMult", {VARIABLE_WIDTH, 0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f, 52.0f, 56.0f, 60.0f, 64.0f, 68.0f, 72.0f, 76.0f, 80.0f, 84.0f, 88.0f, 92.0f, 96.0f, 100.0f, 200.0f}, "multiplicity Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; + ConfigurableAxis bin4DmT{"bin4DmT", {VARIABLE_WIDTH, 1.02f, 1.14f, 1.20f, 1.26f, 1.38f, 1.56f, 1.86f, 4.50f}, "mT Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; + ConfigurableAxis bin4DmultPercentile{"bin4DmultPercentile", {10, 0.0f, 100.0f}, "multiplicity percentile Binning for the 4Dimensional plot: k* vs multiplicity vs multiplicity percentile vs mT (set <> to true in order to use)"}; + ConfigurableAxis binInvMass{"binInvMass", {400, 2.10, 2.50}, "InvMass binning"}; + ConfigurableAxis binpTCharm{"binpTCharm", {360, 0, 36}, "pT binning of charm hadron"}; + ConfigurableAxis binTempFitVarTrack{"binTempFitVarTrack", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot (Track)"}; + ConfigurableAxis binmT{"binmT", {225, 0., 7.5}, "binning mT"}; + ConfigurableAxis binmultTempFit{"binmultTempFit", {1, 0, 1}, "multiplicity Binning for the TempFitVar plot"}; + ConfigurableAxis binMulPercentile{"binMulPercentile", {10, 0.0f, 100.0f}, "multiplicity percentile Binning"}; + ConfigurableAxis binpTTrack{"binpTTrack", {50, 0.5, 10.05}, "pT binning of the pT vs. TempFitVar plot (Track)"}; + ConfigurableAxis binEta{"binEta", {{200, -1.5, 1.5}}, "eta binning"}; + ConfigurableAxis binPhi{"binPhi", {{200, 0, 2.f * 3.14159274101257324e+00f}}, "phi binning"}; + ConfigurableAxis binkT{"binkT", {150, 0., 9.}, "binning kT"}; + ConfigurableAxis binkstar{"binkstar", {1500, 0., 6.}, "binning kstar"}; + ConfigurableAxis binNSigmaTPC{"binNSigmaTPC", {1600, -8, 8}, "Binning of Nsigma TPC plot"}; + ConfigurableAxis binNSigmaTOF{"binNSigmaTOF", {3000, -15, 15}, "Binning of the Nsigma TOF plot"}; + ConfigurableAxis binNSigmaTPCTOF{"binNSigmaTPCTOF", {3000, -15, 15}, "Binning of the Nsigma TPC+TOF plot"}; + ConfigurableAxis binTPCClusters{"binTPCClusters", {163, -0.5, 162.5}, "Binning of TPC found clusters plot"}; + // Mixing axis configurables + ConfigurableAxis mixingBinMult{"mixingBinMult", {VARIABLE_WIDTH, 0.0f, 20.0f, 60.0f, 200.0f}, "Mixing bins - multiplicity"}; + ConfigurableAxis mixingBinMultPercentile{"mixingBinMultPercentile", {VARIABLE_WIDTH, 0.0f, 100.f}, "Mixing bins - multiplicity percentile"}; + ConfigurableAxis mixingBinVztx{"mixingBinVztx", {VARIABLE_WIDTH, -10.0f, -4.f, 0.f, 4.f, 10.f}, "Mixing bins - z-vertex"}; + + ColumnBinningPolicy colBinningMult{{mixingBinVztx, mixingBinMult}, true}; + ColumnBinningPolicy colBinningMultPercentile{{mixingBinVztx, mixingBinMultPercentile}, true}; + ColumnBinningPolicy colBinningMultMultPercentile{{mixingBinVztx, mixingBinMult, mixingBinMultPercentile}, true}; + + FemtoDreamContainer sameEventCont; + FemtoDreamContainer mixedEventCont; + FemtoDreamPairCleaner pairCleaner; + FemtoDreamDetaDphiStar pairCloseRejectionSE; + FemtoDreamDetaDphiStar pairCloseRejectionME; + + femtodreamcollision::BitMaskType bitMask = 1 << 0; /// Histogramming for particle 1 FemtoDreamParticleHisto allTrackHisto; @@ -181,29 +223,12 @@ struct HfTaskCharmHadronsFemtoDream { HistogramRegistry registry{"CorrelationsAndQA", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry registryMixQa{"registryMixQa"}; HistogramRegistry registryCharmHadronQa{"registryCharmHadronQa"}; - /// Partition for particle 1 - - Partition partitionTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && (ncheckbit(aod::femtodreamparticle::cut, cutBitTrack1)) && ifnode(aod::femtodreamparticle::pt * (nexp(aod::femtodreamparticle::eta) + nexp(-1.f * aod::femtodreamparticle::eta)) / 2.f <= pidThresTrack1, ncheckbit(aod::femtodreamparticle::pidcut, tpcBitTrack1), ncheckbit(aod::femtodreamparticle::pidcut, tpcTofBitTrack1)); - - Partition partitionMcTrk1 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && - (ncheckbit(aod::femtodreamparticle::cut, cutBitTrack1)) && - ifnode(aod::femtodreamparticle::pt * (nexp(aod::femtodreamparticle::eta) + nexp(-1.f * aod::femtodreamparticle::eta)) / 2.f <= pidThresTrack1, ncheckbit(aod::femtodreamparticle::pidcut, tpcBitTrack1), ncheckbit(aod::femtodreamparticle::pidcut, tpcTofBitTrack1)); - - /// Partition for particle 2 - Partition partitionCharmHadron = aod::fdhf::bdtBkg < charmHadBkgBDTmax && aod::fdhf::bdtFD < charmHadFdBDTmax && aod::fdhf::bdtFD > charmHadFdBDTmin&& aod::fdhf::bdtPrompt charmHadPromptBDTmin; - Partition partitionMcCharmHadron = aod::fdhf::originMcRec == 1 || aod::fdhf::originMcRec == 2; float massOne = o2::analysis::femtoDream::getMass(pdgCodeTrack1); float massTwo = o2::analysis::femtoDream::getMass(charmHadPDGCode); int8_t partSign = 0; int64_t processType = 0; - SliceCache cache; - Preslice perCol = aod::femtodreamparticle::fdCollisionId; - Produces rowFemtoResultCharm; - Produces rowFemtoResultTrk; - Produces rowFemtoResultColl; - void init(InitContext& /*context*/) { // setup columnpolicy for binning @@ -249,12 +274,36 @@ struct HfTaskCharmHadronsFemtoDream { registryMixQa.fill(HIST("MixingQA/hSECollisionPool"), col.posZ(), col.multNtr()); } + /// Compute the charm hadron candidates mass with the daughter masses + /// assumes the candidate is either a D+ or Λc+ + template + float getCharmHadronMass(const Candidate& cand) + { + float invMass = 0.0f; + if (charmHadPDGCode == o2::constants::physics::Pdg::kLambdaCPlus) { + if (cand.candidateSelFlag() == 1) { + invMass = cand.m(std::array{o2::constants::physics::MassProton, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); + return invMass; + } else { + invMass = cand.m(std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus, o2::constants::physics::MassProton}); + return invMass; + } + } + // D+ → π K π (PDG: 411) + if (charmHadPDGCode == o2::constants::physics::Pdg::kDPlus) { + invMass = cand.m(std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); + return invMass; + } + // Add more channels as needed + return invMass; + } + /// This function processes the same event and takes care of all the histogramming template void doSameEvent(PartitionType& sliceTrk1, CandType& sliceCharmHad, TableTracks const& parts, Collision const& col) { fillCollision(col); - + processType = 1; // for same event for (auto const& [p1, p2] : combinations(CombinationsFullIndexPolicy(sliceTrk1, sliceCharmHad))) { if (p1.trackId() == p2.prong0Id() || p1.trackId() == p2.prong1Id() || p1.trackId() == p2.prong2Id()) @@ -270,25 +319,12 @@ struct HfTaskCharmHadronsFemtoDream { continue; } - // proton track charge - float chargeTrack = 0.; - if ((p1.cut() & 2) == 2) { - chargeTrack = PositiveCharge; - } else { - chargeTrack = NegativeCharge; - } - float kstar = FemtoDreamMath::getkstar(p1, massOne, p2, massTwo); if (kstar > highkstarCut) { continue; } - float invMass; - if (p2.candidateSelFlag() == 1) { - invMass = p2.m(std::array{o2::constants::physics::MassProton, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); - } else { - invMass = p2.m(std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus, o2::constants::physics::MassProton}); - } + float invMass = getCharmHadronMass(p2); if (invMass < charmHadMinInvMass || invMass > charmHadMaxInvMass) { continue; @@ -297,8 +333,23 @@ struct HfTaskCharmHadronsFemtoDream { if (p2.pt() < charmHadMinPt || p2.pt() > charmHadMaxPt) { continue; } + + // proton track charge + float chargeTrack = 0.; + if ((p1.cut() & CutBitChargePositive) == CutBitChargePositive) { + chargeTrack = PositiveCharge; + } else { + chargeTrack = NegativeCharge; + } + int pairSign = 0; + if (chargeTrack == p2.charge()) { + pairSign = LikeSignPair; + } else { + pairSign = UnLikeSignPair; + } + /// Filling QA histograms of the selected tracks - selectedTrackHisto.fillQA(p1, static_cast(ConfTempFitVarMomentum.value), col.multNtr(), col.multV0M()); + selectedTrackHisto.fillQA(p1, static_cast(confTempFitVarMomentum.value), col.multNtr(), col.multV0M()); int charmHadMc = 0; int originType = 0; @@ -307,39 +358,24 @@ struct HfTaskCharmHadronsFemtoDream { originType = p2.originMcRec(); } - rowFemtoResultCharm( - col.globalIndex(), - p2.timeStamp(), + rowFemtoResultPairs( invMass, p2.pt(), - p2.eta(), - p2.phi(), - p2.charge(), + p1.pt(), p2.bdtBkg(), p2.bdtPrompt(), p2.bdtFD(), + kstar, + FemtoDreamMath::getkT(p1, massOne, p2, massTwo), + FemtoDreamMath::getmT(p1, massOne, p2, massTwo), + col.multNtr(), + col.multV0M(), + p2.charge(), + pairSign, + processType, charmHadMc, originType); - rowFemtoResultTrk( - col.globalIndex(), - p2.timeStamp(), - p1.pt(), - p1.eta(), - p1.phi(), - chargeTrack, - p1.tpcNClsFound(), - p1.tpcNClsFindable(), - p1.tpcNClsCrossedRows(), - p1.tpcNSigmaPr(), - p1.tofNSigmaPr()); - - rowFemtoResultColl( - col.globalIndex(), - p2.timeStamp(), - col.posZ(), - col.multNtr()); - sameEventCont.setPair(p1, p2, col.multNtr(), col.multV0M(), use4D, extendedPlots, smearingByOrigin); } } @@ -347,15 +383,15 @@ struct HfTaskCharmHadronsFemtoDream { template void doMixedEvent(CollisionType const& cols, PartType const& parts, PartitionType1& part1, PartitionType2& part2, BinningType policy) { - + processType = 2; // for mixed event // Mixed events that contain the pair of interest - Partition PartitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & BitMask) == BitMask; - PartitionMaskedCol1.bindTable(cols); + Partition partitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & bitMask) == bitMask; + partitionMaskedCol1.bindTable(cols); - Partition PartitionMaskedCol2 = (aod::femtodreamcollision::bitmaskTrackTwo & BitMask) == BitMask; - PartitionMaskedCol2.bindTable(cols); + Partition partitionMaskedCol2 = (aod::femtodreamcollision::bitmaskTrackTwo & bitMask) == bitMask; + partitionMaskedCol2.bindTable(cols); - for (auto const& [collision1, collision2] : combinations(soa::CombinationsBlockFullIndexPolicy(policy, mixingDepth.value, -1, *PartitionMaskedCol1.mFiltered, *PartitionMaskedCol2.mFiltered))) { + for (auto const& [collision1, collision2] : combinations(soa::CombinationsBlockFullIndexPolicy(policy, mixingDepth.value, -1, *partitionMaskedCol1.mFiltered, *partitionMaskedCol2.mFiltered))) { // make sure that tracks in the same events are not mixed if (collision1.globalIndex() == collision2.globalIndex()) { continue; @@ -366,7 +402,7 @@ struct HfTaskCharmHadronsFemtoDream { auto sliceTrk1 = part1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); auto sliceCharmHad = part2->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); - for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(sliceTrk1, sliceCharmHad))) { + for (const auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(sliceTrk1, sliceCharmHad))) { if (useCPR.value) { if (pairCloseRejectionME.isClosePair(p1, p2, parts, collision1.magField())) { @@ -381,12 +417,8 @@ struct HfTaskCharmHadronsFemtoDream { if (kstar > highkstarCut) { continue; } - float invMass; - if (p2.candidateSelFlag() == 1) { - invMass = p2.m(std::array{o2::constants::physics::MassProton, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); - } else { - invMass = p2.m(std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus, o2::constants::physics::MassProton}); - } + + float invMass = getCharmHadronMass(p2); if (invMass < charmHadMinInvMass || invMass > charmHadMaxInvMass) { continue; @@ -395,8 +427,45 @@ struct HfTaskCharmHadronsFemtoDream { if (p2.pt() < charmHadMinPt || p2.pt() > charmHadMaxPt) { continue; } + // proton track charge + float chargeTrack = 0.; + if ((p1.cut() & CutBitChargePositive) == CutBitChargePositive) { + chargeTrack = PositiveCharge; + } else { + chargeTrack = NegativeCharge; + } + int pairSign = 0; + if (chargeTrack == p2.charge()) { + pairSign = LikeSignPair; + } else { + pairSign = UnLikeSignPair; + } + + int charmHadMc = 0; + int originType = 0; + if constexpr (isMc) { + charmHadMc = p2.flagMc(); + originType = p2.originMcRec(); + } + + rowFemtoResultPairs( + invMass, + p2.pt(), + p1.pt(), + p2.bdtBkg(), + p2.bdtPrompt(), + p2.bdtFD(), + kstar, + FemtoDreamMath::getkT(p1, massOne, p2, massTwo), + FemtoDreamMath::getmT(p1, massOne, p2, massTwo), + collision1.multNtr(), + collision1.multV0M(), + p2.charge(), + pairSign, + processType, + charmHadMc, + originType); - // if constexpr (!isMc) mixedEventCont.setPair(p1, p2, collision1.multNtr(), collision1.multV0M(), use4D, extendedPlots, smearingByOrigin); mixedEventCont.setPair(p1, p2, collision1.multNtr(), collision1.multV0M(), use4D, extendedPlots, smearingByOrigin); } } @@ -409,23 +478,66 @@ struct HfTaskCharmHadronsFemtoDream { eventHisto.fillQA(col); auto sliceTrk1 = partitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); auto sliceCharmHad = partitionCharmHadron->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + int64_t timeStamp = -999; + /// Filling QA histograms of the all tracks and all charm hadrons before pairing for (auto const& part : sliceTrk1) { - allTrackHisto.fillQA(part, static_cast(ConfTempFitVarMomentum.value), col.multNtr(), col.multV0M()); - } - for (auto const& part : sliceCharmHad) { - float invMass; - if (part.candidateSelFlag() == 1) { - invMass = part.m(std::array{o2::constants::physics::MassProton, o2::constants::physics::MassKPlus, o2::constants::physics::MassPiPlus}); + allTrackHisto.fillQA(part, static_cast(confTempFitVarMomentum.value), col.multNtr(), col.multV0M()); + + // proton track charge + float chargeTrack = 0.; + if ((part.cut() & CutBitChargePositive) == CutBitChargePositive) { + chargeTrack = PositiveCharge; } else { - invMass = part.m(std::array{o2::constants::physics::MassPiPlus, o2::constants::physics::MassKPlus, o2::constants::physics::MassProton}); + chargeTrack = NegativeCharge; } + timeStamp = part.timeStamp(); + rowFemtoResultTrk( + col.globalIndex(), + timeStamp, + part.pt(), + part.eta(), + part.phi(), + part.trackId(), + chargeTrack, + part.tpcNClsFound(), + part.tpcNClsFindable(), + part.tpcNClsCrossedRows(), + part.tpcNSigmaPr(), + part.tofNSigmaPr()); + } + for (auto const& part : sliceCharmHad) { + float invMass = getCharmHadronMass(part); registryCharmHadronQa.fill(HIST("CharmHadronQA/hPtVsMass"), part.pt(), invMass); + timeStamp = part.timeStamp(); + + rowFemtoResultCharm( + col.globalIndex(), + timeStamp, + invMass, + part.pt(), + part.eta(), + part.phi(), + part.prong0Id(), + part.prong1Id(), + part.prong2Id(), + part.charge(), + part.bdtBkg(), + part.bdtPrompt(), + part.bdtFD()); } - if ((col.bitmaskTrackOne() & BitMask) != BitMask || (col.bitmaskTrackTwo() & BitMask) != BitMask) { + if (sliceCharmHad.size() || sliceTrk1.size()) { + + rowFemtoResultColl( + col.globalIndex(), + timeStamp, + col.posZ(), + col.multNtr()); + } else { return; } + doSameEvent(sliceTrk1, sliceCharmHad, parts, col); } PROCESS_SWITCH(HfTaskCharmHadronsFemtoDream, processSameEvent, "Enable processing same event", false); @@ -470,10 +582,10 @@ struct HfTaskCharmHadronsFemtoDream { } /// Filling QA histograms of the all mc tracks before pairing for (auto const& part : sliceMcTrk1) { - allTrackHisto.fillQA(part, static_cast(ConfTempFitVarMomentum.value), col.multNtr(), col.multV0M()); + allTrackHisto.fillQA(part, static_cast(confTempFitVarMomentum.value), col.multNtr(), col.multV0M()); } - if ((col.bitmaskTrackOne() & BitMask) != BitMask || (col.bitmaskTrackTwo() & BitMask) != BitMask) { + if ((col.bitmaskTrackOne() & bitMask) != bitMask || (col.bitmaskTrackTwo() & bitMask) != bitMask) { return; } doSameEvent(sliceMcTrk1, sliceMcCharmHad, parts, col); diff --git a/PWGHF/HFC/Tasks/taskCorrelationLcHadrons.cxx b/PWGHF/HFC/Tasks/taskCorrelationLcHadrons.cxx index 84386ab9794..fa308c257f0 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationLcHadrons.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationLcHadrons.cxx @@ -142,6 +142,7 @@ struct HfTaskCorrelationLcHadrons { Configurable ptDaughterMin{"ptDaughterMin", 0.1, "min. daughter pT"}; Configurable activateQA{"activateQA", false, "Flag to enable debug histogram"}; Configurable nTpcCrossedRaws{"nTpcCrossedRaws", 70, "Number of crossed TPC Rows"}; + Configurable useCentrality{"useCentrality", false, "Flag for centrality dependent analyses"}; // sign and invMasss Configurable fillSignAndMass{"fillSignAndMass", false, "flag to select Lc-h corr with Lc invarient mass and sign of pairs"}; Configurable calSign{"calSign", false, "flag to calculate sign of pairs"}; @@ -186,6 +187,7 @@ struct HfTaskCorrelationLcHadrons { ConfigurableAxis binsPhi{"binsPhi", {64, -PIHalf, 3. * PIHalf}, "#it{#varphi}"}; ConfigurableAxis binsMultFT0M{"binsMultFT0M", {600, 0., 8000.}, "Multiplicity as FT0M signal amplitude"}; ConfigurableAxis binsPoolBin{"binsPoolBin", {9, 0., 9.}, "PoolBin"}; + ConfigurableAxis binsCentFt0m{"binsCentFt0m", {100, 0., 100.}, "Centrality percentile (FT0M)"}; HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -204,32 +206,33 @@ struct HfTaskCorrelationLcHadrons { AxisSpec axisBdtScore = {binsBdtScore, "Bdt score"}; AxisSpec axisCorrelationState = {2, 0., 2., ""}; AxisSpec axisSignPair = {4, 1., 5.}; + AxisSpec axisCentFT0M = {binsCentFt0m, "Centrality percentile (FT0M)"}; + // Histograms for data analysis - registry.add("hBdtScorePrompt", "Lc BDT prompt score", {HistType::kTH1F, {axisBdtScore}}); - registry.add("hBdtScoreBkg", "Lc BDT bkg score", {HistType::kTH1F, {axisBdtScore}}); + registry.add("hBdtScorePrompt", "Lc BDT prompt score", {HistType::kTH1D, {axisBdtScore}}); + registry.add("hBdtScoreBkg", "Lc BDT bkg score", {HistType::kTH1D, {axisBdtScore}}); registry.add("hMassLcVsPt", "Lc candidates massVsPt", {HistType::kTH2F, {{axisMassLc}, {axisPtLc}}}); registry.add("hMassLcVsPtWoEff", "Lc candidates massVsPt without efficiency", {HistType::kTH2F, {{axisMassLc}, {axisPtLc}}}); if (fillHistoData) { - registry.add("hDeltaEtaPtIntSignalRegion", stringLcHadron + stringSignal + stringDeltaEta + "entries", {HistType::kTH1F, {axisDeltaEta}}); - registry.add("hDeltaPhiPtIntSignalRegion", stringLcHadron + stringSignal + stringDeltaPhi + "entries", {HistType::kTH1F, {axisDeltaPhi}}); + registry.add("hDeltaEtaPtIntSignalRegion", stringLcHadron + stringSignal + stringDeltaEta + "entries", {HistType::kTH1D, {axisDeltaEta}}); + registry.add("hDeltaPhiPtIntSignalRegion", stringLcHadron + stringSignal + stringDeltaPhi + "entries", {HistType::kTH1D, {axisDeltaPhi}}); registry.add("hCorrel2DPtIntSignalRegion", stringLcHadron + stringSignal + stringDeltaPhi + stringDeltaEta + "entries", {HistType::kTH2F, {{axisDeltaPhi}, {axisDeltaEta}}}); - registry.add("hDeltaEtaPtIntSidebands", stringLcHadron + stringSideband + stringDeltaEta + "entries", {HistType::kTH1F, {axisDeltaEta}}); - registry.add("hDeltaPhiPtIntSidebands", stringLcHadron + stringSideband + stringDeltaPhi + "entries", {HistType::kTH1F, {axisDeltaPhi}}); + registry.add("hDeltaEtaPtIntSidebands", stringLcHadron + stringSideband + stringDeltaEta + "entries", {HistType::kTH1D, {axisDeltaEta}}); + registry.add("hDeltaPhiPtIntSidebands", stringLcHadron + stringSideband + stringDeltaPhi + "entries", {HistType::kTH1D, {axisDeltaPhi}}); registry.add("hCorrel2DPtIntSidebands", stringLcHadron + stringSideband + stringDeltaPhi + stringDeltaEta + "entries", {HistType::kTH2F, {{axisDeltaPhi}, {axisDeltaEta}}}); - registry.add("hCorrel2DVsPtSidebands", stringLcHadron + stringSideband + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + "entries", {HistType::kTHnSparseD, {{axisDeltaPhi}, {axisDeltaEta}, {axisPtCorr}, {axisPtHadron}, {axisPoolBin}}}); - registry.add("hDeltaEtaPtIntSidebandLeft", stringLcHadron + "Left" + stringSideband + stringDeltaEta, {HistType::kTH1F, {axisDeltaEta}}); - registry.add("hDeltaPhiPtIntSidebandLeft", stringLcHadron + "Left" + stringSideband + stringDeltaPhi, {HistType::kTH1F, {axisDeltaPhi}}); - registry.add("hDeltaEtaPtIntSidebandRight", stringLcHadron + "Right" + stringSideband + stringDeltaEta, {HistType::kTH1F, {axisDeltaEta}}); - registry.add("hDeltaPhiPtIntSidebandRight", stringLcHadron + "Right" + stringSideband + stringDeltaPhi, {HistType::kTH1F, {axisDeltaPhi}}); + registry.add("hCorrel2DVsPtSidebands", stringLcHadron + stringSideband + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + "entries", {HistType::kTHnSparseF, {{axisDeltaPhi}, {axisDeltaEta}, {axisPtCorr}, {axisPtHadron}, {axisPoolBin}, {axisCentFT0M}}}); + registry.add("hDeltaEtaPtIntSidebandLeft", stringLcHadron + "Left" + stringSideband + stringDeltaEta, {HistType::kTH1D, {axisDeltaEta}}); + registry.add("hDeltaPhiPtIntSidebandLeft", stringLcHadron + "Left" + stringSideband + stringDeltaPhi, {HistType::kTH1D, {axisDeltaPhi}}); + registry.add("hDeltaEtaPtIntSidebandRight", stringLcHadron + "Right" + stringSideband + stringDeltaEta, {HistType::kTH1D, {axisDeltaEta}}); + registry.add("hDeltaPhiPtIntSidebandRight", stringLcHadron + "Right" + stringSideband + stringDeltaPhi, {HistType::kTH1D, {axisDeltaPhi}}); if (!fillSign) { - registry.add("hCorrel2DVsPtSidebandLeft", stringLcHadron + "Left" + stringSideband + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + "entries", {HistType::kTHnSparseD, {{axisDeltaPhi}, {axisDeltaEta}, {axisPtLc}, {axisPtHadron}, {axisPoolBin}}}); - registry.add("hCorrel2DVsPtSidebandRight", stringLcHadron + "Right" + stringSideband + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + "entries", {HistType::kTHnSparseD, {{axisDeltaPhi}, {axisDeltaEta}, {axisPtLc}, {axisPtHadron}, {axisPoolBin}}}); - registry.add("hCorrel2DVsPtSignalRegion", stringLcHadron + stringSignal + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + "entries", {HistType::kTHnSparseD, {{axisDeltaPhi}, {axisDeltaEta}, {axisPtCorr}, {axisPtHadron}, {axisPoolBin}}}); + registry.add("hCorrel2DVsPtSidebandLeft", stringLcHadron + "Left" + stringSideband + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + "entries", {HistType::kTHnSparseF, {{axisDeltaPhi}, {axisDeltaEta}, {axisPtLc}, {axisPtHadron}, {axisPoolBin}, {axisCentFT0M}}}); + registry.add("hCorrel2DVsPtSidebandRight", stringLcHadron + "Right" + stringSideband + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + "entries", {HistType::kTHnSparseF, {{axisDeltaPhi}, {axisDeltaEta}, {axisPtLc}, {axisPtHadron}, {axisPoolBin}, {axisCentFT0M}}}); + registry.add("hCorrel2DVsPtSignalRegion", stringLcHadron + stringSignal + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + "entries", {HistType::kTHnSparseF, {{axisDeltaPhi}, {axisDeltaEta}, {axisPtCorr}, {axisPtHadron}, {axisPoolBin}, {axisCentFT0M}}}); registry.get(HIST("hCorrel2DVsPtSidebandLeft"))->Sumw2(); registry.get(HIST("hCorrel2DVsPtSidebandRight"))->Sumw2(); registry.get(HIST("hCorrel2DVsPtSignalRegion"))->Sumw2(); - } else { registry.add("hCorrel2DVsPtSignSidebandLeft", stringLcHadron + "Left" + stringSideband + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + stringSign + "entries", {HistType::kTHnSparseF, {{axisDeltaPhi}, {axisDeltaEta}, {axisPtLc}, {axisPtHadron}, {axisSignPair}, {axisPoolBin}}}); registry.add("hCorrel2DVsPtSignSidebandRight", stringLcHadron + "Right" + stringSideband + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + stringSign + "entries", {HistType::kTHnSparseF, {{axisDeltaPhi}, {axisDeltaEta}, {axisPtLc}, {axisPtHadron}, {axisSignPair}, {axisPoolBin}}}); @@ -254,18 +257,18 @@ struct HfTaskCorrelationLcHadrons { if (fillHistoMcRec) { registry.add("hMassPromptLcVsPt", "Lc prompt candidates mass Vs Pt", {HistType::kTH2F, {{axisMassLc}, {axisPtLc}}}); registry.add("hMassNonPromptLcVsPt", "Lc non prompt candidates mass Vs Pt", {HistType::kTH2F, {{axisMassLc}, {axisPtLc}}}); - registry.add("hDeltaEtaPtIntSignalRegionMcRec", stringLcHadron + stringSignal + stringDeltaEta + "entries", {HistType::kTH1F, {axisDeltaEta}}); - registry.add("hDeltaPhiPtIntSignalRegionMcRec", stringLcHadron + stringSignal + stringDeltaPhi + "entries", {HistType::kTH1F, {axisDeltaPhi}}); - registry.add("hDeltaEtaPtIntSidebandsMcRec", stringLcHadron + stringSideband + stringDeltaEta + "entries", {HistType::kTH1F, {axisDeltaEta}}); + registry.add("hDeltaEtaPtIntSignalRegionMcRec", stringLcHadron + stringSignal + stringDeltaEta + "entries", {HistType::kTH1D, {axisDeltaEta}}); + registry.add("hDeltaPhiPtIntSignalRegionMcRec", stringLcHadron + stringSignal + stringDeltaPhi + "entries", {HistType::kTH1D, {axisDeltaPhi}}); + registry.add("hDeltaEtaPtIntSidebandsMcRec", stringLcHadron + stringSideband + stringDeltaEta + "entries", {HistType::kTH1D, {axisDeltaEta}}); registry.add("hCorrel2DPtIntSignalRegionMcRec", stringLcHadron + stringSignal + stringDeltaPhi + stringDeltaEta + "entries", {HistType::kTH2F, {{axisDeltaPhi}, {axisDeltaEta}}}); - registry.add("hDeltaPhiPtIntSidebandsMcRec", stringLcHadron + stringSideband + stringDeltaPhi + "entries", {HistType::kTH1F, {axisDeltaPhi}}); + registry.add("hDeltaPhiPtIntSidebandsMcRec", stringLcHadron + stringSideband + stringDeltaPhi + "entries", {HistType::kTH1D, {axisDeltaPhi}}); registry.add("hCorrel2DPtIntSidebandsMcRec", stringLcHadron + stringSideband + stringDeltaPhi + stringDeltaEta + "entries", {HistType::kTH2F, {{axisDeltaPhi}, {axisDeltaEta}}}); registry.add("hCorrel2DVsPtSidebandsMcRec", stringLcHadron + stringSideband + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + "entries", {HistType::kTHnSparseD, {{axisDeltaPhi}, {axisDeltaEta}, {axisPtCorr}, {axisPtHadron}, {axisPoolBin}}}); registry.add("hCorrel2DVsPtPhysicalPrimaryMcRec", stringLcHadron + "(only true primary particles)" + stringSignal, {HistType::kTHnSparseD, {{axisDeltaPhi}, {axisDeltaEta}, {axisPtLc}, {axisPtHadron}, {axisLcPrompt}, {axisPoolBin}}}); - registry.add("hDeltaEtaPtIntSidebandLeftMcRec", stringLcHadron + "Left" + stringSideband + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + "entries", {HistType::kTH1F, {axisDeltaEta}}); - registry.add("hDeltaPhiPtIntSidebandLeftMcRec", stringLcHadron + "Left" + stringSideband + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + "entries", {HistType::kTH1F, {axisDeltaPhi}}); - registry.add("hDeltaEtaPtIntSidebandRightMcRec", stringLcHadron + "Right" + stringSideband + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + "entries", {HistType::kTH1F, {axisDeltaEta}}); - registry.add("hDeltaPhiPtIntSidebandRightMcRec", stringLcHadron + "Right" + stringSideband + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + "entries", {HistType::kTH1F, {axisDeltaPhi}}); + registry.add("hDeltaEtaPtIntSidebandLeftMcRec", stringLcHadron + "Left" + stringSideband + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + "entries", {HistType::kTH1D, {axisDeltaEta}}); + registry.add("hDeltaPhiPtIntSidebandLeftMcRec", stringLcHadron + "Left" + stringSideband + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + "entries", {HistType::kTH1D, {axisDeltaPhi}}); + registry.add("hDeltaEtaPtIntSidebandRightMcRec", stringLcHadron + "Right" + stringSideband + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + "entries", {HistType::kTH1D, {axisDeltaEta}}); + registry.add("hDeltaPhiPtIntSidebandRightMcRec", stringLcHadron + "Right" + stringSideband + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + "entries", {HistType::kTH1D, {axisDeltaPhi}}); if (!fillSign) { registry.add("hCorrel2DVsPtSidebandLeftMcRec", stringLcHadron + "Left" + stringSideband + stringDeltaPhi + stringDeltaEta + stringPtLc + stringPtHadron + "entries", {HistType::kTHnSparseD, {{axisDeltaPhi}, {axisDeltaEta}, {axisPtLc}, {axisPtHadron}, {axisPoolBin}}}); @@ -317,8 +320,8 @@ struct HfTaskCorrelationLcHadrons { } // Histograms for MC Gen analysis if (fillHistoMcGen) { - registry.add("hDeltaEtaPtIntMcGen", stringMcParticles + stringDeltaEta + "entries", {HistType::kTH1F, {axisDeltaEta}}); - registry.add("hDeltaPhiPtIntMcGen", stringMcParticles + stringDeltaPhi + "entries", {HistType::kTH1F, {axisDeltaPhi}}); + registry.add("hDeltaEtaPtIntMcGen", stringMcParticles + stringDeltaEta + "entries", {HistType::kTH1D, {axisDeltaEta}}); + registry.add("hDeltaPhiPtIntMcGen", stringMcParticles + stringDeltaPhi + "entries", {HistType::kTH1D, {axisDeltaPhi}}); registry.add("hCorrel2DPtIntMcGen", stringMcParticles + stringDeltaPhi + stringDeltaEta + "entries", {HistType::kTH2F, {{axisDeltaPhi}, {axisDeltaEta}}}); if (!fillSign) { @@ -353,11 +356,11 @@ struct HfTaskCorrelationLcHadrons { registry.add("hAwayGen", "Away invmass; ptLc; correlationState;entries", {HistType::kTH3F, {{axisMassLc}, {axisPtLc}, {axisCorrelationState}}}); } // Histograms for efficiencies - registry.add("Efficiency/hPtCandMcRecPrompt", stringMcRecoLcPrompt + stringPtLc, {HistType::kTH1F, {axisPtLc}}); - registry.add("Efficiency/hPtCandMcGenPrompt", stringMcGenLcPrompt + stringPtLc, {HistType::kTH1F, {axisPtLc}}); - registry.add("Efficiency/hPtCandMcRecNonPrompt", stringMcRecoLcFd + stringPtLc, {HistType::kTH1F, {axisPtLc}}); - registry.add("Efficiency/hPtCandMcGenNonPrompt", stringMcGenLcFd + stringPtLc, {HistType::kTH1F, {axisPtLc}}); - registry.add("Efficiency/hPtCandMcGenDaughterInAcc", stringMcGenLcFd + stringPtLc, {HistType::kTH1F, {axisPtLc}}); + registry.add("Efficiency/hPtCandMcRecPrompt", stringMcRecoLcPrompt + stringPtLc, {HistType::kTH1D, {axisPtLc}}); + registry.add("Efficiency/hPtCandMcGenPrompt", stringMcGenLcPrompt + stringPtLc, {HistType::kTH1D, {axisPtLc}}); + registry.add("Efficiency/hPtCandMcRecNonPrompt", stringMcRecoLcFd + stringPtLc, {HistType::kTH1D, {axisPtLc}}); + registry.add("Efficiency/hPtCandMcGenNonPrompt", stringMcGenLcFd + stringPtLc, {HistType::kTH1D, {axisPtLc}}); + registry.add("Efficiency/hPtCandMcGenDaughterInAcc", stringMcGenLcFd + stringPtLc, {HistType::kTH1D, {axisPtLc}}); auto hCandidates = registry.add("hCandidates", "Candidate count at different steps", {HistType::kStepTHnF, {axisPtLc, axisMultFT0M, {RecoDecay::OriginType::NonPrompt + 1, +RecoDecay::OriginType::None - 0.5, +RecoDecay::OriginType::NonPrompt + 0.5}}, kCandidateNSteps}); hCandidates->GetAxis(0)->SetTitle("#it{p}_{T} (GeV/#it{c})"); @@ -371,19 +374,19 @@ struct HfTaskCorrelationLcHadrons { ccdb->setLocalObjectValidityChecking(); ccdb->setCreatedNotAfter(ccdbNoLaterThan.value); - mEfficiencyPrompt = std::shared_ptr(ccdb->getForTimeStamp(promptEffCcdbPath, timestampCcdb)); + mEfficiencyPrompt = std::shared_ptr(ccdb->getForTimeStamp(promptEffCcdbPath, timestampCcdb)); if (mEfficiencyPrompt == nullptr) { LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", promptEffCcdbPath.value.c_str()); } LOGF(info, "Loaded trigger efficiency (prompt Lc) histogram from %s", promptEffCcdbPath.value.c_str()); - mEfficiencyFD = std::shared_ptr(ccdb->getForTimeStamp(fdEffCcdbPath, timestampCcdb)); + mEfficiencyFD = std::shared_ptr(ccdb->getForTimeStamp(fdEffCcdbPath, timestampCcdb)); if (mEfficiencyFD == nullptr) { LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", fdEffCcdbPath.value.c_str()); } LOGF(info, "Loaded feed-down Lc efficiency histogram from %s", fdEffCcdbPath.value.c_str()); - mEfficiencyAssociated = std::shared_ptr(ccdb->getForTimeStamp(associatedEffCcdbPath, timestampCcdb)); + mEfficiencyAssociated = std::shared_ptr(ccdb->getForTimeStamp(associatedEffCcdbPath, timestampCcdb)); if (mEfficiencyAssociated == nullptr) { LOGF(fatal, "Could not load efficiency histogram for associated particles from %s", associatedEffCcdbPath.value.c_str()); } @@ -442,6 +445,10 @@ struct HfTaskCorrelationLcHadrons { for (const auto& pairEntry : pairEntries) { // define variables for widely used quantities float deltaPhi = pairEntry.deltaPhi(); + float cent = 0.; + if (useCentrality) { + cent = pairEntry.cent(); + } float deltaEta = pairEntry.deltaEta(); double ptLc = std::abs(pairEntry.ptLc()); double ptHadron = std::abs(pairEntry.ptHadron()); @@ -503,14 +510,13 @@ struct HfTaskCorrelationLcHadrons { if (fillSignAndMass) { registry.fill(HIST("hCorrel2DVsPtSignMass"), deltaPhi, deltaEta, ptLc, ptHadron, massLc, signPair, poolBin, efficiencyWeight); } - // check if correlation entry belongs to signal region, sidebands or is outside both, and fill correlation plots if (massLc > signalRegionInner->at(ptBinLc) && massLc < signalRegionOuter->at(ptBinLc)) { // in signal region if (fillSign) { registry.fill(HIST("hCorrel2DVsPtSignSignalRegion"), deltaPhi, deltaEta, ptLc, ptHadron, signPair, poolBin, efficiencyWeight); } else { - registry.fill(HIST("hCorrel2DVsPtSignalRegion"), deltaPhi, deltaEta, ptLc, ptHadron, poolBin, efficiencyWeight); + registry.fill(HIST("hCorrel2DVsPtSignalRegion"), deltaPhi, deltaEta, ptLc, ptHadron, poolBin, cent, efficiencyWeight); } registry.fill(HIST("hCorrel2DPtIntSignalRegion"), deltaPhi, deltaEta, efficiencyWeight); registry.fill(HIST("hDeltaEtaPtIntSignalRegion"), deltaEta, efficiencyWeight); @@ -521,11 +527,11 @@ struct HfTaskCorrelationLcHadrons { if (fillSign) { registry.fill(HIST("hCorrel2DVsPtSignSidebandLeft"), deltaPhi, deltaEta, ptLc, ptHadron, signPair, poolBin, efficiencyWeight); } else { - registry.fill(HIST("hCorrel2DVsPtSidebandLeft"), deltaPhi, deltaEta, ptLc, ptHadron, poolBin, efficiencyWeight); + registry.fill(HIST("hCorrel2DVsPtSidebandLeft"), deltaPhi, deltaEta, ptLc, ptHadron, poolBin, cent, efficiencyWeight); } registry.fill(HIST("hDeltaEtaPtIntSidebandLeft"), deltaEta, efficiencyWeight); registry.fill(HIST("hDeltaPhiPtIntSidebandLeft"), deltaPhi, efficiencyWeight); - registry.fill(HIST("hCorrel2DVsPtSidebands"), deltaPhi, deltaEta, ptLc, ptHadron, poolBin, efficiencyWeight); + registry.fill(HIST("hCorrel2DVsPtSidebands"), deltaPhi, deltaEta, ptLc, ptHadron, poolBin, cent, efficiencyWeight); registry.fill(HIST("hCorrel2DPtIntSidebands"), deltaPhi, deltaEta, efficiencyWeight); registry.fill(HIST("hDeltaEtaPtIntSidebands"), deltaEta, efficiencyWeight); registry.fill(HIST("hDeltaPhiPtIntSidebands"), deltaPhi, efficiencyWeight); @@ -535,11 +541,11 @@ struct HfTaskCorrelationLcHadrons { if (fillSign) { registry.fill(HIST("hCorrel2DVsPtSignSidebandRight"), deltaPhi, deltaEta, ptLc, ptHadron, signPair, poolBin, efficiencyWeight); } else { - registry.fill(HIST("hCorrel2DVsPtSidebandRight"), deltaPhi, deltaEta, ptLc, ptHadron, poolBin, efficiencyWeight); + registry.fill(HIST("hCorrel2DVsPtSidebandRight"), deltaPhi, deltaEta, ptLc, ptHadron, poolBin, cent, efficiencyWeight); } registry.fill(HIST("hDeltaEtaPtIntSidebandRight"), deltaEta, efficiencyWeight); registry.fill(HIST("hDeltaPhiPtIntSidebandRight"), deltaPhi, efficiencyWeight); - registry.fill(HIST("hCorrel2DVsPtSidebands"), deltaPhi, deltaEta, ptLc, ptHadron, poolBin, efficiencyWeight); + registry.fill(HIST("hCorrel2DVsPtSidebands"), deltaPhi, deltaEta, ptLc, ptHadron, poolBin, cent, efficiencyWeight); registry.fill(HIST("hCorrel2DPtIntSidebands"), deltaPhi, deltaEta, efficiencyWeight); registry.fill(HIST("hDeltaEtaPtIntSidebands"), deltaEta, efficiencyWeight); registry.fill(HIST("hDeltaPhiPtIntSidebands"), deltaPhi, efficiencyWeight); @@ -697,13 +703,13 @@ struct HfTaskCorrelationLcHadrons { registry.fill(HIST("hDeltaPhiPtIntSignalRegionMcRec"), deltaPhi, efficiencyWeight); if (isPhysicalPrimary) { registry.fill(HIST("hCorrel2DVsPtPhysicalPrimaryMcRec"), deltaPhi, deltaEta, ptLc, ptHadron, statusLcPrompt, poolBin, efficiencyWeight); - if (statusLcPrompt == 1 && statusPromptHadron == 1) { + if (statusLcPrompt == 1 && statusPromptHadron == RecoDecay::OriginType::Prompt) { if (fillSign) { registry.fill(HIST("hCorrel2DVsPtSignSignalRegionPromptLcPromptHadronMcRec"), deltaPhi, deltaEta, ptLc, ptHadron, signPair, poolBin, efficiencyWeight); } else { registry.fill(HIST("hCorrel2DVsPtSignalRegionPromptLcPromptHadronMcRec"), deltaPhi, deltaEta, ptLc, ptHadron, poolBin, efficiencyWeight); } - } else if (statusLcPrompt == 0 && statusPromptHadron == 2) { + } else if (statusLcPrompt == 0 && statusPromptHadron == RecoDecay::OriginType::NonPrompt) { if (fillSign) { registry.fill(HIST("hCorrel2DVsPtSignSignalRegionNonPromptLcNonPromptHadronMcRec"), deltaPhi, deltaEta, ptLc, ptHadron, signPair, poolBin, efficiencyWeight); } else { @@ -796,7 +802,7 @@ struct HfTaskCorrelationLcHadrons { } else { registry.fill(HIST("hCorrel2DVsPtMcGenPrompt"), deltaPhi, deltaEta, ptLc, ptHadron, poolBin); } - if (statusPromptHadron == 1) { + if (statusPromptHadron == RecoDecay::OriginType::Prompt) { if (fillSign) { registry.fill(HIST("hCorrel2DVsPtSignMcGenPromptLcPromptHadron"), deltaPhi, deltaEta, ptLc, ptHadron, signPair, poolBin); } else { @@ -809,7 +815,7 @@ struct HfTaskCorrelationLcHadrons { } else { registry.fill(HIST("hCorrel2DVsPtMcGenNonPrompt"), deltaPhi, deltaEta, ptLc, ptHadron, poolBin); } - if (statusPromptHadron == 2) { + if (statusPromptHadron == RecoDecay::OriginType::NonPrompt) { if (fillSign) { registry.fill(HIST("hCorrel2DVsPtSignMcGenNonPromptLcNonPromptHadron"), deltaPhi, deltaEta, ptLc, ptHadron, signPair, poolBin); } else { diff --git a/PWGHF/HFC/Tasks/taskFlow.cxx b/PWGHF/HFC/Tasks/taskFlow.cxx index 6f6870c49fc..b3813942454 100644 --- a/PWGHF/HFC/Tasks/taskFlow.cxx +++ b/PWGHF/HFC/Tasks/taskFlow.cxx @@ -63,6 +63,29 @@ using namespace o2::constants::math; using namespace o2::framework; using namespace o2::framework::expressions; +enum MftTrackSelectionStep { + NoSelection = 0, + Eta, + Cluster, + NMftTrackSelectionSteps +}; + +enum MftTrackAmbiguityStep { + AllMftTracks = 0, + AfterTrackSelection, + NumberOfAmbiguousTracks, + NumberOfNonAmbiguousTracks, + NMftAmbiguitySteps +}; + +enum EventSelectionStep { + AllEvents = 0, + AfterEventSelection, + NEventSelectionSteps +}; + +// static constexpr float kPairCutDefaults[1][5] = {{-1, -1, -1, -1, -1}}; + struct HfTaskFlow { // configurables for processing options @@ -70,11 +93,13 @@ struct HfTaskFlow { Configurable centralityBinsForMc{"centralityBinsForMc", false, "false = OFF, true = ON for data like multiplicity/centrality bins for MC steps"}; Configurable mftMaxDCAxy{"mftMaxDCAxy", 2.0f, "Cut on dcaXY for MFT tracks"}; Configurable doReferenceFlow{"doReferenceFlow", false, "Flag to know if reference flow should be done"}; + // Configurable doTwoTrackCut{"doTwoTrackCut", -1, "Two track cut: -1 = off; >0 otherwise distance value (suggested: 0.02)"}; Configurable processRun2{"processRun2", false, "Flag to run on Run 2 data"}; Configurable processRun3{"processRun3", true, "Flag to run on Run 3 data"}; Configurable processMc{"processMc", false, "Flag to run on MC"}; Configurable nMixedEvents{"nMixedEvents", 5, "Number of mixed events per event"}; - // configurables for collisions + // Configurable twoTrackCutMinRadius{"twoTrackCutMinRadius", 0.8f, "Two track cut : radius in m from which two tracks cuts are applied"}; + // configurables for collisions Configurable zVertexMax{"zVertexMax", 7.0f, "Accepted z-vertex range"}; // configurables for TPC tracks Configurable etaTpcTrackMax{"etaTpcTrackMax", 0.8f, "max. eta of TPC tracks"}; @@ -97,6 +122,7 @@ struct HfTaskFlow { HfHelper hfHelper; SliceCache cache; Service pdg; + // Service ccdb; std::vector hfIndexCache; // ========================= @@ -106,8 +132,11 @@ struct HfTaskFlow { using FilteredCollisionsWSelMult = soa::Filtered>; using HfCandidatesSelD0 = soa::Filtered>; using HfCandidatesSelLc = soa::Filtered>; - // using FilteredMftTracksWColls = soa::Filtered>; - using FilteredMftTracksWColls = soa::Filtered; + + // using FilteredMftTracks = soa::Filtered; + // using FilteredMftTracksWColls = soa::Filtered>; + // using FilteredAndReassociatedMftTracks = soa::Filtered>; + using FilteredTracksWDcaSel = soa::Filtered>; // ========================= @@ -126,7 +155,7 @@ struct HfTaskFlow { using McParticles2ProngMatched = soa::Join; using McParticles3ProngMatched = soa::Join; // using FilteredMftTracksWCollsMcLabels = soa::Filtered>; - using FilteredMftTracksWCollsMcLabels = soa::Filtered>; + using MftTracksMcLabels = soa::Join; using FilteredTracksWDcaSelMC = soa::Filtered>; // ========================= @@ -149,12 +178,12 @@ struct HfTaskFlow { (aod::track::pt > ptTpcTrackMin) && requireGlobalTrackWoPtEtaInFilter(); - Filter mftTrackEtaFilter = (aod::fwdtrack::eta < etaMftTrackMax) && - (aod::fwdtrack::eta > etaMftTrackMin); + // Filter mftTrackEtaFilter = (aod::fwdtrack::eta < etaMftTrackMax) && + // (aod::fwdtrack::eta > etaMftTrackMin); - Filter mftTrackCollisionIdFilter = (aod::fwdtrack::bestCollisionId >= 0); - - Filter mftTrackDcaFilter = (nabs(aod::fwdtrack::bestDCAXY) < mftMaxDCAxy); + // Filters below will be used for uncertainties + // Filter mftTrackCollisionIdFilter = (aod::fwdtrack::bestCollisionId >= 0); + // Filter mftTrackDcaFilter = (nabs(aod::fwdtrack::bestDCAXY) < mftMaxDCAxy); // ========================= // Filters & partitions : MC @@ -185,13 +214,13 @@ struct HfTaskFlow { // Preslice : DATA // ========================= - // Preslice dataPerCol = aod::track::collisionId; + Preslice perCol = o2::aod::fwdtrack::collisionId; // ========================= // Preslice : MC // ========================= - Preslice mftTracksPerCollision = aod::fwdtrack::collisionId; + Preslice mftTracksPerCollision = aod::fwdtrack::collisionId; // Preslice d0CandidatesPerCollision = aod::hf_cand::collisionId; // Preslice mcPerCol = aod::mcparticle::mcCollisionId; // PresliceUnsorted collisionsMcLabelPerMcCollision = aod::mccollisionlabel::mcCollisionId; @@ -234,23 +263,46 @@ struct HfTaskFlow { // ========================= void init(InitContext&) { + const int nBinsMix = axisMultiplicity->size() * axisVertex->size(); + // ========================= // Event histograms // TO-DO : do i have to separate event histograms between DATA and MC ? // ========================= - constexpr int kNBinsEvents = 2; - registry.add("Data/hEventCounter", "hEventCounter", {HistType::kTH1F, {{kNBinsEvents, 0.5, 0.5 + kNBinsEvents}}}); - // set axes of the event counter histogram - std::string labels[kNBinsEvents]; - labels[0] = "all"; - labels[1] = "after Physics selection"; - const int nBinsMix = axisMultiplicity->size() * 14; // 14 bins for z-vertex + registry.add("Data/hEventCounter", "hEventCounter", {HistType::kTH1D, {{EventSelectionStep::NEventSelectionSteps, -0.5, +EventSelectionStep::NEventSelectionSteps - 0.5}}}); + std::string labels[EventSelectionStep::NEventSelectionSteps]; + labels[EventSelectionStep::AllEvents] = "all"; + labels[EventSelectionStep::AfterEventSelection] = "after Physics selection"; + registry.get(HIST("Data/hEventCounter"))->SetMinimum(0); - for (int iBin = 0; iBin < kNBinsEvents; iBin++) { + for (int iBin = 0; iBin < EventSelectionStep::NEventSelectionSteps; iBin++) { registry.get(HIST("Data/hEventCounter"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); } + registry.add("Data/TpcMft/hAmbiguityOfMftTracks", "hAmbiguityOfMftTracks", {HistType::kTH1D, {{MftTrackAmbiguityStep::NMftAmbiguitySteps, -0.5, +MftTrackAmbiguityStep::NMftAmbiguitySteps - 0.5}}}); + std::string labelsAmbiguityOfMftTracks[MftTrackAmbiguityStep::NMftAmbiguitySteps]; + labelsAmbiguityOfMftTracks[MftTrackAmbiguityStep::AllMftTracks] = "all MFT tracks"; + labelsAmbiguityOfMftTracks[MftTrackAmbiguityStep::AfterTrackSelection] = "MFT tracks after selection"; + labelsAmbiguityOfMftTracks[MftTrackAmbiguityStep::NumberOfAmbiguousTracks] = "how much tracks are ambigous"; + labelsAmbiguityOfMftTracks[MftTrackAmbiguityStep::NumberOfNonAmbiguousTracks] = "how much tracks are non-ambiguous"; + registry.get(HIST("Data/TpcMft/hAmbiguityOfMftTracks"))->SetMinimum(0); + + for (int iBin = 0; iBin < NMftAmbiguitySteps; iBin++) { + registry.get(HIST("Data/TpcMft/hAmbiguityOfMftTracks"))->GetXaxis()->SetBinLabel(iBin + 1, labelsAmbiguityOfMftTracks[iBin].data()); + } + + registry.add("Data/TpcMft/hMftTracksSelection", "hMftTracksSelection", {HistType::kTH1D, {{MftTrackSelectionStep::NMftTrackSelectionSteps, -0.5, +MftTrackSelectionStep::NMftTrackSelectionSteps - 0.5}}}); + std::string labelsMftTracksSelection[MftTrackSelectionStep::NMftTrackSelectionSteps]; + labelsMftTracksSelection[MftTrackSelectionStep::NoSelection] = "all MFT tracks"; + labelsMftTracksSelection[MftTrackSelectionStep::Eta] = "MFT tracks after eta selection"; + labelsMftTracksSelection[MftTrackSelectionStep::Cluster] = "MFT tracks after clusters selection"; + registry.get(HIST("Data/TpcMft/hMftTracksSelection"))->SetMinimum(0); + + for (int iBin = 0; iBin < MftTrackSelectionStep::NMftTrackSelectionSteps; iBin++) { + registry.get(HIST("Data/TpcMft/hMftTracksSelection"))->GetXaxis()->SetBinLabel(iBin + 1, labelsMftTracksSelection[iBin].data()); + } + // ========================= // DATA : histograms for TPC-TPC h-h case // ========================= @@ -258,12 +310,12 @@ struct HfTaskFlow { // DATA : event histograms for TPC-TPC h-h same event registry.add("Data/TpcTpc/HadronHadron/SameEvent/hMultiplicity", "hMultiplicity", {HistType::kTH1F, {axisMultiplicity}}); registry.add("Data/TpcTpc/HadronHadron/SameEvent/hVtxZ", "hVtxZ", {HistType::kTH1F, {axisVertex}}); - registry.add("Data/TpcTpc/HadronHadron/SameEvent/hEventCountSame", "bin", {HistType::kTH1F, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); + registry.add("Data/TpcTpc/HadronHadron/SameEvent/hEventCountSame", "bin", {HistType::kTH1D, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); // DATA : associated particles histograms for TPC-TPC h-h same event registry.add("Data/TpcTpc/HadronHadron/SameEvent/hPt", "pT", {HistType::kTH1F, {axisPt}}); - registry.add("Data/TpcTpc/HadronHadron/SameEvent/hEta", "eta", {HistType::kTH1F, {axisEtaTpc}}); - registry.add("Data/TpcTpc/HadronHadron/SameEvent/hPhi", "phi", {HistType::kTH1F, {axisPhi}}); + registry.add("Data/TpcTpc/HadronHadron/SameEvent/hEta", "eta", {HistType::kTH1D, {axisEtaTpc}}); + registry.add("Data/TpcTpc/HadronHadron/SameEvent/hPhi", "phi", {HistType::kTH1D, {axisPhi}}); registry.add("Data/TpcTpc/HadronHadron/SameEvent/hYields", "multiplicity vs pT vs eta", {HistType::kTH3F, {axisMultiplicity, axisPt, axisEtaTpc}}); registry.add("Data/TpcTpc/HadronHadron/SameEvent/hEtaPhi", "multiplicity vs eta vs phi", {HistType::kTH3F, {axisMultiplicity, axisEtaTpc, axisPhi}}); @@ -271,7 +323,7 @@ struct HfTaskFlow { registry.add("Data/TpcTpc/HadronHadron/SameEvent/hVzEta", "eta vs. Vz", {HistType::kTH2F, {axisEtaTpc, axisVertex}}); // DATA : event mixing histograms for TPC-TPC h-h mixed event - registry.add("Data/TpcTpc/HadronHadron/MixedEvent/hEventCountMixing", "bin", {HistType::kTH1F, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); + registry.add("Data/TpcTpc/HadronHadron/MixedEvent/hEventCountMixing", "bin", {HistType::kTH1D, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); // ========================= // DATA : histograms for TPC-TPC HF-h case for 2PRONG @@ -279,16 +331,16 @@ struct HfTaskFlow { // DATA : event histograms for TPC-TPC HF-h same event registry.add("Data/TpcTpc/HfHadron/SameEvent/hPt", "pT", {HistType::kTH1F, {axisPt}}); - registry.add("Data/TpcTpc/HfHadron/SameEvent/hEta", "eta", {HistType::kTH1F, {axisEtaTpc}}); - registry.add("Data/TpcTpc/HfHadron/SameEvent/hPhi", "phi", {HistType::kTH1F, {axisPhi}}); + registry.add("Data/TpcTpc/HfHadron/SameEvent/hEta", "eta", {HistType::kTH1D, {axisEtaTpc}}); + registry.add("Data/TpcTpc/HfHadron/SameEvent/hPhi", "phi", {HistType::kTH1D, {axisPhi}}); registry.add("Data/TpcTpc/HfHadron/SameEvent/hYields", "multiplicity vs pT vs eta", {HistType::kTH3F, {axisMultiplicity, axisPt, axisEtaTpc}}); registry.add("Data/TpcTpc/HfHadron/SameEvent/hEtaPhi", "multiplicity vs eta vs phi", {HistType::kTH3F, {axisMultiplicity, axisEtaTpc, axisPhi}}); - registry.add("Data/TpcTpc/HfHadron/SameEvent/2Prong/hEventCountSame", "bin", {HistType::kTH1F, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); - registry.add("Data/TpcTpc/HfHadron/SameEvent/2Prong/hEta", "eta", {HistType::kTH1F, {axisEtaTpc}}); - registry.add("Data/TpcTpc/HfHadron/SameEvent/2Prong/hPhi", "phi", {HistType::kTH1F, {axisPhi}}); + registry.add("Data/TpcTpc/HfHadron/SameEvent/2Prong/hEventCountSame", "bin", {HistType::kTH1D, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); + registry.add("Data/TpcTpc/HfHadron/SameEvent/2Prong/hEta", "eta", {HistType::kTH1D, {axisEtaTpc}}); + registry.add("Data/TpcTpc/HfHadron/SameEvent/2Prong/hPhi", "phi", {HistType::kTH1D, {axisPhi}}); registry.add("Data/TpcTpc/HfHadron/SameEvent/2Prong/hMultiplicity", "multiplicity;multiplicity;entries", {HistType::kTH1F, {axisMultiplicity}}); - registry.add("Data/TpcTpc/HfHadron/MixedEvent/hEventCountHFMixing", "bin", {HistType::kTH1F, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); + registry.add("Data/TpcTpc/HfHadron/MixedEvent/hEventCountHFMixing", "bin", {HistType::kTH1D, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); // DATA : trigger particles (candidates) histograms for TPC-TPC D0-h same event registry.add("Data/TpcTpc/HfHadron/SameEvent/2Prong/hPtCandidate", "2-prong candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPt}}); @@ -296,7 +348,7 @@ struct HfTaskFlow { registry.add("Data/TpcTpc/HfHadron/SameEvent/2Prong/hPtProng1", "2-prong candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPt}}); registry.add("Data/TpcTpc/HfHadron/SameEvent/2Prong/hMassVsPt", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisMass, axisPt}}); registry.add("Data/TpcTpc/HfHadron/SameEvent/2Prong/hMassVsPtVsMult", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2}); p_{T}; multiplicity", {HistType::kTH3F, {axisMass, axisPt, axisMultiplicity}}); - registry.add("Data/TpcTpc/HfHadron/SameEvent/2Prong/hMass", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {axisMass}}); + registry.add("Data/TpcTpc/HfHadron/SameEvent/2Prong/hMass", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1D, {axisMass}}); registry.add("Data/TpcTpc/HfHadron/SameEvent/2Prong/hEtaCandVsPt", "2-prong candidates;candidate #it{#eta};entries", {HistType::kTH2F, {axisEtaTpc, axisPt}}); registry.add("Data/TpcTpc/HfHadron/SameEvent/2Prong/hSelectionStatus", "2-prong candidates;selection status;entries", {HistType::kTH2F, {{5, -0.5, 4.5}, axisPt}}); @@ -304,17 +356,17 @@ struct HfTaskFlow { // DATA : histograms for TPC-TPC HF-h case for 3PRONG // =================== - registry.add("Data/TpcTpc/HfHadron/SameEvent/3Prong/hEventCountSame", "bin", {HistType::kTH1F, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); + registry.add("Data/TpcTpc/HfHadron/SameEvent/3Prong/hEventCountSame", "bin", {HistType::kTH1D, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); registry.add("Data/TpcTpc/HfHadron/SameEvent/3Prong/hMassVsPt", "3-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisMass, axisPt}}); - registry.add("Data/TpcTpc/HfHadron/SameEvent/3Prong/hMass", "3-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {axisMass}}); + registry.add("Data/TpcTpc/HfHadron/SameEvent/3Prong/hMass", "3-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1D, {axisMass}}); registry.add("Data/TpcTpc/HfHadron/SameEvent/3Prong/hMassVsPtVsMult", "3-prong candidates;inv. mass (p K #pi) (GeV/#it{c}^{2}); p_{T}; multiplicity", {HistType::kTH3F, {axisMass, axisPt, axisMultiplicity}}); registry.add("Data/TpcTpc/HfHadron/SameEvent/3Prong/hMultiplicity", "multiplicity;multiplicity;entries", {HistType::kTH1F, {axisMultiplicity}}); registry.add("Data/TpcTpc/HfHadron/SameEvent/3Prong/hPt", "3-prong candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPt}}); registry.add("Data/TpcTpc/HfHadron/SameEvent/3Prong/hPtProng0", "3-prong candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPt}}); registry.add("Data/TpcTpc/HfHadron/SameEvent/3Prong/hPtProng1", "3-prong candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPt}}); registry.add("Data/TpcTpc/HfHadron/SameEvent/3Prong/hPtProng2", "3-prong candidates;prong 2 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPt}}); - registry.add("Data/TpcTpc/HfHadron/SameEvent/3Prong/hEta", "3-prong candidates;#it{#eta};entries", {HistType::kTH1F, {axisEtaTpc}}); - registry.add("Data/TpcTpc/HfHadron/SameEvent/3Prong/hPhi", "3-prong candidates;#it{#Phi};entries", {HistType::kTH1F, {axisPhi}}); + registry.add("Data/TpcTpc/HfHadron/SameEvent/3Prong/hEta", "3-prong candidates;#it{#eta};entries", {HistType::kTH1D, {axisEtaTpc}}); + registry.add("Data/TpcTpc/HfHadron/SameEvent/3Prong/hPhi", "3-prong candidates;#it{#Phi};entries", {HistType::kTH1D, {axisPhi}}); registry.add("Data/TpcTpc/HfHadron/SameEvent/3Prong/hEtaVsPt", "3-prong candidates;candidate #it{#eta};entries", {HistType::kTH2F, {axisEtaTpc, axisPt}}); registry.add("Data/TpcTpc/HfHadron/SameEvent/3Prong/hPhiVsPt", "3-prong candidates;candidate #it{#Phi};entries", {HistType::kTH2F, {axisPhi, axisPt}}); registry.add("Data/TpcTpc/HfHadron/SameEvent/3Prong/hSelectionStatus", "3-prong candidates;selection status;entries", {HistType::kTH2F, {{5, -0.5, 4.5}, axisPt}}); @@ -324,34 +376,34 @@ struct HfTaskFlow { // ========================= // DATA : trigger particles (TPC tracks) histograms for TPC-MFT h-h same event - registry.add("Data/TpcMft/HadronHadron/SameEvent/hEventCountSame", "bin", {HistType::kTH1F, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); + registry.add("Data/TpcMft/HadronHadron/SameEvent/hEventCountSame", "bin", {HistType::kTH1D, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); registry.add("Data/TpcMft/HadronHadron/SameEvent/hEtaPhiTPC", "multiplicity vs eta vs phi in TPC", {HistType::kTH3F, {axisMultiplicity, axisEtaTpc, axisPhi}}); - registry.add("Data/TpcMft/HadronHadron/SameEvent/hEtaTPC", "etaTPC", {HistType::kTH1F, {axisEtaTpc}}); - registry.add("Data/TpcMft/HadronHadron/SameEvent/hPhiTPC", "phiTPC", {HistType::kTH1F, {axisPhi}}); + registry.add("Data/TpcMft/HadronHadron/SameEvent/hEtaTPC", "etaTPC", {HistType::kTH1D, {axisEtaTpc}}); + registry.add("Data/TpcMft/HadronHadron/SameEvent/hPhiTPC", "phiTPC", {HistType::kTH1D, {axisPhi}}); registry.add("Data/TpcMft/HadronHadron/SameEvent/hPtTPC", "pT", {HistType::kTH1F, {axisPt}}); registry.add("Data/TpcMft/HadronHadron/SameEvent/hYieldsTPC", "multiplicity vs pT vs eta", {HistType::kTH3F, {axisMultiplicity, axisPt, axisEtaTpc}}); registry.add("Data/TpcMft/HadronHadron/SameEvent/hMultiplicityTPC", "multiplicity;multiplicity;entries", {HistType::kTH1F, {axisMultiplicity}}); // DATA : associated particles (MFT tracks) histograms for TPC-MFT h-h same event registry.add("Data/TpcMft/HadronHadron/SameEvent/hEtaPhiMFT", "multiplicity vs eta vs phi in MFT", {HistType::kTH3F, {axisMultiplicity, axisEtaMft, axisPhi}}); - registry.add("Data/TpcMft/HadronHadron/SameEvent/hEtaMFT", "etaMFT", {HistType::kTH1F, {axisEtaMft}}); - registry.add("Data/TpcMft/HadronHadron/SameEvent/hPhiMFT", "phiMFT", {HistType::kTH1F, {axisPhi}}); + registry.add("Data/TpcMft/HadronHadron/SameEvent/hEtaMFT", "etaMFT", {HistType::kTH1D, {axisEtaMft}}); + registry.add("Data/TpcMft/HadronHadron/SameEvent/hPhiMFT", "phiMFT", {HistType::kTH1D, {axisPhi}}); registry.add("Data/TpcMft/HadronHadron/SameEvent/hPtMFT", "pT", {HistType::kTH1F, {axisPt}}); registry.add("Data/TpcMft/HadronHadron/SameEvent/hYieldsMFT", "multiplicity vs pT vs eta", {HistType::kTH3F, {axisMultiplicity, axisPt, axisEtaMft}}); // DATA : histograms for TPC-MFT h-h event mixing for events QA - registry.add("Data/TpcMft/HadronHadron/MixedEvent/hEventCountMixing", "bin", {HistType::kTH1F, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); + registry.add("Data/TpcMft/HadronHadron/MixedEvent/hEventCountMixing", "bin", {HistType::kTH1D, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); // ========================= // DATA : histograms for TPC-MFT HF-h case FOR 2PRONG // ========================= // DATA : trigger particles (candidates) histograms for TPC-MFT HF-h same event - registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hEventCountSame", "bin", {HistType::kTH1F, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); + registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hEventCountSame", "bin", {HistType::kTH1D, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hEtaPhiCandidate", "multiplicity vs eta vs phi in TPC", {HistType::kTH3F, {axisMultiplicity, axisEtaMft, axisPhi}}); - registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hEtaCandidate", "etaTPC", {HistType::kTH1F, {axisEtaMft}}); - registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hPhiCandidate", "phiTPC", {HistType::kTH1F, {axisPhi}}); - registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hYieldsCandidate", "multiplicity vs pT vs eta", {HistType::kTH3F, {axisMultiplicity, axisPt, axisEtaMft}}); + registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hEtaCandidate", "etaTPC", {HistType::kTH1D, {axisEtaTpc}}); + registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hPhiCandidate", "phiTPC", {HistType::kTH1D, {axisPhi}}); + registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hYieldsCandidate", "multiplicity vs pT vs eta", {HistType::kTH3F, {axisMultiplicity, axisPt, axisEtaTpc}}); registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hMultiplicityCandidate", "multiplicity;multiplicity;entries", {HistType::kTH1F, {axisMultiplicity}}); // DATA : trigger particles (candidates) histograms for TPC-MFT HF-h same event @@ -359,42 +411,55 @@ struct HfTaskFlow { registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hPtProng0", "2-prong candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPt}}); registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hPtProng1", "2-prong candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPt}}); registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hMassVsPt", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisMass, axisPt}}); - registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hMass", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {axisMass}}); + registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hMass", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1D, {axisMass}}); registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hMassVsPtVsMult", "2-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2}); p_{T}; multiplicity", {HistType::kTH3F, {axisMass, axisPt, axisMultiplicity}}); - registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hEtaCandVsPt", "2-prong candidates;candidate #it{#eta};entries", {HistType::kTH2F, {axisEtaMft, axisPt}}); + registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hEtaCandVsPt", "2-prong candidates;candidate #it{#eta};entries", {HistType::kTH2F, {axisEtaTpc, axisPt}}); registry.add("Data/TpcMft/HfHadron/SameEvent/2Prong/hSelectionStatus", "2-prong candidates;selection status;entries", {HistType::kTH2F, {{5, -0.5, 4.5}, axisPt}}); // DATA : associated particles (MFT tracks) histograms for TPC-MFT h-h same event registry.add("Data/TpcMft/HfHadron/SameEvent/hEtaPhiMFT", "multiplicity vs eta vs phi in MFT", {HistType::kTH3F, {axisMultiplicity, axisEtaMft, axisPhi}}); - registry.add("Data/TpcMft/HfHadron/SameEvent/hEtaMFT", "etaMFT", {HistType::kTH1F, {axisEtaMft}}); - registry.add("Data/TpcMft/HfHadron/SameEvent/hPhiMFT", "phiMFT", {HistType::kTH1F, {axisPhi}}); + registry.add("Data/TpcMft/HfHadron/SameEvent/hEtaMFT", "etaMFT", {HistType::kTH1D, {axisEtaMft}}); + registry.add("Data/TpcMft/HfHadron/SameEvent/hPhiMFT", "phiMFT", {HistType::kTH1D, {axisPhi}}); registry.add("Data/TpcMft/HfHadron/SameEvent/hPtMFT", "pT", {HistType::kTH1F, {axisPt}}); registry.add("Data/TpcMft/HfHadron/SameEvent/hYieldsMFT", "multiplicity vs pT vs eta", {HistType::kTH3F, {axisMultiplicity, axisPt, axisEtaMft}}); // DATA : histograms for TPC-MFT h-h event mixing for events QA - registry.add("Data/TpcMft/HfHadron/MixedEvent/hEventCountMixing", "bin", {HistType::kTH1F, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); + registry.add("Data/TpcMft/HfHadron/MixedEvent/hEventCountMixing", "bin", {HistType::kTH1D, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); // ========================= // DATA : histograms for TPC-MFT HF-h case FOR 3PRONG // ========================= - registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hEventCountSame", "bin", {HistType::kTH1F, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); - registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hYieldsCandidate", "multiplicity vs pT vs eta", {HistType::kTH3F, {axisMultiplicity, axisPt, axisEtaMft}}); + registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hEventCountSame", "bin", {HistType::kTH1D, {{nBinsMix + 2, -2.5, -0.5 + nBinsMix, "bin"}}}); + registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hYieldsCandidate", "multiplicity vs pT vs eta", {HistType::kTH3F, {axisMultiplicity, axisPt, axisEtaTpc}}); registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hMultiplicityCandidate", "multiplicity;multiplicity;entries", {HistType::kTH1F, {axisMultiplicity}}); - registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hEtaPhiCandidate", "multiplicity vs eta vs phi in TPC", {HistType::kTH3F, {axisMultiplicity, axisEtaMft, axisPhi}}); + registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hEtaPhiCandidate", "multiplicity vs eta vs phi in TPC", {HistType::kTH3F, {axisMultiplicity, axisEtaTpc, axisPhi}}); registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hMassVsPt", "3-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {axisMass, axisPt}}); - registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hMass", "3-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {axisMass}}); + registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hMass", "3-prong candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH1D, {axisMass}}); registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hMassVsPtVsMult", "3-prong candidates;inv. mass (p K #pi) (GeV/#it{c}^{2}); p_{T}; multiplicity", {HistType::kTH3F, {axisMass, axisPt, axisMultiplicity}}); registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hPt", "3-prong candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPt}}); registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hPtProng0", "3-prong candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPt}}); registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hPtProng1", "3-prong candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPt}}); registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hPtProng2", "3-prong candidates;prong 2 #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {axisPt}}); - registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hEta", "3-prong candidates;#it{#eta};entries", {HistType::kTH1F, {axisEtaMft}}); - registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hPhi", "3-prong candidates;#it{#Phi};entries", {HistType::kTH1F, {axisPhi}}); - registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hEtaVsPt", "3-prong candidates;candidate #it{#eta};entries", {HistType::kTH2F, {axisEtaMft, axisPt}}); + registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hEta", "3-prong candidates;#it{#eta};entries", {HistType::kTH1D, {axisEtaTpc}}); + registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hPhi", "3-prong candidates;#it{#Phi};entries", {HistType::kTH1D, {axisPhi}}); + registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hEtaVsPt", "3-prong candidates;candidate #it{#eta};entries", {HistType::kTH2F, {axisEtaTpc, axisPt}}); registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hPhiVsPt", "3-prong candidates;candidate #it{#Phi};entries", {HistType::kTH2F, {axisPhi, axisPt}}); registry.add("Data/TpcMft/HfHadron/SameEvent/3Prong/hSelectionStatus", "3-prong candidates;selection status;entries", {HistType::kTH2F, {{5, -0.5, 4.5}, axisPt}}); + // ========================= + // DATA : histograms for MFT reassociated distributions (to plot all MFT tracks, and only non-ambiguous MFT trakcs) + // ressociated tracks distribution can be found in the normal eta and phi distributions of each individual cases + // ========================= + + // All MFT tracks + registry.add("Data/TpcMft/kCFStepAll/hEta", "eta", {HistType::kTH1D, {axisEtaMft}}); + registry.add("Data/TpcMft/kCFStepAll/hPhi", "phi", {HistType::kTH1D, {axisPhi}}); + + // Only non-ambiguous MFT tracks + registry.add("Data/TpcMft/kCFStepTracked/hEta", "eta", {HistType::kTH1D, {axisEtaMft}}); + registry.add("Data/TpcMft/kCFStepTracked/hPhi", "phi", {HistType::kTH1D, {axisPhi}}); + // ========================= // MC : histograms for TPC-TPC h-h case // ========================= @@ -723,7 +788,7 @@ struct HfTaskFlow { bool isAcceptedCollision(TCollision const& collision, bool fillHistograms = false) { if (fillHistograms) { - registry.fill(HIST("Data/hEventCounter"), 1); + registry.fill(HIST("Data/hEventCounter"), EventSelectionStep::AllEvents); } if (processMc == false) { @@ -733,7 +798,7 @@ struct HfTaskFlow { } if (fillHistograms) { - registry.fill(HIST("Data/hEventCounter"), 2); + registry.fill(HIST("Data/hEventCounter"), EventSelectionStep::AfterEventSelection); } return true; @@ -775,23 +840,48 @@ struct HfTaskFlow { // I tried to put it as a filter, but filters for normal TPC tracks also apply to MFT tracks I think // and it seems that they are not compatible template - bool isAcceptedMftTrack(TTrack const& mftTrack) + bool isAcceptedMftTrack(TTrack const& mftTrack, bool fillHistograms) { // cut on the eta of MFT tracks - // if (mftTrack.eta() > etaMftTrackMax || mftTrack.eta() < etaMftTrackMin) { - // return false; - // } + if (mftTrack.eta() > etaMftTrackMax || mftTrack.eta() < etaMftTrackMin) { + return false; + } + + if (fillHistograms) { + registry.fill(HIST("Data/TpcMft/hMftTracksSelection"), MftTrackSelectionStep::Eta); + } // cut on the number of clusters of the reconstructed MFT track if (mftTrack.nClusters() < nClustersMftTrack) { return false; } + if (fillHistograms) { + registry.fill(HIST("Data/TpcMft/hMftTracksSelection"), MftTrackSelectionStep::Cluster); + } + return true; } + // Cut on ambiguous MFT tracks + template + bool isAmbiguousMftTrack(TTrack const& mftTrack, bool fillHistograms) + { + if (mftTrack.ambDegree() > 1) { + if (fillHistograms) { + registry.fill(HIST("Data/TpcMft/hAmbiguityOfMftTracks"), MftTrackAmbiguityStep::NumberOfAmbiguousTracks); + } + return true; + } + + if (fillHistograms) { + registry.fill(HIST("Data/TpcMft/hAmbiguityOfMftTracks"), MftTrackAmbiguityStep::NumberOfNonAmbiguousTracks); + } + return false; + } + // I am not sure if to template McParticles is useful, I'll address this when doing the MC Gen case of HF-h correlations - template + template bool isAcceptedMcCandidate(TMcTrack& mcCandidate) { auto etaCandidate = mcCandidate.eta(); @@ -870,8 +960,8 @@ struct HfTaskFlow { // fillCorrelations // =============================================================================================================================================================================== - template - void fillCorrelations(TTarget target, + template + void fillCorrelations(TTarget target, CorrelationContainer::CFStep step, TTracksTrig const& tracks1, TTracksAssoc const& tracks2, float multiplicity, float posZ, bool sameEvent) { @@ -919,7 +1009,7 @@ struct HfTaskFlow { // Selections for MC GENERATED if constexpr (std::is_same_v || std::is_same_v) { // TODO: Check how to put this into a Filter -> Pretty sure it cannot be a filter - if (!isAcceptedMcCandidate(track1)) { + if (!isAcceptedMcCandidate(track1)) { continue; } fillingHFcontainer = true; @@ -940,10 +1030,10 @@ struct HfTaskFlow { } // FILL QA PLOTS for trigger particle - if (sameEvent) { - if (processMc == false) { // If DATA - if constexpr (!std::is_same_v) { // IF TPC-TPC case - if constexpr (std::is_same_v) { // IF D0 CASE -> TPC-TPC D0-h + if (sameEvent && (step == CorrelationContainer::kCFStepReconstructed)) { + if (processMc == false) { // If DATA + if constexpr (!std::is_same_v) { // IF TPC-TPC case + if constexpr (std::is_same_v) { // IF D0 CASE -> TPC-TPC D0-h fillTpcTpcD0CandidateQa(multiplicity, track1); } else if constexpr (std::is_same_v) { // IF LC CASE -> TPC-TPC Lc-h fillTpcTpcLcCandidateQa(multiplicity, track1); @@ -960,8 +1050,8 @@ struct HfTaskFlow { } // end of if condition for TPC-TPC or TPC-MFT case } // Maybe I won't need it for MC (first files are way lighter in MC, but also I need to loop over all tracks in MC GEN) - } else { // If MC (add cases later) - if constexpr (!std::is_same_v) { // IF TPC-TPC case + } else { // If MC (add cases later) + if constexpr (!std::is_same_v) { // IF TPC-TPC case fillTpcTpcChChSameEventQaMc(multiplicity, track1); } } @@ -973,8 +1063,10 @@ struct HfTaskFlow { for (const auto& track2 : tracks2) { // apply cuts for MFT tracks - if constexpr (std::is_same_v) { - if (!isAcceptedMftTrack(track2)) { + if constexpr (std::is_same_v) { + registry.fill(HIST("Data/TpcMft/hMftTracksSelection"), MftTrackSelectionStep::NoSelection); + + if (!isAcceptedMftTrack(track2, true)) { continue; } } @@ -989,8 +1081,8 @@ struct HfTaskFlow { // in case of HF-h correlations, remove candidate daughters from the pool of associated hadrons // with which the candidate is being correlated (will not have to do it for TPC-MFT case) - if constexpr (!std::is_same_v) { // if NOT TPC-MFT case -> TPC-TPC case - if constexpr (std::is_same_v) { // Remove the 2 prong daughters + if constexpr (!std::is_same_v) { // if NOT TPC-MFT case -> TPC-TPC case + if constexpr (std::is_same_v) { // Remove the 2 prong daughters if ((track1.prong0Id() == track2.globalIndex()) || (track1.prong1Id() == track2.globalIndex())) { continue; } @@ -1010,6 +1102,10 @@ struct HfTaskFlow { } } + // if constexpr (std::is_same_v) { + // registry.fill(HIST("MC/Gen/TpcMft/HfHadron/SameEvent/hEtaMFT"), track2.eta()); + // } + float eta2 = track2.eta(); float pt2 = track2.pt(); float phi2 = track2.phi(); @@ -1023,6 +1119,7 @@ struct HfTaskFlow { // set range of delta phi in (-pi/2 , 3/2*pi) deltaPhi = RecoDecay::constrainAngle(deltaPhi, -PIHalf); + // IF EVERYTHING WORKS WITH THE REASSOCIATED MFT TRACKS, I WILL HAVE TO CHANGE HOW THOSE FUNCTIONS ARE FILLED TOO if (!fillingHFcontainer) { // fill pair correlations target->getPairHist()->Fill(step, eta1 - eta2, pt2, pt1, multiplicity, deltaPhi, posZ, @@ -1033,10 +1130,10 @@ struct HfTaskFlow { } // FILL QA PLOTS for associated particle - if (sameEvent && (loopCounter == 1)) { + if (sameEvent && (loopCounter == 1) && (step == CorrelationContainer::kCFStepReconstructed)) { // if constexpr (std::is_same_v) { // If DATA - if constexpr (!std::is_same_v) { // IF TPC-TPC case - if constexpr (std::is_same_v) { // IF D0 CASE -> TPC-TPC D0-h + if constexpr (!std::is_same_v) { // IF TPC-TPC case + if constexpr (std::is_same_v) { // IF D0 CASE -> TPC-TPC D0-h fillTpcTpcHfChSameEventQa(multiplicity, track2); } else if constexpr (std::is_same_v) { // IF LC CASE -> TPC-TPC Lc-h fillTpcTpcHfChSameEventQa(multiplicity, track2); @@ -1056,6 +1153,207 @@ struct HfTaskFlow { //} } + if (sameEvent && (loopCounter == 1)) { + // FILL USUAL MFT DISTRIBUTIONS + registry.fill(HIST("Data/TpcMft/kCFStepAll/hEta"), eta2); + registry.fill(HIST("Data/TpcMft/kCFStepAll/hPhi"), phi2); + } + + } // end of loop over tracks2 + } // end of loop over tracks 1 + } + + template + void fillCorrelationsReassociatedMftTracks(TTarget target, CorrelationContainer::CFStep step, + TTracksTrig const& tracks1, TTracksAssoc const& tracks2, + float multiplicity, float posZ, bool sameEvent, bool cutAmbiguousTracks) + { + auto triggerWeight = 1; + auto associatedWeight = 1; + + // To avoid filling associated tracks QA many times + // I fill it only for the first trigger track of the collision + auto loopCounter = 0; + + // + // TRIGGER PARTICLE + // + for (const auto& track1 : tracks1) { + + loopCounter++; + + float eta1 = track1.eta(); + float pt1 = track1.pt(); + float phi1 = track1.phi(); + o2::math_utils::bringTo02Pi(phi1); + + // TODO: add getter for NUE trigger efficiency here + + // calculating inv. mass to be filled into the container below + // Note: this is needed only in case of HF-hadron correlations + // TO DO ? Add one more if condition if its MC ? + bool fillingHFcontainer = false; + double invmass = 0; + if constexpr (std::is_same_v || std::is_same_v) { + // TODO: Check how to put this into a Filter -> Pretty sure it cannot be a filter + if (!isAcceptedCandidate(track1)) { + continue; + } + fillingHFcontainer = true; + if constexpr (std::is_same_v) { // If D0 + invmass = hfHelper.invMassD0ToPiK(track1); + // Should add D0 bar ? + } else { // If Lc + invmass = hfHelper.invMassLcToPKPi(track1); + // Should add Lc bar ? (maybe not its the same mass right ?) + } + } + + //// Selections for MC GENERATED + // if constexpr (std::is_same_v || std::is_same_v) { + // // TODO: Check how to put this into a Filter -> Pretty sure it cannot be a filter + // if (!isAcceptedMcCandidate(track1)) { + // continue; + // } + // fillingHFcontainer = true; + // if constexpr (std::is_same_v) { // If D0 + // invmass = o2::constants::physics::MassD0; + // // Should add D0 bar ? + // } else { // If Lc + // invmass = o2::constants::physics::MassLambdaCPlus; + // // Should add Lc bar ? (maybe not its the same mass right ?) + // } + // } + + // fill single-track distributions + if (!fillingHFcontainer) { // if not HF-h case + target->getTriggerHist()->Fill(step, pt1, multiplicity, posZ, triggerWeight); + } else { + target->getTriggerHist()->Fill(step, pt1, multiplicity, posZ, invmass, triggerWeight); + } + + // FILL QA PLOTS for trigger particle + if (sameEvent && (cutAmbiguousTracks == false)) { + if constexpr (std::is_same_v) { + fillTpcMftD0CandidateQa(multiplicity, track1); + } else if constexpr (std::is_same_v) { + fillTpcTpcLcCandidateQa(multiplicity, track1); + } else { + fillTpcMftChChSameEventQa(multiplicity, track1, true); + } + } + + // + // ASSOCIATED PARTICLE + // + for (const auto& track2 : tracks2) { + + // Fill QA plot for all MFT tracks () (only if cutAmbiguousTracks is false to avoid double counting) + if (!cutAmbiguousTracks) { + registry.fill(HIST("Data/TpcMft/hAmbiguityOfMftTracks"), MftTrackAmbiguityStep::AllMftTracks); + } + + // const auto& reassociatedMftTrack = track2.mfttrack(); + // No one uses const and auto& here, so I will follow + auto reassociatedMftTrack = track2.template mfttrack_as(); + + if (!isAcceptedMftTrack(reassociatedMftTrack, false)) { + continue; + } + + // Fill QA plot for MFT tracks after physical selection (eta + clusters) + if (!cutAmbiguousTracks) { + registry.fill(HIST("Data/TpcMft/hAmbiguityOfMftTracks"), MftTrackAmbiguityStep::AfterTrackSelection); + } + + // We check if the track is ambiguous or non-ambiguous (QA plots are filled in isAmbiguousMftTrack) + // Fill plots only if cutAmbiguousTracks is false (to avoid double counting) + if (isAmbiguousMftTrack(track2, !cutAmbiguousTracks)) { + // If the MFT track is ambiguous we may cut or not on the ambiguous track + if (cutAmbiguousTracks) { + continue; + } + } + + if (reassociatedMftTrack.collisionId() != track2.bestCollisionId()) { + // track.collision_as().posZ() + continue; + } + + // case of h-h correlations where the two types of tracks are the same + // this avoids autocorrelations and double counting of particle pairs + // if constexpr (std::is_same_v) { + // if (track1.index() <= reassociatedMftTrack.index()) { + // continue; + // } + //} + + // in case of HF-h correlations, remove candidate daughters from the pool of associated hadrons + // with which the candidate is being correlated (will not have to do it for TPC-MFT case) + if constexpr (std::is_same_v) { // Remove the 2 prong daughters + if ((track1.prong0Id() == reassociatedMftTrack.globalIndex()) || (track1.prong1Id() == reassociatedMftTrack.globalIndex())) { + continue; + } + } + if constexpr (std::is_same_v) { // Remove the 3 prong daughters + if ((track1.prong0Id() == reassociatedMftTrack.globalIndex()) || (track1.prong1Id() == reassociatedMftTrack.globalIndex()) || (track1.prong2Id() == reassociatedMftTrack.globalIndex())) { + continue; + } + } + + // in case of MC-generated, do additional selection on MCparticles : charge and isPhysicalPrimary + // if (processMc) { + if constexpr (std::is_same_v || std::is_same_v) { + if (!isAcceptedMftMcParticle(reassociatedMftTrack)) { + continue; + } + } + + // if constexpr (std::is_same_v) { + // registry.fill(HIST("MC/Gen/TpcMft/HfHadron/SameEvent/hEtaMFT"), reassociatedMftTrack.eta()); + // } + + float eta2 = reassociatedMftTrack.eta(); + float pt2 = reassociatedMftTrack.pt(); + float phi2 = reassociatedMftTrack.phi(); + o2::math_utils::bringTo02Pi(phi2); + + // TODO: add getter for NUE associated efficiency here + + // TODO: add pair cuts on phi* + + float deltaPhi = phi1 - phi2; + // set range of delta phi in (-pi/2 , 3/2*pi) + deltaPhi = RecoDecay::constrainAngle(deltaPhi, -PIHalf); + + // IF EVERYTHING WORKS WITH THE REASSOCIATED MFT TRACKS, I WILL HAVE TO CHANGE HOW THOSE FUNCTIONS ARE FILLED TOO + if (!fillingHFcontainer) { + // fill pair correlations + target->getPairHist()->Fill(step, eta1 - eta2, pt2, pt1, multiplicity, deltaPhi, posZ, + triggerWeight * associatedWeight); + } else { + target->getPairHist()->Fill(step, eta1 - eta2, pt2, pt1, multiplicity, deltaPhi, posZ, invmass, + triggerWeight * associatedWeight); + } + + // FILL QA PLOTS for associated particle + if (sameEvent && (loopCounter == 1) && (cutAmbiguousTracks == false)) { + if constexpr (std::is_same_v) { + fillTpcMftHfChSameEventQa(multiplicity, reassociatedMftTrack); + } else if constexpr (std::is_same_v) { + fillTpcMftHfChSameEventQa(multiplicity, reassociatedMftTrack); + } else { + fillTpcMftChChSameEventQa(multiplicity, reassociatedMftTrack, false); + } + } + + // QA plots for basic MFT distributions for non-ambiguous tracks only (kCFStepTracked) + if (cutAmbiguousTracks && sameEvent && (loopCounter == 1)) { + // FILL USUAL MFT DISTRIBUTIONS + registry.fill(HIST("Data/TpcMft/kCFStepTracked/hEta"), eta2); + registry.fill(HIST("Data/TpcMft/kCFStepTracked/hPhi"), phi2); + } + } // end of loop over tracks2 } // end of loop over tracks 1 } @@ -1065,7 +1363,7 @@ struct HfTaskFlow { // =============================================================================================================================================================================== template - void mixCollisions(TCollisions const& collisions, + void mixCollisions(TCollisions const& collisions, CorrelationContainer::CFStep step, TTracksTrig const& tracks1, TTracksAssoc const& tracks2, TLambda getPartsSize, OutputObj& corrContainer) @@ -1096,7 +1394,7 @@ struct HfTaskFlow { if constexpr (std::is_same_v) { // If MC registry.fill(HIST("MC/Rec/TpcTpc/HadronHadron/MixedEvent/hEventCountMixing"), bin); } else { // If not MC - if constexpr (std::is_same_v) { // IF TPC-MFT case + if constexpr (std::is_same_v) { // IF TPC-MFT case if constexpr (std::is_same_v || std::is_same_v) { // IF HF-h case -> TPC-MFT HF-h registry.fill(HIST("Data/TpcMft/HfHadron/MixedEvent/hEventCountMixing"), bin); } else { // IF h-h case -> TPC-MFT h-h case @@ -1111,11 +1409,70 @@ struct HfTaskFlow { } // end of if condition for TPC-TPC or TPC-MFT case } - corrContainer->fillEvent(multiplicityTracks1, CorrelationContainer::kCFStepReconstructed); - fillCorrelations(corrContainer, tracks1, tracks2, multiplicityTracks1, collision1.posZ(), false); + corrContainer->fillEvent(multiplicityTracks1, step); + fillCorrelations(corrContainer, step, tracks1, tracks2, multiplicityTracks1, collision1.posZ(), false); } } + /* + template + void mixCollisionsReassociatedMftTracks(TCollisions const& collisions, int step, + TTracksTrig const& tracks1, TTracksAssoc const& tracks2, + TLambda getPartsSize, + OutputObj& corrContainer, + bool cutAmbiguousTracks) + { + + // The first one that I call "Data" should work for data and mc rec + using BinningTypeData = FlexibleBinningPolicy, aod::collision::PosZ, decltype(getPartsSize)>; + + BinningTypeData binningWithTracksSize{{getPartsSize}, {binsMixingVertex, binsMixingMultiplicity}, true}; + auto tracksTuple = std::make_tuple(tracks1, tracks2); + Pair pair{binningWithTracksSize, nMixedEvents, -1, collisions, tracksTuple, &cache}; + + for (const auto& [collision1, tracks1, collision2, tracks2] : pair) { + + if constexpr (!std::is_same_v) { // if NOT MC -> do collision cut + if (!(isAcceptedCollision(collision1, false))) { + continue; + } + if (!(isAcceptedCollision(collision2, false))) { + continue; + } + } + + auto binningValues = binningWithTracksSize.getBinningValues(collision1, collisions); + int bin = binningWithTracksSize.getBin(binningValues); + + const auto multiplicityTracks1 = getPartsSize(collision1); + + + + if constexpr (std::is_same_v) { // If MC + registry.fill(HIST("MC/Rec/TpcTpc/HadronHadron/MixedEvent/hEventCountMixing"), bin); + } else { // If not MC + if constexpr (std::is_same_v) { // IF TPC-MFT case + if constexpr (std::is_same_v || std::is_same_v) { // IF HF-h case -> TPC-MFT HF-h + registry.fill(HIST("Data/TpcMft/HfHadron/MixedEvent/hEventCountMixing"), bin); + } else { // IF h-h case -> TPC-MFT h-h case + registry.fill(HIST("Data/TpcMft/HadronHadron/MixedEvent/hEventCountMixing"), bin); + } + } else { // IF TPC-TPC case + if constexpr (std::is_same_v || std::is_same_v) { // IF HF-h case -> TPC-TPC HF-h + registry.fill(HIST("Data/TpcTpc/HfHadron/MixedEvent/hEventCountHFMixing"), bin); + } else { // IF h-h case -> TPC-TPC h-h case + registry.fill(HIST("Data/TpcTpc/HadronHadron/MixedEvent/hEventCountMixing"), bin); + } + } // end of if condition for TPC-TPC or TPC-MFT case + } + + + corrContainer->fillEvent(multiplicityTracks1, step); + fillCorrelationsReassociatedMftTracks(corrContainer, step, tracks1, tracks2, multiplicityTracks1, collision1.posZ(), false, cutAmbiguousTracks, field ); + } + } + */ + // =============================================================================================================================================================================== // mixCollisions for GENERATED events // =============================================================================================================================================================================== @@ -1143,7 +1500,7 @@ struct HfTaskFlow { registry.fill(HIST("MC/Gen/TpcTpc/HadronHadron/MixedEvent/hEventCountMixing"), bin); corrContainer->fillEvent(multiplicity, CorrelationContainer::kCFStepAll); - fillCorrelations(corrContainer, tracks1, tracks2, multiplicity, collision1.posZ(), false); + fillCorrelations(corrContainer, CorrelationContainer::CFStep::kCFStepAll, tracks1, tracks2, multiplicity, collision1.posZ(), false); } } @@ -1184,7 +1541,7 @@ struct HfTaskFlow { sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); // TO-DO : add if condition for when we will implant corrected correlations (kCFStepReconstructed -> kCFStepCorrected) - fillCorrelations(sameEvent, tracks, tracks, multiplicity, collision.posZ(), true); + fillCorrelations(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, tracks, multiplicity, collision.posZ(), true); } PROCESS_SWITCH(HfTaskFlow, processSameTpcTpcChCh, "DATA : Process same-event correlations for TPC-TPC h-h case", false); @@ -1213,7 +1570,7 @@ struct HfTaskFlow { sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelations(sameEventHf, candidates, tracks, multiplicity, collision.posZ(), true); + fillCorrelations(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, tracks, multiplicity, collision.posZ(), true); } PROCESS_SWITCH(HfTaskFlow, processSameTpcTpcD0Ch, "DATA : Process same-event correlations for TPC-TPC D0-h case", false); @@ -1242,7 +1599,7 @@ struct HfTaskFlow { sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelations(sameEventHf, candidates, tracks, multiplicity, collision.posZ(), true); + fillCorrelations(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, tracks, multiplicity, collision.posZ(), true); } PROCESS_SWITCH(HfTaskFlow, processSameTpcTpcLcCh, "DATA : Process same-event correlations for TPC-TPC Lc-h case", false); @@ -1252,7 +1609,7 @@ struct HfTaskFlow { void processSameTpcMftChCh(FilteredCollisionsWSelMult::iterator const& collision, FilteredTracksWDcaSel const& tracks, - FilteredMftTracksWColls const& mftTracks) + aod::MFTTracks const& mftTracks) { if (!(isAcceptedCollision(collision, true))) { return; @@ -1263,12 +1620,54 @@ struct HfTaskFlow { int bin = baseBinning.getBin(std::make_tuple(collision.posZ(), multiplicity)); registry.fill(HIST("Data/TpcMft/HadronHadron/SameEvent/hEventCountSame"), bin); + // I use kCFStepAll for running my code with all MFTTracks were the reassociation process was not applied + // We don't fill "normal" QA plots with these tracks, only specific plots to compare with other type of MFTTracks sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); + fillCorrelations(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, mftTracks, multiplicity, collision.posZ(), true); - fillCorrelations(sameEvent, tracks, mftTracks, multiplicity, collision.posZ(), true); + // I use the step kCFStepReconstructed for reassociatedMftTracks (most likely the ones we will use in the end) + // sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); + // fillCorrelationsReassociatedMftTracks(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, reassociatedMftTracks, multiplicity, collision.posZ(), true, false); + + // I use kCFStepTracked for running my code with only non-ambiguous MFTTracks + // This is the same as running with reassociatedMftTracks, but applying one more cut in the fillCorrelations function + // We don't fill "normal" QA plots with these tracks, only specific plots to compare with other type of MFTTracks + // sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepTracked); + // fillCorrelationsReassociatedMftTracks(sameEvent, CorrelationContainer::CFStep::kCFStepTracked, tracks, reassociatedMftTracks, multiplicity, collision.posZ(), false, true); } PROCESS_SWITCH(HfTaskFlow, processSameTpcMftChCh, "DATA : Process same-event correlations for TPC-MFT h-h case", false); + void processSameTpcMftChChReassociated(FilteredCollisionsWSelMult::iterator const& collision, + soa::SmallGroups const& reassociatedMftTracks, + FilteredTracksWDcaSel const& tracks, + aod::MFTTracks const& mftTracks) + { + if (!(isAcceptedCollision(collision, true))) { + return; // when process function has iterator + } + + const auto multiplicity = collision.multNTracksPV(); + BinningPolicyBase<2> baseBinning{{axisVertex, axisMultiplicity}, true}; + int bin = baseBinning.getBin(std::make_tuple(collision.posZ(), multiplicity)); + registry.fill(HIST("Data/TpcMft/HadronHadron/SameEvent/hEventCountSame"), bin); + + // I use kCFStepAll for running my code with all MFTTracks were the reassociation process was not applied + // We don't fill "normal" QA plots with these tracks, only specific plots to compare with other type of MFTTracks + sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepAll); + fillCorrelations(sameEvent, CorrelationContainer::CFStep::kCFStepAll, tracks, mftTracks, multiplicity, collision.posZ(), true); + + // I use the step kCFStepReconstructed for reassociatedMftTracks (most likely the ones we will use in the end) + sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); + fillCorrelationsReassociatedMftTracks(sameEvent, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, reassociatedMftTracks, multiplicity, collision.posZ(), true, false); + + // I use kCFStepTracked for running my code with only non-ambiguous MFTTracks + // This is the same as running with reassociatedMftTracks, but applying one more cut in the fillCorrelations function + // We don't fill "normal" QA plots with these tracks, only specific plots to compare with other type of MFTTracks + sameEvent->fillEvent(multiplicity, CorrelationContainer::kCFStepTracked); + fillCorrelationsReassociatedMftTracks(sameEvent, CorrelationContainer::CFStep::kCFStepTracked, tracks, reassociatedMftTracks, multiplicity, collision.posZ(), true, true); + } + PROCESS_SWITCH(HfTaskFlow, processSameTpcMftChChReassociated, "DATA : Process same-event correlations for TPC-MFT h-h case reassociated", false); + // ===================================== // DATA : process same event correlations: TPC-MFT HF-h case for D0 // ===================================== @@ -1276,7 +1675,7 @@ struct HfTaskFlow { void processSameTpcMftD0Ch(FilteredCollisionsWSelMult::iterator const& collision, HfCandidatesSelD0 const& candidates, FilteredTracksWDcaSel const& /*tracks*/, - FilteredMftTracksWColls const& mftTracks) + aod::MFTTracks const& mftTracks) { auto fillEventSelectionPlots = true; @@ -1295,10 +1694,41 @@ struct HfTaskFlow { sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelations(sameEventHf, candidates, mftTracks, multiplicity, collision.posZ(), true); + fillCorrelations(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, mftTracks, multiplicity, collision.posZ(), true); } PROCESS_SWITCH(HfTaskFlow, processSameTpcMftD0Ch, "DATA : Process same-event correlations for TPC-MFT D0-h case", false); + void processSameTpcMftD0ChReassociated(FilteredCollisionsWSelMult::iterator const& collision, + HfCandidatesSelD0 const& candidates, + soa::SmallGroups const& reassociatedMftTracks, + aod::MFTTracks const& mftTracks) + { + if (!(isAcceptedCollision(collision, true))) { + return; // when process function has iterator + } + + const auto multiplicity = collision.multNTracksPV(); + BinningPolicyBase<2> baseBinning{{axisVertex, axisMultiplicity}, true}; + // int bin = baseBinning.getBin(std::make_tuple(collision.posZ(), multiplicity)); + // registry.fill(HIST("Data/TpcMft/HadronHadron/SameEvent/hEventCountSame"), bin); + + // I use kCFStepAll for running my code with all MFTTracks were the reassociation process was not applied + // We don't fill "normal" QA plots with these tracks, only specific plots to compare with other type of MFTTracks + sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepAll); + fillCorrelations(sameEventHf, CorrelationContainer::CFStep::kCFStepAll, candidates, mftTracks, multiplicity, collision.posZ(), true); + + // I use the step kCFStepReconstructed for reassociatedMftTracks (most likely the ones we will use in the end) + sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); + fillCorrelationsReassociatedMftTracks(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, reassociatedMftTracks, multiplicity, collision.posZ(), true, false); + + // I use kCFStepTracked for running my code with only non-ambiguous MFTTracks + // This is the same as running with reassociatedMftTracks, but applying one more cut in the fillCorrelations function + // We don't fill "normal" QA plots with these tracks, only specific plots to compare with other type of MFTTracks + sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepTracked); + fillCorrelationsReassociatedMftTracks(sameEventHf, CorrelationContainer::CFStep::kCFStepTracked, candidates, reassociatedMftTracks, multiplicity, collision.posZ(), true, true); + } + PROCESS_SWITCH(HfTaskFlow, processSameTpcMftD0ChReassociated, "DATA : Process same-event correlations for TPC-MFT D0-h case reassociated", false); + // ===================================== // DATA : process same event correlations: TPC-MFT HF-h case for Lc // ===================================== @@ -1306,7 +1736,7 @@ struct HfTaskFlow { void processSameTpcMftLcCh(FilteredCollisionsWSelMult::iterator const& collision, HfCandidatesSelLc const& candidates, FilteredTracksWDcaSel const& /*tracks*/, - FilteredMftTracksWColls const& mftTracks) + aod::MFTTracks const& mftTracks) { auto fillEventSelectionPlots = true; @@ -1325,10 +1755,41 @@ struct HfTaskFlow { sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); - fillCorrelations(sameEventHf, candidates, mftTracks, multiplicity, collision.posZ(), true); + fillCorrelations(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, mftTracks, multiplicity, collision.posZ(), true); } PROCESS_SWITCH(HfTaskFlow, processSameTpcMftLcCh, "DATA : Process same-event correlations for TPC-MFT Lc-h case", false); + void processSameTpcMftLcChReassociated(FilteredCollisionsWSelMult::iterator const& collision, + HfCandidatesSelLc const& candidates, + soa::SmallGroups const& reassociatedMftTracks, + aod::MFTTracks const& mftTracks) + { + if (!(isAcceptedCollision(collision, true))) { + return; // when process function has iterator + } + + const auto multiplicity = collision.multNTracksPV(); + BinningPolicyBase<2> baseBinning{{axisVertex, axisMultiplicity}, true}; + // int bin = baseBinning.getBin(std::make_tuple(collision.posZ(), multiplicity)); + // registry.fill(HIST("Data/TpcMft/HadronHadron/SameEvent/hEventCountSame"), bin); + + // I use kCFStepAll for running my code with all MFTTracks were the reassociation process was not applied + // We don't fill "normal" QA plots with these tracks, only specific plots to compare with other type of MFTTracks + sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepAll); + fillCorrelations(sameEventHf, CorrelationContainer::CFStep::kCFStepAll, candidates, mftTracks, multiplicity, collision.posZ(), true); + + // I use the step kCFStepReconstructed for reassociatedMftTracks (most likely the ones we will use in the end) + sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); + fillCorrelationsReassociatedMftTracks(sameEventHf, CorrelationContainer::CFStep::kCFStepReconstructed, candidates, reassociatedMftTracks, multiplicity, collision.posZ(), true, false); + + // I use kCFStepTracked for running my code with only non-ambiguous MFTTracks + // This is the same as running with reassociatedMftTracks, but applying one more cut in the fillCorrelations function + // We don't fill "normal" QA plots with these tracks, only specific plots to compare with other type of MFTTracks + sameEventHf->fillEvent(multiplicity, CorrelationContainer::kCFStepTracked); + fillCorrelationsReassociatedMftTracks(sameEventHf, CorrelationContainer::CFStep::kCFStepTracked, candidates, reassociatedMftTracks, multiplicity, collision.posZ(), true, true); + } + PROCESS_SWITCH(HfTaskFlow, processSameTpcMftLcChReassociated, "DATA : Process same-event correlations for TPC-MFT Lc-h case reassociated", false); + // =================================================================================================================================================================================================================================================================== // MONTE-CARLO // =================================================================================================================================================================================================================================================================== @@ -1348,7 +1809,7 @@ struct HfTaskFlow { // registry.fill(HIST("MC/Gen/TpcMft/HfHadron/SameEvent/2Prong/hEventCountSame"), bin); sameEventHfMc->fillEvent(multiplicity, CorrelationContainer::kCFStepAll); - fillCorrelations(sameEventHfMc, mcParticles2Prong, mcParticles, multiplicity, mcCollision.posZ(), true); + fillCorrelations(sameEventHfMc, CorrelationContainer::CFStep::kCFStepAll, mcParticles2Prong, mcParticles, multiplicity, mcCollision.posZ(), true); } PROCESS_SWITCH(HfTaskFlow, processSameTpcMftD0ChMcGen, "MONTE-CARLO : Process same-event correlations for TPC-MFT D0-h case", false); @@ -1367,7 +1828,7 @@ struct HfTaskFlow { // registry.fill(HIST("MC/Gen/TpcMft/HfHadron/SameEvent/2Prong/hEventCountSame"), bin); sameEventHfMc->fillEvent(multiplicity, CorrelationContainer::kCFStepAll); - fillCorrelations(sameEventHfMc, mcParticles3Prong, mcParticles, multiplicity, mcCollision.posZ(), true); + fillCorrelations(sameEventHfMc, CorrelationContainer::CFStep::kCFStepAll, mcParticles3Prong, mcParticles, multiplicity, mcCollision.posZ(), true); } PROCESS_SWITCH(HfTaskFlow, processSameTpcMftLcChMcGen, "MONTE-CARLO : Process same-event correlations for TPC-MFT Lc-h case", false); @@ -1401,7 +1862,7 @@ struct HfTaskFlow { }; // mixCollisions(collisions, tracks, tracks, getTracksSize, mixedEvent); - mixCollisions(collisions, tracks, tracks, getMultiplicity, mixedEvent); + mixCollisions(collisions, CorrelationContainer::CFStep::kCFStepReconstructed, tracks, tracks, getMultiplicity, mixedEvent); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcTpcChCh, "DATA : Process mixed-event correlations for TPC-TPC h-h case", false); @@ -1418,7 +1879,7 @@ struct HfTaskFlow { return multiplicity; }; - mixCollisions(collisions, candidates, tracks, getMultiplicity, mixedEventHf); + mixCollisions(collisions, CorrelationContainer::kCFStepReconstructed, candidates, tracks, getMultiplicity, mixedEventHf); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcTpcD0Ch, "DATA : Process mixed-event correlations for TPC-TPC D0-h case", false); @@ -1435,7 +1896,7 @@ struct HfTaskFlow { return multiplicity; }; - mixCollisions(collisions, candidates, tracks, getMultiplicity, mixedEventHf); + mixCollisions(collisions, CorrelationContainer::kCFStepReconstructed, candidates, tracks, getMultiplicity, mixedEventHf); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcTpcLcCh, "DATA : Process mixed-event correlations for TPC-TPC Lc-h case", false); @@ -1445,14 +1906,23 @@ struct HfTaskFlow { void processMixedTpcMftChCh(FilteredCollisionsWSelMult const& collisions, FilteredTracksWDcaSel const& tracks, - FilteredMftTracksWColls const& mftTracks) + aod::MFTTracks const& mftTracks) { auto getMultiplicity = [](FilteredCollisionsWSelMult::iterator const& collision) { auto multiplicity = collision.numContrib(); return multiplicity; }; - mixCollisions(collisions, tracks, mftTracks, getMultiplicity, mixedEvent); + mixCollisions(collisions, CorrelationContainer::kCFStepReconstructed, tracks, mftTracks, getMultiplicity, mixedEvent); + // mixCollisions(collisions, CorrelationContainer::kCFStepAll, tracks, mftTracks, getMultiplicity, mixedEvent); + + // The next following two lines were supposed to be used to do mixed event with the reassociated MFT tracks + // However it seems the O2physics framework cannot handle how these combinations requests grouping according to Anton Alkin + // So I leave them commented for now until it is solved, and put the "normal" mixCollisions back with kCFStepReconstructed + + // mixCollisionsReassociatedMftTracks(collisions, CorrelationContainer::kCFStepReconstructed, tracks, reassociatedMftTracks, getMultiplicity, mixedEvent, false); + + // mixCollisionsReassociatedMftTracks(collisions, CorrelationContainer::kCFStepTracked, tracks, reassociatedMftTracks, getMultiplicity, mixedEvent, true); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcMftChCh, "DATA : Process mixed-event correlations for TPC-MFT h-h case", false); @@ -1462,7 +1932,7 @@ struct HfTaskFlow { void processMixedTpcMftD0Ch(FilteredCollisionsWSelMult const& collisions, HfCandidatesSelD0 const& candidates, - FilteredMftTracksWColls const& mftTracks, + aod::MFTTracks const& mftTracks, FilteredTracksWDcaSel const& /*tracks*/) { auto getMultiplicity = [](FilteredCollisionsWSelMult::iterator const& collision) { @@ -1470,7 +1940,7 @@ struct HfTaskFlow { return multiplicity; }; - mixCollisions(collisions, candidates, mftTracks, getMultiplicity, mixedEventHf); + mixCollisions(collisions, CorrelationContainer::kCFStepReconstructed, candidates, mftTracks, getMultiplicity, mixedEventHf); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcMftD0Ch, "DATA : Process mixed-event correlations for TPC-MFT D0-h case", false); @@ -1480,14 +1950,14 @@ struct HfTaskFlow { void processMixedTpcMftLcCh(FilteredCollisionsWSelMult const& collisions, HfCandidatesSelLc const& candidates, - FilteredMftTracksWColls const& mftTracks) + aod::MFTTracks const& mftTracks) { auto getMultiplicity = [](FilteredCollisionsWSelMult::iterator const& collision) { auto multiplicity = collision.numContrib(); return multiplicity; }; - mixCollisions(collisions, candidates, mftTracks, getMultiplicity, mixedEventHf); + mixCollisions(collisions, CorrelationContainer::kCFStepReconstructed, candidates, mftTracks, getMultiplicity, mixedEventHf); } PROCESS_SWITCH(HfTaskFlow, processMixedTpcMftLcCh, "DATA : Process mixed-event correlations for TPC-MFT Lc-h case", false); @@ -1539,7 +2009,7 @@ struct HfTaskFlow { void processMcEfficiencyMft(FilteredMcCollisions::iterator const& mcCollision, McParticles const& mcParticles, soa::SmallGroups> const& collisionsMcLabels, - FilteredMftTracksWCollsMcLabels const& mftTTracksMcLabels) + MftTracksMcLabels const& mftTTracksMcLabels) { LOGF(info, "MC collision at vtx-z = %f with %d mc particles and %d reconstructed collisions", mcCollision.posZ(), mcParticles.size(), collisionsMcLabels.size()); diff --git a/PWGHF/HFL/TableProducer/electronSelectionWithTpcEmcal.cxx b/PWGHF/HFL/TableProducer/electronSelectionWithTpcEmcal.cxx index 94bad334ce4..7dac8c0a83d 100644 --- a/PWGHF/HFL/TableProducer/electronSelectionWithTpcEmcal.cxx +++ b/PWGHF/HFL/TableProducer/electronSelectionWithTpcEmcal.cxx @@ -468,8 +468,8 @@ struct HfElectronSelectionWithTpcEmcal { timeEmcCluster = emcCluster.time(); cellEmcCluster = emcCluster.nCells(); - deltaPhiMatch = matchTrack.trackPhiEmcal() - phiMatchEmcCluster; - deltaEtaMatch = matchTrack.trackEtaEmcal() - etaMatchEmcCluster; + deltaPhiMatch = ematchTrack.deltaPhi(); + deltaEtaMatch = ematchTrack.deltaEta(); // Track and EMCal cluster Matching if (std::abs(timeEmcCluster) > timeEmcClusterMax) { diff --git a/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx b/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx index 40739b9be59..3f10c0462fa 100644 --- a/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx +++ b/PWGHF/HFL/Tasks/taskElectronWeakBoson.cxx @@ -17,10 +17,13 @@ #define HomogeneousField // o2-linter: disable=name/macro (required by KFParticle) #endif +#include "PWGHF/Core/CentralityEstimation.h" #include "PWGJE/DataModel/EMCALClusters.h" #include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponseTPC.h" #include "Common/DataModel/TrackSelectionTables.h" #include "EventFiltering/Zorro.h" @@ -58,6 +61,7 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::hf_centrality; struct HfTaskElectronWeakBoson { @@ -103,6 +107,7 @@ struct HfTaskElectronWeakBoson { Configurable massZMin{"massZMin", 60.0, "Minimum Z mass (GeV/c^2)"}; Configurable massZMax{"massZMax", 120.0, "Maximum Z mass (GeV/c^2)"}; + Configurable correctionPtElectron{"correctionPtElectron", 1.0, "momentum correction factor for decay electrons from Z boson"}; // flag for THn Configurable isTHnElectron{"isTHnElectron", true, "Enables THn for electrons"}; @@ -120,6 +125,12 @@ struct HfTaskElectronWeakBoson { Configurable kfConstructMethod{"kfConstructMethod", 2, "KF Construct Method"}; Configurable chiSqNdfMax{"chiSqNdfMax", 10, "Chi2 Max for mass reco by KF particle"}; + // Centrality estimator configuration + Configurable centralityEstimator{"centralityEstimator", CentralityEstimator::FT0M, "Centrality estimator. See CentralityEstimator for valid values."}; + Configurable enableCentralityAnalysis{"enableCentralityAnalysis", true, "Enable centrality-dependent analysis"}; + Configurable centralityMin{"centralityMin", -1, "minimum cut on centrality selection"}; + Configurable centralityMax{"centralityMax", 101, "maximum cut on centrality selection"}; + // CCDB service object Service ccdb; @@ -141,7 +152,7 @@ struct HfTaskElectronWeakBoson { : pt(ptr), eta(e), phi(ph), mass(m), ptchild0(ptzee0), ptchild1(ptzee1), charge(ch) {} }; std::vector reconstructedZ; - + using CollisionsWithCent = soa::Join; using SelectedClusters = o2::aod::EMCALClusters; // PbPb // using TrackEle = o2::soa::Join; @@ -185,6 +196,10 @@ struct HfTaskElectronWeakBoson { if (cfgSkimmedProcessing) { zorroSummary.setObject(zorro.getZorroSummary()); } + // check centrality + if (centralityEstimator < CentralityEstimator::FT0A || centralityEstimator > CentralityEstimator::FV0A) { + LOGF(fatal, "Invalid centrality estimator: %d", static_cast(centralityEstimator.value)); + } // add configurable for CCDB path zorro.setBaseCCDBPath(cfgCCDBPath.value); @@ -195,6 +210,7 @@ struct HfTaskElectronWeakBoson { const AxisSpec axisEta{20, -1.0, 1.0, "#eta"}; const AxisSpec axisPt{nBinsPt, 0, binPtmax, "p_{T}"}; const AxisSpec axisNsigma{100, -5, 5, "N#sigma"}; + const AxisSpec axisDedx{150, 0, 150, "dEdx"}; const AxisSpec axisE{nBinsE, 0, binEmax, "Energy"}; const AxisSpec axisM02{100, 0, 1, "M02"}; const AxisSpec axisdPhi{100, -0.5, 0.5, "dPhi"}; @@ -215,11 +231,14 @@ struct HfTaskElectronWeakBoson { const AxisSpec axisPtHadron{50, 0, 50, "p_{T,hadron} (GeV/c)"}; const AxisSpec axisPtZ{150, 0, 150, "p_{T,Z} (GeV/c)"}; const AxisSpec axisSign{2, -2, 2, "charge sign"}; + const AxisSpec axisCentrality{10, 0, 100, "Centrality (%)"}; + const AxisSpec axisPtRatio{200, 0, 2.0, "pt ratio for h and Z"}; // create registrygrams registry.add("hZvtx", "Z vertex", kTH1D, {axisZvtx}); registry.add("hEventCounterInit", "hEventCounterInit", kTH1D, {axisCounter}); registry.add("hEventCounter", "hEventCounter", kTH1D, {axisCounter}); + registry.add("hCentrality", "Centrality distribution", kTH1D, {axisCentrality}); registry.add("hITSchi2", "ITS #chi^{2}", kTH1F, {axisChi2}); registry.add("hTPCchi2", "TPC #chi^{2}", kTH1F, {axisChi2}); registry.add("hTPCnCls", "TPC NCls", kTH1F, {axisCluster}); @@ -241,15 +260,13 @@ struct HfTaskElectronWeakBoson { registry.add("hEMCtime", "EMC timing", kTH1F, {axisEMCtime}); registry.add("hIsolationEnergy", "Isolation Energy", kTH2F, {{axisE}, {axisIsoEnergy}}); registry.add("hIsolationTrack", "Isolation Track", kTH2F, {{axisE}, {axisIsoTrack}}); - registry.add("hInvMassZeeLs", "invariant mass for Z LS pair", kTH2F, {{axisPt}, {axisInvMassZ}}); - registry.add("hInvMassZeeUls", "invariant mass for Z ULS pair", kTH2F, {{axisPt}, {axisInvMassZ}}); - registry.add("hKfInvMassZeeLs", "invariant mass for Z LS pair KFp", kTH2F, {{axisPt}, {axisInvMassZ}}); - registry.add("hKfInvMassZeeUls", "invariant mass for Z ULS pair KFp", kTH2F, {{axisPt}, {axisInvMassZ}}); - registry.add("hTHnElectrons", "electron info", HistType::kTHnSparseF, {axisPt, axisNsigma, axisM02, axisEop, axisIsoEnergy, axisIsoTrack}); + registry.add("hInvMassZee", "invariant mass for Z ULS pair", HistType::kTHnSparseF, {axisSign, axisPt, axisInvMassZ}); + registry.add("hKfInvMassZee", "invariant mass for Z ULS pair KFp", HistType::kTHnSparseF, {axisSign, axisPt, axisInvMassZ}); + registry.add("hTHnElectrons", "electron info", HistType::kTHnSparseF, {axisPt, axisNsigma, axisM02, axisEop, axisIsoEnergy, axisIsoTrack, axisEta, axisDedx}); registry.add("hTHnTrMatch", "Track EMC Match", HistType::kTHnSparseF, {axisPt, axisdPhi, axisdEta}); // Z-hadron correlation histograms - registry.add("hZHadronDphi", "Z-hadron #Delta#phi correlation", HistType::kTHnSparseF, {axisSign, axisPtZ, axisDPhiZh}); + registry.add("hZHadronDphi", "Z-hadron #Delta#phi correlation", HistType::kTHnSparseF, {axisSign, axisPtZ, axisDPhiZh, axisPtRatio, axisPtHadron}); registry.add("hZptSpectrum", "Z boson p_{T} spectrum", kTH2F, {{axisSign}, {axisPtZ}}); // hisotgram for EMCal trigger @@ -321,6 +338,9 @@ struct HfTaskElectronWeakBoson { // LOG(info) << "Invarimass cal by KF particle "; for (const auto& track : tracks) { + if (std::abs(track.pt() - kfpIsoEle.GetPt()) < ptMatch) { + continue; + } if (track.pt() < ptZeeMin) { continue; } @@ -338,10 +358,12 @@ struct HfTaskElectronWeakBoson { KFPTrack kfpTrackAssEle = createKFPTrackFromTrack(track); KFParticle kfpAssEle(kfpTrackAssEle, pdgAss); // reco by RecoDecay - auto child1 = RecoDecayPtEtaPhi::pVector(kfpIsoEle.GetPt(), kfpIsoEle.GetEta(), kfpIsoEle.GetPhi()); - auto child2 = RecoDecayPtEtaPhi::pVector(kfpAssEle.GetPt(), kfpAssEle.GetEta(), kfpAssEle.GetPhi()); + auto child1 = RecoDecayPtEtaPhi::pVector(kfpIsoEle.GetPt() * correctionPtElectron, kfpIsoEle.GetEta(), kfpIsoEle.GetPhi()); + auto child2 = RecoDecayPtEtaPhi::pVector(kfpAssEle.GetPt() * correctionPtElectron, kfpAssEle.GetEta(), kfpAssEle.GetPhi()); double invMassEE = RecoDecay::m(std::array{child1, child2}, std::array{o2::constants::physics::MassElectron, o2::constants::physics::MassElectron}); + registry.fill(HIST("hInvMassZee"), track.sign() * charge, kfpIsoEle.GetPt(), invMassEE); + // reco by KFparticle const KFParticle* electronPairs[2] = {&kfpIsoEle, &kfpAssEle}; KFParticle zeeKF; @@ -360,17 +382,9 @@ struct HfTaskElectronWeakBoson { } float massZee, massZeeErr; zeeKF.GetMass(massZee, massZeeErr); + registry.fill(HIST("hKfInvMassZee"), track.sign() * charge, kfpIsoEle.GetPt(), massZee); // LOG(info) << "Invarimass cal by KF particle mass = " << massZee; // LOG(info) << "Invarimass cal by RecoDecay = " << invMassEE; - - if (track.sign() * charge > 0) { - registry.fill(HIST("hKfInvMassZeeLs"), kfpIsoEle.GetPt(), massZee); - registry.fill(HIST("hInvMassZeeLs"), kfpIsoEle.GetPt(), invMassEE); - } else { - registry.fill(HIST("hKfInvMassZeeUls"), kfpIsoEle.GetPt(), massZee); - registry.fill(HIST("hInvMassZeeUls"), kfpIsoEle.GetPt(), invMassEE); - } - reconstructedZ.emplace_back( zeeKF.GetPt(), zeeKF.GetEta(), @@ -382,7 +396,8 @@ struct HfTaskElectronWeakBoson { } } - void process(soa::Filtered::iterator const& collision, + // void process(soa::Filtered::iterator const& collision, + void process(soa::Filtered::iterator const& collision, aod::BCsWithTimestamps const&, SelectedClusters const& emcClusters, TrackEle const& tracks, @@ -444,6 +459,16 @@ struct HfTaskElectronWeakBoson { registry.fill(HIST("hZvtx"), collision.posZ()); + // Calculate centrality + if (enableCentralityAnalysis) { + float centrality = o2::hf_centrality::getCentralityColl(collision, centralityEstimator); + // LOG(info) << centrality; + if (centrality < centralityMin || centrality > centralityMax) { + return; + } + registry.fill(HIST("hCentrality"), centrality); + } + for (const auto& track : tracks) { if (std::abs(track.eta()) > etaTrMax) { @@ -556,12 +581,13 @@ struct HfTaskElectronWeakBoson { int trackCount = getIsolatedTrack(track.eta(), track.phi(), track.pt(), tracks) - 1; if (match.track_as().pt() > ptTHnThresh && isTHnElectron) { - registry.fill(HIST("hTHnElectrons"), match.track_as().pt(), match.track_as().tpcNSigmaEl(), m02Emc, eop, isoEnergy, trackCount); + registry.fill(HIST("hTHnElectrons"), match.track_as().pt(), match.track_as().tpcNSigmaEl(), m02Emc, eop, isoEnergy, trackCount, track.eta(), track.tpcSignal()); } // LOG(info) << "E/p" << eop; registry.fill(HIST("hEopNsigTPC"), match.track_as().tpcNSigmaEl(), eop); - if (match.emcalcluster_as().m02() < m02Min || match.emcalcluster_as().m02() > m02Max) + if (match.emcalcluster_as().m02() < m02Min || match.emcalcluster_as().m02() > m02Max) { continue; + } if (match.track_as().tpcNSigmaEl() > nsigTpcMin && match.track_as().tpcNSigmaEl() < nsigTpcMax) { registry.fill(HIST("hEop"), match.track_as().pt(), eop); @@ -622,7 +648,8 @@ struct HfTaskElectronWeakBoson { } // calculate Z-h correlation double deltaPhi = RecoDecay::constrainAngle(trackAss.phi - zBoson.phi, -o2::constants::math::PIHalf); - registry.fill(HIST("hZHadronDphi"), zBoson.charge, zBoson.pt, deltaPhi); + double ptRatio = trackAss.pt / zBoson.pt; + registry.fill(HIST("hZHadronDphi"), zBoson.charge, zBoson.pt, deltaPhi, ptRatio, trackAss.pt); } } } // end of Z-hadron correlation diff --git a/PWGHF/HFL/Tasks/taskSingleElectron.cxx b/PWGHF/HFL/Tasks/taskSingleElectron.cxx index d8a8b6e5b87..12bf351c84d 100644 --- a/PWGHF/HFL/Tasks/taskSingleElectron.cxx +++ b/PWGHF/HFL/Tasks/taskSingleElectron.cxx @@ -18,15 +18,56 @@ #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" +#include #include #include #include +#include + using namespace o2; using namespace o2::constants::math; +using namespace o2::constants::physics; using namespace o2::framework; using namespace o2::framework::expressions; +enum PdgCode { + kEta = 221, + kOmega = 223, + kEtaPrime = 331 +}; + +enum SourceType { + NotElec = 0, // not electron + DirectCharm = 1, // electrons from prompt charm hadrons + DirectBeauty = 2, // electrons from primary beauty hadrons + BeautyCharm = 3, // electrons from non-prompt charm hadrons + DirectGamma = 4, // electrons from direct photon + GammaPi0 = 5, + GammaEta = 6, + GammaOmega = 7, + GammaPhi = 8, + GammaEtaPrime = 9, + GammaRho0 = 10, + GammaK0s = 11, + GammaK0l = 12, + GammaKe3 = 13, + GammaLambda0 = 14, + GammaSigma = 15, + Pi0 = 16, + Eta = 17, + Omega = 18, + Phi = 19, + EtaPrime = 20, + Rho0 = 21, + K0s = 22, + K0l = 23, + Ke3 = 24, + Lambda0 = 25, + Sigma = 26, + Else = 27 +}; + struct HfTaskSingleElectron { // Produces @@ -41,6 +82,7 @@ struct HfTaskSingleElectron { Configurable tpcNClsFoundOverFindableMin{"tpcNClsFoundOverFindableMin", 0.8, "min # of TPC found/findable clusters"}; Configurable tpcChi2perNClMax{"tpcChi2perNClMax", 4., "min # of tpc chi2 per clusters"}; Configurable itsIBClsMin{"itsIBClsMin", 3, "min # of its clusters in IB"}; + Configurable itsChi2perNClMax{"itsChi2perNClMax", 6., "min # of tpc chi2 per clusters"}; Configurable dcaxyMax{"dcaxyMax", 1., "max of track dca in xy"}; Configurable dcazMax{"dcazMax", 2., "max of track dca in z"}; Configurable tofNSigmaMax{"tofNSigmaMax", 3., "max of tof nsigma"}; @@ -54,7 +96,8 @@ struct HfTaskSingleElectron { // using declarations using MyCollisions = soa::Join; - using TracksEl = soa::Join; + using TracksEl = soa::Join; + using McTracksEl = soa::Join; // Filter Filter collZFilter = nabs(aod::collision::posZ) < posZMax; @@ -79,29 +122,39 @@ struct HfTaskSingleElectron { void init(InitContext const&) { // create histograms - histos.add("hEventCounter", "hEventCounter", kTH1F, {axisEvt}); - histos.add("nEvents", "Number of events", kTH1F, {{1, 0., 1.}}); - histos.add("VtxZ", "VtxZ; cm; entries", kTH1F, {axisPosZ}); - histos.add("etaTrack", "etaTrack; #eta; entries", kTH1F, {axisEta}); - histos.add("ptTrack", "#it{p}_{T} distribution of selected tracks; #it{p}_{T} (GeV/#it{c}); entries", kTH1F, {axisPt}); + histos.add("nEvents", "Number of events", kTH1D, {{1, 0., 1.}}); + histos.add("VtxZ", "VtxZ; cm; entries", kTH1D, {axisPosZ}); + histos.add("etaTrack", "etaTrack; #eta; entries", kTH1D, {axisEta}); + histos.add("ptTrack", "#it{p}_{T} distribution of selected tracks; #it{p}_{T} (GeV/#it{c}); entries", kTH1D, {axisPt}); // QA plots for trigger track selection - histos.add("tpcNClsTrack", "tpcNClsTrack", kTH1F, {{200, 0, 200}}); - histos.add("tpcFoundFindableTrack", "", kTH1F, {{10, 0, 1}}); - histos.add("tpcChi2Track", "", kTH1F, {{100, 0, 10}}); - histos.add("itsIBClsTrack", "", kTH1F, {{10, 0, 10}}); - histos.add("dcaXYTrack", "", kTH1F, {{600, -3, 3}}); - histos.add("dcaZTrack", "", kTH1F, {{600, -3, 3}}); + histos.add("tpcNClsTrack", "tpcNClsTrack", kTH1D, {{200, 0, 200}}); + histos.add("tpcFoundFindableTrack", "", kTH1D, {{10, 0, 1}}); + histos.add("tpcChi2Track", "", kTH1D, {{100, 0, 10}}); + histos.add("itsIBClsTrack", "", kTH1D, {{10, 0, 10}}); + histos.add("itsChi2Track", "", kTH1D, {{50, 0, 50}}); + histos.add("dcaXYTrack", "", kTH1D, {{600, -3, 3}}); + histos.add("dcaZTrack", "", kTH1D, {{600, -3, 3}}); // pid - histos.add("tofNSigPt", "", kTH2F, {{axisPtEl}, {axisNsig}}); - histos.add("tofNSigPtQA", "", kTH2F, {{axisPtEl}, {axisNsig}}); - histos.add("tpcNSigPt", "", kTH2F, {{axisPtEl}, {axisNsig}}); - histos.add("tpcNSigPtAfterTofCut", "", kTH2F, {{axisPtEl}, {axisNsig}}); - histos.add("tpcNSigPtQA", "", kTH2F, {{axisPtEl}, {axisNsig}}); + histos.add("tofNSigPt", "", kTH2D, {{axisPtEl}, {axisNsig}}); + histos.add("tofNSigPtQA", "", kTH2D, {{axisPtEl}, {axisNsig}}); + histos.add("tpcNSigPt", "", kTH2D, {{axisPtEl}, {axisNsig}}); + histos.add("tpcNSigPtAfterTofCut", "", kTH2D, {{axisPtEl}, {axisNsig}}); + histos.add("tpcNSigPtQA", "", kTH2D, {{axisPtEl}, {axisNsig}}); // track impact parameter - histos.add("dcaTrack", "", kTH2F, {{axisPtEl}, {axisTrackIp}}); + histos.add("dcaTrack", "", kTH2D, {{axisPtEl}, {axisTrackIp}}); + histos.add("dcaBeauty", "", kTH2D, {{axisPtEl}, {axisTrackIp}}); + histos.add("dcaCharm", "", kTH2D, {{axisPtEl}, {axisTrackIp}}); + histos.add("dcaDalitz", "", kTH2D, {{axisPtEl}, {axisTrackIp}}); + histos.add("dcaConv", "", kTH2D, {{axisPtEl}, {axisTrackIp}}); + + // QA plots for MC + histos.add("hPdgC", "", kTH1D, {{10001, -0.5, 10000.5}}); + histos.add("hPdgB", "", kTH1D, {{10001, -0.5, 10000.5}}); + histos.add("hPdgDa", "", kTH1D, {{10001, -0.5, 10000.5}}); + histos.add("hPdgCo", "", kTH1D, {{10001, -0.5, 10000.5}}); } template @@ -117,9 +170,11 @@ struct HfTaskSingleElectron { if (track.tpcNClsCrossedRows() < tpcNCrossedRowMin) { return false; } + if (track.tpcCrossedRowsOverFindableCls() < tpcNClsFoundOverFindableMin) { return false; } + if (track.tpcChi2NCl() > tpcChi2perNClMax) { return false; } @@ -128,9 +183,14 @@ struct HfTaskSingleElectron { return false; } + if (track.itsChi2NCl() > itsChi2perNClMax) { + return false; + } + if (std::abs(track.dcaXY()) > dcaxyMax) { return false; } + if (std::abs(track.dcaZ()) > dcazMax) { return false; } @@ -138,24 +198,269 @@ struct HfTaskSingleElectron { return true; } - void process(soa::Filtered::iterator const& collision, - TracksEl const& tracks) + template + int getElecSource(const TrackType& track, double& mpt, int& mpdg) + { + auto mcpart = track.mcParticle(); + if (std::abs(mcpart.pdgCode()) != kElectron) { + return NotElec; + } + + int motherPdg = -999; + int grmotherPdg = -999; + int ggrmotherPdg = -999; // mother, grand mother, grand grand mother pdg + int motherPt = -999.; + int grmotherPt = -999; + int ggrmotherPt = -999.; // mother, grand mother, grand grand mother pt + + auto partMother = mcpart.template mothers_as(); // first mother particle of electron + auto partMotherCopy = partMother; // copy of the first mother + auto mctrack = partMother; // will change all the time + + motherPt = partMother.front().pt(); // first mother pt + motherPdg = std::abs(partMother.front().pdgCode()); // first mother pdg + mpt = motherPt; // copy of first mother pt + mpdg = motherPdg; // copy of first mother pdg + + // check if electron from charm hadrons + if ((static_cast(motherPdg / 100.) % 10) == kCharm || (static_cast(motherPdg / 1000.) % 10) == kCharm) { + + // iterate until B hadron is found as an ancestor + while (partMother.size()) { + mctrack = partMother.front().template mothers_as(); + if (mctrack.size()) { + auto const& grmothersIdsVec = mctrack.front().mothersIds(); + + if (grmothersIdsVec.empty()) { + return DirectCharm; + } else { + grmotherPt = mctrack.front().pt(); + grmotherPdg = std::abs(mctrack.front().pdgCode()); + if ((static_cast(grmotherPdg / 100.) % 10) == kBottom || (static_cast(grmotherPdg / 1000.) % 10) == kBottom) { + mpt = grmotherPt; + mpdg = grmotherPdg; + return BeautyCharm; + } + } + } + partMother = mctrack; + } + } else if ((static_cast(motherPdg / 100.) % 10) == kBottom || (static_cast(motherPdg / 1000.) % 10) == kBottom) { // check if electron from beauty hadrons + return DirectBeauty; + } else if (motherPdg == kGamma) { // check if electron from photon conversion + mctrack = partMother.front().template mothers_as(); + if (mctrack.size()) { + auto const& grmothersIdsVec = mctrack.front().mothersIds(); + if (grmothersIdsVec.empty()) { + return DirectGamma; + } else { + grmotherPdg = std::abs(mctrack.front().pdgCode()); + mpdg = grmotherPdg; + mpt = mctrack.front().pt(); + + partMother = mctrack; + mctrack = partMother.front().template mothers_as(); + if (mctrack.size()) { + auto const& ggrmothersIdsVec = mctrack.front().mothersIds(); + if (ggrmothersIdsVec.empty()) { + if (grmotherPdg == kPi0) { + return GammaPi0; + } else if (grmotherPdg == kEta) { + return GammaEta; + } else if (grmotherPdg == kOmega) { + return GammaOmega; + } else if (grmotherPdg == kPhi) { + return GammaPhi; + } else if (grmotherPdg == kEtaPrime) { + return GammaEtaPrime; + } else if (grmotherPdg == kRho770_0) { + return GammaRho0; + } else { + return Else; + } + } else { + ggrmotherPdg = mctrack.front().pdgCode(); + ggrmotherPt = mctrack.front().pt(); + mpdg = ggrmotherPdg; + mpt = ggrmotherPt; + if (grmotherPdg == kPi0) { + if (ggrmotherPdg == kK0Short) { + return GammaK0s; + } else if (ggrmotherPdg == kK0Long) { + return GammaK0l; + } else if (ggrmotherPdg == kKPlus) { + return GammaKe3; + } else if (ggrmotherPdg == kLambda0) { + return GammaLambda0; + } else if (ggrmotherPdg == kSigmaPlus) { + return GammaSigma; + } else { + mpdg = grmotherPdg; + mpt = grmotherPt; + return GammaPi0; + } + } else if (grmotherPdg == kEta) { + mpdg = grmotherPdg; + mpt = grmotherPt; + return GammaEta; + } else if (grmotherPdg == kOmega) { + mpdg = grmotherPdg; + mpt = grmotherPt; + return GammaOmega; + } else if (grmotherPdg == kPhi) { + mpdg = grmotherPdg; + mpt = grmotherPt; + return GammaPhi; + } else if (grmotherPdg == kEtaPrime) { + mpdg = grmotherPdg; + mpt = grmotherPt; + return GammaEtaPrime; + } else if (grmotherPdg == kRho770_0) { + mpdg = grmotherPdg; + mpt = grmotherPt; + return GammaRho0; + } else { + return Else; + } + } + } + } + } + } else { // check if electron from Dalitz decays + mctrack = partMother.front().template mothers_as(); + if (mctrack.size()) { + auto const& grmothersIdsVec = mctrack.front().mothersIds(); + if (grmothersIdsVec.empty()) { + static const std::map pdgToSource = { + {kPi0, Pi0}, + {kEta, Eta}, + {kOmega, Omega}, + {kPhi, Phi}, + {kEtaPrime, EtaPrime}, + {kRho770_0, Rho0}, + {kKPlus, Ke3}, + {kK0Long, K0l}}; + + auto it = pdgToSource.find(motherPdg); + if (it != pdgToSource.end()) { + return it->second; + } + return Else; + + } else { + if (motherPdg == kPi0) { + grmotherPt = mctrack.front().pt(); + grmotherPdg = mctrack.front().pdgCode(); + mpt = grmotherPt; + mpdg = grmotherPdg; + if (grmotherPdg == kK0Short) { + return K0s; + } else if (grmotherPdg == kK0Long) { + return K0l; + } else if (grmotherPdg == kKPlus) { + return Ke3; + } else if (grmotherPdg == kLambda0) { + return Lambda0; + } else if (grmotherPdg == kSigmaPlus) { + return Sigma; + } else { + mpt = motherPt; + mpdg = motherPdg; + return Pi0; + } + } else if (motherPdg == kEta) { + return Eta; + } else if (motherPdg == kOmega) { + return Omega; + } else if (motherPdg == kPhi) { + return Phi; + } else if (motherPdg == kEtaPrime) { + return EtaPrime; + } else if (motherPdg == kRho770_0) { + return Rho0; + } else if (motherPdg == kKPlus) { + return Ke3; + } else if (motherPdg == kK0Long) { + return K0l; + } else { + return Else; + } + } + } + } + + return Else; + } + + void processData(soa::Filtered::iterator const& collision, + TracksEl const& tracks) + { + float flagAnalysedEvt = 0.5; + + if (!collision.sel8()) { + return; + } + + if (collision.numContrib() < nContribMin) { + return; + } + + histos.fill(HIST("VtxZ"), collision.posZ()); + histos.fill(HIST("nEvents"), flagAnalysedEvt); + + for (const auto& track : tracks) { + + if (!trackSel(track)) { + continue; + } + + if (!(track.passedITSRefit() && track.passedTPCRefit())) { + continue; + } + + histos.fill(HIST("etaTrack"), track.eta()); + histos.fill(HIST("ptTrack"), track.pt()); + + histos.fill(HIST("tpcNClsTrack"), track.tpcNClsCrossedRows()); + histos.fill(HIST("tpcFoundFindableTrack"), track.tpcCrossedRowsOverFindableCls()); + histos.fill(HIST("tpcChi2Track"), track.tpcChi2NCl()); + histos.fill(HIST("itsIBClsTrack"), track.itsNClsInnerBarrel()); + histos.fill(HIST("itsChi2Track"), track.itsChi2NCl()); + histos.fill(HIST("dcaXYTrack"), track.dcaXY()); + histos.fill(HIST("dcaZTrack"), track.dcaZ()); + + histos.fill(HIST("tofNSigPt"), track.pt(), track.tofNSigmaEl()); + histos.fill(HIST("tpcNSigPt"), track.pt(), track.tpcNSigmaEl()); + + if (std::abs(track.tofNSigmaEl()) > tofNSigmaMax) { + continue; + } + histos.fill(HIST("tofNSigPtQA"), track.pt(), track.tofNSigmaEl()); + histos.fill(HIST("tpcNSigPtAfterTofCut"), track.pt(), track.tpcNSigmaEl()); + + if (track.tpcNSigmaEl() < tpcNSigmaMin || track.tpcNSigmaEl() > tpcNSigmaMax) { + continue; + } + histos.fill(HIST("tpcNSigPtQA"), track.pt(), track.tpcNSigmaEl()); + + histos.fill(HIST("dcaTrack"), track.pt(), track.dcaXY()); + } + } + PROCESS_SWITCH(HfTaskSingleElectron, processData, "For real data", true); + + void processMc(soa::Filtered::iterator const& collision, + McTracksEl const& tracks, + aod::McParticles const&) { - float flagEventFill = 0.5; float flagAnalysedEvt = 0.5; - histos.fill(HIST("hEventCounter"), flagEventFill); if (!collision.sel8()) { return; } - flagEventFill += 1.; - histos.fill(HIST("hEventCounter"), flagEventFill); if (collision.numContrib() < nContribMin) { return; } - flagEventFill += 1.; - histos.fill(HIST("hEventCounter"), flagEventFill); histos.fill(HIST("VtxZ"), collision.posZ()); histos.fill(HIST("nEvents"), flagAnalysedEvt); @@ -179,6 +484,30 @@ struct HfTaskSingleElectron { histos.fill(HIST("tofNSigPt"), track.pt(), track.tofNSigmaEl()); histos.fill(HIST("tpcNSigPt"), track.pt(), track.tpcNSigmaEl()); + int mpdg; // electron source pdg code + double mpt; // electron source pt + int source = getElecSource(track, mpt, mpdg); + + if (source == DirectBeauty || source == BeautyCharm) { + histos.fill(HIST("hPdgB"), mpdg); + histos.fill(HIST("dcaBeauty"), track.pt(), track.dcaXY()); + } + + if (source == DirectCharm) { + histos.fill(HIST("hPdgC"), mpdg); + histos.fill(HIST("dcaCharm"), track.pt(), track.dcaXY()); + } + + if (source >= GammaPi0 && source <= GammaSigma) { + histos.fill(HIST("hPdgCo"), mpdg); + histos.fill(HIST("dcaConv"), track.pt(), track.dcaXY()); + } + + if (source >= Pi0 && source <= Sigma) { + histos.fill(HIST("hPdgDa"), mpdg); + histos.fill(HIST("dcaDalitz"), track.pt(), track.dcaXY()); + } + if (std::abs(track.tofNSigmaEl()) > tofNSigmaMax) { continue; } @@ -193,6 +522,7 @@ struct HfTaskSingleElectron { histos.fill(HIST("dcaTrack"), track.pt(), track.dcaXY()); } } + PROCESS_SWITCH(HfTaskSingleElectron, processMc, "For real data", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/TableProducer/candidateCreator2Prong.cxx b/PWGHF/TableProducer/candidateCreator2Prong.cxx index e6cc3f02487..c8bc2bd1274 100644 --- a/PWGHF/TableProducer/candidateCreator2Prong.cxx +++ b/PWGHF/TableProducer/candidateCreator2Prong.cxx @@ -89,11 +89,11 @@ using namespace o2::aod::pid_tpc_tof_utils; /// Reconstruction of heavy-flavour 2-prong decay candidates struct HfCandidateCreator2Prong { Produces rowCandidateBase; - Produces rowProng0PidPi; - Produces rowProng0PidKa; - Produces rowProng1PidPi; - Produces rowProng1PidKa; Produces rowCandidateKF; + Produces rowProng0PidPi; + Produces rowProng0PidKa; + Produces rowProng1PidPi; + Produces rowProng1PidKa; // vertexing Configurable constrainKfToPv{"constrainKfToPv", true, "constraint KFParticle to PV"}; @@ -234,7 +234,7 @@ struct HfCandidateCreator2Prong { /// reject candidates not satisfying the event selections auto collision = rowTrackIndexProng2.template collision_as(); float centrality{-1.f}; - uint32_t rejectionMask{0}; + o2::hf_evsel::HfCollisionRejectionMask rejectionMask{}; if constexpr (applyUpcSel) { rejectionMask = hfEvSel.getHfCollisionRejectionMaskWithUpc(collision, centrality, ccdb, registry, bcs); } else { @@ -340,7 +340,7 @@ struct HfCandidateCreator2Prong { if (indexCollision == track1.collisionId() && track1.isPVContributor()) { SETBIT(bitmapProngsContributorsPV, 1); } - uint8_t nProngsContributorsPV = hf_trkcandsel::countOnesInBinary(bitmapProngsContributorsPV); + const auto nProngsContributorsPV = hf_trkcandsel::countOnesInBinary(bitmapProngsContributorsPV); // fill candidate table rows rowCandidateBase(indexCollision, @@ -391,7 +391,7 @@ struct HfCandidateCreator2Prong { /// reject candidates in collisions not satisfying the event selections auto collision = rowTrackIndexProng2.template collision_as(); float centrality{-1.f}; - uint32_t rejectionMask{0}; + o2::hf_evsel::HfCollisionRejectionMask rejectionMask{}; if constexpr (applyUpcSel) { rejectionMask = hfEvSel.getHfCollisionRejectionMaskWithUpc(collision, centrality, ccdb, registry, bcs); } else { @@ -501,7 +501,7 @@ struct HfCandidateCreator2Prong { if (indexCollision == track1.collisionId() && track1.isPVContributor()) { SETBIT(bitmapProngsContributorsPV, 1); } - uint8_t nProngsContributorsPV = hf_trkcandsel::countOnesInBinary(bitmapProngsContributorsPV); + const auto nProngsContributorsPV = hf_trkcandsel::countOnesInBinary(bitmapProngsContributorsPV); // fill candidate table rows rowCandidateBase(indexCollision, @@ -750,7 +750,7 @@ struct HfCandidateCreator2Prong { /// bitmask with event. selection info float centrality{-1.f}; - float occupancy = getOccupancyColl(collision, OccupancyEstimator::Its); + const auto occupancy = o2::hf_occupancy::getOccupancyColl(collision, hfEvSel.occEstimator); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); /// monitor the satisfied event selections @@ -768,7 +768,7 @@ struct HfCandidateCreator2Prong { /// bitmask with event. selection info float centrality{-1.f}; - float occupancy = getOccupancyColl(collision, OccupancyEstimator::Its); + const auto occupancy = o2::hf_occupancy::getOccupancyColl(collision, hfEvSel.occEstimator); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); /// monitor the satisfied event selections @@ -786,7 +786,7 @@ struct HfCandidateCreator2Prong { /// bitmask with event. selection info float centrality{-1.f}; - float occupancy = getOccupancyColl(collision, OccupancyEstimator::Its); + const auto occupancy = o2::hf_occupancy::getOccupancyColl(collision, hfEvSel.occEstimator); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); /// monitor the satisfied event selections @@ -809,7 +809,7 @@ struct HfCandidateCreator2Prong { /// bitmask with event. selection info float centrality{-1.f}; - float occupancy = getOccupancyColl(collision, OccupancyEstimator::Its); + const auto occupancy = o2::hf_occupancy::getOccupancyColl(collision, hfEvSel.occEstimator); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMaskWithUpc(collision, centrality, ccdb, registry, bcs); /// monitor the satisfied event selections @@ -1028,7 +1028,7 @@ struct HfCandidateCreator2ProngExpressions { const auto mcParticlesPerMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, mcCollision.globalIndex()); // Slice the collisions table to get the collision info for the current MC collision float centrality{-1.f}; - uint32_t rejectionMask{0u}; + o2::hf_evsel::HfCollisionRejectionMask rejectionMask{}; int nSplitColl = 0; if constexpr (centEstimator == CentralityEstimator::FT0C) { const auto collSlice = collInfos.sliceBy(colPerMcCollisionFT0C, mcCollision.globalIndex()); diff --git a/PWGHF/TableProducer/candidateCreator3Prong.cxx b/PWGHF/TableProducer/candidateCreator3Prong.cxx index c60300f41be..a549cd24df7 100644 --- a/PWGHF/TableProducer/candidateCreator3Prong.cxx +++ b/PWGHF/TableProducer/candidateCreator3Prong.cxx @@ -91,15 +91,15 @@ using namespace o2::aod::pid_tpc_tof_utils; struct HfCandidateCreator3Prong { Produces rowCandidateBase; Produces rowCandidateKF; - Produces rowProng0PidPi; - Produces rowProng0PidKa; - Produces rowProng0PidPr; - Produces rowProng1PidPi; - Produces rowProng1PidKa; - Produces rowProng1PidPr; - Produces rowProng2PidPi; - Produces rowProng2PidKa; - Produces rowProng2PidPr; + Produces rowProng0PidPi; + Produces rowProng0PidKa; + Produces rowProng0PidPr; + Produces rowProng1PidPi; + Produces rowProng1PidKa; + Produces rowProng1PidPr; + Produces rowProng2PidPi; + Produces rowProng2PidKa; + Produces rowProng2PidPr; // vertexing Configurable propagateToPCA{"propagateToPCA", true, "create tracks version propagated to PCA"}; @@ -276,7 +276,7 @@ struct HfCandidateCreator3Prong { /// reject candidates in collisions not satisfying the event selections auto collision = rowTrackIndexProng3.template collision_as(); float centrality{-1.f}; - uint32_t rejectionMask{0}; + o2::hf_evsel::HfCollisionRejectionMask rejectionMask{}; if constexpr (applyUpcSel) { rejectionMask = hfEvSel.getHfCollisionRejectionMaskWithUpc(collision, centrality, ccdb, registry, bcs); } else { @@ -394,7 +394,7 @@ struct HfCandidateCreator3Prong { if (indexCollision == track2.collisionId() && track2.isPVContributor()) { SETBIT(bitmapProngsContributorsPV, 2); } - uint8_t nProngsContributorsPV = hf_trkcandsel::countOnesInBinary(bitmapProngsContributorsPV); + const auto nProngsContributorsPV = hf_trkcandsel::countOnesInBinary(bitmapProngsContributorsPV); // fill candidate table rows rowCandidateBase(indexCollision, @@ -447,7 +447,7 @@ struct HfCandidateCreator3Prong { /// reject candidates in collisions not satisfying the event selections auto collision = rowTrackIndexProng3.template collision_as(); float centrality{-1.f}; - uint32_t rejectionMask{0}; + o2::hf_evsel::HfCollisionRejectionMask rejectionMask{}; if constexpr (applyUpcSel) { rejectionMask = hfEvSel.getHfCollisionRejectionMaskWithUpc(collision, centrality, ccdb, registry, bcs); } else { @@ -635,7 +635,7 @@ struct HfCandidateCreator3Prong { if (indexCollision == track2.collisionId() && track2.isPVContributor()) { SETBIT(bitmapProngsContributorsPV, 2); } - uint8_t nProngsContributorsPV = hf_trkcandsel::countOnesInBinary(bitmapProngsContributorsPV); + const auto nProngsContributorsPV = hf_trkcandsel::countOnesInBinary(bitmapProngsContributorsPV); // fill candidate table rows rowCandidateBase(indexCollision, @@ -894,7 +894,7 @@ struct HfCandidateCreator3Prong { /// bitmask with event. selection info float centrality{-1.f}; - float occupancy = getOccupancyColl(collision, OccupancyEstimator::Its); + const auto occupancy = o2::hf_occupancy::getOccupancyColl(collision, hfEvSel.occEstimator); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); /// monitor the satisfied event selections @@ -912,7 +912,7 @@ struct HfCandidateCreator3Prong { /// bitmask with event. selection info float centrality{-1.f}; - float occupancy = getOccupancyColl(collision, OccupancyEstimator::Its); + const auto occupancy = o2::hf_occupancy::getOccupancyColl(collision, hfEvSel.occEstimator); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); /// monitor the satisfied event selections @@ -930,7 +930,7 @@ struct HfCandidateCreator3Prong { /// bitmask with event. selection info float centrality{-1.f}; - float occupancy = getOccupancyColl(collision, OccupancyEstimator::Its); + const auto occupancy = o2::hf_occupancy::getOccupancyColl(collision, hfEvSel.occEstimator); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); /// monitor the satisfied event selections @@ -953,7 +953,7 @@ struct HfCandidateCreator3Prong { /// bitmask with event. selection info float centrality{-1.f}; - float occupancy = getOccupancyColl(collision, OccupancyEstimator::Its); + const auto occupancy = o2::hf_occupancy::getOccupancyColl(collision, hfEvSel.occEstimator); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMaskWithUpc(collision, centrality, ccdb, registry, bcs); /// monitor the satisfied event selections @@ -1316,7 +1316,7 @@ struct HfCandidateCreator3ProngExpressions { const auto mcParticlesPerMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, mcCollision.globalIndex()); // Slice the collisions table to get the collision info for the current MC collision float centrality{-1.f}; - uint32_t rejectionMask{0u}; + o2::hf_evsel::HfCollisionRejectionMask rejectionMask{}; int nSplitColl = 0; if constexpr (centEstimator == CentralityEstimator::FT0C) { const auto collSlice = collInfos.sliceBy(colPerMcCollisionFT0C, mcCollision.globalIndex()); diff --git a/PWGHF/TableProducer/candidateCreatorCascade.cxx b/PWGHF/TableProducer/candidateCreatorCascade.cxx index 20e16710463..1bfe94031cb 100644 --- a/PWGHF/TableProducer/candidateCreatorCascade.cxx +++ b/PWGHF/TableProducer/candidateCreatorCascade.cxx @@ -564,7 +564,7 @@ struct HfCandidateCreatorCascadeMc { const auto mcParticlesPerMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, mcCollision.globalIndex()); // Slice the collisions table to get the collision info for the current MC collision float centrality{-1.f}; - uint32_t rejectionMask{0u}; + o2::hf_evsel::HfCollisionRejectionMask rejectionMask{}; int nSplitColl = 0; if constexpr (centEstimator == CentralityEstimator::FT0C) { const auto collSlice = collInfos.sliceBy(colPerMcCollisionFT0C, mcCollision.globalIndex()); diff --git a/PWGHF/TableProducer/candidateCreatorDstar.cxx b/PWGHF/TableProducer/candidateCreatorDstar.cxx index 9036717104b..2fb6092c4e3 100644 --- a/PWGHF/TableProducer/candidateCreatorDstar.cxx +++ b/PWGHF/TableProducer/candidateCreatorDstar.cxx @@ -77,12 +77,12 @@ using HfDstarsWithPvRefitInfo = soa::Join; struct HfCandidateCreatorDstar { Produces rowCandD0Base; Produces rowCandDstarBase; - Produces rowProng0PidPi; - Produces rowProng0PidKa; - Produces rowProng1PidPi; - Produces rowProng1PidKa; - Produces rowProngSoftPiPidPi; - Produces rowProngSoftPiPidKa; + Produces rowProng0PidPi; + Produces rowProng0PidKa; + Produces rowProng1PidPi; + Produces rowProng1PidKa; + Produces rowProngSoftPiPidPi; + Produces rowProngSoftPiPidKa; Configurable fillHistograms{"fillHistograms", true, "fill histograms"}; @@ -732,7 +732,7 @@ struct HfCandidateCreatorDstarExpressions { const auto mcParticlesPerMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, mcCollision.globalIndex()); // Slice the collisions table to get the collision info for the current MC collision float centrality{-1.f}; - uint32_t rejectionMask{0u}; + o2::hf_evsel::HfCollisionRejectionMask rejectionMask{}; int nSplitColl = 0; if constexpr (centEstimator == CentralityEstimator::FT0C) { const auto collSlice = collInfos.sliceBy(colPerMcCollisionFT0C, mcCollision.globalIndex()); diff --git a/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx b/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx index 9a59c28cf9c..e826254ea35 100644 --- a/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx +++ b/PWGHF/TableProducer/candidateCreatorSigmac0plusplus.cxx @@ -587,7 +587,7 @@ struct HfCandidateSigmac0plusplusMc { auto mcCollision = particle.mcCollision(); float centrality{-1.f}; const auto collSlice = collInfos.sliceBy(colPerMcCollision, mcCollision.globalIndex()); - auto rejectionMask = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, collSlice, centrality); + const auto rejectionMask = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, collSlice, centrality); hfEvSelMc.fillHistograms(mcCollision, rejectionMask, 0); if (rejectionMask != 0) { // at least one event selection not satisfied --> reject gen particles from this collision diff --git a/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx b/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx index 9d7413d75d1..5f3e0b3ebba 100644 --- a/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx +++ b/PWGHF/TableProducer/candidateCreatorXic0Omegac0.cxx @@ -2726,7 +2726,7 @@ struct HfCandidateCreatorXic0Omegac0Mc { const auto mcParticlesPerMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, mcCollision.globalIndex()); // Slice the collisions table to get the collision info for the current MC collision float centrality{-1.f}; - uint32_t rejectionMask{0u}; + o2::hf_evsel::HfCollisionRejectionMask rejectionMask{}; int nSplitColl = 0; if constexpr (centEstimator == CentralityEstimator::FT0C) { const auto collSlice = collsWithMcLabels.sliceBy(colPerMcCollisionFT0C, mcCollision.globalIndex()); diff --git a/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx b/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx index 3d5688a6db1..f88a6d573c9 100644 --- a/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx +++ b/PWGHF/TableProducer/candidateCreatorXicToXiPiPi.cxx @@ -798,7 +798,7 @@ struct HfCandidateCreatorXicToXiPiPi { /// bitmask with event. selection info float centrality{-1.f}; - float occupancy = getOccupancyColl(collision, OccupancyEstimator::Its); + const auto occupancy = o2::hf_occupancy::getOccupancyColl(collision, hfEvSel.occEstimator); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); /// monitor the satisfied event selections @@ -815,7 +815,7 @@ struct HfCandidateCreatorXicToXiPiPi { /// bitmask with event. selection info float centrality{-1.f}; - float occupancy = getOccupancyColl(collision, OccupancyEstimator::Its); + const auto occupancy = o2::hf_occupancy::getOccupancyColl(collision, hfEvSel.occEstimator); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); /// monitor the satisfied event selections @@ -832,7 +832,7 @@ struct HfCandidateCreatorXicToXiPiPi { /// bitmask with event. selection info float centrality{-1.f}; - float occupancy = getOccupancyColl(collision, OccupancyEstimator::Its); + const auto occupancy = o2::hf_occupancy::getOccupancyColl(collision, hfEvSel.occEstimator); const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(collision, centrality, ccdb, registry); /// monitor the satisfied event selections @@ -912,6 +912,7 @@ struct HfCandidateCreatorXicToXiPiPiExpressions { int8_t sign = 0; int8_t flag = 0; int8_t origin = RecoDecay::OriginType::None; + float decayLengthGen = -999.f; int8_t nPionsDecayed = 0; int8_t nInteractionsWithMaterial = 0; // for resonance matching @@ -1071,7 +1072,7 @@ struct HfCandidateCreatorXicToXiPiPiExpressions { const auto mcParticlesPerMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, mcCollision.globalIndex()); // Slice the collisions table to get the collision info for the current MC collision float centrality{-1.f}; - uint32_t rejectionMask{0u}; + o2::hf_evsel::HfCollisionRejectionMask rejectionMask{}; int nSplitColl = 0; if constexpr (centEstimator == o2::hf_centrality::CentralityEstimator::FT0C) { const auto collSlice = collInfos.sliceBy(colPerMcCollisionFT0C, mcCollision.globalIndex()); @@ -1088,7 +1089,7 @@ struct HfCandidateCreatorXicToXiPiPiExpressions { if (rejectionMask != 0) { // at least one event selection not satisfied --> reject all particles from this collision for (unsigned int i = 0; i < mcParticlesPerMcColl.size(); ++i) { - rowMcMatchGen(-99, -99, -99); + rowMcMatchGen(-99, -99, -99, decayLengthGen); } continue; } @@ -1134,13 +1135,18 @@ struct HfCandidateCreatorXicToXiPiPiExpressions { // Check whether the charm baryon is non-prompt (from a b quark). if (flag != 0) { origin = RecoDecay::getCharmHadronOrigin(mcParticles, particle, false, &idxBhadMothers); + // Calculate the decay length of the generated particle + auto dau0 = particle.template daughters_as().begin(); + const std::array vtxDau{dau0.vx(), dau0.vy(), dau0.vz()}; + const std::array vtxPV{mcCollision.posX(), mcCollision.posY(), mcCollision.posZ()}; + decayLengthGen = RecoDecay::distance(vtxPV, vtxDau); } // Fill table if (origin == RecoDecay::OriginType::NonPrompt) { auto bHadMother = mcParticles.rawIteratorAt(idxBhadMothers[0]); - rowMcMatchGen(flag, origin, bHadMother.pdgCode()); + rowMcMatchGen(flag, origin, bHadMother.pdgCode(), decayLengthGen); } else { - rowMcMatchGen(flag, origin, 0); + rowMcMatchGen(flag, origin, 0, decayLengthGen); } } // close loop over generated particles } // close loop over McCollisions diff --git a/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx b/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx index dbc06282ce0..bd3cb47b28f 100644 --- a/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx +++ b/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx @@ -16,7 +16,6 @@ /// \author Fabrizio Grosa , CERN #include "PWGHF/Core/HfHelper.h" -#include "PWGHF/Core/HfMlResponseD0ToKPi.h" #include "PWGHF/Core/HfMlResponseDstarToD0Pi.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index ebe0713d03a..8bfd706500a 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -87,6 +87,7 @@ using namespace o2::aod; using namespace o2::hf_centrality; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::constants::physics; // enum for candidate type enum CandidateType { @@ -159,8 +160,8 @@ struct HfTrackIndexSkimCreatorTagSelCollisions { template void selectCollision(const Col& collision, const BCsType& bcs) { - float centrality = -1.; - uint32_t rejectionMask; + float centrality = -1.f; + o2::hf_evsel::HfCollisionRejectionMask rejectionMask{}; if constexpr (applyUpcSel) { rejectionMask = hfEvSel.getHfCollisionRejectionMaskWithUpc( @@ -510,7 +511,7 @@ struct HfTrackIndexSkimCreatorTagSelTracks { /// \param dca is a 2-element array with dca in transverse and longitudinal directions /// \param statusProng is the selection flag template - void isSelectedTrack(const T& hfTrack, const float& trackPt, const float& trackEta, const std::array& dca, int& statusProng) + void isSelectedTrack(const T& hfTrack, const float trackPt, const float trackEta, const std::array& dca, int& statusProng) { if (config.fillHistograms) { registry.fill(HIST("hPtNoCuts"), trackPt); @@ -1267,14 +1268,6 @@ struct HfTrackIndexSkimCreator { o2::base::Propagator::MatCorrType noMatCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE; int runNumber; - double massPi{0.}; - double massK{0.}; - double massProton{0.}; - double massElectron{0.}; - double massMuon{0.}; - double massDzero{0.}; - double massPhi{0.}; - // int nColls{0}; //can be added to run over limited collisions per file - for tesing purposes static constexpr int kN2ProngDecays = hf_cand_2prong::DecayType::N2ProngDecays; // number of 2-prong hadron types @@ -1301,7 +1294,7 @@ struct HfTrackIndexSkimCreator { using FilteredTrackAssocSel = soa::Filtered>; // filter collisions - Filter filterSelectCollisions = (aod::hf_sel_collision::whyRejectColl == static_cast(0)); + Filter filterSelectCollisions = (aod::hf_sel_collision::whyRejectColl == static_cast(0)); // filter track indices Filter filterSelectTrackIds = ((aod::hf_sel_track::isSelProng & static_cast(BIT(CandidateType::Cand2Prong))) != 0u) || ((aod::hf_sel_track::isSelProng & static_cast(BIT(CandidateType::Cand3Prong))) != 0u) || ((aod::hf_sel_track::isSelProng & static_cast(BIT(CandidateType::CandDstar))) != 0u); @@ -1328,34 +1321,26 @@ struct HfTrackIndexSkimCreator { return; } - massPi = o2::constants::physics::MassPiPlus; - massK = o2::constants::physics::MassKPlus; - massProton = o2::constants::physics::MassProton; - massElectron = o2::constants::physics::MassElectron; - massMuon = o2::constants::physics::MassMuonPlus; - massDzero = o2::constants::physics::MassD0; - massPhi = o2::constants::physics::MassPhi; - - arrMass2Prong[hf_cand_2prong::DecayType::D0ToPiK] = std::array{std::array{massPi, massK}, - std::array{massK, massPi}}; + arrMass2Prong[hf_cand_2prong::DecayType::D0ToPiK] = std::array{std::array{MassPiPlus, MassKPlus}, + std::array{MassKPlus, MassPiPlus}}; - arrMass2Prong[hf_cand_2prong::DecayType::JpsiToEE] = std::array{std::array{massElectron, massElectron}, - std::array{massElectron, massElectron}}; + arrMass2Prong[hf_cand_2prong::DecayType::JpsiToEE] = std::array{std::array{MassElectron, MassElectron}, + std::array{MassElectron, MassElectron}}; - arrMass2Prong[hf_cand_2prong::DecayType::JpsiToMuMu] = std::array{std::array{massMuon, massMuon}, - std::array{massMuon, massMuon}}; + arrMass2Prong[hf_cand_2prong::DecayType::JpsiToMuMu] = std::array{std::array{MassMuonPlus, MassMuonPlus}, + std::array{MassMuonPlus, MassMuonPlus}}; - arrMass3Prong[hf_cand_3prong::DecayType::DplusToPiKPi] = std::array{std::array{massPi, massK, massPi}, - std::array{massPi, massK, massPi}}; + arrMass3Prong[hf_cand_3prong::DecayType::DplusToPiKPi] = std::array{std::array{MassPiPlus, MassKPlus, MassPiPlus}, + std::array{MassPiPlus, MassKPlus, MassPiPlus}}; - arrMass3Prong[hf_cand_3prong::DecayType::LcToPKPi] = std::array{std::array{massProton, massK, massPi}, - std::array{massPi, massK, massProton}}; + arrMass3Prong[hf_cand_3prong::DecayType::LcToPKPi] = std::array{std::array{MassProton, MassKPlus, MassPiPlus}, + std::array{MassPiPlus, MassKPlus, MassProton}}; - arrMass3Prong[hf_cand_3prong::DecayType::DsToKKPi] = std::array{std::array{massK, massK, massPi}, - std::array{massPi, massK, massK}}; + arrMass3Prong[hf_cand_3prong::DecayType::DsToKKPi] = std::array{std::array{MassKPlus, MassKPlus, MassPiPlus}, + std::array{MassPiPlus, MassKPlus, MassKPlus}}; - arrMass3Prong[hf_cand_3prong::DecayType::XicToPKPi] = std::array{std::array{massProton, massK, massPi}, - std::array{massPi, massK, massProton}}; + arrMass3Prong[hf_cand_3prong::DecayType::XicToPKPi] = std::array{std::array{MassProton, MassKPlus, MassPiPlus}, + std::array{MassPiPlus, MassKPlus, MassProton}}; // cuts for 2-prong decays retrieved by json. the order must be then one in hf_cand_2prong::DecayType cut2Prong = {config.cutsD0ToPiK, config.cutsJpsiToEE, config.cutsJpsiToMuMu}; @@ -1572,10 +1557,10 @@ struct HfTrackIndexSkimCreator { whichHypo[kN2ProngDecays] = whichHypo[hf_cand_2prong::DecayType::D0ToPiK]; double deltaMass = config.cutsDstarToD0Pi->get(pTBinDstar, 1u); - if (TESTBIT(whichHypo[iDecay2P], 0) && (massHypos[0] > (massDzero + deltaMass) * (massDzero + deltaMass) || massHypos[0] < (massDzero - deltaMass) * (massDzero - deltaMass))) { + if (TESTBIT(whichHypo[iDecay2P], 0) && (massHypos[0] > (MassD0 + deltaMass) * (MassD0 + deltaMass) || massHypos[0] < (MassD0 - deltaMass) * (MassD0 - deltaMass))) { CLRBIT(whichHypo[kN2ProngDecays], 0); } - if (TESTBIT(whichHypo[iDecay2P], 1) && (massHypos[1] > (massDzero + deltaMass) * (massDzero + deltaMass) || massHypos[1] < (massDzero - deltaMass) * (massDzero - deltaMass))) { + if (TESTBIT(whichHypo[iDecay2P], 1) && (massHypos[1] > (MassD0 + deltaMass) * (MassD0 + deltaMass) || massHypos[1] < (MassD0 - deltaMass) * (MassD0 - deltaMass))) { CLRBIT(whichHypo[kN2ProngDecays], 1); } } @@ -1597,13 +1582,13 @@ struct HfTrackIndexSkimCreator { double deltaMassMax = cut3Prong[hf_cand_3prong::DecayType::DsToKKPi].get(pTBin, 4u); if (TESTBIT(whichHypo[hf_cand_3prong::DecayType::DsToKKPi], 0)) { double mass2PhiKKPi = RecoDecay::m2(std::array{pVecTrack0, pVecTrack1}, std::array{arrMass3Prong[hf_cand_3prong::DecayType::DsToKKPi][0][0], arrMass3Prong[hf_cand_3prong::DecayType::DsToKKPi][0][1]}); - if (mass2PhiKKPi > (massPhi + deltaMassMax) * (massPhi + deltaMassMax) || mass2PhiKKPi < (massPhi - deltaMassMax) * (massPhi - deltaMassMax)) { + if (mass2PhiKKPi > (MassPhi + deltaMassMax) * (MassPhi + deltaMassMax) || mass2PhiKKPi < (MassPhi - deltaMassMax) * (MassPhi - deltaMassMax)) { CLRBIT(whichHypo[hf_cand_3prong::DecayType::DsToKKPi], 0); } } if (TESTBIT(whichHypo[hf_cand_3prong::DecayType::DsToKKPi], 1)) { double mass2PhiPiKK = RecoDecay::m2(std::array{pVecTrack1, pVecTrack2}, std::array{arrMass3Prong[hf_cand_3prong::DecayType::DsToKKPi][1][1], arrMass3Prong[hf_cand_3prong::DecayType::DsToKKPi][1][2]}); - if (mass2PhiPiKK > (massPhi + deltaMassMax) * (massPhi + deltaMassMax) || mass2PhiPiKK < (massPhi - deltaMassMax) * (massPhi - deltaMassMax)) { + if (mass2PhiPiKK > (MassPhi + deltaMassMax) * (MassPhi + deltaMassMax) || mass2PhiPiKK < (MassPhi - deltaMassMax) * (MassPhi - deltaMassMax)) { CLRBIT(whichHypo[hf_cand_3prong::DecayType::DsToKKPi], 1); } } @@ -1701,7 +1686,7 @@ struct HfTrackIndexSkimCreator { /// \param cutStatus is a 2D array with outcome of each selection (filled only in debug mode) /// \param isSelected ia s bitmap with selection outcome template - void applySelections2Prong(const T1& pVecCand, const T2& secVtx, const T3& primVtx, T4& cutStatus, int& isSelected) + void applySelection2Prong(const T1& pVecCand, const T2& secVtx, const T3& primVtx, T4& cutStatus, int& isSelected) { if (config.debug || isSelected > 0) { @@ -1912,8 +1897,8 @@ struct HfTrackIndexSkimCreator { // D0 mass double deltaMassD0 = config.cutsDstarToD0Pi->get(pTBin, 1u); // 1u == deltaMassD0Index - double invMassD0 = RecoDecay::m(arrMomD0, std::array{massPi, massK}); - if (std::abs(invMassD0 - massDzero) > deltaMassD0) { + double invMassD0 = RecoDecay::m(arrMomD0, std::array{MassPiPlus, MassKPlus}); + if (std::abs(invMassD0 - MassD0) > deltaMassD0) { isSelected = 0; if (config.debug) { CLRBIT(cutStatus, 1); @@ -1923,7 +1908,7 @@ struct HfTrackIndexSkimCreator { // D*+ mass double maxDeltaMass = config.cutsDstarToD0Pi->get(pTBin, 0u); // 0u == deltaMassIndex - double invMassDstar = RecoDecay::m(arrMom, std::array{massPi, massK, massPi}); + double invMassDstar = RecoDecay::m(arrMom, std::array{MassPiPlus, MassKPlus, MassPiPlus}); deltaMass = invMassDstar - invMassD0; if (deltaMass > maxDeltaMass) { isSelected = 0; @@ -2309,7 +2294,7 @@ struct HfTrackIndexSkimCreator { pvCoord2Prong[1] = pvRefitCoord2Prong[1]; pvCoord2Prong[2] = pvRefitCoord2Prong[2]; } - applySelections2Prong(pVecCandProng2, secondaryVertex2, pvCoord2Prong, cutStatus2Prong, isSelected2ProngCand); + applySelection2Prong(pVecCandProng2, secondaryVertex2, pvCoord2Prong, cutStatus2Prong, isSelected2ProngCand); if (is2ProngCandidateGoodFor3Prong && config.do3Prong == 1) { is2ProngCandidateGoodFor3Prong = isTwoTrackVertexSelectedFor3Prongs(secondaryVertex2, pvCoord2Prong, df2); } @@ -3106,14 +3091,10 @@ struct HfTrackIndexSkimCreatorCascades { o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; int runNumber{0}; - double massP{0.}; - double massK0s{0.}; - double massLc{0.}; - using SelectedCollisions = soa::Filtered>; using FilteredTrackAssocSel = soa::Filtered>; - Filter filterSelectCollisions = (aod::hf_sel_collision::whyRejectColl == static_cast(0)); + Filter filterSelectCollisions = (aod::hf_sel_collision::whyRejectColl == static_cast(0)); Filter filterSelectTrackIds = (aod::hf_sel_track::isSelProng & static_cast(BIT(CandidateType::CandV0bachelor))) != 0u && (config.applyProtonPid == false || (aod::hf_sel_track::isIdentifiedPid & static_cast(BIT(ChannelsProtonPid::LcToPK0S))) != 0u); Preslice trackIndicesPerCollision = aod::track_association::collisionId; @@ -3132,10 +3113,6 @@ struct HfTrackIndexSkimCreatorCascades { config.etaMinV0Daugh.value = -config.etaMaxV0Daugh; } - massP = o2::constants::physics::MassProton; - massK0s = o2::constants::physics::MassK0Short; - massLc = o2::constants::physics::MassLambdaCPlus; - if (config.useDCAFitter) { df2.setPropagateToPCA(config.propagateToPCA); df2.setMaxR(config.maxR); @@ -3225,7 +3202,7 @@ struct HfTrackIndexSkimCreatorCascades { } // V0 invariant mass selection - if (std::abs(v0.mK0Short() - massK0s) > config.cutInvMassV0) { + if (std::abs(v0.mK0Short() - MassK0Short) > config.cutInvMassV0) { continue; // should go to the filter, but since it is a dynamic column, I cannot use it there } @@ -3238,8 +3215,8 @@ struct HfTrackIndexSkimCreatorCascades { // invariant-mass cut: we do it here, before updating the momenta of bach and V0 during the fitting to save CPU // TODO: but one should better check that the value here and after the fitter do not change significantly!!! - double mass2K0sP = RecoDecay::m(std::array{pVecBach, pVecV0}, std::array{massP, massK0s}); - if ((config.cutInvMassCascLc >= 0.) && (std::abs(mass2K0sP - massLc) > config.cutInvMassCascLc)) { + double mass2K0sP = RecoDecay::m(std::array{pVecBach, pVecV0}, std::array{MassProton, MassK0Short}); + if ((config.cutInvMassCascLc >= 0.) && (std::abs(mass2K0sP - MassLambdaCPlus) > config.cutInvMassCascLc)) { continue; } @@ -3281,7 +3258,7 @@ struct HfTrackIndexSkimCreatorCascades { // invariant mass // re-calculate invariant masses with updated momenta, to fill the histogram - mass2K0sP = RecoDecay::m(std::array{pVecBach, pVecV0}, std::array{massP, massK0s}); + mass2K0sP = RecoDecay::m(std::array{pVecBach, pVecV0}, std::array{MassProton, MassK0Short}); std::array posCasc = {0., 0., 0.}; if (config.useDCAFitter) { const auto& cascVtx = df2.getPCACandidate(); @@ -3316,6 +3293,7 @@ struct HfTrackIndexSkimCreatorLfCascades { Configurable do3Prong{"do3Prong", false, "do 3-prong cascade"}; Configurable rejDiffCollTrack{"rejDiffCollTrack", false, "Reject tracks coming from different collisions"}; + Configurable ptTolerance{"ptTolerance", 0.1, "pT tolerance in GeV/c for applying preselections before vertex reconstruction"}; // charm baryon invariant mass spectra limits Configurable massXiPiMin{"massXiPiMin", 2.1, "Invariant mass lower limit for xi pi decay channel"}; @@ -3345,18 +3323,20 @@ struct HfTrackIndexSkimCreatorLfCascades { Configurable ptMinOmegaczeroToOmegaKaLfCasc{"ptMinOmegaczeroToOmegaKaLfCasc", 0.f, "min. pT for Omegaczero in Omega + Ka decays"}; Configurable ptMinXicZeroOmegacZeroToXiPiLfCasc{"ptMinXicZeroOmegacZeroToXiPiLfCasc", 0.f, "min. pT for XicZeroOmegacZero in Xi + Pi decays"}; Configurable ptMinXicplusLfCasc{"ptMinXicplusLfCasc", 0.f, "min. pT for Xicplus in Xi + Pi + Pi decays"}; - Configurable v0TransvRadius{"v0TransvRadius", 1.0, "V0 radius in xy plane"}; // 1.2 (xi) and 1.1 (omega) in run2 - Configurable cascTransvRadius{"cascTransvRadius", 0.4, "Cascade radius in xy plane"}; // 0.5 cm (xi) and 0.6 (omega) in run2 - Configurable dcaBachToPv{"dcaBachToPv", 0.03, "DCA Bach To PV"}; // 0.04 in run2 - Configurable dcaV0ToPv{"dcaV0ToPv", 0.02, "DCA V0 To PV"}; // 0.03 in run2 - Configurable v0CosPA{"v0CosPA", 0.95, "V0 CosPA"}; // 0.97 in run2 - KEEP LOSE to re-cut after PVRefit! - double -> N.B. dcos(x)/dx = 0 at x=0) - Configurable cascCosPA{"cascCosPA", 0.95, "Casc CosPA"}; // 0.97 in run2 - KEEP LOSE to re-cut after PVRefit! - double -> N.B. dcos(x)/dx = 0 at x=0) - Configurable dcaV0Dau{"dcaV0Dau", 2.0, "DCA V0 Daughters"}; // conservative, a cut ar 1.0 should also be fine - Configurable dcaCascDau{"dcaCascDau", 2.0, "DCA Casc Daughters"}; // conservative, a cut ar 1.0 should also be fine - Configurable dcaNegToPv{"dcaNegToPv", 0.05, "DCA Neg To PV"}; // 0.06 in run2 - Configurable dcaPosToPv{"dcaPosToPv", 0.05, "DCA Pos To PV"}; // 0.06 in run2 - Configurable v0MassWindow{"v0MassWindow", 0.01, "V0 mass window"}; // 0.008 in run2 - Configurable cascadeMassWindow{"cascadeMassWindow", 0.01, "Cascade mass window"}; + Configurable v0TransvRadius{"v0TransvRadius", 1.f, "V0 radius in xy plane"}; // 1.2 (xi) and 1.1 (omega) in run2 + Configurable cascTransvRadius{"cascTransvRadius", 0.4f, "Cascade radius in xy plane"}; // 0.5 cm (xi) and 0.6 (omega) in run2 + Configurable decayLengthXicMin{"decayLengthXicMin", -1.f, "Min. decay length of Xic"}; // ... + Configurable dcaBachToPv{"dcaBachToPv", 0.03f, "DCA Bach To PV"}; // 0.04 in run2 + Configurable dcaV0ToPv{"dcaV0ToPv", 0.02f, "DCA V0 To PV"}; // 0.03 in run2 + Configurable v0CosPA{"v0CosPA", 0.95, "V0 CosPA"}; // 0.97 in run2 - KEEP LOSE to re-cut after PVRefit! - double -> N.B. dcos(x)/dx = 0 at x=0) + Configurable cascCosPA{"cascCosPA", 0.95, "Casc CosPA"}; // 0.97 in run2 - KEEP LOSE to re-cut after PVRefit! - double -> N.B. dcos(x)/dx = 0 at x=0) + Configurable xicCosPA{"xicCosPA", 0.95, "Xic CosPA"}; // ... + Configurable dcaV0Dau{"dcaV0Dau", 2.f, "DCA V0 Daughters"}; // conservative, a cut ar 1.0 should also be fine + Configurable dcaCascDau{"dcaCascDau", 2.f, "DCA Casc Daughters"}; // conservative, a cut ar 1.0 should also be fine + Configurable dcaNegToPv{"dcaNegToPv", 0.05f, "DCA Neg To PV"}; // 0.06 in run2 + Configurable dcaPosToPv{"dcaPosToPv", 0.05f, "DCA Pos To PV"}; // 0.06 in run2 + Configurable v0MassWindow{"v0MassWindow", 0.01f, "V0 mass window"}; // 0.008 in run2 + Configurable cascadeMassWindow{"cascadeMassWindow", 0.01f, "Cascade mass window"}; // magnetic field setting from CCDB Configurable isRun2{"isRun2", false, "enable Run 2 or Run 3 GRP objects for magnetic field"}; @@ -3367,7 +3347,6 @@ struct HfTrackIndexSkimCreatorLfCascades { } config; o2::vertexing::DCAFitterN<2> df2; // 2-prong vertex fitter - o2::vertexing::DCAFitterN<3> df3; // 3-prong vertex fitter Service ccdb; o2::base::MatLayerCylSet* lut; o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; @@ -3379,20 +3358,12 @@ struct HfTrackIndexSkimCreatorLfCascades { std::array, kN2ProngDecays> arrMass2Prong; std::array, kN3ProngDecays> arrMass3Prong; - // PDG masses - double massP{0.}; - double massPi{0.}; - double massKaon{0.}; - double massXi{0.}; - double massOmega{0.}; - double massLambda{0.}; - using SelectedCollisions = soa::Filtered>; using SelectedHfTrackAssoc = soa::Filtered>; using CascFull = soa::Join; using V0Full = soa::Join; - Filter filterSelectCollisions = (aod::hf_sel_collision::whyRejectColl == static_cast(0)); + Filter filterSelectCollisions = (aod::hf_sel_collision::whyRejectColl == static_cast(0)); Filter filterSelectTrackIds = (aod::hf_sel_track::isSelProng & static_cast(BIT(CandidateType::CandCascadeBachelor))) != 0u; Preslice tracksPerCollision = aod::track::collisionId; // needed for PV refit @@ -3408,17 +3379,10 @@ struct HfTrackIndexSkimCreatorLfCascades { return; } - massP = o2::constants::physics::MassProton; - massPi = o2::constants::physics::MassPiPlus; - massKaon = o2::constants::physics::MassKPlus; - massXi = o2::constants::physics::MassXiMinus; - massOmega = o2::constants::physics::MassOmegaMinus; - massLambda = o2::constants::physics::MassLambda0; - - arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi] = std::array{massXi, massPi}; - arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi] = std::array{massOmega, massPi}; - arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK] = std::array{massOmega, massKaon}; - arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi] = std::array{massXi, massPi, massPi}; + arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi] = std::array{MassXiMinus, MassPiPlus}; + arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi] = std::array{MassOmegaMinus, MassPiPlus}; + arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK] = std::array{MassOmegaMinus, MassKPlus}; + arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi] = std::array{MassXiMinus, MassPiPlus, MassPiPlus}; df2.setPropagateToPCA(config.propagateToPCA); df2.setMaxR(config.maxR); @@ -3428,14 +3392,6 @@ struct HfTrackIndexSkimCreatorLfCascades { df2.setUseAbsDCA(config.useAbsDCA); df2.setWeightedFinalPCA(config.useWeightedFinalPCA); - df3.setPropagateToPCA(config.propagateToPCA); - df3.setMaxR(config.maxR); - df3.setMaxDZIni(config.maxDZIni); - df3.setMinParamChange(config.minParamChange); - df3.setMinRelChi2Change(config.minRelChi2Change); - df3.setUseAbsDCA(config.useAbsDCA); - df3.setWeightedFinalPCA(config.useWeightedFinalPCA); - ccdb->setURL(config.ccdbUrl); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); @@ -3493,7 +3449,7 @@ struct HfTrackIndexSkimCreatorLfCascades { /// Single-cascade cuts template - bool isPreselectedCascade(const TCascade& casc, const float& pvx, const float& pvy, const float& pvz) + bool isPreselectedCascade(const TCascade& casc, const float pvx, const float pvy, const float pvz) { registry.fill(HIST("hCandidateCounter"), 2.5); @@ -3507,7 +3463,7 @@ struct HfTrackIndexSkimCreatorLfCascades { std::abs(casc.dcav0topv(pvx, pvy, pvz)) > config.dcaV0ToPv && casc.v0radius() > config.v0TransvRadius && casc.cascradius() > config.cascTransvRadius && - std::abs(casc.mLambda() - massLambda) < config.v0MassWindow) { + std::abs(casc.mLambda() - MassLambda0) < config.v0MassWindow) { registry.fill(HIST("hCandidateCounter"), 3.5); // pass cascade selections @@ -3537,6 +3493,71 @@ struct HfTrackIndexSkimCreatorLfCascades { return false; } + /// Method to perform selections for Xic 3-prong candidates before vertex reconstruction + /// \param pVecXi is the momentum array of the Xi daughter track + /// \param pVecPi1 is the momentum array of the first pion daughter track + /// \param pVecPi2 is the momentum array of the second pion daughter track + /// \return selection outcome + template + bool isPreselectedCandidateXic(T1 const& pVecXi, T1 const& pVecPi1, T1 const& pVecPi2) + { + // pt + if (config.ptMinXicplusLfCasc > 0.f) { + const auto pt = RecoDecay::pt(pVecXi, pVecPi1, pVecPi2) + config.ptTolerance; // add tolerance because of no reco decay vertex + if (pt < config.ptMinXicplusLfCasc) { + return false; + } + } + + // invariant mass + if (config.massXiPiPiMin >= 0.f && config.massXiPiPiMax > 0.f) { + const double invMassMin = config.massXiPiPiMin; + const double invMassMax = config.massXiPiPiMax; + const std::array arrMom{pVecXi, pVecPi1, pVecPi2}; + const auto invMass2 = RecoDecay::m2(arrMom, arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi]); + if (invMass2 < invMassMin * invMassMin || invMass2 >= invMassMax * invMassMax) { + return false; + } + } + + return true; + } + + /// Method to perform selections for Xic 3-prong candidates after vertex reconstruction + /// \param pVecCand is the momentum array of the candidate after the reconstruction of the secondary vertex + /// \param secVtx is the secondary vertex + /// \param primVtx is the primary vertex + /// \return selection outcome + template + bool isSelectedCandidateXic(const T1& pVecCand, const T2& secVtx, const T3& primVtx) + { + // pt + if (config.ptMinXicplusLfCasc > 0.f) { + const auto pt = RecoDecay::pt(pVecCand); + if (pt < config.ptMinXicplusLfCasc) { + return false; + } + } + + // CPA + if (config.xicCosPA > -1.f) { + const auto cpa = RecoDecay::cpa(primVtx, secVtx, pVecCand); + if (cpa < config.xicCosPA) { + return false; + } + } + + // decay length + if (config.decayLengthXicMin > 0.f) { + const auto decayLength = RecoDecay::distance(primVtx, secVtx); + if (decayLength < config.decayLengthXicMin) { + return false; + } + } + + return true; + } + void processNoLfCascades(SelectedCollisions const&) { // dummy @@ -3557,19 +3578,16 @@ struct HfTrackIndexSkimCreatorLfCascades { for (const auto& collision : collisions) { // set the magnetic field from CCDB - auto bc = collision.bc_as(); + const auto bc = collision.bc_as(); initCCDB(bc, runNumber, ccdb, config.isRun2 ? config.ccdbPathGrp : config.ccdbPathGrpMag, lut, config.isRun2); - auto magneticField = o2::base::Propagator::Instance()->getNominalBz(); // z component + const auto magneticField = o2::base::Propagator::Instance()->getNominalBz(); // z component df2.setBz(magneticField); df2.setRefitWithMatCorr(config.refitWithMatCorr); - df3.setBz(magneticField); - df3.setRefitWithMatCorr(config.refitWithMatCorr); - // cascade loop - auto thisCollId = collision.globalIndex(); - auto groupedCascades = cascades.sliceBy(cascadesPerCollision, thisCollId); + const auto thisCollId = collision.globalIndex(); + const auto groupedCascades = cascades.sliceBy(cascadesPerCollision, thisCollId); for (const auto& casc : groupedCascades) { @@ -3577,11 +3595,11 @@ struct HfTrackIndexSkimCreatorLfCascades { //----------------accessing particles in the decay chain------------- // cascade daughter - charged particle - auto trackCascDauCharged = casc.bachelor_as(); // meson <- xi track + const auto trackCascDauCharged = casc.bachelor_as(); // meson <- xi track // cascade daughter - V0 - auto trackV0PosDau = casc.posTrack_as(); // p <- V0 track (positive track) 0 + const auto trackV0PosDau = casc.posTrack_as(); // p <- V0 track (positive track) 0 // V0 negative daughter - auto trackV0NegDau = casc.negTrack_as(); // pion <- V0 track (negative track) 1 + const auto trackV0NegDau = casc.negTrack_as(); // pion <- V0 track (negative track) 1 // check that particles come from the same collision if (config.rejDiffCollTrack) { @@ -3601,8 +3619,8 @@ struct HfTrackIndexSkimCreatorLfCascades { continue; } - std::array vertexCasc = {casc.x(), casc.y(), casc.z()}; - std::array pVecCasc = {casc.px(), casc.py(), casc.pz()}; + const std::array vertexCasc = {casc.x(), casc.y(), casc.z()}; + const std::array pVecCasc = {casc.px(), casc.py(), casc.pz()}; std::array covCasc = {0.}; constexpr int MomInd[6] = {9, 13, 14, 18, 19, 20}; // cov matrix elements for momentum component for (int i = 0; i < 6; i++) { @@ -3610,30 +3628,30 @@ struct HfTrackIndexSkimCreatorLfCascades { covCasc[i] = casc.positionCovMat()[i]; } // create cascade track - o2::track::TrackParCov trackCascXi; + o2::track::TrackParCov trackParCovCascXi; if (trackCascDauCharged.sign() > 0) { - trackCascXi = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, 1, true); + trackParCovCascXi = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, 1, true); } else if (trackCascDauCharged.sign() < 0) { - trackCascXi = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, -1, true); + trackParCovCascXi = o2::track::TrackParCov(vertexCasc, pVecCasc, covCasc, -1, true); } else { continue; } - trackCascXi.setAbsCharge(1); + trackParCovCascXi.setAbsCharge(1); - auto trackCascOmega = trackCascXi; + auto trackParCovCascOmega = trackParCovCascXi; - trackCascXi.setPID(o2::track::PID::XiMinus); - trackCascOmega.setPID(o2::track::PID::OmegaMinus); + trackParCovCascXi.setPID(o2::track::PID::XiMinus); + trackParCovCascOmega.setPID(o2::track::PID::OmegaMinus); //--------------combining cascade and pion tracks-------------- - auto groupedBachTrackIndices = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + const auto groupedBachTrackIndices = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); for (auto trackIdCharmBachelor1 = groupedBachTrackIndices.begin(); trackIdCharmBachelor1 != groupedBachTrackIndices.end(); ++trackIdCharmBachelor1) { hfFlag = 0; isGoogForXi2Prong = true; isGoogForOmega2Prong = true; - auto trackCharmBachelor1 = trackIdCharmBachelor1.track_as(); + const auto trackCharmBachelor1 = trackIdCharmBachelor1.track_as(); if ((config.rejDiffCollTrack) && (trackCascDauCharged.collisionId() != trackCharmBachelor1.collisionId())) { continue; @@ -3650,12 +3668,12 @@ struct HfTrackIndexSkimCreatorLfCascades { } // primary pion track to be processed with DCAFitter - auto trackParVarCharmBachelor1 = getTrackParCov(trackCharmBachelor1); + const auto trackParCovCharmBachelor1 = getTrackParCov(trackCharmBachelor1); // find charm baryon decay using xi PID hypothesis (xi pi channel) int nVtxFrom2ProngFitterXiHyp = 0; try { - nVtxFrom2ProngFitterXiHyp = df2.process(trackCascXi, trackParVarCharmBachelor1); + nVtxFrom2ProngFitterXiHyp = df2.process(trackParCovCascXi, trackParCovCharmBachelor1); } catch (...) { if (config.fillHistograms) { registry.fill(HIST("hFitterStatusXi2Prong"), 1); @@ -3680,7 +3698,7 @@ struct HfTrackIndexSkimCreatorLfCascades { std::array, 2> arrMomToXi = {pVecXi, pVecPion1XiHyp}; auto mass2ProngXiHyp = RecoDecay::m(arrMomToXi, arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi]); - if ((std::abs(casc.mXi() - massXi) < config.cascadeMassWindow) && (mass2ProngXiHyp >= config.massXiPiMin) && (mass2ProngXiHyp <= config.massXiPiMax)) { + if ((std::abs(casc.mXi() - MassXiMinus) < config.cascadeMassWindow) && (mass2ProngXiHyp >= config.massXiPiMin) && (mass2ProngXiHyp <= config.massXiPiMax)) { registry.fill(HIST("hRejpTStatusXicZeroOmegacZeroToXiPi"), 0); if (ptXic >= config.ptMinXicZeroOmegacZeroToXiPiLfCasc) { SETBIT(hfFlag, aod::hf_cand_casc_lf::DecayType2Prong::XiczeroOmegaczeroToXiPi); @@ -3701,7 +3719,7 @@ struct HfTrackIndexSkimCreatorLfCascades { // find charm baryon decay using omega PID hypothesis to be combined with the charm bachelor (either pion or kaon) int nVtxFrom2ProngFitterOmegaHyp = 0; try { - nVtxFrom2ProngFitterOmegaHyp = df2.process(trackCascOmega, trackParVarCharmBachelor1); + nVtxFrom2ProngFitterOmegaHyp = df2.process(trackParCovCascOmega, trackParCovCharmBachelor1); } catch (...) { if (config.fillHistograms) { registry.fill(HIST("hFitterStatusOmega2Prong"), 1); @@ -3728,7 +3746,7 @@ struct HfTrackIndexSkimCreatorLfCascades { auto mass2ProngOmegaPiHyp = RecoDecay::m(arrMomToOmega, arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaPi]); auto mass2ProngOmegaKHyp = RecoDecay::m(arrMomToOmega, arrMass2Prong[hf_cand_casc_lf::DecayType2Prong::OmegaczeroToOmegaK]); - if (std::abs(casc.mOmega() - massOmega) < config.cascadeMassWindow) { + if (std::abs(casc.mOmega() - MassOmegaMinus) < config.cascadeMassWindow) { if ((mass2ProngOmegaPiHyp >= config.massOmegaCharmBachelorMin) && (mass2ProngOmegaPiHyp <= config.massOmegaCharmBachelorMax)) { registry.fill(HIST("hRejpTStatusOmegacZeroToOmegaPi"), 0); if (ptOmegac >= config.ptMinOmegacZeroToOmegaPiLfCasc) { @@ -3769,19 +3787,21 @@ struct HfTrackIndexSkimCreatorLfCascades { hfFlag); } - // first loop over tracks + // Xic -> Xi pi pi if (config.do3Prong) { + // Xi mass cut + if (std::abs(casc.mXi() - MassXiMinus) > config.cascadeMassWindow) { + continue; + } - // second loop over positive tracks + // second loop over tracks for (auto trackIdCharmBachelor2 = trackIdCharmBachelor1 + 1; trackIdCharmBachelor2 != groupedBachTrackIndices.end(); ++trackIdCharmBachelor2) { - hfFlag = 0; - if (!TESTBIT(trackIdCharmBachelor2.isSelProng(), CandidateType::CandCascadeBachelor)) { continue; } - auto trackCharmBachelor2 = trackIdCharmBachelor2.track_as(); + const auto trackCharmBachelor2 = trackIdCharmBachelor2.track_as(); if ((config.rejDiffCollTrack) && (trackCascDauCharged.collisionId() != trackCharmBachelor2.collisionId())) { continue; @@ -3797,13 +3817,16 @@ struct HfTrackIndexSkimCreatorLfCascades { continue; } - // primary pion track to be processed with DCAFitter - auto trackParVarPion2 = getTrackParCov(trackCharmBachelor2); + if (!isPreselectedCandidateXic(pVecCasc, trackCharmBachelor1.pVector(), trackCharmBachelor2.pVector())) { + continue; + } // reconstruct Xic with DCAFitter + // Use only bachelor tracks for vertex reconstruction because the Xi track has large uncertainties. int nVtxFrom3ProngFitterXiHyp = 0; try { - nVtxFrom3ProngFitterXiHyp = df3.process(trackCascXi, trackParVarCharmBachelor1, trackParVarPion2); + const auto trackParCovCharmBachelor2 = getTrackParCov(trackCharmBachelor2); + nVtxFrom3ProngFitterXiHyp = df2.process(trackParCovCharmBachelor1, trackParCovCharmBachelor2); } catch (...) { if (config.fillHistograms) { registry.fill(HIST("hFitterStatusXi3Prong"), 1); @@ -3815,48 +3838,44 @@ struct HfTrackIndexSkimCreatorLfCascades { } if (nVtxFrom3ProngFitterXiHyp > 0) { + df2.propagateTracksToVertex(); + if (df2.isPropagateTracksToVertexDone()) { + std::array pVecPi1{}; + std::array pVecPi2{}; + // get bachelor momenta at the Xic vertex + df2.getTrack(0).getPxPyPzGlo(pVecPi1); + df2.getTrack(1).getPxPyPzGlo(pVecPi2); + const auto pVecCand = RecoDecay::pVec(pVecCasc, pVecPi1, pVecPi2); + const auto ptCand = RecoDecay::pt(pVecCand); + const std::array primaryVertex{collision.posX(), collision.posY(), collision.posZ()}; // primary vertex + const auto& secondaryVertex = df2.getPCACandidate(); // secondary vertex + + registry.fill(HIST("hRejpTStatusXicPlusToXiPiPi"), 0); + if (ptCand >= config.ptMinXicplusLfCasc) { + registry.fill(HIST("hRejpTStatusXicPlusToXiPiPi"), 1); + } - df3.propagateTracksToVertex(); - - if (df3.isPropagateTracksToVertexDone()) { - - std::array pVec1 = {0.}; - std::array pVec2 = {0.}; - std::array pVec3 = {0.}; - df3.getTrack(0).getPxPyPzGlo(pVec1); // take the momentum at the Xic vertex - df3.getTrack(1).getPxPyPzGlo(pVec2); - df3.getTrack(2).getPxPyPzGlo(pVec3); - float ptXic3Prong = RecoDecay::pt(pVec1, pVec2, pVec3); - - std::array, 3> arr3Mom = {pVec1, pVec2, pVec3}; - auto mass3Prong = RecoDecay::m(arr3Mom, arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi]); - - if ((std::abs(casc.mXi() - massXi) < config.cascadeMassWindow) && (mass3Prong >= config.massXiPiPiMin) && (mass3Prong <= config.massXiPiPiMax)) { - registry.fill(HIST("hRejpTStatusXicPlusToXiPiPi"), 0); - if (ptXic3Prong >= config.ptMinXicplusLfCasc) { - SETBIT(hfFlag, aod::hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi); - registry.fill(HIST("hRejpTStatusXicPlusToXiPiPi"), 1); - } + if (!isSelectedCandidateXic(pVecCand, secondaryVertex, primaryVertex)) { + continue; } // fill histograms - if (config.fillHistograms && (TESTBIT(hfFlag, aod::hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi))) { + if (config.fillHistograms) { + const std::array arr3Mom{pVecCasc, pVecPi1, pVecPi2}; + const auto mass3Prong = RecoDecay::m(arr3Mom, arrMass3Prong[hf_cand_casc_lf::DecayType3Prong::XicplusToXiPiPi]); registry.fill(HIST("hMassXicPlusToXiPiPi"), mass3Prong); - registry.fill(HIST("hPtCutsXicPlusToXiPiPi"), ptXic3Prong); + registry.fill(HIST("hPtCutsXicPlusToXiPiPi"), ptCand); } - } else if (df3.isPropagationFailure()) { + + // fill table row if a vertex was found + rowTrackIndexCasc3Prong(thisCollId, + casc.cascadeId(), + trackCharmBachelor1.globalIndex(), + trackCharmBachelor2.globalIndex()); + } else if (df2.isPropagationFailure()) { LOGF(info, "Exception caught: failed to propagate tracks (3prong) to charm baryon decay vtx"); } } - - // fill table row only if a vertex was found - if (hfFlag != 0) { - rowTrackIndexCasc3Prong(thisCollId, - casc.cascadeId(), - trackCharmBachelor1.globalIndex(), - trackCharmBachelor2.globalIndex()); - } - } // end 3prong loop } // end 3prong condition diff --git a/PWGHF/TableProducer/treeCreatorDplusToPiKPi.cxx b/PWGHF/TableProducer/treeCreatorDplusToPiKPi.cxx index b4baa783675..cc684c7003f 100644 --- a/PWGHF/TableProducer/treeCreatorDplusToPiKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorDplusToPiKPi.cxx @@ -145,6 +145,7 @@ DECLARE_SOA_TABLE(HfCandDpLites, "AOD", "HFCANDDPLITE", full::Phi, full::Y, full::Centrality, + collision::NumContrib, hf_cand_3prong::FlagMcMatchRec, hf_cand_3prong::OriginMcRec, hf_cand_3prong::FlagMcDecayChanRec) @@ -370,6 +371,7 @@ struct HfTreeCreatorDplusToPiKPi { candidate.eta(), candidate.phi(), hfHelper.yDplus(candidate), + coll.numContrib(), cent, flagMc, originMc, diff --git a/PWGHF/TableProducer/treeCreatorOmegacSt.cxx b/PWGHF/TableProducer/treeCreatorOmegacSt.cxx index c291852c448..1bd4466893e 100644 --- a/PWGHF/TableProducer/treeCreatorOmegacSt.cxx +++ b/PWGHF/TableProducer/treeCreatorOmegacSt.cxx @@ -165,6 +165,7 @@ DECLARE_SOA_COLUMN(DecayLengthXYCasc, decayLengthXYCasc, float); DECLARE_SOA_INDEX_COLUMN_FULL(MotherCasc, motherCasc, int, HfStChBarGens, "_Casc"); DECLARE_SOA_INDEX_COLUMN_FULL(MotherPionOrKaon, motherPionOrKaon, int, HfStChBarGens, "_PionOrKaon"); DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int); +DECLARE_SOA_COLUMN(ToiMask, toiMask, uint32_t); } // namespace hf_st_charmed_baryon DECLARE_SOA_TABLE(HfStChBars, "AOD", "HFSTCHBAR", @@ -220,7 +221,8 @@ DECLARE_SOA_TABLE(HfStChBars, "AOD", "HFSTCHBAR", hf_st_charmed_baryon::DecayLengthXYCasc, hf_st_charmed_baryon::MotherCascId, hf_st_charmed_baryon::MotherPionOrKaonId, - hf_st_charmed_baryon::OriginMcRec); + hf_st_charmed_baryon::OriginMcRec, + hf_st_charmed_baryon::ToiMask); } // namespace o2::aod struct HfTreeCreatorOmegacSt { @@ -256,6 +258,7 @@ struct HfTreeCreatorOmegacSt { Configurable maxNSigmaPion{"maxNSigmaPion", 5., "Max Nsigma for pion to be paired with Omega"}; Configurable maxNSigmaKaon{"maxNSigmaKaon", 5., "Max Nsigma for kaon to be paired with Omega"}; Configurable bzOnly{"bzOnly", true, "Use B_z instead of full field map"}; + Configurable cfgTriggersOfInterest{"cfgTriggersOfInterest", "fTrackedOmega,fHfCharmBarToXiBach", "Triggers of interest, comma separated for Zorro"}; const int itsNClsMin = 4; const float tpcNclsFindableFraction = 0.8; @@ -446,7 +449,7 @@ struct HfTreeCreatorOmegacSt { if (runNumber == 0) { zorroSummary.setObject(zorro.getZorroSummary()); } - zorro.initCCDB(ccdb.service, bc.runNumber(), bc.timestamp(), "fTrackedOmega"); + zorro.initCCDB(ccdb.service, bc.runNumber(), bc.timestamp(), cfgTriggersOfInterest.value); zorro.populateHistRegistry(registry, bc.runNumber()); } runNumber = bc.runNumber(); @@ -463,8 +466,15 @@ struct HfTreeCreatorOmegacSt { } df2.setBz(bz); } + uint32_t toiMask = 0; if (skimmedProcessing) { - zorro.isSelected(collision.bc().globalBC()); + bool sel = zorro.isSelected(bc.globalBC()); + if (sel) { + std::vector toivect = zorro.getTriggerOfInterestResults(); + for (size_t i{0}; i < toivect.size(); i++) { + toiMask |= static_cast(toivect[i]) << i; + } + } } const auto primaryVertex = getPrimaryVertex(collision); @@ -770,7 +780,8 @@ struct HfTreeCreatorOmegacSt { decayLengthCascXY, trackCascMotherId, trackMotherId, - origin); + origin, + toiMask); } } else { continue; diff --git a/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx b/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx index 52a12a02b91..ca2f34ae5d3 100644 --- a/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx +++ b/PWGHF/TableProducer/treeCreatorXicToXiPiPi.cxx @@ -334,7 +334,8 @@ DECLARE_SOA_TABLE(HfCandXicToXiPiPiFullPs, "AOD", "HFXICXI2PIFULLP", full::Pt, full::Eta, full::Phi, - full::Y); + full::Y, + hf_cand_xic_to_xi_pi_pi::DecayLengthMcGen); } // namespace o2::aod /// Writes the full information in an output TTree @@ -723,7 +724,8 @@ struct HfTreeCreatorXicToXiPiPi { particle.pt(), particle.eta(), particle.phi(), - RecoDecay::y(particle.pVector(), o2::constants::physics::MassXiCPlus)); + RecoDecay::y(particle.pVector(), o2::constants::physics::MassXiCPlus), + particle.decayLengthMcGen()); } } } @@ -776,7 +778,8 @@ struct HfTreeCreatorXicToXiPiPi { particle.pt(), particle.eta(), particle.phi(), - RecoDecay::y(particle.pVector(), o2::constants::physics::MassXiCPlus)); + RecoDecay::y(particle.pVector(), o2::constants::physics::MassXiCPlus), + particle.decayLengthMcGen()); } } } diff --git a/PWGHF/Tasks/taskCharmHadImpactPar.cxx b/PWGHF/Tasks/taskCharmHadImpactPar.cxx index 3000d5bf8c5..01c838df129 100644 --- a/PWGHF/Tasks/taskCharmHadImpactPar.cxx +++ b/PWGHF/Tasks/taskCharmHadImpactPar.cxx @@ -269,13 +269,13 @@ struct HfTaskCharmHadImpactPar { } } } - float centrality = 0.; - float occupancy = 0.; + float centrality = 0.f; + float occupancy = 0.f; if (centEstimator != CentralityEstimator::None) { centrality = getCentralityColl(collision, centEstimator); } if (occEstimator != OccupancyEstimator::None) { - occupancy = getOccupancyColl(collision, occEstimator); + occupancy = o2::hf_occupancy::getOccupancyColl(collision, occEstimator); } int8_t flagMcMatchRec = 0; diff --git a/PWGHF/Tasks/taskMcValidation.cxx b/PWGHF/Tasks/taskMcValidation.cxx index 97b57f150bc..8cf7ea7d0ce 100644 --- a/PWGHF/Tasks/taskMcValidation.cxx +++ b/PWGHF/Tasks/taskMcValidation.cxx @@ -283,11 +283,11 @@ struct HfTaskMcValidationGen { // Slice the collisions table to get the collision info for the current MC collision float centrality{105.f}; - int occupancy = 0; + float occupancy{0.f}; if (storeOccupancy) { - occupancy = getOccupancyGenColl(recoCollisions, OccupancyEstimator::Its); + occupancy = o2::hf_occupancy::getOccupancyGenColl(recoCollisions, OccupancyEstimator::Its); } - uint32_t rejectionMask{0u}; + o2::hf_evsel::HfCollisionRejectionMask rejectionMask{}; if constexpr (centEstimator == CentralityEstimator::FT0C) { rejectionMask = hfEvSelMc.getHfMcCollisionRejectionMask(mcCollision, recoCollisions, centrality); } else if constexpr (centEstimator == CentralityEstimator::FT0M) { diff --git a/PWGHF/Utils/utilsAnalysis.h b/PWGHF/Utils/utilsAnalysis.h index 7a2c2f45d0a..d5879647f94 100644 --- a/PWGHF/Utils/utilsAnalysis.h +++ b/PWGHF/Utils/utilsAnalysis.h @@ -35,7 +35,7 @@ enum BHadMothers { NotMatched = 0, LambdaBZero }; /// Convert the B hadron mother PDG for non prompt candidates to a flag -/// \param pdg of the b hadron mother +/// \param flagBHad pdg of the b hadron mother /// \return integer map to specific mothers' PDG codes BHadMothers getBHadMotherFlag(const int flagBHad) { @@ -54,21 +54,21 @@ BHadMothers getBHadMotherFlag(const int flagBHad) return BHadMothers::NotMatched; } -/// Finds pT bin in an array. -/// \param bins array of pT bins -/// \param value pT +/// Finds bin in an array that contains a value. +/// \param bins array of bins +/// \param value value to find /// \return index of the pT bin /// \note Accounts for the offset so that pT bin array can be used to also configure a histogram axis. -template -int findBin(T1 const& binsPt, T2 value) +template +int findBin(TArrayPt const& bins, TNumber const value) { - if (value < binsPt->front()) { + if (value < bins->front()) { return -1; } - if (value >= binsPt->back()) { + if (value >= bins->back()) { return -1; } - return std::distance(binsPt->begin(), std::upper_bound(binsPt->begin(), binsPt->end(), value)) - 1; + return std::distance(bins->begin(), std::upper_bound(bins->begin(), bins->end(), value)) - 1; } /// Single-track cut on DCAxy and DCAz @@ -78,8 +78,12 @@ int findBin(T1 const& binsPt, T2 value) /// \param dcaXY is the prong dcaXY /// \param dcaZ is the prong dcaZ /// \return true if track passes all cuts -template -bool isSelectedTrackDca(T1 const& binsPt, T2 const& cuts, const float pt, const float dcaXY, const float dcaZ) +template +bool isSelectedTrackDca(TArrayPt const& binsPt, + TArrayCuts const& cuts, + const float pt, + const float dcaXY, + const float dcaZ) { auto binPt = findBin(binsPt, pt); if (binPt == -1) { @@ -105,8 +109,10 @@ bool isSelectedTrackDca(T1 const& binsPt, T2 const& cuts, const float pt, const /// \param itsNClustersFoundMin is the minimum number of ITS clusters /// \param itsChi2PerClusterMax is the maximum value of chi2 fit over ITS clusters /// \return true if track passes all cuts -template -bool isSelectedTrackItsQuality(T const& track, const int itsNClustersFoundMin, const float itsChi2PerClusterMax) +template +bool isSelectedTrackItsQuality(TTrack const& track, + const int itsNClustersFoundMin, + const float itsChi2PerClusterMax) { if (track.itsNCls() < itsNClustersFoundMin) { return false; @@ -124,8 +130,12 @@ bool isSelectedTrackItsQuality(T const& track, const int itsNClustersFoundMin, c /// \param tpcNCrossedRowsOverFindableClustersMin is the minimum of TPC CrossedRows/FindableClusters value /// \param tpcChi2PerClusterMax is the maximum value of chi2 fit over TPC clusters /// \return true if track passes all cuts -template -bool isSelectedTrackTpcQuality(T const& track, const int tpcNClustersFoundMin, const int tpcNCrossedRowsMin, const float tpcNCrossedRowsOverFindableClustersMin, const float tpcChi2PerClusterMax) +template +bool isSelectedTrackTpcQuality(TTrack const& track, + const int tpcNClustersFoundMin, + const int tpcNCrossedRowsMin, + const float tpcNCrossedRowsOverFindableClustersMin, + const float tpcChi2PerClusterMax) { if (track.tpcNClsFound() < tpcNClustersFoundMin) { return false; @@ -142,7 +152,7 @@ bool isSelectedTrackTpcQuality(T const& track, const int tpcNClustersFoundMin, c return true; } -/// Mass selection of 2 or 3 prong canidates in triggered data analysis +/// Mass selection of 2 or 3 prong candidates in triggered data analysis /// \tparam nProngs switch between 2-prong and 3-prong selection /// \param invMass is the invariant mass of the candidate /// \param pdgMass is the pdg Mass of the candidate particle @@ -150,10 +160,13 @@ bool isSelectedTrackTpcQuality(T const& track, const int tpcNClustersFoundMin, c /// \param cutConfig is the struct with the pt-dependent mass configurations /// \return true if candidate passes selection template -bool isCandidateInMassRange(const float& invMass, const double& pdgMass, const float& pt, Config const& cutConfig) +bool isCandidateInMassRange(const float invMass, + const double pdgMass, + const float pt, + Config const& cutConfig) { - float peakMean = (pt < cutConfig.ptDeltaMassMax.value) ? ((pdgMass + cutConfig.deltaMassPars->get("constant")) + cutConfig.deltaMassPars->get("linear") * pt) : pdgMass; - float peakWidth = cutConfig.sigmaPars->get("constant") + cutConfig.sigmaPars->get("linear") * pt; + const float peakMean = (pt < cutConfig.ptDeltaMassMax.value) ? ((pdgMass + cutConfig.deltaMassPars->get("constant")) + cutConfig.deltaMassPars->get("linear") * pt) : pdgMass; + const float peakWidth = cutConfig.sigmaPars->get("constant") + cutConfig.sigmaPars->get("linear") * pt; return (!(std::abs(invMass - peakMean) > cutConfig.nSigmaMax.value * peakWidth && pt < cutConfig.ptMassCutMax.value)); } @@ -164,9 +177,9 @@ struct HfTrigger2ProngCuts : o2::framework::ConfigurableGroup { static constexpr float DefaultDeltaMassPars[1][2] = {{-0.0025f, 0.0001f}}; static constexpr float DefaultSigmaPars[1][2] = {{0.01424f, 0.00178f}}; - o2::framework::Configurable nSigmaMax{"nSigmaMax", 2, "Maximum number of sigmas for pT-differential mass cut for 2-prong candidates"}; - o2::framework::Configurable ptDeltaMassMax{"ptDeltaMassMax", 10., "Max pT to apply delta mass shift to PDG mass value for 2-prong candidates"}; - o2::framework::Configurable ptMassCutMax{"ptMassCutMax", 9999., "Max pT to apply pT-differential cut for 2-prong candidates"}; + o2::framework::Configurable nSigmaMax{"nSigmaMax", 2.f, "Maximum number of sigmas for pT-differential mass cut for 2-prong candidates"}; + o2::framework::Configurable ptDeltaMassMax{"ptDeltaMassMax", 10.f, "Max pT to apply delta mass shift to PDG mass value for 2-prong candidates"}; + o2::framework::Configurable ptMassCutMax{"ptMassCutMax", 9999.f, "Max pT to apply pT-differential cut for 2-prong candidates"}; o2::framework::Configurable> deltaMassPars{"deltaMassPars", {DefaultDeltaMassPars[0], 2, {"constant", "linear"}}, "delta mass parameters for HF 2-prong trigger mass cut"}; o2::framework::Configurable> sigmaPars{"sigmaPars", {DefaultSigmaPars[0], 2, {"constant", "linear"}}, "sigma parameters for HF 2-prong trigger mass cut"}; }; @@ -178,8 +191,8 @@ struct HfTrigger3ProngCuts : o2::framework::ConfigurableGroup { static constexpr float DefaultDeltaMassPars[1][2] = {{-0.0025f, 0.0001f}}; static constexpr float DefaultSigmaPars[1][2] = {{0.00796f, 0.00176f}}; o2::framework::Configurable nSigmaMax{"nSigmaMax", 2, "Maximum number of sigmas for pT-differential mass cut for 3-prong candidates"}; - o2::framework::Configurable ptDeltaMassMax{"ptDeltaMassMax", 10., "Max pT to apply delta mass shift to PDG mass value for 3-prong candidates"}; - o2::framework::Configurable ptMassCutMax{"ptMassCutMax", 9999., "Max pT to apply pT-differential cut for 3-prong candidates"}; + o2::framework::Configurable ptDeltaMassMax{"ptDeltaMassMax", 10.f, "Max pT to apply delta mass shift to PDG mass value for 3-prong candidates"}; + o2::framework::Configurable ptMassCutMax{"ptMassCutMax", 9999.f, "Max pT to apply pT-differential cut for 3-prong candidates"}; o2::framework::Configurable> deltaMassPars{"deltaMassPars", {DefaultDeltaMassPars[0], 2, {"constant", "linear"}}, "delta mass parameters for HF 3-prong trigger mass cut"}; o2::framework::Configurable> sigmaPars{"sigmaPars", {DefaultSigmaPars[0], 2, {"constant", "linear"}}, "sigma parameters for HF 3-prong trigger mass cut"}; }; diff --git a/PWGHF/Utils/utilsBfieldCCDB.h b/PWGHF/Utils/utilsBfieldCCDB.h index 8d7166eca4a..d14203161e4 100644 --- a/PWGHF/Utils/utilsBfieldCCDB.h +++ b/PWGHF/Utils/utilsBfieldCCDB.h @@ -34,9 +34,12 @@ /// \param lut is a pointer to the o2::base::MatLayerCylSet object /// \param isRun2 tells whether we are analysing Run2 converted data or not (different GRP object type) template -void initCCDB(TBc const& bc, int& mRunNumber, - o2::framework::Service const& ccdb, std::string const& ccdbPathGrp, o2::base::MatLayerCylSet* lut, - bool isRun2) +void initCCDB(TBc const& bc, + int& mRunNumber, + o2::framework::Service const& ccdb, + std::string const& ccdbPathGrp, + o2::base::MatLayerCylSet* lut, + const bool isRun2) { if (mRunNumber != bc.runNumber()) { LOGF(info, "====== initCCDB function called (isRun2==%d)", isRun2); diff --git a/PWGHF/Utils/utilsDerivedData.h b/PWGHF/Utils/utilsDerivedData.h index 044abed2f90..4a08d37d535 100644 --- a/PWGHF/Utils/utilsDerivedData.h +++ b/PWGHF/Utils/utilsDerivedData.h @@ -39,8 +39,10 @@ namespace o2::analysis::hf_derived /// \param cursor cursor of the filled table /// \param enabled switch for filling the table /// \param size size of the source table -template -void reserveTable(T& cursor, const o2::framework::Configurable& enabled, const uint64_t size) +template +void reserveTable(TCursor& cursor, + const o2::framework::Configurable& enabled, + const uint64_t size) { if (enabled.value) { cursor.reserve(size); @@ -94,36 +96,34 @@ struct HfProducesDerivedData : o2::framework::ProducesGroup { conf = &c; } - template - void reserveTablesCandidates(T size) + void reserveTablesCandidates(const uint64_t size) { o2::analysis::hf_derived::reserveTable(rowCandidateBase, conf->fillCandidateBase, size); } - template - void reserveTablesColl(T size) + void reserveTablesColl(const uint64_t size) { o2::analysis::hf_derived::reserveTable(rowCollBase, conf->fillCollBase, size); o2::analysis::hf_derived::reserveTable(rowCollId, conf->fillCollId, size); } - template - void reserveTablesMcColl(T size) + void reserveTablesMcColl(const uint64_t size) { o2::analysis::hf_derived::reserveTable(rowMcCollBase, conf->fillMcCollBase, size); o2::analysis::hf_derived::reserveTable(rowMcCollId, conf->fillMcCollId, size); o2::analysis::hf_derived::reserveTable(rowMcRCollId, conf->fillMcRCollId, size); } - template - void reserveTablesParticles(T size) + void reserveTablesParticles(const uint64_t size) { o2::analysis::hf_derived::reserveTable(rowParticleBase, conf->fillParticleBase, size); o2::analysis::hf_derived::reserveTable(rowParticleId, conf->fillParticleId, size); } - template - void fillTablesCandidate(const T& candidate, double invMass, double y) + template + void fillTablesCandidate(const TCandidate& candidate, + const double invMass, + const double y) { if (conf->fillCandidateBase.value) { rowCandidateBase( @@ -136,9 +136,8 @@ struct HfProducesDerivedData : o2::framework::ProducesGroup { } } - template - // void fillTablesCollision(const T& collision, int isEventReject, int runNumber) - void fillTablesCollision(const T& collision) + template + void fillTablesCollision(TCollision const& collision) { if (conf->fillCollBase.value) { rowCollBase( @@ -165,8 +164,8 @@ struct HfProducesDerivedData : o2::framework::ProducesGroup { } } - template - void fillTablesMcCollision(const T& mcCollision) + template + void fillTablesMcCollision(TMcCollision const& mcCollision) { if (conf->fillMcCollBase.value) { rowMcCollBase( @@ -186,8 +185,8 @@ struct HfProducesDerivedData : o2::framework::ProducesGroup { } } - template - void fillTablesParticle(const T& particle, U mass) + template + void fillTablesParticle(TMcParticle const& particle, const TMass mass) { if (conf->fillParticleBase.value) { rowParticleBase( @@ -206,10 +205,10 @@ struct HfProducesDerivedData : o2::framework::ProducesGroup { } } - template - void preProcessMcCollisions(CollisionType const& mcCollisions, - o2::framework::Preslice const& mcParticlesPerMcCollision, - ParticleType const& mcParticles) + template + void preProcessMcCollisions(TMcCollisions const& mcCollisions, + o2::framework::Preslice const& mcParticlesPerMcCollision, + TMcParticles const& mcParticles) { if (!conf->fillMcRCollId.value) { return; @@ -217,26 +216,26 @@ struct HfProducesDerivedData : o2::framework::ProducesGroup { hasMcParticles.clear(); // Fill MC collision flags for (const auto& mcCollision : mcCollisions) { - auto thisMcCollId = mcCollision.globalIndex(); - auto particlesThisMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, thisMcCollId); + const auto thisMcCollId = mcCollision.globalIndex(); + const auto particlesThisMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, thisMcCollId); LOGF(debug, "MC collision %d has %d MC particles (preprocess)", thisMcCollId, particlesThisMcColl.size()); hasMcParticles[thisMcCollId] = (particlesThisMcColl.size() > 0); } } - template - void processMcParticles(CollisionType const& mcCollisions, - o2::framework::Preslice const& mcParticlesPerMcCollision, - ParticleType const& mcParticles, - TMass const massParticle) + template + void processMcParticles(TMcCollisions const& mcCollisions, + o2::framework::Preslice const& mcParticlesPerMcCollision, + TMcParticles const& mcParticles, + const TMass massParticle) { // Fill MC collision properties - auto sizeTableMcColl = mcCollisions.size(); + const auto sizeTableMcColl = mcCollisions.size(); reserveTablesMcColl(sizeTableMcColl); for (const auto& mcCollision : mcCollisions) { - auto thisMcCollId = mcCollision.globalIndex(); - auto particlesThisMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, thisMcCollId); - auto sizeTablePart = particlesThisMcColl.size(); + const auto thisMcCollId = mcCollision.globalIndex(); + const auto particlesThisMcColl = mcParticles.sliceBy(mcParticlesPerMcCollision, thisMcCollId); + const auto sizeTablePart = particlesThisMcColl.size(); LOGF(debug, "MC collision %d has %d MC particles", thisMcCollId, sizeTablePart); // Skip MC collisions without HF particles (and without HF candidates in matched reconstructed collisions if saving indices of reconstructed collisions matched to MC collisions) LOGF(debug, "MC collision %d has %d saved derived rec. collisions", thisMcCollId, matchedCollisions[thisMcCollId].size()); diff --git a/PWGHF/Utils/utilsEvSelHf.h b/PWGHF/Utils/utilsEvSelHf.h index 5103d5c4d77..4af173070d5 100644 --- a/PWGHF/Utils/utilsEvSelHf.h +++ b/PWGHF/Utils/utilsEvSelHf.h @@ -55,16 +55,16 @@ enum OccupancyEstimator { None = 0, /// Get the occupancy /// \param collision is the collision with the occupancy information /// \return collision occupancy -template -float getOccupancyColl(Coll const& collision, int occEstimator) +template +float getOccupancyColl(TCollision const& collision, const int occEstimator) { switch (occEstimator) { case OccupancyEstimator::Its: - return collision.trackOccupancyInTimeRange(); + return static_cast(collision.trackOccupancyInTimeRange()); case OccupancyEstimator::Ft0c: - return collision.ft0cOccupancyInTimeRange(); + return static_cast(collision.ft0cOccupancyInTimeRange()); default: - LOG(fatal) << "Occupancy estimator not valid. Possible values are ITS or FT0C."; + LOG(fatal) << "Occupancy estimator not valid. See OccupancyEstimator for valid values."; break; } return -999.f; @@ -73,14 +73,14 @@ float getOccupancyColl(Coll const& collision, int occEstimator) /// \brief Function to get MC collision occupancy /// \param collSlice collection of reconstructed collisions associated to a generated one /// \return generated MC collision occupancy -template -int getOccupancyGenColl(CCs const& collSlice, int occEstimator) +template +float getOccupancyGenColl(TCollisions const& collSlice, const int occEstimator) { - float multiplicity{0.f}; - int occupancy = 0; + using TMult = uint16_t; // type of numContrib + TMult multiplicity{}; + float occupancy{0.f}; for (const auto& collision : collSlice) { - float collMult{0.f}; - collMult = collision.numContrib(); + const TMult collMult = collision.numContrib(); if (collMult > multiplicity) { occupancy = getOccupancyColl(collision, occEstimator); multiplicity = collMult; @@ -115,14 +115,16 @@ enum EventRejection { NEventRejection }; -o2::framework::AxisSpec axisEvents = {EventRejection::NEventRejection, -0.5f, +EventRejection::NEventRejection - 0.5f, ""}; -o2::framework::AxisSpec axisUpcEvents = {o2::aod::sgselector::DoubleGap + 1, -0.5f, +o2::aod::sgselector::DoubleGap + 0.5f, ""}; +using HfCollisionRejectionMask = uint32_t; // 32 bits, in case new ev. selections will be added + +const o2::framework::AxisSpec axisEvents = {EventRejection::NEventRejection, -0.5f, +EventRejection::NEventRejection - 0.5f, ""}; +const o2::framework::AxisSpec axisUpcEvents = {o2::aod::sgselector::DoubleGap + 1, -0.5f, +o2::aod::sgselector::DoubleGap + 0.5f, ""}; /// \brief Function to put labels on monitoring histogram /// \param hRejection monitoring histogram /// \param softwareTriggerLabel bin label for software trigger rejection template -void setEventRejectionLabels(Histo& hRejection, std::string softwareTriggerLabel = "") +void setEventRejectionLabels(Histo& hRejection, std::string const& softwareTriggerLabel = "") { // Puts labels on the collision monitoring histogram. hRejection->GetXaxis()->SetBinLabel(EventRejection::None + 1, "All"); @@ -148,8 +150,8 @@ void setEventRejectionLabels(Histo& hRejection, std::string softwareTriggerLabel struct HfEventSelection : o2::framework::ConfigurableGroup { std::string prefix = "hfEvSel"; // JSON group name // event selection parameters (in chronological order of application) - o2::framework::Configurable centralityMin{"centralityMin", 0., "Minimum centrality"}; - o2::framework::Configurable centralityMax{"centralityMax", 100., "Maximum centrality"}; + o2::framework::Configurable centralityMin{"centralityMin", 0.f, "Minimum centrality"}; + o2::framework::Configurable centralityMax{"centralityMax", 100.f, "Maximum centrality"}; o2::framework::Configurable useSel8Trigger{"useSel8Trigger", true, "Apply the sel8 event selection"}; o2::framework::Configurable triggerClass{"triggerClass", -1, "Trigger class different from sel8 (e.g. kINT7 for Run2) used only if useSel8Trigger is false"}; o2::framework::Configurable useTvxTrigger{"useTvxTrigger", true, "Apply TVX trigger sel"}; @@ -170,7 +172,7 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { o2::framework::Configurable useNoCollInRofStandard{"useNoCollInRofStandard", false, "Reject collisions in ROF standard"}; o2::framework::Configurable softwareTrigger{"softwareTrigger", "", "Label of software trigger. Multiple triggers can be selected dividing them by a comma. Set None if you want bcs that are not selected by any trigger"}; o2::framework::Configurable bcMarginForSoftwareTrigger{"bcMarginForSoftwareTrigger", 100, "Number of BCs of margin for software triggers"}; - o2::framework::Configurable ccdbPathSoftwareTrigger{"ccdbPathSoftwareTrigger", "Users/m/mpuccio/EventFiltering/OTS/Chunked/", "ccdb path for ZORRO objects"}; + o2::framework::Configurable ccdbPathSoftwareTrigger{"ccdbPathSoftwareTrigger", "EventFiltering/Zorro/", "ccdb path for ZORRO objects"}; o2::framework::ConfigurableAxis th2ConfigAxisCent{"th2ConfigAxisCent", {100, 0., 100.}, ""}; o2::framework::ConfigurableAxis th2ConfigAxisOccupancy{"th2ConfigAxisOccupancy", {100, 0, 100000}, ""}; o2::framework::Configurable requireGoodRct{"requireGoodRct", false, "Flag to require good RCT"}; @@ -262,10 +264,13 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { /// \param ccdb ccdb service needed to retrieve the needed info for zorro /// \param registry reference to the histogram registry needed for zorro /// \return bitmask with the event selection criteria not satisfied by the collision - template - uint32_t getHfCollisionRejectionMask(const Coll& collision, float& centrality, o2::framework::Service const& ccdb, o2::framework::HistogramRegistry& registry) + template + HfCollisionRejectionMask getHfCollisionRejectionMask(TCollision const& collision, + float& centrality, + o2::framework::Service const& ccdb, + o2::framework::HistogramRegistry& registry) { - uint32_t rejectionMask{0}; // 32 bits, in case new ev. selections will be added + HfCollisionRejectionMask rejectionMask{}; if constexpr (centEstimator != o2::hf_centrality::CentralityEstimator::None) { centrality = o2::hf_centrality::getCentralityColl(collision, centEstimator); @@ -317,7 +322,7 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { SETBIT(rejectionMask, EventRejection::NoCollInRofStandard); } if (useOccupancyCut) { - float occupancy = o2::hf_occupancy::getOccupancyColl(collision, occEstimator); + const auto occupancy = o2::hf_occupancy::getOccupancyColl(collision, occEstimator); if (occupancy < occupancyMin || occupancy > occupancyMax) { SETBIT(rejectionMask, EventRejection::Occupancy); } @@ -341,9 +346,8 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { if (softwareTrigger.value != "") { // we might have to update it from CCDB - auto bc = collision.template bc_as(); - - int runNumber = bc.runNumber(); + const auto bc = collision.template bc_as(); + const auto runNumber = bc.runNumber(); if (runNumber != currentRun) { // We might need to update Zorro from CCDB if the run number changes zorro.setCCDBpath(ccdbPathSoftwareTrigger); zorro.setBCtolerance(bcMarginForSoftwareTrigger); @@ -366,17 +370,21 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { return rejectionMask; } - template - uint32_t getHfCollisionRejectionMaskWithUpc(const Coll& collision, float& centrality, o2::framework::Service const& ccdb, o2::framework::HistogramRegistry& registry, const BCsType& bcs) + template + HfCollisionRejectionMask getHfCollisionRejectionMaskWithUpc(TCollision const& collision, + float& centrality, + o2::framework::Service const& ccdb, + o2::framework::HistogramRegistry& registry, + TBcs const& bcs) { - auto rejectionMaskWithUpc = getHfCollisionRejectionMask(collision, centrality, ccdb, registry); + auto rejectionMaskWithUpc = getHfCollisionRejectionMask(collision, centrality, ccdb, registry); if (useEvSel) { - SGCutParHolder sgCuts = setSgPreselection(); - auto bc = collision.template foundBC_as(); - auto bcRange = udhelpers::compatibleBCs(collision, sgCuts.NDtcoll(), bcs, sgCuts.minNBCs()); - auto sgSelectionResult = sgSelector.IsSelected(sgCuts, collision, bcRange, bc); - int upcEventType = sgSelectionResult.value; + const SGCutParHolder sgCuts = setSgPreselection(); + const auto bc = collision.template foundBC_as(); + const auto bcRange = udhelpers::compatibleBCs(collision, sgCuts.NDtcoll(), bcs, sgCuts.minNBCs()); + const auto sgSelectionResult = sgSelector.IsSelected(sgCuts, collision, bcRange, bc); + const int upcEventType = sgSelectionResult.value; if (upcEventType > o2::aod::sgselector::DoubleGap) { SETBIT(rejectionMaskWithUpc, EventRejection::UpcEventCut); } else { @@ -390,11 +398,14 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { /// \brief Fills histograms for monitoring event selections satisfied by the collision. /// \param collision analysed collision /// \param rejectionMask bitmask storing the info about which ev. selections are not satisfied by the collision - template - void fillHistograms(Coll const& collision, const uint32_t rejectionMask, float& centrality, float occupancy = -1) + template + void fillHistograms(TCollision const& collision, + const HfCollisionRejectionMask rejectionMask, + const float centrality, + const float occupancy = -1.f) { hCollisions->Fill(EventRejection::None); - const float posZ = collision.posZ(); + const auto posZ = collision.posZ(); hPosZBeforeEvSel->Fill(posZ); for (std::size_t reason = 1; reason < EventRejection::NEventRejection; reason++) { @@ -415,30 +426,31 @@ struct HfEventSelection : o2::framework::ConfigurableGroup { struct HfEventSelectionMc { // event selection parameters (in chronological order of application) - bool useSel8Trigger{false}; // Apply the Sel8 selection - bool useTvxTrigger{false}; // Apply the TVX trigger - bool useTimeFrameBorderCut{true}; // Apply TF border cut - bool useItsRofBorderCut{false}; // Apply the ITS RO frame border cut - float zPvPosMin{-1000.f}; // Minimum PV posZ (cm) - float zPvPosMax{1000.f}; // Maximum PV posZ (cm) - float centralityMin{0.f}; // Minimum centrality - float centralityMax{100.f}; // Maximum centrality - bool requireGoodRct{false}; // Apply RCT selection - std::string rctLabel{""}; // RCT selection flag - bool rctCheckZDC; // require ZDC from RCT - bool rctTreatLimitedAcceptanceAsBad; // RCT flag to reject events with limited acceptance for selected detectors + bool useSel8Trigger{false}; // Apply the Sel8 selection + bool useTvxTrigger{false}; // Apply the TVX trigger + bool useTimeFrameBorderCut{true}; // Apply TF border cut + bool useItsRofBorderCut{false}; // Apply the ITS RO frame border cut + float zPvPosMin{-1000.f}; // Minimum PV posZ (cm) + float zPvPosMax{1000.f}; // Maximum PV posZ (cm) + float centralityMin{0.f}; // Minimum centrality + float centralityMax{100.f}; // Maximum centrality + bool requireGoodRct{false}; // Apply RCT selection + std::string rctLabel{""}; // RCT selection flag + bool rctCheckZDC{false}; // require ZDC from RCT + bool rctTreatLimitedAcceptanceAsBad{false}; // RCT flag to reject events with limited acceptance for selected detectors // util to retrieve the RCT info from CCDB o2::aod::rctsel::RCTFlagsChecker rctChecker; // histogram names static constexpr char NameHistGenCollisionsCent[] = "hGenCollisionsCent"; - std::shared_ptr hGenCollisionsCent; static constexpr char NameHistRecCollisionsCentMc[] = "hRecCollisionsCentMc"; - std::shared_ptr hRecCollisionsCentMc; static constexpr char NameHistNSplitVertices[] = "hNSplitVertices"; - std::shared_ptr hNSplitVertices; static constexpr char NameHistGenCollisions[] = "hGenCollisions"; + + std::shared_ptr hGenCollisionsCent; + std::shared_ptr hRecCollisionsCentMc; + std::shared_ptr hNSplitVertices; std::shared_ptr hGenCollisions; /// \brief Adds collision monitoring histograms in the histogram registry. @@ -456,7 +468,7 @@ struct HfEventSelectionMc { /// \brief Configures the object from the reco workflow /// \param registry reference to the histogram registry /// \param device device spec to get the configs from the reco workflow - void configureFromDevice(const o2::framework::DeviceSpec& device) + void configureFromDevice(o2::framework::DeviceSpec const& device) { for (const auto& option : device.options) { if (option.name.compare("hfEvSel.useSel8Trigger") == 0) { @@ -490,7 +502,8 @@ struct HfEventSelectionMc { /// \brief Inits the HF event selection object /// \param device device spec to get the configs from the reco workflow /// \param registry reference to the histogram registry - void init(const o2::framework::DeviceSpec& device, o2::framework::HistogramRegistry& registry) + void init(o2::framework::DeviceSpec const& device, + o2::framework::HistogramRegistry& registry) { // we get the configuration from the reco workflow configureFromDevice(device); @@ -509,12 +522,14 @@ struct HfEventSelectionMc { /// \param collSlice collection of reconstructed collisions /// \param centrality centrality variable to be set in this function /// \return a bitmask with the event selections not satisfied by the analysed collision - template - uint32_t getHfMcCollisionRejectionMask(TMcColl const& mcCollision, CCs const& collSlice, float& centrality) + template + HfCollisionRejectionMask getHfMcCollisionRejectionMask(TMcCollision const& mcCollision, + TCollisions const& collSlice, + float& centrality) { - uint32_t rejectionMask{0}; - float zPv = mcCollision.posZ(); - auto bc = mcCollision.template bc_as(); + HfCollisionRejectionMask rejectionMask{}; + const auto zPv = mcCollision.posZ(); + const auto bc = mcCollision.template bc_as(); if constexpr (centEstimator != o2::hf_centrality::CentralityEstimator::None) { centrality = o2::hf_centrality::getCentralityGenColl(collSlice, centEstimator); @@ -560,8 +575,10 @@ struct HfEventSelectionMc { /// \brief Fills histogram for monitoring event selections satisfied by the collision. /// \param collision analysed collision /// \param rejectionMask bitmask storing the info about which ev. selections are not satisfied by the collision - template - void fillHistograms(Coll const& mcCollision, const uint32_t rejectionMask, int nSplitColl = 0) + template + void fillHistograms(TMcCollision const& mcCollision, + const HfCollisionRejectionMask rejectionMask, + const int nSplitColl = 0) { hGenCollisions->Fill(EventRejection::None); diff --git a/PWGHF/Utils/utilsMcGen.h b/PWGHF/Utils/utilsMcGen.h index 76152505906..485b15de1af 100644 --- a/PWGHF/Utils/utilsMcGen.h +++ b/PWGHF/Utils/utilsMcGen.h @@ -35,8 +35,12 @@ namespace hf_mc_gen { -template -void fillMcMatchGen2Prong(T const& mcParticles, U const& mcParticlesPerMcColl, V& rowMcMatchGen, bool rejectBackground, bool matchCorrelatedBackground) +template +void fillMcMatchGen2Prong(TMcParticles const& mcParticles, + TMcParticlesPerColl const& mcParticlesPerMcColl, + TCursor& rowMcMatchGen, + const bool rejectBackground, + const bool matchCorrelatedBackground) { using namespace o2::constants::physics; using namespace o2::hf_decay::hf_cand_2prong; @@ -123,8 +127,12 @@ void fillMcMatchGen2Prong(T const& mcParticles, U const& mcParticlesPerMcColl, V } } -template -void fillMcMatchGen3Prong(T const& mcParticles, U const& mcParticlesPerMcColl, V& rowMcMatchGen, bool rejectBackground, std::vector const& pdgMothersCorrelBkg = {}) +template +void fillMcMatchGen3Prong(TMcParticles const& mcParticles, + TMcParticlesPerColl const& mcParticlesPerMcColl, + TCursor& rowMcMatchGen, + const bool rejectBackground, + std::vector const& pdgMothersCorrelBkg = {}) { using namespace o2::constants::physics; using namespace o2::hf_decay::hf_cand_3prong; @@ -157,7 +165,7 @@ void fillMcMatchGen3Prong(T const& mcParticles, U const& mcParticlesPerMcColl, V if (std::abs(particle.pdgCode()) != pdgMother) { continue; // Skip if the particle PDG code does not match the mother PDG code } - auto finalStates = getDecayChannelsMain(pdgMother); + const auto finalStates = getDecayChannelsMain(pdgMother); constexpr int DepthMainMax = 2; // Depth for final state matching constexpr int DepthResoMax = 1; // Depth for resonant decay matching @@ -307,8 +315,8 @@ void fillMcMatchGen3Prong(T const& mcParticles, U const& mcParticlesPerMcColl, V } } -template -void fillMcMatchGenBplus(T const& mcParticles, U& rowMcMatchGen) +template +void fillMcMatchGenBplus(TMcParticles const& mcParticles, TCursor& rowMcMatchGen) { using namespace o2::constants::physics; using namespace o2::hf_decay::hf_cand_beauty; @@ -340,8 +348,8 @@ void fillMcMatchGenBplus(T const& mcParticles, U& rowMcMatchGen) } // B candidate } -template -void fillMcMatchGenB0(T const& mcParticles, U& rowMcMatchGen) +template +void fillMcMatchGenB0(TMcParticles const& mcParticles, TCursor& rowMcMatchGen) { using namespace o2::constants::physics; using namespace o2::hf_decay::hf_cand_beauty; diff --git a/PWGHF/Utils/utilsMcMatching.h b/PWGHF/Utils/utilsMcMatching.h index bac650d36d4..55480879e1a 100644 --- a/PWGHF/Utils/utilsMcMatching.h +++ b/PWGHF/Utils/utilsMcMatching.h @@ -198,7 +198,8 @@ const std::unordered_map particlesToDstarPi = { const std::unordered_map particlesToDplusPi = { {DecayChannelMain::D2starzeroToDplusPi, constants::physics::Pdg::kD2Star0}}; const std::unordered_map particlesToD0Pi = { - {DecayChannelMain::D2starplusToD0Pi, constants::physics::Pdg::kD2StarPlus}}; + {DecayChannelMain::D2starplusToD0Pi, constants::physics::Pdg::kD2StarPlus}, + {DecayChannelMain::DstarToD0Pi, constants::physics::Pdg::kDStar}}; const std::unordered_map particlesToD0Kplus = { {DecayChannelMain::Ds2starToD0Kplus, constants::physics::Pdg::kDS2Star}}; diff --git a/PWGHF/Utils/utilsPid.h b/PWGHF/Utils/utilsPid.h index 4590bb50b2c..bc5024daf75 100644 --- a/PWGHF/Utils/utilsPid.h +++ b/PWGHF/Utils/utilsPid.h @@ -44,40 +44,40 @@ enum PidMethod { /// Function to combine TPC and TOF NSigma /// \param tiny switch between full and tiny (binned) PID tables -/// \param tpcNSigma is the (binned) NSigma separation in TPC (if tiny = true) -/// \param tofNSigma is the (binned) NSigma separation in TOF (if tiny = true) +/// \param nSigmaTpc is the (binned) NSigma separation in TPC (if tiny = true) +/// \param nSigmaTof is the (binned) NSigma separation in TOF (if tiny = true) /// \return combined NSigma of TPC and TOF -template -T1 combineNSigma(T1 tpcNSigma, T1 tofNSigma) +template +TNumber combineNSigma(TNumber nSigmaTpc, TNumber nSigmaTof) { static constexpr float DefaultNSigmaTolerance = .1f; static constexpr float DefaultNSigma = -999.f + DefaultNSigmaTolerance; // -999.f is the default value set in TPCPIDResponse.h and PIDTOF.h if constexpr (tiny) { - tpcNSigma *= aod::pidtpc_tiny::binning::bin_width; - tofNSigma *= aod::pidtof_tiny::binning::bin_width; + nSigmaTpc *= aod::pidtpc_tiny::binning::bin_width; + nSigmaTof *= aod::pidtof_tiny::binning::bin_width; } - if ((tpcNSigma > DefaultNSigma) && (tofNSigma > DefaultNSigma)) { // TPC and TOF - return std::sqrt(.5f * (tpcNSigma * tpcNSigma + tofNSigma * tofNSigma)); + if ((nSigmaTpc > DefaultNSigma) && (nSigmaTof > DefaultNSigma)) { // TPC and TOF + return std::sqrt(.5f * (nSigmaTpc * nSigmaTpc + nSigmaTof * nSigmaTof)); } - if (tpcNSigma > DefaultNSigma) { // only TPC - return std::abs(tpcNSigma); + if (nSigmaTpc > DefaultNSigma) { // only TPC + return std::abs(nSigmaTpc); } - if (tofNSigma > DefaultNSigma) { // only TOF - return std::abs(tofNSigma); + if (nSigmaTof > DefaultNSigma) { // only TOF + return std::abs(nSigmaTof); } - return tofNSigma; // no TPC nor TOF + return nSigmaTof; // no TPC nor TOF } -/// @brief Function to fill tables with HF prong PID information -/// @tparam TRK datatype of the prong track -/// @tparam ROW datatype of the prong PID table to fill -/// @tparam specPid particle species -/// @param track prong track -/// @param rowPid cursor of the prong PID table to fill -template -void fillProngPid(TRK const& track, ROW& rowPid) +/// \brief Function to fill tables with HF prong PID information +/// \tparam specPid particle species +/// \tparam TTrack datatype of the prong track +/// \tparam TCursor datatype of the cursor of the prong PID table to fill +/// \param track prong track +/// \param rowPid cursor of the prong PID table to fill +template +void fillProngPid(TTrack const& track, TCursor& rowPid) { // get PID information for the daughter tracks diff --git a/PWGHF/Utils/utilsTrkCandHf.h b/PWGHF/Utils/utilsTrkCandHf.h index 43db7a21e08..295b8fb7538 100644 --- a/PWGHF/Utils/utilsTrkCandHf.h +++ b/PWGHF/Utils/utilsTrkCandHf.h @@ -22,6 +22,7 @@ #include +#include #include namespace o2::hf_trkcandsel @@ -36,10 +37,10 @@ enum SVFitting { o2::framework::AxisSpec axisCands = {SVFitting::NCases, -0.5f, static_cast(SVFitting::NCases) - 0.5f, ""}; -/// @brief Function to put labels on candidate monitoring histogram +/// \brief Function to put labels on candidate monitoring histogram /// \param hCandidates is the histogram -template -void setLabelHistoCands(Histo& hCandidates) +template +void setLabelHistoCands(THisto& hCandidates) { hCandidates->SetTitle("HF candidate counter;;candidates"); hCandidates->GetXaxis()->SetBinLabel(SVFitting::BeforeFit + 1, "Before secondary vertexing"); @@ -47,16 +48,15 @@ void setLabelHistoCands(Histo& hCandidates) hCandidates->GetXaxis()->SetBinLabel(SVFitting::Fail + 1, "Run-time error in secondary vertexing"); } -/// @brief Function to evaluate number of ones in a binary representation of the argument +/// \brief Function to evaluate number of ones in a binary representation of the argument /// \param num is the input argument -int countOnesInBinary(uint8_t num) +int countOnesInBinary(const uint8_t num) { - int count = 0; - - for (int iBit = 0; iBit < 8; iBit++) { + int count{0}; + constexpr std::size_t NBits{8u}; + for (std::size_t iBit{0u}; iBit < NBits; iBit++) { count += TESTBIT(num, iBit); } - return count; } @@ -66,10 +66,13 @@ int countOnesInBinary(uint8_t num) /// \param binsPtTrack is the array of pt bins for track selection /// \param cutsTrackDCA are the cuts for track DCA selection /// \return true if track passes all cuts -template -bool isSelectedTrackDCA(const T1& trackPar, const T2& dca, const C1& binsPtTrack, const C2& cutsTrackDCA) +template +bool isSelectedTrackDCA(TTrackPar const& trackPar, + TArrayDca const& dca, + TArrayPt const& binsPtTrack, + TArrayCuts const& cutsTrackDCA) { - auto binPtTrack = o2::analysis::findBin(binsPtTrack, trackPar.getPt()); + const auto binPtTrack = o2::analysis::findBin(binsPtTrack, trackPar.getPt()); if (binPtTrack == -1) { return false; } diff --git a/PWGJE/Core/JetCandidateUtilities.h b/PWGJE/Core/JetCandidateUtilities.h index 921b88af9b8..cf745964359 100644 --- a/PWGJE/Core/JetCandidateUtilities.h +++ b/PWGJE/Core/JetCandidateUtilities.h @@ -205,11 +205,11 @@ auto matchedParticle(const T& candidate, const U& tracks, const V& particles) * @param candidate candidate that is being checked * @param table the table to be sliced */ -template -auto slicedPerCandidate(T const& table, U const& candidate, V const& perD0Candidate, M const& perDplusCandidate, N const& perDstarCandidate, O const& perLcCandidate, P const& perB0Candidate, Q const& perBplusCandidate, R const& perDielectronCandidate) +template +auto slicedPerCandidate(T const& table, U const& candidate, V const& perD0Candidate, M const& perDplusCandidate, N const& perDsCandidate, O const& perDstarCandidate, P const& perLcCandidate, Q const& perB0Candidate, R const& perBplusCandidate, S const& perXicToXiPiPiCandidate, A const& perDielectronCandidate) { if constexpr (jethfutilities::isHFCandidate()) { - return jethfutilities::slicedPerHFCandidate(table, candidate, perD0Candidate, perDplusCandidate, perDstarCandidate, perLcCandidate, perB0Candidate, perBplusCandidate); + return jethfutilities::slicedPerHFCandidate(table, candidate, perD0Candidate, perDplusCandidate, perDsCandidate, perDstarCandidate, perLcCandidate, perB0Candidate, perBplusCandidate, perXicToXiPiPiCandidate); } else if constexpr (jetdqutilities::isDielectronCandidate()) { return jetdqutilities::slicedPerDielectronCandidate(table, candidate, perDielectronCandidate); } else { @@ -223,11 +223,11 @@ auto slicedPerCandidate(T const& table, U const& candidate, V const& perD0Candid * @param jet jet that the slice is based on * @param table the table to be sliced */ -template -auto slicedPerJet(T const& table, U const& jet, V const& perD0Jet, M const& perDplusJet, N const& perDstarJet, O const& perLcJet, P const& perB0Jet, Q const& perBplusJet, R const& perDielectronJet) +template +auto slicedPerJet(T const& table, U const& jet, V const& perD0Jet, M const& perDplusJet, N const& perDsJet, O const& perDstarJet, P const& perLcJet, Q const& perB0Jet, R const& perBplusJet, S const& perXicToXiPiPiJet, A const& perDielectronJet) { if constexpr (jethfutilities::isHFTable() || jethfutilities::isHFMcTable()) { - return jethfutilities::slicedPerHFJet(table, jet, perD0Jet, perDplusJet, perDstarJet, perLcJet, perB0Jet, perBplusJet); + return jethfutilities::slicedPerHFJet(table, jet, perD0Jet, perDplusJet, perDsJet, perDstarJet, perLcJet, perB0Jet, perBplusJet, perXicToXiPiPiJet); } else if constexpr (jetdqutilities::isDielectronTable() || jetdqutilities::isDielectronMcTable()) { return jetdqutilities::slicedPerDielectronJet(table, jet, perDielectronJet); } else { diff --git a/PWGJE/Core/JetHFUtilities.h b/PWGJE/Core/JetHFUtilities.h index 9c3edc54f13..6e25d808d37 100644 --- a/PWGJE/Core/JetHFUtilities.h +++ b/PWGJE/Core/JetHFUtilities.h @@ -104,6 +104,42 @@ constexpr bool isDplusMcTable() return isDplusMcCandidate() || isDplusMcCandidate(); } +/** + * returns true if the candidate is from a Ds table + */ +template +constexpr bool isDsCandidate() +{ + return std::is_same_v, o2::aod::CandidatesDsData::iterator> || std::is_same_v, o2::aod::CandidatesDsData::filtered_iterator> || std::is_same_v, o2::aod::CandidatesDsMCD::iterator> || std::is_same_v, o2::aod::CandidatesDsMCD::filtered_iterator>; +} + +/** + * returns true if the particle is from a Ds MC table + */ +template +constexpr bool isDsMcCandidate() +{ + return std::is_same_v, o2::aod::CandidatesDsMCP::iterator> || std::is_same_v, o2::aod::CandidatesDsMCP::filtered_iterator>; +} + +/** + * returns true if the table is a Ds table + */ +template +constexpr bool isDsTable() +{ + return isDsCandidate() || isDsCandidate(); +} + +/** + * returns true if the table is a Ds MC table + */ +template +constexpr bool isDsMcTable() +{ + return isDsMcCandidate() || isDsMcCandidate(); +} + /** * returns true if the candidate is from a D* table */ @@ -248,6 +284,42 @@ constexpr bool isBplusMcTable() return isBplusMcCandidate() || isBplusMcCandidate(); } +/** + * returns true if the candidate is from a XicToXiPiPi table + */ +template +constexpr bool isXicToXiPiPiCandidate() +{ + return std::is_same_v, o2::aod::CandidatesXicToXiPiPiData::iterator> || std::is_same_v, o2::aod::CandidatesXicToXiPiPiData::filtered_iterator> || std::is_same_v, o2::aod::CandidatesXicToXiPiPiMCD::iterator> || std::is_same_v, o2::aod::CandidatesXicToXiPiPiMCD::filtered_iterator>; +} + +/** + * returns true if the particle is from a XicToXiPiPi MC table + */ +template +constexpr bool isXicToXiPiPiMcCandidate() +{ + return std::is_same_v, o2::aod::CandidatesXicToXiPiPiMCP::iterator> || std::is_same_v, o2::aod::CandidatesXicToXiPiPiMCP::filtered_iterator>; +} + +/** + * returns true if the table is a XicToXiPiPi table + */ +template +constexpr bool isXicToXiPiPiTable() +{ + return isXicToXiPiPiCandidate() || isXicToXiPiPiCandidate(); +} + +/** + * returns true if the table is a XicToXiPiPi MC table + */ +template +constexpr bool isXicToXiPiPiMcTable() +{ + return isXicToXiPiPiMcCandidate() || isXicToXiPiPiMcCandidate(); +} + /** * returns true if the candidate is from a HF table * * @param candidate candidate that is being checked @@ -259,6 +331,8 @@ constexpr bool isHFCandidate() return true; } else if constexpr (isDplusCandidate()) { return true; + } else if constexpr (isDsCandidate()) { + return true; } else if constexpr (isDstarCandidate()) { return true; } else if constexpr (isLcCandidate()) { @@ -267,6 +341,8 @@ constexpr bool isHFCandidate() return true; } else if constexpr (isBplusCandidate()) { return true; + } else if constexpr (isXicToXiPiPiCandidate()) { + return true; } else { return false; } @@ -283,13 +359,17 @@ constexpr bool isHFMcCandidate() return true; } else if constexpr (isDplusMcCandidate()) { return true; + } else if constexpr (isDsMcCandidate()) { + return true; } else if constexpr (isDstarMcCandidate()) { return true; } else if constexpr (isLcMcCandidate()) { return true; } else if constexpr (isB0McCandidate()) { return true; - } else if constexpr (isBplusMcCandidate()) { + } else if constexpr (isXicToXiPiPiMcCandidate()) { + return true; + } else if constexpr (isDstarMcCandidate()) { return true; } else { return false; @@ -306,6 +386,8 @@ constexpr bool isHFTable() return true; } else if constexpr (isDplusCandidate() || isDplusCandidate()) { return true; + } else if constexpr (isDsCandidate() || isDsCandidate()) { + return true; } else if constexpr (isDstarCandidate() || isDstarCandidate()) { return true; } else if constexpr (isLcCandidate() || isLcCandidate()) { @@ -314,6 +396,8 @@ constexpr bool isHFTable() return true; } else if constexpr (isBplusCandidate() || isBplusCandidate()) { return true; + } else if constexpr (isXicToXiPiPiCandidate() || isXicToXiPiPiCandidate()) { + return true; } else { return false; } @@ -329,6 +413,8 @@ constexpr bool isHFMcTable() return true; } else if constexpr (isDplusMcCandidate() || isDplusMcCandidate()) { return true; + } else if constexpr (isDsMcCandidate() || isDsMcCandidate()) { + return true; } else if constexpr (isDstarMcCandidate() || isDstarMcCandidate()) { return true; } else if constexpr (isLcMcCandidate() || isLcMcCandidate()) { @@ -337,6 +423,8 @@ constexpr bool isHFMcTable() return true; } else if constexpr (isBplusMcCandidate() || isBplusMcCandidate()) { return true; + } else if constexpr (isXicToXiPiPiMcCandidate() || isXicToXiPiPiMcCandidate()) { + return true; } else { return false; } @@ -361,6 +449,12 @@ constexpr bool isMatchedHFCandidate(T const& candidate) } else { return false; } + } else if constexpr (isDsCandidate()) { + if (std::abs(candidate.flagMcMatchRec()) == o2::hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) { + return true; + } else { + return false; + } } else if constexpr (isDstarCandidate()) { if (std::abs(candidate.flagMcMatchRec()) == o2::hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi) { return true; @@ -385,6 +479,12 @@ constexpr bool isMatchedHFCandidate(T const& candidate) } else { return false; } + } else if constexpr (isXicToXiPiPiCandidate()) { + if (std::abs(candidate.flagMcMatchRec()) == o2::aod::hf_cand_xic_to_xi_pi_pi::DecayType::XicToXiPiPi) { + return true; + } else { + return false; + } } else if constexpr (isD0McCandidate()) { if (std::abs(candidate.flagMcMatchGen()) == o2::hf_decay::hf_cand_2prong::DecayChannelMain::D0ToPiK) { return true; @@ -397,6 +497,12 @@ constexpr bool isMatchedHFCandidate(T const& candidate) } else { return false; } + } else if constexpr (isDsMcCandidate()) { + if (std::abs(candidate.flagMcMatchGen()) == o2::hf_decay::hf_cand_3prong::DecayChannelMain::DsToPiKK) { + return true; + } else { + return false; + } } else if constexpr (isDstarMcCandidate()) { if (std::abs(candidate.flagMcMatchGen()) == o2::hf_decay::hf_cand_dstar::DecayChannelMain::DstarToPiKPi) { return true; @@ -421,6 +527,12 @@ constexpr bool isMatchedHFCandidate(T const& candidate) } else { return false; } + } else if constexpr (isXicToXiPiPiMcCandidate()) { + if (std::abs(candidate.flagMcMatchGen()) == o2::aod::hf_cand_xic_to_xi_pi_pi::DecayType::XicToXiPiPi) { + return true; + } else { + return false; + } } else { return false; } @@ -448,6 +560,12 @@ bool isHFDaughterTrack(T& track, U& candidate, V const& /*tracks*/) } else { return false; } + } else if constexpr (isDsCandidate()) { + if (candidate.prong0Id() == track.globalIndex() || candidate.prong1Id() == track.globalIndex() || candidate.prong2Id() == track.globalIndex()) { + return true; + } else { + return false; + } } else if constexpr (isDstarCandidate()) { if (candidate.prong0Id() == track.globalIndex() || candidate.prong1Id() == track.globalIndex() || candidate.prong2Id() == track.globalIndex()) { return true; @@ -472,6 +590,12 @@ bool isHFDaughterTrack(T& track, U& candidate, V const& /*tracks*/) } else { return false; } + } else if constexpr (isXicToXiPiPiCandidate()) { + if (candidate.prong0Id() == track.globalIndex() || candidate.prong1Id() == track.globalIndex() || candidate.prong2Id() == track.globalIndex() || candidate.prong3Id() == track.globalIndex() || candidate.prong4Id() == track.globalIndex()) { + return true; + } else { + return false; + } } else { return false; } @@ -511,8 +635,8 @@ auto matchedHFParticle(const T& candidate, const U& /*tracks*/, const V& /*parti * @param candidate HF candidate that is being checked * @param table the table to be sliced */ -template -auto slicedPerHFCandidate(T const& table, U const& candidate, V const& perD0Candidate, M const& perDplusCandidate, N const& perDstarCandidate, O const& perLcCandidate, P const& perB0Candidate, Q const& perBplusCandidate) +template +auto slicedPerHFCandidate(T const& table, U const& candidate, V const& perD0Candidate, M const& perDplusCandidate, N const& perDsCandidate, O const& perDstarCandidate, P const& perLcCandidate, Q const& perB0Candidate, R const& perBplusCandidate, S const& perXicToXiPiPiCandidate) { if constexpr (isD0Candidate()) { return table.sliceBy(perD0Candidate, candidate.globalIndex()); @@ -520,12 +644,16 @@ auto slicedPerHFCandidate(T const& table, U const& candidate, V const& perD0Cand return table.sliceBy(perDplusCandidate, candidate.globalIndex()); } else if constexpr (isDstarCandidate()) { return table.sliceBy(perDstarCandidate, candidate.globalIndex()); + } else if constexpr (isDsCandidate()) { + return table.sliceBy(perDsCandidate, candidate.globalIndex()); } else if constexpr (isLcCandidate()) { return table.sliceBy(perLcCandidate, candidate.globalIndex()); } else if constexpr (isB0Candidate()) { return table.sliceBy(perB0Candidate, candidate.globalIndex()); } else if constexpr (isBplusCandidate()) { return table.sliceBy(perBplusCandidate, candidate.globalIndex()); + } else if constexpr (isXicToXiPiPiCandidate()) { + return table.sliceBy(perXicToXiPiPiCandidate, candidate.globalIndex()); } else { return table; } @@ -538,8 +666,8 @@ auto slicedPerHFCandidate(T const& table, U const& candidate, V const& perD0Cand * @param jet jet that is being sliced based on * @param table the table to be sliced */ -template -auto slicedPerHFJet(T const& table, U const& jet, V const& perD0Jet, M const& perDplusJet, N const& perDstarJet, O const& perLcJet, P const& perB0Jet, Q const& perBplusJet) +template +auto slicedPerHFJet(T const& table, U const& jet, V const& perD0Jet, M const& perDplusJet, N const& perDsJet, O const& perDstarJet, P const& perLcJet, Q const& perB0Jet, R const& perBplusJet, S const& perXicToXiPiPiJet) { if constexpr (isD0Table() || isD0McTable()) { return table.sliceBy(perD0Jet, jet.globalIndex()); @@ -547,12 +675,16 @@ auto slicedPerHFJet(T const& table, U const& jet, V const& perD0Jet, M const& pe return table.sliceBy(perDplusJet, jet.globalIndex()); } else if constexpr (isDstarTable() || isDstarMcTable()) { return table.sliceBy(perDstarJet, jet.globalIndex()); + } else if constexpr (isDsTable() || isDsMcTable()) { + return table.sliceBy(perDsJet, jet.globalIndex()); } else if constexpr (isLcTable() || isLcMcTable()) { return table.sliceBy(perLcJet, jet.globalIndex()); } else if constexpr (isB0Table() || isB0McTable()) { return table.sliceBy(perB0Jet, jet.globalIndex()); } else if constexpr (isBplusTable() || isBplusMcTable()) { return table.sliceBy(perBplusJet, jet.globalIndex()); + } else if constexpr (isXicToXiPiPiTable() || isXicToXiPiPiMcTable()) { + return table.sliceBy(perXicToXiPiPiJet, jet.globalIndex()); } else { return table; } @@ -592,6 +724,8 @@ int getHFCandidatePDG(T const& /*candidate*/) return static_cast(o2::constants::physics::Pdg::kD0); } else if constexpr (isDplusCandidate() || isDplusMcCandidate()) { return static_cast(o2::constants::physics::Pdg::kDPlus); + } else if constexpr (isDsCandidate() || isDsMcCandidate()) { + return static_cast(o2::constants::physics::Pdg::kDS); } else if constexpr (isDstarCandidate() || isDstarMcCandidate()) { return static_cast(o2::constants::physics::Pdg::kDStar); } else if constexpr (isLcCandidate() || isLcMcCandidate()) { @@ -600,6 +734,8 @@ int getHFCandidatePDG(T const& /*candidate*/) return static_cast(o2::constants::physics::Pdg::kB0); } else if constexpr (isBplusCandidate() || isBplusMcCandidate()) { return static_cast(o2::constants::physics::Pdg::kBPlus); + } else if constexpr (isXicToXiPiPiCandidate() || isXicToXiPiPiMcCandidate()) { + return static_cast(o2::constants::physics::Pdg::kXiCPlus); } else { return 0; } @@ -615,6 +751,8 @@ int getHFTablePDG() return static_cast(o2::constants::physics::Pdg::kD0); } else if constexpr (isDplusTable() || isDplusMcTable()) { return static_cast(o2::constants::physics::Pdg::kDPlus); + } else if constexpr (isDsTable() || isDsMcTable()) { + return static_cast(o2::constants::physics::Pdg::kDS); } else if constexpr (isDstarTable() || isDstarMcTable()) { return static_cast(o2::constants::physics::Pdg::kDStar); } else if constexpr (isLcTable() || isLcMcTable()) { @@ -623,6 +761,8 @@ int getHFTablePDG() return static_cast(o2::constants::physics::Pdg::kB0); } else if constexpr (isBplusTable() || isBplusMcTable()) { return static_cast(o2::constants::physics::Pdg::kBPlus); + } else if constexpr (isXicToXiPiPiTable() || isXicToXiPiPiMcTable()) { + return static_cast(o2::constants::physics::Pdg::kXiCPlus); } else { return 0; } @@ -640,6 +780,8 @@ float getHFCandidatePDGMass(T const& /*candidate*/) return static_cast(o2::constants::physics::MassD0); } else if constexpr (isDplusCandidate() || isDplusMcCandidate()) { return static_cast(o2::constants::physics::MassDPlus); + } else if constexpr (isDsCandidate() || isDsMcCandidate()) { + return static_cast(o2::constants::physics::MassDS); } else if constexpr (isDstarCandidate() || isDstarMcCandidate()) { return static_cast(o2::constants::physics::MassDStar); } else if constexpr (isLcCandidate() || isLcMcCandidate()) { @@ -648,6 +790,8 @@ float getHFCandidatePDGMass(T const& /*candidate*/) return static_cast(o2::constants::physics::MassB0); } else if constexpr (isBplusCandidate() || isBplusMcCandidate()) { return static_cast(o2::constants::physics::MassBPlus); + } else if constexpr (isXicToXiPiPiCandidate() || isXicToXiPiPiMcCandidate()) { + return static_cast(o2::constants::physics::MassXiCPlus); } else { return -1.0; } @@ -664,6 +808,8 @@ float getHFTablePDGMass() return static_cast(o2::constants::physics::MassD0); } else if constexpr (isDplusTable() || isDplusMcTable()) { return static_cast(o2::constants::physics::MassDPlus); + } else if constexpr (isDsTable() || isDsMcTable()) { + return static_cast(o2::constants::physics::MassDS); } else if constexpr (isDstarTable() || isDstarMcTable()) { return static_cast(o2::constants::physics::MassDStar); } else if constexpr (isLcTable() || isLcMcTable()) { @@ -672,6 +818,8 @@ float getHFTablePDGMass() return static_cast(o2::constants::physics::MassB0); } else if constexpr (isBplusTable() || isBplusMcTable()) { return static_cast(o2::constants::physics::MassBPlus); + } else if constexpr (isXicToXiPiPiTable() || isXicToXiPiPiMcTable()) { + return static_cast(o2::constants::physics::MassXiCPlus); } else { return -1.0; } @@ -829,6 +977,78 @@ void fillDplusCandidateTable(T const& candidate, U& DplusParTable, V& DplusParET } } +template +void fillDsCandidateTable(T const& candidate, U& DsParTable, V& DsParETable, M& DsMlTable, N& DsMCDTable) +{ + + DsParTable( + candidate.chi2PCA(), + candidate.nProngsContributorsPV(), + candidate.cpa(), + candidate.cpaXY(), + candidate.decayLength(), + candidate.decayLengthXY(), + candidate.decayLengthNormalised(), + candidate.decayLengthXYNormalised(), + candidate.ptProng0(), + candidate.ptProng1(), + candidate.ptProng2(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.impactParameter2(), + candidate.impactParameterNormalised0(), + candidate.impactParameterNormalised1(), + candidate.impactParameterNormalised2(), + candidate.nSigTpcPi0(), + candidate.nSigTpcKa0(), + candidate.nSigTofPi0(), + candidate.nSigTofKa0(), + candidate.nSigTpcTofPi0(), + candidate.nSigTpcTofKa0(), + candidate.nSigTpcKa1(), + candidate.nSigTofKa1(), + candidate.nSigTpcTofKa1(), + candidate.nSigTpcPi2(), + candidate.nSigTpcKa2(), + candidate.nSigTofPi2(), + candidate.nSigTofKa2(), + candidate.nSigTpcTofPi2(), + candidate.nSigTpcTofKa2()); + + DsParETable( + candidate.xSecondaryVertex(), + candidate.ySecondaryVertex(), + candidate.zSecondaryVertex(), + candidate.errorDecayLength(), + candidate.errorDecayLengthXY(), + candidate.rSecondaryVertex(), + candidate.pProng0(), + candidate.pProng1(), + candidate.pProng2(), + candidate.pxProng0(), + candidate.pyProng0(), + candidate.pzProng0(), + candidate.pxProng1(), + candidate.pyProng1(), + candidate.pzProng1(), + candidate.pxProng2(), + candidate.pyProng2(), + candidate.pzProng2(), + candidate.errorImpactParameter0(), + candidate.errorImpactParameter1(), + candidate.errorImpactParameter2(), + candidate.ct()); + + std::vector mlScoresVector; + auto mlScoresSpan = candidate.mlScores(); + std::copy(mlScoresSpan.begin(), mlScoresSpan.end(), std::back_inserter(mlScoresVector)); + DsMlTable(mlScoresVector); + + if constexpr (isMc) { + DsMCDTable(candidate.flagMcMatchRec(), candidate.originMcRec(), candidate.isCandidateSwapped(), candidate.flagMcDecayChanRec()); + } +} + template void fillDstarCandidateTable(T const& candidate, U& DstarParTable, V& DstarParDaughterTable, M& DstarMlTable, N& DstarMCDTable) { @@ -1128,6 +1348,75 @@ void fillBplusCandidateTable(T const& candidate, U& BplusParTable, V& BplusParET } } +template +void fillXicToXiPiPiCandidateTable(T const& candidate, U& XicToXiPiPiParTable, V& XicToXiPiPiParETable, M& XicToXiPiPiMlTable, N& XicToXiPiPiMCDTable) +{ + + XicToXiPiPiParTable( + candidate.sign(), + candidate.ptProngXi(), + candidate.ptProngPi0(), + candidate.ptProngPi1(), + candidate.invMassXi(), + candidate.invMassLambda(), + candidate.invMassXiPi0(), + candidate.invMassXiPi1(), + candidate.chi2PCA(), + candidate.ct(), + candidate.decayLength(), + candidate.decayLengthXY(), + candidate.decayLengthNormalised(), + candidate.decayLengthXYNormalised(), + candidate.cpa(), + candidate.cpaXY(), + candidate.cpaXi(), + candidate.cpaXYXi(), + candidate.cpaLambda(), + candidate.cpaXYLambda(), + candidate.impactParameterXi(), + candidate.impactParameterNormalisedXi(), + candidate.impactParameterPi0(), + candidate.impactParameterNormalisedPi0(), + candidate.impactParameterPi1(), + candidate.impactParameterNormalisedPi1(), + candidate.maxNormalisedDeltaIP()); + + XicToXiPiPiParETable( + candidate.cpaLambdaToXi(), + candidate.cpaXYLambdaToXi(), + candidate.pProngPi0(), + candidate.pProngPi1(), + candidate.pBachelorPi(), + candidate.pPiFromLambda(), + candidate.pPrFromLambda(), + candidate.dcaXiDaughters(), + candidate.dcaV0Daughters(), + candidate.dcaPosToPV(), + candidate.dcaNegToPV(), + candidate.dcaBachelorToPV(), + candidate.dcaXYCascToPV(), + candidate.dcaZCascToPV(), + candidate.nSigTpcPiFromXicPlus0(), + candidate.nSigTpcPiFromXicPlus1(), + candidate.nSigTpcBachelorPi(), + candidate.nSigTpcPiFromLambda(), + candidate.nSigTpcPrFromLambda(), + candidate.nSigTofPiFromXicPlus0(), + candidate.nSigTofPiFromXicPlus1(), + candidate.nSigTofBachelorPi(), + candidate.nSigTofPiFromLambda(), + candidate.nSigTofPrFromLambda()); + + std::vector mlScoresVector; + auto mlScoresSpan = candidate.mlScores(); + std::copy(mlScoresSpan.begin(), mlScoresSpan.end(), std::back_inserter(mlScoresVector)); + XicToXiPiPiMlTable(mlScoresVector); + + if constexpr (isMc) { + XicToXiPiPiMCDTable(candidate.flagMcMatchRec(), candidate.originMcRec()); + } +} + template void fillHFCandidateTable(T const& candidate, int32_t collisionIndex, U& HFBaseTable, V& HFParTable, M& HFParETable, N& HFParDaughterTable, O& HFSelectionFlagTable, P& HFMlTable, Q& HFMlDaughterTable, S& HFMCDTable) { @@ -1140,6 +1429,9 @@ void fillHFCandidateTable(T const& candidate, int32_t collisionIndex, U& HFBaseT if constexpr (isDplusCandidate()) { fillDplusCandidateTable(candidate, HFParTable, HFParETable, HFMlTable, HFMCDTable); } + if constexpr (isDsCandidate()) { + fillDsCandidateTable(candidate, HFParTable, HFParETable, HFMlTable, HFMCDTable); + } if constexpr (isDstarCandidate()) { fillDstarCandidateTable(candidate, HFParTable, HFParDaughterTable, HFMlTable, HFMCDTable); } @@ -1152,6 +1444,9 @@ void fillHFCandidateTable(T const& candidate, int32_t collisionIndex, U& HFBaseT if constexpr (isBplusCandidate()) { fillBplusCandidateTable(candidate, HFParTable, HFParETable, HFParDaughterTable, HFMlTable, HFMlDaughterTable, HFMCDTable); } + if constexpr (isXicToXiPiPiCandidate()) { + fillXicToXiPiPiCandidateTable(candidate, HFParTable, HFParETable, HFMlTable, HFMCDTable); + } } template diff --git a/PWGJE/Core/emcalCrossTalkEmulation.cxx b/PWGJE/Core/emcalCrossTalkEmulation.cxx index 9fe9b679461..32b08cd13dc 100644 --- a/PWGJE/Core/emcalCrossTalkEmulation.cxx +++ b/PWGJE/Core/emcalCrossTalkEmulation.cxx @@ -527,7 +527,7 @@ void EMCCrossTalk::addInducedEnergiesToNewCells() } // Avoid cells out of SM - if (ietai < 0 || ietai >= emcal::EMCAL_COLS || iphii < 0 || iphii >= emcal::EMCAL_ROWS) { + if (ietai < 0 || ietai >= NColumns[iSM] || iphii < 0 || iphii >= NRows[iSM]) { continue; } diff --git a/PWGJE/Core/emcalCrossTalkEmulation.h b/PWGJE/Core/emcalCrossTalkEmulation.h index 7d83b95d19e..fb84ec7c1ad 100644 --- a/PWGJE/Core/emcalCrossTalkEmulation.h +++ b/PWGJE/Core/emcalCrossTalkEmulation.h @@ -127,6 +127,9 @@ static constexpr int FirstDCal23SM = 12; // index of the first 2/3 DCal SM static constexpr int LastDCal23SM = 17; // index of the last 2/3 DCal SM static constexpr float MinCellEnergy = 0.01f; // Minimum energy a new cell needs to be added +static constexpr int NColumns[NSM] = {48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 32, 32, 32, 32, 48, 48}; +static constexpr int NRows[NSM] = {24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 8, 8, 24, 24, 24, 24, 24, 24, 8, 8}; + // these labels are for later once labeledArrays work on hyperloop. Currently they sadly only allow fixed size not variable size. // static const std::vector labelsSM{"SM0/all", "SM1", "SM2", "SM3", "SM4", "SM5", "SM6", "SM7", "SM8", "SM9", "SM10", "SM11", "SM12", "SM13", "SM14", "SM15", "SM16", "SM17", "SM18", "SM19"}; // static const std::vector labelsCells = {"Up&Down", "Up&Down x Left|Right", "Left|Right", "2Up&Down + 2Up&Down xLeft|Right"}; diff --git a/PWGJE/Core/utilsBcSelEMC.h b/PWGJE/Core/utilsBcSelEMC.h index 7c23436e876..603e5190655 100644 --- a/PWGJE/Core/utilsBcSelEMC.h +++ b/PWGJE/Core/utilsBcSelEMC.h @@ -44,7 +44,7 @@ enum EventRejection { NEventRejection }; -o2::framework::AxisSpec axisEvents = {EventRejection::NEventRejection, -0.5f, +EventRejection::NEventRejection - 0.5f, ""}; +inline o2::framework::AxisSpec axisEvents = {EventRejection::NEventRejection, -0.5f, +EventRejection::NEventRejection - 0.5f, ""}; /// \brief Function to put labels on monitoring histogram /// \param hRejection monitoring histogram diff --git a/PWGJE/Core/utilsTrackMatchingEMC.h b/PWGJE/Core/utilsTrackMatchingEMC.h index 6256c712ff3..05790a3fb88 100644 --- a/PWGJE/Core/utilsTrackMatchingEMC.h +++ b/PWGJE/Core/utilsTrackMatchingEMC.h @@ -63,10 +63,6 @@ MatchResult matchTracksToCluster( const std::size_t nTracks = trackEta.size(); MatchResult result; - result.matchIndexTrack.resize(nClusters); - result.matchDeltaPhi.resize(nClusters); - result.matchDeltaEta.resize(nClusters); - if (nClusters == 0 || nTracks == 0) { // There are no jets, so nothing to be done. return result; @@ -79,6 +75,10 @@ MatchResult matchTracksToCluster( throw std::invalid_argument("track collection eta and phi sizes don't match. Check the inputs."); } + result.matchIndexTrack.resize(nClusters); + result.matchDeltaPhi.resize(nClusters); + result.matchDeltaEta.resize(nClusters); + // Build the KD-trees using vectors // We build two trees: // treeBase, which contains the base collection. diff --git a/PWGJE/DataModel/Jet.h b/PWGJE/DataModel/Jet.h index 52939d0b16c..9ff72f65448 100644 --- a/PWGJE/DataModel/Jet.h +++ b/PWGJE/DataModel/Jet.h @@ -181,10 +181,12 @@ DECLARE_JET_TABLES_LEVELS(Full, JTrackSub, HfD0Bases, HfD0PBases, "F"); DECLARE_JET_TABLES_LEVELS(Neutral, JTrackSub, HfD0Bases, HfD0PBases, "N"); DECLARE_JET_TABLES_LEVELS(D0Charged, JTrackD0Sub, HfD0Bases, HfD0PBases, "D0"); DECLARE_JET_TABLES_LEVELS(DplusCharged, JTrackDplusSub, HfDplusBases, HfDplusPBases, "DP"); +DECLARE_JET_TABLES_LEVELS(DsCharged, JTrackDsSub, HfDsBases, HfDsPBases, "DS"); DECLARE_JET_TABLES_LEVELS(DstarCharged, JTrackDstarSub, HfDstarBases, HfDstarPBases, "DST"); DECLARE_JET_TABLES_LEVELS(LcCharged, JTrackLcSub, HfLcBases, HfLcPBases, "Lc"); DECLARE_JET_TABLES_LEVELS(B0Charged, JTrackB0Sub, HfB0Bases, HfB0PBases, "B0"); DECLARE_JET_TABLES_LEVELS(BplusCharged, JTrackBplusSub, HfBplusBases, HfBplusPBases, "BP"); +DECLARE_JET_TABLES_LEVELS(XicToXiPiPiCharged, JTrackXicToXiPiPiSub, HfXicToXiPiPiBases, HfXicToXiPiPiPBases, "XICXPP"); DECLARE_JET_TABLES_LEVELS(V0Charged, JTrackSub, V0Cores, JV0Mcs, "V0"); DECLARE_JET_TABLES_LEVELS(DielectronCharged, JTrackSub, Dielectrons, JDielectronMcs, "DIEL"); @@ -231,6 +233,14 @@ using JetParticlesSubDplus = JMcParticleDplusSubs; using McCollisionsDplus = o2::soa::Join; using CandidatesDplusMCP = o2::soa::Join; +using CollisionsDs = o2::soa::Join; +using CandidatesDsData = o2::soa::Join; +using CandidatesDsMCD = o2::soa::Join; +using JetTracksSubDs = JTrackDsSubs; +using JetParticlesSubDs = JMcParticleDsSubs; +using McCollisionsDs = o2::soa::Join; +using CandidatesDsMCP = o2::soa::Join; + using CollisionsDstar = o2::soa::Join; using CandidatesDstarData = o2::soa::Join; using CandidatesDstarMCD = o2::soa::Join; @@ -263,6 +273,14 @@ using JetParticlesSubBplus = JMcParticleBplusSubs; using McCollisionsBplus = o2::soa::Join; using CandidatesBplusMCP = o2::soa::Join; +using CollisionsXicToXiPiPi = o2::soa::Join; +using CandidatesXicToXiPiPiData = o2::soa::Join; +using CandidatesXicToXiPiPiMCD = o2::soa::Join; +using JetTracksSubXicToXiPiPi = JTrackXicToXiPiPiSubs; +using JetParticlesSubXicToXiPiPi = JMcParticleXicToXiPiPiSubs; +using McCollisionsXicToXiPiPi = o2::soa::Join; +using CandidatesXicToXiPiPiMCP = o2::soa::Join; + using CandidatesV0Data = o2::soa::Join; using CandidatesV0MCD = o2::soa::Join; // using V0Daughters = DauTrackExtras; diff --git a/PWGJE/DataModel/JetReducedDataHF.h b/PWGJE/DataModel/JetReducedDataHF.h index f295dbfa398..7a2f1c86cd1 100644 --- a/PWGJE/DataModel/JetReducedDataHF.h +++ b/PWGJE/DataModel/JetReducedDataHF.h @@ -37,6 +37,8 @@ constexpr uint JMarkerBplus = 4; constexpr uint JMarkerDielectron = 5; constexpr uint JMarkerDstar = 6; constexpr uint JMarkerB0 = 7; +constexpr uint JMarkerDs = 8; +constexpr uint JMarkerXicToXiPiPi = 9; namespace jcandidateindices { @@ -124,6 +126,46 @@ DECLARE_SOA_TABLE(JDumDplusMlDaus, "AOD", "JDUMDPMLDAU", // might have to update!!!!!!!!!!!!!!!!!!!!!! +namespace jdsindices +{ +DECLARE_SOA_INDEX_COLUMN_FULL(Prong0, prong0, int, JTracks, "_0"); +DECLARE_SOA_INDEX_COLUMN_FULL(Prong1, prong1, int, JTracks, "_1"); +DECLARE_SOA_INDEX_COLUMN_FULL(Prong2, prong2, int, JTracks, "_2"); +} // namespace jdsindices + +DECLARE_SOA_TABLE_STAGED(JDsCollisionIds, "JDSCOLLID", + jcandidateindices::JCollisionId, + o2::soa::Marker); + +DECLARE_SOA_TABLE_STAGED(JDsMcCollisionIds, "JDSMCCOLLID", + jcandidateindices::JMcCollisionId, + o2::soa::Marker); + +DECLARE_SOA_TABLE_STAGED(JDsIds, "JDSID", + jcandidateindices::JCollisionId, + jdsindices::Prong0Id, + jdsindices::Prong1Id, + jdsindices::Prong2Id); + +DECLARE_SOA_TABLE_STAGED(JDsPIds, "JDSPID", + jcandidateindices::JMcCollisionId, + jcandidateindices::JMcParticleId, + o2::soa::Marker); + +namespace jdummyds +{ + +DECLARE_SOA_COLUMN(DummyDs, dummyDs, bool); + +} // namespace jdummyds +DECLARE_SOA_TABLE(JDumDsParDaus, "AOD", "JDUMDSPARDAU", + jdummyds::DummyDs, + o2::soa::Marker<1>); + +DECLARE_SOA_TABLE(JDumDsMlDaus, "AOD", "JDUMDSMLDAU", + jdummyds::DummyDs, + o2::soa::Marker<2>); + namespace jdstarindices { DECLARE_SOA_INDEX_COLUMN_FULL(Prong0, prong0, int, JTracks, "_0"); @@ -258,6 +300,49 @@ DECLARE_SOA_TABLE_STAGED(JBplusPIds, "JBPPID", jcandidateindices::JMcParticleId, o2::soa::Marker); +namespace jxictoxipipiindices +{ +DECLARE_SOA_INDEX_COLUMN_FULL(Prong0, prong0, int, JTracks, "_0"); +DECLARE_SOA_INDEX_COLUMN_FULL(Prong1, prong1, int, JTracks, "_1"); +DECLARE_SOA_INDEX_COLUMN_FULL(Prong2, prong2, int, JTracks, "_2"); +DECLARE_SOA_INDEX_COLUMN_FULL(Prong3, prong3, int, JTracks, "_3"); +DECLARE_SOA_INDEX_COLUMN_FULL(Prong4, prong4, int, JTracks, "_4"); +} // namespace jxictoxipipiindices + +DECLARE_SOA_TABLE_STAGED(JXicToXiPiPiCollisionIds, "JXICXPPCOLLID", + jcandidateindices::JCollisionId, + o2::soa::Marker); + +DECLARE_SOA_TABLE_STAGED(JXicToXiPiPiMcCollisionIds, "JXICXPPMCCOLLID", + jcandidateindices::JMcCollisionId, + o2::soa::Marker); + +DECLARE_SOA_TABLE_STAGED(JXicToXiPiPiIds, "JXICXPPID", + jcandidateindices::JCollisionId, + jxictoxipipiindices::Prong0Id, + jxictoxipipiindices::Prong1Id, + jxictoxipipiindices::Prong2Id, + jxictoxipipiindices::Prong3Id, + jxictoxipipiindices::Prong4Id); + +DECLARE_SOA_TABLE_STAGED(JXicToXiPiPiPIds, "JXICXPPPID", + jcandidateindices::JMcCollisionId, + jcandidateindices::JMcParticleId, + o2::soa::Marker); + +namespace jdummyxictoxipipi +{ +DECLARE_SOA_COLUMN(DummyXicToXiPiPi, dummyXicToXiPiPi, bool); + +} // namespace jdummyxictoxipipi +DECLARE_SOA_TABLE(JDumXicToXiPiPiParDaus, "AOD", "JDUMXICXPPPARDAU", + jdummyxictoxipipi::DummyXicToXiPiPi, + o2::soa::Marker<1>); + +DECLARE_SOA_TABLE(JDumXicToXiPiPiMlDaus, "AOD", "JDUMXICXPPMLDAU", + jdummyxictoxipipi::DummyXicToXiPiPi, + o2::soa::Marker<2>); + } // namespace o2::aod #endif // PWGJE_DATAMODEL_JETREDUCEDDATAHF_H_ diff --git a/PWGJE/DataModel/JetSubstructure.h b/PWGJE/DataModel/JetSubstructure.h index 88f0578d469..9e09948b253 100644 --- a/PWGJE/DataModel/JetSubstructure.h +++ b/PWGJE/DataModel/JetSubstructure.h @@ -260,10 +260,12 @@ DECLARE_SOA_COLUMN(JetNConstituents, jetNConstituents, int); //! JETSUBSTRUCTURE_TABLES_DEF(C, "C", Charged, charged, JTracks, CJetCOs, "CJETCO", JTrackSubs, CEWSJetCOs, "CEWSJETCO", JTracks, CMCDJetCOs, "CMCDJETCO", JMcParticles, CMCPJetCOs, "CMCPJETCO"); JETSUBSTRUCTURE_TABLES_DEF(D0C, "D0C", D0Charged, d0charged, JTracks, HfD0Bases, "HFD0BASE", JTrackD0Subs, HfD0Bases, "HFD0BASE", JTracks, HfD0Bases, "HFD0BASE", JMcParticles, HfD0PBases, "HFD0PBASE"); JETSUBSTRUCTURE_TABLES_DEF(DplusC, "DPC", DplusCharged, dpluscharged, JTracks, HfDplusBases, "HFDPBASE", JTrackDplusSubs, HfDplusBases, "HFDPBASE", JTracks, HfDplusBases, "HFDPBASE", JMcParticles, HfDplusPBases, "HFDPPBASE"); +JETSUBSTRUCTURE_TABLES_DEF(DsC, "DSC", DsCharged, dscharged, JTracks, HfDsBases, "HFDSBASE", JTrackDsSubs, HfDsBases, "HFDSBASE", JTracks, HfDsBases, "HFDSBASE", JMcParticles, HfDsPBases, "HFDSPBASE"); JETSUBSTRUCTURE_TABLES_DEF(DstarC, "DSTC", DstarCharged, dstarcharged, JTracks, HfDstarBases, "HFDSTBASE", JTrackDstarSubs, HfDstarBases, "HFDSTBASE", JTracks, HfDstarBases, "HFDSTBASE", JMcParticles, HfDstarPBases, "HFDSTPBASE"); JETSUBSTRUCTURE_TABLES_DEF(LcC, "LCC", LcCharged, lccharged, JTracks, HfLcBases, "HFLCBASE", JTrackLcSubs, HfLcBases, "HFLCBASE", JTracks, HfLcBases, "HFLCBASE", JMcParticles, HfLcPBases, "HFLCPBASE"); JETSUBSTRUCTURE_TABLES_DEF(B0C, "B0C", B0Charged, b0charged, JTracks, HfB0Bases, "HFB0BASE", JTrackB0Subs, HfB0Bases, "HFB0BASE", JTracks, HfB0Bases, "HFB0BASE", JMcParticles, HfB0PBases, "HFB0PBASE"); JETSUBSTRUCTURE_TABLES_DEF(BplusC, "BPC", BplusCharged, bpluscharged, JTracks, HfBplusBases, "HFBPBASE", JTrackBplusSubs, HfBplusBases, "HFBPBASE", JTracks, HfBplusBases, "HFBPBASE", JMcParticles, HfBplusPBases, "HFBPPBASE"); +JETSUBSTRUCTURE_TABLES_DEF(XicToXiPiPiC, "XICXPPC", XicToXiPiPiCharged, xictoxipipicharged, JTracks, HfXicToXiPiPiBases, "HFXICXPPBASE", JTrackXicToXiPiPiSubs, HfXicToXiPiPiBases, "HFXICXPPBASE", JTracks, HfXicToXiPiPiBases, "HFXICXPPBASE", JMcParticles, HfXicToXiPiPiPBases, "HFXICXPPPBASE"); JETSUBSTRUCTURE_TABLES_DEF(DielectronC, "DIELC", DielectronCharged, dielectroncharged, JTracks, Dielectrons, "RTDIELECTRON", JTrackDielectronSubs, Dielectrons, "RTDIELECTRON", JTracks, Dielectrons, "RTDIELECTRON", JMcParticles, JDielectronMcs, "JDIELMC"); } // namespace o2::aod diff --git a/PWGJE/DataModel/JetSubtraction.h b/PWGJE/DataModel/JetSubtraction.h index d22237380c7..0635ff8cb77 100644 --- a/PWGJE/DataModel/JetSubtraction.h +++ b/PWGJE/DataModel/JetSubtraction.h @@ -62,6 +62,16 @@ namespace bkgdplusmc DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, HfDplusPBases, "_0"); } // namespace bkgdplusmc +namespace bkgds +{ +DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, HfDsBases, "_0"); +} // namespace bkgds + +namespace bkgdsmc +{ +DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, HfDsPBases, "_0"); +} // namespace bkgdsmc + namespace bkgdstar { DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, HfDstarBases, "_0"); @@ -102,6 +112,16 @@ namespace bkgbplusmc DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, HfBplusPBases, "_0"); } // namespace bkgbplusmc +namespace bkgxictoxipipi +{ +DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, HfXicToXiPiPiBases, "_0"); +} // namespace bkgxictoxipipi + +namespace bkgxictoxipipimc +{ +DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, HfXicToXiPiPiPBases, "_0"); +} // namespace bkgxictoxipipimc + namespace bkgdielectron { DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, Dielectrons, "_0"); @@ -147,66 +167,90 @@ DECLARE_SOA_TABLE(BkgDplusMcRhos, "AOD", "BkgDPMcRho", bkgrho::RhoM, o2::soa::Marker<5>); -DECLARE_SOA_TABLE(BkgDstarRhos, "AOD", "BkgDSTRho", +DECLARE_SOA_TABLE(BkgDsRhos, "AOD", "BkgDSRho", o2::soa::Index<>, bkgrho::Rho, bkgrho::RhoM, o2::soa::Marker<6>); -DECLARE_SOA_TABLE(BkgDstarMcRhos, "AOD", "BkgDSTMcRho", +DECLARE_SOA_TABLE(BkgDsMcRhos, "AOD", "BkgDSMcRho", o2::soa::Index<>, bkgrho::Rho, bkgrho::RhoM, o2::soa::Marker<7>); -DECLARE_SOA_TABLE(BkgLcRhos, "AOD", "BkgLCRho", +DECLARE_SOA_TABLE(BkgDstarRhos, "AOD", "BkgDSTRho", o2::soa::Index<>, bkgrho::Rho, bkgrho::RhoM, o2::soa::Marker<8>); -DECLARE_SOA_TABLE(BkgLcMcRhos, "AOD", "BkgLCMcRho", +DECLARE_SOA_TABLE(BkgDstarMcRhos, "AOD", "BkgDSTMcRho", o2::soa::Index<>, bkgrho::Rho, bkgrho::RhoM, o2::soa::Marker<9>); -DECLARE_SOA_TABLE(BkgB0Rhos, "AOD", "BkgB0Rho", +DECLARE_SOA_TABLE(BkgLcRhos, "AOD", "BkgLCRho", o2::soa::Index<>, bkgrho::Rho, bkgrho::RhoM, o2::soa::Marker<10>); -DECLARE_SOA_TABLE(BkgB0McRhos, "AOD", "BkgB0McRho", +DECLARE_SOA_TABLE(BkgLcMcRhos, "AOD", "BkgLCMcRho", o2::soa::Index<>, bkgrho::Rho, bkgrho::RhoM, o2::soa::Marker<11>); -DECLARE_SOA_TABLE(BkgBplusRhos, "AOD", "BkgBPRho", +DECLARE_SOA_TABLE(BkgB0Rhos, "AOD", "BkgB0Rho", o2::soa::Index<>, bkgrho::Rho, bkgrho::RhoM, o2::soa::Marker<12>); -DECLARE_SOA_TABLE(BkgBplusMcRhos, "AOD", "BkgBPMcRho", +DECLARE_SOA_TABLE(BkgB0McRhos, "AOD", "BkgB0McRho", o2::soa::Index<>, bkgrho::Rho, bkgrho::RhoM, o2::soa::Marker<13>); -DECLARE_SOA_TABLE(BkgDielectronRhos, "AOD", "BkgDIELRho", +DECLARE_SOA_TABLE(BkgBplusRhos, "AOD", "BkgBPRho", o2::soa::Index<>, bkgrho::Rho, bkgrho::RhoM, o2::soa::Marker<14>); -DECLARE_SOA_TABLE(BkgDielectronMcRhos, "AOD", "BkgDIELMcRho", +DECLARE_SOA_TABLE(BkgBplusMcRhos, "AOD", "BkgBPMcRho", o2::soa::Index<>, bkgrho::Rho, bkgrho::RhoM, o2::soa::Marker<15>); +DECLARE_SOA_TABLE(BkgXicToXiPiPiRhos, "AOD", "BkgXICXPPRho", + o2::soa::Index<>, + bkgrho::Rho, + bkgrho::RhoM, + o2::soa::Marker<16>); + +DECLARE_SOA_TABLE(BkgXicToXiPiPiMcRhos, "AOD", "BkgXICXPPMcRho", + o2::soa::Index<>, + bkgrho::Rho, + bkgrho::RhoM, + o2::soa::Marker<17>); + +DECLARE_SOA_TABLE(BkgDielectronRhos, "AOD", "BkgDIELRho", + o2::soa::Index<>, + bkgrho::Rho, + bkgrho::RhoM, + o2::soa::Marker<18>); + +DECLARE_SOA_TABLE(BkgDielectronMcRhos, "AOD", "BkgDIELMcRho", + o2::soa::Index<>, + bkgrho::Rho, + bkgrho::RhoM, + o2::soa::Marker<19>); + DECLARE_SOA_TABLE(JTrackSubs, "AOD", "JTrackSubs", o2::soa::Index<>, bkgcharged::JCollisionId, @@ -312,6 +356,41 @@ DECLARE_SOA_TABLE(JMcParticleDplusSubs, "AOD", "JMcPartDPSubs", using JMcParticleDplusSub = JMcParticleDplusSubs::iterator; +DECLARE_SOA_TABLE(JTrackDsSubs, "AOD", "JTrackDSSubs", + o2::soa::Index<>, + bkgds::CandidateId, + jtrack::Pt, + jtrack::Eta, + jtrack::Phi, + jtrack::TrackSel, + jtrack::Px, + jtrack::Py, + jtrack::Pz, + jtrack::P, + jtrack::Energy); + +using JTrackDsSub = JTrackDsSubs::iterator; + +DECLARE_SOA_TABLE(JMcParticleDsSubs, "AOD", "JMcPartDSSubs", + o2::soa::Index<>, + bkgdsmc::CandidateId, + jmcparticle::Pt, + jmcparticle::Eta, + jmcparticle::Phi, + jmcparticle::Y, + jmcparticle::E, + jmcparticle::PdgCode, + jmcparticle::GenStatusCode, + jmcparticle::HepMCStatusCode, + jmcparticle::IsPhysicalPrimary, + jmcparticle::Px, + jmcparticle::Py, + jmcparticle::Pz, + jmcparticle::P, + jmcparticle::Energy); + +using JMcParticleDsSub = JMcParticleDsSubs::iterator; + DECLARE_SOA_TABLE(JTrackDstarSubs, "AOD", "JTrackDSTSubs", o2::soa::Index<>, bkgdstar::CandidateId, @@ -452,6 +531,41 @@ DECLARE_SOA_TABLE(JMcParticleBplusSubs, "AOD", "JMcPartBPSubs", using JMcParticleBplusSub = JMcParticleBplusSubs::iterator; +DECLARE_SOA_TABLE(JTrackXicToXiPiPiSubs, "AOD", "JTrackXICXPPCSubs", + o2::soa::Index<>, + bkgxictoxipipi::CandidateId, + jtrack::Pt, + jtrack::Eta, + jtrack::Phi, + jtrack::TrackSel, + jtrack::Px, + jtrack::Py, + jtrack::Pz, + jtrack::P, + jtrack::Energy); + +using JTrackXicToXiPiPiSub = JTrackXicToXiPiPiSubs::iterator; + +DECLARE_SOA_TABLE(JMcParticleXicToXiPiPiSubs, "AOD", "JMcPartXICXPPCSubs", + o2::soa::Index<>, + bkgxictoxipipimc::CandidateId, + jmcparticle::Pt, + jmcparticle::Eta, + jmcparticle::Phi, + jmcparticle::Y, + jmcparticle::E, + jmcparticle::PdgCode, + jmcparticle::GenStatusCode, + jmcparticle::HepMCStatusCode, + jmcparticle::IsPhysicalPrimary, + jmcparticle::Px, + jmcparticle::Py, + jmcparticle::Pz, + jmcparticle::P, + jmcparticle::Energy); + +using JMcParticleXicToXiPiPiSub = JMcParticleXicToXiPiPiSubs::iterator; + DECLARE_SOA_TABLE(JTrackDielectronSubs, "AOD", "JTrackDIELSubs", o2::soa::Index<>, bkgdielectron::CandidateId, diff --git a/PWGJE/JetFinders/CMakeLists.txt b/PWGJE/JetFinders/CMakeLists.txt index 86052ffbe88..396fe93a838 100644 --- a/PWGJE/JetFinders/CMakeLists.txt +++ b/PWGJE/JetFinders/CMakeLists.txt @@ -89,6 +89,21 @@ o2physics_add_dpl_workflow(jet-finder-dplus-mcp-charged PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(jet-finder-ds-data-charged + SOURCES jetFinderDsDataCharged.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(jet-finder-ds-mcd-charged + SOURCES jetFinderDsMCDCharged.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(jet-finder-ds-mcp-charged + SOURCES jetFinderDsMCPCharged.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-finder-dstar-data-charged SOURCES jetFinderDstarDataCharged.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport @@ -149,6 +164,21 @@ o2physics_add_dpl_workflow(jet-finder-bplus-mcp-charged PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(jet-finder-xictoxipipi-data-charged + SOURCES jetFinderXicToXiPiPiDataCharged.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(jet-finder-xictoxipipi-mcd-charged + SOURCES jetFinderXicToXiPiPiMCDCharged.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(jet-finder-xictoxipipi-mcp-charged + SOURCES jetFinderXicToXiPiPiMCPCharged.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-finder-v0-data-charged SOURCES jetFinderV0DataCharged.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport diff --git a/PWGJE/JetFinders/jetFinder.cxx b/PWGJE/JetFinders/jetFinder.cxx index 990286c61eb..93a257360c9 100644 --- a/PWGJE/JetFinders/jetFinder.cxx +++ b/PWGJE/JetFinders/jetFinder.cxx @@ -157,9 +157,9 @@ struct JetFinderTask { double jetPtMaxDouble = static_cast(jetPtMaxInt); if (fillTHnSparse) { - registry.add("hJet", "sparse for data or mcd jets", {HistType::kTHnC, {{jetRadiiBins, ""}, {jetPtBinNumber, jetPtMinDouble, jetPtMaxDouble}, {40, -1.0, 1.0}, {18, 0.0, 7.0}}}); - registry.add("hJetEWS", "sparse for data or mcd event-wise subtracted jets", {HistType::kTHnC, {{jetRadiiBins, ""}, {jetPtBinNumber, jetPtMinDouble, jetPtMaxDouble}, {40, -1.0, 1.0}, {18, 0.0, 7.0}}}); - registry.add("hJetMCP", "sparse for mcp jets", {HistType::kTHnC, {{jetRadiiBins, ""}, {jetPtBinNumber, jetPtMinDouble, jetPtMaxDouble}, {40, -1.0, 1.0}, {18, 0.0, 7.0}}}); + registry.add("hJet", "sparse for data or mcd jets", {HistType::kTHnD, {{jetRadiiBins, ""}, {jetPtBinNumber, jetPtMinDouble, jetPtMaxDouble}, {40, -1.0, 1.0}, {18, 0.0, 7.0}}}); + registry.add("hJetEWS", "sparse for data or mcd event-wise subtracted jets", {HistType::kTHnD, {{jetRadiiBins, ""}, {jetPtBinNumber, jetPtMinDouble, jetPtMaxDouble}, {40, -1.0, 1.0}, {18, 0.0, 7.0}}}); + registry.add("hJetMCP", "sparse for mcp jets", {HistType::kTHnD, {{jetRadiiBins, ""}, {jetPtBinNumber, jetPtMinDouble, jetPtMaxDouble}, {40, -1.0, 1.0}, {18, 0.0, 7.0}}}); } } diff --git a/PWGJE/JetFinders/jetFinderDsDataCharged.cxx b/PWGJE/JetFinders/jetFinderDsDataCharged.cxx new file mode 100644 index 00000000000..a822389b6d4 --- /dev/null +++ b/PWGJE/JetFinders/jetFinderDsDataCharged.cxx @@ -0,0 +1,38 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// jet finder Ds data charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/JetFinders/jetFinderHF.cxx" + +#include "PWGJE/DataModel/Jet.h" + +#include +#include +#include +#include + +#include + +using JetFinderDsDataCharged = JetFinderHFTask; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + + tasks.emplace_back(adaptAnalysisTask(cfgc, + SetDefaultProcesses{{{"processChargedJetsData", true}}}, + TaskName{"jet-finder-ds-data-charged"})); + + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/JetFinders/jetFinderDsMCDCharged.cxx b/PWGJE/JetFinders/jetFinderDsMCDCharged.cxx new file mode 100644 index 00000000000..004a732f9a2 --- /dev/null +++ b/PWGJE/JetFinders/jetFinderDsMCDCharged.cxx @@ -0,0 +1,38 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// jet finder Ds mcd charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/JetFinders/jetFinderHF.cxx" + +#include "PWGJE/DataModel/Jet.h" + +#include +#include +#include +#include + +#include + +using JetFinderDsMCDetectorLevelCharged = JetFinderHFTask; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + + tasks.emplace_back(adaptAnalysisTask(cfgc, + SetDefaultProcesses{{{"processChargedJetsMCD", true}}}, + TaskName{"jet-finder-ds-mcd-charged"})); + + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/JetFinders/jetFinderDsMCPCharged.cxx b/PWGJE/JetFinders/jetFinderDsMCPCharged.cxx new file mode 100644 index 00000000000..5c9b54543b2 --- /dev/null +++ b/PWGJE/JetFinders/jetFinderDsMCPCharged.cxx @@ -0,0 +1,38 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// jet finder Ds mcp charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/JetFinders/jetFinderHF.cxx" + +#include "PWGJE/DataModel/Jet.h" + +#include +#include +#include +#include + +#include + +using JetFinderDsMCParticleLevelCharged = JetFinderHFTask; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + + tasks.emplace_back(adaptAnalysisTask(cfgc, + SetDefaultProcesses{{{"processChargedJetsMCP", true}}}, + TaskName{"jet-finder-ds-mcp-charged"})); + + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/JetFinders/jetFinderHF.cxx b/PWGJE/JetFinders/jetFinderHF.cxx index 34409335767..b32921de7b7 100644 --- a/PWGJE/JetFinders/jetFinderHF.cxx +++ b/PWGJE/JetFinders/jetFinderHF.cxx @@ -163,8 +163,8 @@ struct JetFinderHFTask { double jetPtMinDouble = static_cast(jetPtMinInt); double jetPtMaxDouble = static_cast(jetPtMaxInt); - registry.add("hJet", "sparse for data or mcd jets", {HistType::kTHnC, {{jetRadiiBins, ""}, {jetPtBinNumber, jetPtMinDouble, jetPtMaxDouble}, {40, -1.0, 1.0}, {18, 0.0, 7.0}}}); - registry.add("hJetMCP", "sparse for mcp jets", {HistType::kTHnC, {{jetRadiiBins, ""}, {jetPtBinNumber, jetPtMinDouble, jetPtMaxDouble}, {40, -1.0, 1.0}, {18, 0.0, 7.0}}}); + registry.add("hJet", "sparse for data or mcd jets", {HistType::kTHnD, {{jetRadiiBins, ""}, {jetPtBinNumber, jetPtMinDouble, jetPtMaxDouble}, {40, -1.0, 1.0}, {18, 0.0, 7.0}}}); + registry.add("hJetMCP", "sparse for mcp jets", {HistType::kTHnD, {{jetRadiiBins, ""}, {jetPtBinNumber, jetPtMinDouble, jetPtMaxDouble}, {40, -1.0, 1.0}, {18, 0.0, 7.0}}}); } aod::EMCALClusterDefinition clusterDefinition = aod::emcalcluster::getClusterDefinitionFromString(clusterDefinitionS.value); @@ -179,6 +179,8 @@ struct JetFinderHFTask { PresliceOptional> perD0McCandidate = aod::bkgd0mc::candidateId; PresliceOptional> perDplusCandidate = aod::bkgdplus::candidateId; PresliceOptional> perDplusMcCandidate = aod::bkgdplusmc::candidateId; + PresliceOptional> perDsCandidate = aod::bkgds::candidateId; + PresliceOptional> perDsMcCandidate = aod::bkgdsmc::candidateId; PresliceOptional> perDstarCandidate = aod::bkgdstar::candidateId; PresliceOptional> perDstarMcCandidate = aod::bkgdstarmc::candidateId; PresliceOptional> perLcCandidate = aod::bkglc::candidateId; @@ -187,6 +189,8 @@ struct JetFinderHFTask { PresliceOptional> perB0McCandidate = aod::bkgb0mc::candidateId; PresliceOptional> perBplusCandidate = aod::bkgbplus::candidateId; PresliceOptional> perBplusMcCandidate = aod::bkgbplusmc::candidateId; + PresliceOptional> perXicToXiPiPiCandidate = aod::bkgxictoxipipi::candidateId; + PresliceOptional> perXicToXiPiPiMcCandidate = aod::bkgxictoxipipimc::candidateId; PresliceOptional> perDielectronCandidate = aod::bkgdielectron::candidateId; PresliceOptional> perDielectronMcCandidate = aod::bkgdielectronmc::candidateId; @@ -254,7 +258,7 @@ struct JetFinderHFTask { void processChargedEvtWiseSubJetsData(soa::Filtered::iterator const& collision, soa::Filtered const& tracks, CandidateTableData const& candidates) { for (typename CandidateTableData::iterator const& candidate : candidates) { - analyseCharged(collision, jetcandidateutilities::slicedPerCandidate(tracks, candidate, perD0Candidate, perDplusCandidate, perDstarCandidate, perLcCandidate, perB0Candidate, perBplusCandidate, perDielectronCandidate), candidate, jetsEvtWiseSubTable, constituentsEvtWiseSubTable, tracks, jetEWSPtMin, jetEWSPtMax); + analyseCharged(collision, jetcandidateutilities::slicedPerCandidate(tracks, candidate, perD0Candidate, perDplusCandidate, perDsCandidate, perDstarCandidate, perLcCandidate, perB0Candidate, perBplusCandidate, perXicToXiPiPiCandidate, perDielectronCandidate), candidate, jetsEvtWiseSubTable, constituentsEvtWiseSubTable, tracks, jetEWSPtMin, jetEWSPtMax); } } PROCESS_SWITCH(JetFinderHFTask, processChargedEvtWiseSubJetsData, "charged hf jet finding on data with event-wise constituent subtraction", false); @@ -270,7 +274,7 @@ struct JetFinderHFTask { void processChargedEvtWiseSubJetsMCD(soa::Filtered::iterator const& collision, soa::Filtered const& tracks, CandidateTableMCD const& candidates) { for (typename CandidateTableMCD::iterator const& candidate : candidates) { - analyseCharged(collision, jetcandidateutilities::slicedPerCandidate(tracks, candidate, perD0Candidate, perDplusCandidate, perDstarCandidate, perLcCandidate, perB0Candidate, perBplusCandidate, perDielectronCandidate), candidate, jetsEvtWiseSubTable, constituentsEvtWiseSubTable, tracks, jetEWSPtMin, jetEWSPtMax); + analyseCharged(collision, jetcandidateutilities::slicedPerCandidate(tracks, candidate, perD0Candidate, perDplusCandidate, perDsCandidate, perDstarCandidate, perLcCandidate, perB0Candidate, perBplusCandidate, perXicToXiPiPiCandidate, perDielectronCandidate), candidate, jetsEvtWiseSubTable, constituentsEvtWiseSubTable, tracks, jetEWSPtMin, jetEWSPtMax); } } PROCESS_SWITCH(JetFinderHFTask, processChargedEvtWiseSubJetsMCD, "charged hf jet finding on MC detector level with event-wise constituent subtraction", false); @@ -290,7 +294,7 @@ struct JetFinderHFTask { CandidateTableMCP const& candidates) { for (typename CandidateTableMCP::iterator const& candidate : candidates) { - analyseMCP(collision, jetcandidateutilities::slicedPerCandidate(particles, candidate, perD0McCandidate, perDplusMcCandidate, perDstarMcCandidate, perLcMcCandidate, perB0McCandidate, perBplusMcCandidate, perDielectronMcCandidate), candidate, 1, jetPtMin, jetPtMax); + analyseMCP(collision, jetcandidateutilities::slicedPerCandidate(particles, candidate, perD0McCandidate, perDplusMcCandidate, perDsMcCandidate, perDstarMcCandidate, perLcMcCandidate, perB0McCandidate, perBplusMcCandidate, perXicToXiPiPiMcCandidate, perDielectronMcCandidate), candidate, 1, jetPtMin, jetPtMax); } } PROCESS_SWITCH(JetFinderHFTask, processChargedEvtWiseSubJetsMCP, "hf jet finding on MC particle level", false); diff --git a/PWGJE/JetFinders/jetFinderV0.cxx b/PWGJE/JetFinders/jetFinderV0.cxx index 6d8b94d905a..ef4aaba93ab 100644 --- a/PWGJE/JetFinders/jetFinderV0.cxx +++ b/PWGJE/JetFinders/jetFinderV0.cxx @@ -153,8 +153,8 @@ struct JetFinderV0Task { double jetPtMinDouble = static_cast(jetPtMinInt); double jetPtMaxDouble = static_cast(jetPtMaxInt); - registry.add("hJet", "sparse for data or mcd jets", {HistType::kTHnC, {{jetRadiiBins, ""}, {jetPtBinNumber, jetPtMinDouble, jetPtMaxDouble}, {40, -1.0, 1.0}, {18, 0.0, 7.0}}}); - registry.add("hJetMCP", "sparse for mcp jets", {HistType::kTHnC, {{jetRadiiBins, ""}, {jetPtBinNumber, jetPtMinDouble, jetPtMaxDouble}, {40, -1.0, 1.0}, {18, 0.0, 7.0}}}); + registry.add("hJet", "sparse for data or mcd jets", {HistType::kTHnD, {{jetRadiiBins, ""}, {jetPtBinNumber, jetPtMinDouble, jetPtMaxDouble}, {40, -1.0, 1.0}, {18, 0.0, 7.0}}}); + registry.add("hJetMCP", "sparse for mcp jets", {HistType::kTHnD, {{jetRadiiBins, ""}, {jetPtBinNumber, jetPtMinDouble, jetPtMaxDouble}, {40, -1.0, 1.0}, {18, 0.0, 7.0}}}); } Filter collisionFilter = (nabs(aod::jcollision::posZ) < vertexZCut && aod::jcollision::centFT0M >= centralityMin && aod::jcollision::centFT0M < centralityMax && aod::jcollision::trackOccupancyInTimeRange <= trackOccupancyInTimeRangeMax && ((skipMBGapEvents.node() == false) || (aod::jcollision::subGeneratorId != static_cast(jetderiveddatautilities::JCollisionSubGeneratorId::mbGap)))); diff --git a/PWGJE/JetFinders/jetFinderXicToXiPiPiDataCharged.cxx b/PWGJE/JetFinders/jetFinderXicToXiPiPiDataCharged.cxx new file mode 100644 index 00000000000..3ed339e8a32 --- /dev/null +++ b/PWGJE/JetFinders/jetFinderXicToXiPiPiDataCharged.cxx @@ -0,0 +1,38 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// jet finder XicToXiPiPi data charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/JetFinders/jetFinderHF.cxx" + +#include "PWGJE/DataModel/Jet.h" + +#include +#include +#include +#include + +#include + +using JetFinderXicToXiPiPiDataCharged = JetFinderHFTask; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + + tasks.emplace_back(adaptAnalysisTask(cfgc, + SetDefaultProcesses{{{"processChargedJetsData", true}}}, + TaskName{"jet-finder-xictoxipipi-data-charged"})); + + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/JetFinders/jetFinderXicToXiPiPiMCDCharged.cxx b/PWGJE/JetFinders/jetFinderXicToXiPiPiMCDCharged.cxx new file mode 100644 index 00000000000..64c35fe78c6 --- /dev/null +++ b/PWGJE/JetFinders/jetFinderXicToXiPiPiMCDCharged.cxx @@ -0,0 +1,38 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// jet finder D+ mcd charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/JetFinders/jetFinderHF.cxx" + +#include "PWGJE/DataModel/Jet.h" + +#include +#include +#include +#include + +#include + +using JetFinderXicToXiPiPiMCDetectorLevelCharged = JetFinderHFTask; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + + tasks.emplace_back(adaptAnalysisTask(cfgc, + SetDefaultProcesses{{{"processChargedJetsMCD", true}}}, + TaskName{"jet-finder-xictoxipipi-mcd-charged"})); + + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/JetFinders/jetFinderXicToXiPiPiMCPCharged.cxx b/PWGJE/JetFinders/jetFinderXicToXiPiPiMCPCharged.cxx new file mode 100644 index 00000000000..ca4cc98938f --- /dev/null +++ b/PWGJE/JetFinders/jetFinderXicToXiPiPiMCPCharged.cxx @@ -0,0 +1,38 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// jet finder D+ mcp charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/JetFinders/jetFinderHF.cxx" + +#include "PWGJE/DataModel/Jet.h" + +#include +#include +#include +#include + +#include + +using JetFinderXicToXiPiPiMCParticleLevelCharged = JetFinderHFTask; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + + tasks.emplace_back(adaptAnalysisTask(cfgc, + SetDefaultProcesses{{{"processChargedJetsMCP", true}}}, + TaskName{"jet-finder-xictoxipipi-mcp-charged"})); + + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/TableProducer/Matching/CMakeLists.txt b/PWGJE/TableProducer/Matching/CMakeLists.txt index e6526d90f1e..a5450dfb05e 100644 --- a/PWGJE/TableProducer/Matching/CMakeLists.txt +++ b/PWGJE/TableProducer/Matching/CMakeLists.txt @@ -39,6 +39,11 @@ o2physics_add_dpl_workflow(jet-matching-mc-dplus-ch PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(jet-matching-mc-ds-ch + SOURCES jetMatchingMCDsCharged.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-matching-mc-dstar-ch SOURCES jetMatchingMCDstarCharged.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport @@ -59,6 +64,11 @@ o2physics_add_dpl_workflow(jet-matching-mc-bplus-ch PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(jet-matching-mc-xictoxipipi-ch + SOURCES jetMatchingMCXicToXiPiPiCharged.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-matching-mc-dielectron-ch SOURCES jetMatchingMCDielectronCharged.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport @@ -84,6 +94,11 @@ o2physics_add_dpl_workflow(jet-matching-mc-sub-dplus-ch PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(jet-matching-mc-sub-ds-ch + SOURCES jetMatchingMCSubDsCharged.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-matching-mc-sub-dstar-ch SOURCES jetMatchingMCSubDstarCharged.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport @@ -104,6 +119,11 @@ o2physics_add_dpl_workflow(jet-matching-mc-sub-bplus-ch PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(jet-matching-mc-sub-xictoxipipi-ch + SOURCES jetMatchingMCSubXicToXiPiPiCharged.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-matching-mc-sub-dielectron-ch SOURCES jetMatchingMCSubDielectronCharged.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport @@ -124,6 +144,11 @@ o2physics_add_dpl_workflow(jet-matching-sub-dplus-ch PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(jet-matching-sub-ds-ch + SOURCES jetMatchingSubDsCharged.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-matching-sub-dstar-ch SOURCES jetMatchingSubDstarCharged.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport @@ -144,6 +169,11 @@ o2physics_add_dpl_workflow(jet-matching-sub-b0-ch PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(jet-matching-sub-xictoxipipi-ch + SOURCES jetMatchingSubXicToXiPiPiCharged.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-matching-sub-dielectron-ch SOURCES jetMatchingSubDielectronCharged.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport diff --git a/PWGJE/TableProducer/Matching/Substructure/CMakeLists.txt b/PWGJE/TableProducer/Matching/Substructure/CMakeLists.txt index e004a0a52ee..238e84ddc91 100644 --- a/PWGJE/TableProducer/Matching/Substructure/CMakeLists.txt +++ b/PWGJE/TableProducer/Matching/Substructure/CMakeLists.txt @@ -27,6 +27,11 @@ o2physics_add_dpl_workflow(jet-substructure-matching-mc-dplus-ch PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(jet-substructure-matching-mc-ds-ch + SOURCES jetSubstructureMatchingMCDsCharged.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-substructure-matching-mc-dstar-ch SOURCES jetSubstructureMatchingMCDstarCharged.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport @@ -47,6 +52,11 @@ o2physics_add_dpl_workflow(jet-substructure-matching-mc-bplus-ch PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(jet-substructure-matching-mc-xictoxipipi-ch + SOURCES jetSubstructureMatchingMCXicToXiPiPiCharged.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-substructure-matching-mc-dielectron-ch SOURCES jetSubstructureMatchingMCDielectronCharged.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport @@ -67,6 +77,11 @@ o2physics_add_dpl_workflow(jet-substructure-matching-sub-dplus-ch PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(jet-substructure-matching-sub-ds-ch + SOURCES jetSubstructureMatchingSubDsCharged.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-substructure-matching-sub-dstar-ch SOURCES jetSubstructureMatchingSubDstarCharged.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport @@ -87,6 +102,11 @@ o2physics_add_dpl_workflow(jet-substructure-matching-sub-bplus-ch PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(jet-substructure-matching-sub-xictoxipipi-ch + SOURCES jetSubstructureMatchingSubXicToXiPiPiCharged.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-substructure-matching-sub-dielectron-ch SOURCES jetSubstructureMatchingSubDielectronCharged.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport diff --git a/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatching.cxx b/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatching.cxx index 02b4c1b87d1..8cca2025f5e 100644 --- a/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatching.cxx +++ b/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatching.cxx @@ -61,6 +61,8 @@ struct JetSubstructureMatching { PresliceOptional TagSplittingsPerTagJetD0 = aod::d0chargedmcparticlelevelsplitting::jetId; PresliceOptional BaseSplittingsPerBaseJetDplus = aod::dpluschargedmcdetectorlevelsplitting::jetId; PresliceOptional TagSplittingsPerTagJetDplus = aod::dpluschargedmcparticlelevelsplitting::jetId; + PresliceOptional BaseSplittingsPerBaseJetDs = aod::dschargedmcdetectorlevelsplitting::jetId; + PresliceOptional TagSplittingsPerTagJetDs = aod::dschargedmcparticlelevelsplitting::jetId; PresliceOptional BaseSplittingsPerBaseJetDstar = aod::dstarchargedmcdetectorlevelsplitting::jetId; PresliceOptional TagSplittingsPerTagJetDstar = aod::dstarchargedmcparticlelevelsplitting::jetId; PresliceOptional BaseSplittingsPerBaseJetLc = aod::lcchargedmcdetectorlevelsplitting::jetId; @@ -69,6 +71,8 @@ struct JetSubstructureMatching { PresliceOptional TagSplittingsPerTagJetB0 = aod::b0chargedmcparticlelevelsplitting::jetId; PresliceOptional BaseSplittingsPerBaseJetBplus = aod::bpluschargedmcdetectorlevelsplitting::jetId; PresliceOptional TagSplittingsPerTagJetBplus = aod::bpluschargedmcparticlelevelsplitting::jetId; + PresliceOptional BaseSplittingsPerBaseJetXicToXiPiPi = aod::xictoxipipichargedmcdetectorlevelsplitting::jetId; + PresliceOptional TagSplittingsPerTagJetXicToXiPiPi = aod::xictoxipipichargedmcparticlelevelsplitting::jetId; PresliceOptional BaseSplittingsPerBaseJetDielectron = aod::dielectronchargedmcdetectorlevelsplitting::jetId; PresliceOptional TagSplittingsPerTagJetDielectron = aod::dielectronchargedmcparticlelevelsplitting::jetId; @@ -78,6 +82,8 @@ struct JetSubstructureMatching { PresliceOptional TagPairsPerTagJetD0 = aod::d0chargedmcparticlelevelpair::jetId; PresliceOptional BasePairsPerBaseJetDplus = aod::dpluschargedmcdetectorlevelpair::jetId; PresliceOptional TagPairsPerTagJetDplus = aod::dpluschargedmcparticlelevelpair::jetId; + PresliceOptional BasePairsPerBaseJetDs = aod::dschargedmcdetectorlevelpair::jetId; + PresliceOptional TagPairsPerTagJetDs = aod::dschargedmcparticlelevelpair::jetId; PresliceOptional BasePairsPerBaseJetDstar = aod::dstarchargedmcdetectorlevelpair::jetId; PresliceOptional TagPairsPerTagJetDstar = aod::dstarchargedmcparticlelevelpair::jetId; PresliceOptional BasePairsPerBaseJetLc = aod::lcchargedmcdetectorlevelpair::jetId; @@ -86,15 +92,17 @@ struct JetSubstructureMatching { PresliceOptional TagPairsPerTagJetB0 = aod::b0chargedmcparticlelevelpair::jetId; PresliceOptional BasePairsPerBaseJetBplus = aod::bpluschargedmcdetectorlevelpair::jetId; PresliceOptional TagPairsPerTagJetBplus = aod::bpluschargedmcparticlelevelpair::jetId; + PresliceOptional BasePairsPerBaseJetXicToXiPiPi = aod::xictoxipipichargedmcdetectorlevelpair::jetId; + PresliceOptional TagPairsPerTagJetXicToXiPiPi = aod::xictoxipipichargedmcparticlelevelpair::jetId; PresliceOptional BasePairsPerBaseJetDielectron = aod::dielectronchargedmcdetectorlevelpair::jetId; PresliceOptional TagPairsPerTagJetDielectron = aod::dielectronchargedmcparticlelevelpair::jetId; // workaround till binding nodes can be passed as template arguments - template - auto slicedPerJetForMatching(T const& table, U const& jet, V const& perIncluisveJet, M const& perD0Jet, N const& perDplusJet, O const& perDstarJet, P const& perLcJet, Q const& perB0Jet, R const& perBplusJet, S const& perDielectronJet) + template + auto slicedPerJetForMatching(T const& table, U const& jet, V const& perIncluisveJet, M const& perD0Jet, N const& perDplusJet, O const& perDsJet, P const& perDstarJet, Q const& perLcJet, R const& perB0Jet, S const& perBplusJet, A const& perXicToXiPiPiJet, B const& perDielectronJet) { if constexpr (jethfutilities::isHFTable() || jethfutilities::isHFMcTable()) { - return jethfutilities::slicedPerHFJet(table, jet, perD0Jet, perDplusJet, perDstarJet, perLcJet, perB0Jet, perBplusJet); + return jethfutilities::slicedPerHFJet(table, jet, perD0Jet, perDplusJet, perDsJet, perDstarJet, perLcJet, perB0Jet, perBplusJet, perXicToXiPiPiJet); } else if constexpr (jetdqutilities::isDielectronTable() || jetdqutilities::isDielectronMcTable()) { return jetdqutilities::slicedPerDielectronJet(table, jet, perDielectronJet); } else { @@ -157,14 +165,14 @@ struct JetSubstructureMatching { } if (hasMatchedJet) { // auto const& jetTagSplittings = jetsTagSplittings.sliceBy(TagSplittingsPerTagJet, jetTag.globalIndex()); - auto const& jetTagSplittings = slicedPerJetForMatching(jetsTagSplittings, jetTag, TagSplittingsPerTagJetInclusive, TagSplittingsPerTagJetD0, TagSplittingsPerTagJetDplus, TagSplittingsPerTagJetDstar, TagSplittingsPerTagJetLc, TagSplittingsPerTagJetB0, TagSplittingsPerTagJetBplus, TagSplittingsPerTagJetDielectron); + auto const& jetTagSplittings = slicedPerJetForMatching(jetsTagSplittings, jetTag, TagSplittingsPerTagJetInclusive, TagSplittingsPerTagJetD0, TagSplittingsPerTagJetDplus, TagSplittingsPerTagJetDs, TagSplittingsPerTagJetDstar, TagSplittingsPerTagJetLc, TagSplittingsPerTagJetB0, TagSplittingsPerTagJetBplus, TagSplittingsPerTagJetXicToXiPiPi, TagSplittingsPerTagJetDielectron); int tagSplittingIndex = 0; for (auto const& jetTagSplitting : jetTagSplittings) { jetTagSplittingsMap[jetTagSplitting.globalIndex()] = tagSplittingIndex; tagSplittingIndex++; } // auto const& jetTagPairs = jetsTagPairs.sliceBy(TagPairsPerTagJet, jetTag.globalIndex()); - auto const& jetTagPairs = slicedPerJetForMatching(jetsTagPairs, jetTag, TagPairsPerTagJetInclusive, TagPairsPerTagJetD0, TagPairsPerTagJetDplus, TagPairsPerTagJetDstar, TagPairsPerTagJetLc, TagPairsPerTagJetB0, TagPairsPerTagJetBplus, TagPairsPerTagJetDielectron); + auto const& jetTagPairs = slicedPerJetForMatching(jetsTagPairs, jetTag, TagPairsPerTagJetInclusive, TagPairsPerTagJetD0, TagPairsPerTagJetDplus, TagPairsPerTagJetDs, TagPairsPerTagJetDstar, TagPairsPerTagJetLc, TagPairsPerTagJetB0, TagPairsPerTagJetBplus, TagPairsPerTagJetXicToXiPiPi, TagPairsPerTagJetDielectron); int tagPairIndex = 0; for (auto const& jetTagPair : jetTagPairs) { jetTagPairsMap[jetTagPair.globalIndex()] = tagPairIndex; @@ -205,7 +213,7 @@ struct JetSubstructureMatching { } } // auto const& jetBaseSplittings = jetsBaseSplittings.sliceBy(BaseSplittingsPerBaseJet, jetBase.globalIndex()); - auto const& jetBaseSplittings = slicedPerJetForMatching(jetsBaseSplittings, jetBase, BaseSplittingsPerBaseJetInclusive, BaseSplittingsPerBaseJetD0, BaseSplittingsPerBaseJetDplus, BaseSplittingsPerBaseJetDstar, BaseSplittingsPerBaseJetLc, BaseSplittingsPerBaseJetB0, BaseSplittingsPerBaseJetBplus, BaseSplittingsPerBaseJetDielectron); + auto const& jetBaseSplittings = slicedPerJetForMatching(jetsBaseSplittings, jetBase, BaseSplittingsPerBaseJetInclusive, BaseSplittingsPerBaseJetD0, BaseSplittingsPerBaseJetDplus, BaseSplittingsPerBaseJetDs, BaseSplittingsPerBaseJetDstar, BaseSplittingsPerBaseJetLc, BaseSplittingsPerBaseJetB0, BaseSplittingsPerBaseJetBplus, BaseSplittingsPerBaseJetXicToXiPiPi, BaseSplittingsPerBaseJetDielectron); int baseSplittingIndex = 0; for (auto const& jetBaseSplitting : jetBaseSplittings) { jetBaseSplittingsMap[jetBaseSplitting.globalIndex()] = baseSplittingIndex; @@ -213,7 +221,7 @@ struct JetSubstructureMatching { } jetmatchingutilities::doAllMatching(jetBaseSplittings, jetTagSplittings, jetsBasetoTagSplittingsMatchingGeo, jetsBasetoTagSplittingsMatchingPt, jetsBasetoTagSplittingsMatchingHF, jetsTagtoBaseSplittingsMatchingGeo, jetsTagtoBaseSplittingsMatchingPt, jetsTagtoBaseSplittingsMatchingHF, candidatesBase, tracksBase, clustersBase, candidatesTag, tracksTag, tracksTag, doMatchingGeo, doMatchingHf, doMatchingPt, maxMatchingDistance, minPtFraction); // auto const& jetBasePairs = jetsBasePairs.sliceBy(BasePairsPerBaseJet, jetBase.globalIndex()); - auto const& jetBasePairs = slicedPerJetForMatching(jetsBasePairs, jetBase, BasePairsPerBaseJetInclusive, BasePairsPerBaseJetD0, BasePairsPerBaseJetDplus, BasePairsPerBaseJetDstar, BasePairsPerBaseJetLc, BasePairsPerBaseJetB0, BasePairsPerBaseJetBplus, BasePairsPerBaseJetDielectron); + auto const& jetBasePairs = slicedPerJetForMatching(jetsBasePairs, jetBase, BasePairsPerBaseJetInclusive, BasePairsPerBaseJetD0, BasePairsPerBaseJetDplus, BasePairsPerBaseJetDs, BasePairsPerBaseJetDstar, BasePairsPerBaseJetLc, BasePairsPerBaseJetB0, BasePairsPerBaseJetBplus, BasePairsPerBaseJetXicToXiPiPi, BasePairsPerBaseJetDielectron); int basePairIndex = 0; for (auto const& jetBasePair : jetBasePairs) { jetBasePairsMap[jetBasePair.globalIndex()] = basePairIndex; diff --git a/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatchingMCDsCharged.cxx b/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatchingMCDsCharged.cxx new file mode 100644 index 00000000000..e6e76c930be --- /dev/null +++ b/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatchingMCDsCharged.cxx @@ -0,0 +1,51 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// Ds substructure matching mc charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatching.cxx" + +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetReducedData.h" +#include "PWGJE/DataModel/JetSubstructure.h" + +#include +#include +#include +#include +#include + +#include + +using DsChargedJetSubstructureMatchingMC = JetSubstructureMatching, + soa::Join, + aod::DsChargedMCDetectorLevelSPsMatchedToDsChargedMCParticleLevelSPs, + aod::DsChargedMCParticleLevelSPsMatchedToDsChargedMCDetectorLevelSPs, + aod::DsChargedMCDetectorLevelPRsMatchedToDsChargedMCParticleLevelPRs, + aod::DsChargedMCParticleLevelPRsMatchedToDsChargedMCDetectorLevelPRs, + aod::DsChargedMCDetectorLevelSPs, + aod::DsChargedMCParticleLevelSPs, + aod::DsChargedMCDetectorLevelPRs, + aod::DsChargedMCParticleLevelPRs, + aod::CandidatesDsMCD, + aod::CandidatesDsMCP, + aod::JetTracksMCD, + aod::JetParticles, + aod::JDummys>; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-substructure-matching-mc-ds-ch"})); + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatchingMCXicToXiPiPiCharged.cxx b/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatchingMCXicToXiPiPiCharged.cxx new file mode 100644 index 00000000000..b0eea7a3e6d --- /dev/null +++ b/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatchingMCXicToXiPiPiCharged.cxx @@ -0,0 +1,51 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// XicToXiPiPi substructure matching mc charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatching.cxx" + +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetReducedData.h" +#include "PWGJE/DataModel/JetSubstructure.h" + +#include +#include +#include +#include +#include + +#include + +using XicToXiPiPiChargedJetSubstructureMatchingMC = JetSubstructureMatching, + soa::Join, + aod::XicToXiPiPiChargedMCDetectorLevelSPsMatchedToXicToXiPiPiChargedMCParticleLevelSPs, + aod::XicToXiPiPiChargedMCParticleLevelSPsMatchedToXicToXiPiPiChargedMCDetectorLevelSPs, + aod::XicToXiPiPiChargedMCDetectorLevelPRsMatchedToXicToXiPiPiChargedMCParticleLevelPRs, + aod::XicToXiPiPiChargedMCParticleLevelPRsMatchedToXicToXiPiPiChargedMCDetectorLevelPRs, + aod::XicToXiPiPiChargedMCDetectorLevelSPs, + aod::XicToXiPiPiChargedMCParticleLevelSPs, + aod::XicToXiPiPiChargedMCDetectorLevelPRs, + aod::XicToXiPiPiChargedMCParticleLevelPRs, + aod::CandidatesXicToXiPiPiMCD, + aod::CandidatesXicToXiPiPiMCP, + aod::JetTracksMCD, + aod::JetParticles, + aod::JDummys>; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-substructure-matching-mc-xictoxipipi-ch"})); + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatchingSub.cxx b/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatchingSub.cxx index 179a4b96b05..bad062a3044 100644 --- a/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatchingSub.cxx +++ b/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatchingSub.cxx @@ -62,6 +62,8 @@ struct JetSubstructureMatchingSub { PresliceOptional TagSplittingsPerTagJetD0 = aod::d0chargedeventwisesubtractedsplitting::jetId; PresliceOptional BaseSplittingsPerBaseJetDplus = aod::dpluschargedsplitting::jetId; PresliceOptional TagSplittingsPerTagJetDplus = aod::dpluschargedeventwisesubtractedsplitting::jetId; + PresliceOptional BaseSplittingsPerBaseJetDs = aod::dschargedsplitting::jetId; + PresliceOptional TagSplittingsPerTagJetDs = aod::dschargedeventwisesubtractedsplitting::jetId; PresliceOptional BaseSplittingsPerBaseJetDstar = aod::dstarchargedsplitting::jetId; PresliceOptional TagSplittingsPerTagJetDstar = aod::dstarchargedeventwisesubtractedsplitting::jetId; PresliceOptional BaseSplittingsPerBaseJetLc = aod::lcchargedsplitting::jetId; @@ -70,6 +72,8 @@ struct JetSubstructureMatchingSub { PresliceOptional TagSplittingsPerTagJetB0 = aod::b0chargedeventwisesubtractedsplitting::jetId; PresliceOptional BaseSplittingsPerBaseJetBplus = aod::bpluschargedsplitting::jetId; PresliceOptional TagSplittingsPerTagJetBplus = aod::bpluschargedeventwisesubtractedsplitting::jetId; + PresliceOptional BaseSplittingsPerBaseJetXicToXiPiPi = aod::xictoxipipichargedsplitting::jetId; + PresliceOptional TagSplittingsPerTagJetXicToXiPiPi = aod::xictoxipipichargedeventwisesubtractedsplitting::jetId; PresliceOptional BaseSplittingsPerBaseJetDielectron = aod::dielectronchargedsplitting::jetId; PresliceOptional TagSplittingsPerTagJetDielectron = aod::dielectronchargedeventwisesubtractedsplitting::jetId; @@ -79,23 +83,27 @@ struct JetSubstructureMatchingSub { PresliceOptional TagPairsPerTagJetD0 = aod::d0chargedeventwisesubtractedpair::jetId; PresliceOptional BasePairsPerBaseJetDplus = aod::dpluschargedpair::jetId; PresliceOptional TagPairsPerTagJetDplus = aod::dpluschargedeventwisesubtractedpair::jetId; + PresliceOptional BasePairsPerBaseJetDs = aod::dschargedpair::jetId; + PresliceOptional TagPairsPerTagJetDs = aod::dschargedeventwisesubtractedpair::jetId; PresliceOptional BasePairsPerBaseJetDstar = aod::dstarchargedpair::jetId; PresliceOptional TagPairsPerTagJetDstar = aod::dstarchargedeventwisesubtractedpair::jetId; PresliceOptional BasePairsPerBaseJetLc = aod::lcchargedpair::jetId; PresliceOptional TagPairsPerTagJetLc = aod::lcchargedeventwisesubtractedpair::jetId; - PresliceOptional BasePairsPerBaseJetBplus = aod::bpluschargedpair::jetId; - PresliceOptional TagPairsPerTagJetBplus = aod::bpluschargedeventwisesubtractedpair::jetId; PresliceOptional BasePairsPerBaseJetB0 = aod::b0chargedpair::jetId; PresliceOptional TagPairsPerTagJetB0 = aod::b0chargedeventwisesubtractedpair::jetId; + PresliceOptional BasePairsPerBaseJetBplus = aod::bpluschargedpair::jetId; + PresliceOptional TagPairsPerTagJetBplus = aod::bpluschargedeventwisesubtractedpair::jetId; + PresliceOptional BasePairsPerBaseJetXicToXiPiPi = aod::xictoxipipichargedpair::jetId; + PresliceOptional TagPairsPerTagJetXicToXiPiPi = aod::xictoxipipichargedeventwisesubtractedpair::jetId; PresliceOptional BasePairsPerBaseJetDielectron = aod::dielectronchargedpair::jetId; PresliceOptional TagPairsPerTagJetDielectron = aod::dielectronchargedeventwisesubtractedpair::jetId; // workaround till binding nodes can be passed as template arguments - template - auto slicedPerJetForMatching(T const& table, U const& jet, V const& perIncluisveJet, M const& perD0Jet, N const& perDplusJet, O const& perDstarJet, P const& perLcJet, Q const& perB0Jet, R const& perBplusJet, S const& perDielectronJet) + template + auto slicedPerJetForMatching(T const& table, U const& jet, V const& perIncluisveJet, M const& perD0Jet, N const& perDplusJet, O const& perDsJet, P const& perDstarJet, Q const& perLcJet, R const& perB0Jet, S const& perBplusJet, A const& perXicToXiPiPiJet, B const& perDielectronJet) { if constexpr (jethfutilities::isHFTable() || jethfutilities::isHFMcTable()) { - return jethfutilities::slicedPerHFJet(table, jet, perD0Jet, perDplusJet, perDstarJet, perLcJet, perB0Jet, perBplusJet); + return jethfutilities::slicedPerHFJet(table, jet, perD0Jet, perDplusJet, perDsJet, perDstarJet, perLcJet, perB0Jet, perBplusJet, perXicToXiPiPiJet); } else if constexpr (jetdqutilities::isDielectronTable() || jetdqutilities::isDielectronMcTable()) { return jetdqutilities::slicedPerDielectronJet(table, jet, perDielectronJet); } else { @@ -158,14 +166,14 @@ struct JetSubstructureMatchingSub { } if (hasMatchedJet) { // auto const& jetTagSplittings = jetsTagSplittings.sliceBy(TagSplittingsPerTagJet, jetTag.globalIndex()); - auto const& jetTagSplittings = slicedPerJetForMatching(jetsTagSplittings, jetTag, TagSplittingsPerTagJetInclusive, TagSplittingsPerTagJetD0, TagSplittingsPerTagJetDplus, TagSplittingsPerTagJetDstar, TagSplittingsPerTagJetLc, TagSplittingsPerTagJetB0, TagSplittingsPerTagJetBplus, TagSplittingsPerTagJetDielectron); + auto const& jetTagSplittings = slicedPerJetForMatching(jetsTagSplittings, jetTag, TagSplittingsPerTagJetInclusive, TagSplittingsPerTagJetD0, TagSplittingsPerTagJetDplus, TagSplittingsPerTagJetDs, TagSplittingsPerTagJetDstar, TagSplittingsPerTagJetLc, TagSplittingsPerTagJetB0, TagSplittingsPerTagJetBplus, TagSplittingsPerTagJetXicToXiPiPi, TagSplittingsPerTagJetDielectron); int tagSplittingIndex = 0; for (auto const& jetTagSplitting : jetTagSplittings) { jetTagSplittingsMap[jetTagSplitting.globalIndex()] = tagSplittingIndex; tagSplittingIndex++; } // auto const& jetTagPairs = jetsTagPairs.sliceBy(TagPairsPerTagJet, jetTag.globalIndex()); - auto const& jetTagPairs = slicedPerJetForMatching(jetsTagPairs, jetTag, TagPairsPerTagJetInclusive, TagPairsPerTagJetD0, TagPairsPerTagJetDplus, TagPairsPerTagJetDstar, TagPairsPerTagJetLc, TagPairsPerTagJetB0, TagPairsPerTagJetBplus, TagPairsPerTagJetDielectron); + auto const& jetTagPairs = slicedPerJetForMatching(jetsTagPairs, jetTag, TagPairsPerTagJetInclusive, TagPairsPerTagJetD0, TagPairsPerTagJetDplus, TagPairsPerTagJetDs, TagPairsPerTagJetDstar, TagPairsPerTagJetLc, TagPairsPerTagJetB0, TagPairsPerTagJetBplus, TagPairsPerTagJetXicToXiPiPi, TagPairsPerTagJetDielectron); int tagPairIndex = 0; for (auto const& jetTagPair : jetTagPairs) { jetTagPairsMap[jetTagPair.globalIndex()] = tagPairIndex; @@ -206,7 +214,7 @@ struct JetSubstructureMatchingSub { } } // auto const& jetBaseSplittings = jetsBaseSplittings.sliceBy(BaseSplittingsPerBaseJet, jetBase.globalIndex()); - auto const& jetBaseSplittings = slicedPerJetForMatching(jetsBaseSplittings, jetBase, BaseSplittingsPerBaseJetInclusive, BaseSplittingsPerBaseJetD0, BaseSplittingsPerBaseJetDplus, BaseSplittingsPerBaseJetDstar, BaseSplittingsPerBaseJetLc, BaseSplittingsPerBaseJetB0, BaseSplittingsPerBaseJetBplus, BaseSplittingsPerBaseJetDielectron); + auto const& jetBaseSplittings = slicedPerJetForMatching(jetsBaseSplittings, jetBase, BaseSplittingsPerBaseJetInclusive, BaseSplittingsPerBaseJetD0, BaseSplittingsPerBaseJetDplus, BaseSplittingsPerBaseJetDs, BaseSplittingsPerBaseJetDstar, BaseSplittingsPerBaseJetLc, BaseSplittingsPerBaseJetB0, BaseSplittingsPerBaseJetBplus, BaseSplittingsPerBaseJetXicToXiPiPi, BaseSplittingsPerBaseJetDielectron); int baseSplittingIndex = 0; for (auto const& jetBaseSplitting : jetBaseSplittings) { jetBaseSplittingsMap[jetBaseSplitting.globalIndex()] = baseSplittingIndex; @@ -214,7 +222,7 @@ struct JetSubstructureMatchingSub { } jetmatchingutilities::doAllMatching(jetBaseSplittings, jetTagSplittings, jetsBasetoTagSplittingsMatchingGeo, jetsBasetoTagSplittingsMatchingPt, jetsBasetoTagSplittingsMatchingHF, jetsTagtoBaseSplittingsMatchingGeo, jetsTagtoBaseSplittingsMatchingPt, jetsTagtoBaseSplittingsMatchingHF, candidates, tracksBase, clustersBase, candidates, tracksTag, tracksTag, doMatchingGeo, doMatchingHf, doMatchingPt, maxMatchingDistance, minPtFraction); // auto const& jetBasePairs = jetsBasePairs.sliceBy(BasePairsPerBaseJet, jetBase.globalIndex()); - auto const& jetBasePairs = slicedPerJetForMatching(jetsBasePairs, jetBase, BasePairsPerBaseJetInclusive, BasePairsPerBaseJetD0, BasePairsPerBaseJetDplus, BasePairsPerBaseJetDstar, BasePairsPerBaseJetLc, BasePairsPerBaseJetB0, BasePairsPerBaseJetBplus, BasePairsPerBaseJetDielectron); + auto const& jetBasePairs = slicedPerJetForMatching(jetsBasePairs, jetBase, BasePairsPerBaseJetInclusive, BasePairsPerBaseJetD0, BasePairsPerBaseJetDplus, BasePairsPerBaseJetDs, BasePairsPerBaseJetDstar, BasePairsPerBaseJetLc, BasePairsPerBaseJetB0, BasePairsPerBaseJetBplus, BasePairsPerBaseJetXicToXiPiPi, BasePairsPerBaseJetDielectron); int basePairIndex = 0; for (auto const& jetBasePair : jetBasePairs) { jetBasePairsMap[jetBasePair.globalIndex()] = basePairIndex; diff --git a/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatchingSubDsCharged.cxx b/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatchingSubDsCharged.cxx new file mode 100644 index 00000000000..0fa4f86388d --- /dev/null +++ b/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatchingSubDsCharged.cxx @@ -0,0 +1,50 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// substructure matching event-wise subtracted Ds charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatchingSub.cxx" + +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetReducedData.h" +#include "PWGJE/DataModel/JetSubstructure.h" + +#include +#include +#include +#include +#include + +#include + +using DsChargedJetSubstructureMatchingSub = JetSubstructureMatchingSub, + soa::Join, + aod::DsChargedSPsMatchedToDsChargedEventWiseSubtractedSPs, + aod::DsChargedEventWiseSubtractedSPsMatchedToDsChargedSPs, + aod::DsChargedPRsMatchedToDsChargedEventWiseSubtractedPRs, + aod::DsChargedEventWiseSubtractedPRsMatchedToDsChargedPRs, + aod::DsChargedSPs, + aod::DsChargedEventWiseSubtractedSPs, + aod::DsChargedPRs, + aod::DsChargedEventWiseSubtractedPRs, + aod::CandidatesDsData, + aod::JetTracks, + aod::JetTracksSubDs, + aod::JDummys>; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-substructure-matching-sub-ds-ch"})); + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatchingSubXicToXiPiPiCharged.cxx b/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatchingSubXicToXiPiPiCharged.cxx new file mode 100644 index 00000000000..e5641af7a0d --- /dev/null +++ b/PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatchingSubXicToXiPiPiCharged.cxx @@ -0,0 +1,50 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// substructure matching event-wise subtracted XicToXiPiPi charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/TableProducer/Matching/Substructure/jetSubstructureMatchingSub.cxx" + +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetReducedData.h" +#include "PWGJE/DataModel/JetSubstructure.h" + +#include +#include +#include +#include +#include + +#include + +using XicToXiPiPiChargedJetSubstructureMatchingSub = JetSubstructureMatchingSub, + soa::Join, + aod::XicToXiPiPiChargedSPsMatchedToXicToXiPiPiChargedEventWiseSubtractedSPs, + aod::XicToXiPiPiChargedEventWiseSubtractedSPsMatchedToXicToXiPiPiChargedSPs, + aod::XicToXiPiPiChargedPRsMatchedToXicToXiPiPiChargedEventWiseSubtractedPRs, + aod::XicToXiPiPiChargedEventWiseSubtractedPRsMatchedToXicToXiPiPiChargedPRs, + aod::XicToXiPiPiChargedSPs, + aod::XicToXiPiPiChargedEventWiseSubtractedSPs, + aod::XicToXiPiPiChargedPRs, + aod::XicToXiPiPiChargedEventWiseSubtractedPRs, + aod::CandidatesXicToXiPiPiData, + aod::JetTracks, + aod::JetTracksSubXicToXiPiPi, + aod::JDummys>; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-substructure-matching-sub-xictoxipipi-ch"})); + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/TableProducer/Matching/jetMatchingMCDsCharged.cxx b/PWGJE/TableProducer/Matching/jetMatchingMCDsCharged.cxx new file mode 100644 index 00000000000..df7a49e8940 --- /dev/null +++ b/PWGJE/TableProducer/Matching/jetMatchingMCDsCharged.cxx @@ -0,0 +1,42 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// jet matching mc Ds charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/TableProducer/Matching/jetMatchingMC.cxx" + +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetReducedData.h" + +#include +#include +#include +#include +#include + +#include + +using DsChargedJetMatchingMC = JetMatchingMc, + soa::Join, + aod::DsChargedMCDetectorLevelJetsMatchedToDsChargedMCParticleLevelJets, + aod::DsChargedMCParticleLevelJetsMatchedToDsChargedMCDetectorLevelJets, + aod::CandidatesDsMCD, + aod::CandidatesDsMCP, + aod::JDummys>; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-matching-mc-ds-ch"})); + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/TableProducer/Matching/jetMatchingMCSubDsCharged.cxx b/PWGJE/TableProducer/Matching/jetMatchingMCSubDsCharged.cxx new file mode 100644 index 00000000000..2fa5d9f74d9 --- /dev/null +++ b/PWGJE/TableProducer/Matching/jetMatchingMCSubDsCharged.cxx @@ -0,0 +1,39 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// jet matching mc subtracted Ds charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/TableProducer/Matching/jetMatchingMCSub.cxx" + +#include "PWGJE/DataModel/Jet.h" + +#include +#include +#include +#include +#include + +#include + +using DsChargedJetMatchingMCSub = JetMatchingMcSub, + soa::Join, + aod::DsChargedMCDetectorLevelJetsMatchedToDsChargedMCDetectorLevelEventWiseSubtractedJets, + aod::DsChargedMCDetectorLevelEventWiseSubtractedJetsMatchedToDsChargedMCDetectorLevelJets, + aod::CandidatesDsMCD>; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-matching-mc-sub-ds-ch"})); + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/TableProducer/Matching/jetMatchingMCSubXicToXiPiPiCharged.cxx b/PWGJE/TableProducer/Matching/jetMatchingMCSubXicToXiPiPiCharged.cxx new file mode 100644 index 00000000000..595be4a2124 --- /dev/null +++ b/PWGJE/TableProducer/Matching/jetMatchingMCSubXicToXiPiPiCharged.cxx @@ -0,0 +1,39 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// jet matching mc subtracted XicToXiPiPi charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/TableProducer/Matching/jetMatchingMCSub.cxx" + +#include "PWGJE/DataModel/Jet.h" + +#include +#include +#include +#include +#include + +#include + +using XicToXiPiPiChargedJetMatchingMCSub = JetMatchingMcSub, + soa::Join, + aod::XicToXiPiPiChargedMCDetectorLevelJetsMatchedToXicToXiPiPiChargedMCDetectorLevelEventWiseSubtractedJets, + aod::XicToXiPiPiChargedMCDetectorLevelEventWiseSubtractedJetsMatchedToXicToXiPiPiChargedMCDetectorLevelJets, + aod::CandidatesXicToXiPiPiMCD>; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-matching-mc-sub-xictoxipipi-ch"})); + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/TableProducer/Matching/jetMatchingMCXicToXiPiPiCharged.cxx b/PWGJE/TableProducer/Matching/jetMatchingMCXicToXiPiPiCharged.cxx new file mode 100644 index 00000000000..1d14c10bef6 --- /dev/null +++ b/PWGJE/TableProducer/Matching/jetMatchingMCXicToXiPiPiCharged.cxx @@ -0,0 +1,42 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// jet matching mc XicToXiPiPi charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/TableProducer/Matching/jetMatchingMC.cxx" + +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetReducedData.h" + +#include +#include +#include +#include +#include + +#include + +using XicToXiPiPiChargedJetMatchingMC = JetMatchingMc, + soa::Join, + aod::XicToXiPiPiChargedMCDetectorLevelJetsMatchedToXicToXiPiPiChargedMCParticleLevelJets, + aod::XicToXiPiPiChargedMCParticleLevelJetsMatchedToXicToXiPiPiChargedMCDetectorLevelJets, + aod::CandidatesXicToXiPiPiMCD, + aod::CandidatesXicToXiPiPiMCP, + aod::JDummys>; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-matching-mc-xictoxipipi-ch"})); + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/TableProducer/Matching/jetMatchingSubDsCharged.cxx b/PWGJE/TableProducer/Matching/jetMatchingSubDsCharged.cxx new file mode 100644 index 00000000000..d08dd8e6155 --- /dev/null +++ b/PWGJE/TableProducer/Matching/jetMatchingSubDsCharged.cxx @@ -0,0 +1,41 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// jet matching subtracted Ds charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/TableProducer/Matching/jetMatchingSub.cxx" + +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetSubtraction.h" + +#include +#include +#include +#include +#include + +#include + +using DsChargedJetMatchingSub = JetMatchingSub, + soa::Join, + aod::DsChargedJetsMatchedToDsChargedEventWiseSubtractedJets, + aod::DsChargedEventWiseSubtractedJetsMatchedToDsChargedJets, + aod::JTrackDsSubs, + aod::CandidatesDsData>; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-matching-sub-ds-ch"})); + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/TableProducer/Matching/jetMatchingSubXicToXiPiPiCharged.cxx b/PWGJE/TableProducer/Matching/jetMatchingSubXicToXiPiPiCharged.cxx new file mode 100644 index 00000000000..a2efd7f0cde --- /dev/null +++ b/PWGJE/TableProducer/Matching/jetMatchingSubXicToXiPiPiCharged.cxx @@ -0,0 +1,41 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// jet matching subtracted XicToXiPiPi charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/TableProducer/Matching/jetMatchingSub.cxx" + +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetSubtraction.h" + +#include +#include +#include +#include +#include + +#include + +using XicToXiPiPiChargedJetMatchingSub = JetMatchingSub, + soa::Join, + aod::XicToXiPiPiChargedJetsMatchedToXicToXiPiPiChargedEventWiseSubtractedJets, + aod::XicToXiPiPiChargedEventWiseSubtractedJetsMatchedToXicToXiPiPiChargedJets, + aod::JTrackXicToXiPiPiSubs, + aod::CandidatesXicToXiPiPiData>; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-matching-sub-xictoxipipi-ch"})); + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/TableProducer/derivedDataProducer.cxx b/PWGJE/TableProducer/derivedDataProducer.cxx index 045c2648acd..c3de10e5e90 100644 --- a/PWGJE/TableProducer/derivedDataProducer.cxx +++ b/PWGJE/TableProducer/derivedDataProducer.cxx @@ -100,6 +100,10 @@ struct JetDerivedDataProducerTask { Produces jDplusMcCollisionIdsTable; Produces jDplusIdsTable; Produces jDplusParticleIdsTable; + Produces jDsCollisionIdsTable; + Produces jDsMcCollisionIdsTable; + Produces jDsIdsTable; + Produces jDsParticleIdsTable; Produces jDstarCollisionIdsTable; Produces jDstarMcCollisionIdsTable; Produces jDstarIdsTable; @@ -116,6 +120,10 @@ struct JetDerivedDataProducerTask { Produces jBplusMcCollisionIdsTable; Produces jBplusIdsTable; Produces jBplusParticleIdsTable; + Produces jXicToXiPiPiCollisionIdsTable; + Produces jXicToXiPiPiMcCollisionIdsTable; + Produces jXicToXiPiPiIdsTable; + Produces jXicToXiPiPiParticleIdsTable; Produces jV0IdsTable; Produces jV0McCollisionsTable; Produces jV0McCollisionIdsTable; @@ -542,6 +550,38 @@ struct JetDerivedDataProducerTask { } PROCESS_SWITCH(JetDerivedDataProducerTask, processDplusMC, "produces derived index for Dplus particles", false); + void processDsCollisions(aod::HfDsCollIds::iterator const& DsCollision) + { + products.jDsCollisionIdsTable(DsCollision.collisionId()); + } + PROCESS_SWITCH(JetDerivedDataProducerTask, processDsCollisions, "produces derived index for Ds collisions", false); + + void processDsMcCollisions(aod::HfDsMcCollIds::iterator const& DsMcCollision) + { + products.jDsMcCollisionIdsTable(DsMcCollision.mcCollisionId()); + } + PROCESS_SWITCH(JetDerivedDataProducerTask, processDsMcCollisions, "produces derived index for Ds MC collisions", false); + + void processDs(aod::HfDsIds::iterator const& DsCandidate, aod::Tracks const&) + { + auto JProng0ID = trackCollisionMapping.find({DsCandidate.prong0Id(), DsCandidate.prong0_as().collisionId()}); + auto JProng1ID = trackCollisionMapping.find({DsCandidate.prong1Id(), DsCandidate.prong1_as().collisionId()}); + auto JProng2ID = trackCollisionMapping.find({DsCandidate.prong2Id(), DsCandidate.prong2_as().collisionId()}); + if (withCollisionAssociator) { + JProng0ID = trackCollisionMapping.find({DsCandidate.prong0Id(), DsCandidate.collisionId()}); + JProng1ID = trackCollisionMapping.find({DsCandidate.prong1Id(), DsCandidate.collisionId()}); + JProng2ID = trackCollisionMapping.find({DsCandidate.prong2Id(), DsCandidate.collisionId()}); + } + products.jDsIdsTable(DsCandidate.collisionId(), JProng0ID->second, JProng1ID->second, JProng2ID->second); + } + PROCESS_SWITCH(JetDerivedDataProducerTask, processDs, "produces derived index for Ds candidates", false); + + void processDsMC(aod::HfDsPIds::iterator const& DsParticle) + { + products.jDsParticleIdsTable(DsParticle.mcCollisionId(), DsParticle.mcParticleId()); + } + PROCESS_SWITCH(JetDerivedDataProducerTask, processDsMC, "produces derived index for Ds particles", false); + void processDstarCollisions(aod::HfDstarCollIds::iterator const& DstarCollision) { products.jDstarCollisionIdsTable(DstarCollision.collisionId()); @@ -672,6 +712,42 @@ struct JetDerivedDataProducerTask { } PROCESS_SWITCH(JetDerivedDataProducerTask, processBplusMC, "produces derived index for Bplus particles", false); + void processXicToXiPiPiCollisions(aod::HfXicToXiPiPiCollIds::iterator const& XicToXiPiPiCollision) + { + products.jXicToXiPiPiCollisionIdsTable(XicToXiPiPiCollision.collisionId()); + } + PROCESS_SWITCH(JetDerivedDataProducerTask, processXicToXiPiPiCollisions, "produces derived index for XicToXiPiPi collisions", false); + + void processXicToXiPiPiMcCollisions(aod::HfXicToXiPiPiMcCollIds::iterator const& XicToXiPiPiMcCollision) + { + products.jXicToXiPiPiMcCollisionIdsTable(XicToXiPiPiMcCollision.mcCollisionId()); + } + PROCESS_SWITCH(JetDerivedDataProducerTask, processXicToXiPiPiMcCollisions, "produces derived index for XicToXiPiPi MC collisions", false); + + void processXicToXiPiPi(aod::HfXicToXiPiPiIds::iterator const& XicToXiPiPiCandidate, aod::Tracks const&) + { + auto JProng0ID = trackCollisionMapping.find({XicToXiPiPiCandidate.prong0Id(), XicToXiPiPiCandidate.prong0_as().collisionId()}); + auto JProng1ID = trackCollisionMapping.find({XicToXiPiPiCandidate.prong1Id(), XicToXiPiPiCandidate.prong1_as().collisionId()}); + auto JProng2ID = trackCollisionMapping.find({XicToXiPiPiCandidate.prong2Id(), XicToXiPiPiCandidate.prong2_as().collisionId()}); + auto JProng3ID = trackCollisionMapping.find({XicToXiPiPiCandidate.prong3Id(), XicToXiPiPiCandidate.prong3_as().collisionId()}); + auto JProng4ID = trackCollisionMapping.find({XicToXiPiPiCandidate.prong4Id(), XicToXiPiPiCandidate.prong4_as().collisionId()}); + if (withCollisionAssociator) { + JProng0ID = trackCollisionMapping.find({XicToXiPiPiCandidate.prong0Id(), XicToXiPiPiCandidate.collisionId()}); + JProng1ID = trackCollisionMapping.find({XicToXiPiPiCandidate.prong1Id(), XicToXiPiPiCandidate.collisionId()}); + JProng2ID = trackCollisionMapping.find({XicToXiPiPiCandidate.prong2Id(), XicToXiPiPiCandidate.collisionId()}); + JProng3ID = trackCollisionMapping.find({XicToXiPiPiCandidate.prong3Id(), XicToXiPiPiCandidate.collisionId()}); + JProng4ID = trackCollisionMapping.find({XicToXiPiPiCandidate.prong4Id(), XicToXiPiPiCandidate.collisionId()}); + } + products.jXicToXiPiPiIdsTable(XicToXiPiPiCandidate.collisionId(), JProng0ID->second, JProng1ID->second, JProng2ID->second, JProng3ID->second, JProng4ID->second); + } + PROCESS_SWITCH(JetDerivedDataProducerTask, processXicToXiPiPi, "produces derived index for XicToXiPiPi candidates", false); + + void processXicToXiPiPiMC(aod::HfXicToXiPiPiPIds::iterator const& XicToXiPiPiParticle) + { + products.jXicToXiPiPiParticleIdsTable(XicToXiPiPiParticle.mcCollisionId(), XicToXiPiPiParticle.mcParticleId()); + } + PROCESS_SWITCH(JetDerivedDataProducerTask, processXicToXiPiPiMC, "produces derived index for XicToXiPiPi particles", false); + void processV0(aod::V0Indices::iterator const& V0Candidate, aod::Tracks const&) { auto JPosTrackID = trackCollisionMapping.find({V0Candidate.posTrackId(), V0Candidate.posTrack_as().collisionId()}); diff --git a/PWGJE/TableProducer/derivedDataSelector.cxx b/PWGJE/TableProducer/derivedDataSelector.cxx index 9e04a6332b4..215f56b00eb 100644 --- a/PWGJE/TableProducer/derivedDataSelector.cxx +++ b/PWGJE/TableProducer/derivedDataSelector.cxx @@ -60,6 +60,9 @@ struct JetDerivedDataSelector { Configurable thresholdChargedDplusJetPtMin{"thresholdChargedDplusJetPtMin", 0.0, "Minimum charged Dplus jet pt to accept event"}; Configurable thresholdChargedEventWiseSubtractedDplusJetPtMin{"thresholdChargedEventWiseSubtractedDplusJetPtMin", 0.0, "Minimum charged event-wise subtracted Dplus jet pt to accept event"}; Configurable thresholdChargedDplusMCPJetPtMin{"thresholdChargedDplusMCPJetPtMin", 0.0, "Minimum charged Dplus mcp jet pt to accept event"}; + Configurable thresholdChargedDsJetPtMin{"thresholdChargedDsJetPtMin", 0.0, "Minimum charged Ds jet pt to accept event"}; + Configurable thresholdChargedEventWiseSubtractedDsJetPtMin{"thresholdChargedEventWiseSubtractedDsJetPtMin", 0.0, "Minimum charged event-wise subtracted Ds jet pt to accept event"}; + Configurable thresholdChargedDsMCPJetPtMin{"thresholdChargedDsMCPJetPtMin", 0.0, "Minimum charged Ds mcp jet pt to accept event"}; Configurable thresholdChargedDstarJetPtMin{"thresholdChargedDstarJetPtMin", 0.0, "Minimum charged Dstar jet pt to accept event"}; Configurable thresholdChargedEventWiseSubtractedDstarJetPtMin{"thresholdChargedEventWiseSubtractedDstarJetPtMin", 0.0, "Minimum charged event-wise subtracted Dstar jet pt to accept event"}; Configurable thresholdChargedDstarMCPJetPtMin{"thresholdChargedDstarMCPJetPtMin", 0.0, "Minimum charged Dstar mcp jet pt to accept event"}; @@ -72,6 +75,9 @@ struct JetDerivedDataSelector { Configurable thresholdChargedBplusJetPtMin{"thresholdChargedBplusJetPtMin", 0.0, "Minimum charged Bplus jet pt to accept event"}; Configurable thresholdChargedEventWiseSubtractedBplusJetPtMin{"thresholdChargedEventWiseSubtractedBplusJetPtMin", 0.0, "Minimum charged event-wise subtracted Bplus jet pt to accept event"}; Configurable thresholdChargedBplusMCPJetPtMin{"thresholdChargedBplusMCPJetPtMin", 0.0, "Minimum charged Bplus mcp jet pt to accept event"}; + Configurable thresholdChargedXicToXiPiPiJetPtMin{"thresholdChargedXicToXiPiPiJetPtMin", 0.0, "Minimum charged XicToXiPiPi jet pt to accept event"}; + Configurable thresholdChargedEventWiseSubtractedXicToXiPiPiJetPtMin{"thresholdChargedEventWiseSubtractedXicToXiPiPiJetPtMin", 0.0, "Minimum charged event-wise subtracted XicToXiPiPi jet pt to accept event"}; + Configurable thresholdChargedXicToXiPiPiMCPJetPtMin{"thresholdChargedXicToXiPiPiMCPJetPtMin", 0.0, "Minimum charged XicToXiPiPi mcp jet pt to accept event"}; Configurable thresholdChargedDielectronJetPtMin{"thresholdChargedDielectronJetPtMin", 0.0, "Minimum charged Dielectron jet pt to accept event"}; Configurable thresholdChargedEventWiseSubtractedDielectronJetPtMin{"thresholdChargedEventWiseSubtractedDielectronJetPtMin", 0.0, "Minimum charged event-wise subtracted Dielectron jet pt to accept event"}; Configurable thresholdChargedDielectronMCPJetPtMin{"thresholdChargedDielectronMCPJetPtMin", 0.0, "Minimum charged Dielectron mcp jet pt to accept event"}; @@ -218,6 +224,12 @@ struct JetDerivedDataSelector { selectionObjectPtMin = config.thresholdChargedEventWiseSubtractedDplusJetPtMin; } else if constexpr (std::is_same_v, aod::DplusChargedMCParticleLevelJets>) { selectionObjectPtMin = config.thresholdChargedDplusMCPJetPtMin; + } else if constexpr (std::is_same_v, aod::DsChargedJets> || std::is_same_v, aod::DsChargedMCDetectorLevelJets>) { + selectionObjectPtMin = config.thresholdChargedDsJetPtMin; + } else if constexpr (std::is_same_v, aod::DsChargedEventWiseSubtractedJets> || std::is_same_v, aod::DsChargedMCDetectorLevelEventWiseSubtractedJets>) { + selectionObjectPtMin = config.thresholdChargedEventWiseSubtractedDsJetPtMin; + } else if constexpr (std::is_same_v, aod::DsChargedMCParticleLevelJets>) { + selectionObjectPtMin = config.thresholdChargedDsMCPJetPtMin; } else if constexpr (std::is_same_v, aod::DstarChargedJets> || std::is_same_v, aod::DstarChargedMCDetectorLevelJets>) { selectionObjectPtMin = config.thresholdChargedDstarJetPtMin; } else if constexpr (std::is_same_v, aod::DstarChargedEventWiseSubtractedJets> || std::is_same_v, aod::DstarChargedMCDetectorLevelEventWiseSubtractedJets>) { @@ -242,6 +254,12 @@ struct JetDerivedDataSelector { selectionObjectPtMin = config.thresholdChargedEventWiseSubtractedBplusJetPtMin; } else if constexpr (std::is_same_v, aod::BplusChargedMCParticleLevelJets>) { selectionObjectPtMin = config.thresholdChargedBplusMCPJetPtMin; + } else if constexpr (std::is_same_v, aod::XicToXiPiPiChargedJets> || std::is_same_v, aod::XicToXiPiPiChargedMCDetectorLevelJets>) { + selectionObjectPtMin = config.thresholdChargedXicToXiPiPiJetPtMin; + } else if constexpr (std::is_same_v, aod::XicToXiPiPiChargedEventWiseSubtractedJets> || std::is_same_v, aod::XicToXiPiPiChargedMCDetectorLevelEventWiseSubtractedJets>) { + selectionObjectPtMin = config.thresholdChargedEventWiseSubtractedXicToXiPiPiJetPtMin; + } else if constexpr (std::is_same_v, aod::XicToXiPiPiChargedMCParticleLevelJets>) { + selectionObjectPtMin = config.thresholdChargedXicToXiPiPiMCPJetPtMin; } else if constexpr (std::is_same_v, aod::DielectronChargedJets> || std::is_same_v, aod::DielectronChargedMCDetectorLevelJets>) { selectionObjectPtMin = config.thresholdChargedDielectronJetPtMin; } else if constexpr (std::is_same_v, aod::DielectronChargedEventWiseSubtractedJets> || std::is_same_v, aod::DielectronChargedMCDetectorLevelEventWiseSubtractedJets>) { @@ -275,7 +293,7 @@ struct JetDerivedDataSelector { } } if (isTriggerObject) { - if constexpr (std::is_same_v, aod::ChargedMCParticleLevelJets> || std::is_same_v, aod::NeutralMCParticleLevelJets> || std::is_same_v, aod::FullMCParticleLevelJets> || std::is_same_v, aod::D0ChargedMCParticleLevelJets> || std::is_same_v, aod::DplusChargedMCParticleLevelJets> || std::is_same_v, aod::DstarChargedMCParticleLevelJets> || std::is_same_v, aod::LcChargedMCParticleLevelJets> || std::is_same_v, aod::B0ChargedMCParticleLevelJets> || std::is_same_v, aod::BplusChargedMCParticleLevelJets> || std::is_same_v, aod::DielectronChargedMCParticleLevelJets>) { + if constexpr (std::is_same_v, aod::ChargedMCParticleLevelJets> || std::is_same_v, aod::NeutralMCParticleLevelJets> || std::is_same_v, aod::FullMCParticleLevelJets> || std::is_same_v, aod::D0ChargedMCParticleLevelJets> || std::is_same_v, aod::DplusChargedMCParticleLevelJets> || std::is_same_v, aod::DsChargedMCParticleLevelJets> || std::is_same_v, aod::DstarChargedMCParticleLevelJets> || std::is_same_v, aod::LcChargedMCParticleLevelJets> || std::is_same_v, aod::B0ChargedMCParticleLevelJets> || std::is_same_v, aod::BplusChargedMCParticleLevelJets> || std::is_same_v, aod::XicToXiPiPiChargedMCParticleLevelJets> || std::is_same_v, aod::DielectronChargedMCParticleLevelJets>) { if (selectionObject.mcCollisionId() >= 0) { McCollisionFlag[selectionObject.mcCollisionId()] = true; } @@ -314,6 +332,11 @@ struct JetDerivedDataSelector { PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingDplusChargedMCDJets, "process Dplus charged mcd jets", false); PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingDplusChargedMCDetectorLevelEventWiseSubtractedJets, "process Dplus event-wise subtracted charged mcd jets", false); PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingDplusChargedMCPJets, "process Dplus charged mcp jets", false); + PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingDsChargedJets, "process Ds charged jets", false); + PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingDsChargedEventWiseSubtractedJets, "process Ds event-wise subtracted charged jets", false); + PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingDsChargedMCDJets, "process Ds charged mcd jets", false); + PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingDsChargedMCDetectorLevelEventWiseSubtractedJets, "process Ds event-wise subtracted charged mcd jets", false); + PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingDsChargedMCPJets, "process Ds charged mcp jets", false); PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingDstarChargedJets, "process Dstar charged jets", false); PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingDstarChargedEventWiseSubtractedJets, "process Dstar event-wise subtracted charged jets", false); PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingDstarChargedMCDJets, "process Dstar charged mcd jets", false); @@ -334,6 +357,11 @@ struct JetDerivedDataSelector { PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingBplusChargedMCDJets, "process Bplus charged mcd jets", false); PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingBplusChargedMCDetectorLevelEventWiseSubtractedJets, "process Bplus event-wise subtracted charged mcd jets", false); PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingBplusChargedMCPJets, "process Bplus charged mcp jets", false); + PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingXicToXiPiPiChargedJets, "process XicToXiPiPi charged jets", false); + PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingXicToXiPiPiChargedEventWiseSubtractedJets, "process XicToXiPiPi event-wise subtracted charged jets", false); + PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingXicToXiPiPiChargedMCDJets, "process XicToXiPiPi charged mcd jets", false); + PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingXicToXiPiPiChargedMCDetectorLevelEventWiseSubtractedJets, "process XicToXiPiPi event-wise subtracted charged mcd jets", false); + PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingXicToXiPiPiChargedMCPJets, "process XicToXiPiPi charged mcp jets", false); PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingDielectronChargedJets, "process Dielectron charged jets", false); PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingDielectronChargedEventWiseSubtractedJets, "process Dielectron event-wise subtracted charged jets", false); PROCESS_SWITCH_FULL(JetDerivedDataSelector, processSelectionObjects, processSelectingDielectronChargedMCDJets, "process Dielectron charged mcd jets", false); diff --git a/PWGJE/TableProducer/derivedDataWriter.cxx b/PWGJE/TableProducer/derivedDataWriter.cxx index d583250d49f..0a73a14b24b 100644 --- a/PWGJE/TableProducer/derivedDataWriter.cxx +++ b/PWGJE/TableProducer/derivedDataWriter.cxx @@ -120,6 +120,25 @@ struct JetDerivedDataWriter { Produces storedDplusParticleIdsTable; } productsDplus; + struct : ProducesGroup { + Produces storedDsCollisionsTable; + Produces storedDsCollisionIdsTable; + Produces storedDssTable; + Produces storedDsParsTable; + Produces storedDsParExtrasTable; + Produces storedDsParDaughtersDummyTable; + Produces storedDsSelsTable; + Produces storedDsMlsTable; + Produces storedDsMlDughtersDummyTable; + Produces storedDsMcsTable; + Produces storedDsIdsTable; + Produces storedDsMcCollisionsTable; + Produces storedDsMcCollisionIdsTable; + Produces storedDsMcCollisionsMatchingTable; + Produces storedDsParticlesTable; + Produces storedDsParticleIdsTable; + } productsDs; + struct : ProducesGroup { Produces storedDstarCollisionsTable; Produces storedDstarCollisionIdsTable; @@ -196,6 +215,25 @@ struct JetDerivedDataWriter { Produces storedBplusParticleIdsTable; } productsBplus; + struct : ProducesGroup { + Produces storedXicToXiPiPiCollisionsTable; + Produces storedXicToXiPiPiCollisionIdsTable; + Produces storedXicToXiPiPisTable; + Produces storedXicToXiPiPiParsTable; + Produces storedXicToXiPiPiParExtrasTable; + Produces storedXicToXiPiPiParDaughtersDummyTable; + Produces storedXicToXiPiPiSelsTable; + Produces storedXicToXiPiPiMlsTable; + Produces storedXicToXiPiPiMlDughtersDummyTable; + Produces storedXicToXiPiPiMcsTable; + Produces storedXicToXiPiPiIdsTable; + Produces storedXicToXiPiPiMcCollisionsTable; + Produces storedXicToXiPiPiMcCollisionIdsTable; + Produces storedXicToXiPiPiMcCollisionsMatchingTable; + Produces storedXicToXiPiPiParticlesTable; + Produces storedXicToXiPiPiParticleIdsTable; + } productsXicToXiPiPi; + struct : ProducesGroup { Produces storedDielectronCollisionsTable; Produces storedDielectronCollisionIdsTable; @@ -216,17 +254,21 @@ struct JetDerivedDataWriter { Preslice> ParticlesPerMcCollision = aod::jmcparticle::mcCollisionId; Preslice D0McCollisionsPerMcCollision = aod::jcandidateindices::mcCollisionId; Preslice DplusMcCollisionsPerMcCollision = aod::jcandidateindices::mcCollisionId; + Preslice DsMcCollisionsPerMcCollision = aod::jcandidateindices::mcCollisionId; Preslice DstarMcCollisionsPerMcCollision = aod::jcandidateindices::mcCollisionId; Preslice LcMcCollisionsPerMcCollision = aod::jcandidateindices::mcCollisionId; Preslice B0McCollisionsPerMcCollision = aod::jcandidateindices::mcCollisionId; Preslice BplusMcCollisionsPerMcCollision = aod::jcandidateindices::mcCollisionId; + Preslice XicToXiPiPiMcCollisionsPerMcCollision = aod::jcandidateindices::mcCollisionId; Preslice DielectronMcCollisionsPerMcCollision = aod::jcandidateindices::mcCollisionId; Preslice D0ParticlesPerMcCollision = aod::jcandidateindices::mcCollisionId; Preslice DplusParticlesPerMcCollision = aod::jcandidateindices::mcCollisionId; + Preslice DsParticlesPerMcCollision = aod::jcandidateindices::mcCollisionId; Preslice DstarParticlesPerMcCollision = aod::jcandidateindices::mcCollisionId; Preslice LcParticlesPerMcCollision = aod::jcandidateindices::mcCollisionId; Preslice B0ParticlesPerMcCollision = aod::jcandidateindices::mcCollisionId; Preslice BplusParticlesPerMcCollision = aod::jcandidateindices::mcCollisionId; + Preslice XicToXiPiPiParticlesPerMcCollision = aod::jcandidateindices::mcCollisionId; PresliceUnsorted EMCTrackPerTrack = aod::jemctrack::trackId; } preslices; @@ -282,6 +324,21 @@ struct JetDerivedDataWriter { } } + template + void storeDs(soa::Join::iterator const& collision, aod::JTracks const&, aod::CollisionsDs const& DsCollisions, T const& DsCandidates) + { + if (collision.isCollisionSelected()) { + for (const auto& DsCollision : DsCollisions) { // should only ever be one + jethfutilities::fillHFCollisionTable(DsCollision, products.productsDs.storedDsCollisionsTable); + products.productsDs.storedDsCollisionIdsTable(collisionMapping[collision.globalIndex()]); + } + for (const auto& DsCandidate : DsCandidates) { + jethfutilities::fillHFCandidateTable(DsCandidate, products.productsDs.storedDsCollisionsTable.lastIndex(), products.productsDs.storedDssTable, products.productsDs.storedDsParsTable, products.productsDs.storedDsParExtrasTable, products.productsDs.storedDsParDaughtersDummyTable, products.productsDs.storedDsSelsTable, products.productsDs.storedDsMlsTable, products.productsDs.storedDsMlDughtersDummyTable, products.productsDs.storedDsMcsTable); + products.productsDs.storedDsIdsTable(collisionMapping[collision.globalIndex()], trackMapping[DsCandidate.prong0Id()], trackMapping[DsCandidate.prong1Id()], trackMapping[DsCandidate.prong2Id()]); + } + } + } + template void storeDstar(soa::Join::iterator const& collision, aod::JTracks const&, aod::CollisionsDstar const& DstarCollisions, T const& DstarCandidates) { @@ -343,6 +400,21 @@ struct JetDerivedDataWriter { } } + template + void storeXicToXiPiPi(soa::Join::iterator const& collision, aod::JTracks const&, aod::CollisionsXicToXiPiPi const& XicToXiPiPiCollisions, T const& XicToXiPiPiCandidates) + { + if (collision.isCollisionSelected()) { + for (const auto& XicToXiPiPiCollision : XicToXiPiPiCollisions) { // should only ever be one + jethfutilities::fillHFCollisionTable(XicToXiPiPiCollision, products.productsXicToXiPiPi.storedXicToXiPiPiCollisionsTable); + products.productsXicToXiPiPi.storedXicToXiPiPiCollisionIdsTable(collisionMapping[collision.globalIndex()]); + } + for (const auto& XicToXiPiPiCandidate : XicToXiPiPiCandidates) { + jethfutilities::fillHFCandidateTable(XicToXiPiPiCandidate, products.productsXicToXiPiPi.storedXicToXiPiPiCollisionsTable.lastIndex(), products.productsXicToXiPiPi.storedXicToXiPiPisTable, products.productsXicToXiPiPi.storedXicToXiPiPiParsTable, products.productsXicToXiPiPi.storedXicToXiPiPiParExtrasTable, products.productsXicToXiPiPi.storedXicToXiPiPiParDaughtersDummyTable, products.productsXicToXiPiPi.storedXicToXiPiPiSelsTable, products.productsXicToXiPiPi.storedXicToXiPiPiMlsTable, products.productsXicToXiPiPi.storedXicToXiPiPiMlDughtersDummyTable, products.productsXicToXiPiPi.storedXicToXiPiPiMcsTable); + products.productsXicToXiPiPi.storedXicToXiPiPiIdsTable(collisionMapping[collision.globalIndex()], trackMapping[XicToXiPiPiCandidate.prong0Id()], trackMapping[XicToXiPiPiCandidate.prong1Id()], trackMapping[XicToXiPiPiCandidate.prong2Id()], trackMapping[XicToXiPiPiCandidate.prong3Id()], trackMapping[XicToXiPiPiCandidate.prong4Id()]); + } + } + } + void processDummyTable(aod::JDummys const&) { products.storedJDummysTable(1); @@ -474,6 +546,18 @@ struct JetDerivedDataWriter { } PROCESS_SWITCH(JetDerivedDataWriter, processDplusMCD, "write out mcd output tables for Dplus", false); + void processDsData(soa::Join::iterator const& collision, aod::JTracks const& tracks, aod::CollisionsDs const& DsCollisions, aod::CandidatesDsData const& DsCandidates) + { + storeDs(collision, tracks, DsCollisions, DsCandidates); + } + PROCESS_SWITCH(JetDerivedDataWriter, processDsData, "write out data output tables for Ds", false); + + void processDsMCD(soa::Join::iterator const& collision, aod::JTracks const& tracks, aod::CollisionsDs const& DsCollisions, aod::CandidatesDsMCD const& DsCandidates) + { + storeDs(collision, tracks, DsCollisions, DsCandidates); + } + PROCESS_SWITCH(JetDerivedDataWriter, processDsMCD, "write out mcd output tables for Ds", false); + void processDstarData(soa::Join::iterator const& collision, aod::JTracks const& tracks, aod::CollisionsDstar const& DstarCollisions, aod::CandidatesDstarData const& DstarCandidates) { storeDstar(collision, tracks, DstarCollisions, DstarCandidates); @@ -522,6 +606,18 @@ struct JetDerivedDataWriter { } PROCESS_SWITCH(JetDerivedDataWriter, processBplusMCD, "write out mcd output tables for bplus", false); + void processXicToXiPiPiData(soa::Join::iterator const& collision, aod::JTracks const& tracks, aod::CollisionsXicToXiPiPi const& XicToXiPiPiCollisions, aod::CandidatesXicToXiPiPiData const& XicToXiPiPiCandidates) + { + storeXicToXiPiPi(collision, tracks, XicToXiPiPiCollisions, XicToXiPiPiCandidates); + } + PROCESS_SWITCH(JetDerivedDataWriter, processXicToXiPiPiData, "write out data output tables for XicToXiPiPi", false); + + void processXicToXiPiPiMCD(soa::Join::iterator const& collision, aod::JTracks const& tracks, aod::CollisionsXicToXiPiPi const& XicToXiPiPiCollisions, aod::CandidatesXicToXiPiPiMCD const& XicToXiPiPiCandidates) + { + storeXicToXiPiPi(collision, tracks, XicToXiPiPiCollisions, XicToXiPiPiCandidates); + } + PROCESS_SWITCH(JetDerivedDataWriter, processXicToXiPiPiMCD, "write out mcd output tables for XicToXiPiPi", false); + void processDielectron(soa::Join::iterator const& collision, aod::JTracks const&, aod::CollisionsDielectron const& DielectronCollisions, aod::CandidatesDielectronData const& DielectronCandidates) { if (collision.isCollisionSelected()) { @@ -637,6 +733,28 @@ struct JetDerivedDataWriter { } PROCESS_SWITCH(JetDerivedDataWriter, processDplusMCP, "write out Dplus mcp output tables", false); + void processDsMCP(soa::Join const& mcCollisions, aod::McCollisionsDs const& DsMcCollisions, aod::CandidatesDsMCP const& DsParticles) + { + dplusMcCollisionMapping.clear(); + dplusMcCollisionMapping.resize(DsMcCollisions.size(), -1); + for (auto const& mcCollision : mcCollisions) { + if (mcCollision.isMcCollisionSelected()) { + const auto dplusMcCollisionsPerMcCollision = DsMcCollisions.sliceBy(preslices.DsMcCollisionsPerMcCollision, mcCollision.globalIndex()); + for (const auto& dplusMcCollisionPerMcCollision : dplusMcCollisionsPerMcCollision) { // should only ever be one + jethfutilities::fillHFMcCollisionTable(dplusMcCollisionPerMcCollision, products.productsDs.storedDsMcCollisionsTable); + products.productsDs.storedDsMcCollisionIdsTable(mcCollisionMapping[mcCollision.globalIndex()]); + dplusMcCollisionMapping[dplusMcCollisionPerMcCollision.globalIndex()] = products.productsDs.storedDsMcCollisionsTable.lastIndex(); + } + const auto dplusParticlesPerMcCollision = DsParticles.sliceBy(preslices.DsParticlesPerMcCollision, mcCollision.globalIndex()); + for (const auto& DsParticle : dplusParticlesPerMcCollision) { + jethfutilities::fillHFCandidateMcTable(DsParticle, products.productsDs.storedDsMcCollisionsTable.lastIndex(), products.productsDs.storedDsParticlesTable); + products.productsDs.storedDsParticleIdsTable(mcCollisionMapping[mcCollision.globalIndex()], particleMapping[DsParticle.mcParticleId()]); + } + } + } + } + PROCESS_SWITCH(JetDerivedDataWriter, processDsMCP, "write out Ds mcp output tables", false); + void processDstarMCP(soa::Join const& mcCollisions, aod::McCollisionsDstar const& DstarMcCollisions, aod::CandidatesDstarMCP const& DstarParticles) { dstarMcCollisionMapping.clear(); @@ -725,6 +843,28 @@ struct JetDerivedDataWriter { } PROCESS_SWITCH(JetDerivedDataWriter, processBplusMCP, "write out Bplus mcp output tables", false); + void processXicToXiPiPiMCP(soa::Join const& mcCollisions, aod::McCollisionsXicToXiPiPi const& XicToXiPiPiMcCollisions, aod::CandidatesXicToXiPiPiMCP const& XicToXiPiPiParticles) + { + dplusMcCollisionMapping.clear(); + dplusMcCollisionMapping.resize(XicToXiPiPiMcCollisions.size(), -1); + for (auto const& mcCollision : mcCollisions) { + if (mcCollision.isMcCollisionSelected()) { + const auto dplusMcCollisionsPerMcCollision = XicToXiPiPiMcCollisions.sliceBy(preslices.XicToXiPiPiMcCollisionsPerMcCollision, mcCollision.globalIndex()); + for (const auto& dplusMcCollisionPerMcCollision : dplusMcCollisionsPerMcCollision) { // should only ever be one + jethfutilities::fillHFMcCollisionTable(dplusMcCollisionPerMcCollision, products.productsXicToXiPiPi.storedXicToXiPiPiMcCollisionsTable); + products.productsXicToXiPiPi.storedXicToXiPiPiMcCollisionIdsTable(mcCollisionMapping[mcCollision.globalIndex()]); + dplusMcCollisionMapping[dplusMcCollisionPerMcCollision.globalIndex()] = products.productsXicToXiPiPi.storedXicToXiPiPiMcCollisionsTable.lastIndex(); + } + const auto dplusParticlesPerMcCollision = XicToXiPiPiParticles.sliceBy(preslices.XicToXiPiPiParticlesPerMcCollision, mcCollision.globalIndex()); + for (const auto& XicToXiPiPiParticle : dplusParticlesPerMcCollision) { + jethfutilities::fillHFCandidateMcTable(XicToXiPiPiParticle, products.productsXicToXiPiPi.storedXicToXiPiPiMcCollisionsTable.lastIndex(), products.productsXicToXiPiPi.storedXicToXiPiPiParticlesTable); + products.productsXicToXiPiPi.storedXicToXiPiPiParticleIdsTable(mcCollisionMapping[mcCollision.globalIndex()], particleMapping[XicToXiPiPiParticle.mcParticleId()]); + } + } + } + } + PROCESS_SWITCH(JetDerivedDataWriter, processXicToXiPiPiMCP, "write out XicToXiPiPi mcp output tables", false); + void processDielectronMCP(soa::Join::iterator const& mcCollision, aod::JMcParticles const&, soa::Join const& DielectronMcCollisions, aod::CandidatesDielectronMCP const& DielectronParticles) { if (mcCollision.isMcCollisionSelected()) { @@ -830,6 +970,20 @@ struct JetDerivedDataWriter { } PROCESS_SWITCH(JetDerivedDataWriter, processDplusMcCollisionMatch, "write out Dplus McCollision collision label output tables", false); + void processDsMcCollisionMatch(soa::Join::iterator const& mcCollision, soa::Join const& DsMcCollisions, aod::CollisionsDs const&) + { + if (mcCollision.isMcCollisionSelected()) { + for (const auto& DsMcCollision : DsMcCollisions) { // should just be one + std::vector dplusCollisionIDs; + for (auto const& dplusCollisionPerMcCollision : DsMcCollision.hfCollBases_as()) { + dplusCollisionIDs.push_back(dplusMcCollisionMapping[dplusCollisionPerMcCollision.globalIndex()]); + } + products.productsDs.storedDsMcCollisionsMatchingTable(dplusCollisionIDs); + } + } + } + PROCESS_SWITCH(JetDerivedDataWriter, processDsMcCollisionMatch, "write out Ds McCollision collision label output tables", false); + void processDstarMcCollisionMatch(soa::Join::iterator const& mcCollision, soa::Join const& DstarMcCollisions, aod::CollisionsDstar const&) { if (mcCollision.isMcCollisionSelected()) { @@ -885,6 +1039,20 @@ struct JetDerivedDataWriter { } } PROCESS_SWITCH(JetDerivedDataWriter, processBplusMcCollisionMatch, "write out Bplus McCollision collision label output tables", false); + + void processXicToXiPiPiMcCollisionMatch(soa::Join::iterator const& mcCollision, soa::Join const& XicToXiPiPiMcCollisions, aod::CollisionsXicToXiPiPi const&) + { + if (mcCollision.isMcCollisionSelected()) { + for (const auto& XicToXiPiPiMcCollision : XicToXiPiPiMcCollisions) { // should just be one + std::vector dplusCollisionIDs; + for (auto const& dplusCollisionPerMcCollision : XicToXiPiPiMcCollision.hfCollBases_as()) { + dplusCollisionIDs.push_back(dplusMcCollisionMapping[dplusCollisionPerMcCollision.globalIndex()]); + } + products.productsXicToXiPiPi.storedXicToXiPiPiMcCollisionsMatchingTable(dplusCollisionIDs); + } + } + } + PROCESS_SWITCH(JetDerivedDataWriter, processXicToXiPiPiMcCollisionMatch, "write out XicToXiPiPi McCollision collision label output tables", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGJE/TableProducer/emcalClusterHadronicCorrectionTask.cxx b/PWGJE/TableProducer/emcalClusterHadronicCorrectionTask.cxx index 4e4cdedd197..67672c53222 100644 --- a/PWGJE/TableProducer/emcalClusterHadronicCorrectionTask.cxx +++ b/PWGJE/TableProducer/emcalClusterHadronicCorrectionTask.cxx @@ -87,7 +87,7 @@ struct EmcalClusterHadronicCorrectionTask { registry.add("h_Ecluster2", "; Ecluster2 (GeV); entries", {HistType::kTH1F, {{350, 0., 350.}}}); registry.add("h_EclusterAll1", "; EclusterAll1 (GeV); entries", {HistType::kTH1F, {{350, 0., 350.}}}); registry.add("h_EclusterAll2", "; EclusterAll2 (GeV); entries", {HistType::kTH1F, {{350, 0., 350.}}}); - registry.add("h_ClsTime", "Cluster time distribution of uncorrected cluster E; #it{t}_{cls} (ns); entries", {HistType::kTH1F, {{500, -250., 250.}}}); + registry.add("h_ClsTime", "Cluster time distribution of uncorrected cluster E; #it{t}_{cls} (ns); entries", {HistType::kTH1F, {{1500, -600., 900.}}}); registry.add("h_ClsM02", "Cluster M02 distribution of uncorrected cluster E; #it{M}_{02}; entries", {HistType::kTH1F, {{400, 0., 5.}}}); registry.add("h2_ClsEvsNmatches", "Original cluster energy vs Nmatches; Cls E w/o correction (GeV); Nmatches", {HistType::kTH2F, {{350, 0., 350.}, {100, -0.5, 21.}}}); registry.add("h2_ClsEvsEcluster1", "; Cls E w/o correction (GeV); Ecluster1 (GeV)", {HistType::kTH2F, {{350, 0., 350.}, {350, 0., 350.}}}); diff --git a/PWGJE/TableProducer/emcalCorrectionTask.cxx b/PWGJE/TableProducer/emcalCorrectionTask.cxx index 72f7941fa9e..1935748a4a0 100644 --- a/PWGJE/TableProducer/emcalCorrectionTask.cxx +++ b/PWGJE/TableProducer/emcalCorrectionTask.cxx @@ -577,9 +577,8 @@ struct EmcalCorrectionTask { // Adding -1 and later when filling the clusterID<->cellID table skip all cases where this is -1 if (cellIndicesBC.size() < cellsBC.size()) { cellIndicesBC.reserve(cellsBC.size()); - for (size_t iMissing = 0; iMissing < (cellsBC.size() - cellIndicesBC.size()); ++iMissing) { - cellIndicesBC.emplace_back(-1); - } + size_t nMissing = cellsBC.size() - cellIndicesBC.size(); + cellIndicesBC.insert(cellIndicesBC.end(), nMissing, -1); } if (emcCrossTalkConf.createHistograms.value) { for (const auto& cell : cellsBC) { @@ -877,10 +876,12 @@ struct EmcalCorrectionTask { mHistManager.fill(HIST("hClusterFCrossSigmaShortE"), cluster.E(), cluster.getFCross(), cluster.getM20()); } if (indexMapPair && trackGlobalIndex) { - for (unsigned int iTrack = 0; iTrack < indexMapPair->matchIndexTrack[iCluster].size(); iTrack++) { - if (indexMapPair->matchIndexTrack[iCluster][iTrack] >= 0) { - LOG(debug) << "Found track " << (*trackGlobalIndex)[indexMapPair->matchIndexTrack[iCluster][iTrack]] << " in cluster " << cluster.getID(); - matchedTracks(clusters.lastIndex(), (*trackGlobalIndex)[indexMapPair->matchIndexTrack[iCluster][iTrack]], indexMapPair->matchDeltaPhi[iCluster][iTrack], indexMapPair->matchDeltaEta[iCluster][iTrack]); + if (iCluster < indexMapPair->matchIndexTrack.size() && indexMapPair->matchIndexTrack.size() > 0) { + for (unsigned int iTrack = 0; iTrack < indexMapPair->matchIndexTrack[iCluster].size(); iTrack++) { + if (indexMapPair->matchIndexTrack[iCluster][iTrack] >= 0) { + LOG(debug) << "Found track " << (*trackGlobalIndex)[indexMapPair->matchIndexTrack[iCluster][iTrack]] << " in cluster " << cluster.getID(); + matchedTracks(clusters.lastIndex(), (*trackGlobalIndex)[indexMapPair->matchIndexTrack[iCluster][iTrack]], indexMapPair->matchDeltaPhi[iCluster][iTrack], indexMapPair->matchDeltaEta[iCluster][iTrack]); + } } } } diff --git a/PWGJE/TableProducer/eventwiseConstituentSubtractor.cxx b/PWGJE/TableProducer/eventwiseConstituentSubtractor.cxx index f840a339534..fb914aa0277 100644 --- a/PWGJE/TableProducer/eventwiseConstituentSubtractor.cxx +++ b/PWGJE/TableProducer/eventwiseConstituentSubtractor.cxx @@ -44,6 +44,8 @@ struct eventWiseConstituentSubtractorTask { Produces particleSubtractedD0Table; Produces trackSubtractedDplusTable; Produces particleSubtractedDplusTable; + Produces trackSubtractedDsTable; + Produces particleSubtractedDsTable; Produces trackSubtractedDstarTable; Produces particleSubtractedDstarTable; Produces trackSubtractedLcTable; @@ -52,6 +54,8 @@ struct eventWiseConstituentSubtractorTask { Produces particleSubtractedB0Table; Produces trackSubtractedBplusTable; Produces particleSubtractedBplusTable; + Produces trackSubtractedXicToXiPiPiTable; + Produces particleSubtractedXicToXiPiPiTable; Produces trackSubtractedDielectronTable; Produces particleSubtractedDielectronTable; @@ -184,6 +188,18 @@ struct eventWiseConstituentSubtractorTask { } PROCESS_SWITCH(eventWiseConstituentSubtractorTask, processDplusMcCollisions, "Fill table of subtracted tracks for collisions with Dplus MCP candidates", false); + void processDsCollisions(aod::JetCollision const&, soa::Filtered const& tracks, soa::Join const& candidates) + { + analyseHF(tracks, candidates, trackSubtractedDsTable); + } + PROCESS_SWITCH(eventWiseConstituentSubtractorTask, processDsCollisions, "Fill table of subtracted tracks for collisions with Ds candidates", false); + + void processDsMcCollisions(aod::JetMcCollision const&, soa::Filtered const& tracks, soa::Join const& candidates) + { + analyseHFMc(tracks, candidates, particleSubtractedDsTable); + } + PROCESS_SWITCH(eventWiseConstituentSubtractorTask, processDsMcCollisions, "Fill table of subtracted tracks for collisions with Ds MCP candidates", false); + void processDstarCollisions(aod::JetCollision const&, soa::Filtered const& tracks, soa::Join const& candidates) { analyseHF(tracks, candidates, trackSubtractedDstarTable); @@ -232,6 +248,18 @@ struct eventWiseConstituentSubtractorTask { } PROCESS_SWITCH(eventWiseConstituentSubtractorTask, processBplusMcCollisions, "Fill table of subtracted tracks for collisions with Bplus MCP candidates", false); + void processXicToXiPiPiCollisions(aod::JetCollision const&, soa::Filtered const& tracks, soa::Join const& candidates) + { + analyseHF(tracks, candidates, trackSubtractedXicToXiPiPiTable); + } + PROCESS_SWITCH(eventWiseConstituentSubtractorTask, processXicToXiPiPiCollisions, "Fill table of subtracted tracks for collisions with XicToXiPiPi candidates", false); + + void processXicToXiPiPiMcCollisions(aod::JetMcCollision const&, soa::Filtered const& tracks, soa::Join const& candidates) + { + analyseHFMc(tracks, candidates, particleSubtractedXicToXiPiPiTable); + } + PROCESS_SWITCH(eventWiseConstituentSubtractorTask, processXicToXiPiPiMcCollisions, "Fill table of subtracted tracks for collisions with XicToXiPiPi MCP candidates", false); + void processDielectronCollisions(aod::JetCollision const&, soa::Filtered const& tracks, soa::Join const& candidates) { analyseHF(tracks, candidates, trackSubtractedDielectronTable); diff --git a/PWGJE/TableProducer/jetEventWeightMCD.cxx b/PWGJE/TableProducer/jetEventWeightMCD.cxx index 7036f5407f6..ddb518e1bba 100644 --- a/PWGJE/TableProducer/jetEventWeightMCD.cxx +++ b/PWGJE/TableProducer/jetEventWeightMCD.cxx @@ -60,10 +60,12 @@ using NeutralMCJetsEventWeight = JetEventWeightMCDTask; using D0ChargedMCJetsEventWeight = JetEventWeightMCDTask; using DplusChargedMCJetsEventWeight = JetEventWeightMCDTask; +using DsChargedMCJetsEventWeight = JetEventWeightMCDTask; using DstarChargedMCJetsEventWeight = JetEventWeightMCDTask; using LcChargedMCJetsEventWeight = JetEventWeightMCDTask; using B0ChargedMCJetsEventWeight = JetEventWeightMCDTask; using BplusChargedMCJetsEventWeight = JetEventWeightMCDTask; +using XicToXiPiPiChargedMCJetsEventWeight = JetEventWeightMCDTask; using V0ChargedMCJetsEventWeight = JetEventWeightMCDTask; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) @@ -91,6 +93,10 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) adaptAnalysisTask(cfgc, SetDefaultProcesses{}, TaskName{"jet-dplus-eventweight-mcd-charged"})); + tasks.emplace_back( + adaptAnalysisTask(cfgc, + SetDefaultProcesses{}, TaskName{"jet-ds-eventweight-mcd-charged"})); + tasks.emplace_back( adaptAnalysisTask(cfgc, SetDefaultProcesses{}, TaskName{"jet-dstar-eventweight-mcd-charged"})); @@ -107,6 +113,10 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) adaptAnalysisTask(cfgc, SetDefaultProcesses{}, TaskName{"jet-bplus-eventweight-mcd-charged"})); + tasks.emplace_back( + adaptAnalysisTask(cfgc, + SetDefaultProcesses{}, TaskName{"jet-xictoxipipi-eventweight-mcd-charged"})); + tasks.emplace_back( adaptAnalysisTask(cfgc, SetDefaultProcesses{}, TaskName{"jet-v0-eventweight-mcd-charged"})); diff --git a/PWGJE/TableProducer/jetEventWeightMCP.cxx b/PWGJE/TableProducer/jetEventWeightMCP.cxx index ba2efb56ced..7f262e998ea 100644 --- a/PWGJE/TableProducer/jetEventWeightMCP.cxx +++ b/PWGJE/TableProducer/jetEventWeightMCP.cxx @@ -49,10 +49,12 @@ using NeutralMCJetsEventWeight = JetEventWeightMCPTask; using D0ChargedMCJetsEventWeight = JetEventWeightMCPTask; using DplusChargedMCJetsEventWeight = JetEventWeightMCPTask; +using DsChargedMCJetsEventWeight = JetEventWeightMCPTask; using DstarChargedMCJetsEventWeight = JetEventWeightMCPTask; using LcChargedMCJetsEventWeight = JetEventWeightMCPTask; using B0ChargedMCJetsEventWeight = JetEventWeightMCPTask; using BplusChargedMCJetsEventWeight = JetEventWeightMCPTask; +using XicToXiPiPiChargedMCJetsEventWeight = JetEventWeightMCPTask; using V0ChargedMCJetsEventWeight = JetEventWeightMCPTask; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) @@ -80,6 +82,10 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) adaptAnalysisTask(cfgc, SetDefaultProcesses{}, TaskName{"jet-dplus-eventweight-mcp-charged"})); + tasks.emplace_back( + adaptAnalysisTask(cfgc, + SetDefaultProcesses{}, TaskName{"jet-ds-eventweight-mcp-charged"})); + tasks.emplace_back( adaptAnalysisTask(cfgc, SetDefaultProcesses{}, TaskName{"jet-dstar-eventweight-mcp-charged"})); @@ -96,6 +102,10 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) adaptAnalysisTask(cfgc, SetDefaultProcesses{}, TaskName{"jet-bplus-eventweight-mcp-charged"})); + tasks.emplace_back( + adaptAnalysisTask(cfgc, + SetDefaultProcesses{}, TaskName{"jet-xictoxipipi-eventweight-mcp-charged"})); + tasks.emplace_back( adaptAnalysisTask(cfgc, SetDefaultProcesses{}, TaskName{"jet-v0-eventweight-mcp-charged"})); diff --git a/PWGJE/TableProducer/mcOutlierRejector.cxx b/PWGJE/TableProducer/mcOutlierRejector.cxx index 427a5afdfad..48241281565 100644 --- a/PWGJE/TableProducer/mcOutlierRejector.cxx +++ b/PWGJE/TableProducer/mcOutlierRejector.cxx @@ -94,10 +94,12 @@ struct McOutlierRejectorTask { PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionObjects, processSelectingFullMCDetectorLevelJets, "process mc detector level full jets", false); PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionObjects, processSelectingD0ChargedMCDetectorLevelJets, "process mc detector level D0 charged jets", false); PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionObjects, processSelectingDplusChargedMCDetectorLevelJets, "process mc detector level Dplus charged jets", false); - // PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionObjects, processSelectingDstarChargedMCDetectorLevelJets, "process mc detector level Dstar charged jets", false); + PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionObjects, processSelectingDsChargedMCDetectorLevelJets, "process mc detector level Ds charged jets", false); + PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionObjects, processSelectingDstarChargedMCDetectorLevelJets, "process mc detector level Dstar charged jets", false); PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionObjects, processSelectingLcChargedMCDetectorLevelJets, "process mc detector level Lc charged jets", false); - // PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionObjects, processSelectingB0ChargedMCDetectorLevelJets, "process mc detector level B0 charged jets", false); + PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionObjects, processSelectingB0ChargedMCDetectorLevelJets, "process mc detector level B0 charged jets", false); PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionObjects, processSelectingBplusChargedMCDetectorLevelJets, "process mc detector level Bplus charged jets", false); + PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionObjects, processSelectingXicToXiPiPiChargedMCDetectorLevelJets, "process mc detector level XicToXiPiPi charged jets", false); PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionObjects, processSelectingDielectronChargedMCDetectorLevelJets, "process mc detector level Dielectron charged jets", false); PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionObjects, processSelectingTracks, "process tracks", false); PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionMcObjects, processSelectingChargedMCParticleLevelJets, "process mc particle level charged jets", true); @@ -105,10 +107,12 @@ struct McOutlierRejectorTask { PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionMcObjects, processSelectingFullMCParticleLevelJets, "process mc particle level full jets", false); PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionMcObjects, processSelectingD0ChargedMCParticleLevelJets, "process mc particle level D0 charged jets", false); PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionMcObjects, processSelectingDplusChargedMCParticleLevelJets, "process mc particle level Dplus charged jets", false); - // PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionMcObjects, processSelectingDstarChargedMCParticleLevelJets, "process mc particle level Dstar charged jets", false); + PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionMcObjects, processSelectingDsChargedMCParticleLevelJets, "process mc particle level Ds charged jets", false); + PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionMcObjects, processSelectingDstarChargedMCParticleLevelJets, "process mc particle level Dstar charged jets", false); PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionMcObjects, processSelectingLcChargedMCParticleLevelJets, "process mc particle level Lc charged jets", false); - // PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionMcObjects, processSelectingB0ChargedMCParticleLevelJets, "process mc particle level B0 charged jets", false); + PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionMcObjects, processSelectingB0ChargedMCParticleLevelJets, "process mc particle level B0 charged jets", false); PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionMcObjects, processSelectingBplusChargedMCParticleLevelJets, "process mc particle level Bplus charged jets", false); + PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionMcObjects, processSelectingXicToXiPiPiChargedMCParticleLevelJets, "process mc particle level XicToXiPiPi charged jets", false); PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionMcObjects, processSelectingDielectronChargedMCParticleLevelJets, "process mc particle level Dielectron charged jets", false); PROCESS_SWITCH_FULL(McOutlierRejectorTask, processSelectionMcObjects, processSelectingParticles, "process mc particles", false); diff --git a/PWGJE/TableProducer/rhoEstimator.cxx b/PWGJE/TableProducer/rhoEstimator.cxx index b6026e46291..e854868a840 100644 --- a/PWGJE/TableProducer/rhoEstimator.cxx +++ b/PWGJE/TableProducer/rhoEstimator.cxx @@ -48,14 +48,18 @@ struct RhoEstimatorTask { Produces rhoD0McTable; Produces rhoDplusTable; Produces rhoDplusMcTable; + Produces rhoDsTable; + Produces rhoDsMcTable; Produces rhoDstarTable; Produces rhoDstarMcTable; Produces rhoLcTable; Produces rhoLcMcTable; - Produces rhoBplusTable; - Produces rhoBplusMcTable; Produces rhoB0Table; Produces rhoB0McTable; + Produces rhoBplusTable; + Produces rhoBplusMcTable; + Produces rhoXicToXiPiPiTable; + Produces rhoXicToXiPiPiMcTable; Produces rhoDielectronTable; Produces rhoDielectronMcTable; @@ -279,6 +283,34 @@ struct RhoEstimatorTask { } PROCESS_SWITCH(RhoEstimatorTask, processDplusMcCollisions, "Fill rho tables for collisions with Dplus MCP candidates", false); + void processDsCollisions(aod::JetCollision const& collision, soa::Filtered const& tracks, aod::CandidatesDsData const& candidates) + { + for (auto& candidate : candidates) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits) || collision.centFT0M() < config.centralityMin || collision.centFT0M() >= config.centralityMax || collision.trackOccupancyInTimeRange() > config.trackOccupancyInTimeRangeMax || std::abs(collision.posZ()) > config.vertexZCut) { + rhoDsTable(0.0, 0.0); + continue; + } + inputParticles.clear(); + jetfindingutilities::analyseTracks(inputParticles, tracks, trackSelection, config.trackingEfficiency, &candidate); + + auto [rho, rhoM] = bkgSub.estimateRhoAreaMedian(inputParticles, config.doSparse); + rhoDsTable(rho, rhoM); + } + } + PROCESS_SWITCH(RhoEstimatorTask, processDsCollisions, "Fill rho tables for collisions with Ds candidates", false); + + void processDsMcCollisions(aod::JetMcCollision const&, soa::Filtered const& particles, aod::CandidatesDsMCP const& candidates) + { + for (auto& candidate : candidates) { + inputParticles.clear(); + jetfindingutilities::analyseParticles(inputParticles, particleSelection, 1, particles, pdgDatabase, &candidate); + + auto [rho, rhoM] = bkgSub.estimateRhoAreaMedian(inputParticles, config.doSparse); + rhoDsMcTable(rho, rhoM); + } + } + PROCESS_SWITCH(RhoEstimatorTask, processDsMcCollisions, "Fill rho tables for collisions with Ds MCP candidates", false); + void processDstarCollisions(aod::JetCollision const& collision, soa::Filtered const& tracks, aod::CandidatesDstarData const& candidates) { for (auto& candidate : candidates) { @@ -391,6 +423,34 @@ struct RhoEstimatorTask { } PROCESS_SWITCH(RhoEstimatorTask, processBplusMcCollisions, "Fill rho tables for collisions with Bplus MCP candidates", false); + void processXicToXiPiPiCollisions(aod::JetCollision const& collision, soa::Filtered const& tracks, aod::CandidatesXicToXiPiPiData const& candidates) + { + for (auto& candidate : candidates) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits) || collision.centFT0M() < config.centralityMin || collision.centFT0M() >= config.centralityMax || collision.trackOccupancyInTimeRange() > config.trackOccupancyInTimeRangeMax || std::abs(collision.posZ()) > config.vertexZCut) { + rhoXicToXiPiPiTable(0.0, 0.0); + continue; + } + inputParticles.clear(); + jetfindingutilities::analyseTracks(inputParticles, tracks, trackSelection, config.trackingEfficiency, &candidate); + + auto [rho, rhoM] = bkgSub.estimateRhoAreaMedian(inputParticles, config.doSparse); + rhoXicToXiPiPiTable(rho, rhoM); + } + } + PROCESS_SWITCH(RhoEstimatorTask, processXicToXiPiPiCollisions, "Fill rho tables for collisions with XicToXiPiPi candidates", false); + + void processXicToXiPiPiMcCollisions(aod::JetMcCollision const&, soa::Filtered const& particles, aod::CandidatesXicToXiPiPiMCP const& candidates) + { + for (auto& candidate : candidates) { + inputParticles.clear(); + jetfindingutilities::analyseParticles(inputParticles, particleSelection, 1, particles, pdgDatabase, &candidate); + + auto [rho, rhoM] = bkgSub.estimateRhoAreaMedian(inputParticles, config.doSparse); + rhoXicToXiPiPiMcTable(rho, rhoM); + } + } + PROCESS_SWITCH(RhoEstimatorTask, processXicToXiPiPiMcCollisions, "Fill rho tables for collisions with XicToXiPiPi MCP candidates", false); + void processDielectronCollisions(aod::JetCollision const& collision, soa::Filtered const& tracks, aod::CandidatesDielectronData const& candidates) { for (auto& candidate : candidates) { diff --git a/PWGJE/Tasks/CMakeLists.txt b/PWGJE/Tasks/CMakeLists.txt index 08fbfde7fc4..289cff5bd3b 100644 --- a/PWGJE/Tasks/CMakeLists.txt +++ b/PWGJE/Tasks/CMakeLists.txt @@ -54,6 +54,10 @@ o2physics_add_dpl_workflow(photon-charged-trigger-correlation SOURCES photonChargedTriggerCorrelation.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(task-emc-extensive-mc-qa + SOURCES taskEmcExtensiveMcQa.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::EMCALBase O2Physics::AnalysisCore O2Physics::EventFilteringUtils + COMPONENT_NAME Analysis) if(FastJet_FOUND) o2physics_add_dpl_workflow(jet-background-analysis @@ -76,6 +80,10 @@ if(FastJet_FOUND) SOURCES jetSubstructureDplus.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-substructure-ds + SOURCES jetSubstructureDs.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(jet-substructure-dstar SOURCES jetSubstructureDstar.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore @@ -92,6 +100,10 @@ if(FastJet_FOUND) SOURCES jetSubstructureBplus.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-substructure-xictoxipipi + SOURCES jetSubstructureXicToXiPiPi.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(jet-substructure-dielectron SOURCES jetSubstructureDielectron.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore @@ -104,6 +116,10 @@ if(FastJet_FOUND) SOURCES jetSubstructureDplusOutput.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-substructure-ds-output + SOURCES jetSubstructureDsOutput.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(jet-substructure-dstar-output SOURCES jetSubstructureDstarOutput.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore @@ -120,6 +136,10 @@ if(FastJet_FOUND) SOURCES jetSubstructureBplusOutput.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-substructure-xictoxipipi-output + SOURCES jetSubstructureXicToXiPiPiOutput.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(jet-substructure-dielectron-output SOURCES jetSubstructureDielectronOutput.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore @@ -152,6 +172,10 @@ if(FastJet_FOUND) SOURCES jetFinderDplusQA.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-finder-ds-qa + SOURCES jetFinderDsQA.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(jet-finder-dstar-qa SOURCES jetFinderDstarQA.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore @@ -168,6 +192,10 @@ if(FastJet_FOUND) SOURCES jetFinderBplusQA.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-finder-xictoxipipi-qa + SOURCES jetFinderXicToXiPiPiQA.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(jet-finder-dielectron-qa SOURCES jetFinderDielectronQA.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore @@ -272,6 +300,7 @@ if(FastJet_FOUND) o2physics_add_dpl_workflow(full-jet-spectra SOURCES fullJetSpectra.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore + O2Physics::AnalysisCCDB O2Physics::EventFilteringUtils COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(bjet-tagging-ml SOURCES bjetTaggingML.cxx diff --git a/PWGJE/Tasks/bjetTaggingGnn.cxx b/PWGJE/Tasks/bjetTaggingGnn.cxx index 1e74fb21ff3..4e206c43027 100644 --- a/PWGJE/Tasks/bjetTaggingGnn.cxx +++ b/PWGJE/Tasks/bjetTaggingGnn.cxx @@ -57,9 +57,12 @@ struct BjetTaggingGnn { Configurable trackEtaMin{"trackEtaMin", -0.9, "minimum track eta"}; Configurable trackEtaMax{"trackEtaMax", 0.9, "maximum track eta"}; + Configurable maxIPxy{"maxIPxy", 10, "maximum track DCA in xy plane"}; + Configurable maxIPz{"maxIPz", 10, "maximum track DCA in z direction"}; + Configurable trackNppCrit{"trackNppCrit", 0.95, "track not physical primary ratio"}; - // track level configurables + // sv level configurables Configurable svPtMin{"svPtMin", 0.5, "minimum SV pT"}; // jet level configurables @@ -70,9 +73,15 @@ struct BjetTaggingGnn { Configurable> jetRadii{"jetRadii", std::vector{0.4}, "jet resolution parameters"}; + Configurable dbMin{"dbMin", -10., "minimum GNN Db"}; + Configurable dbMax{"dbMax", 20., "maximum GNN Db"}; + Configurable dbNbins{"dbNbins", 3000, "number of bins in axisDbFine"}; + Configurable doDataDriven{"doDataDriven", false, "Flag whether to use fill THnSpase for data driven methods"}; Configurable callSumw2{"callSumw2", false, "Flag whether to call THnSparse::Sumw2() for error calculation"}; + Configurable trainingDatasetRatioParam{"trainingDatasetRatioParam", 0, "Parameter for splitting training/evaluation datasets by collisionId"}; + std::vector eventSelectionBits; std::vector jetRadiiValues; @@ -83,11 +92,11 @@ struct BjetTaggingGnn { eventSelectionBits = jetderiveddatautilities::initialiseEventSelectionBits(static_cast(eventSelections)); - registry.add("h_vertexZ", "Vertex Z;#it{Z} (cm)", {HistType::kTH1F, {{40, -20.0, 20.0}}}); + registry.add("h_vertexZ", "Vertex Z;#it{Z} (cm)", {HistType::kTH1F, {{100, -20.0, 20.0}}}, callSumw2); const AxisSpec axisJetpT{200, 0., 200., "#it{p}_{T} (GeV/#it{c})"}; - const AxisSpec axisDb{200, -10., 20., "#it{D}_{b}"}; - const AxisSpec axisDbFine{3000, -10., 20., "#it{D}_{b}"}; + const AxisSpec axisDb{200, dbMin, dbMax, "#it{D}_{b}"}; + const AxisSpec axisDbFine{dbNbins, dbMin, dbMax, "#it{D}_{b}"}; const AxisSpec axisSVMass{200, 0., 10., "#it{m}_{SV} (GeV/#it{c}^{2})"}; const AxisSpec axisSVEnergy{200, 0., 100., "#it{E}_{SV} (GeV)"}; const AxisSpec axisSLxy{200, 0., 100., "#it{SL}_{xy}"}; @@ -95,40 +104,24 @@ struct BjetTaggingGnn { const AxisSpec axisJetProb{200, 0., 40., "-ln(JP)"}; const AxisSpec axisNTracks{42, 0, 42, "#it{n}_{tracks}"}; - registry.add("h_jetpT", "", {HistType::kTH1F, {axisJetpT}}); + registry.add("h_jetpT", "", {HistType::kTH1F, {axisJetpT}}, callSumw2); registry.add("h_Db", "", {HistType::kTH1F, {axisDbFine}}); registry.add("h2_jetpT_Db", "", {HistType::kTH2F, {axisJetpT, axisDb}}); - registry.add("h2_jetpT_SVMass", "", {HistType::kTH2F, {axisJetpT, axisSVMass}}); - registry.add("h2_jetpT_jetMass", "", {HistType::kTH2F, {axisJetpT, axisJetMass}}); - registry.add("h2_jetpT_jetProb", "", {HistType::kTH2F, {axisJetpT, axisJetProb}}); - registry.add("h2_jetpT_nTracks", "", {HistType::kTH2F, {axisJetpT, axisNTracks}}); if (doprocessMCJets) { - registry.add("h_jetpT_b", "b-jet", {HistType::kTH1F, {axisJetpT}}); - registry.add("h_jetpT_c", "c-jet", {HistType::kTH1F, {axisJetpT}}); - registry.add("h_jetpT_lf", "lf-jet", {HistType::kTH1F, {axisJetpT}}); + registry.add("h_jetpT_b", "b-jet", {HistType::kTH1F, {axisJetpT}}, callSumw2); + registry.add("h_jetpT_c", "c-jet", {HistType::kTH1F, {axisJetpT}}, callSumw2); + registry.add("h_jetpT_lf", "lf-jet", {HistType::kTH1F, {axisJetpT}}, callSumw2); registry.add("h_Db_b", "b-jet", {HistType::kTH1F, {axisDbFine}}); registry.add("h_Db_c", "c-jet", {HistType::kTH1F, {axisDbFine}}); registry.add("h_Db_lf", "lf-jet", {HistType::kTH1F, {axisDbFine}}); registry.add("h2_jetpT_Db_b", "b-jet", {HistType::kTH2F, {axisJetpT, axisDb}}); registry.add("h2_jetpT_Db_c", "c-jet", {HistType::kTH2F, {axisJetpT, axisDb}}); registry.add("h2_jetpT_Db_lf", "lf-jet", {HistType::kTH2F, {axisJetpT, axisDb}}); - registry.add("h2_jetpT_SVMass_b", "b-jet", {HistType::kTH2F, {axisJetpT, axisSVMass}}); - registry.add("h2_jetpT_SVMass_c", "c-jet", {HistType::kTH2F, {axisJetpT, axisSVMass}}); - registry.add("h2_jetpT_SVMass_lf", "lf-jet", {HistType::kTH2F, {axisJetpT, axisSVMass}}); - registry.add("h2_jetpT_jetMass_b", "b-jet", {HistType::kTH2F, {axisJetpT, axisJetMass}}); - registry.add("h2_jetpT_jetMass_c", "c-jet", {HistType::kTH2F, {axisJetpT, axisJetMass}}); - registry.add("h2_jetpT_jetMass_lf", "lf-jet", {HistType::kTH2F, {axisJetpT, axisJetMass}}); - registry.add("h2_jetpT_jetProb_b", "b-jet", {HistType::kTH2F, {axisJetpT, axisJetProb}}); - registry.add("h2_jetpT_jetProb_c", "c-jet", {HistType::kTH2F, {axisJetpT, axisJetProb}}); - registry.add("h2_jetpT_jetProb_lf", "lf-jet", {HistType::kTH2F, {axisJetpT, axisJetProb}}); - registry.add("h2_jetpT_nTracks_b", "b-jet", {HistType::kTH2F, {axisJetpT, axisNTracks}}); - registry.add("h2_jetpT_nTracks_c", "c-jet", {HistType::kTH2F, {axisJetpT, axisNTracks}}); - registry.add("h2_jetpT_nTracks_lf", "lf-jet", {HistType::kTH2F, {axisJetpT, axisNTracks}}); - registry.add("h2_Response_DetjetpT_PartjetpT", "", {HistType::kTH2F, {axisJetpT, axisJetpT}}); - registry.add("h2_Response_DetjetpT_PartjetpT_b", "b-jet", {HistType::kTH2F, {axisJetpT, axisJetpT}}); - registry.add("h2_Response_DetjetpT_PartjetpT_c", "c-jet", {HistType::kTH2F, {axisJetpT, axisJetpT}}); - registry.add("h2_Response_DetjetpT_PartjetpT_lf", "lf-jet", {HistType::kTH2F, {axisJetpT, axisJetpT}}); + registry.add("h2_Response_DetjetpT_PartjetpT", "", {HistType::kTH2F, {axisJetpT, axisJetpT}}, callSumw2); + registry.add("h2_Response_DetjetpT_PartjetpT_b", "b-jet", {HistType::kTH2F, {axisJetpT, axisJetpT}}, callSumw2); + registry.add("h2_Response_DetjetpT_PartjetpT_c", "c-jet", {HistType::kTH2F, {axisJetpT, axisJetpT}}, callSumw2); + registry.add("h2_Response_DetjetpT_PartjetpT_lf", "lf-jet", {HistType::kTH2F, {axisJetpT, axisJetpT}, callSumw2}); registry.add("h2_jetpT_Db_lf_none", "lf-jet (none)", {HistType::kTH2F, {axisJetpT, axisDb}}); registry.add("h2_jetpT_Db_lf_matched", "lf-jet (matched)", {HistType::kTH2F, {axisJetpT, axisDb}}); registry.add("h2_jetpT_Db_npp", "NotPhysPrim", {HistType::kTH2F, {axisJetpT, axisDb}}); @@ -139,17 +132,13 @@ struct BjetTaggingGnn { registry.add("h_Db_npp_b", "NotPhysPrim b-jet", {HistType::kTH1F, {axisDbFine}}); registry.add("h_Db_npp_c", "NotPhysPrim c-jet", {HistType::kTH1F, {axisDbFine}}); registry.add("h_Db_npp_lf", "NotPhysPrim lf-jet", {HistType::kTH1F, {axisDbFine}}); - // registry.add("h2_pT_dcaXY_pp", "tracks", {HistType::kTH2F, {axisJetpT, {200, 0., 1.}}}); - // registry.add("h2_pT_dcaXY_npp", "NotPhysPrim tracks", {HistType::kTH2F, {axisJetpT, {200, 0., 1.}}}); - // registry.add("h2_pT_dcaZ_pp", "tracks", {HistType::kTH2F, {axisJetpT, {200, 0., 2.}}}); - // registry.add("h2_pT_dcaZ_npp", "NotPhysPrim tracks", {HistType::kTH2F, {axisJetpT, {200, 0., 2.}}}); } if (doprocessMCTruthJets) { - registry.add("h_jetpT_particle", "", {HistType::kTH1F, {axisJetpT}}); - registry.add("h_jetpT_particle_b", "particle b-jet", {HistType::kTH1F, {axisJetpT}}); - registry.add("h_jetpT_particle_c", "particle c-jet", {HistType::kTH1F, {axisJetpT}}); - registry.add("h_jetpT_particle_lf", "particle lf-jet", {HistType::kTH1F, {axisJetpT}}); + registry.add("h_jetpT_particle", "", {HistType::kTH1F, {axisJetpT}}, callSumw2); + registry.add("h_jetpT_particle_b", "particle b-jet", {HistType::kTH1F, {axisJetpT}}, callSumw2); + registry.add("h_jetpT_particle_c", "particle c-jet", {HistType::kTH1F, {axisJetpT}}, callSumw2); + registry.add("h_jetpT_particle_lf", "particle lf-jet", {HistType::kTH1F, {axisJetpT}}, callSumw2); } if (doDataDriven) { @@ -181,7 +170,7 @@ struct BjetTaggingGnn { int nTracks = 0; for (const auto& constituent : analysisJet.template tracks_as()) { - if (constituent.pt() < trackPtMin) { + if (constituent.pt() < trackPtMin || !jettaggingutilities::trackAcceptanceWithDca(constituent, maxIPxy, maxIPz)) { continue; } @@ -266,10 +255,6 @@ struct BjetTaggingGnn { registry.fill(HIST("h_jetpT"), analysisJet.pt()); registry.fill(HIST("h_Db"), analysisJet.scoreML()); registry.fill(HIST("h2_jetpT_Db"), analysisJet.pt(), analysisJet.scoreML()); - registry.fill(HIST("h2_jetpT_SVMass"), analysisJet.pt(), mSV); - registry.fill(HIST("h2_jetpT_jetMass"), analysisJet.pt(), analysisJet.mass()); - registry.fill(HIST("h2_jetpT_jetProb"), analysisJet.pt(), analysisJet.jetProb()); - registry.fill(HIST("h2_jetpT_nTracks"), analysisJet.pt(), nTracks); if (doDataDriven) { registry.fill(HIST("hSparse_Incljets"), analysisJet.pt(), analysisJet.scoreML(), mSV, analysisJet.mass(), nTracks); @@ -288,7 +273,12 @@ struct BjetTaggingGnn { return; } - registry.fill(HIST("h_vertexZ"), collision.posZ()); + // Uses only collisionId % trainingDatasetRaioParam != 0 for evaluation dataset + if (trainingDatasetRatioParam && collision.collisionId() % trainingDatasetRatioParam == 0) { + return; + } + + registry.fill(HIST("h_vertexZ"), collision.posZ(), useEventWeight ? collision.weight() : 1.f); for (const auto& analysisJet : MCDjets) { @@ -347,35 +337,19 @@ struct BjetTaggingGnn { registry.fill(HIST("h_jetpT"), analysisJet.pt(), weight); registry.fill(HIST("h_Db"), analysisJet.scoreML(), weight); registry.fill(HIST("h2_jetpT_Db"), analysisJet.pt(), analysisJet.scoreML(), weight); - registry.fill(HIST("h2_jetpT_SVMass"), analysisJet.pt(), mSV, weight); - registry.fill(HIST("h2_jetpT_jetMass"), analysisJet.pt(), analysisJet.mass(), weight); - registry.fill(HIST("h2_jetpT_jetProb"), analysisJet.pt(), analysisJet.jetProb(), weight); - registry.fill(HIST("h2_jetpT_nTracks"), analysisJet.pt(), nTracks, weight); if (jetFlavor == JetTaggingSpecies::beauty) { registry.fill(HIST("h_jetpT_b"), analysisJet.pt(), weight); registry.fill(HIST("h_Db_b"), analysisJet.scoreML(), weight); registry.fill(HIST("h2_jetpT_Db_b"), analysisJet.pt(), analysisJet.scoreML(), weight); - registry.fill(HIST("h2_jetpT_SVMass_b"), analysisJet.pt(), mSV, weight); - registry.fill(HIST("h2_jetpT_jetMass_b"), analysisJet.pt(), analysisJet.mass(), weight); - registry.fill(HIST("h2_jetpT_jetProb_b"), analysisJet.pt(), analysisJet.jetProb(), weight); - registry.fill(HIST("h2_jetpT_nTracks_b"), analysisJet.pt(), nTracks, weight); } else if (jetFlavor == JetTaggingSpecies::charm) { registry.fill(HIST("h_jetpT_c"), analysisJet.pt(), weight); registry.fill(HIST("h_Db_c"), analysisJet.scoreML(), weight); registry.fill(HIST("h2_jetpT_Db_c"), analysisJet.pt(), analysisJet.scoreML(), weight); - registry.fill(HIST("h2_jetpT_SVMass_c"), analysisJet.pt(), mSV, weight); - registry.fill(HIST("h2_jetpT_jetMass_c"), analysisJet.pt(), analysisJet.mass(), weight); - registry.fill(HIST("h2_jetpT_jetProb_c"), analysisJet.pt(), analysisJet.jetProb(), weight); - registry.fill(HIST("h2_jetpT_nTracks_c"), analysisJet.pt(), nTracks, weight); } else { registry.fill(HIST("h_jetpT_lf"), analysisJet.pt(), weight); registry.fill(HIST("h_Db_lf"), analysisJet.scoreML(), weight); registry.fill(HIST("h2_jetpT_Db_lf"), analysisJet.pt(), analysisJet.scoreML(), weight); - registry.fill(HIST("h2_jetpT_SVMass_lf"), analysisJet.pt(), mSV, weight); - registry.fill(HIST("h2_jetpT_jetMass_lf"), analysisJet.pt(), analysisJet.mass(), weight); - registry.fill(HIST("h2_jetpT_jetProb_lf"), analysisJet.pt(), analysisJet.jetProb(), weight); - registry.fill(HIST("h2_jetpT_nTracks_lf"), analysisJet.pt(), nTracks, weight); if (jetFlavor == JetTaggingSpecies::none) { registry.fill(HIST("h2_jetpT_Db_lf_none"), analysisJet.pt(), analysisJet.scoreML(), weight); } else { diff --git a/PWGJE/Tasks/bjetTreeCreator.cxx b/PWGJE/Tasks/bjetTreeCreator.cxx index 103de117469..a3ea1f8611f 100644 --- a/PWGJE/Tasks/bjetTreeCreator.cxx +++ b/PWGJE/Tasks/bjetTreeCreator.cxx @@ -241,6 +241,8 @@ struct BJetTreeCreator { Configurable vtxRes{"vtxRes", 0.01, "Vertex position resolution (cluster size) for GNN vertex predictions (cm)"}; + Configurable trainingDatasetRatioParam{"trainingDatasetRatioParam", 0, "Parameter for splitting training/evaluation datasets by collisionId"}; + std::vector eventSelectionBits; std::vector jetRadiiValues; @@ -488,7 +490,7 @@ struct BJetTreeCreator { trkIdx++; - if (constituent.pt() < trackPtMin) { + if (constituent.pt() < trackPtMin || !jettaggingutilities::trackAcceptanceWithDca(constituent, maxIPxy, maxIPz)) { continue; } @@ -707,7 +709,7 @@ struct BJetTreeCreator { } PROCESS_SWITCH(BJetTreeCreator, processMCJets, "jet information in MC", false); - using MCDJetTableNoSV = soa::Filtered>; + using MCDJetTableNoSV = soa::Filtered>; using JetParticleswID = soa::Join; void processMCJetsForGNN(FilteredCollisionMCD::iterator const& collision, aod::JMcCollisions const&, MCDJetTableNoSV const& MCDjets, MCPJetTable const& MCPjets, JetTracksMCDwID const& allTracks, JetParticleswID const& MCParticles, OriginalTracks const& origTracks, aod::McParticles const& origParticles) @@ -716,7 +718,12 @@ struct BJetTreeCreator { return; } - registry.fill(HIST("h_vertexZ"), collision.posZ()); + // Uses only collisionId % trainingDatasetRaioParam == 0 for training dataset + if (trainingDatasetRatioParam && collision.collisionId() % trainingDatasetRatioParam != 0) { + return; + } + + registry.fill(HIST("h_vertexZ"), collision.posZ(), collision.weight()); auto const mcParticlesPerColl = MCParticles.sliceBy(mcParticlesPerCollision, collision.mcCollisionId()); auto const mcPJetsPerColl = MCPjets.sliceBy(mcpJetsPerCollision, collision.mcCollisionId()); @@ -738,15 +745,7 @@ struct BJetTreeCreator { std::vector indicesTracks; std::vector indicesSVs; - int16_t jetFlavor = 0; - - for (const auto& mcpjet : analysisJet.template matchedJetGeo_as()) { - if (useQuarkDef) { - jetFlavor = jettaggingutilities::getJetFlavor(mcpjet, mcParticlesPerColl); - } else { - jetFlavor = jettaggingutilities::getJetFlavorHadron(mcpjet, mcParticlesPerColl); - } - } + int16_t jetFlavor = analysisJet.origin(); if ((jetFlavor != JetTaggingSpecies::charm && jetFlavor != JetTaggingSpecies::beauty) && (static_cast(std::rand()) / RAND_MAX < getReductionFactor(analysisJet.pt()))) { continue; @@ -760,7 +759,7 @@ struct BJetTreeCreator { analyzeJetTrackInfoForGNN(collision, analysisJet, allTracks, origTracks, indicesTracks, jetFlavor, eventWeight, &trkLabels); registry.fill(HIST("h2_jetMass_jetpT"), analysisJet.pt(), analysisJet.mass(), eventWeight); - registry.fill(HIST("h2_nTracks_jetpT"), analysisJet.pt(), indicesTracks.size()); + registry.fill(HIST("h2_nTracks_jetpT"), analysisJet.pt(), indicesTracks.size(), eventWeight); //+jet registry.fill(HIST("h_jet_pt"), analysisJet.pt()); diff --git a/PWGJE/Tasks/fullJetSpectra.cxx b/PWGJE/Tasks/fullJetSpectra.cxx index bd2deac8148..cdb14a1aa1c 100644 --- a/PWGJE/Tasks/fullJetSpectra.cxx +++ b/PWGJE/Tasks/fullJetSpectra.cxx @@ -22,7 +22,10 @@ #include "PWGJE/DataModel/JetReducedData.h" #include "Common/CCDB/TriggerAliases.h" +#include "EventFiltering/Zorro.h" +#include "EventFiltering/ZorroSummary.h" +#include "CCDB/BasicCCDBManager.h" #include "Framework/ASoA.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" @@ -64,8 +67,10 @@ struct FullJetSpectra { Configurable centralityMax{"centralityMax", 999.0, "maximum centrality"}; Configurable doEMCALEventWorkaround{"doEMCALEventWorkaround", false, "apply the workaround to read the EMC trigger bit by requiring a cell content in the EMCAL"}; Configurable doMBGapTrigger{"doMBGapTrigger", true, "set to true only when using MB-Gap Trigger JJ MC to reject MB events at the collision and track level"}; - // Configurable doMBMC{"doMBMC", false, "set to true only when using MB MC"}; - Configurable checkMcCollisionIsMatched{"checkMcCollisionIsMatched", false, "0: count whole MCcollisions, 1: select MCcollisions which only have their correspond collisions"}; + + // Software Trigger configurables + Configurable doSoftwareTriggerSelection{"doSoftwareTriggerSelection", false, "set to true when using triggered datasets"}; + Configurable triggerMasks{"triggerMasks", "fJetFullHighPt", "possible JE Trigger masks: fJetChLowPt,fJetChHighPt,fEMCALReadout,fJetFullHighPt,fJetFullLowPt"}; // Jet configurables Configurable selectedJetsRadius{"selectedJetsRadius", 0.4, "resolution parameter for histograms without radius"}; @@ -77,7 +82,12 @@ struct FullJetSpectra { Configurable jetPhiMin{"jetPhiMin", 1.80, "minimum jet phi"}; // phi_jet_min for R = 0.4 is 1.80 Configurable jetPhiMax{"jetPhiMax", 2.86, "maximum jet phi"}; // phi_jet_min for R = 0.4 is 2.86 Configurable jetAreaFractionMin{"jetAreaFractionMin", -99.0, "used to make a cut on the jet areas"}; - Configurable leadingConstituentPtMin{"leadingConstituentPtMin", -99.0, "minimum pT selection on jet constituent"}; + + // Leading track and cluster pT configurables + Configurable leadingTrackPtMin{"leadingTrackPtMin", -99.0, "minimum pT selection on jet tracks"}; + Configurable leadingTrackPtMax{"leadingTrackPtMax", 999.0, "maximum pT selection on jet tracks"}; + Configurable leadingClusterPtMin{"leadingClusterPtMin", -99.0, "minimum pT selection on jet clusters"}; + Configurable leadingClusterPtMax{"leadingClusterPtMax", 999.0, "maximum pT selection on jet clusters"}; // Track configurables Configurable trackpTMin{"trackpTMin", 0.15, "minimum track pT"}; @@ -108,14 +118,41 @@ struct FullJetSpectra { int trackSelection = -1; const float kJetAreaFractionMinThreshold = -98.0f; - const float kLeadingConstituentPtMinThreshold = -98.0f; + const float kLeadingTrackPtMinThreshold = -98.0f; + const float kLeadingTrackPtMaxThreshold = 9998.0f; + const float kLeadingClusterPtMinThreshold = -98.0f; + const float kLeadingClusterPtMaxThreshold = 9998.0f; + std::vector eventSelectionBits; std::vector filledJetR; std::vector jetRadiiValues; - + std::vector triggerMaskBits; std::string particleSelection; Service pdgDatabase; + Service ccdb; + + // Instantiate the Zorro processor for skimmed data and define an output object + Zorro zorro; + OutputObj zorroSummary{"zorroSummary"}; + + // Multiplicity Utilities + // struct CentClass { + // const char* name; + // float min; + // float max; + // }; + // // Define multiplicity classes here (example: MB(0-100), HM(0-1), 1-10, 10-20, 20-40, 40-60, 60-100) + // static constexpr int nCentClasses = 4; + // CentClass centClasses[nCentClasses] = { + // {"MB", 0.0, 100.0}, + // {"HM", 0.0, 1.0}, + // {"1_10", 1.0, 10.0}, + // {"10_20", 10.0, 20.0}, + // {"20_40", 20.0, 40.0}, + // {"40_60", 40.0, 60.0}, + // {"60_100", 60.0, 100.0} + // }; // Random splitter instance /* TRandom3 randGen; @@ -174,6 +211,24 @@ struct FullJetSpectra { hDetcollisionCounter->GetXaxis()->SetBinLabel(8, "EMCAcceptedDetColl"); } + if (doprocessJetsTriggeredData) { + auto hDetTrigcollisionCounter = registry.get(HIST("hDetTrigcollisionCounter")); + hDetTrigcollisionCounter->GetXaxis()->SetBinLabel(1, "allDetTrigColl"); + hDetTrigcollisionCounter->GetXaxis()->SetBinLabel(2, "DetTrigCollAfterZorroSelection"); + hDetTrigcollisionCounter->GetXaxis()->SetBinLabel(3, "DetTrigCollWithVertexZ"); + hDetTrigcollisionCounter->GetXaxis()->SetBinLabel(4, "EventsNotSatisfyingEventSelection"); + hDetTrigcollisionCounter->GetXaxis()->SetBinLabel(5, "EMCreadoutDetTrigEventsWithkTVXinEMC"); + hDetTrigcollisionCounter->GetXaxis()->SetBinLabel(6, "OnlyHighPt+NoLowPt+NoMB"); + hDetTrigcollisionCounter->GetXaxis()->SetBinLabel(7, "OnlyLowPt+NoMB"); + hDetTrigcollisionCounter->GetXaxis()->SetBinLabel(8, "OnlyMB"); + hDetTrigcollisionCounter->GetXaxis()->SetBinLabel(9, "FullJetHighPt+FullJetLowPt"); + // hDetTrigcollisionCounter->GetXaxis()->SetBinLabel(9, "EMCAcceptedDetTrigCollWithLow+HighFullJetTriggers"); + hDetTrigcollisionCounter->GetXaxis()->SetBinLabel(10, "FullJetHighPt+MB"); + hDetTrigcollisionCounter->GetXaxis()->SetBinLabel(11, "FullJetLowPt+MB"); + hDetTrigcollisionCounter->GetXaxis()->SetBinLabel(12, "AllRejectedTrigOverlaps"); + hDetTrigcollisionCounter->GetXaxis()->SetBinLabel(13, "EMCAcceptedDetTrigColl"); + } + if (doprocessJetsMCP || doprocessJetsMCPWeighted) { auto hPartcollisionCounter = registry.get(HIST("hPartcollisionCounter")); hPartcollisionCounter->GetXaxis()->SetBinLabel(1, "allMcColl"); @@ -200,15 +255,52 @@ struct FullJetSpectra { hMatchedcollisionCounter->GetXaxis()->SetBinLabel(9, "EMCAcceptedDetColl"); } - if (doprocessMBCollisionsDATAWithMultiplicity || doprocessMBCollisionsWithMultiplicity || doprocessCollisionsWeightedWithMultiplicity) { + if (doprocessMBCollisionsDATAWithMultiplicity || doprocessMBMCDCollisionsWithMultiplicity) { auto hEventmultiplicityCounter = registry.get(HIST("hEventmultiplicityCounter")); hEventmultiplicityCounter->GetXaxis()->SetBinLabel(1, "allDetColl"); hEventmultiplicityCounter->GetXaxis()->SetBinLabel(2, "DetCollWithVertexZ"); + hEventmultiplicityCounter->GetXaxis()->SetBinLabel(3, "EventsNotSatisfyingEventSelection"); + hEventmultiplicityCounter->GetXaxis()->SetBinLabel(4, "EMCreadoutDetEventsWithkTVXinEMC"); + hEventmultiplicityCounter->GetXaxis()->SetBinLabel(5, "AllRejectedEventsAfterEMCEventSelection"); + hEventmultiplicityCounter->GetXaxis()->SetBinLabel(6, "EMCAcceptedDetColl"); + } + + if (doprocessMCDCollisionsWeightedWithMultiplicity) { + auto hEventmultiplicityCounter = registry.get(HIST("hEventmultiplicityCounter")); + hEventmultiplicityCounter->GetXaxis()->SetBinLabel(1, "allWeightedDetColl"); + hEventmultiplicityCounter->GetXaxis()->SetBinLabel(2, "WeightedDetCollWithVertexZ"); hEventmultiplicityCounter->GetXaxis()->SetBinLabel(3, "MBRejectedDetEvents"); - hEventmultiplicityCounter->GetXaxis()->SetBinLabel(4, "EventsNotSatisfyingEventSelection"); - hEventmultiplicityCounter->GetXaxis()->SetBinLabel(5, "EMCreadoutDetEventsWithkTVXinEMC"); - hEventmultiplicityCounter->GetXaxis()->SetBinLabel(6, "AllRejectedEventsAfterEMCEventSelection"); - hEventmultiplicityCounter->GetXaxis()->SetBinLabel(7, "EMCAcceptedDetColl"); + hEventmultiplicityCounter->GetXaxis()->SetBinLabel(4, "WeightedEventsNotSatisfyingEventSelection"); + hEventmultiplicityCounter->GetXaxis()->SetBinLabel(5, "EMCreadoutWeightedDetEventsWithkTVXinEMC"); + hEventmultiplicityCounter->GetXaxis()->SetBinLabel(6, "AllRejectedWeightedEventsAfterEMCEventSelection"); + hEventmultiplicityCounter->GetXaxis()->SetBinLabel(7, "EMCAcceptedWeightedDetColl"); + hEventmultiplicityCounter->GetXaxis()->SetBinLabel(8, "EMCAcceptedWeightedCollAfterTrackSel"); + } + + if (doprocessMBMCPCollisionsWithMultiplicity) { + auto hPartEventmultiplicityCounter = registry.get(HIST("hPartEventmultiplicityCounter")); + hPartEventmultiplicityCounter->GetXaxis()->SetBinLabel(1, "allMcColl"); + hPartEventmultiplicityCounter->GetXaxis()->SetBinLabel(2, "McCollWithVertexZ"); + hPartEventmultiplicityCounter->GetXaxis()->SetBinLabel(3, "RejectedPartCollWithOutliers"); + hPartEventmultiplicityCounter->GetXaxis()->SetBinLabel(4, "MBRejectedPartEvents"); + hPartEventmultiplicityCounter->GetXaxis()->SetBinLabel(5, "RejectedPartCollForDetCollWithSize0or<1"); + hPartEventmultiplicityCounter->GetXaxis()->SetBinLabel(6, "AcceptedPartCollWithSize>=1"); + hPartEventmultiplicityCounter->GetXaxis()->SetBinLabel(7, "EMCreadoutDetEventsWithkTVXinEMC"); + hPartEventmultiplicityCounter->GetXaxis()->SetBinLabel(8, "AllRejectedPartEventsAfterEMCEventSelection"); + hPartEventmultiplicityCounter->GetXaxis()->SetBinLabel(9, "EMCAcceptedPartColl"); + } + + if (doprocessMBMCPCollisionsWeightedWithMultiplicity) { + auto hPartEventmultiplicityCounter = registry.get(HIST("hPartEventmultiplicityCounter")); + hPartEventmultiplicityCounter->GetXaxis()->SetBinLabel(1, "allWeightedMcColl"); + hPartEventmultiplicityCounter->GetXaxis()->SetBinLabel(2, "WeightedMcCollWithVertexZ"); + hPartEventmultiplicityCounter->GetXaxis()->SetBinLabel(3, "RejectedWeightedPartCollWithOutliers"); + hPartEventmultiplicityCounter->GetXaxis()->SetBinLabel(4, "MBRejectedPartEvents"); + hPartEventmultiplicityCounter->GetXaxis()->SetBinLabel(5, "RejectedWeightedPartCollForDetCollWithSize0or<1"); + hPartEventmultiplicityCounter->GetXaxis()->SetBinLabel(6, "AcceptedWeightedPartCollWithSize>=1"); + hPartEventmultiplicityCounter->GetXaxis()->SetBinLabel(7, "EMCreadoutDetEventsWithkTVXinEMC"); + hPartEventmultiplicityCounter->GetXaxis()->SetBinLabel(8, "AllRejectedWeightedPartEventsAfterEMCEventSelection"); + hPartEventmultiplicityCounter->GetXaxis()->SetBinLabel(9, "EMCAcceptedWeightedPartColl"); } } @@ -222,8 +314,10 @@ struct FullJetSpectra { */ void init(o2::framework::InitContext&) { + trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); eventSelectionBits = jetderiveddatautilities::initialiseEventSelectionBits(static_cast(eventSelections)); + triggerMaskBits = jetderiveddatautilities::initialiseTriggerMaskBits(triggerMasks); particleSelection = static_cast(particleSelections); jetRadiiValues = (std::vector)jetRadii; @@ -320,8 +414,12 @@ struct FullJetSpectra { registry.add("h2_track_etaphi", "jet_track #eta vs jet_track #varphi; #eta_{track};#varphi_{track}", {HistType::kTH2F, {{500, -5., 5.}, {160, -1., 7.}}}); registry.add("h2_jet_etaphi", "jet #eta vs jet #varphi; #eta_{jet};#varphi_{jet}", {HistType::kTH2F, {{100, -1., 1.}, {160, -1., 7.}}}); } + if (doprocessJetsTriggeredData) { + registry.add("hDetTrigcollisionCounter", "event status;;entries", {HistType::kTH1F, {{14, 0.0, 14.}}}); + } if (doprocessJetsMCP || doprocessJetsMCPWeighted) { registry.add("hPartcollisionCounter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.0}}}); + registry.add("hRecoMatchesPerMcCollision", "split vertices QA;;entries", {HistType::kTH1F, {{5, 0.0, 5.0}}}); registry.add("h_full_mcpjet_tablesize", "", {HistType::kTH1F, {{4, 0., 5.}}}); registry.add("h_full_mcpjet_ntracks", "", {HistType::kTH1F, {{200, -0.5, 200.}}}); @@ -389,23 +487,96 @@ struct FullJetSpectra { registry.add("h2_full_matchedmcpjet_pt", "Matched MCP jet in EMC Fiducial Acceptance #it{p}_{T,part};#it{p}_{T,part} (GeV/c); Ncounts", {HistType::kTH2F, {{350, 0., 350.}, {10000, 0., 10000.}}}); // Response Matrix - registry.add("h_full_jet_ResponseMatrix", "Full Jets Response Matrix; p_{T,det} (GeV/c); p_{T,part} (GeV/c)", {HistType::kTH2F, {{350, 0., 350.}, {350, 0., 350.}}}); + registry.add("h_full_jet_ResponseMatrix", "Full Jets Response Matrix; p_{T,det} (GeV/c); p_{T,part} (GeV/c)", {HistType::kTH2F, {{500, 0., 500.}, {500, 0., 500.}}}); } - if (doprocessCollisionsWeightedWithMultiplicity || doprocessMBCollisionsWithMultiplicity || doprocessMBCollisionsDATAWithMultiplicity) { + if (doprocessMBCollisionsDATAWithMultiplicity || doprocessMBMCDCollisionsWithMultiplicity || doprocessMCDCollisionsWeightedWithMultiplicity) { registry.add("hEventmultiplicityCounter", "event status;event status;entries", {HistType::kTH1F, {{10, 0.0, 10.0}}}); registry.add("h_FT0Mults_occupancy", "", {HistType::kTH1F, {{3500, 0., 3500.}}}); - registry.add("h2_full_jet_FT0Amplitude", "; FT0C Amplitude; Counts", {HistType::kTH1F, {{3500, 0., 3500.}}}); - registry.add("h2_full_jet_jetpTDetVsFT0Mults", "; p_{T,det} (GeV/c); FT0C Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}); - registry.add("h3_full_jet_jetpTDet_FT0Mults_nef", "; p_{T,det} (GeV/c); FT0C Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {3500, 0., 3500.}, {105, 0.0, 1.05}}}); + + registry.add("h_all_fulljet_Njets", "Full Jet Multiplicity (per Event)", {HistType::kTH1F, {{20, 0., 20.}}}); + registry.add("h_Leading_full_jet_pt", "#it{p}_{T,leading jet};#it{p}_{T_leading jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); + registry.add("h2_full_jet_leadingJetPt_vs_counts", ";#it{p}_{T_leading jet} (GeV/#it{c}); Counts", {HistType::kTH2F, {{350, 0., 350.}, {20, 0., 20.}}}); + registry.add("h_SubLeading_full_jet_pt", "#it{p}_{T,leading jet};#it{p}_{T_leading jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); + registry.add("h2_full_jet_subLeadingJetPt_vs_counts", ";#it{p}_{T_leading jet} (GeV/#it{c}); Counts", {HistType::kTH2F, {{350, 0., 350.}, {20, 0., 20.}}}); + // Inside Jet Loop: + // CASE 1: + registry.add("h_all_fulljet_pt", "#it{p}_{T,fulljet};#it{p}_{T_fulljet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); + registry.add("h_all_fulljet_Nch", ";N_{ch};", {HistType::kTH1F, {{50, 0., 50.}}}); + registry.add("h_all_fulljet_NEF", ";NEF;", {HistType::kTH1F, {{105, 0., 1.05}}}); + registry.add("h2_all_fulljet_jetpTDet_vs_FT0Mults", "; p_{T,det} (GeV/c); FT0M Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}); + registry.add("h2_all_fulljet_jetpTDet_vs_Nch", ";#it{p}_{T_fulljet} (GeV/#it{c}); N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {50, 0., 50.}}}); + registry.add("h3_full_jet_jetpTDet_FT0Mults_nef", "; p_{T,det} (GeV/c); FT0M Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {50, 0., 50.}, {105, 0.0, 1.05}}}); + // CASE 2: + registry.add("h_leading_fulljet_pt", "#it{p}_{T,Leading fulljet};#it{p}_{T_Leadingfulljet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); + registry.add("h_leading_fulljet_Nch", ";N_{ch};", {HistType::kTH1F, {{50, 0., 50.}}}); + registry.add("h_leading_fulljet_NEF", ";NEF;", {HistType::kTH1F, {{105, 0., 1.05}}}); + registry.add("h2_leading_fulljet_jetpTDet_vs_FT0Mults", ";Leading p_{T,det} (GeV/c); FT0M Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}); + registry.add("h2_leading_fulljet_jetpTDet_vs_Nch", ";#it{p}_{T_Leadingfulljet} (GeV/#it{c}); N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {50, 0., 50.}}}); + registry.add("h3_leading_fulljet_jetpTDet_FT0Mults_nef", "; Leading p_{T,det} (GeV/c); FT0M Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {50, 0., 50.}, {105, 0.0, 1.05}}}); + // CASE 3: + registry.add("h_subleading_fulljet_pt", "#it{p}_{T,SubLeading fulljet};#it{p}_{T_SubLeadingfulljet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); + registry.add("h_subleading_fulljet_Nch", ";N_{ch};", {HistType::kTH1F, {{50, 0., 50.}}}); + registry.add("h_subleading_fulljet_NEF", ";NEF;", {HistType::kTH1F, {{105, 0., 1.05}}}); + registry.add("h2_subleading_fulljet_jetpTDet_vs_FT0Mults", ";SubLeading p_{T,det} (GeV/c); FT0M Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}); + registry.add("h2_subleading_fulljet_jetpTDet_vs_Nch", ";#it{p}_{T_SubLeadingfulljet} (GeV/#it{c}); N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {50, 0., 50.}}}); + registry.add("h3_subleading_fulljet_jetpTDet_FT0Mults_nef", "; SubLeading p_{T,det} (GeV/c); FT0M Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {50, 0., 50.}, {105, 0.0, 1.05}}}); + } + + if (doprocessMBMCPCollisionsWithMultiplicity || doprocessMBMCPCollisionsWeightedWithMultiplicity) { + registry.add("hPartEventmultiplicityCounter", "event status;event status;entries", {HistType::kTH1F, {{11, 0.0, 11.0}}}); + registry.add("hRecoMatchesPerMcCollisionMult", "split vertices QA;;entries", {HistType::kTH1F, {{5, 0.0, 5.0}}}); + registry.add("hMCCollMatchedFT0Mult", "", {HistType::kTH1F, {{3500, 0., 3500.}}}); + registry.add("hMCCollMatchedFT0Cent", "", {HistType::kTH1F, {{105, 0., 105.}}}); + + registry.add("h_all_fulljet_Njets_part", "Full Jet Multiplicity (per Event)", {HistType::kTH1F, {{20, 0., 20.}}}); + registry.add("h_Leading_full_jet_pt_part", "#it{p}_{T,leading jet};#it{p}_{T_leading jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); + registry.add("h2_full_jet_leadingJetPt_vs_counts_part", ";#it{p}_{T_leading jet} (GeV/#it{c}); Counts", {HistType::kTH2F, {{350, 0., 350.}, {20, 0., 20.}}}); + registry.add("h_SubLeading_full_jet_pt_part", "#it{p}_{T,leading jet};#it{p}_{T_leading jet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); + registry.add("h2_full_jet_subLeadingJetPt_vs_counts_part", ";#it{p}_{T_leading jet} (GeV/#it{c}); Counts", {HistType::kTH2F, {{350, 0., 350.}, {20, 0., 20.}}}); + + // Inside Jet Loop: + // CASE 1: + registry.add("h_all_fulljet_pt_part", "#it{p}_{T,fulljet};#it{p}_{T_fulljet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); + registry.add("h_all_fulljet_Nch_part", ";N_{ch};", {HistType::kTH1F, {{50, 0., 50.}}}); + registry.add("h_all_fulljet_Nne_part", ";N_{ne};", {HistType::kTH1F, {{100, 0., 100.}}}); + registry.add("h_all_fulljet_NEF_part", ";NEF;", {HistType::kTH1F, {{105, 0., 1.05}}}); + registry.add("h2_all_fulljet_jetpT_vs_FT0Mults_part", "; p_{T,part} (GeV/c); FT0M Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}); + registry.add("h2_all_fulljet_jetpT_vs_Nch_part", ";#it{p}_{T_fulljet} (GeV/#it{c}); N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {50, 0., 50.}}}); + registry.add("h3_full_jet_jetpT_FT0Mults_nef_part", "; p_{T,part} (GeV/c); FT0M Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {50, 0., 50.}, {105, 0.0, 1.05}}}); + // CASE 2: + registry.add("h_leading_fulljet_pt_part", "#it{p}_{T,Leading fulljet};#it{p}_{T_Leadingfulljet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); + registry.add("h_leading_fulljet_Nch_part", ";N_{ch};", {HistType::kTH1F, {{50, 0., 50.}}}); + registry.add("h_leading_fulljet_Nne_part", ";N_{ne};", {HistType::kTH1F, {{100, 0., 100.}}}); + registry.add("h_leading_fulljet_NEF_part", ";NEF;", {HistType::kTH1F, {{105, 0., 1.05}}}); + registry.add("h2_leading_fulljet_jetpT_vs_FT0Mults_part", ";Leading p_{T,part} (GeV/c); FT0M Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}); + registry.add("h2_leading_fulljet_jetpT_vs_Nch_part", ";#it{p}_{T_Leadingfulljet} (GeV/#it{c}); N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {50, 0., 50.}}}); + registry.add("h3_leading_fulljet_jetpT_FT0Mults_nef_part", "; Leading p_{T,part} (GeV/c); FT0M Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {50, 0., 50.}, {105, 0.0, 1.05}}}); + // CASE 3: + registry.add("h_subleading_fulljet_pt_part", "#it{p}_{T,SubLeading fulljet};#it{p}_{T_SubLeadingfulljet} (GeV/#it{c});entries", {HistType::kTH1F, {{350, 0., 350.}}}); + registry.add("h_subleading_fulljet_Nch_part", ";N_{ch};", {HistType::kTH1F, {{50, 0., 50.}}}); + registry.add("h_subleading_fulljet_Nne_part", ";N_{ne};", {HistType::kTH1F, {{100, 0., 100.}}}); + registry.add("h_subleading_fulljet_NEF_part", ";NEF;", {HistType::kTH1F, {{105, 0., 1.05}}}); + registry.add("h2_subleading_fulljet_jetpT_vs_FT0Mults_part", ";SubLeading p_{T,part} (GeV/c); FT0M Multiplicity", {HistType::kTH2F, {{350, 0., 350.}, {3500, 0., 3500.}}}); + registry.add("h2_subleading_fulljet_jetpT_vs_Nch_part", ";#it{p}_{T_SubLeadingfulljet} (GeV/#it{c}); N_{ch}", {HistType::kTH2F, {{350, 0., 350.}, {50, 0., 50.}}}); + registry.add("h3_subleading_fulljet_jetpT_FT0Mults_nef_part", "; SubLeading p_{T,part} (GeV/c); FT0M Multiplicity, nef", {HistType::kTH3F, {{350, 0., 350.}, {50, 0., 50.}, {105, 0.0, 1.05}}}); } // Label the histograms labelCollisionHistograms(registry); // labelMCSplitHistogram(registry); - } // init + // Initialize CCDB access and histogram registry for Zorro processing + template + void initCCDB(const BCType& bc) + { + if (doSoftwareTriggerSelection) { + zorro.initCCDB(ccdb.service, bc.runNumber(), bc.timestamp(), triggerMasks.value); + zorro.populateHistRegistry(registry, bc.runNumber()); + } + } + // Get or generate random value for a specific MC collision /* float getMCCollisionRandomValue(int64_t mcCollisionId) { if (!doMcClosure) return 0.0f; @@ -428,7 +599,9 @@ struct FullJetSpectra { return randomVal; } */ - using EMCCollisionsData = o2::soa::Join; // JetCollisions with EMCAL Collision Labels + using EMCCollisionsData = o2::soa::Join; // JetCollisions with EMCAL Collision Labels + using EMCCollisionsTriggeredData = o2::soa::Join; + using EMCCollisionsMCD = o2::soa::Join; // where, JetCollisionsMCD = JetCollisions+JMcCollisionLbs using FullJetTableDataJoined = soa::Join; @@ -446,37 +619,88 @@ struct FullJetSpectra { // Applying some cuts(filters) on collisions, tracks, clusters Filter eventCuts = (nabs(aod::jcollision::posZ) < vertexZCut && aod::jcollision::centFT0M >= centralityMin && aod::jcollision::centFT0M < centralityMax); - // Filter EMCeventCuts = (nabs(aod::collision::posZ) < vertexZCut && aod::collision::v >= centralityMin && aod::collision::centFT0M < centralityMax); + // Filter EMCeventCuts = (nabs(aod::collision::posZ) < vertexZCut && aod::collision::centrality >= centralityMin && aod::collision::centrality < centralityMax); Filter trackCuts = (aod::jtrack::pt >= trackpTMin && aod::jtrack::pt < trackpTMax && aod::jtrack::eta > trackEtaMin && aod::jtrack::eta < trackEtaMax && aod::jtrack::phi >= trackPhiMin && aod::jtrack::phi <= trackPhiMax); aod::EMCALClusterDefinition clusterDefinition = aod::emcalcluster::getClusterDefinitionFromString(clusterDefinitionS.value); Filter clusterFilter = (aod::jcluster::definition == static_cast(clusterDefinition) && aod::jcluster::eta > clusterEtaMin && aod::jcluster::eta < clusterEtaMax && aod::jcluster::phi >= clusterPhiMin && aod::jcluster::phi <= clusterPhiMax && aod::jcluster::energy >= clusterEnergyMin && aod::jcluster::time > clusterTimeMin && aod::jcluster::time < clusterTimeMax && (clusterRejectExotics && aod::jcluster::isExotic != true)); Preslice JetMCPPerMcCollision = aod::jet::mcCollisionId; PresliceUnsorted> CollisionsPerMCPCollision = aod::jmccollisionlb::mcCollisionId; - template - bool isAcceptedJet(U const& jet) + template + bool isAcceptedRecoJet(U const& jet) { + // if (jetAreaFractionMin > kJetAreaFractionMinThreshold) { + // if (jet.area() < jetAreaFractionMin * o2::constants::math::PI * (jet.r() / 100.0) * (jet.r() / 100.0)) { + // return false; + // } + // } - if (jetAreaFractionMin > kJetAreaFractionMinThreshold) { - if (jet.area() < jetAreaFractionMin * o2::constants::math::PI * (jet.r() / 100.0) * (jet.r() / 100.0)) { + // --- Track cuts: ALL tracks must satisfy 0.15 <= pT <= 200 or 150 GeV/c--- + if (leadingTrackPtMin > kLeadingTrackPtMinThreshold || leadingTrackPtMax < kLeadingTrackPtMaxThreshold) { + bool hasValidTrack = false; + for (const auto& constituent : jet.template tracks_as()) { + const float pt = constituent.pt(); + // Reject if ANY track fails min or max cut + if ((leadingTrackPtMin > kLeadingTrackPtMinThreshold && pt < leadingTrackPtMin) || + (leadingTrackPtMax < kLeadingTrackPtMaxThreshold && pt > leadingTrackPtMax)) { + return false; + } + hasValidTrack = true; // At least one track exists (if needed) + } + // Reject if no tracks exist (edge case) + if (leadingTrackPtMin > kLeadingTrackPtMinThreshold && !hasValidTrack) { return false; } } - if (leadingConstituentPtMin > kLeadingConstituentPtMinThreshold) { - bool isMinleadingConstituent = false; - for (const auto& constituent : jet.template tracks_as()) { - if (constituent.pt() >= leadingConstituentPtMin) { - isMinleadingConstituent = true; - break; + + // --- Cluster cuts: ALL clusters must satisfy min <= pT <= max == 0.3 <= pT <= 250 + if (leadingClusterPtMin > kLeadingClusterPtMinThreshold || leadingClusterPtMax < kLeadingClusterPtMaxThreshold) { + bool hasValidCluster = false; + for (const auto& cluster : jet.template clusters_as()) { + const double pt = cluster.energy() / std::cosh(cluster.eta()); + // Reject if ANY cluster fails min or max cut + if ((leadingClusterPtMin > kLeadingClusterPtMinThreshold && pt < leadingClusterPtMin) || + (leadingClusterPtMax < kLeadingClusterPtMaxThreshold && pt > leadingClusterPtMax)) { + return false; } + hasValidCluster = true; // At least one cluster exists + } + // Reject if no clusters exist (edge case) + if (leadingClusterPtMin > kLeadingClusterPtMinThreshold && !hasValidCluster) { + return false; } + } + return true; + } // isAcceptedRecoJet ends - if (!isMinleadingConstituent) { + template + bool isAcceptedPartJet(U const& jet) + { + // if (jetAreaFractionMin > kJetAreaFractionMinThreshold) { + // if (jet.area() < jetAreaFractionMin * o2::constants::math::PI * (jet.r() / 100.0) * (jet.r() / 100.0)) { + // return false; + // } + // } + // track pt Min cut at the Part level: 0 < pT <= 200 or 150 GeV/c + if (leadingTrackPtMin > kLeadingTrackPtMinThreshold || leadingTrackPtMax < kLeadingTrackPtMaxThreshold) { + bool hasValidParticle = false; + for (const auto& constituent : jet.template tracks_as()) { + const float pt = constituent.pt(); + // Reject if ANY particle fails min or max cut + if ((leadingTrackPtMin > kLeadingTrackPtMinThreshold && pt < leadingTrackPtMin) || + (leadingTrackPtMax < kLeadingTrackPtMaxThreshold && pt > leadingTrackPtMax)) { + return false; + } + hasValidParticle = true; // At least one track exists (if needed) + } + // Reject if no particle exist (edge case) + if (leadingTrackPtMin > kLeadingTrackPtMinThreshold && !hasValidParticle) { return false; } } return true; } + template void fillJetHistograms(T const& jet, float weight = 1.0) { @@ -676,38 +900,34 @@ struct FullJetSpectra { } registry.fill(HIST("hDetcollisionCounter"), 1.5); // DetCollWithVertexZ - if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { - registry.fill(HIST("hDetcollisionCounter"), 2.5); // MBRejectedDetEvents - return; - } if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { - registry.fill(HIST("hDetcollisionCounter"), 3.5); // EventsNotSatisfyingEventSelection + registry.fill(HIST("hDetcollisionCounter"), 4.5); // EventsNotSatisfyingEventSelection return; } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { - registry.fill(HIST("hDetcollisionCounter"), 4.5); // EMCreadoutDetEventsWithkTVXinEMC + registry.fill(HIST("hDetcollisionCounter"), 5.5); // EMCreadoutDetEventsWithkTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { - registry.fill(HIST("hDetcollisionCounter"), 4.5); // EMCreadoutDetEventsWithkTVXinEMC + registry.fill(HIST("hDetcollisionCounter"), 5.5); // EMCreadoutDetEventsWithkTVXinEMC eventAccepted = true; } } if (!eventAccepted) { for (auto const& jet : jets) { - if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax) || !isAcceptedJet(jet)) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax) || !isAcceptedRecoJet(jet)) { fillRejectedJetHistograms(jet, 1.0); } } - registry.fill(HIST("hDetcollisionCounter"), 5.5); // AllRejectedDetEventsAfterEMCEventSelection + registry.fill(HIST("hDetcollisionCounter"), 6.5); // AllRejectedDetEventsAfterEMCEventSelection return; } - registry.fill(HIST("hDetcollisionCounter"), 6.5); // EMCAcceptedDetColl + registry.fill(HIST("hDetcollisionCounter"), 7.5); // EMCAcceptedDetColl for (auto const& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { @@ -716,7 +936,7 @@ struct FullJetSpectra { if (jet.phi() < jetPhiMin || jet.phi() > jetPhiMax) { continue; } - if (!isAcceptedJet(jet)) { + if (!isAcceptedRecoJet(jet)) { continue; } fillJetHistograms(jet); @@ -724,6 +944,126 @@ struct FullJetSpectra { } PROCESS_SWITCH(FullJetSpectra, processJetsData, "Full Jets Data", false); + void processJetsTriggeredData(soa::Filtered::iterator const& collision, FullJetTableDataJoined const& /*jets*/, + aod::JetTracks const&, aod::JetClusters const&, aod::JBCs const&) + { + // bool eventAccepted = false; + + registry.fill(HIST("hDetTrigcollisionCounter"), 0.5); // allDetTrigColl + + // Get BC info associated with the collision before applying any event selections + auto bc = collision.bc_as(); + // Initialize CCDB objects using the BC info + initCCDB(bc); + // If SoftwareTriggerSelection (i.e. skimming) is enabled, skip this event unless it passes Zorro selection + if (doSoftwareTriggerSelection && !zorro.isSelected(bc.globalBC())) { + return; + } + registry.fill(HIST("hDetTrigcollisionCounter"), 1.5); // DetTrigCollAfterZorroSelection + + if (std::fabs(collision.posZ()) > vertexZCut) { + return; + } + registry.fill(HIST("hDetTrigcollisionCounter"), 2.5); // DetTrigCollWithVertexZ + + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits) || !jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { + registry.fill(HIST("hDetTrigcollisionCounter"), 3.5); // EventsNotSatisfyingEvent+TriggerSelection + return; + } + //- should this kTVX HW trigger be still in place?? + if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { + // eventAccepted = true; + registry.fill(HIST("hDetTrigcollisionCounter"), 4.5); // EMCreadoutDetTrigEventsWithkTVXinEMC + } + // split event selections based on selected triggers - + // make sure there're no trigger overlaps: when analysing JetFullHighPt-> check no JetFullLowPt and kTVXinEMC are fired + // when analysing JetFullLowPt, check kTVXinEMC isn't fired! + // apply exclusive trigger bit selections for event selection + // use a flag and fill QA for trigger overlap - + // - how often you reject a higher pT trig because lower trigs were fired : 5 cases -> 2D hist as a funtn of jet pT + // - check how often the ChJet Trigs were fired for every fullJetTrig fired.(don't reject these events but only for QA) + + // Get trigger status + bool hasFullJetHighPt = jetderiveddatautilities::selectTrigger(collision, jetderiveddatautilities::JTrigSel::JetFullHighPt); + bool hasFullJetLowPt = jetderiveddatautilities::selectTrigger(collision, jetderiveddatautilities::JTrigSel::JetFullLowPt); + bool hasMB = jetderiveddatautilities::selectTrigger(collision, jetderiveddatautilities::JTrigSel::EMCALReadout); + + //*****Step 1: Check for pure triggers (NO overlaps)***** + + // Case 1: hasFullJetHighPt && !hasFullJetLowPt && !hasMB : Pure FullJetHighPt + // i.e. for every JetFullHighPt trig that was fired, check the low triggers weren't fired + if (hasFullJetHighPt && !hasFullJetLowPt && !hasMB) { + registry.fill(HIST("hDetTrigcollisionCounter"), 5.5); // OnlyHighPt+NoLowPt+NoMB + } + // Case 2: hasFullJetLowPt && !hasMB : Pure FullJetLowPt + // i.e. for every hasFullJetLowPt trig that was fired, check the MB trig wasn't fired + if (hasFullJetLowPt && !hasMB) { + registry.fill(HIST("hDetTrigcollisionCounter"), 6.5); // OnlyLowPt+NoMB + } + // Case 3: hasMB && !hasFullJetLowPt && !hasFullJetHighPt : Pure MB + // i.e. for every MB trig that was fired, check the higher trigs weren't fired + if (hasMB && !hasFullJetLowPt && !hasFullJetHighPt) { + registry.fill(HIST("hDetTrigcollisionCounter"), 7.5); // OnlyMB + } + + //*****Step 2: Check for trigger overlap cases (for QA):***** + + if (hasFullJetHighPt && hasFullJetLowPt) { + registry.fill(HIST("hDetTrigcollisionCounter"), 8.5); // FullJetHighPt+FullJetLowPt + } + if (hasFullJetHighPt && hasMB) { + registry.fill(HIST("hDetTrigcollisionCounter"), 9.5); // FullJetHighPt+MB + } + if (hasFullJetLowPt && hasMB) { + registry.fill(HIST("hDetTrigcollisionCounter"), 10.5); // FullJetLowPt+MB + } + + //*****Step 3: Reject ALL overlapping events by applying EXCLUSIVE Trigger Selections ***** + // Skip further processing if ANY overlaps exist + if ((hasFullJetHighPt && (hasFullJetLowPt || hasMB)) || (hasFullJetLowPt && hasMB)) { + registry.fill(HIST("hDetTrigcollisionCounter"), 11.5); // AllRejectedTrigOverlaps + return; + } + registry.fill(HIST("hDetTrigcollisionCounter"), 12.5); // EMCAcceptedDetTrigColl + // if (!eventAccepted) { + // // for (auto const& jet : jets) { + // // if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax) || !isAcceptedRecoJet(jet)) { + // // fillRejectedJetHistograms(jet, 1.0); + // // } + // // } + // registry.fill(HIST("hDetTrigcollisionCounter"), 4.5); // AllRejectedDetTrigEventsAfterEMCEventSelection + // return; + // } + // registry.fill(HIST("hDetTrigcollisionCounter"), 5.5); // EMCAcceptedDetTrigCollWithkTVXinEMC + // + + // if (jetderiveddatautilities::selectTrigger(collision, jetderiveddatautilities::JTrigSel::JetChLowPt)) { + // registry.fill(HIST("hDetTrigcollisionCounter"), 8.5); // EMCAcceptedDetTrigCollWithLowChargedJetTriggers + // eventAccepted = true; + // } + // if (jetderiveddatautilities::selectTrigger(collision, jetderiveddatautilities::JTrigSel::JetChHighPt)) { + // registry.fill(HIST("hDetTrigcollisionCounter"), 9.5); // EMCAcceptedDetTrigCollWithHighChargedJetTriggers + // eventAccepted = true; + // } + + // if (jetderiveddatautilities::selectTrigger(collision, jetderiveddatautilities::JTrigSel::JetFullLowPt) && jetderiveddatautilities::selectTrigger(collision, jetderiveddatautilities::JTrigSel::JetFullHighPt)) { + // registry.fill(HIST("hDetTrigcollisionCounter"), 8.5); // EMCAcceptedDetTrigCollWithLow+HighFullJetTriggers + // } + // for (auto const& jet : jets) { + // if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + // continue; + // } + // if (jet.phi() < jetPhiMin || jet.phi() > jetPhiMax) { + // continue; + // } + // if (!isAcceptedRecoJet(jet)) { + // continue; + // } + // fillJetHistograms(jet); + // } + } + PROCESS_SWITCH(FullJetSpectra, processJetsTriggeredData, "Full Jets Triggered Data", false); + void processJetsMCD(soa::Filtered::iterator const& collision, JetTableMCDJoined const& jets, aod::JetTracks const&, aod::JetClusters const&) { bool eventAccepted = false; @@ -782,8 +1122,8 @@ struct FullJetSpectra { } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content - eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; registry.fill(HIST("hDetcollisionCounter"), 5.5); // EMCreadoutDetEventsWithkTVXinEMC } } @@ -796,7 +1136,7 @@ struct FullJetSpectra { if (!eventAccepted) { for (auto const& jet : jets) { - if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax) || !isAcceptedJet(jet)) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax) || !isAcceptedRecoJet(jet)) { fillRejectedJetHistograms(jet, 1.0); } } @@ -812,7 +1152,7 @@ struct FullJetSpectra { if (jet.phi() < jetPhiMin || jet.phi() > jetPhiMax) { continue; } - if (!isAcceptedJet(jet)) { + if (!isAcceptedRecoJet(jet)) { continue; } fillJetHistograms(jet); @@ -876,8 +1216,8 @@ struct FullJetSpectra { } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content - eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; registry.fill(HIST("hDetcollisionCounter"), 5.5, collision.mcCollision().weight()); // EMCreadoutDetEventsWithkTVXinEMC } } @@ -890,7 +1230,7 @@ struct FullJetSpectra { if (!eventAccepted) { for (auto const& jet : jets) { - if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax) || !isAcceptedJet(jet)) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax) || !isAcceptedRecoJet(jet)) { fillRejectedJetHistograms(jet, collision.mcCollision().weight()); } } @@ -906,7 +1246,7 @@ struct FullJetSpectra { if (jet.phi() < jetPhiMin || jet.phi() > jetPhiMax) { continue; } - if (!isAcceptedJet(jet)) { + if (!isAcceptedRecoJet(jet)) { continue; } fillJetHistograms(jet, collision.mcCollision().weight()); @@ -952,38 +1292,38 @@ struct FullJetSpectra { return; } registry.fill(HIST("hPartcollisionCounter"), 1.5); // McCollWithVertexZ - if (collisions.size() < 1) { - return; - } - registry.fill(HIST("hPartcollisionCounter"), 2.5); // PartCollWithSize>1 - - if (collisions.size() == 0) { - registry.fill(HIST("hPartcollisionCounter"), 3.5); // RejectedPartCollForDetCollWithSize0 - return; - } // outlier check: for every outlier jet, reject the whole event for (auto const& jet : jets) { if (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) { - registry.fill(HIST("hPartcollisionCounter"), 4.5); // RejectedPartCollWithOutliers + registry.fill(HIST("hPartcollisionCounter"), 2.5); // RejectedPartCollWithOutliers return; } } if (doMBGapTrigger && mccollision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { // Fill rejected MB events; - registry.fill(HIST("hPartcollisionCounter"), 5.5); // MBRejectedPartEvents + registry.fill(HIST("hPartcollisionCounter"), 3.5); // MBRejectedPartEvents + return; + } + + auto collisionspermcpjet = collisions.sliceBy(CollisionsPerMCPCollision, mccollision.globalIndex()); + registry.fill(HIST("hRecoMatchesPerMcCollision"), collisionspermcpjet.size()); // for split vertices QA + + if (collisionspermcpjet.size() == 0 || collisionspermcpjet.size() < 1) { + registry.fill(HIST("hPartcollisionCounter"), 4.5); // RejectedPartCollForDetCollWithSize0or<1 return; } + registry.fill(HIST("hPartcollisionCounter"), 5.5); // AcceptedPartCollWithSize>=1 - for (auto const& collision : collisions) { + for (auto const& collision : collisionspermcpjet) { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { - return; + continue; } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content - eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; registry.fill(HIST("hPartcollisionCounter"), 6.5); // EMCreadoutDetEventsWithkTVXinEMC } } @@ -998,24 +1338,16 @@ struct FullJetSpectra { registry.fill(HIST("hPartcollisionCounter"), 7.5); // AllRejectedPartEventsAfterEMCEventSelection return; } - registry.fill(HIST("hPartcollisionCounter"), 8.5); // EMCAcceptedWeightedPartColl + registry.fill(HIST("hPartcollisionCounter"), 8.5); // EMCAcceptedPartColl for (auto const& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { continue; } - if (!isAcceptedJet(jet)) { + if (!isAcceptedPartJet(jet)) { continue; } - if (checkMcCollisionIsMatched) { // basically checks if the same collisions are generated at the Part level as those at the Det level - auto collisionspermcpjet = collisions.sliceBy(CollisionsPerMCPCollision, jet.mcCollisionId()); - if (collisionspermcpjet.size() >= 1 && jetderiveddatautilities::selectCollision(collisionspermcpjet.begin(), eventSelectionBits)) { - // Now here for every matched collision, I fill the corresponding jet histograms. - fillMCPHistograms(jet); - } - } else { - fillMCPHistograms(jet); - } + fillMCPHistograms(jet); } } PROCESS_SWITCH(FullJetSpectra, processJetsMCP, "Full Jets at Particle Level", false); @@ -1057,45 +1389,45 @@ struct FullJetSpectra { return; } registry.fill(HIST("hPartcollisionCounter"), 1.5, mccollision.weight()); // McCollWithVertexZ - if (collisions.size() < 1) { - return; - } - registry.fill(HIST("hPartcollisionCounter"), 2.5, mccollision.weight()); // PartCollWithSize>1 - - if (collisions.size() == 0) { - registry.fill(HIST("hPartcollisionCounter"), 3.5, mccollision.weight()); // RejectedPartCollForDetCollWithSize0 - return; - } // outlier check: for every outlier jet, reject the whole event for (auto const& jet : jets) { if (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) { - registry.fill(HIST("hPartcollisionCounter"), 4.5, mccollision.weight()); // RejectedPartCollWithOutliers + registry.fill(HIST("hPartcollisionCounter"), 2.5, mccollision.weight()); // RejectedPartCollWithOutliers return; } } if (doMBGapTrigger && mccollision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { // Fill rejected MB events - registry.fill(HIST("hPartcollisionCounter"), 5.5, mccollision.weight()); // MBRejectedPartEvents + registry.fill(HIST("hPartcollisionCounter"), 3.5, mccollision.weight()); // MBRejectedPartEvents return; } - for (auto const& collision : collisions) { + auto collisionspermcpjet = collisions.sliceBy(CollisionsPerMCPCollision, mccollision.globalIndex()); + registry.fill(HIST("hRecoMatchesPerMcCollision"), collisionspermcpjet.size(), mccollision.weight()); // for split vertices QA + + if (collisionspermcpjet.size() == 0 || collisionspermcpjet.size() < 1) { + registry.fill(HIST("hPartcollisionCounter"), 4.5, mccollision.weight()); // RejectedPartCollForDetCollWithSize0or<1 + return; + } + registry.fill(HIST("hPartcollisionCounter"), 5.5, mccollision.weight()); // AcceptedPartCollWithSize>=1 + + for (auto const& collision : collisionspermcpjet) { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { - return; + continue; } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content - eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { - registry.fill(HIST("hPartcollisionCounter"), 6.5, mccollision.weight()); // EMCreadoutDetJJEventsWithkTVXinEMC + eventAccepted = true; + registry.fill(HIST("hPartcollisionCounter"), 6.5, mccollision.weight()); // EMCreadoutDetEventsWithkTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; - registry.fill(HIST("hPartcollisionCounter"), 6.5, mccollision.weight()); // EMCreadoutDetJJEventsWithkTVXinEMC + registry.fill(HIST("hPartcollisionCounter"), 6.5, mccollision.weight()); // EMCreadoutDetEventsWithkTVXinEMC } } } @@ -1110,22 +1442,13 @@ struct FullJetSpectra { if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { return; } - if (!isAcceptedJet(jet)) { + if (!isAcceptedPartJet(jet)) { return; } if (doMBGapTrigger && jet.eventWeight() == 1) { return; } - - if (checkMcCollisionIsMatched) { - auto collisionspermcpjet = collisions.sliceBy(CollisionsPerMCPCollision, jet.mcCollisionId()); - - if (collisionspermcpjet.size() >= 1 && jetderiveddatautilities::selectCollision(collisionspermcpjet.begin(), eventSelectionBits)) { - fillMCPHistograms(jet, jet.eventWeight()); - } - } else { - fillMCPHistograms(jet, jet.eventWeight()); - } + fillMCPHistograms(jet, jet.eventWeight()); } } PROCESS_SWITCH(FullJetSpectra, processJetsMCPWeighted, "Full Jets at Particle Level on weighted events", false); @@ -1197,8 +1520,8 @@ struct FullJetSpectra { } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content - eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; registry.fill(HIST("hMatchedcollisionCounter"), 6.5); // EMCreadoutDetEventsWithkTVXinEMC } } @@ -1215,6 +1538,9 @@ struct FullJetSpectra { registry.fill(HIST("hMatchedcollisionCounter"), 8.5); // EMCAcceptedDetColl for (const auto& mcdjet : mcdjets) { + if (!isAcceptedRecoJet(mcdjet)) { + continue; + } if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { continue; } @@ -1224,10 +1550,11 @@ struct FullJetSpectra { registry.fill(HIST("h2_full_fakemcdjets"), mcdjet.pt(), fakeMcdJet, 1.0); continue; } - if (!isAcceptedJet(mcdjet)) { - continue; - } + for (const auto& mcpjet : mcdjet.template matchedJetGeo_as()) { + if (!isAcceptedPartJet(mcpjet)) { + return; + } // apply emcal fiducial cuts to the matched particle level jets if (mcpjet.eta() > jetEtaMax || mcpjet.eta() < jetEtaMin || mcpjet.phi() > jetPhiMax || mcpjet.phi() < jetPhiMin) { fakeMcpJet++; @@ -1313,8 +1640,8 @@ struct FullJetSpectra { } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content - eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; registry.fill(HIST("hMatchedcollisionCounter"), 6.5, eventWeight); // EMCreadoutDetJJEventsWithkTVXinEMC } } @@ -1331,6 +1658,9 @@ struct FullJetSpectra { registry.fill(HIST("hMatchedcollisionCounter"), 8.5, eventWeight); // EMCAcceptedDetColl for (const auto& mcdjet : mcdjets) { + if (!isAcceptedRecoJet(mcdjet)) { + continue; + } // Check if MCD jet is within the EMCAL fiducial region; if not then flag it as a fake jet if (mcdjet.phi() < jetPhiMin || mcdjet.phi() > jetPhiMax || mcdjet.eta() < jetEtaMin || mcdjet.eta() > jetEtaMax) { fakeMcdJet++; @@ -1340,11 +1670,11 @@ struct FullJetSpectra { if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { continue; } - if (!isAcceptedJet(mcdjet)) { - continue; - } for (const auto& mcpjet : mcdjet.template matchedJetGeo_as()) { + if (!isAcceptedPartJet(mcpjet)) { + return; + } // apply emcal fiducial cuts to the matched particle level jets - if the matched mcp jet lies outside of the EMCAL fiducial, flag it as a fake jet if (mcpjet.eta() > jetEtaMax || mcpjet.eta() < jetEtaMin || mcpjet.phi() > jetPhiMax || mcpjet.phi() < jetPhiMin) { fakeMcpJet++; @@ -1414,8 +1744,8 @@ struct FullJetSpectra { if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content - eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; registry.fill(HIST("hCollisionsUnweighted"), 4.5); // EMCreadoutDetEventsWithkTVXinEMC } } @@ -1473,8 +1803,8 @@ struct FullJetSpectra { if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content - eventAccepted = true; if (collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; registry.fill(HIST("hCollisionsUnweighted"), 4.5); // EMCreadoutDetEventsWithkTVXinEMC } } @@ -1537,9 +1867,9 @@ struct FullJetSpectra { if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content - eventAccepted = true; fillTrackHistograms(tracks, clusters, eventWeight); if (collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; registry.fill(HIST("hCollisionsWeighted"), 4.5, eventWeight); // EMCreadoutDetJJEventsWithkTVXinEMC } } @@ -1567,89 +1897,168 @@ struct FullJetSpectra { } PROCESS_SWITCH(FullJetSpectra, processTracksWeighted, "Full Jet tracks weighted", false); - void processCollisionsWeightedWithMultiplicity(soa::Filtered::iterator const& collision, JetTableMCDWeightedJoined const& mcdjets, aod::JMcCollisions const&, soa::Filtered const& tracks, soa::Filtered const& clusters) + void processMBCollisionsDATAWithMultiplicity(soa::Filtered::iterator const& collision, FullJetTableDataJoined const& jets, aod::JetTracks const& /*tracks*/, aod::JetClusters const& /*clusters*/) { bool eventAccepted = false; - float eventWeight = collision.mcCollision().weight(); - float neutralEnergy = 0.0; - registry.fill(HIST("hEventmultiplicityCounter"), 0.5, eventWeight); // allDetColl + registry.fill(HIST("hEventmultiplicityCounter"), 0.5); // allDetColl if (std::fabs(collision.posZ()) > vertexZCut) { - registry.fill(HIST("hEventmultiplicityCounter"), 1.5, eventWeight); // DetCollWithVertexZ - return; - } - if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { - registry.fill(HIST("hEventmultiplicityCounter"), 2.5, eventWeight); // MBRejectedDetEvents return; } + registry.fill(HIST("hEventmultiplicityCounter"), 1.5); // DetCollWithVertexZ + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { - registry.fill(HIST("hEventmultiplicityCounter"), 3.5, eventWeight); // EventsNotSatisfyingEventSelection - return; - } - if (doMBGapTrigger && eventWeight == 1) { - registry.fill(HIST("hEventmultiplicityCounter"), 2.5, eventWeight); // MBRejectedDetEvents + registry.fill(HIST("hEventmultiplicityCounter"), 2.5); // EventsNotSatisfyingEventSelection return; } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content - eventAccepted = true; - fillTrackHistograms(tracks, clusters, eventWeight); if (collision.alias_bit(kTVXinEMC)) { - registry.fill(HIST("hEventmultiplicityCounter"), 4.5, eventWeight); // EMCreadoutDetJJEventsWithkTVXinEMC + eventAccepted = true; + registry.fill(HIST("hEventmultiplicityCounter"), 3.5); // EMCreadoutDetEventsWithkTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; - registry.fill(HIST("hEventmultiplicityCounter"), 4.5, eventWeight); // EMCreadoutDetJJEventsWithkTVXinEMC + registry.fill(HIST("hEventmultiplicityCounter"), 3.5); // EMCreadoutDetEventsWithkTVXinEMC } } if (!eventAccepted) { - registry.fill(HIST("hEventmultiplicityCounter"), 5.5, eventWeight); // AllRejectedDetEventsAfterEMCEventSelection + registry.fill(HIST("hEventmultiplicityCounter"), 4.5); // AllRejectedDetEventsAfterEMCEventSelection return; } - registry.fill(HIST("hCollisionsWeighted"), 6.5); // EMCAcceptedWeightedDetColl + registry.fill(HIST("hEventmultiplicityCounter"), 5.5); // EMCAcceptedDetColl - for (auto const& track : tracks) { - if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { + registry.fill(HIST("h_FT0Mults_occupancy"), collision.multFT0M()); + + // Jet processing - NEW IMPLEMENTATION + std::vector::iterator> selectedJets; + // static int eventCounter = 0; + int nJetsThisEvent = 0; + // Debug output + // std::cout << "===== Event " << ++eventCounter << " (Collision ID: " << collision.globalIndex() << ") =====" << std::endl; + + // Verify jet-collision association + for (auto const& jet : jets) { + if (jet.collisionId() != collision.globalIndex()) { + std::cout << "WARNING: Jet with pT " << jet.pt() << " belongs to collision " << jet.collisionId() + << " but processing collision " << collision.globalIndex() << std::endl; continue; } - } - registry.fill(HIST("hEventmultiplicityCounter"), 7.5, eventWeight); // EMCAcceptedWeightedCollAfterTrackSel - registry.fill(HIST("h_FT0Mults_occupancy"), collision.multFT0M(), eventWeight); - for (auto const& mcdjet : mcdjets) { - float pTHat = 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)); - if (mcdjet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) { // MCD jets outlier rejection - return; - } - if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) continue; - } - if (mcdjet.phi() < jetPhiMin || mcdjet.phi() > jetPhiMax) { + if (jet.phi() < jetPhiMin || jet.phi() > jetPhiMax) continue; - } - if (!isAcceptedJet(mcdjet)) { + if (!isAcceptedRecoJet(jet)) continue; + + selectedJets.push_back(jet); + nJetsThisEvent++; + // std::cout << "Selected jet pT: " << jet.pt() << " (collision ID: " << jet.collisionId() << ")" << std::endl; + } + // 1. Sort selected jets by pT before processing + std::sort(selectedJets.begin(), selectedJets.end(), + [](auto const& a, auto const& b) { return (*a).pt() > (*b).pt(); }); + + // std::cout << "Number of selected jets: " << selectedJets.size() << std::endl; + + // // 2. Reset counters for each event + // int numberOfChargedParticles = 0; + // int totalNumberOfChargedParticles = 0; + // int leadingJetCount = 0; + // + // std::cout << "Number of selected jets per event: " << selectedJets.size() << std::endl; + // for (const auto& jetIter : selectedJets) { + // std::cout << "Jet pT of selectedJets: " << (*jetIter).pt() << std::endl; + // } + // //Checking Event Counter + // static int eventCounter = 0; + // std::cout << "===== Event " << ++eventCounter << " =====" << std::endl; + // std::cout << "******************************************** " << std::endl; + if (selectedJets.size() == 0) { // no jets = no leading jet + return; + } + + if (selectedJets.size() > 0) { + // Jet multiplicity per event + registry.fill(HIST("h_all_fulljet_Njets"), selectedJets.size(), 1.0); + + // Select Leading Jet for N_ch calculation (for every leading jet that is found). There's always one leading jet per event! + auto const& leadingJet = *selectedJets[0]; + auto const& leadingJetPt = leadingJet.pt(); // jet pT distribution of the leading jet + // std::cout << "Leading Jet pT: " << leadingJetPt << std::endl; + registry.fill(HIST("h_Leading_full_jet_pt"), leadingJetPt, 1.0); + registry.fill(HIST("h2_full_jet_leadingJetPt_vs_counts"), leadingJetPt, nJetsThisEvent, 1.0); + } + + if (selectedJets.size() > 1) { + auto const& subLeadingJet = *selectedJets[1]; + auto const& subLeadingJetPt = subLeadingJet.pt(); // jet pT distribution of the subleading jet i.e. 2nd leading jet + registry.fill(HIST("h_SubLeading_full_jet_pt"), subLeadingJetPt, 1.0); + registry.fill(HIST("h2_full_jet_subLeadingJetPt_vs_counts"), subLeadingJetPt, nJetsThisEvent, 1.0); + } + // Process ALL selected jets (not just leading) + for (size_t i = 0; i < selectedJets.size(); i++) { + auto const& jet = *selectedJets[i]; + float jetPt = jet.pt(); + bool isLeading = (i == 0); + bool isSubLeading = (i == 1 && selectedJets.size() > 1); // first sub-leading jet + + // Count charged particles(NCh) for this jet + int numberOfChargedParticles = 0; + for (const auto& jettrack : jet.tracks_as()) { + if (jetderiveddatautilities::selectTrack(jettrack, trackSelection)) { + numberOfChargedParticles++; + } else + continue; } - registry.fill(HIST("h2_full_jet_jetpTDetVsFT0Mults"), mcdjet.pt(), collision.multFT0M(), eventWeight); - for (auto const& cluster : clusters) { - neutralEnergy += cluster.energy(); + // Calculate neutral energy fraction for this jet + float neutralEnergy = 0.0; + for (const auto& jetcluster : jet.clusters_as()) { + neutralEnergy += jetcluster.energy(); + } + float nef = neutralEnergy / jet.energy(); + + // CASE 1: Fill histograms for ALL selected jets + registry.fill(HIST("h_all_fulljet_pt"), jetPt, 1.0); + registry.fill(HIST("h_all_fulljet_Nch"), numberOfChargedParticles, 1.0); + registry.fill(HIST("h_all_fulljet_NEF"), nef, 1.0); + registry.fill(HIST("h2_all_fulljet_jetpTDet_vs_FT0Mults"), jetPt, collision.multFT0M(), 1.0); + registry.fill(HIST("h2_all_fulljet_jetpTDet_vs_Nch"), jetPt, numberOfChargedParticles, 1.0); + registry.fill(HIST("h3_full_jet_jetpTDet_FT0Mults_nef"), jetPt, collision.multFT0M(), nef, 1.0); + + // CASE 2: Additional leading jet processing + if (isLeading) { + registry.fill(HIST("h_leading_fulljet_pt"), jetPt, 1.0); + registry.fill(HIST("h_leading_fulljet_Nch"), numberOfChargedParticles, 1.0); + registry.fill(HIST("h_leading_fulljet_NEF"), nef, 1.0); + registry.fill(HIST("h2_leading_fulljet_jetpTDet_vs_FT0Mults"), jetPt, collision.multFT0M(), 1.0); + registry.fill(HIST("h2_leading_fulljet_jetpTDet_vs_Nch"), jetPt, numberOfChargedParticles, 1.0); + registry.fill(HIST("h3_leading_fulljet_jetpTDet_FT0Mults_nef"), jetPt, collision.multFT0M(), nef, 1.0); + } + + // CASE 3: Additional first sub-leading jet processing + if (isSubLeading) { + registry.fill(HIST("h_subleading_fulljet_pt"), jetPt, 1.0); + registry.fill(HIST("h_subleading_fulljet_Nch"), numberOfChargedParticles, 1.0); + registry.fill(HIST("h_subleading_fulljet_NEF"), nef, 1.0); + registry.fill(HIST("h2_subleading_fulljet_jetpTDet_vs_FT0Mults"), jetPt, collision.multFT0M(), 1.0); + registry.fill(HIST("h2_subleading_fulljet_jetpTDet_vs_Nch"), jetPt, numberOfChargedParticles, 1.0); + registry.fill(HIST("h3_subleading_fulljet_jetpTDet_FT0Mults_nef"), jetPt, collision.multFT0M(), nef, 1.0); } - auto nef = neutralEnergy / mcdjet.energy(); - registry.fill(HIST("h3_full_jet_jetpTDet_FT0Mults_nef"), mcdjet.pt(), collision.multFT0M(), nef, eventWeight); } } - PROCESS_SWITCH(FullJetSpectra, processCollisionsWeightedWithMultiplicity, "Weighted Collisions for Full Jets Multiplicity Studies", false); + PROCESS_SWITCH(FullJetSpectra, processMBCollisionsDATAWithMultiplicity, "MB DATA Collisions for Full Jets Multiplicity Studies", false); - void processMBCollisionsWithMultiplicity(soa::Filtered::iterator const& collision, JetTableMCDJoined const& mcdjets, aod::JMcCollisions const&, soa::Filtered const& tracks, soa::Filtered const& clusters) + void processMBMCDCollisionsWithMultiplicity(soa::Filtered::iterator const& collision, JetTableMCDJoined const& mcdjets, aod::JMcCollisions const&, aod::JetTracks const& /*tracks*/, aod::JetClusters const& /*clusters*/) { bool eventAccepted = false; - float pTHat = 10. / (std::pow(1.0, 1.0 / pTHatExponent)); - float neutralEnergy = 0.0; + // float pTHat = 10. / (std::pow(1.0, 1.0 / pTHatExponent)); registry.fill(HIST("hEventmultiplicityCounter"), 0.5); // allDetColl if (std::fabs(collision.posZ()) > vertexZCut) { @@ -1657,136 +2066,628 @@ struct FullJetSpectra { } registry.fill(HIST("hEventmultiplicityCounter"), 1.5); // DetCollWithVertexZ - if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { - registry.fill(HIST("hEventmultiplicityCounter"), 2.5); // MBRejectedDetEvents - return; - } if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { - registry.fill(HIST("hEventmultiplicityCounter"), 3.5); // EventsNotSatisfyingEventSelection + registry.fill(HIST("hEventmultiplicityCounter"), 2.5); // EventsNotSatisfyingEventSelection return; } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content eventAccepted = true; - fillTrackHistograms(tracks, clusters, 1.0); + // fillTrackHistograms(tracks, clusters, 1.0); if (collision.alias_bit(kTVXinEMC)) { - registry.fill(HIST("hEventmultiplicityCounter"), 4.5); // EMCreadoutDetEventsWithkTVXinEMC + registry.fill(HIST("hEventmultiplicityCounter"), 3.5); // EMCreadoutDetEventsWithkTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; - registry.fill(HIST("hEventmultiplicityCounter"), 4.5); // EMCreadoutDetEventsWithkTVXinEMC + registry.fill(HIST("hEventmultiplicityCounter"), 3.5); // EMCreadoutDetEventsWithkTVXinEMC } } if (!eventAccepted) { - registry.fill(HIST("hEventmultiplicityCounter"), 5.5); // AllRejectedDetEventsAfterEMCEventSelection + registry.fill(HIST("hEventmultiplicityCounter"), 4.5); // AllRejectedDetEventsAfterEMCEventSelection return; } - registry.fill(HIST("hEventmultiplicityCounter"), 6.5); // EMCAcceptedDetColl + registry.fill(HIST("hEventmultiplicityCounter"), 5.5); // EMCAcceptedDetColl - for (auto const& track : tracks) { - if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { - continue; - } - } - registry.fill(HIST("hEventmultiplicityCounter"), 7.5); // EMCAcceptedCollAfterTrackSel registry.fill(HIST("h_FT0Mults_occupancy"), collision.multFT0M()); + std::vector::iterator> selectedJets; + // static int eventCounter = 0; + int nJetsThisEvent = 0; + // Debug output + // std::cout << "===== Event " << ++eventCounter << " (Collision ID: " << collision.globalIndex() << ") =====" << std::endl; + + // Verify jet-collision association for (auto const& mcdjet : mcdjets) { - if (mcdjet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) { // MCD (Detector Level) Outlier Rejection - return; - } - if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + if (mcdjet.collisionId() != collision.globalIndex()) { + std::cout << "WARNING: Jet with pT " << mcdjet.pt() << " belongs to collision " << mcdjet.collisionId() + << " but processing collision " << collision.globalIndex() << std::endl; continue; } - if (mcdjet.phi() < jetPhiMin || mcdjet.phi() > jetPhiMax) { + + if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) continue; - } - if (!isAcceptedJet(mcdjet)) { + if (mcdjet.phi() < jetPhiMin || mcdjet.phi() > jetPhiMax) continue; + if (!isAcceptedRecoJet(mcdjet)) + continue; + + selectedJets.push_back(mcdjet); + nJetsThisEvent++; + // std::cout << "Selected jet pT: " << jet.pt() << " (collision ID: " << jet.collisionId() << ")" << std::endl; + } + // 1. Sort selected jets by pT before processing + std::sort(selectedJets.begin(), selectedJets.end(), + [](auto const& a, auto const& b) { return (*a).pt() > (*b).pt(); }); + + if (selectedJets.size() == 0) { // no jets = no leading jet + return; + } + + if (selectedJets.size() > 0) { + // Jet multiplicity per event + registry.fill(HIST("h_all_fulljet_Njets"), selectedJets.size(), 1.0); + + // Select Leading Jet for N_ch calculation (for every leading jet that is found). There's always one leading jet per event! + auto const& leadingJet = *selectedJets[0]; + auto const& leadingJetPt = leadingJet.pt(); // jet pT distribution of the leading jet + // std::cout << "Leading Jet pT: " << leadingJetPt << std::endl; + registry.fill(HIST("h_Leading_full_jet_pt"), leadingJetPt, 1.0); + registry.fill(HIST("h2_full_jet_leadingJetPt_vs_counts"), leadingJetPt, nJetsThisEvent, 1.0); + } + + if (selectedJets.size() > 1) { + auto const& subLeadingJet = *selectedJets[1]; + auto const& subLeadingJetPt = subLeadingJet.pt(); // jet pT distribution of the subleading jet i.e. 2nd leading jet + registry.fill(HIST("h_SubLeading_full_jet_pt"), subLeadingJetPt, 1.0); + registry.fill(HIST("h2_full_jet_subLeadingJetPt_vs_counts"), subLeadingJetPt, nJetsThisEvent, 1.0); + } + // Process ALL selected jets (not just leading) + for (size_t i = 0; i < selectedJets.size(); i++) { + auto const& jet = *selectedJets[i]; + float jetPt = jet.pt(); + bool isLeading = (i == 0); + bool isSubLeading = (i == 1 && selectedJets.size() > 1); // first sub-leading jet + + // Count charged particles(NCh) for this jet + int numberOfChargedParticles = 0; + for (const auto& jettrack : jet.tracks_as()) { + if (jetderiveddatautilities::selectTrack(jettrack, trackSelection)) { + numberOfChargedParticles++; + } else + continue; } - registry.fill(HIST("h2_full_jet_jetpTDetVsFT0Mults"), mcdjet.pt(), collision.multFT0M(), 1.0); - for (auto const& cluster : clusters) { - neutralEnergy += cluster.energy(); + // Calculate neutral energy fraction for this jet + float neutralEnergy = 0.0; + for (const auto& jetcluster : jet.clusters_as()) { + neutralEnergy += jetcluster.energy(); + } + float nef = neutralEnergy / jet.energy(); + + // CASE 1: Fill histograms for ALL selected jets + registry.fill(HIST("h_all_fulljet_pt"), jetPt, 1.0); + registry.fill(HIST("h_all_fulljet_Nch"), numberOfChargedParticles, 1.0); + registry.fill(HIST("h_all_fulljet_NEF"), nef, 1.0); + registry.fill(HIST("h2_all_fulljet_jetpTDet_vs_FT0Mults"), jetPt, collision.multFT0M(), 1.0); + registry.fill(HIST("h2_all_fulljet_jetpTDet_vs_Nch"), jetPt, numberOfChargedParticles, 1.0); + registry.fill(HIST("h3_full_jet_jetpTDet_FT0Mults_nef"), jetPt, collision.multFT0M(), nef, 1.0); + + // CASE 2: Additional leading jet processing + if (isLeading) { + registry.fill(HIST("h_leading_fulljet_pt"), jetPt, 1.0); + registry.fill(HIST("h_leading_fulljet_Nch"), numberOfChargedParticles, 1.0); + registry.fill(HIST("h_leading_fulljet_NEF"), nef, 1.0); + registry.fill(HIST("h2_leading_fulljet_jetpTDet_vs_FT0Mults"), jetPt, collision.multFT0M(), 1.0); + registry.fill(HIST("h2_leading_fulljet_jetpTDet_vs_Nch"), jetPt, numberOfChargedParticles, 1.0); + registry.fill(HIST("h3_leading_fulljet_jetpTDet_FT0Mults_nef"), jetPt, collision.multFT0M(), nef, 1.0); + } + + // CASE 3: Additional first sub-leading jet processing + if (isSubLeading) { + registry.fill(HIST("h_subleading_fulljet_pt"), jetPt, 1.0); + registry.fill(HIST("h_subleading_fulljet_Nch"), numberOfChargedParticles, 1.0); + registry.fill(HIST("h_subleading_fulljet_NEF"), nef, 1.0); + registry.fill(HIST("h2_subleading_fulljet_jetpTDet_vs_FT0Mults"), jetPt, collision.multFT0M(), 1.0); + registry.fill(HIST("h2_subleading_fulljet_jetpTDet_vs_Nch"), jetPt, numberOfChargedParticles, 1.0); + registry.fill(HIST("h3_subleading_fulljet_jetpTDet_FT0Mults_nef"), jetPt, collision.multFT0M(), nef, 1.0); } - auto nef = neutralEnergy / mcdjet.energy(); - registry.fill(HIST("h3_full_jet_jetpTDet_FT0Mults_nef"), mcdjet.pt(), collision.multFT0M(), nef, 1.0); } } - PROCESS_SWITCH(FullJetSpectra, processMBCollisionsWithMultiplicity, "MB MCD Collisions for Full Jets Multiplicity Studies", false); + PROCESS_SWITCH(FullJetSpectra, processMBMCDCollisionsWithMultiplicity, "MB MCD Collisions for Full Jets Multiplicity Studies", false); - void processMBCollisionsDATAWithMultiplicity(soa::Filtered::iterator const& collision, FullJetTableDataJoined const& jets, soa::Filtered const& tracks, soa::Filtered const& clusters) + void processMCDCollisionsWeightedWithMultiplicity(soa::Filtered::iterator const& collision, JetTableMCDWeightedJoined const& mcdjets, aod::JMcCollisions const&, aod::JetTracks const& tracks, aod::JetClusters const& clusters) { bool eventAccepted = false; - float neutralEnergy = 0.0; + float eventWeight = collision.mcCollision().weight(); - registry.fill(HIST("hEventmultiplicityCounter"), 0.5); // allDetColl + registry.fill(HIST("hEventmultiplicityCounter"), 0.5, eventWeight); // allWeightedDetColl if (std::fabs(collision.posZ()) > vertexZCut) { return; } - registry.fill(HIST("hEventmultiplicityCounter"), 1.5); // DetCollWithVertexZ + registry.fill(HIST("hEventmultiplicityCounter"), 1.5, eventWeight); // WeightedDetCollWithVertexZ + if (doMBGapTrigger && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { - registry.fill(HIST("hEventmultiplicityCounter"), 2.5); // MBRejectedDetEvents + registry.fill(HIST("hEventmultiplicityCounter"), 2.5, eventWeight); // MBRejectedDetEvents return; } if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { - registry.fill(HIST("hEventmultiplicityCounter"), 3.5); // EventsNotSatisfyingEventSelection + registry.fill(HIST("hEventmultiplicityCounter"), 3.5, eventWeight); // WeightedEventsNotSatisfyingEventSelection + return; + } + if (doMBGapTrigger && eventWeight == 1) { + registry.fill(HIST("hEventmultiplicityCounter"), 2.5, eventWeight); // MBRejectedDetEvents return; } if (doEMCALEventWorkaround) { if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content eventAccepted = true; - fillTrackHistograms(tracks, clusters, 1.0); + fillTrackHistograms(tracks, clusters, eventWeight); if (collision.alias_bit(kTVXinEMC)) { - registry.fill(HIST("hEventmultiplicityCounter"), 4.5); // EMCreadoutDetEventsWithkTVXinEMC + registry.fill(HIST("hEventmultiplicityCounter"), 4.5, eventWeight); // EMCreadoutWeightedDetJJEventsWithkTVXinEMC } } } else { if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { eventAccepted = true; - registry.fill(HIST("hEventmultiplicityCounter"), 4.5); // EMCreadoutDetEventsWithkTVXinEMC + registry.fill(HIST("hEventmultiplicityCounter"), 4.5, eventWeight); // EMCreadoutWeightedDetJJEventsWithkTVXinEMC } } if (!eventAccepted) { - registry.fill(HIST("hEventmultiplicityCounter"), 5.5); // AllRejectedDetEventsAfterEMCEventSelection + registry.fill(HIST("hEventmultiplicityCounter"), 5.5, eventWeight); // AllRejectedWeightedDetEventsAfterEMCEventSelection return; } - registry.fill(HIST("hEventmultiplicityCounter"), 6.5); // EMCAcceptedDetColl - + registry.fill(HIST("hEventmultiplicityCounter"), 6.5, eventWeight); // EMCAcceptedWeightedDetColl for (auto const& track : tracks) { if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { continue; } } - registry.fill(HIST("hEventmultiplicityCounter"), 7.5); // EMCAcceptedCollAfterTrackSel - registry.fill(HIST("h_FT0Mults_occupancy"), collision.multFT0M()); + registry.fill(HIST("hEventmultiplicityCounter"), 7.5, eventWeight); // EMCAcceptedWeightedCollAfterTrackSel + + registry.fill(HIST("h_FT0Mults_occupancy"), collision.multFT0M(), eventWeight); + + std::vector::iterator> selectedJets; + int nJetsThisEvent = 0; + + for (auto const& mcdjet : mcdjets) { + float pTHat = 10. / (std::pow(eventWeight, 1.0 / pTHatExponent)); + + if (mcdjet.collisionId() != collision.globalIndex()) { + std::cout << "WARNING: Jet with pT " << mcdjet.pt() << " belongs to collision " << mcdjet.collisionId() + << " but processing collision " << collision.globalIndex() << std::endl; + continue; + } + if (mcdjet.pt() > pTHatMaxMCD * pTHat || pTHat < pTHatAbsoluteMin) { // MCD jets outlier rejection + return; + } + if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + if (mcdjet.phi() < jetPhiMin || mcdjet.phi() > jetPhiMax) { + continue; + } + if (!isAcceptedRecoJet(mcdjet)) { + continue; + } + selectedJets.push_back(mcdjet); + nJetsThisEvent++; + } + // 1. Sort selected jets by pT before processing + std::sort(selectedJets.begin(), selectedJets.end(), + [](auto const& a, auto const& b) { return (*a).pt() > (*b).pt(); }); + + if (selectedJets.size() == 0) { // no jets = no leading jet + return; + } + if (selectedJets.size() > 0) { + // Jet multiplicity per event + registry.fill(HIST("h_all_fulljet_Njets"), selectedJets.size(), eventWeight); + + // Select Leading Jet for N_ch calculation (for every leading jet that is found). There's always one leading jet per event! + auto const& leadingJet = *selectedJets[0]; + auto const& leadingJetPt = leadingJet.pt(); // jet pT distribution of the leading jet + // std::cout << "Leading Jet pT: " << leadingJetPt << std::endl; + registry.fill(HIST("h_Leading_full_jet_pt"), leadingJetPt, eventWeight); + registry.fill(HIST("h2_full_jet_leadingJetPt_vs_counts"), leadingJetPt, nJetsThisEvent, eventWeight); + } + + if (selectedJets.size() > 1) { + auto const& subLeadingJet = *selectedJets[1]; + auto const& subLeadingJetPt = subLeadingJet.pt(); // jet pT distribution of the subleading jet i.e. 2nd leading jet + registry.fill(HIST("h_SubLeading_full_jet_pt"), subLeadingJetPt, eventWeight); + registry.fill(HIST("h2_full_jet_subLeadingJetPt_vs_counts"), subLeadingJetPt, nJetsThisEvent, eventWeight); + } + // Process ALL selected jets (not just leading) + for (size_t i = 0; i < selectedJets.size(); i++) { + auto const& jet = *selectedJets[i]; + float jetPt = jet.pt(); + bool isLeading = (i == 0); + bool isSubLeading = (i == 1 && selectedJets.size() > 1); // first sub-leading jet + + // Count charged particles(NCh) for this jet + int numberOfChargedParticles = 0; + for (const auto& jettrack : jet.tracks_as()) { + if (jetderiveddatautilities::selectTrack(jettrack, trackSelection)) { + numberOfChargedParticles++; + } else + continue; + } + + // Calculate neutral energy fraction for this jet + float neutralEnergy = 0.0; + for (const auto& jetcluster : jet.clusters_as()) { + neutralEnergy += jetcluster.energy(); + } + float nef = neutralEnergy / jet.energy(); + + // CASE 1: Fill histograms for ALL selected jets + registry.fill(HIST("h_all_fulljet_pt"), jetPt, eventWeight); + registry.fill(HIST("h_all_fulljet_Nch"), numberOfChargedParticles, eventWeight); + registry.fill(HIST("h_all_fulljet_NEF"), nef, eventWeight); + registry.fill(HIST("h2_all_fulljet_jetpTDet_vs_FT0Mults"), jetPt, collision.multFT0M(), eventWeight); + registry.fill(HIST("h2_all_fulljet_jetpTDet_vs_Nch"), jetPt, numberOfChargedParticles, eventWeight); + registry.fill(HIST("h3_full_jet_jetpTDet_FT0Mults_nef"), jetPt, collision.multFT0M(), nef, eventWeight); + + // CASE 2: Additional leading jet processing + if (isLeading) { + registry.fill(HIST("h_leading_fulljet_pt"), jetPt, eventWeight); + registry.fill(HIST("h_leading_fulljet_Nch"), numberOfChargedParticles, eventWeight); + registry.fill(HIST("h_leading_fulljet_NEF"), nef, eventWeight); + registry.fill(HIST("h2_leading_fulljet_jetpTDet_vs_FT0Mults"), jetPt, collision.multFT0M(), eventWeight); + registry.fill(HIST("h2_leading_fulljet_jetpTDet_vs_Nch"), jetPt, numberOfChargedParticles, eventWeight); + registry.fill(HIST("h3_leading_fulljet_jetpTDet_FT0Mults_nef"), jetPt, collision.multFT0M(), nef, eventWeight); + } + + // CASE 3: Additional first sub-leading jet processing + if (isSubLeading) { + registry.fill(HIST("h_subleading_fulljet_pt"), jetPt, eventWeight); + registry.fill(HIST("h_subleading_fulljet_Nch"), numberOfChargedParticles, eventWeight); + registry.fill(HIST("h_subleading_fulljet_NEF"), nef, eventWeight); + registry.fill(HIST("h2_subleading_fulljet_jetpTDet_vs_FT0Mults"), jetPt, collision.multFT0M(), eventWeight); + registry.fill(HIST("h2_subleading_fulljet_jetpTDet_vs_Nch"), jetPt, numberOfChargedParticles, eventWeight); + registry.fill(HIST("h3_subleading_fulljet_jetpTDet_FT0Mults_nef"), jetPt, collision.multFT0M(), nef, eventWeight); + } + } + } + PROCESS_SWITCH(FullJetSpectra, processMCDCollisionsWeightedWithMultiplicity, "Weighted MCD Collisions for Full Jets Multiplicity Studies", false); + + void processMBMCPCollisionsWithMultiplicity(aod::JetMcCollision const& mccollision, + JetTableMCPJoined const& jets, aod::JetParticles const& /*particles*/, + soa::SmallGroups const& collisions) + { + bool eventAccepted = false; + double weight = 1.0; + float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); + float mcpMult = 0.0f; + float mcpCent = 0.0f; + + registry.fill(HIST("hPartEventmultiplicityCounter"), 0.5); // allMcColl + if (std::fabs(mccollision.posZ()) > vertexZCut) { + return; + } + registry.fill(HIST("hPartEventmultiplicityCounter"), 1.5); // McCollWithVertexZ + + // outlier check: for every outlier jet, reject the whole event for (auto const& jet : jets) { - if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + if (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) { + registry.fill(HIST("hPartEventmultiplicityCounter"), 2.5); // RejectedPartCollWithOutliers + return; + } + } + + if (doMBGapTrigger && mccollision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + // Fill rejected MB events; + registry.fill(HIST("hPartEventmultiplicityCounter"), 3.5); // MBRejectedPartEvents + return; + } + + // Perform MC Collision matching, i.e. match the current MC collision to its associated reco (MCD) collision + // to get the corresponding FT0M component at the particle level + auto collisionspermcpjet = collisions.sliceBy(CollisionsPerMCPCollision, mccollision.globalIndex()); + registry.fill(HIST("hRecoMatchesPerMcCollisionMult"), collisionspermcpjet.size()); // for split vertices QA + + if (collisionspermcpjet.size() == 0 || collisionspermcpjet.size() < 1) { + registry.fill(HIST("hPartEventmultiplicityCounter"), 4.5); // RejectedPartCollForDetCollWithSize0or<1 + return; + } + registry.fill(HIST("hPartEventmultiplicityCounter"), 5.5); // AcceptedPartCollWithSize>1 + + for (auto const& collision : collisionspermcpjet) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { continue; } - if (jet.phi() < jetPhiMin || jet.phi() > jetPhiMax) { + if (doEMCALEventWorkaround) { + if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content + if (collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; + registry.fill(HIST("hPartEventmultiplicityCounter"), 6.5); // EMCreadoutDetEventsWithkTVXinEMC + } + } + } else { + if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; + registry.fill(HIST("hPartEventmultiplicityCounter"), 6.5); // EMCreadoutDetEventsWithkTVXinEMC + } + } + mcpMult += collision.multFT0M(); + mcpCent += collision.centFT0M(); + } // collision loop ends + + if (!eventAccepted) { + registry.fill(HIST("hPartEventmultiplicityCounter"), 7.5); // AllRejectedPartEventsAfterEMCEventSelection + return; + } + registry.fill(HIST("hPartEventmultiplicityCounter"), 8.5); // EMCAcceptedPartColl + registry.fill(HIST("hMCCollMatchedFT0Mult"), mcpMult); + registry.fill(HIST("hMCCollMatchedFT0Cent"), mcpCent); + + std::vector::iterator> selectedJets; + int nJetsThisEvent = 0; + + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) + continue; + if (jet.phi() < jetPhiMin || jet.phi() > jetPhiMax) + continue; + if (!isAcceptedPartJet(jet)) continue; + + selectedJets.push_back(jet); + nJetsThisEvent++; + } + // 1. Sort selected jets by pT before processing + std::sort(selectedJets.begin(), selectedJets.end(), + [](auto const& a, auto const& b) { return (*a).pt() > (*b).pt(); }); + + if (selectedJets.size() == 0) { // no jets = no leading jet + return; + } + + if (selectedJets.size() > 0) { + // Jet multiplicity per event + registry.fill(HIST("h_all_fulljet_Njets_part"), selectedJets.size(), 1.0); + + // Select Leading Jet for N_ch calculation (for every leading jet that is found). There's always one leading jet per event! + auto const& leadingJet = *selectedJets[0]; + auto const& leadingJetPt = leadingJet.pt(); // jet pT distribution of the leading jet + // std::cout << "Leading Jet pT: " << leadingJetPt << std::endl; + registry.fill(HIST("h_Leading_full_jet_pt_part"), leadingJetPt, 1.0); + registry.fill(HIST("h2_full_jet_leadingJetPt_vs_counts_part"), leadingJetPt, nJetsThisEvent, 1.0); + } + + if (selectedJets.size() > 1) { + auto const& subLeadingJet = *selectedJets[1]; + auto const& subLeadingJetPt = subLeadingJet.pt(); // jet pT distribution of the subleading jet i.e. 2nd leading jet + registry.fill(HIST("h_SubLeading_full_jet_pt_part"), subLeadingJetPt, 1.0); + registry.fill(HIST("h2_full_jet_subLeadingJetPt_vs_counts_part"), subLeadingJetPt, nJetsThisEvent, 1.0); + } + // Process ALL selected jets (not just leading) + for (size_t i = 0; i < selectedJets.size(); i++) { + auto const& jet = *selectedJets[i]; + float jetPt = jet.pt(); + bool isLeading = (i == 0); + bool isSubLeading = (i == 1 && selectedJets.size() > 1); // first sub-leading jet + + // Count charged particles(NCh) and neutral particles (NNe) for this jet + int numberOfChargedParticles = 0; + int numberOfNeutralParticles = 0; + float neutralEnergy = 0.0f; + for (const auto& constituent : jet.tracks_as()) { + auto pdgParticle = pdgDatabase->GetParticle(constituent.pdgCode()); + if (pdgParticle->Charge() == 0) { + numberOfNeutralParticles++; + neutralEnergy += constituent.e(); + } else { + numberOfChargedParticles++; + } + } + float nef = neutralEnergy / jet.energy(); + + // CASE 1: Fill histograms for ALL selected jets + registry.fill(HIST("h_all_fulljet_pt_part"), jetPt, 1.0); + registry.fill(HIST("h_all_fulljet_Nch_part"), numberOfChargedParticles, 1.0); + registry.fill(HIST("h_all_fulljet_Nne_part"), numberOfNeutralParticles, 1.0); + registry.fill(HIST("h_all_fulljet_NEF_part"), nef, 1.0); + registry.fill(HIST("h2_all_fulljet_jetpT_vs_FT0Mults_part"), jetPt, mcpMult, 1.0); + registry.fill(HIST("h2_all_fulljet_jetpT_vs_Nch_part"), jetPt, numberOfChargedParticles, 1.0); + registry.fill(HIST("h3_full_jet_jetpT_FT0Mults_nef_part"), jetPt, mcpMult, nef, 1.0); + + // CASE 2: Additional leading jet processing + if (isLeading) { + registry.fill(HIST("h_leading_fulljet_pt_part"), jetPt, 1.0); + registry.fill(HIST("h_leading_fulljet_Nch_part"), numberOfChargedParticles, 1.0); + registry.fill(HIST("h_leading_fulljet_Nne_part"), numberOfNeutralParticles, 1.0); + registry.fill(HIST("h_leading_fulljet_NEF_part"), nef, 1.0); + registry.fill(HIST("h2_leading_fulljet_jetpT_vs_FT0Mults_part"), jetPt, mcpMult, 1.0); + registry.fill(HIST("h2_leading_fulljet_jetpT_vs_Nch_part"), jetPt, numberOfChargedParticles, 1.0); + registry.fill(HIST("h3_leading_fulljet_jetpT_FT0Mults_nef_part"), jetPt, mcpMult, nef, 1.0); + } + + // CASE 3: Additional first sub-leading jet processing + if (isSubLeading) { + registry.fill(HIST("h_subleading_fulljet_pt_part"), jetPt, 1.0); + registry.fill(HIST("h_subleading_fulljet_Nch_part"), numberOfChargedParticles, 1.0); + registry.fill(HIST("h_subleading_fulljet_Nne_part"), numberOfNeutralParticles, 1.0); + registry.fill(HIST("h_subleading_fulljet_NEF_part"), nef, 1.0); + registry.fill(HIST("h2_subleading_fulljet_jetpT_vs_FT0Mults_part"), jetPt, mcpMult, 1.0); + registry.fill(HIST("h2_subleading_fulljet_jetpT_vs_Nch_part"), jetPt, numberOfChargedParticles, 1.0); + registry.fill(HIST("h3_subleading_fulljet_jetpT_FT0Mults_nef_part"), jetPt, mcpMult, nef, 1.0); } - if (!isAcceptedJet(jet)) { + } + } + PROCESS_SWITCH(FullJetSpectra, processMBMCPCollisionsWithMultiplicity, "MB MCP Collisions for Full Jets Multiplicity Studies", false); + + void processMBMCPCollisionsWeightedWithMultiplicity(aod::JetMcCollision const& mccollision, + JetTableMCPWeightedJoined const& jets, aod::JetParticles const& /*particles*/, + soa::SmallGroups const& collisions) + { + bool eventAccepted = false; + float pTHat = 10. / (std::pow(mccollision.weight(), 1.0 / pTHatExponent)); + float mcpMult = 0.0f; + float mcpCent = 0.0f; + + registry.fill(HIST("hPartEventmultiplicityCounter"), 0.5, mccollision.weight()); // allWeightedMcColl + if (std::fabs(mccollision.posZ()) > vertexZCut) { + return; + } + registry.fill(HIST("hPartEventmultiplicityCounter"), 1.5, mccollision.weight()); // WeightedMcCollWithVertexZ + + // outlier check: for every outlier jet, reject the whole event + for (auto const& jet : jets) { + if (jet.pt() > pTHatMaxMCP * pTHat || pTHat < pTHatAbsoluteMin) { + registry.fill(HIST("hPartEventmultiplicityCounter"), 2.5, mccollision.weight()); // RejectedWeightedPartCollWithOutliers + return; + } + } + + if (doMBGapTrigger && mccollision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { + // Fill rejected MB events; + registry.fill(HIST("hPartEventmultiplicityCounter"), 3.5, mccollision.weight()); // MBRejectedPartEvents + return; + } + + // Perform MC Collision matching, i.e. match the current MC collision to its associated reco (MCD) collision + // to get the corresponding FT0M component at the particle level + auto collisionspermcpjet = collisions.sliceBy(CollisionsPerMCPCollision, mccollision.globalIndex()); + registry.fill(HIST("hRecoMatchesPerMcCollisionMult"), collisionspermcpjet.size(), mccollision.weight()); // for split vertices QA + + if (collisionspermcpjet.size() == 0 || collisionspermcpjet.size() < 1) { + registry.fill(HIST("hPartEventmultiplicityCounter"), 4.5, mccollision.weight()); // RejectedWeightedPartCollForDetCollWithSize0or<1 + return; + } + registry.fill(HIST("hPartEventmultiplicityCounter"), 5.5, mccollision.weight()); // AcceptedWeightedPartCollWithSize>1 + + for (auto const& collision : collisionspermcpjet) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits, doMBGapTrigger)) { continue; } - registry.fill(HIST("h2_full_jet_jetpTDetVsFT0Mults"), jet.pt(), collision.multFT0M(), 1.0); + if (doEMCALEventWorkaround) { + if (collision.isEmcalReadout() && !collision.isAmbiguous()) { // i.e. EMCAL has a cell content + if (collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; + registry.fill(HIST("hPartEventmultiplicityCounter"), 6.5, mccollision.weight()); // EMCreadoutDetEventsWithkTVXinEMC + } + } + } else { + if (!collision.isAmbiguous() && jetderiveddatautilities::eventEMCAL(collision) && collision.alias_bit(kTVXinEMC)) { + eventAccepted = true; + registry.fill(HIST("hPartEventmultiplicityCounter"), 6.5, mccollision.weight()); // EMCreadoutDetEventsWithkTVXinEMC + } + } + mcpMult += collision.multFT0M(); + mcpCent += collision.centFT0M(); + } // collision loop ends - for (auto const& cluster : clusters) { - neutralEnergy += cluster.energy(); + if (!eventAccepted) { + registry.fill(HIST("hPartEventmultiplicityCounter"), 7.5, mccollision.weight()); // AllRejectedWeightedPartEventsAfterEMCEventSelection + return; + } + registry.fill(HIST("hPartEventmultiplicityCounter"), 8.5, mccollision.weight()); // EMCAcceptedWeightedPartColl + registry.fill(HIST("hMCCollMatchedFT0Mult"), mcpMult, mccollision.weight()); + registry.fill(HIST("hMCCollMatchedFT0Cent"), mcpCent, mccollision.weight()); + + std::vector::iterator> selectedJets; + int nJetsThisEvent = 0; + + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) + continue; + if (jet.phi() < jetPhiMin || jet.phi() > jetPhiMax) + continue; + if (!isAcceptedPartJet(jet)) + continue; + + selectedJets.push_back(jet); + nJetsThisEvent++; + } + // 1. Sort selected jets by pT before processing + std::sort(selectedJets.begin(), selectedJets.end(), + [](auto const& a, auto const& b) { return (*a).pt() > (*b).pt(); }); + + if (selectedJets.size() == 0) { // no jets = no leading jet + return; + } + + if (selectedJets.size() > 0) { + // Jet multiplicity per event + registry.fill(HIST("h_all_fulljet_Njets_part"), selectedJets.size(), mccollision.weight()); + + // Select Leading Jet for N_ch calculation (for every leading jet that is found). There's always one leading jet per event! + auto const& leadingJet = *selectedJets[0]; + auto const& leadingJetPt = leadingJet.pt(); // jet pT distribution of the leading jet + // std::cout << "Leading Jet pT: " << leadingJetPt << std::endl; + registry.fill(HIST("h_Leading_full_jet_pt_part"), leadingJetPt, mccollision.weight()); + registry.fill(HIST("h2_full_jet_leadingJetPt_vs_counts_part"), leadingJetPt, nJetsThisEvent, mccollision.weight()); + } + + if (selectedJets.size() > 1) { + auto const& subLeadingJet = *selectedJets[1]; + auto const& subLeadingJetPt = subLeadingJet.pt(); // jet pT distribution of the subleading jet i.e. 2nd leading jet + registry.fill(HIST("h_SubLeading_full_jet_pt_part"), subLeadingJetPt, mccollision.weight()); + registry.fill(HIST("h2_full_jet_subLeadingJetPt_vs_counts_part"), subLeadingJetPt, nJetsThisEvent, mccollision.weight()); + } + // Process ALL selected jets (not just leading) + for (size_t i = 0; i < selectedJets.size(); i++) { + auto const& jet = *selectedJets[i]; + float jetPt = jet.pt(); + bool isLeading = (i == 0); + bool isSubLeading = (i == 1 && selectedJets.size() > 1); // first sub-leading jet + + // Count charged particles(NCh) and neutral particles (NNe) for this jet + int numberOfChargedParticles = 0; + int numberOfNeutralParticles = 0; + float neutralEnergy = 0.0f; + for (const auto& constituent : jet.tracks_as()) { + auto pdgParticle = pdgDatabase->GetParticle(constituent.pdgCode()); + if (pdgParticle->Charge() == 0) { + numberOfNeutralParticles++; + neutralEnergy += constituent.e(); + } else { + numberOfChargedParticles++; + } + } + float nef = neutralEnergy / jet.energy(); + + // CASE 1: Fill histograms for ALL selected jets + registry.fill(HIST("h_all_fulljet_pt_part"), jetPt, mccollision.weight()); + registry.fill(HIST("h_all_fulljet_Nch_part"), numberOfChargedParticles, mccollision.weight()); + registry.fill(HIST("h_all_fulljet_Nne_part"), numberOfNeutralParticles, mccollision.weight()); + registry.fill(HIST("h_all_fulljet_NEF_part"), nef, mccollision.weight()); + registry.fill(HIST("h2_all_fulljet_jetpT_vs_FT0Mults_part"), jetPt, mcpMult, mccollision.weight()); + registry.fill(HIST("h2_all_fulljet_jetpT_vs_Nch_part"), jetPt, numberOfChargedParticles, mccollision.weight()); + registry.fill(HIST("h3_full_jet_jetpT_FT0Mults_nef_part"), jetPt, mcpMult, nef, mccollision.weight()); + + // CASE 2: Additional leading jet processing + if (isLeading) { + registry.fill(HIST("h_leading_fulljet_pt_part"), jetPt, mccollision.weight()); + registry.fill(HIST("h_leading_fulljet_Nch_part"), numberOfChargedParticles, mccollision.weight()); + registry.fill(HIST("h_leading_fulljet_Nne_part"), numberOfNeutralParticles, mccollision.weight()); + registry.fill(HIST("h_leading_fulljet_NEF_part"), nef, mccollision.weight()); + registry.fill(HIST("h2_leading_fulljet_jetpT_vs_FT0Mults_part"), jetPt, mcpMult, mccollision.weight()); + registry.fill(HIST("h2_leading_fulljet_jetpT_vs_Nch_part"), jetPt, numberOfChargedParticles, mccollision.weight()); + registry.fill(HIST("h3_leading_fulljet_jetpT_FT0Mults_nef_part"), jetPt, mcpMult, nef, mccollision.weight()); + } + + // CASE 3: Additional first sub-leading jet processing + if (isSubLeading) { + registry.fill(HIST("h_subleading_fulljet_pt_part"), jetPt, mccollision.weight()); + registry.fill(HIST("h_subleading_fulljet_Nch_part"), numberOfChargedParticles, mccollision.weight()); + registry.fill(HIST("h_subleading_fulljet_Nne_part"), numberOfNeutralParticles, mccollision.weight()); + registry.fill(HIST("h_subleading_fulljet_NEF_part"), nef, mccollision.weight()); + registry.fill(HIST("h2_subleading_fulljet_jetpT_vs_FT0Mults_part"), jetPt, mcpMult, mccollision.weight()); + registry.fill(HIST("h2_subleading_fulljet_jetpT_vs_Nch_part"), jetPt, numberOfChargedParticles, mccollision.weight()); + registry.fill(HIST("h3_subleading_fulljet_jetpT_FT0Mults_nef_part"), jetPt, mcpMult, nef, mccollision.weight()); } - auto nef = neutralEnergy / jet.energy(); - registry.fill(HIST("h3_full_jet_jetpTDet_FT0Mults_nef"), jet.pt(), collision.multFT0M(), nef, 1.0); } } - PROCESS_SWITCH(FullJetSpectra, processMBCollisionsDATAWithMultiplicity, "MB DATA Collisions for Full Jets Multiplicity Studies", false); + PROCESS_SWITCH(FullJetSpectra, processMBMCPCollisionsWeightedWithMultiplicity, "MB MCP Weighted Collisions for Full Jets Multiplicity Studies", false); }; // struct diff --git a/PWGJE/Tasks/jetFinderDsQA.cxx b/PWGJE/Tasks/jetFinderDsQA.cxx new file mode 100644 index 00000000000..e04915fb975 --- /dev/null +++ b/PWGJE/Tasks/jetFinderDsQA.cxx @@ -0,0 +1,37 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// jet finder Ds charged QA task +// +/// \author Nima Zardoshti + +#include "PWGJE/Tasks/jetFinderHFQA.cxx" + +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetSubtraction.h" + +#include +#include +#include +#include + +#include + +using JetFinderDsQATask = JetFinderHFQATask; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + tasks.emplace_back(adaptAnalysisTask(cfgc, + SetDefaultProcesses{}, + TaskName{"jet-finder-charged-ds-qa"})); + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/Tasks/jetFinderHFQA.cxx b/PWGJE/Tasks/jetFinderHFQA.cxx index fee889a62ea..b82a5943265 100644 --- a/PWGJE/Tasks/jetFinderHFQA.cxx +++ b/PWGJE/Tasks/jetFinderHFQA.cxx @@ -493,10 +493,12 @@ struct JetFinderHFQATask { PresliceOptional> perD0CandidateTracks = aod::bkgd0::candidateId; PresliceOptional> perDplusCandidateTracks = aod::bkgdplus::candidateId; + PresliceOptional> perDsCandidateTracks = aod::bkgds::candidateId; PresliceOptional> perDstarCandidateTracks = aod::bkgdstar::candidateId; PresliceOptional> perLcCandidateTracks = aod::bkglc::candidateId; PresliceOptional> perB0CandidateTracks = aod::bkgb0::candidateId; PresliceOptional> perBplusCandidateTracks = aod::bkgbplus::candidateId; + PresliceOptional> perXicToXiPiPiCandidateTracks = aod::bkgxictoxipipi::candidateId; PresliceOptional> perDielectronCandidateTracks = aod::bkgdielectron::candidateId; template @@ -1523,7 +1525,7 @@ struct JetFinderHFQATask { } for (auto const& candidate : candidates) { - for (auto const& track : jetcandidateutilities::slicedPerCandidate(tracks, candidate, perD0CandidateTracks, perDplusCandidateTracks, perDstarCandidateTracks, perLcCandidateTracks, perB0CandidateTracks, perBplusCandidateTracks, perDielectronCandidateTracks)) { + for (auto const& track : jetcandidateutilities::slicedPerCandidate(tracks, candidate, perD0CandidateTracks, perDplusCandidateTracks, perDsCandidateTracks, perDstarCandidateTracks, perLcCandidateTracks, perB0CandidateTracks, perBplusCandidateTracks, perXicToXiPiPiCandidateTracks, perDielectronCandidateTracks)) { registry.fill(HIST("h3_centrality_track_pt_track_phi_eventwiseconstituentsubtracted"), collision.centFT0M(), track.pt(), track.phi()); registry.fill(HIST("h3_centrality_track_pt_track_eta_eventwiseconstituentsubtracted"), collision.centFT0M(), track.pt(), track.eta()); registry.fill(HIST("h3_track_pt_track_eta_track_phi_eventwiseconstituentsubtracted"), track.pt(), track.eta(), track.phi()); diff --git a/PWGJE/Tasks/jetFinderXicToXiPiPiQA.cxx b/PWGJE/Tasks/jetFinderXicToXiPiPiQA.cxx new file mode 100644 index 00000000000..a86a40f0d67 --- /dev/null +++ b/PWGJE/Tasks/jetFinderXicToXiPiPiQA.cxx @@ -0,0 +1,37 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// jet finder XicToXiPiPi charged QA task +// +/// \author Nima Zardoshti + +#include "PWGJE/Tasks/jetFinderHFQA.cxx" + +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetSubtraction.h" + +#include +#include +#include +#include + +#include + +using JetFinderXicToXiPiPiQATask = JetFinderHFQATask; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + tasks.emplace_back(adaptAnalysisTask(cfgc, + SetDefaultProcesses{}, + TaskName{"jet-finder-charged-xictoxipipi-qa"})); + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/Tasks/jetFragmentation.cxx b/PWGJE/Tasks/jetFragmentation.cxx index ce9bfa6fcb0..5a6104ad872 100644 --- a/PWGJE/Tasks/jetFragmentation.cxx +++ b/PWGJE/Tasks/jetFragmentation.cxx @@ -90,9 +90,9 @@ struct JetFragmentation { Configurable> ptBinsAntiLambda{"ptBinsAntiLambda", {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 10.0, 15.0, 20.0, 25.0}, "AntiLambda pt Vals"}; // NB: these must be one shorter than ptbin vectors! - Configurable> purityK0S{"purityK0S", {0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9}, "K0S purity per pt bin"}; - Configurable> purityLambda{"purityLambda", {0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9}, "Lambda purity per pt bin"}; - Configurable> purityAntiLambda{"purityAntiLambda", {0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9}, "AntiLambda purity per pt bin"}; + Configurable> signalProbK0S{"signalProbK0S", {0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9}, "K0S signal probability per pt bin"}; + Configurable> signalProbLambda{"signalProbLambda", {0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9}, "Lambda signal probability per pt bin"}; + Configurable> signalProbAntiLambda{"signalProbAntiLambda", {0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9}, "AntiLambda signal probability per pt bin"}; Configurable vertexZCut{"vertexZCut", 10.f, "vertex z cut"}; Configurable v0EtaMin{"v0EtaMin", -0.75, "minimum data V0 eta"}; @@ -786,8 +786,15 @@ struct JetFragmentation { registry.add("matching/jets/V0/missJetPtV0TrackProj", "Misses", HistType::kTH2D, {partJetPtAxis, partZAxis}, true); // Matching - Matched K0S - registry.add("matching/jets/V0/matchDetJetPtK0STrackProjPartJetPtK0STrackProj", "Matched", HistType::kTHnSparseD, {detJetPtAxis, detZAxis, partJetPtAxis, partZAxis}, true); - registry.add("matching/jets/V0/partJetPtK0SPtDetJetPtK0SPt", "matched jet Pt, K_{S}^{0} Pt", HistType::kTHnSparseD, {partJetPtAxis, v0PtAxis, detJetPtAxis, v0PtAxis}, true); + registry.add("matching/jets/V0/partJetPtK0SPtDetJetPtK0SPt", "Matched Pt and pt", HistType::kTHnSparseD, {partJetPtAxis, v0PtAxis, detJetPtAxis, v0PtAxis}, true); + registry.add("matching/jets/V0/partJetPtK0STrackProjDetJetPtK0STrackProj", "Matched pt and z", HistType::kTHnSparseD, {partJetPtAxis, partZAxis, detJetPtAxis, detZAxis}, true); + + registry.add("matching/jets/V0/partJetPtK0SPtDetJetPtK0SPtRightCollision", "Matched Pt, right collision", HistType::kTHnSparseD, {partJetPtAxis, v0PtAxis, detJetPtAxis, v0PtAxis}, true); + registry.add("matching/jets/V0/partJetPtK0STrackProjDetJetPtK0STrackProjRightCollision", "Matched pt and z, right collision", HistType::kTHnSparseD, {partJetPtAxis, partZAxis, detJetPtAxis, detZAxis}, true); + + registry.add("matching/jets/V0/partJetPtK0SPtDetJetPtK0SPtWrongCollision", "Matched Pt, wrong collision", HistType::kTHnSparseD, {partJetPtAxis, v0PtAxis, detJetPtAxis, v0PtAxis}, true); + registry.add("matching/jets/V0/partJetPtK0STrackProjDetJetPtK0STrackProjWrongCollision", "Matched pt and z, wrong collision", HistType::kTHnSparseD, {partJetPtAxis, partZAxis, detJetPtAxis, detZAxis}, true); + // Matching - Matched K0S: pt registry.add("matching/jets/V0/partJetPtK0SPtDetJetPtK0SPtCtauLambda", "matched jet Pt, K^{0}_{S} Pt, Ctau #Lambda^{0}", HistType::kTHnSparseD, {partJetPtAxis, v0PtAxis, detJetPtAxis, v0PtAxis, v0CtauAxis}, true); registry.add("matching/jets/V0/partJetPtK0SPtDetJetPtK0SPtCtauAntiLambda", "matched jet Pt, K^{0}_{S} Pt, Ctau #bar{#Lambda}^{0}", HistType::kTHnSparseD, {partJetPtAxis, v0PtAxis, detJetPtAxis, v0PtAxis, v0CtauAxis}, true); @@ -833,8 +840,15 @@ struct JetFragmentation { registry.add("matching/jets/V0/missJetPtK0STrackProj", "Misses", HistType::kTH2D, {partJetPtAxis, partZAxis}, true); // Matching - Matched Lambda - registry.add("matching/jets/V0/matchDetJetPtLambdaTrackProjPartJetPtLambdaTrackProj", "Matched", HistType::kTHnSparseD, {detJetPtAxis, detZAxis, partJetPtAxis, partZAxis}, true); - registry.add("matching/jets/V0/partJetPtLambdaPtDetJetPtLambdaPt", "matched jet Pt, #Lambda^{0} Pt", HistType::kTHnSparseD, {partJetPtAxis, v0PtAxis, detJetPtAxis, v0PtAxis}, true); + registry.add("matching/jets/V0/partJetPtLambdaPtDetJetPtLambdaPt", "matched Pt", HistType::kTHnSparseD, {partJetPtAxis, v0PtAxis, detJetPtAxis, v0PtAxis}, true); + registry.add("matching/jets/V0/partJetPtLambdaTrackProjDetJetPtLambdaTrackProj", "Matched pt and z", HistType::kTHnSparseD, {partJetPtAxis, partZAxis, detJetPtAxis, detZAxis}, true); + + registry.add("matching/jets/V0/partJetPtLambdaPtDetJetPtLambdaPtRightCollision", "matched Pt, right collision", HistType::kTHnSparseD, {partJetPtAxis, v0PtAxis, detJetPtAxis, v0PtAxis}, true); + registry.add("matching/jets/V0/partJetPtLambdaTrackProjDetJetPtLambdaTrackProjRightCollision", "Matched pt and z, right collision", HistType::kTHnSparseD, {partJetPtAxis, partZAxis, detJetPtAxis, detZAxis}, true); + + registry.add("matching/jets/V0/partJetPtLambdaPtDetJetPtLambdaPtWrongCollision", "matched Pt, Wrong collision", HistType::kTHnSparseD, {partJetPtAxis, v0PtAxis, detJetPtAxis, v0PtAxis}, true); + registry.add("matching/jets/V0/partJetPtLambdaTrackProjDetJetPtLambdaTrackProjWrongCollision", "Matched pt and z, Wrong collision", HistType::kTHnSparseD, {partJetPtAxis, partZAxis, detJetPtAxis, detZAxis}, true); + // Matching - Matched Lambda: pt registry.add("matching/jets/V0/partJetPtLambdaPtDetJetPtLambdaPtCtauK0S", "matched jet Pt, #{K}^{0}_{S} Pt, Ctau #{K}^{0}_{S}", HistType::kTHnSparseD, {partJetPtAxis, v0PtAxis, detJetPtAxis, v0PtAxis, v0CtauAxis}, true); registry.add("matching/jets/V0/partJetPtLambdaPtDetJetPtLambdaPtCtauLambda", "matched jet Pt, #Lambda^{0} Pt, Ctau #Lambda^{0}", HistType::kTHnSparseD, {partJetPtAxis, v0PtAxis, detJetPtAxis, v0PtAxis, v0CtauAxis}, true); @@ -883,8 +897,15 @@ struct JetFragmentation { registry.add("matching/jets/V0/missJetPtLambdaTrackProj", "Misses", HistType::kTH2D, {partJetPtAxis, partZAxis}, true); // Matching - Matched AntiLambda - registry.add("matching/jets/V0/matchDetJetPtAntiLambdaTrackProjPartJetPtAntiLambdaTrackProj", "Matched", HistType::kTHnSparseD, {detJetPtAxis, detZAxis, partJetPtAxis, partZAxis}, true); - registry.add("matching/jets/V0/partJetPtAntiLambdaPtDetJetPtAntiLambdaPt", "matched jet Pt, #bar{#Lambda}^{0} Pt", HistType::kTHnSparseD, {partJetPtAxis, v0PtAxis, detJetPtAxis, v0PtAxis}, true); + registry.add("matching/jets/V0/partJetPtAntiLambdaPtDetJetPtAntiLambdaPt", "matched Pt", HistType::kTHnSparseD, {partJetPtAxis, v0PtAxis, detJetPtAxis, v0PtAxis}, true); + registry.add("matching/jets/V0/partJetPtAntiLambdaTrackProjDetJetPtAntiLambdaTrackProj", "Matched pt and z", HistType::kTHnSparseD, {partJetPtAxis, partZAxis, detJetPtAxis, detZAxis}, true); + + registry.add("matching/jets/V0/partJetPtAntiLambdaPtDetJetPtAntiLambdaPtRightCollision", "matched Pt, right collision", HistType::kTHnSparseD, {partJetPtAxis, v0PtAxis, detJetPtAxis, v0PtAxis}, true); + registry.add("matching/jets/V0/partJetPtAntiLambdaTrackProjDetJetPtAntiLambdaTrackProjRightCollision", "Matched pt and z, right collision", HistType::kTHnSparseD, {partJetPtAxis, partZAxis, detJetPtAxis, detZAxis}, true); + + registry.add("matching/jets/V0/partJetPtAntiLambdaPtDetJetPtAntiLambdaPtWrongCollision", "matched Pt, Wrong collision", HistType::kTHnSparseD, {partJetPtAxis, v0PtAxis, detJetPtAxis, v0PtAxis}, true); + registry.add("matching/jets/V0/partJetPtAntiLambdaTrackProjDetJetPtAntiLambdaTrackProjWrongCollision", "Matched pt and z, Wrong collision", HistType::kTHnSparseD, {partJetPtAxis, partZAxis, detJetPtAxis, detZAxis}, true); + // Matching - Matched AntiLambda: pt registry.add("matching/jets/V0/partJetPtAntiLambdaPtDetJetPtAntiLambdaPtCtauK0S", "matched jet Pt, #{K}^{0}_{S} Pt, Ctau #{K}^{0}_{S}", HistType::kTHnSparseD, {partJetPtAxis, v0PtAxis, detJetPtAxis, v0PtAxis, v0CtauAxis}, true); registry.add("matching/jets/V0/partJetPtAntiLambdaPtDetJetPtAntiLambdaPtCtauLambda", "matched jet Pt, #bar{#Lambda}^{0} Pt, Ctau #Lambda^{0}", HistType::kTHnSparseD, {partJetPtAxis, v0PtAxis, detJetPtAxis, v0PtAxis, v0CtauAxis}, true); @@ -1106,17 +1127,17 @@ struct JetFragmentation { if (v0.isK0SCandidate()) { int ptBin = getPtBin(v0.pt(), ptBinsK0S); if (ptBin >= 0) { - purity = purityK0S->at(ptBin); + purity = signalProbK0S->at(ptBin); } } else if (v0.isLambdaCandidate()) { int ptBin = getPtBin(v0.pt(), ptBinsLambda); if (ptBin >= 0) { - purity = purityLambda->at(ptBin); + purity = signalProbLambda->at(ptBin); } } else if (v0.isAntiLambdaCandidate()) { int ptBin = getPtBin(v0.pt(), ptBinsAntiLambda); if (ptBin >= 0) { - purity = purityAntiLambda->at(ptBin); + purity = signalProbAntiLambda->at(ptBin); } } return purity; @@ -1541,7 +1562,9 @@ struct JetFragmentation { double conePt[nCones] = {0., 0.}; int nV0sinCone[nCones] = {0, 0}; for (const auto& v0 : v0s) { - // Need to check if v0 passed jet finder selection/preselector cuts + if (v0.isRejectedCandidate()) + continue; + bool v0InCones = false; double dEta = v0.eta() - jet.eta(); double dPhi[nCones] = {RecoDecay::constrainAngle(v0.phi() - conePhi[0], -constants::math::PI), @@ -2123,6 +2146,7 @@ struct JetFragmentation { template // Reconstructed signal for in-jet V0s void fillMatchingV0FragHistograms(CollisionType const& collision, DetJetType const& detJet, PartJetType const& partJet, V0Type const& v0, ParticleType const& particle, double weight = 1.) { + bool correctCollision = (collision.mcCollisionId() == particle.mcCollisionId()); double detTrackProj = getMomFrac(detJet, v0); double partTrackProj = getMomFrac(partJet, particle); @@ -2158,8 +2182,15 @@ struct JetFragmentation { registry.fill(HIST("matching/jets/V0/partJetPtV0TrackProjDetJetPtV0TrackProjDCAd"), partJet.pt(), partTrackProj, detJet.pt(), detTrackProj, v0.dcaV0daughters(), weight); if (std::abs(particle.pdgCode()) == PDG_t::kK0Short) { // K0S - registry.fill(HIST("matching/jets/V0/matchDetJetPtK0STrackProjPartJetPtK0STrackProj"), detJet.pt(), detTrackProj, partJet.pt(), partTrackProj, weight); registry.fill(HIST("matching/jets/V0/partJetPtK0SPtDetJetPtK0SPt"), partJet.pt(), particle.pt(), detJet.pt(), v0.pt(), weight); + registry.fill(HIST("matching/jets/V0/partJetPtK0STrackProjDetJetPtK0STrackProj"), partJet.pt(), partTrackProj, detJet.pt(), detTrackProj, weight); + if (correctCollision) { + registry.fill(HIST("matching/jets/V0/partJetPtK0SPtDetJetPtK0SPtRightCollision"), partJet.pt(), particle.pt(), detJet.pt(), v0.pt(), weight); + registry.fill(HIST("matching/jets/V0/partJetPtK0STrackProjDetJetPtK0STrackProjRightCollision"), partJet.pt(), partTrackProj, detJet.pt(), detTrackProj, weight); + } else { + registry.fill(HIST("matching/jets/V0/partJetPtK0SPtDetJetPtK0SPtWrongCollision"), partJet.pt(), particle.pt(), detJet.pt(), v0.pt(), weight); + registry.fill(HIST("matching/jets/V0/partJetPtK0STrackProjDetJetPtK0STrackProjWrongCollision"), partJet.pt(), partTrackProj, detJet.pt(), detTrackProj, weight); + } registry.fill(HIST("matching/jets/V0/partJetPtK0SPtDetJetPtK0SPtCtauLambda"), partJet.pt(), particle.pt(), detJet.pt(), v0.pt(), ctauLambda, weight); registry.fill(HIST("matching/jets/V0/partJetPtK0SPtDetJetPtK0SPtCtauAntiLambda"), partJet.pt(), particle.pt(), detJet.pt(), v0.pt(), ctauAntiLambda, weight); @@ -2185,8 +2216,15 @@ struct JetFragmentation { registry.fill(HIST("matching/jets/V0/partJetPtK0STrackProjDetJetPtK0STrackProjDCAposneg"), partJet.pt(), partTrackProj, detJet.pt(), detTrackProj, v0.dcapostopv(), v0.dcanegtopv(), weight); registry.fill(HIST("matching/jets/V0/partJetPtK0STrackProjDetJetPtK0STrackProjDCAd"), partJet.pt(), partTrackProj, detJet.pt(), detTrackProj, v0.dcaV0daughters(), weight); } else if (particle.pdgCode() == PDG_t::kLambda0) { // Lambda - registry.fill(HIST("matching/jets/V0/matchDetJetPtLambdaTrackProjPartJetPtLambdaTrackProj"), detJet.pt(), detTrackProj, partJet.pt(), partTrackProj, weight); registry.fill(HIST("matching/jets/V0/partJetPtLambdaPtDetJetPtLambdaPt"), partJet.pt(), particle.pt(), detJet.pt(), v0.pt(), weight); + registry.fill(HIST("matching/jets/V0/partJetPtLambdaTrackProjDetJetPtLambdaTrackProj"), partJet.pt(), partTrackProj, detJet.pt(), detTrackProj, weight); + if (correctCollision) { + registry.fill(HIST("matching/jets/V0/partJetPtLambdaPtDetJetPtLambdaPtRightCollision"), partJet.pt(), particle.pt(), detJet.pt(), v0.pt(), weight); + registry.fill(HIST("matching/jets/V0/partJetPtLambdaTrackProjDetJetPtLambdaTrackProjRightCollision"), partJet.pt(), partTrackProj, detJet.pt(), detTrackProj, weight); + } else { + registry.fill(HIST("matching/jets/V0/partJetPtLambdaPtDetJetPtLambdaPtWrongCollision"), partJet.pt(), particle.pt(), detJet.pt(), v0.pt(), weight); + registry.fill(HIST("matching/jets/V0/partJetPtLambdaTrackProjDetJetPtLambdaTrackProjWrongCollision"), partJet.pt(), partTrackProj, detJet.pt(), detTrackProj, weight); + } registry.fill(HIST("matching/jets/V0/partJetPtLambdaPtDetJetPtLambdaPtCtauLambda"), partJet.pt(), particle.pt(), detJet.pt(), v0.pt(), ctauLambda, weight); registry.fill(HIST("matching/jets/V0/partJetPtLambdaPtDetJetPtLambdaPtCtauAntiLambda"), partJet.pt(), particle.pt(), detJet.pt(), v0.pt(), ctauAntiLambda, weight); @@ -2217,8 +2255,15 @@ struct JetFragmentation { registry.fill(HIST("matching/jets/V0/partJetPtLambdaPtDetJetPtLambdaPtLambdaReflection"), partJet.pt(), particle.pt(), detJet.pt(), v0.pt(), v0.mK0Short(), v0.mLambda(), v0.mAntiLambda(), reflectedMass, weight); registry.fill(HIST("matching/jets/V0/partJetPtLambdaTrackProjDetJetPtLambdaTrackProjLambdaReflection"), partJet.pt(), partTrackProj, detJet.pt(), detTrackProj, v0.mK0Short(), v0.mLambda(), v0.mAntiLambda(), reflectedMass, weight); } else if (particle.pdgCode() == PDG_t::kLambda0Bar) { // AntiLambda - registry.fill(HIST("matching/jets/V0/matchDetJetPtAntiLambdaTrackProjPartJetPtAntiLambdaTrackProj"), detJet.pt(), detTrackProj, partJet.pt(), partTrackProj, weight); registry.fill(HIST("matching/jets/V0/partJetPtAntiLambdaPtDetJetPtAntiLambdaPt"), partJet.pt(), particle.pt(), detJet.pt(), v0.pt(), weight); + registry.fill(HIST("matching/jets/V0/partJetPtAntiLambdaTrackProjDetJetPtAntiLambdaTrackProj"), partJet.pt(), partTrackProj, detJet.pt(), detTrackProj, weight); + if (correctCollision) { + registry.fill(HIST("matching/jets/V0/partJetPtAntiLambdaPtDetJetPtAntiLambdaPtRightCollision"), partJet.pt(), particle.pt(), detJet.pt(), v0.pt(), weight); + registry.fill(HIST("matching/jets/V0/partJetPtAntiLambdaTrackProjDetJetPtAntiLambdaTrackProjRightCollision"), partJet.pt(), partTrackProj, detJet.pt(), detTrackProj, weight); + } else { + registry.fill(HIST("matching/jets/V0/partJetPtAntiLambdaPtDetJetPtAntiLambdaPtWrongCollision"), partJet.pt(), particle.pt(), detJet.pt(), v0.pt(), weight); + registry.fill(HIST("matching/jets/V0/partJetPtAntiLambdaTrackProjDetJetPtAntiLambdaTrackProjWrongCollision"), partJet.pt(), partTrackProj, detJet.pt(), detTrackProj, weight); + } registry.fill(HIST("matching/jets/V0/partJetPtAntiLambdaPtDetJetPtAntiLambdaPtCtauLambda"), partJet.pt(), particle.pt(), detJet.pt(), v0.pt(), ctauLambda, weight); registry.fill(HIST("matching/jets/V0/partJetPtAntiLambdaPtDetJetPtAntiLambdaPtCtauAntiLambda"), partJet.pt(), particle.pt(), detJet.pt(), v0.pt(), ctauAntiLambda, weight); @@ -2650,20 +2695,20 @@ struct JetFragmentation { if (v0.isRejectedCandidate()) continue; - float purity = getV0SignalProb(v0); + float signalProb = getV0SignalProb(v0); nV0inJet++; - wV0inJet += purity; + wV0inJet += signalProb; if (v0.isK0SCandidate()) { nK0SinJet++; - wK0SinJet += purity; + wK0SinJet += signalProb; } if (v0.isLambdaCandidate()) { nLambdainJet++; - wLambdainJet += purity; + wLambdainJet += signalProb; } if (v0.isAntiLambdaCandidate()) { nAntiLambdainJet++; - wAntiLambdainJet += purity; + wAntiLambdainJet += signalProb; } fillDataV0FragHistograms(jcoll, jet, v0); diff --git a/PWGJE/Tasks/jetHadronRecoil.cxx b/PWGJE/Tasks/jetHadronRecoil.cxx index 211e7c1f7ed..d327fa277b6 100644 --- a/PWGJE/Tasks/jetHadronRecoil.cxx +++ b/PWGJE/Tasks/jetHadronRecoil.cxx @@ -72,15 +72,15 @@ struct JetHadronRecoil { Configurable ptTTsigMax{"ptTTsigMax", 50, "signal maximum trigger track pt"}; Configurable fracSig{"fracSig", 0.9, "fraction of events to use for signal"}; Configurable jetR{"jetR", 0.4, "jet resolution parameter"}; - Configurable pTHatExponent{"pTHatExponent", 4.0, "exponent of the event weight for the calculation of pTHat"}; Configurable pTHatMaxMCD{"pTHatMaxMCD", 999.0, "maximum fraction of hard scattering for jet acceptance in detector MC"}; Configurable pTHatMaxMCP{"pTHatMaxMCP", 999.0, "maximum fraction of hard scattering for jet acceptance in particle MC"}; Configurable pTHatTrackMaxMCD{"pTHatTrackMaxMCD", 999.0, "maximum fraction of hard scattering for track acceptance in detector MC"}; Configurable pTHatTrackMaxMCP{"pTHatTrackMaxMCP", 999.0, "maximum fraction of hard scattering for track acceptance in particle MC"}; + Configurable pTHatMinEvent{"pTHatMinEvent", -1.0, "minimum absolute event pTHat"}; Configurable rhoReferenceShift{"rhoReferenceShift", 0.0, "shift in rho calculated in reference events for consistency with signal events"}; Configurable triggerMasks{"triggerMasks", "", "possible JE Trigger masks: fJetChLowPt,fJetChHighPt,fTrackLowPt,fTrackHighPt,fJetD0ChLowPt,fJetD0ChHighPt,fJetLcChLowPt,fJetLcChHighPt,fEMCALReadout,fJetFullHighPt,fJetFullLowPt,fJetNeutralHighPt,fJetNeutralLowPt,fGammaVeryHighPtEMCAL,fGammaVeryHighPtDCAL,fGammaHighPtEMCAL,fGammaHighPtDCAL,fGammaLowPtEMCAL,fGammaLowPtDCAL,fGammaVeryLowPtEMCAL,fGammaVeryLowPtDCAL"}; Configurable skipMBGapEvents{"skipMBGapEvents", false, "flag to choose to reject min. bias gap events; jet-level rejection applied at the jet finder level, here rejection is applied for collision and track process functions"}; - Configurable wtaMethod{"wtaMethod", 1, "method for WTA axis definition: 0 = matching closest WTA jet (incorrect), 1 = recluster original jet"}; + Configurable outlierRejectEvent{"outlierRejectEvent", true, "where outliers are found, reject event (true) or just reject the single track/jet (false)"}; Preslice> partJetsPerCollision = aod::jet::mcCollisionId; @@ -128,7 +128,7 @@ struct JetHadronRecoil { {"hEtaTrack", "Track #eta;#eta;entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}}, {"hPhiTrack", "Track #phi;#phi;entries", {HistType::kTH1F, {{100, 0.0, o2::constants::math::TwoPI}}}}, {"hTrack3D", "3D tracks histogram;p_{T};#eta;#phi", {HistType::kTH3F, {{200, 0, 200}, {100, -1.0, 1.0}, {100, 0.0, o2::constants::math::TwoPI}}}}, - {"hPtTrackPtHard", "Track p_{T} vs #hat{p};p_{T};#frac{p_{T}}{#hat{p}}", {HistType::kTH2F, {{200, 0, 200}, {20, 0, 5}}}}, + {"hPtTrackPtHard", "Tracks vs pThard;#frac{p_{T}}{#hat{p}};p_{T}", {HistType::kTH2F, {{20, 0, 5}, {200, 0, 200}}}}, {"hConstituents3D", "3D constituents histogram;p_{T};#eta;#phi", {HistType::kTH3F, {{200, 0, 200}, {100, -1.0, 1.0}, {100, 0.0, o2::constants::math::TwoPI}}}}, {"hReferencePtDPhi", "jet p_{T} vs DPhi;#Delta#phi;p_{T,jet}", {HistType::kTH2F, {{100, 0, o2::constants::math::TwoPI}, {500, -100, 400}}}}, {"hReferencePtDPhiShifts", "rho shifts;#Delta#phi;p_{T,jet};shifts", {HistType::kTH3F, {{100, 0, o2::constants::math::TwoPI}, {500, -100, 400}, {20, 0.0, 2.0}}}}, @@ -145,6 +145,8 @@ struct JetHadronRecoil { {"hJetEta", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}}, {"hJetPhi", "jet #phi;#phi_{jet};entries", {HistType::kTH1F, {{100, 0.0, o2::constants::math::TwoPI}}}}, {"hJet3D", "3D jet distribution;p_{T};#eta;#phi", {HistType::kTH3F, {{500, -100, 400}, {100, -1.0, 1.0}, {100, 0.0, o2::constants::math::TwoPI}}}}, + {"hTracksvsJets", "comparing leading tracks and jets;p_{T,track};p_{T,jet};#hat{p}", {HistType::kTH3F, {{200, 0, 200}, {500, -100, 400}, {195, 5, 200}}}}, + {"hPartvsJets", "comparing leading particles and jets;p_{T,part};p_{T,jet};#hat{p}", {HistType::kTH3F, {{200, 0, 200}, {500, -100, 400}, {195, 5, 200}}}}, {"hPtPart", "Particle p_{T};p_{T};entries", {HistType::kTH1F, {{200, 0, 200}}}}, {"hEtaPart", "Particle #eta;#eta;entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}}, {"hPhiPart", "Particle #phi;#phi;entries", {HistType::kTH1F, {{100, 0.0, o2::constants::math::TwoPI}}}}, @@ -176,7 +178,7 @@ struct JetHadronRecoil { {"hPtMatched1d", "p_{T} matching 1d;p_{T,part}", {HistType::kTH1F, {{400, 0, 400}}}}, {"hDeltaRMatched1d", "#DeltaR matching 1d;#DeltaR_{part}", {HistType::kTH1F, {dRAxisPart}}}, {"hPtResolution", "p_{T} resolution;p_{T,part};Relative Resolution", {HistType::kTH2F, {{400, 0, 400}, {1000, -5.0, 5.0}}}}, - {"hPhiResolution", "#phi resolution;#p{T,part};Resolution", {HistType::kTH2F, {{400, 0, 400}, {1000, -7.0, 7.0}}}}, + {"hPhiResolution", "#phi resolution;#p_{T,part};Resolution", {HistType::kTH2F, {{400, 0, 400}, {1000, -7.0, 7.0}}}}, {"hDeltaRResolution", "#DeltaR Resolution;p_{T,part};Resolution", {HistType::kTH2F, {{400, 0, 400}, {1000, -0.15, 0.15}}}}, {"hFullMatching", "Full 6D matching;p_{T,det};p_{T,part};#phi_{det};#phi_{part};#DeltaR_{det};#DeltaR_{part}", {HistType::kTHnSparseD, {ptAxisDet, ptAxisPart, phiAxisDet, phiAxisPart, dRAxisDet, dRAxisPart}}}}}; @@ -203,8 +205,8 @@ struct JetHadronRecoil { jetReclusterer.recombScheme = fastjet::WTA_pt_scheme; } - template - void fillHistograms(T const& jets, W const& jetsWTA, U const& tracks, float weight = 1.0, float rho = 0.0) + template + void fillHistograms(T const& jets, U const& tracks, float weight = 1.0, float rho = 0.0, float pTHat = 999.0) { bool isSigCol; std::vector phiTTAr; @@ -214,7 +216,8 @@ struct JetHadronRecoil { int trigNumber = 0; int nTT = 0; double leadingPT = 0; - float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); + double leadingTrackPt = 0; + double leadingJetPt = 0; float rhoReference = rho + rhoReferenceShift; float dice = rand->Rndm(); @@ -227,8 +230,15 @@ struct JetHadronRecoil { if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { continue; } + if (track.pt() > leadingTrackPt) { + leadingTrackPt = track.pt(); + } if (track.pt() > pTHatTrackMaxMCD * pTHat) { - return; + if (outlierRejectEvent) { + return; + } else { + continue; + } } if (isSigCol && track.pt() < ptTTsigMax && track.pt() > ptTTsigMin) { phiTTAr.push_back(track.phi()); @@ -246,7 +256,7 @@ struct JetHadronRecoil { registry.fill(HIST("hEtaTrack"), track.eta(), weight); registry.fill(HIST("hPhiTrack"), track.phi(), weight); registry.fill(HIST("hTrack3D"), track.pt(), track.eta(), track.phi(), weight); - registry.fill(HIST("hPtTrackPtHard"), track.pt(), track.pt() / pTHat, weight); + registry.fill(HIST("hPtTrackPtHard"), track.pt() / pTHat, track.pt(), weight); } if (nTT > 0) { @@ -269,10 +279,16 @@ struct JetHadronRecoil { registry.fill(HIST("hReferenceTriggersPtHard"), ptTT / pTHat, weight); } } - for (const auto& jet : jets) { + if (jet.pt() > leadingJetPt) { + leadingJetPt = jet.pt(); + } if (jet.pt() > pTHatMaxMCD * pTHat) { - return; + if (outlierRejectEvent) { + return; + } else { + continue; + } } for (const auto& constituent : jet.template tracks_as()) { if (constituent.pt() > leadingPT) { @@ -288,7 +304,7 @@ struct JetHadronRecoil { registry.fill(HIST("hJetPhi"), jet.phi(), weight); registry.fill(HIST("hJet3D"), jet.pt() - (rho * jet.area()), jet.eta(), jet.phi(), weight); - double dR = getWTAaxisDifference(jet, jetsWTA, tracks); + double dR = getWTAaxisDifference(jet, tracks); registry.fill(HIST("hDeltaR"), dR, weight); registry.fill(HIST("hDeltaRpT"), jet.pt() - (rho * jet.area()), dR, weight); @@ -328,10 +344,11 @@ struct JetHadronRecoil { } } } + registry.fill(HIST("hTracksvsJets"), leadingTrackPt, leadingJetPt, pTHat, weight); } - template - void fillMCPHistograms(T const& jets, W const& jetsWTA, U const& particles, float weight = 1.0) + template + void fillMCPHistograms(T const& jets, U const& particles, float weight = 1.0, float pTHat = 999.0) { bool isSigCol; std::vector phiTTAr; @@ -340,8 +357,8 @@ struct JetHadronRecoil { double ptTT = 0; int trigNumber = 0; int nTT = 0; - float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); - + double leadingPartPt = 0; + double leadingJetPt = 0; float dice = rand->Rndm(); if (dice < fracSig) isSigCol = true; @@ -349,8 +366,15 @@ struct JetHadronRecoil { isSigCol = false; for (const auto& particle : particles) { + if (particle.pt() > leadingPartPt) { + leadingPartPt = particle.pt(); + } if (particle.pt() > pTHatTrackMaxMCD * pTHat) { - return; + if (outlierRejectEvent) { + return; + } else { + continue; + } } auto pdgParticle = pdg->GetParticle(particle.pdgCode()); if (!pdgParticle) { @@ -393,8 +417,15 @@ struct JetHadronRecoil { } for (const auto& jet : jets) { + if (jet.pt() > leadingJetPt) { + leadingJetPt = jet.pt(); + } if (jet.pt() > pTHatMaxMCP * pTHat) { - return; + if (outlierRejectEvent) { + return; + } else { + continue; + } } for (const auto& constituent : jet.template tracks_as()) { registry.fill(HIST("hConstituents3D"), constituent.pt(), constituent.eta(), constituent.phi()); @@ -404,7 +435,7 @@ struct JetHadronRecoil { registry.fill(HIST("hJetPhi"), jet.phi(), weight); registry.fill(HIST("hJet3D"), jet.pt(), jet.eta(), jet.phi(), weight); - double dR = getWTAaxisDifference(jet, jetsWTA, particles); + double dR = getWTAaxisDifference(jet, particles); registry.fill(HIST("hDeltaRPart"), dR, weight); registry.fill(HIST("hDeltaRpTPart"), jet.pt(), dR, weight); @@ -436,29 +467,37 @@ struct JetHadronRecoil { } } } + registry.fill(HIST("hPartvsJets"), leadingPartPt, leadingJetPt, pTHat, weight); } - template - void fillMatchedHistograms(T const& jetsBase, V const& mcdjetsWTA, W const& mcpjetsWTA, U const&, X const& tracks, Y const& particles, float weight = 1.0, float rho = 0.0) + template + void fillMatchedHistograms(T const& jetsBase, U const&, X const& tracks, Y const& particles, float weight = 1.0, float rho = 0.0, float pTHat = 999.0) { for (const auto& jetBase : jetsBase) { double dR = 0; double dRp = 0; - float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); if (jetBase.pt() > pTHatMaxMCD * pTHat) { - return; + if (outlierRejectEvent) { + return; + } else { + continue; + } } - dR = getWTAaxisDifference(jetBase, mcdjetsWTA, tracks, true); + dR = getWTAaxisDifference(jetBase, tracks); if (jetBase.has_matchedJetGeo()) { for (const auto& jetTag : jetBase.template matchedJetGeo_as>()) { if (jetTag.pt() > pTHatMaxMCP * pTHat) { - return; + if (outlierRejectEvent) { + return; + } else { + continue; + } } - dRp = getWTAaxisDifference(jetTag, mcpjetsWTA, particles, true); + dRp = getWTAaxisDifference(jetTag, particles); registry.fill(HIST("hPtMatched"), jetBase.pt() - (rho * jetBase.area()), jetTag.pt(), weight); registry.fill(HIST("hPhiMatched"), jetBase.phi(), jetTag.phi(), weight); @@ -474,8 +513,8 @@ struct JetHadronRecoil { } } - template - void fillRecoilJetMatchedHistograms(T const& jetsBase, V const& mcdjetsWTA, W const& mcpjetsWTA, U const&, X const& tracks, Y const& particles, float weight = 1.0, float rho = 0.0) + template + void fillRecoilJetMatchedHistograms(T const& jetsBase, U const&, X const& tracks, Y const& particles, float weight = 1.0, float rho = 0.0, float pTHat = 999.0) { std::vector phiTTAr; std::vector phiTTArPart; @@ -483,7 +522,6 @@ struct JetHadronRecoil { double phiTTPart = 0; int trigNumber = 0; int nTT = 0; - float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); for (const auto& track : tracks) { if (!track.has_mcParticle()) { @@ -493,7 +531,11 @@ struct JetHadronRecoil { continue; } if (track.pt() > pTHatTrackMaxMCD * pTHat) { - return; + if (outlierRejectEvent) { + return; + } else { + continue; + } } if (track.pt() < ptTTsigMax && track.pt() > ptTTsigMin) { phiTTAr.push_back(track.phi()); @@ -506,7 +548,7 @@ struct JetHadronRecoil { if (nTT > 0) { trigNumber = rand->Integer(nTT); phiTT = phiTTAr[trigNumber]; - phiTTPart = phiTTAr[trigNumber]; + phiTTPart = phiTTArPart[trigNumber]; } else { return; } @@ -516,28 +558,36 @@ struct JetHadronRecoil { double dRp = 0; if (jetBase.pt() > pTHatMaxMCD * pTHat) { - return; + if (outlierRejectEvent) { + return; + } else { + continue; + } } float dphi = RecoDecay::constrainAngle(jetBase.phi() - phiTT); - dR = getWTAaxisDifference(jetBase, mcdjetsWTA, tracks, true); + dR = getWTAaxisDifference(jetBase, tracks); if (jetBase.has_matchedJetGeo()) { for (const auto& jetTag : jetBase.template matchedJetGeo_as>()) { if (jetTag.pt() > pTHatMaxMCP * pTHat) { - return; + if (outlierRejectEvent) { + return; + } else { + continue; + } } float dphip = RecoDecay::constrainAngle(jetTag.phi() - phiTTPart); - dRp = getWTAaxisDifference(jetTag, mcpjetsWTA, particles, true); + dRp = getWTAaxisDifference(jetTag, particles); + registry.fill(HIST("hPtMatched"), jetBase.pt() - (rho * jetBase.area()), jetTag.pt(), weight); + registry.fill(HIST("hPhiMatched"), dphi, dphip, weight); + registry.fill(HIST("hPtResolution"), jetTag.pt(), (jetTag.pt() - (jetBase.pt() - (rho * jetBase.area()))) / jetTag.pt(), weight); + registry.fill(HIST("hPhiResolution"), jetTag.pt(), dphip - dphi, weight); + registry.fill(HIST("hDeltaRMatched"), dR, dRp, weight); + registry.fill(HIST("hDeltaRResolution"), jetTag.pt(), dRp - dR, weight); + registry.fill(HIST("hFullMatching"), jetBase.pt() - (rho * jetBase.area()), jetTag.pt(), dphi, dphip, dR, dRp, weight); if ((std::abs(dphi - o2::constants::math::PI) < 0.6) || (std::abs(dphip - o2::constants::math::PI) < 0.6)) { - registry.fill(HIST("hPtMatched"), jetBase.pt() - (rho * jetBase.area()), jetTag.pt(), weight); - registry.fill(HIST("hPhiMatched"), dphi, dphip, weight); - registry.fill(HIST("hPtResolution"), jetTag.pt(), (jetTag.pt() - (jetBase.pt() - (rho * jetBase.area()))) / jetTag.pt(), weight); - registry.fill(HIST("hPhiResolution"), jetTag.pt(), dphip - dphi, weight); - registry.fill(HIST("hDeltaRMatched"), dR, dRp, weight); - registry.fill(HIST("hDeltaRResolution"), jetTag.pt(), dRp - dR, weight); - registry.fill(HIST("hFullMatching"), jetBase.pt() - (rho * jetBase.area()), jetTag.pt(), dphi, dphip, dR, dRp, weight); registry.fill(HIST("hPtMatched1d"), jetTag.pt(), weight); registry.fill(HIST("hDeltaRMatched1d"), dRp, weight); } @@ -548,7 +598,6 @@ struct JetHadronRecoil { void processData(soa::Filtered::iterator const& collision, soa::Filtered> const& jets, - soa::Filtered> const& jetsWTA, soa::Filtered const& tracks) { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { @@ -558,13 +607,12 @@ struct JetHadronRecoil { return; } registry.fill(HIST("hZvtxSelected"), collision.posZ()); - fillHistograms(jets, jetsWTA, tracks); + fillHistograms(jets, tracks); } PROCESS_SWITCH(JetHadronRecoil, processData, "process data", true); void processDataWithRhoSubtraction(soa::Filtered>::iterator const& collision, soa::Filtered> const& jets, - soa::Filtered> const& jetsWTA, soa::Filtered const& tracks) { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { @@ -574,13 +622,13 @@ struct JetHadronRecoil { return; } registry.fill(HIST("hZvtxSelected"), collision.posZ()); - fillHistograms(jets, jetsWTA, tracks, 1.0, collision.rho()); + fillHistograms(jets, tracks, 1.0, collision.rho()); } PROCESS_SWITCH(JetHadronRecoil, processDataWithRhoSubtraction, "process data with rho subtraction", false); - void processMCD(soa::Filtered::iterator const& collision, + void processMCD(soa::Filtered>::iterator const& collision, + aod::JMcCollisions const&, soa::Filtered> const& jets, - soa::Filtered> const& jetsWTA, soa::Filtered const& tracks) { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { @@ -592,14 +640,17 @@ struct JetHadronRecoil { if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { return; } + if (collision.mcCollision().ptHard() < pTHatMinEvent) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ()); - fillHistograms(jets, jetsWTA, tracks); + fillHistograms(jets, tracks, 1.0, 0.0, collision.mcCollision().ptHard()); } PROCESS_SWITCH(JetHadronRecoil, processMCD, "process MC detector level", false); - void processMCDWithRhoSubtraction(soa::Filtered>::iterator const& collision, + void processMCDWithRhoSubtraction(soa::Filtered>::iterator const& collision, + aod::JMcCollisions const&, soa::Filtered> const& jets, - soa::Filtered> const& jetsWTA, soa::Filtered const& tracks) { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { @@ -611,15 +662,17 @@ struct JetHadronRecoil { if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { return; } + if (collision.mcCollision().ptHard() < pTHatMinEvent) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ()); - fillHistograms(jets, jetsWTA, tracks, 1.0, collision.rho()); + fillHistograms(jets, tracks, 1.0, collision.rho(), collision.mcCollision().ptHard()); } PROCESS_SWITCH(JetHadronRecoil, processMCDWithRhoSubtraction, "process MC detector level with rho subtraction", false); void processMCDWeighted(soa::Filtered>::iterator const& collision, aod::JMcCollisions const&, soa::Filtered> const& jets, - soa::Filtered> const& jetsWTA, soa::Filtered const& tracks) { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { @@ -631,15 +684,17 @@ struct JetHadronRecoil { if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { return; } + if (collision.mcCollision().ptHard() < pTHatMinEvent) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ(), collision.mcCollision().weight()); - fillHistograms(jets, jetsWTA, tracks, collision.mcCollision().weight()); + fillHistograms(jets, tracks, collision.mcCollision().weight(), 0.0, collision.mcCollision().ptHard()); } PROCESS_SWITCH(JetHadronRecoil, processMCDWeighted, "process MC detector level with event weights", false); void processMCDWeightedWithRhoSubtraction(soa::Filtered>::iterator const& collision, aod::JMcCollisions const&, soa::Filtered> const& jets, - soa::Filtered> const& jetsWTA, soa::Filtered const& tracks) { if (!jetderiveddatautilities::selectCollision(collision, eventSelectionBits)) { @@ -651,14 +706,16 @@ struct JetHadronRecoil { if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { return; } + if (collision.mcCollision().ptHard() < pTHatMinEvent) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ(), collision.mcCollision().weight()); - fillHistograms(jets, jetsWTA, tracks, collision.mcCollision().weight(), collision.rho()); + fillHistograms(jets, tracks, collision.mcCollision().weight(), collision.rho(), collision.mcCollision().ptHard()); } PROCESS_SWITCH(JetHadronRecoil, processMCDWeightedWithRhoSubtraction, "process MC detector level with event weights and rho subtraction", false); void processMCP(aod::JetMcCollision const& collision, soa::Filtered> const& jets, - soa::Filtered> const& jetsWTA, soa::Filtered const& particles) { if (std::abs(collision.posZ()) > vertexZCut) { @@ -667,14 +724,16 @@ struct JetHadronRecoil { if (skipMBGapEvents && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { return; } + if (collision.ptHard() < pTHatMinEvent) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ()); - fillMCPHistograms(jets, jetsWTA, particles); + fillMCPHistograms(jets, particles, 1.0, collision.ptHard()); } PROCESS_SWITCH(JetHadronRecoil, processMCP, "process MC particle level", false); void processMCPWeighted(aod::JetMcCollision const& collision, soa::Filtered> const& jets, - soa::Filtered> const& jetsWTA, soa::Filtered const& particles) { if (std::abs(collision.posZ()) > vertexZCut) { @@ -683,15 +742,16 @@ struct JetHadronRecoil { if (skipMBGapEvents && collision.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap) { return; } + if (collision.ptHard() < pTHatMinEvent) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ(), collision.weight()); - fillMCPHistograms(jets, jetsWTA, particles, collision.weight()); + fillMCPHistograms(jets, particles, collision.weight(), collision.ptHard()); } PROCESS_SWITCH(JetHadronRecoil, processMCPWeighted, "process MC particle level with event weights", false); - void processJetsMCPMCDMatched(soa::Filtered::iterator const& collision, + void processJetsMCPMCDMatched(soa::Filtered>::iterator const& collision, soa::Filtered> const& mcdjets, - soa::Filtered> const& mcdjetsWTA, - soa::Filtered> const& mcpjetsWTA, aod::JetTracks const& tracks, aod::JetParticles const& particles, aod::JetMcCollisions const&, @@ -703,16 +763,16 @@ struct JetHadronRecoil { if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { return; } + if (collision.mcCollision().ptHard() < pTHatMinEvent) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ()); - const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(partJetsPerCollision, collision.mcCollisionId()); - fillMatchedHistograms(mcdjets, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles); + fillMatchedHistograms(mcdjets, mcpjets, tracks, particles); } PROCESS_SWITCH(JetHadronRecoil, processJetsMCPMCDMatched, "process MC matched (inc jets)", false); - void processJetsMCPMCDMatchedWithRhoSubtraction(soa::Filtered>::iterator const& collision, + void processJetsMCPMCDMatchedWithRhoSubtraction(soa::Filtered>::iterator const& collision, soa::Filtered> const& mcdjets, - soa::Filtered> const& mcdjetsWTA, - soa::Filtered> const& mcpjetsWTA, aod::JetTracks const& tracks, aod::JetParticles const& particles, aod::JetMcCollisions const&, @@ -724,16 +784,16 @@ struct JetHadronRecoil { if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { return; } + if (collision.mcCollision().ptHard() < pTHatMinEvent) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ()); - const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(partJetsPerCollision, collision.mcCollisionId()); - fillMatchedHistograms(mcdjets, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles); + fillMatchedHistograms(mcdjets, mcpjets, tracks, particles, 1.0, 0.0, collision.mcCollision().ptHard()); } PROCESS_SWITCH(JetHadronRecoil, processJetsMCPMCDMatchedWithRhoSubtraction, "process MC matched (inc jets) with rho subtraction", false); - void processJetsMCPMCDMatchedWeighted(soa::Filtered::iterator const& collision, + void processJetsMCPMCDMatchedWeighted(soa::Filtered>::iterator const& collision, soa::Filtered> const& mcdjets, - soa::Filtered> const& mcdjetsWTA, - soa::Filtered> const& mcpjetsWTA, aod::JetTracks const& tracks, aod::JetParticles const& particles, aod::JetMcCollisions const&, @@ -745,16 +805,16 @@ struct JetHadronRecoil { if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { return; } + if (collision.mcCollision().ptHard() < pTHatMinEvent) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ()); - const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(partJetsPerCollision, collision.mcCollisionId()); - fillMatchedHistograms(mcdjets, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles, collision.mcCollision().weight()); + fillMatchedHistograms(mcdjets, mcpjets, tracks, particles, collision.mcCollision().weight(), 0.0, collision.mcCollision().ptHard()); } PROCESS_SWITCH(JetHadronRecoil, processJetsMCPMCDMatchedWeighted, "process MC matched with event weights (inc jets)", false); - void processJetsMCPMCDMatchedWeightedWithRhoSubtraction(soa::Filtered>::iterator const& collision, + void processJetsMCPMCDMatchedWeightedWithRhoSubtraction(soa::Filtered>::iterator const& collision, soa::Filtered> const& mcdjets, - soa::Filtered> const& mcdjetsWTA, - soa::Filtered> const& mcpjetsWTA, aod::JetTracks const& tracks, aod::JetParticles const& particles, aod::JetMcCollisions const&, @@ -766,16 +826,16 @@ struct JetHadronRecoil { if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { return; } + if (collision.mcCollision().ptHard() < pTHatMinEvent) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ()); - const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(partJetsPerCollision, collision.mcCollisionId()); - fillMatchedHistograms(mcdjets, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles, collision.mcCollision().weight(), collision.rho()); + fillMatchedHistograms(mcdjets, mcpjets, tracks, particles, collision.mcCollision().weight(), collision.rho(), collision.mcCollision().ptHard()); } PROCESS_SWITCH(JetHadronRecoil, processJetsMCPMCDMatchedWeightedWithRhoSubtraction, "process MC matched with event weights (inc jets) and rho subtraction", false); - void processRecoilJetsMCPMCDMatched(soa::Filtered::iterator const& collision, + void processRecoilJetsMCPMCDMatched(soa::Filtered>::iterator const& collision, soa::Filtered> const& mcdjets, - soa::Filtered> const& mcdjetsWTA, - soa::Filtered> const& mcpjetsWTA, soa::Filtered const& tracks, soa::Filtered const& particles, aod::JetMcCollisions const&, @@ -787,16 +847,16 @@ struct JetHadronRecoil { if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { return; } + if (collision.mcCollision().ptHard() < pTHatMinEvent) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ()); - const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(partJetsPerCollision, collision.mcCollisionId()); - fillRecoilJetMatchedHistograms(mcdjets, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles); + fillRecoilJetMatchedHistograms(mcdjets, mcpjets, tracks, particles, 1.0, 0.0, collision.mcCollision().ptHard()); } PROCESS_SWITCH(JetHadronRecoil, processRecoilJetsMCPMCDMatched, "process MC matched (recoil jets)", false); - void processRecoilJetsMCPMCDMatchedWeighted(soa::Filtered::iterator const& collision, + void processRecoilJetsMCPMCDMatchedWeighted(soa::Filtered>::iterator const& collision, soa::Filtered> const& mcdjets, - soa::Filtered> const& mcdjetsWTA, - soa::Filtered> const& mcpjetsWTA, soa::Filtered const& tracks, soa::Filtered const& particles, aod::JetMcCollisions const&, @@ -808,55 +868,34 @@ struct JetHadronRecoil { if (!jetderiveddatautilities::selectTrigger(collision, triggerMaskBits)) { return; } + if (collision.mcCollision().ptHard() < pTHatMinEvent) { + return; + } registry.fill(HIST("hZvtxSelected"), collision.posZ()); - const auto& mcpjetsWTACut = mcpjetsWTA.sliceBy(partJetsPerCollision, collision.mcCollisionId()); - fillRecoilJetMatchedHistograms(mcdjets, mcdjetsWTA, mcpjetsWTACut, mcpjets, tracks, particles, collision.mcCollision().weight()); + fillRecoilJetMatchedHistograms(mcdjets, mcpjets, tracks, particles, collision.mcCollision().weight(), 0.0, collision.mcCollision().ptHard()); } PROCESS_SWITCH(JetHadronRecoil, processRecoilJetsMCPMCDMatchedWeighted, "process MC matched with event weights (recoil jets)", false); - template - double getWTAaxisDifference(T const& jet, U const& jetsWTA, X const& /*tracks or particles*/, bool isMatched = false) + template + double getWTAaxisDifference(T const& jet, X const& /*tracks or particles*/) { double deltaPhi = -1; - double deltaEta = -1; double deltaY = -1; double dR = -1; - if (wtaMethod == 0) { - // get WTA matched jet - should just be one jet matched geometrically - if (isMatched) { - // response - requires alternative method - for (const auto& jetWTA : jetsWTA) { - double djetp = RecoDecay::sqrtSumOfSquares(RecoDecay::constrainAngle(jet.phi() - jetWTA.phi(), -o2::constants::math::PI), jet.eta() - jetWTA.eta()); - if (djetp < 0.6 * jetR) { - dR = djetp; - break; - } - } - } else { - // MCP or MCD - for (const auto& jetWTA : jet.template matchedJetGeo_as>()) { - deltaPhi = RecoDecay::constrainAngle(jetWTA.phi() - jet.phi(), -o2::constants::math::PI); - deltaEta = jetWTA.eta() - jet.eta(); - dR = RecoDecay::sqrtSumOfSquares(deltaPhi, deltaEta); - } - } - } else if (wtaMethod == 1) { - // recluster jet - jetConstituents.clear(); - for (auto& jetConstituent : jet.template tracks_as()) { - fastjetutilities::fillTracks(jetConstituent, jetConstituents, jetConstituent.globalIndex()); - } - jetReclustered.clear(); - fastjet::ClusterSequenceArea clusterSeq(jetReclusterer.findJets(jetConstituents, jetReclustered)); - jetReclustered = sorted_by_pt(jetReclustered); - - deltaPhi = RecoDecay::constrainAngle(jet.phi() - jetReclustered[0].phi(), -o2::constants::math::PI); - deltaY = jet.y() - jetReclustered[0].rap(); - dR = RecoDecay::sqrtSumOfSquares(deltaPhi, deltaY); - LOG(debug) << "orig. jet n const = " << jet.tracksIds().size() << " pt = " << jet.pt() << " eta = " << jet.eta() << " phi = " << jet.phi(); - LOG(debug) << "recl. jet n const = " << clusterSeq.constituents(jetReclustered[0]).size() << " pt = " << jetReclustered[0].pt() << " eta = " << jetReclustered[0].eta() << " phi = " << jetReclustered[0].phi(); - LOG(debug) << "distance = " << dR; - } + jetConstituents.clear(); + for (auto& jetConstituent : jet.template tracks_as()) { + fastjetutilities::fillTracks(jetConstituent, jetConstituents, jetConstituent.globalIndex()); + } + jetReclustered.clear(); + fastjet::ClusterSequenceArea clusterSeq(jetReclusterer.findJets(jetConstituents, jetReclustered)); + jetReclustered = sorted_by_pt(jetReclustered); + + deltaPhi = RecoDecay::constrainAngle(jet.phi() - jetReclustered[0].phi(), -o2::constants::math::PI); + deltaY = jet.y() - jetReclustered[0].rap(); + dR = RecoDecay::sqrtSumOfSquares(deltaPhi, deltaY); + LOG(debug) << "orig. jet n const = " << jet.tracksIds().size() << " pt = " << jet.pt() << " eta = " << jet.eta() << " phi = " << jet.phi(); + LOG(debug) << "recl. jet n const = " << clusterSeq.constituents(jetReclustered[0]).size() << " pt = " << jetReclustered[0].pt() << " eta = " << jetReclustered[0].eta() << " phi = " << jetReclustered[0].phi(); + LOG(debug) << "distance = " << dR; return dR; } }; diff --git a/PWGJE/Tasks/jetShape.cxx b/PWGJE/Tasks/jetShape.cxx index 3fe14ba6490..9a7c857e256 100644 --- a/PWGJE/Tasks/jetShape.cxx +++ b/PWGJE/Tasks/jetShape.cxx @@ -43,8 +43,8 @@ struct JetShapeTask { Configurable nBinsNSigma{"nBinsNSigma", 101, "Number of nsigma bins"}; Configurable nSigmaMin{"nSigmaMin", -10.1f, "Min value of nsigma"}; Configurable nSigmaMax{"nSigmaMax", 10.1f, "Max value of nsigma"}; - Configurable nBinsP{"nBinsP", 700, "Number of p bins"}; - Configurable nBinsPt{"nBinsPt", 500, "Number of pT bins"}; + Configurable nBinsPForDedx{"nBinsPForDedx", 700, "Number of p bins"}; + Configurable nBinsPForBeta{"nBinsPForBeta", 500, "Number of pT bins"}; Configurable nBinsTpcDedx{"nBinsTpcDedx", 500, "Number of DEdx bins"}; Configurable nBinsTofBeta{"nBinsTofBeta", 350, "Number of Beta bins"}; Configurable pMax{"pMax", 7.0f, "Max value of p"}; @@ -52,19 +52,36 @@ struct JetShapeTask { Configurable nBinsDistance{"nBinsDistance", 7, "Number of distance bins"}; Configurable distanceMax{"distanceMax", 0.7f, "Max value of distance"}; Configurable nSigmaTofCut{"nSigmaTofCut", 2.0f, "Number of sigma cut for TOF PID"}; + Configurable tpcNSigmaPrMin{"tpcNSigmaPrMin", -3.5f, "Min value of tpcNsigmaProton"}; + Configurable tpcNSigmaPrMax{"tpcNSigmaPrMax", 0.5f, "Max value of tpcNsigmaProton"}; + Configurable tpcNSigmaPiMin{"tpcNSigmaPiMin", -0.5f, "Min value of tpcNsigmaPion"}; + Configurable tpcNSigmaPiMax{"tpcNSigmaPiMax", 3.5f, "Max value of tpcNsigmaPion"}; HistogramRegistry registry{"registry", {{"tpcTofPi", "tpcTofPi", {HistType::kTHnSparseD, {{35, 0, pMax}, {nBinsNSigma, nSigmaMin, nSigmaMax}, {nBinsDistance, 0, distanceMax}}}}, {"tpcTofPr", "tpcTofPr", {HistType::kTHnSparseD, {{35, 0, pMax}, {nBinsNSigma, nSigmaMin, nSigmaMax}, {nBinsDistance, 0, distanceMax}}}}, + {"tpcTofPiOutOfJet", "tpcTofPiOutOfJet", {HistType::kTH2F, {{35, 0, pMax}, {nBinsNSigma, nSigmaMin, nSigmaMax}}}}, + {"tpcTofPrOutOfJet", "tpcTofPrOutOfJet", {HistType::kTH2F, {{35, 0, pMax}, {nBinsNSigma, nSigmaMin, nSigmaMax}}}}, {"tpcPi", "tpcPi", {HistType::kTH2F, {{70, 0, pMax}, {nBinsNSigma, nSigmaMin, nSigmaMax}}}}, {"tofPi", "tofPi", {HistType::kTH2F, {{50, 0, ptMax}, {nBinsNSigma, nSigmaMin, nSigmaMax}}}}, {"tpcPr", "tpcPr", {HistType::kTH2F, {{70, 0, pMax}, {nBinsNSigma, nSigmaMin, nSigmaMax}}}}, {"tofPr", "tofPr", {HistType::kTH2F, {{50, 0, ptMax}, {nBinsNSigma, nSigmaMin, nSigmaMax}}}}, - {"tpcDedx", "tpcDedx", {HistType::kTHnSparseD, {{nBinsP, 0, pMax}, {nBinsTpcDedx, 0, 1000}, {nBinsDistance, 0, distanceMax}}}}, - {"tofBeta", "tofBeta", {HistType::kTHnSparseD, {{nBinsPt, 0, ptMax}, {nBinsTofBeta, 0.4, 1.1}, {nBinsDistance, 0, distanceMax}}}}, - {"pVsPtForProton", "pVsPtForProton", {HistType::kTHnSparseD, {{70, 0, pMax}, {50, 0, ptMax}, {nBinsDistance, 0, distanceMax}}}}, - {"pVsPtForPion", "pVsPtPion", {HistType::kTHnSparseD, {{70, 0, pMax}, {50, 0, ptMax}, {nBinsDistance, 0, distanceMax}}}}, + {"tpcDedx", "tpcDedx", {HistType::kTHnSparseD, {{nBinsPForDedx, 0, pMax}, {nBinsTpcDedx, 0, 1000}, {nBinsDistance, 0, distanceMax}}}}, + {"tpcDedxOutOfJet", "tpcDedxOutOfJet", {HistType::kTH2F, {{nBinsPForDedx, 0, pMax}, {nBinsTpcDedx, 0, 1000}}}}, + {"tofBeta", "tofBeta", {HistType::kTH2F, {{nBinsPForBeta, 0, pMax}, {nBinsTofBeta, 0.4, 1.1}}}}, + {"pVsPtForPr", "pVsPtForPr", {HistType::kTHnSparseD, {{70, 0, pMax}, {50, 0, ptMax}, {nBinsDistance, 0, distanceMax}}}}, + {"pVsPtForPi", "pVsPtPi", {HistType::kTHnSparseD, {{70, 0, pMax}, {50, 0, ptMax}, {nBinsDistance, 0, distanceMax}}}}, + {"pVsPtForPrOutOfJet", "pVsPtForPrOutOfJet", {HistType::kTH2F, {{70, 0, pMax}, {50, 0, ptMax}}}}, + {"pVsPtForPiOutOfJet", "pVsPtPionOutOfJet", {HistType::kTH2F, {{70, 0, pMax}, {50, 0, ptMax}}}}, {"tofMass", "tofMass", {HistType::kTH1F, {{300, 0, 3}}}}, + {"trackPhi", "trackPhi", {HistType::kTH1F, {{80, -1, 7}}}}, + {"trackEta", "trackEta", {HistType::kTH1F, {{100, -1, 1}}}}, + {"trackTpcNClsCrossedRows", "trackTpcNClsCrossedRows", {HistType::kTH1F, {{50, 0, 200}}}}, + {"trackDcaXY", "trackDcaXY", {HistType::kTH1F, {{40, -10, 10}}}}, + {"trackItsChi2NCl", "trackItsChi2NCl", {HistType::kTH1F, {{60, 0, 30}}}}, + {"trackTpcChi2NCl", "trackTpcChi2NCl", {HistType::kTH1F, {{100, 0, 50}}}}, + {"trackTpcNClsFound", "trackTpcNClsFound", {HistType::kTH1F, {{100, 0, 200}}}}, + {"trackItsNCls", "trackItsNCls", {HistType::kTH1F, {{10, 0, 10}}}}, {"jetPt", "jet pT;#it{p}_{T,jet} (GeV/#it{c});entries", {HistType::kTH1F, {{200, 0., 200.}}}}, {"jetEta", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}}, {"jetPhi", "jet #phi;#phi_{jet};entries", {HistType::kTH1F, {{80, -1.0, 7.}}}}, @@ -179,6 +196,7 @@ struct JetShapeTask { float ptCorr = jet.pt() - collision.rho() * jet.area(); for (const auto& track : tracks) { + float preDeltaPhi1 = track.phi() - jet.phi(); float deltaPhi1 = RecoDecay::constrainAngle(preDeltaPhi1); float deltaEta = track.eta() - jet.eta(); @@ -200,8 +218,8 @@ struct JetShapeTask { float preDeltaPhiBg1 = track.phi() - phiBg1; float preDeltaPhiBg2 = track.phi() - phiBg2; - float deltaPhiBg1 = RecoDecay::constrainAngle(preDeltaPhiBg1); - float deltaPhiBg2 = RecoDecay::constrainAngle(preDeltaPhiBg2); + float deltaPhiBg1 = RecoDecay::constrainAngle(preDeltaPhiBg1, -o2::constants::math::PI); + float deltaPhiBg2 = RecoDecay::constrainAngle(preDeltaPhiBg2, -o2::constants::math::PI); float distanceBg1 = std::sqrt(deltaEta * deltaEta + deltaPhiBg1 * deltaPhiBg1); float distanceBg2 = std::sqrt(deltaEta * deltaEta + deltaPhiBg2 * deltaPhiBg2); @@ -257,6 +275,16 @@ struct JetShapeTask { // tracks conditions for (const auto& track : tracks) { + + registry.fill(HIST("trackTpcNClsCrossedRows"), track.tpcNClsCrossedRows()); + registry.fill(HIST("trackDcaXY"), track.dcaXY()); + registry.fill(HIST("trackItsChi2NCl"), track.itsChi2NCl()); + registry.fill(HIST("trackTpcChi2NCl"), track.tpcChi2NCl()); + registry.fill(HIST("trackTpcNClsFound"), track.tpcNClsFound()); + registry.fill(HIST("trackItsNCls"), track.itsNCls()); + registry.fill(HIST("trackEta"), track.eta()); + registry.fill(HIST("trackPhi"), track.phi()); + if (std::abs(track.eta()) > etaTrUp) continue; if (track.tpcNClsCrossedRows() < nclcrossTpcMin) @@ -274,8 +302,6 @@ struct JetShapeTask { // PID check registry.fill(HIST("tofMass"), track.mass()); - - // for calculate purity registry.fill(HIST("tpcPi"), track.p(), track.tpcNSigmaPi()); registry.fill(HIST("tofPi"), track.pt(), track.tofNSigmaPi()); registry.fill(HIST("tpcPr"), track.p(), track.tpcNSigmaPr()); @@ -289,18 +315,54 @@ struct JetShapeTask { // calculate distance from jet axis float distance = std::sqrt(deltaEta * deltaEta + deltaPhi1 * deltaPhi1); + // Define perpendicular cone axes in phi + float phiBg1 = jet.phi() + (o2::constants::math::PIHalf); + float phiBg2 = jet.phi() - (o2::constants::math::PIHalf); + + // Calculate delta phi for background cones + float preDeltaPhiBg1 = track.phi() - phiBg1; + float preDeltaPhiBg2 = track.phi() - phiBg2; + float deltaPhiBg1 = RecoDecay::constrainAngle(preDeltaPhiBg1, -o2::constants::math::PI); + float deltaPhiBg2 = RecoDecay::constrainAngle(preDeltaPhiBg2, -o2::constants::math::PI); + + // Calculate distance to background cone axes + float distanceBg1 = std::sqrt(deltaEta * deltaEta + deltaPhiBg1 * deltaPhiBg1); + float distanceBg2 = std::sqrt(deltaEta * deltaEta + deltaPhiBg2 * deltaPhiBg2); + + // Fill histogram if track is inside one of the perpendicular cones + if (distanceBg1 < jetR || distanceBg2 < jetR) { + registry.fill(HIST("tpcDedxOutOfJet"), track.p(), track.tpcSignal()); + + if (std::abs(track.tofNSigmaPi()) < nSigmaTofCut) { + registry.fill(HIST("tpcTofPiOutOfJet"), track.p(), track.tpcNSigmaPi()); + if (track.tpcNSigmaPi() > tpcNSigmaPiMin && track.tpcNSigmaPi() < tpcNSigmaPiMax) { + registry.fill(HIST("pVsPtForPiOutOfJet"), track.p(), track.pt()); + } + } + if (std::abs(track.tofNSigmaPr()) < nSigmaTofCut) { + registry.fill(HIST("tpcTofPrOutOfJet"), track.p(), track.tpcNSigmaPr()); + if (track.tpcNSigmaPr() > tpcNSigmaPrMin && track.tpcNSigmaPr() < tpcNSigmaPrMax) { + registry.fill(HIST("pVsPtForPrOutOfJet"), track.p(), track.pt()); + } + } + } + registry.fill(HIST("distanceVsTrackpt"), distance, track.pt()); registry.fill(HIST("tpcDedx"), track.p(), track.tpcSignal(), distance); - registry.fill(HIST("tofBeta"), track.pt(), track.beta(), distance); + registry.fill(HIST("tofBeta"), track.p(), track.beta()); if (std::abs(track.tofNSigmaPr()) < nSigmaTofCut) { - registry.fill(HIST("pVsPtForProton"), track.p(), track.pt(), distance); registry.fill(HIST("tpcTofPr"), track.p(), track.tpcNSigmaPr(), distance); + if (track.tpcNSigmaPr() > tpcNSigmaPrMin && track.tpcNSigmaPr() < tpcNSigmaPrMax) { + registry.fill(HIST("pVsPtForPr"), track.p(), track.pt(), distance); + } } if (std::abs(track.tofNSigmaPi()) < nSigmaTofCut) { - registry.fill(HIST("pVsPtForPion"), track.p(), track.pt(), distance); registry.fill(HIST("tpcTofPi"), track.p(), track.tpcNSigmaPi(), distance); + if (track.tpcNSigmaPi() > tpcNSigmaPiMin && track.tpcNSigmaPi() < tpcNSigmaPiMax) { + registry.fill(HIST("pVsPtForPi"), track.p(), track.pt(), distance); + } } } } diff --git a/PWGJE/Tasks/jetSubstructureDs.cxx b/PWGJE/Tasks/jetSubstructureDs.cxx new file mode 100644 index 00000000000..3207ba667e3 --- /dev/null +++ b/PWGJE/Tasks/jetSubstructureDs.cxx @@ -0,0 +1,39 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// jet substructure Ds charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/Tasks/jetSubstructureHF.cxx" + +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetSubstructure.h" +#include "PWGJE/DataModel/JetSubtraction.h" + +#include +#include +#include +#include +#include + +#include + +using JetSubstructureDs = JetSubstructureHFTask, soa::Join, soa::Join, soa::Join, aod::CandidatesDsData, aod::CandidatesDsMCP, aod::DsCJetSSs, aod::DsChargedSPs, aod::DsChargedPRs, aod::DsCMCDJetSSs, aod::DsChargedMCDetectorLevelSPs, aod::DsChargedMCDetectorLevelPRs, aod::DsCMCPJetSSs, aod::DsChargedMCParticleLevelSPs, aod::DsChargedMCParticleLevelPRs, aod::DsCEWSJetSSs, aod::DsChargedEventWiseSubtractedSPs, aod::DsChargedEventWiseSubtractedPRs, aod::JTrackDsSubs>; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + tasks.emplace_back(adaptAnalysisTask(cfgc, + SetDefaultProcesses{}, + TaskName{"jet-substructure-ds"})); + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/Tasks/jetSubstructureDsOutput.cxx b/PWGJE/Tasks/jetSubstructureDsOutput.cxx new file mode 100644 index 00000000000..91f0ae4b54d --- /dev/null +++ b/PWGJE/Tasks/jetSubstructureDsOutput.cxx @@ -0,0 +1,40 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// jet substructure output Ds charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/Tasks/jetSubstructureHFOutput.cxx" + +#include "PWGHF/DataModel/DerivedTables.h" +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetReducedDataHF.h" +#include "PWGJE/DataModel/JetSubstructure.h" +#include "PWGJE/DataModel/JetSubtraction.h" + +#include +#include +#include +#include +#include + +#include + +using JetSubstructureOutputDs = JetSubstructureHFOutputTask, aod::McCollisionsDs, aod::CandidatesDsData, aod::CandidatesDsMCD, aod::CandidatesDsMCP, aod::BkgDsRhos, aod::BkgDsMcRhos, aod::JTrackDsSubs, soa::Join, soa::Join, soa::Join, soa::Join, aod::DsCJetCOs, aod::DsCJetOs, aod::DsCJetSSOs, aod::DsCJetMOs, soa::Join, soa::Join, soa::Join, aod::DsCMCDJetCOs, aod::DsCMCDJetOs, aod::DsCMCDJetSSOs, aod::DsCMCDJetMOs, soa::Join, soa::Join, soa::Join, soa::Join, aod::DsCMCPJetCOs, aod::DsCMCPJetMCCOs, aod::DsCMCPJetOs, aod::DsCMCPJetSSOs, aod::DsCMCPJetMOs, soa::Join, soa::Join, soa::Join, aod::DsCEWSJetCOs, aod::DsCEWSJetOs, aod::DsCEWSJetSSOs, aod::DsCEWSJetMOs, aod::StoredHfDsCollBase, aod::StoredHfDsBases, aod::StoredHfDsPars, aod::StoredHfDsParEs, aod::JDumDsParDaus, aod::StoredHfDsSels, aod::StoredHfDsMls, aod::JDumDsMlDaus, aod::StoredHfDsMcs, aod::StoredHfDsMcCollBases, aod::StoredHfDsMcRCollIds, aod::StoredHfDsPBases>; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + tasks.emplace_back(adaptAnalysisTask(cfgc, SetDefaultProcesses{}, TaskName{"jet-substructure-ds-output"})); + + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/Tasks/jetSubstructureHF.cxx b/PWGJE/Tasks/jetSubstructureHF.cxx index c098236dae7..1117a79bd37 100644 --- a/PWGJE/Tasks/jetSubstructureHF.cxx +++ b/PWGJE/Tasks/jetSubstructureHF.cxx @@ -130,20 +130,24 @@ struct JetSubstructureHFTask { Preslice TracksPerCollision = aod::jtrack::collisionId; PresliceOptional TracksPerD0DataSub = aod::bkgd0::candidateId; PresliceOptional TracksPerDplusDataSub = aod::bkgdplus::candidateId; + PresliceOptional TracksPerDsDataSub = aod::bkgds::candidateId; PresliceOptional TracksPerDstarDataSub = aod::bkgdstar::candidateId; PresliceOptional TracksPerLcDataSub = aod::bkglc::candidateId; PresliceOptional TracksPerB0DataSub = aod::bkgb0::candidateId; PresliceOptional TracksPerBplusDataSub = aod::bkgbplus::candidateId; + PresliceOptional TracksPerXicToXiPiPiDataSub = aod::bkgxictoxipipi::candidateId; PresliceOptional TracksPerDielectronDataSub = aod::bkgdielectron::candidateId; Preslice ParticlesPerMcCollision = aod::jmcparticle::mcCollisionId; - template - auto selectSlicer(T const& D0Slicer, U const& DplusSlicer, V const& DstarSlicer, M const& LcSlicer, N const& B0Slicer, O const& BplusSlicer, P const& DielectronSlicer) + template + auto selectSlicer(T const& D0Slicer, U const& DplusSlicer, V const& DsSlicer, M const& DstarSlicer, N const& LcSlicer, O const& B0Slicer, P const& BplusSlicer, Q const& XicToXiPiPiSlicer, R const& DielectronSlicer) { if constexpr (jethfutilities::isD0Table()) { return D0Slicer; } else if constexpr (jethfutilities::isDplusTable()) { return DplusSlicer; + } else if constexpr (jethfutilities::isDsTable()) { + return DsSlicer; } else if constexpr (jethfutilities::isDstarTable()) { return DstarSlicer; } else if constexpr (jethfutilities::isLcTable()) { @@ -152,6 +156,8 @@ struct JetSubstructureHFTask { return B0Slicer; } else if constexpr (jethfutilities::isBplusTable()) { return BplusSlicer; + } else if constexpr (jethfutilities::isXicToXiPiPiTable()) { + return XicToXiPiPiSlicer; } else if constexpr (jetdqutilities::isDielectronTable()) { return DielectronSlicer; } else { @@ -441,7 +447,7 @@ struct JetSubstructureHFTask { CandidateTable const& candidates, TracksSub const& tracks) { - analyseCharged(jet, tracks, candidates, selectSlicer(TracksPerD0DataSub, TracksPerDplusDataSub, TracksPerDstarDataSub, TracksPerLcDataSub, TracksPerB0DataSub, TracksPerBplusDataSub, TracksPerDielectronDataSub), jetSubstructureDataSubTable, jetSplittingsDataSubTable, jetPairsDataSubTable); + analyseCharged(jet, tracks, candidates, selectSlicer(TracksPerD0DataSub, TracksPerDplusDataSub, TracksPerDsDataSub, TracksPerDstarDataSub, TracksPerLcDataSub, TracksPerB0DataSub, TracksPerBplusDataSub, TracksPerXicToXiPiPiDataSub, TracksPerDielectronDataSub), jetSubstructureDataSubTable, jetSplittingsDataSubTable, jetPairsDataSubTable); } PROCESS_SWITCH(JetSubstructureHFTask, processChargedJetsDataSub, "HF jet substructure on data", false); diff --git a/PWGJE/Tasks/jetSubstructureHFOutput.cxx b/PWGJE/Tasks/jetSubstructureHFOutput.cxx index ee3aaebc142..0a77074c8ce 100644 --- a/PWGJE/Tasks/jetSubstructureHFOutput.cxx +++ b/PWGJE/Tasks/jetSubstructureHFOutput.cxx @@ -151,6 +151,16 @@ struct JetSubstructureHFOutputTask { PresliceOptional> DplusPairsPerJetMCD = aod::dpluschargedmcdetectorlevelpair::jetId; PresliceOptional> DplusPairsPerJetMCP = aod::dpluschargedmcparticlelevelpair::jetId; + PresliceOptional> DsSplittingsPerJetData = aod::dschargedsplitting::jetId; + PresliceOptional> DsSplittingsPerJetDataSub = aod::dschargedeventwisesubtractedsplitting::jetId; + PresliceOptional> DsSplittingsPerJetMCD = aod::dschargedmcdetectorlevelsplitting::jetId; + PresliceOptional> DsSplittingsPerJetMCP = aod::dschargedmcparticlelevelsplitting::jetId; + + PresliceOptional> DsPairsPerJetData = aod::dschargedpair::jetId; + PresliceOptional> DsPairsPerJetDataSub = aod::dschargedeventwisesubtractedpair::jetId; + PresliceOptional> DsPairsPerJetMCD = aod::dschargedmcdetectorlevelpair::jetId; + PresliceOptional> DsPairsPerJetMCP = aod::dschargedmcparticlelevelpair::jetId; + PresliceOptional> DstarSplittingsPerJetData = aod::dstarchargedsplitting::jetId; PresliceOptional> DstarSplittingsPerJetDataSub = aod::dstarchargedeventwisesubtractedsplitting::jetId; PresliceOptional> DstarSplittingsPerJetMCD = aod::dstarchargedmcdetectorlevelsplitting::jetId; @@ -191,6 +201,16 @@ struct JetSubstructureHFOutputTask { PresliceOptional> BplusPairsPerJetMCD = aod::bpluschargedmcdetectorlevelpair::jetId; PresliceOptional> BplusPairsPerJetMCP = aod::bpluschargedmcparticlelevelpair::jetId; + PresliceOptional> XicToXiPiPiSplittingsPerJetData = aod::xictoxipipichargedsplitting::jetId; + PresliceOptional> XicToXiPiPiSplittingsPerJetDataSub = aod::xictoxipipichargedeventwisesubtractedsplitting::jetId; + PresliceOptional> XicToXiPiPiSplittingsPerJetMCD = aod::xictoxipipichargedmcdetectorlevelsplitting::jetId; + PresliceOptional> XicToXiPiPiSplittingsPerJetMCP = aod::xictoxipipichargedmcparticlelevelsplitting::jetId; + + PresliceOptional> XicToXiPiPiPairsPerJetData = aod::xictoxipipichargedpair::jetId; + PresliceOptional> XicToXiPiPiPairsPerJetDataSub = aod::xictoxipipichargedeventwisesubtractedpair::jetId; + PresliceOptional> XicToXiPiPiPairsPerJetMCD = aod::xictoxipipichargedmcdetectorlevelpair::jetId; + PresliceOptional> XicToXiPiPiPairsPerJetMCP = aod::xictoxipipichargedmcparticlelevelpair::jetId; + PresliceOptional> DielectronSplittingsPerJetData = aod::dielectronchargedsplitting::jetId; PresliceOptional> DielectronSplittingsPerJetDataSub = aod::dielectronchargedeventwisesubtractedsplitting::jetId; PresliceOptional> DielectronSplittingsPerJetMCD = aod::dielectronchargedmcdetectorlevelsplitting::jetId; @@ -383,8 +403,8 @@ struct JetSubstructureHFOutputTask { } } - template - void analyseSubstructureMatched(T const& jets, U const& allSplittings, V const& allPairs, M const& D0SplittingsPerJet, N const DplusSplittingsPerJet, O const DstarSplittingsPerJet, P const& LcSplittingsPerJet, Q const& B0SplittingsPerJet, R const& BplusSplittingsPerJet, S const& DielectronSplittingsPerJet, A const& D0PairsPerJet, B const DplusPairsPerJet, C const& DstarPairsPerJet, D const& LcPairsPerJet, E const& B0PairsPerJet, F const& BplusPairsPerJet, G const& DielectronPairsPerJet, std::vector>& splittingMatchesGeoVecVec, std::vector>& splittingMatchesPtVecVec, std::vector>& splittingMatchesHFVecVec, std::vector>& pairMatchesVecVec, float jetPtMin) + template + void analyseSubstructureMatched(T const& jets, U const& allSplittings, V const& allPairs, M const& D0SplittingsPerJet, N const DplusSplittingsPerJet, O const& DsSplittingsPerJet, P const DstarSplittingsPerJet, Q const& LcSplittingsPerJet, R const& B0SplittingsPerJet, S const& BplusSplittingsPerJet, A const& XicToXiPiPiSplittingsPerJet, B const& DielectronSplittingsPerJet, C const& D0PairsPerJet, D const DplusPairsPerJet, E const& DsPairsPerJet, F const& DstarPairsPerJet, G const& LcPairsPerJet, H const& B0PairsPerJet, I const& BplusPairsPerJet, J const& XicToXiPiPiPairsPerJet, K const& DielectronPairsPerJet, std::vector>& splittingMatchesGeoVecVec, std::vector>& splittingMatchesPtVecVec, std::vector>& splittingMatchesHFVecVec, std::vector>& pairMatchesVecVec, float jetPtMin) { for (const auto& jet : jets) { if (jet.pt() < jetPtMin) { @@ -395,9 +415,9 @@ struct JetSubstructureHFOutputTask { } for (const auto& jetRadiiValue : jetRadiiValues) { if (jet.r() == round(jetRadiiValue * 100.0f)) { - auto splittings = jetcandidateutilities::slicedPerJet(allSplittings, jet, D0SplittingsPerJet, DplusSplittingsPerJet, DstarSplittingsPerJet, LcSplittingsPerJet, B0SplittingsPerJet, BplusSplittingsPerJet, DielectronSplittingsPerJet); + auto splittings = jetcandidateutilities::slicedPerJet(allSplittings, jet, D0SplittingsPerJet, DplusSplittingsPerJet, DsSplittingsPerJet, DstarSplittingsPerJet, LcSplittingsPerJet, B0SplittingsPerJet, BplusSplittingsPerJet, XicToXiPiPiSplittingsPerJet, DielectronSplittingsPerJet); fillSplittingMatchingVectors(splittings, jet.globalIndex(), splittingMatchesGeoVecVec, splittingMatchesPtVecVec, splittingMatchesHFVecVec); - auto pairs = jetcandidateutilities::slicedPerJet(allPairs, jet, D0PairsPerJet, DplusPairsPerJet, DstarPairsPerJet, LcPairsPerJet, B0PairsPerJet, BplusPairsPerJet, DielectronPairsPerJet); + auto pairs = jetcandidateutilities::slicedPerJet(allPairs, jet, D0PairsPerJet, DplusPairsPerJet, DsPairsPerJet, DstarPairsPerJet, LcPairsPerJet, B0PairsPerJet, BplusPairsPerJet, XicToXiPiPiPairsPerJet, DielectronPairsPerJet); fillPairMatchingVectors(pairs, jet.globalIndex(), pairMatchesVecVec); } } @@ -656,12 +676,12 @@ struct JetSubstructureHFOutputTask { splittingMatchesPtVecVecData.assign(jets.size(), {}); splittingMatchesHFVecVecData.assign(jets.size(), {}); pairMatchesVecVecData.assign(jets.size(), {}); - analyseSubstructureMatched(jets, splittingsData, pairsData, preslices.D0SplittingsPerJetData, preslices.DplusSplittingsPerJetData, preslices.DstarSplittingsPerJetData, preslices.LcSplittingsPerJetData, preslices.B0SplittingsPerJetData, preslices.BplusSplittingsPerJetData, preslices.DielectronSplittingsPerJetData, preslices.D0PairsPerJetData, preslices.DplusPairsPerJetData, preslices.DstarPairsPerJetData, preslices.LcPairsPerJetData, preslices.B0PairsPerJetData, preslices.BplusPairsPerJetData, preslices.DielectronPairsPerJetData, splittingMatchesGeoVecVecData, splittingMatchesPtVecVecData, splittingMatchesHFVecVecData, pairMatchesVecVecData, configs.jetPtMinData); + analyseSubstructureMatched(jets, splittingsData, pairsData, preslices.D0SplittingsPerJetData, preslices.DplusSplittingsPerJetData, preslices.DsSplittingsPerJetData, preslices.DstarSplittingsPerJetData, preslices.LcSplittingsPerJetData, preslices.B0SplittingsPerJetData, preslices.BplusSplittingsPerJetData, preslices.XicToXiPiPiSplittingsPerJetData, preslices.DielectronSplittingsPerJetData, preslices.D0PairsPerJetData, preslices.DplusPairsPerJetData, preslices.DsPairsPerJetData, preslices.DstarPairsPerJetData, preslices.LcPairsPerJetData, preslices.B0PairsPerJetData, preslices.BplusPairsPerJetData, preslices.XicToXiPiPiPairsPerJetData, preslices.DielectronPairsPerJetData, splittingMatchesGeoVecVecData, splittingMatchesPtVecVecData, splittingMatchesHFVecVecData, pairMatchesVecVecData, configs.jetPtMinData); splittingMatchesGeoVecVecDataSub.assign(jetsSub.size(), {}); splittingMatchesPtVecVecDataSub.assign(jetsSub.size(), {}); splittingMatchesHFVecVecDataSub.assign(jetsSub.size(), {}); pairMatchesVecVecDataSub.assign(jetsSub.size(), {}); - analyseSubstructureMatched(jetsSub, splittingsDataSub, pairsDataSub, preslices.D0SplittingsPerJetDataSub, preslices.DplusSplittingsPerJetDataSub, preslices.DstarSplittingsPerJetDataSub, preslices.LcSplittingsPerJetDataSub, preslices.B0SplittingsPerJetDataSub, preslices.BplusSplittingsPerJetDataSub, preslices.DielectronSplittingsPerJetDataSub, preslices.D0PairsPerJetDataSub, preslices.DplusPairsPerJetDataSub, preslices.DstarPairsPerJetDataSub, preslices.LcPairsPerJetDataSub, preslices.B0PairsPerJetDataSub, preslices.BplusPairsPerJetDataSub, preslices.DielectronPairsPerJetDataSub, splittingMatchesGeoVecVecDataSub, splittingMatchesPtVecVecDataSub, splittingMatchesHFVecVecDataSub, pairMatchesVecVecDataSub, configs.jetPtMinDataSub); + analyseSubstructureMatched(jetsSub, splittingsDataSub, pairsDataSub, preslices.D0SplittingsPerJetDataSub, preslices.DplusSplittingsPerJetDataSub, preslices.DsSplittingsPerJetDataSub, preslices.DstarSplittingsPerJetDataSub, preslices.LcSplittingsPerJetDataSub, preslices.B0SplittingsPerJetDataSub, preslices.BplusSplittingsPerJetDataSub, preslices.XicToXiPiPiSplittingsPerJetDataSub, preslices.DielectronSplittingsPerJetDataSub, preslices.D0PairsPerJetDataSub, preslices.DplusPairsPerJetDataSub, preslices.DsPairsPerJetDataSub, preslices.DstarPairsPerJetDataSub, preslices.LcPairsPerJetDataSub, preslices.B0PairsPerJetDataSub, preslices.BplusPairsPerJetDataSub, preslices.XicToXiPiPiPairsPerJetDataSub, preslices.DielectronPairsPerJetDataSub, splittingMatchesGeoVecVecDataSub, splittingMatchesPtVecVecDataSub, splittingMatchesHFVecVecDataSub, pairMatchesVecVecDataSub, configs.jetPtMinDataSub); } PROCESS_SWITCH(JetSubstructureHFOutputTask, processOutputSubstructureMatchingData, "jet substructure matching output Data", false); @@ -702,12 +722,12 @@ struct JetSubstructureHFOutputTask { splittingMatchesPtVecVecMCD.assign(jetsMCD.size(), {}); splittingMatchesHFVecVecMCD.assign(jetsMCD.size(), {}); pairMatchesVecVecMCD.assign(jetsMCD.size(), {}); - analyseSubstructureMatched(jetsMCD, splittingsMCD, pairsMCD, preslices.D0SplittingsPerJetMCD, preslices.DplusSplittingsPerJetMCD, preslices.DstarSplittingsPerJetMCD, preslices.LcSplittingsPerJetMCD, preslices.B0SplittingsPerJetMCD, preslices.BplusSplittingsPerJetMCD, preslices.DielectronSplittingsPerJetMCD, preslices.D0PairsPerJetMCD, preslices.DplusPairsPerJetMCD, preslices.DstarPairsPerJetMCD, preslices.LcPairsPerJetMCD, preslices.B0PairsPerJetMCD, preslices.BplusPairsPerJetMCD, preslices.DielectronPairsPerJetMCD, splittingMatchesGeoVecVecMCD, splittingMatchesPtVecVecMCD, splittingMatchesHFVecVecMCD, pairMatchesVecVecMCD, configs.jetPtMinMCD); + analyseSubstructureMatched(jetsMCD, splittingsMCD, pairsMCD, preslices.D0SplittingsPerJetMCD, preslices.DplusSplittingsPerJetMCD, preslices.DsSplittingsPerJetMCD, preslices.DstarSplittingsPerJetMCD, preslices.LcSplittingsPerJetMCD, preslices.B0SplittingsPerJetMCD, preslices.BplusSplittingsPerJetMCD, preslices.XicToXiPiPiSplittingsPerJetMCD, preslices.DielectronSplittingsPerJetMCD, preslices.D0PairsPerJetMCD, preslices.DplusPairsPerJetMCD, preslices.DsPairsPerJetMCD, preslices.DstarPairsPerJetMCD, preslices.LcPairsPerJetMCD, preslices.B0PairsPerJetMCD, preslices.BplusPairsPerJetMCD, preslices.XicToXiPiPiPairsPerJetMCD, preslices.DielectronPairsPerJetMCD, splittingMatchesGeoVecVecMCD, splittingMatchesPtVecVecMCD, splittingMatchesHFVecVecMCD, pairMatchesVecVecMCD, configs.jetPtMinMCD); splittingMatchesGeoVecVecMCP.assign(jetsMCP.size(), {}); splittingMatchesPtVecVecMCP.assign(jetsMCP.size(), {}); splittingMatchesHFVecVecMCP.assign(jetsMCP.size(), {}); pairMatchesVecVecMCP.assign(jetsMCP.size(), {}); - analyseSubstructureMatched(jetsMCP, splittingsMCP, pairsMCP, preslices.D0SplittingsPerJetMCP, preslices.DplusSplittingsPerJetMCP, preslices.DstarSplittingsPerJetMCP, preslices.LcSplittingsPerJetMCP, preslices.B0SplittingsPerJetMCP, preslices.BplusSplittingsPerJetMCP, preslices.DielectronSplittingsPerJetMCP, preslices.D0PairsPerJetMCP, preslices.DplusPairsPerJetMCP, preslices.DstarPairsPerJetMCP, preslices.LcPairsPerJetMCP, preslices.B0PairsPerJetMCP, preslices.BplusPairsPerJetMCP, preslices.DielectronPairsPerJetMCP, splittingMatchesGeoVecVecMCP, splittingMatchesPtVecVecMCP, splittingMatchesHFVecVecMCP, pairMatchesVecVecMCP, configs.jetPtMinMCP); + analyseSubstructureMatched(jetsMCP, splittingsMCP, pairsMCP, preslices.D0SplittingsPerJetMCP, preslices.DplusSplittingsPerJetMCP, preslices.DsSplittingsPerJetMCP, preslices.DstarSplittingsPerJetMCP, preslices.LcSplittingsPerJetMCP, preslices.B0SplittingsPerJetMCP, preslices.BplusSplittingsPerJetMCP, preslices.XicToXiPiPiSplittingsPerJetMCP, preslices.DielectronSplittingsPerJetMCP, preslices.D0PairsPerJetMCP, preslices.DplusPairsPerJetMCP, preslices.DsPairsPerJetMCP, preslices.DstarPairsPerJetMCP, preslices.LcPairsPerJetMCP, preslices.B0PairsPerJetMCP, preslices.BplusPairsPerJetMCP, preslices.XicToXiPiPiPairsPerJetMCP, preslices.DielectronPairsPerJetMCP, splittingMatchesGeoVecVecMCP, splittingMatchesPtVecVecMCP, splittingMatchesHFVecVecMCP, pairMatchesVecVecMCP, configs.jetPtMinMCP); } PROCESS_SWITCH(JetSubstructureHFOutputTask, processOutputSubstructureMatchingMC, "jet substructure matching output MC", false); diff --git a/PWGJE/Tasks/jetSubstructureXicToXiPiPi.cxx b/PWGJE/Tasks/jetSubstructureXicToXiPiPi.cxx new file mode 100644 index 00000000000..ca58df3a425 --- /dev/null +++ b/PWGJE/Tasks/jetSubstructureXicToXiPiPi.cxx @@ -0,0 +1,39 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// jet substructure XicToXiPiPi charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/Tasks/jetSubstructureHF.cxx" + +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetSubstructure.h" +#include "PWGJE/DataModel/JetSubtraction.h" + +#include +#include +#include +#include +#include + +#include + +using JetSubstructureXicToXiPiPi = JetSubstructureHFTask, soa::Join, soa::Join, soa::Join, aod::CandidatesXicToXiPiPiData, aod::CandidatesXicToXiPiPiMCP, aod::XicToXiPiPiCJetSSs, aod::XicToXiPiPiChargedSPs, aod::XicToXiPiPiChargedPRs, aod::XicToXiPiPiCMCDJetSSs, aod::XicToXiPiPiChargedMCDetectorLevelSPs, aod::XicToXiPiPiChargedMCDetectorLevelPRs, aod::XicToXiPiPiCMCPJetSSs, aod::XicToXiPiPiChargedMCParticleLevelSPs, aod::XicToXiPiPiChargedMCParticleLevelPRs, aod::XicToXiPiPiCEWSJetSSs, aod::XicToXiPiPiChargedEventWiseSubtractedSPs, aod::XicToXiPiPiChargedEventWiseSubtractedPRs, aod::JTrackXicToXiPiPiSubs>; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + tasks.emplace_back(adaptAnalysisTask(cfgc, + SetDefaultProcesses{}, + TaskName{"jet-substructure-xictoxipipi"})); + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/Tasks/jetSubstructureXicToXiPiPiOutput.cxx b/PWGJE/Tasks/jetSubstructureXicToXiPiPiOutput.cxx new file mode 100644 index 00000000000..93d3f884090 --- /dev/null +++ b/PWGJE/Tasks/jetSubstructureXicToXiPiPiOutput.cxx @@ -0,0 +1,40 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +// jet substructure output XicToXiPiPi charged task +// +/// \author Nima Zardoshti + +#include "PWGJE/Tasks/jetSubstructureHFOutput.cxx" + +#include "PWGHF/DataModel/DerivedTables.h" +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/DataModel/JetReducedDataHF.h" +#include "PWGJE/DataModel/JetSubstructure.h" +#include "PWGJE/DataModel/JetSubtraction.h" + +#include +#include +#include +#include +#include + +#include + +using JetSubstructureOutputXicToXiPiPi = JetSubstructureHFOutputTask, aod::McCollisionsXicToXiPiPi, aod::CandidatesXicToXiPiPiData, aod::CandidatesXicToXiPiPiMCD, aod::CandidatesXicToXiPiPiMCP, aod::BkgXicToXiPiPiRhos, aod::BkgXicToXiPiPiMcRhos, aod::JTrackXicToXiPiPiSubs, soa::Join, soa::Join, soa::Join, soa::Join, aod::XicToXiPiPiCJetCOs, aod::XicToXiPiPiCJetOs, aod::XicToXiPiPiCJetSSOs, aod::XicToXiPiPiCJetMOs, soa::Join, soa::Join, soa::Join, aod::XicToXiPiPiCMCDJetCOs, aod::XicToXiPiPiCMCDJetOs, aod::XicToXiPiPiCMCDJetSSOs, aod::XicToXiPiPiCMCDJetMOs, soa::Join, soa::Join, soa::Join, soa::Join, aod::XicToXiPiPiCMCPJetCOs, aod::XicToXiPiPiCMCPJetMCCOs, aod::XicToXiPiPiCMCPJetOs, aod::XicToXiPiPiCMCPJetSSOs, aod::XicToXiPiPiCMCPJetMOs, soa::Join, soa::Join, soa::Join, aod::XicToXiPiPiCEWSJetCOs, aod::XicToXiPiPiCEWSJetOs, aod::XicToXiPiPiCEWSJetSSOs, aod::XicToXiPiPiCEWSJetMOs, aod::StoredHfXicToXiPiPiCollBase, aod::StoredHfXicToXiPiPiBases, aod::StoredHfXicToXiPiPiPars, aod::StoredHfXicToXiPiPiParEs, aod::JDumXicToXiPiPiParDaus, aod::StoredHfXicToXiPiPiSels, aod::StoredHfXicToXiPiPiMls, aod::JDumXicToXiPiPiMlDaus, aod::StoredHfXicToXiPiPiMcs, aod::StoredHfXicToXiPiPiMcCollBases, aod::StoredHfXicToXiPiPiMcRCollIds, aod::StoredHfXicToXiPiPiPBases>; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + tasks.emplace_back(adaptAnalysisTask(cfgc, SetDefaultProcesses{}, TaskName{"jet-substructure-xictoxipipi-output"})); + + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/Tasks/mcGeneratorStudies.cxx b/PWGJE/Tasks/mcGeneratorStudies.cxx index c783a0a8c09..a1bfe3a5500 100644 --- a/PWGJE/Tasks/mcGeneratorStudies.cxx +++ b/PWGJE/Tasks/mcGeneratorStudies.cxx @@ -60,6 +60,7 @@ struct MCGeneratorStudies { Configurable mRequireNoSameBunchPileup{"mRequireNoSameBunchPileup", true, "require no same bunch pileup in event cut"}; Configurable mRequireGoodZvtxFT0vsPV{"mRequireGoodZvtxFT0vsPV", true, "require good Zvtx between FT0 vs. PV in event cut"}; Configurable mRequireEMCReadoutInMB{"mRequireEMCReadoutInMB", true, "require the EMC to be read out in an MB collision (kTVXinEMC)"}; + Configurable mRequireEMCReadoutInL0{"mRequireEMCReadoutInL0", false, "require the EMC to be read out by L0 trigger"}; void init(InitContext const&) { @@ -159,7 +160,7 @@ struct MCGeneratorStudies { continue; else if (mSelectOnlyChargedParticles && TDatabasePDG::Instance()->GetParticle(mcParticle.pdgCode())->Charge()) continue; - if (fabs(mcParticle.y()) > mRapidityCut) + if (std::abs(mcParticle.y()) > mRapidityCut) continue; if (!mcParticle.isPhysicalPrimary() && !mcParticle.producedByGenerator()) continue; @@ -186,7 +187,7 @@ struct MCGeneratorStudies { continue; else if (mSelectOnlyChargedParticles && TDatabasePDG::Instance()->GetParticle(mcParticle.pdgCode())->Charge()) continue; - if (fabs(mcParticle.y()) > mRapidityCut) + if (std::abs(mcParticle.y()) > mRapidityCut) continue; if (!mcParticle.isPhysicalPrimary() && !mcParticle.producedByGenerator()) continue; @@ -198,7 +199,7 @@ struct MCGeneratorStudies { mHistManager.fill(HIST("Yield_Accepted"), mcParticle.pt()); if (!mRequireTVX || collision.selection_bit(o2::aod::evsel::kIsTriggerTVX)) { mHistManager.fill(HIST("Yield_T"), mcParticle.pt()); - if (abs(collision.posZ()) < mVertexCut) { + if (std::abs(collision.posZ()) < mVertexCut) { mHistManager.fill(HIST("Yield_TZ"), mcParticle.pt()); if (!mRequireSel8 || collision.sel8()) { mHistManager.fill(HIST("Yield_TZS"), mcParticle.pt()); @@ -207,9 +208,11 @@ struct MCGeneratorStudies { if (!mRequireNoSameBunchPileup || collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { mHistManager.fill(HIST("Yield_TZSGU"), mcParticle.pt()); if (!mRequireEMCReadoutInMB || (mRequireEMCCellContent ? collision.isemcreadout() : collision.alias_bit(kTVXinEMC))) { - mHistManager.fill(HIST("Yield_TZSGUE"), mcParticle.pt()); - if (isAccepted(mcParticle, mcParticles)) - mHistManager.fill(HIST("Yield_TZSGUE_Accepted"), mcParticle.pt()); + if (!mRequireEMCReadoutInL0 || (collision.alias_bit(kEMC7) || collision.alias_bit(kDMC7))) { + mHistManager.fill(HIST("Yield_TZSGUE"), mcParticle.pt()); + if (isAccepted(mcParticle, mcParticles)) + mHistManager.fill(HIST("Yield_TZSGUE_Accepted"), mcParticle.pt()); + } } } } @@ -271,7 +274,7 @@ struct MCGeneratorStudies { fRegistry->fill(HIST("hEMCollisionCounter"), 7.0); if (collision.sel8()) fRegistry->fill(HIST("hEMCollisionCounter"), 8.0); - if (abs(collision.posZ()) < 10.0) + if (std::abs(collision.posZ()) < 10.0) fRegistry->fill(HIST("hEMCollisionCounter"), 9.0); if (collision.alias_bit(kTVXinEMC)) fRegistry->fill(HIST("hEMCollisionCounter"), 10.0); @@ -284,7 +287,7 @@ struct MCGeneratorStudies { fRegistry->fill(HIST("hCollisionCounter"), 1); if (!mRequireTVX || collision.selection_bit(o2::aod::evsel::kIsTriggerTVX)) { fRegistry->fill(HIST("hCollisionCounter"), 2); - if (abs(collision.posZ()) < mVertexCut) { + if (std::abs(collision.posZ()) < mVertexCut) { fRegistry->fill(HIST("hCollisionCounter"), 3); if (!mRequireSel8 || collision.sel8()) { fRegistry->fill(HIST("hCollisionCounter"), 4); @@ -292,8 +295,11 @@ struct MCGeneratorStudies { fRegistry->fill(HIST("hCollisionCounter"), 5); if (!mRequireNoSameBunchPileup || collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { fRegistry->fill(HIST("hCollisionCounter"), 6); - if (!mRequireEMCReadoutInMB || (mRequireEMCCellContent ? collision.isemcreadout() : collision.alias_bit(kTVXinEMC))) - fRegistry->fill(HIST("hCollisionCounter"), 7); + if (!mRequireEMCReadoutInMB || (mRequireEMCCellContent ? collision.isemcreadout() : collision.alias_bit(kTVXinEMC))) { + if (!mRequireEMCReadoutInL0 || (collision.alias_bit(kEMC7) || collision.alias_bit(kDMC7))) { + fRegistry->fill(HIST("hCollisionCounter"), 7); + } + } } } } diff --git a/PWGJE/Tasks/nucleiInJets.cxx b/PWGJE/Tasks/nucleiInJets.cxx index 298850f5bf5..37fb0764947 100644 --- a/PWGJE/Tasks/nucleiInJets.cxx +++ b/PWGJE/Tasks/nucleiInJets.cxx @@ -59,6 +59,7 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::constants::physics; struct nucleiInJets { enum Particle { @@ -88,19 +89,19 @@ struct nucleiInJets { case -2212: // antip return -Particle::kProton; - case 1000010020: // Deuteron + case Pdg::kDeuteron: // Deuteron return Particle::kDeuteron; - case -1000010020: // AntiDeuteron + case -Pdg::kDeuteron: // AntiDeuteron return -Particle::kDeuteron; - case 1000010030: // Triton + case Pdg::kTriton: // Triton return Particle::kTriton; - case -1000010030: // AntiTriton + case -Pdg::kTriton: // AntiTriton return -Particle::kTriton; - case 1000020030: // Helium + case Pdg::kHelium3: // Helium return Particle::kHelium; - case -1000020030: // AntiHelium + case -Pdg::kHelium3: // AntiHelium return -Particle::kHelium; default: return 0; // Default case for unknown or unmapped PDG codes @@ -170,15 +171,6 @@ struct nucleiInJets { Configurable applySkim{"applySkim", false, "Apply skimming"}; Configurable cfgSkim{"cfgSkim", "fHighFt0Mult", "Configurable for skimming"}; - static constexpr float gMassProton = 0.93827208f; - static constexpr float gMassDeuteron = 1.87561f; - static constexpr float gMassTriton = 2.80892f; - static constexpr float gMassHelium = 2.80839f; - static constexpr int PDGProton = 2212; - static constexpr int PDGDeuteron = 1000010020; - static constexpr int PDGTriton = 1000010030; - static constexpr int PDGHelium = 1000020030; - // using EventTable = soa::Join; using EventTable = aod::JetCollisions; using EventTableMC = soa::Join; @@ -225,6 +217,7 @@ struct nucleiInJets { const AxisSpec dcaxyAxis{binsDCA, "DCAxy (cm)"}; const AxisSpec dcazAxis{binsDCA, "DCAz (cm)"}; const AxisSpec dedxAxis{binsdEdx, "d#it{E}/d#it{x} A.U."}; + const AxisSpec vzAxis{300, -15.f, 15.f, "Vz (cm)"}; const AxisSpec betaAxis{binsBeta, "TOF #beta"}; const AxisSpec ptZHeAxis{binsPtZHe, "#it{p}_{T}"}; @@ -246,6 +239,8 @@ struct nucleiInJets { jetHist.get(HIST("hNEventsInc"))->GetXaxis()->SetBinLabel(2, "Sel8"); jetHist.get(HIST("hNEventsInc"))->GetXaxis()->SetBinLabel(3, "|Vz|<10"); + jetHist.add("hNEventsIncVsCent", "hNEventsIncVsCent", {HistType::kTH2D, {{vzAxis}, {CentAxis}}}); + // TPC nSigma vs pT (inclusive) jetHist.add("tracksInc/proton/h3PtVsProtonNSigmaTPCVsPt", "pT(p) vs NSigmaTPC (p) vs centrality; #it{p}_{T} (GeV/#it{c}); NSigmaTPC; centrality", HistType::kTH3F, {PtAxis, {200, -10, 10}, CentAxis}); jetHist.add("tracksInc/antiProton/h3PtVsantiProtonNSigmaTPCVsPt", "pT(#bar{p}) vs NSigmaTPC (#bar{p}) vs centrality; #it{p}_{T} (GeV/#it{c}); NSigmaTPC; centrality", HistType::kTH3F, {PtAxis, {200, -10, 10}, CentAxis}); @@ -260,9 +255,9 @@ struct nucleiInJets { jetHist.add("jet/nJetsPerEvent", "nJetsPerEvent", kTH1F, {{15, .0, 15.}}); jetHist.add("mcpJet/nJetsPerEvent", "nJetsPerEvent", kTH1F, {{15, .0, 15.}}); jetHist.add("mcdJet/nJetsPerEvent", "nJetsPerEvent", kTH1F, {{15, .0, 15.}}); - jetHist.add("jet/vertexZ", "vertexZ (Jet flag)", kTH1F, {{100, -15.0, 15.0}}); - jetHist.add("vertexZ", "vertexZ (all)", kTH1F, {{100, -15.0, 15.0}}); - jetHist.add("jetOut/vertexZ", "vertexZ (without z-flag)", kTH1F, {{100, -15.0, 15.0}}); + jetHist.add("jet/vertexZ", "vertexZ (Jet flag)", kTH1F, {{vzAxis}}); + jetHist.add("vertexZ", "vertexZ (all)", kTH1F, {{vzAxis}}); + jetHist.add("jetOut/vertexZ", "vertexZ (without z-flag)", kTH1F, {{vzAxis}}); //////////////////////////// // MC //////////////////////////// @@ -273,8 +268,8 @@ struct nucleiInJets { h->GetXaxis()->SetBinLabel(3, "vz < 10"); h->GetXaxis()->SetBinLabel(4, "ingt0"); - jetHist.add("mcpJet/vertexZ", "vertexZ (All)", kTH1F, {{100, -15.0, 15.0}}); - jetHist.add("mcdJet/vertexZ", "vertexZ (All)", kTH1F, {{100, -15.0, 15.0}}); + jetHist.add("mcpJet/vertexZ", "vertexZ (All)", kTH1F, {{vzAxis}}); + jetHist.add("mcdJet/vertexZ", "vertexZ (All)", kTH1F, {{vzAxis}}); jetHist.add("mcdJet/eventStat", "vertexZ (All)", kTH1F, {{5, .0, 5.0}}); auto h1 = jetHist.get(HIST("mcdJet/eventStat")); h1->GetXaxis()->SetBinLabel(1, "All"); @@ -282,8 +277,8 @@ struct nucleiInJets { h1->GetXaxis()->SetBinLabel(3, "vz< 10"); h1->GetXaxis()->SetBinLabel(4, "ingt0"); - jetHist.add("recmatched/vertexZ", "vertexZ (All)", kTH1F, {{100, -15.0, 15.0}}); - jetHist.add("genmatched/vertexZ", "vertexZ (All)", kTH1F, {{100, -15.0, 15.0}}); + jetHist.add("recmatched/vertexZ", "vertexZ (All)", kTH1F, {{vzAxis}}); + jetHist.add("genmatched/vertexZ", "vertexZ (All)", kTH1F, {{vzAxis}}); ////////////////////////////////////////////// // inside jet @@ -415,18 +410,18 @@ struct nucleiInJets { if (cEnableProtonQA) { jetHist.add("tracks/proton/dca/after/hDCAxyVsPtProton", "DCAxy vs Pt (p)", HistType::kTH2F, {{dcaxyAxis}, {PtAxis}}); - jetHist.add("tracksInc/proton/dca/after/hDCAxyVsPtProton", "DCAxy vs Pt (p)", HistType::kTH2F, {{dcaxyAxis}, {PtAxis}}); + jetHist.add("tracksInc/proton/dca/after/hDCAxyVsPtProton", "DCAxy vs Pt (p)", HistType::kTH3F, {{dcaxyAxis}, {PtAxis}, {CentAxis}}); jetHist.add("tracks/antiProton/dca/after/hDCAxyVsPtantiProton", "DCAxy vs Pt (#bar{p})", HistType::kTH2F, {{dcaxyAxis}, {PtAxis}}); jetHist.add("tracks/proton/dca/after/hDCAzVsPtProton", "DCAz vs Pt (p)", HistType::kTH2F, {{dcazAxis}, {PtAxis}}); - jetHist.add("tracksInc/proton/dca/after/hDCAzVsPtProton", "DCAz vs Pt (p)", HistType::kTH2F, {{dcazAxis}, {PtAxis}}); + jetHist.add("tracksInc/proton/dca/after/hDCAzVsPtProton", "DCAz vs Pt (p)", HistType::kTH3F, {{dcazAxis}, {PtAxis}, {CentAxis}}); jetHist.add("tracks/antiProton/dca/after/hDCAzVsPtantiProton", "DCAz vs Pt (#bar{p})", HistType::kTH2F, {{dcazAxis}, {PtAxis}}); } if (cEnableDeuteronQA) { jetHist.add("tracks/deuteron/dca/after/hDCAxyVsPtDeuteron", "DCAxy vs Pt (d)", HistType::kTH2F, {{dcaxyAxis}, {PtAxis}}); - jetHist.add("tracksInc/deuteron/dca/after/hDCAxyVsPtDeuteron", "DCAxy vs Pt (d)", HistType::kTH2F, {{dcaxyAxis}, {PtAxis}}); + jetHist.add("tracksInc/deuteron/dca/after/hDCAxyVsPtDeuteron", "DCAxy vs Pt (d)", HistType::kTH3F, {{dcaxyAxis}, {PtAxis}, {CentAxis}}); jetHist.add("tracks/antiDeuteron/dca/after/hDCAxyVsPtantiDeuteron", "DCAxy vs Pt (#bar{d})", HistType::kTH2F, {{dcaxyAxis}, {PtAxis}}); jetHist.add("tracks/deuteron/dca/after/hDCAzVsPtDeuteron", "DCAz vs Pt (d)", HistType::kTH2F, {{dcazAxis}, {PtAxis}}); - jetHist.add("tracksInc/deuteron/dca/after/hDCAzVsPtDeuteron", "DCAz vs Pt (d)", HistType::kTH2F, {{dcazAxis}, {PtAxis}}); + jetHist.add("tracksInc/deuteron/dca/after/hDCAzVsPtDeuteron", "DCAz vs Pt (d)", HistType::kTH3F, {{dcazAxis}, {PtAxis}, {CentAxis}}); jetHist.add("tracks/antiDeuteron/dca/after/hDCAzVsPtantiDeuteron", "DCAz vs Pt (#bar{d})", HistType::kTH2F, {{dcazAxis}, {PtAxis}}); } if (cEnableTritonQA) { @@ -463,20 +458,20 @@ struct nucleiInJets { jetHist.add("tracks/helium/h2TOFmass2HeliumVsPt", "#Delta M^{2} (t) vs #it{p}_{T}t; TOFmass2; #it{p}_{T}/z (GeV)", HistType::kTH2F, {{massHeAxis}, {ptZHeAxis}}); jetHist.add("tracks/antiHelium/h2TOFmass2antiHeliumVsPt", "#Delta M^{2} (t) vs #it{p}_{T}; TOFmass2; #it{p}_{T}/z (GeV)", HistType::kTH2F, {{massHeAxis}, {ptZHeAxis}}); - jetHist.add("tracksInc/proton/h2TOFmassProtonVsPt", "h2TOFmassProtonVsPt; TOFmass; #it{p}_{T} (GeV)", HistType::kTH2F, {{80, 0.4, 4.}, {50, 0., 5.}}); - jetHist.add("tracksInc/antiProton/h2TOFmassantiProtonVsPt", "h2TOFmassantiProtonVsPt; TOFmass; #it{p}_{T} (GeV)", HistType::kTH2F, {{80, 0.4, 4.}, {50, 0., 5.}}); - jetHist.add("tracksInc/deuteron/h2TOFmassDeuteronVsPt", "h2TOFmassDeuteronVsPt; TOFmass; #it{p}_{T} (GeV)", HistType::kTH2F, {{80, 0.4, 4.}, {50, 0., 5.}}); - jetHist.add("tracksInc/antiDeuteron/h2TOFmassantiDeuteronVsPt", "h2TOFmassantiDeuteronVsPt; TOFmass; #it{p}_{T} (GeV)", HistType::kTH2F, {{80, 0.4, 4.}, {50, 0., 5.}}); + jetHist.add("tracksInc/proton/h2TOFmassProtonVsPt", "h2TOFmassProtonVsPt; TOFmass; #it{p}_{T} (GeV)", HistType::kTH3F, {{80, 0.4, 4.}, {50, 0., 5.}, {CentAxis}}); + jetHist.add("tracksInc/antiProton/h2TOFmassantiProtonVsPt", "h2TOFmassantiProtonVsPt; TOFmass; #it{p}_{T} (GeV)", HistType::kTH3F, {{80, 0.4, 4.}, {50, 0., 5.}, {CentAxis}}); + jetHist.add("tracksInc/deuteron/h2TOFmassDeuteronVsPt", "h2TOFmassDeuteronVsPt; TOFmass; #it{p}_{T} (GeV)", HistType::kTH3F, {{80, 0.4, 4.}, {50, 0., 5.}, {CentAxis}}); + jetHist.add("tracksInc/antiDeuteron/h2TOFmassantiDeuteronVsPt", "h2TOFmassantiDeuteronVsPt; TOFmass; #it{p}_{T} (GeV)", HistType::kTH3F, {{80, 0.4, 4.}, {50, 0., 5.}, {CentAxis}}); - jetHist.add("tracksInc/proton/h2TOFmass2ProtonVsPt", "#Delta M^{2} (t) vs #it{p}_{T}; TOFmass2; #it{p}_{T} (GeV)", HistType::kTH2F, {{massPrAxis}, {250, 0., 5.}}); - jetHist.add("tracksInc/antiProton/h2TOFmass2antiProtonVsPt", "#Delta M^{2} (t) vs #it{p}_{T}; TOFmass2; #it{p}_{T} (GeV)", HistType::kTH2F, {{massPrAxis}, {250, 0., 5.}}); - jetHist.add("tracksInc/deuteron/h2TOFmass2DeuteronVsPt", "#Delta M^{2} (t) vs #it{p}_{T}; TOFmass2; #it{p}_{T} (GeV)", HistType::kTH2F, {{massDeAxis}, {250, 0., 5.}}); - jetHist.add("tracksInc/antiDeuteron/h2TOFmass2antiDeuteronVsPt", "#Delta M^{2} (t) vs #it{p}_{T}; TOFmass2; #it{p}_{T} (GeV)", HistType::kTH2F, {{massDeAxis}, {250, 0., 5.}}); + jetHist.add("tracksInc/proton/h2TOFmass2ProtonVsPt", "#Delta M^{2} (t) vs #it{p}_{T}; TOFmass2; #it{p}_{T} (GeV)", HistType::kTH3F, {{massPrAxis}, {250, 0., 5.}, {CentAxis}}); + jetHist.add("tracksInc/antiProton/h2TOFmass2antiProtonVsPt", "#Delta M^{2} (t) vs #it{p}_{T}; TOFmass2; #it{p}_{T} (GeV)", HistType::kTH3F, {{massPrAxis}, {250, 0., 5.}, {CentAxis}}); + jetHist.add("tracksInc/deuteron/h2TOFmass2DeuteronVsPt", "#Delta M^{2} (t) vs #it{p}_{T}; TOFmass2; #it{p}_{T} (GeV)", HistType::kTH3F, {{massDeAxis}, {250, 0., 5.}, {CentAxis}}); + jetHist.add("tracksInc/antiDeuteron/h2TOFmass2antiDeuteronVsPt", "#Delta M^{2} (t) vs #it{p}_{T}; TOFmass2; #it{p}_{T} (GeV)", HistType::kTH3F, {{massDeAxis}, {250, 0., 5.}, {CentAxis}}); - jetHist.add("tracksInc/proton/h2TofNsigmaProtonVsPt", "h2TofNsigmaProtonVsPt; TofNsigma; #it{p}_{T} (GeV)", HistType::kTH2F, {{100, -5, 5}, {100, 0., 10.}}); - jetHist.add("tracksInc/antiProton/h2TofNsigmaantiProtonVsPt", "h2TofNsigmaantiProtonVsPt; TofNsigma; #it{p}_{T} (GeV)", HistType::kTH2F, {{100, -5, 5}, {100, 0., 10.}}); - jetHist.add("tracksInc/deuteron/h2TofNsigmaDeuteronVsPt", "h2TofNsigmaDeuteronVsPt; TofNsigma; #it{p}_{T} (GeV)", HistType::kTH2F, {{100, -5, 5}, {100, 0., 10.}}); - jetHist.add("tracksInc/antiDeuteron/h2TofNsigmaantiDeuteronVsPt", "h2TofNsigmaantiDeuteronVsPt; TofNsigma; #it{p}_{T} (GeV)", HistType::kTH2F, {{100, -5, 5}, {100, 0., 10.}}); + jetHist.add("tracksInc/proton/h2TofNsigmaProtonVsPt", "h2TofNsigmaProtonVsPt; TofNsigma; #it{p}_{T} (GeV)", HistType::kTH3F, {{100, -5, 5}, {100, 0., 10.}, {CentAxis}}); + jetHist.add("tracksInc/antiProton/h2TofNsigmaantiProtonVsPt", "h2TofNsigmaantiProtonVsPt; TofNsigma; #it{p}_{T} (GeV)", HistType::kTH3F, {{100, -5, 5}, {100, 0., 10.}, {CentAxis}}); + jetHist.add("tracksInc/deuteron/h2TofNsigmaDeuteronVsPt", "h2TofNsigmaDeuteronVsPt; TofNsigma; #it{p}_{T} (GeV)", HistType::kTH3F, {{100, -5, 5}, {100, 0., 10.}, {CentAxis}}); + jetHist.add("tracksInc/antiDeuteron/h2TofNsigmaantiDeuteronVsPt", "h2TofNsigmaantiDeuteronVsPt; TofNsigma; #it{p}_{T} (GeV)", HistType::kTH3F, {{100, -5, 5}, {100, 0., 10.}, {CentAxis}}); // TOF hist nSigma jetHist.add("tracks/proton/h2TofNsigmaProtonVsPt", "h2TofNsigmaProtonVsPt; TofNsigma; #it{p}_{T} (GeV)", HistType::kTH2F, {{100, -5, 5}, {50, 0., 5.}}); @@ -495,7 +490,7 @@ struct nucleiInJets { jetHist.get(HIST("recInc/eventStat"))->GetXaxis()->SetBinLabel(2, "Sel8"); jetHist.get(HIST("recInc/eventStat"))->GetXaxis()->SetBinLabel(3, "|Vz|<10"); - jetHist.add("recInc/vertexZ", "vertexZ (inclusive)", HistType::kTH1F, {{100, -15.0, 15.0}}); + jetHist.add("recInc/vertexZ", "vertexZ (inclusive)", HistType::kTH2F, {{vzAxis}, {CentAxis}}); jetHist.add("recInc/pt/PtParticleTypeTPC", "Pt vs ParticleType vs Centrality (TPC)", HistType::kTH3F, {{100, 0.f, 10.f}, {14, -7, 7}, {100, 0, 100}}); jetHist.add("recInc/pt/PtParticleTypeTPCTOF", "Pt vs ParticleType vs Centrality (TPC+TOF)", HistType::kTH3F, {{100, 0.f, 10.f}, {14, -7, 7}, {100, 0, 100}}); jetHist.add("recInc/pt/PtParticleTypeTPCTOFVeto", "Pt vs ParticleType vs Centrality (TPC+TOF Veto)", HistType::kTH3F, {{100, 0.f, 10.f}, {14, -7, 7}, {100, 0, 100}}); @@ -643,8 +638,8 @@ struct nucleiInJets { { std::array PerpendicularConeAxisPhi = {-999.0f, -999.0f}; // build 2 perp cones in phi around the leading jet (right and left of the jet) - PerpendicularConeAxisPhi[0] = RecoDecay::constrainAngle(jetPhi + (M_PI / 2.)); // This will contrain the angel between 0-2Pi - PerpendicularConeAxisPhi[1] = RecoDecay::constrainAngle(jetPhi - (M_PI / 2.)); // This will contrain the angel between 0-2Pi + PerpendicularConeAxisPhi[0] = RecoDecay::constrainAngle(jetPhi + (o2::constants::math::PIHalf)); // This will contrain the angel between 0-2Pi + PerpendicularConeAxisPhi[1] = RecoDecay::constrainAngle(jetPhi - (o2::constants::math::PIHalf)); // This will contrain the angel between 0-2Pi return PerpendicularConeAxisPhi; } @@ -711,7 +706,7 @@ struct nucleiInJets { if (isWithLeadingJet) { double delPhi = TVector2::Phi_mpi_pi(leadingJetPtEtaPhi[2] - trk.phi()); double delEta = leadingJetPtEtaPhi[1] - trk.eta(); - double R = TMath::Sqrt((delEta * delEta) + (delPhi * delPhi)); + double R = RecoDecay::sumOfSquares(delEta, delPhi); if (R < cfgjetR) jetFlag = true; jetPt = leadingJetPtEtaPhi[0]; @@ -719,15 +714,15 @@ struct nucleiInJets { std::array perpConePhiJet = getPerpendicuarPhi(leadingJetPtEtaPhi[2]); double delPhiPerpCone1 = TVector2::Phi_mpi_pi(perpConePhiJet[0] - trk.phi()); double delPhiPerpCone2 = TVector2::Phi_mpi_pi(perpConePhiJet[1] - trk.phi()); - double RPerpCone1 = TMath::Sqrt((delEta * delEta) + (delPhiPerpCone1 * delPhiPerpCone1)); - double RPerpCone2 = TMath::Sqrt((delEta * delEta) + (delPhiPerpCone2 * delPhiPerpCone2)); + double RPerpCone1 = RecoDecay::sumOfSquares(delEta, delPhiPerpCone1); + double RPerpCone2 = RecoDecay::sumOfSquares(delEta, delPhiPerpCone2); if (RPerpCone1 < cfgjetR || RPerpCone2 < cfgjetR) jetFlagPerpCone = true; } else { for (auto const& jet : jets) { double delPhi = TVector2::Phi_mpi_pi(jet.phi() - trk.phi()); double delEta = jet.eta() - trk.eta(); - double R = TMath::Sqrt((delEta * delEta) + (delPhi * delPhi)); + double R = RecoDecay::sumOfSquares(delEta, delPhi); if (R < cfgjetR) jetFlag = true; jetPt = jet.pt(); @@ -737,7 +732,7 @@ struct nucleiInJets { // tof float massTOF = -999; if (trk.hasTOF()) { - massTOF = trk.p() * TMath::Sqrt(1.f / (trk.beta() * trk.beta()) - 1.f); + massTOF = trk.p() * std::sqrt(1.f / (trk.beta() * trk.beta()) - 1.f); } if (addTOFplots && trk.hasTOF()) { @@ -819,13 +814,13 @@ struct nucleiInJets { if (addTOFplots && trk.hasTOF()) { if (!useTPCpreSel) { jetHist.fill(HIST("tracks/proton/h2TOFmassProtonVsPt_jet"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/proton/h2TOFmass2ProtonVsPt_jet"), massTOF * massTOF - gMassProton * gMassProton, trk.pt()); + jetHist.fill(HIST("tracks/proton/h2TOFmass2ProtonVsPt_jet"), massTOF * massTOF - MassProton * MassProton, trk.pt()); jetHist.fill(HIST("tracks/deuteron/h2TOFmassDeuteronVsPt_jet"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/deuteron/h2TOFmass2DeuteronVsPt_jet"), massTOF * massTOF - gMassDeuteron * gMassDeuteron, trk.pt()); + jetHist.fill(HIST("tracks/deuteron/h2TOFmass2DeuteronVsPt_jet"), massTOF * massTOF - MassDeuteron * MassDeuteron, trk.pt()); jetHist.fill(HIST("tracks/triton/h2TOFmassTritonVsPt_jet"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/triton/h2TOFmass2TritonVsPt_jet"), massTOF * massTOF - gMassTriton * gMassTriton, trk.pt()); + jetHist.fill(HIST("tracks/triton/h2TOFmass2TritonVsPt_jet"), massTOF * massTOF - MassTriton * MassTriton, trk.pt()); jetHist.fill(HIST("tracks/helium/h2TOFmassHeliumVsPt_jet"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/helium/h2TOFmass2HeliumVsPt_jet"), massTOF * massTOF - gMassHelium * gMassHelium, trk.pt()); + jetHist.fill(HIST("tracks/helium/h2TOFmass2HeliumVsPt_jet"), massTOF * massTOF - MassHelium3 * MassHelium3, trk.pt()); jetHist.fill(HIST("tracks/proton/h2TofNsigmaProtonVsPt_jet"), trk.tofNSigmaPr(), trk.pt()); jetHist.fill(HIST("tracks/deuteron/h2TofNsigmaDeuteronVsPt_jet"), trk.tofNSigmaDe(), trk.pt()); jetHist.fill(HIST("tracks/helium/h2TofNsigmaHeliumVsPt_jet"), trk.tofNSigmaHe(), trk.pt()); @@ -835,24 +830,24 @@ struct nucleiInJets { } else { if (std::abs(trk.tpcNSigmaPr()) < cfgnTPCPIDPr) { jetHist.fill(HIST("tracks/proton/h2TOFmassProtonVsPt_jet"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/proton/h2TOFmass2ProtonVsPt_jet"), massTOF * massTOF - gMassProton * gMassProton, trk.pt()); + jetHist.fill(HIST("tracks/proton/h2TOFmass2ProtonVsPt_jet"), massTOF * massTOF - MassProton * MassProton, trk.pt()); jetHist.fill(HIST("tracks/proton/h2TofNsigmaProtonVsPt_jet"), trk.tofNSigmaPr(), trk.pt()); jetHist.fill(HIST("tracks/proton/h3TpcNsigmaTofNsigmaProtonVsPt_jet"), trk.tpcNSigmaPr(), trk.tofNSigmaPr(), trk.pt()); } if (std::abs(trk.tpcNSigmaDe()) < cfgnTPCPIDDe) { jetHist.fill(HIST("tracks/deuteron/h2TOFmassDeuteronVsPt_jet"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/deuteron/h2TOFmass2DeuteronVsPt_jet"), massTOF * massTOF - gMassDeuteron * gMassDeuteron, trk.pt()); + jetHist.fill(HIST("tracks/deuteron/h2TOFmass2DeuteronVsPt_jet"), massTOF * massTOF - MassDeuteron * MassDeuteron, trk.pt()); jetHist.fill(HIST("tracks/deuteron/h2TofNsigmaDeuteronVsPt_jet"), trk.tofNSigmaDe(), trk.pt()); jetHist.fill(HIST("tracks/deuteron/h3TpcNsigmaTofNsigmaDeuteronVsPt_jet"), trk.tpcNSigmaDe(), trk.tofNSigmaDe(), trk.pt()); } if (std::abs(trk.tpcNSigmaTr()) < cfgnTPCPIDTr) { jetHist.fill(HIST("tracks/triton/h2TOFmassTritonVsPt_jet"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/triton/h2TOFmass2TritonVsPt_jet"), massTOF * massTOF - gMassTriton * gMassTriton, trk.pt()); + jetHist.fill(HIST("tracks/triton/h2TOFmass2TritonVsPt_jet"), massTOF * massTOF - MassTriton * MassTriton, trk.pt()); jetHist.fill(HIST("tracks/triton/h2TofNsigmaTritonVsPt_jet"), trk.tofNSigmaTr(), trk.pt()); } if (std::abs(trk.tpcNSigmaHe()) < cfgnTPCPIDHe) { jetHist.fill(HIST("tracks/helium/h2TOFmassHeliumVsPt_jet"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/helium/h2TOFmass2HeliumVsPt_jet"), massTOF * massTOF - gMassHelium * gMassHelium, trk.pt()); + jetHist.fill(HIST("tracks/helium/h2TOFmass2HeliumVsPt_jet"), massTOF * massTOF - MassHelium3 * MassHelium3, trk.pt()); jetHist.fill(HIST("tracks/helium/h2TofNsigmaHeliumVsPt_jet"), trk.tofNSigmaHe(), trk.pt()); } } @@ -935,43 +930,41 @@ struct nucleiInJets { if (addTOFplots && trk.hasTOF()) { if (!useTPCpreSel) { jetHist.fill(HIST("tracks/antiProton/h2TOFmassantiProtonVsPt_jet"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/antiProton/h2TOFmass2antiProtonVsPt_jet"), massTOF * massTOF - gMassProton * gMassProton, trk.pt()); + jetHist.fill(HIST("tracks/antiProton/h2TOFmass2antiProtonVsPt_jet"), massTOF * massTOF - MassProton * MassProton, trk.pt()); jetHist.fill(HIST("tracks/antiProton/h2TofNsigmaantiProtonVsPt_jet"), trk.tofNSigmaPr(), trk.pt()); jetHist.fill(HIST("tracks/antiProton/h3TpcNsigmaTofNsigmaantiProtonVsPt_jet"), trk.tpcNSigmaPr(), trk.tofNSigmaPr(), trk.pt()); - jetHist.fill(HIST("tracks/antiDeuteron/h2TOFmassantiDeuteronVsPt_jet"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/antiDeuteron/h2TOFmass2antiDeuteronVsPt_jet"), massTOF * massTOF - gMassDeuteron * gMassDeuteron, trk.pt()); + jetHist.fill(HIST("tracks/antiDeuteron/h2TOFmass2antiDeuteronVsPt_jet"), massTOF * massTOF - MassDeuteron * MassDeuteron, trk.pt()); jetHist.fill(HIST("tracks/antiDeuteron/h2TofNsigmaantiDeuteronVsPt_jet"), trk.tofNSigmaDe(), trk.pt()); jetHist.fill(HIST("tracks/antiDeuteron/h3TpcNsigmaTofNsigmaantiDeuteronVsPt_jet"), trk.tpcNSigmaDe(), trk.tofNSigmaDe(), trk.pt()); jetHist.fill(HIST("tracks/antiTriton/h2TOFmassantiTritonVsPt_jet"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/antiTriton/h2TOFmass2antiTritonVsPt_jet"), massTOF * massTOF - gMassTriton * gMassTriton, trk.pt()); + jetHist.fill(HIST("tracks/antiTriton/h2TOFmass2antiTritonVsPt_jet"), massTOF * massTOF - MassTriton * MassTriton, trk.pt()); jetHist.fill(HIST("tracks/antiTriton/h2TofNsigmaantiTritonVsPt_jet"), trk.tofNSigmaTr(), trk.pt()); - jetHist.fill(HIST("tracks/antiHelium/h2TOFmassantiHeliumVsPt_jet"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/antiHelium/h2TOFmass2antiHeliumVsPt_jet"), massTOF * massTOF - gMassHelium * gMassHelium, trk.pt()); + jetHist.fill(HIST("tracks/antiHelium/h2TOFmass2antiHeliumVsPt_jet"), massTOF * massTOF - MassHelium3 * MassHelium3, trk.pt()); jetHist.fill(HIST("tracks/antiHelium/h2TofNsigmaantiHeliumVsPt_jet"), trk.tofNSigmaHe(), trk.pt()); } else { if (std::abs(trk.tpcNSigmaPr()) < cfgnTPCPIDPr) { jetHist.fill(HIST("tracks/antiProton/h2TOFmassantiProtonVsPt_jet"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/antiProton/h2TOFmass2antiProtonVsPt_jet"), massTOF * massTOF - gMassProton * gMassProton, trk.pt()); + jetHist.fill(HIST("tracks/antiProton/h2TOFmass2antiProtonVsPt_jet"), massTOF * massTOF - MassProton * MassProton, trk.pt()); jetHist.fill(HIST("tracks/antiProton/h2TofNsigmaantiProtonVsPt_jet"), trk.tofNSigmaPr(), trk.pt()); jetHist.fill(HIST("tracks/antiProton/h3TpcNsigmaTofNsigmaantiProtonVsPt_jet"), trk.tpcNSigmaPr(), trk.tofNSigmaPr(), trk.pt()); } if (std::abs(trk.tpcNSigmaDe()) < cfgnTPCPIDDe) { jetHist.fill(HIST("tracks/antiDeuteron/h2TOFmassantiDeuteronVsPt_jet"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/antiDeuteron/h2TOFmass2antiDeuteronVsPt_jet"), massTOF * massTOF - gMassDeuteron * gMassDeuteron, trk.pt()); + jetHist.fill(HIST("tracks/antiDeuteron/h2TOFmass2antiDeuteronVsPt_jet"), massTOF * massTOF - MassDeuteron * MassDeuteron, trk.pt()); jetHist.fill(HIST("tracks/antiDeuteron/h2TofNsigmaantiDeuteronVsPt_jet"), trk.tofNSigmaDe(), trk.pt()); jetHist.fill(HIST("tracks/antiDeuteron/h3TpcNsigmaTofNsigmaantiDeuteronVsPt_jet"), trk.tpcNSigmaDe(), trk.tofNSigmaDe(), trk.pt()); } if (std::abs(trk.tpcNSigmaTr()) < cfgnTPCPIDTr) { jetHist.fill(HIST("tracks/antiTriton/h2TOFmassantiTritonVsPt_jet"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/antiTriton/h2TOFmass2antiTritonVsPt_jet"), massTOF * massTOF - gMassTriton * gMassTriton, trk.pt()); + jetHist.fill(HIST("tracks/antiTriton/h2TOFmass2antiTritonVsPt_jet"), massTOF * massTOF - MassTriton * MassTriton, trk.pt()); jetHist.fill(HIST("tracks/antiTriton/h2TofNsigmaantiTritonVsPt_jet"), trk.tofNSigmaTr(), trk.pt()); } if (std::abs(trk.tpcNSigmaHe()) < cfgnTPCPIDHe) { jetHist.fill(HIST("tracks/antiHelium/h2TOFmassantiHeliumVsPt_jet"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/antiHelium/h2TOFmass2antiHeliumVsPt_jet"), massTOF * massTOF - gMassHelium * gMassHelium, trk.pt()); + jetHist.fill(HIST("tracks/antiHelium/h2TOFmass2antiHeliumVsPt_jet"), massTOF * massTOF - MassHelium3 * MassHelium3, trk.pt()); jetHist.fill(HIST("tracks/antiHelium/h2TofNsigmaantiHeliumVsPt_jet"), trk.tofNSigmaHe(), trk.pt()); } } @@ -1073,45 +1066,45 @@ struct nucleiInJets { if (addTOFplots && trk.hasTOF()) { if (!useTPCpreSel) { jetHist.fill(HIST("tracks/proton/h2TOFmassProtonVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/proton/h2TOFmass2ProtonVsPt"), massTOF * massTOF - gMassProton * gMassProton, trk.pt()); + jetHist.fill(HIST("tracks/proton/h2TOFmass2ProtonVsPt"), massTOF * massTOF - MassProton * MassProton, trk.pt()); jetHist.fill(HIST("tracks/proton/h2TofNsigmaProtonVsPt"), trk.tofNSigmaPr(), trk.pt()); jetHist.fill(HIST("tracks/deuteron/h2TOFmassDeuteronVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - gMassDeuteron * gMassDeuteron, trk.pt()); + jetHist.fill(HIST("tracks/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - MassDeuteron * MassDeuteron, trk.pt()); jetHist.fill(HIST("tracks/deuteron/h2TofNsigmaDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt()); jetHist.fill(HIST("tracks/triton/h2TOFmassTritonVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/triton/h2TOFmass2TritonVsPt"), massTOF * massTOF - gMassTriton * gMassTriton, trk.pt()); + jetHist.fill(HIST("tracks/triton/h2TOFmass2TritonVsPt"), massTOF * massTOF - MassTriton * MassTriton, trk.pt()); jetHist.fill(HIST("tracks/helium/h2TofNsigmaHeliumVsPt"), trk.tofNSigmaHe(), trk.pt()); jetHist.fill(HIST("tracks/helium/h2TOFmassHeliumVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/helium/h2TOFmass2HeliumVsPt"), massTOF * massTOF - gMassHelium * gMassHelium, trk.pt()); + jetHist.fill(HIST("tracks/helium/h2TOFmass2HeliumVsPt"), massTOF * massTOF - MassHelium3 * MassHelium3, trk.pt()); jetHist.fill(HIST("tracks/triton/h2TofNsigmaTritonVsPt"), trk.tofNSigmaTr(), trk.pt()); } else { if (std::abs(trk.tpcNSigmaPr()) < cfgnTPCPIDPr) { jetHist.fill(HIST("tracks/proton/h2TOFmassProtonVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/proton/h2TOFmass2ProtonVsPt"), massTOF * massTOF - gMassProton * gMassProton, trk.pt()); + jetHist.fill(HIST("tracks/proton/h2TOFmass2ProtonVsPt"), massTOF * massTOF - MassProton * MassProton, trk.pt()); jetHist.fill(HIST("tracks/proton/h2TofNsigmaProtonVsPt"), trk.tofNSigmaPr(), trk.pt()); if (jetFlagPerpCone && isWithLeadingJet) jetHist.fill(HIST("tracks/perpCone/proton/h2TofNsigmaProtonVsPt"), trk.tofNSigmaPr(), trk.pt()); } if (std::abs(trk.tpcNSigmaDe()) < cfgnTPCPIDDe) { jetHist.fill(HIST("tracks/deuteron/h2TOFmassDeuteronVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - gMassDeuteron * gMassDeuteron, trk.pt()); + jetHist.fill(HIST("tracks/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - MassDeuteron * MassDeuteron, trk.pt()); jetHist.fill(HIST("tracks/deuteron/h2TofNsigmaDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt()); if (jetFlagPerpCone && isWithLeadingJet) jetHist.fill(HIST("tracks/perpCone/deuteron/h2TofNsigmaDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt()); } if (std::abs(trk.tpcNSigmaTr()) < cfgnTPCPIDTr) { jetHist.fill(HIST("tracks/triton/h2TOFmassTritonVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/triton/h2TOFmass2TritonVsPt"), massTOF * massTOF - gMassTriton * gMassTriton, trk.pt()); + jetHist.fill(HIST("tracks/triton/h2TOFmass2TritonVsPt"), massTOF * massTOF - MassTriton * MassTriton, trk.pt()); jetHist.fill(HIST("tracks/triton/h2TofNsigmaTritonVsPt"), trk.tofNSigmaTr(), trk.pt()); if (jetFlagPerpCone && isWithLeadingJet) jetHist.fill(HIST("tracks/perpCone/triton/h2TofNsigmaTritonVsPt"), trk.tofNSigmaTr(), trk.pt()); } if (std::abs(trk.tpcNSigmaHe()) < cfgnTPCPIDHe) { jetHist.fill(HIST("tracks/helium/h2TOFmassHeliumVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/helium/h2TOFmass2HeliumVsPt"), massTOF * massTOF - gMassHelium * gMassHelium, trk.pt()); + jetHist.fill(HIST("tracks/helium/h2TOFmass2HeliumVsPt"), massTOF * massTOF - MassHelium3 * MassHelium3, trk.pt()); jetHist.fill(HIST("tracks/helium/h2TofNsigmaHeliumVsPt"), trk.tofNSigmaHe(), trk.pt()); if (jetFlagPerpCone && isWithLeadingJet) jetHist.fill(HIST("tracks/perpCone/helium/h2TofNsigmaHeliumVsPt"), trk.tofNSigmaHe(), trk.pt()); @@ -1191,45 +1184,45 @@ struct nucleiInJets { if (addTOFplots && trk.hasTOF()) { if (!useTPCpreSel) { jetHist.fill(HIST("tracks/antiProton/h2TOFmassantiProtonVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/antiProton/h2TOFmass2antiProtonVsPt"), massTOF * massTOF - gMassProton * gMassProton, trk.pt()); + jetHist.fill(HIST("tracks/antiProton/h2TOFmass2antiProtonVsPt"), massTOF * massTOF - MassProton * MassProton, trk.pt()); jetHist.fill(HIST("tracks/antiProton/h2TofNsigmaantiProtonVsPt"), trk.tofNSigmaPr(), trk.pt()); jetHist.fill(HIST("tracks/antiDeuteron/h2TOFmassantiDeuteronVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/antiDeuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - gMassDeuteron * gMassDeuteron, trk.pt()); + jetHist.fill(HIST("tracks/antiDeuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - MassDeuteron * MassDeuteron, trk.pt()); jetHist.fill(HIST("tracks/antiDeuteron/h2TofNsigmaantiDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt()); jetHist.fill(HIST("tracks/antiTriton/h2TOFmassantiTritonVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/antiTriton/h2TOFmass2antiTritonVsPt"), massTOF * massTOF - gMassTriton * gMassTriton, trk.pt()); + jetHist.fill(HIST("tracks/antiTriton/h2TOFmass2antiTritonVsPt"), massTOF * massTOF - MassTriton * MassTriton, trk.pt()); jetHist.fill(HIST("tracks/antiHelium/h2TofNsigmaantiHeliumVsPt"), trk.tofNSigmaHe(), trk.pt()); jetHist.fill(HIST("tracks/antiHelium/h2TOFmassantiHeliumVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/antiHelium/h2TOFmass2antiHeliumVsPt"), massTOF * massTOF - gMassHelium * gMassHelium, trk.pt()); + jetHist.fill(HIST("tracks/antiHelium/h2TOFmass2antiHeliumVsPt"), massTOF * massTOF - MassHelium3 * MassHelium3, trk.pt()); jetHist.fill(HIST("tracks/antiTriton/h2TofNsigmaantiTritonVsPt"), trk.tofNSigmaTr(), trk.pt()); } else { if (std::abs(trk.tpcNSigmaPr()) < cfgnTPCPIDPr) { jetHist.fill(HIST("tracks/antiProton/h2TOFmassantiProtonVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/antiProton/h2TOFmass2antiProtonVsPt"), massTOF * massTOF - gMassProton * gMassProton, trk.pt()); + jetHist.fill(HIST("tracks/antiProton/h2TOFmass2antiProtonVsPt"), massTOF * massTOF - MassProton * MassProton, trk.pt()); jetHist.fill(HIST("tracks/antiProton/h2TofNsigmaantiProtonVsPt"), trk.tofNSigmaPr(), trk.pt()); if (jetFlagPerpCone && isWithLeadingJet) jetHist.fill(HIST("tracks/perpCone/antiProton/h2TofNsigmaantiProtonVsPt"), trk.tofNSigmaPr(), trk.pt()); } if (std::abs(trk.tpcNSigmaDe()) < cfgnTPCPIDDe) { jetHist.fill(HIST("tracks/antiDeuteron/h2TOFmassantiDeuteronVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/antiDeuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - gMassDeuteron * gMassDeuteron, trk.pt()); + jetHist.fill(HIST("tracks/antiDeuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - MassDeuteron * MassDeuteron, trk.pt()); jetHist.fill(HIST("tracks/antiDeuteron/h2TofNsigmaantiDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt()); if (jetFlagPerpCone && isWithLeadingJet) jetHist.fill(HIST("tracks/perpCone/antiDeuteron/h2TofNsigmaantiDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt()); } if (std::abs(trk.tpcNSigmaTr()) < cfgnTPCPIDTr) { jetHist.fill(HIST("tracks/antiTriton/h2TOFmassantiTritonVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/antiTriton/h2TOFmass2antiTritonVsPt"), massTOF * massTOF - gMassTriton * gMassTriton, trk.pt()); + jetHist.fill(HIST("tracks/antiTriton/h2TOFmass2antiTritonVsPt"), massTOF * massTOF - MassTriton * MassTriton, trk.pt()); jetHist.fill(HIST("tracks/antiTriton/h2TofNsigmaantiTritonVsPt"), trk.tofNSigmaTr(), trk.pt()); if (jetFlagPerpCone && isWithLeadingJet) jetHist.fill(HIST("tracks/perpCone/antiTriton/h2TofNsigmaantiTritonVsPt"), trk.tofNSigmaTr(), trk.pt()); } if (std::abs(trk.tpcNSigmaHe()) < cfgnTPCPIDHe) { jetHist.fill(HIST("tracks/antiHelium/h2TOFmassantiHeliumVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracks/antiHelium/h2TOFmass2antiHeliumVsPt"), massTOF * massTOF - gMassHelium * gMassHelium, trk.pt()); + jetHist.fill(HIST("tracks/antiHelium/h2TOFmass2antiHeliumVsPt"), massTOF * massTOF - MassHelium3 * MassHelium3, trk.pt()); jetHist.fill(HIST("tracks/antiHelium/h2TofNsigmaantiHeliumVsPt"), trk.tofNSigmaHe(), trk.pt()); if (jetFlagPerpCone && isWithLeadingJet) jetHist.fill(HIST("tracks/perpCone/antiHelium/h2TofNsigmaantiHeliumVsPt"), trk.tofNSigmaHe(), trk.pt()); @@ -1287,7 +1280,7 @@ struct nucleiInJets { if (isWithJetEvents && nJets == 0) return; jetHist.fill(HIST("jet/h1JetEvents"), 0.5); - for (auto& track : tracks) { + for (const auto& track : tracks) { auto trk = track.track_as(); fillTrackInfo(trk, chargedjets, leadingJetWithPtEtaPhi); } @@ -1369,7 +1362,7 @@ struct nucleiInJets { default: centrality = -999; } - + jetHist.fill(HIST("hNEventsIncVsCent"), coll.posZ(), centrality); for (const auto& track : tracks) { auto trk = track.track_as(); if (!isTrackSelected(trk)) { @@ -1405,36 +1398,36 @@ struct nucleiInJets { } float massTOF = -999; if (addTOFplots && trk.hasTOF()) { - massTOF = trk.p() * TMath::Sqrt(1.f / (trk.beta() * trk.beta()) - 1.f); + massTOF = trk.p() * std::sqrt(1.f / (trk.beta() * trk.beta()) - 1.f); if (!useTPCpreSel) { - jetHist.fill(HIST("tracksInc/proton/h2TOFmassProtonVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracksInc/proton/h2TOFmass2ProtonVsPt"), massTOF * massTOF - gMassProton * gMassProton, trk.pt()); - jetHist.fill(HIST("tracksInc/proton/h2TofNsigmaProtonVsPt"), trk.tofNSigmaPr(), trk.pt()); + jetHist.fill(HIST("tracksInc/proton/h2TOFmassProtonVsPt"), massTOF, trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/proton/h2TOFmass2ProtonVsPt"), massTOF * massTOF - MassProton * MassProton, trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/proton/h2TofNsigmaProtonVsPt"), trk.tofNSigmaPr(), trk.pt(), centrality); - jetHist.fill(HIST("tracksInc/deuteron/h2TOFmassDeuteronVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracksInc/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - gMassDeuteron * gMassDeuteron, trk.pt()); - jetHist.fill(HIST("tracksInc/deuteron/h2TofNsigmaDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt()); + jetHist.fill(HIST("tracksInc/deuteron/h2TOFmassDeuteronVsPt"), massTOF, trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - MassDeuteron * MassDeuteron, trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/deuteron/h2TofNsigmaDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt(), centrality); } else { if (std::abs(trk.tpcNSigmaPr()) < cfgnTPCPIDPr) { - jetHist.fill(HIST("tracksInc/proton/h2TOFmassProtonVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracksInc/proton/h2TOFmass2ProtonVsPt"), massTOF * massTOF - gMassProton * gMassProton, trk.pt()); - jetHist.fill(HIST("tracksInc/proton/h2TofNsigmaProtonVsPt"), trk.tofNSigmaPr(), trk.pt()); + jetHist.fill(HIST("tracksInc/proton/h2TOFmassProtonVsPt"), massTOF, trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/proton/h2TOFmass2ProtonVsPt"), massTOF * massTOF - MassProton * MassProton, trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/proton/h2TofNsigmaProtonVsPt"), trk.tofNSigmaPr(), trk.pt(), centrality); } if (std::abs(trk.tpcNSigmaDe()) < cfgnTPCPIDDe) { - jetHist.fill(HIST("tracksInc/deuteron/h2TOFmassDeuteronVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracksInc/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - gMassDeuteron * gMassDeuteron, trk.pt()); - jetHist.fill(HIST("tracksInc/deuteron/h2TofNsigmaDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt()); + jetHist.fill(HIST("tracksInc/deuteron/h2TOFmassDeuteronVsPt"), massTOF, trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - MassDeuteron * MassDeuteron, trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/deuteron/h2TofNsigmaDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt(), centrality); } } } if (cEnableProtonQA && std::abs(trk.tpcNSigmaPr()) < cfgnTPCPIDPr) { - jetHist.fill(HIST("tracksInc/proton/dca/after/hDCAxyVsPtProton"), trk.dcaXY(), trk.pt()); - jetHist.fill(HIST("tracksInc/proton/dca/after/hDCAzVsPtProton"), trk.dcaZ(), trk.pt()); + jetHist.fill(HIST("tracksInc/proton/dca/after/hDCAxyVsPtProton"), trk.dcaXY(), trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/proton/dca/after/hDCAzVsPtProton"), trk.dcaZ(), trk.pt(), centrality); } if (cEnableDeuteronQA && std::abs(trk.tpcNSigmaDe()) < cfgnTPCPIDDe) { - jetHist.fill(HIST("tracksInc/deuteron/dca/after/hDCAxyVsPtDeuteron"), trk.dcaXY(), trk.pt()); - jetHist.fill(HIST("tracksInc/deuteron/dca/after/hDCAzVsPtDeuteron"), trk.dcaZ(), trk.pt()); + jetHist.fill(HIST("tracksInc/deuteron/dca/after/hDCAxyVsPtDeuteron"), trk.dcaXY(), trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/deuteron/dca/after/hDCAzVsPtDeuteron"), trk.dcaZ(), trk.pt(), centrality); } } else { // anti-particle info @@ -1464,29 +1457,29 @@ struct nucleiInJets { } float massTOF = -999; if (addTOFplots && trk.hasTOF()) { - massTOF = trk.p() * TMath::Sqrt(1.f / (trk.beta() * trk.beta()) - 1.f); + massTOF = trk.p() * std::sqrt(1.f / (trk.beta() * trk.beta()) - 1.f); if (!useTPCpreSel) { - jetHist.fill(HIST("tracksInc/antiProton/h2TOFmassantiProtonVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracksInc/antiProton/h2TOFmass2antiProtonVsPt"), massTOF * massTOF - gMassProton * gMassProton, trk.pt()); - jetHist.fill(HIST("tracksInc/antiProton/h2TofNsigmaantiProtonVsPt"), trk.tofNSigmaPr(), trk.pt()); + jetHist.fill(HIST("tracksInc/antiProton/h2TOFmassantiProtonVsPt"), massTOF, trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/antiProton/h2TOFmass2antiProtonVsPt"), massTOF * massTOF - MassProton * MassProton, trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/antiProton/h2TofNsigmaantiProtonVsPt"), trk.tofNSigmaPr(), trk.pt(), centrality); - jetHist.fill(HIST("tracksInc/antiDeuteron/h2TOFmassantiDeuteronVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracksInc/antiDeuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - gMassDeuteron * gMassDeuteron, trk.pt()); - jetHist.fill(HIST("tracksInc/antiDeuteron/h2TofNsigmaantiDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt()); + jetHist.fill(HIST("tracksInc/antiDeuteron/h2TOFmassantiDeuteronVsPt"), massTOF, trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/antiDeuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - MassDeuteron * MassDeuteron, trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/antiDeuteron/h2TofNsigmaantiDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt(), centrality); } else { if (std::abs(trk.tpcNSigmaPr()) < cfgnTPCPIDPr) { - jetHist.fill(HIST("tracksInc/antiProton/h2TOFmassantiProtonVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracksInc/antiProton/h2TOFmass2antiProtonVsPt"), massTOF * massTOF - gMassProton * gMassProton, trk.pt()); - jetHist.fill(HIST("tracksInc/antiProton/h2TofNsigmaantiProtonVsPt"), trk.tofNSigmaPr(), trk.pt()); + jetHist.fill(HIST("tracksInc/antiProton/h2TOFmassantiProtonVsPt"), massTOF, trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/antiProton/h2TOFmass2antiProtonVsPt"), massTOF * massTOF - MassProton * MassProton, trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/antiProton/h2TofNsigmaantiProtonVsPt"), trk.tofNSigmaPr(), trk.pt(), centrality); } if (std::abs(trk.tpcNSigmaDe()) < cfgnTPCPIDDe) { - jetHist.fill(HIST("tracksInc/antiDeuteron/h2TOFmassantiDeuteronVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracksInc/antiDeuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - gMassDeuteron * gMassDeuteron, trk.pt()); - jetHist.fill(HIST("tracksInc/antiDeuteron/h2TofNsigmaantiDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt()); + jetHist.fill(HIST("tracksInc/antiDeuteron/h2TOFmassantiDeuteronVsPt"), massTOF, trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/antiDeuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - MassDeuteron * MassDeuteron, trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/antiDeuteron/h2TofNsigmaantiDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt(), centrality); } else { - jetHist.fill(HIST("tracksInc/antiDeuteron/h2TOFmassantiDeuteronVsPt"), massTOF, trk.pt()); - jetHist.fill(HIST("tracksInc/antiDeuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - gMassDeuteron * gMassDeuteron, trk.pt()); - jetHist.fill(HIST("tracksInc/antiDeuteron/h2TofNsigmaantiDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt()); + jetHist.fill(HIST("tracksInc/antiDeuteron/h2TOFmassantiDeuteronVsPt"), massTOF, trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/antiDeuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - MassDeuteron * MassDeuteron, trk.pt(), centrality); + jetHist.fill(HIST("tracksInc/antiDeuteron/h2TofNsigmaantiDeuteronVsPt"), trk.tofNSigmaDe(), trk.pt(), centrality); } } } @@ -1518,7 +1511,7 @@ struct nucleiInJets { jetHist.fill(HIST("mcpJet/eventStat"), 3.5); int nJets = 0; - for (auto& mcpjet : mcpjets) { + for (const auto& mcpjet : mcpjets) { jetHist.fill(HIST("mcpJet/hJetPt"), mcpjet.pt()); jetHist.fill(HIST("mcpJet/hJetEta"), mcpjet.eta()); jetHist.fill(HIST("mcpJet/hJetPhi"), mcpjet.phi()); @@ -1536,10 +1529,10 @@ struct nucleiInJets { bool jetFlag = false; // float jetPt = -999.; - for (auto& mcpjet : mcpjets) { + for (const auto& mcpjet : mcpjets) { double delPhi = TVector2::Phi_mpi_pi(mcpjet.phi() - mcParticle.phi()); double delEta = mcpjet.eta() - mcParticle.eta(); - double R = TMath::Sqrt((delEta * delEta) + (delPhi * delPhi)); + double R = RecoDecay::sqrtSumOfSquares(delEta, delPhi); if (R < cfgjetR) jetFlag = true; // jetPt = mcpjet.pt(); @@ -1592,7 +1585,7 @@ struct nucleiInJets { jetHist.fill(HIST("mcdJet/nJetsPerEvent"), nJets); if (isWithJetEvents && nJets == 0) return; - for (auto& track : tracks) { + for (const auto& track : tracks) { auto fullTrack = track.track_as(); if (!isTrackSelected(fullTrack)) continue; @@ -1609,21 +1602,21 @@ struct nucleiInJets { if (isWithLeadingJet) { double delPhi = TVector2::Phi_mpi_pi(leadingJetWithPtEtaPhi[2] - track.phi()); double delEta = leadingJetWithPtEtaPhi[1] - track.eta(); - double R = TMath::Sqrt((delEta * delEta) + (delPhi * delPhi)); + double R = RecoDecay::sqrtSumOfSquares(delEta, delPhi); if (R < cfgjetR) jetFlag = true; std::array perpConePhiJet = getPerpendicuarPhi(leadingJetWithPtEtaPhi[2]); double delPhiPerpCone1 = TVector2::Phi_mpi_pi(perpConePhiJet[0] - track.phi()); double delPhiPerpCone2 = TVector2::Phi_mpi_pi(perpConePhiJet[1] - track.phi()); - double RPerpCone1 = TMath::Sqrt((delEta * delEta) + (delPhiPerpCone1 * delPhiPerpCone1)); - double RPerpCone2 = TMath::Sqrt((delEta * delEta) + (delPhiPerpCone2 * delPhiPerpCone2)); + double RPerpCone1 = RecoDecay::sqrtSumOfSquares(delEta, delPhiPerpCone1); + double RPerpCone2 = RecoDecay::sqrtSumOfSquares(delEta, delPhiPerpCone2); if (RPerpCone1 < cfgjetR || RPerpCone2 < cfgjetR) jetFlagPerpCone = true; } else { - for (auto& mcdjet : mcdjets) { + for (const auto& mcdjet : mcdjets) { double delPhi = TVector2::Phi_mpi_pi(mcdjet.phi() - track.phi()); double delEta = mcdjet.eta() - track.eta(); - double R = TMath::Sqrt((delEta * delEta) + (delPhi * delPhi)); + double R = RecoDecay::sqrtSumOfSquares(delEta, delPhi); if (R < cfgjetR) jetFlag = true; // jetPt = mcdjet.pt(); @@ -1673,10 +1666,10 @@ struct nucleiInJets { if (mcdjets.size() == 0) return; std::vector leadingJetWithPtEtaPhi(3); - for (auto& mcdjet : mcdjets) { + for (const auto& mcdjet : mcdjets) { if (!mcdjet.has_matchedJetGeo()) continue; - for (auto& mcpjet : mcdjet.template matchedJetGeo_as()) { + for (const auto& mcpjet : mcdjet.template matchedJetGeo_as()) { if (!mcpjet.has_matchedJetGeo()) continue; @@ -1750,21 +1743,21 @@ struct nucleiInJets { if (isWithLeadingJet) { double delPhi = TVector2::Phi_mpi_pi(leadingJetWithPtEtaPhi[2] - track.phi()); double delEta = leadingJetWithPtEtaPhi[1] - track.eta(); - double R = TMath::Sqrt((delEta * delEta) + (delPhi * delPhi)); + double R = RecoDecay::sqrtSumOfSquares(delEta, delPhi); if (R < cfgjetR) jetFlag = true; std::array perpConePhiJet = getPerpendicuarPhi(leadingJetWithPtEtaPhi[2]); double delPhiPerpCone1 = TVector2::Phi_mpi_pi(perpConePhiJet[0] - track.phi()); double delPhiPerpCone2 = TVector2::Phi_mpi_pi(perpConePhiJet[1] - track.phi()); - double RPerpCone1 = TMath::Sqrt((delEta * delEta) + (delPhiPerpCone1 * delPhiPerpCone1)); - double RPerpCone2 = TMath::Sqrt((delEta * delEta) + (delPhiPerpCone2 * delPhiPerpCone2)); + double RPerpCone1 = RecoDecay::sqrtSumOfSquares(delEta, delPhiPerpCone1); + double RPerpCone2 = RecoDecay::sqrtSumOfSquares(delEta, delPhiPerpCone2); if (RPerpCone1 < cfgjetR || RPerpCone2 < cfgjetR) jetFlagPerpCone = true; } else { for (std::size_t iDJet = 0; iDJet < mcdJetPt.size(); iDJet++) { double delPhi = TVector2::Phi_mpi_pi(mcdJetPhi[iDJet] - track.phi()); double delEta = mcdJetEta[iDJet] - track.eta(); - double R = TMath::Sqrt((delEta * delEta) + (delPhi * delPhi)); + double R = RecoDecay::sqrtSumOfSquares(delEta, delPhi); if (R < cfgjetR) { jetFlag = true; @@ -1827,14 +1820,14 @@ struct nucleiInJets { if (isWithLeadingJet) { double delPhi = TVector2::Phi_mpi_pi(leadingJetWithPtEtaPhi[2] - mcParticle.phi()); double delEta = leadingJetWithPtEtaPhi[1] - mcParticle.eta(); - double R = TMath::Sqrt((delEta * delEta) + (delPhi * delPhi)); + double R = RecoDecay::sqrtSumOfSquares(delEta, delPhi); if (R < cfgjetR) jetFlagMC = true; std::array perpConePhiJet = getPerpendicuarPhi(leadingJetWithPtEtaPhi[2]); double delPhiPerpCone1 = TVector2::Phi_mpi_pi(perpConePhiJet[0] - mcParticle.phi()); double delPhiPerpCone2 = TVector2::Phi_mpi_pi(perpConePhiJet[1] - mcParticle.phi()); - double RPerpCone1 = TMath::Sqrt((delEta * delEta) + (delPhiPerpCone1 * delPhiPerpCone1)); - double RPerpCone2 = TMath::Sqrt((delEta * delEta) + (delPhiPerpCone2 * delPhiPerpCone2)); + double RPerpCone1 = RecoDecay::sqrtSumOfSquares(delEta, delPhiPerpCone1); + double RPerpCone2 = RecoDecay::sqrtSumOfSquares(delEta, delPhiPerpCone2); if (RPerpCone1 < cfgjetR || RPerpCone2 < cfgjetR) jetFlagPerpConeMC = true; } else { @@ -1842,7 +1835,7 @@ struct nucleiInJets { for (std::size_t iDJet = 0; iDJet < mcdJetPt.size(); iDJet++) { double delPhi = TVector2::Phi_mpi_pi(mcdJetPhi[iDJet] - mcParticle.phi()); double delEta = mcdJetEta[iDJet] - mcParticle.eta(); - double R = TMath::Sqrt((delEta * delEta) + (delPhi * delPhi)); + double R = RecoDecay::sqrtSumOfSquares(delEta, delPhi); if (R < cfgjetR) { jetFlagMC = true; break; @@ -1911,7 +1904,7 @@ struct nucleiInJets { jetHist.fill(HIST("genmatched/leadingJet/hGenJetPt"), leadingMCPJet.pt()); if (leadingMCPJet.has_matchedJetGeo()) { jetHist.fill(HIST("genmatched/leadingJet/hGenJetPtMatched"), leadingMCPJet.pt()); - for (auto& mcdjet : leadingMCPJet.template matchedJetGeo_as()) { + for (const auto& mcdjet : leadingMCPJet.template matchedJetGeo_as()) { // Assuming matchedJetGeo_as returns valid MCD jets; no redundant has check needed // Store jet properties mcdJetPt.push_back(mcdjet.pt()); @@ -1950,7 +1943,7 @@ struct nucleiInJets { for (std::size_t iDJet = 0; iDJet < mcpJetPt.size(); iDJet++) { double delPhi = TVector2::Phi_mpi_pi(mcpJetPhi[iDJet] - mcParticle.phi()); double delEta = mcpJetEta[iDJet] - mcParticle.eta(); - double R = TMath::Sqrt((delEta * delEta) + (delPhi * delPhi)); + double R = RecoDecay::sqrtSumOfSquares(delEta, delPhi); if (R < cfgjetR) { jetFlag = true; @@ -1971,8 +1964,6 @@ struct nucleiInJets { jetHist.fill(HIST("recInc/eventStat"), 1.5); if (std::abs(coll.posZ()) > 10) // bad vertex return; - - jetHist.fill(HIST("recInc/vertexZ"), coll.posZ()); jetHist.fill(HIST("recInc/eventStat"), 2.5); float centrality = -999; @@ -1989,7 +1980,7 @@ struct nucleiInJets { default: centrality = -999; } - + jetHist.fill(HIST("recInc/vertexZ"), coll.posZ(), centrality); for (const auto& track : tracks) { if (!isTrackSelected(track)) { continue; diff --git a/PWGJE/Tasks/recoilJets.cxx b/PWGJE/Tasks/recoilJets.cxx index 1a7b3c785ff..286b0b5004c 100644 --- a/PWGJE/Tasks/recoilJets.cxx +++ b/PWGJE/Tasks/recoilJets.cxx @@ -1,4 +1,4 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// Copyright 2020-2022 CERN and copyright holders of ALICE O2. // See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. // All rights not expressly granted are reserved. // @@ -19,6 +19,7 @@ #include "PWGJE/DataModel/JetSubtraction.h" #include "Common/Core/RecoDecay.h" +#include "Common/DataModel/Multiplicity.h" #include "CommonConstants/MathConstants.h" #include "Framework/ASoA.h" @@ -29,6 +30,7 @@ #include #include #include +#include #include #include "TRandom3.h" @@ -47,63 +49,105 @@ using namespace o2::framework; using namespace o2::framework::expressions; // Shorthand notations -using FilteredColl = soa::Filtered>::iterator; -using FilteredCollPartLevel = soa::Filtered>::iterator; -using FilteredCollDetLevelGetWeight = soa::Filtered>::iterator; - -using FilteredJets = soa::Filtered>; -using FilteredJetsDetLevel = soa::Filtered>; -using FilteredJetsPartLevel = soa::Filtered>; - -using FilteredMatchedJetsDetLevel = soa::Filtered>; -using FilteredMatchedJetsPartLevel = soa::Filtered>; +using FilteredColl = + soa::Filtered>::iterator; +using FilteredCollPartLevel = + soa::Filtered>::iterator; +using FilteredCollDetLevelGetWeight = + soa::Filtered>::iterator; +using FilteredEventMultiplicity = + soa::Filtered>::iterator; + +using FilteredJets = + soa::Filtered>; +using FilteredJetsDetLevel = + soa::Filtered>; +using FilteredJetsPartLevel = + soa::Filtered>; + +using FilteredMatchedJetsDetLevel = soa::Filtered>; +using FilteredMatchedJetsPartLevel = soa::Filtered>; using FilteredTracks = soa::Filtered; +using FilteredParticles = soa::Filtered; struct RecoilJets { // List of configurable parameters Configurable evSel{"evSel", "sel8", "Choose event selection"}; - Configurable trkSel{"trkSel", "globalTracks", "Set track selection"}; + Configurable trkSel{"trkSel", "globalTracks", + "Set track selection"}; Configurable vertexZCut{"vertexZCut", 10., "Accepted z-vertex range"}; - Configurable fracSig{"fracSig", 0.9, "Fraction of events to use for signal TT"}; - Configurable bGetMissJets{"bGetMissJets", false, "Flag to get miss histo for particle level jets"}; + Configurable fracSig{"fracSig", 0.9, + "Fraction of events to use for signal TT"}; - Configurable trkPtMin{"trkPtMin", 0.15, "Minimum pT of acceptanced tracks"}; - Configurable trkPtMax{"trkPtMax", 100., "Maximum pT of acceptanced tracks"}; + Configurable trkPtMin{"trkPtMin", 0.15, + "Minimum pT of acceptanced tracks"}; + Configurable trkPtMax{"trkPtMax", 100., + "Maximum pT of acceptanced tracks"}; Configurable trkEtaCut{"trkEtaCut", 0.9, "Eta acceptance of TPC"}; Configurable jetR{"jetR", 0.4, "Jet cone radius"}; - Configurable triggerMasks{"triggerMasks", "", "Relevant trigger masks: fTrackLowPt,fTrackHighPt"}; - Configurable skipMBGapEvents{"skipMBGapEvents", false, "flag to choose to reject min. bias gap events; jet-level rejection applied at the jet finder level, here rejection is applied for collision and track process functions"}; + Configurable triggerMasks{"triggerMasks", "", + "Relevant trigger masks: fTrackLowPt,fTrackHighPt"}; + Configurable skipMBGapEvents{"skipMBGapEvents", false, + "flag to choose to reject min. bias gap events; jet-level rejection " + "applied at the jet finder level, here rejection is applied for " + "collision and track process functions"}; + + Configurable meanFT0A{"meanFT0A", -1.0, "Mean value of FT0A"}; + + Configurable meanFT0C{"meanFT0C", -1.0, "Mean value of FT0C"}; + + Configurable meanFT0M{"meanFT0M", -1.0, "Mean value of FT0M"}; // List of configurable parameters for MC - Configurable pTHatExponent{"pTHatExponent", 4.0, "Exponent of the event weight for the calculation of pTHat"}; - Configurable pTHatMax{"pTHatMax", 999.0, "Maximum fraction of hard scattering for jet acceptance in MC"}; + Configurable pTHatExponent{"pTHatExponent", 4.0, + "Exponent of the event weight for the calculation of pTHat"}; + Configurable pTHatMax{"pTHatMax", 999.0, + "Maximum fraction of hard scattering for jet acceptance in MC"}; // Parameters for recoil jet selection - Configurable ptTTrefMin{"ptTTrefMin", 5., "Minimum pT of reference TT"}; - Configurable ptTTrefMax{"ptTTrefMax", 7., "Maximum pT of reference TT"}; + Configurable ptTTrefMin{"ptTTrefMin", 5., + "Minimum pT of reference TT"}; + Configurable ptTTrefMax{"ptTTrefMax", 7., + "Maximum pT of reference TT"}; Configurable ptTTsigMin{"ptTTsigMin", 20., "Minimum pT of signal TT"}; Configurable ptTTsigMax{"ptTTsigMax", 50., "Maximum pT of signal TT"}; - Configurable recoilRegion{"recoilRegion", 0.6, "Width of recoil acceptance"}; + Configurable recoilRegion{"recoilRegion", 0.6, + "Width of recoil acceptance"}; + + Configurable maxJetConstituentPt{"maxJetConstituentPt", 100., + "Remove jets with constituent above this pt cut"}; // List of configurable parameters for histograms - Configurable histJetPt{"histJetPt", 100, "Maximum value of jet pT shown in histograms"}; + Configurable histJetPt{"histJetPt", 100, + "Maximum value of jet pT shown in histograms"}; // Axes specification AxisSpec pT{histJetPt, 0.0, histJetPt * 1.0, "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec jetPTcorr{histJetPt + 20, -20., histJetPt * 1.0, "#it{p}_{T, jet}^{ch, corr} (GeV/#it{c})"}; + AxisSpec jetPTcorr{histJetPt + 20, -20., histJetPt * 1.0, + "#it{p}_{T, jet}^{ch, corr} (GeV/#it{c})"}; AxisSpec phiAngle{40, 0.0, constants::math::TwoPI, "#it{#varphi} (rad)"}; - AxisSpec deltaPhiAngle{52, 0.0, constants::math::PI, "#Delta#it{#varphi} (rad)"}; + AxisSpec deltaPhiAngle{52, 0.0, constants::math::PI, + "#Delta#it{#varphi} (rad)"}; AxisSpec pseudorap{40, -1., 1., "#it{#eta}"}; AxisSpec pseudorapJets{20, -0.5, 0.5, "#it{#eta}_{jet}"}; AxisSpec jetArea{50, 0.0, 5., "Area_{jet}"}; AxisSpec rhoArea{60, 0.0, 60., "#it{#rho} #times Area_{jet}"}; AxisSpec rho{50, 0.0, 50., "#it{#rho}"}; - Preslice partJetsPerCollision = aod::jet::mcCollisionId; + Preslice partJetsPerCollision = + aod::jet::mcCollisionId; TRandom3* rand = new TRandom3(0); @@ -111,8 +155,10 @@ struct RecoilJets { Filter collisionFilter = nabs(aod::jcollision::posZ) < vertexZCut; Filter collisionFilterMC = nabs(aod::jmccollision::posZ) < vertexZCut; - // Declare filters on accepted tracks and MC particles (settings for jet reco are provided in the jet finder wagon) - Filter trackFilter = aod::jtrack::pt > trkPtMin&& aod::jtrack::pt < trkPtMax&& nabs(aod::jtrack::eta) < trkEtaCut; + // Declare filters on accepted tracks and MC particles (settings for jet reco + // are provided in the jet finder wagon) + Filter trackFilter = aod::jtrack::pt > trkPtMin&& aod::jtrack::pt < + trkPtMax&& nabs(aod::jtrack::eta) < trkEtaCut; Filter partFilter = nabs(aod::jmcparticle::eta) < trkEtaCut; // Declare filter on jets @@ -131,114 +177,281 @@ struct RecoilJets { std::string evSelToString = static_cast(evSel); std::string trkSelToString = static_cast(trkSel); - eventSelectionBits = jetderiveddatautilities::initialiseEventSelectionBits(evSelToString); - trackSelection = jetderiveddatautilities::initialiseTrackSelection(trkSelToString); - triggerMaskBits = jetderiveddatautilities::initialiseTriggerMaskBits(triggerMasks); + eventSelectionBits = + jetderiveddatautilities::initialiseEventSelectionBits(evSelToString); + trackSelection = + jetderiveddatautilities::initialiseTrackSelection(trkSelToString); + triggerMaskBits = + jetderiveddatautilities::initialiseTriggerMaskBits(triggerMasks); // List of raw and MC det. distributions if (doprocessData || doprocessMCDetLevel || doprocessMCDetLevelWeighted) { - spectra.add("hEventSelectionCount", "Count # of events in the analysis", kTH1F, {{3, 0.0, 3.}}); - spectra.get(HIST("hEventSelectionCount"))->GetXaxis()->SetBinLabel(1, "Total # of events"); - spectra.get(HIST("hEventSelectionCount"))->GetXaxis()->SetBinLabel(2, Form("# of events after sel. %s", evSelToString.data())); - spectra.get(HIST("hEventSelectionCount"))->GetXaxis()->SetBinLabel(3, "# of events w. outlier"); - - spectra.add("vertexZ", "Z vertex of collisions", kTH1F, {{60, -12., 12.}}); - spectra.add("hHasAssocMcCollision", "Has det. level coll. associat. MC coll.", kTH1F, {{2, 0.0, 2.}}); - spectra.get(HIST("hHasAssocMcCollision"))->GetXaxis()->SetBinLabel(1, "Yes"); - spectra.get(HIST("hHasAssocMcCollision"))->GetXaxis()->SetBinLabel(2, "No"); - - spectra.add("hTrackSelectionCount", "Count # of tracks in the analysis", kTH1F, {{2, 0.0, 2.}}); - spectra.get(HIST("hTrackSelectionCount"))->GetXaxis()->SetBinLabel(1, "Total # of tracks"); - spectra.get(HIST("hTrackSelectionCount"))->GetXaxis()->SetBinLabel(2, Form("# of tracks after sel. %s", trkSelToString.data())); - - spectra.add("hTrackPtEtaPhi", "Charact. of tracks", kTH3F, {pT, pseudorap, phiAngle}); - - spectra.add("hTTSig_pT", "pT spectrum of all found TT_{Sig} cand.", kTH1F, {{40, 10., 50.}}); // needed to distinguish merged data from diff. wagons - - spectra.add("hNtrig", "Total number of selected triggers per class", kTH1F, {{2, 0.0, 2.}}); + spectra.add("hEventSelectionCount", "Count # of events in the analysis", + kTH1F, {{3, 0.0, 3.}}); + spectra.get(HIST("hEventSelectionCount")) + ->GetXaxis() + ->SetBinLabel(1, "Total # of events"); + spectra.get(HIST("hEventSelectionCount")) + ->GetXaxis() + ->SetBinLabel( + 2, Form("# of events after sel. %s", evSelToString.data())); + spectra.get(HIST("hEventSelectionCount")) + ->GetXaxis() + ->SetBinLabel(3, "# of events w. outlier"); + + spectra.add("vertexZ", "Z vertex of collisions", kTH1F, + {{60, -12., 12.}}); + spectra.add("hHasAssocMcCollision", + "Has det. level coll. associat. MC coll.", kTH1F, + {{2, 0.0, 2.}}); + spectra.get(HIST("hHasAssocMcCollision")) + ->GetXaxis() + ->SetBinLabel(1, "Yes"); + spectra.get(HIST("hHasAssocMcCollision")) + ->GetXaxis() + ->SetBinLabel(2, "No"); + + spectra.add("hTrackSelectionCount", "Count # of tracks in the analysis", + kTH1F, {{2, 0.0, 2.}}); + spectra.get(HIST("hTrackSelectionCount")) + ->GetXaxis() + ->SetBinLabel(1, "Total # of tracks"); + spectra.get(HIST("hTrackSelectionCount")) + ->GetXaxis() + ->SetBinLabel( + 2, Form("# of tracks after sel. %s", trkSelToString.data())); + + spectra.add("hTrackPtEtaPhi", "Charact. of tracks", kTH3F, + {pT, pseudorap, phiAngle}); + + spectra.add( + "hTTSig_pT", "pT spectrum of all found TT_{Sig} cand.", kTH1F, + {{40, 10., + 50.}}); // needed to distinguish merged data from diff. wagons + + spectra.add("hNtrig", "Total number of selected triggers per class", + kTH1F, {{2, 0.0, 2.}}); spectra.get(HIST("hNtrig"))->GetXaxis()->SetBinLabel(1, "TT_{ref}"); spectra.get(HIST("hNtrig"))->GetXaxis()->SetBinLabel(2, "TT_{sig}"); - spectra.add("hTTRef_per_event", "Number of TT_{Ref} per event", kTH1F, {{15, 0.5, 15.5}}); - spectra.add("hTTSig_per_event", "Number of TT_{Sig} per event", kTH1F, {{10, 0.5, 10.5}}); - - spectra.add("hJetPtEtaPhiRhoArea", "Charact. of inclusive jets", kTHnSparseF, {pT, pseudorapJets, phiAngle, rho, jetArea}); - - spectra.add("hDPhi_JetPt_Corr_TTRef", "Events w. TT_{Ref}: #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH2F, {deltaPhiAngle, jetPTcorr}); - spectra.add("hDPhi_JetPt_Corr_TTSig", "Events w. TT_{Sig}: #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH2F, {deltaPhiAngle, jetPTcorr}); - spectra.add("hDPhi_JetPt_TTRef", "Events w. TT_{Ref}: #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH2F, {deltaPhiAngle, pT}); - spectra.add("hDPhi_JetPt_TTSig", "Events w. TT_{Sig}: #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH2F, {deltaPhiAngle, pT}); - - spectra.add("hRecoil_JetPt_Corr_TTRef", "Events w. TT_{Ref}: #it{p}_{T} of recoil jets", kTH1F, {jetPTcorr}); - spectra.add("hRecoil_JetPt_Corr_TTSig", "Events w. TT_{Sig}: #it{p}_{T} of recoil jets", kTH1F, {jetPTcorr}); - spectra.add("hRecoil_JetPt_TTRef", "Events w. TT_{Ref}: #it{p}_{T} of recoil jets", kTH1F, {pT}); - spectra.add("hRecoil_JetPt_TTSig", "Events w. TT_{Sig}: #it{p}_{T} of recoil jets", kTH1F, {pT}); - - spectra.add("hJetArea_JetPt_Rho_TTRef", "Events w. TT_{Ref}: A_{jet} & jet pT & #rho", kTH3F, {jetArea, pT, rho}); - spectra.add("hJetArea_JetPt_Rho_TTSig", "Events w. TT_{Sig}: A_{jet} & jet pT & #rho", kTH3F, {jetArea, pT, rho}); + spectra.add("hTTRef_per_event", "Number of TT_{Ref} per event", kTH1F, + {{15, 0.5, 15.5}}); + spectra.add("hTTSig_per_event", "Number of TT_{Sig} per event", kTH1F, + {{10, 0.5, 10.5}}); + + spectra.add("hJetPtEtaPhiRhoArea", "Charact. of inclusive jets", + kTHnSparseF, {pT, pseudorapJets, phiAngle, rho, jetArea}); + + spectra.add("hDPhi_JetPt_Corr_TTRef", + "Events w. TT_{Ref}: #Delta#varphi & #it{p}_{T, jet}^{ch}", + kTH2F, {deltaPhiAngle, jetPTcorr}); + spectra.add("hDPhi_JetPt_Corr_TTSig", + "Events w. TT_{Sig}: #Delta#varphi & #it{p}_{T, jet}^{ch}", + kTH2F, {deltaPhiAngle, jetPTcorr}); + spectra.add("hDPhi_JetPt_TTRef", + "Events w. TT_{Ref}: #Delta#varphi & #it{p}_{T, jet}^{ch}", + kTH2F, {deltaPhiAngle, pT}); + spectra.add("hDPhi_JetPt_TTSig", + "Events w. TT_{Sig}: #Delta#varphi & #it{p}_{T, jet}^{ch}", + kTH2F, {deltaPhiAngle, pT}); + + spectra.add("hRecoil_JetPt_Corr_TTRef", + "Events w. TT_{Ref}: #it{p}_{T} of recoil jets", kTH1F, + {jetPTcorr}); + spectra.add("hRecoil_JetPt_Corr_TTSig", + "Events w. TT_{Sig}: #it{p}_{T} of recoil jets", kTH1F, + {jetPTcorr}); + spectra.add("hRecoil_JetPt_TTRef", + "Events w. TT_{Ref}: #it{p}_{T} of recoil jets", kTH1F, {pT}); + spectra.add("hRecoil_JetPt_TTSig", + "Events w. TT_{Sig}: #it{p}_{T} of recoil jets", kTH1F, {pT}); + + spectra.add("hJetArea_JetPt_Rho_TTRef", + "Events w. TT_{Ref}: A_{jet} & jet pT & #rho", kTH3F, + {jetArea, pT, rho}); + spectra.add("hJetArea_JetPt_Rho_TTSig", + "Events w. TT_{Sig}: A_{jet} & jet pT & #rho", kTH3F, + {jetArea, pT, rho}); } // List of MC particle level distributions if (doprocessMCPartLevel || doprocessMCPartLevelWeighted) { - spectra.add("vertexZMC", "Z vertex of jmccollision", kTH1F, {{60, -12., 12.}}); + spectra.add("vertexZMC", "Z vertex of jmccollision", kTH1F, + {{60, -12., 12.}}); spectra.add("ptHat", "Distribution of pT hat", kTH1F, {{500, 0.0, 100.}}); - spectra.add("hPartPtEtaPhi", "Charact. of particles", kTH3F, {pT, pseudorap, phiAngle}); - spectra.add("hNtrig_Part", "Total number of selected triggers per class", kTH1F, {{2, 0.0, 2.}}); - spectra.get(HIST("hNtrig_Part"))->GetXaxis()->SetBinLabel(1, "TT_{ref}"); - spectra.get(HIST("hNtrig_Part"))->GetXaxis()->SetBinLabel(2, "TT_{sig}"); - - spectra.add("hTTRef_per_event_Part", "Number of TT_{Ref} per event", kTH1F, {{15, 0.5, 15.5}}); - spectra.add("hTTSig_per_event_Part", "Number of TT_{Sig} per event", kTH1F, {{10, 0.5, 10.5}}); - - spectra.add("hJetPtEtaPhiRhoArea_Part", "Charact. of inclusive part. level jets", kTHnSparseF, {pT, pseudorapJets, phiAngle, rho, jetArea}); - - spectra.add("hDPhi_JetPt_Corr_TTRef_Part", "Events w. TT_{Ref}: #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH2F, {deltaPhiAngle, jetPTcorr}); - spectra.add("hDPhi_JetPt_Corr_TTSig_Part", "Events w. TT_{Sig}: #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH2F, {deltaPhiAngle, jetPTcorr}); - spectra.add("hDPhi_JetPt_TTRef_Part", "Events w. TT_{Ref}: #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH2F, {deltaPhiAngle, pT}); - spectra.add("hDPhi_JetPt_TTSig_Part", "Events w. TT_{Sig}: #Delta#varphi & #it{p}_{T, jet}^{ch}", kTH2F, {deltaPhiAngle, pT}); - - spectra.add("hRecoil_JetPt_Corr_TTRef_Part", "Events w. TT_{Ref}: #it{p}_{T} of recoil jets", kTH1F, {jetPTcorr}); - spectra.add("hRecoil_JetPt_Corr_TTSig_Part", "Events w. TT_{Sig}: #it{p}_{T} of recoil jets", kTH1F, {jetPTcorr}); - spectra.add("hRecoil_JetPt_TTRef_Part", "Events w. TT_{Ref}: #it{p}_{T} of recoil jets", kTH1F, {pT}); - spectra.add("hRecoil_JetPt_TTSig_Part", "Events w. TT_{Sig}: #it{p}_{T} of recoil jets", kTH1F, {pT}); - - spectra.add("hJetArea_JetPt_Rho_TTRef_Part", "Events w. TT_{Ref}: A_{jet} & jet pT & #rho", kTH3F, {jetArea, pT, rho}); - spectra.add("hJetArea_JetPt_Rho_TTSig_Part", "Events w. TT_{Sig}: A_{jet} & jet pT & #rho", kTH3F, {jetArea, pT, rho}); + spectra.add("hEventSelectionCountPartLevel", + "Count # of events in the part. level analysis", kTH1F, + {{2, 0.0, 2.}}); + spectra.get(HIST("hEventSelectionCountPartLevel")) + ->GetXaxis() + ->SetBinLabel(1, "Total # of events"); + spectra.get(HIST("hEventSelectionCountPartLevel")) + ->GetXaxis() + ->SetBinLabel(2, "# of events w. outlier"); + + spectra.add("hCountNumberOutliersFrameWork", + "Count # of outlier events based on flag from JE fw", kTH1F, + {{1, 0.0, 1.}}); + spectra.get(HIST("hCountNumberOutliersFrameWork")) + ->GetXaxis() + ->SetBinLabel(1, "Oulier flag true"); + + spectra.add("hPartPtEtaPhi", "Charact. of particles", kTH3F, + {pT, pseudorap, phiAngle}); + spectra.add("hNtrig_Part", "Total number of selected triggers per class", + kTH1F, {{2, 0.0, 2.}}); + spectra.get(HIST("hNtrig_Part")) + ->GetXaxis() + ->SetBinLabel(1, "TT_{ref}"); + spectra.get(HIST("hNtrig_Part")) + ->GetXaxis() + ->SetBinLabel(2, "TT_{sig}"); + + spectra.add("hTTRef_per_event_Part", "Number of TT_{Ref} per event", + kTH1F, {{15, 0.5, 15.5}}); + spectra.add("hTTSig_per_event_Part", "Number of TT_{Sig} per event", + kTH1F, {{10, 0.5, 10.5}}); + + spectra.add("hJetPtEtaPhiRhoArea_Part", + "Charact. of inclusive part. level jets", kTHnSparseF, + {pT, pseudorapJets, phiAngle, rho, jetArea}); + + spectra.add("hDPhi_JetPt_Corr_TTRef_Part", + "Events w. TT_{Ref}: #Delta#varphi & #it{p}_{T, jet}^{ch}", + kTH2F, {deltaPhiAngle, jetPTcorr}); + spectra.add("hDPhi_JetPt_Corr_TTSig_Part", + "Events w. TT_{Sig}: #Delta#varphi & #it{p}_{T, jet}^{ch}", + kTH2F, {deltaPhiAngle, jetPTcorr}); + spectra.add("hDPhi_JetPt_TTRef_Part", + "Events w. TT_{Ref}: #Delta#varphi & #it{p}_{T, jet}^{ch}", + kTH2F, {deltaPhiAngle, pT}); + spectra.add("hDPhi_JetPt_TTSig_Part", + "Events w. TT_{Sig}: #Delta#varphi & #it{p}_{T, jet}^{ch}", + kTH2F, {deltaPhiAngle, pT}); + + spectra.add("hRecoil_JetPt_Corr_TTRef_Part", + "Events w. TT_{Ref}: #it{p}_{T} of recoil jets", kTH1F, + {jetPTcorr}); + spectra.add("hRecoil_JetPt_Corr_TTSig_Part", + "Events w. TT_{Sig}: #it{p}_{T} of recoil jets", kTH1F, + {jetPTcorr}); + spectra.add("hRecoil_JetPt_TTRef_Part", + "Events w. TT_{Ref}: #it{p}_{T} of recoil jets", kTH1F, {pT}); + spectra.add("hRecoil_JetPt_TTSig_Part", + "Events w. TT_{Sig}: #it{p}_{T} of recoil jets", kTH1F, {pT}); + + spectra.add("hJetArea_JetPt_Rho_TTRef_Part", + "Events w. TT_{Ref}: A_{jet} & jet pT & #rho", kTH3F, + {jetArea, pT, rho}); + spectra.add("hJetArea_JetPt_Rho_TTSig_Part", + "Events w. TT_{Sig}: A_{jet} & jet pT & #rho", kTH3F, + {jetArea, pT, rho}); + + spectra.add("hDiffInOutlierRemove", + "Difference between pT hat from code and fw", kTH1F, + {{502, -0.2, 50.}}); } // Jet matching: part. vs. det. if (doprocessJetsMatched || doprocessJetsMatchedWeighted) { - spectra.add("hJetPt_DetLevel_vs_PartLevel", "Correlation jet pT at det. vs. part. levels", kTH2F, {{200, 0.0, 200.}, {200, 0.0, 200.}}); - // spectra.add("hJetPt_Corr_PartLevel_vs_DetLevel", "Correlation jet pT at part. vs. det. levels", kTH2F, {jetPTcorr, jetPTcorr}); - spectra.add("hJetPt_DetLevel_vs_PartLevel_RecoilJets", "Correlation recoil jet pT at part. vs. det. levels", kTH2F, {{200, 0.0, 200.}, {200, 0.0, 200.}}); - // spectra.add("hJetPt_Corr_PartLevel_vs_DetLevel_RecoilJets", "Correlation recoil jet pT at part. vs. det. levels", kTH2F, {jetPTcorr, jetPTcorr}); - - if (bGetMissJets) { - spectra.add("hMissedJets_pT", "Part. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}}); - // spectra.add("hMissedJets_Corr_pT", "Part. level jets w/o matched pair", kTH1F, {jetPTcorr}); - spectra.add("hMissedJets_pT_RecoilJets", "Part. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}}); - // spectra.add("hMissedJets_Corr_pT_RecoilJets", "Part. level jets w/o matched pair", kTH1F, {jetPTcorr}); - } else { - spectra.add("hFakeJets_pT", "Det. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}}); - // spectra.add("hFakeJets_Corr_pT", "Det. level jets w/o matched pair", kTH1F, {jetPTcorr}); - spectra.add("hFakeJets_pT_RecoilJets", "Det. level jets w/o matched pair", kTH1F, {{200, 0.0, 200.}}); - // spectra.add("hFakeJets_Corr_pT_RecoilJets", "Det. level jets w/o matched pair", kTH1F, {jetPTcorr}); - } - - spectra.add("hJetPt_resolution", "Jet p_{T} relative resolution as a func. of jet #it{p}_{T, part}", kTH2F, {{100, -5., 5.}, pT}); - spectra.add("hJetPt_resolution_RecoilJets", "Jet p_{T} relative resolution as a func. of jet #it{p}_{T, part}", kTH2F, {{100, -5., 5.}, pT}); - - spectra.add("hJetPhi_resolution", "#varphi resolution as a func. of jet #it{p}_{T, part}", kTH2F, {{40, -1., 1.}, pT}); - spectra.add("hJetPhi_resolution_RecoilJets", "#varphi resolution as a func. of jet #it{p}_{T, part}", kTH2F, {{40, -1., 1.}, pT}); + spectra.add("hJetPt_DetLevel_vs_PartLevel", + "Correlation jet pT at det. vs. part. levels", kTH2F, + {{200, 0.0, 200.}, {200, 0.0, 200.}}); + // spectra.add("hJetPt_Corr_PartLevel_vs_DetLevel", "Correlation jet pT at + // part. vs. det. levels", kTH2F, {jetPTcorr, jetPTcorr}); + spectra.add("hJetPt_DetLevel_vs_PartLevel_RecoilJets", + "Correlation recoil jet pT at part. vs. det. levels", kTH2F, + {{200, 0.0, 200.}, {200, 0.0, 200.}}); + // spectra.add("hJetPt_Corr_PartLevel_vs_DetLevel_RecoilJets", + // "Correlation recoil jet pT at part. vs. det. levels", kTH2F, + // {jetPTcorr, jetPTcorr}); + + spectra.add("hMissedJets_pT", "Part. level jets w/o matched pair", kTH1F, + {{200, 0.0, 200.}}); + // spectra.add("hMissedJets_Corr_pT", "Part. level jets w/o matched pair", + // kTH1F, {jetPTcorr}); + spectra.add("hMissedJets_pT_RecoilJets", + "Part. level jets w/o matched pair", kTH1F, + {{200, 0.0, 200.}}); + // spectra.add("hMissedJets_Corr_pT_RecoilJets", "Part. level jets w/o + // matched pair", kTH1F, {jetPTcorr}); + spectra.add("hFakeJets_pT", "Det. level jets w/o matched pair", kTH1F, + {{200, 0.0, 200.}}); + // spectra.add("hFakeJets_Corr_pT", "Det. level jets w/o matched pair", + // kTH1F, {jetPTcorr}); + spectra.add("hFakeJets_pT_RecoilJets", "Det. level jets w/o matched pair", + kTH1F, {{200, 0.0, 200.}}); + // spectra.add("hFakeJets_Corr_pT_RecoilJets", "Det. level jets w/o + // matched pair", kTH1F, {jetPTcorr}); + + spectra.add( + "hJetPt_resolution", + "Jet p_{T} relative resolution as a func. of jet #it{p}_{T, part}", + kTH2F, {{100, -5., 5.}, pT}); + spectra.add( + "hJetPt_resolution_RecoilJets", + "Jet p_{T} relative resolution as a func. of jet #it{p}_{T, part}", + kTH2F, {{100, -5., 5.}, pT}); + + spectra.add("hJetPhi_resolution", + "#varphi resolution as a func. of jet #it{p}_{T, part}", + kTH2F, {{40, -1., 1.}, pT}); + spectra.add("hJetPhi_resolution_RecoilJets", + "#varphi resolution as a func. of jet #it{p}_{T, part}", + kTH2F, {{40, -1., 1.}, pT}); + + spectra.add("hNumberMatchedJetsPerOneBaseJet", + "# of taged jets per 1 base jet vs. jet pT", kTH2F, + {{10, 0.5, 10.5}, {100, 0.0, 100.}}); + } - spectra.add("hNumberMatchedJetsPerOneBaseJet", "# of taged jets per 1 base jet vs. jet pT", kTH2F, {{10, 0.5, 10.5}, {100, 0.0, 100.}}); + if (doprocessMultiplicity) { + spectra.add("hMultFT0A", "Mult. signal from FTOA", kTH1F, + {{1500, 0.0, 30000.}}); + spectra.add("hMultFT0C", "Mult. signal from FTOC", kTH1F, + {{1500, 0.0, 30000.}}); + spectra.add("hMultFT0M", "Total mult. signal from FT0A & FTOC", kTH1F, + {{3000, 0.0, 60000.}}); + + spectra.add("hScaleMultFT0A", "Scaled mult. signal from FTOA", kTH1F, + {{200, 0.0, 20.}}); + spectra.add("hScaleMultFT0C", "Scaled mult. signal from FTOC", kTH1F, + {{200, 0.0, 20.}}); + spectra.add("hScaleMultFT0M", "Scaled total mult. signal from FT0A & FTOC", kTH1F, + {{2000, 0.0, 20.}}); + spectra.add("hScaleMultFT0M_v2", "Scaled total mult. signal from FT0A & FTOC", kTH1F, + {{2000, 0.0, 20.}}); + + spectra.add("hMultZNA", "Mult. signal from ZDC A-side", kTH1F, + {{500, 0.0, 10000.}}); + spectra.add("hMultZNC", "Mult. signal from ZDC C-side", kTH1F, + {{500, 0.0, 10000.}}); + spectra.add("hMultZNM", "Total mult. signal from ZDCs", kTH1F, + {{1000, 0.0, 20000.}}); + + // Correlations + spectra.add("hMultFT0A_vs_ZNA", "Correlation of signals FTOA vs ZNA", + kTH2F, {{1500, 0.0, 30000.}, {500, 0.0, 10000.}}); + spectra.add("hMultFT0C_vs_ZNC", "Correlation of signals FTOC vs ZNC", + kTH2F, {{1500, 0.0, 30000.}, {500, 0.0, 10000.}}); + spectra.add("hMultFT0M_vs_ZNM", "Correlation of signals FTOM vs ZNM", + kTH2F, {{3000, 0.0, 60000.}, {1000, 0.0, 20000.}}); + spectra.add("hScaleMultFT0A_vs_ZNA", "Correlation of signals FT0A/meanFT0A vs ZNA", + kTH2F, {{200, 0.0, 20.}, {500, 0.0, 10000.}}); + spectra.add("hScaleMultFT0C_vs_ZNC", "Correlation of signals FT0C/meanFT0C vs ZNC", + kTH2F, {{200, 0.0, 20.}, {500, 0.0, 10000.}}); + spectra.add("hScaleMultFT0M_vs_ZNM", "Correlation of signals FT0M/meanTF0M vs ZNM", + kTH2F, {{200, 0.0, 20.}, {1000, 0.0, 20000.}}); + spectra.add("hScaleMultFT0Mv2_vs_ZNM", "Correlation of signals FT0M/meanTF0M v2 vs ZNM", + kTH2F, {{200, 0.0, 20.}, {1000, 0.0, 20000.}}); } } // Fill histograms with raw or MC det. level data template - void fillHistograms(Collision const& collision, Jets const& jets, Tracks const& tracks, float weight = 1.) + void fillHistograms(Collision const& collision, Jets const& jets, + Tracks const& tracks, float weight = 1.) { bool bSigEv = false; std::vector vPhiOfTT; @@ -265,7 +478,8 @@ struct RecoilJets { continue; spectra.fill(HIST("hTrackSelectionCount"), 1.5); - spectra.fill(HIST("hTrackPtEtaPhi"), track.pt(), track.eta(), track.phi(), weight); + spectra.fill(HIST("hTrackPtEtaPhi"), track.pt(), track.eta(), track.phi(), + weight); // Search for TT candidate if (bSigEv && (track.pt() > ptTTsigMin && track.pt() < ptTTsigMax)) { @@ -294,29 +508,40 @@ struct RecoilJets { } for (const auto& jet : jets) { - spectra.fill(HIST("hJetPtEtaPhiRhoArea"), jet.pt(), jet.eta(), jet.phi(), collision.rho(), jet.area(), weight); + // skip jets which have a constituent with pT above specified cut + if (isJetWithHighPtConstituent(jet, tracks)) + continue; + + spectra.fill(HIST("hJetPtEtaPhiRhoArea"), jet.pt(), jet.eta(), jet.phi(), + collision.rho(), jet.area(), weight); if (nTT > 0) { auto [dphi, bRecoilJet] = isRecoilJet(jet, phiTT); if (bSigEv) { - spectra.fill(HIST("hDPhi_JetPt_Corr_TTSig"), dphi, jet.pt() - collision.rho() * jet.area(), weight); + spectra.fill(HIST("hDPhi_JetPt_Corr_TTSig"), dphi, + jet.pt() - collision.rho() * jet.area(), weight); spectra.fill(HIST("hDPhi_JetPt_TTSig"), dphi, jet.pt(), weight); - spectra.fill(HIST("hJetArea_JetPt_Rho_TTSig"), jet.area(), jet.pt(), collision.rho(), weight); + spectra.fill(HIST("hJetArea_JetPt_Rho_TTSig"), jet.area(), jet.pt(), + collision.rho(), weight); if (bRecoilJet) { - spectra.fill(HIST("hRecoil_JetPt_Corr_TTSig"), jet.pt() - collision.rho() * jet.area(), weight); + spectra.fill(HIST("hRecoil_JetPt_Corr_TTSig"), + jet.pt() - collision.rho() * jet.area(), weight); spectra.fill(HIST("hRecoil_JetPt_TTSig"), jet.pt(), weight); } } else { - spectra.fill(HIST("hDPhi_JetPt_Corr_TTRef"), dphi, jet.pt() - collision.rho() * jet.area(), weight); + spectra.fill(HIST("hDPhi_JetPt_Corr_TTRef"), dphi, + jet.pt() - collision.rho() * jet.area(), weight); spectra.fill(HIST("hDPhi_JetPt_TTRef"), dphi, jet.pt(), weight); - spectra.fill(HIST("hJetArea_JetPt_Rho_TTRef"), jet.area(), jet.pt(), collision.rho(), weight); + spectra.fill(HIST("hJetArea_JetPt_Rho_TTRef"), jet.area(), jet.pt(), + collision.rho(), weight); if (bRecoilJet) { - spectra.fill(HIST("hRecoil_JetPt_Corr_TTRef"), jet.pt() - collision.rho() * jet.area(), weight); + spectra.fill(HIST("hRecoil_JetPt_Corr_TTRef"), + jet.pt() - collision.rho() * jet.area(), weight); spectra.fill(HIST("hRecoil_JetPt_TTRef"), jet.pt(), weight); } } @@ -325,7 +550,8 @@ struct RecoilJets { } template - void fillMCPHistograms(Collision const& collision, Jets const& jets, Particles const& particles, float weight = 1.) + void fillMCPHistograms(Collision const& collision, Jets const& jets, + Particles const& particles, float weight = 1.) { bool bSigEv = false; std::vector vPhiOfTT; @@ -339,8 +565,10 @@ struct RecoilJets { bSigEv = true; for (const auto& jet : jets) { - if (jet.pt() > pTHatMax * pTHat) + if (jet.pt() > pTHatMax * pTHat) { + spectra.fill(HIST("hEventSelectionCountPartLevel"), 1.5); return; + } } for (const auto& particle : particles) { @@ -353,14 +581,17 @@ struct RecoilJets { if (bParticleNeutral || !particle.isPhysicalPrimary()) continue; - spectra.fill(HIST("hPartPtEtaPhi"), particle.pt(), particle.eta(), particle.phi(), weight); + spectra.fill(HIST("hPartPtEtaPhi"), particle.pt(), particle.eta(), + particle.phi(), weight); - if (bSigEv && (particle.pt() > ptTTsigMin && particle.pt() < ptTTsigMax)) { + if (bSigEv && + (particle.pt() > ptTTsigMin && particle.pt() < ptTTsigMax)) { vPhiOfTT.push_back(particle.phi()); ++nTT; } - if (!bSigEv && (particle.pt() > ptTTrefMin && particle.pt() < ptTTrefMax)) { + if (!bSigEv && + (particle.pt() > ptTTrefMin && particle.pt() < ptTTrefMax)) { vPhiOfTT.push_back(particle.phi()); ++nTT; } @@ -380,7 +611,8 @@ struct RecoilJets { } for (const auto& jet : jets) { - spectra.fill(HIST("hJetPtEtaPhiRhoArea_Part"), jet.pt(), jet.eta(), jet.phi(), collision.rho(), jet.area(), weight); + spectra.fill(HIST("hJetPtEtaPhiRhoArea_Part"), jet.pt(), jet.eta(), + jet.phi(), collision.rho(), jet.area(), weight); if (nTT > 0) { @@ -388,23 +620,29 @@ struct RecoilJets { if (bSigEv) { - spectra.fill(HIST("hDPhi_JetPt_Corr_TTSig_Part"), dphi, jet.pt() - collision.rho() * jet.area(), weight); + spectra.fill(HIST("hDPhi_JetPt_Corr_TTSig_Part"), dphi, + jet.pt() - collision.rho() * jet.area(), weight); spectra.fill(HIST("hDPhi_JetPt_TTSig_Part"), dphi, jet.pt(), weight); - spectra.fill(HIST("hJetArea_JetPt_Rho_TTSig_Part"), jet.area(), jet.pt(), collision.rho(), weight); + spectra.fill(HIST("hJetArea_JetPt_Rho_TTSig_Part"), jet.area(), + jet.pt(), collision.rho(), weight); if (bRecoilJet) { - spectra.fill(HIST("hRecoil_JetPt_Corr_TTSig_Part"), jet.pt() - collision.rho() * jet.area(), weight); + spectra.fill(HIST("hRecoil_JetPt_Corr_TTSig_Part"), + jet.pt() - collision.rho() * jet.area(), weight); spectra.fill(HIST("hRecoil_JetPt_TTSig_Part"), jet.pt(), weight); } } else { - spectra.fill(HIST("hDPhi_JetPt_Corr_TTRef_Part"), dphi, jet.pt() - collision.rho() * jet.area(), weight); + spectra.fill(HIST("hDPhi_JetPt_Corr_TTRef_Part"), dphi, + jet.pt() - collision.rho() * jet.area(), weight); spectra.fill(HIST("hDPhi_JetPt_TTRef_Part"), dphi, jet.pt(), weight); - spectra.fill(HIST("hJetArea_JetPt_Rho_TTRef_Part"), jet.area(), jet.pt(), collision.rho(), weight); + spectra.fill(HIST("hJetArea_JetPt_Rho_TTRef_Part"), jet.area(), + jet.pt(), collision.rho(), weight); if (bRecoilJet) { - spectra.fill(HIST("hRecoil_JetPt_Corr_TTRef_Part"), jet.pt() - collision.rho() * jet.area(), weight); + spectra.fill(HIST("hRecoil_JetPt_Corr_TTRef_Part"), + jet.pt() - collision.rho() * jet.area(), weight); spectra.fill(HIST("hRecoil_JetPt_TTRef_Part"), jet.pt(), weight); } } @@ -413,7 +651,9 @@ struct RecoilJets { } template - void fillMatchedHistograms(TracksTable const& tracks, JetsBase const& jetsBase, JetsTag const& jetsTag, float weight = 1.) + void fillMatchedHistograms(TracksTable const& tracks, + JetsBase const& jetsBase, JetsTag const& jetsTag, + float weight = 1.) { std::vector vPhiOfTT; double phiTTSig = 0.; @@ -439,13 +679,54 @@ struct RecoilJets { phiTTSig = getPhiTT(vPhiOfTT); for (const auto& jetBase : jetsBase) { - bool bIsBaseJetRecoil = get<1>(isRecoilJet(jetBase, phiTTSig)) && bIsThereTTSig; - dataForUnfolding(jetBase, jetsTag, bIsBaseJetRecoil, weight); + bool bIsBaseJetRecoil = + get<1>(isRecoilJet(jetBase, phiTTSig)) && bIsThereTTSig; + dataForUnfolding(jetBase, jetsTag, bIsBaseJetRecoil, tracks, weight); } } - void processData(FilteredColl const& collision, - FilteredTracks const& tracks, + template + void fillMultiplicityHistograms(Collision const& collision, + float weight = 1.) + { + + spectra.fill(HIST("hMultFT0A"), collision.multFT0A(), weight); + spectra.fill(HIST("hMultFT0C"), collision.multFT0C(), weight); + spectra.fill(HIST("hMultFT0M"), collision.multFT0M(), weight); + + float scaledFT0Mv2 = 0.5 * (collision.multFT0A() / meanFT0A + collision.multFT0C() / meanFT0C); + + spectra.fill(HIST("hScaleMultFT0A"), collision.multFT0A() / meanFT0A, weight); + spectra.fill(HIST("hScaleMultFT0C"), collision.multFT0C() / meanFT0C, weight); + spectra.fill(HIST("hScaleMultFT0M"), collision.multFT0M() / meanFT0M, weight); + spectra.fill(HIST("hScaleMultFT0M_v2"), scaledFT0Mv2, + weight); + + spectra.fill(HIST("hMultZNA"), collision.multZNA(), weight); + spectra.fill(HIST("hMultZNC"), collision.multZNC(), weight); + spectra.fill(HIST("hMultZNM"), collision.multZNA() + collision.multZNC(), + weight); + + // Correlations + spectra.fill(HIST("hMultFT0A_vs_ZNA"), collision.multFT0A(), + collision.multZNA(), weight); + spectra.fill(HIST("hMultFT0C_vs_ZNC"), collision.multFT0C(), + collision.multZNC(), weight); + spectra.fill(HIST("hMultFT0M_vs_ZNM"), collision.multFT0M(), + collision.multZNA() + collision.multZNC(), weight); + spectra.fill(HIST("hScaleMultFT0A_vs_ZNA"), collision.multFT0A() / meanFT0A, + collision.multZNA(), weight); + spectra.fill(HIST("hScaleMultFT0C_vs_ZNC"), collision.multFT0C() / meanFT0C, + collision.multZNC(), weight); + spectra.fill(HIST("hScaleMultFT0M_vs_ZNM"), collision.multFT0M() / meanFT0M, + collision.multZNA() + collision.multZNC(), weight); + spectra.fill(HIST("hScaleMultFT0Mv2_vs_ZNM"), scaledFT0Mv2, + collision.multZNA() + collision.multZNC(), weight); + } + + //------------------------------------------------------------------------------ + // Process functions + void processData(FilteredColl const& collision, FilteredTracks const& tracks, FilteredJets const& jets) { spectra.fill(HIST("hEventSelectionCount"), 0.5); @@ -473,7 +754,8 @@ struct RecoilJets { spectra.fill(HIST("vertexZ"), collision.posZ()); fillHistograms(collision, jets, tracks); } - PROCESS_SWITCH(RecoilJets, processMCDetLevel, "process MC detector level", false); + PROCESS_SWITCH(RecoilJets, processMCDetLevel, "process MC detector level", + false); void processMCDetLevelWeighted(FilteredCollDetLevelGetWeight const& collision, aod::JetMcCollisions const&, @@ -497,32 +779,46 @@ struct RecoilJets { fillHistograms(collision, jets, tracks, weight); } - PROCESS_SWITCH(RecoilJets, processMCDetLevelWeighted, "process MC detector level with event weight", false); + PROCESS_SWITCH(RecoilJets, processMCDetLevelWeighted, + "process MC detector level with event weight", false); void processMCPartLevel(FilteredCollPartLevel const& collision, - aod::JetParticles const& particles, + FilteredParticles const& particles, FilteredJetsPartLevel const& jets) { + spectra.fill(HIST("hEventSelectionCountPartLevel"), 0.5); if (skipMBGapEvent(collision)) return; spectra.fill(HIST("vertexZMC"), collision.posZ()); fillMCPHistograms(collision, jets, particles); } - PROCESS_SWITCH(RecoilJets, processMCPartLevel, "process MC particle level", false); + PROCESS_SWITCH(RecoilJets, processMCPartLevel, "process MC particle level", + false); void processMCPartLevelWeighted(FilteredCollPartLevel const& collision, - aod::JetParticles const& particles, + FilteredParticles const& particles, FilteredJetsPartLevel const& jets) { + spectra.fill(HIST("hEventSelectionCountPartLevel"), 0.5); if (skipMBGapEvent(collision)) return; auto weight = collision.weight(); + + auto calcPtHat = getPtHat(weight); + auto pThatFromFW = collision.ptHard(); + spectra.fill(HIST("hDiffInOutlierRemove"), calcPtHat - pThatFromFW); + if (collision.isOutlier()) + spectra.fill(HIST("hCountNumberOutliersFrameWork"), 0.5); + + // LOG(debug) << "Difference between pT hat: " << calcPtHat - pThatFromFW; + spectra.fill(HIST("vertexZMC"), collision.posZ(), weight); fillMCPHistograms(collision, jets, particles, weight); } - PROCESS_SWITCH(RecoilJets, processMCPartLevelWeighted, "process MC particle level with event weight", false); + PROCESS_SWITCH(RecoilJets, processMCPartLevelWeighted, + "process MC particle level with event weight", false); void processJetsMatched(FilteredCollDetLevelGetWeight const& collision, aod::JetMcCollisions const&, @@ -533,15 +829,13 @@ struct RecoilJets { if (skipEvent(collision) || skipMBGapEvent(collision)) return; - auto mcpjetsPerMCCollision = mcpjets.sliceBy(partJetsPerCollision, collision.mcCollisionId()); + auto mcpjetsPerMCCollision = + mcpjets.sliceBy(partJetsPerCollision, collision.mcCollisionId()); - if (bGetMissJets) { - fillMatchedHistograms(tracks, mcpjetsPerMCCollision, mcdjets); - } else { - fillMatchedHistograms(tracks, mcdjets, mcpjetsPerMCCollision); - } + fillMatchedHistograms(tracks, mcpjetsPerMCCollision, mcdjets); } - PROCESS_SWITCH(RecoilJets, processJetsMatched, "process matching of MC jets (no weight)", false); + PROCESS_SWITCH(RecoilJets, processJetsMatched, + "process matching of MC jets (no weight)", false); void processJetsMatchedWeighted(FilteredCollDetLevelGetWeight const& collision, aod::JetMcCollisions const&, @@ -552,16 +846,24 @@ struct RecoilJets { if (skipEvent(collision) || skipMBGapEvent(collision)) return; - auto mcpjetsPerMCCollision = mcpjets.sliceBy(partJetsPerCollision, collision.mcCollisionId()); + auto mcpjetsPerMCCollision = + mcpjets.sliceBy(partJetsPerCollision, collision.mcCollisionId()); auto weight = collision.mcCollision().weight(); - if (bGetMissJets) { - fillMatchedHistograms(tracks, mcpjetsPerMCCollision, mcdjets, weight); - } else { - fillMatchedHistograms(tracks, mcdjets, mcpjetsPerMCCollision, weight); - } + fillMatchedHistograms(tracks, mcpjetsPerMCCollision, mcdjets, weight); } - PROCESS_SWITCH(RecoilJets, processJetsMatchedWeighted, "process matching of MC jets (weighted)", false); + PROCESS_SWITCH(RecoilJets, processJetsMatchedWeighted, + "process matching of MC jets (weighted)", false); + + void processMultiplicity(FilteredEventMultiplicity const& collision) + { + if (skipEvent(collision)) + return; + + fillMultiplicityHistograms(collision); + } + PROCESS_SWITCH(RecoilJets, processMultiplicity, "process multiplicity", + false); //------------------------------------------------------------------------------ // Auxiliary functions @@ -569,13 +871,17 @@ struct RecoilJets { bool skipEvent(const Collision& coll) { /// \brief: trigger cut is needed for pp data - return !jetderiveddatautilities::selectCollision(coll, eventSelectionBits) || !jetderiveddatautilities::selectTrigger(coll, triggerMaskBits); + return !jetderiveddatautilities::selectCollision(coll, + eventSelectionBits) || + !jetderiveddatautilities::selectTrigger(coll, triggerMaskBits); } template bool skipMBGapEvent(const Collision& coll) { - return skipMBGapEvents && coll.subGeneratorId() == jetderiveddatautilities::JCollisionSubGeneratorId::mbGap; + return skipMBGapEvents && + coll.subGeneratorId() == + jetderiveddatautilities::JCollisionSubGeneratorId::mbGap; } template @@ -585,10 +891,10 @@ struct RecoilJets { } template - std::tuple isRecoilJet(const Jet& jet, - double phiTT) + std::tuple isRecoilJet(const Jet& jet, double phiTT) { - double dphi = std::fabs(RecoDecay::constrainAngle(jet.phi() - phiTT, -constants::math::PI)); + double dphi = std::fabs( + RecoDecay::constrainAngle(jet.phi() - phiTT, -constants::math::PI)); return {dphi, (constants::math::PI - recoilRegion) < dphi}; } @@ -603,54 +909,85 @@ struct RecoilJets { return 10. / (std::pow(weight, 1.0 / pTHatExponent)); } - template - void dataForUnfolding(JetBase const& jetBase, JetsTag const&, bool bIsBaseJetRecoil, float weight = 1.0) + template + bool isJetWithHighPtConstituent(Jet const& jet, Tracks const&) + { + bool bIsJetWithHighPtConstituent = false; + for (const auto& jetConstituent : jet.template tracks_as()) { + if (jetConstituent.pt() > maxJetConstituentPt) { + bIsJetWithHighPtConstituent = true; + break; + } + } + return bIsJetWithHighPtConstituent; + } + + template + void dataForUnfolding(PartJet const& partJet, DetJet const& detJets, + bool bIsBaseJetRecoil, TracksTable const& tracks, float weight = 1.) { - bool bIsThereMatchedJet = jetBase.has_matchedJetGeo(); + bool bIsThereMatchedJet = partJet.has_matchedJetGeo(); + if (bIsThereMatchedJet) { - const auto& jetsMatched = jetBase.template matchedJetGeo_as>(); + const auto& jetsMatched = + partJet.template matchedJetGeo_as>(); for (const auto& jetMatched : jetsMatched) { - spectra.fill(HIST("hNumberMatchedJetsPerOneBaseJet"), jetsMatched.size(), jetMatched.pt(), weight); - if (bGetMissJets) { - // Mean that base jet is particle level jet - spectra.fill(HIST("hJetPt_DetLevel_vs_PartLevel"), jetMatched.pt(), jetBase.pt(), weight); - spectra.fill(HIST("hJetPt_resolution"), (jetBase.pt() - jetMatched.pt()) / jetBase.pt(), jetBase.pt(), weight); - spectra.fill(HIST("hJetPhi_resolution"), jetBase.phi() - jetMatched.phi(), jetBase.pt(), weight); + // skip matches where detector level jets have a constituent with pT above specified cut + bool skipMatchedDetJet = isJetWithHighPtConstituent(jetMatched, tracks); - if (bIsBaseJetRecoil) { - spectra.fill(HIST("hJetPt_DetLevel_vs_PartLevel_RecoilJets"), jetMatched.pt(), jetBase.pt(), weight); - spectra.fill(HIST("hJetPt_resolution_RecoilJets"), (jetBase.pt() - jetMatched.pt()) / jetBase.pt(), jetBase.pt(), weight); - spectra.fill(HIST("hJetPhi_resolution_RecoilJets"), jetBase.phi() - jetMatched.phi(), jetBase.pt(), weight); - } + if (skipMatchedDetJet) { + // Miss jets + spectra.fill(HIST("hMissedJets_pT"), partJet.pt(), weight); + if (bIsBaseJetRecoil) + spectra.fill(HIST("hMissedJets_pT_RecoilJets"), partJet.pt(), weight); } else { - // Mean that base jet is detector level jet - spectra.fill(HIST("hJetPt_DetLevel_vs_PartLevel"), jetBase.pt(), jetMatched.pt(), weight); - spectra.fill(HIST("hJetPt_resolution"), (jetMatched.pt() - jetBase.pt()) / jetMatched.pt(), jetMatched.pt(), weight); - spectra.fill(HIST("hJetPhi_resolution"), jetMatched.phi() - jetBase.phi(), jetMatched.phi(), weight); + spectra.fill(HIST("hNumberMatchedJetsPerOneBaseJet"), + jetsMatched.size(), jetMatched.pt(), weight); + spectra.fill(HIST("hJetPt_DetLevel_vs_PartLevel"), jetMatched.pt(), + partJet.pt(), weight); + spectra.fill(HIST("hJetPt_resolution"), + (partJet.pt() - jetMatched.pt()) / partJet.pt(), + partJet.pt(), weight); + spectra.fill(HIST("hJetPhi_resolution"), + partJet.phi() - jetMatched.phi(), partJet.pt(), weight); if (bIsBaseJetRecoil) { - spectra.fill(HIST("hJetPt_DetLevel_vs_PartLevel_RecoilJets"), jetBase.pt(), jetMatched.pt(), weight); - spectra.fill(HIST("hJetPt_resolution_RecoilJets"), (jetMatched.pt() - jetBase.pt()) / jetMatched.pt(), jetMatched.pt(), weight); - spectra.fill(HIST("hJetPhi_resolution_RecoilJets"), jetMatched.phi() - jetBase.phi(), jetMatched.phi(), weight); + spectra.fill(HIST("hJetPt_DetLevel_vs_PartLevel_RecoilJets"), + jetMatched.pt(), partJet.pt(), weight); + spectra.fill(HIST("hJetPt_resolution_RecoilJets"), + (partJet.pt() - jetMatched.pt()) / partJet.pt(), + partJet.pt(), weight); + spectra.fill(HIST("hJetPhi_resolution_RecoilJets"), + partJet.phi() - jetMatched.phi(), partJet.pt(), weight); } } } } else { - // No closest jet - if (bGetMissJets) { - spectra.fill(HIST("hMissedJets_pT"), jetBase.pt(), weight); - if (bIsBaseJetRecoil) - spectra.fill(HIST("hMissedJets_pT_RecoilJets"), jetBase.pt(), weight); - } else { - spectra.fill(HIST("hFakeJets_pT"), jetBase.pt(), weight); + // Miss jets + spectra.fill(HIST("hMissedJets_pT"), partJet.pt(), weight); + if (bIsBaseJetRecoil) + spectra.fill(HIST("hMissedJets_pT_RecoilJets"), partJet.pt(), weight); + } + + // Fake jets + for (const auto& detJet : detJets) { + if (isJetWithHighPtConstituent(detJet, tracks)) + continue; + + bIsThereMatchedJet = detJet.has_matchedJetGeo(); + if (!bIsThereMatchedJet) { + spectra.fill(HIST("hFakeJets_pT"), detJet.pt(), weight); if (bIsBaseJetRecoil) - spectra.fill(HIST("hFakeJets_pT_RecoilJets"), jetBase.pt(), weight); + spectra.fill(HIST("hFakeJets_pT_RecoilJets"), detJet.pt(), weight); } } } }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; } +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGJE/Tasks/taskEmcExtensiveMcQa.cxx b/PWGJE/Tasks/taskEmcExtensiveMcQa.cxx new file mode 100644 index 00000000000..9c2002c9a11 --- /dev/null +++ b/PWGJE/Tasks/taskEmcExtensiveMcQa.cxx @@ -0,0 +1,229 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file taskEmcExtensiveMcQa.cxx +/// \brief Exensive monitoring task for EMCal clusters in MC +/// \author Marvin Hemmer , Goethe University Frankfurt +/// \since 31.07.2025 + +#include "PWGJE/DataModel/EMCALClusters.h" +// HF headers for event selection +#include "PWGHF/Core/CentralityEstimation.h" +#include "PWGHF/Utils/utilsEvSelHf.h" + +#include "Common/CCDB/ctpRateFetcher.h" +#include "Common/DataModel/EventSelection.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::constants; +using namespace o2::hf_evsel; +using namespace o2::hf_centrality; +using CollisionEvSels = o2::soa::Join; +using BcEvSelIt = o2::soa::Join::iterator; +using SelectedClusters = o2::soa::Filtered>; + +namespace poi +{ +enum PoI { + kPhoton = 0, + kElectronPrim = 1, + kElectronSec = 2, + kMuon = 3, + kHadronCharge = 4, + kHadronNeutral = 5, + kNPoI = 6 +}; +} // namespace poi + +/// \struct TaskEmcExtensiveMcQa +struct TaskEmcExtensiveMcQa { + + static constexpr int NSM = 20; // there 20 supermodlues for the EMCal + std::array arrPDGHadronNeutral = {kNeutron, kK0Short, kK0Long, kLambda0, physics::kXi0, kSigma0}; + + SliceCache cache; + Preslice psClusterPerCollision = o2::aod::emcalcluster::collisionId; + Preslice perCluster = o2::aod::emcalclustercell::emcalclusterId; + + HistogramRegistry mHistManager{"EMCalExtensiveMCQAHistograms"}; + + o2::emcal::Geometry* mGeometry = nullptr; + o2::framework::Service ccdb; + + ctpRateFetcher rateFetcher; + HfEventSelection hfEvSel; + HfEventSelectionMc hfEvSelMc; + + // configurable parameters + Configurable applyEvSels{"applyEvSels", true, "Flag to apply event selection."}; + Configurable clusterDefinition{"clusterDefinition", 10, "cluster definition to be selected, e.g. 10=kV3Default"}; + Configurable ctpFetcherSource{"ctpFetcherSource", "T0VTX", "Source for CTP rate fetching, e.g. T0VTX, T0CE, T0SC, ZNC (hadronic)"}; + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + + // configurable axis + ConfigurableAxis nClustersBinning{"nClustersBinning", {201, -0.5, 200.5}, "binning for the number of clusters"}; + + ConfigurableAxis clusterEnergy{"clusterEnergy", {100, 0., 10}, "binning for the cluster energy in GeV"}; + ConfigurableAxis clusterM02{"clusterM02", {100, 0., 2.0}, "binning for the cluster M02"}; + ConfigurableAxis clusterM20{"clusterM20", {100, 0., 2.0}, "binning for the cluster M20"}; + ConfigurableAxis clusterNCellBinning{"clusterNCellBinning", {100, 0.5, 100.5}, "binning for the number of cells per cluster"}; + ConfigurableAxis clusterOriginRadius{"clusterOriginRadius", {225, 0., 450}, "binning for the radial original point of the main contributor of a cluster"}; + ConfigurableAxis clusterNContributor{"clusterNContributor", {20, 0.5, 20.5}, "binning for the number of contributor of a cluster"}; + ConfigurableAxis clusterEnergyRatio{"clusterEnergyRatio", {100, 0., 10.}, "binning for ratio of the deposited energy of the leading particle to its generated momentum cluster"}; + ConfigurableAxis collisionCent{"collisionCent", {10, 0., 100.}, "binning for the event centrality"}; + + std::vector mCellTime; + + /// \brief Create output histograms and initialize geometry + void init(InitContext const&) + { + // load geometry just in case we need it + mGeometry = o2::emcal::Geometry::GetInstanceFromRunNumber(300000); + + // create common axes + const AxisSpec numberClustersAxis{nClustersBinning, "#it{N}_{cl}/ #it{N}_{event}"}; + const AxisSpec axisParticle = {poi::kNPoI, -0.5f, +poi::kNPoI - 0.5f, ""}; + const AxisSpec axisEnergy{clusterEnergy, "#it{E}_{cl} (GeV)"}; + const AxisSpec axisM02{clusterM02, "#it{M}_{02}"}; + const AxisSpec axisM20{clusterM20, "#it{M}_{20}"}; + const AxisSpec axisNCell{clusterNCellBinning, "#it{N}_{cells}"}; + const AxisSpec axisRadius{clusterOriginRadius, "#it{R}_{origin} (cm)"}; + const AxisSpec axisNContributor{clusterNContributor, "#it{N}_{particles}"}; + const AxisSpec axisCent{collisionCent, "cent (%)"}; + const AxisSpec axisLeadingEnergy{clusterEnergy, "#it{E}_{lead} (GeV)"}; + const AxisSpec axisLeadingGenMomentum{clusterEnergy, "#it{p}_{lead, gen} (GeV/#it{c})"}; + const AxisSpec axisLeadingRatio{clusterEnergy, "#it{E}_{lead}/#it{p}_{lead, gen} (#it{c})"}; + + // create histograms + + // event properties + mHistManager.add("numberOfClustersEvents", "number of clusters per event (selected events)", HistType::kTH1D, {numberClustersAxis}); + + // cluster properties (matched clusters) + mHistManager.add("hSparseClusterQA", "THnSparse for Cluster QA", HistType::kTHnSparseF, {axisEnergy, axisM02, axisM20, axisNCell, axisRadius, axisParticle, axisNContributor, axisCent}); + mHistManager.add("hSparseClusterContributors", "THnSparse with cluster contributors and energies", HistType::kTHnSparseF, {axisEnergy, axisParticle, axisNContributor, axisLeadingEnergy, axisLeadingGenMomentum, axisLeadingRatio, axisCent}); + mHistManager.add("clusterEtaPhi", "Eta and phi of cluster", HistType::kTH2F, {{140, -0.7, 0.7}, {360, 0, o2::constants::math::TwoPI}}); + + hfEvSel.addHistograms(mHistManager); + + ccdb->setURL(ccdbUrl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + } + + template + bool isCollSelected(const Coll& coll, float& cent) + { + const auto rejectionMask = hfEvSel.getHfCollisionRejectionMask(coll, cent, ccdb, mHistManager); + /// monitor the satisfied event selections + hfEvSel.fillHistograms(coll, rejectionMask, cent); + return rejectionMask == 0; + } + + /// \brief returns the PoI type of a mcparticle + /// \param mcparticle is the mcparticle we want to find the PoI type + /// \param mcparticles table containing the mcparticles + /// \return PoI type of the given mcparticle + template + int findPoIType(T const& mcparticle) + { + auto pdgValue = std::abs(mcparticle.pdgCode()); + switch (pdgValue) { + case kGamma: { + return poi::kPhoton; + } + case kElectron: { + if (mcparticle.isPhysicalPrimary()) { + return poi::kElectronPrim; + } else { + return poi::kElectronSec; + } + } + case kMuonMinus: { + return poi::kMuon; + } + default: { + auto it = std::find(arrPDGHadronNeutral.begin(), arrPDGHadronNeutral.end(), pdgValue); + if (it != arrPDGHadronNeutral.end()) { + return poi::kHadronNeutral; + } + return poi::kHadronCharge; + } + } + } + + Filter clusterDefinitionSelection = (o2::aod::emcalcluster::definition == clusterDefinition); + + /// \brief Process EMCAL clusters that are matched to a collisions + void processCollisions(CollisionEvSels const& collisions, SelectedClusters const& clusters, McParticles const& /*mcparticles*/) + { + + for (const auto& collision : collisions) { + float cent = -1.f; + if (applyEvSels && !isCollSelected(collision, cent)) { + continue; + } + + auto groupedClusters = clusters.sliceBy(psClusterPerCollision, collision.globalIndex()); + mHistManager.fill(HIST("numberOfClustersEvents"), groupedClusters.size()); + + for (const auto& cluster : groupedClusters) { + mHistManager.fill(HIST("clusterEtaPhi"), cluster.eta(), cluster.phi()); + // axisEnergy, axisTime, axisM02, axisNCell, axisRadius, axisParticle + if (cluster.mcParticle().size() == 0) { + LOG(info) << "Somehow cluster.mcParticle().size() == 0!"; + continue; + } + auto mainMcParticle = cluster.mcParticle_as()[0]; + float radius = std::hypot(mainMcParticle.vx(), mainMcParticle.vy()); + float momentum = mainMcParticle.p(); + float leadingEnergy = cluster.energy() * cluster.amplitudeA()[0]; + float leadingFraction = leadingEnergy / momentum; + mHistManager.fill(HIST("hSparseClusterQA"), cluster.energy(), cluster.m02(), cluster.m20(), cluster.nCells(), radius, findPoIType(mainMcParticle), cluster.mcParticle().size(), cent); + mHistManager.fill(HIST("hSparseClusterContributors"), cluster.energy(), findPoIType(mainMcParticle), cluster.mcParticle().size(), leadingEnergy, momentum, leadingFraction, cent); + } + } + } + PROCESS_SWITCH(TaskEmcExtensiveMcQa, processCollisions, "Process clusters from collision", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{ + adaptAnalysisTask(cfgc)}; + return workflow; +} diff --git a/PWGJE/Tasks/v0QA.cxx b/PWGJE/Tasks/v0QA.cxx index 9cd648beafd..8b79b780ae4 100644 --- a/PWGJE/Tasks/v0QA.cxx +++ b/PWGJE/Tasks/v0QA.cxx @@ -57,12 +57,15 @@ using MCPV0JetsWithConstituents = soa::Join; using MatchedMCPV0JetsWithConstituents = soa::Join; +using JetMcCollisionsWithPIs = soa::Join; + struct V0QA { HistogramRegistry registry{"registry"}; Configurable evSel{"evSel", "sel8WithoutTimeFrameBorderCut", "choose event selection"}; Configurable yPartMax{"yPartMax", 0.5, "Maximum rapidity of particles"}; Configurable vertexZCut{"vertexZCut", 10.0, "Vertex Z cut"}; + Configurable v0Fraction{"v0Fraction", 1.0, "Fraction of V0s to be kept inside jets"}; Filter jetCollisionFilter = nabs(aod::jcollision::posZ) < vertexZCut; @@ -121,72 +124,96 @@ struct V0QA { const AxisSpec axisSharedFraction{binTPCNClSharedFraction, "Fraction shared clusters TPC"}; const AxisSpec axisCrossedRowsOverFindable{binTPCCrossedRowsOverFindableCl, "Crossed rows / findable clusters TPC"}; + const bool doSumw2 = true; + if (doprocessFlags) { registry.add("inclusive/V0Flags", "V0Flags", HistType::kTH2D, {{5, -0.5, 4.5}, {5, -0.5, 4.5}}); } if (doprocessMcD) { - registry.add("inclusive/hEvents", "Events", {HistType::kTH1D, {{2, 0.0f, 2.0f}}}); - registry.add("inclusive/K0SPtEtaMass", "K0S Pt, Eta, Mass", HistType::kTH3D, {axisV0Pt, axisEta, axisK0SM}); - registry.add("inclusive/InvMassK0STrue", "Invariant mass of K0S", HistType::kTH3D, {axisV0Pt, axisV0Radius, axisK0SM}); - registry.add("inclusive/InvMassLambdaTrue", "Invariant mass of Lambda", HistType::kTH3D, {axisV0Pt, axisV0Radius, axisLambdaM}); - registry.add("inclusive/LambdaPtEtaMass", "Lambda Pt, Eta, Mass", HistType::kTH3D, {axisV0Pt, axisEta, axisLambdaM}); - registry.add("inclusive/InvMassAntiLambdaTrue", "Invariant mass of AntiLambda", HistType::kTH3D, {axisV0Pt, axisV0Radius, axisAntiLambdaM}); - registry.add("inclusive/AntiLambdaPtEtaMass", "AntiLambda Pt, Eta, Mass", HistType::kTH3D, {axisV0Pt, axisEta, axisAntiLambdaM}); + registry.add("inclusive/hEvents", "Events", {HistType::kTH1D, {{3, 0.0f, 3.0f}}}, doSumw2); + + registry.add("inclusive/K0SPtEtaMass", "K0S Pt, Eta, Mass", HistType::kTH3D, {axisV0Pt, axisEta, axisK0SM}, doSumw2); + registry.add("inclusive/InvMassK0STrue", "Invariant mass of K0S", HistType::kTH3D, {axisV0Pt, axisV0Radius, axisK0SM}, doSumw2); + registry.add("inclusive/K0SPtEtaMassWrongCollision", "K0S Pt, Eta, Mass (Wrong Collision)", HistType::kTH3D, {axisV0Pt, axisEta, axisK0SM}, doSumw2); + registry.add("inclusive/LambdaPtEtaMass", "Lambda Pt, Eta, Mass", HistType::kTH3D, {axisV0Pt, axisEta, axisLambdaM}, doSumw2); + registry.add("inclusive/InvMassLambdaTrue", "Invariant mass of Lambda", HistType::kTH3D, {axisV0Pt, axisV0Radius, axisLambdaM}, doSumw2); + registry.add("inclusive/LambdaPtEtaMassWrongCollision", "Lambda Pt, Eta, Mass (Wrong Collision)", HistType::kTH3D, {axisV0Pt, axisEta, axisLambdaM}, doSumw2); + registry.add("inclusive/AntiLambdaPtEtaMass", "AntiLambda Pt, Eta, Mass", HistType::kTH3D, {axisV0Pt, axisEta, axisAntiLambdaM}, doSumw2); + registry.add("inclusive/InvMassAntiLambdaTrue", "Invariant mass of AntiLambda", HistType::kTH3D, {axisV0Pt, axisV0Radius, axisAntiLambdaM}, doSumw2); + registry.add("inclusive/AntiLambdaPtEtaMassWrongCollision", "AntiLambda Pt, Eta, Mass (Wrong Collision)", HistType::kTH3D, {axisV0Pt, axisEta, axisAntiLambdaM}, doSumw2); + + registry.add("jets/JetPtEtaPhi", "Jet Pt, Eta, Phi", HistType::kTH3D, {axisJetPt, axisEta, axisPhi}, doSumw2); + registry.add("jets/JetPtEtaK0SPt", "Jet Pt, Eta, K0S Pt", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}, doSumw2); + registry.add("jets/JetPtEtaK0SZ", "Jet Pt, Eta, K0S Z", HistType::kTH3D, {axisJetPt, axisEta, axisV0Z}, doSumw2); + registry.add("jets/JetPtEtaK0SPtWrongCollision", "Jet Pt, Eta, K0S Pt (Wrong Collision)", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}, doSumw2); + registry.add("jets/JetPtEtaK0SZWrongCollision", "Jet Pt, Eta, K0S Z (Wrong Collision)", HistType::kTH3D, {axisJetPt, axisEta, axisV0Z}, doSumw2); + registry.add("jets/JetPtEtaLambdaPt", "Jet Pt, Eta, Lambda Pt", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}, doSumw2); + registry.add("jets/JetPtEtaLambdaZ", "Jet Pt, Eta, Lambda Z", HistType::kTH3D, {axisJetPt, axisEta, axisV0Z}, doSumw2); + registry.add("jets/JetPtEtaLambdaPtWrongCollision", "Jet Pt, Eta, Lambda Pt (Wrong Collision)", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}, doSumw2); + registry.add("jets/JetPtEtaLambdaZWrongCollision", "Jet Pt, Eta, Lambda Z (Wrong Collision)", HistType::kTH3D, {axisJetPt, axisEta, axisV0Z}, doSumw2); + registry.add("jets/JetPtEtaAntiLambdaPt", "Jet Pt, Eta, AntiLambda Pt", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}, doSumw2); + registry.add("jets/JetPtEtaAntiLambdaZ", "Jet Pt, Eta, AntiLambda Z", HistType::kTH3D, {axisJetPt, axisEta, axisV0Z}, doSumw2); + registry.add("jets/JetPtEtaAntiLambdaPtWrongCollision", "Jet Pt, Eta, AntiLambda Pt (Wrong Collision)", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}, doSumw2); + registry.add("jets/JetPtEtaAntiLambdaZWrongCollision", "Jet Pt, Eta, AntiLambda Z (Wrong Collision)", HistType::kTH3D, {axisJetPt, axisEta, axisV0Z}, doSumw2); + + registry.add("jets/JetsPtEta", "Matched Jet Pt, Eta", HistType::kTH3D, {axisJetPt, axisJetPt, axisEta}, doSumw2); + registry.add("jets/JetsPtEtaK0SPt", "Matched Jet Pt, Eta, K0S Pt", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt}, doSumw2); + registry.add("jets/JetsPtEtaK0SZ", "Matched Jet Pt, Eta, K0S Z", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Z}, doSumw2); + registry.add("jets/JetsPtEtaK0SPtWrongCollision", "Matched Jet Pt, Eta, K0S Pt (Wrong Collision)", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt}, doSumw2); + registry.add("jets/JetsPtEtaK0SZWrongCollision", "Matched Jet Pt, Eta, K0S Z (Wrong Collision)", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Z}, doSumw2); + registry.add("jets/JetsPtEtaLambdaPt", "Matched Jet Pt, Eta, Lambda Pt", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt}, doSumw2); + registry.add("jets/JetsPtEtaLambdaZ", "Matched Jet Pt, Eta, Lambda Z", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Z}, doSumw2); + registry.add("jets/JetsPtEtaLambdaPtWrongCollision", "Matched Jet Pt, Eta, Lambda Pt (Wrong Collision)", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt}, doSumw2); + registry.add("jets/JetsPtEtaLambdaZWrongCollision", "Matched Jet Pt, Eta, Lambda Z (Wrong Collision)", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Z}, doSumw2); + registry.add("jets/JetsPtEtaAntiLambdaPt", "Matched Jet Pt, Eta, AntiLambda Pt", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt}, doSumw2); + registry.add("jets/JetsPtEtaAntiLambdaZ", "Matched Jet Pt, Eta, AntiLambda Z", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Z}, doSumw2); + registry.add("jets/JetsPtEtaAntiLambdaPtWrongCollision", "Matched Jet Pt, Eta, AntiLambda Pt (Wrong Collision)", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt}, doSumw2); + registry.add("jets/JetsPtEtaAntiLambdaZWrongCollision", "Matched Jet Pt, Eta, AntiLambda Z (Wrong Collision)", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Z}, doSumw2); } if (doprocessMcP) { - registry.add("inclusive/hMcEvents", "MC Events", {HistType::kTH1D, {{2, 0.0f, 2.0f}}}); - registry.add("inclusive/GeneratedK0S", "Generated K0S", HistType::kTH3D, {axisV0Pt, axisEta, axisV0Radius}); - registry.add("inclusive/GeneratedLambda", "Generated Lambda", HistType::kTH3D, {axisV0Pt, axisEta, axisV0Radius}); - registry.add("inclusive/GeneratedAntiLambda", "Generated AntiLambda", HistType::kTH3D, {axisV0Pt, axisEta, axisV0Radius}); - } - if (doprocessMcDJets) { - registry.add("jets/hJetEvents", "Jet Events", {HistType::kTH1D, {{2, 0.0f, 2.0f}}}); - registry.add("jets/JetPtEtaK0SPt", "Jet Pt, Eta, K0S Pt", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}); - registry.add("jets/InvMassJetK0STrue", "Invariant mass of K0S in jets", HistType::kTH3D, {axisJetPt, axisV0Pt, axisK0SM}); - registry.add("jets/JetPtEtaLambdaPt", "Jet Pt, Eta, Lambda Pt", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}); - registry.add("jets/InvMassJetLambdaTrue", "Invariant mass of Lambda in jets", HistType::kTH3D, {axisJetPt, axisV0Pt, axisLambdaM}); - registry.add("jets/JetPtEtaAntiLambdaPt", "Jet Pt, Eta, AntiLambda Pt", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}); - registry.add("jets/InvMassJetAntiLambdaTrue", "Invariant mass of AntiLambda in jets", HistType::kTH3D, {axisJetPt, axisV0Pt, axisAntiLambdaM}); - } - if (doprocessMcDMatchedJets) { - registry.add("jets/hMatchedJetEvents", "Matched Jet Events", {HistType::kTH1D, {{2, 0.0f, 2.0f}}}); - registry.add("jets/JetsPtEtaK0SPt", "Matched Jet Pt, Eta, K0S Pt", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt}); - registry.add("jets/InvMassJetsK0STrue", "Invariant mass of K0S in matched jets", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisV0Pt, axisK0SM}); - registry.add("jets/JetsPtEtaLambdaPt", "Matched Jet Pt, Eta, Lambda Pt", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt}); - registry.add("jets/InvMassJetsLambdaTrue", "Invariant mass of Lambda in matched jets", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisV0Pt, axisLambdaM}); - registry.add("jets/JetsPtEtaAntiLambdaPt", "Matched Jet Pt, Eta, AntiLambda Pt", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt}); - registry.add("jets/InvMassJetsAntiLambdaTrue", "Invariant mass of AntiLambda in matched jets", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisV0Pt, axisAntiLambdaM}); - } - if (doprocessMcPJets) { - registry.add("jets/hMcJetEvents", "MC Jet Events", {HistType::kTH1D, {{2, 0.0f, 2.0f}}}); - registry.add("jets/GeneratedJetK0S", "Generated Jet K0S", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}); - registry.add("jets/GeneratedJetLambda", "Generated Jet Lambda", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}); - registry.add("jets/GeneratedJetAntiLambda", "Generated Jet AntiLambda", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}); + registry.add("inclusive/hMcEvents", "MC Events", {HistType::kTH1D, {{3, 0.0f, 3.0f}}}, doSumw2); + registry.add("inclusive/GeneratedK0S", "Generated K0S", HistType::kTH3D, {axisV0Pt, axisEta, axisV0Radius}, doSumw2); + registry.add("inclusive/GeneratedLambda", "Generated Lambda", HistType::kTH3D, {axisV0Pt, axisEta, axisV0Radius}, doSumw2); + registry.add("inclusive/GeneratedAntiLambda", "Generated AntiLambda", HistType::kTH3D, {axisV0Pt, axisEta, axisV0Radius}, doSumw2); + + registry.add("jets/GeneratedJets", "Generated Jets", HistType::kTH3D, {axisJetPt, axisEta, axisPhi}, doSumw2); + registry.add("jets/GeneratedJetK0S", "Generated Jet K0S", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}, doSumw2); + registry.add("jets/GeneratedJetK0SFrag", "Generated Jet K0S", HistType::kTH3D, {axisJetPt, axisEta, axisV0Z}, doSumw2); + registry.add("jets/GeneratedJetLambda", "Generated Jet Lambda", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}, doSumw2); + registry.add("jets/GeneratedJetLambdaFrag", "Generated Jet Lambda", HistType::kTH3D, {axisJetPt, axisEta, axisV0Z}, doSumw2); + registry.add("jets/GeneratedJetAntiLambda", "Generated Jet AntiLambda", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}, doSumw2); + registry.add("jets/GeneratedJetAntiLambdaFrag", "Generated Jet AntiLambda", HistType::kTH3D, {axisJetPt, axisEta, axisV0Z}, doSumw2); } if (doprocessCollisionAssociation) { registry.add("collisions/V0PtEta", "V0 Pt, Eta", HistType::kTH2D, {axisV0Pt, axisEta}); - registry.add("collisions/V0PtEtaWrongColl", "V0 Pt, Eta, wrong collision", HistType::kTH2D, {axisV0Pt, axisEta}); + registry.add("collisions/V0PtEtaWrongColl", "V0 Pt, Eta, (Wrong Collision)", HistType::kTH2D, {axisV0Pt, axisEta}); registry.add("collisions/K0SPtEtaMass", "K0S Pt, Eta, Mass", HistType::kTH3D, {axisV0Pt, axisEta, axisK0SM}); - registry.add("collisions/K0SPtEtaMassWrongColl", "K0S Pt, Eta, Mass, wrong collision", HistType::kTH3D, {axisV0Pt, axisEta, axisK0SM}); + registry.add("collisions/K0SPtEtaMassWrongColl", "K0S Pt, Eta, Mass, (Wrong Collision)", HistType::kTH3D, {axisV0Pt, axisEta, axisK0SM}); registry.add("collisions/LambdaPtEtaMass", "Lambda Pt, Eta, Mass", HistType::kTH3D, {axisV0Pt, axisEta, axisLambdaM}); - registry.add("collisions/LambdaPtEtaMassWrongColl", "Lambda Pt, Eta, Mass, wrong collision", HistType::kTH3D, {axisV0Pt, axisEta, axisLambdaM}); + registry.add("collisions/LambdaPtEtaMassWrongColl", "Lambda Pt, Eta, Mass, (Wrong Collision)", HistType::kTH3D, {axisV0Pt, axisEta, axisLambdaM}); registry.add("collisions/AntiLambdaPtEtaMass", "AntiLambda Pt, Eta, Mass", HistType::kTH3D, {axisV0Pt, axisEta, axisAntiLambdaM}); - registry.add("collisions/AntiLambdaPtEtaMassWrongColl", "AntiLambda Pt, Eta, Mass, wrong collision", HistType::kTH3D, {axisV0Pt, axisEta, axisAntiLambdaM}); + registry.add("collisions/AntiLambdaPtEtaMassWrongColl", "AntiLambda Pt, Eta, Mass, (Wrong Collision)", HistType::kTH3D, {axisV0Pt, axisEta, axisAntiLambdaM}); registry.add("collisions/XiMinusPtYLambdaPt", "#Xi^{-} Pt, Y, #Lambda Pt", HistType::kTH3D, {axisV0Pt, axisEta, axisV0Pt}); - registry.add("collisions/XiMinusPtYLambdaPtWrongColl", "#Xi^{-} Pt, Y, #Lambda Pt, wrong collision", HistType::kTH3D, {axisV0Pt, axisEta, axisV0Pt}); + registry.add("collisions/XiMinusPtYLambdaPtWrongColl", "#Xi^{-} Pt, Y, #Lambda Pt, (Wrong Collision)", HistType::kTH3D, {axisV0Pt, axisEta, axisV0Pt}); registry.add("collisions/XiPlusPtYAntiLambdaPt", "#Xi^{+} Pt, Y, #bar{#Lambda} Pt", HistType::kTH3D, {axisV0Pt, axisEta, axisV0Pt}); - registry.add("collisions/XiPlusPtYAntiLambdaPtWrongColl", "#Xi^{+} Pt, Y, #bar{#Lambda} Pt, wrong collision", HistType::kTH3D, {axisV0Pt, axisEta, axisV0Pt}); + registry.add("collisions/XiPlusPtYAntiLambdaPtWrongColl", "#Xi^{+} Pt, Y, #bar{#Lambda} Pt, (Wrong Collision)", HistType::kTH3D, {axisV0Pt, axisEta, axisV0Pt}); } if (doprocessCollisionAssociationJets) { registry.add("collisions/JetPtEtaV0Pt", "Jet Pt, Eta, V0 Pt", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}); registry.add("collisions/JetPtEtaV0PtWrongColl", "Jet Pt, Eta, V0 Pt", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}); registry.add("collisions/JetPtEtaK0SPtMass", "Jet Pt, Eta, K0S Pt Mass", HistType::kTHnSparseD, {axisJetPt, axisEta, axisV0Pt, axisK0SM}); + registry.add("collisions/JetPtEtaK0SFragMass", "Jet Pt, Eta, K0S Frag Mass", HistType::kTHnSparseD, {axisJetPt, axisEta, axisV0Z, axisK0SM}); registry.add("collisions/JetPtEtaK0SPtMassWrongColl", "Jet Pt, Eta, K0S Pt Mass", HistType::kTHnSparseD, {axisJetPt, axisEta, axisV0Pt, axisK0SM}); + registry.add("collisions/JetPtEtaK0SFragMassWrongColl", "Jet Pt, Eta, K0S Frag Mass", HistType::kTHnSparseD, {axisJetPt, axisEta, axisV0Z, axisK0SM}); registry.add("collisions/JetPtEtaLambdaPtMass", "Jet Pt, Eta, Lambda Pt Mass", HistType::kTHnSparseD, {axisJetPt, axisEta, axisV0Pt, axisLambdaM}); + registry.add("collisions/JetPtEtaLambdaFragMass", "Jet Pt, Eta, Lambda Frag Mass", HistType::kTHnSparseD, {axisJetPt, axisEta, axisV0Z, axisLambdaM}); registry.add("collisions/JetPtEtaLambdaPtMassWrongColl", "Jet Pt, Eta, Lambda Pt Mass", HistType::kTHnSparseD, {axisJetPt, axisEta, axisV0Pt, axisLambdaM}); + registry.add("collisions/JetPtEtaLambdaFragMassWrongColl", "Jet Pt, Eta, Lambda Frag Mass", HistType::kTHnSparseD, {axisJetPt, axisEta, axisV0Z, axisLambdaM}); registry.add("collisions/JetPtEtaAntiLambdaPtMass", "Jet Pt, Eta, AntiLambda Pt Mass", HistType::kTHnSparseD, {axisJetPt, axisEta, axisV0Pt, axisAntiLambdaM}); + registry.add("collisions/JetPtEtaAntiLambdaFragMass", "Jet Pt, Eta, AntiLambda Frag Mass", HistType::kTHnSparseD, {axisJetPt, axisEta, axisV0Z, axisAntiLambdaM}); registry.add("collisions/JetPtEtaAntiLambdaPtMassWrongColl", "Jet Pt, Eta, AntiLambda Pt Mass", HistType::kTHnSparseD, {axisJetPt, axisEta, axisV0Pt, axisAntiLambdaM}); + registry.add("collisions/JetPtEtaAntiLambdaFragMassWrongColl", "Jet Pt, Eta, AntiLambda Frag Mass", HistType::kTHnSparseD, {axisJetPt, axisEta, axisV0Z, axisAntiLambdaM}); registry.add("collisions/JetPtEtaXiMinusPtLambdaPt", "Jet Pt, #Xi^{-} Pt, #Lambda Pt", HistType::kTHnSparseD, {axisJetPt, axisEta, axisV0Pt, axisV0Pt}); registry.add("collisions/JetPtEtaXiMinusPtLambdaPtWrongColl", "Jet Pt, #Xi^{-} Pt, #Lambda Pt", HistType::kTHnSparseD, {axisJetPt, axisEta, axisV0Pt, axisV0Pt}); @@ -197,11 +224,16 @@ struct V0QA { registry.add("collisions/JetsPtEtaV0Pt", "Jets Pt, Eta, V0 Pt", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt}); registry.add("collisions/JetsPtEtaV0PtWrongColl", "Jets Pt, Eta, V0 Pt", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt}); registry.add("collisions/JetsPtEtaK0SPtMass", "Jets Pt, Eta, K0S Pt Mass", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt, axisK0SM}); - registry.add("collisions/JetsPtEtaK0SPtMassWrongColl", "Jets Pt, Eta, K0S Pt Mass", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt, axisK0SM}); + registry.add("collisions/JetsPtEtaK0SFragMass", "Jets Pt, Eta, K0S Frag Mass", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Z, axisK0SM}); + registry.add("collisions/JetsPtEtaK0SFragMassWrongColl", "Jets Pt, Eta, K0S Frag Mass", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Z, axisK0SM}); registry.add("collisions/JetsPtEtaLambdaPtMass", "Jets Pt, Eta, Lambda Pt Mass", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt, axisLambdaM}); + registry.add("collisions/JetsPtEtaLambdaFragMass", "Jets Pt, Eta, Lambda Frag Mass", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Z, axisLambdaM}); registry.add("collisions/JetsPtEtaLambdaPtMassWrongColl", "Jets Pt, Eta, Lambda Pt Mass", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt, axisLambdaM}); + registry.add("collisions/JetsPtEtaLambdaFragMassWrongColl", "Jets Pt, Eta, Lambda Frag Mass", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Z, axisLambdaM}); registry.add("collisions/JetsPtEtaAntiLambdaPtMass", "Jets Pt, Eta, AntiLambda Pt Mass", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt, axisAntiLambdaM}); + registry.add("collisions/JetsPtEtaAntiLambdaFragMass", "Jets Pt, Eta, AntiLambda Frag Mass", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Z, axisAntiLambdaM}); registry.add("collisions/JetsPtEtaAntiLambdaPtMassWrongColl", "Jets Pt, Eta, AntiLambda Pt Mass", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt, axisAntiLambdaM}); + registry.add("collisions/JetsPtEtaAntiLambdaFragMassWrongColl", "Jets Pt, Eta, AntiLambda Frag Mass", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Z, axisAntiLambdaM}); registry.add("collisions/JetsPtEtaXiMinusPtLambdaPt", "Jets Pt, Eta, #Xi^{-} Pt, #Lambda Pt", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt, axisV0Pt}); registry.add("collisions/JetsPtEtaXiMinusPtLambdaPtWrongColl", "Jets Pt, Eta, #Xi^{-} Pt, #Lambda Pt", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisEta, axisV0Pt, axisV0Pt}); @@ -221,6 +253,7 @@ struct V0QA { registry.add("feeddown/JetsPtXiPlusPtAntiLambdaPt", "Jets Pt, #Xi^{+} Pt, #bar{#Lambda} Pt", HistType::kTHnSparseD, {axisJetPt, axisJetPt, axisV0Pt, axisV0Pt}); } if (doprocessTestWeightedJetFinder) { + registry.add("tests/weighted/hEvents", "Events", {HistType::kTH1D, {{2, 0.0f, 2.0f}}}); registry.add("tests/weighted/JetPtEtaPhi", "Jet Pt, Eta, Phi", HistType::kTH3D, {axisJetPt, axisEta, axisPhi}); registry.add("tests/weighted/JetPtEtaV0Pt", "Jet Pt, Eta, V0 Pt", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}); registry.add("tests/weighted/JetPtEtaV0Z", "Jet Pt, Eta, V0 Z", HistType::kTH3D, {axisJetPt, axisEta, axisV0Z}); @@ -232,6 +265,7 @@ struct V0QA { registry.add("tests/weighted/JetPtEtaAntiLambdaZ", "Jet Pt, Eta, AntiLambda Z", HistType::kTH3D, {axisJetPt, axisEta, axisV0Z}); } if (doprocessTestSubtractedJetFinder) { + registry.add("tests/hEvents", "Events", {HistType::kTH1D, {{2, 0.0f, 2.0f}}}); registry.add("tests/nosub/JetPtEtaPhi", "Jet Pt, Eta, Phi", HistType::kTH3D, {axisJetPt, axisEta, axisPhi}); registry.add("tests/nosub/JetPtEtaV0Pt", "Jet Pt, Eta, V0 Pt", HistType::kTH3D, {axisJetPt, axisEta, axisV0Pt}); registry.add("tests/nosub/JetPtEtaV0Z", "Jet Pt, Eta, V0 Z", HistType::kTH3D, {axisJetPt, axisEta, axisV0Z}); @@ -455,6 +489,135 @@ struct V0QA { return (track.itsClusterMap() & (1 << ibit)); } + template + void fillMcDV0(T const& v0, bool correctCollision, double weight) + { + int pdg = v0.mcParticle().pdgCode(); + if (std::abs(pdg) == PDG_t::kK0Short) { + registry.fill(HIST("inclusive/K0SPtEtaMass"), v0.pt(), v0.eta(), v0.mK0Short(), weight); + registry.fill(HIST("inclusive/InvMassK0STrue"), v0.pt(), v0.v0radius(), v0.mK0Short(), weight); + if (!correctCollision) + registry.fill(HIST("inclusive/K0SPtEtaMassWrongCollision"), v0.pt(), v0.eta(), v0.mK0Short(), weight); + } else if (pdg == PDG_t::kLambda0) { + registry.fill(HIST("inclusive/LambdaPtEtaMass"), v0.pt(), v0.eta(), v0.mLambda(), weight); + registry.fill(HIST("inclusive/InvMassLambdaTrue"), v0.pt(), v0.v0radius(), v0.mLambda(), weight); + if (!correctCollision) + registry.fill(HIST("inclusive/LambdaPtEtaMassWrongCollision"), v0.pt(), v0.eta(), v0.mLambda(), weight); + } else if (pdg == PDG_t::kLambda0Bar) { + registry.fill(HIST("inclusive/AntiLambdaPtEtaMass"), v0.pt(), v0.eta(), v0.mAntiLambda(), weight); + registry.fill(HIST("inclusive/InvMassAntiLambdaTrue"), v0.pt(), v0.v0radius(), v0.mAntiLambda(), weight); + if (!correctCollision) + registry.fill(HIST("inclusive/AntiLambdaPtEtaMassWrongCollision"), v0.pt(), v0.eta(), v0.mAntiLambda(), weight); + } + } + + template + void fillMcDJets(U const& mcdjet, double weight) + { + registry.fill(HIST("jets/JetPtEtaPhi"), mcdjet.pt(), mcdjet.eta(), mcdjet.phi(), weight); + for (const auto& mcpjet : mcdjet.template matchedJetGeo_as()) { + registry.fill(HIST("jets/JetsPtEta"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), weight); + } + } + template + void fillMcDV0InJets(T const& mcdjet, U const& v0, bool correctCollision, double weight) + { + int pdg = v0.mcParticle().pdgCode(); + double z = v0.pt() / mcdjet.pt(); + if (std::abs(pdg) == PDG_t::kK0Short) { + registry.fill(HIST("jets/JetPtEtaK0SPt"), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); + registry.fill(HIST("jets/JetPtEtaK0SZ"), mcdjet.pt(), mcdjet.eta(), z, weight); + if (!correctCollision) { + registry.fill(HIST("jets/JetPtEtaK0SPtWrongCollision"), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); + registry.fill(HIST("jets/JetPtEtaK0SZWrongCollision"), mcdjet.pt(), mcdjet.eta(), z, weight); + } + } else if (pdg == PDG_t::kLambda0) { + registry.fill(HIST("jets/JetPtEtaLambdaPt"), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); + registry.fill(HIST("jets/JetPtEtaLambdaZ"), mcdjet.pt(), mcdjet.eta(), z, weight); + if (!correctCollision) { + registry.fill(HIST("jets/JetPtEtaLambdaPtWrongCollision"), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); + registry.fill(HIST("jets/JetPtEtaLambdaZWrongCollision"), mcdjet.pt(), mcdjet.eta(), z, weight); + } + } else if (pdg == PDG_t::kLambda0Bar) { + registry.fill(HIST("jets/JetPtEtaAntiLambdaPt"), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); + registry.fill(HIST("jets/JetPtEtaAntiLambdaZ"), mcdjet.pt(), mcdjet.eta(), z, weight); + if (!correctCollision) { + registry.fill(HIST("jets/JetPtEtaAntiLambdaPtWrongCollision"), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); + registry.fill(HIST("jets/JetPtEtaAntiLambdaZWrongCollision"), mcdjet.pt(), mcdjet.eta(), z, weight); + } + } + } + + template + void fillMcDV0InMatchedJets(T const& mcpjet, U const& mcdjet, V const& v0, bool correctCollision, double weight) + { + int pdg = v0.mcParticle().pdgCode(); + double z = v0.pt() / mcdjet.pt(); + if (std::abs(pdg) == PDG_t::kK0Short) { + registry.fill(HIST("jets/JetsPtEtaK0SPt"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); + registry.fill(HIST("jets/JetsPtEtaK0SZ"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), z, weight); + if (!correctCollision) { + registry.fill(HIST("jets/JetsPtEtaK0SPtWrongCollision"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); + registry.fill(HIST("jets/JetsPtEtaK0SZWrongCollision"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), z, weight); + } + } else if (pdg == PDG_t::kLambda0) { + registry.fill(HIST("jets/JetsPtEtaLambdaPt"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); + registry.fill(HIST("jets/JetsPtEtaLambdaZ"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), z, weight); + if (!correctCollision) { + registry.fill(HIST("jets/JetsPtEtaLambdaPtWrongCollision"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); + registry.fill(HIST("jets/JetsPtEtaLambdaZWrongCollision"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), z, weight); + } + } else if (pdg == PDG_t::kLambda0Bar) { + registry.fill(HIST("jets/JetsPtEtaAntiLambdaPt"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); + registry.fill(HIST("jets/JetsPtEtaAntiLambdaZ"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), z, weight); + if (!correctCollision) { + registry.fill(HIST("jets/JetsPtEtaAntiLambdaPtWrongCollision"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); + registry.fill(HIST("jets/JetsPtEtaAntiLambdaZWrongCollision"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), z, weight); + } + } + } + + template + void fillMcPV0(T const& pv0, double weight) + { + // Can calculate this from aod::CandidatesV0MCD (contains decay vertex) + double rDecay = 1.0; + + if (pv0.pdgCode() == PDG_t::kK0Short) { + registry.fill(HIST("inclusive/GeneratedK0S"), pv0.pt(), pv0.eta(), rDecay, weight); + } + if (pv0.pdgCode() == PDG_t::kLambda0) { + registry.fill(HIST("inclusive/GeneratedLambda"), pv0.pt(), pv0.eta(), rDecay, weight); + } + if (pv0.pdgCode() == PDG_t::kLambda0Bar) { + registry.fill(HIST("inclusive/GeneratedAntiLambda"), pv0.pt(), pv0.eta(), rDecay, weight); + } + } + + template + void fillMcPJets(T const& jet, double weight) + { + registry.fill(HIST("jets/GeneratedJets"), jet.pt(), jet.eta(), jet.phi(), weight); + } + + template + void fillMcPV0InJets(T const& jet, U const& pv0, double weight) + { + double z = pv0.pt() / jet.pt(); + if (pv0.pdgCode() == PDG_t::kK0Short) { + registry.fill(HIST("jets/GeneratedJetK0S"), jet.pt(), jet.eta(), pv0.pt(), weight); + registry.fill(HIST("jets/GeneratedJetK0SFrag"), jet.pt(), jet.eta(), z, weight); + } + if (pv0.pdgCode() == PDG_t::kLambda0) { + registry.fill(HIST("jets/GeneratedJetLambda"), jet.pt(), jet.eta(), pv0.pt(), weight); + registry.fill(HIST("jets/GeneratedJetLambdaFrag"), jet.pt(), jet.eta(), z, weight); + } + if (pv0.pdgCode() == PDG_t::kLambda0Bar) { + registry.fill(HIST("jets/GeneratedJetAntiLambda"), jet.pt(), jet.eta(), pv0.pt(), weight); + registry.fill(HIST("jets/GeneratedJetAntiLambdaFrag"), jet.pt(), jet.eta(), z, weight); + } + } + template void fillTrackQa(V const& v0) { @@ -712,41 +875,48 @@ struct V0QA { } PROCESS_SWITCH(V0QA, processFlags, "V0 flags", false); - void processMcD(soa::Filtered::iterator const& jcoll, aod::JetMcCollisions const&, CandidatesV0MCDWithFlags const& v0s, aod::McParticles const&) + void processMcD(soa::Filtered::iterator const& jcoll, CandidatesV0MCDWithFlags const& v0s, aod::McParticles const&, MatchedMCDV0JetsWithConstituents const& mcdjets, MatchedMCPV0JetsWithConstituents const&, aod::CandidatesV0MCP const&, aod::JetTracksMCD const& jTracks, JetMcCollisionsWithPIs const&, aod::McCollisions const&) { registry.fill(HIST("inclusive/hEvents"), 0.5); if (!isCollisionReconstructed(jcoll, eventSelectionBits)) { return; } registry.fill(HIST("inclusive/hEvents"), 1.5); - double weight = jcoll.mcCollision().weight(); + auto mcColl = jcoll.template mcCollision_as(); + double weight = mcColl.weight(); + registry.fill(HIST("inclusive/hEvents"), 2.5, weight); for (const auto& v0 : v0s) { - if (!v0.has_mcParticle()) + if (!v0.has_mcParticle() || v0.isRejectedCandidate()) continue; - if (v0.isRejectedCandidate()) - continue; + bool correctCollision = (mcColl.mcCollisionId() == v0.mcParticle().mcCollisionId()); + fillMcDV0(v0, correctCollision, weight); + } // v0 loop - int pdg = v0.mcParticle().pdgCode(); - if (std::abs(pdg) == PDG_t::kK0Short) { - registry.fill(HIST("inclusive/K0SPtEtaMass"), v0.pt(), v0.eta(), v0.mK0Short(), weight); - registry.fill(HIST("inclusive/InvMassK0STrue"), v0.pt(), v0.v0radius(), v0.mK0Short(), weight); - } - // Lambda - if (pdg == PDG_t::kLambda0) { - registry.fill(HIST("inclusive/LambdaPtEtaMass"), v0.pt(), v0.eta(), v0.mLambda(), weight); - registry.fill(HIST("inclusive/InvMassLambdaTrue"), v0.pt(), v0.v0radius(), v0.mLambda(), weight); - } - if (pdg == PDG_t::kLambda0Bar) { - registry.fill(HIST("inclusive/AntiLambdaPtEtaMass"), v0.pt(), v0.eta(), v0.mAntiLambda(), weight); - registry.fill(HIST("inclusive/InvMassAntiLambdaTrue"), v0.pt(), v0.v0radius(), v0.mAntiLambda(), weight); - } - } + for (const auto& mcdjet : mcdjets) { + fillMcDJets(mcdjet, weight); + for (const auto& v0 : mcdjet.template candidates_as()) { + if (!v0.has_mcParticle() || v0.isRejectedCandidate()) + continue; + + bool correctCollision = (mcColl.mcCollisionId() == v0.mcParticle().mcCollisionId()); + fillMcDV0InJets(mcdjet, v0, correctCollision, weight); + + for (const auto& mcpjet : mcdjet.template matchedJetGeo_as()) { + for (const auto& pv0 : mcpjet.template candidates_as()) { + if (!v0sAreMatched(v0, pv0, jTracks)) + continue; + + fillMcDV0InMatchedJets(mcpjet, mcdjet, v0, correctCollision, weight); + } // v0 particle loop + } // mcpjet loop + } // v0 loop + } // mcd jet loop } PROCESS_SWITCH(V0QA, processMcD, "Reconstructed true V0s", false); - void processMcP(aod::JetMcCollision const& mccoll, aod::CandidatesV0MCP const& pv0s, soa::SmallGroups const& collisions) + void processMcP(aod::JetMcCollision const& mccoll, soa::SmallGroups const& collisions, MCPV0JetsWithConstituents const& jets, aod::CandidatesV0MCP const& pv0s) { registry.fill(HIST("inclusive/hMcEvents"), 0.5); bool isReconstructed = false; @@ -766,169 +936,40 @@ struct V0QA { registry.fill(HIST("inclusive/hMcEvents"), 1.5); double weight = mccoll.weight(); + registry.fill(HIST("inclusive/hMcEvents"), 2.5, weight); for (const auto& pv0 : pv0s) { - if (!pv0.has_daughters()) - continue; - if (!pv0.isPhysicalPrimary()) + if (!pv0.has_daughters() || !pv0.isPhysicalPrimary()) continue; if (std::abs(pv0.y()) > yPartMax) continue; - // Can calculate this from aod::CandidatesV0MCD (contains decay vertex) - double rDecay = 1.0; - - if (pv0.pdgCode() == PDG_t::kK0Short) { - registry.fill(HIST("inclusive/GeneratedK0S"), pv0.pt(), pv0.eta(), rDecay, weight); - } - if (pv0.pdgCode() == PDG_t::kLambda0) { - registry.fill(HIST("inclusive/GeneratedLambda"), pv0.pt(), pv0.eta(), rDecay, weight); - } - if (pv0.pdgCode() == PDG_t::kLambda0Bar) { - registry.fill(HIST("inclusive/GeneratedAntiLambda"), pv0.pt(), pv0.eta(), rDecay, weight); - } - } - } - PROCESS_SWITCH(V0QA, processMcP, "Particle level V0s", false); - - void processMcDJets(soa::Filtered::iterator const& jcoll, aod::JetMcCollisions const&, MCDV0JetsWithConstituents const& mcdjets, CandidatesV0MCDWithFlags const&, aod::McParticles const&) - { - registry.fill(HIST("jets/hJetEvents"), 0.5); - if (!isCollisionReconstructed(jcoll, eventSelectionBits)) - return; - - registry.fill(HIST("jets/hJetEvents"), 1.5); - double weight = jcoll.mcCollision().weight(); - - for (const auto& mcdjet : mcdjets) { - // if (!jetfindingutilities::isInEtaAcceptance(jet, -99., -99., v0EtaMin, v0EtaMax)) - for (const auto& v0 : mcdjet.template candidates_as()) { - if (!v0.has_mcParticle()) - continue; - - int pdg = v0.mcParticle().pdgCode(); - - // Check V0 decay kinematics - if (v0.isRejectedCandidate()) - continue; - - // K0S - if (std::abs(pdg) == PDG_t::kK0Short) { - registry.fill(HIST("jets/JetPtEtaK0SPt"), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); - registry.fill(HIST("jets/InvMassJetK0STrue"), mcdjet.pt(), v0.pt(), v0.mK0Short(), weight); - } - // Lambda - if (pdg == PDG_t::kLambda0) { - registry.fill(HIST("jets/JetPtEtaLambdaPt"), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); - registry.fill(HIST("jets/InvMassJetLambdaTrue"), mcdjet.pt(), v0.pt(), v0.mLambda(), weight); - } - if (pdg == PDG_t::kLambda0Bar) { - registry.fill(HIST("jets/JetPtEtaAntiLambdaPt"), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); - registry.fill(HIST("jets/InvMassJetAntiLambdaTrue"), mcdjet.pt(), v0.pt(), v0.mAntiLambda(), weight); - } - } - } - } - PROCESS_SWITCH(V0QA, processMcDJets, "Reconstructed true V0s in jets", false); - - void processMcDMatchedJets(soa::Filtered::iterator const& jcoll, aod::JetMcCollisions const&, MatchedMCDV0JetsWithConstituents const& mcdjets, MatchedMCPV0JetsWithConstituents const&, CandidatesV0MCDWithFlags const&, aod::CandidatesV0MCP const&, aod::JetTracksMCD const& jTracks, aod::McParticles const&) - { - registry.fill(HIST("jets/hMatchedJetEvents"), 0.5); - if (!isCollisionReconstructed(jcoll, eventSelectionBits)) - return; - - registry.fill(HIST("jets/hMatchedJetEvents"), 1.5); - double weight = jcoll.mcCollision().weight(); - - for (const auto& mcdjet : mcdjets) { - // if (!jetfindingutilities::isInEtaAcceptance(mcdjet, -99., -99., v0EtaMin, v0EtaMax)) - for (const auto& mcpjet : mcdjet.template matchedJetGeo_as()) { - for (const auto& v0 : mcdjet.template candidates_as()) { - if (!v0.has_mcParticle()) - continue; - - for (const auto& pv0 : mcpjet.template candidates_as()) { - if (!v0sAreMatched(v0, pv0, jTracks)) - continue; - int pdg = pv0.pdgCode(); - - // Check V0 decay kinematics - if (v0.isRejectedCandidate()) - continue; - - // K0S - if (std::abs(pdg) == PDG_t::kK0Short) { - registry.fill(HIST("jets/JetsPtEtaK0SPt"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); - registry.fill(HIST("jets/InvMassJetsK0STrue"), mcpjet.pt(), mcdjet.pt(), v0.pt(), v0.mK0Short(), weight); - } - // Lambda - if (pdg == PDG_t::kLambda0) { - registry.fill(HIST("jets/JetsPtEtaLambdaPt"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); - registry.fill(HIST("jets/InvMassJetsLambdaTrue"), mcpjet.pt(), mcdjet.pt(), v0.pt(), v0.mLambda(), weight); - } - if (pdg == PDG_t::kLambda0Bar) { - registry.fill(HIST("jets/JetsPtEtaAntiLambdaPt"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); - registry.fill(HIST("jets/InvMassJetsAntiLambdaTrue"), mcpjet.pt(), mcdjet.pt(), v0.pt(), v0.mAntiLambda(), weight); - } - } - } - } - } - } - PROCESS_SWITCH(V0QA, processMcDMatchedJets, "Reconstructed true V0s in jets", false); - - void processMcPJets(aod::JetMcCollision const& mccoll, soa::SmallGroups const& collisions, MCPV0JetsWithConstituents const& jets, aod::CandidatesV0MCP const&) - { - registry.fill(HIST("jets/hMcJetEvents"), 0.5); - bool isReconstructed = false; - - for (const auto& collision : collisions) { - if (!isCollisionReconstructed(collision, eventSelectionBits)) - continue; - - if (collision.mcCollision().globalIndex() != mccoll.globalIndex()) - continue; - - isReconstructed = true; - break; + fillMcPV0(pv0, weight); } - if (!isReconstructed) - return; - - registry.fill(HIST("jets/hMcJetEvents"), 1.5); - double weight = mccoll.weight(); for (const auto& jet : jets) { if (!jetfindingutilities::isInEtaAcceptance(jet, -99., -99., -1. * yPartMax, yPartMax)) continue; + fillMcPJets(jet, weight); + for (const auto& pv0 : jet.template candidates_as()) { - if (!pv0.has_daughters()) - continue; - if (!pv0.isPhysicalPrimary()) + if (!pv0.has_daughters() || !pv0.isPhysicalPrimary()) continue; - if (pv0.pdgCode() == PDG_t::kK0Short) { - registry.fill(HIST("jets/GeneratedJetK0S"), jet.pt(), jet.eta(), pv0.pt(), weight); - } - if (pv0.pdgCode() == PDG_t::kLambda0) { - registry.fill(HIST("jets/GeneratedJetLambda"), jet.pt(), jet.eta(), pv0.pt(), weight); - } - if (pv0.pdgCode() == PDG_t::kLambda0Bar) { - registry.fill(HIST("jets/GeneratedJetAntiLambda"), jet.pt(), jet.eta(), pv0.pt(), weight); - } + fillMcPV0InJets(jet, pv0, weight); } } } - PROCESS_SWITCH(V0QA, processMcPJets, "Particle level V0s in jets", false); + PROCESS_SWITCH(V0QA, processMcP, "Particle level V0s", false); - void processCollisionAssociation(soa::Filtered::iterator const& jcoll, CandidatesV0MCDWithFlags const& v0s, soa::Join const&, aod::McCollisions const&, aod::McParticles const&) + void processCollisionAssociation(soa::Filtered::iterator const& jcoll, CandidatesV0MCDWithFlags const& v0s, JetMcCollisionsWithPIs const&, aod::McCollisions const&, aod::McParticles const&) { // Based on PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx if (!jcoll.has_mcCollision()) return; - auto mcColl = jcoll.template mcCollision_as>(); + auto mcColl = jcoll.template mcCollision_as(); double weight = mcColl.weight(); for (const auto& v0 : v0s) { @@ -989,12 +1030,12 @@ struct V0QA { } PROCESS_SWITCH(V0QA, processCollisionAssociation, "V0 collision association", false); - void processCollisionAssociationJets(soa::Filtered::iterator const& jcoll, MCDV0JetsWithConstituents const& mcdjets, CandidatesV0MCDWithFlags const&, soa::Join const&, aod::McCollisions const&, aod::McParticles const&) + void processCollisionAssociationJets(soa::Filtered::iterator const& jcoll, MCDV0JetsWithConstituents const& mcdjets, CandidatesV0MCDWithFlags const&, JetMcCollisionsWithPIs const&, aod::McCollisions const&, aod::McParticles const&) { - if (!jcoll.has_mcCollision()) + if (!isCollisionReconstructed(jcoll, eventSelectionBits)) return; - auto mcColl = jcoll.template mcCollision_as>(); + auto mcColl = jcoll.template mcCollision_as(); double weight = mcColl.weight(); for (const auto& mcdjet : mcdjets) { @@ -1006,31 +1047,38 @@ struct V0QA { auto pv0 = v0.mcParticle(); bool correctCollision = (mcColl.mcCollisionId() == pv0.mcCollisionId()); int pdg = pv0.pdgCode(); + double z = v0.pt() / mcdjet.pt(); // Check V0 decay kinematics if (v0.isRejectedCandidate()) continue; - registry.fill(HIST("collisions/JetPtEtaV0Pt"), mcdjet.pt(), mcdjet.eta(), pv0.pt(), weight); + registry.fill(HIST("collisions/JetPtEtaV0Pt"), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); if (!correctCollision) { - registry.fill(HIST("collisions/JetPtEtaV0PtWrongColl"), mcdjet.pt(), mcdjet.eta(), pv0.pt(), weight); + registry.fill(HIST("collisions/JetPtEtaV0PtWrongColl"), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); } if (std::abs(pdg) == PDG_t::kK0Short) { - registry.fill(HIST("collisions/JetPtEtaK0SPtMass"), mcdjet.pt(), mcdjet.eta(), pv0.pt(), v0.mK0Short(), weight); + registry.fill(HIST("collisions/JetPtEtaK0SPtMass"), mcdjet.pt(), mcdjet.eta(), v0.pt(), v0.mK0Short(), weight); + registry.fill(HIST("collisions/JetPtEtaK0SFragMass"), mcdjet.pt(), mcdjet.eta(), z, v0.mK0Short(), weight); if (!correctCollision) { - registry.fill(HIST("collisions/JetPtEtaK0SPtMassWrongColl"), mcdjet.pt(), mcdjet.eta(), pv0.pt(), v0.mK0Short(), weight); + registry.fill(HIST("collisions/JetPtEtaK0SPtMassWrongColl"), mcdjet.pt(), mcdjet.eta(), v0.pt(), v0.mK0Short(), weight); + registry.fill(HIST("collisions/JetPtEtaK0SFragMassWrongColl"), mcdjet.pt(), mcdjet.eta(), z, v0.mK0Short(), weight); } } if (pdg == PDG_t::kLambda0) { - registry.fill(HIST("collisions/JetPtEtaLambdaPtMass"), mcdjet.pt(), mcdjet.eta(), pv0.pt(), v0.mLambda(), weight); + registry.fill(HIST("collisions/JetPtEtaLambdaPtMass"), mcdjet.pt(), mcdjet.eta(), v0.pt(), v0.mLambda(), weight); + registry.fill(HIST("collisions/JetPtEtaLambdaFragMass"), mcdjet.pt(), mcdjet.eta(), z, v0.mLambda(), weight); if (!correctCollision) { - registry.fill(HIST("collisions/JetPtEtaLambdaPtMassWrongColl"), mcdjet.pt(), mcdjet.eta(), pv0.pt(), v0.mLambda(), weight); + registry.fill(HIST("collisions/JetPtEtaLambdaPtMassWrongColl"), mcdjet.pt(), mcdjet.eta(), v0.pt(), v0.mLambda(), weight); + registry.fill(HIST("collisions/JetPtEtaLambdaFragMassWrongColl"), mcdjet.pt(), mcdjet.eta(), z, v0.mLambda(), weight); } } if (pdg == PDG_t::kLambda0Bar) { - registry.fill(HIST("collisions/JetPtEtaAntiLambdaPtMass"), mcdjet.pt(), mcdjet.eta(), pv0.pt(), v0.mAntiLambda(), weight); + registry.fill(HIST("collisions/JetPtEtaAntiLambdaPtMass"), mcdjet.pt(), mcdjet.eta(), v0.pt(), v0.mAntiLambda(), weight); + registry.fill(HIST("collisions/JetPtEtaAntiLambdaFragMass"), mcdjet.pt(), mcdjet.eta(), z, v0.mAntiLambda(), weight); if (!correctCollision) { - registry.fill(HIST("collisions/JetPtEtaAntiLambdaPtMassWrongColl"), mcdjet.pt(), mcdjet.eta(), pv0.pt(), v0.mAntiLambda(), weight); + registry.fill(HIST("collisions/JetPtEtaAntiLambdaPtMassWrongColl"), mcdjet.pt(), mcdjet.eta(), v0.pt(), v0.mAntiLambda(), weight); + registry.fill(HIST("collisions/JetPtEtaAntiLambdaFragMassWrongColl"), mcdjet.pt(), mcdjet.eta(), z, v0.mAntiLambda(), weight); } } @@ -1041,15 +1089,15 @@ struct V0QA { pdg = mother.pdgCode(); correctCollision = (mcColl.mcCollisionId() == mother.mcCollisionId()); if (pdg == PDG_t::kXiMinus) { - registry.fill(HIST("collisions/JetPtEtaXiMinusPtLambdaPt"), mcdjet.pt(), mcdjet.eta(), mother.pt(), pv0.pt(), weight); + registry.fill(HIST("collisions/JetPtEtaXiMinusPtLambdaPt"), mcdjet.pt(), mcdjet.eta(), mother.pt(), v0.pt(), weight); if (!correctCollision) { - registry.fill(HIST("collisions/JetPtEtaXiMinusPtLambdaPtWrongColl"), mcdjet.pt(), mcdjet.eta(), mother.pt(), pv0.pt(), weight); + registry.fill(HIST("collisions/JetPtEtaXiMinusPtLambdaPtWrongColl"), mcdjet.pt(), mcdjet.eta(), mother.pt(), v0.pt(), weight); } } if (pdg == PDG_t::kXiPlusBar) { - registry.fill(HIST("collisions/JetPtEtaXiPlusPtAntiLambdaPt"), mcdjet.pt(), mcdjet.eta(), mother.pt(), pv0.pt(), weight); + registry.fill(HIST("collisions/JetPtEtaXiPlusPtAntiLambdaPt"), mcdjet.pt(), mcdjet.eta(), mother.pt(), v0.pt(), weight); if (!correctCollision) { - registry.fill(HIST("collisions/JetPtEtaXiPlusPtAntiLambdaPtWrongColl"), mcdjet.pt(), mcdjet.eta(), mother.pt(), pv0.pt(), weight); + registry.fill(HIST("collisions/JetPtEtaXiPlusPtAntiLambdaPtWrongColl"), mcdjet.pt(), mcdjet.eta(), mother.pt(), v0.pt(), weight); } } } // for v0s @@ -1057,12 +1105,12 @@ struct V0QA { } PROCESS_SWITCH(V0QA, processCollisionAssociationJets, "V0 in jets collision association", false); - void processCollisionAssociationMatchedJets(soa::Filtered::iterator const& jcoll, MatchedMCDV0JetsWithConstituents const& mcdjets, MatchedMCPV0JetsWithConstituents const&, CandidatesV0MCDWithFlags const&, aod::CandidatesV0MCP const&, soa::Join const&, aod::McCollisions const&, aod::McParticles const&, aod::JetTracksMCD const& jTracks) + void processCollisionAssociationMatchedJets(soa::Filtered::iterator const& jcoll, MatchedMCDV0JetsWithConstituents const& mcdjets, MatchedMCPV0JetsWithConstituents const&, CandidatesV0MCDWithFlags const&, aod::CandidatesV0MCP const&, JetMcCollisionsWithPIs const&, aod::McCollisions const&, aod::McParticles const&, aod::JetTracksMCD const& jTracks) { if (!jcoll.has_mcCollision()) return; - auto mcColl = jcoll.template mcCollision_as>(); + auto mcColl = jcoll.template mcCollision_as(); double weight = mcColl.weight(); for (const auto& mcdjet : mcdjets) { @@ -1077,31 +1125,38 @@ struct V0QA { int pdg = pv0.pdgCode(); bool correctCollision = (mcColl.mcCollisionId() == pv0.mcCollisionId()); + double z = v0.pt() / mcdjet.pt(); // Check V0 decay kinematics if (v0.isRejectedCandidate()) continue; - registry.fill(HIST("collisions/JetsPtEtaV0Pt"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), pv0.pt(), weight); + registry.fill(HIST("collisions/JetsPtEtaV0Pt"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); if (!correctCollision) { - registry.fill(HIST("collisions/JetsPtEtaV0PtWrongColl"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), pv0.pt(), weight); + registry.fill(HIST("collisions/JetsPtEtaV0PtWrongColl"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), weight); } if (std::abs(pdg) == PDG_t::kK0Short) { - registry.fill(HIST("collisions/JetsPtEtaK0SPtMass"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), pv0.pt(), v0.mK0Short(), weight); + registry.fill(HIST("collisions/JetsPtEtaK0SPtMass"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), v0.mK0Short(), weight); + registry.fill(HIST("collisions/JetsPtEtaK0SFragMass"), mcpjet.pt(), mcdjet.eta(), z, v0.mK0Short(), weight); if (!correctCollision) { - registry.fill(HIST("collisions/JetsPtEtaK0SPtMassWrongColl"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), pv0.pt(), v0.mK0Short(), weight); + registry.fill(HIST("collisions/JetsPtEtaK0SPtMassWrongColl"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), v0.mK0Short(), weight); + registry.fill(HIST("collisions/JetsPtEtaK0SFragMassWrongColl"), mcpjet.pt(), mcdjet.eta(), z, v0.mK0Short(), weight); } } if (pdg == PDG_t::kLambda0) { - registry.fill(HIST("collisions/JetsPtEtaLambdaPtMass"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), pv0.pt(), v0.mLambda(), weight); + registry.fill(HIST("collisions/JetsPtEtaLambdaPtMass"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), v0.mLambda(), weight); + registry.fill(HIST("collisions/JetsPtEtaLambdaFragMass"), mcpjet.pt(), mcdjet.eta(), z, v0.mLambda(), weight); if (!correctCollision) { - registry.fill(HIST("collisions/JetsPtEtaLambdaPtMassWrongColl"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), pv0.pt(), v0.mLambda(), weight); + registry.fill(HIST("collisions/JetsPtEtaLambdaPtMassWrongColl"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), v0.mLambda(), weight); + registry.fill(HIST("collisions/JetsPtEtaLambdaFragMassWrongColl"), mcpjet.pt(), mcdjet.eta(), z, v0.mLambda(), weight); } } if (pdg == PDG_t::kLambda0Bar) { - registry.fill(HIST("collisions/JetsPtEtaAntiLambdaPtMass"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), pv0.pt(), v0.mAntiLambda(), weight); + registry.fill(HIST("collisions/JetsPtEtaAntiLambdaPtMass"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), v0.mAntiLambda(), weight); + registry.fill(HIST("collisions/JetsPtEtaAntiLambdaFragMass"), mcpjet.pt(), mcdjet.eta(), z, v0.mAntiLambda(), weight); if (!correctCollision) { - registry.fill(HIST("collisions/JetsPtEtaAntiLambdaPtMassWrongColl"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), pv0.pt(), v0.mAntiLambda(), weight); + registry.fill(HIST("collisions/JetsPtEtaAntiLambdaPtMassWrongColl"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), v0.pt(), v0.mAntiLambda(), weight); + registry.fill(HIST("collisions/JetsPtEtaAntiLambdaFragMassWrongColl"), mcpjet.pt(), mcdjet.eta(), z, v0.mAntiLambda(), weight); } } @@ -1112,15 +1167,15 @@ struct V0QA { pdg = mother.pdgCode(); correctCollision = (mcColl.mcCollisionId() == mother.mcCollisionId()); if (pdg == PDG_t::kXiMinus) { - registry.fill(HIST("collisions/JetsPtEtaXiMinusPtLambdaPt"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), mother.pt(), pv0.pt(), weight); + registry.fill(HIST("collisions/JetsPtEtaXiMinusPtLambdaPt"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), mother.pt(), v0.pt(), weight); if (!correctCollision) { - registry.fill(HIST("collisions/JetsPtEtaXiMinusPtLambdaPtWrongColl"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), mother.pt(), pv0.pt(), weight); + registry.fill(HIST("collisions/JetsPtEtaXiMinusPtLambdaPtWrongColl"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), mother.pt(), v0.pt(), weight); } } if (pdg == PDG_t::kXiPlusBar) { - registry.fill(HIST("collisions/JetsPtEtaXiPlusPtAntiLambdaPt"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), mother.pt(), pv0.pt(), weight); + registry.fill(HIST("collisions/JetsPtEtaXiPlusPtAntiLambdaPt"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), mother.pt(), v0.pt(), weight); if (!correctCollision) { - registry.fill(HIST("collisions/JetsPtEtaXiPlusPtAntiLambdaPtWrongColl"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), mother.pt(), pv0.pt(), weight); + registry.fill(HIST("collisions/JetsPtEtaXiPlusPtAntiLambdaPtWrongColl"), mcpjet.pt(), mcdjet.pt(), mcdjet.eta(), mother.pt(), v0.pt(), weight); } } } // for pv0 @@ -1130,13 +1185,13 @@ struct V0QA { } PROCESS_SWITCH(V0QA, processCollisionAssociationMatchedJets, "V0 in matched jets collision association", false); - void processFeeddown(soa::Filtered::iterator const& jcoll, CandidatesV0MCDWithFlags const& v0s, aod::CandidatesV0MCP const&, soa::Join const&, aod::McCollisions const&, aod::McParticles const&) + void processFeeddown(soa::Filtered::iterator const& jcoll, CandidatesV0MCDWithFlags const& v0s, aod::CandidatesV0MCP const&, JetMcCollisionsWithPIs const&, aod::McCollisions const&, aod::McParticles const&) { // Based on PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx if (!jcoll.has_mcCollision()) return; - auto mcColl = jcoll.template mcCollision_as>(); + auto mcColl = jcoll.template mcCollision_as(); double weight = mcColl.weight(); for (const auto& v0 : v0s) { @@ -1166,13 +1221,13 @@ struct V0QA { } PROCESS_SWITCH(V0QA, processFeeddown, "Inclusive feeddown", false); - void processFeeddownJets(soa::Filtered::iterator const& jcoll, MCDV0JetsWithConstituents const& mcdjets, CandidatesV0MCDWithFlags const&, aod::CandidatesV0MCP const&, soa::Join const&, aod::McCollisions const&, aod::McParticles const&) + void processFeeddownJets(soa::Filtered::iterator const& jcoll, MCDV0JetsWithConstituents const& mcdjets, CandidatesV0MCDWithFlags const&, aod::CandidatesV0MCP const&, JetMcCollisionsWithPIs const&, aod::McCollisions const&, aod::McParticles const&) { // Based on PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx if (!jcoll.has_mcCollision()) return; - auto mcColl = jcoll.template mcCollision_as>(); + auto mcColl = jcoll.template mcCollision_as(); double weight = mcColl.weight(); for (const auto& mcdjet : mcdjets) { @@ -1204,13 +1259,13 @@ struct V0QA { } PROCESS_SWITCH(V0QA, processFeeddownJets, "Jets feeddown", false); - void processFeeddownMatchedJets(soa::Filtered::iterator const& jcoll, MatchedMCDV0JetsWithConstituents const& mcdjets, aod::JetTracksMCD const& jTracks, MatchedMCPV0JetsWithConstituents const&, CandidatesV0MCDWithFlags const&, aod::CandidatesV0MCP const&, soa::Join const&, aod::McCollisions const&, aod::McParticles const&) + void processFeeddownMatchedJets(soa::Filtered::iterator const& jcoll, MatchedMCDV0JetsWithConstituents const& mcdjets, aod::JetTracksMCD const& jTracks, MatchedMCPV0JetsWithConstituents const&, CandidatesV0MCDWithFlags const&, aod::CandidatesV0MCP const&, JetMcCollisionsWithPIs const&, aod::McCollisions const&, aod::McParticles const&) { // Based on PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx if (!jcoll.has_mcCollision()) return; - auto mcColl = jcoll.template mcCollision_as>(); + auto mcColl = jcoll.template mcCollision_as(); double weight = mcColl.weight(); for (const auto& mcdjet : mcdjets) { @@ -1249,9 +1304,12 @@ struct V0QA { // Test the difference between excluding V0s from jet finding and subtracting V0s from jets afterwards void processTestWeightedJetFinder(soa::Filtered::iterator const& jcoll, soa::Join const& jets, aod::CandidatesV0Data const&) { + registry.fill(HIST("tests/weighted/hEvents"), 0.5); if (!jetderiveddatautilities::selectCollision(jcoll, eventSelectionBits)) return; + registry.fill(HIST("tests/weighted/hEvents"), 1.5); + for (const auto& jet : jets) { registry.fill(HIST("tests/weighted/JetPtEtaPhi"), jet.pt(), jet.eta(), jet.phi()); @@ -1283,9 +1341,12 @@ struct V0QA { void processTestSubtractedJetFinder(soa::Filtered::iterator const& jcoll, soa::Join const& jets, aod::CandidatesV0Data const&) { + registry.fill(HIST("tests/hEvents"), 0.5); if (!jetderiveddatautilities::selectCollision(jcoll, eventSelectionBits)) return; + registry.fill(HIST("tests/hEvents"), 1.5); + for (const auto& jet : jets) { registry.fill(HIST("tests/nosub/JetPtEtaPhi"), jet.pt(), jet.eta(), jet.phi()); @@ -1312,7 +1373,7 @@ struct V0QA { registry.fill(HIST("tests/nosub/JetPtEtaAntiLambdaZ"), jet.pt(), jet.eta(), z); } - if (v0.isRejectedCandidate()) { + if (gRandom->Uniform() > v0Fraction) { // Rejected V0 ptjetsub -= v0.pt(); } else { // Accepted V0 v0Pt.push_back(v0.pt()); diff --git a/PWGLF/DataModel/LFCKSSpinalignmentTables.h b/PWGLF/DataModel/LFCKSSpinalignmentTables.h index 7e6447459cc..6593d22fe6b 100644 --- a/PWGLF/DataModel/LFCKSSpinalignmentTables.h +++ b/PWGLF/DataModel/LFCKSSpinalignmentTables.h @@ -33,6 +33,7 @@ namespace o2::aod namespace kshortpionevent { DECLARE_SOA_COLUMN(Cent, cent, float); +DECLARE_SOA_COLUMN(Posz, posz, float); DECLARE_SOA_COLUMN(CollIndex, collIndex, float); DECLARE_SOA_COLUMN(PsiFT0C, psiFT0C, float); DECLARE_SOA_COLUMN(PsiFT0A, psiFT0A, float); @@ -41,6 +42,7 @@ DECLARE_SOA_COLUMN(PsiTPC, psiTPC, float); DECLARE_SOA_TABLE(KShortpionEvents, "AOD", "KSHORTPIONEVENT", o2::soa::Index<>, kshortpionevent::Cent, + kshortpionevent::Posz, kshortpionevent::CollIndex, kshortpionevent::PsiFT0C, kshortpionevent::PsiFT0A, @@ -63,7 +65,6 @@ DECLARE_SOA_COLUMN(KShortMass, kShortMass, float); //! KShort Ma DECLARE_SOA_COLUMN(PionBachPx, pionBachPx, float); //! Bachelor Pion Px DECLARE_SOA_COLUMN(PionBachPy, pionBachPy, float); //! Bachelor Pion Py DECLARE_SOA_COLUMN(PionBachPz, pionBachPz, float); //! Bachelor Pion Pz -DECLARE_SOA_COLUMN(PionBachSign, pionBachSign, int); //! Bachelor Pion Sign DECLARE_SOA_COLUMN(PionBachTPC, pionBachTPC, float); //! Bachelor Pion nsigmatpc DECLARE_SOA_COLUMN(PionBachTOFHit, pionBachTOFHit, int); //! Bachelor Pion tof hit availability DECLARE_SOA_COLUMN(PionBachTOF, pionBachTOF, float); //! Bachelor Pion nsigmatof @@ -71,7 +72,7 @@ DECLARE_SOA_COLUMN(PionBachIndex, pionBachIndex, int); //! Bachelor DECLARE_SOA_COLUMN(PionIndex1, pionIndex1, int); //! Daughter Pion index1 DECLARE_SOA_COLUMN(PionIndex2, pionIndex2, int); //! Daughter Pion index2 } // namespace kshortpionpair -DECLARE_SOA_TABLE(KShortpionPairs, "AOD", "KSHORTPIONPAIR", +DECLARE_SOA_TABLE(KShortTracks, "AOD", "KSHORTTRACK", o2::soa::Index<>, kshortpionpair::KShortpionEventId, kshortpionpair::V0Cospa, @@ -85,17 +86,23 @@ DECLARE_SOA_TABLE(KShortpionPairs, "AOD", "KSHORTPIONPAIR", kshortpionpair::KShortPy, kshortpionpair::KShortPz, kshortpionpair::KShortMass, + kshortpionpair::PionIndex1, + kshortpionpair::PionIndex2); + +using KShortTrack = KShortTracks::iterator; + +DECLARE_SOA_TABLE(PionTracks, "AOD", "PIONTRACK", + o2::soa::Index<>, + kshortpionpair::KShortpionEventId, kshortpionpair::PionBachPx, kshortpionpair::PionBachPy, kshortpionpair::PionBachPz, - kshortpionpair::PionBachSign, + // kshortpionpair::PionBachSign, kshortpionpair::PionBachTPC, kshortpionpair::PionBachTOFHit, kshortpionpair::PionBachTOF, - kshortpionpair::PionBachIndex, - kshortpionpair::PionIndex1, - kshortpionpair::PionIndex2); + kshortpionpair::PionBachIndex); -using KShortpionPair = KShortpionPairs::iterator; +using PionTrack = PionTracks::iterator; } // namespace o2::aod #endif // PWGLF_DATAMODEL_LFCKSSPINALIGNMENTTABLES_H_ diff --git a/PWGLF/DataModel/LFHyperNucleiKinkTables.h b/PWGLF/DataModel/LFHyperNucleiKinkTables.h index 797a1d3c109..a661e4dec32 100644 --- a/PWGLF/DataModel/LFHyperNucleiKinkTables.h +++ b/PWGLF/DataModel/LFHyperNucleiKinkTables.h @@ -24,6 +24,7 @@ namespace o2::aod namespace hyperkink { +DECLARE_SOA_COLUMN(MagPolarity, magPolarity, int8_t); //! Magnetic field polarity DECLARE_SOA_COLUMN(XPV, xPV, float); //! Primary vertex of the candidate (x direction) DECLARE_SOA_COLUMN(YPV, yPV, float); //! Primary vertex of the candidate (y direction) DECLARE_SOA_COLUMN(ZPV, zPV, float); //! Primary vertex of the candidate (z direction) @@ -54,6 +55,7 @@ DECLARE_SOA_COLUMN(ItsClusterSizesMoth, itsClusterSizesMoth, uint32_t); //! ITS DECLARE_SOA_COLUMN(ItsClusterSizesDaug, itsClusterSizesDaug, uint32_t); //! ITS cluster size of the daughter track DECLARE_SOA_COLUMN(NSigmaTPCDaug, nSigmaTPCDaug, float); //! Number of tpc sigmas of the daughter track DECLARE_SOA_COLUMN(NSigmaITSDaug, nSigmaITSDaug, float); //! Number of ITS sigmas of the daughter track +DECLARE_SOA_COLUMN(NSigmaTOFDaug, nSigmaTOFDaug, float); //! Number of TOF sigmas of the daughter track DECLARE_SOA_COLUMN(IsSignal, isSignal, bool); //! bool: true for hyperhelium4signal DECLARE_SOA_COLUMN(IsSignalReco, isSignalReco, bool); //! bool: true if the signal is reconstructed @@ -82,6 +84,7 @@ DECLARE_SOA_COLUMN(UpdatePzMothPV, updatePzMothPV, float); //! updated pz o DECLARE_SOA_TABLE(HypKinkCand, "AOD", "HYPKINKCANDS", o2::soa::Index<>, + hyperkink::MagPolarity, hyperkink::XPV, hyperkink::YPV, hyperkink::ZPV, hyperkink::XSV, hyperkink::YSV, hyperkink::ZSV, hyperkink::IsMatter, @@ -92,10 +95,13 @@ DECLARE_SOA_TABLE(HypKinkCand, "AOD", "HYPKINKCANDS", hyperkink::PxDaugSV, hyperkink::PyDaugSV, hyperkink::PzDaugSV, hyperkink::DcaMothPv, hyperkink::DcaDaugPv, hyperkink::DcaKinkTopo, hyperkink::ItsChi2Moth, hyperkink::ItsClusterSizesMoth, hyperkink::ItsClusterSizesDaug, - hyperkink::NSigmaTPCDaug, hyperkink::NSigmaITSDaug); + hyperkink::NSigmaTPCDaug, hyperkink::NSigmaITSDaug, hyperkink::NSigmaTOFDaug, + hyperkink::PxMothPV, hyperkink::PyMothPV, hyperkink::PzMothPV, + hyperkink::UpdatePxMothPV, hyperkink::UpdatePyMothPV, hyperkink::UpdatePzMothPV); DECLARE_SOA_TABLE(MCHypKinkCand, "AOD", "MCHYPKINKCANDS", o2::soa::Index<>, + hyperkink::MagPolarity, hyperkink::XPV, hyperkink::YPV, hyperkink::ZPV, hyperkink::XSV, hyperkink::YSV, hyperkink::ZSV, hyperkink::IsMatter, @@ -106,7 +112,7 @@ DECLARE_SOA_TABLE(MCHypKinkCand, "AOD", "MCHYPKINKCANDS", hyperkink::PxDaugSV, hyperkink::PyDaugSV, hyperkink::PzDaugSV, hyperkink::DcaMothPv, hyperkink::DcaDaugPv, hyperkink::DcaKinkTopo, hyperkink::ItsChi2Moth, hyperkink::ItsClusterSizesMoth, hyperkink::ItsClusterSizesDaug, - hyperkink::NSigmaTPCDaug, hyperkink::NSigmaITSDaug, + hyperkink::NSigmaTPCDaug, hyperkink::NSigmaITSDaug, hyperkink::NSigmaTOFDaug, hyperkink::IsSignal, hyperkink::IsSignalReco, hyperkink::IsCollReco, hyperkink::IsSurvEvSelection, hyperkink::TrueXSV, hyperkink::TrueYSV, hyperkink::TrueZSV, hyperkink::TruePxMothPV, hyperkink::TruePyMothPV, hyperkink::TruePzMothPV, diff --git a/PWGLF/DataModel/LFHypernucleiTables.h b/PWGLF/DataModel/LFHypernucleiTables.h index f144daccba6..f0f37bf4d86 100644 --- a/PWGLF/DataModel/LFHypernucleiTables.h +++ b/PWGLF/DataModel/LFHypernucleiTables.h @@ -60,6 +60,8 @@ DECLARE_SOA_COLUMN(NTPCpidClusPi, nTPCpidClusPi, uint8_t); // Number DECLARE_SOA_COLUMN(TPCsignalHe, tpcSignalHe, uint16_t); // TPC signal of the He daughter DECLARE_SOA_COLUMN(TPCsignalPi, tpcSignalPi, uint16_t); // TPC signal of the Pi daughter DECLARE_SOA_COLUMN(TPCChi2He, tpcChi2He, float); // TPC chi2 of the He daughter +DECLARE_SOA_COLUMN(ITSChi2He, itsChi2He, float); // ITS chi2 of the He daughter +DECLARE_SOA_COLUMN(ITSChi2Pi, itsChi2Pi, float); // ITS chi2 of the Pi daughter DECLARE_SOA_COLUMN(TrackedClSize, trackedClSize, int); // int: zero for non-tracked candidates DECLARE_SOA_COLUMN(Flags, flags, uint8_t); // Flags for PID in tracking (bits [0, 3] for negative daughter, [4,7] for positive daughter) DECLARE_SOA_COLUMN(TPCmomHe, tpcMomHe, float); // TPC momentum of the He daughter @@ -94,7 +96,7 @@ DECLARE_SOA_TABLE(DataHypCands, "AOD", "HYPCANDS", hyperrec::XDecVtx, hyperrec::YDecVtx, hyperrec::ZDecVtx, hyperrec::DcaV0Daug, hyperrec::DcaHe, hyperrec::DcaPi, hyperrec::NSigmaHe, hyperrec::NTPCclusHe, hyperrec::NTPCclusPi, hyperrec::NTPCpidClusHe, hyperrec::NTPCpidClusPi, - hyperrec::TPCmomHe, hyperrec::TPCmomPi, hyperrec::TPCsignalHe, hyperrec::TPCsignalPi, hyperrec::TPCChi2He, + hyperrec::TPCmomHe, hyperrec::TPCmomPi, hyperrec::TPCsignalHe, hyperrec::TPCsignalPi, hyperrec::TPCChi2He, hyperrec::ITSChi2He, hyperrec::ITSChi2Pi, hyperrec::TOFMass, hyperrec::ITSclusterSizesHe, hyperrec::ITSclusterSizesPi, hyperrec::Flags, hyperrec::TrackedClSize); @@ -113,7 +115,7 @@ DECLARE_SOA_TABLE(DataHypCandsFlow, "AOD", "HYPCANDSFLOW", hyperrec::XDecVtx, hyperrec::YDecVtx, hyperrec::ZDecVtx, hyperrec::DcaV0Daug, hyperrec::DcaHe, hyperrec::DcaPi, hyperrec::NSigmaHe, hyperrec::NTPCclusHe, hyperrec::NTPCclusPi, hyperrec::NTPCpidClusHe, hyperrec::NTPCpidClusPi, - hyperrec::TPCmomHe, hyperrec::TPCmomPi, hyperrec::TPCsignalHe, hyperrec::TPCsignalPi, hyperrec::TPCChi2He, + hyperrec::TPCmomHe, hyperrec::TPCmomPi, hyperrec::TPCsignalHe, hyperrec::TPCsignalPi, hyperrec::TPCChi2He, hyperrec::ITSChi2He, hyperrec::ITSChi2Pi, hyperrec::TOFMass, hyperrec::ITSclusterSizesHe, hyperrec::ITSclusterSizesPi, hyperrec::Flags, hyperrec::TrackedClSize); @@ -129,7 +131,7 @@ DECLARE_SOA_TABLE(MCHypCands, "AOD", "MCHYPCANDS", hyperrec::XDecVtx, hyperrec::YDecVtx, hyperrec::ZDecVtx, hyperrec::DcaV0Daug, hyperrec::DcaHe, hyperrec::DcaPi, hyperrec::NSigmaHe, hyperrec::NTPCclusHe, hyperrec::NTPCclusPi, hyperrec::NTPCpidClusHe, hyperrec::NTPCpidClusPi, - hyperrec::TPCmomHe, hyperrec::TPCmomPi, hyperrec::TPCsignalHe, hyperrec::TPCsignalPi, hyperrec::TPCChi2He, + hyperrec::TPCmomHe, hyperrec::TPCmomPi, hyperrec::TPCsignalHe, hyperrec::TPCsignalPi, hyperrec::TPCChi2He, hyperrec::ITSChi2He, hyperrec::ITSChi2Pi, hyperrec::TOFMass, hyperrec::ITSclusterSizesHe, hyperrec::ITSclusterSizesPi, hyperrec::Flags, hyperrec::TrackedClSize, diff --git a/PWGLF/DataModel/LFKinkDecayTables.h b/PWGLF/DataModel/LFKinkDecayTables.h index 9533bd66116..d8df2eb865f 100644 --- a/PWGLF/DataModel/LFKinkDecayTables.h +++ b/PWGLF/DataModel/LFKinkDecayTables.h @@ -47,6 +47,21 @@ DECLARE_SOA_COLUMN(DcaMothPv, dcaMothPv, float); //! DCA of the mother to th DECLARE_SOA_COLUMN(DcaDaugPv, dcaDaugPv, float); //! DCA of the daughter kink to the primary vertex DECLARE_SOA_COLUMN(DcaKinkTopo, dcaKinkTopo, float); //! DCA of the kink topology +DECLARE_SOA_COLUMN(NSigmaTPCPi, nSigmaTPCPi, float); //! Number of sigmas for the pion candidate from Sigma kink in TPC +DECLARE_SOA_COLUMN(NSigmaTPCPr, nSigmaTPCPr, float); //! Number of sigmas for the proton candidate from Sigma kink in TPC +DECLARE_SOA_COLUMN(NSigmaTPCKa, nSigmaTPCKa, float); //! Number of sigmas for the kaon candidate from Sigma kink in TPC +DECLARE_SOA_COLUMN(NSigmaTOFPi, nSigmaTOFPi, float); //! Number of sigmas for the pion candidate from Sigma kink in TOF +DECLARE_SOA_COLUMN(NSigmaTOFPr, nSigmaTOFPr, float); //! Number of sigmas for the proton candidate from Sigma kink in TOF +DECLARE_SOA_COLUMN(NSigmaTOFKa, nSigmaTOFKa, float); //! Number of sigmas for the kaon candidate from Sigma kink in TOF + +// MC Columns +DECLARE_SOA_COLUMN(MothPdgCode, mothPdgCode, int); //! PDG code of the Sigma daughter +DECLARE_SOA_COLUMN(DaugPdgCode, daugPdgCode, int); //! PDG code of the kink daughter +DECLARE_SOA_COLUMN(PtMC, ptMC, float); //! pT of the candidate in MC +DECLARE_SOA_COLUMN(MassMC, massMC, float); //! Invariant mass of the candidate in MC +DECLARE_SOA_COLUMN(DecayRadiusMC, decayRadiusMC, float); //! Decay radius of the candidate in MC +DECLARE_SOA_COLUMN(CollisionIdCheck, collisionIdCheck, bool); //! Check if mcDaughter collision ID matches the reconstructed collision ID + // DYNAMIC COLUMNS DECLARE_SOA_DYNAMIC_COLUMN(PxDaugNeut, pxDaugNeut, //! Px of the daughter neutral particle @@ -120,6 +135,26 @@ DECLARE_SOA_TABLE(KinkCandsUnbound, "AOD", "UBKINKCANDS", kinkcand::MSigmaPlus, kinkcand::MXiMinus); +DECLARE_SOA_TABLE(SlimKinkCands, "AOD", "SLIMKINKCANDS", + kinkcand::XDecVtx, kinkcand::YDecVtx, kinkcand::ZDecVtx, + kinkcand::PxMoth, kinkcand::PyMoth, kinkcand::PzMoth, + kinkcand::PxDaug, kinkcand::PyDaug, kinkcand::PzDaug, + kinkcand::DcaMothPv, kinkcand::DcaDaugPv, kinkcand::DcaKinkTopo, + kinkcand::MothSign, + kinkcand::NSigmaTPCPi, kinkcand::NSigmaTPCPr, kinkcand::NSigmaTPCKa, + kinkcand::NSigmaTOFPi, kinkcand::NSigmaTOFPr, kinkcand::NSigmaTOFKa); + +DECLARE_SOA_TABLE(SlimKinkCandsMC, "AOD", "SLIMKINKCANDSMC", + kinkcand::XDecVtx, kinkcand::YDecVtx, kinkcand::ZDecVtx, + kinkcand::PxMoth, kinkcand::PyMoth, kinkcand::PzMoth, + kinkcand::PxDaug, kinkcand::PyDaug, kinkcand::PzDaug, + kinkcand::DcaMothPv, kinkcand::DcaDaugPv, kinkcand::DcaKinkTopo, + kinkcand::MothSign, + kinkcand::NSigmaTPCPi, kinkcand::NSigmaTPCPr, kinkcand::NSigmaTPCKa, + kinkcand::NSigmaTOFPi, kinkcand::NSigmaTOFPr, kinkcand::NSigmaTOFKa, + kinkcand::MothPdgCode, kinkcand::DaugPdgCode, + kinkcand::PtMC, kinkcand::MassMC, kinkcand::DecayRadiusMC, kinkcand::CollisionIdCheck); + } // namespace o2::aod #endif // PWGLF_DATAMODEL_LFKINKDECAYTABLES_H_ diff --git a/PWGLF/DataModel/LFPIDTOFGenericTables.h b/PWGLF/DataModel/LFPIDTOFGenericTables.h new file mode 100644 index 00000000000..3a52a8a8ca5 --- /dev/null +++ b/PWGLF/DataModel/LFPIDTOFGenericTables.h @@ -0,0 +1,59 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +/// \file LFPIDTOFGenericTables.h +/// \brief Table for event time without remving track bias +/// \author Yuanzhe Wang + +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" + +#ifndef PWGLF_DATAMODEL_LFPIDTOFGENERICTABLES_H_ +#define PWGLF_DATAMODEL_LFPIDTOFGENERICTABLES_H_ +#include "Common/Core/PID/PIDTOF.h" + +#include "CommonDataFormat/InteractionRecord.h" + +namespace o2::aod +{ +namespace evtime +{ + +DECLARE_SOA_COLUMN(EvTime, evTime, float); //! Event time. Can be obtained via a combination of detectors e.g. TOF, FT0A, FT0C +DECLARE_SOA_COLUMN(EvTimeErr, evTimeErr, float); //! Error of event time. Can be obtained via a combination of detectors e.g. TOF, FT0A, FT0C +DECLARE_SOA_COLUMN(EvTimeTOF, evTimeTOF, float); //! Event time computed with the TOF detector +DECLARE_SOA_COLUMN(EvTimeTOFErr, evTimeTOFErr, float); //! Error of the event time computed with the TOF detector +DECLARE_SOA_COLUMN(EvTimeFT0, evTimeFT0, float); //! Event time computed with the FT0 detector +DECLARE_SOA_COLUMN(EvTimeFT0Err, evTimeFT0Err, float); //! Error of the event time computed with the FT0 detector +} // namespace evtime + +DECLARE_SOA_TABLE(EvTimeTOFFT0, "AOD", "EvTimeTOFFT0", //! Table of the event time. One entry per collision. + evtime::EvTime, + evtime::EvTimeErr, + evtime::EvTimeTOF, + evtime::EvTimeTOFErr, + evtime::EvTimeFT0, + evtime::EvTimeFT0Err); + +namespace tracktime +{ + +DECLARE_SOA_COLUMN(EvTimeForTrack, evTimeForTrack, float); //! Event time. Removed the bias for the specific track +DECLARE_SOA_COLUMN(EvTimeErrForTrack, evTimeErrForTrack, float); //! Error of event time. Removed the bias for the specific track +} // namespace tracktime + +DECLARE_SOA_TABLE(EvTimeTOFFT0ForTrack, "AOD", "EvTimeForTrack", //! Table of the event time. One entry per track. + tracktime::EvTimeForTrack, + tracktime::EvTimeErrForTrack); + +} // namespace o2::aod + +#endif // PWGLF_DATAMODEL_LFPIDTOFGENERICTABLES_H_ diff --git a/PWGLF/DataModel/LFSlimHeLambda.h b/PWGLF/DataModel/LFSlimHeLambda.h index fc0178907df..8745ac1838a 100644 --- a/PWGLF/DataModel/LFSlimHeLambda.h +++ b/PWGLF/DataModel/LFSlimHeLambda.h @@ -42,17 +42,22 @@ DECLARE_SOA_COLUMN(CosPA, cosPA, float); DECLARE_SOA_COLUMN(DCAxy, dcaXY, float); DECLARE_SOA_COLUMN(DCAz, dcaZ, float); DECLARE_SOA_COLUMN(TPCnCls, tpcNCls, int); +DECLARE_SOA_COLUMN(TPCnClsPID, tpcNClsPID, int); DECLARE_SOA_COLUMN(ITSClusterSizes, itsClusterSizes, uint32_t); +DECLARE_SOA_COLUMN(NsigmaTPCPion, nSigmaTPCPion, float); +DECLARE_SOA_COLUMN(NsigmaTPCProton, nSigmaTPCProton, float); DECLARE_SOA_COLUMN(NsigmaTPC, nSigmaTPC, float); -// DECLARE_SOA_COLUMN(NsigmaTPCproton, nSigmaTPCproton, float); DECLARE_SOA_COLUMN(DCAdaughters, dcaDaughters, float); DECLARE_SOA_COLUMN(DCAPVProton, dcaPVProton, float); DECLARE_SOA_COLUMN(DCAPVPion, dcaPVPion, float); DECLARE_SOA_COLUMN(V0Radius, v0Radius, float); DECLARE_SOA_COLUMN(Sign, sign, int8_t); } // namespace lfv0he3 -DECLARE_SOA_TABLE(LFHe3, "AOD", "LFHE3V0", lfv0he3::LFEventId, lfv0he3::Pt, lfv0he3::Eta, lfv0he3::Phi, lfv0he3::DCAxy, lfv0he3::DCAz, lfv0he3::TPCnCls, lfv0he3::ITSClusterSizes, lfv0he3::NsigmaTPC, lfv0he3::Sign); -DECLARE_SOA_TABLE(LFLambda, "AOD", "LFLAMBDA", lfv0he3::LFEventId, lfv0he3::Pt, lfv0he3::Eta, lfv0he3::Phi, lfv0he3::Mass, lfv0he3::CosPA, lfv0he3::DCAdaughters, lfv0he3::DCAPVProton, lfv0he3::DCAPVPion, lfv0he3::V0Radius, lfv0he3::Sign); +DECLARE_SOA_TABLE_VERSIONED(LFHe3_000, "AOD", "LFHE3V0", 0, lfv0he3::LFEventId, lfv0he3::Pt, lfv0he3::Eta, lfv0he3::Phi, lfv0he3::DCAxy, lfv0he3::DCAz, lfv0he3::TPCnCls, lfv0he3::ITSClusterSizes, lfv0he3::NsigmaTPC, lfv0he3::Sign); +DECLARE_SOA_TABLE_VERSIONED(LFLambda_000, "AOD", "LFLAMBDA", 0, lfv0he3::LFEventId, lfv0he3::Pt, lfv0he3::Eta, lfv0he3::Phi, lfv0he3::Mass, lfv0he3::CosPA, lfv0he3::DCAdaughters, lfv0he3::DCAPVProton, lfv0he3::DCAPVPion, lfv0he3::V0Radius, lfv0he3::Sign); + +DECLARE_SOA_TABLE_VERSIONED(LFHe3_001, "AOD", "LFHE3V0", 1, lfv0he3::LFEventId, lfv0he3::Pt, lfv0he3::Eta, lfv0he3::Phi, lfv0he3::DCAxy, lfv0he3::DCAz, lfv0he3::TPCnCls, lfv0he3::TPCnClsPID, lfv0he3::ITSClusterSizes, lfv0he3::NsigmaTPC, lfv0he3::Sign); +DECLARE_SOA_TABLE_VERSIONED(LFLambda_001, "AOD", "LFLAMBDA", 1, lfv0he3::LFEventId, lfv0he3::Pt, lfv0he3::Eta, lfv0he3::Phi, lfv0he3::Mass, lfv0he3::CosPA, lfv0he3::DCAdaughters, lfv0he3::DCAPVProton, lfv0he3::DCAPVPion, lfv0he3::V0Radius, lfv0he3::NsigmaTPCProton, lfv0he3::NsigmaTPCPion, lfv0he3::Sign); } // namespace o2::aod struct he3Candidate { @@ -61,6 +66,7 @@ struct he3Candidate { float dcaXY = -999.f; float dcaZ = -999.f; int tpcNClsFound = 0; // Number of TPC clusters found + int tpcNClsPID = 0; // Number of TPC clusters used for PID int itsNCls = 0; // Number of ITS clusters uint32_t itsClusterSizes = 0; // ITS cluster sizes int8_t sign = 0; // Charge sign of the He3 candidate @@ -75,7 +81,7 @@ struct lambdaCandidate { float dcaPionToPV = -999.f; // DCA of the pion to primary vertex float v0Radius = -1.f; // V0 radius float protonNSigmaTPC = -999.f; // Proton TPC nSigma - float pionNSigmaTPC = -999.f; + float pionNSigmaTPC = -999.f; // Pion TPC nSigma int8_t sign = 0; // Charge sign of the Lambda candidate }; diff --git a/PWGLF/DataModel/LFStrangenessPIDTables.h b/PWGLF/DataModel/LFStrangenessPIDTables.h index e689dc28141..0b7e95ce302 100644 --- a/PWGLF/DataModel/LFStrangenessPIDTables.h +++ b/PWGLF/DataModel/LFStrangenessPIDTables.h @@ -47,6 +47,10 @@ DECLARE_SOA_TABLE(DauTrackTOFPIDs, "AOD", "DAUTRACKTOFPID", // raw table (for po namespace v0data { +// define constants for NSigma operation +const float kNoTOFValue = -1e+6; +const float kEpsilon = 1e-4; + // ==== TOF INFORMATION === // lengths as stored in the AO2D for TOF calculations DECLARE_SOA_COLUMN(PosTOFLengthToPV, posTOFLengthToPV, float); //! positive track length to PV @@ -79,6 +83,45 @@ DECLARE_SOA_COLUMN(TOFNSigmaALaPi, tofNSigmaALaPi, float); //! positive DECLARE_SOA_COLUMN(TOFNSigmaK0PiPlus, tofNSigmaK0PiPlus, float); //! positive track NSigma from pion <- k0short expectation DECLARE_SOA_COLUMN(TOFNSigmaK0PiMinus, tofNSigmaK0PiMinus, float); //! negative track NSigma from pion <- k0short expectation +// dynamics based on n-sigmas with use-only-if-tof-present logic +DECLARE_SOA_DYNAMIC_COLUMN(TofLambdaCompatibility, tofLambdaCompatibility, //! compatibility with being lambda, checked only if TOF present. Argument: number of sigmas + [](float tofNSigmaLaPr, float tofNSigmaLaPi, float nsigma) -> float { + bool compatible = true; + if (std::abs(tofNSigmaLaPr - kNoTOFValue) > kEpsilon && std::abs(tofNSigmaLaPr) > nsigma) { + compatible = false; // reject only if info present and incompatible + } + if (std::abs(tofNSigmaLaPi - kNoTOFValue) > kEpsilon && std::abs(tofNSigmaLaPi) > nsigma) { + compatible = false; // reject only if info present and incompatible + } + return compatible; + }); + +// dynamics based on n-sigmas with use-only-if-tof-present logic +DECLARE_SOA_DYNAMIC_COLUMN(TofAntiLambdaCompatibility, tofAntiLambdaCompatibility, //! compatibility with being lambda, checked only if TOF present. Argument: number of sigmas + [](float tofNSigmaALaPr, float tofNSigmaALaPi, float nsigma) -> float { + bool compatible = true; + if (std::abs(tofNSigmaALaPr - kNoTOFValue) > kEpsilon && std::abs(tofNSigmaALaPr) > nsigma) { + compatible = false; // reject only if info present and incompatible + } + if (std::abs(tofNSigmaALaPi - kNoTOFValue) > kEpsilon && std::abs(tofNSigmaALaPi) > nsigma) { + compatible = false; // reject only if info present and incompatible + } + return compatible; + }); + +// dynamics based on n-sigmas with use-only-if-tof-present logic +DECLARE_SOA_DYNAMIC_COLUMN(TofK0ShortCompatibility, tofK0ShortCompatibility, //! compatibility with being lambda, checked only if TOF present. Argument: number of sigmas + [](float tofNSigmaK0PiPlus, float tofNSigmaK0PiMinus, float nsigma) -> float { + bool compatible = true; + if (std::abs(tofNSigmaK0PiPlus - kNoTOFValue) > kEpsilon && std::abs(tofNSigmaK0PiPlus) > nsigma) { + compatible = false; // reject only if info present and incompatible + } + if (std::abs(tofNSigmaK0PiMinus - kNoTOFValue) > kEpsilon && std::abs(tofNSigmaK0PiMinus) > nsigma) { + compatible = false; // reject only if info present and incompatible + } + return compatible; + }); + // beta values DECLARE_SOA_COLUMN(TofBetaLambda, tofBetaLambda, float); //! beta value with Lambda hypothesis DECLARE_SOA_COLUMN(TofBetaAntiLambda, tofBetaAntiLambda, float); //! beta value with AntiLambda hypothesis @@ -120,10 +163,17 @@ DECLARE_SOA_TABLE(V0TOFBetas, "AOD", "V0TOFBETA", // processed info table (for a DECLARE_SOA_TABLE(V0TOFNSigmas, "AOD", "V0TOFNSIGMA", // processed NSigma table (for analysis) v0data::TOFNSigmaLaPr, v0data::TOFNSigmaLaPi, v0data::TOFNSigmaALaPr, v0data::TOFNSigmaALaPi, - v0data::TOFNSigmaK0PiPlus, v0data::TOFNSigmaK0PiMinus); + v0data::TOFNSigmaK0PiPlus, v0data::TOFNSigmaK0PiMinus, + v0data::TofLambdaCompatibility, + v0data::TofAntiLambdaCompatibility, + v0data::TofK0ShortCompatibility); namespace cascdata { +// define constants for NSigma operation +const float kNoTOFValue = -1e+6; +const float kEpsilon = 1e-4; + // lengths as stored in the AO2D for TOF calculations DECLARE_SOA_COLUMN(PosTOFLengthToPV, posTOFLengthToPV, float); //! positive track length DECLARE_SOA_COLUMN(NegTOFLengthToPV, negTOFLengthToPV, float); //! negative track length @@ -154,6 +204,38 @@ DECLARE_SOA_COLUMN(TOFNSigmaXiPi, tofNSigmaXiPi, float); //! bachelor track DECLARE_SOA_COLUMN(TOFNSigmaOmLaPi, tofNSigmaOmLaPi, float); //! meson track NSigma from pion <- lambda <- om expectation DECLARE_SOA_COLUMN(TOFNSigmaOmLaPr, tofNSigmaOmLaPr, float); //! baryon track NSigma from proton <- lambda <- om expectation DECLARE_SOA_COLUMN(TOFNSigmaOmKa, tofNSigmaOmKa, float); //! bachelor track NSigma from kaon <- om expectation + +// dynamics based on n-sigmas with use-only-if-tof-present logic +DECLARE_SOA_DYNAMIC_COLUMN(TofXiCompatibility, tofXiCompatibility, //! compatibility with being lambda, checked only if TOF present. Argument: number of sigmas + [](float tofNSigmaXiLaPr, float tofNSigmaXiLaPi, float tofNSigmaXiPi, float nsigma) -> float { + bool compatible = true; + if (std::abs(tofNSigmaXiLaPr - kNoTOFValue) > kEpsilon && std::abs(tofNSigmaXiLaPr) > nsigma) { + compatible = false; // reject only if info present and incompatible + } + if (std::abs(tofNSigmaXiLaPi - kNoTOFValue) > kEpsilon && std::abs(tofNSigmaXiLaPi) > nsigma) { + compatible = false; // reject only if info present and incompatible + } + if (std::abs(tofNSigmaXiPi - kNoTOFValue) > kEpsilon && std::abs(tofNSigmaXiPi) > nsigma) { + compatible = false; // reject only if info present and incompatible + } + return compatible; + }); + +DECLARE_SOA_DYNAMIC_COLUMN(TofOmegaCompatibility, tofOmegaCompatibility, //! compatibility with being lambda, checked only if TOF present. Argument: number of sigmas + [](float tofNSigmaOmLaPr, float tofNSigmaOmLaPi, float tofNSigmaOmKa, float nsigma) -> float { + bool compatible = true; + if (std::abs(tofNSigmaOmLaPr - kNoTOFValue) > kEpsilon && std::abs(tofNSigmaOmLaPr) > nsigma) { + compatible = false; // reject only if info present and incompatible + } + if (std::abs(tofNSigmaOmLaPi - kNoTOFValue) > kEpsilon && std::abs(tofNSigmaOmLaPi) > nsigma) { + compatible = false; // reject only if info present and incompatible + } + if (std::abs(tofNSigmaOmKa - kNoTOFValue) > kEpsilon && std::abs(tofNSigmaOmKa) > nsigma) { + compatible = false; // reject only if info present and incompatible + } + return compatible; + }); + } // namespace cascdata // /-|-\-|-/-|-\-|-/-|-\-|-/-|-\-|-/-|-\-|-/-|-\-|-/-|-\-|-/-|-\-|-/-|-\-|-/-|-\-|-/ @@ -173,7 +255,9 @@ DECLARE_SOA_TABLE(CascTOFPIDs, "AOD", "CASCTOFPID", // processed information for cascdata::BachTOFDeltaTOmKa); DECLARE_SOA_TABLE(CascTOFNSigmas, "AOD", "CascTOFNSigmas", // Nsigmas for cascades cascdata::TOFNSigmaXiLaPi, cascdata::TOFNSigmaXiLaPr, cascdata::TOFNSigmaXiPi, - cascdata::TOFNSigmaOmLaPi, cascdata::TOFNSigmaOmLaPr, cascdata::TOFNSigmaOmKa); + cascdata::TOFNSigmaOmLaPi, cascdata::TOFNSigmaOmLaPr, cascdata::TOFNSigmaOmKa, + cascdata::TofXiCompatibility, + cascdata::TofOmegaCompatibility); } // namespace o2::aod #endif // PWGLF_DATAMODEL_LFSTRANGENESSPIDTABLES_H_ diff --git a/PWGLF/DataModel/LFStrangenessTables.h b/PWGLF/DataModel/LFStrangenessTables.h index 3ee36c7c54a..ca58973dff8 100644 --- a/PWGLF/DataModel/LFStrangenessTables.h +++ b/PWGLF/DataModel/LFStrangenessTables.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -709,11 +710,38 @@ DECLARE_SOA_DYNAMIC_COLUMN(PFracNeg, pfracneg, // Calculated on the fly with mass assumption + dynamic tables DECLARE_SOA_DYNAMIC_COLUMN(MLambda, mLambda, //! mass under lambda hypothesis - [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::m(std::array{std::array{pxpos, pypos, pzpos}, std::array{pxneg, pyneg, pzneg}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); }); + [](int v0type, float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { + if ((v0type & (0x1 << o2::dataformats::V0Index::kPhotonOnly)) != 0) { + return 0.0f; // provide mass only if NOT a photon with TPC-only tracks (special handling) + }; + return RecoDecay::m(std::array{std::array{pxpos, pypos, pzpos}, std::array{pxneg, pyneg, pzneg}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); + }); DECLARE_SOA_DYNAMIC_COLUMN(MAntiLambda, mAntiLambda, //! mass under antilambda hypothesis - [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::m(std::array{std::array{pxpos, pypos, pzpos}, std::array{pxneg, pyneg, pzneg}}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); }); + [](int v0type, float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { + if ((v0type & (0x1 << o2::dataformats::V0Index::kPhotonOnly)) != 0) { + return 0.0f; // provide mass only if NOT a photon with TPC-only tracks (special handling) + }; + return RecoDecay::m(std::array{std::array{pxpos, pypos, pzpos}, std::array{pxneg, pyneg, pzneg}}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); + }); DECLARE_SOA_DYNAMIC_COLUMN(MK0Short, mK0Short, //! mass under K0short hypothesis - [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::m(std::array{std::array{pxpos, pypos, pzpos}, std::array{pxneg, pyneg, pzneg}}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); }); + [](int v0type, float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { + if ((v0type & (0x1 << o2::dataformats::V0Index::kPhotonOnly)) != 0) { + return 0.0f; // provide mass only if NOT a photon with TPC-only tracks (special handling) + }; + return RecoDecay::m(std::array{std::array{pxpos, pypos, pzpos}, std::array{pxneg, pyneg, pzneg}}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); + }); +DECLARE_SOA_DYNAMIC_COLUMN(MLambda_unchecked, mLambda_unchecked, //! mass under lambda hypothesis without v0 type check (will include TPC only and potentially duplicates! use with care) + [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { + return RecoDecay::m(std::array{std::array{pxpos, pypos, pzpos}, std::array{pxneg, pyneg, pzneg}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); + }); +DECLARE_SOA_DYNAMIC_COLUMN(MAntiLambda_unchecked, mAntiLambda_unchecked, //! mass under antilambda hypothesis without v0 type check (will include TPC only and potentially duplicates! use with care) + [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { + return RecoDecay::m(std::array{std::array{pxpos, pypos, pzpos}, std::array{pxneg, pyneg, pzneg}}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); + }); +DECLARE_SOA_DYNAMIC_COLUMN(MK0Short_unchecked, mK0Short_unchecked, //! mass under K0short hypothesis without v0 type check (will include TPC only and potentially duplicates! use with care) + [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { + return RecoDecay::m(std::array{std::array{pxpos, pypos, pzpos}, std::array{pxneg, pyneg, pzneg}}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); + }); DECLARE_SOA_DYNAMIC_COLUMN(MGamma, mGamma, //! mass under gamma hypothesis [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { return RecoDecay::m(std::array{std::array{pxpos, pypos, pzpos}, std::array{pxneg, pyneg, pzneg}}, std::array{o2::constants::physics::MassElectron, o2::constants::physics::MassElectron}); }); // Account for rigidity in case of hypertriton @@ -772,12 +800,12 @@ DECLARE_SOA_DYNAMIC_COLUMN(PositiveEta, positiveeta, //! positive daughter eta DECLARE_SOA_DYNAMIC_COLUMN(PositivePhi, positivephi, //! positive daughter phi [](float PxPos, float PyPos) -> float { return RecoDecay::phi(PxPos, PyPos); }); -DECLARE_SOA_DYNAMIC_COLUMN(IsStandardV0, isStandardV0, //! is standard V0 - [](uint8_t V0Type) -> bool { return V0Type == 1; }); +DECLARE_SOA_DYNAMIC_COLUMN(IsStandardV0, isStandardV0, //! is standard V0 - note: photons excluded via '==' + [](uint8_t V0Type) -> bool { return V0Type == o2::dataformats::V0Index::kStandaloneV0; }); DECLARE_SOA_DYNAMIC_COLUMN(IsPhotonTPConly, isPhotonTPConly, //! is tpc-only photon V0 - [](uint8_t V0Type) -> bool { return V0Type & (1 << 1); }); + [](uint8_t V0Type) -> bool { return V0Type & (1 << o2::dataformats::V0Index::kPhotonOnly); }); DECLARE_SOA_DYNAMIC_COLUMN(IsCollinear, isCollinear, //! is collinear V0 - [](uint8_t V0Type) -> bool { return V0Type & (1 << 2); }); + [](uint8_t V0Type) -> bool { return V0Type & (1 << o2::dataformats::V0Index::kCollinear); }); DECLARE_SOA_DYNAMIC_COLUMN(RapidityMC, rapidityMC, //! rapidity (0:K0, 1:L, 2:Lbar) [](float PxMC, float PyMC, float PzMC, int value) -> float { @@ -794,6 +822,24 @@ DECLARE_SOA_DYNAMIC_COLUMN(PositivePtMC, positiveptMC, //! positive daughter pT [](float pxposMC, float pyposMC) -> float { return RecoDecay::sqrtSumOfSquares(pxposMC, pyposMC); }); DECLARE_SOA_DYNAMIC_COLUMN(PtMC, ptMC, //! V0 pT [](float pxMC, float pyMC) -> float { return RecoDecay::sqrtSumOfSquares(pxMC, pyMC); }); + +// declare legacy mass getters in v0data legacy name space +// caution: these do not have intrinsic protection against photon candidates +namespace legacy +{ +DECLARE_SOA_DYNAMIC_COLUMN(MLambda, mLambda, //! mass under lambda hypothesis without v0 type check (will include TPC only and potentially duplicates! use with care) + [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { + return RecoDecay::m(std::array{std::array{pxpos, pypos, pzpos}, std::array{pxneg, pyneg, pzneg}}, std::array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); + }); +DECLARE_SOA_DYNAMIC_COLUMN(MAntiLambda, mAntiLambda, //! mass under antilambda hypothesis without v0 type check (will include TPC only and potentially duplicates! use with care) + [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { + return RecoDecay::m(std::array{std::array{pxpos, pypos, pzpos}, std::array{pxneg, pyneg, pzneg}}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); + }); +DECLARE_SOA_DYNAMIC_COLUMN(MK0Short, mK0Short, //! mass under K0short hypothesis without v0 type check (will include TPC only and potentially duplicates! use with care) + [](float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) -> float { + return RecoDecay::m(std::array{std::array{pxpos, pypos, pzpos}, std::array{pxneg, pyneg, pzneg}}, std::array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); + }); +} // namespace legacy } // namespace v0data DECLARE_SOA_TABLE(V0Indices, "AOD", "V0INDEX", //! index table when using AO2Ds @@ -835,9 +881,12 @@ DECLARE_SOA_TABLE_STAGED(V0CoresBase, "V0CORE", //! core information about decay v0data::PFracNeg, // 24 // Invariant masses - v0data::MLambda, - v0data::MAntiLambda, - v0data::MK0Short, + v0data::MLambda, + v0data::MAntiLambda, + v0data::MK0Short, + v0data::MLambda_unchecked, + v0data::MAntiLambda_unchecked, + v0data::MK0Short_unchecked, v0data::MGamma, v0data::MHypertriton, v0data::MAntiHypertriton, @@ -916,9 +965,9 @@ DECLARE_SOA_TABLE_FULL(StoredV0fCCores, "V0fCCores", "AOD", "V0FCCORE", //! core v0data::PFracNeg, // 24 // Invariant masses - v0data::MLambda, - v0data::MAntiLambda, - v0data::MK0Short, + v0data::MLambda, + v0data::MAntiLambda, + v0data::MK0Short, v0data::MGamma, v0data::MHypertriton, v0data::MAntiHypertriton, diff --git a/PWGLF/DataModel/LFhe3HadronTables.h b/PWGLF/DataModel/LFhe3HadronTables.h index f0dbc5cc3dd..07ce17853ea 100644 --- a/PWGLF/DataModel/LFhe3HadronTables.h +++ b/PWGLF/DataModel/LFhe3HadronTables.h @@ -36,6 +36,7 @@ DECLARE_SOA_COLUMN(DCAxyHe3, dcaxyHe3, float); DECLARE_SOA_COLUMN(DCAzHe3, dcazHe3, float); DECLARE_SOA_COLUMN(DCAxyHad, dcaxyHad, float); DECLARE_SOA_COLUMN(DCAzHad, dcazHad, float); +DECLARE_SOA_COLUMN(DCApair, dcapair, float); DECLARE_SOA_COLUMN(SignalTPCHe3, signalTPCHe3, float); DECLARE_SOA_COLUMN(InnerParamTPCHe3, innerParamTPCHe3, float); @@ -75,9 +76,12 @@ DECLARE_SOA_COLUMN(Multiplicity, multiplicity, uint16_t); DECLARE_SOA_COLUMN(CentralityFT0C, centFT0C, float); DECLARE_SOA_COLUMN(MultiplicityFT0C, multiplicityFT0C, float); -DECLARE_SOA_COLUMN(IsMotherLi4, isMotherLi4, bool); -DECLARE_SOA_COLUMN(IsHe3Primary, isHe3Primary, bool); -DECLARE_SOA_COLUMN(IsHadPrimary, isHadPrimary, bool); +/* Flags: 0 - both primary, + 1 - both from Li4, + 2 - both from hypertriton, + 3 - mixed pair (a primary and one from Li4/hypertriton/material/other decays or any other combination) +*/ +DECLARE_SOA_COLUMN(Flags, flags, uint8_t); } // namespace he3HadronTablesNS @@ -92,6 +96,7 @@ DECLARE_SOA_TABLE(he3HadronTable, "AOD", "HE3HADTABLE", he3HadronTablesNS::DCAzHe3, he3HadronTablesNS::DCAxyHad, he3HadronTablesNS::DCAzHad, + he3HadronTablesNS::DCApair, he3HadronTablesNS::SignalTPCHe3, he3HadronTablesNS::InnerParamTPCHe3, he3HadronTablesNS::SignalTPCHad, @@ -120,9 +125,7 @@ DECLARE_SOA_TABLE(he3HadronTableMC, "AOD", "HE3HADTABLEMC", he3HadronTablesNS::PhiMCHad, he3HadronTablesNS::SignedPtMC, he3HadronTablesNS::MassMC, - he3HadronTablesNS::IsMotherLi4, - he3HadronTablesNS::IsHe3Primary, - he3HadronTablesNS::IsHadPrimary) + he3HadronTablesNS::Flags) DECLARE_SOA_TABLE(he3HadronMult, "AOD", "HE3HADMULT", he3HadronTablesNS::CollisionId, he3HadronTablesNS::ZVertex, diff --git a/PWGLF/DataModel/Vtx3BodyTables.h b/PWGLF/DataModel/Vtx3BodyTables.h index 352687192eb..55bdea60789 100644 --- a/PWGLF/DataModel/Vtx3BodyTables.h +++ b/PWGLF/DataModel/Vtx3BodyTables.h @@ -67,10 +67,10 @@ DECLARE_SOA_COLUMN(DCAZTrackPiToPV, dcaZtrackPiToPv, float); //! DCAZ of pion DECLARE_SOA_COLUMN(DCAZTrackDeToPV, dcaZtrackDeToPv, float); //! DCAZ of deuteron to PV // DCAs to SV -DECLARE_SOA_COLUMN(DCATrackPrToSV, dcaTrackPrToSv, float); //! DCA of proton to SV -DECLARE_SOA_COLUMN(DCATrackPiToSV, dcaTrackPiToSv, float); //! DCA of pion to SV -DECLARE_SOA_COLUMN(DCATrackDeToSV, dcaTrackDeToSv, float); //! DCA of deuteron to SV -DECLARE_SOA_COLUMN(DCAVtxDaughters, dcaVtxdaughters, float); //! Quadratic sum of DCA between daughters at SV +DECLARE_SOA_COLUMN(DCATrackPrToSV, dcaTrackPrToSv, float); //! DCA of proton to SV +DECLARE_SOA_COLUMN(DCATrackPiToSV, dcaTrackPiToSv, float); //! DCA of pion to SV +DECLARE_SOA_COLUMN(DCATrackDeToSV, dcaTrackDeToSv, float); //! DCA of deuteron to SV +DECLARE_SOA_COLUMN(DCAVtxToDaughtersAv, dcaVtxToDaughtersAv, float); //! Quadratic sum of DCA between daughters at SV // CosPA DECLARE_SOA_COLUMN(CosPA, cosPA, float); //! Cosine of pointing angle of the 3body candidate @@ -211,7 +211,7 @@ DECLARE_SOA_TABLE(Vtx3BodyDatas, "AOD", "VTX3BODYDATA", //! vtx3body::DCAXYTrackPrToPV, vtx3body::DCAXYTrackPiToPV, vtx3body::DCAXYTrackDeToPV, vtx3body::DCAZTrackPrToPV, vtx3body::DCAZTrackPiToPV, vtx3body::DCAZTrackDeToPV, vtx3body::DCATrackPrToSV, vtx3body::DCATrackPiToSV, vtx3body::DCATrackDeToSV, - vtx3body::DCAVtxDaughters, + vtx3body::DCAVtxToDaughtersAv, vtx3body::CosPA, vtx3body::Ct, vtx3body::TPCNSigmaPr, vtx3body::TPCNSigmaPi, vtx3body::TPCNSigmaDe, vtx3body::TPCNSigmaPiBach, vtx3body::TOFNSigmaDe, @@ -260,7 +260,7 @@ DECLARE_SOA_TABLE(McVtx3BodyDatas, "AOD", "MC3BODYDATA", //! vtx3body::DCAXYTrackPrToPV, vtx3body::DCAXYTrackPiToPV, vtx3body::DCAXYTrackDeToPV, vtx3body::DCAZTrackPrToPV, vtx3body::DCAZTrackPiToPV, vtx3body::DCAZTrackDeToPV, vtx3body::DCATrackPrToSV, vtx3body::DCATrackPiToSV, vtx3body::DCATrackDeToSV, - vtx3body::DCAVtxDaughters, + vtx3body::DCAVtxToDaughtersAv, vtx3body::CosPA, vtx3body::Ct, vtx3body::TPCNSigmaPr, vtx3body::TPCNSigmaPi, vtx3body::TPCNSigmaDe, vtx3body::TPCNSigmaPiBach, vtx3body::TOFNSigmaDe, diff --git a/PWGLF/DataModel/cascqaanalysis.h b/PWGLF/DataModel/cascqaanalysis.h index efe98908517..be74e5241bd 100644 --- a/PWGLF/DataModel/cascqaanalysis.h +++ b/PWGLF/DataModel/cascqaanalysis.h @@ -138,7 +138,14 @@ DECLARE_SOA_COLUMN(BDTResponseOmega, bdtResponseOmega, float); DECLARE_SOA_COLUMN(CosThetaStarLambdaFromOmega, cosThetaStarLambdaFromOmega, float); DECLARE_SOA_COLUMN(CosThetaStarLambdaFromXi, cosThetaStarLambdaFromXi, float); DECLARE_SOA_COLUMN(CosThetaStarProton, cosThetaStarProton, float); - +DECLARE_SOA_COLUMN(V0Radius, v0Radius, float); +DECLARE_SOA_COLUMN(DcaPosToPV, dcaPosToPV, float); +DECLARE_SOA_COLUMN(DcaNegToPV, dcaNegToPV, float); +DECLARE_SOA_COLUMN(V0CosPA, v0CosPA, double); +DECLARE_SOA_COLUMN(DcaV0Daughters, dcaV0Daughters, float); +DECLARE_SOA_COLUMN(Pzs2Lambda, pzs2Lambda, double); +DECLARE_SOA_COLUMN(Cos2ThetaLambda, cos2ThetaLambda, double); +DECLARE_SOA_COLUMN(CosThetaLambda, cosThetaLambda, double); } // namespace cascadesflow DECLARE_SOA_TABLE(MyCascades, "AOD", "MYCASCADES", o2::soa::Index<>, @@ -173,6 +180,9 @@ DECLARE_SOA_TABLE(CascTraining, "AOD", "CascTraining", o2::soa::Index<>, DECLARE_SOA_TABLE(CascAnalysis, "AOD", "CascAnalysis", o2::soa::Index<>, cascadesflow::CentFT0C, cascadesflow::IsNoCollInTimeRange, cascadesflow::IsNoCollInRof, cascadesflow::HasEventPlane, cascadesflow::HasSpectatorPlane, cascadesflow::Sign, cascadesflow::Pt, cascadesflow::Eta, cascadesflow::Phi, cascadesflow::MassLambda, cascadesflow::MassXi, cascadesflow::MassOmega, cascadesflow::V2CSP, cascadesflow::V2CEP, cascadesflow::V1SPzdcA, cascadesflow::V1SPzdcC, cascadesflow::PsiT0C, cascadesflow::BDTResponseXi, cascadesflow::BDTResponseOmega, cascadesflow::CosThetaStarLambdaFromOmega, cascadesflow::CosThetaStarLambdaFromXi, cascadesflow::CosThetaStarProton, mycascades::McPdgCode); +DECLARE_SOA_TABLE(LambdaAnalysis, "AOD", "LambdaAnalysis", o2::soa::Index<>, + cascadesflow::CentFT0C, cascadesflow::HasEventPlane, cascadesflow::HasSpectatorPlane, cascadesflow::Sign, cascadesflow::Pt, cascadesflow::Phi, cascadesflow::MassLambda, cascadesflow::V0Radius, cascadesflow::DcaPosToPV, cascadesflow::DcaNegToPV, cascadesflow::V0CosPA, cascadesflow::DcaV0Daughters, cascadesflow::V2CEP, cascadesflow::PsiT0C, cascadesflow::Pzs2Lambda, cascadesflow::Cos2ThetaLambda, cascadesflow::CosThetaLambda); + namespace myMCcascades { diff --git a/PWGLF/DataModel/pidTOFGeneric.h b/PWGLF/DataModel/pidTOFGeneric.h deleted file mode 100644 index a0d287a7643..00000000000 --- a/PWGLF/DataModel/pidTOFGeneric.h +++ /dev/null @@ -1,220 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -#ifndef PWGLF_DATAMODEL_PIDTOFGENERIC_H_ -#define PWGLF_DATAMODEL_PIDTOFGENERIC_H_ -#include "CommonDataFormat/InteractionRecord.h" -#include "Common/Core/PID/PIDTOF.h" - -namespace o2::aod -{ -namespace evtime -{ - -DECLARE_SOA_COLUMN(EvTime, evTime, float); //! Event time. Can be obtained via a combination of detectors e.g. TOF, FT0A, FT0C -DECLARE_SOA_COLUMN(EvTimeErr, evTimeErr, float); //! Error of event time. Can be obtained via a combination of detectors e.g. TOF, FT0A, FT0C -DECLARE_SOA_COLUMN(EvTimeTOF, evTimeTOF, float); //! Event time computed with the TOF detector -DECLARE_SOA_COLUMN(EvTimeTOFErr, evTimeTOFErr, float); //! Error of the event time computed with the TOF detector -DECLARE_SOA_COLUMN(EvTimeFT0, evTimeFT0, float); //! Event time computed with the FT0 detector -DECLARE_SOA_COLUMN(EvTimeFT0Err, evTimeFT0Err, float); //! Error of the event time computed with the FT0 detector -} // namespace evtime - -DECLARE_SOA_TABLE(EvTimeTOFFT0, "AOD", "EvTimeTOFFT0", //! Table of the event time. One entry per collision. - evtime::EvTime, - evtime::EvTimeErr, - evtime::EvTimeTOF, - evtime::EvTimeTOFErr, - evtime::EvTimeFT0, - evtime::EvTimeFT0Err); - -namespace tracktime -{ - -DECLARE_SOA_COLUMN(EvTimeForTrack, evTimeForTrack, float); //! Event time. Removed the bias for the specific track -DECLARE_SOA_COLUMN(EvTimeErrForTrack, evTimeErrForTrack, float); //! Error of event time. Removed the bias for the specific track -} // namespace tracktime - -DECLARE_SOA_TABLE(EvTimeTOFFT0ForTrack, "AOD", "EvTimeForTrack", //! Table of the event time. One entry per track. - tracktime::EvTimeForTrack, - tracktime::EvTimeErrForTrack); - -namespace pidtofgeneric -{ - -static constexpr float kCSPEED = TMath::C() * 1.0e2f * 1.0e-12f; // c in cm/ps - -template -class TofPidNewCollision -{ - public: - TofPidNewCollision() = default; - ~TofPidNewCollision() = default; - - o2::pid::tof::TOFResoParamsV2 mRespParamsV2; - o2::track::PID::ID pidType; - - template - using ResponseImplementation = o2::pid::tof::ExpTimes; - static constexpr auto responseEl = ResponseImplementation(); - static constexpr auto responseMu = ResponseImplementation(); - static constexpr auto responsePi = ResponseImplementation(); - static constexpr auto responseKa = ResponseImplementation(); - static constexpr auto responsePr = ResponseImplementation(); - static constexpr auto responseDe = ResponseImplementation(); - static constexpr auto responseTr = ResponseImplementation(); - static constexpr auto responseHe = ResponseImplementation(); - static constexpr auto responseAl = ResponseImplementation(); - - void SetParams(o2::pid::tof::TOFResoParamsV2 const& para) - { - mRespParamsV2.setParameters(para); - } - - void SetPidType(o2::track::PID::ID pidId) - { - pidType = pidId; - } - - template - float GetTOFNSigma(o2::track::PID::ID pidId, TTrack const& track, TCollision const& originalcol, TCollision const& correctedcol, bool EnableBCAO2D = true); - - template - float GetTOFNSigma(TTrack const& track, TCollision const& originalcol, TCollision const& correctedcol, bool EnableBCAO2D = true); - - float GetTOFNSigma(TTrack const& track); - float GetTOFNSigma(o2::track::PID::ID pidId, TTrack const& track); - - float CalculateTOFNSigma(o2::track::PID::ID pidId, TTrack const& track, double tofsignal, double evTime, double evTimeErr) - { - - float expSigma, tofNsigma = -999; - - switch (pidId) { - case 0: - expSigma = responseEl.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); - tofNsigma = (tofsignal - evTime - responseEl.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - break; - case 1: - expSigma = responseMu.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); - tofNsigma = (tofsignal - evTime - responseMu.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - break; - case 2: - expSigma = responsePi.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); - tofNsigma = (tofsignal - evTime - responsePi.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - break; - case 3: - expSigma = responseKa.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); - tofNsigma = (tofsignal - evTime - responseKa.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - break; - case 4: - expSigma = responsePr.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); - tofNsigma = (tofsignal - evTime - responsePr.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - break; - case 5: - expSigma = responseDe.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); - tofNsigma = (tofsignal - evTime - responseDe.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - break; - case 6: - expSigma = responseTr.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); - tofNsigma = (tofsignal - evTime - responseTr.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - break; - case 7: - expSigma = responseHe.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); - tofNsigma = (tofsignal - evTime - responseHe.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - break; - case 8: - expSigma = responseAl.GetExpectedSigma(mRespParamsV2, track, tofsignal, evTimeErr); - tofNsigma = (tofsignal - evTime - responseAl.GetCorrectedExpectedSignal(mRespParamsV2, track)) / expSigma; - break; - default: - LOG(fatal) << "Wrong particle ID in TofPidSecondary class"; - return -999; - } - - return tofNsigma; - } -}; - -template -template -float TofPidNewCollision::GetTOFNSigma(o2::track::PID::ID pidId, TTrack const& track, TCollision const& originalcol, TCollision const& correctedcol, bool EnableBCAO2D) -{ - - if (!track.has_collision() || !track.hasTOF()) { - return -999; - } - - float mMassHyp = o2::track::pid_constants::sMasses2Z[track.pidForTracking()]; - float expTime = track.length() * sqrt((mMassHyp * mMassHyp) + (track.tofExpMom() * track.tofExpMom())) / (kCSPEED * track.tofExpMom()); // L*E/(p*c) = L/v - - float evTime = correctedcol.evTime(); - float evTimeErr = correctedcol.evTimeErr(); - float tofsignal = track.trackTime() * 1000 + expTime; // in ps - - if (originalcol.globalIndex() == correctedcol.globalIndex()) { - evTime = track.evTimeForTrack(); - evTimeErr = track.evTimeErrForTrack(); - } else { - if (EnableBCAO2D) { - auto originalbc = originalcol.template bc_as(); - auto correctedbc = correctedcol.template bc_as(); - o2::InteractionRecord originalIR = o2::InteractionRecord::long2IR(originalbc.globalBC()); - o2::InteractionRecord correctedIR = o2::InteractionRecord::long2IR(correctedbc.globalBC()); - tofsignal += originalIR.differenceInBCNS(correctedIR) * 1000; - } else { - auto originalbc = originalcol.template foundBC_as(); - auto correctedbc = correctedcol.template foundBC_as(); - o2::InteractionRecord originalIR = o2::InteractionRecord::long2IR(originalbc.globalBC()); - o2::InteractionRecord correctedIR = o2::InteractionRecord::long2IR(correctedbc.globalBC()); - tofsignal += originalIR.differenceInBCNS(correctedIR) * 1000; - } - } - - float tofNsigma = CalculateTOFNSigma(pidId, track, tofsignal, evTime, evTimeErr); - return tofNsigma; -} - -template -template -float TofPidNewCollision::GetTOFNSigma(TTrack const& track, TCollision const& originalcol, TCollision const& correctedcol, bool EnableBCAO2D) -{ - return GetTOFNSigma(pidType, track, originalcol, correctedcol, EnableBCAO2D); -} - -template -float TofPidNewCollision::GetTOFNSigma(o2::track::PID::ID pidId, TTrack const& track) -{ - - if (!track.has_collision() || !track.hasTOF()) { - return -999; - } - - float mMassHyp = o2::track::pid_constants::sMasses2Z[track.pidForTracking()]; - float expTime = track.length() * sqrt((mMassHyp * mMassHyp) + (track.tofExpMom() * track.tofExpMom())) / (kCSPEED * track.tofExpMom()); // L*E/(p*c) = L/v - - float evTime = track.evTimeForTrack(); - float evTimeErr = track.evTimeErrForTrack(); - float tofsignal = track.trackTime() * 1000 + expTime; // in ps - - float tofNsigma = CalculateTOFNSigma(pidId, track, tofsignal, evTime, evTimeErr); - return tofNsigma; -} - -template -float TofPidNewCollision::GetTOFNSigma(TTrack const& track) -{ - return GetTOFNSigma(pidType, track); -} - -} // namespace pidtofgeneric -} // namespace o2::aod - -#endif // PWGLF_DATAMODEL_PIDTOFGENERIC_H_ diff --git a/PWGLF/TableProducer/Common/kinkBuilder.cxx b/PWGLF/TableProducer/Common/kinkBuilder.cxx index 64605ec9897..eb68fe85b39 100644 --- a/PWGLF/TableProducer/Common/kinkBuilder.cxx +++ b/PWGLF/TableProducer/Common/kinkBuilder.cxx @@ -91,6 +91,7 @@ struct kinkCandidate { struct kinkBuilder { enum PartType { kSigmaMinus = 0, + kHypertriton, kHyperhelium4sigma }; Produces outputDataTable; @@ -111,6 +112,7 @@ struct kinkBuilder { Configurable nTPCClusMinDaug{"nTPCClusMinDaug", 80, "daug NTPC clusters cut"}; Configurable askTOFforDaug{"askTOFforDaug", false, "If true, ask for TOF signal"}; Configurable doSVRadiusCut{"doSVRadiusCut", true, "If true, apply the cut on the radius of the secondary vertex and tracksIU"}; + Configurable updateMothTrackUsePV{"updateMothTrackUsePV", false, "If true, update the mother track parameters using the primary vertex"}; o2::vertexing::DCAFitterN<2> fitter; o2::base::MatLayerCylSet* lut = nullptr; @@ -160,6 +162,11 @@ struct kinkBuilder { mothMass = o2::constants::physics::MassSigmaMinus; chargedDauMass = o2::constants::physics::MassPiMinus; neutDauMass = o2::constants::physics::MassNeutron; + } else if (hypoMoth == kHypertriton) { + charge = 1; + mothMass = o2::constants::physics::MassHyperTriton; + chargedDauMass = o2::constants::physics::MassTriton; + neutDauMass = o2::constants::physics::MassPi0; } else if (hypoMoth == kHyperhelium4sigma) { charge = 2; mothMass = o2::constants::physics::MassHyperHelium4; @@ -198,6 +205,8 @@ struct kinkBuilder { AxisSpec massAxis(100, 1.1, 1.4, "m (GeV/#it{c}^{2})"); if (hypoMoth == kSigmaMinus) { massAxis = AxisSpec{100, 1.1, 1.4, "m (GeV/#it{c}^{2})"}; + } else if (hypoMoth == kHypertriton) { + massAxis = AxisSpec{100, 2.94, 3.2, "m (GeV/#it{c}^{2})"}; } else if (hypoMoth == kHyperhelium4sigma) { massAxis = AxisSpec{100, 3.85, 4.25, "m (GeV/#it{c}^{2})"}; } @@ -313,6 +322,14 @@ struct kinkBuilder { continue; } + if (updateMothTrackUsePV) { + // update the mother track parameters using the primary vertex + trackParCovMoth = trackParCovMothPV; + if (!trackParCovMoth.update(primaryVertex)) { + continue; + } + } + int nCand = 0; try { nCand = fitter.process(trackParCovMoth, trackParCovDaug); diff --git a/PWGLF/TableProducer/Nuspex/CMakeLists.txt b/PWGLF/TableProducer/Nuspex/CMakeLists.txt index 66c91c16392..98dac784da5 100644 --- a/PWGLF/TableProducer/Nuspex/CMakeLists.txt +++ b/PWGLF/TableProducer/Nuspex/CMakeLists.txt @@ -94,9 +94,9 @@ o2physics_add_dpl_workflow(nuclei-flow-trees PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DetectorsBase O2Physics::EventFilteringUtils COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(hyperhelium4sigma-reco-task - SOURCES hyperhelium4sigmaRecoTask.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore +o2physics_add_dpl_workflow(hyperkink-reco-task + SOURCES hyperkinkRecoTask.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::TOFBase COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(he3-lambda-analysis diff --git a/PWGLF/TableProducer/Nuspex/LFTreeCreatorClusterStudies.cxx b/PWGLF/TableProducer/Nuspex/LFTreeCreatorClusterStudies.cxx index efb6a15543e..ffa41989881 100644 --- a/PWGLF/TableProducer/Nuspex/LFTreeCreatorClusterStudies.cxx +++ b/PWGLF/TableProducer/Nuspex/LFTreeCreatorClusterStudies.cxx @@ -241,6 +241,7 @@ struct LfTreeCreatorClusterStudies { {"photon_radiusV0", "Photon conversion radius (xy) V0; radius (cm); counts", {HistType::kTH1F, {{100, 0., 100.}}}}, {"photon_conversion_position", "Photon conversion position; x (cm); y (cm)", {HistType::kTH2F, {{250, -5.f, 5.f}, {250, -5.f, 5.f}}}}, {"photon_conversion_position_layer", "Photon conversion position (ITS layers); x (cm); y (cm)", {HistType::kTH2F, {{100, -5.f, 5.f}, {100, -5.f, 5.f}}}}, + {"casc_dca_daughter_pairs", "DCA (xy) for cascade daughter pairs; DCAxy (cm); counts", {HistType::kTH1F, {{100, -0.1, 0.1}}}}, {"Xi_vs_Omega", "Mass Xi vs Omega; mass Omega (GeV/#it{c}^{2}); mass Xi (GeV/#it{c}^{2})", {HistType::kTH2F, {{50, 1.f, 2.f}, {50, 1.f, 2.f}}}}, {"massOmega", "Mass #Omega; signed #it{p}_{T} (GeV/#it{c}); mass (GeV/#it{c}^{2})", {HistType::kTH2F, {{100, -5.f, 5.f}, {100, 1.62f, 1.72f}}}}, {"massOmegaWithBkg", "Mass Omega with Background; mass Omega (GeV/#it{c}^{2}); counts", {HistType::kTH1F, {{100, 1.62f, 1.72f}}}}, @@ -420,6 +421,7 @@ struct LfTreeCreatorClusterStudies { bool qualitySelectionCascade(const double dcaCascDaughters, const double cosPA) { + m_hAnalysis.fill(HIST("casc_dca_daughter_pairs"), dcaCascDaughters); if (std::abs(dcaCascDaughters) > cascsetting_dcaCascDaughters) { return false; } @@ -616,7 +618,7 @@ struct LfTreeCreatorClusterStudies { { float beta = o2::pid::tof::Beta::GetBeta(candidate); beta = std::min(1.f - 1.e-6f, std::max(1.e-4f, beta)); /// sometimes beta > 1 or < 0, to be checked - return candidate.tpcInnerParam() * 2.f * std::sqrt(1.f / (beta * beta) - 1.f); + return candidate.tpcInnerParam() * std::sqrt(1.f / (beta * beta) - 1.f); } // ========================================================================================================= @@ -816,6 +818,7 @@ struct LfTreeCreatorClusterStudies { return; } + m_v0TrackParCovs.emplace_back(v0TrackParCov); float massV0 = fillHistogramsV0(massLambdaV0, massAntiLambdaV0, momMother, candidatePos, candidateNeg, alphaAP, qtAP, radiusV0, v0Bitmask); candidatePos.massMother = massV0; candidateNeg.massMother = massV0; @@ -942,7 +945,7 @@ struct LfTreeCreatorClusterStudies { return; } m_hAnalysis.fill(HIST("de_selections"), DeSelections::kDeNClsIts); - if (!selectionPIDtpcDe(track)) { + if (std::abs(track.tpcNSigmaDe()) > desetting_nsigmatpc) { return; } m_hAnalysis.fill(HIST("de_selections"), DeSelections::kDePIDtpc); @@ -950,7 +953,7 @@ struct LfTreeCreatorClusterStudies { return; } m_hAnalysis.fill(HIST("de_selections"), DeSelections::kDePIDtof); - m_hAnalysis.fill(HIST("nSigmaTPCDe"), track.p() * track.sign(), computeNSigmaDe(track)); + m_hAnalysis.fill(HIST("nSigmaTPCDe"), track.p() * track.sign(), track.tpcNSigmaDe()); m_hAnalysis.fill(HIST("nSigmaITSDe"), track.p() * track.sign(), m_responseITS.nSigmaITS(track.itsClusterSizes(), track.p(), track.eta())); m_hAnalysis.fill(HIST("nSigmaTOFDe"), track.p() * track.sign(), track.tofNSigmaDe()); m_hAnalysis.fill(HIST("TOFmassDe"), track.p() * track.sign(), computeTOFmassDe(track)); @@ -968,7 +971,7 @@ struct LfTreeCreatorClusterStudies { m_ClusterStudiesTableExtra( track.tpcInnerParam() * track.sign(), // pTPC_De, track.pidForTracking(), // PIDinTrk_De, - computeNSigmaDe(track), // TpcNSigma_De, + track.tpcNSigmaDe(), // TpcNSigma_De, track.tofNSigmaDe(), // TofNSigma_De, computeTOFmassDe(track), // TofMass_De, -999.f, // cosPA, diff --git a/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx b/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx index a113a8ecbd8..bcd914b3df3 100644 --- a/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx +++ b/PWGLF/TableProducer/Nuspex/decay3bodybuilder.cxx @@ -17,10 +17,11 @@ #include "TableHelper.h" +#include "PWGLF/DataModel/LFPIDTOFGenericTables.h" #include "PWGLF/DataModel/Reduced3BodyTables.h" #include "PWGLF/DataModel/Vtx3BodyTables.h" -#include "PWGLF/DataModel/pidTOFGeneric.h" #include "PWGLF/Utils/decay3bodyBuilderHelper.h" +#include "PWGLF/Utils/pidTOFGeneric.h" #include "Common/Core/PID/PIDTOF.h" #include "Common/Core/RecoDecay.h" @@ -66,6 +67,8 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +o2::common::core::MetadataHelper metadataInfo; + static constexpr int nParameters = 1; static const std::vector tableNames{ "Decay3BodyIndices", @@ -143,7 +146,9 @@ struct decay3bodyBuilder { // building options Configurable useKFParticle{"useKFParticle", false, "Use KFParticle for decay3body building"}; Configurable kfSetTopologicalConstraint{"kfSetTopologicalConstraint", false, "Set topological vertex constraint in case of KFParticle reconstruction"}; + Configurable buildOnlyTracked{"buildOnlyTracked", false, "Build only tracked decay3bodys"}; Configurable useSelections{"useSelections", true, "Apply selections during decay3body building"}; + Configurable useChi2Selection{"useChi2Selection", true, "Apply chi2 selection during decay3body building"}; Configurable useTPCforPion{"useTPCforPion", false, "Flag to ask for TPC info for pion track (PID, nClusters), false: pion track can be ITS only"}; Configurable acceptTPCOnly{"acceptTPCOnly", false, "Accept TPC only tracks as daughters"}; Configurable askOnlyITSMatch{"askOnlyITSMatch", true, "ask only ITS match to distinguish TPC only tracks"}; @@ -166,7 +171,7 @@ struct decay3bodyBuilder { Configurable minTOFnSigmaDeuteron{"minTOFnSigmaDeuteron", -5.0, "Min TOF nSigma of deuteron daughter"}; Configurable maxTOFnSigmaDeuteron{"maxTOFnSigmaDeuteron", 5.0, "Max TOF nSigma of deuteron daughter"}; Configurable minPDeuteronUseTOF{"minPDeuteronUseTOF", 1.0, "Min P of deuteron to use TOF PID"}; - Configurable maxDCADauAtSV{"maxDCADauAtSV", 0.5, "Max DCA of daughters at SV (quadratic sum of daughter DCAs between each other)"}; + Configurable maxDCADauToSVaverage{"maxDCADauToSVaverage", 0.5, "Max DCA of daughters to SV (quadratic sum of daughter DCAs to SV / 3)"}; // candidate selections Configurable maxRapidity{"maxRapidity", 1.0, "Max rapidity of decay3body vertex"}; Configurable minPt{"minPt", 2.0, "Min Pt of decay3body candidate"}; @@ -202,17 +207,6 @@ struct decay3bodyBuilder { Configurable maxDCAZ3Body{"maxDCAZ3Body", 1.0, "Max DCA Z of 3body"}; } mixingOpts; - struct : ConfigurableGroup { - std::string prefix = "tofPIDOpts"; - Configurable timestamp{"ccdb-timestamp", -1, "timestamp of the object"}; - Configurable paramFileName{"paramFileName", "", "Path to the parametrization object. If empty the parametrization is not taken from file"}; - Configurable parametrizationPath{"parametrizationPath", "TOF/Calib/Params", "Path of the TOF parametrization on the CCDB or in the file, if the paramFileName is not empty"}; - Configurable passName{"passName", "", "Name of the pass inside of the CCDB parameter collection. If empty, the automatically deceted from metadata (to be implemented!!!)"}; - Configurable timeShiftCCDBPath{"timeShiftCCDBPath", "", "Path of the TOF time shift vs eta. If empty none is taken"}; - Configurable loadResponseFromCCDB{"loadResponseFromCCDB", false, "Flag to load the response from the CCDB"}; - Configurable fatalOnPassNotAvailable{"fatalOnPassNotAvailable", true, "Flag to throw a fatal if the pass is not available in the retrieved CCDB object"}; - } tofPIDOpts; - // Helper struct to contain MC information prior to filling struct mc3Bodyinfo { int label; @@ -254,7 +248,9 @@ struct decay3bodyBuilder { // bachelor TOF PID o2::aod::pidtofgeneric::TofPidNewCollision bachelorTOFPID; // to be updated in Init based on the hypothesis o2::aod::pidtofgeneric::TofPidNewCollision bachelorTOFPIDLabeled; // to be updated in Init based on the hypothesis - o2::pid::tof::TOFResoParamsV2 mRespParamsV2; + // TOF response and input parameters + o2::pid::tof::TOFResoParamsV3 mRespParamsV3; + o2::aod::pidtofgeneric::TOFCalibConfig mTOFCalibConfig; // TOF Calib configuration // 3body mixing using Binning3BodyKF = ColumnBinningPolicy; @@ -272,7 +268,7 @@ struct decay3bodyBuilder { // MC info std::vector isGoodCollision; - void init(InitContext&) + void init(InitContext& initContext) { zorroSummary.setObject(zorro.getZorroSummary()); @@ -287,6 +283,13 @@ struct decay3bodyBuilder { ccdb->setLocalObjectValidityChecking(); ccdb->setFatalWhenNull(false); + // TOF PID parameters initialization + if (doprocessRealData == true || doprocessMonteCarlo == true) { + mTOFCalibConfig.metadataInfo = metadataInfo; + mTOFCalibConfig.inheritFromBaseTask(initContext); + mTOFCalibConfig.initSetup(mRespParamsV3, ccdb); + } + // Set material correction if (useMatCorrType == 1) { LOGF(info, "TGeo correction requested, loading geometry"); @@ -326,7 +329,7 @@ struct decay3bodyBuilder { helper.decay3bodyselections.minTOFnSigmaDeuteron = decay3bodyBuilderOpts.minTOFnSigmaDeuteron; helper.decay3bodyselections.maxTOFnSigmaDeuteron = decay3bodyBuilderOpts.maxTOFnSigmaDeuteron; helper.decay3bodyselections.minPDeuteronUseTOF = decay3bodyBuilderOpts.minPDeuteronUseTOF; - helper.decay3bodyselections.maxDCADauAtSV = decay3bodyBuilderOpts.maxDCADauAtSV; + helper.decay3bodyselections.maxDCADauToSVaverage = decay3bodyBuilderOpts.maxDCADauToSVaverage; helper.decay3bodyselections.maxRapidity = decay3bodyBuilderOpts.maxRapidity; helper.decay3bodyselections.minPt = decay3bodyBuilderOpts.minPt; helper.decay3bodyselections.maxPt = decay3bodyBuilderOpts.maxPt; @@ -393,7 +396,7 @@ struct decay3bodyBuilder { LOGF(info, "-~> min TOF nSigma deuteron ......: %f", decay3bodyBuilderOpts.minTOFnSigmaDeuteron.value); LOGF(info, "-~> max TOF nSigma deuteron ......: %f", decay3bodyBuilderOpts.maxTOFnSigmaDeuteron.value); LOGF(info, "-~> min p bach use TOF ...........: %f", decay3bodyBuilderOpts.minPDeuteronUseTOF.value); - LOGF(info, "-~> max DCA dau at SV ............: %f", decay3bodyBuilderOpts.maxDCADauAtSV.value); + LOGF(info, "-~> max DCA dau at SV ............: %f", decay3bodyBuilderOpts.maxDCADauToSVaverage.value); LOGF(info, "-~> max rapidity .................: %f", decay3bodyBuilderOpts.maxRapidity.value); LOGF(info, "-~> min pT .......................: %f", decay3bodyBuilderOpts.minPt.value); LOGF(info, "-~> max pT .......................: %f", decay3bodyBuilderOpts.maxPt.value); @@ -526,66 +529,7 @@ struct decay3bodyBuilder { // mark run as configured mRunNumber = bc.runNumber(); - // Initial TOF PID Paras, copied from PIDTOF.h - tofPIDOpts.timestamp.value = bc.timestamp(); - ccdb->setTimestamp(tofPIDOpts.timestamp.value); - // Not later than now objects - ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); - // TODO: implement the automatic pass name detection from metadata - if (tofPIDOpts.passName.value == "") { - tofPIDOpts.passName.value = "unanchored"; // temporary default - LOG(warning) << "Passed autodetect mode for pass, not implemented yet, waiting for metadata. Taking '" << tofPIDOpts.passName.value << "'"; - } - LOG(info) << "Using parameter collection, starting from pass '" << tofPIDOpts.passName.value << "'"; - - const std::string fname = tofPIDOpts.paramFileName.value; - if (!fname.empty()) { // Loading the parametrization from file - LOG(info) << "Loading exp. sigma parametrization from file " << fname << ", using param: " << tofPIDOpts.parametrizationPath.value; - if (1) { - o2::tof::ParameterCollection paramCollection; - paramCollection.loadParamFromFile(fname, tofPIDOpts.parametrizationPath.value); - LOG(info) << "+++ Loaded parameter collection from file +++"; - if (!paramCollection.retrieveParameters(mRespParamsV2, tofPIDOpts.passName.value)) { - if (tofPIDOpts.fatalOnPassNotAvailable) { - LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", tofPIDOpts.passName.value.data()); - } else { - LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", tofPIDOpts.passName.value.data()); - } - } else { - mRespParamsV2.setShiftParameters(paramCollection.getPars(tofPIDOpts.passName.value)); - mRespParamsV2.printShiftParameters(); - } - } else { - mRespParamsV2.loadParamFromFile(fname.data(), tofPIDOpts.parametrizationPath.value); - } - } else if (tofPIDOpts.loadResponseFromCCDB) { // Loading it from CCDB - LOG(info) << "Loading exp. sigma parametrization from CCDB, using path: " << tofPIDOpts.parametrizationPath.value << " for timestamp " << tofPIDOpts.timestamp.value; - o2::tof::ParameterCollection* paramCollection = ccdb->getForTimeStamp(tofPIDOpts.parametrizationPath.value, tofPIDOpts.timestamp.value); - paramCollection->print(); - if (!paramCollection->retrieveParameters(mRespParamsV2, tofPIDOpts.passName.value)) { // Attempt at loading the parameters with the pass defined - if (tofPIDOpts.fatalOnPassNotAvailable) { - LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", tofPIDOpts.passName.value.data()); - } else { - LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", tofPIDOpts.passName.value.data()); - } - } else { // Pass is available, load non standard parameters - mRespParamsV2.setShiftParameters(paramCollection->getPars(tofPIDOpts.passName.value)); - mRespParamsV2.printShiftParameters(); - } - } - mRespParamsV2.print(); - if (tofPIDOpts.timeShiftCCDBPath.value != "") { - if (tofPIDOpts.timeShiftCCDBPath.value.find(".root") != std::string::npos) { - mRespParamsV2.setTimeShiftParameters(tofPIDOpts.timeShiftCCDBPath.value, "gmean_Pos", true); - mRespParamsV2.setTimeShiftParameters(tofPIDOpts.timeShiftCCDBPath.value, "gmean_Neg", false); - } else { - mRespParamsV2.setTimeShiftParameters(ccdb->getForTimeStamp(Form("%s/pos", tofPIDOpts.timeShiftCCDBPath.value.c_str()), tofPIDOpts.timestamp.value), true); - mRespParamsV2.setTimeShiftParameters(ccdb->getForTimeStamp(Form("%s/neg", tofPIDOpts.timeShiftCCDBPath.value.c_str()), tofPIDOpts.timestamp.value), false); - } - } - - bachelorTOFPID.SetParams(mRespParamsV2); - bachelorTOFPIDLabeled.SetParams(mRespParamsV2); + mTOFCalibConfig.processSetup(mRespParamsV3, ccdb, bc); return true; } @@ -720,6 +664,11 @@ struct decay3bodyBuilder { registry.fill(HIST("Counters/hInputStatistics"), kVtx3BodyDatas, decay3bodys.size()); int lastRunNumber = -1; for (const auto& decay3body : decay3bodys) { + // only build tracked decay3body if aksed + if (decay3bodyBuilderOpts.buildOnlyTracked && fTrackedClSizeVector[decay3body.globalIndex()] == 0) { + continue; + } + // skip decay3body without assigned collision /// TODO: do we want this?? if (decay3body.collisionId() < 0) { @@ -765,9 +714,9 @@ struct decay3bodyBuilder { tofNSigmaDeuteron = trackDeuteron.tofNSigmaDe(); } else if constexpr (soa::is_table) { // running over AO2Ds if constexpr (soa::is_table) { // running over MC (track table with labels) - tofNSigmaDeuteron = getTOFnSigma(collision, trackDeuteron); + tofNSigmaDeuteron = getTOFnSigma(mRespParamsV3, collision, trackDeuteron); } else { // running over real data - tofNSigmaDeuteron = getTOFnSigma(collision, trackDeuteron); + tofNSigmaDeuteron = getTOFnSigma(mRespParamsV3, collision, trackDeuteron); } } @@ -782,6 +731,7 @@ struct decay3bodyBuilder { decay3bodyBuilderOpts.useKFParticle, decay3bodyBuilderOpts.kfSetTopologicalConstraint, decay3bodyBuilderOpts.useSelections, + decay3bodyBuilderOpts.useChi2Selection, decay3bodyBuilderOpts.useTPCforPion, decay3bodyBuilderOpts.acceptTPCOnly, decay3bodyBuilderOpts.askOnlyITSMatch, @@ -958,7 +908,7 @@ struct decay3bodyBuilder { -1., -1., -1., // trackDCAxyToPV: 0 - proton, 1 - pion, 2 - deuteron -1., -1., -1., // trackDCAzToPV: 0 - proton, 1 - pion, 2 - deuteron -1., -1., -1., // daughterDCAtoSV: 0 - proton, 1 - pion, 2 - deuteron - -1., // daughterDCAatSV + -1., // daughterDCAtoSVaverage -1., -1., // cosPA, ctau -1., -1., -1., -1., // tpcNsigma: 0 - proton, 1 - pion, 2 - deuteron, 3 - bach with pion hyp -1., // tofNsigmaDeuteron @@ -1079,15 +1029,15 @@ struct decay3bodyBuilder { // ______________________________________________________________ // function to calculate correct TOF nSigma for deuteron track template - double getTOFnSigma(TCollision const& collision, TTrack const& track) + double getTOFnSigma(o2::pid::tof::TOFResoParamsV3 const& parameters, TCollision const& collision, TTrack const& track) { // TOF PID of deuteron if (track.has_collision() && track.hasTOF()) { auto originalcol = track.template collision_as(); if constexpr (isMC) { - return bachelorTOFPIDLabeled.GetTOFNSigma(track, originalcol, collision); + return bachelorTOFPIDLabeled.GetTOFNSigma(parameters, track, originalcol, collision); } else { - return bachelorTOFPID.GetTOFNSigma(track, originalcol, collision); + return bachelorTOFPID.GetTOFNSigma(parameters, track, originalcol, collision); } } return -999; @@ -1117,7 +1067,7 @@ struct decay3bodyBuilder { helper.decay3body.trackDCAxyToPV[0], helper.decay3body.trackDCAxyToPV[1], helper.decay3body.trackDCAxyToPV[2], // 0 - proton, 1 - pion, 2 - deuteron helper.decay3body.trackDCAzToPV[0], helper.decay3body.trackDCAzToPV[1], helper.decay3body.trackDCAzToPV[2], // 0 - proton, 1 - pion, 2 - deuteron helper.decay3body.daughterDCAtoSV[0], helper.decay3body.daughterDCAtoSV[1], helper.decay3body.daughterDCAtoSV[2], // 0 - proton, 1 - pion, 2 - deuteron - helper.decay3body.daughterDCAatSV, + helper.decay3body.daughterDCAtoSVaverage, helper.decay3body.cosPA, helper.decay3body.ctau, helper.decay3body.tpcNsigma[0], helper.decay3body.tpcNsigma[1], helper.decay3body.tpcNsigma[2], helper.decay3body.tpcNsigma[2], // 0 - proton, 1 - pion, 2 - deuteron, 3 - bach with pion hyp helper.decay3body.tofNsigmaDeuteron, @@ -1146,7 +1096,7 @@ struct decay3bodyBuilder { helper.decay3body.trackDCAxyToPV[0], helper.decay3body.trackDCAxyToPV[1], helper.decay3body.trackDCAxyToPV[2], // 0 - proton, 1 - pion, 2 - deuteron helper.decay3body.trackDCAzToPV[0], helper.decay3body.trackDCAzToPV[1], helper.decay3body.trackDCAzToPV[2], // 0 - proton, 1 - pion, 2 - deuteron helper.decay3body.daughterDCAtoSV[0], helper.decay3body.daughterDCAtoSV[1], helper.decay3body.daughterDCAtoSV[2], // 0 - proton, 1 - pion, 2 - deuteron - helper.decay3body.daughterDCAatSV, + helper.decay3body.daughterDCAtoSVaverage, helper.decay3body.cosPA, helper.decay3body.ctau, helper.decay3body.tpcNsigma[0], helper.decay3body.tpcNsigma[1], helper.decay3body.tpcNsigma[2], helper.decay3body.tpcNsigma[2], // 0 - proton, 1 - pion, 2 - deuteron, 3 - bach with pion hyp helper.decay3body.tofNsigmaDeuteron, @@ -1184,6 +1134,7 @@ struct decay3bodyBuilder { decay3bodyBuilderOpts.useKFParticle, decay3bodyBuilderOpts.kfSetTopologicalConstraint, decay3bodyBuilderOpts.useSelections, + decay3bodyBuilderOpts.useChi2Selection, decay3bodyBuilderOpts.useTPCforPion, decay3bodyBuilderOpts.acceptTPCOnly, decay3bodyBuilderOpts.askOnlyITSMatch, @@ -1376,6 +1327,7 @@ struct decay3bodyBuilder { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { + metadataInfo.initMetadata(cfgc); return WorkflowSpec{ adaptAnalysisTask(cfgc)}; } diff --git a/PWGLF/TableProducer/Nuspex/he3HadronFemto.cxx b/PWGLF/TableProducer/Nuspex/he3HadronFemto.cxx index 547d4b08c3b..f50262bd998 100644 --- a/PWGLF/TableProducer/Nuspex/he3HadronFemto.cxx +++ b/PWGLF/TableProducer/Nuspex/he3HadronFemto.cxx @@ -15,30 +15,9 @@ /// \author Your Name (your.email@cern.ch) /// \since April 2025 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include // std::prev - -#include "Framework/ASoAHelpers.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/StepTHn.h" +#include "PWGLF/DataModel/EPCalibrationTables.h" +#include "PWGLF/DataModel/LFhe3HadronTables.h" +#include "PWGLF/Utils/svPoolCreator.h" #include "Common/Core/PID/PIDTOF.h" #include "Common/Core/PID/TPCPIDResponse.h" @@ -52,21 +31,40 @@ #include "Common/DataModel/PIDResponseITS.h" #include "Common/DataModel/TrackSelectionTables.h" #include "Common/TableProducer/PID/pidTOFBase.h" - #include "EventFiltering/Zorro.h" #include "EventFiltering/ZorroSummary.h" #include "CCDB/BasicCCDBManager.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsTPC/BetheBlochAleph.h" -#include "DataFormatsParameters/GRPObject.h" #include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DataFormatsTPC/BetheBlochAleph.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/Track.h" -#include "PWGLF/DataModel/EPCalibrationTables.h" -#include "PWGLF/DataModel/LFhe3HadronTables.h" -#include "PWGLF/Utils/svPoolCreator.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include // std::prev +#include +#include using namespace o2; using namespace o2::framework; @@ -86,15 +84,12 @@ namespace constexpr double betheBlochDefault[1][6]{{-1.e32, -1.e32, -1.e32, -1.e32, -1.e32, -1.e32}}; static const std::vector betheBlochParNames{"p0", "p1", "p2", "p3", "p4", "resolution"}; -// constexpr float he3Mass = o2::constants::physics::MassHelium3; -// constexpr float protonMass = o2::constants::physics::MassProton; -// constexpr float pionchargedMass = o2::constants::physics::MassPiPlus; -constexpr int Li4PDG = 1000030040; +constexpr int Li4PDG = o2::constants::physics::Pdg::kLithium4; +constexpr int H3LPDG = o2::constants::physics::Pdg::kHyperTriton; constexpr int ProtonPDG = PDG_t::kProton; constexpr int PionPDG = PDG_t::kPiPlus; constexpr int He3PDG = o2::constants::physics::Pdg::kHelium3; constexpr float CommonInite = 0.0f; -// constexpr int pichargedPDG = 211; enum Selections { kNoCuts = 0, @@ -103,6 +98,21 @@ enum Selections { kAll }; +enum Flags { + kBothPrimaries = BIT(0), + kBothFromLi4 = BIT(1), + kBothFromHypertriton = BIT(2), + kMixedPair = BIT(3), // a primary and one from Li4/hypertriton/material/other decays (or any other combination) +}; + +enum ParticleFlags { + kPhysicalPrimary = BIT(0), // primary particle + kFromLi4 = BIT(1), // from Li4 decay + kFromHypertriton = BIT(2), // from hypertriton decay + kFromMaterial = BIT(3), // from material + kFromOtherDecays = BIT(4), // from other decays +}; + } // namespace struct He3HadCandidate { @@ -124,6 +134,7 @@ struct He3HadCandidate { float dcazHe3 = -10.f; float dcaxyHad = -10.f; float dcazHad = -10.f; + float dcaPair = -10.f; // DCA between the two tracks uint16_t tpcSignalHe3 = 0u; uint16_t tpcSignalHad = 0u; @@ -163,9 +174,9 @@ struct He3HadCandidate { float etaHadMC = -99.f; float phiHadMC = -99.f; - bool isHe3Primary = false; - bool isHadPrimary = false; - bool isMotherLi4 = false; + uint8_t flagsHe3 = 0; // flags for He3 + uint8_t flagsHad = 0; // flags for hadron + uint8_t flags = 0; // flags for the pair // collision information int32_t collisionID = 0; @@ -200,6 +211,7 @@ struct he3HadronFemto { Configurable settingSaveUSandLS{"settingSaveUSandLS", true, "Save All Pairs"}; Configurable settingIsMC{"settingIsMC", false, "Run MC"}; Configurable settingFillMultiplicity{"settingFillMultiplicity", false, "Fill multiplicity table"}; + Configurable settingFillPrimariesAndMixedMc{"settingFillPrimariesAndMixedMc", false, "Fill primary MC tracks and mixed tracks (e.g. a primary track and one from Li4)"}; // Zorro Configurable settingSkimmedProcessing{"settingSkimmedProcessing", false, "Skimmed dataset processing"}; @@ -250,30 +262,30 @@ struct he3HadronFemto { { {"hVtxZBefore", "Vertex distribution in Z before selections;Z (cm)", {HistType::kTH1F, {{400, -20.0, 20.0}}}}, {"hVtxZ", "Vertex distribution in Z;Z (cm)", {HistType::kTH1F, {{400, -20.0, 20.0}}}}, - {"hCentralityFT0A", ";Centrality FT0A", {HistType::kTH1F, {{100, 0, 100.0}}}}, - {"hCentralityFT0C", ";Centrality FT0C", {HistType::kTH1F, {{100, 0, 100.0}}}}, + {"hCentralityFT0A", ";Centrality FT0A (%)", {HistType::kTH1F, {{100, 0, 100.0}}}}, + {"hCentralityFT0C", ";Centrality FT0C (%)", {HistType::kTH1F, {{100, 0, 100.0}}}}, {"hNcontributor", "Number of primary vertex contributor", {HistType::kTH1F, {{2000, 0.0f, 2000.0f}}}}, {"hTrackSel", "Accepted tracks", {HistType::kTH1F, {{Selections::kAll, -0.5, static_cast(Selections::kAll) - 0.5}}}}, {"hEvents", "; Events;", {HistType::kTH1F, {{3, -0.5, 2.5}}}}, {"hEmptyPool", "svPoolCreator did not find track pairs false/true", {HistType::kTH1F, {{2, -0.5, 1.5}}}}, - {"hDCAxyHe3", ";DCA_{xy} (cm)", {HistType::kTH1F, {{200, -5.0f, 5.0f}}}}, - {"hDCAzHe3", ";DCA_{z} (cm)", {HistType::kTH1F, {{200, -1.0f, 1.0f}}}}, - {"hNClsHe3ITS", ";N_{ITS} Cluster", {HistType::kTH1F, {{20, -10.0f, 10.0f}}}}, - {"hNClsHadITS", ";N_{ITS} Cluster", {HistType::kTH1F, {{20, -10.0f, 10.0f}}}}, - {"hChi2NClHe3ITS", ";Chi2_{ITS} Ncluster", {HistType::kTH1F, {{100, 0, 100.0f}}}}, - {"hChi2NClHadITS", ";Chi2_{ITS} Ncluster", {HistType::kTH1F, {{100, 0, 100.0f}}}}, + {"hDCAxyHe3", "^{3}He;DCA_{xy} (cm)", {HistType::kTH1F, {{200, -5.0f, 5.0f}}}}, + {"hDCAzHe3", "^{3}He;DCA_{z} (cm)", {HistType::kTH1F, {{200, -1.0f, 1.0f}}}}, + {"hNClsHe3ITS", "^{3}He;N_{ITS} Cluster", {HistType::kTH1F, {{20, -10.0f, 10.0f}}}}, + {"hNClsHadITS", "had;N_{ITS} Cluster", {HistType::kTH1F, {{20, -10.0f, 10.0f}}}}, + {"hChi2NClHe3ITS", "^{3}He;Chi2_{ITS} Ncluster", {HistType::kTH1F, {{100, 0, 100.0f}}}}, + {"hChi2NClHadITS", "had;Chi2_{ITS} Ncluster", {HistType::kTH1F, {{100, 0, 100.0f}}}}, {"hhe3HadtInvMass", "; M(^{3}He + p) (GeV/#it{c}^{2})", {HistType::kTH1F, {{300, 3.74f, 4.34f}}}}, - {"hHe3Pt", "#it{p}_{T} distribution; #it{p}_{T} (GeV/#it{c})", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, - {"hHadronPt", "Pt distribution; #it{p}_{T} (GeV/#it{c})", {HistType::kTH1F, {{120, -3.0f, 3.0f}}}}, + {"hHe3Pt", "^{3}He; #it{p}_{T} (GeV/#it{c})", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, + {"hHadronPt", "had; #it{p}_{T} (GeV/#it{c})", {HistType::kTH1F, {{120, -3.0f, 3.0f}}}}, {"h2dEdxHe3candidates", "dEdx distribution; #it{p} (GeV/#it{c}); dE/dx (a.u.)", {HistType::kTH2F, {{200, -5.0f, 5.0f}, {100, 0.0f, 2000.0f}}}}, {"h2NsigmaHe3TPC", "NsigmaHe3 TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(^{3}He)", {HistType::kTH2F, {{20, -5.0f, 5.0f}, {200, -5.0f, 5.0f}}}}, {"h2NsigmaHe3TPC_preselection", "NsigmaHe3 TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(^{3}He)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, {"h2NSigmaHe3ITS_preselection", "NsigmaHe3 ITS distribution; signed #it{p}_{T} (GeV/#it{c}); n#sigma_{ITS} ^{3}He", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {120, -3.0f, 3.0f}}}}, {"h2NSigmaHe3ITS", "NsigmaHe3 ITS distribution; signed #it{p}_{T} (GeV/#it{c}); n#sigma_{ITS} ^{3}He", {HistType::kTH2F, {{50, -5.0f, 5.0f}, {120, -3.0f, 3.0f}}}}, - {"h2NsigmaHadronTPC", "NsigmaHadron TPC distribution; #it{p}_{T}(GeV/#it{c}); n#sigma_{TPC}(p)", {HistType::kTH2F, {{20, -5.0f, 5.0f}, {200, -5.0f, 5.0f}}}}, - {"h2NsigmaHadronTPC_preselection", "NsigmaHe3 TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(^{3}He)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, - {"h2NsigmaHadronTOF", "NsigmaHadron TOF distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(p)", {HistType::kTH2F, {{20, -5.0f, 5.0f}, {200, -5.0f, 5.0f}}}}, - {"h2NsigmaHadronTOF_preselection", "NsigmaHadron TOF distribution; #iit{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(p)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, + {"h2NsigmaHadronTPC", "NsigmaHadron TPC distribution; #it{p}_{T}(GeV/#it{c}); n#sigma_{TPC}(had)", {HistType::kTH2F, {{20, -5.0f, 5.0f}, {200, -5.0f, 5.0f}}}}, + {"h2NsigmaHadronTPC_preselection", "NsigmaHe3 TPC distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TPC}(had)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, + {"h2NsigmaHadronTOF", "NsigmaHadron TOF distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(had)", {HistType::kTH2F, {{20, -5.0f, 5.0f}, {200, -5.0f, 5.0f}}}}, + {"h2NsigmaHadronTOF_preselection", "NsigmaHadron TOF distribution; #it{p}_{T} (GeV/#it{c}); n#sigma_{TOF}(had)", {HistType::kTH2F, {{100, -5.0f, 5.0f}, {400, -10.0f, 10.0f}}}}, }, OutputObjHandlingPolicy::AnalysisObject, false, @@ -370,13 +382,14 @@ struct he3HadronFemto { mQaRegistry.fill(HIST("hEvents"), 0); mQaRegistry.fill(HIST("hVtxZBefore"), collision.posZ()); + auto bc = collision.template bc_as(); + initCCDB(bc); + if constexpr (isMC) { if (/*!collision.sel8() ||*/ std::abs(collision.posZ()) > settingCutVertex) { return false; } } else { - auto bc = collision.template bc_as(); - initCCDB(bc); if (!collision.sel8() || std::abs(collision.posZ()) > settingCutVertex) { return false; @@ -516,53 +529,65 @@ struct he3HadronFemto { // ================================================================================================================== - template - bool fillCandidateInfo(const Ttrack& trackHe3, const Ttrack& trackHad, const CollBracket& collBracket, const Tcollisions& collisions, He3HadCandidate& he3Hadcand, const Ttracks& /*trackTable*/, bool isMixedEvent) + template + std::array getCollisionVertex(const Tcollisions& collisions, int32_t collisionID) { - const int numCoordinates = 3; - if (!isMixedEvent) { - auto trackCovHe3 = getTrackParCov(trackHe3); - auto trackCovHad = getTrackParCov(trackHad); - int nCand = CommonInite; - try { - nCand = mFitter.process(trackCovHe3, trackCovHad); - } catch (...) { - LOG(error) << "Exception caught in DCA fitter process call!"; - return false; - } - if (nCand == 0) { - return false; - } + auto collision = collisions.rawIteratorAt(collisionID); + std::array collisionVertex = {collision.posX(), collision.posY(), collision.posZ()}; + return collisionVertex; + } - // associate collision id as the one that minimises the distance between the vertex and the PCAs of the daughters - double distanceMin = -1; - unsigned int collIdxMin = 0; - const float defaultTodistance = 0.0f; - for (int collIdx = collBracket.getMin(); collIdx <= collBracket.getMax(); collIdx++) { - auto collision = collisions.rawIteratorAt(collIdx); - std::array collVtx = {collision.posX(), collision.posY(), collision.posZ()}; - const auto& pca = mFitter.getPCACandidate(); - float distance = defaultTodistance; - for (int i = 0; i < numCoordinates; i++) { - distance += (pca[i] - collVtx[i]) * (pca[i] - collVtx[i]); - } - if (distanceMin < 0 || distance < distanceMin) { - distanceMin = distance; - collIdxMin = collIdx; - } - } + template + int32_t getCollisionID(const Ttrack& trackHe3, const Ttrack& trackHad, const CollBracket& collBracket, const Tcollisions& collisions, bool isMixedEvent) + { + if (isMixedEvent) { + return collBracket.getMin(); + } - if (!mGoodCollisions[collIdxMin]) { - return false; + auto trackCovHe3 = getTrackParCov(trackHe3); + auto trackCovHad = getTrackParCov(trackHad); + int nCand = CommonInite; + try { + nCand = mFitter.process(trackCovHe3, trackCovHad); + } catch (...) { + LOG(error) << "Exception caught in DCA fitter process call!"; + return false; + } + if (nCand == 0) { + return false; + } + + // associate collision id as the one that minimises the distance between the vertex and the PCAs of the daughters + double distanceMin = -1; + unsigned int collIdxMin = 0; + const float defaultTodistance = 0.0f; + for (int collIdx = collBracket.getMin(); collIdx <= collBracket.getMax(); collIdx++) { + std::array collisionVertex = getCollisionVertex(collisions, collIdx); + const auto& pca = mFitter.getPCACandidate(); + float distance = defaultTodistance; + for (int i = 0; i < 3; i++) { + distance += (pca[i] - collisionVertex[i]) * (pca[i] - collisionVertex[i]); + } + if (distanceMin < 0 || distance < distanceMin) { + distanceMin = distance; + collIdxMin = collIdx; } - he3Hadcand.collisionID = collIdxMin; + } - } else { - he3Hadcand.collisionID = collBracket.getMin(); + if (!mGoodCollisions[collIdxMin]) { + return false; } + return collIdxMin; + } + + template + bool fillCandidateInfo(const Ttrack& trackHe3, const Ttrack& trackHad, const CollBracket& collBracket, const Tcollisions& collisions, He3HadCandidate& he3Hadcand, const Ttracks& /*trackTable*/, bool isMixedEvent) + { + he3Hadcand.collisionID = getCollisionID(trackHe3, trackHad, collBracket, collisions, isMixedEvent); + std::array collisionVertex = getCollisionVertex(collisions, he3Hadcand.collisionID); he3Hadcand.momHe3 = std::array{trackHe3.px(), trackHe3.py(), trackHe3.pz()}; - for (int i = 0; i < numCoordinates; i++) + for (int i = 0; i < 3; i++) he3Hadcand.momHe3[i] = he3Hadcand.momHe3[i] * 2; he3Hadcand.momHad = std::array{trackHad.px(), trackHad.py(), trackHad.pz()}; float invMass = CommonInite; @@ -585,10 +610,20 @@ struct he3HadronFemto { he3Hadcand.signHe3 = trackHe3.sign(); he3Hadcand.signHad = trackHad.sign(); - he3Hadcand.dcaxyHe3 = trackHe3.dcaXY(); - he3Hadcand.dcaxyHad = trackHad.dcaXY(); - he3Hadcand.dcazHe3 = trackHe3.dcaZ(); - he3Hadcand.dcazHad = trackHad.dcaZ(); + // he3Hadcand.dcaxyHe3 = trackHe3.dcaXY(); + // he3Hadcand.dcaxyHad = trackHad.dcaXY(); + // he3Hadcand.dcazHe3 = trackHe3.dcaZ(); + // he3Hadcand.dcazHad = trackHad.dcaZ(); + auto trackCovHe3 = getTrackParCov(trackHe3); + auto trackCovHad = getTrackParCov(trackHad); + std::array dcaInfo; + o2::base::Propagator::Instance()->propagateToDCABxByBz({collisionVertex[0], collisionVertex[1], collisionVertex[2]}, trackCovHe3, 2.f, mFitter.getMatCorrType(), &dcaInfo); + he3Hadcand.dcaxyHe3 = dcaInfo[0]; + he3Hadcand.dcazHe3 = dcaInfo[1]; + o2::base::Propagator::Instance()->propagateToDCABxByBz({collisionVertex[0], collisionVertex[1], collisionVertex[2]}, trackCovHad, 2.f, mFitter.getMatCorrType(), &dcaInfo); + he3Hadcand.dcaxyHad = dcaInfo[0]; + he3Hadcand.dcazHad = dcaInfo[1]; + he3Hadcand.dcaPair = std::sqrt(std::abs(mFitter.getChi2AtPCACandidate())); he3Hadcand.tpcSignalHe3 = trackHe3.tpcSignal(); bool heliumPID = trackHe3.pidForTracking() == o2::track::PID::Helium3 || trackHe3.pidForTracking() == o2::track::PID::Alpha; @@ -645,15 +680,12 @@ struct he3HadronFemto { template void fillCandidateInfoMC(const Mc& mctrackHe3, const Mc& mctrackHad, He3HadCandidate& he3Hadcand) { - LOG(info) << "--------------------------Filling candidate info MC"; he3Hadcand.momHe3MC = mctrackHe3.pt() * (mctrackHe3.pdgCode() > 0 ? 1 : -1); he3Hadcand.etaHe3MC = mctrackHe3.eta(); he3Hadcand.phiHe3MC = mctrackHe3.phi(); he3Hadcand.momHadMC = mctrackHad.pt() * (mctrackHad.pdgCode() > 0 ? 1 : -1); he3Hadcand.etaHadMC = mctrackHad.eta(); he3Hadcand.phiHadMC = mctrackHad.phi(); - he3Hadcand.isHe3Primary = mctrackHe3.isPhysicalPrimary(); - he3Hadcand.isHadPrimary = mctrackHad.isPhysicalPrimary(); } template @@ -662,7 +694,6 @@ struct he3HadronFemto { he3Hadcand.l4PtMC = mctrackMother.pt() * (mctrackMother.pdgCode() > 0 ? 1 : -1); const double eLit = mctrackHe3.e() + mctrackHad.e(); he3Hadcand.l4MassMC = std::sqrt(eLit * eLit - mctrackMother.p() * mctrackMother.p()); - he3Hadcand.isMotherLi4 = std::abs(mctrackMother.pdgCode()) == Li4PDG; } template @@ -749,6 +780,7 @@ struct he3HadronFemto { he3Hadcand.dcazHe3, he3Hadcand.dcaxyHad, he3Hadcand.dcazHad, + he3Hadcand.dcaPair, he3Hadcand.tpcSignalHe3, he3Hadcand.momHe3TPC, he3Hadcand.tpcSignalHad, @@ -778,9 +810,7 @@ struct he3HadronFemto { he3Hadcand.phiHadMC, he3Hadcand.l4PtMC, he3Hadcand.l4MassMC, - he3Hadcand.isMotherLi4, - he3Hadcand.isHe3Primary, - he3Hadcand.isHadPrimary); + he3Hadcand.flags); } if (settingFillMultiplicity) { outputMultiplicityTable( @@ -826,6 +856,67 @@ struct he3HadronFemto { } } + template + void setMcParticleFlag(const TmcParticle& mcParticle, std::vector& mothers, uint8_t& flag) + { + if (mcParticle.isPhysicalPrimary()) { + + flag |= ParticleFlags::kPhysicalPrimary; + if (!mcParticle.has_mothers()) { + return; + } + + for (const auto& mother : mcParticle.template mothers_as()) { + mothers.push_back(mother.globalIndex()); + if (std::abs(mother.pdgCode()) == Li4PDG) { + flag |= ParticleFlags::kFromLi4; + } else if (std::abs(mother.pdgCode()) == H3LPDG) { + flag |= ParticleFlags::kFromHypertriton; + } else { + flag |= ParticleFlags::kFromOtherDecays; + } + } + + } else { + + if (!mcParticle.has_mothers()) { + flag |= ParticleFlags::kFromMaterial; + return; + } + + for (const auto& mother : mcParticle.template mothers_as()) { + mothers.push_back(mother.globalIndex()); + if (std::abs(mother.pdgCode()) == Li4PDG) { + flag |= ParticleFlags::kFromLi4; + } else if (std::abs(mother.pdgCode()) == H3LPDG) { + flag |= ParticleFlags::kFromHypertriton; + } else { + flag |= ParticleFlags::kFromOtherDecays; + } + } + } + } + + void searchForCommonMotherTrack(const std::vector& motherHe3Idxs, const std::vector& motherHadIdxs, const aod::McParticles& mcParticles, McIter& motherParticle, He3HadCandidate& he3Hadcand, bool& isMixedPair, const int motherPdgCode) + { + std::unordered_set motherHe3SetIdxs(motherHe3Idxs.begin(), motherHe3Idxs.end()); + for (const auto& motherHadIdx : motherHadIdxs) { + if (!motherHe3SetIdxs.contains(motherHadIdx)) { + continue; + } + + motherParticle = mcParticles.rawIteratorAt(motherHadIdx); + if (std::abs(motherParticle.pdgCode()) != motherPdgCode || std::abs(motherParticle.y()) > 1) { + continue; + } + isMixedPair = false; + break; + } + if (!isMixedPair) { + he3Hadcand.flags |= Flags::kBothFromLi4; + } + } + template void fillMcParticles(const Tcollisions& collisions, const TmcParticles& mcParticles, std::vector& filledMothers) { @@ -948,29 +1039,58 @@ struct he3HadronFemto { auto mctrackHe3 = heTrack.mcParticle(); auto mctrackHad = prTrack.mcParticle(); - if (std::abs(mctrackHe3.pdgCode()) != He3PDG || std::abs(mctrackHad.pdgCode()) != ProtonPDG) { + if (std::abs(mctrackHe3.pdgCode()) != He3PDG || std::abs(mctrackHad.pdgCode()) != settingHadPDGCode) { continue; } - for (const auto& mothertrack : mctrackHe3.mothers_as()) { - for (const auto& mothertrackHad : mctrackHad.mothers_as()) { - - if (mothertrack != mothertrackHad || std::abs(mothertrack.pdgCode()) != Li4PDG || std::abs(mothertrack.y()) > 1) { - continue; - } - - He3HadCandidate he3Hadcand; - if (!fillCandidateInfo(heTrack, prTrack, collBracket, collisions, he3Hadcand, tracks, /*mix*/ false)) { - continue; - } - fillCandidateInfoMC(mctrackHe3, mctrackHad, he3Hadcand); - fillMotherInfoMC(mctrackHe3, mctrackHad, mothertrack, he3Hadcand); - fillHistograms(he3Hadcand); - auto collision = collisions.rawIteratorAt(he3Hadcand.collisionID); - fillTable(he3Hadcand, collision, /*isMC*/ true); - filledMothers.push_back(mothertrack.globalIndex()); + He3HadCandidate he3Hadcand; + McIter motherParticle; + std::vector motherHe3Idxs, motherHadIdxs; + setMcParticleFlag(mctrackHe3, motherHe3Idxs, he3Hadcand.flagsHe3); + setMcParticleFlag(mctrackHad, motherHadIdxs, he3Hadcand.flagsHad); + + bool isMixedPair = true; + + if ((he3Hadcand.flagsHe3 == ParticleFlags::kPhysicalPrimary && he3Hadcand.flagsHad == ParticleFlags::kPhysicalPrimary)) { + he3Hadcand.flags |= Flags::kBothPrimaries; + isMixedPair = false; + + } else if ((he3Hadcand.flagsHe3 & ParticleFlags::kFromLi4) && (he3Hadcand.flagsHad & ParticleFlags::kFromLi4)) { + + searchForCommonMotherTrack(motherHe3Idxs, motherHadIdxs, mcParticles, motherParticle, he3Hadcand, isMixedPair, Li4PDG); + if (!isMixedPair) { + he3Hadcand.flags |= Flags::kBothFromLi4; + } + + } else if ((he3Hadcand.flagsHe3 & ParticleFlags::kFromHypertriton) && (he3Hadcand.flagsHad & ParticleFlags::kFromHypertriton)) { + + searchForCommonMotherTrack(motherHe3Idxs, motherHadIdxs, mcParticles, motherParticle, he3Hadcand, isMixedPair, H3LPDG); + if (!isMixedPair) { + he3Hadcand.flags |= Flags::kBothFromHypertriton; } } + + if (isMixedPair) { + he3Hadcand.flags |= Flags::kMixedPair; + } + + if (!settingFillPrimariesAndMixedMc && ((he3Hadcand.flags == Flags::kMixedPair) || he3Hadcand.flags == Flags::kBothPrimaries)) { + continue; + } + + if (!fillCandidateInfo(heTrack, prTrack, collBracket, collisions, he3Hadcand, tracks, /*mix*/ false)) { + continue; + } + fillCandidateInfoMC(mctrackHe3, mctrackHad, he3Hadcand); + + if ((he3Hadcand.flags == Flags::kBothFromLi4) || (he3Hadcand.flags == Flags::kBothFromHypertriton)) { + fillMotherInfoMC(mctrackHe3, mctrackHad, motherParticle, he3Hadcand); + filledMothers.push_back(motherParticle.globalIndex()); + } + + fillHistograms(he3Hadcand); + auto collision = collisions.rawIteratorAt(he3Hadcand.collisionID); + fillTable(he3Hadcand, collision, /*isMC*/ true); } } diff --git a/PWGLF/TableProducer/Nuspex/he3LambdaAnalysis.cxx b/PWGLF/TableProducer/Nuspex/he3LambdaAnalysis.cxx index d10a1338e55..9482de6d51e 100644 --- a/PWGLF/TableProducer/Nuspex/he3LambdaAnalysis.cxx +++ b/PWGLF/TableProducer/Nuspex/he3LambdaAnalysis.cxx @@ -92,8 +92,8 @@ struct he3LambdaAnalysis { o2::vertexing::DCAFitterN<2> fitter; Produces lfHe3V0Collision; - Produces lfHe3; - Produces lfLambda; + Produces lfHe3; + Produces lfLambda; // Configurables for event selection struct : ConfigurableGroup { @@ -280,6 +280,7 @@ struct he3LambdaAnalysis { candidate.dcaXY = dcaInfo[0]; candidate.dcaZ = dcaInfo[1]; candidate.tpcNClsFound = track.tpcNClsFound(); + candidate.tpcNClsPID = track.tpcNClsPID(); candidate.itsNCls = track.itsNCls(); candidate.itsClusterSizes = track.itsClusterSizes(); candidate.sign = track.sign() > 0 ? 1 : -1; @@ -376,11 +377,11 @@ struct he3LambdaAnalysis { lfHe3V0Collision(collision.posZ(), collision.centFT0C()); for (const auto& he3 : he3Candidates) { lfHe3(lfHe3V0Collision.lastIndex(), he3.momentum.Pt(), he3.momentum.Eta(), he3.momentum.Phi(), - he3.dcaXY, he3.dcaZ, he3.tpcNClsFound, he3.itsClusterSizes, he3.nSigmaTPC, he3.sign); + he3.dcaXY, he3.dcaZ, he3.tpcNClsFound, he3.tpcNClsPID, he3.itsClusterSizes, he3.nSigmaTPC, he3.sign); } for (const auto& lambda : lambdaCandidates) { lfLambda(lfHe3V0Collision.lastIndex(), lambda.momentum.Pt(), lambda.momentum.Eta(), lambda.momentum.Phi(), - lambda.mass, lambda.cosPA, lambda.dcaV0Daughters, lambda.dcaProtonToPV, lambda.dcaPionToPV, lambda.v0Radius, lambda.sign); + lambda.mass, lambda.cosPA, lambda.dcaV0Daughters, lambda.dcaProtonToPV, lambda.dcaPionToPV, lambda.v0Radius, lambda.protonNSigmaTPC, lambda.pionNSigmaTPC, lambda.sign); } for (const auto& he3 : he3Candidates) { @@ -391,12 +392,6 @@ struct he3LambdaAnalysis { } } PROCESS_SWITCH(he3LambdaAnalysis, processData, "Process data", true); - - // void processDerived(o2::aod::LFEvents::iterator const& collision, o2::aod::LFHe3 const& he3s, o2::aod::LFLambda const& lambdas) - // { - // - // } - // PROCESS_SWITCH(he3LambdaAnalysis, processDerived, "Process derived", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/TableProducer/Nuspex/hyperRecoTask.cxx b/PWGLF/TableProducer/Nuspex/hyperRecoTask.cxx index ebf9943064d..e93828980b1 100644 --- a/PWGLF/TableProducer/Nuspex/hyperRecoTask.cxx +++ b/PWGLF/TableProducer/Nuspex/hyperRecoTask.cxx @@ -110,6 +110,8 @@ struct hyperCandidate { uint16_t tpcSignalHe3 = 0u; uint16_t tpcSignalPi = 0u; float tpcChi2He3 = 0.f; + float itsChi2He3 = 0.f; + float itsChi2Pi = 0.f; float massTOFHe3 = 0.f; uint8_t nTPCClustersHe3 = 0u; uint8_t nTPCClustersPi = 0u; @@ -413,6 +415,8 @@ struct hyperRecoTask { hypCand.nTPCpidClusPi = (int16_t)piTrack.tpcNClsFindable() - piTrack.tpcNClsFindableMinusPID(); hypCand.tpcSignalPi = piTrack.tpcSignal(); hypCand.tpcChi2He3 = heTrack.tpcChi2NCl(); + hypCand.itsChi2He3 = heTrack.itsChi2NCl(); + hypCand.itsChi2Pi = piTrack.itsChi2NCl(); hypCand.clusterSizeITSPi = piTrack.itsClusterSizes(); bool heliumPID = heTrack.pidForTracking() == o2::track::PID::Helium3 || heTrack.pidForTracking() == o2::track::PID::Alpha; hypCand.momHe3TPC = (heliumPID && cfgCompensatePIDinTracking) ? heTrack.tpcInnerParam() / 2 : heTrack.tpcInnerParam(); @@ -687,7 +691,7 @@ struct hyperRecoTask { hypCand.dcaV0dau, hypCand.he3DCAXY, hypCand.piDCAXY, hypCand.nSigmaHe3, hypCand.nTPCClustersHe3, hypCand.nTPCClustersPi, hypCand.nTPCpidClusHe3, hypCand.nTPCpidClusPi, - hypCand.momHe3TPC, hypCand.momPiTPC, hypCand.tpcSignalHe3, hypCand.tpcSignalPi, hypCand.tpcChi2He3, + hypCand.momHe3TPC, hypCand.momPiTPC, hypCand.tpcSignalHe3, hypCand.tpcSignalPi, hypCand.tpcChi2He3, hypCand.itsChi2He3, hypCand.itsChi2Pi, hypCand.massTOFHe3, hypCand.clusterSizeITSHe3, hypCand.clusterSizeITSPi, hypCand.flags, trackedHypClSize); } @@ -722,7 +726,7 @@ struct hyperRecoTask { hypCand.dcaV0dau, hypCand.he3DCAXY, hypCand.piDCAXY, hypCand.nSigmaHe3, hypCand.nTPCClustersHe3, hypCand.nTPCClustersPi, hypCand.nTPCpidClusHe3, hypCand.nTPCpidClusPi, - hypCand.momHe3TPC, hypCand.momPiTPC, hypCand.tpcSignalHe3, hypCand.tpcSignalPi, hypCand.tpcChi2He3, + hypCand.momHe3TPC, hypCand.momPiTPC, hypCand.tpcSignalHe3, hypCand.tpcSignalPi, hypCand.tpcChi2He3, hypCand.itsChi2He3, hypCand.itsChi2Pi, hypCand.massTOFHe3, hypCand.clusterSizeITSHe3, hypCand.clusterSizeITSPi, hypCand.flags, trackedHypClSize); } @@ -757,7 +761,7 @@ struct hyperRecoTask { hypCand.decVtx[0], hypCand.decVtx[1], hypCand.decVtx[2], hypCand.dcaV0dau, hypCand.he3DCAXY, hypCand.piDCAXY, hypCand.nSigmaHe3, hypCand.nTPCClustersHe3, hypCand.nTPCClustersPi, hypCand.nTPCpidClusHe3, hypCand.nTPCpidClusPi, - hypCand.momHe3TPC, hypCand.momPiTPC, hypCand.tpcSignalHe3, hypCand.tpcSignalPi, hypCand.tpcChi2He3, + hypCand.momHe3TPC, hypCand.momPiTPC, hypCand.tpcSignalHe3, hypCand.tpcSignalPi, hypCand.tpcChi2He3, hypCand.itsChi2He3, hypCand.itsChi2Pi, hypCand.massTOFHe3, hypCand.clusterSizeITSHe3, hypCand.clusterSizeITSPi, hypCand.flags, trackedHypClSize, chargeFactor * hypCand.genPt(), hypCand.genPhi(), hypCand.genEta(), hypCand.genPtHe3(), @@ -831,7 +835,7 @@ struct hyperRecoTask { -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 0, 0, + -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, false, chargeFactor * hypCand.genPt(), hypCand.genPhi(), hypCand.genEta(), hypCand.genPtHe3(), hypCand.gDecVtx[0], hypCand.gDecVtx[1], hypCand.gDecVtx[2], diff --git a/PWGLF/TableProducer/Nuspex/hyperhelium4sigmaRecoTask.cxx b/PWGLF/TableProducer/Nuspex/hyperhelium4sigmaRecoTask.cxx deleted file mode 100644 index 300fe513e8e..00000000000 --- a/PWGLF/TableProducer/Nuspex/hyperhelium4sigmaRecoTask.cxx +++ /dev/null @@ -1,1140 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -// -/// \file hyperhelium4sigmaRecoTask.cxx -/// \brief QA and analysis task for hyper-helium4sigma (HyperHe4S) -/// \author Yuanzhe Wang - -#include "PWGLF/DataModel/LFHyperNucleiKinkTables.h" -#include "PWGLF/DataModel/LFKinkDecayTables.h" - -#include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/PIDResponse.h" -#include "Common/DataModel/PIDResponseITS.h" - -#include "CCDB/BasicCCDBManager.h" -#include "CommonConstants/PhysicsConstants.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DetectorsBase/GeometryManager.h" -#include "DetectorsBase/Propagator.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/Track.h" - -#include -#include -#include -#include - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; - -using CollisionsFull = soa::Join; -using MCLabeledCollisionsFull = soa::Join; -using FullTracksExtIU = soa::Join; -using MCLabeledTracksIU = soa::Join; - -enum Channel { - k2body = 0, // helium4, pion0 - k3body_p, // triton, proton, pion0 - k3body_n, // triton, neutron, pion+ - kNDecayChannel -}; - -enum DaughterType { - kDaugAlpha = 0, - kDaugTriton, - kDaugProton, - kDaugChargedPion, - kDaugNeutron, - kDaugPion0, - kNDaughterType, - kNChargedDaughterType = kDaugNeutron -}; - -namespace -{ -constexpr std::array LayerRadii{2.33959f, 3.14076f, 3.91924f, 19.6213f, 24.5597f, 34.388f, 39.3329f}; -constexpr int kITSLayers = 7; -constexpr int kITSInnerBarrelLayers = 3; -// constexpr int kITSOuterBarrelLayers = 4; -constexpr std::array kDaugghterPDG = { - o2::constants::physics::Pdg::kAlpha, - o2::constants::physics::Pdg::kTriton, - PDG_t::kProton, - PDG_t::kPiPlus, - PDG_t::kNeutron, - PDG_t::kPi0}; - -const std::array covPosSV{6.4462712107237135f, 0.1309793068144521f, 6.626654155592929f, -0.4510297694023185f, 0.16996629627762413f, 4.109195981415627f}; - -std::shared_ptr hMothCounter; -std::shared_ptr hMoth2BCounter; -std::shared_ptr hDaugCounter[kNChargedDaughterType]; -std::shared_ptr hDaugTPCNSigma[kNChargedDaughterType]; -std::shared_ptr hRecoMothCounter; -std::shared_ptr hRecoDaugAlphaCounter; -} // namespace - -//-------------------------------------------------------------- -// Check the decay channel of hyperhelium4sigma -template -Channel getDecayChannelHe4S(TMCParticle const& particle, std::vector& list) -{ - if (std::abs(particle.pdgCode()) != o2::constants::physics::Pdg::kHyperHelium4Sigma) { - return kNDecayChannel; - } - - // list: charged (alpha or triton), charged or empty, neutral - list.clear(); - list.resize(3, -1); - - bool haveAlpha = false, haveTriton = false, haveProton = false, haveNeuteron = false; - bool haveAntiAlpha = false, haveAntiTriton = false, haveAntiProton = false, haveAntiNeuteron = false; - bool havePionPlus = false, havePionMinus = false, havePion0 = false; - for (const auto& mcDaughter : particle.template daughters_as()) { - if (mcDaughter.pdgCode() == o2::constants::physics::Pdg::kAlpha) { - haveAlpha = true; - list[0] = mcDaughter.globalIndex(); - } - if (mcDaughter.pdgCode() == -o2::constants::physics::Pdg::kAlpha) { - haveAntiAlpha = true; - list[0] = mcDaughter.globalIndex(); - } - if (mcDaughter.pdgCode() == o2::constants::physics::Pdg::kTriton) { - haveTriton = true; - list[0] = mcDaughter.globalIndex(); - } - if (mcDaughter.pdgCode() == -o2::constants::physics::Pdg::kTriton) { - haveAntiTriton = true; - list[0] = mcDaughter.globalIndex(); - } - if (mcDaughter.pdgCode() == PDG_t::kProton) { - haveProton = true; - list[1] = mcDaughter.globalIndex(); - } - if (mcDaughter.pdgCode() == -PDG_t::kProton) { - haveAntiProton = true; - list[1] = mcDaughter.globalIndex(); - } - if (mcDaughter.pdgCode() == PDG_t::kNeutron) { - haveNeuteron = true; - list[2] = mcDaughter.globalIndex(); - } - if (mcDaughter.pdgCode() == -PDG_t::kNeutron) { - haveAntiNeuteron = true; - list[2] = mcDaughter.globalIndex(); - } - if (mcDaughter.pdgCode() == PDG_t::kPiPlus) { - havePionPlus = true; - list[1] = mcDaughter.globalIndex(); - } - if (mcDaughter.pdgCode() == -PDG_t::kPiPlus) { - havePionMinus = true; - list[1] = mcDaughter.globalIndex(); - } - if (mcDaughter.pdgCode() == PDG_t::kPi0) { - havePion0 = true; - list[2] = mcDaughter.globalIndex(); - } - } - - if ((haveAlpha && havePion0) || (haveAntiAlpha && havePion0)) { - return k2body; - } else if ((haveTriton && haveProton && havePion0) || (haveAntiTriton && haveAntiProton && havePion0)) { - return k3body_p; - } else if ((haveTriton && haveNeuteron && havePionPlus) || (haveAntiTriton && haveAntiNeuteron && havePionMinus)) { - return k3body_n; - } - - return kNDecayChannel; -} - -//-------------------------------------------------------------- -// Extract track parameters from a mcparticle, use global coordinates as the local one -template -o2::track::TrackParametrization getTrackParFromMC(const T& mcparticle, int charge = 1) -{ - int sign = mcparticle.pdgCode() > 0 ? 1 : -1; // ok for hyperhelium4sigma - TrackPrecision snp = mcparticle.py() / (mcparticle.pt() + 1.e-10f); - TrackPrecision tgl = mcparticle.pz() / (mcparticle.pt() + 1.e-10f); - std::array arraypar = {mcparticle.vy(), mcparticle.vz(), snp, - tgl, charge * sign / (mcparticle.pt() + 1.e-10f)}; - return o2::track::TrackParametrization(mcparticle.vx(), 0, std::move(arraypar)); -} - -//-------------------------------------------------------------- -// construct index array from mcParticle to track -template -void setTrackIDForMC(std::vector& mcPartIndices, aod::McParticles const& particlesMC, TTrackTable const& tracks) -{ - mcPartIndices.clear(); - mcPartIndices.resize(particlesMC.size()); - std::fill(mcPartIndices.begin(), mcPartIndices.end(), -1); - for (const auto& track : tracks) { - if (track.has_mcParticle()) { - auto mcparticle = track.template mcParticle_as(); - if (mcPartIndices[mcparticle.globalIndex()] == -1) { - mcPartIndices[mcparticle.globalIndex()] = track.globalIndex(); - } else { - auto candTrack = tracks.rawIteratorAt(mcPartIndices[mcparticle.globalIndex()]); - // Use the track which has innest information (also best quality? - if (track.x() < candTrack.x()) { - mcPartIndices[mcparticle.globalIndex()] = track.globalIndex(); - } - } - } - } -} - -//-------------------------------------------------------------- -// get TPCNSigma for daughter track -template -float getTPCNSigma(const TTrack& track, const int daughterType) -{ - float nSigma = -999.f; - switch (daughterType) { - case kDaugAlpha: - nSigma = track.tpcNSigmaAl(); - break; - case kDaugTriton: - nSigma = track.tpcNSigmaTr(); - break; - case kDaugProton: - nSigma = track.tpcNSigmaPr(); - break; - case kDaugChargedPion: - nSigma = track.tpcNSigmaPi(); - break; - default: - break; - } - return nSigma; -} - -//-------------------------------------------------------------- -// Refit the momentum of the mother track -template -bool refitMotherTrack(const TTrack& track, o2::track::TrackParametrizationWithError& trackPar, const o2::dataformats::VertexBase& primaryVtx, const o2::dataformats::VertexBase& secondaryVtx) -{ - float trackIUPos[2] = {track.y(), track.z()}; - float trackIUCov[3] = {track.cYY(), track.cZY(), track.cZZ()}; - - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVtx, trackPar, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrLUT); - - trackPar.resetCovariance(1e15); - if (!trackPar.update(primaryVtx)) { - return false; - } - - trackPar.rotate(track.alpha()); - o2::base::Propagator::Instance()->PropagateToXBxByBz(trackPar, track.x()); - if (!trackPar.update(trackIUPos, trackIUCov)) { - return false; - } - - o2::base::Propagator::Instance()->propagateToDCABxByBz(secondaryVtx, trackPar, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrLUT); - if (!trackPar.update(secondaryVtx)) { - return false; - } - - return true; -} - -//-------------------------------------------------------------- -struct Hyphe4sCandidate { - - bool isMatter = false; - - std::array posPV = {0.0f, 0.0f, 0.0f}; - std::array posSV = {0.0f, 0.0f, 0.0f}; - std::array lastPosMoth = {0.0f, 0.0f, 0.0f}; // last position of mother track at the radii of ITS layer which has the outermost update - std::array momMothSV = {0.0f, 0.0f, 0.0f}; - std::array momDaugSV = {0.0f, 0.0f, 0.0f}; - - float dcaXYMothPv = -999.f; - float dcaXYDaugPv = -999.f; - float dcaKinkTopo = -999.f; - - float chi2ITSMoth = 0.0f; - uint32_t itsClusterSizeMoth = 0u; - uint32_t itsClusterSizeDaug = 0u; - float nSigmaTPCDaug = -999.f; - float nSigmaITSDaug = -999.f; - - // mc information - bool isSignal = false; - bool isSignalReco = false; - bool isCollReco = false; - bool isSurvEvSelection = false; - - std::array truePosSV = {0.0f, 0.0f, 0.0f}; - std::array trueMomMothPV = {0.0f, 0.0f, 0.0f}; // generated mother momentum at primary vertex - std::array trueMomMothSV = {0.0f, 0.0f, 0.0f}; // true mother momentum at decay vertex - std::array trueMomDaugSV = {0.0f, 0.0f, 0.0f}; // true daughter momentum at decay vertex - - bool isMothReco = false; - std::array momMothPV = {0.0f, 0.0f, 0.0f}; - std::array updateMomMothPV = {0.0f, 0.0f, 0.0f}; // mother momentum at primary vertex after update using PV -}; - -//-------------------------------------------------------------- -// analysis task for hyperhelium4sigma 2-body decay -struct Hyperhelium4sigmaRecoTask { - - Produces outputDataTable; - Produces outputMCTable; - - Service ccdb; - o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; - - std::vector mcHe4sIndices; - - // Histograms are defined with HistogramRegistry - HistogramRegistry registry{"registry", {}}; - - // Configurable for event selection - Configurable doEventCut{"doEventCut", true, "Apply event selection"}; - Configurable maxZVertex{"maxZVertex", 10.0f, "Accepted z-vertex range (cm)"}; - Configurable cutNSigmaAl{"cutNSigmaAl", 5, "NSigmaTPCAlpha"}; - - // CCDB options - Configurable inputBz{"inputBz", -999, "bz field, -999 is automatic"}; - Configurable ccdbPath{"ccdbPath", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; - - int mRunNumber; - float mBz; - o2::base::MatLayerCylSet* lut = nullptr; - - o2::aod::ITSResponse itsResponse; - - void init(InitContext const&) - { - // Axes - const AxisSpec vertexZAxis{100, -15., 15., "vtx_{Z} [cm]"}; - const AxisSpec ptAxis{50, -10, 10, "#it{p}_{T} (GeV/#it{c})"}; - const AxisSpec nSigmaAxis{120, -6.f, 6.f, "n#sigma_{#alpha}"}; - const AxisSpec massAxis{100, 3.85, 4.25, "m (GeV/#it{c}^{2})"}; - const AxisSpec diffPxAxis{200, -10.f, 10.f, "#Delta #it{p}_{x} (GeV/#it{c})"}; - const AxisSpec diffPyAxis{200, -10.f, 10.f, "#Delta #it{p}_{y} (GeV/#it{c})"}; - const AxisSpec diffPtAxis{200, -10.f, 10.f, "#Delta #it{p}_{T} (GeV/#it{c})"}; - const AxisSpec diffPzAxis{200, -10.f, 10.f, "#Delta #it{p}_{z} (GeV/#it{c})"}; - const AxisSpec radiusAxis{40, 0.f, 40.f, "R (cm)"}; - - registry.add("hEventCounter", "hEventCounter", HistType::kTH1F, {{2, 0, 2}}); - registry.add("hVertexZCollision", "hVertexZCollision", HistType::kTH1F, {vertexZAxis}); - registry.add("hCandidateCounter", "hCandidateCounter", HistType::kTH1F, {{3, 0, 3}}); - - if (doprocessMC == true) { - itsResponse.setMCDefaultParameters(); - - registry.add("hTrueCandidateCounter", "hTrueCandidateCounter", HistType::kTH1F, {{3, 0, 3}}); - registry.add("hDiffSVx", ";#Delta x (cm);", HistType::kTH1F, {{200, -10, 10}}); - registry.add("hDiffSVy", ";#Delta y (cm);", HistType::kTH1F, {{200, -10, 10}}); - registry.add("hDiffSVz", ";#Delta z (cm);", HistType::kTH1F, {{200, -10, 10}}); - registry.add("h2RecSVRVsTrueSVR", ";Reconstruced SV R (cm);True SV R (cm);", HistType::kTH2F, {radiusAxis, radiusAxis}); - registry.add("h2TrueMotherDiffPxVsRecSVR", ";Reconstruced SV R (cm);#Delta #it{p}_{T} (GeV/#it{c});", HistType::kTH2F, {radiusAxis, diffPxAxis}); - registry.add("h2TrueMotherDiffPyVsRecSVR", ";Reconstruced SV R (cm);#Delta #it{p}_{T} (GeV/#it{c});", HistType::kTH2F, {radiusAxis, diffPyAxis}); - registry.add("h2TrueMotherDiffPtVsRecSVR", ";Reconstruced SV R (cm);#Delta #it{p}_{T} (GeV/#it{c});", HistType::kTH2F, {radiusAxis, diffPtAxis}); - registry.add("h2TrueMotherDiffPzVsRecSVR", ";Reconstruced SV R (cm);#Delta #it{p}_{z} (GeV/#it{c});", HistType::kTH2F, {radiusAxis, diffPzAxis}); - registry.add("h2TrueMotherDiffTglVsRecSVR", ";Reconstruced SV R (cm);#Delta tan#lambda;", HistType::kTH2F, {radiusAxis, {200, -0.1, 0.1}}); - registry.add("h2TrueMotherDiffEtaVsRecSVR", ";Reconstruced SV R (cm);#Delta #eta;", HistType::kTH2F, {radiusAxis, {200, -0.1, 0.1}}); - registry.add("hDiffDauPx", ";#Delta p_{x} (GeV/#it{c}); ", HistType::kTH1D, {{200, -10, 10}}); - registry.add("hDiffDauPy", ";#Delta p_{y} (GeV/#it{c}); ", HistType::kTH1D, {{200, -10, 10}}); - registry.add("hDiffDauPz", ";#Delta p_{z} (GeV/#it{c}); ", HistType::kTH1D, {{200, -10, 10}}); - registry.add("h2TrueSignalMassPt", "h2TrueSignalMassPt", HistType::kTH2F, {{ptAxis, massAxis}}); - registry.add("h2TrueSignalNSigmaAlPt", "h2TrueSignalNSigmaAlPt", HistType::kTH2F, {{ptAxis, nSigmaAxis}}); - - registry.add("hDCAXYMothToRecSV", "hDCAXYMothToRecSV", HistType::kTH1F, {{200, -10, 10}}); - registry.add("hDCAZMothToRecSV", "hDCAZMothToRecSV", HistType::kTH1F, {{200, -10, 10}}); - } - - registry.add("h2MassHyperhelium4sigmaPt", "h2MassHyperhelium4sigmaPt", HistType::kTH2F, {{ptAxis, massAxis}}); - registry.add("h2NSigmaAlPt", "h2NSigmaAlPt", HistType::kTH2F, {{ptAxis, nSigmaAxis}}); - - ccdb->setURL(ccdbPath); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - ccdb->setFatalWhenNull(false); - } - - void initCCDB(aod::BCs::iterator const& bc) - { - if (mRunNumber == bc.runNumber()) { - return; - } - mRunNumber = bc.runNumber(); - ccdb->clearCache(grpmagPath.value.data()); - LOG(info) << "Initializing CCDB for run " << mRunNumber; - o2::parameters::GRPMagField* grpmag = ccdb->getForRun(grpmagPath, mRunNumber); - o2::base::Propagator::initFieldFromGRP(grpmag); - mBz = grpmag->getNominalL3Field(); - - if (!lut) { - lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(lutPath)); - } - o2::base::Propagator::Instance()->setMatLUT(lut); - LOG(info) << "Task initialized for run " << mRunNumber << " with magnetic field " << mBz << " kZG"; - } - - template - void fillCandidate(Hyphe4sCandidate& hyphe4sCand, TCollision const& collision, TKindCandidate const& kinkCand, TTrack const& trackMoth, TTrack const& trackDaug) - { - hyphe4sCand.isMatter = kinkCand.mothSign() > 0; - hyphe4sCand.posPV[0] = collision.posX(); - hyphe4sCand.posPV[1] = collision.posY(); - hyphe4sCand.posPV[2] = collision.posZ(); - hyphe4sCand.posSV[0] = kinkCand.xDecVtx() + collision.posX(); - hyphe4sCand.posSV[1] = kinkCand.yDecVtx() + collision.posY(); - hyphe4sCand.posSV[2] = kinkCand.zDecVtx() + collision.posZ(); - - hyphe4sCand.momMothSV[0] = kinkCand.pxMoth(); - hyphe4sCand.momMothSV[1] = kinkCand.pyMoth(); - hyphe4sCand.momMothSV[2] = kinkCand.pzMoth(); - hyphe4sCand.momDaugSV[0] = kinkCand.pxDaug(); - hyphe4sCand.momDaugSV[1] = kinkCand.pyDaug(); - hyphe4sCand.momDaugSV[2] = kinkCand.pzDaug(); - - hyphe4sCand.dcaXYMothPv = kinkCand.dcaMothPv(); - hyphe4sCand.dcaXYDaugPv = kinkCand.dcaDaugPv(); - hyphe4sCand.dcaKinkTopo = kinkCand.dcaKinkTopo(); - - fillCandidateRecoMoth(hyphe4sCand, collision, trackMoth); - - hyphe4sCand.itsClusterSizeDaug = trackDaug.itsClusterSizes(); - hyphe4sCand.nSigmaTPCDaug = trackDaug.tpcNSigmaAl(); - hyphe4sCand.nSigmaITSDaug = itsResponse.nSigmaITS(trackDaug); - - int lastLayerMoth = 0; - for (int i = 6; i >= 0; i--) { - if (trackMoth.itsClusterMap() & (1 << i)) { - lastLayerMoth = i; - break; - } - } - auto trackparMother = getTrackParCov(trackMoth); - o2::base::Propagator::Instance()->PropagateToXBxByBz(trackparMother, LayerRadii[lastLayerMoth]); - std::array posLastHit{-999.f}; - trackparMother.getXYZGlo(posLastHit); - hyphe4sCand.lastPosMoth[0] = posLastHit[0]; - hyphe4sCand.lastPosMoth[1] = posLastHit[1]; - hyphe4sCand.lastPosMoth[2] = posLastHit[2]; - } - - template - void fillCandidateRecoMoth(Hyphe4sCandidate& hyphe4sCand, TCollision const& collision, TTrack const& trackMoth) - { - hyphe4sCand.isMothReco = true; - hyphe4sCand.chi2ITSMoth = trackMoth.itsChi2NCl(); - hyphe4sCand.itsClusterSizeMoth = trackMoth.itsClusterSizes(); - - auto motherTrackPar = getTrackParCov(trackMoth); - o2::dataformats::VertexBase primaryVtx = {{collision.posX(), collision.posY(), collision.posZ()}, {collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()}}; - std::array pMotherPv = {-999.f}; - if (o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVtx, motherTrackPar, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) { - motherTrackPar.getPxPyPzGlo(pMotherPv); - } - hyphe4sCand.momMothPV[0] = pMotherPv[0]; - hyphe4sCand.momMothPV[1] = pMotherPv[1]; - hyphe4sCand.momMothPV[2] = pMotherPv[2]; - - std::array updatePMotherPv = {-999.f}; - if (motherTrackPar.update(primaryVtx)) { - motherTrackPar.getPxPyPzGlo(updatePMotherPv); - } - hyphe4sCand.updateMomMothPV[0] = updatePMotherPv[0]; - hyphe4sCand.updateMomMothPV[1] = updatePMotherPv[1]; - hyphe4sCand.updateMomMothPV[2] = updatePMotherPv[2]; - } - - template - void fillCandidateMCInfo(Hyphe4sCandidate& hyphe4sCand, TMCParticle const& mcMothTrack, TMCParticle const& mcDauTrack, TMCParticle const& mcNeutDauTrack) - { - hyphe4sCand.truePosSV[0] = mcDauTrack.vx(); - hyphe4sCand.truePosSV[1] = mcDauTrack.vy(); - hyphe4sCand.truePosSV[2] = mcDauTrack.vz(); - hyphe4sCand.trueMomMothPV[0] = mcMothTrack.px(); - hyphe4sCand.trueMomMothPV[1] = mcMothTrack.py(); - hyphe4sCand.trueMomMothPV[2] = mcMothTrack.pz(); - hyphe4sCand.trueMomMothSV[0] = mcDauTrack.px() + mcNeutDauTrack.px(); - hyphe4sCand.trueMomMothSV[1] = mcDauTrack.py() + mcNeutDauTrack.py(); - hyphe4sCand.trueMomMothSV[2] = mcDauTrack.pz() + mcNeutDauTrack.pz(); - hyphe4sCand.trueMomDaugSV[0] = mcDauTrack.px(); - hyphe4sCand.trueMomDaugSV[1] = mcDauTrack.py(); - hyphe4sCand.trueMomDaugSV[2] = mcDauTrack.pz(); - } - - void processData(CollisionsFull const& collisions, aod::KinkCands const& KinkCands, FullTracksExtIU const&, aod::BCs const&) - { - for (const auto& collision : collisions) { - registry.fill(HIST("hEventCounter"), 0); - if (doEventCut && (std::abs(collision.posZ()) > maxZVertex || !collision.sel8())) { - continue; - } - registry.fill(HIST("hEventCounter"), 1); - registry.fill(HIST("hVertexZCollision"), collision.posZ()); - } - - for (const auto& kinkCand : KinkCands) { - registry.fill(HIST("hCandidateCounter"), 0); - auto collision = kinkCand.collision_as(); - if (doEventCut && (std::abs(collision.posZ()) > maxZVertex || !collision.sel8())) { - continue; - } - registry.fill(HIST("hCandidateCounter"), 1); - - auto dauTrack = kinkCand.trackDaug_as(); - if (std::abs(dauTrack.tpcNSigmaAl()) > cutNSigmaAl) { - continue; - } - float invMass = RecoDecay::m(std::array{std::array{kinkCand.pxDaug(), kinkCand.pyDaug(), kinkCand.pzDaug()}, std::array{kinkCand.pxDaugNeut(), kinkCand.pyDaugNeut(), kinkCand.pzDaugNeut()}}, std::array{o2::constants::physics::MassAlpha, o2::constants::physics::MassPi0}); - registry.fill(HIST("hCandidateCounter"), 2); - registry.fill(HIST("h2MassHyperhelium4sigmaPt"), kinkCand.mothSign() * kinkCand.ptMoth(), invMass); - registry.fill(HIST("h2NSigmaAlPt"), kinkCand.mothSign() * kinkCand.ptDaug(), dauTrack.tpcNSigmaAl()); - - auto bc = collision.bc_as(); - initCCDB(bc); - auto motherTrack = kinkCand.trackMoth_as(); - Hyphe4sCandidate hyphe4sCand; - fillCandidate(hyphe4sCand, collision, kinkCand, motherTrack, dauTrack); - - o2::dataformats::VertexBase primaryVtx = {{collision.posX(), collision.posY(), collision.posZ()}, {collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()}}; - o2::dataformats::VertexBase secondaryVtx = {{kinkCand.xDecVtx() + collision.posX(), kinkCand.yDecVtx() + collision.posY(), kinkCand.zDecVtx() + collision.posZ()}, {covPosSV[0], covPosSV[1], covPosSV[2], covPosSV[3], covPosSV[4], covPosSV[5]}}; - std::array refitPPV = {-999.f}; - std::array refitPSV = {-999.f}; - auto motherTrackPar = getTrackParCov(motherTrack); - if (refitMotherTrack(motherTrack, motherTrackPar, primaryVtx, secondaryVtx)) { - motherTrackPar.getPxPyPzGlo(refitPSV); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVtx, motherTrackPar, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrLUT); - motherTrackPar.getPxPyPzGlo(refitPPV); - } - - outputDataTable( - hyphe4sCand.posPV[0], hyphe4sCand.posPV[1], hyphe4sCand.posPV[2], - hyphe4sCand.posSV[0], hyphe4sCand.posSV[1], hyphe4sCand.posSV[2], - hyphe4sCand.isMatter, - hyphe4sCand.lastPosMoth[0], hyphe4sCand.lastPosMoth[1], hyphe4sCand.lastPosMoth[2], - hyphe4sCand.momMothSV[0], hyphe4sCand.momMothSV[1], hyphe4sCand.momMothSV[2], - refitPPV[0], refitPPV[1], refitPPV[2], - refitPSV[0], refitPSV[1], refitPSV[2], - hyphe4sCand.momDaugSV[0], hyphe4sCand.momDaugSV[1], hyphe4sCand.momDaugSV[2], - hyphe4sCand.dcaXYMothPv, hyphe4sCand.dcaXYDaugPv, hyphe4sCand.dcaKinkTopo, - hyphe4sCand.chi2ITSMoth, hyphe4sCand.itsClusterSizeMoth, hyphe4sCand.itsClusterSizeDaug, - hyphe4sCand.nSigmaTPCDaug, hyphe4sCand.nSigmaITSDaug); - } - } - PROCESS_SWITCH(Hyperhelium4sigmaRecoTask, processData, "process data", true); - - void processMC(MCLabeledCollisionsFull const& collisions, aod::KinkCands const& KinkCands, MCLabeledTracksIU const& tracks, aod::McParticles const& particlesMC, aod::McCollisions const& mcCollisions, aod::BCs const&) - { - mcHe4sIndices.clear(); - std::vector mcPartIndices; - setTrackIDForMC(mcPartIndices, particlesMC, tracks); - std::vector isReconstructedMCCollisions(mcCollisions.size(), false); - std::vector isSelectedMCCollisions(mcCollisions.size(), false); - std::vector isGoodCollisions(collisions.size(), false); - std::vector dauIDList(3, -1); - - for (const auto& collision : collisions) { - isReconstructedMCCollisions[collision.mcCollisionId()] = true; - registry.fill(HIST("hEventCounter"), 0); - if (doEventCut && (!collision.selection_bit(aod::evsel::kIsTriggerTVX) || !collision.selection_bit(aod::evsel::kNoTimeFrameBorder) || std::abs(collision.posZ()) > maxZVertex)) { - continue; - } - registry.fill(HIST("hEventCounter"), 1); - registry.fill(HIST("hVertexZCollision"), collision.posZ()); - isSelectedMCCollisions[collision.mcCollisionId()] = true; - isGoodCollisions[collision.globalIndex()] = true; - } - - for (const auto& kinkCand : KinkCands) { - auto motherTrack = kinkCand.trackMoth_as(); - auto dauTrack = kinkCand.trackDaug_as(); - - bool isTrueSignal = false; - if (motherTrack.has_mcParticle() && dauTrack.has_mcParticle()) { - auto mcMotherTrack = motherTrack.mcParticle_as(); - auto mcDauTrack = dauTrack.mcParticle_as(); - auto dChannel = getDecayChannelHe4S(mcMotherTrack, dauIDList); - if (dChannel == k2body && dauIDList[0] == mcDauTrack.globalIndex()) { - isTrueSignal = true; - } - } - - registry.fill(HIST("hCandidateCounter"), 0); - if (isTrueSignal) { - registry.fill(HIST("hTrueCandidateCounter"), 0); - } - auto collision = kinkCand.collision_as(); - if (!isGoodCollisions[collision.globalIndex()]) { - continue; - } - registry.fill(HIST("hCandidateCounter"), 1); - if (isTrueSignal) { - registry.fill(HIST("hTrueCandidateCounter"), 1); - } - - if (std::abs(dauTrack.tpcNSigmaAl()) > cutNSigmaAl) { - continue; - } - float invMass = RecoDecay::m(std::array{std::array{kinkCand.pxDaug(), kinkCand.pyDaug(), kinkCand.pzDaug()}, std::array{kinkCand.pxDaugNeut(), kinkCand.pyDaugNeut(), kinkCand.pzDaugNeut()}}, std::array{o2::constants::physics::MassAlpha, o2::constants::physics::MassPi0}); - registry.fill(HIST("hCandidateCounter"), 2); - if (isTrueSignal) { - registry.fill(HIST("hTrueCandidateCounter"), 2); - } - registry.fill(HIST("h2MassHyperhelium4sigmaPt"), kinkCand.mothSign() * kinkCand.ptMoth(), invMass); - registry.fill(HIST("h2NSigmaAlPt"), kinkCand.mothSign() * kinkCand.ptDaug(), dauTrack.tpcNSigmaAl()); - - auto bc = collision.bc_as(); - initCCDB(bc); - Hyphe4sCandidate hyphe4sCand; - fillCandidate(hyphe4sCand, collision, kinkCand, motherTrack, dauTrack); - - std::array posDecVtx = {kinkCand.xDecVtx() + collision.posX(), kinkCand.yDecVtx() + collision.posY(), kinkCand.zDecVtx() + collision.posZ()}; - - o2::dataformats::VertexBase primaryVtx = {{collision.posX(), collision.posY(), collision.posZ()}, {collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()}}; - o2::dataformats::VertexBase secondaryVtx = {{posDecVtx[0], posDecVtx[1], posDecVtx[2]}, {covPosSV[0], covPosSV[1], covPosSV[2], covPosSV[3], covPosSV[4], covPosSV[5]}}; - std::array refitPPV = {-999.f}; - std::array refitPSV = {-999.f}; - auto motherTrackPar = getTrackParCov(motherTrack); - if (refitMotherTrack(motherTrack, motherTrackPar, primaryVtx, secondaryVtx)) { - motherTrackPar.getPxPyPzGlo(refitPSV); - o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVtx, motherTrackPar, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrLUT); - motherTrackPar.getPxPyPzGlo(refitPPV); - } - - // qa for true signal - if (isTrueSignal) { - auto mcMotherTrack = motherTrack.mcParticle_as(); - auto mcDauTrack = dauTrack.mcParticle_as(); - auto mcNeutTrack = particlesMC.rawIteratorAt(dauIDList[2]); - float recSVR = std::sqrt(posDecVtx[0] * posDecVtx[0] + posDecVtx[1] * posDecVtx[1]); - registry.fill(HIST("hDiffSVx"), posDecVtx[0] - mcDauTrack.vx()); - registry.fill(HIST("hDiffSVy"), posDecVtx[1] - mcDauTrack.vy()); - registry.fill(HIST("hDiffSVz"), posDecVtx[2] - mcDauTrack.vz()); - registry.fill(HIST("h2RecSVRVsTrueSVR"), recSVR, std::hypot(mcDauTrack.vx(), mcDauTrack.vy())); - registry.fill(HIST("h2TrueMotherDiffPtVsRecSVR"), recSVR, mcMotherTrack.pt() - kinkCand.ptMoth()); - registry.fill(HIST("h2TrueMotherDiffPzVsRecSVR"), recSVR, mcMotherTrack.pz() - kinkCand.pzMoth()); - registry.fill(HIST("h2TrueMotherDiffTglVsRecSVR"), recSVR, mcMotherTrack.pz() / mcMotherTrack.pt() - motherTrack.tgl()); - registry.fill(HIST("h2TrueMotherDiffEtaVsRecSVR"), recSVR, mcMotherTrack.eta() - motherTrack.eta()); - registry.fill(HIST("hDiffDauPx"), kinkCand.pxDaug() - mcDauTrack.px()); - registry.fill(HIST("hDiffDauPy"), kinkCand.pyDaug() - mcDauTrack.py()); - registry.fill(HIST("hDiffDauPz"), kinkCand.pzDaug() - mcDauTrack.pz()); - registry.fill(HIST("h2TrueSignalMassPt"), kinkCand.mothSign() * kinkCand.ptMoth(), invMass); - registry.fill(HIST("h2TrueSignalNSigmaAlPt"), kinkCand.mothSign() * kinkCand.ptDaug(), dauTrack.tpcNSigmaAl()); - - hyphe4sCand.isSignal = true; - hyphe4sCand.isSignalReco = true; - hyphe4sCand.isCollReco = true; - hyphe4sCand.isSurvEvSelection = true; - fillCandidateMCInfo(hyphe4sCand, mcMotherTrack, mcDauTrack, mcNeutTrack); - mcHe4sIndices.push_back(mcMotherTrack.globalIndex()); - - std::array dcaInfo; - auto mcMotherTrackPar = getTrackParFromMC(mcMotherTrack, 2); - o2::base::Propagator::Instance()->propagateToDCABxByBz({posDecVtx[0], posDecVtx[1], posDecVtx[2]}, mcMotherTrackPar, 2.f, matCorr, &dcaInfo); - registry.fill(HIST("hDCAXYMothToRecSV"), dcaInfo[0]); - registry.fill(HIST("hDCAZMothToRecSV"), dcaInfo[1]); - std::array mcPMotherSV = {-999.f, -999.f, -999.f}; - mcMotherTrackPar.getPxPyPzGlo(mcPMotherSV); - registry.fill(HIST("h2TrueMotherDiffPxVsRecSVR"), recSVR, mcPMotherSV[0] - kinkCand.pxMoth()); - registry.fill(HIST("h2TrueMotherDiffPyVsRecSVR"), recSVR, mcPMotherSV[1] - kinkCand.pyMoth()); - } - - outputMCTable( - hyphe4sCand.posPV[0], hyphe4sCand.posPV[1], hyphe4sCand.posPV[2], - hyphe4sCand.posSV[0], hyphe4sCand.posSV[1], hyphe4sCand.posSV[2], - hyphe4sCand.isMatter, - hyphe4sCand.lastPosMoth[0], hyphe4sCand.lastPosMoth[1], hyphe4sCand.lastPosMoth[2], - hyphe4sCand.momMothSV[0], hyphe4sCand.momMothSV[1], hyphe4sCand.momMothSV[2], - refitPPV[0], refitPPV[1], refitPPV[2], - refitPSV[0], refitPSV[1], refitPSV[2], - hyphe4sCand.momDaugSV[0], hyphe4sCand.momDaugSV[1], hyphe4sCand.momDaugSV[2], - hyphe4sCand.dcaXYMothPv, hyphe4sCand.dcaXYDaugPv, hyphe4sCand.dcaKinkTopo, - hyphe4sCand.chi2ITSMoth, hyphe4sCand.itsClusterSizeMoth, hyphe4sCand.itsClusterSizeDaug, - hyphe4sCand.nSigmaTPCDaug, hyphe4sCand.nSigmaITSDaug, - hyphe4sCand.isSignal, hyphe4sCand.isSignalReco, hyphe4sCand.isCollReco, hyphe4sCand.isSurvEvSelection, - hyphe4sCand.truePosSV[0], hyphe4sCand.truePosSV[1], hyphe4sCand.truePosSV[2], - hyphe4sCand.trueMomMothPV[0], hyphe4sCand.trueMomMothPV[1], hyphe4sCand.trueMomMothPV[2], - hyphe4sCand.trueMomMothSV[0], hyphe4sCand.trueMomMothSV[1], hyphe4sCand.trueMomMothSV[2], - hyphe4sCand.trueMomDaugSV[0], hyphe4sCand.trueMomDaugSV[1], hyphe4sCand.trueMomDaugSV[2], - hyphe4sCand.isMothReco, hyphe4sCand.momMothPV[0], hyphe4sCand.momMothPV[1], hyphe4sCand.momMothPV[2], - hyphe4sCand.updateMomMothPV[0], hyphe4sCand.updateMomMothPV[1], hyphe4sCand.updateMomMothPV[2]); - } - - // fill hyperhelium4sigma signals which are not reconstructed - for (auto const& mcparticle : particlesMC) { - auto dChannel = getDecayChannelHe4S(mcparticle, dauIDList); - if (dChannel != k2body) { - continue; - } - if (std::find(mcHe4sIndices.begin(), mcHe4sIndices.end(), mcparticle.globalIndex()) != mcHe4sIndices.end()) { - continue; - } - - Hyphe4sCandidate hyphe4sCand; - auto mcDauTrack = particlesMC.rawIteratorAt(dauIDList[0]); - auto mcNeutTrack = particlesMC.rawIteratorAt(dauIDList[2]); - fillCandidateMCInfo(hyphe4sCand, mcparticle, mcDauTrack, mcNeutTrack); - - if (mcPartIndices[mcparticle.globalIndex()] != -1) { - auto mothTrack = tracks.rawIteratorAt(mcPartIndices[mcparticle.globalIndex()]); - if (mothTrack.has_collision()) { - auto collision = mothTrack.collision_as(); - auto bc = collision.template bc_as(); - initCCDB(bc); - fillCandidateRecoMoth(hyphe4sCand, collision, mothTrack); - } - } - - outputMCTable( - -1, -1, -1, - -1, -1, -1, - -1, - -1, -1, -1, - -1, -1, -1, - -1, -1, -1, - -1, -1, -1, - -1, -1, -1, - -1, -1, -1, - -1, -1, -1, - -1, -1, - true, false, isReconstructedMCCollisions[mcparticle.mcCollisionId()], isSelectedMCCollisions[mcparticle.mcCollisionId()], - hyphe4sCand.truePosSV[0], hyphe4sCand.truePosSV[1], hyphe4sCand.truePosSV[2], - hyphe4sCand.trueMomMothPV[0], hyphe4sCand.trueMomMothPV[1], hyphe4sCand.trueMomMothPV[2], - hyphe4sCand.trueMomMothSV[0], hyphe4sCand.trueMomMothSV[1], hyphe4sCand.trueMomMothSV[2], - hyphe4sCand.trueMomDaugSV[0], hyphe4sCand.trueMomDaugSV[1], hyphe4sCand.trueMomDaugSV[2], - hyphe4sCand.isMothReco, hyphe4sCand.momMothPV[0], hyphe4sCand.momMothPV[1], hyphe4sCand.momMothPV[2], - hyphe4sCand.updateMomMothPV[0], hyphe4sCand.updateMomMothPV[1], hyphe4sCand.updateMomMothPV[2]); - } - } - PROCESS_SWITCH(Hyperhelium4sigmaRecoTask, processMC, "process MC", false); -}; - -//-------------------------------------------------------------- -// check the performance of mcparticle -struct Hyperhelium4sigmaQa { - - HistogramRegistry genQAHist{"genQAHist", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry recoQAHist{"recoQAHist", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - - ConfigurableAxis ptBins{"ptBins", {200, 0.f, 10.f}, "Binning for #it{p}_{T} (GeV/#it{c})"}; - ConfigurableAxis ctBins{"ctBins", {100, 0.f, 25.f}, "Binning for c#it{t} (cm)"}; - ConfigurableAxis rigidityBins{"rigidityBins", {200, -10.f, 10.f}, "Binning for #it{p}_{T} (GeV/#it{c})"}; - ConfigurableAxis nsigmaBins{"nsigmaBins", {120, -6.f, 6.f}, "Binning for n sigma"}; - ConfigurableAxis invMassBins{"invMassBins", {100, 3.85f, 4.15f}, "Binning for invariant mass (GeV/#it{c}^{2})"}; - ConfigurableAxis radiusBins{"radiusBins", {40, 0.f, 40.f}, "Binning for radius in xy plane (cm)"}; - - o2::aod::ITSResponse itsResponse; - - void init(InitContext&) - { - if (doprocessMC == true) { - itsResponse.setMCDefaultParameters(); - - const AxisSpec pAxis{ptBins, "#it{p} (GeV/#it{c})"}; - const AxisSpec ptAxis{ptBins, "#it{p}_{T} (GeV/#it{c})"}; - const AxisSpec ctAxis{ctBins, "c#it{t} (cm)"}; - const AxisSpec rigidityAxis{rigidityBins, "p/z (GeV/#it{c})"}; - const AxisSpec nsigmaAxis{nsigmaBins, "TPC n#sigma"}; - const AxisSpec itsnsigmaAxis{nsigmaBins, "ITS n#sigma"}; - const AxisSpec invMassAxis{invMassBins, "Inv Mass (GeV/#it{c}^{2})"}; - const AxisSpec diffPtAxis{200, -10.f, 10.f, "#Delta p_{T} (GeV/#it{c})"}; - const AxisSpec diffPzAxis{200, -10.f, 10.f, "#Delta p_{z} (GeV/#it{c})"}; - const AxisSpec itsRadiusAxis{radiusBins, "ITS R (cm)"}; - const AxisSpec svRadiuAxis{radiusBins, "Decay Vertex R (cm)"}; - - auto hCollCounter = genQAHist.add("hCollCounter", "hCollCounter", HistType::kTH1F, {{2, 0.0f, 2.0f}}); - hCollCounter->GetXaxis()->SetBinLabel(1, "Reconstructed Collisions"); - hCollCounter->GetXaxis()->SetBinLabel(2, "Selected"); - auto hMcCollCounter = genQAHist.add("hMcCollCounter", "hMcCollCounter", HistType::kTH1F, {{2, 0.0f, 2.0f}}); - hMcCollCounter->GetXaxis()->SetBinLabel(1, "MC Collisions"); - hMcCollCounter->GetXaxis()->SetBinLabel(2, "Reconstructed"); - - auto hGenHyperHelium4SigmaCounter = genQAHist.add("hGenHyperHelium4SigmaCounter", "", HistType::kTH1F, {{11, 0.f, 11.f}}); - hGenHyperHelium4SigmaCounter->GetXaxis()->SetBinLabel(1, "He4S All"); - hGenHyperHelium4SigmaCounter->GetXaxis()->SetBinLabel(2, "Matter"); - hGenHyperHelium4SigmaCounter->GetXaxis()->SetBinLabel(3, "AntiMatter"); - hGenHyperHelium4SigmaCounter->GetXaxis()->SetBinLabel(4, "#alpha + #pi^{0}"); - hGenHyperHelium4SigmaCounter->GetXaxis()->SetBinLabel(5, "#bar{#alpha} + #pi^{0}"); - hGenHyperHelium4SigmaCounter->GetXaxis()->SetBinLabel(6, "t + p + #pi^{0}"); - hGenHyperHelium4SigmaCounter->GetXaxis()->SetBinLabel(7, "#bar{t} + #bar{p} + #pi^{0}"); - hGenHyperHelium4SigmaCounter->GetXaxis()->SetBinLabel(8, "t + n + #pi^{+}"); - hGenHyperHelium4SigmaCounter->GetXaxis()->SetBinLabel(9, "#bar{t} + #bar{n} + #pi^{+}"); - hGenHyperHelium4SigmaCounter->GetXaxis()->SetBinLabel(10, "Tracks found"); - hGenHyperHelium4SigmaCounter->GetXaxis()->SetBinLabel(11, "Unexpected"); - - auto hEvtSelectedHyperHelium4SigmaCounter = genQAHist.add("hEvtSelectedHyperHelium4SigmaCounter", "", HistType::kTH1F, {{2, 0.f, 2.f}}); - hEvtSelectedHyperHelium4SigmaCounter->GetXaxis()->SetBinLabel(1, "Generated"); - hEvtSelectedHyperHelium4SigmaCounter->GetXaxis()->SetBinLabel(2, "Survived"); - - genQAHist.add("hGenHyperHelium4SigmaP", "", HistType::kTH1F, {pAxis}); - genQAHist.add("hGenHyperHelium4SigmaPt", "", HistType::kTH1F, {ptAxis}); - genQAHist.add("hGenHyperHelium4SigmaCt", "", HistType::kTH1F, {ctAxis}); - genQAHist.add("hMcRecoInvMass", "", HistType::kTH1F, {invMassAxis}); - - // efficiency/criteria studies for tracks which are true candidates - hMothCounter = recoQAHist.add("hMothCounter", "", HistType::kTH1F, {{9, 0.f, 9.f}}); - hMoth2BCounter = recoQAHist.add("hMoth2BCounter", "", HistType::kTH1F, {{9, 0.f, 9.f}}); - for (const auto& hist : {hMothCounter, hMoth2BCounter}) { - hist->GetXaxis()->SetBinLabel(1, "Generated"); - hist->GetXaxis()->SetBinLabel(2, "Reconstructed"); - hist->GetXaxis()->SetBinLabel(3, "eta"); - hist->GetXaxis()->SetBinLabel(4, "has collision"); - hist->GetXaxis()->SetBinLabel(5, "ITSonly"); - hist->GetXaxis()->SetBinLabel(6, "ITS hits"); - hist->GetXaxis()->SetBinLabel(7, "ITS IR"); - hist->GetXaxis()->SetBinLabel(8, "ITS chi2"); - hist->GetXaxis()->SetBinLabel(9, "pt"); - } - recoQAHist.add("h2TrueMotherDiffPtVsTrueSVR", ";Decay Vertex R (cm);#Delta p_{T} (GeV/#it{c});", HistType::kTH2F, {svRadiuAxis, diffPtAxis}); - recoQAHist.add("h2TrueMotherDiffPzVsTrueSVR", ";Decay Vertex R (cm);#Delta p_{z} (GeV/#it{c});", HistType::kTH2F, {svRadiuAxis, diffPzAxis}); - recoQAHist.add("h2TrueMotherDiffTglVsTrueSVR", ";Decay Vertex R (cm);#Delta tgl;", HistType::kTH2F, {svRadiuAxis, {200, -1.f, 1.f}}); - recoQAHist.add("h2TrueMotherDiffEtaVsTrueSVR", ";Decay Vertex R (cm);#Delta #eta;", HistType::kTH2F, {svRadiuAxis, {200, -1.f, 1.f}}); - recoQAHist.add("h2GoodMotherDiffPtVsTrueSVR", ";Decay Vertex R (cm);#Delta p_{T} (GeV/#it{c});", HistType::kTH2F, {svRadiuAxis, diffPtAxis}); - recoQAHist.add("h2GoodMotherDiffPzVsTrueSVR", ";Decay Vertex R (cm);#Delta p_{z} (GeV/#it{c});", HistType::kTH2F, {svRadiuAxis, diffPzAxis}); - - hDaugCounter[kDaugAlpha] = recoQAHist.add("hDaugAlphaCounter", "", HistType::kTH1F, {{9, 0.f, 9.f}}); - hDaugCounter[kDaugTriton] = recoQAHist.add("hDaugTritonCounter", "", HistType::kTH1F, {{9, 0.f, 9.f}}); - hDaugCounter[kDaugProton] = recoQAHist.add("hDaugProtonCounter", "", HistType::kTH1F, {{9, 0.f, 9.f}}); - hDaugCounter[kDaugChargedPion] = recoQAHist.add("hDaugPionCounter", "", HistType::kTH1F, {{9, 0.f, 9.f}}); - hDaugTPCNSigma[kDaugAlpha] = recoQAHist.add("hDaugAlphaTPCNSigma", "", HistType::kTH2F, {rigidityAxis, nsigmaAxis}); - hDaugTPCNSigma[kDaugTriton] = recoQAHist.add("hDaugTritonTPCNSigma", "", HistType::kTH2F, {rigidityAxis, nsigmaAxis}); - hDaugTPCNSigma[kDaugProton] = recoQAHist.add("hDaugProtonTPCNSigma", "", HistType::kTH2F, {rigidityAxis, nsigmaAxis}); - hDaugTPCNSigma[kDaugChargedPion] = recoQAHist.add("hDaugPionTPCNSigma", "", HistType::kTH2F, {rigidityAxis, nsigmaAxis}); - recoQAHist.add("hDaugAlphaITSNSigmaCheck", "", HistType::kTH2F, {rigidityAxis, itsnsigmaAxis}); - - hRecoMothCounter = recoQAHist.add("hRecoMothCounter", "", HistType::kTH1F, {{9, 0.f, 9.f}}); - hRecoDaugAlphaCounter = recoQAHist.add("hRecoDaugAlphaCounter", "", HistType::kTH1F, {{9, 0.f, 9.f}}); - for (const auto& hist : {hDaugCounter[kDaugAlpha], hDaugCounter[kDaugTriton], hDaugCounter[kDaugProton], hDaugCounter[kDaugChargedPion], hRecoMothCounter, hRecoDaugAlphaCounter}) { - hist->GetXaxis()->SetBinLabel(1, "Generated"); - hist->GetXaxis()->SetBinLabel(2, "Reconstructed"); - hist->GetXaxis()->SetBinLabel(3, "eta"); - hist->GetXaxis()->SetBinLabel(4, "has ITS&TPC"); - hist->GetXaxis()->SetBinLabel(5, "TPC crossed rows"); - hist->GetXaxis()->SetBinLabel(6, "TPC Ncls"); - hist->GetXaxis()->SetBinLabel(7, "TPC n#sigma"); - hist->GetXaxis()->SetBinLabel(8, "ITS hits"); - hist->GetXaxis()->SetBinLabel(9, "has TOF)"); - } - - recoQAHist.add("hMothIsPVContributer", "", HistType::kTH1F, {{2, 0.f, 2.f}}); - recoQAHist.add("hMothITSCls", "", HistType::kTH1F, {{8, 0.f, 8.f}}); - recoQAHist.add("hDaugAlphaIsPVContributer", "", HistType::kTH1F, {{2, 0.f, 2.f}}); - recoQAHist.add("hDaugAlphaITSCls", "", HistType::kTH1F, {{8, 0.f, 8.f}}); - recoQAHist.add("hDaugAlphaITSNSigma", "", HistType::kTH2F, {rigidityAxis, itsnsigmaAxis}); - recoQAHist.add("hReco2BDauAlphaPVsITSNSigma", "", HistType::kTH2F, {rigidityAxis, itsnsigmaAxis}); - recoQAHist.add("hReco2BCandidateCount", "", HistType::kTH1F, {{4, 0.f, 4.f}}); - } - } - - Configurable skipRejectedEvents{"skipRejectedEvents", false, "Flag to skip events that fail event selection cuts"}; - Configurable doEventCut{"doEventCut", true, "Apply event selection"}; - Configurable maxZVertex{"maxZVertex", 10.0f, "Accepted z-vertex range (cm)"}; - Configurable only2BodyDecay{"only2BodyDecay", true, "Only consider 2-body decays for hyperhelium4sigma"}; - - Configurable etaMax{"etaMax", 1., "eta cut for tracks"}; - Configurable minPtMoth{"minPtMoth", 0.5, "Minimum pT/z of the hyperhelium4sigma candidate"}; - Configurable tpcPidNsigmaCut{"tpcPidNsigmaCut", 5, "tpcPidNsigmaCut"}; - Configurable nTPCClusMinDaug{"nTPCClusMinDaug", 80, "daug NTPC clusters cut"}; - Configurable itsMaxChi2{"itsMaxChi2", 36, "max chi2 for ITS"}; - Configurable minRatioTPCNCls{"minRatioTPCNCls", 0.8, "min ratio of TPC crossed rows to findable clusters"}; - - Preslice permcCollision = o2::aod::mcparticle::mcCollisionId; - - // qa for mother track selection - template - bool motherTrackCheck(const TTrack& track, const std::shared_ptr hist) - { - hist->Fill(1); - - if (std::abs(track.eta()) > etaMax) { - return false; - } - hist->Fill(2); - - if (!track.has_collision()) { - return false; - } - hist->Fill(3); - - if (!track.hasITS() || track.hasTPC() || track.hasTOF()) { - return false; - } - hist->Fill(4); - - if (track.itsNCls() >= kITSLayers - 1) { - return false; - } - hist->Fill(5); - - if (track.itsNClsInnerBarrel() != kITSInnerBarrelLayers) { - return false; - } - hist->Fill(6); - - if (track.itsChi2NCl() >= itsMaxChi2) { - return false; - } - hist->Fill(7); - - if (track.pt() <= minPtMoth) { - return false; - } - hist->Fill(8); - - return true; - } - - // qa for daughter track selection - template - bool daughterTrackCheck(const TTrack& track, const std::shared_ptr hist, float tpcNSigma) - { - hist->Fill(1); - - if (std::abs(track.eta()) > etaMax) { - return false; - } - hist->Fill(2); - - if (!track.hasITS() || !track.hasTPC()) { - return false; - } - hist->Fill(3); - - if (track.tpcNClsCrossedRows() <= minRatioTPCNCls * track.tpcNClsFindable()) { - return false; - } - hist->Fill(4); - - if (track.tpcNClsFound() <= nTPCClusMinDaug) { - return false; - } - hist->Fill(5); - - if (std::abs(tpcNSigma) > tpcPidNsigmaCut) { - return false; - } - hist->Fill(6); - - if (track.itsNClsInnerBarrel() != 0 || track.itsNCls() > kITSInnerBarrelLayers) { - return false; - } - hist->Fill(7); - - if (track.hasTOF()) { - return false; - } - hist->Fill(8); - - return true; - } - - void processData(o2::aod::Collisions const&) - { - // dummy process function; - } - PROCESS_SWITCH(Hyperhelium4sigmaQa, processData, "process data", true); - - void processMC(aod::McCollisions const& mcCollisions, aod::McParticles const& particlesMC, MCLabeledCollisionsFull const& collisions, MCLabeledTracksIU const& tracks, aod::BCs const&) - { - std::vector mcPartIndices; - setTrackIDForMC(mcPartIndices, particlesMC, tracks); - std::vector isSelectedMCCollisions(mcCollisions.size(), false); - std::vector dauIDList(3, -1); - for (const auto& collision : collisions) { - genQAHist.fill(HIST("hCollCounter"), 0.5); - if (doEventCut && (!collision.selection_bit(aod::evsel::kIsTriggerTVX) || !collision.selection_bit(aod::evsel::kNoTimeFrameBorder) || std::abs(collision.posZ()) > maxZVertex)) { - continue; - } - genQAHist.fill(HIST("hCollCounter"), 1.5); - isSelectedMCCollisions[collision.mcCollisionId()] = true; - } - - for (const auto& mcCollision : mcCollisions) { - genQAHist.fill(HIST("hMcCollCounter"), 0.5); - if (isSelectedMCCollisions[mcCollision.globalIndex()]) { // Check that the event is reconstructed and that the reconstructed events pass the selection - genQAHist.fill(HIST("hMcCollCounter"), 1.5); - } else { - if (skipRejectedEvents) { - continue; - } - } - - const auto& dparticlesMC = particlesMC.sliceBy(permcCollision, mcCollision.globalIndex()); - - for (const auto& mcparticle : dparticlesMC) { - - bool isMatter; - if (mcparticle.pdgCode() == o2::constants::physics::Pdg::kHyperHelium4Sigma) { - isMatter = true; - } else if (mcparticle.pdgCode() == -o2::constants::physics::Pdg::kHyperHelium4Sigma) { - isMatter = false; - } else { - continue; - } - - auto dChannel = getDecayChannelHe4S(mcparticle, dauIDList); - if (dChannel == kNDecayChannel) { - genQAHist.fill(HIST("hGenHyperHelium4SigmaCounter"), 10.5); - continue; - } - - // qa for mother tracks - if (dChannel == k2body) { - recoQAHist.fill(HIST("hMoth2BCounter"), 0); - } else { - if (only2BodyDecay) { - continue; // skip 3-body decays - } - } - recoQAHist.fill(HIST("hMothCounter"), 0); - - genQAHist.fill(HIST("hGenHyperHelium4SigmaCounter"), 0.5); - genQAHist.fill(HIST("hGenHyperHelium4SigmaCounter"), isMatter ? 1.5 : 2.5); - genQAHist.fill(HIST("hEvtSelectedHyperHelium4SigmaCounter"), 0.5); - if (isSelectedMCCollisions[mcCollision.globalIndex()]) { - genQAHist.fill(HIST("hEvtSelectedHyperHelium4SigmaCounter"), 1.5); - } - - float svPos[3] = {-999, -999, -999}; - std::vector> dauMom(kNDaughterType, std::vector(3, -999.0f)); - for (const auto& mcparticleDaughter : mcparticle.daughters_as()) { - for (int type = 0; type < kNDaughterType; type++) { - if (std::abs(mcparticleDaughter.pdgCode()) == kDaugghterPDG[type]) { - dauMom[type][0] = mcparticleDaughter.px(); - dauMom[type][1] = mcparticleDaughter.py(); - dauMom[type][2] = mcparticleDaughter.pz(); - - if (type <= kDaugTriton) { - svPos[0] = mcparticleDaughter.vx(); - svPos[1] = mcparticleDaughter.vy(); - svPos[2] = mcparticleDaughter.vz(); - } - - if (type < kNChargedDaughterType) { - hDaugCounter[type]->Fill(0.f); - // if daughter track is reconstructed - if (type <= kNChargedDaughterType && mcPartIndices[mcparticleDaughter.globalIndex()] != -1) { - auto track = tracks.rawIteratorAt(mcPartIndices[mcparticleDaughter.globalIndex()]); - float tpcNSigma = getTPCNSigma(track, type); - daughterTrackCheck(track, hDaugCounter[type], tpcNSigma); - if (track.hasTPC()) { - hDaugTPCNSigma[type]->Fill(track.p() * track.sign(), tpcNSigma); - } - if (type == kDaugAlpha && track.itsNCls() > kITSLayers - 2) { - recoQAHist.fill(HIST("hDaugAlphaITSNSigmaCheck"), track.p() * track.sign(), itsResponse.nSigmaITS(track)); - } - } - } - } - } - } - - genQAHist.fill(HIST("hGenHyperHelium4SigmaP"), mcparticle.p()); - genQAHist.fill(HIST("hGenHyperHelium4SigmaPt"), mcparticle.pt()); - float ct = RecoDecay::sqrtSumOfSquares(svPos[0] - mcparticle.vx(), svPos[1] - mcparticle.vy(), svPos[2] - mcparticle.vz()) * o2::constants::physics::MassHyperHelium4Sigma / mcparticle.p(); - genQAHist.fill(HIST("hGenHyperHelium4SigmaCt"), ct); - - // if mother track is reconstructed - if (mcPartIndices[mcparticle.globalIndex()] != -1) { - auto motherTrack = tracks.rawIteratorAt(mcPartIndices[mcparticle.globalIndex()]); - bool isGoodMother = motherTrackCheck(motherTrack, hMothCounter); - if (dChannel == k2body) { - motherTrackCheck(motherTrack, hMoth2BCounter); - } - float svR = RecoDecay::sqrtSumOfSquares(svPos[0], svPos[1]); - float diffpt = mcparticle.pt() - 2 * motherTrack.pt(); - float diffpz = mcparticle.pz() - 2 * motherTrack.pz(); - - recoQAHist.fill(HIST("h2TrueMotherDiffPtVsTrueSVR"), svR, diffpt); - recoQAHist.fill(HIST("h2TrueMotherDiffPzVsTrueSVR"), svR, diffpz); - recoQAHist.fill(HIST("h2TrueMotherDiffTglVsTrueSVR"), svR, mcparticle.pz() / mcparticle.pt() - motherTrack.tgl()); - recoQAHist.fill(HIST("h2TrueMotherDiffEtaVsTrueSVR"), svR, mcparticle.eta() - motherTrack.eta()); - if (isGoodMother) { - recoQAHist.fill(HIST("h2GoodMotherDiffPtVsTrueSVR"), svR, diffpt); - recoQAHist.fill(HIST("h2GoodMotherDiffPzVsTrueSVR"), svR, diffpz); - } - - // if mother track and charged daughters are all reconstructed - bool isDauReconstructed = mcPartIndices[dauIDList[0]] != -1 && (dChannel == k2body ? true : mcPartIndices[dauIDList[1]] != -1); - if (isDauReconstructed) { - genQAHist.fill(HIST("hGenHyperHelium4SigmaCounter"), 9.5); - - // qa for bc matching for reconstructed tracks - if (dChannel == k2body) { - auto daughterTrack = tracks.rawIteratorAt(mcPartIndices[dauIDList[0]]); - bool isMoth = motherTrackCheck(motherTrack, hRecoMothCounter); - bool isDaug = daughterTrackCheck(daughterTrack, hRecoDaugAlphaCounter, daughterTrack.tpcNSigmaAl()); - - recoQAHist.fill(HIST("hReco2BCandidateCount"), 0.5); - recoQAHist.fill(HIST("hRecoMothCounter"), 0.5); - recoQAHist.fill(HIST("hMothITSCls"), motherTrack.itsNCls()); - recoQAHist.fill(HIST("hRecoDaugAlphaCounter"), 0.5); - recoQAHist.fill(HIST("hMothIsPVContributer"), motherTrack.isPVContributor() ? 1.5 : 0.5); - recoQAHist.fill(HIST("hDaugAlphaIsPVContributer"), daughterTrack.isPVContributor() ? 1.5 : 0.5); - - float itsNSigma = itsResponse.nSigmaITS(daughterTrack); - if (daughterTrack.hasITS()) { - recoQAHist.fill(HIST("hDaugAlphaITSNSigma"), daughterTrack.sign() * daughterTrack.p(), itsNSigma); - recoQAHist.fill(HIST("hDaugAlphaITSCls"), daughterTrack.itsNCls()); - } - - if (motherTrack.has_collision() && daughterTrack.has_collision()) { - recoQAHist.fill(HIST("hReco2BCandidateCount"), 1.5); - if (motherTrack.collisionId() == daughterTrack.collisionId()) { - recoQAHist.fill(HIST("hReco2BCandidateCount"), 2.5); - } - } - - if (isMoth && isDaug) { - recoQAHist.fill(HIST("hReco2BCandidateCount"), 3.5); - recoQAHist.fill(HIST("hReco2BDauAlphaPVsITSNSigma"), daughterTrack.sign() * daughterTrack.p(), itsNSigma); - } - } - } - } - - // qa for branching ratios and invariant mass - if (dChannel == k2body) { - genQAHist.fill(HIST("hGenHyperHelium4SigmaCounter"), isMatter ? 3.5 : 4.5); - float hyperHelium4SigmaMCMass = RecoDecay::m(std::array{std::array{dauMom[kDaugAlpha][0], dauMom[kDaugAlpha][1], dauMom[kDaugAlpha][2]}, std::array{dauMom[kDaugPion0][0], dauMom[kDaugPion0][1], dauMom[kDaugPion0][2]}}, std::array{o2::constants::physics::MassAlpha, o2::constants::physics::MassPi0}); - genQAHist.fill(HIST("hMcRecoInvMass"), hyperHelium4SigmaMCMass); - } else if (dChannel == k3body_p) { - genQAHist.fill(HIST("hGenHyperHelium4SigmaCounter"), isMatter ? 5.5 : 6.5); - float hyperHelium4SigmaMCMass = RecoDecay::m(std::array{std::array{dauMom[kDaugTriton][0], dauMom[kDaugTriton][1], dauMom[kDaugTriton][2]}, std::array{dauMom[kDaugProton][0], dauMom[kDaugProton][1], dauMom[kDaugProton][2]}, std::array{dauMom[kDaugPion0][0], dauMom[kDaugPion0][1], dauMom[kDaugPion0][2]}}, std::array{o2::constants::physics::MassTriton, o2::constants::physics::MassProton, o2::constants::physics::MassPi0}); - genQAHist.fill(HIST("hMcRecoInvMass"), hyperHelium4SigmaMCMass); - } else if (dChannel == k3body_n) { - genQAHist.fill(HIST("hGenHyperHelium4SigmaCounter"), isMatter ? 7.5 : 8.5); - float hyperHelium4SigmaMCMass = RecoDecay::m(std::array{std::array{dauMom[kDaugTriton][0], dauMom[kDaugTriton][1], dauMom[kDaugTriton][2]}, std::array{dauMom[kDaugNeutron][0], dauMom[kDaugNeutron][1], dauMom[kDaugNeutron][2]}, std::array{dauMom[kDaugChargedPion][0], dauMom[kDaugChargedPion][1], dauMom[kDaugChargedPion][2]}}, std::array{o2::constants::physics::MassTriton, o2::constants::physics::MassNeutron, o2::constants::physics::MassPiPlus}); - genQAHist.fill(HIST("hMcRecoInvMass"), hyperHelium4SigmaMCMass); - } - } - } - } - PROCESS_SWITCH(Hyperhelium4sigmaQa, processMC, "do QA for MC prodcutions", false); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - }; -} diff --git a/PWGLF/TableProducer/Nuspex/hyperkinkRecoTask.cxx b/PWGLF/TableProducer/Nuspex/hyperkinkRecoTask.cxx new file mode 100644 index 00000000000..4c7ac865c18 --- /dev/null +++ b/PWGLF/TableProducer/Nuspex/hyperkinkRecoTask.cxx @@ -0,0 +1,1366 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +/// \file hyperkinkRecoTask.cxx +/// \brief QA and analysis task for kink decay of hypernuclei +/// \author Yuanzhe Wang + +#include "PWGLF/DataModel/LFHyperNucleiKinkTables.h" +#include "PWGLF/DataModel/LFKinkDecayTables.h" +#include "PWGLF/DataModel/LFPIDTOFGenericTables.h" +#include "PWGLF/Utils/pidTOFGeneric.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/PIDResponseITS.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CommonConstants/PhysicsConstants.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +o2::common::core::MetadataHelper metadataInfo; + +using CollisionsFull = soa::Join; +using MCLabeledCollisionsFull = soa::Join; +using FullTracksExtIU = soa::Join; +using MCLabeledTracksIU = soa::Join; + +enum PartType { + kHypertriton = 0, + kHyperhelium4sigma +}; + +enum DaughterType { + kDaugCharged = 0, + kDaugNeutral, + kNDaughterType +}; + +namespace +{ +constexpr std::array LayerRadii{2.33959f, 3.14076f, 3.91924f, 19.6213f, 24.5597f, 34.388f, 39.3329f}; +constexpr int kITSLayers = 7; +constexpr int kITSInnerBarrelLayers = 3; +// constexpr int kITSOuterBarrelLayers = 4; + +const std::array covPosSV{6.4462712107237135f, 0.1309793068144521f, 6.626654155592929f, -0.4510297694023185f, 0.16996629627762413f, 4.109195981415627f}; + +std::shared_ptr hMothCounter; +std::shared_ptr hDaugCounter; +std::shared_ptr hDaugTPCNSigma; +std::shared_ptr hRecoMothCounter; +std::shared_ptr hRecoDaugCounter; +} // namespace + +//-------------------------------------------------------------- +struct H3LDecay { + enum Channel { + k2bodyNeutral = 0, // triton, pion0 + k2bodyCharged, + k3bodyCharged, + kNChannel + }; + + template + static Channel getDecayChannel(TMCParticle const& particle, std::vector& list) + { + if (std::abs(particle.pdgCode()) != o2::constants::physics::Pdg::kHyperTriton) { + return kNChannel; + } + + list.clear(); + list.resize(2, -1); + + bool haveHelium3 = false, haveAntiHelium3 = false, haveDeuteron = false, haveAntiDeuteron = false; + bool haveProton = false, haveAntiProton = false, havePionPlus = false, havePionMinus = false; + bool haveTriton = false, haveAntiTriton = false, havePion0 = false; + for (const auto& mcDaughter : particle.template daughters_as()) { + if (mcDaughter.pdgCode() == o2::constants::physics::Pdg::kTriton) { + haveTriton = true; + list[0] = mcDaughter.globalIndex(); + } + if (mcDaughter.pdgCode() == -o2::constants::physics::Pdg::kTriton) { + haveAntiTriton = true; + list[0] = mcDaughter.globalIndex(); + } + if (mcDaughter.pdgCode() == PDG_t::kPi0) { + havePion0 = true; + list[1] = mcDaughter.globalIndex(); + } + if (mcDaughter.pdgCode() == o2::constants::physics::Pdg::kHelium3) { + haveHelium3 = true; + } + if (mcDaughter.pdgCode() == -o2::constants::physics::Pdg::kHelium3) { + haveAntiHelium3 = true; + } + if (mcDaughter.pdgCode() == o2::constants::physics::Pdg::kDeuteron) { + haveDeuteron = true; + } + if (mcDaughter.pdgCode() == -o2::constants::physics::Pdg::kDeuteron) { + haveAntiDeuteron = true; + } + if (mcDaughter.pdgCode() == PDG_t::kProton) { + haveProton = true; + } + if (mcDaughter.pdgCode() == -PDG_t::kProton) { + haveAntiProton = true; + } + if (mcDaughter.pdgCode() == PDG_t::kPiPlus) { + havePionPlus = true; + } + if (mcDaughter.pdgCode() == -PDG_t::kPiPlus) { + havePionMinus = true; + } + } + + if ((haveTriton && havePion0) || (haveAntiTriton && havePion0)) { + return H3LDecay::k2bodyNeutral; + } else if ((haveHelium3 && havePionMinus) || (haveAntiHelium3 && havePionPlus)) { + return H3LDecay::k2bodyCharged; + } else if ((haveDeuteron && haveProton && havePionMinus) || (haveAntiDeuteron && haveAntiProton && havePionPlus)) { + return H3LDecay::k3bodyCharged; + } else { + return kNChannel; + } + } +}; + +//-------------------------------------------------------------- +// Check the decay channel of hyperhelium4sigma +struct He4SDecay { + enum Channel { + k2body = 0, // helium4, pion0 + k3body_p, // triton, proton, pion0 + k3body_n, // triton, neutron, pion+ + kNChannel + }; + + template + static Channel getDecayChannel(TMCParticle const& particle, std::vector& list) + { + if (std::abs(particle.pdgCode()) != o2::constants::physics::Pdg::kHyperHelium4Sigma) { + return kNChannel; + } + + list.clear(); + list.resize(2, -1); + + bool haveAlpha = false, haveTriton = false, haveProton = false, haveNeuteron = false; + bool haveAntiAlpha = false, haveAntiTriton = false, haveAntiProton = false, haveAntiNeuteron = false; + bool havePionPlus = false, havePionMinus = false, havePion0 = false; + for (const auto& mcDaughter : particle.template daughters_as()) { + if (mcDaughter.pdgCode() == o2::constants::physics::Pdg::kAlpha) { + haveAlpha = true; + list[0] = mcDaughter.globalIndex(); + } + if (mcDaughter.pdgCode() == -o2::constants::physics::Pdg::kAlpha) { + haveAntiAlpha = true; + list[0] = mcDaughter.globalIndex(); + } + if (mcDaughter.pdgCode() == o2::constants::physics::Pdg::kTriton) { + haveTriton = true; + } + if (mcDaughter.pdgCode() == -o2::constants::physics::Pdg::kTriton) { + haveAntiTriton = true; + } + if (mcDaughter.pdgCode() == PDG_t::kProton) { + haveProton = true; + } + if (mcDaughter.pdgCode() == -PDG_t::kProton) { + haveAntiProton = true; + } + if (mcDaughter.pdgCode() == PDG_t::kNeutron) { + haveNeuteron = true; + } + if (mcDaughter.pdgCode() == -PDG_t::kNeutron) { + haveAntiNeuteron = true; + } + if (mcDaughter.pdgCode() == PDG_t::kPiPlus) { + havePionPlus = true; + } + if (mcDaughter.pdgCode() == -PDG_t::kPiPlus) { + havePionMinus = true; + } + if (mcDaughter.pdgCode() == PDG_t::kPi0) { + havePion0 = true; + list[1] = mcDaughter.globalIndex(); + } + } + + if ((haveAlpha && havePion0) || (haveAntiAlpha && havePion0)) { + return He4SDecay::k2body; + } else if ((haveTriton && haveProton && havePion0) || (haveAntiTriton && haveAntiProton && havePion0)) { + return He4SDecay::k3body_p; + } else if ((haveTriton && haveNeuteron && havePionPlus) || (haveAntiTriton && haveAntiNeuteron && havePionMinus)) { + return He4SDecay::k3body_n; + } + + return kNChannel; + } +}; + +//-------------------------------------------------------------- +// Extract track parameters from a mcparticle, use global coordinates as the local one +template +o2::track::TrackParametrization getTrackParFromMC(const T& mcparticle, int charge = 1) +{ + int sign = mcparticle.pdgCode() > 0 ? 1 : -1; // ok for hypernuclei + TrackPrecision snp = mcparticle.py() / (mcparticle.pt() + 1.e-10f); + TrackPrecision tgl = mcparticle.pz() / (mcparticle.pt() + 1.e-10f); + std::array arraypar = {mcparticle.vy(), mcparticle.vz(), snp, + tgl, charge * sign / (mcparticle.pt() + 1.e-10f)}; + return o2::track::TrackParametrization(mcparticle.vx(), 0, std::move(arraypar)); +} + +//-------------------------------------------------------------- +// construct index array from mcParticle to track +template +void setTrackIDForMC(std::vector& mcPartIndices, aod::McParticles const& particlesMC, TTrackTable const& tracks) +{ + mcPartIndices.clear(); + mcPartIndices.resize(particlesMC.size()); + std::fill(mcPartIndices.begin(), mcPartIndices.end(), -1); + for (const auto& track : tracks) { + if (track.has_mcParticle()) { + auto mcparticle = track.template mcParticle_as(); + if (mcPartIndices[mcparticle.globalIndex()] == -1) { + mcPartIndices[mcparticle.globalIndex()] = track.globalIndex(); + } else { + auto candTrack = tracks.rawIteratorAt(mcPartIndices[mcparticle.globalIndex()]); + // Use the track which has innest information (also best quality? + if (track.x() < candTrack.x()) { + mcPartIndices[mcparticle.globalIndex()] = track.globalIndex(); + } + } + } + } +} + +//-------------------------------------------------------------- +// get ITSNSigma for daughter track +template +float getITSNSigma(const TTrack& track, o2::aod::ITSResponse& itsResponse, o2::track::PID partType) +{ + float nSigma = -999.f; + switch (partType) { + case o2::track::PID::Alpha: + nSigma = itsResponse.nSigmaITS(track); + break; + case o2::track::PID::Triton: + nSigma = itsResponse.nSigmaITS(track); + break; + default: + break; + } + return nSigma; +} + +//-------------------------------------------------------------- +// get default TOFNSigma for daughter track +template +float getDefaultTOFNSigma(const TTrack& track, o2::track::PID partType) +{ + float nSigma = -999.f; + switch (partType) { + case o2::track::PID::Alpha: + nSigma = track.tofNSigmaAl(); + break; + case o2::track::PID::Triton: + nSigma = track.tofNSigmaTr(); + break; + default: + break; + } + return nSigma; +} + +//-------------------------------------------------------------- +// get TPCNSigma for daughter track +template +float getTPCNSigma(const TTrack& track, o2::track::PID partType) +{ + float nSigma = -999.f; + switch (partType) { + case o2::track::PID::Alpha: + nSigma = track.tpcNSigmaAl(); + break; + case o2::track::PID::Triton: + nSigma = track.tpcNSigmaTr(); + break; + default: + break; + } + return nSigma; +} + +//-------------------------------------------------------------- +// Refit the momentum of the mother track +template +bool refitMotherTrack(const TTrack& track, o2::track::TrackParametrizationWithError& trackPar, const o2::dataformats::VertexBase& primaryVtx, const o2::dataformats::VertexBase& secondaryVtx) +{ + float trackIUPos[2] = {track.y(), track.z()}; + float trackIUCov[3] = {track.cYY(), track.cZY(), track.cZZ()}; + + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVtx, trackPar, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrLUT); + + trackPar.resetCovariance(1e15); + if (!trackPar.update(primaryVtx)) { + return false; + } + + trackPar.rotate(track.alpha()); + o2::base::Propagator::Instance()->PropagateToXBxByBz(trackPar, track.x()); + if (!trackPar.update(trackIUPos, trackIUCov)) { + return false; + } + + o2::base::Propagator::Instance()->propagateToDCABxByBz(secondaryVtx, trackPar, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrLUT); + if (!trackPar.update(secondaryVtx)) { + return false; + } + + return true; +} + +//-------------------------------------------------------------- +struct HypKinkCandidate { + + bool isMatter = false; + + std::array posPV = {0.0f, 0.0f, 0.0f}; + std::array posSV = {0.0f, 0.0f, 0.0f}; + std::array lastPosMoth = {0.0f, 0.0f, 0.0f}; // last position of mother track at the radii of ITS layer which has the outermost update + std::array momMothSV = {0.0f, 0.0f, 0.0f}; + std::array momDaugSV = {0.0f, 0.0f, 0.0f}; + + float dcaXYMothPv = -999.f; + float dcaXYDaugPv = -999.f; + float dcaKinkTopo = -999.f; + + float chi2ITSMoth = 0.0f; + uint32_t itsClusterSizeMoth = 0u; + uint32_t itsClusterSizeDaug = 0u; + float nSigmaTPCDaug = -999.f; + float nSigmaITSDaug = -999.f; + float nSigmaTOFDaug = -999.f; // recalculated TOF NSigma + + // mc information + bool isSignal = false; + bool isSignalReco = false; + bool isCollReco = false; + bool isSurvEvSelection = false; + + std::array truePosSV = {0.0f, 0.0f, 0.0f}; + std::array trueMomMothPV = {0.0f, 0.0f, 0.0f}; // generated mother momentum at primary vertex + std::array trueMomMothSV = {0.0f, 0.0f, 0.0f}; // true mother momentum at decay vertex + std::array trueMomDaugSV = {0.0f, 0.0f, 0.0f}; // true daughter momentum at decay vertex + + bool isMothReco = false; + std::array momMothPV = {0.0f, 0.0f, 0.0f}; + std::array updateMomMothPV = {0.0f, 0.0f, 0.0f}; // mother momentum at primary vertex after update using PV +}; + +//-------------------------------------------------------------- +// analysis task for 2-body kink decay +struct HyperkinkRecoTask { + + Produces outputDataTable; + Produces outputMCTable; + + Service ccdb; + o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrLUT; + + std::vector mcPartIndices; + + // Histograms are defined with HistogramRegistry + HistogramRegistry registry{"registry", {}}; + + Configurable hypoMoth{"hypoMoth", kHypertriton, "Mother particle hypothesis"}; + // Configurable for event selection + Configurable doEventCut{"doEventCut", true, "Apply event selection"}; + Configurable maxZVertex{"maxZVertex", 10.0f, "Accepted z-vertex range (cm)"}; + Configurable cutTPCNSigmaDaug{"cutTPCNSigmaDaug", 5, "TPC NSigma cut for daughter tracks"}; + Configurable cutTOFNSigmaDaug{"cutTOFNSigmaDaug", 1000, "TOF NSigma cut for daughter tracks"}; + Configurable askTOFForDaug{"askTOFForDaug", false, "If true, ask for TOF signal"}; + + // CCDB options + Configurable inputBz{"inputBz", -999, "bz field, -999 is automatic"}; + Configurable ccdbPath{"ccdbPath", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; + + int mRunNumber; + float mBz; + o2::base::MatLayerCylSet* lut = nullptr; + + o2::aod::ITSResponse itsResponse; + + float massChargedDaug = 999.f; + float massNeutralDaug = 999.f; + int pdgMoth = 0; + std::array pdgDaug = {o2::constants::physics::Pdg::kTriton, PDG_t::kPi0}; // pdgcode of charged (0) and neutral (1) daughter particles + o2::track::PID pidTypeDaug = o2::track::PID::Triton; + + // secondary TOF PID + o2::aod::pidtofgeneric::TofPidNewCollision secondaryTOFPID; // to be updated in Init based on the hypothesis + o2::aod::pidtofgeneric::TofPidNewCollision secondaryTOFPIDLabeled; // to be updated in Init based on the hypothesis + // TOF response and input parameters + o2::pid::tof::TOFResoParamsV3 mRespParamsV3; + o2::aod::pidtofgeneric::TOFCalibConfig mTOFCalibConfig; // TOF Calib configuration + + void init(InitContext& initContext) + { + if (hypoMoth == kHypertriton) { + massChargedDaug = o2::constants::physics::MassTriton; + massNeutralDaug = o2::constants::physics::MassPi0; + pdgMoth = o2::constants::physics::Pdg::kHyperTriton; + pdgDaug[kDaugCharged] = o2::constants::physics::Pdg::kTriton; + pdgDaug[kDaugNeutral] = PDG_t::kPi0; + pidTypeDaug = o2::track::PID::Triton; + } else if (hypoMoth == kHyperhelium4sigma) { + massChargedDaug = o2::constants::physics::MassAlpha; + massNeutralDaug = o2::constants::physics::MassPi0; + pdgMoth = o2::constants::physics::Pdg::kHyperHelium4Sigma; + pdgDaug[kDaugCharged] = o2::constants::physics::Pdg::kAlpha; + pdgDaug[kDaugNeutral] = PDG_t::kPi0; + pidTypeDaug = o2::track::PID::Alpha; + } else { + LOG(fatal) << "Unknown mother particle hypothesis"; + } + + // Axes + const AxisSpec vertexZAxis{100, -15., 15., "vtx_{Z} [cm]"}; + const AxisSpec ptAxis{50, -10, 10, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec nSigmaAxis{120, -6.f, 6.f, "n#sigma"}; + AxisSpec massAxis(100, 2.94, 3.2, "m (GeV/#it{c}^{2})"); + if (hypoMoth == kHyperhelium4sigma) { + massAxis = AxisSpec{100, 3.85, 4.25, "m (GeV/#it{c}^{2})"}; + } + const AxisSpec diffPtAxis{200, -10.f, 10.f, "#Delta #it{p}_{T} (GeV/#it{c})"}; + const AxisSpec diffPzAxis{200, -10.f, 10.f, "#Delta #it{p}_{z} (GeV/#it{c})"}; + const AxisSpec radiusAxis{40, 0.f, 40.f, "R (cm)"}; + + registry.add("hEventCounter", "hEventCounter", HistType::kTH1F, {{2, 0, 2}}); + registry.add("hVertexZCollision", "hVertexZCollision", HistType::kTH1F, {vertexZAxis}); + registry.add("hCandidateCounter", "hCandidateCounter", HistType::kTH1F, {{4, 0, 4}}); + + if (doprocessMC == true) { + itsResponse.setMCDefaultParameters(); + + registry.add("hTrueCandidateCounter", "hTrueCandidateCounter", HistType::kTH1F, {{4, 0, 4}}); + registry.add("hDiffSVx", ";#Delta x (cm);", HistType::kTH1F, {{200, -10, 10}}); + registry.add("hDiffSVy", ";#Delta y (cm);", HistType::kTH1F, {{200, -10, 10}}); + registry.add("hDiffSVz", ";#Delta z (cm);", HistType::kTH1F, {{200, -10, 10}}); + registry.add("h2RecSVRVsTrueSVR", ";Reconstruced SV R (cm);True SV R (cm);", HistType::kTH2F, {radiusAxis, radiusAxis}); + registry.add("h2TrueMotherDiffPtVsRecSVR", ";Reconstruced SV R (cm);#Delta #it{p}_{T} (GeV/#it{c});", HistType::kTH2F, {radiusAxis, diffPtAxis}); + registry.add("h2TrueMotherDiffEtaVsRecSVR", ";Reconstruced SV R (cm);#Delta #eta;", HistType::kTH2F, {radiusAxis, {200, -0.1, 0.1}}); + registry.add("hDiffDauPx", ";#Delta p_{x} (GeV/#it{c}); ", HistType::kTH1D, {{200, -10, 10}}); + registry.add("hDiffDauPy", ";#Delta p_{y} (GeV/#it{c}); ", HistType::kTH1D, {{200, -10, 10}}); + registry.add("hDiffDauPz", ";#Delta p_{z} (GeV/#it{c}); ", HistType::kTH1D, {{200, -10, 10}}); + registry.add("h2TrueSignalMassPt", "h2TrueSignalMassPt", HistType::kTH2F, {{ptAxis, massAxis}}); + registry.add("h2TrueDaugTPCNSigmaPt", "h2TrueDaugTPCNSigmaPt", HistType::kTH2F, {{ptAxis, nSigmaAxis}}); + + registry.add("hDCAXYMothToRecSV", "hDCAXYMothToRecSV", HistType::kTH1F, {{200, -10, 10}}); + registry.add("hDCAZMothToRecSV", "hDCAZMothToRecSV", HistType::kTH1F, {{200, -10, 10}}); + + registry.add("hDaugOldTOFNSigma_CorrectCol", "hDaugOldTOFNSigma_CorrectCol", HistType::kTH1F, {{600, -300, 300}}); + registry.add("hDaugOldTOFNSigma_WrongCol", "hDaugOldTOFNSigma_WrongCol", HistType::kTH1F, {{600, -300, 300}}); + registry.add("hDaugNewTOFNSigma_CorrectCol", "hDaugNewTOFNSigma_CorrectCol", HistType::kTH1F, {{600, -300, 300}}); + registry.add("hDaugNewTOFNSigma_WrongCol", "hDaugNewTOFNSigma_WrongCol", HistType::kTH1F, {{600, -300, 300}}); + } + + registry.add("h2MothMassPt", "h2MothMassPt", HistType::kTH2F, {{ptAxis, massAxis}}); + registry.add("h2DaugTPCNSigmaPt", "h2DaugTPCNSigmaPt", HistType::kTH2F, {{ptAxis, nSigmaAxis}}); + + ccdb->setURL(ccdbPath); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(false); + + mTOFCalibConfig.metadataInfo = metadataInfo; + mTOFCalibConfig.inheritFromBaseTask(initContext); + mTOFCalibConfig.initSetup(mRespParamsV3, ccdb); + secondaryTOFPID.SetPidType(pidTypeDaug); + secondaryTOFPIDLabeled.SetPidType(pidTypeDaug); + } + + void initCCDB(aod::BCsWithTimestamps::iterator const& bc) + { + if (mRunNumber == bc.runNumber()) { + return; + } + mRunNumber = bc.runNumber(); + ccdb->clearCache(grpmagPath.value.data()); + LOG(info) << "Initializing CCDB for run " << mRunNumber; + o2::parameters::GRPMagField* grpmag = ccdb->getForRun(grpmagPath, mRunNumber); + o2::base::Propagator::initFieldFromGRP(grpmag); + mBz = grpmag->getNominalL3Field(); + + if (!lut) { + lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(lutPath)); + } + o2::base::Propagator::Instance()->setMatLUT(lut); + LOG(info) << "Task initialized for run " << mRunNumber << " with magnetic field " << mBz << " kZG"; + + mTOFCalibConfig.processSetup(mRespParamsV3, ccdb, bc); + } + + // ______________________________________________________________ + // get recalulate TOFNSigma for daughter track + template + double getTOFNSigma(o2::pid::tof::TOFResoParamsV3 const& parameters, TTrack const& track, TCollision const& collision, TCollision const& originalcol) + { + // TOF PID of deuteron + if (track.has_collision() && track.hasTOF()) { + if constexpr (isMC) { + return secondaryTOFPIDLabeled.GetTOFNSigma(parameters, track, originalcol, collision); + } else { + return secondaryTOFPID.GetTOFNSigma(parameters, track, originalcol, collision); + } + } + return -999; + } + + template + void fillCandidate(HypKinkCandidate& hypkinkCand, TCollision const& collision, TKindCandidate const& kinkCand, TTrack const& trackMoth, TTrack const& trackDaug) + { + hypkinkCand.isMatter = kinkCand.mothSign() > 0; + hypkinkCand.posPV[0] = collision.posX(); + hypkinkCand.posPV[1] = collision.posY(); + hypkinkCand.posPV[2] = collision.posZ(); + hypkinkCand.posSV[0] = kinkCand.xDecVtx() + collision.posX(); + hypkinkCand.posSV[1] = kinkCand.yDecVtx() + collision.posY(); + hypkinkCand.posSV[2] = kinkCand.zDecVtx() + collision.posZ(); + + hypkinkCand.momMothSV[0] = kinkCand.pxMoth(); + hypkinkCand.momMothSV[1] = kinkCand.pyMoth(); + hypkinkCand.momMothSV[2] = kinkCand.pzMoth(); + hypkinkCand.momDaugSV[0] = kinkCand.pxDaug(); + hypkinkCand.momDaugSV[1] = kinkCand.pyDaug(); + hypkinkCand.momDaugSV[2] = kinkCand.pzDaug(); + + hypkinkCand.dcaXYMothPv = kinkCand.dcaMothPv(); + hypkinkCand.dcaXYDaugPv = kinkCand.dcaDaugPv(); + hypkinkCand.dcaKinkTopo = kinkCand.dcaKinkTopo(); + + fillCandidateRecoMoth(hypkinkCand, collision, trackMoth); + + hypkinkCand.itsClusterSizeDaug = trackDaug.itsClusterSizes(); + hypkinkCand.nSigmaTPCDaug = getTPCNSigma(trackDaug, pidTypeDaug); + hypkinkCand.nSigmaITSDaug = getITSNSigma(trackDaug, itsResponse, pidTypeDaug); + + int lastLayerMoth = 0; + for (int i = 6; i >= 0; i--) { + if (trackMoth.itsClusterMap() & (1 << i)) { + lastLayerMoth = i; + break; + } + } + auto trackparMother = getTrackParCov(trackMoth); + o2::base::Propagator::Instance()->PropagateToXBxByBz(trackparMother, LayerRadii[lastLayerMoth]); + std::array posLastHit{-999.f}; + trackparMother.getXYZGlo(posLastHit); + hypkinkCand.lastPosMoth[0] = posLastHit[0]; + hypkinkCand.lastPosMoth[1] = posLastHit[1]; + hypkinkCand.lastPosMoth[2] = posLastHit[2]; + } + + template + void fillCandidateRecoMoth(HypKinkCandidate& hypkinkCand, TCollision const& collision, TTrack const& trackMoth) + { + hypkinkCand.isMothReco = true; + hypkinkCand.chi2ITSMoth = trackMoth.itsChi2NCl(); + hypkinkCand.itsClusterSizeMoth = trackMoth.itsClusterSizes(); + + auto motherTrackPar = getTrackParCov(trackMoth); + o2::dataformats::VertexBase primaryVtx = {{collision.posX(), collision.posY(), collision.posZ()}, {collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()}}; + std::array pMotherPv = {-999.f}; + if (o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVtx, motherTrackPar, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) { + motherTrackPar.getPxPyPzGlo(pMotherPv); + } + hypkinkCand.momMothPV[0] = pMotherPv[0]; + hypkinkCand.momMothPV[1] = pMotherPv[1]; + hypkinkCand.momMothPV[2] = pMotherPv[2]; + + std::array updatePMotherPv = {-999.f}; + if (motherTrackPar.update(primaryVtx)) { + motherTrackPar.getPxPyPzGlo(updatePMotherPv); + } + hypkinkCand.updateMomMothPV[0] = updatePMotherPv[0]; + hypkinkCand.updateMomMothPV[1] = updatePMotherPv[1]; + hypkinkCand.updateMomMothPV[2] = updatePMotherPv[2]; + } + + template + void fillCandidateMCInfo(HypKinkCandidate& hypkinkCand, TMCParticle const& mcMothTrack, TMCParticle const& mcDaugTrack, TMCParticle const& mcNeutDaugTrack) + { + hypkinkCand.truePosSV[0] = mcDaugTrack.vx(); + hypkinkCand.truePosSV[1] = mcDaugTrack.vy(); + hypkinkCand.truePosSV[2] = mcDaugTrack.vz(); + hypkinkCand.trueMomMothPV[0] = mcMothTrack.px(); + hypkinkCand.trueMomMothPV[1] = mcMothTrack.py(); + hypkinkCand.trueMomMothPV[2] = mcMothTrack.pz(); + hypkinkCand.trueMomMothSV[0] = mcDaugTrack.px() + mcNeutDaugTrack.px(); + hypkinkCand.trueMomMothSV[1] = mcDaugTrack.py() + mcNeutDaugTrack.py(); + hypkinkCand.trueMomMothSV[2] = mcDaugTrack.pz() + mcNeutDaugTrack.pz(); + hypkinkCand.trueMomDaugSV[0] = mcDaugTrack.px(); + hypkinkCand.trueMomDaugSV[1] = mcDaugTrack.py(); + hypkinkCand.trueMomDaugSV[2] = mcDaugTrack.pz(); + } + + void processData(CollisionsFull const& collisions, aod::KinkCands const& KinkCands, FullTracksExtIU const&, aod::BCsWithTimestamps const&) + { + for (const auto& collision : collisions) { + registry.fill(HIST("hEventCounter"), 0); + if (doEventCut && (std::abs(collision.posZ()) > maxZVertex || !collision.sel8())) { + continue; + } + registry.fill(HIST("hEventCounter"), 1); + registry.fill(HIST("hVertexZCollision"), collision.posZ()); + } + + for (const auto& kinkCand : KinkCands) { + registry.fill(HIST("hCandidateCounter"), 0); + auto collision = kinkCand.collision_as(); + if (doEventCut && (std::abs(collision.posZ()) > maxZVertex || !collision.sel8())) { + continue; + } + registry.fill(HIST("hCandidateCounter"), 1); + + auto daugTrack = kinkCand.trackDaug_as(); + float tpcNSigmaDaug = getTPCNSigma(daugTrack, pidTypeDaug); + if (std::abs(tpcNSigmaDaug) > cutTPCNSigmaDaug) { + continue; + } + float invMass = RecoDecay::m(std::array{std::array{kinkCand.pxDaug(), kinkCand.pyDaug(), kinkCand.pzDaug()}, std::array{kinkCand.pxDaugNeut(), kinkCand.pyDaugNeut(), kinkCand.pzDaugNeut()}}, std::array{massChargedDaug, massNeutralDaug}); + registry.fill(HIST("hCandidateCounter"), 2); + registry.fill(HIST("h2MothMassPt"), kinkCand.mothSign() * kinkCand.ptMoth(), invMass); + registry.fill(HIST("h2DaugTPCNSigmaPt"), kinkCand.mothSign() * kinkCand.ptDaug(), tpcNSigmaDaug); + + auto bc = collision.bc_as(); + initCCDB(bc); + auto motherTrack = kinkCand.trackMoth_as(); + float nSigmaTOF = -999.f; + if (daugTrack.hasTOF() && daugTrack.has_collision()) { + auto originalDaugCol = daugTrack.collision_as(); + nSigmaTOF = getTOFNSigma(mRespParamsV3, daugTrack, collision, originalDaugCol); + } + if ((daugTrack.hasTOF() || askTOFForDaug) && std::abs(nSigmaTOF) > cutTOFNSigmaDaug) { + continue; + } + + registry.fill(HIST("hCandidateCounter"), 2); + HypKinkCandidate hypkinkCand; + fillCandidate(hypkinkCand, collision, kinkCand, motherTrack, daugTrack); + hypkinkCand.nSigmaTOFDaug = nSigmaTOF; + + o2::dataformats::VertexBase primaryVtx = {{collision.posX(), collision.posY(), collision.posZ()}, {collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()}}; + o2::dataformats::VertexBase secondaryVtx = {{kinkCand.xDecVtx() + collision.posX(), kinkCand.yDecVtx() + collision.posY(), kinkCand.zDecVtx() + collision.posZ()}, {covPosSV[0], covPosSV[1], covPosSV[2], covPosSV[3], covPosSV[4], covPosSV[5]}}; + std::array refitPPV = {-999.f}; + std::array refitPSV = {-999.f}; + auto motherTrackPar = getTrackParCov(motherTrack); + if (refitMotherTrack(motherTrack, motherTrackPar, primaryVtx, secondaryVtx)) { + motherTrackPar.getPxPyPzGlo(refitPSV); + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVtx, motherTrackPar, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrLUT); + motherTrackPar.getPxPyPzGlo(refitPPV); + } + + outputDataTable( + mBz > 0 ? 1 : -1, + hypkinkCand.posPV[0], hypkinkCand.posPV[1], hypkinkCand.posPV[2], + hypkinkCand.posSV[0], hypkinkCand.posSV[1], hypkinkCand.posSV[2], + hypkinkCand.isMatter, + hypkinkCand.lastPosMoth[0], hypkinkCand.lastPosMoth[1], hypkinkCand.lastPosMoth[2], + hypkinkCand.momMothSV[0], hypkinkCand.momMothSV[1], hypkinkCand.momMothSV[2], + refitPPV[0], refitPPV[1], refitPPV[2], + refitPSV[0], refitPSV[1], refitPSV[2], + hypkinkCand.momDaugSV[0], hypkinkCand.momDaugSV[1], hypkinkCand.momDaugSV[2], + hypkinkCand.dcaXYMothPv, hypkinkCand.dcaXYDaugPv, hypkinkCand.dcaKinkTopo, + hypkinkCand.chi2ITSMoth, hypkinkCand.itsClusterSizeMoth, hypkinkCand.itsClusterSizeDaug, + hypkinkCand.nSigmaTPCDaug, hypkinkCand.nSigmaITSDaug, hypkinkCand.nSigmaTOFDaug, + hypkinkCand.momMothPV[0], hypkinkCand.momMothPV[1], hypkinkCand.momMothPV[2], + hypkinkCand.updateMomMothPV[0], hypkinkCand.updateMomMothPV[1], hypkinkCand.updateMomMothPV[2]); + } + } + PROCESS_SWITCH(HyperkinkRecoTask, processData, "process data", true); + + void processMC(MCLabeledCollisionsFull const& collisions, aod::KinkCands const& KinkCands, MCLabeledTracksIU const& tracks, aod::McParticles const& particlesMC, aod::McCollisions const& mcCollisions, aod::BCsWithTimestamps const&) + { + mcPartIndices.clear(); + std::vector mcPartIndices; + setTrackIDForMC(mcPartIndices, particlesMC, tracks); + std::vector isReconstructedMCCollisions(mcCollisions.size(), false); + std::vector isSelectedMCCollisions(mcCollisions.size(), false); + std::vector isGoodCollisions(collisions.size(), false); + std::vector dauIDList(2, -1); + + for (const auto& collision : collisions) { + isReconstructedMCCollisions[collision.mcCollisionId()] = true; + registry.fill(HIST("hEventCounter"), 0); + if (doEventCut && (!collision.selection_bit(aod::evsel::kIsTriggerTVX) || !collision.selection_bit(aod::evsel::kNoTimeFrameBorder) || std::abs(collision.posZ()) > maxZVertex)) { + continue; + } + registry.fill(HIST("hEventCounter"), 1); + registry.fill(HIST("hVertexZCollision"), collision.posZ()); + isSelectedMCCollisions[collision.mcCollisionId()] = true; + isGoodCollisions[collision.globalIndex()] = true; + } + + for (const auto& kinkCand : KinkCands) { + auto motherTrack = kinkCand.trackMoth_as(); + auto daugTrack = kinkCand.trackDaug_as(); + + bool isKinkSignal = false; + if (motherTrack.has_mcParticle() && daugTrack.has_mcParticle()) { + auto mcMothTrack = motherTrack.mcParticle_as(); + auto mcDaugTrack = daugTrack.mcParticle_as(); + if (hypoMoth == kHypertriton) { + auto dChannel = H3LDecay::getDecayChannel(mcMothTrack, dauIDList); + if (dChannel == H3LDecay::k2bodyNeutral && dauIDList[0] == mcDaugTrack.globalIndex()) { + isKinkSignal = true; + } + } else if (hypoMoth == kHyperhelium4sigma) { + auto dChannel = He4SDecay::getDecayChannel(mcMothTrack, dauIDList); + if (dChannel == He4SDecay::k2body && dauIDList[0] == mcDaugTrack.globalIndex()) { + isKinkSignal = true; + } + } + } + + registry.fill(HIST("hCandidateCounter"), 0); + if (isKinkSignal) { + registry.fill(HIST("hTrueCandidateCounter"), 0); + } + auto collision = kinkCand.collision_as(); + if (!isGoodCollisions[collision.globalIndex()]) { + continue; + } + registry.fill(HIST("hCandidateCounter"), 1); + if (isKinkSignal) { + registry.fill(HIST("hTrueCandidateCounter"), 1); + } + + float tpcNSigmaDaug = getTPCNSigma(daugTrack, pidTypeDaug); + if (std::abs(tpcNSigmaDaug) > cutTPCNSigmaDaug) { + continue; + } + float invMass = RecoDecay::m(std::array{std::array{kinkCand.pxDaug(), kinkCand.pyDaug(), kinkCand.pzDaug()}, std::array{kinkCand.pxDaugNeut(), kinkCand.pyDaugNeut(), kinkCand.pzDaugNeut()}}, std::array{massChargedDaug, massNeutralDaug}); + registry.fill(HIST("hCandidateCounter"), 2); + if (isKinkSignal) { + registry.fill(HIST("hTrueCandidateCounter"), 2); + } + registry.fill(HIST("h2MothMassPt"), kinkCand.mothSign() * kinkCand.ptMoth(), invMass); + registry.fill(HIST("h2DaugTPCNSigmaPt"), kinkCand.mothSign() * kinkCand.ptDaug(), tpcNSigmaDaug); + + auto bc = collision.bc_as(); + initCCDB(bc); + float nSigmaTOF = -999.f; + if (daugTrack.hasTOF() && daugTrack.has_collision()) { + auto originalDaugCol = daugTrack.collision_as(); + float defaultNSigmaTOF = getDefaultTOFNSigma(daugTrack, pidTypeDaug); + nSigmaTOF = getTOFNSigma(mRespParamsV3, daugTrack, collision, originalDaugCol); + if (originalDaugCol.globalIndex() == collision.globalIndex()) { + registry.fill(HIST("hDaugOldTOFNSigma_CorrectCol"), defaultNSigmaTOF); + registry.fill(HIST("hDaugNewTOFNSigma_CorrectCol"), nSigmaTOF); + } else { + registry.fill(HIST("hDaugOldTOFNSigma_WrongCol"), defaultNSigmaTOF); + registry.fill(HIST("hDaugNewTOFNSigma_WrongCol"), nSigmaTOF); + } + } + if ((daugTrack.hasTOF() || askTOFForDaug) && std::abs(nSigmaTOF) > cutTOFNSigmaDaug) { + continue; + } + registry.fill(HIST("hCandidateCounter"), 3); + if (isKinkSignal) { + registry.fill(HIST("hTrueCandidateCounter"), 3); + } + + HypKinkCandidate hypkinkCand; + fillCandidate(hypkinkCand, collision, kinkCand, motherTrack, daugTrack); + hypkinkCand.nSigmaTOFDaug = nSigmaTOF; + + std::array posDecVtx = {kinkCand.xDecVtx() + collision.posX(), kinkCand.yDecVtx() + collision.posY(), kinkCand.zDecVtx() + collision.posZ()}; + + o2::dataformats::VertexBase primaryVtx = {{collision.posX(), collision.posY(), collision.posZ()}, {collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()}}; + o2::dataformats::VertexBase secondaryVtx = {{posDecVtx[0], posDecVtx[1], posDecVtx[2]}, {covPosSV[0], covPosSV[1], covPosSV[2], covPosSV[3], covPosSV[4], covPosSV[5]}}; + std::array refitPPV = {-999.f}; + std::array refitPSV = {-999.f}; + auto motherTrackPar = getTrackParCov(motherTrack); + if (refitMotherTrack(motherTrack, motherTrackPar, primaryVtx, secondaryVtx)) { + motherTrackPar.getPxPyPzGlo(refitPSV); + o2::base::Propagator::Instance()->propagateToDCABxByBz(primaryVtx, motherTrackPar, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrLUT); + motherTrackPar.getPxPyPzGlo(refitPPV); + } + + // QA, store mcInfo for true signals + if (isKinkSignal) { + auto mcMothTrack = motherTrack.mcParticle_as(); + auto mcDaugTrack = daugTrack.mcParticle_as(); + auto mcNeutTrack = particlesMC.rawIteratorAt(dauIDList[1]); + float recSVR = std::sqrt(posDecVtx[0] * posDecVtx[0] + posDecVtx[1] * posDecVtx[1]); + registry.fill(HIST("hDiffSVx"), posDecVtx[0] - mcDaugTrack.vx()); + registry.fill(HIST("hDiffSVy"), posDecVtx[1] - mcDaugTrack.vy()); + registry.fill(HIST("hDiffSVz"), posDecVtx[2] - mcDaugTrack.vz()); + registry.fill(HIST("h2RecSVRVsTrueSVR"), recSVR, std::hypot(mcDaugTrack.vx(), mcDaugTrack.vy())); + registry.fill(HIST("h2TrueMotherDiffPtVsRecSVR"), recSVR, mcMothTrack.pt() - kinkCand.ptMoth()); + registry.fill(HIST("h2TrueMotherDiffEtaVsRecSVR"), recSVR, mcMothTrack.eta() - motherTrack.eta()); + registry.fill(HIST("hDiffDauPx"), kinkCand.pxDaug() - mcDaugTrack.px()); + registry.fill(HIST("hDiffDauPy"), kinkCand.pyDaug() - mcDaugTrack.py()); + registry.fill(HIST("hDiffDauPz"), kinkCand.pzDaug() - mcDaugTrack.pz()); + registry.fill(HIST("h2TrueSignalMassPt"), kinkCand.mothSign() * kinkCand.ptMoth(), invMass); + registry.fill(HIST("h2TrueDaugTPCNSigmaPt"), kinkCand.mothSign() * kinkCand.ptDaug(), tpcNSigmaDaug); + + hypkinkCand.isSignal = true; + hypkinkCand.isSignalReco = true; + fillCandidateMCInfo(hypkinkCand, mcMothTrack, mcDaugTrack, mcNeutTrack); + mcPartIndices.push_back(mcMothTrack.globalIndex()); + + std::array dcaInfo; + auto mcMothTrackPar = getTrackParFromMC(mcMothTrack, 2); + o2::base::Propagator::Instance()->propagateToDCABxByBz({posDecVtx[0], posDecVtx[1], posDecVtx[2]}, mcMothTrackPar, 2.f, matCorr, &dcaInfo); + registry.fill(HIST("hDCAXYMothToRecSV"), dcaInfo[0]); + registry.fill(HIST("hDCAZMothToRecSV"), dcaInfo[1]); + } + + hypkinkCand.isCollReco = true; + hypkinkCand.isSurvEvSelection = true; + + outputMCTable( + mBz > 0 ? 1 : -1, + hypkinkCand.posPV[0], hypkinkCand.posPV[1], hypkinkCand.posPV[2], + hypkinkCand.posSV[0], hypkinkCand.posSV[1], hypkinkCand.posSV[2], + hypkinkCand.isMatter, + hypkinkCand.lastPosMoth[0], hypkinkCand.lastPosMoth[1], hypkinkCand.lastPosMoth[2], + hypkinkCand.momMothSV[0], hypkinkCand.momMothSV[1], hypkinkCand.momMothSV[2], + refitPPV[0], refitPPV[1], refitPPV[2], + refitPSV[0], refitPSV[1], refitPSV[2], + hypkinkCand.momDaugSV[0], hypkinkCand.momDaugSV[1], hypkinkCand.momDaugSV[2], + hypkinkCand.dcaXYMothPv, hypkinkCand.dcaXYDaugPv, hypkinkCand.dcaKinkTopo, + hypkinkCand.chi2ITSMoth, hypkinkCand.itsClusterSizeMoth, hypkinkCand.itsClusterSizeDaug, + hypkinkCand.nSigmaTPCDaug, hypkinkCand.nSigmaITSDaug, hypkinkCand.nSigmaTOFDaug, + hypkinkCand.isSignal, hypkinkCand.isSignalReco, hypkinkCand.isCollReco, hypkinkCand.isSurvEvSelection, + hypkinkCand.truePosSV[0], hypkinkCand.truePosSV[1], hypkinkCand.truePosSV[2], + hypkinkCand.trueMomMothPV[0], hypkinkCand.trueMomMothPV[1], hypkinkCand.trueMomMothPV[2], + hypkinkCand.trueMomMothSV[0], hypkinkCand.trueMomMothSV[1], hypkinkCand.trueMomMothSV[2], + hypkinkCand.trueMomDaugSV[0], hypkinkCand.trueMomDaugSV[1], hypkinkCand.trueMomDaugSV[2], + hypkinkCand.isMothReco, hypkinkCand.momMothPV[0], hypkinkCand.momMothPV[1], hypkinkCand.momMothPV[2], + hypkinkCand.updateMomMothPV[0], hypkinkCand.updateMomMothPV[1], hypkinkCand.updateMomMothPV[2]); + } + + // fill kink signals which are not reconstructed + for (auto const& mcparticle : particlesMC) { + bool isKinkSignal = false; + if (hypoMoth == kHypertriton) { + auto dChannel = H3LDecay::getDecayChannel(mcparticle, dauIDList); + if (dChannel == H3LDecay::k2bodyNeutral) { + isKinkSignal = true; + } + } else if (hypoMoth == kHyperhelium4sigma) { + auto dChannel = He4SDecay::getDecayChannel(mcparticle, dauIDList); + if (dChannel == He4SDecay::k2body) { + isKinkSignal = true; + } + } + if (!isKinkSignal) { + continue; + } + + if (std::find(mcPartIndices.begin(), mcPartIndices.end(), mcparticle.globalIndex()) != mcPartIndices.end()) { + continue; + } + + HypKinkCandidate hypkinkCand; + auto mcDaugTrack = particlesMC.rawIteratorAt(dauIDList[0]); + auto mcNeutTrack = particlesMC.rawIteratorAt(dauIDList[1]); + fillCandidateMCInfo(hypkinkCand, mcparticle, mcDaugTrack, mcNeutTrack); + + if (mcPartIndices[mcparticle.globalIndex()] != -1) { + auto mothTrack = tracks.rawIteratorAt(mcPartIndices[mcparticle.globalIndex()]); + if (mothTrack.has_collision()) { + auto collision = mothTrack.collision_as(); + auto bc = collision.template bc_as(); + initCCDB(bc); + fillCandidateRecoMoth(hypkinkCand, collision, mothTrack); + } + } + + outputMCTable( + mBz > 0 ? 1 : -1, + -1, -1, -1, + -1, -1, -1, + -1, + -1, -1, -1, + -1, -1, -1, + -1, -1, -1, + -1, -1, -1, + -1, -1, -1, + -1, -1, -1, + -1, -1, -1, + -1, -1, -1, + true, false, isReconstructedMCCollisions[mcparticle.mcCollisionId()], isSelectedMCCollisions[mcparticle.mcCollisionId()], + hypkinkCand.truePosSV[0], hypkinkCand.truePosSV[1], hypkinkCand.truePosSV[2], + hypkinkCand.trueMomMothPV[0], hypkinkCand.trueMomMothPV[1], hypkinkCand.trueMomMothPV[2], + hypkinkCand.trueMomMothSV[0], hypkinkCand.trueMomMothSV[1], hypkinkCand.trueMomMothSV[2], + hypkinkCand.trueMomDaugSV[0], hypkinkCand.trueMomDaugSV[1], hypkinkCand.trueMomDaugSV[2], + hypkinkCand.isMothReco, hypkinkCand.momMothPV[0], hypkinkCand.momMothPV[1], hypkinkCand.momMothPV[2], + hypkinkCand.updateMomMothPV[0], hypkinkCand.updateMomMothPV[1], hypkinkCand.updateMomMothPV[2]); + } + } + PROCESS_SWITCH(HyperkinkRecoTask, processMC, "process MC", false); +}; + +//-------------------------------------------------------------- +// check the performance of mcparticle +struct HyperkinkQa { + + Configurable hypoMoth{"hypoMoth", kHypertriton, "Mother particle hypothesis"}; + + HistogramRegistry genQAHist{"genQAHist", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry recoQAHist{"recoQAHist", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + ConfigurableAxis ptBins{"ptBins", {200, 0.f, 10.f}, "Binning for #it{p}_{T} (GeV/#it{c})"}; + ConfigurableAxis ctBins{"ctBins", {100, 0.f, 25.f}, "Binning for c#it{t} (cm)"}; + ConfigurableAxis rigidityBins{"rigidityBins", {200, -10.f, 10.f}, "Binning for #it{p}_{T} (GeV/#it{c})"}; + ConfigurableAxis nsigmaBins{"nsigmaBins", {120, -6.f, 6.f}, "Binning for n sigma"}; + ConfigurableAxis invMassBins{"invMassBins", {100, 3.85f, 4.15f}, "Binning for invariant mass (GeV/#it{c}^{2})"}; + ConfigurableAxis radiusBins{"radiusBins", {40, 0.f, 40.f}, "Binning for radius in xy plane (cm)"}; + + o2::aod::ITSResponse itsResponse; + + int charge = 1; + float massMoth = 999.f; + float massChargedDaug = 999.f; + float massNeutralDaug = 999.f; + int pdgMoth = 0; + std::array pdgDaug = {o2::constants::physics::Pdg::kTriton, PDG_t::kPi0}; // pdgcode of charged (0) and neutral (1) daughter particles + o2::track::PID pidTypeDaug = o2::track::PID::Triton; + + void init(InitContext&) + { + if (doprocessMC == true) { + itsResponse.setMCDefaultParameters(); + + if (hypoMoth == kHypertriton) { + charge = 1; + massMoth = o2::constants::physics::MassHyperTriton; + massChargedDaug = o2::constants::physics::MassTriton; + massNeutralDaug = o2::constants::physics::MassPi0; + pdgMoth = o2::constants::physics::Pdg::kHyperTriton; + pdgDaug[kDaugCharged] = o2::constants::physics::Pdg::kTriton; + pdgDaug[kDaugNeutral] = PDG_t::kPi0; + pidTypeDaug = o2::track::PID::Triton; + } else if (hypoMoth == kHyperhelium4sigma) { + charge = 2; + massMoth = o2::constants::physics::MassHyperHelium4Sigma; + massChargedDaug = o2::constants::physics::MassAlpha; + massNeutralDaug = o2::constants::physics::MassPi0; + pdgMoth = o2::constants::physics::Pdg::kHyperHelium4Sigma; + pdgDaug[kDaugCharged] = o2::constants::physics::Pdg::kAlpha; + pdgDaug[kDaugNeutral] = PDG_t::kPi0; + pidTypeDaug = o2::track::PID::Alpha; + } else { + LOG(fatal) << "Unknown mother particle hypothesis"; + } + + const AxisSpec pAxis{ptBins, "#it{p} (GeV/#it{c})"}; + const AxisSpec ptAxis{ptBins, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec ctAxis{ctBins, "c#it{t} (cm)"}; + const AxisSpec rigidityAxis{rigidityBins, "p/z (GeV/#it{c})"}; + const AxisSpec nsigmaAxis{nsigmaBins, "TPC n#sigma"}; + const AxisSpec itsnsigmaAxis{nsigmaBins, "ITS n#sigma"}; + const AxisSpec invMassAxis{invMassBins, "Inv Mass (GeV/#it{c}^{2})"}; + const AxisSpec diffPtAxis{200, -10.f, 10.f, "#Delta p_{T} (GeV/#it{c})"}; + const AxisSpec diffPzAxis{200, -10.f, 10.f, "#Delta p_{z} (GeV/#it{c})"}; + const AxisSpec itsRadiusAxis{radiusBins, "ITS R (cm)"}; + const AxisSpec svRadiuAxis{radiusBins, "Decay Vertex R (cm)"}; + + auto hCollCounter = genQAHist.add("hCollCounter", "hCollCounter", HistType::kTH1F, {{2, 0.0f, 2.0f}}); + hCollCounter->GetXaxis()->SetBinLabel(1, "Reconstructed Collisions"); + hCollCounter->GetXaxis()->SetBinLabel(2, "Selected"); + auto hMcCollCounter = genQAHist.add("hMcCollCounter", "hMcCollCounter", HistType::kTH1F, {{2, 0.0f, 2.0f}}); + hMcCollCounter->GetXaxis()->SetBinLabel(1, "MC Collisions"); + hMcCollCounter->GetXaxis()->SetBinLabel(2, "Reconstructed"); + + if (hypoMoth == kHypertriton) { + auto hGenHyperMothCounter = genQAHist.add("hGenHyperMothCounter", "", HistType::kTH1F, {{10, 0.f, 10.f}}); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(1, "H3L All"); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(2, "Matter"); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(3, "AntiMatter"); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(4, "t + #pi^{0}"); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(5, "#bar{t} + #pi^{0}"); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(6, "{}^{3}He + #pi^{-}"); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(7, "{}^{3}#bar{He} + #pi^{+}"); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(8, "d + p + #pi^{-}"); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(9, "#bar{d} + #bar{p} + #pi^{+}"); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(10, "Others"); + } else if (hypoMoth == kHyperhelium4sigma) { + auto hGenHyperMothCounter = genQAHist.add("hGenHyperMothCounter", "", HistType::kTH1F, {{10, 0.f, 10.f}}); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(1, "He4S All"); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(2, "Matter"); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(3, "AntiMatter"); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(4, "#alpha + #pi^{0}"); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(5, "#bar{#alpha} + #pi^{0}"); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(6, "t + p + #pi^{0}"); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(7, "#bar{t} + #bar{p} + #pi^{0}"); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(8, "t + n + #pi^{+}"); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(9, "#bar{t} + #bar{n} + #pi^{+}"); + hGenHyperMothCounter->GetXaxis()->SetBinLabel(10, "Others"); + } + + auto hEvtSelectedHyperMothCounter = genQAHist.add("hEvtSelectedHyperMothCounter", "", HistType::kTH1F, {{2, 0.f, 2.f}}); + hEvtSelectedHyperMothCounter->GetXaxis()->SetBinLabel(1, "Generated"); + hEvtSelectedHyperMothCounter->GetXaxis()->SetBinLabel(2, "Survived"); + + genQAHist.add("hGenHyperMothP", "", HistType::kTH1F, {pAxis}); + genQAHist.add("hGenHyperMothPt", "", HistType::kTH1F, {ptAxis}); + genQAHist.add("hGenHyperMothCt", "", HistType::kTH1F, {ctAxis}); + genQAHist.add("hMcRecoInvMass", "", HistType::kTH1F, {invMassAxis}); + + // efficiency/criteria studies for tracks which are true candidates + hMothCounter = recoQAHist.add("hMothCounter", "", HistType::kTH1F, {{9, 0.f, 9.f}}); + hMothCounter->GetXaxis()->SetBinLabel(1, "Generated"); + hMothCounter->GetXaxis()->SetBinLabel(2, "Reconstructed"); + hMothCounter->GetXaxis()->SetBinLabel(3, "eta"); + hMothCounter->GetXaxis()->SetBinLabel(4, "has collision"); + hMothCounter->GetXaxis()->SetBinLabel(5, "ITSonly"); + hMothCounter->GetXaxis()->SetBinLabel(6, "ITS hits"); + hMothCounter->GetXaxis()->SetBinLabel(7, "ITS IR"); + hMothCounter->GetXaxis()->SetBinLabel(8, "ITS chi2"); + hMothCounter->GetXaxis()->SetBinLabel(9, "pt"); + recoQAHist.add("h2TrueMotherDiffPtVsTrueSVR", ";Decay Vertex R (cm);#Delta p_{T} (GeV/#it{c});", HistType::kTH2F, {svRadiuAxis, diffPtAxis}); + recoQAHist.add("h2TrueMotherDiffEtaVsTrueSVR", ";Decay Vertex R (cm);#Delta #eta;", HistType::kTH2F, {svRadiuAxis, {200, -1.f, 1.f}}); + recoQAHist.add("h2GoodMotherDiffPtVsTrueSVR", ";Decay Vertex R (cm);#Delta p_{T} (GeV/#it{c});", HistType::kTH2F, {svRadiuAxis, diffPtAxis}); + + hDaugCounter = recoQAHist.add("hDaugCounter", "", HistType::kTH1F, {{9, 0.f, 9.f}}); + hDaugTPCNSigma = recoQAHist.add("hDaugTPCNSigma", "", HistType::kTH2F, {rigidityAxis, nsigmaAxis}); + + hRecoMothCounter = recoQAHist.add("hRecoMothCounter", "", HistType::kTH1F, {{9, 0.f, 9.f}}); + hRecoDaugCounter = recoQAHist.add("hRecoDaugCounter", "", HistType::kTH1F, {{9, 0.f, 9.f}}); + for (const auto& hist : {hDaugCounter, hRecoMothCounter, hRecoDaugCounter}) { + hist->GetXaxis()->SetBinLabel(1, "Generated"); + hist->GetXaxis()->SetBinLabel(2, "Reconstructed"); + hist->GetXaxis()->SetBinLabel(3, "eta"); + hist->GetXaxis()->SetBinLabel(4, "has ITS&TPC"); + hist->GetXaxis()->SetBinLabel(5, "TPC crossed rows"); + hist->GetXaxis()->SetBinLabel(6, "TPC Ncls"); + hist->GetXaxis()->SetBinLabel(7, "TPC n#sigma"); + hist->GetXaxis()->SetBinLabel(8, "ITS hits"); + hist->GetXaxis()->SetBinLabel(9, "has TOF"); + } + + recoQAHist.add("hMothIsPVContributer", "", HistType::kTH1F, {{2, 0.f, 2.f}}); + recoQAHist.add("hMothITSCls", "", HistType::kTH1F, {{8, 0.f, 8.f}}); + recoQAHist.add("hDaugIsPVContributer", "", HistType::kTH1F, {{2, 0.f, 2.f}}); + recoQAHist.add("hDaugITSCls", "", HistType::kTH1F, {{8, 0.f, 8.f}}); + recoQAHist.add("hDaugITSNSigma", "", HistType::kTH2F, {rigidityAxis, itsnsigmaAxis}); + recoQAHist.add("hRecoDaugPVsITSNSigma", "", HistType::kTH2F, {rigidityAxis, itsnsigmaAxis}); + recoQAHist.add("hRecoCandidateCount", "", HistType::kTH1F, {{4, 0.f, 4.f}}); + } + } + + Configurable skipRejectedEvents{"skipRejectedEvents", false, "Flag to skip events that fail event selection cuts"}; + Configurable doEventCut{"doEventCut", true, "Apply event selection"}; + Configurable maxZVertex{"maxZVertex", 10.0f, "Accepted z-vertex range (cm)"}; + + Configurable etaMax{"etaMax", 1., "eta cut for tracks"}; + Configurable minPtMoth{"minPtMoth", 0.5, "Minimum pT/z of the mother track"}; + Configurable tpcPidNsigmaCut{"tpcPidNsigmaCut", 5, "tpcPidNsigmaCut"}; + Configurable nTPCClusMinDaug{"nTPCClusMinDaug", 80, "daug NTPC clusters cut"}; + Configurable itsMaxChi2{"itsMaxChi2", 36, "max chi2 for ITS"}; + Configurable minRatioTPCNCls{"minRatioTPCNCls", 0.8, "min ratio of TPC crossed rows to findable clusters"}; + + Preslice permcCollision = o2::aod::mcparticle::mcCollisionId; + + // QA for mother track selection + template + bool motherTrackCheck(const TTrack& track, const std::shared_ptr hist) + { + hist->Fill(1); + + if (std::abs(track.eta()) > etaMax) { + return false; + } + hist->Fill(2); + + if (!track.has_collision()) { + return false; + } + hist->Fill(3); + + if (!track.hasITS() || track.hasTPC() || track.hasTOF()) { + return false; + } + hist->Fill(4); + + if (track.itsNCls() >= kITSLayers - 1) { + return false; + } + hist->Fill(5); + + if (track.itsNClsInnerBarrel() != kITSInnerBarrelLayers) { + return false; + } + hist->Fill(6); + + if (track.itsChi2NCl() >= itsMaxChi2) { + return false; + } + hist->Fill(7); + + if (track.pt() <= minPtMoth) { + return false; + } + hist->Fill(8); + + return true; + } + + // qa for daughter track selection + template + bool daughterTrackCheck(const TTrack& track, const std::shared_ptr hist, float tpcNSigma) + { + hist->Fill(1); + + if (std::abs(track.eta()) > etaMax) { + return false; + } + hist->Fill(2); + + if (!track.hasITS() || !track.hasTPC()) { + return false; + } + hist->Fill(3); + + if (track.tpcNClsCrossedRows() <= minRatioTPCNCls * track.tpcNClsFindable()) { + return false; + } + hist->Fill(4); + + if (track.tpcNClsFound() <= nTPCClusMinDaug) { + return false; + } + hist->Fill(5); + + if (std::abs(tpcNSigma) > tpcPidNsigmaCut) { + return false; + } + hist->Fill(6); + + if (track.itsNClsInnerBarrel() != 0 || track.itsNCls() > kITSInnerBarrelLayers) { + return false; + } + hist->Fill(7); + + if (track.hasTOF()) { + return false; + } + hist->Fill(8); + + return true; + } + + void processData(o2::aod::Collisions const&) + { + // dummy process function; + } + PROCESS_SWITCH(HyperkinkQa, processData, "process data", true); + + void processMC(aod::McCollisions const& mcCollisions, aod::McParticles const& particlesMC, MCLabeledCollisionsFull const& collisions, MCLabeledTracksIU const& tracks, aod::BCsWithTimestamps const&) + { + std::vector mcPartIndices; + setTrackIDForMC(mcPartIndices, particlesMC, tracks); + std::vector isSelectedMCCollisions(mcCollisions.size(), false); + std::vector dauIDList(2, -1); + for (const auto& collision : collisions) { + genQAHist.fill(HIST("hCollCounter"), 0.5); + if (doEventCut && (!collision.selection_bit(aod::evsel::kIsTriggerTVX) || !collision.selection_bit(aod::evsel::kNoTimeFrameBorder) || std::abs(collision.posZ()) > maxZVertex)) { + continue; + } + genQAHist.fill(HIST("hCollCounter"), 1.5); + isSelectedMCCollisions[collision.mcCollisionId()] = true; + } + + for (const auto& mcCollision : mcCollisions) { + genQAHist.fill(HIST("hMcCollCounter"), 0.5); + if (isSelectedMCCollisions[mcCollision.globalIndex()]) { // Check that the event is reconstructed and that the reconstructed events pass the selection + genQAHist.fill(HIST("hMcCollCounter"), 1.5); + } else { + if (skipRejectedEvents) { + continue; + } + } + + const auto& dparticlesMC = particlesMC.sliceBy(permcCollision, mcCollision.globalIndex()); + + for (const auto& mcparticle : dparticlesMC) { + if (std::abs(mcparticle.pdgCode()) != pdgMoth) { + continue; + } + bool isMatter = mcparticle.pdgCode() > 0; + genQAHist.fill(HIST("hGenHyperMothCounter"), 0.5); + genQAHist.fill(HIST("hGenHyperMothCounter"), isMatter ? 1.5 : 2.5); + + // QA for decay channels + bool isKinkSignal = false; + if (hypoMoth == kHypertriton) { + auto dChannel = H3LDecay::getDecayChannel(mcparticle, dauIDList); + if (dChannel == H3LDecay::k2bodyNeutral) { + genQAHist.fill(HIST("hGenHyperMothCounter"), isMatter ? 3.5 : 4.5); + isKinkSignal = true; + } else if (dChannel == H3LDecay::k2bodyCharged) { + genQAHist.fill(HIST("hGenHyperMothCounter"), isMatter ? 5.5 : 6.5); + } else if (dChannel == H3LDecay::k3bodyCharged) { + genQAHist.fill(HIST("hGenHyperMothCounter"), isMatter ? 7.5 : 8.5); + } else if (dChannel == H3LDecay::kNChannel) { + genQAHist.fill(HIST("hGenHyperMothCounter"), 9.5); + continue; + } + } else if (hypoMoth == kHyperhelium4sigma) { + auto dChannel = He4SDecay::getDecayChannel(mcparticle, dauIDList); + if (dChannel == He4SDecay::k2body) { + genQAHist.fill(HIST("hGenHyperMothCounter"), isMatter ? 3.5 : 4.5); + isKinkSignal = true; + } else if (dChannel == He4SDecay::k3body_p) { + genQAHist.fill(HIST("hGenHyperMothCounter"), isMatter ? 5.5 : 6.5); + } else if (dChannel == He4SDecay::k3body_n) { + genQAHist.fill(HIST("hGenHyperMothCounter"), isMatter ? 7.5 : 8.5); + } else if (dChannel == He4SDecay::kNChannel) { + genQAHist.fill(HIST("hGenHyperMothCounter"), 9.5); + continue; + } + } + + if (!isKinkSignal) { + continue; + } + recoQAHist.fill(HIST("hMothCounter"), 0); + + genQAHist.fill(HIST("hEvtSelectedHyperMothCounter"), 0.5); + if (isSelectedMCCollisions[mcCollision.globalIndex()]) { + genQAHist.fill(HIST("hEvtSelectedHyperMothCounter"), 1.5); + } + + float svPos[3] = {-999, -999, -999}; + std::vector> dauMom(kNDaughterType, std::vector(3, -999.0f)); + for (const auto& mcparticleDaughter : mcparticle.daughters_as()) { + for (int type = 0; type < kNDaughterType; type++) { + if (std::abs(mcparticleDaughter.pdgCode()) == pdgDaug[type]) { + dauMom[type][0] = mcparticleDaughter.px(); + dauMom[type][1] = mcparticleDaughter.py(); + dauMom[type][2] = mcparticleDaughter.pz(); + + if (type == kDaugCharged) { + svPos[0] = mcparticleDaughter.vx(); + svPos[1] = mcparticleDaughter.vy(); + svPos[2] = mcparticleDaughter.vz(); + + // if daughter track is reconstructed + if (mcPartIndices[mcparticleDaughter.globalIndex()] != -1) { + hDaugCounter->Fill(0.f); + auto track = tracks.rawIteratorAt(mcPartIndices[mcparticleDaughter.globalIndex()]); + float tpcNSigma = getTPCNSigma(track, pidTypeDaug); + daughterTrackCheck(track, hDaugCounter, tpcNSigma); + if (track.hasTPC()) { + hDaugTPCNSigma->Fill(track.p() * track.sign(), tpcNSigma); + } + } + } + } + } + } + + genQAHist.fill(HIST("hGenHyperMothP"), mcparticle.p()); + genQAHist.fill(HIST("hGenHyperMothPt"), mcparticle.pt()); + float ct = RecoDecay::sqrtSumOfSquares(svPos[0] - mcparticle.vx(), svPos[1] - mcparticle.vy(), svPos[2] - mcparticle.vz()) * massMoth / mcparticle.p(); + genQAHist.fill(HIST("hGenHyperMothCt"), ct); + float hypermothMCMass = RecoDecay::m(std::array{std::array{dauMom[kDaugCharged][0], dauMom[kDaugCharged][1], dauMom[kDaugCharged][2]}, std::array{dauMom[kDaugNeutral][0], dauMom[kDaugNeutral][1], dauMom[kDaugNeutral][2]}}, std::array{massChargedDaug, massNeutralDaug}); + genQAHist.fill(HIST("hMcRecoInvMass"), hypermothMCMass); + + // if mother track is reconstructed + if (mcPartIndices[mcparticle.globalIndex()] != -1) { + auto motherTrack = tracks.rawIteratorAt(mcPartIndices[mcparticle.globalIndex()]); + bool isGoodMother = motherTrackCheck(motherTrack, hMothCounter); + float svR = RecoDecay::sqrtSumOfSquares(svPos[0], svPos[1]); + float diffpt = mcparticle.pt() - charge * motherTrack.pt(); + + recoQAHist.fill(HIST("h2TrueMotherDiffPtVsTrueSVR"), svR, diffpt); + recoQAHist.fill(HIST("h2TrueMotherDiffEtaVsTrueSVR"), svR, mcparticle.eta() - motherTrack.eta()); + if (isGoodMother) { + recoQAHist.fill(HIST("h2GoodMotherDiffPtVsTrueSVR"), svR, diffpt); + } + + // if mother track and charged daughters are all reconstructed + bool isDauReconstructed = mcPartIndices[dauIDList[0]] != -1; + if (isDauReconstructed) { + auto daughterTrack = tracks.rawIteratorAt(mcPartIndices[dauIDList[0]]); + bool isMoth = motherTrackCheck(motherTrack, hRecoMothCounter); + bool isDaug = daughterTrackCheck(daughterTrack, hRecoDaugCounter, getTPCNSigma(daughterTrack, pidTypeDaug)); + + recoQAHist.fill(HIST("hRecoCandidateCount"), 0.5); + recoQAHist.fill(HIST("hRecoMothCounter"), 0.5); + recoQAHist.fill(HIST("hMothITSCls"), motherTrack.itsNCls()); + recoQAHist.fill(HIST("hRecoDaugCounter"), 0.5); + recoQAHist.fill(HIST("hMothIsPVContributer"), motherTrack.isPVContributor() ? 1.5 : 0.5); + recoQAHist.fill(HIST("hDaugIsPVContributer"), daughterTrack.isPVContributor() ? 1.5 : 0.5); + + float itsNSigma = getITSNSigma(daughterTrack, itsResponse, pidTypeDaug); + if (daughterTrack.hasITS()) { + recoQAHist.fill(HIST("hDaugITSNSigma"), daughterTrack.sign() * daughterTrack.p(), itsNSigma); + recoQAHist.fill(HIST("hDaugITSCls"), daughterTrack.itsNCls()); + } + + if (motherTrack.has_collision() && daughterTrack.has_collision()) { + recoQAHist.fill(HIST("hRecoCandidateCount"), 1.5); + if (motherTrack.collisionId() == daughterTrack.collisionId()) { + recoQAHist.fill(HIST("hRecoCandidateCount"), 2.5); + } + } + + if (isMoth && isDaug) { + recoQAHist.fill(HIST("hRecoCandidateCount"), 3.5); + recoQAHist.fill(HIST("hRecoDaugPVsITSNSigma"), daughterTrack.sign() * daughterTrack.p(), itsNSigma); + } + } + } + } + } + } + PROCESS_SWITCH(HyperkinkQa, processMC, "do QA for MC prodcutions", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + metadataInfo.initMetadata(cfgc); + return WorkflowSpec{ + // Parse the metadata + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + }; +} diff --git a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx index f1c60d198e1..5891997bc54 100644 --- a/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx +++ b/PWGLF/TableProducer/Nuspex/nucleiSpectra.cxx @@ -53,6 +53,7 @@ #include "Math/Vector4D.h" #include "TRandom3.h" +#include #include #include @@ -988,6 +989,7 @@ struct nucleiSpectra { if (particle.isPhysicalPrimary()) { flags |= kIsPhysicalPrimary; nuclei::hGenNuclei[iS][particle.pdgCode() < 0]->Fill(1., particle.pt()); + // antinuclei from B hadrons are classified as physical primaries if (particle.has_mothers()) { for (auto& motherparticle : particle.mothers_as()) { if (std::find(nuclei::hfMothCodes.begin(), nuclei::hfMothCodes.end(), std::abs(motherparticle.pdgCode())) != nuclei::hfMothCodes.end()) { @@ -998,7 +1000,10 @@ struct nucleiSpectra { } } } - } else if (particle.has_mothers()) { + } else if (particle.getProcess() == TMCProcess::kPDecay) { + if (!particle.has_mothers()) { + continue; // skip secondaries from weak decay without mothers + } flags |= kIsSecondaryFromWeakDecay; for (auto& motherparticle : particle.mothers_as()) { motherPdgCode = motherparticle.pdgCode(); diff --git a/PWGLF/TableProducer/Nuspex/pidTOFGeneric.cxx b/PWGLF/TableProducer/Nuspex/pidTOFGeneric.cxx index 9997d4d27c8..7a3afb2b71d 100644 --- a/PWGLF/TableProducer/Nuspex/pidTOFGeneric.cxx +++ b/PWGLF/TableProducer/Nuspex/pidTOFGeneric.cxx @@ -11,33 +11,37 @@ /// /// \file pidTOFGeneric.cxx -/// \origin Based on pidTOFBase.cxx +/// \origin Based on pidTOFMerged.cxx /// \brief Task to produce event Time obtained from TOF and FT0. -/// In order to redo TOF PID for tracks which are linked to wrong collisions +/// In order to redo TOF PID for secondary tracks which are linked to wrong collisions +/// \author Yuanzhe Wang /// +#include #include #include -#include // O2 includes #include "CCDB/BasicCCDBManager.h" -#include "TOFBase/EventTimeMaker.h" #include "Framework/AnalysisTask.h" #include "ReconstructionDataFormats/Track.h" +#include "TOFBase/EventTimeMaker.h" // O2Physics includes +#include "PWGLF/DataModel/LFPIDTOFGenericTables.h" +#include "PWGLF/Utils/pidTOFGeneric.h" + #include "Common/Core/TableHelper.h" -#include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/FT0Corrected.h" #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "PID/ParamBase.h" #include "PID/PIDTOF.h" -#include "PWGLF/DataModel/pidTOFGeneric.h" +#include "PID/ParamBase.h" using namespace o2; using namespace o2::framework; @@ -45,13 +49,19 @@ using namespace o2::pid; using namespace o2::framework::expressions; using namespace o2::track; +o2::common::core::MetadataHelper metadataInfo; + /// Selection criteria for tracks used for TOF event time float trackSampleMinMomentum = 0.5f; float trackSampleMaxMomentum = 2.f; template bool filterForTOFEventTime(const trackType& tr) { - return (tr.hasTOF() && tr.p() > trackSampleMinMomentum && tr.p() < trackSampleMaxMomentum && (tr.trackType() == o2::aod::track::TrackTypeEnum::Track || tr.trackType() == o2::aod::track::TrackTypeEnum::TrackIU)); + return (tr.hasTOF() && + tr.p() > trackSampleMinMomentum && tr.p() < trackSampleMaxMomentum && + tr.hasITS() && + tr.hasTPC() && + (tr.trackType() == o2::aod::track::TrackTypeEnum::Track || tr.trackType() == o2::aod::track::TrackTypeEnum::TrackIU)); } // accept all /// Specialization of TOF event time maker @@ -69,342 +79,275 @@ o2::tof::eventTimeContainer evTimeMakerForTracks(const trackTypeContainer& track } /// Task to produce the event time tables for generic TOF PID +/// Modified based on pidTOFMerge.cxx struct pidTOFGeneric { // Tables to produce Produces tableEvTime; // Table for global event time Produces tableEvTimeForTrack; // Table for event time after removing bias from the track - static constexpr float diamond = 6.0; // Collision diamond used in the estimation of the TOF event time - static constexpr float errDiamond = diamond * 33.356409f; - static constexpr float weightDiamond = 1.f / (errDiamond * errDiamond); + static constexpr bool kRemoveTOFEvTimeBias = true; // Flag to subtract the Ev. Time bias for low multiplicity events with TOF + static constexpr float kDiamond = 6.0; // Collision diamond used in the estimation of the TOF event time + static constexpr float kErrDiamond = kDiamond * 33.356409f; + static constexpr float kWeightDiamond = 1.f / (kErrDiamond * kErrDiamond); bool enableTable = false; - // Detector response and input parameters - o2::pid::tof::TOFResoParamsV2 mRespParamsV2; - Service ccdb; - Configurable inheritFromBaseTask{"inheritFromBaseTask", true, "Flag to iherit all common configurables from the TOF base task"}; + Configurable fastTOFPID{"fastTOFPID", false, "Flag to enable computeEvTimeFast for evTimeMaker"}; - // CCDB configuration (inherited from TOF signal task) - Configurable url{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable timestamp{"ccdb-timestamp", -1, "timestamp of the object"}; // Event time configurations Configurable minMomentum{"minMomentum", 0.5f, "Minimum momentum to select track sample for TOF event time"}; Configurable maxMomentum{"maxMomentum", 2.0f, "Maximum momentum to select track sample for TOF event time"}; Configurable maxEvTimeTOF{"maxEvTimeTOF", 100000.0f, "Maximum value of the TOF event time"}; Configurable sel8TOFEvTime{"sel8TOFEvTime", false, "Flag to compute the ev. time only for events that pass the sel8 ev. selection"}; + Configurable mComputeEvTimeWithTOF{"computeEvTimeWithTOF", -1, "Compute ev. time with TOF. -1 (autoset), 0 no, 1 yes"}; + Configurable mComputeEvTimeWithFT0{"computeEvTimeWithFT0", -1, "Compute ev. time with FT0. -1 (autoset), 0 no, 1 yes"}; Configurable maxNtracksInSet{"maxNtracksInSet", 10, "Size of the set to consider for the TOF ev. time computation"}; - // TOF Calib configuration - Configurable paramFileName{"paramFileName", "", "Path to the parametrization object. If empty the parametrization is not taken from file"}; - Configurable parametrizationPath{"parametrizationPath", "TOF/Calib/Params", "Path of the TOF parametrization on the CCDB or in the file, if the paramFileName is not empty"}; - Configurable passName{"passName", "", "Name of the pass inside of the CCDB parameter collection. If empty, the automatically deceted from metadata (to be implemented!!!)"}; - Configurable loadResponseFromCCDB{"loadResponseFromCCDB", false, "Flag to load the response from the CCDB"}; - Configurable enableTimeDependentResponse{"enableTimeDependentResponse", false, "Flag to use the collision timestamp to fetch the PID Response"}; - Configurable fatalOnPassNotAvailable{"fatalOnPassNotAvailable", true, "Flag to throw a fatal if the pass is not available in the retrieved CCDB object"}; + + // TOF response and input parameters + o2::pid::tof::TOFResoParamsV3 mRespParamsV3; + Service ccdb; + o2::aod::pidtofgeneric::TOFCalibConfig mTOFCalibConfig; // TOF Calib configuration void init(o2::framework::InitContext& initContext) { - if (inheritFromBaseTask.value) { - if (!getTaskOptionValue(initContext, "tof-signal", "ccdb-url", url.value, true)) { - LOG(fatal) << "Could not get ccdb-url from tof-signal task"; - } - if (!getTaskOptionValue(initContext, "tof-signal", "ccdb-timestamp", timestamp.value, true)) { - LOG(fatal) << "Could not get ccdb-timestamp from tof-signal task"; - } - } - - trackSampleMinMomentum = minMomentum; - trackSampleMaxMomentum = maxMomentum; - LOG(info) << "Configuring track sample for TOF ev. time: " << trackSampleMinMomentum << " < p < " << trackSampleMaxMomentum; - // Check that both processes are not enabled - int nEnabled = 0; - if (doprocessNoFT0 == true) { - LOGF(info, "Enabling process function: processNoFT0"); - nEnabled++; - } - if (doprocessFT0 == true) { - LOGF(info, "Enabling process function: processFT0"); - nEnabled++; - } - if (doprocessOnlyFT0 == true) { - LOGF(info, "Enabling process function: processOnlyFT0"); - nEnabled++; - } - if (nEnabled > 1) { - LOGF(fatal, "Cannot enable more process functions at the same time. Please choose one."); - } + mTOFCalibConfig.metadataInfo = metadataInfo; + mTOFCalibConfig.inheritFromBaseTask(initContext); // Checking that the table is requested in the workflow and enabling it enableTable = isTableRequiredInWorkflow(initContext, "EvTimeTOFFT0") || isTableRequiredInWorkflow(initContext, "EvTimeTOFFT0ForTrack"); if (!enableTable) { LOG(info) << "Table for global Event time is not required, disabling it"; - return; + // return; //TODO: uncomment this line } + enableTable = true; // Force enabling the table for now LOG(info) << "Table EvTimeTOFFT0 enabled!"; - if (sel8TOFEvTime.value == true) { - LOG(info) << "TOF event time will be computed for collisions that pass the event selection only!"; - } - // Getting the parametrization parameters - ccdb->setURL(url.value); - ccdb->setTimestamp(timestamp.value); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - // Not later than now objects - ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); - // - - // TODO: implement the automatic pass name detection from metadata - if (passName.value == "") { - passName.value = "unanchored"; // temporary default - LOG(warning) << "Passed autodetect mode for pass, not implemented yet, waiting for metadata. Taking '" << passName.value << "'"; - } - LOG(info) << "Using parameter collection, starting from pass '" << passName.value << "'"; - - const std::string fname = paramFileName.value; - if (!fname.empty()) { // Loading the parametrization from file - LOG(info) << "Loading exp. sigma parametrization from file " << fname << ", using param: " << parametrizationPath.value; - if (1) { - o2::tof::ParameterCollection paramCollection; - paramCollection.loadParamFromFile(fname, parametrizationPath.value); - LOG(info) << "+++ Loaded parameter collection from file +++"; - if (!paramCollection.retrieveParameters(mRespParamsV2, passName.value)) { - if (fatalOnPassNotAvailable) { - LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); - } else { - LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); - } - } else { - mRespParamsV2.setShiftParameters(paramCollection.getPars(passName.value)); - mRespParamsV2.printShiftParameters(); - } - } else { - mRespParamsV2.loadParamFromFile(fname.data(), parametrizationPath.value); - } - } else if (loadResponseFromCCDB) { // Loading it from CCDB - LOG(info) << "Loading exp. sigma parametrization from CCDB, using path: " << parametrizationPath.value << " for timestamp " << timestamp.value; - - o2::tof::ParameterCollection* paramCollection = ccdb->getForTimeStamp(parametrizationPath.value, timestamp.value); - paramCollection->print(); - if (!paramCollection->retrieveParameters(mRespParamsV2, passName.value)) { - if (fatalOnPassNotAvailable) { - LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); - } else { - LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); + if (mTOFCalibConfig.autoSetProcessFunctions()) { + LOG(info) << "Autodetecting process functions"; + if (metadataInfo.isFullyDefined()) { + if (metadataInfo.isRun3()) { + doprocessRun3.value = true; } - } else { - mRespParamsV2.setShiftParameters(paramCollection->getPars(passName.value)); - mRespParamsV2.printShiftParameters(); } } - mRespParamsV2.print(); - o2::tof::eventTimeContainer::setMaxNtracksInSet(maxNtracksInSet.value); - o2::tof::eventTimeContainer::printConfig(); - } - /// - /// Process function to prepare the event time on Run 3 data without the FT0 - using TrksEvTime = soa::Join; - // Define slice per collision - Preslice perCollision = aod::track::collisionId; - template - using ResponseImplementationEvTime = o2::pid::tof::ExpTimes; - using EvTimeCollisions = soa::Join; - void processNoFT0(TrksEvTime& tracks, - EvTimeCollisions const& collisions) - { - if (!enableTable) { - return; - } - tableEvTime.reserve(collisions.size()); - tableEvTimeForTrack.reserve(tracks.size()); - - // for tracks not assigned to a collision - for (auto track : tracks) { - if (!track.has_collision()) { - tableEvTimeForTrack(0.f, 999.f); + if (metadataInfo.isFullyDefined()) { + if (!metadataInfo.isRun3()) { + LOG(fatal) << "Run3 process not supported in pidTOFGeneric task"; } } - for (auto const& collision : collisions) { // Loop on collisions - const auto& tracksInCollision = tracks.sliceBy(perCollision, collision.globalIndex()); - if ((sel8TOFEvTime.value == true) && !collision.sel8()) { - tableEvTime(0.f, 999.f, 0.f, 999.f, 0.f, 999.f); - for (int i = 0; i < tracksInCollision.size(); i++) { - tableEvTimeForTrack(0.f, 999.f); - } - continue; - } - - // First make table for event time - const auto evTimeTOF = evTimeMakerForTracks(tracksInCollision, mRespParamsV2, diamond, fastTOFPID); - int nGoodTracksForTOF = 0; // count for ntrackIndex for removeBias() - float et = evTimeTOF.mEventTime; - float erret = evTimeTOF.mEventTimeError; + trackSampleMinMomentum = minMomentum; + trackSampleMaxMomentum = maxMomentum; + LOG(info) << "Configuring track sample for TOF ev. time: " << trackSampleMinMomentum << " < p < " << trackSampleMaxMomentum; - if (erret < errDiamond && (maxEvTimeTOF <= 0.f || abs(et) < maxEvTimeTOF)) { - } else { - et = 0.f; - erret = errDiamond; - } - tableEvTime(et, erret, et, erret, 0.f, 999.f); - for (auto const& track : tracksInCollision) { - evTimeTOF.removeBias(track, nGoodTracksForTOF, et, erret, 2); - if (erret < errDiamond && (maxEvTimeTOF <= 0.f || abs(et) < maxEvTimeTOF)) { - } else { - et = 0.f; - erret = errDiamond; - } - tableEvTimeForTrack(et, erret); - } + if (sel8TOFEvTime.value == true) { + LOG(info) << "TOF event time will be computed for collisions that pass the event selection only!"; } + mTOFCalibConfig.initSetup(mRespParamsV3, ccdb); // Getting the parametrization parameters + + o2::tof::eventTimeContainer::setMaxNtracksInSet(maxNtracksInSet.value); + o2::tof::eventTimeContainer::printConfig(); } - PROCESS_SWITCH(pidTOFGeneric, processNoFT0, "Process without FT0", false); + + void process(aod::BCs const&) {} /// - /// Process function to prepare the event for each track on Run 3 data with the FT0 + /// Process function to prepare the event for each track on Run 3 data without the FT0 + // Define slice per collision + using Run3Cols = aod::Collisions; + using EvTimeCollisions = soa::Join; using EvTimeCollisionsFT0 = soa::Join; - void processFT0(TrksEvTime& tracks, - aod::FT0s const&, - EvTimeCollisionsFT0 const& collisions) + using Run3Trks = o2::soa::Join; + using Run3TrksWtof = soa::Join; + Preslice perCollision = aod::track::collisionId; + template + using ResponseImplementationEvTime = o2::pid::tof::ExpTimes; + + void processRun3(Run3TrksWtof const& tracks, + aod::FT0s const&, + EvTimeCollisionsFT0 const& collisions, + aod::BCsWithTimestamps const& bcs) { if (!enableTable) { return; } + LOG(debug) << "Processing Run3 data for TOF event time"; + tableEvTime.reserve(collisions.size()); tableEvTimeForTrack.reserve(tracks.size()); - std::vector tEvTimeForTrack; - std::vector tEvTimeErrForTrack; - tEvTimeForTrack.resize(tracks.size()); - tEvTimeErrForTrack.resize(tracks.size()); - - // for tracks not assigned to a collision - for (auto track : tracks) { - if (!track.has_collision()) { - tEvTimeForTrack[track.globalIndex()] = 0.f; - tEvTimeErrForTrack[track.globalIndex()] = 999.f; + mTOFCalibConfig.processSetup(mRespParamsV3, ccdb, bcs.iteratorAt(0)); // Update the calibration parameters + + // Autoset the processing mode for the event time computation + if (mComputeEvTimeWithTOF == -1 || mComputeEvTimeWithFT0 == -1) { + switch (mTOFCalibConfig.collisionSystem()) { + case CollisionSystemType::kCollSyspp: // pp + mComputeEvTimeWithTOF.value = ((mComputeEvTimeWithTOF == -1) ? 0 : mComputeEvTimeWithTOF.value); + mComputeEvTimeWithFT0.value = ((mComputeEvTimeWithFT0 == -1) ? 1 : mComputeEvTimeWithFT0.value); + break; + case CollisionSystemType::kCollSysPbPb: // PbPb + mComputeEvTimeWithTOF.value = ((mComputeEvTimeWithTOF == -1) ? 1 : mComputeEvTimeWithTOF.value); + mComputeEvTimeWithFT0.value = ((mComputeEvTimeWithFT0 == -1) ? 0 : mComputeEvTimeWithFT0.value); + break; + default: + LOG(fatal) << "Collision system " << mTOFCalibConfig.collisionSystem() << " " << CollisionSystemType::getCollisionSystemName(mTOFCalibConfig.collisionSystem()) << " not supported for TOF event time computation"; + break; } } + LOG(debug) << "Running on " << CollisionSystemType::getCollisionSystemName(mTOFCalibConfig.collisionSystem()) << " mComputeEvTimeWithTOF " << mComputeEvTimeWithTOF.value << " mComputeEvTimeWithFT0 " << mComputeEvTimeWithFT0.value; - for (auto const& collision : collisions) { // Loop on collisions - const auto& tracksInCollision = tracks.sliceBy(perCollision, collision.globalIndex()); - if ((sel8TOFEvTime.value == true) && !collision.sel8()) { - tableEvTime(0.f, 999.f, 0.f, 999.f, 0.f, 999.f); - for (auto track : tracksInCollision) { - tEvTimeForTrack[track.globalIndex()] = 0.f; - tEvTimeErrForTrack[track.globalIndex()] = 999.f; + if (mComputeEvTimeWithTOF == 1 && mComputeEvTimeWithFT0 == 1) { + int lastCollisionId = -1; // Last collision ID analysed + for (auto const& t : tracks) { // Loop on collisions + if (!t.has_collision() || ((sel8TOFEvTime.value == true) && !t.collision_as().sel8())) { // Track was not assigned, cannot compute event time or event did not pass the event selection + tableEvTimeForTrack(0.f, 999.f); + continue; } - continue; - } - - // Compute the TOF event time - const auto evTimeTOF = evTimeMakerForTracks(tracksInCollision, mRespParamsV2, diamond, fastTOFPID); - - float t0TOF[2] = {static_cast(evTimeTOF.mEventTime), static_cast(evTimeTOF.mEventTimeError)}; // Value and error of TOF - float t0AC[2] = {.0f, 999.f}; // Value and error of T0A or T0C or T0AC + if (t.collisionId() == lastCollisionId) { // Event time from this collision is already in the table + continue; + } + /// Create new table for the tracks in a collision + lastCollisionId = t.collisionId(); /// Cache last collision ID - float eventTime = 0.f; - float sumOfWeights = 0.f; - float weight = 0.f; + const auto& tracksInCollision = tracks.sliceBy(perCollision, lastCollisionId); + const auto& collision = t.collision_as(); - if (t0TOF[1] < errDiamond && (maxEvTimeTOF <= 0 || abs(t0TOF[0]) < maxEvTimeTOF)) { - weight = 1.f / (t0TOF[1] * t0TOF[1]); - eventTime += t0TOF[0] * weight; - sumOfWeights += weight; - } + // Compute the TOF event time + const auto evTimeMakerTOF = evTimeMakerForTracks(tracksInCollision, mRespParamsV3, kDiamond, fastTOFPID); - if (collision.has_foundFT0()) { // T0 measurement is available - // const auto& ft0 = collision.foundFT0(); - if (collision.t0ACValid()) { - t0AC[0] = collision.t0AC() * 1000.f; - t0AC[1] = collision.t0resolution() * 1000.f; - } + float t0AC[2] = {.0f, 999.f}; // Value and error of T0A or T0C or T0AC + float t0TOF[2] = {static_cast(evTimeMakerTOF.mEventTime), static_cast(evTimeMakerTOF.mEventTimeError)}; // Value and error of TOF - weight = 1.f / (t0AC[1] * t0AC[1]); - eventTime += t0AC[0] * weight; - sumOfWeights += weight; - } + int nGoodTracksForTOF = 0; + float eventTime = 0.f; + float sumOfWeights = 0.f; + float weight = 0.f; - if (sumOfWeights < weightDiamond) { // avoiding sumOfWeights = 0 or worse that diamond - eventTime = 0; - sumOfWeights = weightDiamond; - } - tableEvTime(eventTime / sumOfWeights, sqrt(1. / sumOfWeights), t0TOF[0], t0TOF[1], t0AC[0], t0AC[1]); - - int nGoodTracksForTOF = 0; // count for ntrackIndex for removeBias() - for (auto const& track : tracksInCollision) { - // Reset the event time - eventTime = 0.f; - sumOfWeights = 0.f; - weight = 0.f; - // Remove the bias on TOF ev. time - evTimeTOF.removeBias(track, nGoodTracksForTOF, t0TOF[0], t0TOF[1], 2); - if (t0TOF[1] < errDiamond && (maxEvTimeTOF <= 0 || abs(t0TOF[0]) < maxEvTimeTOF)) { + if (t0TOF[1] < kErrDiamond && (maxEvTimeTOF <= 0 || std::abs(t0TOF[0]) < maxEvTimeTOF)) { weight = 1.f / (t0TOF[1] * t0TOF[1]); eventTime += t0TOF[0] * weight; sumOfWeights += weight; } - // Add the contribution from FT0 if it is available, t0AC is already calculated - if (collision.has_foundFT0()) { + if (collision.has_foundFT0()) { // T0 measurement is available + // const auto& ft0 = collision.foundFT0(); + if (collision.t0ACValid()) { + t0AC[0] = collision.t0AC() * 1000.f; + t0AC[1] = collision.t0resolution() * 1000.f; + } + weight = 1.f / (t0AC[1] * t0AC[1]); eventTime += t0AC[0] * weight; sumOfWeights += weight; } - if (sumOfWeights < weightDiamond) { // avoiding sumOfWeights = 0 or worse that diamond - eventTime = 0; - sumOfWeights = weightDiamond; + tableEvTime(eventTime / sumOfWeights, std::sqrt(1. / sumOfWeights), t0TOF[0], t0TOF[1], t0AC[0], t0AC[1]); + + for (auto const& trk : tracksInCollision) { // Loop on Tracks + // Reset the event time + eventTime = 0.f; + sumOfWeights = 0.f; + weight = 0.f; + // Remove the bias on TOF ev. time + if constexpr (kRemoveTOFEvTimeBias) { + evTimeMakerTOF.removeBias(trk, nGoodTracksForTOF, t0TOF[0], t0TOF[1], 2); + } + if (t0TOF[1] < kErrDiamond && (maxEvTimeTOF <= 0 || std::abs(t0TOF[0]) < maxEvTimeTOF)) { + weight = 1.f / (t0TOF[1] * t0TOF[1]); + eventTime += t0TOF[0] * weight; + sumOfWeights += weight; + } + + if (collision.has_foundFT0()) { // T0 measurement is available + // const auto& ft0 = collision.foundFT0(); + if (collision.t0ACValid()) { + t0AC[0] = collision.t0AC() * 1000.f; + t0AC[1] = collision.t0resolution() * 1000.f; + } + + weight = 1.f / (t0AC[1] * t0AC[1]); + eventTime += t0AC[0] * weight; + sumOfWeights += weight; + } + + if (sumOfWeights < kWeightDiamond) { // avoiding sumOfWeights = 0 or worse that kDiamond + eventTime = 0; + sumOfWeights = kWeightDiamond; + } + tableEvTimeForTrack(eventTime / sumOfWeights, std::sqrt(1. / sumOfWeights)); } - tEvTimeForTrack[track.globalIndex()] = eventTime / sumOfWeights; - tEvTimeErrForTrack[track.globalIndex()] = sqrt(1. / sumOfWeights); } - } - for (int i = 0; i < tracks.size(); i++) { - tableEvTimeForTrack(tEvTimeForTrack[i], tEvTimeErrForTrack[i]); - } - } - PROCESS_SWITCH(pidTOFGeneric, processFT0, "Process with FT0", true); + } else if (mComputeEvTimeWithTOF == 1 && mComputeEvTimeWithFT0 == 0) { + int lastCollisionId = -1; // Last collision ID analysed + for (auto const& t : tracks) { // Loop on collisions + if (!t.has_collision() || ((sel8TOFEvTime.value == true) && !t.collision_as().sel8())) { // Track was not assigned, cannot compute event time or event did not pass the event selection + tableEvTimeForTrack(0.f, 999.f); + continue; + } + if (t.collisionId() == lastCollisionId) { // Event time from this collision is already in the table + continue; + } + /// Create new table for the tracks in a collision + lastCollisionId = t.collisionId(); /// Cache last collision ID - /// - /// Process function to prepare the event time on Run 3 data with only the FT0 - void processOnlyFT0(EvTimeCollisionsFT0 const& collisions, - TrksEvTime& tracks, - aod::FT0s const&) - { - if (!enableTable) { - return; - } - tableEvTime.reserve(collisions.size()); - tableEvTimeForTrack.reserve(tracks.size()); + const auto& tracksInCollision = tracks.sliceBy(perCollision, lastCollisionId); - // for tracks not assigned to a collision - for (auto track : tracks) { - if (!track.has_collision()) { - tableEvTimeForTrack(0.f, 999.f); - } - } + // First make table for event time + const auto evTimeMakerTOF = evTimeMakerForTracks(tracksInCollision, mRespParamsV3, kDiamond, fastTOFPID); + int nGoodTracksForTOF = 0; + float et = evTimeMakerTOF.mEventTime; + float erret = evTimeMakerTOF.mEventTimeError; - for (auto const& collision : collisions) { - const auto& tracksInCollision = tracks.sliceBy(perCollision, collision.globalIndex()); - if (collision.has_foundFT0()) { // T0 measurement is available - // const auto& ft0 = collision.foundFT0(); - if (collision.t0ACValid()) { - tableEvTime(collision.t0AC() * 1000.f, collision.t0resolution() * 1000.f, 0.f, 999.f, collision.t0AC() * 1000.f, collision.t0resolution() * 1000.f); - for (int i = 0; i < tracks.size(); i++) { - tableEvTimeForTrack(collision.t0AC() * 1000.f, collision.t0resolution() * 1000.f); + if (erret < kErrDiamond && (maxEvTimeTOF <= 0.f || std::abs(et) < maxEvTimeTOF)) { + } else { + et = 0.f; + erret = kErrDiamond; + } + tableEvTime(et, erret, et, erret, 0.f, 999.f); + + for (auto const& trk : tracksInCollision) { // Loop on Tracks + if constexpr (kRemoveTOFEvTimeBias) { + evTimeMakerTOF.removeBias(trk, nGoodTracksForTOF, et, erret, 2); + } + if (erret < kErrDiamond && (maxEvTimeTOF <= 0.f || std::abs(et) < maxEvTimeTOF)) { + } else { + et = 0.f; + erret = kErrDiamond; } - return; + tableEvTimeForTrack(et, erret); + } + } + } else if (mComputeEvTimeWithTOF == 0 && mComputeEvTimeWithFT0 == 1) { + for (const auto& track : tracks) { + if (!track.has_collision()) { + tableEvTimeForTrack(0.f, 999.f); } } - tableEvTime(0.f, 999.f, 0.f, 999.f, 0.f, 999.f); - for (int i = 0; i < tracksInCollision.size(); i++) { - tableEvTimeForTrack(0.f, 999.f); + + for (auto const& collision : collisions) { + const auto& tracksInCollision = tracks.sliceBy(perCollision, collision.globalIndex()); + if (collision.has_foundFT0()) { // T0 measurement is available + // const auto& ft0 = collision.foundFT0(); + if (collision.t0ACValid()) { + tableEvTime(collision.t0AC() * 1000.f, collision.t0resolution() * 1000.f, 0.f, 999.f, collision.t0AC() * 1000.f, collision.t0resolution() * 1000.f); + for (int i = 0; i < tracksInCollision.size(); i++) { + tableEvTimeForTrack(collision.t0AC() * 1000.f, collision.t0resolution() * 1000.f); + } + continue; + } + } + tableEvTime(0.f, 999.f, 0.f, 999.f, 0.f, 999.f); + for (int i = 0; i < tracksInCollision.size(); i++) { + tableEvTimeForTrack(0.f, 999.f); + } } + } else { + LOG(fatal) << "Invalid configuration for TOF event time computation"; } } - PROCESS_SWITCH(pidTOFGeneric, processOnlyFT0, "Process only with FT0", false); + PROCESS_SWITCH(pidTOFGeneric, processRun3, "Process the Run3 data", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { + metadataInfo.initMetadata(cfgc); return WorkflowSpec{ adaptAnalysisTask(cfgc)}; } diff --git a/PWGLF/TableProducer/Nuspex/reduced3bodyCreator.cxx b/PWGLF/TableProducer/Nuspex/reduced3bodyCreator.cxx index 091f0b03580..e164dc2794c 100644 --- a/PWGLF/TableProducer/Nuspex/reduced3bodyCreator.cxx +++ b/PWGLF/TableProducer/Nuspex/reduced3bodyCreator.cxx @@ -16,8 +16,9 @@ #include "TableHelper.h" +#include "PWGLF/DataModel/LFPIDTOFGenericTables.h" #include "PWGLF/DataModel/Reduced3BodyTables.h" -#include "PWGLF/DataModel/pidTOFGeneric.h" +#include "PWGLF/Utils/pidTOFGeneric.h" #include "Common/Core/PID/PIDTOF.h" #include "Common/Core/RecoDecay.h" @@ -64,6 +65,8 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +o2::common::core::MetadataHelper metadataInfo; + using FullTracksExtIU = soa::Join; using FullTracksExtPIDIU = soa::Join; @@ -112,14 +115,16 @@ struct reduced3bodyCreator { int mRunNumber; float mBz; - o2::pid::tof::TOFResoParamsV2 mRespParamsV2; + // TOF response and input parameters + o2::pid::tof::TOFResoParamsV3 mRespParamsV3; + o2::aod::pidtofgeneric::TOFCalibConfig mTOFCalibConfig; // TOF Calib configuration // tracked cluster size std::vector fTrackedClSizeVector; HistogramRegistry registry{"registry", {}}; - void init(InitContext&) + void init(InitContext& initContext) { mRunNumber = 0; zorroSummary.setObject(zorro.getZorroSummary()); @@ -130,6 +135,11 @@ struct reduced3bodyCreator { ccdb->setLocalObjectValidityChecking(); ccdb->setFatalWhenNull(false); + // TOF PID parameters initialization + mTOFCalibConfig.metadataInfo = metadataInfo; + mTOFCalibConfig.inheritFromBaseTask(initContext); + mTOFCalibConfig.initSetup(mRespParamsV3, ccdb); + fitter3body.setPropagateToPCA(true); fitter3body.setMaxR(200.); //->maxRIni3body fitter3body.setMinParamChange(1e-3); @@ -186,66 +196,8 @@ struct reduced3bodyCreator { KFParticle::SetField(mBz); #endif - // Initial TOF PID Paras, copied from PIDTOF.h - timestamp.value = bc.timestamp(); - ccdb->setTimestamp(timestamp.value); - // Not later than now objects - ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); - // TODO: implement the automatic pass name detection from metadata - if (passName.value == "") { - passName.value = "unanchored"; // temporary default - LOG(warning) << "Passed autodetect mode for pass, not implemented yet, waiting for metadata. Taking '" << passName.value << "'"; - } - LOG(info) << "Using parameter collection, starting from pass '" << passName.value << "'"; - - const std::string fname = paramFileName.value; - if (!fname.empty()) { // Loading the parametrization from file - LOG(info) << "Loading exp. sigma parametrization from file " << fname << ", using param: " << parametrizationPath.value; - if (1) { - o2::tof::ParameterCollection paramCollection; - paramCollection.loadParamFromFile(fname, parametrizationPath.value); - LOG(info) << "+++ Loaded parameter collection from file +++"; - if (!paramCollection.retrieveParameters(mRespParamsV2, passName.value)) { - if (fatalOnPassNotAvailable) { - LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); - } else { - LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); - } - } else { - mRespParamsV2.setShiftParameters(paramCollection.getPars(passName.value)); - mRespParamsV2.printShiftParameters(); - } - } else { - mRespParamsV2.loadParamFromFile(fname.data(), parametrizationPath.value); - } - } else if (loadResponseFromCCDB) { // Loading it from CCDB - LOG(info) << "Loading exp. sigma parametrization from CCDB, using path: " << parametrizationPath.value << " for timestamp " << timestamp.value; - o2::tof::ParameterCollection* paramCollection = ccdb->getForTimeStamp(parametrizationPath.value, timestamp.value); - paramCollection->print(); - if (!paramCollection->retrieveParameters(mRespParamsV2, passName.value)) { // Attempt at loading the parameters with the pass defined - if (fatalOnPassNotAvailable) { - LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); - } else { - LOGF(warning, "Pass '%s' not available in the retrieved CCDB object", passName.value.data()); - } - } else { // Pass is available, load non standard parameters - mRespParamsV2.setShiftParameters(paramCollection->getPars(passName.value)); - mRespParamsV2.printShiftParameters(); - } - } - mRespParamsV2.print(); - if (timeShiftCCDBPath.value != "") { - if (timeShiftCCDBPath.value.find(".root") != std::string::npos) { - mRespParamsV2.setTimeShiftParameters(timeShiftCCDBPath.value, "gmean_Pos", true); - mRespParamsV2.setTimeShiftParameters(timeShiftCCDBPath.value, "gmean_Neg", false); - } else { - mRespParamsV2.setTimeShiftParameters(ccdb->getForTimeStamp(Form("%s/pos", timeShiftCCDBPath.value.c_str()), timestamp.value), true); - mRespParamsV2.setTimeShiftParameters(ccdb->getForTimeStamp(Form("%s/neg", timeShiftCCDBPath.value.c_str()), timestamp.value), false); - } - } - fitter3body.setBz(mBz); - bachelorTOFPID.SetParams(mRespParamsV2); + mTOFCalibConfig.processSetup(mRespParamsV3, ccdb, bc); } //------------------------------------------------------------------ @@ -388,7 +340,7 @@ struct reduced3bodyCreator { // TOF PID of bachelor must be calcualted here // ---------------------------------------------- auto originalcol = daughter2.template collision_as(); - double tofNSigmaBach = bachelorTOFPID.GetTOFNSigma(daughter2, originalcol, collision); + double tofNSigmaBach = bachelorTOFPID.GetTOFNSigma(mRespParamsV3, daughter2, originalcol, collision); // ---------------------------------------------- // -------- save reduced track table with decay3body daughters ---------- @@ -469,6 +421,7 @@ struct reduced3bodyInitializer { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { + metadataInfo.initMetadata(cfgc); return WorkflowSpec{ adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), diff --git a/PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx b/PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx index 3d3e2b61d2c..7fe17c42d4a 100644 --- a/PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx +++ b/PWGLF/TableProducer/Nuspex/trHeAnalysis.cxx @@ -16,8 +16,11 @@ /// /// \author Matthias Herzer , Goethe University Frankfurt /// -#include -#include +#include "PWGLF/DataModel/LFNucleiTables.h" +#include "PWGLF/DataModel/LFPIDTOFGenericTables.h" +#include "PWGLF/DataModel/LFParticleIdentification.h" +#include "PWGLF/Utils/pidTOFGeneric.h" + #include "Common/CCDB/EventSelectionParams.h" #include "Common/Core/PID/TPCPIDResponse.h" #include "Common/Core/trackUtilities.h" @@ -26,18 +29,20 @@ #include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/TrackSelectionTables.h" + #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" -#include "PWGLF/DataModel/LFNucleiTables.h" -#include "PWGLF/DataModel/LFParticleIdentification.h" #include "ReconstructionDataFormats/PID.h" #include "ReconstructionDataFormats/Track.h" -#include "PWGLF/DataModel/pidTOFGeneric.h" + #include +#include +#include + namespace o2::aod { namespace h3_data diff --git a/PWGLF/TableProducer/Resonances/cksspinalignment.cxx b/PWGLF/TableProducer/Resonances/cksspinalignment.cxx index 91bb6662dbc..56fc938f43b 100644 --- a/PWGLF/TableProducer/Resonances/cksspinalignment.cxx +++ b/PWGLF/TableProducer/Resonances/cksspinalignment.cxx @@ -60,7 +60,8 @@ using namespace o2::aod::rctsel; struct cksspinalignment { Produces kshortpionEvent; - Produces kshortpionPair; + Produces kshortTrack; + Produces pionTrack; Service ccdb; @@ -279,14 +280,14 @@ struct cksspinalignment { std::vector v0Lifetime = {}; // std::vector armenteros = {}; std::vector pionBachelorIndex = {}; - std::vector pionBachelorSign = {}; + // std::vector pionBachelorSign = {}; std::vector pionBachelorTPC = {}; std::vector pionBachelorTOF = {}; std::vector pionBachelorTOFHit = {}; int numbV0 = 0; auto centrality = collision.centFT0C(); - // auto vz = collision.posZ(); + auto vz = collision.posZ(); int occupancy = collision.trackOccupancyInTimeRange(); auto psiFT0C = collision.psiFT0C(); auto psiFT0A = collision.psiFT0A(); @@ -318,6 +319,8 @@ struct cksspinalignment { auto track1ID = track1.globalIndex(); auto track1sign = track1.sign(); + if (track1sign == 0) + continue; auto track1nsigTPC = track1.tpcNSigmaPi(); auto track1nsigTOF = -999.9; auto track1TOFHit = -1; @@ -327,52 +330,57 @@ struct cksspinalignment { histos.fill(HIST("hTrkSelInfo"), 4.5); } pionbach = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), o2::constants::physics::MassPionCharged); - for (const auto& v0 : V0s) { - histos.fill(HIST("hV0Info"), 0.5); - auto [kshortTag, isValid] = getK0sTags(v0, collision); - if (kshortTag && isValid) { - histos.fill(HIST("hV0Info"), 1.5); - auto postrack1 = v0.template posTrack_as(); - auto negtrack1 = v0.template negTrack_as(); - positiveIndex.push_back(postrack1.globalIndex()); - negativeIndex.push_back(negtrack1.globalIndex()); - v0Cospa.push_back(v0.v0cosPA()); - v0Radius.push_back(v0.v0radius()); - dcaPositive.push_back(std::abs(v0.dcapostopv())); - dcaNegative.push_back(std::abs(v0.dcanegtopv())); - dcaBetweenDaughter.push_back(std::abs(v0.dcaV0daughters())); - v0Lifetime.push_back(v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * (o2::constants::physics::MassK0)); - // armenteros.push_back((v0.qtarm() / std::abs(v0.alpha()))); - - pion = ROOT::Math::PxPyPzMVector(v0.pxpos(), v0.pypos(), v0.pzpos(), o2::constants::physics::MassPionCharged); - antiPion = ROOT::Math::PxPyPzMVector(v0.pxneg(), v0.pyneg(), v0.pzneg(), o2::constants::physics::MassPionCharged); - kshort = pion + antiPion; - // chargedkstar = kshort + pionbach; - kshortMother.push_back(kshort); - // chargedkstarMother.push_back(chargedkstar); - pionBachelor.push_back(pionbach); - pionBachelorIndex.push_back(track1ID); - pionBachelorSign.push_back(track1sign); - pionBachelorTPC.push_back(track1nsigTPC); - pionBachelorTOF.push_back(track1nsigTOF); - pionBachelorTOFHit.push_back(track1TOFHit); - histos.fill(HIST("hKShortMass"), kshort.M()); - } - numbV0 = numbV0 + 1; + pionBachelor.push_back(pionbach); + pionBachelorIndex.push_back(track1ID); + // pionBachelorSign.push_back(track1sign); + pionBachelorTPC.push_back(track1nsigTPC); + pionBachelorTOF.push_back(track1nsigTOF); + pionBachelorTOFHit.push_back(track1TOFHit); + } + for (const auto& v0 : V0s) { + histos.fill(HIST("hV0Info"), 0.5); + auto [kshortTag, isValid] = getK0sTags(v0, collision); + if (kshortTag && isValid) { + histos.fill(HIST("hV0Info"), 1.5); + auto postrack1 = v0.template posTrack_as(); + auto negtrack1 = v0.template negTrack_as(); + positiveIndex.push_back(postrack1.globalIndex()); + negativeIndex.push_back(negtrack1.globalIndex()); + v0Cospa.push_back(v0.v0cosPA()); + v0Radius.push_back(v0.v0radius()); + dcaPositive.push_back(std::abs(v0.dcapostopv())); + dcaNegative.push_back(std::abs(v0.dcanegtopv())); + dcaBetweenDaughter.push_back(std::abs(v0.dcaV0daughters())); + v0Lifetime.push_back(v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * (o2::constants::physics::MassK0)); + // armenteros.push_back((v0.qtarm() / std::abs(v0.alpha()))); + + pion = ROOT::Math::PxPyPzMVector(v0.pxpos(), v0.pypos(), v0.pzpos(), o2::constants::physics::MassPionCharged); + antiPion = ROOT::Math::PxPyPzMVector(v0.pxneg(), v0.pyneg(), v0.pzneg(), o2::constants::physics::MassPionCharged); + kshort = pion + antiPion; + // chargedkstar = kshort + pionbach; + kshortMother.push_back(kshort); + // chargedkstarMother.push_back(chargedkstar); + histos.fill(HIST("hKShortMass"), kshort.M()); } + numbV0 = numbV0 + 1; } if (numbV0 > 1 && v0Cospa.size() > 1) { histos.fill(HIST("hEvtSelInfo"), 3.5); - kshortpionEvent(centrality, collision.index(), psiFT0C, psiFT0A, psiTPC); + kshortpionEvent(centrality, vz, collision.index(), psiFT0C, psiFT0A, psiTPC); auto indexEvent = kshortpionEvent.lastIndex(); //// Fill track table for Charged KStar////////////////// for (auto icks = kshortMother.begin(); icks != kshortMother.end(); ++icks) { auto iter = std::distance(kshortMother.begin(), icks); kshortDummy = kshortMother.at(iter); // chargedkstarDummy = chargedkstarMother.at(iter); - pionDummy = pionBachelor.at(iter); - kshortpionPair(indexEvent, v0Cospa.at(iter), v0Radius.at(iter), dcaPositive.at(iter), dcaNegative.at(iter), dcaBetweenDaughter.at(iter), v0Lifetime.at(iter), kshortDummy.Px(), kshortDummy.Py(), kshortDummy.Pz(), kshortDummy.M(), pionDummy.Px(), pionDummy.Py(), pionDummy.Pz(), pionBachelorSign.at(iter), pionBachelorTPC.at(iter), pionBachelorTOFHit.at(iter), pionBachelorTOF.at(iter), pionBachelorIndex.at(iter), positiveIndex.at(iter), negativeIndex.at(iter)); + kshortTrack(indexEvent, v0Cospa.at(iter), v0Radius.at(iter), dcaPositive.at(iter), dcaNegative.at(iter), dcaBetweenDaughter.at(iter), v0Lifetime.at(iter), kshortDummy.Px(), kshortDummy.Py(), kshortDummy.Pz(), kshortDummy.M(), positiveIndex.at(iter), negativeIndex.at(iter)); + } + for (auto ipi = pionBachelor.begin(); ipi != pionBachelor.end(); ++ipi) { + auto iterpi = std::distance(pionBachelor.begin(), ipi); + pionDummy = pionBachelor.at(iterpi); + + pionTrack(indexEvent, pionDummy.Px(), pionDummy.Py(), pionDummy.Pz(), pionBachelorTPC.at(iterpi), pionBachelorTOFHit.at(iterpi), pionBachelorTOF.at(iterpi), pionBachelorIndex.at(iterpi)); } } } diff --git a/PWGLF/TableProducer/Resonances/f1protonreducedtable.cxx b/PWGLF/TableProducer/Resonances/f1protonreducedtable.cxx index ce0cdcf3af5..842c0e46c82 100644 --- a/PWGLF/TableProducer/Resonances/f1protonreducedtable.cxx +++ b/PWGLF/TableProducer/Resonances/f1protonreducedtable.cxx @@ -400,7 +400,7 @@ struct f1protonreducedtable { std::vector setValuesBB(o2::ccdb::CcdbApi& ccdbApi, aod::BCsWithTimestamps::iterator const& bunchCrossing, const std::string ccdbPath) { - map metadata; + std::map metadata; auto h = ccdbApi.retrieveFromTFileAny(ccdbPath, metadata, bunchCrossing.timestamp()); // auto h = ccdb->getForTimeStamp(ccdbPath, bunchCrossing.timestamp()); // check if possible to use this without getting fatal if (!h) { diff --git a/PWGLF/TableProducer/Resonances/filterf1proton.cxx b/PWGLF/TableProducer/Resonances/filterf1proton.cxx index 831209b0905..99d02c744cb 100644 --- a/PWGLF/TableProducer/Resonances/filterf1proton.cxx +++ b/PWGLF/TableProducer/Resonances/filterf1proton.cxx @@ -368,7 +368,7 @@ struct filterf1proton { std::vector setValuesBB(o2::ccdb::CcdbApi& ccdbApi, aod::BCsWithTimestamps::iterator const& bunchCrossing, const std::string ccdbPath) { - map metadata; + std::map metadata; auto h = ccdbApi.retrieveFromTFileAny(ccdbPath, metadata, bunchCrossing.timestamp()); // auto h = ccdb->getForTimeStamp(ccdbPath, bunchCrossing.timestamp()); // check if possible to use this without getting fatal if (!h) { diff --git a/PWGLF/TableProducer/Strangeness/CMakeLists.txt b/PWGLF/TableProducer/Strangeness/CMakeLists.txt index 1224f01df0f..b9ae33532f2 100644 --- a/PWGLF/TableProducer/Strangeness/CMakeLists.txt +++ b/PWGLF/TableProducer/Strangeness/CMakeLists.txt @@ -36,8 +36,8 @@ o2physics_add_dpl_workflow(cascademcfinder PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(cascadepid - SOURCES cascadepid.cxx +o2physics_add_dpl_workflow(strangenesstofpid + SOURCES strangenesstofpid.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DetectorsBase COMPONENT_NAME Analysis) @@ -81,16 +81,16 @@ o2physics_add_dpl_workflow(lambdakzeromcfinder PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(lambdakzeropid - SOURCES lambdakzeropid.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::DetectorsBase - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(lambdakzerospawner SOURCES lambdakzerospawner.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(sigmaminus-task + SOURCES sigmaminustask.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(strange-tree-creator SOURCES strangeTreeCreator.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore diff --git a/PWGLF/TableProducer/Strangeness/cascadeflow.cxx b/PWGLF/TableProducer/Strangeness/cascadeflow.cxx index 5179a89846b..dc38426e90e 100644 --- a/PWGLF/TableProducer/Strangeness/cascadeflow.cxx +++ b/PWGLF/TableProducer/Strangeness/cascadeflow.cxx @@ -42,15 +42,17 @@ using namespace o2::framework::expressions; using std::array; using DauTracks = soa::Join; -using CollEventPlane = soa::Join::iterator; -using CollEventPlaneCentralFW = soa::Join::iterator; -using CollEventAndSpecPlane = soa::Join::iterator; -using CollEventAndSpecPlaneCentralFW = soa::Join::iterator; +using CollEventPlane = soa::Join::iterator; +using CollEventPlaneCentralFW = soa::Join::iterator; +using CollEventAndSpecPlane = soa::Join::iterator; +using CollEventAndSpecPlaneCentralFW = soa::Join::iterator; using MCCollisionsStra = soa::Join; +using V0Candidates = soa::Join; using CascCandidates = soa::Join; using CascMCCandidates = soa::Join; -const int nParticles = 2; +const int nParticles = 2; // Xi, Omega +const int nCharges = 2; // Lambda, AntiLambda const int nParameters = 4; namespace cascadev2 @@ -77,6 +79,17 @@ std::shared_ptr hBkgScoreAfterSel[nParticles]; std::shared_ptr hSparseV2C[nParticles]; } // namespace cascadev2 +namespace lambdav2 +{ +enum species { Lambda = 0, + AntiLambda = 1 }; +static const std::vector speciesNames{"Lambda", "AntiLambda"}; +const double AlphaLambda[2] = {0.747, -0.757}; // decay parameter of Lambda and AntiLambda + +std::shared_ptr hMassBeforeSelVsPt[nCharges]; +std::shared_ptr hMassAfterSelVsPt[nCharges]; +} // namespace lambdav2 + namespace cascade_flow_cuts_ml { // direction of the cut @@ -143,6 +156,8 @@ struct cascadeFlow { Configurable isFillTHNXi_PzVsPsi{"isFillTHNXi_PzVsPsi", 1, ""}; Configurable isFillTHNOmega{"isFillTHNOmega", 1, ""}; Configurable isFillTHNOmega_PzVsPsi{"isFillTHNOmega_PzVsPsi", 1, ""}; + Configurable isFillTHNLambda{"isFillTHNLambda", 1, ""}; + Configurable isFillTHNLambda_PzVsPsi{"isFillTHNLambda_PzVsPsi", 1, ""}; Configurable isFillTHN_V2{"isFillTHN_V2", 1, ""}; Configurable isFillTHN_Pz{"isFillTHN_Pz", 1, ""}; Configurable isFillTHN_PzFromLambda{"isFillTHN_PzFromLambda", 1, ""}; @@ -155,6 +170,11 @@ struct cascadeFlow { ConfigurableAxis axisQVs{"axisQVs", {500, -10.f, 10.f}, "axisQVs"}; ConfigurableAxis axisQVsNorm{"axisQVsNorm", {200, -1.f, 1.f}, "axisQVsNorm"}; + // Configurable for shift correction + Configurable cfgShiftCorr{"cfgShiftCorr", 0, ""}; + Configurable cfgShiftPath{"cfgShiftPath", "Users/j/junlee/Qvector/QvecCalib/Shift", "Path for Shift"}; + Configurable cfgnMods{"cfgnMods", 1, "The number of modulations of interest starting from 2"}; + // THN axes ConfigurableAxis thnConfigAxisFT0C{"thnConfigAxisFT0C", {8, 0, 80}, "FT0C centrality (%)"}; ConfigurableAxis thnConfigAxisEta{"thnConfigAxisEta", {8, -0.8, 0.8}, "pseudorapidity"}; @@ -208,6 +228,24 @@ struct cascadeFlow { Configurable MaxOmegaMass{"MaxOmegaMass", 1.690, ""}; } CandidateConfigs; + struct : ConfigurableGroup { + Configurable MinPtV0{"MinPtV0", 0.2, "Min pt of v0"}; + Configurable MaxPtV0{"MaxPtV0", 10, "Max pt of v0"}; + Configurable MinMassLambda{"MinMassLambda", 1.105, ""}; + Configurable MaxMassLambda{"MaxMassLambda", 1.125, ""}; + Configurable MinMassLambdaInTree{"MinMassLambdaInTree", 1.09, ""}; + Configurable MaxMassLambdaInTree{"MaxMassLambdaInTree", 1.14, ""}; + Configurable etaV0{"etaV0", 0.8, "etaV0"}; + Configurable v0cospa{"v0cospa", 0.97, "min V0 CosPA"}; + Configurable dcav0dau{"dcav0dau", 1.0, "max DCA V0 Daughters (cm)"}; + Configurable dcanegtopv{"dcanegtopv", .05, "min DCA Neg To PV (cm)"}; + Configurable dcapostopv{"dcapostopv", .05, "min DCA Pos To PV (cm)"}; + Configurable v0radius{"v0radius", 1.2, "minimum V0 radius (cm)"}; + Configurable v0radiusMax{"v0radiusMax", 1E5, "maximum V0 radius (cm)"}; + Configurable rapidityLambda{"rapidityLambda", 0.5, "rapidityLambda"}; + Configurable etaLambda{"etaLambda", 0.8, "etaLambda"}; + } V0Configs; + Configurable sideBandStart{"sideBandStart", 5, "Start of the sideband region in number of sigmas"}; Configurable sideBandEnd{"sideBandEnd", 7, "End of the sideband region in number of sigmas"}; Configurable downsample{"downsample", 1., "Downsample training output tree"}; @@ -230,8 +268,10 @@ struct cascadeFlow { Configurable acceptancePathsCCDBXi{"acceptancePathsCCDBXi", "Users/c/chdemart/AcceptanceXi", "Paths of Xi acceptance on CCDB"}; Configurable acceptancePathsCCDBOmega{"acceptancePathsCCDBOmega", "Users/c/chdemart/AcceptanceOmega", "Paths of Omega acceptance on CCDB"}; Configurable acceptancePathsCCDBLambda{"acceptancePathsCCDBLambda", "Users/c/chdemart/AcceptanceLambda", "Paths of Lambda acceptance on CCDB"}; + Configurable acceptancePathsCCDBPrimaryLambda{"acceptancePathsCCDBPrimaryLambda", "Users/c/chdemart/AcceptanceLambda", "Paths of PrimaryLambda acceptance on CCDB"}; Configurable acceptanceHistoNameCasc{"acceptanceHistoNameCasc", "histoCos2ThetaNoFit2D", "Histo name of acceptance on CCDB"}; Configurable acceptanceHistoNameLambda{"acceptanceHistoNameLambda", "histoCos2ThetaLambdaFromCNoFit2D", "Histo name of acceptance on CCDB"}; + Configurable acceptanceHistoNamePrimaryLambda{"acceptanceHistoNamePrimaryLambda", "histoCos2ThetaLambdaFromCNoFit2D", "Histo name of acceptance on CCDB"}; // ML inference Configurable isApplyML{"isApplyML", 1, "Flag to apply ML selections"}; @@ -360,6 +400,64 @@ struct cascadeFlow { return true; } + template + bool isLambdaAccepted(TDaughter negExtra, TDaughter posExtra, int& counter) // loose cuts on topological selections of v0s + { + // TPC cuts as those implemented for the training of the signal + if (doNTPCSigmaCut) { + if (std::abs(posExtra.tpcNSigmaPr()) > nsigmatpcPr || std::abs(negExtra.tpcNSigmaPi()) > nsigmatpcPi) + return false; + } + counter++; + + if (posExtra.tpcCrossedRows() < mintpccrrows || negExtra.tpcCrossedRows() < mintpccrrows) + return false; + + counter++; + return true; + } + template + bool isAntiLambdaAccepted(TDaughter negExtra, TDaughter posExtra, int& counter) // loose cuts on topological selections of v0s + { + // TPC cuts as those implemented for the training of the signal + if (doNTPCSigmaCut) { + if (std::abs(negExtra.tpcNSigmaPr()) > nsigmatpcPr || std::abs(posExtra.tpcNSigmaPi()) > nsigmatpcPi) + return false; + } + counter++; + + if (posExtra.tpcCrossedRows() < mintpccrrows || negExtra.tpcCrossedRows() < mintpccrrows) + return false; + + counter++; + return true; + } + + template + bool isV0TopoAccepted(TV0 v0) + { + // topological selections + if (v0.v0radius() < V0Configs.v0radius) + return false; + if (v0.v0radius() > V0Configs.v0radiusMax) + return false; + if (std::abs(v0.dcapostopv()) < V0Configs.dcapostopv) + return false; + if (std::abs(v0.dcanegtopv()) < V0Configs.dcanegtopv) + return false; + if (v0.v0cosPA() < V0Configs.v0cospa) + return false; + if (v0.dcaV0daughters() > V0Configs.dcav0dau) + return false; + // rapidity selection + if (std::abs(v0.yLambda()) > V0Configs.rapidityLambda) + return false; + if (std::abs(v0.eta()) > V0Configs.etaLambda) + return false; + + return true; + } + double GetPhiInRange(double phi) { while (phi < 0) { @@ -371,10 +469,58 @@ struct cascadeFlow { return phi; } + int currentRunNumber = -999; + int lastRunNumber = -999; + std::vector shiftprofile{}; + std::string fullCCDBShiftCorrPath; + + template + double ApplyShiftCorrection(TCollision coll, double psiT0C) + { + int nmode = 2; + auto deltapsiFT0C = 0.0; + + for (int ishift = 1; ishift <= 10; ishift++) { + auto coeffshiftxFT0C = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(coll.centFT0C(), 0.5, ishift - 0.5)); + auto coeffshiftyFT0C = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(coll.centFT0C(), 1.5, ishift - 0.5)); + + deltapsiFT0C += ((1 / (1.0 * ishift)) * (-coeffshiftxFT0C * TMath::Cos(ishift * static_cast(nmode) * psiT0C) + coeffshiftyFT0C * TMath::Sin(ishift * static_cast(nmode) * psiT0C))); + } + return psiT0C + deltapsiFT0C; + } + + template + double ComputeEPResolutionwShifts(TCollision coll, double psiT0C, double psiTPCA, double psiTPCC) + { + int nmode = 2; + auto deltapsiFT0C = 0.0; + auto deltapsiTPCA = 0.0; + auto deltapsiTPCC = 0.0; + for (int ishift = 1; ishift <= 10; ishift++) { + auto coeffshiftxFT0C = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(coll.centFT0C(), 0.5, ishift - 0.5)); + auto coeffshiftyFT0C = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(coll.centFT0C(), 1.5, ishift - 0.5)); + auto coeffshiftxTPCA = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(coll.centFT0C(), 2.5, ishift - 0.5)); + auto coeffshiftyTPCA = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(coll.centFT0C(), 3.5, ishift - 0.5)); + auto coeffshiftxTPCC = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(coll.centFT0C(), 4.5, ishift - 0.5)); + auto coeffshiftyTPCC = shiftprofile.at(nmode - 2)->GetBinContent(shiftprofile.at(nmode - 2)->FindBin(coll.centFT0C(), 5.5, ishift - 0.5)); + deltapsiFT0C += ((1 / (1.0 * ishift)) * (-coeffshiftxFT0C * TMath::Cos(ishift * static_cast(nmode) * psiT0C) + coeffshiftyFT0C * TMath::Sin(ishift * static_cast(nmode) * psiT0C))); + deltapsiTPCA += ((1 / (1.0 * ishift)) * (-coeffshiftxTPCA * TMath::Cos(ishift * static_cast(nmode) * psiTPCA) + coeffshiftyTPCA * TMath::Sin(ishift * static_cast(nmode) * psiTPCA))); + deltapsiTPCC += ((1 / (1.0 * ishift)) * (-coeffshiftxTPCC * TMath::Cos(ishift * static_cast(nmode) * psiTPCC) + coeffshiftyTPCC * TMath::Sin(ishift * static_cast(nmode) * psiTPCC))); + } + // histos.fill(HIST("psi2/QA/EP_FT0C_shifted"), coll.centFT0C(), psiT0C + deltapsiFT0C); + // histos.fill(HIST("psi2/QA/EP_TPCA_shifted"), coll.centFT0C(), psiTPCA + deltapsiTPCA); + // histos.fill(HIST("psi2/QA/EP_TPCC_shifted"), coll.centFT0C(), psiTPCC + deltapsiTPCC); + resolution.fill(HIST("QVectorsT0CTPCA_Shifted"), coll.centFT0C(), TMath::Cos(static_cast(nmode) * (psiT0C + deltapsiFT0C - psiTPCA - deltapsiTPCA))); + resolution.fill(HIST("QVectorsT0CTPCC_Shifted"), coll.centFT0C(), TMath::Cos(static_cast(nmode) * (psiT0C + deltapsiFT0C - psiTPCC - deltapsiTPCC))); + resolution.fill(HIST("QVectorsTPCAC_Shifted"), coll.centFT0C(), TMath::Cos(static_cast(nmode) * (psiTPCA + deltapsiTPCA - psiTPCC - deltapsiTPCC))); + return true; + } + // objects to use for acceptance correction TH2F* hAcceptanceXi; TH2F* hAcceptanceOmega; TH2F* hAcceptanceLambda; + TH2F* hAcceptancePrimaryLambda; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; HistogramRegistry histosMCGen{"histosMCGen", {}, OutputObjHandlingPolicy::AnalysisObject, false, true}; @@ -383,6 +529,7 @@ struct cascadeFlow { // Tables to produce Produces trainingSample; Produces analysisSample; + Produces analysisLambdaSample; Configurable> parSigmaMass{ "parSigmaMass", {cascadev2::massSigmaParameters[0], nParameters, nParticles, @@ -480,6 +627,36 @@ struct cascadeFlow { cosThetaStarProton, pdgCode); } + + template + void fillAnalysedLambdaTable(collision_t coll, bool hasEventPlane, bool hasSpectatorPlane, int chargeIndex, v0_t v0, float v2CEP, float psiT0C, double pzs2Lambda, double cos2ThetaLambda, double cosThetaLambda) + { + double invMassLambda = 0; + if (chargeIndex == 0) + invMassLambda = v0.mLambda(); + else if (chargeIndex == 1) + invMassLambda = v0.mAntiLambda(); + else + invMassLambda = v0.mLambda(); + analysisLambdaSample(coll.centFT0C(), + hasEventPlane, + hasSpectatorPlane, + chargeIndex, + v0.pt(), + v0.phi(), + invMassLambda, + v0.v0radius(), + v0.dcapostopv(), + v0.dcanegtopv(), + v0.v0cosPA(), + v0.dcaV0daughters(), + v2CEP, + psiT0C, + pzs2Lambda, + cos2ThetaLambda, + cosThetaLambda); + } + void initAcceptanceFromCCDB() { LOG(info) << "Loading acceptance from CCDB "; @@ -492,6 +669,10 @@ struct cascadeFlow { TList* listAcceptanceLambda = ccdb->get(acceptancePathsCCDBLambda); if (!listAcceptanceLambda) LOG(fatal) << "Problem getting TList object with acceptance for Lambda!"; + TList* listAcceptancePrimaryLambda = ccdb->get(acceptancePathsCCDBPrimaryLambda); + if (!listAcceptancePrimaryLambda) + LOG(fatal) << "Problem getting TList object with acceptance for Primary Lambda!"; + hAcceptanceXi = static_cast(listAcceptanceXi->FindObject(Form("%s", acceptanceHistoNameCasc->data()))); if (!hAcceptanceXi) { LOG(fatal) << "The histogram for Xi is not there!"; @@ -507,6 +688,11 @@ struct cascadeFlow { LOG(fatal) << "The histogram for Lambda is not there!"; } hAcceptanceLambda->SetName("hAcceptanceLambda"); + hAcceptancePrimaryLambda = static_cast(listAcceptancePrimaryLambda->FindObject(Form("%s", acceptanceHistoNamePrimaryLambda->data()))); + if (!hAcceptancePrimaryLambda) { + LOG(fatal) << "The histogram for Primary Lambda is not there!"; + } + hAcceptancePrimaryLambda->SetName("hAcceptancePrimaryLambda"); LOG(info) << "Acceptance now loaded"; } @@ -515,9 +701,14 @@ struct cascadeFlow { float minMass[2]{1.28, 1.6}; float maxMass[2]{1.36, 1.73}; + float minMassLambda[2]{1.09, 1.09}; + float maxMassLambda[2]{1.14, 1.14}; const AxisSpec massCascAxis[2]{{static_cast((maxMass[0] - minMass[0]) / 0.001f), minMass[0], maxMass[0], "#Xi candidate mass (GeV/c^{2})"}, {static_cast((maxMass[1] - minMass[1]) / 0.001f), minMass[1], maxMass[1], "#Omega candidate mass (GeV/c^{2})"}}; - const AxisSpec ptAxis{static_cast((CandidateConfigs.MaxPt - CandidateConfigs.MinPt) / 0.2), CandidateConfigs.MinPt, CandidateConfigs.MaxPt, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec massLambdaAxis[2]{{static_cast((maxMassLambda[0] - minMassLambda[0]) / 0.001f), minMassLambda[0], maxMassLambda[0], "#Lambda candidate mass (GeV/c^{2})"}, + {static_cast((maxMassLambda[1] - minMassLambda[1]) / 0.001f), minMassLambda[1], maxMassLambda[1], "#bar{#Lambda} candidate mass (GeV/c^{2})"}}; + const AxisSpec ptAxisCasc{static_cast((CandidateConfigs.MaxPt - CandidateConfigs.MinPt) / 0.2), CandidateConfigs.MinPt, CandidateConfigs.MaxPt, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec ptAxisLambda{static_cast((V0Configs.MaxPtV0 - V0Configs.MinPtV0) / 0.2), V0Configs.MinPtV0, V0Configs.MaxPtV0, "#it{p}_{T} (GeV/#it{c})"}; const AxisSpec v2Axis{200, -1., 1., "#it{v}_{2}"}; const AxisSpec CentAxis{18, 0., 90., "FT0C centrality percentile"}; TString hNEventsLabels[10] = {"All", "sel8", "z vrtx", "kNoSameBunchPileup", "kIsGoodZvtxFT0vsPV", "trackOccupancyInTimeRange", "kNoCollInTimeRange", "kNoCollInROF", "kTVXinTRD", "kIsGoodEventEP"}; @@ -531,6 +722,9 @@ struct cascadeFlow { resolution.add("QVectorsNormT0CTPCC", "QVectorsNormT0CTPCC", HistType::kTH2F, {axisQVsNorm, CentAxis}); resolution.add("QVectorsNormTPCAC", "QVectorsNormTPCCB", HistType::kTH2F, {axisQVsNorm, CentAxis}); resolution.add("QVectorsSpecPlane", "QVectorsSpecPlane", HistType::kTH2F, {axisQVsNorm, CentAxis}); + resolution.add("QVectorsT0CTPCA_Shifted", "QVectorsT0CTPCA_Shifted", HistType::kTH2F, {axisQVs, CentAxis}); + resolution.add("QVectorsT0CTPCC_Shifted", "QVectorsT0CTPCC_Shifted", HistType::kTH2F, {axisQVs, CentAxis}); + resolution.add("QVectorsTPCAC_Shifted", "QVectorsTPCAC_Shifted", HistType::kTH2F, {axisQVs, CentAxis}); histos.add("hNEvents", "hNEvents", {HistType::kTH1F, {{10, 0.f, 10.f}}}); for (Int_t n = 1; n <= histos.get(HIST("hNEvents"))->GetNbinsX(); n++) { @@ -553,8 +747,12 @@ struct cascadeFlow { histos.add("hMultNTracksITSTPCVsCentrality", "hMultNTracksITSTPCVsCentrality", kTH2F, {{100, 0, 100}, {1000, 0, 5000}}); histos.add("hCandidate", "hCandidate", HistType::kTH1F, {{22, -0.5, 21.5}}); + histos.add("hLambdaCandidate", "hLambdaCandidate", HistType::kTH1F, {{5, -0.5, 4.5}}); histos.add("hCascadeSignal", "hCascadeSignal", HistType::kTH1F, {{6, -0.5, 5.5}}); histos.add("hCascade", "hCascade", HistType::kTH1F, {{6, -0.5, 5.5}}); + histos.add("hCascadeDauSel", "hCascadeDauSel", HistType::kTH1F, {{2, -0.5, 1.5}}); + histos.add("hLambdaDauSel", "hLambdaDauSel", HistType::kTH1F, {{3, -0.5, 2.5}}); + histos.add("hALambdaDauSel", "hALambdaDauSel", HistType::kTH1F, {{3, -0.5, 2.5}}); histos.add("hXiPtvsCent", "hXiPtvsCent", HistType::kTH2F, {{100, 0, 100}, {400, 0, 20}}); histos.add("hXiPtvsCentEta08", "hXiPtvsCentEta08", HistType::kTH2F, {{100, 0, 100}, {400, 0, 20}}); histos.add("hXiPtvsCentY05", "hXiPtvsCentY05", HistType::kTH2F, {{100, 0, 100}, {400, 0, 20}}); @@ -563,6 +761,8 @@ struct cascadeFlow { histos.add("hOmegaPtvsCentY05", "hOmegaPtvsCentY05", HistType::kTH2F, {{100, 0, 100}, {400, 0, 20}}); histos.add("hCascadePhi", "hCascadePhi", HistType::kTH1F, {{100, 0, o2::constants::math::TwoPI}}); histos.add("hcascminuspsiT0C", "hcascminuspsiT0C", HistType::kTH1F, {{100, 0, o2::constants::math::PI}}); + histos.add("hLambdaPhi", "hLambdaPhi", HistType::kTH1F, {{100, 0, o2::constants::math::TwoPI}}); + histos.add("hlambdaminuspsiT0C", "hlambdaminuspsiT0C", HistType::kTH1F, {{100, 0, o2::constants::math::PI}}); histos.add("hv2CEPvsFT0C", "hv2CEPvsFT0C", HistType::kTH2F, {CentAxis, {100, -1, 1}}); histos.add("hv2CEPvsv2CSP", "hv2CEPvsV2CSP", HistType::kTH2F, {{100, -1, 1}, {100, -1, 1}}); histos.add("hv1EPvsv1SP", "hV1EPvsV1SP", HistType::kTH2F, {{100, -1, 1}, {100, -1, 1}}); @@ -643,6 +843,20 @@ struct cascadeFlow { if (fillingConfigs.isFillTHN_AccFromLambdaVsLambda) histos.add("hOmegaCos2ThetaVsPsiFromLambdaL", "THn for cos2Theta of Lambda vs Lambda mass and pt", HistType::kTHnF, {thnAxisFT0C, thnAxisCharge, thnAxisEta, thnAxisPtLambda, thnAxisMassLambda, thnAxisBDTScore, thnAxisCos2ThetaL, thnAxisPsiDiff}); } + if (fillingConfigs.isFillTHNLambda) { + if (fillingConfigs.isFillTHN_V2) + histos.add("hLambdaV2", "THn for v2 of Lambda", HistType::kTHnF, {thnAxisFT0C, thnAxisCharge, thnAxisPtLambda, thnAxisMassLambda, thnAxisV2}); + if (fillingConfigs.isFillTHN_Pz) + histos.add("hLambdaPzs2", "THn for Pzs2 of Lambda", HistType::kTHnF, {thnAxisFT0C, thnAxisCharge, thnAxisPtLambda, thnAxisMassLambda, thnAxisPzs2Lambda}); + if (fillingConfigs.isFillTHN_Acc) + histos.add("hLambdaCos2Theta", "THn for Cos2Theta of Lambda", HistType::kTHnF, {thnAxisFT0C, thnAxisCharge, thnAxisEta, thnAxisPtLambda, thnAxisMassLambda, thnAxisCos2Theta}); + } + if (fillingConfigs.isFillTHNLambda_PzVsPsi) { + if (fillingConfigs.isFillTHN_Pz) + histos.add("hLambdaPzVsPsi", "THn for cosTheta of Lambda", HistType::kTHnF, {thnAxisFT0C, thnAxisCharge, thnAxisPtLambda, thnAxisMassLambda, thnAxisCosThetaProtonAlpha, thnAxisPsiDiff}); + if (fillingConfigs.isFillTHN_Acc) + histos.add("hLambdaCos2ThetaVsPsi", "THn for cos2Theta of Lambda", HistType::kTHnF, {thnAxisFT0C, thnAxisCharge, thnAxisEta, thnAxisPtLambda, thnAxisMassLambda, thnAxisCos2Theta, thnAxisPsiDiff}); + } histosMCGen.add("h2DGenXiEta08", "h2DGenXiEta08", HistType::kTH2F, {{100, 0, 100}, {400, 0, 20}}); histosMCGen.add("h2DGenOmegaEta08", "h2DGenOmegaEta08", HistType::kTH2F, {{100, 0, 100}, {400, 0, 20}}); @@ -661,14 +875,19 @@ struct cascadeFlow { } for (int iS{0}; iS < nParticles; ++iS) { - cascadev2::hMassBeforeSelVsPt[iS] = histos.add(Form("hMassBeforeSelVsPt%s", cascadev2::speciesNames[iS].data()), "hMassBeforeSelVsPt", HistType::kTH2F, {massCascAxis[iS], ptAxis}); - cascadev2::hMassAfterSelVsPt[iS] = histos.add(Form("hMassAfterSelVsPt%s", cascadev2::speciesNames[iS].data()), "hMassAfterSelVsPt", HistType::kTH2F, {massCascAxis[iS], ptAxis}); + cascadev2::hMassBeforeSelVsPt[iS] = histos.add(Form("hMassBeforeSelVsPt%s", cascadev2::speciesNames[iS].data()), "hMassBeforeSelVsPt", HistType::kTH2F, {massCascAxis[iS], ptAxisCasc}); + cascadev2::hMassAfterSelVsPt[iS] = histos.add(Form("hMassAfterSelVsPt%s", cascadev2::speciesNames[iS].data()), "hMassAfterSelVsPt", HistType::kTH2F, {massCascAxis[iS], ptAxisCasc}); cascadev2::hSignalScoreBeforeSel[iS] = histos.add(Form("hSignalScoreBeforeSel%s", cascadev2::speciesNames[iS].data()), "Signal score before selection;BDT first score;entries", HistType::kTH1F, {{100, 0., 1.}}); cascadev2::hBkgScoreBeforeSel[iS] = histos.add(Form("hBkgScoreBeforeSel%s", cascadev2::speciesNames[iS].data()), "Bkg score before selection;BDT first score;entries", HistType::kTH1F, {{100, 0., 1.}}); cascadev2::hSignalScoreAfterSel[iS] = histos.add(Form("hSignalScoreAfterSel%s", cascadev2::speciesNames[iS].data()), "Signal score after selection;BDT first score;entries", HistType::kTH1F, {{100, 0., 1.}}); cascadev2::hBkgScoreAfterSel[iS] = histos.add(Form("hBkgScoreAfterSel%s", cascadev2::speciesNames[iS].data()), "Bkg score after selection;BDT first score;entries", HistType::kTH1F, {{100, 0., 1.}}); - cascadev2::hSparseV2C[iS] = histos.add(Form("hSparseV2C%s", cascadev2::speciesNames[iS].data()), "hSparseV2C", HistType::kTHnF, {massCascAxis[iS], ptAxis, v2Axis, CentAxis}); + cascadev2::hSparseV2C[iS] = histos.add(Form("hSparseV2C%s", cascadev2::speciesNames[iS].data()), "hSparseV2C", HistType::kTHnF, {massCascAxis[iS], ptAxisCasc, v2Axis, CentAxis}); } + for (int iS{0}; iS < nCharges; ++iS) { + lambdav2::hMassBeforeSelVsPt[iS] = histos.add(Form("hMassBeforeSelVsPt%s", lambdav2::speciesNames[iS].data()), "hMassBeforeSelVsPt", HistType::kTH2F, {massLambdaAxis[iS], ptAxisLambda}); + lambdav2::hMassAfterSelVsPt[iS] = histos.add(Form("hMassAfterSelVsPt%s", lambdav2::speciesNames[iS].data()), "hMassAfterSelVsPt", HistType::kTH2F, {massLambdaAxis[iS], ptAxisLambda}); + } + if (isApplyML) { // Configure and initialise the ML class mlResponseXi.configure(binsPtMl, cutsMl, cutDirMl, nClassesMl); @@ -771,11 +990,13 @@ struct cascadeFlow { auto bachExtra = casc.bachTrackExtra_as(); int counter = 0; - IsCascAccepted(casc, negExtra, posExtra, bachExtra, counter); + bool isCascCandidate = 0; + isCascCandidate = IsCascAccepted(casc, negExtra, posExtra, bachExtra, counter); histos.fill(HIST("hCascadeSignal"), counter); // PDG cascades - fillTrainingTable(coll, casc, pdgCode); + if (isCascCandidate) + fillTrainingTable(coll, casc, pdgCode); // I only store cascades that passed PID and track quality selections } } @@ -815,10 +1036,33 @@ struct cascadeFlow { ROOT::Math::XYZVector spectatorplaneVecZDCA{std::cos(coll.psiZDCA()), std::sin(coll.psiZDCA()), 0}; // eta positive = projectile ROOT::Math::XYZVector spectatorplaneVecZDCC{std::cos(coll.psiZDCC()), std::sin(coll.psiZDCC()), 0}; // eta negative = target - const float PsiT0C = std::atan2(coll.qvecFT0CIm(), coll.qvecFT0CRe()) * 0.5f; - histos.fill(HIST("hPsiT0C"), PsiT0C); + const float psiT0C = std::atan2(coll.qvecFT0CIm(), coll.qvecFT0CRe()) * 0.5f; + const float psiTPCA = std::atan2(coll.qvecBPosIm(), coll.qvecBPosRe()) * 0.5f; + const float psiTPCC = std::atan2(coll.qvecBNegIm(), coll.qvecBNegRe()) * 0.5f; + float psiT0CCorr = psiT0C; + + if (cfgShiftCorr) { + currentRunNumber = coll.runNumber(); + if (currentRunNumber != lastRunNumber) { + shiftprofile.clear(); + for (int i = 2; i < cfgnMods + 2; i++) { + fullCCDBShiftCorrPath = cfgShiftPath; + fullCCDBShiftCorrPath += "/v"; + fullCCDBShiftCorrPath += std::to_string(i); + auto objshift = ccdb->getForTimeStamp(fullCCDBShiftCorrPath, coll.timestamp()); + shiftprofile.push_back(objshift); + } + lastRunNumber = currentRunNumber; + } + } + if (cfgShiftCorr) { + psiT0CCorr = ApplyShiftCorrection(coll, psiT0C); + ComputeEPResolutionwShifts(coll, psiT0C, psiTPCA, psiTPCC); + } + + histos.fill(HIST("hPsiT0C"), psiT0CCorr); histos.fill(HIST("hPsiZDCA_vs_ZDCC"), coll.psiZDCC(), coll.psiZDCA()); - histos.fill(HIST("hPsiT0CvsCentFT0C"), coll.centFT0C(), PsiT0C); + histos.fill(HIST("hPsiT0CvsCentFT0C"), coll.centFT0C(), psiT0CCorr); resolution.fill(HIST("QVectorsT0CTPCA"), eventplaneVecT0C.Dot(eventplaneVecTPCA), coll.centFT0C()); resolution.fill(HIST("QVectorsT0CTPCC"), eventplaneVecT0C.Dot(eventplaneVecTPCC), coll.centFT0C()); @@ -837,8 +1081,12 @@ struct cascadeFlow { auto bachExtra = casc.bachTrackExtra_as(); int counter = 0; - IsCascAccepted(casc, negExtra, posExtra, bachExtra, counter); + bool isCascCandidate = 0; + isCascCandidate = IsCascAccepted(casc, negExtra, posExtra, bachExtra, counter); histos.fill(HIST("hCascade"), counter); + histos.fill(HIST("hCascadeDauSel"), (int)isCascCandidate); + if (!isCascCandidate) + continue; // ML selections bool isSelectedCasc[2]{false, false}; @@ -890,7 +1138,7 @@ struct cascadeFlow { ROOT::Math::XYZVector cascQvec{std::cos(2 * casc.phi()), std::sin(2 * casc.phi()), 0}; auto v2CSP = cascQvec.Dot(eventplaneVecT0C); // not normalised by amplitude - auto cascminuspsiT0C = GetPhiInRange(casc.phi() - PsiT0C); + auto cascminuspsiT0C = GetPhiInRange(casc.phi() - psiT0CCorr); auto v2CEP = std::cos(2.0 * cascminuspsiT0C); ROOT::Math::XYZVector cascUvec{std::cos(casc.phi()), std::sin(casc.phi()), 0}; auto v1SP_ZDCA = cascUvec.Dot(spectatorplaneVecZDCA); @@ -924,9 +1172,9 @@ struct cascadeFlow { auto etaLambda = RecoDecay::eta(std::array{casc.pxlambda(), casc.pylambda(), casc.pzlambda()}); // acceptance values if requested - double MeanCos2ThetaLambdaFromXi = 1; - double MeanCos2ThetaLambdaFromOmega = 1; - double MeanCos2ThetaProtonFromLambda = 1; + double meanCos2ThetaLambdaFromXi = 1; + double meanCos2ThetaLambdaFromOmega = 1; + double meanCos2ThetaProtonFromLambda = 1; if (applyAcceptanceCorrection) { if (ptLambda < CandidateConfigs.MinPtLambda || ptLambda > CandidateConfigs.MaxPtLambda) { continue; @@ -938,24 +1186,24 @@ struct cascadeFlow { int bin2DXi = hAcceptanceXi->FindBin(casc.pt(), casc.eta()); int bin2DOmega = hAcceptanceOmega->FindBin(casc.pt(), casc.eta()); int bin2DLambda = hAcceptanceLambda->FindBin(ptLambda, etaLambda); - MeanCos2ThetaLambdaFromXi = hAcceptanceXi->GetBinContent(bin2DXi); - MeanCos2ThetaLambdaFromOmega = hAcceptanceOmega->GetBinContent(bin2DOmega); - MeanCos2ThetaProtonFromLambda = hAcceptanceLambda->GetBinContent(bin2DLambda); + meanCos2ThetaLambdaFromXi = hAcceptanceXi->GetBinContent(bin2DXi); + meanCos2ThetaLambdaFromOmega = hAcceptanceOmega->GetBinContent(bin2DOmega); + meanCos2ThetaProtonFromLambda = hAcceptanceLambda->GetBinContent(bin2DLambda); } - int ChargeIndex = 0; + int chargeIndex = 0; if (casc.sign() > 0) - ChargeIndex = 1; - double Pzs2Xi = cosThetaStarLambda[0] * std::sin(2 * (casc.phi() - PsiT0C)) / cascadev2::AlphaXi[ChargeIndex] / MeanCos2ThetaLambdaFromXi; - double Pzs2Omega = cosThetaStarLambda[1] * std::sin(2 * (casc.phi() - PsiT0C)) / cascadev2::AlphaOmega[ChargeIndex] / MeanCos2ThetaLambdaFromOmega; - double Cos2ThetaXi = cosThetaStarLambda[0] * cosThetaStarLambda[0]; - double Cos2ThetaOmega = cosThetaStarLambda[1] * cosThetaStarLambda[1]; - double Pzs2LambdaFromCasc = cosThetaStarProton * std::sin(2 * (casc.phi() - PsiT0C)) / cascadev2::AlphaLambda[ChargeIndex] / MeanCos2ThetaProtonFromLambda; - double Cos2ThetaLambda = cosThetaStarProton * cosThetaStarProton; - - double CosThetaXiWithAlpha = cosThetaStarLambda[0] / cascadev2::AlphaXi[ChargeIndex]; - double CosThetaOmegaWithAlpha = cosThetaStarLambda[1] / cascadev2::AlphaOmega[ChargeIndex]; - double CosThetaProtonWithAlpha = cosThetaStarProton / cascadev2::AlphaLambda[ChargeIndex]; + chargeIndex = 1; + double pzs2Xi = cosThetaStarLambda[0] * std::sin(2 * (casc.phi() - psiT0CCorr)) / cascadev2::AlphaXi[chargeIndex] / meanCos2ThetaLambdaFromXi; + double pzs2Omega = cosThetaStarLambda[1] * std::sin(2 * (casc.phi() - psiT0CCorr)) / cascadev2::AlphaOmega[chargeIndex] / meanCos2ThetaLambdaFromOmega; + double cos2ThetaXi = cosThetaStarLambda[0] * cosThetaStarLambda[0]; + double cos2ThetaOmega = cosThetaStarLambda[1] * cosThetaStarLambda[1]; + double pzs2LambdaFromCasc = cosThetaStarProton * std::sin(2 * (casc.phi() - psiT0CCorr)) / cascadev2::AlphaLambda[chargeIndex] / meanCos2ThetaProtonFromLambda; + double cos2ThetaLambda = cosThetaStarProton * cosThetaStarProton; + + double cosThetaXiWithAlpha = cosThetaStarLambda[0] / cascadev2::AlphaXi[chargeIndex]; + double cosThetaOmegaWithAlpha = cosThetaStarLambda[1] / cascadev2::AlphaOmega[chargeIndex]; + double cosThetaProtonWithAlpha = cosThetaStarProton / cascadev2::AlphaLambda[chargeIndex]; histos.fill(HIST("hv2CEPvsFT0C"), coll.centFT0C(), v2CEP); histos.fill(HIST("hv2CEPvsv2CSP"), v2CSP, v2CEP); @@ -982,73 +1230,73 @@ struct cascadeFlow { if (std::abs(casc.eta()) < CandidateConfigs.etaCasc) { if (fillingConfigs.isFillTHNXi) { if (fillingConfigs.isFillTHN_V2) - histos.get(HIST("hXiV2"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], v2CEP); + histos.get(HIST("hXiV2"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], v2CEP); if (fillingConfigs.isFillTHN_Pz) - histos.get(HIST("hXiPzs2"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], Pzs2Xi); + histos.get(HIST("hXiPzs2"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], pzs2Xi); if (casc.mLambda() > CandidateConfigs.MinLambdaMass && casc.mLambda() < CandidateConfigs.MaxLambdaMass) { if (fillingConfigs.isFillTHN_PzFromLambda) - histos.get(HIST("hXiPzs2FromLambda"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], Pzs2LambdaFromCasc); + histos.get(HIST("hXiPzs2FromLambda"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], pzs2LambdaFromCasc); } if (fillingConfigs.isFillTHN_Acc) - histos.get(HIST("hXiCos2Theta"))->Fill(coll.centFT0C(), ChargeIndex, casc.eta(), casc.pt(), casc.mXi(), BDTresponse[0], Cos2ThetaXi); + histos.get(HIST("hXiCos2Theta"))->Fill(coll.centFT0C(), chargeIndex, casc.eta(), casc.pt(), casc.mXi(), BDTresponse[0], cos2ThetaXi); if (fillingConfigs.isFillTHN_AccFromLambdaVsCasc) - histos.get(HIST("hXiCos2ThetaFromLambda"))->Fill(coll.centFT0C(), ChargeIndex, casc.eta(), casc.pt(), casc.mXi(), BDTresponse[0], Cos2ThetaLambda); + histos.get(HIST("hXiCos2ThetaFromLambda"))->Fill(coll.centFT0C(), chargeIndex, casc.eta(), casc.pt(), casc.mXi(), BDTresponse[0], cos2ThetaLambda); if (casc.mXi() > CandidateConfigs.MinXiMass && casc.mXi() < CandidateConfigs.MaxXiMass) { if (fillingConfigs.isFillTHN_AccFromLambdaVsLambda) - histos.get(HIST("hXiCos2ThetaFromLambdaL"))->Fill(coll.centFT0C(), ChargeIndex, etaLambda, ptLambda, casc.mLambda(), BDTresponse[0], Cos2ThetaLambda); + histos.get(HIST("hXiCos2ThetaFromLambdaL"))->Fill(coll.centFT0C(), chargeIndex, etaLambda, ptLambda, casc.mLambda(), BDTresponse[0], cos2ThetaLambda); histos.get(HIST("massXi_ProtonAcc"))->Fill(casc.mXi()); } } if (fillingConfigs.isFillTHNXi_PzVsPsi) { if (fillingConfigs.isFillTHN_Pz) - histos.get(HIST("hXiPzVsPsi"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], CosThetaXiWithAlpha, 2 * cascminuspsiT0C); + histos.get(HIST("hXiPzVsPsi"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], cosThetaXiWithAlpha, 2 * cascminuspsiT0C); if (fillingConfigs.isFillTHN_PzFromLambda) - histos.get(HIST("hXiPzVsPsiFromLambda"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], CosThetaProtonWithAlpha, 2 * cascminuspsiT0C); + histos.get(HIST("hXiPzVsPsiFromLambda"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], cosThetaProtonWithAlpha, 2 * cascminuspsiT0C); if (casc.mLambda() > CandidateConfigs.MinLambdaMass && casc.mLambda() < CandidateConfigs.MaxLambdaMass) { if (fillingConfigs.isFillTHN_Acc) - histos.get(HIST("hXiCos2ThetaVsPsi"))->Fill(coll.centFT0C(), ChargeIndex, casc.eta(), casc.pt(), casc.mXi(), BDTresponse[0], Cos2ThetaXi, 2 * cascminuspsiT0C); + histos.get(HIST("hXiCos2ThetaVsPsi"))->Fill(coll.centFT0C(), chargeIndex, casc.eta(), casc.pt(), casc.mXi(), BDTresponse[0], cos2ThetaXi, 2 * cascminuspsiT0C); } if (fillingConfigs.isFillTHN_AccFromLambdaVsCasc) - histos.get(HIST("hXiCos2ThetaVsPsiFromLambda"))->Fill(coll.centFT0C(), ChargeIndex, casc.eta(), casc.pt(), casc.mXi(), BDTresponse[0], Cos2ThetaLambda, 2 * cascminuspsiT0C); + histos.get(HIST("hXiCos2ThetaVsPsiFromLambda"))->Fill(coll.centFT0C(), chargeIndex, casc.eta(), casc.pt(), casc.mXi(), BDTresponse[0], cos2ThetaLambda, 2 * cascminuspsiT0C); if (casc.mXi() > CandidateConfigs.MinXiMass && casc.mXi() < CandidateConfigs.MaxXiMass) { if (fillingConfigs.isFillTHN_AccFromLambdaVsLambda) - histos.get(HIST("hXiCos2ThetaVsPsiFromLambdaL"))->Fill(coll.centFT0C(), ChargeIndex, etaLambda, ptLambda, casc.mLambda(), BDTresponse[0], Cos2ThetaLambda, 2 * cascminuspsiT0C); + histos.get(HIST("hXiCos2ThetaVsPsiFromLambdaL"))->Fill(coll.centFT0C(), chargeIndex, etaLambda, ptLambda, casc.mLambda(), BDTresponse[0], cos2ThetaLambda, 2 * cascminuspsiT0C); histos.get(HIST("massXi_ProtonAcc"))->Fill(casc.mXi()); } } if (fillingConfigs.isFillTHNOmega) { if (fillingConfigs.isFillTHN_V2) - histos.get(HIST("hOmegaV2"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], v2CEP); + histos.get(HIST("hOmegaV2"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], v2CEP); if (fillingConfigs.isFillTHN_Pz) - histos.get(HIST("hOmegaPzs2"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], Pzs2Omega); + histos.get(HIST("hOmegaPzs2"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], pzs2Omega); if (casc.mLambda() > CandidateConfigs.MinLambdaMass && casc.mLambda() < CandidateConfigs.MaxLambdaMass) { if (fillingConfigs.isFillTHN_PzFromLambda) - histos.get(HIST("hOmegaPzs2FromLambda"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], Pzs2LambdaFromCasc); + histos.get(HIST("hOmegaPzs2FromLambda"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], pzs2LambdaFromCasc); } if (fillingConfigs.isFillTHN_Acc) - histos.get(HIST("hOmegaCos2Theta"))->Fill(coll.centFT0C(), ChargeIndex, casc.eta(), casc.pt(), casc.mOmega(), BDTresponse[1], Cos2ThetaOmega); + histos.get(HIST("hOmegaCos2Theta"))->Fill(coll.centFT0C(), chargeIndex, casc.eta(), casc.pt(), casc.mOmega(), BDTresponse[1], cos2ThetaOmega); if (fillingConfigs.isFillTHN_AccFromLambdaVsCasc) - histos.get(HIST("hOmegaCos2ThetaFromLambda"))->Fill(coll.centFT0C(), ChargeIndex, casc.eta(), casc.pt(), casc.mOmega(), BDTresponse[1], Cos2ThetaLambda); + histos.get(HIST("hOmegaCos2ThetaFromLambda"))->Fill(coll.centFT0C(), chargeIndex, casc.eta(), casc.pt(), casc.mOmega(), BDTresponse[1], cos2ThetaLambda); if (casc.mOmega() > CandidateConfigs.MinOmegaMass && casc.mOmega() < CandidateConfigs.MaxOmegaMass) { if (fillingConfigs.isFillTHN_AccFromLambdaVsLambda) - histos.get(HIST("hOmegaCos2ThetaFromLambdaL"))->Fill(coll.centFT0C(), ChargeIndex, etaLambda, ptLambda, casc.mLambda(), BDTresponse[1], Cos2ThetaLambda); + histos.get(HIST("hOmegaCos2ThetaFromLambdaL"))->Fill(coll.centFT0C(), chargeIndex, etaLambda, ptLambda, casc.mLambda(), BDTresponse[1], cos2ThetaLambda); histos.get(HIST("massOmega_ProtonAcc"))->Fill(casc.mOmega()); } } if (fillingConfigs.isFillTHNOmega_PzVsPsi) { if (fillingConfigs.isFillTHN_Pz) - histos.get(HIST("hOmegaPzVsPsi"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], CosThetaOmegaWithAlpha, 2 * cascminuspsiT0C); + histos.get(HIST("hOmegaPzVsPsi"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], cosThetaOmegaWithAlpha, 2 * cascminuspsiT0C); if (fillingConfigs.isFillTHN_PzFromLambda) - histos.get(HIST("hOmegaPzVsPsiFromLambda"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], CosThetaProtonWithAlpha, 2 * cascminuspsiT0C); + histos.get(HIST("hOmegaPzVsPsiFromLambda"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], cosThetaProtonWithAlpha, 2 * cascminuspsiT0C); if (casc.mLambda() > CandidateConfigs.MinLambdaMass && casc.mLambda() < CandidateConfigs.MaxLambdaMass) { if (fillingConfigs.isFillTHN_Acc) - histos.get(HIST("hOmegaCos2ThetaVsPsi"))->Fill(coll.centFT0C(), ChargeIndex, casc.eta(), casc.pt(), casc.mOmega(), BDTresponse[1], Cos2ThetaOmega, 2 * cascminuspsiT0C); + histos.get(HIST("hOmegaCos2ThetaVsPsi"))->Fill(coll.centFT0C(), chargeIndex, casc.eta(), casc.pt(), casc.mOmega(), BDTresponse[1], cos2ThetaOmega, 2 * cascminuspsiT0C); } if (fillingConfigs.isFillTHN_AccFromLambdaVsCasc) - histos.get(HIST("hOmegaCos2ThetaVsPsiFromLambda"))->Fill(coll.centFT0C(), ChargeIndex, casc.eta(), casc.pt(), casc.mOmega(), BDTresponse[1], Cos2ThetaLambda, 2 * cascminuspsiT0C); + histos.get(HIST("hOmegaCos2ThetaVsPsiFromLambda"))->Fill(coll.centFT0C(), chargeIndex, casc.eta(), casc.pt(), casc.mOmega(), BDTresponse[1], cos2ThetaLambda, 2 * cascminuspsiT0C); if (casc.mOmega() > CandidateConfigs.MinOmegaMass && casc.mOmega() < CandidateConfigs.MaxOmegaMass) { if (fillingConfigs.isFillTHN_AccFromLambdaVsLambda) - histos.get(HIST("hOmegaCos2ThetaVsPsiFromLambdaL"))->Fill(coll.centFT0C(), ChargeIndex, etaLambda, ptLambda, casc.mLambda(), BDTresponse[1], Cos2ThetaLambda, 2 * cascminuspsiT0C); + histos.get(HIST("hOmegaCos2ThetaVsPsiFromLambdaL"))->Fill(coll.centFT0C(), chargeIndex, etaLambda, ptLambda, casc.mLambda(), BDTresponse[1], cos2ThetaLambda, 2 * cascminuspsiT0C); histos.get(HIST("massOmega_ProtonAcc"))->Fill(casc.mOmega()); } } @@ -1056,7 +1304,7 @@ struct cascadeFlow { if (isSelectedCasc[0] || isSelectedCasc[1]) { if (fillingConfigs.isFillTree) - fillAnalysedTable(coll, hasEventPlane, hasSpectatorPlane, casc, v2CSP, v2CEP, v1SP_ZDCA, v1SP_ZDCC, PsiT0C, BDTresponse[0], BDTresponse[1], 0); + fillAnalysedTable(coll, hasEventPlane, hasSpectatorPlane, casc, v2CSP, v2CEP, v1SP_ZDCA, v1SP_ZDCC, psiT0CCorr, BDTresponse[0], BDTresponse[1], 0); } } } @@ -1092,9 +1340,30 @@ struct cascadeFlow { ROOT::Math::XYZVector eventplaneVecTPCA{coll.qvecBPosRe(), coll.qvecBPosIm(), 0}; ROOT::Math::XYZVector eventplaneVecTPCC{coll.qvecBNegRe(), coll.qvecBNegIm(), 0}; - const float PsiT0C = std::atan2(coll.qvecFT0CIm(), coll.qvecFT0CRe()) * 0.5f; - histos.fill(HIST("hPsiT0C"), PsiT0C); - histos.fill(HIST("hPsiT0CvsCentFT0C"), coll.centFT0C(), PsiT0C); + const float psiT0C = std::atan2(coll.qvecFT0CIm(), coll.qvecFT0CRe()) * 0.5f; + const float psiTPCA = std::atan2(coll.qvecBPosIm(), coll.qvecBPosRe()) * 0.5f; + const float psiTPCC = std::atan2(coll.qvecBNegIm(), coll.qvecBNegRe()) * 0.5f; + float psiT0CCorr = psiT0C; + if (cfgShiftCorr) { + currentRunNumber = coll.runNumber(); + if (currentRunNumber != lastRunNumber) { + shiftprofile.clear(); + for (int i = 2; i < cfgnMods + 2; i++) { + fullCCDBShiftCorrPath = cfgShiftPath; + fullCCDBShiftCorrPath += "/v"; + fullCCDBShiftCorrPath += std::to_string(i); + auto objshift = ccdb->getForTimeStamp(fullCCDBShiftCorrPath, coll.timestamp()); + shiftprofile.push_back(objshift); + } + lastRunNumber = currentRunNumber; + } + } + if (cfgShiftCorr) { + psiT0CCorr = ApplyShiftCorrection(coll, psiT0C); + ComputeEPResolutionwShifts(coll, psiT0C, psiTPCA, psiTPCC); + } + histos.fill(HIST("hPsiT0C"), psiT0CCorr); + histos.fill(HIST("hPsiT0CvsCentFT0C"), coll.centFT0C(), psiT0CCorr); resolution.fill(HIST("QVectorsT0CTPCA"), eventplaneVecT0C.Dot(eventplaneVecTPCA), coll.centFT0C()); resolution.fill(HIST("QVectorsT0CTPCC"), eventplaneVecT0C.Dot(eventplaneVecTPCC), coll.centFT0C()); @@ -1112,8 +1381,12 @@ struct cascadeFlow { auto bachExtra = casc.bachTrackExtra_as(); int counter = 0; - IsCascAccepted(casc, negExtra, posExtra, bachExtra, counter); + bool isCascCandidate = 0; + isCascCandidate = IsCascAccepted(casc, negExtra, posExtra, bachExtra, counter); histos.fill(HIST("hCascade"), counter); + histos.fill(HIST("hCascadeDauSel"), (int)isCascCandidate); + if (!isCascCandidate) + continue; // ML selections bool isSelectedCasc[nParticles]{false, false}; @@ -1165,7 +1438,7 @@ struct cascadeFlow { ROOT::Math::XYZVector cascQvec{std::cos(2 * casc.phi()), std::sin(2 * casc.phi()), 0}; auto v2CSP = cascQvec.Dot(eventplaneVecT0C); // not normalised by amplitude - auto cascminuspsiT0C = GetPhiInRange(casc.phi() - PsiT0C); + auto cascminuspsiT0C = GetPhiInRange(casc.phi() - psiT0CCorr); auto v2CEP = std::cos(2.0 * cascminuspsiT0C); ROOT::Math::XYZVector cascUvec{std::cos(casc.phi()), std::sin(casc.phi()), 0}; @@ -1193,9 +1466,9 @@ struct cascadeFlow { auto etaLambda = RecoDecay::eta(std::array{casc.pxlambda(), casc.pylambda(), casc.pzlambda()}); // acceptance values if requested - double MeanCos2ThetaLambdaFromXi = 1; - double MeanCos2ThetaLambdaFromOmega = 1; - double MeanCos2ThetaProtonFromLambda = 1; + double meanCos2ThetaLambdaFromXi = 1; + double meanCos2ThetaLambdaFromOmega = 1; + double meanCos2ThetaProtonFromLambda = 1; if (applyAcceptanceCorrection) { if (ptLambda < CandidateConfigs.MinPtLambda || ptLambda > CandidateConfigs.MaxPtLambda) { continue; @@ -1207,24 +1480,24 @@ struct cascadeFlow { int bin2DXi = hAcceptanceXi->FindBin(casc.pt(), casc.eta()); int bin2DOmega = hAcceptanceOmega->FindBin(casc.pt(), casc.eta()); int bin2DLambda = hAcceptanceLambda->FindBin(ptLambda, etaLambda); - MeanCos2ThetaLambdaFromXi = hAcceptanceXi->GetBinContent(bin2DXi); - MeanCos2ThetaLambdaFromOmega = hAcceptanceOmega->GetBinContent(bin2DOmega); - MeanCos2ThetaProtonFromLambda = hAcceptanceLambda->GetBinContent(bin2DLambda); + meanCos2ThetaLambdaFromXi = hAcceptanceXi->GetBinContent(bin2DXi); + meanCos2ThetaLambdaFromOmega = hAcceptanceOmega->GetBinContent(bin2DOmega); + meanCos2ThetaProtonFromLambda = hAcceptanceLambda->GetBinContent(bin2DLambda); } - int ChargeIndex = 0; + int chargeIndex = 0; if (casc.sign() > 0) - ChargeIndex = 1; - double Pzs2Xi = cosThetaStarLambda[0] * std::sin(2 * (casc.phi() - PsiT0C)) / cascadev2::AlphaXi[ChargeIndex] / MeanCos2ThetaLambdaFromXi; - double Pzs2Omega = cosThetaStarLambda[1] * std::sin(2 * (casc.phi() - PsiT0C)) / cascadev2::AlphaOmega[ChargeIndex] / MeanCos2ThetaLambdaFromOmega; - double Cos2ThetaXi = cosThetaStarLambda[0] * cosThetaStarLambda[0]; - double Cos2ThetaOmega = cosThetaStarLambda[1] * cosThetaStarLambda[1]; - double Pzs2LambdaFromCasc = cosThetaStarProton * std::sin(2 * (casc.phi() - PsiT0C)) / cascadev2::AlphaLambda[ChargeIndex] / MeanCos2ThetaProtonFromLambda; - double Cos2ThetaLambda = cosThetaStarProton * cosThetaStarProton; - - double CosThetaXiWithAlpha = cosThetaStarLambda[0] / cascadev2::AlphaXi[ChargeIndex]; - double CosThetaOmegaWithAlpha = cosThetaStarLambda[1] / cascadev2::AlphaOmega[ChargeIndex]; - double CosThetaProtonWithAlpha = cosThetaStarProton / cascadev2::AlphaLambda[ChargeIndex]; + chargeIndex = 1; + double pzs2Xi = cosThetaStarLambda[0] * std::sin(2 * (casc.phi() - psiT0CCorr)) / cascadev2::AlphaXi[chargeIndex] / meanCos2ThetaLambdaFromXi; + double pzs2Omega = cosThetaStarLambda[1] * std::sin(2 * (casc.phi() - psiT0CCorr)) / cascadev2::AlphaOmega[chargeIndex] / meanCos2ThetaLambdaFromOmega; + double cos2ThetaXi = cosThetaStarLambda[0] * cosThetaStarLambda[0]; + double cos2ThetaOmega = cosThetaStarLambda[1] * cosThetaStarLambda[1]; + double pzs2LambdaFromCasc = cosThetaStarProton * std::sin(2 * (casc.phi() - psiT0CCorr)) / cascadev2::AlphaLambda[chargeIndex] / meanCos2ThetaProtonFromLambda; + double cos2ThetaLambda = cosThetaStarProton * cosThetaStarProton; + + double cosThetaXiWithAlpha = cosThetaStarLambda[0] / cascadev2::AlphaXi[chargeIndex]; + double cosThetaOmegaWithAlpha = cosThetaStarLambda[1] / cascadev2::AlphaOmega[chargeIndex]; + double cosThetaProtonWithAlpha = cosThetaStarProton / cascadev2::AlphaLambda[chargeIndex]; histos.fill(HIST("hv2CEPvsFT0C"), coll.centFT0C(), v2CEP); histos.fill(HIST("hv2CEPvsv2CSP"), v2CSP, v2CEP); @@ -1249,73 +1522,73 @@ struct cascadeFlow { if (std::abs(casc.eta()) < CandidateConfigs.etaCasc) { if (fillingConfigs.isFillTHNXi) { if (fillingConfigs.isFillTHN_V2) - histos.get(HIST("hXiV2"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], v2CEP); + histos.get(HIST("hXiV2"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], v2CEP); if (fillingConfigs.isFillTHN_Pz) - histos.get(HIST("hXiPzs2"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], Pzs2Xi); + histos.get(HIST("hXiPzs2"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], pzs2Xi); if (casc.mLambda() > CandidateConfigs.MinLambdaMass && casc.mLambda() < CandidateConfigs.MaxLambdaMass) { if (fillingConfigs.isFillTHN_PzFromLambda) - histos.get(HIST("hXiPzs2FromLambda"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], Pzs2LambdaFromCasc); + histos.get(HIST("hXiPzs2FromLambda"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], pzs2LambdaFromCasc); } if (fillingConfigs.isFillTHN_Acc) - histos.get(HIST("hXiCos2Theta"))->Fill(coll.centFT0C(), ChargeIndex, casc.eta(), casc.pt(), casc.mXi(), BDTresponse[0], Cos2ThetaXi); + histos.get(HIST("hXiCos2Theta"))->Fill(coll.centFT0C(), chargeIndex, casc.eta(), casc.pt(), casc.mXi(), BDTresponse[0], cos2ThetaXi); if (fillingConfigs.isFillTHN_AccFromLambdaVsCasc) - histos.get(HIST("hXiCos2ThetaFromLambda"))->Fill(coll.centFT0C(), ChargeIndex, casc.eta(), casc.pt(), casc.mXi(), BDTresponse[0], Cos2ThetaLambda); + histos.get(HIST("hXiCos2ThetaFromLambda"))->Fill(coll.centFT0C(), chargeIndex, casc.eta(), casc.pt(), casc.mXi(), BDTresponse[0], cos2ThetaLambda); if (casc.mXi() > CandidateConfigs.MinXiMass && casc.mXi() < CandidateConfigs.MaxXiMass) { if (fillingConfigs.isFillTHN_AccFromLambdaVsLambda) - histos.get(HIST("hXiCos2ThetaFromLambdaL"))->Fill(coll.centFT0C(), ChargeIndex, etaLambda, ptLambda, casc.mLambda(), BDTresponse[0], Cos2ThetaLambda); + histos.get(HIST("hXiCos2ThetaFromLambdaL"))->Fill(coll.centFT0C(), chargeIndex, etaLambda, ptLambda, casc.mLambda(), BDTresponse[0], cos2ThetaLambda); histos.get(HIST("massXi_ProtonAcc"))->Fill(casc.mXi()); } } if (fillingConfigs.isFillTHNXi_PzVsPsi) { if (fillingConfigs.isFillTHN_Pz) - histos.get(HIST("hXiPzVsPsi"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], CosThetaXiWithAlpha, 2 * cascminuspsiT0C); + histos.get(HIST("hXiPzVsPsi"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], cosThetaXiWithAlpha, 2 * cascminuspsiT0C); if (fillingConfigs.isFillTHN_PzFromLambda) - histos.get(HIST("hXiPzVsPsiFromLambda"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], CosThetaProtonWithAlpha, 2 * cascminuspsiT0C); + histos.get(HIST("hXiPzVsPsiFromLambda"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mXi(), BDTresponse[0], cosThetaProtonWithAlpha, 2 * cascminuspsiT0C); if (casc.mLambda() > CandidateConfigs.MinLambdaMass && casc.mLambda() < CandidateConfigs.MaxLambdaMass) { if (fillingConfigs.isFillTHN_Acc) - histos.get(HIST("hXiCos2ThetaVsPsi"))->Fill(coll.centFT0C(), ChargeIndex, casc.eta(), casc.pt(), casc.mXi(), BDTresponse[0], Cos2ThetaXi, 2 * cascminuspsiT0C); + histos.get(HIST("hXiCos2ThetaVsPsi"))->Fill(coll.centFT0C(), chargeIndex, casc.eta(), casc.pt(), casc.mXi(), BDTresponse[0], cos2ThetaXi, 2 * cascminuspsiT0C); } if (fillingConfigs.isFillTHN_AccFromLambdaVsCasc) - histos.get(HIST("hXiCos2ThetaVsPsiFromLambda"))->Fill(coll.centFT0C(), ChargeIndex, casc.eta(), casc.pt(), casc.mXi(), BDTresponse[0], Cos2ThetaLambda, 2 * cascminuspsiT0C); + histos.get(HIST("hXiCos2ThetaVsPsiFromLambda"))->Fill(coll.centFT0C(), chargeIndex, casc.eta(), casc.pt(), casc.mXi(), BDTresponse[0], cos2ThetaLambda, 2 * cascminuspsiT0C); if (casc.mXi() > CandidateConfigs.MinXiMass && casc.mXi() < CandidateConfigs.MaxXiMass) { if (fillingConfigs.isFillTHN_AccFromLambdaVsLambda) - histos.get(HIST("hXiCos2ThetaVsPsiFromLambdaL"))->Fill(coll.centFT0C(), ChargeIndex, etaLambda, ptLambda, casc.mLambda(), BDTresponse[0], Cos2ThetaLambda, 2 * cascminuspsiT0C); + histos.get(HIST("hXiCos2ThetaVsPsiFromLambdaL"))->Fill(coll.centFT0C(), chargeIndex, etaLambda, ptLambda, casc.mLambda(), BDTresponse[0], cos2ThetaLambda, 2 * cascminuspsiT0C); histos.get(HIST("massXi_ProtonAcc"))->Fill(casc.mXi()); } } if (fillingConfigs.isFillTHNOmega) { if (fillingConfigs.isFillTHN_V2) - histos.get(HIST("hOmegaV2"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], v2CEP); + histos.get(HIST("hOmegaV2"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], v2CEP); if (fillingConfigs.isFillTHN_Pz) - histos.get(HIST("hOmegaPzs2"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], Pzs2Omega); + histos.get(HIST("hOmegaPzs2"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], pzs2Omega); if (casc.mLambda() > CandidateConfigs.MinLambdaMass && casc.mLambda() < CandidateConfigs.MaxLambdaMass) { if (fillingConfigs.isFillTHN_PzFromLambda) - histos.get(HIST("hOmegaPzs2FromLambda"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], Pzs2LambdaFromCasc); + histos.get(HIST("hOmegaPzs2FromLambda"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], pzs2LambdaFromCasc); } if (fillingConfigs.isFillTHN_Acc) - histos.get(HIST("hOmegaCos2Theta"))->Fill(coll.centFT0C(), ChargeIndex, casc.eta(), casc.pt(), casc.mOmega(), BDTresponse[1], Cos2ThetaOmega); + histos.get(HIST("hOmegaCos2Theta"))->Fill(coll.centFT0C(), chargeIndex, casc.eta(), casc.pt(), casc.mOmega(), BDTresponse[1], cos2ThetaOmega); if (fillingConfigs.isFillTHN_AccFromLambdaVsCasc) - histos.get(HIST("hOmegaCos2ThetaFromLambda"))->Fill(coll.centFT0C(), ChargeIndex, casc.eta(), casc.pt(), casc.mOmega(), BDTresponse[1], Cos2ThetaLambda); + histos.get(HIST("hOmegaCos2ThetaFromLambda"))->Fill(coll.centFT0C(), chargeIndex, casc.eta(), casc.pt(), casc.mOmega(), BDTresponse[1], cos2ThetaLambda); if (casc.mOmega() > CandidateConfigs.MinOmegaMass && casc.mOmega() < CandidateConfigs.MaxOmegaMass) { if (fillingConfigs.isFillTHN_AccFromLambdaVsLambda) - histos.get(HIST("hOmegaCos2ThetaFromLambdaL"))->Fill(coll.centFT0C(), ChargeIndex, etaLambda, ptLambda, casc.mLambda(), BDTresponse[1], Cos2ThetaLambda); + histos.get(HIST("hOmegaCos2ThetaFromLambdaL"))->Fill(coll.centFT0C(), chargeIndex, etaLambda, ptLambda, casc.mLambda(), BDTresponse[1], cos2ThetaLambda); histos.get(HIST("massOmega_ProtonAcc"))->Fill(casc.mOmega()); } } if (fillingConfigs.isFillTHNOmega_PzVsPsi) { if (fillingConfigs.isFillTHN_Pz) - histos.get(HIST("hOmegaPzVsPsi"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], CosThetaOmegaWithAlpha, 2 * cascminuspsiT0C); + histos.get(HIST("hOmegaPzVsPsi"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], cosThetaOmegaWithAlpha, 2 * cascminuspsiT0C); if (fillingConfigs.isFillTHN_PzFromLambda) - histos.get(HIST("hOmegaPzVsPsiFromLambda"))->Fill(coll.centFT0C(), ChargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], CosThetaProtonWithAlpha, 2 * cascminuspsiT0C); + histos.get(HIST("hOmegaPzVsPsiFromLambda"))->Fill(coll.centFT0C(), chargeIndex, casc.pt(), casc.mOmega(), BDTresponse[1], cosThetaProtonWithAlpha, 2 * cascminuspsiT0C); if (casc.mLambda() > CandidateConfigs.MinLambdaMass && casc.mLambda() < CandidateConfigs.MaxLambdaMass) { if (fillingConfigs.isFillTHN_Acc) - histos.get(HIST("hOmegaCos2ThetaVsPsi"))->Fill(coll.centFT0C(), ChargeIndex, casc.eta(), casc.pt(), casc.mOmega(), BDTresponse[1], Cos2ThetaOmega, 2 * cascminuspsiT0C); + histos.get(HIST("hOmegaCos2ThetaVsPsi"))->Fill(coll.centFT0C(), chargeIndex, casc.eta(), casc.pt(), casc.mOmega(), BDTresponse[1], cos2ThetaOmega, 2 * cascminuspsiT0C); } if (fillingConfigs.isFillTHN_AccFromLambdaVsCasc) - histos.get(HIST("hOmegaCos2ThetaVsPsiFromLambda"))->Fill(coll.centFT0C(), ChargeIndex, casc.eta(), casc.pt(), casc.mOmega(), BDTresponse[1], Cos2ThetaLambda, 2 * cascminuspsiT0C); + histos.get(HIST("hOmegaCos2ThetaVsPsiFromLambda"))->Fill(coll.centFT0C(), chargeIndex, casc.eta(), casc.pt(), casc.mOmega(), BDTresponse[1], cos2ThetaLambda, 2 * cascminuspsiT0C); if (casc.mOmega() > CandidateConfigs.MinOmegaMass && casc.mOmega() < CandidateConfigs.MaxOmegaMass) { if (fillingConfigs.isFillTHN_AccFromLambdaVsLambda) - histos.get(HIST("hOmegaCos2ThetaVsPsiFromLambdaL"))->Fill(coll.centFT0C(), ChargeIndex, etaLambda, ptLambda, casc.mLambda(), BDTresponse[1], Cos2ThetaLambda, 2 * cascminuspsiT0C); + histos.get(HIST("hOmegaCos2ThetaVsPsiFromLambdaL"))->Fill(coll.centFT0C(), chargeIndex, etaLambda, ptLambda, casc.mLambda(), BDTresponse[1], cos2ThetaLambda, 2 * cascminuspsiT0C); histos.get(HIST("massOmega_ProtonAcc"))->Fill(casc.mOmega()); } } @@ -1323,11 +1596,215 @@ struct cascadeFlow { if (isSelectedCasc[0] || isSelectedCasc[1]) { if (fillingConfigs.isFillTree) - fillAnalysedTable(coll, hasEventPlane, 0, casc, v2CSP, v2CEP, 0, 0, PsiT0C, BDTresponse[0], BDTresponse[1], 0); + fillAnalysedTable(coll, hasEventPlane, 0, casc, v2CSP, v2CEP, 0, 0, psiT0CCorr, BDTresponse[0], BDTresponse[1], 0); } } } + void processAnalyseLambdaEP2CentralFW(CollEventPlaneCentralFW const& coll, V0Candidates const& V0s, DauTracks const&) + { + + if (!AcceptEvent(coll, 1)) { + return; + } + + // select only events used for the calibration of the event plane + if (isGoodEventEP) { + if (std::abs(coll.qvecFT0CRe()) > 990 || std::abs(coll.qvecFT0CIm()) > 990 || std::abs(coll.qvecBNegRe()) > 990 || std::abs(coll.qvecBNegIm()) > 990 || std::abs(coll.qvecBPosRe()) > 990 || std::abs(coll.qvecBPosIm()) > 990) { + return; + } + } + + bool hasSpectatorPlane = 0; + bool hasEventPlane = 1; + + histos.fill(HIST("hNEvents"), 9.5); + histos.fill(HIST("hEventNchCorrelationAfterEP"), coll.multNTracksPVeta1(), coll.multNTracksGlobal()); + histos.fill(HIST("hEventPVcontributorsVsCentralityAfterEP"), coll.centFT0C(), coll.multNTracksPVeta1()); + histos.fill(HIST("hEventGlobalTracksVsCentralityAfterEP"), coll.centFT0C(), coll.multNTracksGlobal()); + + histos.fill(HIST("hEventCentrality"), coll.centFT0C()); + histos.fill(HIST("hEventVertexZ"), coll.posZ()); + + ROOT::Math::XYZVector eventplaneVecT0C{coll.qvecFT0CRe(), coll.qvecFT0CIm(), 0}; + ROOT::Math::XYZVector eventplaneVecTPCA{coll.qvecBPosRe(), coll.qvecBPosIm(), 0}; + ROOT::Math::XYZVector eventplaneVecTPCC{coll.qvecBNegRe(), coll.qvecBNegIm(), 0}; + + const float psiT0C = std::atan2(coll.qvecFT0CIm(), coll.qvecFT0CRe()) * 0.5f; + const float psiTPCA = std::atan2(coll.qvecBPosIm(), coll.qvecBPosRe()) * 0.5f; + const float psiTPCC = std::atan2(coll.qvecBNegIm(), coll.qvecBNegRe()) * 0.5f; + float psiT0CCorr = psiT0C; + if (cfgShiftCorr) { + currentRunNumber = coll.runNumber(); + if (currentRunNumber != lastRunNumber) { + shiftprofile.clear(); + for (int i = 2; i < cfgnMods + 2; i++) { + fullCCDBShiftCorrPath = cfgShiftPath; + fullCCDBShiftCorrPath += "/v"; + fullCCDBShiftCorrPath += std::to_string(i); + auto objshift = ccdb->getForTimeStamp(fullCCDBShiftCorrPath, coll.timestamp()); + shiftprofile.push_back(objshift); + } + lastRunNumber = currentRunNumber; + } + } + if (cfgShiftCorr) { + psiT0CCorr = ApplyShiftCorrection(coll, psiT0C); + ComputeEPResolutionwShifts(coll, psiT0C, psiTPCA, psiTPCC); + } + histos.fill(HIST("hPsiT0C"), psiT0CCorr); + histos.fill(HIST("hPsiT0CvsCentFT0C"), coll.centFT0C(), psiT0CCorr); + + resolution.fill(HIST("QVectorsT0CTPCA"), eventplaneVecT0C.Dot(eventplaneVecTPCA), coll.centFT0C()); + resolution.fill(HIST("QVectorsT0CTPCC"), eventplaneVecT0C.Dot(eventplaneVecTPCC), coll.centFT0C()); + resolution.fill(HIST("QVectorsTPCAC"), eventplaneVecTPCA.Dot(eventplaneVecTPCC), coll.centFT0C()); + resolution.fill(HIST("QVectorsNormT0CTPCA"), eventplaneVecT0C.Dot(eventplaneVecTPCA) / (coll.qTPCR() * coll.sumAmplFT0C()), coll.centFT0C()); + resolution.fill(HIST("QVectorsNormT0CTPCC"), eventplaneVecT0C.Dot(eventplaneVecTPCC) / (coll.qTPCL() * coll.sumAmplFT0C()), coll.centFT0C()); + resolution.fill(HIST("QVectorsNormTPCAC"), eventplaneVecTPCA.Dot(eventplaneVecTPCC) / (coll.qTPCR() * coll.qTPCL()), coll.centFT0C()); + + std::vector bdtScore[nParticles]; + for (auto const& v0 : V0s) { + + /// Add some minimal cuts for single track variables (min number of TPC clusters) + auto negExtra = v0.negTrackExtra_as(); + auto posExtra = v0.posTrackExtra_as(); + + int counterLambda = 0; + int counterALambda = 0; + bool isLambdaCandidate = 0; + bool isALambdaCandidate = 0; + if (isLambdaAccepted(negExtra, posExtra, counterLambda)) + isLambdaCandidate = 1; + if (isAntiLambdaAccepted(negExtra, posExtra, counterALambda)) + isALambdaCandidate = 1; + histos.fill(HIST("hLambdaDauSel"), counterLambda); + histos.fill(HIST("hALambdaDauSel"), counterALambda); + + // pt cut + if (v0.pt() < V0Configs.MinPtV0 || v0.pt() > V0Configs.MaxPtV0) { + continue; + } + + float massV0[nCharges]{v0.mLambda(), v0.mAntiLambda()}; + lambdav2::hMassBeforeSelVsPt[0]->Fill(massV0[0], v0.pt()); + lambdav2::hMassBeforeSelVsPt[1]->Fill(massV0[1], v0.pt()); + + bool isSelectedV0[2]{false, false}; + if (isV0TopoAccepted(v0) && isLambdaCandidate) + isSelectedV0[0] = true; + if (isV0TopoAccepted(v0) && isALambdaCandidate) + isSelectedV0[1] = true; + + int chargeIndex = -1; + if (isSelectedV0[0] && !isSelectedV0[1]) { // Lambdas + histos.fill(HIST("hLambdaCandidate"), 0); + chargeIndex = 0; + } + if (isSelectedV0[1] && !isSelectedV0[0]) { // AntiLambdas + histos.fill(HIST("hLambdaCandidate"), 1); + chargeIndex = 1; + } + if (isSelectedV0[0] && isSelectedV0[1]) { + histos.fill(HIST("hLambdaCandidate"), 2); + if (v0.mLambda() > V0Configs.MinMassLambda && v0.mLambda() < V0Configs.MaxMassLambda && v0.mAntiLambda() > V0Configs.MinMassLambda && v0.mAntiLambda() < V0Configs.MaxMassLambda) { + histos.fill(HIST("hLambdaCandidate"), 3); + continue; // in case of ambiguity between Lambda and AntiLambda, I skip the particle; checked to be zero in range 1.105 - 1.125 + } + if (v0.mLambda() > V0Configs.MinMassLambda && v0.mLambda() < V0Configs.MaxMassLambda) + chargeIndex = 0; + else if (v0.mAntiLambda() > V0Configs.MinMassLambda && v0.mAntiLambda() < V0Configs.MaxMassLambda) + chargeIndex = 1; + else { + chargeIndex = 2; // these are bkg candidates + histos.fill(HIST("hLambdaCandidate"), 4); + } + } + if (!isSelectedV0[0] && !isSelectedV0[1]) + continue; + + ROOT::Math::XYZVector lambdaQvec{std::cos(2 * v0.phi()), std::sin(2 * v0.phi()), 0}; + auto v2CSP = lambdaQvec.Dot(eventplaneVecT0C); // not normalised by amplitude + auto lambdaminuspsiT0C = GetPhiInRange(v0.phi() - psiT0CCorr); + auto v2CEP = std::cos(2.0 * lambdaminuspsiT0C); + ROOT::Math::XYZVector lambdaUvec{std::cos(v0.phi()), std::sin(v0.phi()), 0}; + + // polarization variables + double massLambda = o2::constants::physics::MassLambda; + float cosThetaStarProton[nCharges]; + ROOT::Math::PxPyPzMVector lambdaVector, protonVector[nCharges]; + lambdaVector.SetCoordinates(v0.px(), v0.py(), v0.pz(), massLambda); + ROOT::Math::Boost lambdaBoost{lambdaVector.BoostToCM()}; + for (int i{0}; i < nCharges; ++i) { + if (i == 0) + protonVector[i].SetCoordinates(v0.pxpos(), v0.pypos(), v0.pzpos(), o2::constants::physics::MassProton); + else + protonVector[i].SetCoordinates(v0.pxneg(), v0.pyneg(), v0.pzneg(), o2::constants::physics::MassProton); + auto boostedProton{lambdaBoost(protonVector[i])}; + cosThetaStarProton[i] = boostedProton.Pz() / boostedProton.P(); + } + + // acceptance values if requested + double meanCos2ThetaProtonFromLambda = 1; + if (applyAcceptanceCorrection) { + int bin2DLambda = hAcceptanceLambda->FindBin(v0.pt(), v0.eta()); + meanCos2ThetaProtonFromLambda = hAcceptancePrimaryLambda->GetBinContent(bin2DLambda); + } + + double pzs2Lambda = 0; + double cos2ThetaLambda = 0; + double cosThetaLambda = 0; + if (chargeIndex == 0) { + pzs2Lambda = cosThetaStarProton[0] * std::sin(2 * (v0.phi() - psiT0CCorr)) / lambdav2::AlphaLambda[0] / meanCos2ThetaProtonFromLambda; + cos2ThetaLambda = cosThetaStarProton[0] * cosThetaStarProton[0]; + cosThetaLambda = cosThetaStarProton[0] / cascadev2::AlphaLambda[0] / meanCos2ThetaProtonFromLambda; + } else if (chargeIndex == 1) { + pzs2Lambda = cosThetaStarProton[1] * std::sin(2 * (v0.phi() - psiT0CCorr)) / lambdav2::AlphaLambda[1] / meanCos2ThetaProtonFromLambda; + cos2ThetaLambda = cosThetaStarProton[1] * cosThetaStarProton[1]; + cosThetaLambda = cosThetaStarProton[1] / cascadev2::AlphaLambda[1] / meanCos2ThetaProtonFromLambda; + } else { // I treat these bkg candidates as Lambdas for the purpose of calculating Pz + pzs2Lambda = cosThetaStarProton[0] * std::sin(2 * (v0.phi() - psiT0CCorr)) / lambdav2::AlphaLambda[0] / meanCos2ThetaProtonFromLambda; + cos2ThetaLambda = cosThetaStarProton[0] * cosThetaStarProton[0]; + cosThetaLambda = cosThetaStarProton[0] / cascadev2::AlphaLambda[0] / meanCos2ThetaProtonFromLambda; + } + + histos.fill(HIST("hv2CEPvsFT0C"), coll.centFT0C(), v2CEP); + histos.fill(HIST("hv2CEPvsv2CSP"), v2CSP, v2CEP); + histos.fill(HIST("hLambdaPhi"), v0.phi()); + histos.fill(HIST("hlambdaminuspsiT0C"), lambdaminuspsiT0C); + + if (fillingConfigs.isFillTHNLambda) { + if (fillingConfigs.isFillTHN_V2) + histos.get(HIST("hLambdaV2"))->Fill(coll.centFT0C(), chargeIndex, v0.pt(), v0.mLambda(), v2CEP); + if (fillingConfigs.isFillTHN_Pz) { + histos.get(HIST("hLambdaPzs2"))->Fill(coll.centFT0C(), chargeIndex, v0.pt(), v0.mLambda(), pzs2Lambda); + } + if (fillingConfigs.isFillTHN_Acc) + histos.get(HIST("hLambdaCos2Theta"))->Fill(coll.centFT0C(), chargeIndex, v0.eta(), v0.pt(), v0.mLambda(), cos2ThetaLambda); + } + if (fillingConfigs.isFillTHNLambda_PzVsPsi) { + if (fillingConfigs.isFillTHN_Pz) + histos.get(HIST("hLambdaPzVsPsi"))->Fill(coll.centFT0C(), chargeIndex, v0.pt(), v0.mLambda(), cosThetaLambda, 2 * lambdaminuspsiT0C); + if (fillingConfigs.isFillTHN_Acc) + histos.get(HIST("hLambdaCos2ThetaVsPsi"))->Fill(coll.centFT0C(), chargeIndex, v0.eta(), v0.pt(), v0.mLambda(), cos2ThetaLambda, 2 * lambdaminuspsiT0C); + } + + double invMassLambda = 0; + if (chargeIndex == 0) + invMassLambda = v0.mLambda(); + else if (chargeIndex == 1) + invMassLambda = v0.mAntiLambda(); + else + invMassLambda = v0.mLambda(); + + // mass selection + if (invMassLambda < V0Configs.MinMassLambdaInTree || invMassLambda > V0Configs.MaxMassLambdaInTree) + continue; + + if (fillingConfigs.isFillTree) + fillAnalysedLambdaTable(coll, hasEventPlane, hasSpectatorPlane, chargeIndex, v0, v2CEP, psiT0CCorr, pzs2Lambda, cos2ThetaLambda, cosThetaLambda); + } + } + void processAnalyseDataEPCentralFW(CollEventAndSpecPlaneCentralFW const& coll, CascCandidates const& Cascades, DauTracks const&) { @@ -1370,9 +1847,30 @@ struct cascadeFlow { float NormQvTPCA = std::sqrt(eventplaneVecTPCA.Dot(eventplaneVecTPCA)); float NormQvTPCC = std::sqrt(eventplaneVecTPCC.Dot(eventplaneVecTPCC)); - const float PsiT0C = std::atan2(coll.qvecFT0CIm(), coll.qvecFT0CRe()) * 0.5f; - histos.fill(HIST("hPsiT0C"), PsiT0C); - histos.fill(HIST("hPsiT0CvsCentFT0C"), coll.centFT0C(), PsiT0C); + const float psiT0C = std::atan2(coll.qvecFT0CIm(), coll.qvecFT0CRe()) * 0.5f; + const float psiTPCA = std::atan2(coll.qvecBPosIm(), coll.qvecBPosRe()) * 0.5f; + const float psiTPCC = std::atan2(coll.qvecBNegIm(), coll.qvecBNegRe()) * 0.5f; + float psiT0CCorr = psiT0C; + if (cfgShiftCorr) { + currentRunNumber = coll.runNumber(); + if (currentRunNumber != lastRunNumber) { + shiftprofile.clear(); + for (int i = 2; i < cfgnMods + 2; i++) { + fullCCDBShiftCorrPath = cfgShiftPath; + fullCCDBShiftCorrPath += "/v"; + fullCCDBShiftCorrPath += std::to_string(i); + auto objshift = ccdb->getForTimeStamp(fullCCDBShiftCorrPath, coll.timestamp()); + shiftprofile.push_back(objshift); + } + lastRunNumber = currentRunNumber; + } + } + if (cfgShiftCorr) { + psiT0CCorr = ApplyShiftCorrection(coll, psiT0C); + ComputeEPResolutionwShifts(coll, psiT0C, psiTPCA, psiTPCC); + } + histos.fill(HIST("hpsiT0C"), psiT0CCorr); + histos.fill(HIST("hpsiT0CvsCentFT0C"), coll.centFT0C(), psiT0CCorr); resolution.fill(HIST("QVectorsT0CTPCA"), eventplaneVecT0C.Dot(eventplaneVecTPCA), coll.centFT0C()); resolution.fill(HIST("QVectorsT0CTPCC"), eventplaneVecT0C.Dot(eventplaneVecTPCC), coll.centFT0C()); @@ -1391,8 +1889,12 @@ struct cascadeFlow { auto bachExtra = casc.bachTrackExtra_as(); int counter = 0; - IsCascAccepted(casc, negExtra, posExtra, bachExtra, counter); + bool isCascCandidate = 0; + isCascCandidate = IsCascAccepted(casc, negExtra, posExtra, bachExtra, counter); histos.fill(HIST("hCascade"), counter); + histos.fill(HIST("hCascadeDauSel"), (int)isCascCandidate); + if (!isCascCandidate) + continue; // ML selections bool isSelectedCasc[nParticles]{false, false}; @@ -1444,7 +1946,7 @@ struct cascadeFlow { ROOT::Math::XYZVector cascQvec{std::cos(2 * casc.phi()), std::sin(2 * casc.phi()), 0}; auto v2CSP = cascQvec.Dot(eventplaneVecT0C); - auto cascminuspsiT0C = GetPhiInRange(casc.phi() - PsiT0C); + auto cascminuspsiT0C = GetPhiInRange(casc.phi() - psiT0CCorr); auto v2CEP = std::cos(2.0 * cascminuspsiT0C); ROOT::Math::XYZVector cascUvec{std::cos(casc.phi()), std::sin(casc.phi()), 0}; auto v1SP_ZDCA = cascUvec.Dot(spectatorplaneVecZDCA); @@ -1476,7 +1978,7 @@ struct cascadeFlow { } if (isSelectedCasc[0] || isSelectedCasc[1]) if (fillingConfigs.isFillTree) - fillAnalysedTable(coll, hasEventPlane, hasSpectatorPlane, casc, v2CSP, v2CEP, v1SP_ZDCA, v1SP_ZDCC, PsiT0C, BDTresponse[0], BDTresponse[1], 0); + fillAnalysedTable(coll, hasEventPlane, hasSpectatorPlane, casc, v2CSP, v2CEP, v1SP_ZDCA, v1SP_ZDCC, psiT0CCorr, BDTresponse[0], BDTresponse[1], 0); } } @@ -1488,7 +1990,7 @@ struct cascadeFlow { } bool hasEventPlane = 0; // no info at the moment - bool hasSpectatorPlane = 0; // no infor at the moment + bool hasSpectatorPlane = 0; // no info at the moment histos.fill(HIST("hNEvents"), 9.5); histos.fill(HIST("hEventNchCorrelationAfterEP"), coll.multNTracksPVeta1(), coll.multNTracksGlobal()); @@ -1537,8 +2039,12 @@ struct cascadeFlow { auto bachExtra = casc.bachTrackExtra_as(); int counter = 0; - IsCascAccepted(casc, negExtra, posExtra, bachExtra, counter); + bool isCascCandidate = 0; + isCascCandidate = IsCascAccepted(casc, negExtra, posExtra, bachExtra, counter); histos.fill(HIST("hCascade"), counter); + histos.fill(HIST("hCascadeDauSel"), (int)isCascCandidate); + if (!isCascCandidate) + continue; // ML selections bool isSelectedCasc[nParticles]{false, false}; @@ -1590,7 +2096,7 @@ struct cascadeFlow { histos.fill(HIST("hCascadePhi"), casc.phi()); float BDTresponse[nParticles]{0.f, 0.f}; - const float PsiT0C = 0; // not defined in MC for now + const float psiT0C = 0; // not defined in MC for now auto v2CSP = 0; // not defined in MC for now auto v2CEP = 0; // not defined in MC for now auto v1SP_ZDCA = 0; // not defined in MC for now @@ -1605,7 +2111,7 @@ struct cascadeFlow { continue; } if (isSelectedCasc[0] || isSelectedCasc[1]) - fillAnalysedTable(coll, hasEventPlane, hasSpectatorPlane, casc, v2CSP, v2CEP, v1SP_ZDCA, v1SP_ZDCC, PsiT0C, BDTresponse[0], BDTresponse[1], pdgCode); + fillAnalysedTable(coll, hasEventPlane, hasSpectatorPlane, casc, v2CSP, v2CEP, v1SP_ZDCA, v1SP_ZDCC, psiT0C, BDTresponse[0], BDTresponse[1], pdgCode); } } @@ -1707,6 +2213,7 @@ struct cascadeFlow { PROCESS_SWITCH(cascadeFlow, processAnalyseData, "Process to apply ML model to the data", false); PROCESS_SWITCH(cascadeFlow, processAnalyseDataEP2CentralFW, "Process to apply ML model to the data - second order event plane calibration from central framework", false); PROCESS_SWITCH(cascadeFlow, processAnalyseDataEPCentralFW, "Process to apply ML model to the data - event plane calibration from central framework", false); + PROCESS_SWITCH(cascadeFlow, processAnalyseLambdaEP2CentralFW, "Process to measure flow and polarization of Lambda - event plane calibration from central framework", false); PROCESS_SWITCH(cascadeFlow, processAnalyseMC, "Process to apply ML model to the MC", false); PROCESS_SWITCH(cascadeFlow, processMCGen, "Process to store MC generated particles", false); }; diff --git a/PWGLF/TableProducer/Strangeness/cascadepid.cxx b/PWGLF/TableProducer/Strangeness/cascadepid.cxx deleted file mode 100644 index 3c7c82dacdd..00000000000 --- a/PWGLF/TableProducer/Strangeness/cascadepid.cxx +++ /dev/null @@ -1,632 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -// -// *+-+*+-+*+-+*+-+*+-+*+-+* -// Cascade PID tables -// *+-+*+-+*+-+*+-+*+-+*+-+* -// -/// \author Nicolò Jacazio -/// \author David Dobrigkeit Chinellato -/// \since 22/11/2023 -/// \brief Table producer for Casc daughter PID info -// -// This task produces daughter PID information for strange daughters -// taking into account the (candidate-by-candidate) time spent as a heavier -// (strange, weakly-decaying) particle. This task is meant to be a test, as -// it hasn't been fully tested yet! Use at your own peril for now :-) - -#include -#include -#include -#include -#include -#include - -#include "Framework/runDataProcessing.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "DCAFitter/DCAFitterN.h" -#include "ReconstructionDataFormats/Track.h" -#include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/LFStrangenessPIDTables.h" -#include "PWGLF/DataModel/LFParticleIdentification.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "CCDB/BasicCCDBManager.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Common/TableProducer/PID/pidTOFBase.h" -#include "Common/DataModel/PIDResponse.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; -using std::array; - -// For original data loops -using CascOriginalDatas = soa::Join; -using TracksWithAllExtras = soa::Join; - -// Cores with references and TOF pid -using dauTracks = soa::Join; -using CascDerivedDatas = soa::Join; - -struct cascadepid { - // TOF pid for strangeness (recalculated with topology) - Produces casctofpids; // table with base info - Produces casctofnsigmas; // table with Nsigmas - - Service ccdb; - - // For manual sliceBy - Preslice perCollisionOriginal = o2::aod::cascdata::collisionId; - ; - Preslice perCollisionDerived = o2::aod::cascdata::straCollisionId; - - HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - - // Operation and minimisation criteria - Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; - Configurable tofPosition{"tofPosition", 377.934f, "TOF effective (inscribed) radius"}; - Configurable doQA{"doQA", true, "create QA histos"}; - Configurable qaV0DCADau{"qaV0DCADau", 0.5, "DCA daughters (cm) for QA plots"}; - Configurable qaCascDCADau{"qaCascDCADau", 0.5, "DCA daughters (cm) for QA plots"}; - Configurable qaV0CosPA{"qaV0CosPA", 0.995, "CosPA for QA plots"}; - Configurable qaCascCosPA{"qaCascCosPA", 0.995, "CosPA for QA plots"}; - Configurable qaMassWindow{"qaMassWindow", 0.005, "Mass window around expected (in GeV/c2) for QA plots"}; - Configurable qaTPCNSigma{"qaTPCNSigma", 5, "TPC N-sigma to apply for qa plots"}; - Configurable doNSigmas{"doNSigmas", false, "calculate TOF N-sigma"}; - Configurable doQANSigma{"doQANSigma", false, "create QA of Nsigma histos"}; - - // CCDB options - Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; - Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; - Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; - Configurable nSigmaPath{"nSigmaPath", "Users/d/ddobrigk/stratof", "Path of information for n-sigma calculation"}; - - // manual - Configurable useCustomRunNumber{"useCustomRunNumber", false, "Use custom timestamp"}; - Configurable manualRunNumber{"manualRunNumber", 544122, "manual run number if no collisions saved"}; - - ConfigurableAxis axisEta{"axisEta", {20, -1.0f, +1.0f}, "#eta"}; - ConfigurableAxis axisDeltaTime{"axisDeltaTime", {2000, -1000.0f, +1000.0f}, "delta-time (ps)"}; - ConfigurableAxis axisNSigma{"axisNSigma", {200, -10.0f, +10.0f}, "N(#sigma)"}; - ConfigurableAxis axisTime{"axisTime", {200, 0.0f, +20000.0f}, "T (ps)"}; - 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}, "p_{T} (GeV/c)"}; - - bool nSigmaCalibLoaded; - TList* nSigmaCalibObjects; - TH1 *hMeanPosXiPi, *hSigmaPosXiPi; - TH1 *hMeanPosXiPr, *hSigmaPosXiPr; - TH1 *hMeanNegXiPi, *hSigmaNegXiPi; - TH1 *hMeanNegXiPr, *hSigmaNegXiPr; - TH1 *hMeanBachXiPi, *hSigmaBachXiPi; - TH1 *hMeanPosOmPi, *hSigmaPosOmPi; - TH1 *hMeanPosOmPr, *hSigmaPosOmPr; - TH1 *hMeanNegOmPi, *hSigmaNegOmPi; - TH1 *hMeanNegOmPr, *hSigmaNegOmPr; - TH1 *hMeanBachOmKa, *hSigmaBachOmKa; - - int mRunNumber; - float d_bz; - float maxSnp; // max sine phi for propagation - float maxStep; // max step size (cm) for propagation - - /// function to calculate track length of this track up to a certain segment of a detector - /// to be used internally in another funcrtion that calculates length until it finds the proper one - /// warning: this could be optimised further for speed - /// \param track the input track - /// \param x1 x of the first point of the detector segment - /// \param y1 y of the first point of the detector segment - /// \param x2 x of the first point of the detector segment - /// \param y2 y of the first point of the detector segment - /// \param magneticField the magnetic field to use when propagating - float trackLengthToSegment(o2::track::TrackPar track, float x1, float y1, float x2, float y2, float magneticField) - { - // don't make use of the track parametrization - float length = -104; - - // causality protection - std::array mom; - track.getPxPyPzGlo(mom); - // get start point - std::array startPoint; - track.getXYZGlo(startPoint); - - // better replaced with scalar momentum check later - // if (((x1 + x2) * mom[0] + (y1 + y2) * mom[1]) < 0.0f) - // return -101; - - // get circle X, Y please - o2::math_utils::CircleXYf_t trcCircle; - float sna, csa; - track.getCircleParams(magneticField, trcCircle, sna, csa); - - // Calculate necessary inner product - float segmentModulus = std::hypot(x2 - x1, y2 - y1); - float alongSegment = ((trcCircle.xC - x1) * (x2 - x1) + (trcCircle.yC - y1) * (y2 - y1)) / segmentModulus; - - // find point of closest approach between segment and circle center - float pcaX = (x2 - x1) * alongSegment / segmentModulus + x1; - float pcaY = (y2 - y1) * alongSegment / segmentModulus + y1; - - float centerDistToPC = std::hypot(pcaX - trcCircle.xC, pcaY - trcCircle.yC); - - // distance pca-to-intercept in multiples of segment modulus (for convenience) - if (centerDistToPC > trcCircle.rC) - return -103; - - float pcaToIntercept = TMath::Sqrt(TMath::Abs(trcCircle.rC * trcCircle.rC - centerDistToPC * centerDistToPC)); - - float interceptX1 = pcaX + (x2 - x1) / segmentModulus * pcaToIntercept; - float interceptY1 = pcaY + (y2 - y1) / segmentModulus * pcaToIntercept; - float interceptX2 = pcaX - (x2 - x1) / segmentModulus * pcaToIntercept; - float interceptY2 = pcaY - (y2 - y1) / segmentModulus * pcaToIntercept; - - float scalarCheck1 = ((x2 - x1) * (interceptX1 - x1) + (y2 - y1) * (interceptY1 - y1)) / segmentModulus; - float scalarCheck2 = ((x2 - x1) * (interceptX2 - x1) + (y2 - y1) * (interceptY2 - y1)) / segmentModulus; - - float cosAngle1 = -1000, sinAngle1 = -1000, modulus1 = -1000; - float cosAngle2 = -1000, sinAngle2 = -1000, modulus2 = -1000; - float length1 = -1000, length2 = -1000; - - modulus1 = std::hypot(interceptX1 - trcCircle.xC, interceptY1 - trcCircle.yC) * std::hypot(startPoint[0] - trcCircle.xC, startPoint[1] - trcCircle.yC); - cosAngle1 = (interceptX1 - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (interceptY1 - trcCircle.yC) * (startPoint[1] - trcCircle.yC); - sinAngle1 = (interceptX1 - trcCircle.xC) * (startPoint[1] - trcCircle.yC) - (interceptY1 - trcCircle.yC) * (startPoint[0] - trcCircle.xC); - cosAngle1 /= modulus1; - sinAngle1 /= modulus1; - length1 = trcCircle.rC * TMath::ACos(cosAngle1); - length1 *= sqrt(1.0f + track.getTgl() * track.getTgl()); - - modulus2 = std::hypot(interceptX2 - trcCircle.xC, interceptY2 - trcCircle.yC) * std::hypot(startPoint[0] - trcCircle.xC, startPoint[1] - trcCircle.yC); - cosAngle2 = (interceptX2 - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (interceptY2 - trcCircle.yC) * (startPoint[1] - trcCircle.yC); - sinAngle2 = (interceptX2 - trcCircle.xC) * (startPoint[1] - trcCircle.yC) - (interceptY2 - trcCircle.yC) * (startPoint[0] - trcCircle.xC); - cosAngle2 /= modulus2; - sinAngle2 /= modulus2; - length2 = trcCircle.rC * TMath::ACos(cosAngle2); - length2 *= sqrt(1.0f + track.getTgl() * track.getTgl()); - - // rotate transverse momentum vector such that it is at intercepts - float angle1 = TMath::ACos(cosAngle1); - if (sinAngle1 < 0) - angle1 *= -1.0f; - float px1 = +TMath::Cos(angle1) * mom[0] + TMath::Sin(angle1) * mom[1]; - float py1 = -TMath::Sin(angle1) * mom[0] + TMath::Cos(angle1) * mom[1]; - - float angle2 = TMath::ACos(cosAngle2); - if (sinAngle2 < 0) - angle2 *= -1.0f; - float px2 = +TMath::Cos(angle2) * mom[0] + TMath::Sin(angle2) * mom[1]; - float py2 = -TMath::Sin(angle2) * mom[0] + TMath::Cos(angle2) * mom[1]; - - float midSegX = 0.5f * (x2 + x1); - float midSegY = 0.5f * (y2 + y1); - - float scalarMomentumCheck1 = px1 * midSegX + py1 * midSegY; - float scalarMomentumCheck2 = px2 * midSegX + py2 * midSegY; - - if (scalarCheck1 > 0.0f && scalarCheck1 < segmentModulus && scalarMomentumCheck1 > 0.0f) { - length = length1; - // X = interceptX1; Y = interceptY1; - } - if (scalarCheck2 > 0.0f && scalarCheck2 < segmentModulus && scalarMomentumCheck2 > 0.0f) { - length = length2; - // X = interceptX2; Y = interceptY2; - } - return length; - } - - /// function to calculate track length of this track up to a certain segmented detector - /// \param track the input track - /// \param magneticField the magnetic field to use when propagating - float findInterceptLength(o2::track::TrackPar track, float magneticField) - { - float length = 1e+6; - for (int iSeg = 0; iSeg < 18; iSeg++) { - // Detector segmentation loop - float segmentAngle = 20.0f / 180.0f * TMath::Pi(); - float theta = static_cast(iSeg) * 20.0f / 180.0f * TMath::Pi(); - float halfWidth = tofPosition * TMath::Tan(0.5f * segmentAngle); - float x1 = TMath::Cos(theta) * (-halfWidth) + TMath::Sin(theta) * tofPosition; - float y1 = -TMath::Sin(theta) * (-halfWidth) + TMath::Cos(theta) * tofPosition; - float x2 = TMath::Cos(theta) * (+halfWidth) + TMath::Sin(theta) * tofPosition; - float y2 = -TMath::Sin(theta) * (+halfWidth) + TMath::Cos(theta) * tofPosition; - float thisLength = trackLengthToSegment(track, x1, y1, x2, y2, magneticField); - if (thisLength < length && thisLength > 0) - length = thisLength; - } - if (length > 1e+5) - length = -100; // force negative to avoid misunderstandings - return length; - } - - void init(InitContext&) - { - mRunNumber = 0; - d_bz = 0; - maxSnp = 0.85f; // could be changed later - maxStep = 2.00f; // could be changed later - - ccdb->setURL(ccdburl); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - ccdb->setFatalWhenNull(false); - - nSigmaCalibLoaded = false; - nSigmaCalibObjects = nullptr; - - // measured vs expected total time QA - if (doQA) { - // standard deltaTime values - histos.add("hArcDebug", "hArcDebug", kTH2F, {axisPt, {500, -5.0f, 10.0f}}); - histos.add("h2dposDeltaTimeAsXiPi", "h2dposDeltaTimeAsXiPi", {HistType::kTH3F, {axisPt, axisEta, axisDeltaTime}}); - histos.add("h2dposDeltaTimeAsXiPr", "h2dposDeltaTimeAsXiPr", {HistType::kTH3F, {axisPt, axisEta, axisDeltaTime}}); - histos.add("h2dnegDeltaTimeAsXiPi", "h2dnegDeltaTimeAsXiPi", {HistType::kTH3F, {axisPt, axisEta, axisDeltaTime}}); - histos.add("h2dnegDeltaTimeAsXiPr", "h2dnegDeltaTimeAsXiPr", {HistType::kTH3F, {axisPt, axisEta, axisDeltaTime}}); - histos.add("h2dbachDeltaTimeAsXiPi", "h2dbachDeltaTimeAsXiPi", {HistType::kTH3F, {axisPt, axisEta, axisDeltaTime}}); - - histos.add("h2dposDeltaTimeAsOmPi", "h2dposDeltaTimeAsOmPi", {HistType::kTH3F, {axisPt, axisEta, axisDeltaTime}}); - histos.add("h2dposDeltaTimeAsOmPr", "h2dposDeltaTimeAsOmPr", {HistType::kTH3F, {axisPt, axisEta, axisDeltaTime}}); - histos.add("h2dnegDeltaTimeAsOmPi", "h2dnegDeltaTimeAsOmPi", {HistType::kTH3F, {axisPt, axisEta, axisDeltaTime}}); - histos.add("h2dnegDeltaTimeAsOmPr", "h2dnegDeltaTimeAsOmPr", {HistType::kTH3F, {axisPt, axisEta, axisDeltaTime}}); - histos.add("h2dbachDeltaTimeAsOmKa", "h2dbachDeltaTimeAsOmKa", {HistType::kTH3F, {axisPt, axisEta, axisDeltaTime}}); - } - - if (doQANSigma) { - // standard NSigma values - histos.add("h2dNSigmaXiLaPi", "h2dNSigmaXiLaPi", {HistType::kTH2F, {axisPt, axisNSigma}}); - histos.add("h2dNSigmaXiLaPr", "h2dNSigmaXiLaPr", {HistType::kTH2F, {axisPt, axisNSigma}}); - histos.add("h2dNSigmaXiPi", "h2dNSigmaXiPi", {HistType::kTH2F, {axisPt, axisNSigma}}); - histos.add("h2dNSigmaOmLaPi", "h2dNSigmaOmLaPi", {HistType::kTH2F, {axisPt, axisNSigma}}); - histos.add("h2dNSigmaOmLaPr", "h2dNSigmaOmLaPr", {HistType::kTH2F, {axisPt, axisNSigma}}); - histos.add("h2dNSigmaOmKa", "h2dNSigmaOmKa", {HistType::kTH2F, {axisPt, axisNSigma}}); - } - } - - void initCCDB(int runNumber) - { - if (mRunNumber == runNumber) { - return; - } - - // In case override, don't proceed, please - no CCDB access required - if (d_bz_input > -990) { - d_bz = d_bz_input; - o2::parameters::GRPMagField grpmag; - if (fabs(d_bz) > 1e-5) { - grpmag.setL3Current(30000.f / (d_bz / 5.0f)); - } - o2::base::Propagator::initFieldFromGRP(&grpmag); - mRunNumber = runNumber; - return; - } - - o2::parameters::GRPObject* grpo = ccdb->getForRun(grpPath, runNumber); - o2::parameters::GRPMagField* grpmag = 0x0; - if (grpo) { - o2::base::Propagator::initFieldFromGRP(grpo); - // Fetch magnetic field from ccdb for current collision - d_bz = grpo->getNominalL3Field(); - LOG(info) << "Retrieved GRP for run " << runNumber << " with magnetic field of " << d_bz << " kZG"; - } else { - grpmag = ccdb->getForRun(grpmagPath, runNumber); - if (!grpmag) { - LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for run " << runNumber; - } - o2::base::Propagator::initFieldFromGRP(grpmag); - // Fetch magnetic field from ccdb for current collision - d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); - LOG(info) << "Retrieved GRP for run " << runNumber << " with magnetic field of " << d_bz << " kZG"; - } - - // if TOF Nsigma desired - if (doNSigmas) { - nSigmaCalibObjects = ccdb->getForRun(nSigmaPath, runNumber); - if (nSigmaCalibObjects) { - LOGF(info, "loaded TList with this many objects: %i", nSigmaCalibObjects->GetEntries()); - - hMeanPosXiPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanPosXiPi")); - hMeanPosXiPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanPosXiPr")); - hMeanNegXiPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanNegXiPi")); - hMeanNegXiPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanNegXiPr")); - hMeanBachXiPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanBachXiPi")); - hMeanPosOmPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanPosOmPi")); - hMeanPosOmPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanPosOmPr")); - hMeanNegOmPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanNegOmPi")); - hMeanNegOmPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanNegOmPr")); - hMeanBachOmKa = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanBachOmKa")); - - hSigmaPosXiPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaPosXiPi")); - hSigmaPosXiPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaPosXiPr")); - hSigmaNegXiPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaNegXiPi")); - hSigmaNegXiPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaNegXiPr")); - hSigmaBachXiPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaBachXiPi")); - hSigmaPosOmPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaPosOmPi")); - hSigmaPosOmPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaPosOmPr")); - hSigmaNegOmPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaNegOmPi")); - hSigmaNegOmPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaNegOmPr")); - hSigmaBachOmKa = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaBachOmKa")); - - if (!hMeanPosXiPi || !hMeanPosXiPr || !hMeanNegXiPi || !hMeanNegXiPr || !hMeanBachXiPi) - LOG(info) << "Problems finding xi mean histograms!"; - if (!hMeanPosOmPi || !hMeanPosOmPr || !hMeanNegOmPi || !hMeanNegOmPr || !hMeanBachOmKa) - LOG(info) << "Problems finding omega sigma histograms!"; - if (!hSigmaPosXiPi || !hSigmaPosXiPr || !hSigmaNegXiPi || !hSigmaNegXiPr || !hSigmaBachXiPi) - LOG(info) << "Problems finding xi sigma histograms!"; - if (!hSigmaPosOmPi || !hSigmaPosOmPr || !hSigmaNegOmPi || !hSigmaNegOmPr || !hSigmaBachOmKa) - LOG(info) << "Problems finding omega sigma histograms!"; - } - } - mRunNumber = runNumber; - } - - float velocity(float lMomentum, float lMass) - { - // Momentum p and mass m -> returns speed in centimeters per picosecond - // Useful for TOF calculations - float lA = (lMomentum / lMass) * (lMomentum / lMass); - return 0.0299792458 * TMath::Sqrt(lA / (1 + lA)); - } - - template - void processCascadeCandidate(TCollision const& collision, TCascade const& cascade, TTrack const& pTra, TTrack const& nTra, TTrack const& bTra) - { - // initialize from positions and momenta as needed - o2::track::TrackPar posTrack = o2::track::TrackPar({cascade.xlambda(), cascade.ylambda(), cascade.zlambda()}, {cascade.pxpos(), cascade.pypos(), cascade.pzpos()}, +1); - o2::track::TrackPar negTrack = o2::track::TrackPar({cascade.xlambda(), cascade.ylambda(), cascade.zlambda()}, {cascade.pxneg(), cascade.pyneg(), cascade.pzneg()}, -1); - o2::track::TrackPar bachTrack = o2::track::TrackPar({cascade.x(), cascade.y(), cascade.z()}, {cascade.pxbach(), cascade.pybach(), cascade.pzbach()}, cascade.sign()); - o2::track::TrackPar cascTrack = o2::track::TrackPar({cascade.x(), cascade.y(), cascade.z()}, {cascade.px(), cascade.py(), cascade.pz()}, cascade.sign()); - - // start calculation: calculate velocities - float velocityPositivePr = velocity(posTrack.getP(), o2::constants::physics::MassProton); - float velocityPositivePi = velocity(posTrack.getP(), o2::constants::physics::MassPionCharged); - float velocityNegativePr = velocity(negTrack.getP(), o2::constants::physics::MassProton); - float velocityNegativePi = velocity(negTrack.getP(), o2::constants::physics::MassPionCharged); - float velocityBachelorPi = velocity(bachTrack.getP(), o2::constants::physics::MassPionCharged); - float velocityBachelorKa = velocity(bachTrack.getP(), o2::constants::physics::MassKaonCharged); - float velocityXi = velocity(cascTrack.getP(), o2::constants::physics::MassXiMinus); - float velocityOm = velocity(cascTrack.getP(), o2::constants::physics::MassOmegaMinus); - float velocityLa = velocity(std::hypot(cascade.pxlambda(), cascade.pylambda(), cascade.pzlambda()), o2::constants::physics::MassLambda); - - // calculate daughter length to TOF intercept - float lengthPositive = findInterceptLength(posTrack, d_bz); // FIXME: tofPosition ok? adjust? - float lengthNegative = findInterceptLength(negTrack, d_bz); // FIXME: tofPosition ok? adjust? - float lengthBachelor = findInterceptLength(bachTrack, d_bz); // FIXME: tofPosition ok? adjust? - - // calculate mother lengths - float lengthV0 = std::hypot(cascade.xlambda() - cascade.x(), cascade.ylambda() - cascade.y(), cascade.zlambda() - cascade.z()); - float lengthCascade = -1e+6; - const o2::math_utils::Point3D collVtx{collision.posX(), collision.posY(), collision.posZ()}; - bool successPropag = o2::base::Propagator::Instance()->propagateToDCA(collVtx, cascTrack, d_bz, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrNONE); - float d = -1.0f, d3d = 0.0f; - float linearToPV = std::hypot(cascade.x() - collision.posX(), cascade.y() - collision.posY(), cascade.z() - collision.posZ()); - if (successPropag) { - std::array cascCloseToPVPosition; - cascTrack.getXYZGlo(cascCloseToPVPosition); - o2::math_utils::CircleXYf_t trcCircleCascade; - float sna, csa; - cascTrack.getCircleParams(d_bz, trcCircleCascade, sna, csa); - - // calculate 2D distance between two points - d = std::hypot(cascade.x() - cascCloseToPVPosition[0], cascade.y() - cascCloseToPVPosition[1]); - d3d = std::hypot(cascade.x() - cascCloseToPVPosition[0], cascade.y() - cascCloseToPVPosition[1], cascade.z() - cascCloseToPVPosition[2]); // cross-check variable - float sinThetaOverTwo = d / (2.0f * trcCircleCascade.rC); - lengthCascade = 2.0f * trcCircleCascade.rC * TMath::ASin(sinThetaOverTwo); - lengthCascade *= sqrt(1.0f + cascTrack.getTgl() * cascTrack.getTgl()); - } - - if (!successPropag) { - lengthCascade = linearToPV; // if propagation failed, use linear estimate (optional: actually do not define?) - } - - // lambda, xi and omega flight time is always defined - float lambdaFlight = lengthV0 / velocityLa; - float xiFlight = lengthCascade / velocityXi; - float omFlight = lengthCascade / velocityOm; - float posFlightPi = lengthPositive / velocityPositivePi; - float posFlightPr = lengthPositive / velocityPositivePr; - float negFlightPi = lengthNegative / velocityNegativePi; - float negFlightPr = lengthNegative / velocityNegativePr; - float bachFlightPi = lengthBachelor / velocityBachelorPi; - float bachFlightKa = lengthBachelor / velocityBachelorKa; - - // initialize delta-times (actual PID variables) - float posDeltaTimeAsXiPi = -1e+6, posDeltaTimeAsXiPr = -1e+6; - float negDeltaTimeAsXiPi = -1e+6, negDeltaTimeAsXiPr = -1e+6; - float bachDeltaTimeAsXiPi = -1e+6; - float posDeltaTimeAsOmPi = -1e+6, posDeltaTimeAsOmPr = -1e+6; - float negDeltaTimeAsOmPi = -1e+6, negDeltaTimeAsOmPr = -1e+6; - float bachDeltaTimeAsOmKa = -1e+6; - - if (pTra.hasTOF()) { - posDeltaTimeAsXiPi = (pTra.tofSignal() - pTra.tofEvTime()) - (xiFlight + lambdaFlight + posFlightPi); - posDeltaTimeAsXiPr = (pTra.tofSignal() - pTra.tofEvTime()) - (xiFlight + lambdaFlight + posFlightPr); - posDeltaTimeAsOmPi = (pTra.tofSignal() - pTra.tofEvTime()) - (omFlight + lambdaFlight + posFlightPi); - posDeltaTimeAsOmPr = (pTra.tofSignal() - pTra.tofEvTime()) - (omFlight + lambdaFlight + posFlightPr); - } - if (nTra.hasTOF()) { - negDeltaTimeAsXiPi = (nTra.tofSignal() - nTra.tofEvTime()) - (xiFlight + lambdaFlight + negFlightPi); - negDeltaTimeAsXiPr = (nTra.tofSignal() - nTra.tofEvTime()) - (xiFlight + lambdaFlight + negFlightPr); - negDeltaTimeAsOmPi = (nTra.tofSignal() - nTra.tofEvTime()) - (omFlight + lambdaFlight + negFlightPi); - negDeltaTimeAsOmPr = (nTra.tofSignal() - nTra.tofEvTime()) - (omFlight + lambdaFlight + negFlightPr); - } - if (bTra.hasTOF()) { - bachDeltaTimeAsXiPi = (bTra.tofSignal() - bTra.tofEvTime()) - (xiFlight + bachFlightPi); - bachDeltaTimeAsOmKa = (bTra.tofSignal() - bTra.tofEvTime()) - (omFlight + bachFlightKa); - } - - casctofpids( - posDeltaTimeAsXiPi, posDeltaTimeAsXiPr, negDeltaTimeAsXiPi, negDeltaTimeAsXiPr, bachDeltaTimeAsXiPi, - posDeltaTimeAsOmPi, posDeltaTimeAsOmPr, negDeltaTimeAsOmPi, negDeltaTimeAsOmPr, bachDeltaTimeAsOmKa); - - float nSigmaXiLaPr = -1e+6; - float nSigmaXiLaPi = -1e+6; - float nSigmaXiPi = -1e+6; - float nSigmaOmLaPr = -1e+6; - float nSigmaOmLaPi = -1e+6; - float nSigmaOmKa = -1e+6; - - // go for Nsigma values if requested - if (doNSigmas) { - // Xi hypothesis ________________________ - if (cascade.sign() < 0) { // XiMinus - if (posDeltaTimeAsXiPr > -1e+5) // proton from Lambda from XiMinus has signal - nSigmaXiLaPr = (posDeltaTimeAsXiPr - hMeanPosXiPr->Interpolate(cascade.pt())) / hSigmaPosXiPr->Interpolate(cascade.pt()); - if (negDeltaTimeAsXiPi > -1e+5) // pion from Lambda from XiMinus has signal - nSigmaXiLaPi = (negDeltaTimeAsXiPi - hMeanNegXiPi->Interpolate(cascade.pt())) / hSigmaNegXiPi->Interpolate(cascade.pt()); - if (bachDeltaTimeAsXiPi > -1e+5) // pion from XiMinus has signal - nSigmaXiPi = (bachDeltaTimeAsXiPi - hMeanBachXiPi->Interpolate(cascade.pt())) / hSigmaBachXiPi->Interpolate(cascade.pt()); - if (posDeltaTimeAsOmPr > -1e+5) // proton from Lambda from OmegaMinus has signal - nSigmaOmLaPr = (posDeltaTimeAsOmPr - hMeanPosOmPr->Interpolate(cascade.pt())) / hSigmaPosOmPr->Interpolate(cascade.pt()); - if (negDeltaTimeAsOmPi > -1e+5) // pion from Lambda from OmegaMinus has signal - nSigmaOmLaPi = (negDeltaTimeAsOmPi - hMeanNegOmPi->Interpolate(cascade.pt())) / hSigmaNegOmPi->Interpolate(cascade.pt()); - if (bachDeltaTimeAsOmKa > -1e+5) // kaon from OmegaMinus has signal - nSigmaOmKa = (bachDeltaTimeAsOmKa - hMeanBachOmKa->Interpolate(cascade.pt())) / hSigmaBachOmKa->Interpolate(cascade.pt()); - } else { - if (posDeltaTimeAsXiPi > -1e+5) // proton from Lambda from XiMinus has signal - nSigmaXiLaPi = (posDeltaTimeAsXiPi - hMeanPosXiPi->Interpolate(cascade.pt())) / hSigmaPosXiPi->Interpolate(cascade.pt()); - if (negDeltaTimeAsXiPr > -1e+5) // pion from Lambda from XiMinus has signal - nSigmaXiLaPr = (negDeltaTimeAsXiPr - hMeanNegXiPr->Interpolate(cascade.pt())) / hSigmaNegXiPr->Interpolate(cascade.pt()); - if (bachDeltaTimeAsXiPi > -1e+5) // pion from XiMinus has signal - nSigmaXiPi = (bachDeltaTimeAsXiPi - hMeanBachXiPi->Interpolate(cascade.pt())) / hSigmaBachXiPi->Interpolate(cascade.pt()); - if (posDeltaTimeAsOmPi > -1e+5) // proton from Lambda from OmegaMinus has signal - nSigmaOmLaPi = (posDeltaTimeAsOmPi - hMeanPosOmPi->Interpolate(cascade.pt())) / hSigmaPosOmPi->Interpolate(cascade.pt()); - if (negDeltaTimeAsOmPr > -1e+5) // pion from Lambda from OmegaMinus has signal - nSigmaOmLaPr = (negDeltaTimeAsOmPr - hMeanNegOmPr->Interpolate(cascade.pt())) / hSigmaNegOmPr->Interpolate(cascade.pt()); - if (bachDeltaTimeAsOmKa > -1e+5) // kaon from OmegaMinus has signal - nSigmaOmKa = (bachDeltaTimeAsOmKa - hMeanBachOmKa->Interpolate(cascade.pt())) / hSigmaBachOmKa->Interpolate(cascade.pt()); - } - casctofnsigmas(nSigmaXiLaPi, nSigmaXiLaPr, nSigmaXiPi, nSigmaOmLaPi, nSigmaOmLaPr, nSigmaOmKa); - } - - if (doQA) { - // fill QA histograms for cross-checking - histos.fill(HIST("hArcDebug"), cascade.pt(), lengthCascade - d3d); // for debugging purposes - - if (cascade.dcaV0daughters() < qaV0DCADau && cascade.dcacascdaughters() < qaCascDCADau && cascade.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) > qaV0CosPA && cascade.casccosPA(collision.posX(), collision.posY(), collision.posZ()) > qaCascCosPA) { - if (cascade.sign() < 0) { - if (std::abs(cascade.mXi() - 1.32171) < qaMassWindow && fabs(pTra.tpcNSigmaPr()) < qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < qaTPCNSigma && fabs(bTra.tpcNSigmaPi()) < qaTPCNSigma) { - histos.fill(HIST("h2dposDeltaTimeAsXiPr"), cascade.pt(), cascade.eta(), posDeltaTimeAsXiPr); - histos.fill(HIST("h2dnegDeltaTimeAsXiPi"), cascade.pt(), cascade.eta(), negDeltaTimeAsXiPi); - histos.fill(HIST("h2dbachDeltaTimeAsXiPi"), cascade.pt(), cascade.eta(), bachDeltaTimeAsXiPi); - if (doQANSigma) { - histos.fill(HIST("h2dNSigmaXiLaPi"), cascade.pt(), nSigmaXiLaPi); - histos.fill(HIST("h2dNSigmaXiLaPr"), cascade.pt(), nSigmaXiLaPr); - histos.fill(HIST("h2dNSigmaXiPi"), cascade.pt(), nSigmaXiPi); - } - } - if (std::abs(cascade.mOmega() - 1.67245) < qaMassWindow && fabs(pTra.tpcNSigmaPr()) < qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < qaTPCNSigma && fabs(bTra.tpcNSigmaKa()) < qaTPCNSigma) { - histos.fill(HIST("h2dposDeltaTimeAsOmPr"), cascade.pt(), cascade.eta(), posDeltaTimeAsOmPr); - histos.fill(HIST("h2dnegDeltaTimeAsOmPi"), cascade.pt(), cascade.eta(), negDeltaTimeAsOmPi); - histos.fill(HIST("h2dbachDeltaTimeAsOmKa"), cascade.pt(), cascade.eta(), bachDeltaTimeAsOmKa); - if (doQANSigma) { - histos.fill(HIST("h2dNSigmaOmLaPi"), cascade.pt(), nSigmaOmLaPi); - histos.fill(HIST("h2dNSigmaOmLaPr"), cascade.pt(), nSigmaOmLaPr); - histos.fill(HIST("h2dNSigmaOmKa"), cascade.pt(), nSigmaOmKa); - } - } - } else { - if (std::abs(cascade.mXi() - 1.32171) < qaMassWindow && fabs(pTra.tpcNSigmaPi()) < qaTPCNSigma && fabs(nTra.tpcNSigmaPr()) < qaTPCNSigma && fabs(bTra.tpcNSigmaPi()) < qaTPCNSigma) { - histos.fill(HIST("h2dposDeltaTimeAsXiPi"), cascade.pt(), cascade.eta(), posDeltaTimeAsXiPi); - histos.fill(HIST("h2dnegDeltaTimeAsXiPr"), cascade.pt(), cascade.eta(), negDeltaTimeAsXiPr); - histos.fill(HIST("h2dbachDeltaTimeAsXiPi"), cascade.pt(), cascade.eta(), bachDeltaTimeAsXiPi); - if (doQANSigma) { - histos.fill(HIST("h2dNSigmaXiLaPi"), cascade.pt(), nSigmaXiLaPi); - histos.fill(HIST("h2dNSigmaXiLaPr"), cascade.pt(), nSigmaXiLaPr); - histos.fill(HIST("h2dNSigmaXiPi"), cascade.pt(), nSigmaXiPi); - } - } - if (std::abs(cascade.mOmega() - 1.67245) < qaMassWindow && fabs(pTra.tpcNSigmaPi()) < qaTPCNSigma && fabs(nTra.tpcNSigmaPr()) < qaTPCNSigma && fabs(bTra.tpcNSigmaKa()) < qaTPCNSigma) { - histos.fill(HIST("h2dposDeltaTimeAsOmPi"), cascade.pt(), cascade.eta(), posDeltaTimeAsOmPi); - histos.fill(HIST("h2dnegDeltaTimeAsOmPr"), cascade.pt(), cascade.eta(), negDeltaTimeAsOmPr); - histos.fill(HIST("h2dbachDeltaTimeAsOmKa"), cascade.pt(), cascade.eta(), bachDeltaTimeAsOmKa); - if (doQANSigma) { - histos.fill(HIST("h2dNSigmaOmLaPi"), cascade.pt(), nSigmaOmLaPi); - histos.fill(HIST("h2dNSigmaOmLaPr"), cascade.pt(), nSigmaOmLaPr); - histos.fill(HIST("h2dNSigmaOmKa"), cascade.pt(), nSigmaOmKa); - } - } - } - } - } - } - - void processStandardData(aod::Collisions const& collisions, CascOriginalDatas const& Cascades, TracksWithAllExtras const&, aod::BCsWithTimestamps const& /*bcs*/) - { - // Fire up CCDB with first collision in record. If no collisions, bypass - if (useCustomRunNumber || collisions.size() < 1) { - initCCDB(manualRunNumber); - } else { - auto collision = collisions.begin(); - auto bc = collision.bc_as(); - initCCDB(bc.runNumber()); - } - - for (const auto& collision : collisions) { - // Do analysis with collision-grouped V0s, retain full collision information - const uint64_t collIdx = collision.globalIndex(); - auto CascTable_thisCollision = Cascades.sliceBy(perCollisionOriginal, collIdx); - // cascade table sliced - for (auto const& cascade : CascTable_thisCollision) { - // de-reference interlinks by hand for derived data - auto pTra = cascade.posTrack_as(); - auto nTra = cascade.negTrack_as(); - auto bTra = cascade.bachelor_as(); - - processCascadeCandidate(collision, cascade, pTra, nTra, bTra); - } - } - } - - void processDerivedData(soa::Join const& collisions, CascDerivedDatas const& Cascades, dauTracks const&) - { - // Fire up CCDB with first collision in record. If no collisions, bypass - if (useCustomRunNumber || collisions.size() < 1) { - initCCDB(manualRunNumber); - } else { - auto collision = collisions.begin(); - initCCDB(collision.runNumber()); - } - - for (const auto& collision : collisions) { - // Do analysis with collision-grouped V0s, retain full collision information - const uint64_t collIdx = collision.globalIndex(); - auto CascTable_thisCollision = Cascades.sliceBy(perCollisionDerived, collIdx); - // cascade table sliced - for (auto const& cascade : CascTable_thisCollision) { - // de-reference interlinks by hand for derived data - auto pTra = cascade.posTrackExtra_as(); - auto nTra = cascade.negTrackExtra_as(); - auto bTra = cascade.bachTrackExtra_as(); - - processCascadeCandidate(collision, cascade, pTra, nTra, bTra); - } - } - } - - PROCESS_SWITCH(cascadepid, processStandardData, "Process standard data", true); - PROCESS_SWITCH(cascadepid, processDerivedData, "Process derived data", false); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; -} diff --git a/PWGLF/TableProducer/Strangeness/lambdakzeropid.cxx b/PWGLF/TableProducer/Strangeness/lambdakzeropid.cxx deleted file mode 100644 index c6041aa0e02..00000000000 --- a/PWGLF/TableProducer/Strangeness/lambdakzeropid.cxx +++ /dev/null @@ -1,656 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -// -// *+-+*+-+*+-+*+-+*+-+*+-+* -// Lambdakzero PID -// *+-+*+-+*+-+*+-+*+-+*+-+* -// -/// \author Nicolò Jacazio -/// \author David Dobrigkeit Chinellato -/// \since 11/05/2023 -/// \brief Table producer for V0 daughter PID info -// -// This task produces daughter PID information for strange daughters -// taking into account the (candidate-by-candidate) time spent as a heavier -// (strange, weakly-decaying) particle. This task is meant to be a test, as -// it hasn't been fully tested yet! Use at your own peril for now :-) - -#include -#include -#include -#include -#include -#include - -#include "Framework/runDataProcessing.h" -#include "Framework/RunningWorkflowInfo.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "DCAFitter/DCAFitterN.h" -#include "ReconstructionDataFormats/Track.h" -#include "Common/Core/RecoDecay.h" -#include "Common/Core/trackUtilities.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/LFStrangenessPIDTables.h" -#include "PWGLF/DataModel/LFParticleIdentification.h" -#include "Common/Core/TrackSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "DetectorsBase/Propagator.h" -#include "DetectorsBase/GeometryManager.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "CCDB/BasicCCDBManager.h" -#include "DataFormatsCalibration/MeanVertexObject.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Common/TableProducer/PID/pidTOFBase.h" -#include "Common/DataModel/PIDResponse.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; -using std::array; - -// For original data loops -using V0OriginalDatas = soa::Join; -using TracksWithAllExtras = soa::Join; - -// For derived data analysis -using dauTracks = soa::Join; -using V0DerivedDatas = soa::Join; - -struct lambdakzeropid { - // TOF pid for strangeness (recalculated with topology) - Produces v0tofpid; // table with Nsigmas - Produces v0tofbeta; // table with betas - Produces v0tofdebugs; // table with extra debug information - Produces v0tofnsigmas; // table with nsigmas - - Service ccdb; - - // mean vertex position to be used if no collision associated - o2::dataformats::MeanVertexObject* mVtx = nullptr; - - // For manual sliceBy - Preslice perCollisionOriginal = o2::aod::v0data::collisionId; - ; - Preslice perCollisionDerived = o2::aod::v0data::straCollisionId; - - HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - - // Operation and minimisation criteria - Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; - Configurable tofPosition{"tofPosition", 377.934f, "TOF effective (inscribed) radius"}; - Configurable doQA{"doQA", true, "create QA histos"}; - Configurable doQANSigma{"doQANSigma", true, "create QA of Nsigma histos"}; - Configurable qaDCADau{"qaDCADau", 0.5, "DCA daughters (cm) for QA plots"}; - Configurable qaCosPA{"qaCosPA", 0.999, "CosPA for QA plots"}; - Configurable qaMassWindow{"qaMassWindow", 0.005, "Mass window around expected (in GeV/c2) for QA plots"}; - Configurable qaTPCNSigma{"qaTPCNSigma", 5, "TPC N-sigma to apply for qa plots"}; - Configurable doNSigmas{"doNSigmas", false, "calculate TOF N-sigma"}; - - // CCDB options - Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; - Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; - Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; - Configurable nSigmaPath{"nSigmaPath", "Users/d/ddobrigk/stratof", "Path of information for n-sigma calculation"}; - Configurable mVtxPath{"mVtxPath", "GLO/Calib/MeanVertex", "Path of the mean vertex file"}; - - // manual - Configurable useCustomRunNumber{"useCustomRunNumber", false, "Use custom timestamp"}; - Configurable manualRunNumber{"manualRunNumber", 544122, "manual run number if no collisions saved"}; - - ConfigurableAxis axisEta{"axisEta", {20, -1.0f, +1.0f}, "#eta"}; - ConfigurableAxis axisDeltaTime{"axisDeltaTime", {2000, -1000.0f, +1000.0f}, "delta-time (ps)"}; - ConfigurableAxis axisTime{"axisTime", {200, 0.0f, +20000.0f}, "T (ps)"}; - ConfigurableAxis axisNSigma{"axisNSigma", {200, -10.0f, +10.0f}, "N(#sigma)"}; - 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}, "p_{T} (GeV/c)"}; - - // for n-sigma calibration - bool nSigmaCalibLoaded; - TList* nSigmaCalibObjects; - TH1 *hMeanPosLaPi, *hSigmaPosLaPi; - TH1 *hMeanPosLaPr, *hSigmaPosLaPr; - TH1 *hMeanNegLaPi, *hSigmaNegLaPi; - TH1 *hMeanNegLaPr, *hSigmaNegLaPr; - TH1 *hMeanPosK0Pi, *hSigmaPosK0Pi; - TH1 *hMeanNegK0Pi, *hSigmaNegK0Pi; - - int mRunNumber; - float d_bz; - float maxSnp; // max sine phi for propagation - float maxStep; // max step size (cm) for propagation - - // enum to keep track of the TOF-related properties for V0s - enum tofEnum { kLength = 0, - kHasTOF, - kNEnums }; - - /// function to calculate track length of this track up to a certain segment of a detector - /// to be used internally in another funcrtion that calculates length until it finds the proper one - /// warning: this could be optimised further for speed - /// \param track the input track - /// \param x1 x of the first point of the detector segment - /// \param y1 y of the first point of the detector segment - /// \param x2 x of the first point of the detector segment - /// \param y2 y of the first point of the detector segment - /// \param magneticField the magnetic field to use when propagating - float trackLengthToSegment(o2::track::TrackPar track, float x1, float y1, float x2, float y2, float magneticField) - { - // don't make use of the track parametrization - float length = -104; - - // causality protection - std::array mom; - track.getPxPyPzGlo(mom); - // get start point - std::array startPoint; - track.getXYZGlo(startPoint); - - // better replaced with scalar momentum check later - // if (((x1 + x2) * mom[0] + (y1 + y2) * mom[1]) < 0.0f) - // return -101; - - // get circle X, Y please - o2::math_utils::CircleXYf_t trcCircle; - float sna, csa; - track.getCircleParams(magneticField, trcCircle, sna, csa); - - // Calculate necessary inner product - float segmentModulus = std::hypot(x2 - x1, y2 - y1); - float alongSegment = ((trcCircle.xC - x1) * (x2 - x1) + (trcCircle.yC - y1) * (y2 - y1)) / segmentModulus; - - // find point of closest approach between segment and circle center - float pcaX = (x2 - x1) * alongSegment / segmentModulus + x1; - float pcaY = (y2 - y1) * alongSegment / segmentModulus + y1; - - float centerDistToPC = std::hypot(pcaX - trcCircle.xC, pcaY - trcCircle.yC); - - // distance pca-to-intercept in multiples of segment modulus (for convenience) - if (centerDistToPC > trcCircle.rC) - return -103; - - float pcaToIntercept = TMath::Sqrt(TMath::Abs(trcCircle.rC * trcCircle.rC - centerDistToPC * centerDistToPC)); - - float interceptX1 = pcaX + (x2 - x1) / segmentModulus * pcaToIntercept; - float interceptY1 = pcaY + (y2 - y1) / segmentModulus * pcaToIntercept; - float interceptX2 = pcaX - (x2 - x1) / segmentModulus * pcaToIntercept; - float interceptY2 = pcaY - (y2 - y1) / segmentModulus * pcaToIntercept; - - float scalarCheck1 = ((x2 - x1) * (interceptX1 - x1) + (y2 - y1) * (interceptY1 - y1)) / segmentModulus; - float scalarCheck2 = ((x2 - x1) * (interceptX2 - x1) + (y2 - y1) * (interceptY2 - y1)) / segmentModulus; - - float cosAngle1 = -1000, sinAngle1 = -1000, modulus1 = -1000; - float cosAngle2 = -1000, sinAngle2 = -1000, modulus2 = -1000; - float length1 = -1000, length2 = -1000; - - modulus1 = std::hypot(interceptX1 - trcCircle.xC, interceptY1 - trcCircle.yC) * std::hypot(startPoint[0] - trcCircle.xC, startPoint[1] - trcCircle.yC); - cosAngle1 = (interceptX1 - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (interceptY1 - trcCircle.yC) * (startPoint[1] - trcCircle.yC); - sinAngle1 = (interceptX1 - trcCircle.xC) * (startPoint[1] - trcCircle.yC) - (interceptY1 - trcCircle.yC) * (startPoint[0] - trcCircle.xC); - cosAngle1 /= modulus1; - sinAngle1 /= modulus1; - length1 = trcCircle.rC * TMath::ACos(cosAngle1); - length1 *= sqrt(1.0f + track.getTgl() * track.getTgl()); - - modulus2 = std::hypot(interceptX2 - trcCircle.xC, interceptY2 - trcCircle.yC) * std::hypot(startPoint[0] - trcCircle.xC, startPoint[1] - trcCircle.yC); - cosAngle2 = (interceptX2 - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (interceptY2 - trcCircle.yC) * (startPoint[1] - trcCircle.yC); - sinAngle2 = (interceptX2 - trcCircle.xC) * (startPoint[1] - trcCircle.yC) - (interceptY2 - trcCircle.yC) * (startPoint[0] - trcCircle.xC); - cosAngle2 /= modulus2; - sinAngle2 /= modulus2; - length2 = trcCircle.rC * TMath::ACos(cosAngle2); - length2 *= sqrt(1.0f + track.getTgl() * track.getTgl()); - - // rotate transverse momentum vector such that it is at intercepts - float angle1 = TMath::ACos(cosAngle1); - if (sinAngle1 < 0) - angle1 *= -1.0f; - float px1 = +TMath::Cos(angle1) * mom[0] + TMath::Sin(angle1) * mom[1]; - float py1 = -TMath::Sin(angle1) * mom[0] + TMath::Cos(angle1) * mom[1]; - - float angle2 = TMath::ACos(cosAngle2); - if (sinAngle2 < 0) - angle2 *= -1.0f; - float px2 = +TMath::Cos(angle2) * mom[0] + TMath::Sin(angle2) * mom[1]; - float py2 = -TMath::Sin(angle2) * mom[0] + TMath::Cos(angle2) * mom[1]; - - float midSegX = 0.5f * (x2 + x1); - float midSegY = 0.5f * (y2 + y1); - - float scalarMomentumCheck1 = px1 * midSegX + py1 * midSegY; - float scalarMomentumCheck2 = px2 * midSegX + py2 * midSegY; - - if (scalarCheck1 > 0.0f && scalarCheck1 < segmentModulus && scalarMomentumCheck1 > 0.0f) { - length = length1; - // X = interceptX1; Y = interceptY1; - } - if (scalarCheck2 > 0.0f && scalarCheck2 < segmentModulus && scalarMomentumCheck2 > 0.0f) { - length = length2; - // X = interceptX2; Y = interceptY2; - } - return length; - } - - /// function to calculate track length of this track up to a certain segmented detector - /// \param track the input track - /// \param magneticField the magnetic field to use when propagating - float findInterceptLength(o2::track::TrackPar track, float magneticField) - { - float length = 1e+6; - for (int iSeg = 0; iSeg < 18; iSeg++) { - // Detector segmentation loop - float segmentAngle = 20.0f / 180.0f * TMath::Pi(); - float theta = static_cast(iSeg) * 20.0f / 180.0f * TMath::Pi(); - float halfWidth = tofPosition * TMath::Tan(0.5f * segmentAngle); - float x1 = TMath::Cos(theta) * (-halfWidth) + TMath::Sin(theta) * tofPosition; - float y1 = -TMath::Sin(theta) * (-halfWidth) + TMath::Cos(theta) * tofPosition; - float x2 = TMath::Cos(theta) * (+halfWidth) + TMath::Sin(theta) * tofPosition; - float y2 = -TMath::Sin(theta) * (+halfWidth) + TMath::Cos(theta) * tofPosition; - float thisLength = trackLengthToSegment(track, x1, y1, x2, y2, magneticField); - if (thisLength < length && thisLength > 0) - length = thisLength; - } - if (length > 1e+5) - length = -100; // force negative to avoid misunderstandings - return length; - } - - void init(InitContext&) - { - nSigmaCalibLoaded = false; - nSigmaCalibObjects = nullptr; - - // for n-sigma calibration - hMeanPosLaPi = nullptr; - hSigmaPosLaPi = nullptr; - hMeanPosLaPr = nullptr; - hSigmaPosLaPr = nullptr; - hMeanNegLaPi = nullptr; - hSigmaNegLaPi = nullptr; - hMeanNegLaPr = nullptr; - hSigmaNegLaPr = nullptr; - hMeanPosK0Pi = nullptr; - hSigmaNegK0Pi = nullptr; - hMeanNegK0Pi = nullptr; - hSigmaNegK0Pi = nullptr; - - mRunNumber = 0; - d_bz = 0; - maxSnp = 0.85f; // could be changed later - maxStep = 2.00f; // could be changed later - - ccdb->setURL(ccdburl); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - ccdb->setFatalWhenNull(false); - - // per event - histos.add("hCandidateCounter", "hCandidateCounter", kTH1F, {{500, -0.5f, 499.5f}}); - - // measured vs expected total time QA - if (doQA) { - histos.add("h2dProtonMeasuredVsExpected", "h2dProtonMeasuredVsExpected", {HistType::kTH2F, {axisTime, axisTime}}); - histos.add("h2dPionMeasuredVsExpected", "h2dPionMeasuredVsExpected", {HistType::kTH2F, {axisTime, axisTime}}); - - // standard deltaTime values - histos.add("h2dDeltaTimePositiveLambdaPi", "h2dDeltaTimePositiveLambdaPi", {HistType::kTH3F, {axisPt, axisEta, axisDeltaTime}}); - histos.add("h2dDeltaTimeNegativeLambdaPi", "h2dDeltaTimeNegativeLambdaPi", {HistType::kTH3F, {axisPt, axisEta, axisDeltaTime}}); - histos.add("h2dDeltaTimePositiveLambdaPr", "h2dDeltaTimePositiveLambdaPr", {HistType::kTH3F, {axisPt, axisEta, axisDeltaTime}}); - histos.add("h2dDeltaTimeNegativeLambdaPr", "h2dDeltaTimeNegativeLambdaPr", {HistType::kTH3F, {axisPt, axisEta, axisDeltaTime}}); - histos.add("h2dDeltaTimePositiveK0ShortPi", "h2dDeltaTimePositiveK0ShortPi", {HistType::kTH3F, {axisPt, axisEta, axisDeltaTime}}); - histos.add("h2dDeltaTimeNegativeK0ShortPi", "h2dDeltaTimeNegativeK0ShortPi", {HistType::kTH3F, {axisPt, axisEta, axisDeltaTime}}); - - histos.add("h2dPositiveTOFProperties", "h2dPositiveTOFProperties", {HistType::kTH2F, {axisPt, {4, -0.5, 3.5f}}}); - histos.add("h2dNegativeTOFProperties", "h2dNegativeTOFProperties", {HistType::kTH2F, {axisPt, {4, -0.5, 3.5f}}}); - - if (doQANSigma) { - // standard NSigma values - histos.add("h2dNSigmaPositiveLambdaPi", "h2dNSigmaPositiveLambdaPi", {HistType::kTH2F, {axisPt, axisNSigma}}); - histos.add("h2dNSigmaNegativeLambdaPi", "h2dNSigmaNegativeLambdaPi", {HistType::kTH2F, {axisPt, axisNSigma}}); - histos.add("h2dNSigmaPositiveLambdaPr", "h2dNSigmaPositiveLambdaPr", {HistType::kTH2F, {axisPt, axisNSigma}}); - histos.add("h2dNSigmaNegativeLambdaPr", "h2dNSigmaNegativeLambdaPr", {HistType::kTH2F, {axisPt, axisNSigma}}); - histos.add("h2dNSigmaPositiveK0ShortPi", "h2dNSigmaPositiveK0ShortPi", {HistType::kTH2F, {axisPt, axisNSigma}}); - histos.add("h2dNSigmaNegativeK0ShortPi", "h2dNSigmaNegativeK0ShortPi", {HistType::kTH2F, {axisPt, axisNSigma}}); - } - - // delta lambda decay time - histos.add("h2dLambdaDeltaDecayTime", "h2dLambdaDeltaDecayTime", {HistType::kTH2F, {axisPt, axisDeltaTime}}); - } - } - - void initCCDB(int runNumber) - { - if (mRunNumber == runNumber) { - return; - } - - // In case override, don't proceed, please - no CCDB access required - if (d_bz_input > -990) { - d_bz = d_bz_input; - o2::parameters::GRPMagField grpmag; - if (fabs(d_bz) > 1e-5) { - grpmag.setL3Current(30000.f / (d_bz / 5.0f)); - } - o2::base::Propagator::initFieldFromGRP(&grpmag); - mVtx = ccdb->getForRun(mVtxPath, runNumber); - mRunNumber = runNumber; - return; - } - - o2::parameters::GRPObject* grpo = ccdb->getForRun(grpPath, runNumber); - o2::parameters::GRPMagField* grpmag = 0x0; - if (grpo) { - o2::base::Propagator::initFieldFromGRP(grpo); - // Fetch magnetic field from ccdb for current collision - d_bz = grpo->getNominalL3Field(); - LOG(info) << "Retrieved GRP for run " << runNumber << " with magnetic field of " << d_bz << " kZG"; - } else { - grpmag = ccdb->getForRun(grpmagPath, runNumber); - if (!grpmag) { - LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for run " << runNumber; - } - o2::base::Propagator::initFieldFromGRP(grpmag); - // Fetch magnetic field from ccdb for current collision - d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); - mVtx = ccdb->getForRun(mVtxPath, runNumber); - LOG(info) << "Retrieved GRP for run " << runNumber << " with magnetic field of " << d_bz << " kZG"; - } - - // if TOF Nsigma desired - if (doNSigmas) { - nSigmaCalibObjects = ccdb->getForRun(nSigmaPath, runNumber); - if (nSigmaCalibObjects) { - LOGF(info, "loaded TList with this many objects: %i", nSigmaCalibObjects->GetEntries()); - - hMeanPosLaPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanPosLaPi")); - hMeanPosLaPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanPosLaPr")); - hMeanNegLaPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanNegLaPi")); - hMeanNegLaPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanNegLaPr")); - hMeanPosK0Pi = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanPosK0Pi")); - hMeanNegK0Pi = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanNegK0Pi")); - - hSigmaPosLaPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaPosLaPi")); - hSigmaPosLaPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaPosLaPr")); - hSigmaNegLaPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaNegLaPi")); - hSigmaNegLaPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaNegLaPr")); - hSigmaPosK0Pi = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaPosK0Pi")); - hSigmaNegK0Pi = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaNegK0Pi")); - - if (!hMeanPosLaPi) - LOG(info) << "Problems finding mean histogram hMeanPosLaPi!"; - if (!hMeanPosLaPr) - LOG(info) << "Problems finding mean histogram hMeanPosLaPr!"; - if (!hMeanNegLaPi) - LOG(info) << "Problems finding mean histogram hMeanNegLaPi!"; - if (!hMeanNegLaPr) - LOG(info) << "Problems finding mean histogram hMeanNegLaPr!"; - if (!hMeanPosK0Pi) - LOG(info) << "Problems finding mean histogram hMeanPosK0Pi!"; - if (!hMeanNegK0Pi) - LOG(info) << "Problems finding mean histogram hMeanNegK0Pi!"; - if (!hSigmaPosK0Pi || !hSigmaNegK0Pi || !hSigmaPosLaPi || !hSigmaPosLaPr || !hSigmaNegLaPi || !hSigmaNegLaPr) { - LOG(info) << "Problems finding sigma histograms!"; - } - } - } - mRunNumber = runNumber; - } - - float velocity(float lMomentum, float lMass) - { - // Momentum p and mass m -> returns speed in centimeters per picosecond - // Useful for TOF calculations - float lA = (lMomentum / lMass) * (lMomentum / lMass); - return 0.0299792458 * TMath::Sqrt(lA / (1 + lA)); - } - - // templatized process function for symmetric operation in derived and original AO2D - template - void processV0Candidate(TCollision const& collision, TV0 const& v0, TTrack const& pTra, TTrack const& nTra) - { - // time of V0 segment - float lengthV0 = std::hypot(v0.x() - collision.getX(), v0.y() - collision.getY(), v0.z() - collision.getZ()); - float velocityK0Short = velocity(v0.p(), o2::constants::physics::MassKaonNeutral); - float velocityLambda = velocity(v0.p(), o2::constants::physics::MassLambda); - float timeK0Short = lengthV0 / velocityK0Short; // in picoseconds - float timeLambda = lengthV0 / velocityLambda; // in picoseconds - - // initialize from V0 position and momenta - o2::track::TrackPar posTrack = o2::track::TrackPar({v0.x(), v0.y(), v0.z()}, {v0.pxpos(), v0.pypos(), v0.pzpos()}, +1); - o2::track::TrackPar negTrack = o2::track::TrackPar({v0.x(), v0.y(), v0.z()}, {v0.pxneg(), v0.pyneg(), v0.pzneg()}, -1); - - float deltaTimePositiveLambdaPi = -1e+6; - float deltaTimeNegativeLambdaPi = -1e+6; - float deltaTimePositiveLambdaPr = -1e+6; - float deltaTimeNegativeLambdaPr = -1e+6; - float deltaTimePositiveK0ShortPi = -1e+6; - float deltaTimeNegativeK0ShortPi = -1e+6; - - float nSigmaPositiveLambdaPi = -1e+3; - float nSigmaPositiveLambdaPr = -1e+3; - float nSigmaNegativeLambdaPi = -1e+3; - float nSigmaNegativeLambdaPr = -1e+3; - float nSigmaPositiveK0ShortPi = -1e+3; - float nSigmaNegativeK0ShortPi = -1e+3; - - float velocityPositivePr = velocity(posTrack.getP(), o2::constants::physics::MassProton); - float velocityPositivePi = velocity(posTrack.getP(), o2::constants::physics::MassPionCharged); - float velocityNegativePr = velocity(negTrack.getP(), o2::constants::physics::MassProton); - float velocityNegativePi = velocity(negTrack.getP(), o2::constants::physics::MassPionCharged); - - float lengthPositive = findInterceptLength(posTrack, d_bz); // FIXME: tofPosition ok? adjust? - float lengthNegative = findInterceptLength(negTrack, d_bz); // FIXME: tofPosition ok? adjust? - float timePositivePr = lengthPositive / velocityPositivePr; - float timePositivePi = lengthPositive / velocityPositivePi; - float timeNegativePr = lengthNegative / velocityNegativePr; - float timeNegativePi = lengthNegative / velocityNegativePi; - - if (pTra.hasTOF() && lengthPositive > 0) { - deltaTimePositiveLambdaPr = (pTra.tofSignal() - pTra.tofEvTime()) - (timeLambda + timePositivePr); - deltaTimePositiveLambdaPi = (pTra.tofSignal() - pTra.tofEvTime()) - (timeLambda + timePositivePi); - deltaTimePositiveK0ShortPi = (pTra.tofSignal() - pTra.tofEvTime()) - (timeK0Short + timePositivePi); - } - if (nTra.hasTOF() && lengthNegative > 0) { - deltaTimeNegativeLambdaPr = (nTra.tofSignal() - nTra.tofEvTime()) - (timeLambda + timeNegativePr); - deltaTimeNegativeLambdaPi = (nTra.tofSignal() - nTra.tofEvTime()) - (timeLambda + timeNegativePi); - deltaTimeNegativeK0ShortPi = (nTra.tofSignal() - nTra.tofEvTime()) - (timeK0Short + timeNegativePi); - } - - if (doQA) { - // calculate and pack properties for QA purposes - int posProperties = 0; - if (lengthPositive > 0) - posProperties = posProperties | (static_cast(1) << kLength); - if (pTra.hasTOF()) - posProperties = posProperties | (static_cast(1) << kHasTOF); - int negProperties = 0; - if (lengthNegative > 0) - negProperties = negProperties | (static_cast(1) << kLength); - if (nTra.hasTOF()) - negProperties = negProperties | (static_cast(1) << kHasTOF); - - histos.fill(HIST("h2dPositiveTOFProperties"), v0.pt(), posProperties); - histos.fill(HIST("h2dNegativeTOFProperties"), v0.pt(), negProperties); - } - - float deltaDecayTimeLambda = -10e+4; - float deltaDecayTimeAntiLambda = -10e+4; - float deltaDecayTimeK0Short = -10e+4; - if (nTra.hasTOF() && pTra.hasTOF() > 0 && lengthPositive > 0 && lengthNegative > 0) { // does not depend on event time - deltaDecayTimeLambda = (pTra.tofSignal() - timePositivePr) - (nTra.tofSignal() - timeNegativePi); - deltaDecayTimeAntiLambda = (pTra.tofSignal() - timePositivePi) - (nTra.tofSignal() - timeNegativePr); - deltaDecayTimeK0Short = (pTra.tofSignal() - timePositivePi) - (nTra.tofSignal() - timeNegativePi); - } - - // calculate betas - - float evTimeMean = 0.5f * (pTra.tofEvTime() + nTra.tofEvTime()); - float decayTimeLambda = 0.5f * ((pTra.tofSignal() - timePositivePr) + (nTra.tofSignal() - timeNegativePi)) - evTimeMean; - float decayTimeAntiLambda = 0.5f * ((pTra.tofSignal() - timePositivePi) + (nTra.tofSignal() - timeNegativePr)) - evTimeMean; - float decayTimeK0Short = 0.5f * ((pTra.tofSignal() - timePositivePi) + (nTra.tofSignal() - timeNegativePi)) - evTimeMean; - - float betaLambda = -1e+6; - float betaAntiLambda = -1e+6; - float betaK0Short = -1e+6; - - if (nTra.hasTOF() && pTra.hasTOF()) { - betaLambda = (lengthV0 / decayTimeLambda) / 0.0299792458; - betaAntiLambda = (lengthV0 / decayTimeAntiLambda) / 0.0299792458; - betaK0Short = (lengthV0 / decayTimeK0Short) / 0.0299792458; - } - - v0tofpid(deltaTimePositiveLambdaPi, deltaTimePositiveLambdaPr, - deltaTimeNegativeLambdaPi, deltaTimeNegativeLambdaPr, - deltaTimePositiveK0ShortPi, deltaTimeNegativeK0ShortPi, - deltaDecayTimeLambda, deltaDecayTimeAntiLambda, deltaDecayTimeK0Short); - v0tofbeta(betaLambda, betaAntiLambda, betaK0Short); - v0tofdebugs(timeLambda, timeK0Short, timePositivePr, timePositivePi, timeNegativePr, timeNegativePi); - - // do Nsigmas if requested - if (doNSigmas) { - // sweep through all viable hypotheses and produce N-sigma - - if (deltaTimePositiveLambdaPi > -1e+5) - nSigmaPositiveLambdaPi = (deltaTimePositiveLambdaPi - hMeanPosLaPi->Interpolate(v0.pt())) / hSigmaPosLaPi->Interpolate(v0.pt()); - if (deltaTimePositiveLambdaPr > -1e+5) - nSigmaPositiveLambdaPr = (deltaTimePositiveLambdaPr - hMeanPosLaPr->Interpolate(v0.pt())) / hSigmaPosLaPr->Interpolate(v0.pt()); - if (deltaTimeNegativeLambdaPi > -1e+5) - nSigmaNegativeLambdaPi = (deltaTimeNegativeLambdaPi - hMeanNegLaPi->Interpolate(v0.pt())) / hSigmaNegLaPi->Interpolate(v0.pt()); - if (deltaTimeNegativeLambdaPr > -1e+5) - nSigmaNegativeLambdaPr = (deltaTimeNegativeLambdaPr - hMeanNegLaPr->Interpolate(v0.pt())) / hSigmaNegLaPr->Interpolate(v0.pt()); - if (deltaTimePositiveK0ShortPi > -1e+5) - nSigmaPositiveK0ShortPi = (deltaTimePositiveK0ShortPi - hMeanPosK0Pi->Interpolate(v0.pt())) / hSigmaPosK0Pi->Interpolate(v0.pt()); - if (deltaTimeNegativeK0ShortPi > -1e+5) - nSigmaNegativeK0ShortPi = (deltaTimeNegativeK0ShortPi - hMeanNegK0Pi->Interpolate(v0.pt())) / hSigmaNegK0Pi->Interpolate(v0.pt()); - - v0tofnsigmas( - nSigmaPositiveLambdaPr, nSigmaNegativeLambdaPi, - nSigmaNegativeLambdaPr, nSigmaPositiveLambdaPi, - nSigmaPositiveK0ShortPi, nSigmaNegativeK0ShortPi); - } - - if (doQA) { - if (pTra.hasTOF()) { - histos.fill(HIST("h2dProtonMeasuredVsExpected"), - (timeLambda + timePositivePr), - (pTra.tofSignal() - pTra.tofEvTime())); - if (v0.v0cosPA() > qaCosPA && v0.dcaV0daughters() < qaDCADau) { - if (std::abs(v0.mLambda() - 1.115683) < qaMassWindow && fabs(pTra.tpcNSigmaPr()) < qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < qaTPCNSigma) { - histos.fill(HIST("h2dDeltaTimePositiveLambdaPr"), v0.pt(), v0.eta(), deltaTimePositiveLambdaPr); - if (doQANSigma) - histos.fill(HIST("h2dNSigmaPositiveLambdaPr"), v0.pt(), nSigmaPositiveLambdaPr); - } - if (std::abs(v0.mAntiLambda() - 1.115683) < qaMassWindow && fabs(pTra.tpcNSigmaPi()) < qaTPCNSigma && fabs(nTra.tpcNSigmaPr()) < qaTPCNSigma) { - histos.fill(HIST("h2dDeltaTimePositiveLambdaPi"), v0.pt(), v0.eta(), deltaTimePositiveLambdaPi); - if (doQANSigma) - histos.fill(HIST("h2dNSigmaPositiveLambdaPi"), v0.pt(), nSigmaPositiveLambdaPi); - } - if (std::abs(v0.mK0Short() - 0.497) < qaMassWindow && fabs(pTra.tpcNSigmaPi()) < qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < qaTPCNSigma) { - histos.fill(HIST("h2dDeltaTimePositiveK0ShortPi"), v0.pt(), v0.eta(), deltaTimePositiveK0ShortPi); - if (doQANSigma) - histos.fill(HIST("h2dNSigmaPositiveK0ShortPi"), v0.pt(), nSigmaPositiveK0ShortPi); - } - } - } - - if (nTra.hasTOF()) { - histos.fill(HIST("h2dPionMeasuredVsExpected"), - (timeLambda + timeNegativePi), - (nTra.tofSignal() - nTra.tofEvTime())); - if (v0.v0cosPA() > qaCosPA && v0.dcaV0daughters() < qaDCADau) { - if (std::abs(v0.mLambda() - 1.115683) < qaMassWindow && fabs(pTra.tpcNSigmaPr()) < qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < qaTPCNSigma) { - histos.fill(HIST("h2dDeltaTimeNegativeLambdaPi"), v0.pt(), v0.eta(), deltaTimeNegativeLambdaPi); - if (doQANSigma) - histos.fill(HIST("h2dNSigmaNegativeLambdaPi"), v0.pt(), nSigmaNegativeLambdaPi); - } - if (std::abs(v0.mAntiLambda() - 1.115683) < qaMassWindow && fabs(pTra.tpcNSigmaPi()) < qaTPCNSigma && fabs(nTra.tpcNSigmaPr()) < qaTPCNSigma) { - histos.fill(HIST("h2dDeltaTimeNegativeLambdaPr"), v0.pt(), v0.eta(), deltaTimeNegativeLambdaPr); - if (doQANSigma) - histos.fill(HIST("h2dNSigmaNegativeLambdaPr"), v0.pt(), nSigmaNegativeLambdaPr); - } - if (std::abs(v0.mK0Short() - 0.497) < qaMassWindow && fabs(pTra.tpcNSigmaPi()) < qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < qaTPCNSigma) { - histos.fill(HIST("h2dDeltaTimeNegativeK0ShortPi"), v0.pt(), v0.eta(), deltaTimeNegativeK0ShortPi); - if (doQANSigma) - histos.fill(HIST("h2dNSigmaNegativeK0ShortPi"), v0.pt(), nSigmaNegativeK0ShortPi); - } - } - } - // delta lambda decay time - histos.fill(HIST("h2dLambdaDeltaDecayTime"), v0.pt(), deltaDecayTimeLambda); - } - } - - void processStandardData(aod::Collisions const& collisions, V0OriginalDatas const& V0s, TracksWithAllExtras const&, aod::BCsWithTimestamps const& /*bcs*/) - { - // Fire up CCDB with first collision in record. If no collisions, bypass - if (useCustomRunNumber || collisions.size() < 1) { - initCCDB(manualRunNumber); - } else { - auto collision = collisions.begin(); - auto bc = collision.bc_as(); - initCCDB(bc.runNumber()); - } - - for (const auto& V0 : V0s) { - // for storing whatever is the relevant quantity for the PV - o2::dataformats::VertexBase primaryVertex; - if (V0.has_collision()) { - auto const& collision = V0.collision(); - primaryVertex.setPos({collision.posX(), collision.posY(), collision.posZ()}); - primaryVertex.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); - } else { - primaryVertex.setPos({mVtx->getX(), mVtx->getY(), mVtx->getZ()}); - } - - auto pTra = V0.posTrack_as(); - auto nTra = V0.negTrack_as(); - processV0Candidate(primaryVertex, V0, pTra, nTra); - } - } - - void processDerivedData(soa::Join const& collisions, V0DerivedDatas const& V0s, dauTracks const&) - { - // Fire up CCDB with first collision in record. If no collisions, bypass - if (useCustomRunNumber || collisions.size() < 1) { - initCCDB(manualRunNumber); - } else { - auto collision = collisions.begin(); - initCCDB(collision.runNumber()); - } - - for (const auto& V0 : V0s) { - // for storing whatever is the relevant quantity for the PV - o2::dataformats::VertexBase primaryVertex; - if (V0.has_straCollision()) { - auto const& collision = V0.straCollision_as>(); - primaryVertex.setPos({collision.posX(), collision.posY(), collision.posZ()}); - // cov: won't be used anyways, all fine - primaryVertex.setCov(1e-6, 1e-6, 1e-6, 1e-6, 1e-6, 1e-6); - } else { - primaryVertex.setPos({mVtx->getX(), mVtx->getY(), mVtx->getZ()}); - } - - auto pTra = V0.posTrackExtra_as(); - auto nTra = V0.negTrackExtra_as(); - processV0Candidate(primaryVertex, V0, pTra, nTra); - } - } - - PROCESS_SWITCH(lambdakzeropid, processStandardData, "Process standard data", true); - PROCESS_SWITCH(lambdakzeropid, processDerivedData, "Process derived data", false); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; -} diff --git a/PWGLF/TableProducer/Strangeness/lambdaspincorrelation.cxx b/PWGLF/TableProducer/Strangeness/lambdaspincorrelation.cxx index 3878bf4e29a..8d48b8d991b 100644 --- a/PWGLF/TableProducer/Strangeness/lambdaspincorrelation.cxx +++ b/PWGLF/TableProducer/Strangeness/lambdaspincorrelation.cxx @@ -78,6 +78,7 @@ struct lambdaspincorrelation { ConfigurableAxis axisMultiplicityClass{"axisMultiplicityClass", {8, 0, 80}, "multiplicity percentile for bin"}; // events + Configurable cfgEventTypepp{"cfgEventTypepp", false, "Type of collisions"}; Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable cfgCutCentralityMax{"cfgCutCentralityMax", 80.0f, "Accepted maximum Centrality"}; Configurable cfgCutCentralityMin{"cfgCutCentralityMin", 0.0f, "Accepted minimum Centrality"}; @@ -242,7 +243,7 @@ struct lambdaspincorrelation { Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; Filter centralityFilter = (nabs(aod::cent::centFT0C) < cfgCutCentralityMax && nabs(aod::cent::centFT0C) > cfgCutCentralityMin); - using EventCandidates = soa::Filtered>; + using EventCandidates = soa::Filtered>; using AllTrackCandidates = soa::Join; using ResoV0s = aod::V0Datas; @@ -261,6 +262,8 @@ struct lambdaspincorrelation { int numbV0 = 0; // LOGF(info, "event collisions: (%d)", collision.index()); auto centrality = collision.centFT0C(); + if (cfgEventTypepp) + centrality = collision.centFT0M(); auto vz = collision.posZ(); int occupancy = collision.trackOccupancyInTimeRange(); histos.fill(HIST("hEvtSelInfo"), 0.5); @@ -359,6 +362,8 @@ struct lambdaspincorrelation { int numbV0 = 0; // LOGF(info, "event collisions: (%d)", collision.index()); auto centrality = collision.centFT0C(); + if (cfgEventTypepp) + centrality = collision.centFT0M(); auto vz = collision.posZ(); int occupancy = collision.trackOccupancyInTimeRange(); histos.fill(HIST("hEvtSelInfo"), 0.5); diff --git a/PWGLF/TableProducer/Strangeness/propagationService.cxx b/PWGLF/TableProducer/Strangeness/propagationService.cxx index 6140dd2cc8b..191b920d9ef 100644 --- a/PWGLF/TableProducer/Strangeness/propagationService.cxx +++ b/PWGLF/TableProducer/Strangeness/propagationService.cxx @@ -31,6 +31,7 @@ #include "Common/DataModel/TrackSelectionTables.h" #include "Common/Tools/StandardCCDBLoader.h" #include "Common/Tools/TrackPropagationModule.h" +#include "Common/Tools/TrackTuner.h" #include "CCDB/BasicCCDBManager.h" #include "CCDB/CcdbApi.h" @@ -46,6 +47,8 @@ #include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/DCA.h" +#include + using namespace o2; using namespace o2::framework; // using namespace o2::framework::expressions; @@ -81,6 +84,9 @@ struct propagationService { o2::pwglf::strangenessbuilder::preSelectOpts preSelectOpts; o2::pwglf::strangenessbuilder::BuilderModule strangenessBuilderModule; + // the track tuner object -> needs to be here as it inherits from ConfigurableGroup (+ has its own copy of ccdbApi) + TrackTuner trackTunerObj; + // track propagation o2::common::TrackPropagationProducts trackPropagationProducts; o2::common::TrackPropagationConfigurables trackPropagationConfigurables; @@ -97,21 +103,21 @@ struct propagationService { ccdb->setURL(ccdburl.value); // task-specific - trackPropagation.init(trackPropagationConfigurables, histos, initContext); + trackPropagation.init(trackPropagationConfigurables, trackTunerObj, histos, initContext); strangenessBuilderModule.init(baseOpts, v0BuilderOpts, cascadeBuilderOpts, preSelectOpts, histos, initContext); } void processRealData(soa::Join const& collisions, aod::V0s const& v0s, aod::Cascades const& cascades, aod::TrackedCascades const& trackedCascades, FullTracksExtIU const& tracks, aod::BCsWithTimestamps const& bcs) { ccdbLoader.initCCDBfromBCs(standardCCDBLoaderConfigurables, ccdb, bcs); - trackPropagation.fillTrackTables(trackPropagationConfigurables, ccdbLoader, collisions, tracks, trackPropagationProducts, histos); + trackPropagation.fillTrackTables(trackPropagationConfigurables, trackTunerObj, ccdbLoader, collisions, tracks, trackPropagationProducts, histos); strangenessBuilderModule.dataProcess(ccdb, histos, collisions, static_cast(nullptr), v0s, cascades, trackedCascades, tracks, bcs, static_cast(nullptr), products); } void processMonteCarlo(soa::Join const& collisions, aod::McCollisions const& mccollisions, aod::V0s const& v0s, aod::Cascades const& cascades, aod::TrackedCascades const& trackedCascades, FullTracksExtLabeledIU const& tracks, aod::BCsWithTimestamps const& bcs, aod::McParticles const& mcParticles) { ccdbLoader.initCCDBfromBCs(standardCCDBLoaderConfigurables, ccdb, bcs); - trackPropagation.fillTrackTables(trackPropagationConfigurables, ccdbLoader, collisions, tracks, trackPropagationProducts, histos); + trackPropagation.fillTrackTables(trackPropagationConfigurables, trackTunerObj, ccdbLoader, collisions, tracks, trackPropagationProducts, histos); strangenessBuilderModule.dataProcess(ccdb, histos, collisions, mccollisions, v0s, cascades, trackedCascades, tracks, bcs, mcParticles, products); } diff --git a/PWGLF/TableProducer/Strangeness/sigmaminustask.cxx b/PWGLF/TableProducer/Strangeness/sigmaminustask.cxx new file mode 100644 index 00000000000..e6441c413e0 --- /dev/null +++ b/PWGLF/TableProducer/Strangeness/sigmaminustask.cxx @@ -0,0 +1,689 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file sigmaminustask.cxx +/// \brief Example of a simple task for the analysis of the Sigma-minus +/// \author Francesco Mazzaschi + +#include "PWGLF/DataModel/LFKinkDecayTables.h" + +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponse.h" + +#include "CCDB/BasicCCDBManager.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/PID.h" +#include "ReconstructionDataFormats/Track.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +using TracksFull = soa::Join; +using CollisionsFull = soa::Join; +using CollisionsFullMC = soa::Join; + +struct sigmaminustask { + + // Output Tables + Produces outputDataTable; + Produces outputDataTableMC; + + // Histograms are defined with HistogramRegistry + HistogramRegistry rEventSelection{"eventSelection", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rSigmaMinus{"sigmaminus", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry rFindable{"findable", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + // Configurable for event selection + Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; + Configurable cutNSigmaPi{"cutNSigmaPi", 4, "NSigmaTPCPion"}; + Configurable cutRapMotherMC{"cutRapMotherMC", 1.0f, "Rapidity cut for mother Sigma in MC"}; + Configurable cutMinQtAP{"cutMinQtAP", 0.15f, "Minimum Qt for Armenteros-Podolanski cut"}; + Configurable cutMaxQtAP{"cutMaxQtAP", 0.20f, "Maximum Qt for Armenteros-Podolanski cut"}; + Configurable cutPtGen{"cutPtGen", 0.5f, "Minimum pT for generated sigma particles"}; + + Configurable fillOutputTree{"fillOutputTree", true, "If true, fill the output tree with Kink candidates"}; + + // Configurables for findable tracks (kinkBuilder.cxx efficiency) + Configurable minPtMothKB{"minPtMothKB", 0.5f, "Minimum pT of the mother"}; + Configurable maxPhiDiffKB{"maxPhiDiffKB", 100.0f, "Max phi difference between the kink daughter and the mother"}; + Configurable maxZDiffKB{"maxZDiffKB", 20.0f, "Max z difference between the kink daughter and the mother"}; + Configurable etaMaxKB{"etaMaxKB", 1.0f, "Max eta for both mother and daughter"}; + Configurable nTPCClusMinDaugKB{"nTPCClusMinDaugKB", 80, "Min daug NTPC clusters"}; + Configurable radiusCutKB{"radiusCutKB", 19.6213f, "Min reconstructed decay radius of the mother"}; + Configurable maxDcaMothPvKB{"maxDcaMothPvKB", 0.1f, "Max DCA of the mother to PV"}; + Configurable minDcaDaugPvKB{"minDcaDaugPvKB", 0.1f, "Min DCA of the daughter to PV"}; + + Preslice mPerCol = aod::track::collisionId; + + // Constants + float radToDeg = o2::constants::math::Rad2Deg; + + // Services CCDB + Service ccdb; + Configurable ccdbPath{"ccdbPath", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; + Configurable cfgMaterialCorrection{"cfgMaterialCorrection", static_cast(o2::base::Propagator::MatCorrType::USEMatCorrLUT), "Type of material correction"}; + + // Runtime variables + int mRunNumber = 0; + float mBz = 0.0f; + o2::base::MatLayerCylSet* matLUT = nullptr; + + void init(InitContext const&) + { + // Initialize CCDB + ccdb->setURL(ccdbPath); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(true); + + matLUT = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get("GLO/Param/MatLUT")); + + // Axes + const AxisSpec ptAxis{100, -10, 10, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec ptUnsignedAxis{100, 0, 10, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec nSigmaPiAxis{60, -30, 30, "n#sigma_{#pi}"}; + const AxisSpec nSigmaPrAxis{60, -30, 30, "n#sigma_{p}"}; + const AxisSpec sigmaMassAxis{100, 1.1, 1.4, "m (GeV/#it{c}^{2})"}; + const AxisSpec xiMassAxis{100, 1.2, 1.6, "m_{#Xi} (GeV/#it{c}^{2})"}; + const AxisSpec pdgAxis{10001, -5000, 5000, "PDG code"}; + const AxisSpec vertexZAxis{100, -15., 15., "vrtx_{Z} [cm]"}; + const AxisSpec dcaMothAxis{100, 0, 0.03, "DCA [cm]"}; + const AxisSpec dcaDaugAxis{200, 0, 20, "DCA [cm]"}; + const AxisSpec radiusAxis{100, -1, 40, "Decay radius [cm]"}; + const AxisSpec alphaAPAxis{200, -1.0, 1.0, "#alpha_{AP}"}; + const AxisSpec qtAPAxis{200, 0.0, 0.5, "q_{T,AP}"}; + const AxisSpec cosPointingAngleAxis{100, -1.0, 1.0, "Cos#theta_{PA}"}; + + const AxisSpec ptResolutionAxis{100, -1.0, 1.0, "(#it{p}_{T}^{rec} - #it{p}_{T}^{gen}) / #it{p}_{T}^{gen}"}; + const AxisSpec massResolutionAxis{100, -0.5, 0.5, "(m_{rec} - m_{gen}) / m_{gen}"}; + const AxisSpec radiusResolutionAxis{100, -0.5, 0.5, "(r_{rec} - r_{gen}) / r_{gen}"}; + + const AxisSpec boolAxis{2, -0.5, 1.5, "Boolean value"}; + const AxisSpec filtersAxis{12, -0.5, 11.5, "Filter index"}; + const AxisSpec fakeITSAxis{8, -1.5, 6.5, "Fake ITS cluster layer"}; + + // Event selection + rEventSelection.add("hVertexZRec", "hVertexZRec", {HistType::kTH1F, {vertexZAxis}}); + // Sigma-minus reconstruction + rSigmaMinus.add("h2MassSigmaMinusPt", "h2MassSigmaMinusPt", {HistType::kTH2F, {ptAxis, sigmaMassAxis}}); + rSigmaMinus.add("h2SigmaMassVsXiMass", "h2SigmaMassVsXiMass", {HistType::kTH2F, {xiMassAxis, sigmaMassAxis}}); + rSigmaMinus.add("h2NSigmaTPCPiPt", "h2NSigmaTPCPiPt", {HistType::kTH2F, {ptAxis, nSigmaPiAxis}}); + rSigmaMinus.add("h2DCAMothPt", "h2DCAMothPt", {HistType::kTH2F, {ptAxis, dcaMothAxis}}); + rSigmaMinus.add("h2DCADaugPt", "h2DCADaugPt", {HistType::kTH2F, {ptAxis, dcaDaugAxis}}); + rSigmaMinus.add("h2ArmenterosPreCuts", "h2ArmenterosPreCuts", {HistType::kTH2F, {alphaAPAxis, qtAPAxis}}); + rSigmaMinus.add("h2ArmenterosPostCuts", "h2ArmenterosPostCuts", {HistType::kTH2F, {alphaAPAxis, qtAPAxis}}); + rSigmaMinus.add("h2CosPointingAnglePt", "h2CosPointingAnglePt", {HistType::kTH2F, {ptAxis, cosPointingAngleAxis}}); + + if (doprocessMC) { + // Add MC histograms if needed + rSigmaMinus.add("h2MassPtMCRec", "h2MassPtMCRec", {HistType::kTH2F, {ptAxis, sigmaMassAxis}}); + rSigmaMinus.add("h2MassPtMCGen", "h2MassPtMCGen", {HistType::kTH2F, {ptAxis, sigmaMassAxis}}); + + rSigmaMinus.add("h2MassResolution", "h2MassResolution", {HistType::kTH2F, {ptAxis, massResolutionAxis}}); + rSigmaMinus.add("h2PtResolution", "h2PtResolution", {HistType::kTH2F, {ptAxis, ptResolutionAxis}}); + rSigmaMinus.add("h2RadiusResolution", "h2RadiusResolution", {HistType::kTH2F, {ptAxis, radiusResolutionAxis}}); + + rSigmaMinus.add("h2NSigmaTOFPiPt", "h2NSigmaTOFPiPt", {HistType::kTH2F, {ptAxis, nSigmaPiAxis}}); + rSigmaMinus.add("h2NSigmaTOFPrPt", "h2NSigmaTOFPrPt", {HistType::kTH2F, {ptAxis, nSigmaPrAxis}}); + + // BC ID comparison histograms + rSigmaMinus.add("hMcCollIdCoherence", "McCollId (coll == daug)", {HistType::kTH1F, {boolAxis}}); + rSigmaMinus.add("h2CollId_BCId", "(McCollId coherence) vs (EvSelBC == McBC)", {HistType::kTH2F, {boolAxis, boolAxis}}); + rSigmaMinus.add("h2BCId_comp", "(McBC == EvSelBC) vs (BC == EvSelBC)", {HistType::kTH2F, {boolAxis, boolAxis}}); + } + + if (doprocessFindable) { + std::vector filterLabels = {"Initial", "ITS/TPC present", "ITS/TPC quality", "Moth p_{T}", "max #eta", "max #Delta#phi", "max #Delta Z", "max DCAmoth", "min DCAdaug", "min Radius", "sel8 coll", "Daug TOF"}; + + // Add findable Sigma histograms + rFindable.add("hfakeITSfindable", "hfakeITSfindable", {HistType::kTH1F, {fakeITSAxis}}); + rFindable.add("hFilterIndex", "hFilterIndex", {HistType::kTH1F, {filtersAxis}}); + rFindable.add("h2MCRadiusFilterIndex", "h2MCRadiusFilterIndex", {HistType::kTH2F, {filtersAxis, radiusAxis}}); + rFindable.add("h2RecRadiusFilterIndex", "h2RecRadiusFilterIndex", {HistType::kTH2F, {filtersAxis, radiusAxis}}); + + auto hFilterIndex = rFindable.get(HIST("hFilterIndex")); + auto h2MCRadiusFilterIndex = rFindable.get(HIST("h2MCRadiusFilterIndex")); + auto h2RecRadiusFilterIndex = rFindable.get(HIST("h2RecRadiusFilterIndex")); + for (size_t i = 0; i < filterLabels.size(); ++i) { + hFilterIndex->GetXaxis()->SetBinLabel(i + 1, filterLabels[i].c_str()); + h2MCRadiusFilterIndex->GetXaxis()->SetBinLabel(i + 1, filterLabels[i].c_str()); + h2RecRadiusFilterIndex->GetXaxis()->SetBinLabel(i + 1, filterLabels[i].c_str()); + } + + rFindable.add("h2MCRadiusFilter_plus_protonkink", "h2MCRadiusFilter_plus_protonkink", {HistType::kTH2F, {filtersAxis, radiusAxis}}); + rFindable.add("h2MCRadiusFilter_plus_pikink", "h2MCRadiusFilter_plus_pikink", {HistType::kTH2F, {filtersAxis, radiusAxis}}); + rFindable.add("h2MCRadiusFilter_minus_pikink", "h2MCRadiusFilter_minus_pikink", {HistType::kTH2F, {filtersAxis, radiusAxis}}); + + rFindable.add("h2PtFilter_plus_protonkink", "h2PtFilter_plus_protonkink", {HistType::kTH2F, {filtersAxis, ptUnsignedAxis}}); + rFindable.add("h2PtFilter_plus_pikink", "h2PtFilter_plus_pikink", {HistType::kTH2F, {filtersAxis, ptUnsignedAxis}}); + rFindable.add("h2PtFilter_minus_pikink", "h2PtFilter_minus_pikink", {HistType::kTH2F, {filtersAxis, ptUnsignedAxis}}); + + rFindable.add("h2PtDaugFilter_plus_protonkink", "h2PtDaugFilter_plus_protonkink", {HistType::kTH2F, {filtersAxis, ptUnsignedAxis}}); + rFindable.add("h2PtDaugFilter_plus_pikink", "h2PtDaugFilter_plus_pikink", {HistType::kTH2F, {filtersAxis, ptUnsignedAxis}}); + rFindable.add("h2PtDaugFilter_minus_pikink", "h2PtDaugFilter_minus_pikink", {HistType::kTH2F, {filtersAxis, ptUnsignedAxis}}); + + rFindable.add("h2DCAMothPt_protonkink", "h2DCAMothPt_protonkink", {HistType::kTH2F, {ptUnsignedAxis, dcaMothAxis}}); + rFindable.add("h2DCADaugPt_protonkink", "h2DCADaugPt_protonkink", {HistType::kTH2F, {ptUnsignedAxis, dcaDaugAxis}}); + rFindable.add("h2DCAMothPt_pikink", "h2DCAMothPt_pikink", {HistType::kTH2F, {ptUnsignedAxis, dcaMothAxis}}); + rFindable.add("h2DCADaugPt_pikink", "h2DCADaugPt_pikink", {HistType::kTH2F, {ptUnsignedAxis, dcaDaugAxis}}); + } + } + + void initCCDB(aod::BCs::iterator const& bc) + { + if (mRunNumber == bc.runNumber()) { + return; + } + mRunNumber = bc.runNumber(); + LOG(info) << "Initializing CCDB for run " << mRunNumber; + o2::parameters::GRPMagField* grpmag = ccdb->getForRun(grpmagPath, mRunNumber); + o2::base::Propagator::initFieldFromGRP(grpmag); + mBz = grpmag->getNominalL3Field(); + if (!matLUT) { + matLUT = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(lutPath)); + } + o2::base::Propagator::Instance()->setMatLUT(matLUT); + LOG(info) << "Task initialized for run " << mRunNumber << " with magnetic field " << mBz << " kZG"; + } + + float alphaAP(const std::array& momMother, const std::array& momKink) + { + std::array momMissing = {momMother[0] - momKink[0], momMother[1] - momKink[1], momMother[2] - momKink[2]}; + float lQlP = std::inner_product(momMother.begin(), momMother.end(), momKink.begin(), 0.f); + float lQlN = std::inner_product(momMother.begin(), momMother.end(), momMissing.begin(), 0.f); + return (lQlP - lQlN) / (lQlP + lQlN); + } + + float qtAP(const std::array& momMother, const std::array& momKink) + { + float dp = std::inner_product(momMother.begin(), momMother.end(), momKink.begin(), 0.f); + float p2V0 = std::inner_product(momMother.begin(), momMother.end(), momMother.begin(), 0.f); + float p2A = std::inner_product(momKink.begin(), momKink.end(), momKink.begin(), 0.f); + return std::sqrt(p2A - dp * dp / p2V0); + } + + float cosPAngle(const std::array& momMother, const std::array& posMother, const std::array& posKink) + { + std::array vMother = {posKink[0] - posMother[0], posKink[1] - posMother[1], posKink[2] - posMother[2]}; + float pMother = std::sqrt(std::inner_product(momMother.begin(), momMother.end(), momMother.begin(), 0.f)); + float vMotherNorm = std::sqrt(std::inner_product(vMother.begin(), vMother.end(), vMother.begin(), 0.f)); + return (std::inner_product(momMother.begin(), momMother.end(), vMother.begin(), 0.f)) / (pMother * vMotherNorm); + } + + void processData(CollisionsFull::iterator const& collision, aod::KinkCands const& KinkCands, TracksFull const&) + { + if (std::abs(collision.posZ()) > cutzvertex || !collision.sel8()) { + return; + } + rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); + + for (const auto& kinkCand : KinkCands) { + auto dauTrack = kinkCand.trackDaug_as(); + + if (std::abs(dauTrack.tpcNSigmaPi()) > cutNSigmaPi) { + continue; + } + + float alphaAPValue = alphaAP(std::array{kinkCand.pxMoth(), kinkCand.pyMoth(), kinkCand.pzMoth()}, std::array{kinkCand.pxDaug(), kinkCand.pyDaug(), kinkCand.pzDaug()}); + float qtValue = qtAP(std::array{kinkCand.pxMoth(), kinkCand.pyMoth(), kinkCand.pzMoth()}, std::array{kinkCand.pxDaug(), kinkCand.pyDaug(), kinkCand.pzDaug()}); + rSigmaMinus.fill(HIST("h2ArmenterosPreCuts"), alphaAPValue, qtValue); + + if (qtValue < cutMinQtAP || qtValue > cutMaxQtAP) { + continue; + } + float cosPointingAngleRec = cosPAngle(std::array{kinkCand.pxMoth(), kinkCand.pyMoth(), kinkCand.pzMoth()}, + std::array{0.0f, 0.0f, 0.0f}, + std::array{kinkCand.xDecVtx(), kinkCand.yDecVtx(), kinkCand.zDecVtx()}); + rSigmaMinus.fill(HIST("h2CosPointingAnglePt"), kinkCand.mothSign() * kinkCand.ptMoth(), cosPointingAngleRec); + rSigmaMinus.fill(HIST("h2ArmenterosPostCuts"), alphaAPValue, qtValue); + rSigmaMinus.fill(HIST("h2MassSigmaMinusPt"), kinkCand.mothSign() * kinkCand.ptMoth(), kinkCand.mSigmaMinus()); + rSigmaMinus.fill(HIST("h2SigmaMassVsXiMass"), kinkCand.mXiMinus(), kinkCand.mSigmaMinus()); + rSigmaMinus.fill(HIST("h2NSigmaTPCPiPt"), kinkCand.mothSign() * kinkCand.ptMoth(), dauTrack.tpcNSigmaPi()); + rSigmaMinus.fill(HIST("h2DCAMothPt"), kinkCand.mothSign() * kinkCand.ptMoth(), kinkCand.dcaMothPv()); + rSigmaMinus.fill(HIST("h2DCADaugPt"), kinkCand.mothSign() * kinkCand.ptDaug(), kinkCand.dcaDaugPv()); + + if (fillOutputTree) { + outputDataTable(kinkCand.xDecVtx(), kinkCand.yDecVtx(), kinkCand.zDecVtx(), + kinkCand.pxMoth(), kinkCand.pyMoth(), kinkCand.pzMoth(), + kinkCand.pxDaug(), kinkCand.pyDaug(), kinkCand.pzDaug(), + kinkCand.dcaMothPv(), kinkCand.dcaDaugPv(), kinkCand.dcaKinkTopo(), + kinkCand.mothSign(), + dauTrack.tpcNSigmaPi(), dauTrack.tpcNSigmaPr(), dauTrack.tpcNSigmaKa(), + dauTrack.tofNSigmaPi(), dauTrack.tofNSigmaPr(), dauTrack.tofNSigmaKa()); + } + } + } + PROCESS_SWITCH(sigmaminustask, processData, "Data processing", true); + + void processMC(CollisionsFullMC const& collisions, aod::KinkCands const& KinkCands, aod::McTrackLabels const& trackLabelsMC, aod::McParticles const& particlesMC, TracksFull const&, aod::McCollisions const&) + { + for (const auto& collision : collisions) { + if (std::abs(collision.posZ()) > cutzvertex || !collision.sel8()) { + continue; + } + + rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); + auto kinkCandPerColl = KinkCands.sliceBy(mPerCol, collision.globalIndex()); + + for (const auto& kinkCand : kinkCandPerColl) { + + auto dauTrack = kinkCand.trackDaug_as(); + auto mothTrack = kinkCand.trackMoth_as(); + if (dauTrack.sign() != mothTrack.sign()) { + LOG(info) << "Skipping kink candidate with opposite sign daughter and mother: " << kinkCand.globalIndex(); + continue; // Skip if the daughter has the opposite sign as the mother + } + if (std::abs(dauTrack.tpcNSigmaPi()) > cutNSigmaPi) { + continue; + } + + // histograms filled with all kink candidates + float alphaAPValue = alphaAP(std::array{kinkCand.pxMoth(), kinkCand.pyMoth(), kinkCand.pzMoth()}, std::array{kinkCand.pxDaug(), kinkCand.pyDaug(), kinkCand.pzDaug()}); + float qtValue = qtAP(std::array{kinkCand.pxMoth(), kinkCand.pyMoth(), kinkCand.pzMoth()}, std::array{kinkCand.pxDaug(), kinkCand.pyDaug(), kinkCand.pzDaug()}); + rSigmaMinus.fill(HIST("h2ArmenterosPreCuts"), alphaAPValue, qtValue); + rSigmaMinus.fill(HIST("h2MassSigmaMinusPt"), kinkCand.mothSign() * kinkCand.ptMoth(), kinkCand.mSigmaMinus()); + rSigmaMinus.fill(HIST("h2SigmaMassVsXiMass"), kinkCand.mXiMinus(), kinkCand.mSigmaMinus()); + rSigmaMinus.fill(HIST("h2NSigmaTPCPiPt"), kinkCand.mothSign() * kinkCand.ptMoth(), dauTrack.tpcNSigmaPi()); + + // do MC association + auto mcLabSigma = trackLabelsMC.rawIteratorAt(mothTrack.globalIndex()); + auto mcLabPiDau = trackLabelsMC.rawIteratorAt(dauTrack.globalIndex()); + if (mcLabSigma.has_mcParticle() && mcLabPiDau.has_mcParticle()) { + auto mcTrackSigma = mcLabSigma.mcParticle_as(); + auto mcTrackPiDau = mcLabPiDau.mcParticle_as(); + if (!mcTrackPiDau.has_mothers()) { + continue; + } + for (auto& piMother : mcTrackPiDau.mothers_as()) { + if (piMother.globalIndex() != mcTrackSigma.globalIndex()) { + continue; + } + if (std::abs(mcTrackSigma.pdgCode()) != 3112 && std::abs(mcTrackSigma.pdgCode()) != 3222) { + continue; + } + if (std::abs(mcTrackPiDau.pdgCode()) != 211 && std::abs(mcTrackPiDau.pdgCode()) != 2212) { + continue; + } + + float MotherMassMC = std::sqrt(piMother.e() * piMother.e() - piMother.p() * piMother.p()); + float MotherpTMC = piMother.pt(); + float deltaXMother = mcTrackPiDau.vx() - piMother.vx(); + float deltaYMother = mcTrackPiDau.vy() - piMother.vy(); + float decayRadiusMC = std::sqrt(deltaXMother * deltaXMother + deltaYMother * deltaYMother); + float decayRadiusRec = std::sqrt(kinkCand.xDecVtx() * kinkCand.xDecVtx() + kinkCand.yDecVtx() * kinkCand.yDecVtx()); + float cosPointingAngleRec = cosPAngle(std::array{kinkCand.pxMoth(), kinkCand.pyMoth(), kinkCand.pzMoth()}, + std::array{0.0f, 0.0f, 0.0f}, + std::array{kinkCand.xDecVtx(), kinkCand.yDecVtx(), kinkCand.zDecVtx()}); + + // Check coherence of MCcollision Id for daughter MCparticle and reconstructed collision + bool mcCollisionIdCheck = false; + if (collision.has_mcCollision()) { + mcCollisionIdCheck = collision.mcCollision().globalIndex() == mcTrackPiDau.mcCollisionId(); + } + // Check bunch crossing ID coherence + auto mcCollision = mcTrackPiDau.template mcCollision_as(); + // bool BCId_vs_MCBCId = collision.bcId() == mcCollision.bcId(); + bool BCId_vs_EvSel = collision.bcId() == collision.foundBCId(); + bool EvSel_vs_MCBCId = collision.foundBCId() == mcCollision.bcId(); + + rSigmaMinus.fill(HIST("hMcCollIdCoherence"), static_cast(mcCollisionIdCheck)); + rSigmaMinus.fill(HIST("h2CollId_BCId"), static_cast(mcCollisionIdCheck), static_cast(EvSel_vs_MCBCId)); + rSigmaMinus.fill(HIST("h2BCId_comp"), static_cast(EvSel_vs_MCBCId), static_cast(BCId_vs_EvSel)); + + rSigmaMinus.fill(HIST("h2MassPtMCRec"), kinkCand.mothSign() * kinkCand.ptMoth(), kinkCand.mSigmaMinus()); + rSigmaMinus.fill(HIST("h2MassResolution"), kinkCand.mothSign() * kinkCand.ptMoth(), (kinkCand.mSigmaMinus() - MotherMassMC) / MotherMassMC); + rSigmaMinus.fill(HIST("h2PtResolution"), kinkCand.mothSign() * kinkCand.ptMoth(), (kinkCand.ptMoth() - MotherpTMC) / MotherpTMC); + rSigmaMinus.fill(HIST("h2RadiusResolution"), kinkCand.mothSign() * kinkCand.ptMoth(), (decayRadiusRec - decayRadiusMC) / decayRadiusMC); + rSigmaMinus.fill(HIST("h2DCAMothPt"), kinkCand.mothSign() * kinkCand.ptMoth(), kinkCand.dcaMothPv()); + rSigmaMinus.fill(HIST("h2DCADaugPt"), kinkCand.mothSign() * kinkCand.ptMoth(), kinkCand.dcaDaugPv()); + rSigmaMinus.fill(HIST("h2CosPointingAnglePt"), kinkCand.mothSign() * kinkCand.ptMoth(), cosPointingAngleRec); + rSigmaMinus.fill(HIST("h2ArmenterosPostCuts"), alphaAPValue, qtValue); + if (std::abs(mcTrackPiDau.pdgCode()) == 211) { + rSigmaMinus.fill(HIST("h2NSigmaTOFPiPt"), kinkCand.mothSign() * kinkCand.ptMoth(), dauTrack.tofNSigmaPi()); + } else if (std::abs(mcTrackPiDau.pdgCode()) == 2212) { + rSigmaMinus.fill(HIST("h2NSigmaTOFPrPt"), kinkCand.mothSign() * kinkCand.ptMoth(), dauTrack.tofNSigmaPr()); + } + + // fill the output table with Mc information + if (fillOutputTree) { + outputDataTableMC(kinkCand.xDecVtx(), kinkCand.yDecVtx(), kinkCand.zDecVtx(), + kinkCand.pxMoth(), kinkCand.pyMoth(), kinkCand.pzMoth(), + kinkCand.pxDaug(), kinkCand.pyDaug(), kinkCand.pzDaug(), + kinkCand.dcaMothPv(), kinkCand.dcaDaugPv(), kinkCand.dcaKinkTopo(), + kinkCand.mothSign(), + dauTrack.tpcNSigmaPi(), dauTrack.tpcNSigmaPr(), dauTrack.tpcNSigmaKa(), + dauTrack.tofNSigmaPi(), dauTrack.tofNSigmaPr(), dauTrack.tofNSigmaKa(), + mcTrackSigma.pdgCode(), mcTrackPiDau.pdgCode(), + MotherpTMC, MotherMassMC, decayRadiusMC, mcCollisionIdCheck); + } + } + } // MC association and selection + } // kink cand loop + } // collision loop + + // Loop over all generated particles to fill MC histograms + for (const auto& mcPart : particlesMC) { + if ((std::abs(mcPart.pdgCode()) != 3112 && std::abs(mcPart.pdgCode()) != 3222) || std::abs(mcPart.y()) > cutRapMotherMC) { // only sigma mothers and rapidity cut + continue; + } + + if (mcPart.pt() < cutPtGen) { + continue; // Skip if pT is below threshold + } + + if (!mcPart.has_daughters()) { + continue; // Skip if no daughters + } + bool hasSigmaDaughter = false; + int daug_pdg = 0; + std::array secVtx; + std::array momDaug; + for (const auto& daughter : mcPart.daughters_as()) { + if (std::abs(daughter.pdgCode()) == 211 || std::abs(daughter.pdgCode()) == 2212) { // Pi or proton daughter + hasSigmaDaughter = true; + secVtx = {daughter.vx(), daughter.vy(), daughter.vz()}; + momDaug = {daughter.px(), daughter.py(), daughter.pz()}; + daug_pdg = daughter.pdgCode(); + break; // Found a daughter, exit loop + } + } + if (!hasSigmaDaughter) { + continue; // Skip if no pi/proton daughter found + } + float mcMass = std::sqrt(mcPart.e() * mcPart.e() - mcPart.p() * mcPart.p()); + float mcDecayRadius = std::sqrt((secVtx[0] - mcPart.vx()) * (secVtx[0] - mcPart.vx()) + (secVtx[1] - mcPart.vy()) * (secVtx[1] - mcPart.vy())); + int sigmaSign = mcPart.pdgCode() > 0 ? 1 : -1; // Determine the sign of the Sigma + rSigmaMinus.fill(HIST("h2MassPtMCGen"), sigmaSign * mcPart.pt(), mcMass); + + // Fill output table with non reconstructed MC candidates + if (fillOutputTree) { + outputDataTableMC(-999, -999, -999, + -999, -999, -999, + -999, -999, -999, + -999, -999, -999, + sigmaSign, + -999, -999, -999, + -999, -999, -999, + mcPart.pdgCode(), daug_pdg, + mcPart.pt(), mcMass, mcDecayRadius, false); + } + } + } + PROCESS_SWITCH(sigmaminustask, processMC, "MC processing", false); + + void fillFindableHistograms(int filterIndex, float mcRadius, float recRadius, float ptMoth, float ptDaug, bool isSigmaMinus, bool isPiDaughter) + { + rFindable.fill(HIST("hFilterIndex"), filterIndex); + rFindable.fill(HIST("h2MCRadiusFilterIndex"), filterIndex, mcRadius); + rFindable.fill(HIST("h2RecRadiusFilterIndex"), filterIndex, recRadius); + + if (isPiDaughter) { + if (isSigmaMinus) { + rFindable.fill(HIST("h2MCRadiusFilter_minus_pikink"), filterIndex, mcRadius); + rFindable.fill(HIST("h2PtFilter_minus_pikink"), filterIndex, ptMoth); + rFindable.fill(HIST("h2PtDaugFilter_minus_pikink"), filterIndex, ptDaug); + } else { + rFindable.fill(HIST("h2MCRadiusFilter_plus_pikink"), filterIndex, mcRadius); + rFindable.fill(HIST("h2PtFilter_plus_pikink"), filterIndex, ptMoth); + rFindable.fill(HIST("h2PtDaugFilter_plus_pikink"), filterIndex, ptDaug); + } + } else { + if (!isSigmaMinus) { + rFindable.fill(HIST("h2MCRadiusFilter_plus_protonkink"), filterIndex, mcRadius); + rFindable.fill(HIST("h2PtFilter_plus_protonkink"), filterIndex, ptMoth); + rFindable.fill(HIST("h2PtDaugFilter_plus_protonkink"), filterIndex, ptDaug); + } + } + } + + void processFindable(aod::KinkCands const& kinkCands, aod::McTrackLabels const& trackLabelsMC, + TracksFull const& tracks, aod::McParticles const&, CollisionsFullMC const&, aod::BCs const&) + { + // A - generated findable track pairs map: mcMother.globalIndex() -> (motherTrack.globalIndex(), daughterTrack.globalIndex()) + std::unordered_map> allCandsIndices; + + for (const auto& track : tracks) { + auto mcLabel = trackLabelsMC.rawIteratorAt(track.globalIndex()); + if (!mcLabel.has_mcParticle()) { + continue; + } + auto mcParticle = mcLabel.mcParticle_as(); + + if (mcParticle.has_daughters() && (std::abs(mcParticle.pdgCode()) == 3112 || std::abs(mcParticle.pdgCode()) == 3222)) { + allCandsIndices[mcParticle.globalIndex()] = {track.globalIndex(), -1}; + } + } + + for (const auto& track : tracks) { + auto mcLabel = trackLabelsMC.rawIteratorAt(track.globalIndex()); + if (!mcLabel.has_mcParticle()) { + continue; + } + auto mcParticle = mcLabel.mcParticle_as(); + + if (mcParticle.has_mothers() && (std::abs(mcParticle.pdgCode()) == 211 || std::abs(mcParticle.pdgCode()) == 2212)) { + for (const auto& mother : mcParticle.mothers_as()) { + auto it = allCandsIndices.find(mother.globalIndex()); + if (it != allCandsIndices.end()) { + it->second.second = track.globalIndex(); + break; + } + } + } + } + + // B - reconstructed kinkcands map: mcMother.globalIndex() -> kinkCand.globalIndex() + std::unordered_map findableToKinkCand; + for (const auto& kinkCand : kinkCands) { + auto motherTrack = kinkCand.trackMoth_as(); + auto daughterTrack = kinkCand.trackDaug_as(); + + auto mcLabMoth = trackLabelsMC.rawIteratorAt(motherTrack.globalIndex()); + auto mcLabDaug = trackLabelsMC.rawIteratorAt(daughterTrack.globalIndex()); + if (!mcLabMoth.has_mcParticle() || !mcLabDaug.has_mcParticle()) { + continue; + } + auto mcMother = mcLabMoth.mcParticle_as(); + auto mcDaughter = mcLabDaug.mcParticle_as(); + + if (std::abs(mcMother.pdgCode()) != 3112 && std::abs(mcMother.pdgCode()) != 3222) { + continue; + } + if (std::abs(mcDaughter.pdgCode()) != 211 && std::abs(mcDaughter.pdgCode()) != 2212) { + continue; + } + + auto findableIt = allCandsIndices.find(mcMother.globalIndex()); + if (findableIt != allCandsIndices.end() && + findableIt->second.first == motherTrack.globalIndex() && + findableIt->second.second == daughterTrack.globalIndex()) { + + findableToKinkCand[mcMother.globalIndex()] = kinkCand.globalIndex(); + } + } + + // C - loop on valid pairs for findable analysis + for (const auto& [mcMotherIndex, trackIndices] : allCandsIndices) { + if (trackIndices.second == -1 || trackIndices.first == -1) { + continue; + } + + // Retrieve mother and daughter tracks and mcParticles + auto motherTrack = tracks.rawIteratorAt(trackIndices.first); + auto daughterTrack = tracks.rawIteratorAt(trackIndices.second); + auto mcLabMoth = trackLabelsMC.rawIteratorAt(motherTrack.globalIndex()); + auto mcLabDaug = trackLabelsMC.rawIteratorAt(daughterTrack.globalIndex()); + auto mcMother = mcLabMoth.mcParticle_as(); + auto mcDaughter = mcLabDaug.mcParticle_as(); + + // Compute useful quantities for histograms + bool isSigmaMinus = (std::abs(mcMother.pdgCode()) == 3112); + bool isPiDaughter = (std::abs(mcDaughter.pdgCode()) == 211); + + float recPtDaughter = daughterTrack.pt(); + float recPtMother = motherTrack.pt(); + float mcRadius = std::sqrt((mcMother.vx() - mcDaughter.vx()) * (mcMother.vx() - mcDaughter.vx()) + (mcMother.vy() - mcDaughter.vy()) * (mcMother.vy() - mcDaughter.vy())); + float recRadius = -1.0; + if (findableToKinkCand.find(mcMother.globalIndex()) != findableToKinkCand.end()) { + auto kinkCand = kinkCands.rawIteratorAt(findableToKinkCand[mcMother.globalIndex()]); + recRadius = std::sqrt(kinkCand.xDecVtx() * kinkCand.xDecVtx() + kinkCand.yDecVtx() * kinkCand.yDecVtx()); + } + + // Check for detector mismatches in ITS mother tracks + auto mask_value = mcLabMoth.mcMask(); + int mismatchITS_index = -1; + + for (int i = 0; i < 7; ++i) { // ITS has layers 0-6, bit ON means mismatch + if ((mask_value & (1 << i)) != 0) { + mismatchITS_index = i; + break; + } + } + + // Define filter index and progressively apply kinkbuilder cuts to track pairs + int filterIndex = 0; + fillFindableHistograms(filterIndex, mcRadius, recRadius, recPtMother, recPtDaughter, isSigmaMinus, isPiDaughter); + + // 1 - tracks with right ITS, TPC, TOF signals + if (motherTrack.has_collision() && motherTrack.hasITS() && !motherTrack.hasTPC() && !motherTrack.hasTOF() && + daughterTrack.hasITS() && daughterTrack.hasTPC()) { + filterIndex += 1; + fillFindableHistograms(filterIndex, mcRadius, recRadius, recPtMother, recPtDaughter, isSigmaMinus, isPiDaughter); + rFindable.fill(HIST("hfakeITSfindable"), mismatchITS_index); + } else { + continue; + } + + // 2 - moth+daug track quality cuts + bool motherGoodITS = motherTrack.hasITS() && motherTrack.itsNCls() < 6 && motherTrack.itsNClsInnerBarrel() == 3 && motherTrack.itsChi2NCl() < 36; + bool daughterGoodITSTPC = daughterTrack.hasITS() && daughterTrack.hasTPC() && daughterTrack.itsNClsInnerBarrel() == 0 && + daughterTrack.itsNCls() < 4 && daughterTrack.tpcNClsCrossedRows() > 0.8 * daughterTrack.tpcNClsFindable() && daughterTrack.tpcNClsFound() > nTPCClusMinDaugKB; + if (motherGoodITS && daughterGoodITSTPC) { + filterIndex += 1; + fillFindableHistograms(filterIndex, mcRadius, recRadius, recPtMother, recPtDaughter, isSigmaMinus, isPiDaughter); + } else { + continue; + } + + // 3 - mother track min pT + if (motherTrack.pt() > minPtMothKB) { + filterIndex += 1; + fillFindableHistograms(filterIndex, mcRadius, recRadius, recPtMother, recPtDaughter, isSigmaMinus, isPiDaughter); + } else { + continue; + } + + // 4 - geometric cuts: eta + if (std::abs(motherTrack.eta()) < etaMaxKB && std::abs(daughterTrack.eta()) < etaMaxKB) { + filterIndex += 1; + fillFindableHistograms(filterIndex, mcRadius, recRadius, recPtMother, recPtDaughter, isSigmaMinus, isPiDaughter); + } else { + continue; + } + + // 5 - geometric cuts: phi difference + if (std::abs(motherTrack.phi() - daughterTrack.phi()) * radToDeg < maxPhiDiffKB) { + filterIndex += 1; + fillFindableHistograms(filterIndex, mcRadius, recRadius, recPtMother, recPtDaughter, isSigmaMinus, isPiDaughter); + } else { + continue; + } + + // DCA calculation: initialization CCDB + auto collision = motherTrack.template collision_as(); + auto bc = collision.template bc_as(); + initCCDB(bc); + const o2::math_utils::Point3D collVtx{collision.posX(), collision.posY(), collision.posZ()}; + o2::track::TrackParCov trackParCovMoth = getTrackParCov(motherTrack); + o2::track::TrackParCov trackParCovDaug = getTrackParCov(daughterTrack); + + // get DCA to PV for mother and daughter tracks + std::array dcaInfoMoth; + o2::base::Propagator::Instance()->propagateToDCA(collVtx, trackParCovMoth, mBz, 2.f, static_cast(cfgMaterialCorrection.value), &dcaInfoMoth); + std::array dcaInfoDaug; + o2::base::Propagator::Instance()->propagateToDCA(collVtx, trackParCovDaug, mBz, 2.f, static_cast(cfgMaterialCorrection.value), &dcaInfoDaug); + float dcaXYMother = std::abs(dcaInfoMoth[0]); + float dcaXYDaughter = std::abs(dcaInfoDaug[0]); + if (isPiDaughter) { + rFindable.fill(HIST("h2DCAMothPt_pikink"), recPtMother, dcaXYMother); + rFindable.fill(HIST("h2DCADaugPt_pikink"), recPtDaughter, dcaXYDaughter); + } else { + rFindable.fill(HIST("h2DCAMothPt_protonkink"), recPtMother, dcaXYMother); + rFindable.fill(HIST("h2DCADaugPt_protonkink"), recPtDaughter, dcaXYDaughter); + } + + // 6 - max Z difference + if (std::abs(trackParCovMoth.getZ() - trackParCovDaug.getZ()) < maxZDiffKB) { + filterIndex += 1; + fillFindableHistograms(filterIndex, mcRadius, recRadius, recPtMother, recPtDaughter, isSigmaMinus, isPiDaughter); + } else { + continue; + } + + // 7 - DCA mother + if (dcaXYMother < maxDcaMothPvKB) { + filterIndex += 1; + fillFindableHistograms(filterIndex, mcRadius, recRadius, recPtMother, recPtDaughter, isSigmaMinus, isPiDaughter); + } else { + continue; + } + + // 8 - DCA daughter + if (dcaXYDaughter > minDcaDaugPvKB) { + filterIndex += 1; + fillFindableHistograms(filterIndex, mcRadius, recRadius, recPtMother, recPtDaughter, isSigmaMinus, isPiDaughter); + } else { + continue; + } + + // 9 - radius cut + if (recRadius > radiusCutKB) { + filterIndex += 1; + fillFindableHistograms(filterIndex, mcRadius, recRadius, recPtMother, recPtDaughter, isSigmaMinus, isPiDaughter); + } else { + continue; + } + + // 10 - collision selection + if (!(std::abs(collision.posZ()) > cutzvertex || !collision.sel8())) { + filterIndex += 1; + fillFindableHistograms(filterIndex, mcRadius, recRadius, recPtMother, recPtDaughter, isSigmaMinus, isPiDaughter); + } else { + continue; + } + + // 11 - TOF daughter presence + if (daughterTrack.hasTOF()) { + filterIndex += 1; + fillFindableHistograms(filterIndex, mcRadius, recRadius, recPtMother, recPtDaughter, isSigmaMinus, isPiDaughter); + } + } + } + + PROCESS_SWITCH(sigmaminustask, processFindable, "Findable Sigma processing", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx b/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx index bca1b08b07f..d7012626b4f 100644 --- a/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx +++ b/PWGLF/TableProducer/Strangeness/strangenessbuilder.cxx @@ -1648,7 +1648,8 @@ struct StrangenessBuilder { auto const& collision = collisions.rawIteratorAt(v0.collisionId); if (!mVDriftMgr.moveTPCTrack(collision, posTrack, posTrackPar)) { - return; + products.v0dataLink(-1, -1); + continue; } } @@ -1660,7 +1661,8 @@ struct StrangenessBuilder { auto const& collision = collisions.rawIteratorAt(v0.collisionId); if (!mVDriftMgr.moveTPCTrack(collision, negTrack, negTrackPar)) { - return; + products.v0dataLink(-1, -1); + continue; } } } @@ -1925,6 +1927,8 @@ struct StrangenessBuilder { } } // enabled tables check } // constexpr requires check + } else { + products.v0dataLink(-1, -1); } } diff --git a/PWGLF/TableProducer/Strangeness/strangenesstofpid.cxx b/PWGLF/TableProducer/Strangeness/strangenesstofpid.cxx new file mode 100644 index 00000000000..75cb771dbea --- /dev/null +++ b/PWGLF/TableProducer/Strangeness/strangenesstofpid.cxx @@ -0,0 +1,1012 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +// *+-+*+-+*+-+*+-+*+-+*+-+* +// Lambdakzero PID +// *+-+*+-+*+-+*+-+*+-+*+-+* +// +/// \author Nicolò Jacazio +/// \author David Dobrigkeit Chinellato +/// \since 11/05/2023 +/// \brief Table producer for V0 daughter PID info +// +// This task produces daughter PID information for strange daughters +// taking into account the (candidate-by-candidate) time spent as a heavier +// (strange, weakly-decaying) particle. This task is meant to be a test, as +// it hasn't been fully tested yet! Use at your own peril for now :-) + +#include "TableHelper.h" + +#include "PWGLF/DataModel/LFParticleIdentification.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/TableProducer/PID/pidTOFBase.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CommonConstants/PhysicsConstants.h" +#include "DCAFitter/DCAFitterN.h" +#include "DataFormatsCalibration/MeanVertexObject.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DetectorsBase/GeometryManager.h" +#include "DetectorsBase/Propagator.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/RunningWorkflowInfo.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using std::array; + +// For original data loops +using V0OriginalDatas = soa::Join; +using CascOriginalDatas = soa::Join; +using TracksWithAllExtras = soa::Join; + +// For derived data analysis +using dauTracks = soa::Join; +using V0DerivedDatas = soa::Join; +using CascDerivedDatas = soa::Join; + +struct strangenesstofpid { + // TOF pid for strangeness (recalculated with topology) + Produces v0tofpid; // table with Nsigmas + Produces v0tofbeta; // table with betas + Produces v0tofdebugs; // table with extra debug information + Produces v0tofnsigmas; // table with nsigmas + Produces casctofpids; // cascades: table with base info + Produces casctofnsigmas; // cascades: table with Nsigmas + + Service ccdb; + + // mean vertex position to be used if no collision associated + o2::dataformats::MeanVertexObject* mVtx = nullptr; + + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + // master switches + Configurable calculateV0s{"calculateV0s", -1, "calculate V0-related TOF PID (0: no, 1: yes, -1: auto)"}; + Configurable calculateCascades{"calculateCascades", -1, "calculate cascade-related TOF PID (0: no, 1: yes, -1: auto)"}; + + // Operation and minimisation criteria + Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; + Configurable tofPosition{"tofPosition", 377.934f, "TOF effective (inscribed) radius"}; + Configurable doQA{"doQA", true, "create QA histos"}; + Configurable doNSigmas{"doNSigmas", false, "calculate TOF N-sigma"}; + Configurable doQANSigma{"doQANSigma", true, "create QA of Nsigma histos"}; + + // configurables related to V0s + struct : ConfigurableGroup { + std::string prefix = "v0Calibration"; + Configurable qaDCADau{"qaDCADau", 0.5, "DCA daughters (cm) for QA plots"}; + Configurable qaCosPA{"qaCosPA", 0.999, "CosPA for QA plots"}; + Configurable qaMassWindow{"qaMassWindow", 0.005, "Mass window around expected (in GeV/c2) for QA plots"}; + Configurable qaTPCNSigma{"qaTPCNSigma", 5, "TPC N-sigma to apply for qa plots"}; + } v0Group; + + // configurables related to V0s + struct : ConfigurableGroup { + std::string prefix = "cascadeCalibration"; + Configurable qaV0DCADau{"qaV0DCADau", 0.5, "DCA daughters (cm) for QA plots"}; + Configurable qaCascDCADau{"qaCascDCADau", 0.5, "DCA daughters (cm) for QA plots"}; + Configurable qaV0CosPA{"qaV0CosPA", 0.995, "CosPA for QA plots"}; + Configurable qaCascCosPA{"qaCascCosPA", 0.995, "CosPA for QA plots"}; + Configurable qaMassWindow{"qaMassWindow", 0.005, "Mass window around expected (in GeV/c2) for QA plots"}; + Configurable qaTPCNSigma{"qaTPCNSigma", 5, "TPC N-sigma to apply for qa plots"}; + } cascadeGroup; + + // CCDB options + Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; + Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; + Configurable nSigmaPath{"nSigmaPath", "Users/d/ddobrigk/stratof", "Path of information for n-sigma calculation"}; + Configurable mVtxPath{"mVtxPath", "GLO/Calib/MeanVertex", "Path of the mean vertex file"}; + + // manual + Configurable useCustomRunNumber{"useCustomRunNumber", false, "Use custom timestamp"}; + Configurable manualRunNumber{"manualRunNumber", 544122, "manual run number if no collisions saved"}; + + ConfigurableAxis axisEta{"axisEta", {20, -1.0f, +1.0f}, "#eta"}; + ConfigurableAxis axisDeltaTime{"axisDeltaTime", {2000, -1000.0f, +1000.0f}, "delta-time (ps)"}; + ConfigurableAxis axisTime{"axisTime", {200, 10000.0f, +20000.0f}, "T (ps)"}; + ConfigurableAxis axisNSigma{"axisNSigma", {200, -10.0f, +10.0f}, "N(#sigma)"}; + ConfigurableAxis axisExpectedOverMeasured{"axisExpectedOverMeasured", {200, 0.9f, 2.9f}, "T_{exp}/T_{meas}"}; + + // master p axis + ConfigurableAxis axisP{"axisP", {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}, "p_{T} (GeV/c)"}; + + // for zooming in at low values only (e-loss studies and effective correction) + ConfigurableAxis axisSmallP{"axisSmallP", {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}, "p_{T} (GeV/c)"}; + + // for n-sigma calibration + bool nSigmaCalibLoaded; + TList* nSigmaCalibObjects; + TH1 *hMeanPosLaPi, *hSigmaPosLaPi; + TH1 *hMeanPosLaPr, *hSigmaPosLaPr; + TH1 *hMeanNegLaPi, *hSigmaNegLaPi; + TH1 *hMeanNegLaPr, *hSigmaNegLaPr; + TH1 *hMeanPosK0Pi, *hSigmaPosK0Pi; + TH1 *hMeanNegK0Pi, *hSigmaNegK0Pi; + TH1 *hMeanPosXiPi, *hSigmaPosXiPi; + TH1 *hMeanPosXiPr, *hSigmaPosXiPr; + TH1 *hMeanNegXiPi, *hSigmaNegXiPi; + TH1 *hMeanNegXiPr, *hSigmaNegXiPr; + TH1 *hMeanBachXiPi, *hSigmaBachXiPi; + TH1 *hMeanPosOmPi, *hSigmaPosOmPi; + TH1 *hMeanPosOmPr, *hSigmaPosOmPr; + TH1 *hMeanNegOmPi, *hSigmaNegOmPi; + TH1 *hMeanNegOmPr, *hSigmaNegOmPr; + TH1 *hMeanBachOmKa, *hSigmaBachOmKa; + + int mRunNumber; + float d_bz; + float maxSnp; // max sine phi for propagation + float maxStep; // max step size (cm) for propagation + + // enum to keep track of the TOF-related properties for V0s + enum tofEnum { kLength = 0, + kHasTOF, + kNEnums }; + + /// function to calculate track length of this track up to a certain segment of a detector + /// to be used internally in another funcrtion that calculates length until it finds the proper one + /// warning: this could be optimised further for speed + /// \param track the input track + /// \param x1 x of the first point of the detector segment + /// \param y1 y of the first point of the detector segment + /// \param x2 x of the first point of the detector segment + /// \param y2 y of the first point of the detector segment + /// \param magneticField the magnetic field to use when propagating + float trackLengthToSegment(o2::track::TrackPar track, float x1, float y1, float x2, float y2, float magneticField) + { + // don't make use of the track parametrization + float length = -104; + + // causality protection + std::array mom; + track.getPxPyPzGlo(mom); + // get start point + std::array startPoint; + track.getXYZGlo(startPoint); + + // better replaced with scalar momentum check later + // if (((x1 + x2) * mom[0] + (y1 + y2) * mom[1]) < 0.0f) + // return -101; + + // get circle X, Y please + o2::math_utils::CircleXYf_t trcCircle; + float sna, csa; + track.getCircleParams(magneticField, trcCircle, sna, csa); + + // Calculate necessary inner product + float segmentModulus = std::hypot(x2 - x1, y2 - y1); + float alongSegment = ((trcCircle.xC - x1) * (x2 - x1) + (trcCircle.yC - y1) * (y2 - y1)) / segmentModulus; + + // find point of closest approach between segment and circle center + float pcaX = (x2 - x1) * alongSegment / segmentModulus + x1; + float pcaY = (y2 - y1) * alongSegment / segmentModulus + y1; + + float centerDistToPC = std::hypot(pcaX - trcCircle.xC, pcaY - trcCircle.yC); + + // distance pca-to-intercept in multiples of segment modulus (for convenience) + if (centerDistToPC > trcCircle.rC) + return -103; + + float pcaToIntercept = TMath::Sqrt(TMath::Abs(trcCircle.rC * trcCircle.rC - centerDistToPC * centerDistToPC)); + + float interceptX1 = pcaX + (x2 - x1) / segmentModulus * pcaToIntercept; + float interceptY1 = pcaY + (y2 - y1) / segmentModulus * pcaToIntercept; + float interceptX2 = pcaX - (x2 - x1) / segmentModulus * pcaToIntercept; + float interceptY2 = pcaY - (y2 - y1) / segmentModulus * pcaToIntercept; + + float scalarCheck1 = ((x2 - x1) * (interceptX1 - x1) + (y2 - y1) * (interceptY1 - y1)) / segmentModulus; + float scalarCheck2 = ((x2 - x1) * (interceptX2 - x1) + (y2 - y1) * (interceptY2 - y1)) / segmentModulus; + + float cosAngle1 = -1000, sinAngle1 = -1000, modulus1 = -1000; + float cosAngle2 = -1000, sinAngle2 = -1000, modulus2 = -1000; + float length1 = -1000, length2 = -1000; + + modulus1 = std::hypot(interceptX1 - trcCircle.xC, interceptY1 - trcCircle.yC) * std::hypot(startPoint[0] - trcCircle.xC, startPoint[1] - trcCircle.yC); + cosAngle1 = (interceptX1 - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (interceptY1 - trcCircle.yC) * (startPoint[1] - trcCircle.yC); + sinAngle1 = (interceptX1 - trcCircle.xC) * (startPoint[1] - trcCircle.yC) - (interceptY1 - trcCircle.yC) * (startPoint[0] - trcCircle.xC); + cosAngle1 /= modulus1; + sinAngle1 /= modulus1; + length1 = trcCircle.rC * TMath::ACos(cosAngle1); + length1 *= sqrt(1.0f + track.getTgl() * track.getTgl()); + + modulus2 = std::hypot(interceptX2 - trcCircle.xC, interceptY2 - trcCircle.yC) * std::hypot(startPoint[0] - trcCircle.xC, startPoint[1] - trcCircle.yC); + cosAngle2 = (interceptX2 - trcCircle.xC) * (startPoint[0] - trcCircle.xC) + (interceptY2 - trcCircle.yC) * (startPoint[1] - trcCircle.yC); + sinAngle2 = (interceptX2 - trcCircle.xC) * (startPoint[1] - trcCircle.yC) - (interceptY2 - trcCircle.yC) * (startPoint[0] - trcCircle.xC); + cosAngle2 /= modulus2; + sinAngle2 /= modulus2; + length2 = trcCircle.rC * TMath::ACos(cosAngle2); + length2 *= sqrt(1.0f + track.getTgl() * track.getTgl()); + + // rotate transverse momentum vector such that it is at intercepts + float angle1 = TMath::ACos(cosAngle1); + if (sinAngle1 < 0) + angle1 *= -1.0f; + float px1 = +TMath::Cos(angle1) * mom[0] + TMath::Sin(angle1) * mom[1]; + float py1 = -TMath::Sin(angle1) * mom[0] + TMath::Cos(angle1) * mom[1]; + + float angle2 = TMath::ACos(cosAngle2); + if (sinAngle2 < 0) + angle2 *= -1.0f; + float px2 = +TMath::Cos(angle2) * mom[0] + TMath::Sin(angle2) * mom[1]; + float py2 = -TMath::Sin(angle2) * mom[0] + TMath::Cos(angle2) * mom[1]; + + float midSegX = 0.5f * (x2 + x1); + float midSegY = 0.5f * (y2 + y1); + + float scalarMomentumCheck1 = px1 * midSegX + py1 * midSegY; + float scalarMomentumCheck2 = px2 * midSegX + py2 * midSegY; + + if (scalarCheck1 > 0.0f && scalarCheck1 < segmentModulus && scalarMomentumCheck1 > 0.0f) { + length = length1; + // X = interceptX1; Y = interceptY1; + } + if (scalarCheck2 > 0.0f && scalarCheck2 < segmentModulus && scalarMomentumCheck2 > 0.0f) { + length = length2; + // X = interceptX2; Y = interceptY2; + } + return length; + } + + /// function to calculate track length of this track up to a certain segmented detector + /// \param track the input track + /// \param magneticField the magnetic field to use when propagating + float findInterceptLength(o2::track::TrackPar track, float magneticField) + { + float length = 1e+6; + for (int iSeg = 0; iSeg < 18; iSeg++) { + // Detector segmentation loop + float segmentAngle = 20.0f / 180.0f * TMath::Pi(); + float theta = static_cast(iSeg) * 20.0f / 180.0f * TMath::Pi(); + float halfWidth = tofPosition * TMath::Tan(0.5f * segmentAngle); + float x1 = TMath::Cos(theta) * (-halfWidth) + TMath::Sin(theta) * tofPosition; + float y1 = -TMath::Sin(theta) * (-halfWidth) + TMath::Cos(theta) * tofPosition; + float x2 = TMath::Cos(theta) * (+halfWidth) + TMath::Sin(theta) * tofPosition; + float y2 = -TMath::Sin(theta) * (+halfWidth) + TMath::Cos(theta) * tofPosition; + float thisLength = trackLengthToSegment(track, x1, y1, x2, y2, magneticField); + if (thisLength < length && thisLength > 0) + length = thisLength; + } + if (length > 1e+5) + length = -100; // force negative to avoid misunderstandings + return length; + } + + void init(InitContext& initContext) + { + if (calculateV0s.value < 0) { + // check if TOF information is required, enable if so + calculateV0s.value = isTableRequiredInWorkflow(initContext, "V0TOFNSigmas"); + if (calculateV0s.value > 0) { + LOGF(info, "Strangeness TOF PID: V0 calculations enabled automatically"); + } + } + if (calculateCascades.value < 0) { + // check if TOF information is required, enable if so + calculateCascades.value = isTableRequiredInWorkflow(initContext, "CascTOFNSigmas"); + if (calculateCascades.value > 0) { + LOGF(info, "Strangeness TOF PID: Cascade calculations enabled automatically"); + } + } + + nSigmaCalibLoaded = false; + nSigmaCalibObjects = nullptr; + + // for n-sigma calibration + hMeanPosLaPi = nullptr; + hSigmaPosLaPi = nullptr; + hMeanPosLaPr = nullptr; + hSigmaPosLaPr = nullptr; + hMeanNegLaPi = nullptr; + hSigmaNegLaPi = nullptr; + hMeanNegLaPr = nullptr; + hSigmaNegLaPr = nullptr; + hMeanPosK0Pi = nullptr; + hSigmaNegK0Pi = nullptr; + hMeanNegK0Pi = nullptr; + hSigmaNegK0Pi = nullptr; + + mRunNumber = 0; + d_bz = 0; + maxSnp = 0.85f; // could be changed later + maxStep = 2.00f; // could be changed later + + ccdb->setURL(ccdburl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(false); + + // per event + histos.add("hCandidateCounter", "hCandidateCounter", kTH1F, {{500, -0.5f, 499.5f}}); + + // measured vs expected total time QA + if (doQA) { + // plots for effective eloss corrections - Lambda case + histos.add("h2dProtonMeasuredVsExpected", "h2dProtonMeasuredVsExpected", {HistType::kTH3F, {axisSmallP, axisExpectedOverMeasured, axisEta}}); + histos.add("h2dPionMeasuredVsExpected", "h2dPionMeasuredVsExpected", {HistType::kTH3F, {axisSmallP, axisExpectedOverMeasured, axisEta}}); + + histos.add("hArcDebug", "hArcDebug", kTH2F, {axisP, {50, -5.0f, 10.0f}}); + + // standard deltaTime values + if (calculateV0s.value > 0) { + histos.add("h2dDeltaTimePositiveLambdaPi", "h2dDeltaTimePositiveLambdaPi", {HistType::kTH3F, {axisP, axisEta, axisDeltaTime}}); + histos.add("h2dDeltaTimeNegativeLambdaPi", "h2dDeltaTimeNegativeLambdaPi", {HistType::kTH3F, {axisP, axisEta, axisDeltaTime}}); + histos.add("h2dDeltaTimePositiveLambdaPr", "h2dDeltaTimePositiveLambdaPr", {HistType::kTH3F, {axisP, axisEta, axisDeltaTime}}); + histos.add("h2dDeltaTimeNegativeLambdaPr", "h2dDeltaTimeNegativeLambdaPr", {HistType::kTH3F, {axisP, axisEta, axisDeltaTime}}); + histos.add("h2dDeltaTimePositiveK0ShortPi", "h2dDeltaTimePositiveK0ShortPi", {HistType::kTH3F, {axisP, axisEta, axisDeltaTime}}); + histos.add("h2dDeltaTimeNegativeK0ShortPi", "h2dDeltaTimeNegativeK0ShortPi", {HistType::kTH3F, {axisP, axisEta, axisDeltaTime}}); + } + + if (calculateCascades.value > 0) { + histos.add("h2dposDeltaTimeAsXiPi", "h2dposDeltaTimeAsXiPi", {HistType::kTH3F, {axisP, axisEta, axisDeltaTime}}); + histos.add("h2dposDeltaTimeAsXiPr", "h2dposDeltaTimeAsXiPr", {HistType::kTH3F, {axisP, axisEta, axisDeltaTime}}); + histos.add("h2dnegDeltaTimeAsXiPi", "h2dnegDeltaTimeAsXiPi", {HistType::kTH3F, {axisP, axisEta, axisDeltaTime}}); + histos.add("h2dnegDeltaTimeAsXiPr", "h2dnegDeltaTimeAsXiPr", {HistType::kTH3F, {axisP, axisEta, axisDeltaTime}}); + histos.add("h2dbachDeltaTimeAsXiPi", "h2dbachDeltaTimeAsXiPi", {HistType::kTH3F, {axisP, axisEta, axisDeltaTime}}); + + histos.add("h2dposDeltaTimeAsOmPi", "h2dposDeltaTimeAsOmPi", {HistType::kTH3F, {axisP, axisEta, axisDeltaTime}}); + histos.add("h2dposDeltaTimeAsOmPr", "h2dposDeltaTimeAsOmPr", {HistType::kTH3F, {axisP, axisEta, axisDeltaTime}}); + histos.add("h2dnegDeltaTimeAsOmPi", "h2dnegDeltaTimeAsOmPi", {HistType::kTH3F, {axisP, axisEta, axisDeltaTime}}); + histos.add("h2dnegDeltaTimeAsOmPr", "h2dnegDeltaTimeAsOmPr", {HistType::kTH3F, {axisP, axisEta, axisDeltaTime}}); + histos.add("h2dbachDeltaTimeAsOmKa", "h2dbachDeltaTimeAsOmKa", {HistType::kTH3F, {axisP, axisEta, axisDeltaTime}}); + } + + histos.add("h2dPositiveTOFProperties", "h2dPositiveTOFProperties", {HistType::kTH2F, {axisP, {4, -0.5, 3.5f}}}); + histos.add("h2dNegativeTOFProperties", "h2dNegativeTOFProperties", {HistType::kTH2F, {axisP, {4, -0.5, 3.5f}}}); + + if (doQANSigma) { + if (calculateV0s.value > 0) { + histos.add("h2dNSigmaPositiveLambdaPi", "h2dNSigmaPositiveLambdaPi", {HistType::kTH2F, {axisP, axisNSigma}}); + histos.add("h2dNSigmaNegativeLambdaPi", "h2dNSigmaNegativeLambdaPi", {HistType::kTH2F, {axisP, axisNSigma}}); + histos.add("h2dNSigmaPositiveLambdaPr", "h2dNSigmaPositiveLambdaPr", {HistType::kTH2F, {axisP, axisNSigma}}); + histos.add("h2dNSigmaNegativeLambdaPr", "h2dNSigmaNegativeLambdaPr", {HistType::kTH2F, {axisP, axisNSigma}}); + histos.add("h2dNSigmaPositiveK0ShortPi", "h2dNSigmaPositiveK0ShortPi", {HistType::kTH2F, {axisP, axisNSigma}}); + histos.add("h2dNSigmaNegativeK0ShortPi", "h2dNSigmaNegativeK0ShortPi", {HistType::kTH2F, {axisP, axisNSigma}}); + } + + if (calculateCascades.value > 0) { + histos.add("h2dNSigmaXiLaPi", "h2dNSigmaXiLaPi", {HistType::kTH2F, {axisP, axisNSigma}}); + histos.add("h2dNSigmaXiLaPr", "h2dNSigmaXiLaPr", {HistType::kTH2F, {axisP, axisNSigma}}); + histos.add("h2dNSigmaXiPi", "h2dNSigmaXiPi", {HistType::kTH2F, {axisP, axisNSigma}}); + histos.add("h2dNSigmaOmLaPi", "h2dNSigmaOmLaPi", {HistType::kTH2F, {axisP, axisNSigma}}); + histos.add("h2dNSigmaOmLaPr", "h2dNSigmaOmLaPr", {HistType::kTH2F, {axisP, axisNSigma}}); + histos.add("h2dNSigmaOmKa", "h2dNSigmaOmKa", {HistType::kTH2F, {axisP, axisNSigma}}); + } + } + + // delta lambda decay time + histos.add("h2dLambdaDeltaDecayTime", "h2dLambdaDeltaDecayTime", {HistType::kTH2F, {axisP, axisDeltaTime}}); + } + } + + void initCCDB(int runNumber) + { + if (mRunNumber == runNumber) { + return; + } + + // In case override, don't proceed, please - no CCDB access required + if (d_bz_input > -990) { + d_bz = d_bz_input; + o2::parameters::GRPMagField grpmag; + if (fabs(d_bz) > 1e-5) { + grpmag.setL3Current(30000.f / (d_bz / 5.0f)); + } + o2::base::Propagator::initFieldFromGRP(&grpmag); + mVtx = ccdb->getForRun(mVtxPath, runNumber); + mRunNumber = runNumber; + return; + } + + o2::parameters::GRPObject* grpo = ccdb->getForRun(grpPath, runNumber); + o2::parameters::GRPMagField* grpmag = 0x0; + if (grpo) { + o2::base::Propagator::initFieldFromGRP(grpo); + // Fetch magnetic field from ccdb for current collision + d_bz = grpo->getNominalL3Field(); + LOG(info) << "Retrieved GRP for run " << runNumber << " with magnetic field of " << d_bz << " kZG"; + } else { + grpmag = ccdb->getForRun(grpmagPath, runNumber); + if (!grpmag) { + LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for run " << runNumber; + } + o2::base::Propagator::initFieldFromGRP(grpmag); + // Fetch magnetic field from ccdb for current collision + d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); + mVtx = ccdb->getForRun(mVtxPath, runNumber); + LOG(info) << "Retrieved GRP for run " << runNumber << " with magnetic field of " << d_bz << " kZG"; + } + + // if TOF Nsigma desired + if (doNSigmas) { + nSigmaCalibObjects = ccdb->getForRun(nSigmaPath, runNumber); + if (nSigmaCalibObjects) { + LOGF(info, "loaded TList with this many objects: %i", nSigmaCalibObjects->GetEntries()); + nSigmaCalibLoaded = true; // made it thus far, mark loaded + + if (calculateV0s.value) { + hMeanPosLaPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanPosLaPi")); + hMeanPosLaPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanPosLaPr")); + hMeanNegLaPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanNegLaPi")); + hMeanNegLaPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanNegLaPr")); + hMeanPosK0Pi = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanPosK0Pi")); + hMeanNegK0Pi = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanNegK0Pi")); + + hSigmaPosLaPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaPosLaPi")); + hSigmaPosLaPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaPosLaPr")); + hSigmaNegLaPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaNegLaPi")); + hSigmaNegLaPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaNegLaPr")); + hSigmaPosK0Pi = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaPosK0Pi")); + hSigmaNegK0Pi = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaNegK0Pi")); + + if (!hMeanPosLaPi) + LOG(info) << "Problems finding mean histogram hMeanPosLaPi!"; + if (!hMeanPosLaPr) + LOG(info) << "Problems finding mean histogram hMeanPosLaPr!"; + if (!hMeanNegLaPi) + LOG(info) << "Problems finding mean histogram hMeanNegLaPi!"; + if (!hMeanNegLaPr) + LOG(info) << "Problems finding mean histogram hMeanNegLaPr!"; + if (!hMeanPosK0Pi) + LOG(info) << "Problems finding mean histogram hMeanPosK0Pi!"; + if (!hMeanNegK0Pi) + LOG(info) << "Problems finding mean histogram hMeanNegK0Pi!"; + if (!hSigmaPosK0Pi || !hSigmaNegK0Pi || !hSigmaPosLaPi || !hSigmaPosLaPr || !hSigmaNegLaPi || !hSigmaNegLaPr) { + LOG(info) << "Problems finding sigma histograms!"; + } + + if (calculateCascades.value) { + hMeanPosXiPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanPosXiPi")); + hMeanPosXiPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanPosXiPr")); + hMeanNegXiPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanNegXiPi")); + hMeanNegXiPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanNegXiPr")); + hMeanBachXiPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanBachXiPi")); + hMeanPosOmPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanPosOmPi")); + hMeanPosOmPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanPosOmPr")); + hMeanNegOmPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanNegOmPi")); + hMeanNegOmPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanNegOmPr")); + hMeanBachOmKa = reinterpret_cast(nSigmaCalibObjects->FindObject("hMeanBachOmKa")); + + hSigmaPosXiPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaPosXiPi")); + hSigmaPosXiPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaPosXiPr")); + hSigmaNegXiPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaNegXiPi")); + hSigmaNegXiPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaNegXiPr")); + hSigmaBachXiPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaBachXiPi")); + hSigmaPosOmPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaPosOmPi")); + hSigmaPosOmPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaPosOmPr")); + hSigmaNegOmPi = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaNegOmPi")); + hSigmaNegOmPr = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaNegOmPr")); + hSigmaBachOmKa = reinterpret_cast(nSigmaCalibObjects->FindObject("hSigmaBachOmKa")); + + if (!hMeanPosXiPi || !hMeanPosXiPr || !hMeanNegXiPi || !hMeanNegXiPr || !hMeanBachXiPi) + LOG(info) << "Problems finding xi mean histograms!"; + if (!hMeanPosOmPi || !hMeanPosOmPr || !hMeanNegOmPi || !hMeanNegOmPr || !hMeanBachOmKa) + LOG(info) << "Problems finding omega sigma histograms!"; + if (!hSigmaPosXiPi || !hSigmaPosXiPr || !hSigmaNegXiPi || !hSigmaNegXiPr || !hSigmaBachXiPi) + LOG(info) << "Problems finding xi sigma histograms!"; + if (!hSigmaPosOmPi || !hSigmaPosOmPr || !hSigmaNegOmPi || !hSigmaNegOmPr || !hSigmaBachOmKa) + LOG(info) << "Problems finding omega sigma histograms!"; + } + } + } + } + mRunNumber = runNumber; + } + + float velocity(float lMomentum, float lMass) + { + // Momentum p and mass m -> returns speed in centimeters per picosecond + // Useful for TOF calculations + float lA = (lMomentum / lMass) * (lMomentum / lMass); + return 0.0299792458 * TMath::Sqrt(lA / (1 + lA)); + } + + // templatized process function for symmetric operation in derived and original AO2D + template + void processV0Candidate(TCollision const& collision, TV0 const& v0, TTrack const& pTra, TTrack const& nTra) + { + // time of V0 segment + float lengthV0 = std::hypot(v0.x() - collision.getX(), v0.y() - collision.getY(), v0.z() - collision.getZ()); + float velocityK0Short = velocity(v0.p(), o2::constants::physics::MassKaonNeutral); + float velocityLambda = velocity(v0.p(), o2::constants::physics::MassLambda); + float timeK0Short = lengthV0 / velocityK0Short; // in picoseconds + float timeLambda = lengthV0 / velocityLambda; // in picoseconds + + // initialize from V0 position and momenta + o2::track::TrackPar posTrack = o2::track::TrackPar({v0.x(), v0.y(), v0.z()}, {v0.pxpos(), v0.pypos(), v0.pzpos()}, +1); + o2::track::TrackPar negTrack = o2::track::TrackPar({v0.x(), v0.y(), v0.z()}, {v0.pxneg(), v0.pyneg(), v0.pzneg()}, -1); + + float deltaTimePositiveLambdaPi = o2::aod::v0data::kNoTOFValue; + float deltaTimeNegativeLambdaPi = o2::aod::v0data::kNoTOFValue; + float deltaTimePositiveLambdaPr = o2::aod::v0data::kNoTOFValue; + float deltaTimeNegativeLambdaPr = o2::aod::v0data::kNoTOFValue; + float deltaTimePositiveK0ShortPi = o2::aod::v0data::kNoTOFValue; + float deltaTimeNegativeK0ShortPi = o2::aod::v0data::kNoTOFValue; + + float nSigmaPositiveLambdaPi = o2::aod::v0data::kNoTOFValue; + float nSigmaPositiveLambdaPr = o2::aod::v0data::kNoTOFValue; + float nSigmaNegativeLambdaPi = o2::aod::v0data::kNoTOFValue; + float nSigmaNegativeLambdaPr = o2::aod::v0data::kNoTOFValue; + float nSigmaPositiveK0ShortPi = o2::aod::v0data::kNoTOFValue; + float nSigmaNegativeK0ShortPi = o2::aod::v0data::kNoTOFValue; + + float velocityPositivePr = velocity(posTrack.getP(), o2::constants::physics::MassProton); + float velocityPositivePi = velocity(posTrack.getP(), o2::constants::physics::MassPionCharged); + float velocityNegativePr = velocity(negTrack.getP(), o2::constants::physics::MassProton); + float velocityNegativePi = velocity(negTrack.getP(), o2::constants::physics::MassPionCharged); + + float lengthPositive = findInterceptLength(posTrack, d_bz); // FIXME: tofPosition ok? adjust? + float lengthNegative = findInterceptLength(negTrack, d_bz); // FIXME: tofPosition ok? adjust? + float timePositivePr = lengthPositive / velocityPositivePr; + float timePositivePi = lengthPositive / velocityPositivePi; + float timeNegativePr = lengthNegative / velocityNegativePr; + float timeNegativePi = lengthNegative / velocityNegativePi; + + if (pTra.hasTOF() && lengthPositive > 0) { + deltaTimePositiveLambdaPr = (pTra.tofSignal() - pTra.tofEvTime()) - (timeLambda + timePositivePr); + deltaTimePositiveLambdaPi = (pTra.tofSignal() - pTra.tofEvTime()) - (timeLambda + timePositivePi); + deltaTimePositiveK0ShortPi = (pTra.tofSignal() - pTra.tofEvTime()) - (timeK0Short + timePositivePi); + } + if (nTra.hasTOF() && lengthNegative > 0) { + deltaTimeNegativeLambdaPr = (nTra.tofSignal() - nTra.tofEvTime()) - (timeLambda + timeNegativePr); + deltaTimeNegativeLambdaPi = (nTra.tofSignal() - nTra.tofEvTime()) - (timeLambda + timeNegativePi); + deltaTimeNegativeK0ShortPi = (nTra.tofSignal() - nTra.tofEvTime()) - (timeK0Short + timeNegativePi); + } + + if (doQA) { + // calculate and pack properties for QA purposes + int posProperties = 0; + if (lengthPositive > 0) + posProperties = posProperties | (static_cast(1) << kLength); + if (pTra.hasTOF()) + posProperties = posProperties | (static_cast(1) << kHasTOF); + int negProperties = 0; + if (lengthNegative > 0) + negProperties = negProperties | (static_cast(1) << kLength); + if (nTra.hasTOF()) + negProperties = negProperties | (static_cast(1) << kHasTOF); + + histos.fill(HIST("h2dPositiveTOFProperties"), v0.p(), posProperties); + histos.fill(HIST("h2dNegativeTOFProperties"), v0.p(), negProperties); + } + + float deltaDecayTimeLambda = -10e+4; + float deltaDecayTimeAntiLambda = -10e+4; + float deltaDecayTimeK0Short = -10e+4; + if (nTra.hasTOF() && pTra.hasTOF() > 0 && lengthPositive > 0 && lengthNegative > 0) { // does not depend on event time + deltaDecayTimeLambda = (pTra.tofSignal() - timePositivePr) - (nTra.tofSignal() - timeNegativePi); + deltaDecayTimeAntiLambda = (pTra.tofSignal() - timePositivePi) - (nTra.tofSignal() - timeNegativePr); + deltaDecayTimeK0Short = (pTra.tofSignal() - timePositivePi) - (nTra.tofSignal() - timeNegativePi); + } + + // calculate betas + + float evTimeMean = 0.5f * (pTra.tofEvTime() + nTra.tofEvTime()); + float decayTimeLambda = 0.5f * ((pTra.tofSignal() - timePositivePr) + (nTra.tofSignal() - timeNegativePi)) - evTimeMean; + float decayTimeAntiLambda = 0.5f * ((pTra.tofSignal() - timePositivePi) + (nTra.tofSignal() - timeNegativePr)) - evTimeMean; + float decayTimeK0Short = 0.5f * ((pTra.tofSignal() - timePositivePi) + (nTra.tofSignal() - timeNegativePi)) - evTimeMean; + + float betaLambda = o2::aod::cascdata::kNoTOFValue; + ; + float betaAntiLambda = o2::aod::cascdata::kNoTOFValue; + ; + float betaK0Short = o2::aod::cascdata::kNoTOFValue; + ; + + if (nTra.hasTOF() && pTra.hasTOF()) { + betaLambda = (lengthV0 / decayTimeLambda) / 0.0299792458; + betaAntiLambda = (lengthV0 / decayTimeAntiLambda) / 0.0299792458; + betaK0Short = (lengthV0 / decayTimeK0Short) / 0.0299792458; + } + + v0tofpid(deltaTimePositiveLambdaPi, deltaTimePositiveLambdaPr, + deltaTimeNegativeLambdaPi, deltaTimeNegativeLambdaPr, + deltaTimePositiveK0ShortPi, deltaTimeNegativeK0ShortPi, + deltaDecayTimeLambda, deltaDecayTimeAntiLambda, deltaDecayTimeK0Short); + v0tofbeta(betaLambda, betaAntiLambda, betaK0Short); + v0tofdebugs(timeLambda, timeK0Short, timePositivePr, timePositivePi, timeNegativePr, timeNegativePi); + + // do Nsigmas if requested + if (doNSigmas && nSigmaCalibLoaded) { + // sweep through all viable hypotheses and produce N-sigma + + if (deltaTimePositiveLambdaPi > -1e+5) + nSigmaPositiveLambdaPi = (deltaTimePositiveLambdaPi - hMeanPosLaPi->Interpolate(v0.p())) / hSigmaPosLaPi->Interpolate(v0.p()); + if (deltaTimePositiveLambdaPr > -1e+5) + nSigmaPositiveLambdaPr = (deltaTimePositiveLambdaPr - hMeanPosLaPr->Interpolate(v0.p())) / hSigmaPosLaPr->Interpolate(v0.p()); + if (deltaTimeNegativeLambdaPi > -1e+5) + nSigmaNegativeLambdaPi = (deltaTimeNegativeLambdaPi - hMeanNegLaPi->Interpolate(v0.p())) / hSigmaNegLaPi->Interpolate(v0.p()); + if (deltaTimeNegativeLambdaPr > -1e+5) + nSigmaNegativeLambdaPr = (deltaTimeNegativeLambdaPr - hMeanNegLaPr->Interpolate(v0.p())) / hSigmaNegLaPr->Interpolate(v0.p()); + if (deltaTimePositiveK0ShortPi > -1e+5) + nSigmaPositiveK0ShortPi = (deltaTimePositiveK0ShortPi - hMeanPosK0Pi->Interpolate(v0.p())) / hSigmaPosK0Pi->Interpolate(v0.p()); + if (deltaTimeNegativeK0ShortPi > -1e+5) + nSigmaNegativeK0ShortPi = (deltaTimeNegativeK0ShortPi - hMeanNegK0Pi->Interpolate(v0.p())) / hSigmaNegK0Pi->Interpolate(v0.p()); + + v0tofnsigmas( + nSigmaPositiveLambdaPr, nSigmaNegativeLambdaPi, + nSigmaNegativeLambdaPr, nSigmaPositiveLambdaPi, + nSigmaPositiveK0ShortPi, nSigmaNegativeK0ShortPi); + } + + float positiveP = std::hypot(v0.pxpos(), v0.pypos(), v0.pzpos()); + float negativeP = std::hypot(v0.pxneg(), v0.pyneg(), v0.pzneg()); + + if (doQA) { + if (pTra.hasTOF()) { + if (v0.v0cosPA() > v0Group.qaCosPA && v0.dcaV0daughters() < v0Group.qaDCADau) { + if (std::abs(v0.mLambda() - 1.115683) < v0Group.qaMassWindow && fabs(pTra.tpcNSigmaPr()) < v0Group.qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma) { + histos.fill(HIST("h2dDeltaTimePositiveLambdaPr"), v0.p(), v0.eta(), deltaTimePositiveLambdaPr); + histos.fill(HIST("h2dProtonMeasuredVsExpected"), + (timeLambda + timePositivePr) / (pTra.tofSignal() - pTra.tofEvTime()), + positiveP, v0.positiveeta()); + if (doQANSigma) + histos.fill(HIST("h2dNSigmaPositiveLambdaPr"), v0.p(), nSigmaPositiveLambdaPr); + } + if (std::abs(v0.mAntiLambda() - 1.115683) < v0Group.qaMassWindow && fabs(pTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma && fabs(nTra.tpcNSigmaPr()) < v0Group.qaTPCNSigma) { + histos.fill(HIST("h2dDeltaTimePositiveLambdaPi"), v0.p(), v0.eta(), deltaTimePositiveLambdaPi); + if (doQANSigma) + histos.fill(HIST("h2dNSigmaPositiveLambdaPi"), v0.p(), nSigmaPositiveLambdaPi); + } + if (std::abs(v0.mK0Short() - 0.497) < v0Group.qaMassWindow && fabs(pTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma) { + histos.fill(HIST("h2dDeltaTimePositiveK0ShortPi"), v0.p(), v0.eta(), deltaTimePositiveK0ShortPi); + if (doQANSigma) + histos.fill(HIST("h2dNSigmaPositiveK0ShortPi"), v0.p(), nSigmaPositiveK0ShortPi); + } + } + } + + if (nTra.hasTOF()) { + if (v0.v0cosPA() > v0Group.qaCosPA && v0.dcaV0daughters() < v0Group.qaDCADau) { + if (std::abs(v0.mLambda() - 1.115683) < v0Group.qaMassWindow && fabs(pTra.tpcNSigmaPr()) < v0Group.qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma) { + histos.fill(HIST("h2dDeltaTimeNegativeLambdaPi"), v0.p(), v0.eta(), deltaTimeNegativeLambdaPi); + histos.fill(HIST("h2dPionMeasuredVsExpected"), + (timeLambda + timeNegativePi) / (nTra.tofSignal() - nTra.tofEvTime()), + negativeP, v0.negativeeta()); + if (doQANSigma) + histos.fill(HIST("h2dNSigmaNegativeLambdaPi"), v0.p(), nSigmaNegativeLambdaPi); + } + if (std::abs(v0.mAntiLambda() - 1.115683) < v0Group.qaMassWindow && fabs(pTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma && fabs(nTra.tpcNSigmaPr()) < v0Group.qaTPCNSigma) { + histos.fill(HIST("h2dDeltaTimeNegativeLambdaPr"), v0.p(), v0.eta(), deltaTimeNegativeLambdaPr); + if (doQANSigma) + histos.fill(HIST("h2dNSigmaNegativeLambdaPr"), v0.p(), nSigmaNegativeLambdaPr); + } + if (std::abs(v0.mK0Short() - 0.497) < v0Group.qaMassWindow && fabs(pTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < v0Group.qaTPCNSigma) { + histos.fill(HIST("h2dDeltaTimeNegativeK0ShortPi"), v0.p(), v0.eta(), deltaTimeNegativeK0ShortPi); + if (doQANSigma) + histos.fill(HIST("h2dNSigmaNegativeK0ShortPi"), v0.p(), nSigmaNegativeK0ShortPi); + } + } + } + // delta lambda decay time + histos.fill(HIST("h2dLambdaDeltaDecayTime"), v0.p(), deltaDecayTimeLambda); + } + } + + template + void processCascadeCandidate(TCollision const& collision, TCascade const& cascade, TTrack const& pTra, TTrack const& nTra, TTrack const& bTra) + { + // initialize from positions and momenta as needed + o2::track::TrackPar posTrack = o2::track::TrackPar({cascade.xlambda(), cascade.ylambda(), cascade.zlambda()}, {cascade.pxpos(), cascade.pypos(), cascade.pzpos()}, +1); + o2::track::TrackPar negTrack = o2::track::TrackPar({cascade.xlambda(), cascade.ylambda(), cascade.zlambda()}, {cascade.pxneg(), cascade.pyneg(), cascade.pzneg()}, -1); + o2::track::TrackPar bachTrack = o2::track::TrackPar({cascade.x(), cascade.y(), cascade.z()}, {cascade.pxbach(), cascade.pybach(), cascade.pzbach()}, cascade.sign()); + o2::track::TrackPar cascTrack = o2::track::TrackPar({cascade.x(), cascade.y(), cascade.z()}, {cascade.px(), cascade.py(), cascade.pz()}, cascade.sign()); + + // start calculation: calculate velocities + float velocityPositivePr = velocity(posTrack.getP(), o2::constants::physics::MassProton); + float velocityPositivePi = velocity(posTrack.getP(), o2::constants::physics::MassPionCharged); + float velocityNegativePr = velocity(negTrack.getP(), o2::constants::physics::MassProton); + float velocityNegativePi = velocity(negTrack.getP(), o2::constants::physics::MassPionCharged); + float velocityBachelorPi = velocity(bachTrack.getP(), o2::constants::physics::MassPionCharged); + float velocityBachelorKa = velocity(bachTrack.getP(), o2::constants::physics::MassKaonCharged); + float velocityXi = velocity(cascTrack.getP(), o2::constants::physics::MassXiMinus); + float velocityOm = velocity(cascTrack.getP(), o2::constants::physics::MassOmegaMinus); + float velocityLa = velocity(std::hypot(cascade.pxlambda(), cascade.pylambda(), cascade.pzlambda()), o2::constants::physics::MassLambda); + + // calculate daughter length to TOF intercept + float lengthPositive = findInterceptLength(posTrack, d_bz); // FIXME: tofPosition ok? adjust? + float lengthNegative = findInterceptLength(negTrack, d_bz); // FIXME: tofPosition ok? adjust? + float lengthBachelor = findInterceptLength(bachTrack, d_bz); // FIXME: tofPosition ok? adjust? + + // calculate mother lengths + float lengthV0 = std::hypot(cascade.xlambda() - cascade.x(), cascade.ylambda() - cascade.y(), cascade.zlambda() - cascade.z()); + float lengthCascade = o2::aod::cascdata::kNoTOFValue; + ; + const o2::math_utils::Point3D collVtx{collision.getX(), collision.getY(), collision.getZ()}; + bool successPropag = o2::base::Propagator::Instance()->propagateToDCA(collVtx, cascTrack, d_bz, 2.f, o2::base::Propagator::MatCorrType::USEMatCorrNONE); + float d = -1.0f, d3d = 0.0f; + float linearToPV = std::hypot(cascade.x() - collision.getX(), cascade.y() - collision.getY(), cascade.z() - collision.getZ()); + if (successPropag) { + std::array cascCloseToPVPosition; + cascTrack.getXYZGlo(cascCloseToPVPosition); + o2::math_utils::CircleXYf_t trcCircleCascade; + float sna, csa; + cascTrack.getCircleParams(d_bz, trcCircleCascade, sna, csa); + + // calculate 2D distance between two points + d = std::hypot(cascade.x() - cascCloseToPVPosition[0], cascade.y() - cascCloseToPVPosition[1]); + d3d = std::hypot(cascade.x() - cascCloseToPVPosition[0], cascade.y() - cascCloseToPVPosition[1], cascade.z() - cascCloseToPVPosition[2]); // cross-check variable + float sinThetaOverTwo = d / (2.0f * trcCircleCascade.rC); + lengthCascade = 2.0f * trcCircleCascade.rC * TMath::ASin(sinThetaOverTwo); + lengthCascade *= sqrt(1.0f + cascTrack.getTgl() * cascTrack.getTgl()); + } + + if (!successPropag) { + lengthCascade = linearToPV; // if propagation failed, use linear estimate (optional: actually do not define?) + } + + // lambda, xi and omega flight time is always defined + float lambdaFlight = lengthV0 / velocityLa; + float xiFlight = lengthCascade / velocityXi; + float omFlight = lengthCascade / velocityOm; + float posFlightPi = lengthPositive / velocityPositivePi; + float posFlightPr = lengthPositive / velocityPositivePr; + float negFlightPi = lengthNegative / velocityNegativePi; + float negFlightPr = lengthNegative / velocityNegativePr; + float bachFlightPi = lengthBachelor / velocityBachelorPi; + float bachFlightKa = lengthBachelor / velocityBachelorKa; + + // initialize delta-times (actual PID variables) + float posDeltaTimeAsXiPi = o2::aod::cascdata::kNoTOFValue, posDeltaTimeAsXiPr = o2::aod::cascdata::kNoTOFValue; + float negDeltaTimeAsXiPi = o2::aod::cascdata::kNoTOFValue, negDeltaTimeAsXiPr = o2::aod::cascdata::kNoTOFValue; + float bachDeltaTimeAsXiPi = o2::aod::cascdata::kNoTOFValue; + float posDeltaTimeAsOmPi = o2::aod::cascdata::kNoTOFValue, posDeltaTimeAsOmPr = o2::aod::cascdata::kNoTOFValue; + float negDeltaTimeAsOmPi = o2::aod::cascdata::kNoTOFValue, negDeltaTimeAsOmPr = o2::aod::cascdata::kNoTOFValue; + float bachDeltaTimeAsOmKa = o2::aod::cascdata::kNoTOFValue; + + if (pTra.hasTOF()) { + posDeltaTimeAsXiPi = (pTra.tofSignal() - pTra.tofEvTime()) - (xiFlight + lambdaFlight + posFlightPi); + posDeltaTimeAsXiPr = (pTra.tofSignal() - pTra.tofEvTime()) - (xiFlight + lambdaFlight + posFlightPr); + posDeltaTimeAsOmPi = (pTra.tofSignal() - pTra.tofEvTime()) - (omFlight + lambdaFlight + posFlightPi); + posDeltaTimeAsOmPr = (pTra.tofSignal() - pTra.tofEvTime()) - (omFlight + lambdaFlight + posFlightPr); + } + if (nTra.hasTOF()) { + negDeltaTimeAsXiPi = (nTra.tofSignal() - nTra.tofEvTime()) - (xiFlight + lambdaFlight + negFlightPi); + negDeltaTimeAsXiPr = (nTra.tofSignal() - nTra.tofEvTime()) - (xiFlight + lambdaFlight + negFlightPr); + negDeltaTimeAsOmPi = (nTra.tofSignal() - nTra.tofEvTime()) - (omFlight + lambdaFlight + negFlightPi); + negDeltaTimeAsOmPr = (nTra.tofSignal() - nTra.tofEvTime()) - (omFlight + lambdaFlight + negFlightPr); + } + if (bTra.hasTOF()) { + bachDeltaTimeAsXiPi = (bTra.tofSignal() - bTra.tofEvTime()) - (xiFlight + bachFlightPi); + bachDeltaTimeAsOmKa = (bTra.tofSignal() - bTra.tofEvTime()) - (omFlight + bachFlightKa); + } + + casctofpids( + posDeltaTimeAsXiPi, posDeltaTimeAsXiPr, negDeltaTimeAsXiPi, negDeltaTimeAsXiPr, bachDeltaTimeAsXiPi, + posDeltaTimeAsOmPi, posDeltaTimeAsOmPr, negDeltaTimeAsOmPi, negDeltaTimeAsOmPr, bachDeltaTimeAsOmKa); + + float nSigmaXiLaPr = o2::aod::cascdata::kNoTOFValue; + ; + float nSigmaXiLaPi = o2::aod::cascdata::kNoTOFValue; + ; + float nSigmaXiPi = o2::aod::cascdata::kNoTOFValue; + ; + float nSigmaOmLaPr = o2::aod::cascdata::kNoTOFValue; + ; + float nSigmaOmLaPi = o2::aod::cascdata::kNoTOFValue; + ; + float nSigmaOmKa = o2::aod::cascdata::kNoTOFValue; + ; + + // go for Nsigma values if requested + if (doNSigmas && nSigmaCalibLoaded) { + // Xi hypothesis ________________________ + if (cascade.sign() < 0) { // XiMinus + if (posDeltaTimeAsXiPr > -1e+5) // proton from Lambda from XiMinus has signal + nSigmaXiLaPr = (posDeltaTimeAsXiPr - hMeanPosXiPr->Interpolate(cascade.p())) / hSigmaPosXiPr->Interpolate(cascade.p()); + if (negDeltaTimeAsXiPi > -1e+5) // pion from Lambda from XiMinus has signal + nSigmaXiLaPi = (negDeltaTimeAsXiPi - hMeanNegXiPi->Interpolate(cascade.p())) / hSigmaNegXiPi->Interpolate(cascade.p()); + if (bachDeltaTimeAsXiPi > -1e+5) // pion from XiMinus has signal + nSigmaXiPi = (bachDeltaTimeAsXiPi - hMeanBachXiPi->Interpolate(cascade.p())) / hSigmaBachXiPi->Interpolate(cascade.p()); + if (posDeltaTimeAsOmPr > -1e+5) // proton from Lambda from OmegaMinus has signal + nSigmaOmLaPr = (posDeltaTimeAsOmPr - hMeanPosOmPr->Interpolate(cascade.p())) / hSigmaPosOmPr->Interpolate(cascade.p()); + if (negDeltaTimeAsOmPi > -1e+5) // pion from Lambda from OmegaMinus has signal + nSigmaOmLaPi = (negDeltaTimeAsOmPi - hMeanNegOmPi->Interpolate(cascade.p())) / hSigmaNegOmPi->Interpolate(cascade.p()); + if (bachDeltaTimeAsOmKa > -1e+5) // kaon from OmegaMinus has signal + nSigmaOmKa = (bachDeltaTimeAsOmKa - hMeanBachOmKa->Interpolate(cascade.p())) / hSigmaBachOmKa->Interpolate(cascade.p()); + } else { + if (posDeltaTimeAsXiPi > -1e+5) // proton from Lambda from XiMinus has signal + nSigmaXiLaPi = (posDeltaTimeAsXiPi - hMeanPosXiPi->Interpolate(cascade.p())) / hSigmaPosXiPi->Interpolate(cascade.p()); + if (negDeltaTimeAsXiPr > -1e+5) // pion from Lambda from XiMinus has signal + nSigmaXiLaPr = (negDeltaTimeAsXiPr - hMeanNegXiPr->Interpolate(cascade.p())) / hSigmaNegXiPr->Interpolate(cascade.p()); + if (bachDeltaTimeAsXiPi > -1e+5) // pion from XiMinus has signal + nSigmaXiPi = (bachDeltaTimeAsXiPi - hMeanBachXiPi->Interpolate(cascade.p())) / hSigmaBachXiPi->Interpolate(cascade.p()); + if (posDeltaTimeAsOmPi > -1e+5) // proton from Lambda from OmegaMinus has signal + nSigmaOmLaPi = (posDeltaTimeAsOmPi - hMeanPosOmPi->Interpolate(cascade.p())) / hSigmaPosOmPi->Interpolate(cascade.p()); + if (negDeltaTimeAsOmPr > -1e+5) // pion from Lambda from OmegaMinus has signal + nSigmaOmLaPr = (negDeltaTimeAsOmPr - hMeanNegOmPr->Interpolate(cascade.p())) / hSigmaNegOmPr->Interpolate(cascade.p()); + if (bachDeltaTimeAsOmKa > -1e+5) // kaon from OmegaMinus has signal + nSigmaOmKa = (bachDeltaTimeAsOmKa - hMeanBachOmKa->Interpolate(cascade.p())) / hSigmaBachOmKa->Interpolate(cascade.p()); + } + casctofnsigmas(nSigmaXiLaPi, nSigmaXiLaPr, nSigmaXiPi, nSigmaOmLaPi, nSigmaOmLaPr, nSigmaOmKa); + } + + if (doQA) { + // fill QA histograms for cross-checking + histos.fill(HIST("hArcDebug"), cascade.p(), lengthCascade - d3d); // for debugging purposes + + if (cascade.dcaV0daughters() < cascadeGroup.qaV0DCADau && cascade.dcacascdaughters() < cascadeGroup.qaCascDCADau && cascade.v0cosPA(collision.getX(), collision.getY(), collision.getZ()) > cascadeGroup.qaV0CosPA && cascade.casccosPA(collision.getX(), collision.getY(), collision.getZ()) > cascadeGroup.qaCascCosPA) { + if (cascade.sign() < 0) { + if (std::abs(cascade.mXi() - 1.32171) < cascadeGroup.qaMassWindow && fabs(pTra.tpcNSigmaPr()) < cascadeGroup.qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < cascadeGroup.qaTPCNSigma && fabs(bTra.tpcNSigmaPi()) < cascadeGroup.qaTPCNSigma) { + histos.fill(HIST("h2dposDeltaTimeAsXiPr"), cascade.p(), cascade.eta(), posDeltaTimeAsXiPr); + histos.fill(HIST("h2dnegDeltaTimeAsXiPi"), cascade.p(), cascade.eta(), negDeltaTimeAsXiPi); + histos.fill(HIST("h2dbachDeltaTimeAsXiPi"), cascade.p(), cascade.eta(), bachDeltaTimeAsXiPi); + if (doQANSigma) { + histos.fill(HIST("h2dNSigmaXiLaPi"), cascade.p(), nSigmaXiLaPi); + histos.fill(HIST("h2dNSigmaXiLaPr"), cascade.p(), nSigmaXiLaPr); + histos.fill(HIST("h2dNSigmaXiPi"), cascade.p(), nSigmaXiPi); + } + } + if (std::abs(cascade.mOmega() - 1.67245) < cascadeGroup.qaMassWindow && fabs(pTra.tpcNSigmaPr()) < cascadeGroup.qaTPCNSigma && fabs(nTra.tpcNSigmaPi()) < cascadeGroup.qaTPCNSigma && fabs(bTra.tpcNSigmaKa()) < cascadeGroup.qaTPCNSigma) { + histos.fill(HIST("h2dposDeltaTimeAsOmPr"), cascade.p(), cascade.eta(), posDeltaTimeAsOmPr); + histos.fill(HIST("h2dnegDeltaTimeAsOmPi"), cascade.p(), cascade.eta(), negDeltaTimeAsOmPi); + histos.fill(HIST("h2dbachDeltaTimeAsOmKa"), cascade.p(), cascade.eta(), bachDeltaTimeAsOmKa); + if (doQANSigma) { + histos.fill(HIST("h2dNSigmaOmLaPi"), cascade.p(), nSigmaOmLaPi); + histos.fill(HIST("h2dNSigmaOmLaPr"), cascade.p(), nSigmaOmLaPr); + histos.fill(HIST("h2dNSigmaOmKa"), cascade.p(), nSigmaOmKa); + } + } + } else { + if (std::abs(cascade.mXi() - 1.32171) < cascadeGroup.qaMassWindow && fabs(pTra.tpcNSigmaPi()) < cascadeGroup.qaTPCNSigma && fabs(nTra.tpcNSigmaPr()) < cascadeGroup.qaTPCNSigma && fabs(bTra.tpcNSigmaPi()) < cascadeGroup.qaTPCNSigma) { + histos.fill(HIST("h2dposDeltaTimeAsXiPi"), cascade.p(), cascade.eta(), posDeltaTimeAsXiPi); + histos.fill(HIST("h2dnegDeltaTimeAsXiPr"), cascade.p(), cascade.eta(), negDeltaTimeAsXiPr); + histos.fill(HIST("h2dbachDeltaTimeAsXiPi"), cascade.p(), cascade.eta(), bachDeltaTimeAsXiPi); + if (doQANSigma) { + histos.fill(HIST("h2dNSigmaXiLaPi"), cascade.p(), nSigmaXiLaPi); + histos.fill(HIST("h2dNSigmaXiLaPr"), cascade.p(), nSigmaXiLaPr); + histos.fill(HIST("h2dNSigmaXiPi"), cascade.p(), nSigmaXiPi); + } + } + if (std::abs(cascade.mOmega() - 1.67245) < cascadeGroup.qaMassWindow && fabs(pTra.tpcNSigmaPi()) < cascadeGroup.qaTPCNSigma && fabs(nTra.tpcNSigmaPr()) < cascadeGroup.qaTPCNSigma && fabs(bTra.tpcNSigmaKa()) < cascadeGroup.qaTPCNSigma) { + histos.fill(HIST("h2dposDeltaTimeAsOmPi"), cascade.p(), cascade.eta(), posDeltaTimeAsOmPi); + histos.fill(HIST("h2dnegDeltaTimeAsOmPr"), cascade.p(), cascade.eta(), negDeltaTimeAsOmPr); + histos.fill(HIST("h2dbachDeltaTimeAsOmKa"), cascade.p(), cascade.eta(), bachDeltaTimeAsOmKa); + if (doQANSigma) { + histos.fill(HIST("h2dNSigmaOmLaPi"), cascade.p(), nSigmaOmLaPi); + histos.fill(HIST("h2dNSigmaOmLaPr"), cascade.p(), nSigmaOmLaPr); + histos.fill(HIST("h2dNSigmaOmKa"), cascade.p(), nSigmaOmKa); + } + } + } + } + } + } + + void processStandardData(aod::Collisions const& collisions, V0OriginalDatas const& V0s, CascOriginalDatas const& cascades, TracksWithAllExtras const&, aod::BCsWithTimestamps const& /*bcs*/) + { + // Fire up CCDB with first collision in record. If no collisions, bypass + if (useCustomRunNumber || collisions.size() < 1) { + initCCDB(manualRunNumber); + } else { + auto collision = collisions.begin(); + auto bc = collision.bc_as(); + initCCDB(bc.runNumber()); + } + + if (calculateV0s.value) { + for (const auto& V0 : V0s) { + // for storing whatever is the relevant quantity for the PV + o2::dataformats::VertexBase primaryVertex; + if (V0.has_collision()) { + auto const& collision = V0.collision(); + primaryVertex.setPos({collision.posX(), collision.posY(), collision.posZ()}); + primaryVertex.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + } else { + primaryVertex.setPos({mVtx->getX(), mVtx->getY(), mVtx->getZ()}); + } + + auto pTra = V0.posTrack_as(); + auto nTra = V0.negTrack_as(); + processV0Candidate(primaryVertex, V0, pTra, nTra); + } + } + + if (calculateCascades.value) { + for (const auto& cascade : cascades) { + // for storing whatever is the relevant quantity for the PV + o2::dataformats::VertexBase primaryVertex; + if (cascade.has_collision()) { + auto const& collision = cascade.collision(); + primaryVertex.setPos({collision.posX(), collision.posY(), collision.posZ()}); + primaryVertex.setCov(collision.covXX(), collision.covXY(), collision.covYY(), collision.covXZ(), collision.covYZ(), collision.covZZ()); + } else { + primaryVertex.setPos({mVtx->getX(), mVtx->getY(), mVtx->getZ()}); + } + + auto pTra = cascade.posTrack_as(); + auto nTra = cascade.negTrack_as(); + auto bTra = cascade.bachelor_as(); + processCascadeCandidate(primaryVertex, cascade, pTra, nTra, bTra); + } + } + } + + void processDerivedData(soa::Join const& collisions, V0DerivedDatas const& V0s, CascDerivedDatas const& cascades, dauTracks const&) + { + // Fire up CCDB with first collision in record. If no collisions, bypass + if (useCustomRunNumber || collisions.size() < 1) { + initCCDB(manualRunNumber); + } else { + auto collision = collisions.begin(); + initCCDB(collision.runNumber()); + } + + if (calculateV0s.value) { + for (const auto& V0 : V0s) { + // for storing whatever is the relevant quantity for the PV + o2::dataformats::VertexBase primaryVertex; + if (V0.has_straCollision()) { + auto const& collision = V0.straCollision_as>(); + primaryVertex.setPos({collision.posX(), collision.posY(), collision.posZ()}); + // cov: won't be used anyways, all fine + primaryVertex.setCov(1e-6, 1e-6, 1e-6, 1e-6, 1e-6, 1e-6); + } else { + primaryVertex.setPos({mVtx->getX(), mVtx->getY(), mVtx->getZ()}); + } + + auto pTra = V0.posTrackExtra_as(); + auto nTra = V0.negTrackExtra_as(); + processV0Candidate(primaryVertex, V0, pTra, nTra); + } + } + + if (calculateCascades.value) { + for (const auto& cascade : cascades) { + // for storing whatever is the relevant quantity for the PV + o2::dataformats::VertexBase primaryVertex; + if (cascade.has_straCollision()) { + auto const& collision = cascade.straCollision_as>(); + primaryVertex.setPos({collision.posX(), collision.posY(), collision.posZ()}); + primaryVertex.setCov(1e-6, 1e-6, 1e-6, 1e-6, 1e-6, 1e-6); + } else { + primaryVertex.setPos({mVtx->getX(), mVtx->getY(), mVtx->getZ()}); + } + + auto pTra = cascade.posTrackExtra_as(); + auto nTra = cascade.negTrackExtra_as(); + auto bTra = cascade.bachTrackExtra_as(); + processCascadeCandidate(primaryVertex, cascade, pTra, nTra, bTra); + } + } + } + + PROCESS_SWITCH(strangenesstofpid, processStandardData, "Process standard data", true); + PROCESS_SWITCH(strangenesstofpid, processDerivedData, "Process derived data", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/Tasks/GlobalEventProperties/flattenictyPikp.cxx b/PWGLF/Tasks/GlobalEventProperties/flattenictyPikp.cxx index 51511ece0cf..101898b826d 100644 --- a/PWGLF/Tasks/GlobalEventProperties/flattenictyPikp.cxx +++ b/PWGLF/Tasks/GlobalEventProperties/flattenictyPikp.cxx @@ -193,17 +193,18 @@ struct FlattenictyPikp { int runNumber{-1}; Configurable multEst{"multEst", 1, "0: without multiplicity; 1: MultFT0M; 2: MultTPC"}; - Configurable applyCalibGain{"applyCalibGain", true, "equalize detector amplitudes"}; + Configurable applyCalibGain{"applyCalibGain", false, "equalize detector amplitudes"}; Configurable applyCalibVtx{"applyCalibVtx", false, "equalize Amp vs vtx"}; - Configurable applyCalibDeDx{"applyCalibDeDx", true, "calibration of dedx signal"}; + Configurable applyCalibDeDx{"applyCalibDeDx", false, "calibration of dedx signal"}; Configurable cfgFillTrackQaHist{"cfgFillTrackQaHist", false, "fill track QA histograms"}; + Configurable cfgFilldEdxCalibHist{"cfgFilldEdxCalibHist", false, "fill dEdx calibration histograms"}; Configurable cfgFilldEdxQaHist{"cfgFilldEdxQaHist", false, "fill dEdx QA histograms"}; Configurable cfgFillNsigmaQAHist{"cfgFillNsigmaQAHist", false, "fill nsigma QA histograms"}; - Configurable cfgFillChrgType{"cfgFillChrgType", true, "fill histograms per charge types"}; - Configurable> paramsFuncMIPposEta{"paramsFuncMIPposEta", std::vector{-1.f}, "parameters of pol2"}; - Configurable> paramsFuncMIPnegEta{"paramsFuncMIPnegEta", std::vector{-1.f}, "parameters of pol2"}; - Configurable> paramsFuncPlateuPosEta{"paramsFuncPlateuPosEta", std::vector{-1.f}, "parameters of pol2"}; - Configurable> paramsFuncPlateuNegEta{"paramsFuncPlateuNegEta", std::vector{-1.f}, "parameters of pol2"}; + Configurable cfgFillV0Hist{"cfgFillV0Hist", false, "fill V0 histograms"}; + Configurable cfgFillChrgType{"cfgFillChrgType", false, "fill histograms per charge types"}; + Configurable> paramsFuncMIPpos{"paramsFuncMIPpos", std::vector{-1.f}, "parameters of pol2"}; + Configurable> paramsFuncMIPneg{"paramsFuncMIPneg", std::vector{-1.f}, "parameters of pol2"}; + Configurable> paramsFuncMIPall{"paramsFuncMIPall", std::vector{-1.f}, "parameters of pol2"}; Configurable cfgGainEqCcdbPath{"cfgGainEqCcdbPath", "Users/g/gbencedi/flattenicity/GainEq", "CCDB path for gain equalization constants"}; Configurable cfgVtxEqCcdbPath{"cfgVtxEqCcdbPath", "Users/g/gbencedi/flattenicity/ZvtxEq", "CCDB path for z-vertex equalization constants"}; Configurable cfgUseCcdbForRun{"cfgUseCcdbForRun", true, "Get ccdb object based on run number instead of timestamp"}; @@ -227,17 +228,21 @@ struct FlattenictyPikp { struct : ConfigurableGroup { ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, "pT binning"}; - ConfigurableAxis axisMultPerc{"axisMultPerc", {100, 0, 100}, "Multiplicity percentiles binning"}; - ConfigurableAxis axisVertexZ{"axisVertexZ", {60, -15., 15.}, "Vertex z binning"}; + ConfigurableAxis axisFlatPerc{"axisFlatPerc", {102, -0.01, 1.01}, "Flattenicity percentiles binning"}; + ConfigurableAxis axisMultPerc{"axisMultPerc", {20, 0, 100}, "Multiplicity percentiles binning"}; + ConfigurableAxis axisVertexZ{"axisVertexZ", {80, -20., 20.}, "Vertex z binning"}; ConfigurableAxis axisMult{"axisMult", {301, -0.5, 300.5}, "Multiplicity binning"}; ConfigurableAxis axisDCAxy{"axisDCAxy", {200, -5, 5}, "DCAxy binning"}; ConfigurableAxis axisDCAz{"axisDCAz", {200, -5, 5}, "DCAz binning"}; ConfigurableAxis axisPhi = {"axisPhi", {60, 0, constants::math::TwoPI}, "#varphi binning"}; ConfigurableAxis axisPhiMod = {"axisPhiMod", {100, 0, constants::math::PI / 9}, "fmod(#varphi,#pi/9)"}; ConfigurableAxis axisEta = {"axisEta", {8, -0.8, 0.8}, "#eta binning"}; - ConfigurableAxis axisDedx{"axisDedx", {1000, 0, 1000}, "dE/dx binning"}; + ConfigurableAxis axisDedx{"axisDedx", {100, 0, 100}, "dE/dx binning"}; ConfigurableAxis axisNsigmaTPC{"axisNsigmaTPC", {200, -10, 10}, "nsigmaTPC binning"}; ConfigurableAxis axisNsigmaTOF{"axisNsigmaTOF", {200, -10, 10}, "nsigmaTOF binning"}; + ConfigurableAxis axisAmplFV0{"axsAmplFV0", {4096, 0, 4096}, "FV0 amplitude (ADC) binning"}; + ConfigurableAxis axisAmplFV0Sum{"axisAmplFV0Sum", {4096, 0, 4096 * 49}, "FV0 amplitude sum (ADC) binning"}; + ConfigurableAxis axisChannelFV0{"axisChannelFV0", {49, 0., 49.}, "FV0 channel ID binning"}; } binOpt; struct : ConfigurableGroup { @@ -309,22 +314,27 @@ struct FlattenictyPikp { TF1* fPhiCutLow = nullptr; TF1* fPhiCutHigh = nullptr; - std::unique_ptr fDeDxVsEtaPos = nullptr; - std::unique_ptr fDeDxVsEtaNeg = nullptr; - std::unique_ptr fEDeDxVsEtaPos = nullptr; - std::unique_ptr fEDeDxVsEtaNeg = nullptr; + std::vector> fDeDxVsEta; + std::vector> vecParams; void init(InitContext&) { - auto vecParamsMIPposEta = (std::vector)paramsFuncMIPposEta; - auto vecParamsMIPnegEta = (std::vector)paramsFuncMIPnegEta; - auto vecParamsPlateuPosEta = (std::vector)paramsFuncPlateuPosEta; - auto vecParamsPlateuNegEta = (std::vector)paramsFuncPlateuNegEta; + auto vecParamsMIPpos = (std::vector)paramsFuncMIPpos; + auto vecParamsMIPneg = (std::vector)paramsFuncMIPneg; + auto vecParamsMIPall = (std::vector)paramsFuncMIPall; - fDeDxVsEtaPos = setFuncPars(vecParamsMIPposEta); - fDeDxVsEtaNeg = setFuncPars(vecParamsMIPnegEta); - fEDeDxVsEtaPos = setFuncPars(vecParamsPlateuPosEta); - fEDeDxVsEtaNeg = setFuncPars(vecParamsPlateuNegEta); + auto addVec = [&](std::vector>& targetVec, const std::string& name) { + targetVec.emplace_back(vecParamsMIPpos); + targetVec.emplace_back(vecParamsMIPneg); + targetVec.emplace_back(vecParamsMIPall); + if (!vecParams.size()) { + LOG(info) << "size of " << name << "is zero."; + } + }; + addVec(vecParams, "vecParams"); + for (const auto& params : vecParams) { + fDeDxVsEta.emplace_back(setFuncPars(params)); + } ccdb->setURL(ccdbConf.ccdbUrl.value); ccdb->setCaching(true); @@ -353,8 +363,8 @@ struct FlattenictyPikp { const AxisSpec chargeAxis{2, -2.f, 2.f, "Charge"}; const AxisSpec dEdxAxis{binOpt.axisDedx, "TPC dEdx (a.u.)"}; - const AxisSpec vtxzAxis{100, -20, 20, "Z_{vtx} (cm)"}; - const AxisSpec flatAxis{102, -0.01, 1.01, "Flat FV0"}; + const AxisSpec vtxzAxis{binOpt.axisVertexZ, "Z_{vtx} (cm)"}; + const AxisSpec flatAxis{binOpt.axisFlatPerc, "Flat FV0"}; const AxisSpec etaAxis{binOpt.axisEta, "#eta"}; const AxisSpec phiAxis{binOpt.axisPhi, "#varphi"}; const AxisSpec phiAxisMod{binOpt.axisPhiMod, "fmod(#varphi,#pi/9)"}; @@ -366,8 +376,9 @@ struct FlattenictyPikp { const AxisSpec clTpcAxis{160, 0, 160, "Number of clusters in TPC"}; const AxisSpec nSigmaTPCAxis{binOpt.axisNsigmaTPC, "n#sigma_{TPC}"}; const AxisSpec nSigmaTOFAxis{binOpt.axisNsigmaTOF, "n#sigma_{TOF}"}; - const AxisSpec amplitudeFT0 = {5000, 0, 10000, "FT0 amplitude"}; - const AxisSpec channelFT0Axis = {220, 0.0, 220.0, "FT0 channel"}; + const AxisSpec amplitudeFV0{binOpt.axisAmplFV0, "FV0 amplitude (ADC)"}; + const AxisSpec amplitudeFV0Sum{binOpt.axisAmplFV0Sum, "FV0 amplitude sm (ADC)"}; + const AxisSpec channelFV0Axis{binOpt.axisChannelFV0, "FV0 channel ID"}; AxisSpec multAxis{binOpt.axisMultPerc, "multiplicity estimator"}; @@ -385,7 +396,7 @@ struct FlattenictyPikp { } // Event counter - flatchrg.add("Events/hEvtSel", "Number of events; Cut; #Events Passed Cut", {HistType::kTH1D, {{nEvtSel, 0, nEvtSel}}}); + flatchrg.add("Events/hEvtSel", "Number of events; Cut; #Events Passed Cut", {HistType::kTH1F, {{nEvtSel, 0, nEvtSel}}}); flatchrg.get(HIST("Events/hEvtSel"))->GetXaxis()->SetBinLabel(evtSelAll + 1, "Events read"); flatchrg.get(HIST("Events/hEvtSel"))->GetXaxis()->SetBinLabel(evtSelSel8 + 1, "Evt. sel8"); flatchrg.get(HIST("Events/hEvtSel"))->GetXaxis()->SetBinLabel(evtSelNoITSROFrameBorder + 1, "NoITSROFrameBorder"); @@ -397,7 +408,7 @@ struct FlattenictyPikp { flatchrg.get(HIST("Events/hEvtSel"))->GetXaxis()->SetBinLabel(evtSelVtxZ + 1, "Vtx-z pos"); flatchrg.get(HIST("Events/hEvtSel"))->GetXaxis()->SetBinLabel(evtSelINELgt0 + 1, "INEL>0"); // Track counter - flatchrg.add("Tracks/hTrkSel", "Number of tracks; Cut; #Tracks Passed Cut", {HistType::kTH1D, {{nTrkSel, 0, nTrkSel}}}); + flatchrg.add("Tracks/hTrkSel", "Number of tracks; Cut; #Tracks Passed Cut", {HistType::kTH1F, {{nTrkSel, 0, nTrkSel}}}); flatchrg.get(HIST("Tracks/hTrkSel"))->GetXaxis()->SetBinLabel(trkSelEta + 1, "Eta"); flatchrg.get(HIST("Tracks/hTrkSel"))->GetXaxis()->SetBinLabel(trkSelPt + 1, "Pt"); flatchrg.get(HIST("Tracks/hTrkSel"))->GetXaxis()->SetBinLabel(trkSelDCA + 1, "DCA"); @@ -411,50 +422,59 @@ struct FlattenictyPikp { } if (doprocessFlat) { - flatchrg.add("Events/hVtxZ", "Measured vertex z position", HistType::kTH1D, {vtxzAxis}); - flatchrg.add("Events/hFlatVsMultEst", "hFlatVsMultEst", HistType::kTH2D, {flatAxis, multAxis}); - flatchrg.add("Tracks/postSel/hPVsPtEta", "; #it{p} (GeV/#it{c}); #it{p}_{T} (GeV/#it{c}); #eta;", {HistType::kTH3D, {pAxis, ptAxis, etaAxis}}); + flatchrg.add("Events/hVtxZ", "Measured vertex z position", HistType::kTH1F, {vtxzAxis}); + flatchrg.add("Events/hFlatVsMultEst", "hFlatVsMultEst", HistType::kTH2F, {flatAxis, multAxis}); + flatchrg.add("Tracks/postSel/hPVsPtEta", "; #it{p} (GeV/#it{c}); #it{p}_{T} (GeV/#it{c}); #eta;", {HistType::kTH3F, {pAxis, ptAxis, etaAxis}}); if (cfgFillTrackQaHist || cfgFilldEdxQaHist || cfgFillNsigmaQAHist) { if (cfgFillTrackQaHist) { - flatchrg.add("Tracks/postSel/hPtPhi", "; #it{p}_{T} (GeV/#it{c}); fmod(#varphi,#pi/9)", {HistType::kTH2D, {ptAxis, phiAxisMod}}); - flatchrg.add("Tracks/postSel/hPtVsWOcutDCA", "hPtVsWOcutDCA", HistType::kTH2D, {ptAxis, dcaXYAxis}); - flatchrg.add("Tracks/postSel/hPt", "", HistType::kTH1D, {ptAxis}); - flatchrg.add("Tracks/postSel/hPhi", "", HistType::kTH1D, {phiAxis}); - flatchrg.add("Tracks/postSel/hEta", "", HistType::kTH1D, {etaAxis}); - flatchrg.add("Tracks/postSel/hDCAXYvsPt", "", HistType::kTH2D, {ptAxis, dcaXYAxis}); - flatchrg.add("Tracks/postSel/hDCAZvsPt", "", HistType::kTH2D, {ptAxis, dcaZAxis}); + flatchrg.add("Tracks/postSel/hPtPhi", "; #it{p}_{T} (GeV/#it{c}); fmod(#varphi,#pi/9)", {HistType::kTH2F, {ptAxis, phiAxisMod}}); + flatchrg.add("Tracks/postSel/hPtVsWOcutDCA", "hPtVsWOcutDCA", HistType::kTH2F, {ptAxis, dcaXYAxis}); + flatchrg.add("Tracks/postSel/hPt", "", HistType::kTH1F, {ptAxis}); + flatchrg.add("Tracks/postSel/hPhi", "", HistType::kTH1F, {phiAxis}); + flatchrg.add("Tracks/postSel/hEta", "", HistType::kTH1F, {etaAxis}); + flatchrg.add("Tracks/postSel/hDCAXYvsPt", "", HistType::kTH2F, {ptAxis, dcaXYAxis}); + flatchrg.add("Tracks/postSel/hDCAZvsPt", "", HistType::kTH2F, {ptAxis, dcaZAxis}); // tpc - flatchrg.add("Tracks/postSel/hPtPhiTPCCluster", "; #it{p}_{T} (GeV/#it{c}); fmod(#varphi,#pi/9); N_{cluster}", {HistType::kTHnSparseD, {ptAxis, phiAxisMod, clTpcAxis}}); - flatchrg.add("Tracks/postSel/hShTpcClvsPt", "", {HistType::kTH2D, {ptAxis, shCluserAxis}}); - flatchrg.add("Tracks/postSel/hCrossTPCvsPt", "", {HistType::kTH2D, {ptAxis, clTpcAxis}}); - flatchrg.add("Tracks/postSel/hTPCCluster", "N_{cluster}", HistType::kTH1D, {clTpcAxis}); - flatchrg.add("Tracks/postSel/tpcNClsShared", " ; # shared TPC clusters TPC", HistType::kTH1D, {{165, -0.5, 164.5}}); - flatchrg.add("Tracks/postSel/tpcCrossedRows", " ; # crossed TPC rows", HistType::kTH1D, {{165, -0.5, 164.5}}); - flatchrg.add("Tracks/postSel/tpcCrossedRowsOverFindableCls", " ; crossed rows / findable TPC clusters", HistType::kTH1D, {{60, 0.7, 1.3}}); + if (cfgStoreThnSparse) { + flatchrg.add("Tracks/postSel/hPtPhiTPCCluster", "; #it{p}_{T} (GeV/#it{c}); fmod(#varphi,#pi/9); N_{cluster}", {HistType::kTHnSparseF, {ptAxis, phiAxisMod, clTpcAxis}}); + } else { + flatchrg.add("Tracks/postSel/hPtPhiTPCCluster", "; #it{p}_{T} (GeV/#it{c}); fmod(#varphi,#pi/9); N_{cluster}", {HistType::kTH2F, {ptAxis, phiAxisMod}}); + } + flatchrg.add("Tracks/postSel/hShTpcClvsPt", "", {HistType::kTH2F, {ptAxis, shCluserAxis}}); + flatchrg.add("Tracks/postSel/hCrossTPCvsPt", "", {HistType::kTH2F, {ptAxis, clTpcAxis}}); + flatchrg.add("Tracks/postSel/hTPCCluster", "N_{cluster}", HistType::kTH1F, {clTpcAxis}); + flatchrg.add("Tracks/postSel/tpcNClsShared", " ; # shared TPC clusters TPC", HistType::kTH1F, {{165, -0.5, 164.5}}); + flatchrg.add("Tracks/postSel/tpcCrossedRows", " ; # crossed TPC rows", HistType::kTH1F, {{165, -0.5, 164.5}}); + flatchrg.add("Tracks/postSel/tpcCrossedRowsOverFindableCls", " ; crossed rows / findable TPC clusters", HistType::kTH1F, {{60, 0.7, 1.3}}); // its - flatchrg.add("Tracks/postSel/itsNCls", " ; # ITS clusters", HistType::kTH1D, {{8, -0.5, 7.5}}); - flatchrg.add("Tracks/postSel/hChi2ITSTrkSegment", "chi2ITS", HistType::kTH1D, {{100, -0.5, 99.5}}); + flatchrg.add("Tracks/postSel/itsNCls", " ; # ITS clusters", HistType::kTH1F, {{8, -0.5, 7.5}}); + flatchrg.add("Tracks/postSel/hChi2ITSTrkSegment", "chi2ITS", HistType::kTH1F, {{100, -0.5, 99.5}}); // tof - flatchrg.add("Tracks/postSel/hTOFPvsBeta", "Beta from TOF; #it{p} (GeV/#it{c}); #beta", {HistType::kTH2D, {pAxis, {120, 0.0, 1.2}}}); - flatchrg.add("Tracks/postSel/hTOFpi", "Primary Pions from TOF; #eta; #it{p} (GeV/#it{c}); dEdx", {HistType::kTHnSparseD, {etaAxis, pAxis, dEdxAxis}}); + flatchrg.add("Tracks/postSel/hTOFPvsBeta", "Beta from TOF; #it{p} (GeV/#it{c}); #beta", {HistType::kTH2F, {pAxis, {120, 0.0, 1.2}}}); + if (cfgStoreThnSparse) { + flatchrg.add("Tracks/postSel/hTOFpi", "Primary Pions from TOF; #eta; #it{p} (GeV/#it{c}); dEdx", {HistType::kTHnSparseF, {etaAxis, pAxis, dEdxAxis}}); + } else { + flatchrg.add("Tracks/postSel/hTOFpi", "Primary Pions from TOF; #eta; #it{p} (GeV/#it{c}); dEdx", {HistType::kTH3F, {etaAxis, pAxis, dEdxAxis}}); + } } if (cfgFilldEdxQaHist) { - flatchrg.add("Tracks/postCalib/all/hMIP", "; mult; flat; #eta; #LT dE/dx #GT_{MIP, primary tracks};", {HistType::kTHnSparseD, {multAxis, flatAxis, etaAxis, dEdxAxis}}); - flatchrg.add("Tracks/postCalib/all/hPlateau", "; mult; flat; #eta; #LT dE/dx #GT_{Plateau, primary tracks};", {HistType::kTHnSparseD, {multAxis, flatAxis, etaAxis, dEdxAxis}}); - flatchrg.add("Tracks/postCalib/all/hMIPVsEta", "; #eta; #LT dE/dx #GT_{MIP, primary tracks};", {HistType::kTH2D, {etaAxis, dEdxAxis}}); - flatchrg.add("Tracks/postCalib/all/pMIPVsEta", "; #eta; #LT dE/dx #GT_{MIP, primary tracks};", {HistType::kTProfile, {etaAxis}}); - flatchrg.add("Tracks/postCalib/all/hMIPVsPhi", "; #varphi; #LT dE/dx #GT_{MIP, primary tracks};", {HistType::kTH2D, {phiAxis, dEdxAxis}}); + if (cfgStoreThnSparse) { + flatchrg.add("Tracks/postCalib/all/hMIP", "; mult; flat; #eta; #LT dE/dx #GT_{MIP, primary tracks};", {HistType::kTHnSparseF, {multAxis, flatAxis, etaAxis, dEdxAxis}}); + flatchrg.add("Tracks/postCalib/all/hPlateau", "; mult; flat; #eta; #LT dE/dx #GT_{Plateau, primary tracks};", {HistType::kTHnSparseF, {multAxis, flatAxis, etaAxis, dEdxAxis}}); + } else { + flatchrg.add("Tracks/postCalib/all/hMIP", "; #eta; #LT dE/dx #GT_{MIP, primary tracks};", {HistType::kTH2F, {etaAxis, dEdxAxis}}); + flatchrg.add("Tracks/postCalib/all/hPlateau", "; #eta; #LT dE/dx #GT_{Plateau, primary tracks};", {HistType::kTH2F, {etaAxis, dEdxAxis}}); + } + flatchrg.add("Tracks/postCalib/all/hMIPVsPhi", "; #varphi; #LT dE/dx #GT_{MIP, primary tracks};", {HistType::kTH2F, {phiAxis, dEdxAxis}}); flatchrg.add("Tracks/postCalib/all/pMIPVsPhi", "; #varphi; #LT dE/dx #GT_{MIP, primary tracks};", {HistType::kTProfile, {phiAxis}}); - flatchrg.add("Tracks/postCalib/all/hMIPVsPhiVsEta", "; #varphi; #LT dE/dx #GT_{MIP, primary tracks}; #eta;", {HistType::kTH3D, {phiAxis, dEdxAxis, etaAxis}}); - flatchrg.add("Tracks/postCalib/all/hPlateauVsEta", "; #eta; #LT dE/dx #GT_{Plateau, primary tracks};", {HistType::kTH2D, {etaAxis, dEdxAxis}}); - flatchrg.add("Tracks/postCalib/all/pPlateauVsEta", "; #eta; #LT dE/dx #GT_{Plateau, primary tracks};", {HistType::kTProfile, {etaAxis}}); - flatchrg.add("Tracks/postCalib/all/hPlateauVsPhi", "; #varphi; #LT dE/dx #GT_{Plateau, primary tracks};", {HistType::kTH2D, {phiAxis, dEdxAxis}}); + flatchrg.add("Tracks/postCalib/all/hMIPVsPhiVsEta", "; #varphi; #LT dE/dx #GT_{MIP, primary tracks}; #eta;", {HistType::kTH3F, {phiAxis, dEdxAxis, etaAxis}}); + flatchrg.add("Tracks/postCalib/all/hPlateauVsPhi", "; #varphi; #LT dE/dx #GT_{Plateau, primary tracks};", {HistType::kTH2F, {phiAxis, dEdxAxis}}); flatchrg.add("Tracks/postCalib/all/pPlateauVsPhi", "; #varphi; #LT dE/dx #GT_{Plateau, primary tracks};", {HistType::kTProfile, {phiAxis}}); - flatchrg.add("Tracks/postCalib/all/hPlateauVsPhiVsEta", "; #varphi; #LT dE/dx #GT_{Plateau, primary tracks}; #eta;", {HistType::kTH3D, {phiAxis, dEdxAxis, etaAxis}}); + flatchrg.add("Tracks/postCalib/all/hPlateauVsPhiVsEta", "; #varphi; #LT dE/dx #GT_{Plateau, primary tracks}; #eta;", {HistType::kTH3F, {phiAxis, dEdxAxis, etaAxis}}); + flatchrg.addClone("Tracks/postCalib/all/", "Tracks/preCalib/all/"); if (cfgFillChrgType) { flatchrg.addClone("Tracks/postCalib/all/", "Tracks/postCalib/pos/"); flatchrg.addClone("Tracks/postCalib/all/", "Tracks/postCalib/neg/"); - flatchrg.addClone("Tracks/postCalib/all/", "Tracks/preCalib/all/"); flatchrg.addClone("Tracks/preCalib/all/", "Tracks/preCalib/pos/"); flatchrg.addClone("Tracks/preCalib/all/", "Tracks/preCalib/neg/"); } @@ -462,49 +482,61 @@ struct FlattenictyPikp { if (cfgFillNsigmaQAHist) { for (int i = 0; i < NpartChrg; i++) { const std::string strID = Form("/%s/%s", (i < Npart) ? "pos" : "neg", Pid[i % Npart]); - hPtNsigmaTPC[i] = flatchrg.add("Tracks/hPtNsigmaTPC" + strID, " ; p_{T} (GeV/c)", HistType::kTH2D, {ptAxis, nSigmaTPCAxis}); if (cfgStoreThnSparse) { - hThPtNsigmaTPC[i] = flatchrg.add("Tracks/hThPtNsigmaTPC" + strID, " ; p_{T} (GeV/c)", HistType::kTHnSparseD, {ptAxis, nSigmaTPCAxis, multAxis, flatAxis}); + hThPtNsigmaTPC[i] = flatchrg.add("Tracks/hThPtNsigmaTPC" + strID, " ; p_{T} (GeV/c)", HistType::kTHnSparseF, {ptAxis, nSigmaTPCAxis, multAxis, flatAxis}); + } else { + hPtNsigmaTPC[i] = flatchrg.add("Tracks/hPtNsigmaTPC" + strID, " ; p_{T} (GeV/c)", HistType::kTH2F, {ptAxis, nSigmaTPCAxis}); } - hPtNsigmaTOF[i] = flatchrg.add("Tracks/hPtNsigmaTOF" + strID, " ; p_{T} (GeV/c)", HistType::kTH2D, {ptAxis, nSigmaTOFAxis}); - hPtNsigmaTPCTOF[i] = flatchrg.add("Tracks/hPtNsigmaTPCTOF" + strID, PidChrg[i], HistType::kTH2D, {nSigmaTPCAxis, nSigmaTOFAxis}); + hPtNsigmaTOF[i] = flatchrg.add("Tracks/hPtNsigmaTOF" + strID, " ; p_{T} (GeV/c)", HistType::kTH2F, {ptAxis, nSigmaTOFAxis}); + hPtNsigmaTPCTOF[i] = flatchrg.add("Tracks/hPtNsigmaTPCTOF" + strID, PidChrg[i], HistType::kTH2F, {nSigmaTPCAxis, nSigmaTOFAxis}); } } } flatchrg.addClone("Tracks/postSel/", "Tracks/preSel/"); // FV0 QA - flatchrg.add("FV0/hFV0AmplWCalib", "", HistType::kTH2D, {{48, -0.5, 47.5, "channel"}, {500, -0.5, +19999.5, "FV0 amplitude"}}); - flatchrg.add("FV0/hFV0AmplvsVtxzWoCalib", "", HistType::kTH2D, {{30, -15.0, +15.0, "z vtx (cm)"}, {1000, -0.5, +39999.5, "FV0 amplitude"}}); - flatchrg.add("FV0/hFV0AmplvsVtxzCalib", "", HistType::kTH2D, {{30, -15.0, +15.0, "z vtx (cm)"}, {1000, -0.5, +39999.5, "FV0 amplitude"}}); - flatchrg.add("FV0/hFV0amp", "", {HistType::kTH2D, {channelFT0Axis, amplitudeFT0}}); - flatchrg.add("FV0/pFV0amp", "", HistType::kTProfile, {channelFT0Axis}); - flatchrg.add("FV0/hFV0ampCorr", "", {HistType::kTH2D, {channelFT0Axis, amplitudeFT0}}); + flatchrg.add("FV0/hFV0AmplWCalib", "", {HistType::kTH2F, {channelFV0Axis, amplitudeFV0}}); + flatchrg.add("FV0/hFV0AmplvsVtxzWoCalib", "", {HistType::kTH2F, {vtxzAxis, amplitudeFV0Sum}}); + flatchrg.add("FV0/hFV0AmplvsVtxzCalib", "", {HistType::kTH2F, {vtxzAxis, amplitudeFV0Sum}}); + flatchrg.add("FV0/hFV0amp", "", {HistType::kTH2F, {channelFV0Axis, amplitudeFV0}}); + flatchrg.add("FV0/pFV0amp", "", HistType::kTProfile, {channelFV0Axis}); + flatchrg.add("FV0/hFV0ampCorr", "", {HistType::kTH2F, {channelFV0Axis, amplitudeFV0}}); // V0's QA - flatchrg.add("Tracks/V0qa/hV0Pt", "pT", HistType::kTH1D, {{100, 0.0f, 10}}); - flatchrg.add("Tracks/V0qa/hV0ArmPod", ";#alpha; #it{q}_T", HistType::kTH2D, {{200, -1.0f, +1.0f}, {250, 0.0f, 0.25f}}); + flatchrg.add("Tracks/V0qa/hV0Pt", "pT", HistType::kTH1F, {{100, 0.0f, 10}}); + flatchrg.add("Tracks/V0qa/hV0ArmPod", ";#alpha; #it{q}_T", HistType::kTH2F, {{200, -1.0f, +1.0f}, {250, 0.0f, 0.25f}}); // dEdx PID - flatchrg.add({"Tracks/all/hdEdx", "; #eta; mult; flat; #it{p} (GeV/#it{c}); dEdx", {HistType::kTHnSparseD, {etaAxis, multAxis, flatAxis, pAxis, dEdxAxis}}}); + flatchrg.add({"Tracks/all/hdEdx", "; #eta; mult; flat; #it{p} (GeV/#it{c}); dEdx", {HistType::kTHnSparseF, {etaAxis, multAxis, flatAxis, pAxis, dEdxAxis}}}); // Clean samples - flatchrg.add({"Tracks/CleanTof/all/hPiTof", "; #eta; mult; flat; #it{p} (GeV/#it{c}); dEdx", {HistType::kTHnSparseD, {etaAxis, multAxis, flatAxis, pAxis, dEdxAxis}}}); - flatchrg.add({"Tracks/CleanV0/pos/hEV0", "; #eta; mult; flat; #it{p} (GeV/#it{c}); dEdx", {HistType::kTHnSparseD, {etaAxis, multAxis, flatAxis, pAxis, dEdxAxis}}}); - flatchrg.add({"Tracks/CleanV0/pos/hPiV0", "; #eta; mult; flat; #it{p} (GeV/#it{c}); dEdx", {HistType::kTHnSparseD, {etaAxis, multAxis, flatAxis, pAxis, dEdxAxis}}}); - flatchrg.add({"Tracks/CleanV0/pos/hPV0", "; #eta; mult; flat; #it{p} (GeV/#it{c}); dEdx", {HistType::kTHnSparseD, {etaAxis, multAxis, flatAxis, pAxis, dEdxAxis}}}); - flatchrg.addClone("Tracks/CleanV0/pos/", "Tracks/CleanV0/neg/"); + if (cfgFillV0Hist) { + if (cfgStoreThnSparse) { + flatchrg.add({"Tracks/CleanTof/all/hPiTof", "; #eta; mult; flat; #it{p} (GeV/#it{c}); dEdx", {HistType::kTHnSparseF, {etaAxis, multAxis, flatAxis, pAxis, dEdxAxis}}}); + flatchrg.add({"Tracks/CleanV0/pos/hEV0", "; #eta; mult; flat; #it{p} (GeV/#it{c}); dEdx", {HistType::kTHnSparseF, {etaAxis, multAxis, flatAxis, pAxis, dEdxAxis}}}); + flatchrg.add({"Tracks/CleanV0/pos/hPiV0", "; #eta; mult; flat; #it{p} (GeV/#it{c}); dEdx", {HistType::kTHnSparseF, {etaAxis, multAxis, flatAxis, pAxis, dEdxAxis}}}); + flatchrg.add({"Tracks/CleanV0/pos/hPV0", "; #eta; mult; flat; #it{p} (GeV/#it{c}); dEdx", {HistType::kTHnSparseF, {etaAxis, multAxis, flatAxis, pAxis, dEdxAxis}}}); + } else { + flatchrg.add({"Tracks/CleanTof/all/hPiTof", "; #eta; mult; flat; #it{p} (GeV/#it{c}); dEdx", {HistType::kTH3F, {etaAxis, pAxis, dEdxAxis}}}); + flatchrg.add({"Tracks/CleanV0/pos/hEV0", "; #eta; mult; flat; #it{p} (GeV/#it{c}); dEdx", {HistType::kTH3F, {etaAxis, pAxis, dEdxAxis}}}); + flatchrg.add({"Tracks/CleanV0/pos/hPiV0", "; #eta; mult; flat; #it{p} (GeV/#it{c}); dEdx", {HistType::kTH3F, {etaAxis, pAxis, dEdxAxis}}}); + flatchrg.add({"Tracks/CleanV0/pos/hPV0", "; #eta; mult; flat; #it{p} (GeV/#it{c}); dEdx", {HistType::kTH3F, {etaAxis, pAxis, dEdxAxis}}}); + } + flatchrg.addClone("Tracks/CleanV0/pos/", "Tracks/CleanV0/neg/"); + if (cfgFillChrgType) { + flatchrg.addClone("Tracks/CleanTof/all/", "Tracks/CleanTof/pos/"); + flatchrg.addClone("Tracks/CleanTof/all/", "Tracks/CleanTof/neg/"); + } + } if (cfgFillChrgType) { flatchrg.addClone("Tracks/all/", "Tracks/pos/"); flatchrg.addClone("Tracks/all/", "Tracks/neg/"); - flatchrg.addClone("Tracks/CleanTof/all/", "Tracks/CleanTof/pos/"); - flatchrg.addClone("Tracks/CleanTof/all/", "Tracks/CleanTof/neg/"); } } if (doprocessMC) { - auto h = flatchrg.add("hEvtGenRec", "Generated and Reconstructed MC Collisions", kTH1D, {{3, 0.5, 3.5}}); + auto h = flatchrg.add("hEvtGenRec", "Generated and Reconstructed MC Collisions", kTH1F, {{3, 0.5, 3.5}}); h->GetXaxis()->SetBinLabel(1, "Gen coll"); h->GetXaxis()->SetBinLabel(2, "Rec coll"); h->GetXaxis()->SetBinLabel(3, "INEL>0"); - flatchrg.add("hEvtMcGenColls", "Number of events; Cut; #Events Passed Cut", {HistType::kTH1D, {{5, 0.5, 5.5}}}); + flatchrg.add("hEvtMcGenColls", "Number of events; Cut; #Events Passed Cut", {HistType::kTH1F, {{5, 0.5, 5.5}}}); flatchrg.get(HIST("hEvtMcGenColls"))->GetXaxis()->SetBinLabel(1, "Gen. coll"); flatchrg.get(HIST("hEvtMcGenColls"))->GetXaxis()->SetBinLabel(2, "At least 1 reco"); flatchrg.get(HIST("hEvtMcGenColls"))->GetXaxis()->SetBinLabel(3, "Reco. coll."); @@ -512,78 +544,81 @@ struct FlattenictyPikp { for (int i = 0; i < NpartChrg; i++) { const std::string strID = Form("/%s/%s", (i < Npart) ? "pos" : "neg", Pid[i % Npart]); - hPtGenRecEvt[i] = flatchrg.add("Tracks/hPtGenRecEvt" + strID, " ; p_{T} (GeV/c)", HistType::kTH1D, {ptAxis}); - hPtGenPrimRecEvt[i] = flatchrg.add("Tracks/hPtGenPrimRecEvt" + strID, " ; p_{T} (GeV/c)", HistType::kTH1D, {ptAxis}); - hPtEffGenPrim[i] = flatchrg.add("Tracks/hPtEffGenPrim" + strID, " ; p_{T} (GeV/c)", HistType::kTH3D, {multAxis, flatAxis, ptAxis}); - hPtEffGenWeak[i] = flatchrg.add("Tracks/hPtEffGenWeak" + strID, " ; p_{T} (GeV/c)", HistType::kTH3D, {multAxis, flatAxis, ptAxis}); - hPtEffGenMat[i] = flatchrg.add("Tracks/hPtEffGenMat" + strID, " ; p_{T} (GeV/c)", HistType::kTH3D, {multAxis, flatAxis, ptAxis}); - hPtEffRecPrim[i] = flatchrg.add("Tracks/hPtEffRecPrim" + strID, " ; p_{T} (GeV/c)", HistType::kTH3D, {multAxis, flatAxis, ptAxis}); - hPtEffRecWeak[i] = flatchrg.add("Tracks/hPtEffRecWeak" + strID, " ; p_{T} (GeV/c)", HistType::kTH3D, {multAxis, flatAxis, ptAxis}); - hPtEffRecMat[i] = flatchrg.add("Tracks/hPtEffRecMat" + strID, " ; p_{T} (GeV/c)", HistType::kTH3D, {multAxis, flatAxis, ptAxis}); - hDCAxyBadCollPrim[i] = flatchrg.add("Tracks/hDCAxyBadCollPrim" + strID, " ; p_{T} (GeV/c)", HistType::kTH2D, {ptAxis, dcaXYAxis}); - hDCAxyBadCollWeak[i] = flatchrg.add("Tracks/hDCAxyBadCollWeak" + strID, " ; p_{T} (GeV/c)", HistType::kTH2D, {ptAxis, dcaXYAxis}); - hDCAxyBadCollMat[i] = flatchrg.add("Tracks/hDCAxyBadCollMat" + strID, " ; p_{T} (GeV/c)", HistType::kTH2D, {ptAxis, dcaXYAxis}); - hPtVsDCAxyPrim[i] = flatchrg.add("Tracks/hPtVsDCAxyPrim" + strID, " ; p_{T} (GeV/c)", HistType::kTH2D, {ptAxis, dcaXYAxis}); - hPtVsDCAxyWeak[i] = flatchrg.add("Tracks/hPtVsDCAxyWeak" + strID, " ; p_{T} (GeV/c)", HistType::kTH2D, {ptAxis, dcaXYAxis}); - hPtVsDCAxyMat[i] = flatchrg.add("Tracks/hPtVsDCAxyMat" + strID, " ; p_{T} (GeV/c)", HistType::kTH2D, {ptAxis, dcaXYAxis}); - } - - flatchrg.add({"hPtOut", " ; p_{T} (GeV/c)", {HistType::kTH1D, {ptAxis}}}); - flatchrg.add({"hPtOutPrim", " ; p_{T} (GeV/c)", {HistType::kTH1D, {ptAxis}}}); - flatchrg.add({"hPtOutNoEtaCut", " ; p_{T} (GeV/c)", {HistType::kTH1D, {ptAxis}}}); - flatchrg.add({"PtOutFakes", " ; p_{T} (GeV/c)", {HistType::kTH1D, {ptAxis}}}); - flatchrg.add("hPtVsDCAxyPrimAll", "hPtVsDCAxyPrimAll", HistType::kTH2D, {ptAxis, dcaXYAxis}); - flatchrg.add("hPtVsDCAxyWeakAll", "hPtVsDCAxyWeakAll", HistType::kTH2D, {ptAxis, dcaXYAxis}); - flatchrg.add("hPtVsDCAxyMatAll", "hPtVsDCAxyMatAll", HistType::kTH2D, {ptAxis, dcaXYAxis}); - flatchrg.add("hPtVsDCAxyAll", "hPtVsDCAxyAll", HistType::kTH2D, {ptAxis, dcaXYAxis}); - flatchrg.add({"ResponseGen", " ; N_{part}; F_{FV0};", {HistType::kTHnSparseD, {multAxis, flatAxis}}}); - flatchrg.add("h1flatencityFV0MCGen", "", HistType::kTH1D, {{102, -0.01, 1.01, "1-flatencityFV0"}}); + hPtGenRecEvt[i] = flatchrg.add("Tracks/hPtGenRecEvt" + strID, " ; p_{T} (GeV/c)", HistType::kTH1F, {ptAxis}); + hPtGenPrimRecEvt[i] = flatchrg.add("Tracks/hPtGenPrimRecEvt" + strID, " ; p_{T} (GeV/c)", HistType::kTH1F, {ptAxis}); + hPtEffGenPrim[i] = flatchrg.add("Tracks/hPtEffGenPrim" + strID, " ; p_{T} (GeV/c)", HistType::kTH3F, {multAxis, flatAxis, ptAxis}); + hPtEffGenWeak[i] = flatchrg.add("Tracks/hPtEffGenWeak" + strID, " ; p_{T} (GeV/c)", HistType::kTH3F, {multAxis, flatAxis, ptAxis}); + hPtEffGenMat[i] = flatchrg.add("Tracks/hPtEffGenMat" + strID, " ; p_{T} (GeV/c)", HistType::kTH3F, {multAxis, flatAxis, ptAxis}); + hPtEffRecPrim[i] = flatchrg.add("Tracks/hPtEffRecPrim" + strID, " ; p_{T} (GeV/c)", HistType::kTH3F, {multAxis, flatAxis, ptAxis}); + hPtEffRecWeak[i] = flatchrg.add("Tracks/hPtEffRecWeak" + strID, " ; p_{T} (GeV/c)", HistType::kTH3F, {multAxis, flatAxis, ptAxis}); + hPtEffRecMat[i] = flatchrg.add("Tracks/hPtEffRecMat" + strID, " ; p_{T} (GeV/c)", HistType::kTH3F, {multAxis, flatAxis, ptAxis}); + hDCAxyBadCollPrim[i] = flatchrg.add("Tracks/hDCAxyBadCollPrim" + strID, " ; p_{T} (GeV/c)", HistType::kTH2F, {ptAxis, dcaXYAxis}); + hDCAxyBadCollWeak[i] = flatchrg.add("Tracks/hDCAxyBadCollWeak" + strID, " ; p_{T} (GeV/c)", HistType::kTH2F, {ptAxis, dcaXYAxis}); + hDCAxyBadCollMat[i] = flatchrg.add("Tracks/hDCAxyBadCollMat" + strID, " ; p_{T} (GeV/c)", HistType::kTH2F, {ptAxis, dcaXYAxis}); + hPtVsDCAxyPrim[i] = flatchrg.add("Tracks/hPtVsDCAxyPrim" + strID, " ; p_{T} (GeV/c)", HistType::kTH2F, {ptAxis, dcaXYAxis}); + hPtVsDCAxyWeak[i] = flatchrg.add("Tracks/hPtVsDCAxyWeak" + strID, " ; p_{T} (GeV/c)", HistType::kTH2F, {ptAxis, dcaXYAxis}); + hPtVsDCAxyMat[i] = flatchrg.add("Tracks/hPtVsDCAxyMat" + strID, " ; p_{T} (GeV/c)", HistType::kTH2F, {ptAxis, dcaXYAxis}); + } + + flatchrg.add({"hPtOut", " ; p_{T} (GeV/c)", {HistType::kTH1F, {ptAxis}}}); + flatchrg.add({"hPtOutPrim", " ; p_{T} (GeV/c)", {HistType::kTH1F, {ptAxis}}}); + flatchrg.add({"hPtOutNoEtaCut", " ; p_{T} (GeV/c)", {HistType::kTH1F, {ptAxis}}}); + flatchrg.add({"PtOutFakes", " ; p_{T} (GeV/c)", {HistType::kTH1F, {ptAxis}}}); + flatchrg.add("hPtVsDCAxyPrimAll", "hPtVsDCAxyPrimAll", HistType::kTH2F, {ptAxis, dcaXYAxis}); + flatchrg.add("hPtVsDCAxyWeakAll", "hPtVsDCAxyWeakAll", HistType::kTH2F, {ptAxis, dcaXYAxis}); + flatchrg.add("hPtVsDCAxyMatAll", "hPtVsDCAxyMatAll", HistType::kTH2F, {ptAxis, dcaXYAxis}); + flatchrg.add("hPtVsDCAxyAll", "hPtVsDCAxyAll", HistType::kTH2F, {ptAxis, dcaXYAxis}); + flatchrg.add({"ResponseGen", " ; N_{part}; F_{FV0};", {HistType::kTHnSparseF, {multAxis, flatAxis}}}); + flatchrg.add("h1flatencityFV0MCGen", "", HistType::kTH1F, {{102, -0.01, 1.01, "1-flatencityFV0"}}); + + // Hash list for efficiency + listEfficiency.setObject(new THashList); + static_for<0, 1>([&](auto pidSgn) { + bookMcHist(); + bookMcHist(); + bookMcHist(); + initEfficiency(); + initEfficiency(); + initEfficiency(); + }); } if (doprocessMCclosure) { for (int i = 0; i < Npart; i++) { - flatchrg.add({fmt::format(kPtMCclosurePrimF.data(), kSpeciesAll[i]).c_str(), " ; p_{T} (GeV/c)", {HistType::kTH3D, {multAxis, flatAxis, ptAxis}}}); + flatchrg.add({fmt::format(kPtMCclosurePrimF.data(), kSpeciesAll[i]).c_str(), " ; p_{T} (GeV/c)", {HistType::kTH3F, {multAxis, flatAxis, ptAxis}}}); } } if (doprocessSgnLoss) { - flatchrg.add("hFlatMCGenRecColl", "hFlatMCGenRecColl", {HistType::kTH1D, {flatAxis}}); - flatchrg.add("hFlatMCGen", "hFlatMCGen", {HistType::kTH1D, {flatAxis}}); + flatchrg.add("hFlatMCGenRecColl", "hFlatMCGenRecColl", {HistType::kTH1F, {flatAxis}}); + flatchrg.add("hFlatMCGen", "hFlatMCGen", {HistType::kTH1F, {flatAxis}}); // Event counter - flatchrg.add("hEvtMcGen", "hEvtMcGen", {HistType::kTH1D, {{4, 0.f, 4.f}}}); + flatchrg.add("hEvtMcGen", "hEvtMcGen", {HistType::kTH1F, {{4, 0.f, 4.f}}}); flatchrg.get(HIST("hEvtMcGen"))->GetXaxis()->SetBinLabel(1, "all"); flatchrg.get(HIST("hEvtMcGen"))->GetXaxis()->SetBinLabel(2, "z-vtx"); flatchrg.get(HIST("hEvtMcGen"))->GetXaxis()->SetBinLabel(3, "INELgt0"); - flatchrg.add("hEvtMCRec", "hEvtMCRec", {HistType::kTH1D, {{4, 0.f, 4.f}}}); + flatchrg.add("hEvtMCRec", "hEvtMCRec", {HistType::kTH1F, {{4, 0.f, 4.f}}}); flatchrg.get(HIST("hEvtMCRec"))->GetXaxis()->SetBinLabel(1, "all"); flatchrg.get(HIST("hEvtMCRec"))->GetXaxis()->SetBinLabel(2, "evt sel"); flatchrg.get(HIST("hEvtMCRec"))->GetXaxis()->SetBinLabel(3, "INELgt0"); - flatchrg.add("hEvtMcGenRecColl", "hEvtMcGenRecColl", {HistType::kTH1D, {{2, 0.f, 2.f}}}); + flatchrg.add("hEvtMcGenRecColl", "hEvtMcGenRecColl", {HistType::kTH1F, {{2, 0.f, 2.f}}}); flatchrg.get(HIST("hEvtMcGenRecColl"))->GetXaxis()->SetBinLabel(1, "INEL"); flatchrg.get(HIST("hEvtMcGenRecColl"))->GetXaxis()->SetBinLabel(2, "INELgt0"); - flatchrg.add("hFlatGenINELgt0", "hFlatGenINELgt0", {HistType::kTH1D, {flatAxis}}); + flatchrg.add("hFlatGenINELgt0", "hFlatGenINELgt0", {HistType::kTH1F, {flatAxis}}); for (int i = 0; i < NpartChrg; ++i) { - flatchrg.add({fmt::format(kPtGenPrimSgnF.data(), kSpecies[i]).c_str(), " ; p_{T} (GeV/c)", {HistType::kTH3D, {multAxis, flatAxis, ptAxis}}}); - flatchrg.add({fmt::format(kPtGenPrimSgnINELF.data(), kSpecies[i]).c_str(), " ; p_{T} (GeV/c)", {HistType::kTH3D, {multAxis, flatAxis, ptAxis}}}); - flatchrg.add({fmt::format(kPtRecCollPrimSgnF.data(), kSpecies[i]).c_str(), " ; p_{T} (GeV/c)", {HistType::kTH3D, {multAxis, flatAxis, ptAxis}}}); - flatchrg.add({fmt::format(kPtRecCollPrimSgnINELF.data(), kSpecies[i]).c_str(), " ; p_{T} (GeV/c)", {HistType::kTH3D, {multAxis, flatAxis, ptAxis}}}); - flatchrg.add({fmt::format(kPtGenRecCollPrimSgnF.data(), kSpecies[i]).c_str(), " ; p_{T} (GeV/c)", {HistType::kTH3D, {multAxis, flatAxis, ptAxis}}}); - flatchrg.add({fmt::format(kPtGenRecCollPrimSgnINELF.data(), kSpecies[i]).c_str(), " ; p_{T} (GeV/c)", {HistType::kTH3D, {multAxis, flatAxis, ptAxis}}}); - } - } - - // Hash list for efficiency - listEfficiency.setObject(new THashList); - static_for<0, 1>([&](auto pidSgn) { - bookMcHist(); - bookMcHist(); - bookMcHist(); - initEfficiency(); - initEfficiency(); - initEfficiency(); - }); + flatchrg.add({fmt::format(kPtGenPrimSgnF.data(), kSpecies[i]).c_str(), " ; p_{T} (GeV/c)", {HistType::kTH3F, {multAxis, flatAxis, ptAxis}}}); + flatchrg.add({fmt::format(kPtGenPrimSgnINELF.data(), kSpecies[i]).c_str(), " ; p_{T} (GeV/c)", {HistType::kTH3F, {multAxis, flatAxis, ptAxis}}}); + flatchrg.add({fmt::format(kPtRecCollPrimSgnF.data(), kSpecies[i]).c_str(), " ; p_{T} (GeV/c)", {HistType::kTH3F, {multAxis, flatAxis, ptAxis}}}); + flatchrg.add({fmt::format(kPtRecCollPrimSgnINELF.data(), kSpecies[i]).c_str(), " ; p_{T} (GeV/c)", {HistType::kTH3F, {multAxis, flatAxis, ptAxis}}}); + flatchrg.add({fmt::format(kPtGenRecCollPrimSgnF.data(), kSpecies[i]).c_str(), " ; p_{T} (GeV/c)", {HistType::kTH3F, {multAxis, flatAxis, ptAxis}}}); + flatchrg.add({fmt::format(kPtGenRecCollPrimSgnINELF.data(), kSpecies[i]).c_str(), " ; p_{T} (GeV/c)", {HistType::kTH3F, {multAxis, flatAxis, ptAxis}}}); + } + } + + LOG(info) << "Size of the histograms:"; + flatchrg.print(); } void initCCDB(aod::BCsWithTimestamps::iterator const& bc) @@ -675,7 +710,7 @@ struct FlattenictyPikp { void fillNsigma(T const& tracks, const C& collision) { const float mult = getMult(collision); - const float flat = fillFlat(collision); + const float flat = fillFlat(collision); for (const auto& track : tracks) { checkNsigma(track, mult, flat); } @@ -701,7 +736,6 @@ struct FlattenictyPikp { for (const auto& track : tracks) { float dEdx = track.tpcSignal(); - bool posP = (track.sign() * track.tpcInnerParam() > 0) ? true : false; if (cfgFillTrackQaHist) { fillTrackQA(track); } @@ -711,98 +745,145 @@ struct FlattenictyPikp { if (cfgFillTrackQaHist) { fillTrackQA(track); } - if (cfgFilldEdxQaHist) { - filldEdxQA(track, collision, dEdx); - if (posP) { - filldEdxQA(track, collision, dEdx); + if (cfgFilldEdxCalibHist && cfgFilldEdxQaHist) { + if (cfgFillChrgType) { + if (track.sign() * track.tpcInnerParam() > 0) { + filldEdxQA(track, collision, dEdx); + } else { + filldEdxQA(track, collision, dEdx); + } } else { - filldEdxQA(track, collision, dEdx); + filldEdxQA(track, collision, dEdx); } } if (applyCalibDeDx) { - dEdx *= (50.0 / getCalibration(true, track.eta())); - } - if (cfgFilldEdxQaHist) { - filldEdxQA(track, collision, dEdx); - if (posP) { - filldEdxQA(track, collision, dEdx); + if (cfgFillChrgType) { + dEdx *= (50.0 / getCalibration(fDeDxVsEta, track)); + if (cfgFilldEdxQaHist) { + if (track.sign() * track.tpcInnerParam() > 0) { + filldEdxQA(track, collision, dEdx); + } else { + filldEdxQA(track, collision, dEdx); + } + } } else { - filldEdxQA(track, collision, dEdx); + dEdx *= (50.0 / getCalibration(fDeDxVsEta, track)); + if (cfgFilldEdxQaHist) { + filldEdxQA(track, collision, dEdx); + } } } // PID TPC dEdx - flatchrg.fill(HIST(kPrefix) + HIST(kCharge[kAll]) + HIST("hdEdx"), track.eta(), mult, flat, track.tpcInnerParam(), dEdx); - if (posP) { - flatchrg.fill(HIST(kPrefix) + HIST(kCharge[kPos]) + HIST("hdEdx"), track.eta(), mult, flat, track.tpcInnerParam(), dEdx); + if (cfgFillChrgType) { + if (track.sign() * track.tpcInnerParam() > 0) { + flatchrg.fill(HIST(kPrefix) + HIST(kCharge[kPos]) + HIST("hdEdx"), track.eta(), mult, flat, track.tpcInnerParam(), dEdx); + } else { + flatchrg.fill(HIST(kPrefix) + HIST(kCharge[kNeg]) + HIST("hdEdx"), track.eta(), mult, flat, track.tpcInnerParam(), dEdx); + } } else { - flatchrg.fill(HIST(kPrefix) + HIST(kCharge[kNeg]) + HIST("hdEdx"), track.eta(), mult, flat, track.tpcInnerParam(), dEdx); + flatchrg.fill(HIST(kPrefix) + HIST(kCharge[kAll]) + HIST("hdEdx"), track.eta(), mult, flat, track.tpcInnerParam(), dEdx); } // TOF pions - if (track.hasTOF() && track.beta() > 1.) { - if (selTOFPi(track)) { - flatchrg.fill(HIST(kPrefixCleanTof) + HIST(kCharge[kAll]) + HIST("hPiTof"), track.eta(), mult, flat, track.tpcInnerParam(), dEdx); - if (posP) { - flatchrg.fill(HIST(kPrefixCleanTof) + HIST(kCharge[kPos]) + HIST("hPiTof"), track.eta(), mult, flat, track.tpcInnerParam(), dEdx); - } else { - flatchrg.fill(HIST(kPrefixCleanTof) + HIST(kCharge[kNeg]) + HIST("hPiTof"), track.eta(), mult, flat, track.tpcInnerParam(), dEdx); + if (cfgFillV0Hist) { + if (track.hasTOF() && track.beta() > 1.) { + if (selTOFPi(track)) { + if (cfgFillChrgType) { + if (track.sign() * track.tpcInnerParam() > 0) { + if (cfgStoreThnSparse) { + flatchrg.fill(HIST(kPrefixCleanTof) + HIST(kCharge[kPos]) + HIST("hPiTof"), track.eta(), mult, flat, track.tpcInnerParam(), dEdx); + } else { + flatchrg.fill(HIST(kPrefixCleanTof) + HIST(kCharge[kPos]) + HIST("hPiTof"), track.eta(), track.tpcInnerParam(), dEdx); + } + } else { + if (cfgStoreThnSparse) { + flatchrg.fill(HIST(kPrefixCleanTof) + HIST(kCharge[kNeg]) + HIST("hPiTof"), track.eta(), mult, flat, track.tpcInnerParam(), dEdx); + } else { + flatchrg.fill(HIST(kPrefixCleanTof) + HIST(kCharge[kNeg]) + HIST("hPiTof"), track.eta(), track.tpcInnerParam(), dEdx); + } + } + } else { + if (cfgStoreThnSparse) { + flatchrg.fill(HIST(kPrefixCleanTof) + HIST(kCharge[kAll]) + HIST("hPiTof"), track.eta(), mult, flat, track.tpcInnerParam(), dEdx); + } else { + flatchrg.fill(HIST(kPrefixCleanTof) + HIST(kCharge[kAll]) + HIST("hPiTof"), track.eta(), track.tpcInnerParam(), dEdx); + } + } } } } } // V0s - for (const auto& v0 : v0s) { - if (!isGoodV0Track(v0, tracks)) { - continue; - } + if (cfgFillV0Hist) { + for (const auto& v0 : v0s) { + if (!isGoodV0Track(v0, tracks)) { + continue; + } - const auto& posTrack = v0.template posTrack_as(); - const auto& negTrack = v0.template negTrack_as(); - float dEdxPos = posTrack.tpcSignal(); - float dEdxNeg = negTrack.tpcSignal(); + const auto& posTrack = v0.template posTrack_as(); + const auto& negTrack = v0.template negTrack_as(); + float dEdxPos = posTrack.tpcSignal(); + float dEdxNeg = negTrack.tpcSignal(); - if (applyCalibDeDx) { - dEdxPos *= (50.0 / getCalibration(true, posTrack.eta())); - dEdxNeg *= (50.0 / getCalibration(true, negTrack.eta())); - } + if (applyCalibDeDx) { + dEdxPos *= (50.0 / getCalibration(fDeDxVsEta, posTrack)); + dEdxNeg *= (50.0 / getCalibration(fDeDxVsEta, negTrack)); + } - if (selectTypeV0s(v0, posTrack, negTrack) == kGa) { // Gamma selection - flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kPos]) + HIST("hEV0"), posTrack.eta(), mult, flat, posTrack.sign() * posTrack.tpcInnerParam(), dEdxPos); - flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kNeg]) + HIST("hEV0"), negTrack.eta(), mult, flat, negTrack.sign() * negTrack.tpcInnerParam(), dEdxNeg); - } - if (selectTypeV0s(v0, posTrack, negTrack) == kKz) { // K0S -> pi + pi - flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kPos]) + HIST("hPiV0"), posTrack.eta(), mult, flat, posTrack.sign() * posTrack.tpcInnerParam(), dEdxPos); - flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kNeg]) + HIST("hPiV0"), negTrack.eta(), mult, flat, negTrack.sign() * negTrack.tpcInnerParam(), dEdxNeg); - } - if (selectTypeV0s(v0, posTrack, negTrack) == kLam) { // L -> p + pi- - flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kPos]) + HIST("hPV0"), posTrack.eta(), mult, flat, posTrack.sign() * posTrack.tpcInnerParam(), dEdxPos); - flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kNeg]) + HIST("hPV0"), negTrack.eta(), mult, flat, negTrack.sign() * negTrack.tpcInnerParam(), dEdxNeg); - } - if (selectTypeV0s(v0, posTrack, negTrack) == kaLam) { // L -> p + pi- - flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kPos]) + HIST("hPiV0"), posTrack.eta(), mult, flat, posTrack.sign() * posTrack.tpcInnerParam(), dEdxPos); - flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kNeg]) + HIST("hPiV0"), negTrack.eta(), mult, flat, negTrack.sign() * negTrack.tpcInnerParam(), dEdxNeg); + if (selectTypeV0s(v0, posTrack, negTrack) == kGa) { // Gamma selection + if (cfgStoreThnSparse) { + flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kPos]) + HIST("hEV0"), posTrack.eta(), mult, flat, posTrack.sign() * posTrack.tpcInnerParam(), dEdxPos); + flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kNeg]) + HIST("hEV0"), negTrack.eta(), mult, flat, negTrack.sign() * negTrack.tpcInnerParam(), dEdxNeg); + } else { + flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kPos]) + HIST("hEV0"), posTrack.eta(), posTrack.sign() * posTrack.tpcInnerParam(), dEdxPos); + flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kNeg]) + HIST("hEV0"), negTrack.eta(), negTrack.sign() * negTrack.tpcInnerParam(), dEdxNeg); + } + } + if (selectTypeV0s(v0, posTrack, negTrack) == kKz) { // K0S -> pi + pi + if (cfgStoreThnSparse) { + flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kPos]) + HIST("hPiV0"), posTrack.eta(), mult, flat, posTrack.sign() * posTrack.tpcInnerParam(), dEdxPos); + flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kNeg]) + HIST("hPiV0"), negTrack.eta(), mult, flat, negTrack.sign() * negTrack.tpcInnerParam(), dEdxNeg); + } else { + flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kPos]) + HIST("hPiV0"), posTrack.eta(), posTrack.sign() * posTrack.tpcInnerParam(), dEdxPos); + flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kNeg]) + HIST("hPiV0"), negTrack.eta(), negTrack.sign() * negTrack.tpcInnerParam(), dEdxNeg); + } + } + if (selectTypeV0s(v0, posTrack, negTrack) == kLam) { // L -> p + pi- + if (cfgStoreThnSparse) { + flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kPos]) + HIST("hPV0"), posTrack.eta(), mult, flat, posTrack.sign() * posTrack.tpcInnerParam(), dEdxPos); + flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kNeg]) + HIST("hPV0"), negTrack.eta(), mult, flat, negTrack.sign() * negTrack.tpcInnerParam(), dEdxNeg); + } else { + flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kPos]) + HIST("hPV0"), posTrack.eta(), posTrack.sign() * posTrack.tpcInnerParam(), dEdxPos); + flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kNeg]) + HIST("hPV0"), negTrack.eta(), negTrack.sign() * negTrack.tpcInnerParam(), dEdxNeg); + } + } + if (selectTypeV0s(v0, posTrack, negTrack) == kaLam) { // L -> p + pi- + if (cfgStoreThnSparse) { + flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kPos]) + HIST("hPiV0"), posTrack.eta(), mult, flat, posTrack.sign() * posTrack.tpcInnerParam(), dEdxPos); + flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kNeg]) + HIST("hPiV0"), negTrack.eta(), mult, flat, negTrack.sign() * negTrack.tpcInnerParam(), dEdxNeg); + } else { + flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kPos]) + HIST("hPiV0"), posTrack.eta(), posTrack.sign() * posTrack.tpcInnerParam(), dEdxPos); + flatchrg.fill(HIST(kPrefixCleanV0) + HIST(kCharge[kNeg]) + HIST("hPiV0"), negTrack.eta(), negTrack.sign() * negTrack.tpcInnerParam(), dEdxNeg); + } + } } } } - float getCalibration(bool isMIP, const float& eta) + template + float getCalibration(std::vector> const& fCalib, V const& track) { - double valCalib = 999.0; - if (eta < 0.) { - if (isMIP) { - valCalib = fDeDxVsEtaNeg->Eval(eta); - // LOGF(info, "--------> \t fDeDxVsEtaNeg->Eval(%f) = %f", eta, valCalib); + float valCalib = -1.; + if constexpr (isChrg) { + if (track.sign() * track.tpcInnerParam() > 0) { + valCalib = fCalib.at(0)->Eval(track.eta()); } else { - valCalib = fEDeDxVsEtaNeg->Eval(eta); + valCalib = fCalib.at(1)->Eval(track.eta()); } } else { - if (isMIP) { - valCalib = fDeDxVsEtaPos->Eval(eta); - } else { - valCalib = fEDeDxVsEtaPos->Eval(eta); - } + valCalib = fCalib.at(2)->Eval(track.eta()); } return valCalib; } @@ -837,7 +918,11 @@ struct FlattenictyPikp { if (cfgFillTrackQaHist) { flatchrg.fill(HIST("Tracks/preSel/hPtPhi"), track.pt(), phimodn); if (track.hasTPC() && track.hasITS()) { - flatchrg.fill(HIST("Tracks/preSel/hPtPhiTPCCluster"), track.pt(), phimodn, track.tpcNClsFindable() - track.tpcNClsFindableMinusFound()); + if (cfgStoreThnSparse) { + flatchrg.fill(HIST("Tracks/preSel/hPtPhiTPCCluster"), track.pt(), phimodn, track.tpcNClsFindable() - track.tpcNClsFindableMinusFound()); + } else { + flatchrg.fill(HIST("Tracks/preSel/hPtPhiTPCCluster"), track.pt(), phimodn); + } } } if (phimodn < fphiCutHigh->Eval(track.pt()) && phimodn > fphiCutLow->Eval(track.pt())) { @@ -846,7 +931,11 @@ struct FlattenictyPikp { if (cfgFillTrackQaHist) { flatchrg.fill(HIST("Tracks/postSel/hPtPhi"), track.pt(), phimodn); if (track.hasTPC() && track.hasITS()) { - flatchrg.fill(HIST("Tracks/postSel/hPtPhiTPCCluster"), track.pt(), phimodn, track.tpcNClsFindable() - track.tpcNClsFindableMinusFound()); + if (cfgStoreThnSparse) { + flatchrg.fill(HIST("Tracks/postSel/hPtPhiTPCCluster"), track.pt(), phimodn, track.tpcNClsFindable() - track.tpcNClsFindableMinusFound()); + } else { + flatchrg.fill(HIST("Tracks/postSel/hPtPhiTPCCluster"), track.pt(), phimodn); + } } } return true; @@ -1000,14 +1089,16 @@ struct FlattenictyPikp { } if (track.sign() > 0) { - hPtNsigmaTPC[pid]->Fill(track.pt(), valTPCnsigma); if (cfgStoreThnSparse) { hThPtNsigmaTPC[pid]->Fill(track.pt(), valTPCnsigma, mult, flat); + } else { + hPtNsigmaTPC[pid]->Fill(track.pt(), valTPCnsigma); } } else { - hPtNsigmaTPC[pid + Npart]->Fill(track.pt(), valTPCnsigma); if (cfgStoreThnSparse) { hThPtNsigmaTPC[pid + Npart]->Fill(track.pt(), valTPCnsigma, mult, flat); + } else { + hPtNsigmaTPC[pid + Npart]->Fill(track.pt(), valTPCnsigma); } } if (!track.hasTOF()) { @@ -1064,23 +1155,27 @@ struct FlattenictyPikp { inline void filldEdxQA(T const& track, C const& collision, const float dEdx) { const float mult = getMult(collision); - const float flat = fillFlat(collision); + const float flat = fillFlat(collision); // float dEdx = track.tpcSignal(); if constexpr (fillHist) { if (track.tpcInnerParam() >= trkSelOpt.cfgMomMIPMin && track.tpcInnerParam() <= trkSelOpt.cfgMomMIPMax) { if (dEdx > trkSelOpt.cfgDeDxMIPMin && dEdx < trkSelOpt.cfgDeDxMIPMax) { // MIP pions - flatchrg.fill(HIST(kPrefix) + HIST(kStatCalib[ft]) + HIST(kCharge[chrg]) + HIST("hMIP"), mult, flat, track.eta(), dEdx); - flatchrg.fill(HIST(kPrefix) + HIST(kStatCalib[ft]) + HIST(kCharge[chrg]) + HIST("hMIPVsEta"), track.eta(), dEdx); - flatchrg.fill(HIST(kPrefix) + HIST(kStatCalib[ft]) + HIST(kCharge[chrg]) + HIST("pMIPVsEta"), track.eta(), dEdx); + if (cfgStoreThnSparse) { + flatchrg.fill(HIST(kPrefix) + HIST(kStatCalib[ft]) + HIST(kCharge[chrg]) + HIST("hMIP"), mult, flat, track.eta(), dEdx); + } else { + flatchrg.fill(HIST(kPrefix) + HIST(kStatCalib[ft]) + HIST(kCharge[chrg]) + HIST("hMIP"), track.eta(), dEdx); + } flatchrg.fill(HIST(kPrefix) + HIST(kStatCalib[ft]) + HIST(kCharge[chrg]) + HIST("hMIPVsPhi"), track.phi(), dEdx); flatchrg.fill(HIST(kPrefix) + HIST(kStatCalib[ft]) + HIST(kCharge[chrg]) + HIST("hMIPVsPhiVsEta"), track.phi(), dEdx, track.eta()); flatchrg.fill(HIST(kPrefix) + HIST(kStatCalib[ft]) + HIST(kCharge[chrg]) + HIST("pMIPVsPhi"), track.phi(), dEdx); } if (dEdx > trkSelOpt.cfgDeDxMIPMax + 10. && dEdx < trkSelOpt.cfgDeDxMIPMax + 30.) { // Plateau electrons if (std::abs(track.beta() - 1) < trkSelOpt.cfgBetaPlateuMax) { - flatchrg.fill(HIST(kPrefix) + HIST(kStatCalib[ft]) + HIST(kCharge[chrg]) + HIST("hPlateau"), mult, flat, track.eta(), dEdx); - flatchrg.fill(HIST(kPrefix) + HIST(kStatCalib[ft]) + HIST(kCharge[chrg]) + HIST("hPlateauVsEta"), track.eta(), dEdx); - flatchrg.fill(HIST(kPrefix) + HIST(kStatCalib[ft]) + HIST(kCharge[chrg]) + HIST("pPlateauVsEta"), track.eta(), dEdx); + if (cfgStoreThnSparse) { + flatchrg.fill(HIST(kPrefix) + HIST(kStatCalib[ft]) + HIST(kCharge[chrg]) + HIST("hPlateau"), mult, flat, track.eta(), dEdx); + } else { + flatchrg.fill(HIST(kPrefix) + HIST(kStatCalib[ft]) + HIST(kCharge[chrg]) + HIST("hPlateau"), track.eta(), dEdx); + } flatchrg.fill(HIST(kPrefix) + HIST(kStatCalib[ft]) + HIST(kCharge[chrg]) + HIST("hPlateauVsPhi"), track.phi(), dEdx); flatchrg.fill(HIST(kPrefix) + HIST(kStatCalib[ft]) + HIST(kCharge[chrg]) + HIST("hPlateauVsPhiVsEta"), track.phi(), dEdx, track.eta()); flatchrg.fill(HIST(kPrefix) + HIST(kStatCalib[ft]) + HIST(kCharge[chrg]) + HIST("pPlateauVsPhi"), track.phi(), dEdx); @@ -1533,8 +1628,8 @@ struct FlattenictyPikp { constexpr int kHistIdx = id + pidSgn * Npart; auto kIdx = static_cast(id); const std::string strID = Form("/%s/%s", (pidSgn == 0 && id < Npart) ? "pos" : "neg", Pid[kIdx]); - hPtEffRec[kHistIdx] = flatchrg.add("Tracks/hPtEffRec" + strID, " ; p_{T} (GeV/c)", HistType::kTH1D, {ptAxis}); - hPtEffGen[kHistIdx] = flatchrg.add("Tracks/hPtEffGen" + strID, " ; p_{T} (GeV/c)", HistType::kTH1D, {ptAxis}); + hPtEffRec[kHistIdx] = flatchrg.add("Tracks/hPtEffRec" + strID, " ; p_{T} (GeV/c)", HistType::kTH1F, {ptAxis}); + hPtEffGen[kHistIdx] = flatchrg.add("Tracks/hPtEffGen" + strID, " ; p_{T} (GeV/c)", HistType::kTH1F, {ptAxis}); } template diff --git a/PWGLF/Tasks/GlobalEventProperties/heavyionMultiplicity.cxx b/PWGLF/Tasks/GlobalEventProperties/heavyionMultiplicity.cxx index b91db8d09e0..6637d6f2dcd 100644 --- a/PWGLF/Tasks/GlobalEventProperties/heavyionMultiplicity.cxx +++ b/PWGLF/Tasks/GlobalEventProperties/heavyionMultiplicity.cxx @@ -48,14 +48,14 @@ using namespace o2::framework::expressions; using namespace o2::aod::track; using namespace o2::aod::evsel; -using CollisionDataTable = soa::Join; -using ColDataTablepp = soa::Join; +using CollisionDataTable = soa::Join; +using ColDataTablepp = soa::Join; using TrackDataTable = soa::Join; using FilTrackDataTable = soa::Filtered; using CollisionMCTrueTable = aod::McCollisions; using TrackMCTrueTable = aod::McParticles; -using CollisionMCRecTable = soa::SmallGroups>; -using ColMCRecTablepp = soa::SmallGroups>; +using CollisionMCRecTable = soa::SmallGroups>; +using ColMCRecTablepp = soa::SmallGroups>; using TrackMCRecTable = soa::Join; using FilTrackMCRecTable = soa::Filtered; using V0TrackCandidates = soa::Join; @@ -115,7 +115,6 @@ AxisSpec axisMassLambda = {200, 1.07, 1.17, "Lambda/AntiLamda Mass", "Lambda/Ant AxisSpec axisTracks{9, 0.5, 9.5, "#tracks", "TrackAxis"}; auto static constexpr kMinCharge = 3.f; auto static constexpr kMinpTcut = 0.1f; -auto static constexpr kEtaInelgt0 = 1.0f; auto static constexpr kNItslayers = 7; struct HeavyionMultiplicity { @@ -160,10 +159,13 @@ struct HeavyionMultiplicity { Configurable isApplyNoHighMultCollInPrevRof{"isApplyNoHighMultCollInPrevRof", false, "Enable NoHighMultCollInPrevRof cut"}; Configurable isApplyFT0CbasedOccupancy{"isApplyFT0CbasedOccupancy", false, "Enable FT0CbasedOccupancy cut"}; Configurable isApplyCentFT0C{"isApplyCentFT0C", true, "Centrality based on FT0C"}; + Configurable isApplyCentFV0A{"isApplyCentFV0A", false, "Centrality based on FV0A"}; Configurable isApplyCentFT0CVariant1{"isApplyCentFT0CVariant1", false, "Centrality based on FT0C variant1"}; Configurable isApplyCentFT0M{"isApplyCentFT0M", false, "Centrality based on FT0A + FT0C"}; Configurable isApplyCentNGlobal{"isApplyCentNGlobal", false, "Centrality based on global tracks"}; Configurable isApplyCentMFT{"isApplyCentMFT", false, "Centrality based on MFT tracks"}; + Configurable isApplySplitRecCol{"isApplySplitRecCol", false, "Split MC reco collisions"}; + Configurable isApplyInelgt0{"isApplyInelgt0", false, "Enable INEL > 0 condition"}; void init(InitContext const&) { @@ -190,6 +192,7 @@ struct HeavyionMultiplicity { x->SetBinLabel(6, "ApplyNoCollInTimeRangeStandard"); x->SetBinLabel(7, "ApplyNoCollInRofStandard"); x->SetBinLabel(8, "ApplyNoHighMultCollInPrevRof"); + x->SetBinLabel(9, "INEL > 0"); if (doprocessData) { histos.add("CentPercentileHist", "CentPercentileHist", kTH1D, {axisCent}, false); @@ -307,6 +310,11 @@ struct HeavyionMultiplicity { return false; } histos.fill(HIST("EventHist"), 8); + + if (isApplyInelgt0 && !col.isInelGt0()) { + return false; + } + histos.fill(HIST("EventHist"), 9); return true; } @@ -317,6 +325,9 @@ struct HeavyionMultiplicity { if (isApplyCentFT0C) { cent = col.centFT0C(); } + if (isApplyCentFV0A) { + cent = col.centFV0A(); + } if (isApplyCentFT0CVariant1) { cent = col.centFT0CVariant1(); } @@ -434,6 +445,11 @@ struct HeavyionMultiplicity { void processMonteCarlo(CollisionMCTrueTable::iterator const&, CollisionMCRecTable const& RecCols, TrackMCTrueTable const& GenParticles, FilTrackMCRecTable const& RecTracks) { + + if (isApplySplitRecCol && (RecCols.size() == 0 || RecCols.size() > 1)) { + return; + } + for (const auto& RecCol : RecCols) { if (!isEventSelected(RecCol)) { continue; @@ -663,41 +679,31 @@ struct HeavyionMultiplicity { return; } - // INEL>0 sample - auto nTrks = 0; + histos.fill(HIST("VtxZHist"), cols.posZ()); + histos.fill(HIST("MultPercentileHist"), cols.centFT0M()); + histos.fill(HIST("hdatazvtxmultpp"), cols.posZ(), cols.centFT0M()); + for (const auto& track : tracks) { if (!isTrackSelected(track)) { continue; } - if (track.eta() < kEtaInelgt0) { - nTrks++; + histos.fill(HIST("PhiVsEtaHistpp"), track.phi(), track.eta()); + histos.fill(HIST("hdatadndetapp"), cols.posZ(), cols.centFT0M(), track.eta(), track.phi(), kGlobalplusITS); + if (track.hasTPC()) { + histos.fill(HIST("hdatadndetapp"), cols.posZ(), cols.centFT0M(), track.eta(), track.phi(), kGlobalonly); + } else { + histos.fill(HIST("hdatadndetapp"), cols.posZ(), cols.centFT0M(), track.eta(), track.phi(), kITSonly); } } // track loop - - if (nTrks > 0) { - histos.fill(HIST("EventHist"), 9); - histos.fill(HIST("VtxZHist"), cols.posZ()); - histos.fill(HIST("MultPercentileHist"), cols.centFT0M()); - histos.fill(HIST("hdatazvtxmultpp"), cols.posZ(), cols.centFT0M()); - - for (const auto& track : tracks) { - if (!isTrackSelected(track)) { - continue; - } - histos.fill(HIST("PhiVsEtaHistpp"), track.phi(), track.eta()); - histos.fill(HIST("hdatadndetapp"), cols.posZ(), cols.centFT0M(), track.eta(), track.phi(), kGlobalplusITS); - if (track.hasTPC()) { - histos.fill(HIST("hdatadndetapp"), cols.posZ(), cols.centFT0M(), track.eta(), track.phi(), kGlobalonly); - } else { - histos.fill(HIST("hdatadndetapp"), cols.posZ(), cols.centFT0M(), track.eta(), track.phi(), kITSonly); - } - } // track loop - } // nTrks>0 } PROCESS_SWITCH(HeavyionMultiplicity, processppData, "process pp data", false); void processppMonteCarlo(CollisionMCTrueTable::iterator const&, ColMCRecTablepp const& RecCols, TrackMCTrueTable const& GenParticles, FilTrackMCRecTable const& RecTracks) { + if (isApplySplitRecCol && (RecCols.size() == 0 || RecCols.size() > 1)) { + return; + } + for (const auto& RecCol : RecCols) { if (!isEventSelected(RecCol)) { continue; @@ -705,103 +711,89 @@ struct HeavyionMultiplicity { auto recTracksPart = RecTracks.sliceBy(perCollision, RecCol.globalIndex()); std::vector mclabels; - // INEL>0 sample - auto nTrks = 0; + histos.fill(HIST("VtxZHist"), RecCol.posZ()); + histos.fill(HIST("MultPercentileMCRecHist"), RecCol.centFT0M()); + histos.fill(HIST("hmczvtxmultpp"), RecCol.posZ(), RecCol.centFT0M()); + for (const auto& Rectrack : recTracksPart) { if (!isTrackSelected(Rectrack)) { continue; } - if (Rectrack.eta() < kEtaInelgt0) { - nTrks++; + histos.fill(HIST("MCrecPhiVsEtaHistpp"), Rectrack.phi(), Rectrack.eta()); + histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), RecCol.centFT0M(), Rectrack.eta(), Rectrack.phi(), static_cast(kSpAll), kGlobalplusITS); + if (Rectrack.hasTPC()) { + histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), RecCol.centFT0M(), Rectrack.eta(), Rectrack.phi(), static_cast(kSpAll), kGlobalonly); + } else { + histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), RecCol.centFT0M(), Rectrack.eta(), Rectrack.phi(), static_cast(kSpAll), kITSonly); } - } - if (nTrks > 0) { - histos.fill(HIST("EventHist"), 9); - histos.fill(HIST("VtxZHist"), RecCol.posZ()); - histos.fill(HIST("MultPercentileMCRecHist"), RecCol.centFT0M()); - histos.fill(HIST("hmczvtxmultpp"), RecCol.posZ(), RecCol.centFT0M()); - - for (const auto& Rectrack : recTracksPart) { - if (!isTrackSelected(Rectrack)) { - continue; - } - histos.fill(HIST("MCrecPhiVsEtaHistpp"), Rectrack.phi(), Rectrack.eta()); - histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), RecCol.centFT0M(), Rectrack.eta(), Rectrack.phi(), static_cast(kSpAll), kGlobalplusITS); - if (Rectrack.hasTPC()) { - histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), RecCol.centFT0M(), Rectrack.eta(), Rectrack.phi(), static_cast(kSpAll), kGlobalonly); - } else { - histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), RecCol.centFT0M(), Rectrack.eta(), Rectrack.phi(), static_cast(kSpAll), kITSonly); - } - - if (Rectrack.has_mcParticle()) { - int pid = kBkg; - auto mcpart = Rectrack.template mcParticle_as(); - if (mcpart.isPhysicalPrimary()) { - switch (std::abs(mcpart.pdgCode())) { - case PDG_t::kPiPlus: - pid = kSpPion; - break; - case PDG_t::kKPlus: - pid = kSpKaon; - break; - case PDG_t::kProton: - pid = kSpProton; - break; - default: - pid = kSpOther; - break; - } - } else { - pid = kSpNotPrimary; - } - if (mcpart.has_mothers()) { - auto mcpartMother = mcpart.template mothers_as().front(); - if (mcpartMother.pdgCode() == PDG_t::kK0Short || std::abs(mcpartMother.pdgCode()) == PDG_t::kLambda0) { - pid = kSpStrangeDecay; - } - } - if (find(mclabels.begin(), mclabels.end(), Rectrack.mcParticleId()) != mclabels.end()) { - pid = kBkg; + if (Rectrack.has_mcParticle()) { + int pid = kBkg; + auto mcpart = Rectrack.template mcParticle_as(); + if (mcpart.isPhysicalPrimary()) { + switch (std::abs(mcpart.pdgCode())) { + case PDG_t::kPiPlus: + pid = kSpPion; + break; + case PDG_t::kKPlus: + pid = kSpKaon; + break; + case PDG_t::kProton: + pid = kSpProton; + break; + default: + pid = kSpOther; + break; } - mclabels.push_back(Rectrack.mcParticleId()); - histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), RecCol.centFT0M(), Rectrack.eta(), Rectrack.phi(), static_cast(pid), kGlobalplusITS); } else { - histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), RecCol.centFT0M(), Rectrack.eta(), Rectrack.phi(), static_cast(kBkg), kGlobalplusITS); + pid = kSpNotPrimary; } - } // track (mcrec) loop - - for (const auto& particle : GenParticles) { - if (!isGenTrackSelected(particle)) { - continue; + if (mcpart.has_mothers()) { + auto mcpartMother = mcpart.template mothers_as().front(); + if (mcpartMother.pdgCode() == PDG_t::kK0Short || std::abs(mcpartMother.pdgCode()) == PDG_t::kLambda0) { + pid = kSpStrangeDecay; + } } - histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), RecCol.centFT0M(), particle.eta(), particle.phi(), static_cast(kSpAll), kNoGenpTVar); - if (particle.pt() < kMinpTcut) { - histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), RecCol.centFT0M(), particle.eta(), particle.phi(), static_cast(kSpAll), kGenpTup, -10.0 * particle.pt() + 2); - histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), RecCol.centFT0M(), particle.eta(), particle.phi(), static_cast(kSpAll), kGenpTdown, 5.0 * particle.pt() + 0.5); - } else { - histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), RecCol.centFT0M(), particle.eta(), particle.phi(), static_cast(kSpAll), kGenpTup); - histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), RecCol.centFT0M(), particle.eta(), particle.phi(), static_cast(kSpAll), kGenpTdown); + if (find(mclabels.begin(), mclabels.end(), Rectrack.mcParticleId()) != mclabels.end()) { + pid = kBkg; } + mclabels.push_back(Rectrack.mcParticleId()); + histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), RecCol.centFT0M(), Rectrack.eta(), Rectrack.phi(), static_cast(pid), kGlobalplusITS); + } else { + histos.fill(HIST("hmcrecdndetapp"), RecCol.posZ(), RecCol.centFT0M(), Rectrack.eta(), Rectrack.phi(), static_cast(kBkg), kGlobalplusITS); + } + } // track (mcrec) loop - int pid = 0; - switch (std::abs(particle.pdgCode())) { - case PDG_t::kPiPlus: - pid = kSpPion; - break; - case PDG_t::kKPlus: - pid = kSpKaon; - break; - case PDG_t::kProton: - pid = kSpProton; - break; - default: - pid = kSpOther; - break; - } - histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), RecCol.centFT0M(), particle.eta(), particle.phi(), static_cast(pid), kNoGenpTVar); - } // track (mcgen) loop - } // nTrks>0 + for (const auto& particle : GenParticles) { + if (!isGenTrackSelected(particle)) { + continue; + } + histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), RecCol.centFT0M(), particle.eta(), particle.phi(), static_cast(kSpAll), kNoGenpTVar); + if (particle.pt() < kMinpTcut) { + histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), RecCol.centFT0M(), particle.eta(), particle.phi(), static_cast(kSpAll), kGenpTup, -10.0 * particle.pt() + 2); + histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), RecCol.centFT0M(), particle.eta(), particle.phi(), static_cast(kSpAll), kGenpTdown, 5.0 * particle.pt() + 0.5); + } else { + histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), RecCol.centFT0M(), particle.eta(), particle.phi(), static_cast(kSpAll), kGenpTup); + histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), RecCol.centFT0M(), particle.eta(), particle.phi(), static_cast(kSpAll), kGenpTdown); + } + + int pid = 0; + switch (std::abs(particle.pdgCode())) { + case PDG_t::kPiPlus: + pid = kSpPion; + break; + case PDG_t::kKPlus: + pid = kSpKaon; + break; + case PDG_t::kProton: + pid = kSpProton; + break; + default: + pid = kSpOther; + break; + } + histos.fill(HIST("hmcgendndetapp"), RecCol.posZ(), RecCol.centFT0M(), particle.eta(), particle.phi(), static_cast(pid), kNoGenpTVar); + } // track (mcgen) loop } // collision loop } PROCESS_SWITCH(HeavyionMultiplicity, processppMonteCarlo, "process pp MC", false); diff --git a/PWGLF/Tasks/GlobalEventProperties/uccZdc.cxx b/PWGLF/Tasks/GlobalEventProperties/uccZdc.cxx index ea894e460c3..465b0caa8a3 100644 --- a/PWGLF/Tasks/GlobalEventProperties/uccZdc.cxx +++ b/PWGLF/Tasks/GlobalEventProperties/uccZdc.cxx @@ -69,19 +69,22 @@ using SimTracks = soa::Join, kSizeBootStrapEnsemble> hNch{}; std::array, kSizeBootStrapEnsemble> hPoisson{}; +std::array, kSizeBootStrapEnsemble> hNchVsT0M{}; +std::array, kSizeBootStrapEnsemble> hNchVsV0A{}; +std::array, kSizeBootStrapEnsemble> hNchVsZN{}; + std::array, kSizeBootStrapEnsemble> pNchVsOneParCorrVsZN{}; std::array, kSizeBootStrapEnsemble> pNchVsTwoParCorrVsZN{}; std::array, kSizeBootStrapEnsemble> pNchVsThreeParCorrVsZN{}; -std::array, kSizeBootStrapEnsemble> pOneParCorrVsT0M{}; -std::array, kSizeBootStrapEnsemble> pTwoParCorrVsT0M{}; -std::array, kSizeBootStrapEnsemble> pThreeParCorrVsT0M{}; +std::array, kSizeBootStrapEnsemble> pNchVsOneParCorrVsT0M{}; +std::array, kSizeBootStrapEnsemble> pNchVsTwoParCorrVsT0M{}; +std::array, kSizeBootStrapEnsemble> pNchVsThreeParCorrVsT0M{}; -std::array, kSizeBootStrapEnsemble> pOneParCorrVsV0A{}; -std::array, kSizeBootStrapEnsemble> pTwoParCorrVsV0A{}; -std::array, kSizeBootStrapEnsemble> pThreeParCorrVsV0A{}; +std::array, kSizeBootStrapEnsemble> pNchVsOneParCorrVsV0A{}; +std::array, kSizeBootStrapEnsemble> pNchVsTwoParCorrVsV0A{}; +std::array, kSizeBootStrapEnsemble> pNchVsThreeParCorrVsV0A{}; std::array, kSizeBootStrapEnsemble> pOneParCorrVsNch{}; std::array, kSizeBootStrapEnsemble> pTwoParCorrVsNch{}; @@ -89,14 +92,7 @@ std::array, kSizeBootStrapEnsemble> pThreeParCorrVsNch std::array, kSizeBootStrapEnsemble> hPoissonMC{}; std::array, kSizeBootStrapEnsemble> hNchGen{}; - -// std::array, kSizeBootStrapEnsemble> pOneParCorrVsT0MGen{}; -// std::array, kSizeBootStrapEnsemble> pTwoParCorrVsT0MGen{}; -// std::array, kSizeBootStrapEnsemble> pThreeParCorrVsT0MGen{}; -// -// std::array, kSizeBootStrapEnsemble> pOneParCorrVsV0AGen{}; -// std::array, kSizeBootStrapEnsemble> pTwoParCorrVsV0AGen{}; -// std::array, kSizeBootStrapEnsemble> pThreeParCorrVsV0AGen{}; +std::array, kSizeBootStrapEnsemble> hNch{}; std::array, kSizeBootStrapEnsemble> pOneParCorrVsNchGen{}; std::array, kSizeBootStrapEnsemble> pTwoParCorrVsNchGen{}; @@ -119,13 +115,13 @@ struct UccZdc { Configurable isOccupancyCut{"isOccupancyCut", true, "Occupancy cut?"}; Configurable isApplyFT0CbasedOccupancy{"isApplyFT0CbasedOccupancy", false, "T0C Occu cut"}; Configurable isTDCcut{"isTDCcut", false, "Use TDC cut"}; - Configurable isZEMcut{"isZEMcut", true, "Use ZEM cut"}; Configurable useMidRapNchSel{"useMidRapNchSel", true, "Use mid-rapidit Nch selection"}; Configurable applyEff{"applyEff", true, "Apply track-by-track efficiency correction"}; Configurable applyFD{"applyFD", false, "Apply track-by-track feed down correction"}; Configurable correctNch{"correctNch", true, "Correct also Nch"}; Configurable skipRecoColGTOne{"skipRecoColGTOne", true, "Remove collisions if reconstructed more than once"}; Configurable detector4Calibration{"detector4Calibration", "T0M", "Detector for nSigma-Nch rejection"}; + Configurable detectorZDC{"detectorZDC", "ZN", "Detector for Cent. Selec. based on spectator neutrons"}; // Event selection Configurable posZcut{"posZcut", +10.0, "z-vertex position cut"}; @@ -150,6 +146,7 @@ struct UccZdc { Configurable minNch{"minNch", 0, "Min Nch (|eta|<0.8)"}; Configurable minZN{"minZN", -0.5, "Min ZN signal"}; Configurable minTdc{"minTdc", -15.0, "minimum TDC"}; + Configurable arbScale{"arbScale", 100.0, "Scale factor for forward multiplicity"}; Configurable maxNch{"maxNch", 3000, "Max Nch (|eta|<0.8)"}; Configurable maxITSTrack{"maxITSTrack", 6000., "Min ITS tracks"}; @@ -230,6 +227,7 @@ struct UccZdc { const char* tiT0C{"T0C (#times 1/100, -3.3 < #eta < -2.1)"}; const char* tiT0M{"T0A+T0C (#times 1/100, -3.3 < #eta < -2.1 and 3.5 < #eta < 4.9)"}; const char* tiNch{"#it{N}_{ch} (|#eta| < 0.8)"}; + const char* tiNPV{"#it{N}_{PV} (|#eta|<1)"}; const char* tiV0A{"V0A (#times 1/100, 2.2 < #eta < 5)"}; const char* tiZNs{"ZNA + ZNC"}; const char* tiZPs{"ZPA + ZPC"}; @@ -253,8 +251,11 @@ struct UccZdc { registry.add("ExcludedEvtVsFT0M", Form(";%s;Entries;", tiT0M), kTH1F, {{nBinsAmpFT0, 0., maxAmpFT0}}); registry.add("ExcludedEvtVsFV0A", Form(";%s;Entries;", tiT0M), kTH1F, {{nBinsAmpV0A, 0., maxAmpV0A}}); registry.add("ExcludedEvtVsNch", Form(";%s;Entries;", tiNch), kTH1F, {{nBinsNch, minNch, maxNch}}); + registry.add("ExcludedEvtVsNPV", Form(";%s;Entries;", tiNPV), kTH1F, {{nBinsITSTrack, 0, maxITSTrack}}); registry.add("Nch", Form(";%s;Entries;", tiNch), kTH1F, {{nBinsNch, minNch, maxNch}}); registry.add("NchVsOneParCorr", Form(";%s;%s;", tiNch, tiOneParCorr), kTProfile, {{nBinsNch, minNch, maxNch}}); + registry.add("NchVsTwoParCorr", Form(";%s;#LT[#it{p}_{T}^{(2)}]#GT;", tiNch), kTProfile, {{nBinsNch, minNch, maxNch}}); + registry.add("NchVsThreeParCorr", Form(";%s;#LT[#it{p}_{T}^{(3)}]#GT;", tiNch), kTProfile, {{nBinsNch, minNch, maxNch}}); auto hstat = registry.get(HIST("hEventCounter")); auto* x = hstat->GetXaxis(); @@ -277,35 +278,41 @@ struct UccZdc { x->SetBinLabel(17, "Within ZEM cut?"); if (doprocessZdcCollAss) { - registry.add("NchVsT0Mamp", Form(";%s;%s;", tiNch, tiT0M), kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsAmpFT0, 0., maxAmpFT0}}}); - registry.add("NchVsV0Aamp", Form(";%s;%s;", tiNch, tiV0A), kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsAmpV0A, 0., maxAmpV0A}}}); + registry.add("NchVsT0M", Form(";%s;%s;", tiNch, tiT0M), kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsAmpFT0, 0., maxAmpFT0}}}); + registry.add("NchVsV0A", Form(";%s;%s;", tiNch, tiV0A), kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsAmpV0A, 0., maxAmpV0A}}}); registry.add("NchVsZN", Form(";%s;%s;", tiNch, tiZNs), kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZN, minZN, maxZN}}}); registry.add("NchVsZP", Form(";%s;%s;", tiNch, tiZPs), kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZP, minZN, maxZP}}}); registry.add("NchVsZNVsPt", Form(";%s;%s;%s", tiNch, tiZNs, tiPt), kTH3F, {{{nBinsNch, minNch, maxNch}, {nBinsZN, minZN, maxZN}, {axisPt}}}); + registry.add("NchVsOneParCorrVsZN", Form(";%s;%s;%s", tiNch, tiZNs, tiOneParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZN, minZN, maxZN}}}); registry.add("NchVsTwoParCorrVsZN", Form(";%s;%s;%s", tiNch, tiZNs, tiTwoParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZN, minZN, maxZN}}}); registry.add("NchVsThreeParCorrVsZN", Form(";%s;%s;%s", tiNch, tiZNs, tiThreeParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZN, minZN, maxZN}}}); - registry.add("OneParCorrVsT0M", Form(";%s;%s;", tiT0M, tiOneParCorr), kTProfile, {{nBinsAmpFT0, 0., maxAmpFT0}}); - registry.add("TwoParCorrVsT0M", Form(";%s;%s;", tiT0M, tiTwoParCorr), kTProfile, {{nBinsAmpFT0, 0., maxAmpFT0}}); - registry.add("ThreeParCorrVsT0M", Form(";%s;%s;", tiT0M, tiThreeParCorr), kTProfile, {{nBinsAmpFT0, 0., maxAmpFT0}}); - registry.add("OneParCorrVsV0A", Form(";%s;%s;", tiV0A, tiOneParCorr), kTProfile, {{nBinsAmpV0A, 0., maxAmpV0A}}); - registry.add("TwoParCorrVsV0A", Form(";%s;%s;", tiV0A, tiTwoParCorr), kTProfile, {{nBinsAmpV0A, 0., maxAmpV0A}}); - registry.add("ThreeParCorrVsV0A", Form(";%s;%s;", tiV0A, tiThreeParCorr), kTProfile, {{nBinsAmpV0A, 0., maxAmpV0A}}); + + registry.add("NchVsOneParCorrVsT0M", Form(";%s;%s;%s", tiNch, tiT0M, tiOneParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsAmpFT0, 0., maxAmpFT0}}}); + registry.add("NchVsTwoParCorrVsT0M", Form(";%s;%s;%s", tiNch, tiT0M, tiTwoParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsAmpFT0, 0., maxAmpFT0}}}); + registry.add("NchVsThreeParCorrVsT0M", Form(";%s;%s;%s", tiNch, tiT0M, tiThreeParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsAmpFT0, 0., maxAmpFT0}}}); + + registry.add("NchVsOneParCorrVsV0A", Form(";%s;%s;%s", tiNch, tiV0A, tiOneParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsAmpV0A, 0., maxAmpV0A}}}); + registry.add("NchVsTwoParCorrVsV0A", Form(";%s;%s;%s", tiNch, tiV0A, tiTwoParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsAmpV0A, 0., maxAmpV0A}}}); + registry.add("NchVsThreeParCorrVsV0A", Form(";%s;%s;%s", tiNch, tiV0A, tiThreeParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsAmpV0A, 0., maxAmpV0A}}}); for (int i = 0; i < kSizeBootStrapEnsemble; i++) { - hNch[i] = registry.add(Form("Nch_Replica%d", i), Form(";%s;Entries", tiNch), kTH1F, {{nBinsNch, minNch, maxNch}}); - hPoisson[i] = registry.add(Form("Poisson_Replica%d", i), ";#it{k};Entries", kTH1F, {{11, -0.5, 10.5}}); - pNchVsOneParCorrVsZN[i] = registry.add(Form("NchVsOneParCorrVsZN_Replica%d", i), Form(";%s;%s;%s", tiNch, tiZNs, tiOneParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZN, minZN, maxZN}}}); - pNchVsTwoParCorrVsZN[i] = registry.add(Form("NchVsTwoParCorrVsZN_Replica%d", i), Form(";%s;%s;%s", tiNch, tiZNs, tiTwoParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZN, minZN, maxZN}}}); - pNchVsThreeParCorrVsZN[i] = registry.add(Form("NchVsThreeParCorrVsZN_Replica%d", i), Form(";%s;%s;%s", tiNch, tiZNs, tiThreeParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZN, minZN, maxZN}}}); - - pOneParCorrVsT0M[i] = registry.add(Form("OneParCorrVsT0M_Replica%d", i), Form(";%s;%s;", tiT0M, tiOneParCorr), kTProfile, {{nBinsAmpFT0, 0., maxAmpFT0}}); - pTwoParCorrVsT0M[i] = registry.add(Form("TwoParCorrVsT0M_Replica%d", i), Form(";%s;%s;", tiT0M, tiTwoParCorr), kTProfile, {{nBinsAmpFT0, 0., maxAmpFT0}}); - pThreeParCorrVsT0M[i] = registry.add(Form("ThreeParCorrVsT0M_Replica%d", i), Form(";%s;%s;", tiT0M, tiThreeParCorr), kTProfile, {{nBinsAmpFT0, 0., maxAmpFT0}}); - - pOneParCorrVsV0A[i] = registry.add(Form("OneParCorrVsV0A_Replica%d", i), Form(";%s;%s;", tiV0A, tiOneParCorr), kTProfile, {{nBinsAmpV0A, 0., maxAmpV0A}}); - pTwoParCorrVsV0A[i] = registry.add(Form("TwoParCorrVsV0A_Replica%d", i), Form(";%s;%s;", tiV0A, tiTwoParCorr), kTProfile, {{nBinsAmpV0A, 0., maxAmpV0A}}); - pThreeParCorrVsV0A[i] = registry.add(Form("ThreeParCorrVsV0A_Replica%d", i), Form(";%s;%s;", tiV0A, tiThreeParCorr), kTProfile, {{nBinsAmpV0A, 0., maxAmpV0A}}); + hNchVsZN[i] = registry.add(Form("NchVsZN_Rep%d", i), Form(";%s;%s", tiNch, tiZNs), kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsZN, minZN, maxZN}}}); + hNchVsV0A[i] = registry.add(Form("NchVsV0A_Rep%d", i), Form(";%s;%s", tiNch, tiV0A), kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsAmpV0A, 0., maxAmpV0A}}}); + hNchVsT0M[i] = registry.add(Form("NchVsT0M_Rep%d", i), Form(";%s;%s", tiNch, tiT0M), kTH2F, {{{nBinsNch, minNch, maxNch}, {nBinsAmpFT0, 0., maxAmpFT0}}}); + hPoisson[i] = registry.add(Form("Poisson_Rep%d", i), ";#it{k};Entries", kTH1F, {{11, -0.5, 10.5}}); + + pNchVsOneParCorrVsZN[i] = registry.add(Form("NchVsOneParCorrVsZN_Rep%d", i), Form(";%s;%s;%s", tiNch, tiZNs, tiOneParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZN, minZN, maxZN}}}); + pNchVsTwoParCorrVsZN[i] = registry.add(Form("NchVsTwoParCorrVsZN_Rep%d", i), Form(";%s;%s;%s", tiNch, tiZNs, tiTwoParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZN, minZN, maxZN}}}); + pNchVsThreeParCorrVsZN[i] = registry.add(Form("NchVsThreeParCorrVsZN_Rep%d", i), Form(";%s;%s;%s", tiNch, tiZNs, tiThreeParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsZN, minZN, maxZN}}}); + + pNchVsOneParCorrVsT0M[i] = registry.add(Form("NchVsOneParCorrVsT0M_Rep%d", i), Form(";%s;%s;%s", tiNch, tiT0M, tiOneParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsAmpFT0, 0., maxAmpFT0}}}); + pNchVsTwoParCorrVsT0M[i] = registry.add(Form("NchVsTwoParCorrVsT0M_Rep%d", i), Form(";%s;%s;%s", tiNch, tiT0M, tiTwoParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsAmpFT0, 0., maxAmpFT0}}}); + pNchVsThreeParCorrVsT0M[i] = registry.add(Form("NchVsThreeParCorrVsT0M_Rep%d", i), Form(";%s;%s;%s", tiNch, tiT0M, tiThreeParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsAmpFT0, 0., maxAmpFT0}}}); + + pNchVsOneParCorrVsV0A[i] = registry.add(Form("NchVsOneParCorrVsV0A_Rep%d", i), Form(";%s;%s;%s", tiNch, tiV0A, tiOneParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsAmpV0A, 0., maxAmpV0A}}}); + pNchVsTwoParCorrVsV0A[i] = registry.add(Form("NchVsTwoParCorrVsV0A_Rep%d", i), Form(";%s;%s;%s", tiNch, tiV0A, tiTwoParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsAmpV0A, 0., maxAmpV0A}}}); + pNchVsThreeParCorrVsV0A[i] = registry.add(Form("NchVsThreeParCorrVsV0A_Rep%d", i), Form(";%s;%s;%s", tiNch, tiV0A, tiThreeParCorr), kTProfile2D, {{{nBinsNch, minNch, maxNch}, {nBinsAmpV0A, 0., maxAmpV0A}}}); } } @@ -327,8 +334,6 @@ struct UccZdc { registry.add("NchvsOneParCorrGen", Form("MC Closure;%s;%s", tiNch, tiOneParCorr), kTProfile, {{nBinsNch, minNch, maxNch}}); registry.add("NchvsTwoParCorrGen", Form("MC Closure;%s;%s", tiNch, tiTwoParCorr), kTProfile, {{nBinsNch, minNch, maxNch}}); registry.add("NchvsThreeParCorrGen", Form("MC Closure;%s;%s", tiNch, tiThreeParCorr), kTProfile, {{nBinsNch, minNch, maxNch}}); - registry.add("NchVsTwoParCorr", Form("MC Closure;%s;%s", tiNch, tiTwoParCorr), kTProfile, {{nBinsNch, minNch, maxNch}}); - registry.add("NchVsThreeParCorr", Form("MC Closure;%s;%s", tiNch, tiThreeParCorr), kTProfile, {{nBinsNch, minNch, maxNch}}); // Corrections registry.add("zPosMC", "Filled at MC closure + Corrections;;Entries;", kTH1F, {axisZpos}); registry.add("hEventCounterMC", "Event counter", kTH1F, {axisEvent}); @@ -357,38 +362,20 @@ struct UccZdc { for (int i = 0; i < kSizeBootStrapEnsemble; i++) { - hPoissonMC[i] = registry.add(Form("PoissonMC_Replica%d", i), ";#it{k};Entries", kTH1F, {{11, -0.5, 10.5}}); - hNchGen[i] = registry.add(Form("NchGen_Replica%d", i), Form(";%s;Entries", tiNch), kTH1F, {{nBinsNch, minNch, maxNch}}); - - pOneParCorrVsNchGen[i] = registry.add(Form("OneParCorrVsNchGen_Replica%d", i), Form(";%s;%s;", tiNch, tiOneParCorr), kTProfile, {{nBinsNch, minNch, maxNch}}); - pTwoParCorrVsNchGen[i] = registry.add(Form("TwoParCorrVsNchGen_Replica%d", i), Form(";%s;%s;", tiNch, tiTwoParCorr), kTProfile, {{nBinsNch, minNch, maxNch}}); - pThreeParCorrVsNchGen[i] = registry.add(Form("ThreeParCorrVsNchGen_Replica%d", i), Form(";%s;%s;", tiNch, tiThreeParCorr), kTProfile, {{nBinsNch, minNch, maxNch}}); - - // pOneParCorrVsT0MGen[i] = registry.add(Form("OneParCorrVsT0MGen_Replica%d",i),Form(";%s;%s;",tiT0M,tiOneParCorr), kTProfile,{{nBinsAmpFT0,0.,maxAmpFT0}}); - // pTwoParCorrVsT0MGen[i] = registry.add(Form("TwoParCorrVsT0MGen_Replica%d",i),Form(";%s;%s;",tiT0M,tiTwoParCorr), kTProfile,{{nBinsAmpFT0,0.,maxAmpFT0}}); - // pThreeParCorrVsT0MGen[i] = registry.add(Form("ThreeParCorrVsT0MGen_Replica%d",i),Form(";%s;%s;",tiT0M,tiThreeParCorr), kTProfile,{{nBinsAmpFT0,0.,maxAmpFT0}}); + hPoissonMC[i] = registry.add(Form("PoissonMC_Rep%d", i), ";#it{k};Entries", kTH1F, {{11, -0.5, 10.5}}); + hNchGen[i] = registry.add(Form("NchGen_Rep%d", i), Form(";%s;Entries", tiNch), kTH1F, {{nBinsNch, minNch, maxNch}}); + pOneParCorrVsNchGen[i] = registry.add(Form("OneParCorrVsNchGen_Rep%d", i), Form(";%s;%s;", tiNch, tiOneParCorr), kTProfile, {{nBinsNch, minNch, maxNch}}); + pTwoParCorrVsNchGen[i] = registry.add(Form("TwoParCorrVsNchGen_Rep%d", i), Form(";%s;%s;", tiNch, tiTwoParCorr), kTProfile, {{nBinsNch, minNch, maxNch}}); + pThreeParCorrVsNchGen[i] = registry.add(Form("ThreeParCorrVsNchGen_Rep%d", i), Form(";%s;%s;", tiNch, tiThreeParCorr), kTProfile, {{nBinsNch, minNch, maxNch}}); - // pOneParCorrVsV0AGen[i] = registry.add(Form("OneParCorrVsV0AGen_Replica%d",i),Form(";%s;%s;",tiT0M,tiOneParCorr), kTProfile,{{nBinsAmpFT0,0.,maxAmpFT0}}); - // pTwoParCorrVsV0AGen[i] = registry.add(Form("TwoParCorrVsV0AGen_Replica%d",i),Form(";%s;%s;",tiT0M,tiTwoParCorr), kTProfile,{{nBinsAmpFT0,0.,maxAmpFT0}}); - // pThreeParCorrVsV0AGen[i] = registry.add(Form("ThreeParCorrVsV0AGen_Replica%d",i),Form(";%s;%s;",tiT0M,tiThreeParCorr), kTProfile,{{nBinsAmpFT0,0.,maxAmpFT0}}); + hNch[i] = registry.add(Form("Nch_Rep%d", i), Form(";%s;Entries", tiNch), kTH1F, {{nBinsNch, minNch, maxNch}}); + hPoisson[i] = registry.add(Form("Poisson_Rep%d", i), ";#it{k};Entries", kTH1F, {{11, -0.5, 10.5}}); - hNch[i] = registry.add(Form("Nch_Replica%d", i), Form(";%s;Entries", tiNch), kTH1F, {{nBinsNch, minNch, maxNch}}); - hPoisson[i] = registry.add(Form("Poisson_Replica%d", i), ";#it{k};Entries", kTH1F, {{11, -0.5, 10.5}}); - - pOneParCorrVsNch[i] = registry.add(Form("OneParCorrVsNch_Replica%d", i), Form(";%s;%s;", tiNch, tiOneParCorr), kTProfile, {{nBinsNch, minNch, maxNch}}); - pTwoParCorrVsNch[i] = registry.add(Form("TwoParCorrVsNch_Replica%d", i), Form(";%s;%s;", tiNch, tiTwoParCorr), kTProfile, {{nBinsNch, minNch, maxNch}}); - pThreeParCorrVsNch[i] = registry.add(Form("ThreeParCorrVsNch_Replica%d", i), Form(";%s;%s;", tiNch, tiTwoParCorr), kTProfile, {{nBinsNch, minNch, maxNch}}); - - // pOneParCorrVsT0M[i] = registry.add(Form("OneParCorrVsT0M_Replica%d",i),Form(";%s;%s;",tiT0M,tiOneParCorr),kTProfile,{{nBinsAmpFT0,0.,maxAmpFT0}}); - // pTwoParCorrVsT0M[i] = registry.add(Form("TwoParCorrVsT0M_Replica%d",i),Form(";%s;%s;",tiT0M,tiTwoParCorr),kTProfile,{{nBinsAmpFT0,0.,maxAmpFT0}}); - // pThreeParCorrVsT0M[i] = registry.add(Form("ThreeParCorrVsT0M_Replica%d",i),Form(";%s;%s;",tiT0M,tiThreeParCorr),kTProfile,{{nBinsAmpFT0,0.,maxAmpFT0}}); - // - // pOneParCorrVsV0A[i] = registry.add(Form("OneParCorrVsV0A_Replica%d",i),Form(";%s;%s;",tiV0A,tiOneParCorr),kTProfile,{{nBinsAmpV0A,0.,maxAmpV0A}}); - // pTwoParCorrVsV0A[i] = registry.add(Form("TwoParCorrVsV0A_Replica%d",i),Form(";%s;%s;",tiV0A,tiTwoParCorr),kTProfile,{{nBinsAmpV0A,0.,maxAmpV0A}}); - // pThreeParCorrVsV0A[i] = registry.add(Form("ThreeParCorrVsV0A_Replica%d",i),Form(";%s;%s;",tiV0A,tiThreeParCorr),kTProfile,{{nBinsAmpV0A,0.,maxAmpV0A}}); + pOneParCorrVsNch[i] = registry.add(Form("OneParCorrVsNch_Rep%d", i), Form(";%s;%s;", tiNch, tiOneParCorr), kTProfile, {{nBinsNch, minNch, maxNch}}); + pTwoParCorrVsNch[i] = registry.add(Form("TwoParCorrVsNch_Rep%d", i), Form(";%s;%s;", tiNch, tiTwoParCorr), kTProfile, {{nBinsNch, minNch, maxNch}}); + pThreeParCorrVsNch[i] = registry.add(Form("ThreeParCorrVsNch_Rep%d", i), Form(";%s;%s;", tiNch, tiTwoParCorr), kTProfile, {{nBinsNch, minNch, maxNch}}); } } - if (doprocessQA) { registry.add("zPos", ";;Entries;", kTH1F, {axisZpos}); registry.add("T0Ccent", ";;Entries", kTH1F, {axisCent}); @@ -427,6 +414,7 @@ struct UccZdc { LOG(info) << "\tcorrectNch=" << correctNch.value; LOG(info) << "\tpaTHEff=" << paTHEff.value; LOG(info) << "\tpaTHFD=" << paTHFD.value; + LOG(info) << "\tdetectorZDC=" << detectorZDC.value; LOG(info) << "\tuseMidRapNchSel=" << useMidRapNchSel.value; LOG(info) << "\tdetector4Calibration=" << detector4Calibration.value; LOG(info) << "\tnSigmaNchCut=" << nSigmaNchCut.value; @@ -510,8 +498,8 @@ struct UccZdc { if (occuValue < minOccCut || occuValue > maxOccCut) { return false; } + registry.fill(HIST("hEventCounter"), EvCutLabel::OccuCut); } - registry.fill(HIST("hEventCounter"), EvCutLabel::OccuCut); if (col.centFT0C() < minT0CcentCut || col.centFT0C() > maxT0CcentCut) { return false; @@ -542,8 +530,8 @@ struct UccZdc { registry.fill(HIST("hEventCounter"), EvCutLabel::Zdc); auto zdc = foundBC.zdc(); - double aT0A{-999.}; - double aT0C{-999.}; + double aT0A{0.}; + double aT0C{0.}; if (foundBC.has_ft0()) { for (const auto& amplitude : foundBC.ft0().amplitudeA()) { aT0A += amplitude; @@ -556,17 +544,18 @@ struct UccZdc { } registry.fill(HIST("hEventCounter"), EvCutLabel::TZero); - double aV0A{-999.}; + double aV0A{0.}; if (foundBC.has_fv0a()) { for (const auto& amplitude : foundBC.fv0a().amplitude()) { aV0A += amplitude; } } - const double normT0M{(aT0A + aT0C) / 100.}; - const double normV0A{aV0A / 100.}; - const double normT0A{aT0A / 100.}; - const double normT0C{aT0C / 100.}; + const double nPV{collision.multNTracksPVeta1() / 1.}; + const double normT0M{(aT0A + aT0C) / arbScale}; + const double normV0A{aV0A / arbScale}; + const double normT0A{aT0A / arbScale}; + const double normT0C{aT0C / arbScale}; float znA{zdc.amplitudeZNA()}; float znC{zdc.amplitudeZNC()}; float zpA{zdc.amplitudeZPA()}; @@ -593,14 +582,6 @@ struct UccZdc { registry.fill(HIST("hEventCounter"), EvCutLabel::Tdc); } - // ZEM cut - if (isZEMcut) { - if (sumZEMs < zemCut) { - return; - } - registry.fill(HIST("hEventCounter"), EvCutLabel::Zem); - } - int itsTracks = 0, glbTracks = 0; for (const auto& track : tracks) { if (track.hasITS() && ((track.eta() > minEta) && (track.eta() < maxEta))) { @@ -633,6 +614,9 @@ struct UccZdc { if (s1 == "V0A") { xEval = normV0A; } + if (s1 == "NPV") { + xEval = nPV; + } const int bin4Calibration{cfgNch.hMeanNch->FindBin(xEval)}; const double meanNch{cfgNch.hMeanNch->GetBinContent(bin4Calibration)}; @@ -644,6 +628,7 @@ struct UccZdc { registry.fill(HIST("ExcludedEvtVsFT0M"), normT0M); registry.fill(HIST("ExcludedEvtVsFV0A"), normV0A); registry.fill(HIST("ExcludedEvtVsNch"), glbTracks); + registry.fill(HIST("ExcludedEvtVsNPV"), nPV); skipEvent = true; } } @@ -652,7 +637,7 @@ struct UccZdc { return; } - double meanpt{0.}; + double sumpt{0.}; for (const auto& track : tracks) { // Track Selection if (!track.isGlobalTrack()) { @@ -669,24 +654,12 @@ struct UccZdc { registry.fill(HIST("EtaVsPhi"), track.eta(), track.phi()); registry.fill(HIST("sigma1Pt"), track.pt(), track.sigma1Pt()); registry.fill(HIST("dcaXYvspT"), track.dcaXY(), track.pt()); - meanpt += track.pt(); + sumpt += track.pt(); } registry.fill(HIST("zPos"), collision.posZ()); registry.fill(HIST("T0Ccent"), collision.centFT0C()); - registry.fill(HIST("ZNAamp"), znA); - registry.fill(HIST("ZNCamp"), znC); - registry.fill(HIST("ZPAamp"), zpA); - registry.fill(HIST("ZPCamp"), zpC); - registry.fill(HIST("ZNAVsZNC"), znC, znA); - registry.fill(HIST("ZNAVsZPA"), zpA, znA); - registry.fill(HIST("ZNCVsZPC"), zpC, znC); - registry.fill(HIST("ZPAVsZPC"), zpC, zpA); - registry.fill(HIST("ZNVsZEM"), sumZEMs, sumZNs); registry.fill(HIST("Debunch"), tZDCdif, tZDCsum); - registry.fill(HIST("ZNVsFT0A"), normT0A, sumZNs); - registry.fill(HIST("ZNVsFT0C"), normT0C, sumZNs); - registry.fill(HIST("ZNVsFT0M"), normT0M, sumZNs); registry.fill(HIST("NchVsFV0A"), normV0A, glbTracks); registry.fill(HIST("NchVsFT0A"), normT0A, glbTracks); registry.fill(HIST("NchVsFT0C"), normT0C, glbTracks); @@ -695,12 +668,29 @@ struct UccZdc { registry.fill(HIST("Nch"), glbTracks); registry.fill(HIST("NchVsNPV"), collision.multNTracksPVeta1(), glbTracks); registry.fill(HIST("NchVsITStracks"), itsTracks, glbTracks); - registry.fill(HIST("ZNAVsNch"), glbTracks, znA); - registry.fill(HIST("ZNCVsNch"), glbTracks, znC); - registry.fill(HIST("ZNVsNch"), glbTracks, sumZNs); - registry.fill(HIST("ZNDifVsNch"), glbTracks, znA - znC); if (glbTracks >= minNchSel) - registry.fill(HIST("NchVsOneParCorr"), glbTracks, meanpt / glbTracks); + registry.fill(HIST("NchVsOneParCorr"), glbTracks, sumpt / glbTracks); + + // ZEM cut + if (sumZEMs > zemCut) { + registry.fill(HIST("hEventCounter"), EvCutLabel::Zem); + registry.fill(HIST("ZNAamp"), znA); + registry.fill(HIST("ZNCamp"), znC); + registry.fill(HIST("ZPAamp"), zpA); + registry.fill(HIST("ZPCamp"), zpC); + registry.fill(HIST("ZNAVsZNC"), znC, znA); + registry.fill(HIST("ZNAVsZPA"), zpA, znA); + registry.fill(HIST("ZNCVsZPC"), zpC, znC); + registry.fill(HIST("ZPAVsZPC"), zpC, zpA); + registry.fill(HIST("ZNVsZEM"), sumZEMs, sumZNs); + registry.fill(HIST("ZNVsFT0A"), normT0A, sumZNs); + registry.fill(HIST("ZNVsFT0C"), normT0C, sumZNs); + registry.fill(HIST("ZNVsFT0M"), normT0M, sumZNs); + registry.fill(HIST("ZNAVsNch"), glbTracks, znA); + registry.fill(HIST("ZNCVsNch"), glbTracks, znC); + registry.fill(HIST("ZNVsNch"), glbTracks, sumZNs); + registry.fill(HIST("ZNDifVsNch"), glbTracks, znA - znC); + } } PROCESS_SWITCH(UccZdc, processQA, "Process QA", true); void processZdcCollAss(o2::aod::ColEvSels::iterator const& collision, o2::aod::BCsRun3 const& /*bcs*/, aod::Zdcs const& /*zdcs*/, aod::FV0As const& /*fv0as*/, aod::FT0s const& /*ft0s*/, TheFilteredTracks const& tracks) @@ -718,8 +708,8 @@ struct UccZdc { } registry.fill(HIST("hEventCounter"), EvCutLabel::Zdc); - double aT0A{-999.}; - double aT0C{-999.}; + double aT0A{0.}; + double aT0C{0.}; if (foundBC.has_ft0()) { for (const auto& amplitude : foundBC.ft0().amplitudeA()) { aT0A += amplitude; @@ -732,15 +722,16 @@ struct UccZdc { } registry.fill(HIST("hEventCounter"), EvCutLabel::TZero); - double aV0A{-999.}; + double aV0A{0.}; if (foundBC.has_fv0a()) { for (const auto& amplitude : foundBC.fv0a().amplitude()) { aV0A += amplitude; } } - const double normT0M{(aT0A + aT0C) / 100.}; - const double normV0A{aV0A / 100.}; + const double nPV{collision.multNTracksPVeta1() / 1.}; + const double normT0M{(aT0A + aT0C) / arbScale}; + const double normV0A{aV0A / arbScale}; float znA{foundBC.zdc().amplitudeZNA()}; float znC{foundBC.zdc().amplitudeZNC()}; float zpA{foundBC.zdc().amplitudeZPA()}; @@ -757,10 +748,19 @@ struct UccZdc { znC /= kCollEnergy; zpA /= kCollEnergy; zpC /= kCollEnergy; - const double sumZNs{znA + znC}; + double sumZNs{-999.}; const double sumZPs{zpA + zpC}; const double sumZEMs{aZEM1 + aZEM2}; + TString sZDC = TString(detectorZDC.value); + if (sZDC == "ZNA") { + sumZNs = znA; + } else if (sZDC == "ZNC") { + sumZNs = znC; + } else { + sumZNs = (znA + znC); + } + // TDC cut if (isTDCcut) { if (std::sqrt(std::pow(tZDCdif, 2.) + std::pow(tZDCsum, 2.)) > tdcCut) { @@ -769,16 +769,8 @@ struct UccZdc { registry.fill(HIST("hEventCounter"), EvCutLabel::Tdc); } - // ZEM cut - if (isZEMcut) { - if (sumZEMs < zemCut) { - return; - } - registry.fill(HIST("hEventCounter"), EvCutLabel::Zem); - } - // Nch-based selection - int glbTracks{0}; + double glbTracks{0.0}; for (const auto& track : tracks) { // Track Selection if (!track.isGlobalTrack()) { @@ -790,11 +782,7 @@ struct UccZdc { if ((track.eta() < minEta) || (track.eta() > maxEta)) { continue; } - glbTracks++; - } - - if (glbTracks < minNchSel) { - return; + glbTracks += 1.0; } bool skipEvent{false}; @@ -811,6 +799,9 @@ struct UccZdc { if (s1 == "V0A") { xEval = normV0A; } + if (s1 == "NPV") { + xEval = nPV; + } const int bin4Calibration{cfgNch.hMeanNch->FindBin(xEval)}; const double meanNch{cfgNch.hMeanNch->GetBinContent(bin4Calibration)}; @@ -822,6 +813,7 @@ struct UccZdc { registry.fill(HIST("ExcludedEvtVsFT0M"), normT0M); registry.fill(HIST("ExcludedEvtVsFV0A"), normV0A); registry.fill(HIST("ExcludedEvtVsNch"), glbTracks); + registry.fill(HIST("ExcludedEvtVsNPV"), nPV); skipEvent = true; } } @@ -831,14 +823,19 @@ struct UccZdc { return; } - double nchMult{static_cast(glbTracks)}; - std::vector pTs; - std::vector vecFD; - std::vector vecEff; + // Reject low-multiplcicity events + if (glbTracks < minNchSel) { + return; + } + + double nchMult{glbTracks}; + std::vector pTs; + std::vector vecFD; + std::vector vecEff; // apply corrections if (applyEff || applyFD) { - + nchMult = 0.; loadCorrections(foundBC.timestamp()); if (!(cfg.hEfficiency && cfg.hFeedDown)) return; @@ -871,8 +868,14 @@ struct UccZdc { } } - if (applyEff && !correctNch) - nchMult = static_cast(glbTracks); + if (applyEff && !correctNch) { + nchMult = glbTracks; + } + + // Reject low-multiplcicity events + if (nchMult < minNchSel) { + return; + } // Fill vectors for [pT] measurement for (const auto& track : tracks) { @@ -930,48 +933,47 @@ struct UccZdc { getPTpowers(pTs, vecEff, vecFD, p1, w1, p2, w2, p3, w3, p4, w4); // EbE one-particle pT correlation - double oneParCorr{p1 / w1}; + const double oneParCorr{p1 / w1}; // EbE two-particle pT correlation - double denTwoParCorr{std::pow(w1, 2.) - w2}; - double numTwoParCorr{std::pow(p1, 2.) - p2}; - double twoParCorr{numTwoParCorr / denTwoParCorr}; + const double denTwoParCorr{std::pow(w1, 2.) - w2}; + const double numTwoParCorr{std::pow(p1, 2.) - p2}; + const double twoParCorr{numTwoParCorr / denTwoParCorr}; // EbE three-particle pT correlation - double denThreeParCorr{std::pow(w1, 3.) - 3. * w2 * w1 + 2. * w3}; - double numThreeParCorr{std::pow(p1, 3.) - 3. * p2 * p1 + 2. * p3}; - double threeParCorr{numThreeParCorr / denThreeParCorr}; - - // EbE four-particle pT correlation - // double denFourParCorr{std::pow(w1, 4.) - 6. * w2 * std::pow(w1, 2.) + 3. * std::pow(w2, 2.) + 8 * w3 * w1 - 6. * w4}; - // double numFourParCorr{std::pow(p1, 4.) - 6. * p2 * std::pow(p1, 2.) + 3. * std::pow(p2, 2.) + 8 * p3 * p1 - 6. * p4}; - // double fourParCorr{numFourParCorr / denFourParCorr}; + const double denThreeParCorr{std::pow(w1, 3.) - (3. * w2 * w1) + (2. * w3)}; + const double numThreeParCorr{std::pow(p1, 3.) - (3. * p2 * p1) + (2. * p3)}; + const double threeParCorr{numThreeParCorr / denThreeParCorr}; // One-dimensional distributions registry.fill(HIST("Nch"), nchMult); registry.fill(HIST("NchUncorrected"), glbTracks); + registry.fill(HIST("NchVsV0A"), nchMult, normV0A); + registry.fill(HIST("NchVsT0M"), nchMult, normT0M); - registry.fill(HIST("NchVsV0Aamp"), nchMult, normV0A); - registry.fill(HIST("NchVsT0Mamp"), nchMult, normT0M); - registry.fill(HIST("NchVsZN"), nchMult, sumZNs); - registry.fill(HIST("NchVsZP"), nchMult, sumZPs); - - registry.fill(HIST("NchVsOneParCorr"), nchMult, oneParCorr, w1); + registry.fill(HIST("NchVsOneParCorr"), nchMult, oneParCorr); + registry.fill(HIST("NchVsTwoParCorr"), nchMult, twoParCorr); + registry.fill(HIST("NchVsThreeParCorr"), nchMult, threeParCorr); - registry.fill(HIST("NchVsOneParCorrVsZN"), nchMult, sumZNs, oneParCorr, w1); - registry.fill(HIST("NchVsTwoParCorrVsZN"), nchMult, sumZNs, twoParCorr, denTwoParCorr); - registry.fill(HIST("NchVsThreeParCorrVsZN"), nchMult, sumZNs, threeParCorr, denThreeParCorr); + registry.fill(HIST("NchVsOneParCorrVsT0M"), nchMult, normT0M, oneParCorr); + registry.fill(HIST("NchVsTwoParCorrVsT0M"), nchMult, normT0M, twoParCorr); + registry.fill(HIST("NchVsThreeParCorrVsT0M"), nchMult, normT0M, threeParCorr); - registry.fill(HIST("OneParCorrVsT0M"), normT0M, oneParCorr, w1); - registry.fill(HIST("TwoParCorrVsT0M"), normT0M, twoParCorr, denTwoParCorr); - registry.fill(HIST("ThreeParCorrVsT0M"), normT0M, threeParCorr, denThreeParCorr); + registry.fill(HIST("NchVsOneParCorrVsV0A"), nchMult, normV0A, oneParCorr); + registry.fill(HIST("NchVsTwoParCorrVsV0A"), nchMult, normV0A, twoParCorr); + registry.fill(HIST("NchVsThreeParCorrVsV0A"), nchMult, normV0A, threeParCorr); - registry.fill(HIST("OneParCorrVsV0A"), normV0A, oneParCorr, w1); - registry.fill(HIST("TwoParCorrVsV0A"), normV0A, twoParCorr, denTwoParCorr); - registry.fill(HIST("ThreeParCorrVsV0A"), normV0A, threeParCorr, denThreeParCorr); + if (sumZEMs > zemCut) { + registry.fill(HIST("hEventCounter"), EvCutLabel::Zem); + registry.fill(HIST("NchVsZN"), nchMult, sumZNs); + registry.fill(HIST("NchVsZP"), nchMult, sumZPs); + registry.fill(HIST("NchVsOneParCorrVsZN"), nchMult, sumZNs, oneParCorr); + registry.fill(HIST("NchVsTwoParCorrVsZN"), nchMult, sumZNs, twoParCorr); + registry.fill(HIST("NchVsThreeParCorrVsZN"), nchMult, sumZNs, threeParCorr); + } const uint64_t timeStamp{foundBC.timestamp()}; - eventSampling(tracks, normV0A, normT0M, sumZNs, timeStamp); + eventSampling(tracks, normV0A, normT0M, sumZNs, sumZEMs, timeStamp); } PROCESS_SWITCH(UccZdc, processZdcCollAss, "Process ZDC W/Coll Ass.", true); @@ -1011,17 +1013,10 @@ struct UccZdc { aT0C += amplitude; } } else { - return; + continue; } - // double aV0A{-999.}; - // if (foundBC.has_fv0a()) { - // for (const auto& amplitude : foundBC.fv0a().amplitude()) { aV0A += amplitude; } - // } - - const double normT0M{(aT0A + aT0C) / 100.}; - // const double normV0A{aV0A/100.}; - + const double normT0M{(aT0A + aT0C) / arbScale}; double nchRaw{0.}; double nchMult{0.}; double nchMC{0.}; @@ -1073,18 +1068,18 @@ struct UccZdc { // Reject event if nchRaw less than a lower cutoff if (nchRaw < minNchSel) { - return; + continue; } - // Calculates the event weight, W_k const int foundNchBin{cfg.hEfficiency->GetXaxis()->FindBin(nchRaw)}; + // Calculates the event weight, W_k for (const auto& track : groupedTracks) { // Track Selection if (track.eta() < minEta || track.eta() > maxEta) { continue; } - if (track.pt() < minPt || track.pt() > maxPt) { + if (track.pt() < minPt || track.pt() > maxPtSpectra) { continue; } if (!track.isGlobalTrack()) { @@ -1108,8 +1103,6 @@ struct UccZdc { if (std::abs(charge) < kMinCharge) { continue; } - // Is it a primary particle? - // if (!particle.isPhysicalPrimary()) { continue; } const double pt{static_cast(track.pt())}; const int foundPtBin{cfg.hEfficiency->GetYaxis()->FindBin(pt)}; @@ -1132,10 +1125,8 @@ struct UccZdc { const double denTwoParCorr{std::pow(w1, 2.) - w2}; const double numTwoParCorr{std::pow(p1, 2.) - p2}; - const double denThreeParCorr{std::pow(w1, 3.) - 3. * w2 * w1 + 2. * w3}; - const double numThreeParCorr{std::pow(p1, 3.) - 3. * p2 * p1 + 2. * p3}; - // const double denFourParCorr{std::pow(w1, 4.) - 6. * w2 * std::pow(w1, 2.) + 3. * std::pow(w2, 2.) + 8 * w3 * w1 - 6. * w4}; - // const double numFourParCorr{std::pow(p1, 4.) - 6. * p2 * std::pow(p1, 2.) + 3. * std::pow(p2, 2.) + 8 * p3 * p1 - 6. * p4}; + const double denThreeParCorr{std::pow(w1, 3.) - (3. * w2 * w1) + (2. * w3)}; + const double numThreeParCorr{std::pow(p1, 3.) - (3. * p2 * p1) + (2. * p3)}; const double oneParCorr{p1 / w1}; const double twoParCorr{numTwoParCorr / denTwoParCorr}; @@ -1143,16 +1134,16 @@ struct UccZdc { registry.fill(HIST("Nch"), nchMult); registry.fill(HIST("NchUncorrected"), nchRaw); - registry.fill(HIST("NchVsOneParCorr"), nchMult, oneParCorr, w1); - registry.fill(HIST("NchVsTwoParCorr"), nchMult, twoParCorr, denTwoParCorr); - registry.fill(HIST("NchVsThreeParCorr"), nchMult, threeParCorr, denThreeParCorr); + registry.fill(HIST("NchVsOneParCorr"), nchMult, oneParCorr); + registry.fill(HIST("NchVsTwoParCorr"), nchMult, twoParCorr); + registry.fill(HIST("NchVsThreeParCorr"), nchMult, threeParCorr); //--------------------------- Generated MC --------------------------- std::vector pTsMC; std::vector vecFullEff; std::vector vecFDEqualOne; - // Calculates the event weight, W_k + // calculates the true Nch for (const auto& particle : mcParticles) { if (particle.eta() < minEta || particle.eta() > maxEta) { continue; @@ -1178,18 +1169,45 @@ struct UccZdc { if (!particle.isPhysicalPrimary()) { continue; } - - float pt{particle.pt()}; - pTsMC.emplace_back(pt); - vecFullEff.emplace_back(1.); - vecFDEqualOne.emplace_back(1.); nchMC++; } if (nchMC < minNchSel) { continue; } - // printf("nchMult = %f | nchMC = %f | nchMult/nchMc = %f\n",nchMult,nchMC,nchMult/nchMC); + + // Calculates the event weight, W_k + for (const auto& particle : mcParticles) { + if (particle.eta() < minEta || particle.eta() > maxEta) { + continue; + } + if (particle.pt() < minPt || particle.pt() > maxPtSpectra) { + continue; + } + + auto charge{0.}; + // Get the MC particle + auto* pdgParticle = pdg->GetParticle(particle.pdgCode()); + if (pdgParticle != nullptr) { + charge = pdgParticle->Charge(); + } else { + continue; + } + + // Is it a charged particle? + if (std::abs(charge) < kMinCharge) { + continue; + } + // Is it a primary particle? + if (!particle.isPhysicalPrimary()) { + continue; + } + + const float pt{particle.pt()}; + pTsMC.emplace_back(pt); + vecFullEff.emplace_back(1.); + vecFDEqualOne.emplace_back(1.); + } double p1MC, p2MC, p3MC, p4MC, w1MC, w2MC, w3MC, w4MC; p1MC = p2MC = p3MC = p4MC = w1MC = w2MC = w3MC = w4MC = 0.0; @@ -1197,20 +1215,17 @@ struct UccZdc { const double denTwoParCorrMC{std::pow(w1MC, 2.) - w2MC}; const double numTwoParCorrMC{std::pow(p1MC, 2.) - p2MC}; - const double denThreeParCorrMC{std::pow(w1MC, 3.) - 3. * w2MC * w1MC + 2. * w3MC}; - const double numThreeParCorrMC{std::pow(p1MC, 3.) - 3. * p2MC * p1MC + 2. * p3MC}; - // const double denFourParCorrMC{std::pow(w1MC, 4.) - 6. * w2MC * std::pow(w1MC, 2.) + 3. * std::pow(w2MC, 2.) + 8 * w3MC * w1MC - 6. * w4MC}; - // const double numFourParCorrMC{std::pow(p1MC, 4.) - 6. * p2MC * std::pow(p1MC, 2.) + 3. * std::pow(p2MC, 2.) + 8 * p3MC * p1MC - 6. * p4MC}; + const double denThreeParCorrMC{std::pow(w1MC, 3.) - (3. * w2MC * w1MC) + (2. * w3MC)}; + const double numThreeParCorrMC{std::pow(p1MC, 3.) - (3. * p2MC * p1MC) + (2. * p3MC)}; const double oneParCorrMC{p1MC / w1MC}; const double twoParCorrMC{numTwoParCorrMC / denTwoParCorrMC}; const double threeParCorrMC{numThreeParCorrMC / denThreeParCorrMC}; - // const double fourParCorrMC{numFourParCorrMC / denFourParCorrMC}; registry.fill(HIST("NchGen"), nchMC); - registry.fill(HIST("NchvsOneParCorrGen"), nchMC, oneParCorrMC, w1MC); - registry.fill(HIST("NchvsTwoParCorrGen"), nchMC, twoParCorrMC, denTwoParCorrMC); - registry.fill(HIST("NchvsThreeParCorrGen"), nchMC, threeParCorrMC, denThreeParCorrMC); + registry.fill(HIST("NchvsOneParCorrGen"), nchMC, oneParCorrMC); + registry.fill(HIST("NchvsTwoParCorrGen"), nchMC, twoParCorrMC); + registry.fill(HIST("NchvsThreeParCorrGen"), nchMC, threeParCorrMC); //------------------ Poisson sampling eventSamplingMC(mcParticles, timeStamp); @@ -1218,7 +1233,6 @@ struct UccZdc { } else { // Correction with the remaining half of the sample registry.fill(HIST("EvtsDivided"), 1); //----- MC reconstructed -----// - // const auto& groupedTracks{simTracks.sliceBy(perCollision, collision.globalIndex())}; for (const auto& track : groupedTracks) { // Track Selection if (track.eta() < minEta || track.eta() > maxEta) { @@ -1230,9 +1244,6 @@ struct UccZdc { if (!track.isGlobalTrack()) { continue; } - registry.fill(HIST("ZposVsEta"), collision.posZ(), track.eta()); - registry.fill(HIST("EtaVsPhi"), track.eta(), track.phi()); - registry.fill(HIST("dcaXYvspT"), track.dcaXY(), track.pt()); nchRaw++; } @@ -1241,7 +1252,7 @@ struct UccZdc { if (track.eta() < minEta || track.eta() > maxEta) { continue; } - if (track.pt() < minPt || track.pt() > maxPt) { + if (track.pt() < minPt || track.pt() > maxPtSpectra) { continue; } if (!track.isGlobalTrack()) { @@ -1265,8 +1276,13 @@ struct UccZdc { if (std::abs(charge) < kMinCharge) { continue; } + // All charged particles registry.fill(HIST("Pt_all_ch"), nchRaw, track.pt()); + registry.fill(HIST("ZposVsEta"), collision.posZ(), track.eta()); + registry.fill(HIST("EtaVsPhi"), track.eta(), track.phi()); + registry.fill(HIST("dcaXYvspT"), track.dcaXY(), track.pt()); + // Is it a primary particle? if (!particle.isPhysicalPrimary()) { continue; @@ -1293,7 +1309,7 @@ struct UccZdc { if (particle.eta() < minEta || particle.eta() > maxEta) { continue; } - if (particle.pt() < minPt || particle.pt() > maxPt) { + if (particle.pt() < minPt || particle.pt() > maxPtSpectra) { continue; } @@ -1375,7 +1391,7 @@ struct UccZdc { std::vector vecFD; std::vector vecEff; - // Calculates the event weight, W_k + // Calculates the true Nch for (const auto& particle : mcParticles) { if (particle.eta() < minEta || particle.eta() > maxEta) { continue; @@ -1401,18 +1417,45 @@ struct UccZdc { if (!particle.isPhysicalPrimary()) { continue; } - - float pt{particle.pt()}; - pTs.emplace_back(pt); - vecEff.emplace_back(1.); - vecFD.emplace_back(1.); nchMult++; } if (nchMult < minNchSel) { continue; } - // printf("nchMult = %f | nchMC = %f | nchMult/nchMc = %f\n",nchMult,nchMC,nchMult/nchMC); + + // Calculates the event weight, W_k + for (const auto& particle : mcParticles) { + if (particle.eta() < minEta || particle.eta() > maxEta) { + continue; + } + if (particle.pt() < minPt || particle.pt() > maxPtSpectra) { + continue; + } + + auto charge{0.}; + // Get the MC particle + auto* pdgParticle = pdg->GetParticle(particle.pdgCode()); + if (pdgParticle != nullptr) { + charge = pdgParticle->Charge(); + } else { + continue; + } + + // Is it a charged particle? + if (std::abs(charge) < kMinCharge) { + continue; + } + // Is it a primary particle? + if (!particle.isPhysicalPrimary()) { + continue; + } + + const float pt{particle.pt()}; + pTs.emplace_back(pt); + vecEff.emplace_back(1.); + vecFD.emplace_back(1.); + } double p1, p2, p3, p4, w1, w2, w3, w4; p1 = p2 = p3 = p4 = w1 = w2 = w3 = w4 = 0.0; @@ -1427,23 +1470,14 @@ struct UccZdc { const double twoParCorr{numTwoParCorr / denTwoParCorr}; // EbE three-particle pT correlation - const double denThreeParCorr{std::pow(w1, 3.) - 3. * w2 * w1 + 2. * w3}; - const double numThreeParCorr{std::pow(p1, 3.) - 3. * p2 * p1 + 2. * p3}; + const double denThreeParCorr{std::pow(w1, 3.) - (3. * w2 * w1) + (2. * w3)}; + const double numThreeParCorr{std::pow(p1, 3.) - (3. * p2 * p1) + (2. * p3)}; const double threeParCorr{numThreeParCorr / denThreeParCorr}; hNchGen[replica]->Fill(nchMult); - - pOneParCorrVsNchGen[replica]->Fill(nchMult, oneParCorr, w1); - pTwoParCorrVsNchGen[replica]->Fill(nchMult, twoParCorr, denTwoParCorr); - pThreeParCorrVsNchGen[replica]->Fill(nchMult, threeParCorr, denThreeParCorr); - - // pOneParCorrVsV0AGen[replica]->Fill(normV0A, oneParCorr, w1); - // pTwoParCorrVsV0AGen[replica]->Fill(normV0A, twoParCorr, denTwoParCorr); - // pThreeParCorrVsV0AGen[replica]->Fill(normV0A, threeParCorr, denThreeParCorr); - - // pOneParCorrVsT0MGen[replica]->Fill(normT0M, oneParCorr, w1); - // pTwoParCorrVsT0MGen[replica]->Fill(normT0M, twoParCorr, denTwoParCorr); - // pThreeParCorrVsT0MGen[replica]->Fill(normT0M, threeParCorr, denThreeParCorr); + pOneParCorrVsNchGen[replica]->Fill(nchMult, oneParCorr); + pTwoParCorrVsNchGen[replica]->Fill(nchMult, twoParCorr); + pThreeParCorrVsNchGen[replica]->Fill(nchMult, threeParCorr); } // event per replica } // replica's loop } @@ -1468,7 +1502,7 @@ struct UccZdc { std::vector vecFD; std::vector vecEff; - // Calculates the uncorrected Nch multiplicity + // Calculates the uncorrected Nch for (const auto& track : tracks) { // Track Selection if (!track.isGlobalTrack()) { @@ -1502,10 +1536,10 @@ struct UccZdc { continue; } - float pt{track.pt()}; + const float pt{track.pt()}; double fdValue{1.}; - int foundPtBin{cfg.hEfficiency->GetYaxis()->FindBin(pt)}; - double effValue{cfg.hEfficiency->GetBinContent(foundNchBin, foundPtBin)}; + const int foundPtBin{cfg.hEfficiency->GetYaxis()->FindBin(pt)}; + const double effValue{cfg.hEfficiency->GetBinContent(foundNchBin, foundPtBin)}; if (applyFD) fdValue = cfg.hFeedDown->GetBinContent(foundNchBin, foundPtBin); @@ -1536,10 +1570,10 @@ struct UccZdc { continue; } - float pt{track.pt()}; + const float pt{track.pt()}; double fdValue{1.}; - int foundPtBin{cfg.hEfficiency->GetYaxis()->FindBin(pt)}; - double effValue{cfg.hEfficiency->GetBinContent(foundNchBin, foundPtBin)}; + const int foundPtBin{cfg.hEfficiency->GetYaxis()->FindBin(pt)}; + const double effValue{cfg.hEfficiency->GetBinContent(foundNchBin, foundPtBin)}; if (applyFD) fdValue = cfg.hFeedDown->GetBinContent(foundNchBin, foundPtBin); @@ -1579,29 +1613,20 @@ struct UccZdc { const double twoParCorr{numTwoParCorr / denTwoParCorr}; // EbE three-particle pT correlation - const double denThreeParCorr{std::pow(w1, 3.) - 3. * w2 * w1 + 2. * w3}; - const double numThreeParCorr{std::pow(p1, 3.) - 3. * p2 * p1 + 2. * p3}; + const double denThreeParCorr{std::pow(w1, 3.) - (3. * w2 * w1) + (2. * w3)}; + const double numThreeParCorr{std::pow(p1, 3.) - (3. * p2 * p1) + (2. * p3)}; const double threeParCorr{numThreeParCorr / denThreeParCorr}; hNch[replica]->Fill(nchMult); - - pOneParCorrVsNch[replica]->Fill(nchMult, oneParCorr, w1); - pTwoParCorrVsNch[replica]->Fill(nchMult, twoParCorr, denTwoParCorr); - pThreeParCorrVsNch[replica]->Fill(nchMult, threeParCorr, denThreeParCorr); - - // pOneParCorrVsV0A[replica]->Fill(normV0A, oneParCorr, w1); - // pTwoParCorrVsV0A[replica]->Fill(normV0A, twoParCorr, denTwoParCorr); - // pThreeParCorrVsV0A[replica]->Fill(normV0A, threeParCorr, denThreeParCorr); - // - // pOneParCorrVsT0M[replica]->Fill(normT0M, oneParCorr, w1); - // pTwoParCorrVsT0M[replica]->Fill(normT0M, twoParCorr, denTwoParCorr); - // pThreeParCorrVsT0M[replica]->Fill(normT0M, threeParCorr, denThreeParCorr); + pOneParCorrVsNch[replica]->Fill(nchMult, oneParCorr); + pTwoParCorrVsNch[replica]->Fill(nchMult, twoParCorr); + pThreeParCorrVsNch[replica]->Fill(nchMult, threeParCorr); } // event per replica } // replica's loop } template - void eventSampling(const T& tracks, const U& normV0A, const U& normT0M, const U& sumZNs, const V& timeStamp) + void eventSampling(const T& tracks, const U& normV0A, const U& normT0M, const U& sumZNs, const U& sumZEMs, const V& timeStamp) { TRandom3 rndGen(timeStamp); std::vector vPoisson; @@ -1700,8 +1725,6 @@ struct UccZdc { pTs.emplace_back(pt); vecEff.emplace_back(effValue); vecFD.emplace_back(fdValue); - // To calculate event-averaged - registry.fill(HIST("NchVsZNVsPt"), nchMult, sumZNs, pt * (fdValue / effValue)); } } } else { @@ -1717,9 +1740,6 @@ struct UccZdc { pTs.emplace_back(track.pt()); vecEff.emplace_back(1.); vecFD.emplace_back(1.); - - // To calculate event-averaged - registry.fill(HIST("NchVsZNVsPt"), nchMult, sumZNs, track.pt()); } } @@ -1736,30 +1756,33 @@ struct UccZdc { const double twoParCorr{numTwoParCorr / denTwoParCorr}; // EbE three-particle pT correlation - const double denThreeParCorr{std::pow(w1, 3.) - 3. * w2 * w1 + 2. * w3}; - const double numThreeParCorr{std::pow(p1, 3.) - 3. * p2 * p1 + 2. * p3}; + const double denThreeParCorr{std::pow(w1, 3.) - (3. * w2 * w1) + (2. * w3)}; + const double numThreeParCorr{std::pow(p1, 3.) - (3. * p2 * p1) + (2. * p3)}; const double threeParCorr{numThreeParCorr / denThreeParCorr}; - hNch[replica]->Fill(nchMult); - pNchVsOneParCorrVsZN[replica]->Fill(nchMult, sumZNs, oneParCorr, w1); - pNchVsTwoParCorrVsZN[replica]->Fill(nchMult, sumZNs, twoParCorr, denTwoParCorr); - pNchVsThreeParCorrVsZN[replica]->Fill(nchMult, sumZNs, threeParCorr, denThreeParCorr); + hNchVsV0A[replica]->Fill(nchMult, normV0A); + hNchVsT0M[replica]->Fill(nchMult, normT0M); + + pNchVsOneParCorrVsT0M[replica]->Fill(nchMult, normT0M, oneParCorr); + pNchVsTwoParCorrVsT0M[replica]->Fill(nchMult, normT0M, twoParCorr); + pNchVsThreeParCorrVsT0M[replica]->Fill(nchMult, normT0M, threeParCorr); - pOneParCorrVsV0A[replica]->Fill(normV0A, oneParCorr, w1); - pTwoParCorrVsV0A[replica]->Fill(normV0A, twoParCorr, denTwoParCorr); - pThreeParCorrVsV0A[replica]->Fill(normV0A, threeParCorr, denThreeParCorr); + pNchVsOneParCorrVsV0A[replica]->Fill(nchMult, normV0A, oneParCorr); + pNchVsTwoParCorrVsV0A[replica]->Fill(nchMult, normV0A, twoParCorr); + pNchVsThreeParCorrVsV0A[replica]->Fill(nchMult, normV0A, threeParCorr); - pOneParCorrVsT0M[replica]->Fill(normT0M, oneParCorr, w1); - pTwoParCorrVsT0M[replica]->Fill(normT0M, twoParCorr, denTwoParCorr); - pThreeParCorrVsT0M[replica]->Fill(normT0M, threeParCorr, denThreeParCorr); + if (sumZEMs > zemCut) { + hNchVsZN[replica]->Fill(nchMult, sumZNs); + pNchVsOneParCorrVsZN[replica]->Fill(nchMult, sumZNs, oneParCorr); + pNchVsTwoParCorrVsZN[replica]->Fill(nchMult, sumZNs, twoParCorr); + pNchVsThreeParCorrVsZN[replica]->Fill(nchMult, sumZNs, threeParCorr); + } } // event per replica } // replica's loop } void loadCorrections(uint64_t timeStamp) { - // if (cfg.correctionsLoaded) return; - if (paTHEff.value.empty() == false) { cfg.hEfficiency = ccdb->getForTimeStamp(paTHEff, timeStamp); if (cfg.hEfficiency == nullptr) { diff --git a/PWGLF/Tasks/Nuspex/CMakeLists.txt b/PWGLF/Tasks/Nuspex/CMakeLists.txt index 05b1bc2ca8e..cc23b8d0544 100644 --- a/PWGLF/Tasks/Nuspex/CMakeLists.txt +++ b/PWGLF/Tasks/Nuspex/CMakeLists.txt @@ -79,8 +79,8 @@ o2physics_add_dpl_workflow(spectra-tpc-tiny-pikapr PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(spectra-charged - SOURCES spectraCharged.cxx +o2physics_add_dpl_workflow(charged-particles + SOURCES chargedParticles.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) @@ -137,7 +137,7 @@ o2physics_add_dpl_workflow(angular-correlations-in-jets o2physics_add_dpl_workflow(antinuclei-in-jets SOURCES antinucleiInJets.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::PWGJECore FastJet::FastJet FastJet::Contrib + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::EventFilteringUtils O2Physics::PWGJECore FastJet::FastJet FastJet::Contrib COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(kink-pika @@ -150,4 +150,9 @@ o2physics_add_dpl_workflow(he3-lambda-derived-analysis PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(dedx-pid-analysis + SOURCES dedxPidAnalysis.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + endif() diff --git a/PWGLF/Tasks/Nuspex/LFNucleiBATask.cxx b/PWGLF/Tasks/Nuspex/LFNucleiBATask.cxx index 8e5f159d331..288c5fecf21 100644 --- a/PWGLF/Tasks/Nuspex/LFNucleiBATask.cxx +++ b/PWGLF/Tasks/Nuspex/LFNucleiBATask.cxx @@ -466,6 +466,7 @@ struct LFNucleiBATask { // DCAxy,z if (outFlagOptions.makeDCABeforeCutPlots) { histos.add("tracks/dca/before/hDCAxyVsDCAzVsPt", "DCAxy vs DCAz vs Pt/z; DCAxy; DCAz", HistType::kTH3F, {{140, -0.7f, 0.7f}, {160, -0.8f, 0.8f}, {binsPtHe}}); + histos.add("tracks/dca/before/hDCAxyVsDCAz", "DCAxy vs DCAz (before cuts)", HistType::kTH2F, {{550, -1.1, 1.1}, {550, -1.1, 1.1}}); histos.add("tracks/dca/before/hDCAxy", "DCAxy", HistType::kTH1F, {dcaxyAxis}); histos.add("tracks/dca/before/hDCAz", "DCAz", HistType::kTH1F, {dcazAxis}); @@ -505,6 +506,9 @@ struct LFNucleiBATask { if (enableHe) { histos.add("tracks/helium/dca/before/hDCAxyVsDCAzVsPtHelium", "DCAxy vs DCAz vs Pt/z (He); DCAxy; DCAz", HistType::kTH3F, {{140, -0.7f, 0.7f}, {160, -0.8f, 0.8f}, {binsPtZHe}}); histos.add("tracks/helium/dca/before/hDCAxyVsDCAzVsPtantiHelium", "DCAxy vs DCAz vs Pt/z (#bar{He}); DCAxy; DCAz", HistType::kTH3F, {{140, -0.7f, 0.7f}, {160, -0.8f, 0.8f}, {binsPtZHe}}); + histos.add("tracks/helium/dca/before/h3DCAvsPtHelium", "", HistType::kTHnSparseD, {dcaxyAxis, dcazAxis, ptZHeAxis}); + histos.add("tracks/helium/dca/before/h3DCAvsPtantiHelium", "", HistType::kTHnSparseD, {dcaxyAxis, dcazAxis, ptZHeAxis}); + histos.add("tracks/helium/dca/before/hDCAxyVsPtHelium", "DCAxy vs Pt (He)", HistType::kTH2F, {{ptZHeAxis}, {dcaxyAxis}}); histos.add("tracks/helium/dca/before/hDCAxyVsPtantiHelium", "DCAxy vs Pt (#bar{He})", HistType::kTH2F, {{ptZHeAxis}, {dcaxyAxis}}); histos.add("tracks/helium/dca/before/hDCAzVsPtHelium", "DCAz vs Pt (He)", HistType::kTH2F, {{ptZHeAxis}, {dcazAxis}}); @@ -561,6 +565,8 @@ struct LFNucleiBATask { if (enableHe && outFlagOptions.makeDCAAfterCutPlots) { histos.add("tracks/helium/dca/after/hDCAxyVsDCAzVsPtHelium", "DCAxy vs DCAz vs Pt/z (He); DCAxy; DCAz", HistType::kTH3F, {{140, -0.7f, 0.7f}, {160, -0.8f, 0.8f}, {binsPtZHe}}); histos.add("tracks/helium/dca/after/hDCAxyVsDCAzVsPtantiHelium", "DCAxy vs DCAz vs Pt/z (#bar{He}); DCAxy; DCAz", HistType::kTH3F, {{140, -0.7f, 0.7f}, {160, -0.8f, 0.8f}, {binsPtZHe}}); + histos.add("tracks/helium/dca/after/h3DCAvsPtHelium", "", HistType::kTHnSparseD, {dcaxyAxis, dcazAxis, ptZHeAxis}); + histos.add("tracks/helium/dca/after/h3DCAvsPtantiHelium", "", HistType::kTHnSparseD, {dcaxyAxis, dcazAxis, ptZHeAxis}); histos.add("tracks/helium/dca/after/hDCAxyVsPtHelium", "DCAxy vs Pt (He)", HistType::kTH2F, {{ptZHeAxis}, {dcaxyAxis}}); histos.add("tracks/helium/dca/after/hDCAxyVsPtantiHelium", "DCAxy vs Pt (#bar{He})", HistType::kTH2F, {{ptZHeAxis}, {dcaxyAxis}}); histos.add("tracks/helium/dca/after/hDCAzVsPtHelium", "DCAz vs Pt (He)", HistType::kTH2F, {{ptZHeAxis}, {dcazAxis}}); @@ -2531,12 +2537,14 @@ struct LFNucleiBATask { if (isHe && std::abs(track.tpcNSigmaHe()) < nsigmaTPCvar.nsigmaTPCHe) { histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsDCAzVsPtHelium"), track.dcaXY(), track.dcaZ(), hePt); + histos.fill(HIST("tracks/helium/dca/before/h3DCAvsPtHelium"), track.dcaXY(), track.dcaZ(), hePt); if (track.hasTOF() && outFlagOptions.doTOFplots) { histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsDCAzVsPtHelium"), track.dcaXY(), track.dcaZ(), hePt); } } if (isAntiHe && std::abs(track.tpcNSigmaHe()) < nsigmaTPCvar.nsigmaTPCHe) { histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsDCAzVsPtantiHelium"), track.dcaXY(), track.dcaZ(), antihePt); + histos.fill(HIST("tracks/helium/dca/before/h3DCAvsPtantiHelium"), track.dcaXY(), track.dcaZ(), antihePt); if (track.hasTOF() && outFlagOptions.doTOFplots) { histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsDCAzVsPtantiHelium"), track.dcaXY(), track.dcaZ(), antihePt); } @@ -3697,12 +3705,14 @@ struct LFNucleiBATask { if (isHeWTPCpid) { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsDCAzVsPtHelium"), track.dcaXY(), track.dcaZ(), hePt); + histos.fill(HIST("tracks/helium/dca/after/h3DCAvsPtHelium"), track.dcaXY(), track.dcaZ(), hePt); if (track.hasTOF() && outFlagOptions.doTOFplots) { histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsDCAzVsPtHelium"), track.dcaXY(), track.dcaZ(), hePt); } } if (isAntiHeWTPCpid) { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsDCAzVsPtantiHelium"), track.dcaXY(), track.dcaZ(), antihePt); + histos.fill(HIST("tracks/helium/dca/after/h3DCAvsPtantiHelium"), track.dcaXY(), track.dcaZ(), antihePt); if (track.hasTOF() && outFlagOptions.doTOFplots) { histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsDCAzVsPtantiHelium"), track.dcaXY(), track.dcaZ(), antihePt); } diff --git a/PWGLF/Tasks/Nuspex/antinucleiInJets.cxx b/PWGLF/Tasks/Nuspex/antinucleiInJets.cxx index b4509b40f28..c710fce3735 100644 --- a/PWGLF/Tasks/Nuspex/antinucleiInJets.cxx +++ b/PWGLF/Tasks/Nuspex/antinucleiInJets.cxx @@ -22,11 +22,13 @@ #include "Common/Core/TrackSelection.h" #include "Common/Core/trackUtilities.h" -#include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/PIDResponse.h" #include "Common/DataModel/PIDResponseITS.h" #include "Common/DataModel/TrackSelectionTables.h" +#include "EventFiltering/Zorro.h" +#include "EventFiltering/ZorroSummary.h" #include "CCDB/BasicCCDBManager.h" #include "CCDB/CcdbApi.h" @@ -75,36 +77,49 @@ using namespace o2::constants::physics; using namespace o2::constants::math; using std::array; -using SelectedCollisions = soa::Join; -using SimCollisions = soa::Join; -using GenCollisions = aod::McCollisions; - -using FullNucleiTracks = soa::Join; - -using MCTracks = soa::Join; +// Define convenient aliases for commonly used table joins +using SelectedCollisions = soa::Join; +using RecCollisionsMc = soa::Join; +using GenCollisionsMc = aod::McCollisions; +using AntiNucleiTracks = soa::Join; +using AntiNucleiTracksMc = soa::Join; struct AntinucleiInJets { - // histogram registries + // Histogram registries for data, MC, quality control, multiplicity and correlations HistogramRegistry registryData{"registryData", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; HistogramRegistry registryMC{"registryMC", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; HistogramRegistry registryQC{"registryQC", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; HistogramRegistry registryMult{"registryMult", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - - // global parameters - Configurable minJetPt{"minJetPt", 10.0, "Minimum pt of the jet"}; + HistogramRegistry registryCorr{"registryCorr", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + // Event selection criteria + Configurable rejectITSROFBorder{"rejectITSROFBorder", true, "Reject events near the ITS ROF border"}; + Configurable rejectTFBorder{"rejectTFBorder", true, "Reject events near the TF border"}; + Configurable requireVtxITSTPC{"requireVtxITSTPC", true, "Require at least one ITS-TPC matched track"}; + Configurable rejectSameBunchPileup{"rejectSameBunchPileup", true, "Reject events with same-bunch pileup collisions"}; + Configurable requireIsGoodZvtxFT0VsPV{"requireIsGoodZvtxFT0VsPV", true, "Require consistent FT0 vs PV z-vertex"}; + Configurable requireIsVertexTOFmatched{"requireIsVertexTOFmatched", false, "Require at least one vertex track matched to TOF"}; + + // Skimmed data flag and list of active triggers for processing + Configurable cfgSkimmedProcessing{"cfgSkimmedProcessing", false, "Skimmed dataset processing"}; + Configurable triggerList{"triggerList", "fHe", "Trigger list"}; + + // Jet selection and event filtering parameters + Configurable minJetPt{"minJetPt", 10.0, "Minimum pt of the jet after bkg subtraction"}; Configurable ptLeadingMin{"ptLeadingMin", 5.0, "pt Leading Min"}; Configurable rJet{"rJet", 0.3, "Jet resolution parameter R"}; Configurable zVtx{"zVtx", 10.0, "Maximum zVertex"}; + Configurable applyAreaCut{"applyAreaCut", false, "apply area cut"}; + Configurable maxNormalizedJetArea{"maxNormalizedJetArea", 0.6, "area cut"}; Configurable deltaEtaEdge{"deltaEtaEdge", 0.05, "eta gap from the edge"}; + Configurable nSyst{"nSyst", 50, "number of systematic variations"}; - // track parameters + // Track quality, kinematic, and PID selection parameters Configurable requirePvContributor{"requirePvContributor", false, "require that the track is a PV contributor"}; Configurable applyItsPid{"applyItsPid", true, "apply ITS PID"}; - Configurable rejectEvents{"rejectEvents", false, "reject some events"}; - Configurable rejectionPercentage{"rejectionPercentage", 3, "percentage of events to reject"}; Configurable minItsNclusters{"minItsNclusters", 5, "minimum number of ITS clusters"}; - Configurable minTpcNcrossedRows{"minTpcNcrossedRows", 80, "minimum number of TPC crossed pad rows"}; + Configurable minTpcNcrossedRows{"minTpcNcrossedRows", 100, "minimum number of TPC crossed pad rows"}; Configurable maxChiSquareTpc{"maxChiSquareTpc", 4.0, "maximum TPC chi^2/Ncls"}; Configurable maxChiSquareIts{"maxChiSquareIts", 36.0, "maximum ITS chi^2/Ncls"}; Configurable minPt{"minPt", 0.3, "minimum pt of the tracks"}; @@ -119,51 +134,53 @@ struct AntinucleiInJets { Configurable ptMaxItsPidProt{"ptMaxItsPidProt", 1.0, "maximum pt for ITS PID for protons"}; Configurable ptMaxItsPidDeut{"ptMaxItsPidDeut", 1.0, "maximum pt for ITS PID for deuterons"}; Configurable ptMaxItsPidHel{"ptMaxItsPidHel", 1.0, "maximum pt for ITS PID for helium"}; - Configurable nSigmaItsMin{"nSigmaItsMin", -2.0, "nSigmaITS min"}; - Configurable nSigmaItsMax{"nSigmaItsMax", +2.0, "nSigmaITS max"}; - - // reweighting - Configurable urlToCcdb{"urlToCcdb", "http://alice-ccdb.cern.ch", "url of the personal ccdb"}; - Configurable pathToFile{"pathToFile", "", "path to file with reweighting"}; - Configurable histoNameWeightAntipJet{"histoNameWeightAntipJet", "", "reweighting histogram: antip in jet"}; - Configurable histoNameWeightAntipUe{"histoNameWeightAntipUe", "", "reweighting histogram: antip in ue"}; - TH2F* twoDweightsAntipJet; - TH2F* twoDweightsAntipUe; - - // jet pt unfolding - Configurable applyPtUnfolding{"applyPtUnfolding", true, "apply jet pt unfolding"}; - Configurable urlToCcdbPtUnfolding{"urlToCcdbPtUnfolding", "http://alice-ccdb.cern.ch", "url of the personal ccdb"}; - Configurable pathToFilePtUnfolding{"pathToFilePtUnfolding", "Users/c/chpinto/My/Object/ResponseMatrix", "path to file with pt unfolding"}; - Configurable histoNamePtUnfolding{"histoNamePtUnfolding", "detectorResponseMatrix", "pt unfolding histogram"}; - TH2F* responseMatrix; + Configurable nSigmaItsMin{"nSigmaItsMin", -3.0, "nSigmaITS min"}; + Configurable nSigmaItsMax{"nSigmaItsMax", +3.0, "nSigmaITS max"}; + Configurable setMCDefaultItsParams{"setMCDefaultItsParams", false, "set MC default parameters"}; + // CCDB manager service for accessing condition data Service ccdb; + + // Direct interface to the CCDB API for manual data access o2::ccdb::CcdbApi ccdbApi; + // Instantiate the main Zorro processing object and define an output to store summary information + Zorro zorro; + OutputObj zorroSummary{"zorroSummary"}; + + // Utility object for jet background subtraction methods JetBkgSubUtils backgroundSub; + // Initialize ITS PID Response object + o2::aod::ITSResponse itsResponse; + + // Initialize CCDB access and histogram registry for Zorro processing + void initCCDB(aod::BCsWithTimestamps::iterator const& bc) + { + if (cfgSkimmedProcessing) { + zorro.initCCDB(ccdb.service, bc.runNumber(), bc.timestamp(), triggerList); + zorro.populateHistRegistry(registryData, bc.runNumber()); + } + } + void init(InitContext const&) { - ccdb->setURL(urlToCcdb.value); - ccdb->setCaching(true); - ccdb->setLocalObjectValidityChecking(); - ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); - ccdb->setFatalWhenNull(false); - - getReweightingHistograms(ccdb, TString(pathToFile), TString(histoNameWeightAntipJet), TString(histoNameWeightAntipUe)); - - if (applyPtUnfolding) { - getPtUnfoldingHistogram(ccdb, TString(pathToFilePtUnfolding), TString(histoNamePtUnfolding)); - } else { - responseMatrix = nullptr; + // Set summary object if processing skimmed data + if (cfgSkimmedProcessing) { + zorroSummary.setObject(zorro.getZorroSummary()); + } + + // Set default MC parametrization for ITS response + if (setMCDefaultItsParams) { + itsResponse.setMCDefaultParameters(); } - // binning + // Binning double min = 0.0; double max = 6.0; int nbins = 120; - // QC histograms + // Quality control histograms for jet/UE topology and multiplicity if (doprocessQC) { registryQC.add("deltaEta_deltaPhi_jet", "deltaEta_deltaPhi_jet", HistType::kTH2F, {{200, -0.5, 0.5, "#Delta#eta"}, {200, 0, PIHalf, "#Delta#phi"}}); registryQC.add("deltaEta_deltaPhi_ue", "deltaEta_deltaPhi_ue", HistType::kTH2F, {{200, -0.5, 0.5, "#Delta#eta"}, {200, 0, PIHalf, "#Delta#phi"}}); @@ -179,151 +196,224 @@ struct AntinucleiInJets { registryQC.add("nJetsInAcceptance", "nJetsInAcceptance", HistType::kTH1F, {{50, 0, 50, "#it{n}_{Jet}"}}); registryQC.add("nJetsSelectedHighPt", "nJetsSelectedHighPt", HistType::kTH1F, {{50, 0, 50, "#it{n}_{Jet}"}}); registryQC.add("jetPtDifference", "jetPtDifference", HistType::kTH1F, {{200, -1, 1, "#Deltap_{T}^{jet}"}}); + registryQC.add("ptDistributionJetCone", "ptDistributionJetCone", HistType::kTH1F, {{2000, 0, 200, "#it{p}_{T} (GeV/#it{c})"}}); + registryQC.add("ptDistributionJet", "ptDistributionJet", HistType::kTH1F, {{2000, 0, 200, "#it{p}_{T} (GeV/#it{c})"}}); } + // Multiplicity histograms: check charged-particle multiplicity in events with selected jets (Run 3) or ptTrigger > threshold (Run 2-like) if (doprocessMultEvents) { registryMult.add("multiplicityEvtsPtLeading", "multiplicityEvtsPtLeading", HistType::kTH1F, {{1000, 0, 1000, "#it{N}_{ch}"}}); registryMult.add("multiplicityEvtsWithJet", "multiplicityEvtsWithJet", HistType::kTH1F, {{1000, 0, 1000, "#it{N}_{ch}"}}); } - // data histograms + // Histograms for real data if (doprocessData) { - // event counter data - registryData.add("number_of_events_data", "number of events in data", HistType::kTH1F, {{10, 0, 10, "counter"}}); - registryData.add("number_of_rejected_events", "check on number of events rejected", HistType::kTH1F, {{10, 0, 10, "counter"}}); + // Event counters + registryData.add("number_of_events_data", "number of events in data", HistType::kTH1F, {{20, 0, 20, "counter"}}); - // Jet Area - registryData.add("jetEffectiveArea", "jetEffectiveArea", HistType::kTH1F, {{2000, 0, 2, "Area/#piR^{2}"}}); - registryData.add("ptDistributionJet", "ptDistributionJet", HistType::kTH1F, {{2000, 0, 200, "#it{p}_{T} (GeV/#it{c})"}}); + // Jet effective area over piR^2 + registryData.add("jetEffectiveAreaOverPiR2", "jet effective area / piR^2", HistType::kTH1F, {{2000, 0, 2, "Area/#piR^{2}"}}); - // antiprotons + // Antiprotons registryData.add("antiproton_jet_tpc", "antiproton_jet_tpc", HistType::kTH2F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); registryData.add("antiproton_jet_tof", "antiproton_jet_tof", HistType::kTH2F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TOF}"}}); registryData.add("antiproton_ue_tpc", "antiproton_ue_tpc", HistType::kTH2F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); registryData.add("antiproton_ue_tof", "antiproton_ue_tof", HistType::kTH2F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TOF}"}}); - registryData.add("antiproton_dca_jet", "antiproton_dca_jet", HistType::kTH2F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {200, -1, 1, "DCA_{xy} (cm)"}}); - registryData.add("antiproton_dca_ue", "antiproton_dca_ue", HistType::kTH2F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {200, -1, 1, "DCA_{xy} (cm)"}}); - - // antideuterons - registryData.add("antideuteron_jet_tpc", "antideuteron_jet_tpc", HistType::kTH2F, {{nbins, min * 2, max * 2, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); - registryData.add("antideuteron_jet_tof", "antideuteron_jet_tof", HistType::kTH2F, {{nbins, min * 2, max * 2, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TOF}"}}); - registryData.add("antideuteron_ue_tpc", "antideuteron_ue_tpc", HistType::kTH2F, {{nbins, min * 2, max * 2, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); - registryData.add("antideuteron_ue_tof", "antideuteron_ue_tof", HistType::kTH2F, {{nbins, min * 2, max * 2, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TOF}"}}); - - // deuterons - registryData.add("deuteron_jet_tof", "deuteron_jet_tof", HistType::kTH2F, {{nbins, min * 2, max * 2, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TOF}"}}); - registryData.add("deuteron_ue_tof", "deuteron_ue_tof", HistType::kTH2F, {{nbins, min * 2, max * 2, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TOF}"}}); - - // antihelium-3 - registryData.add("antihelium3_jet_tpc", "antihelium3_jet_tpc", HistType::kTH2F, {{nbins, min * 3, max * 3, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); - registryData.add("antihelium3_ue_tpc", "antihelium3_ue_tpc", HistType::kTH2F, {{nbins, min * 3, max * 3, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); - - // helium-3 - registryData.add("helium3_jet_tpc", "helium3_jet_tpc", HistType::kTH2F, {{nbins, min * 3, max * 3, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); - registryData.add("helium3_ue_tpc", "helium3_ue_tpc", HistType::kTH2F, {{nbins, min * 3, max * 3, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); + registryData.add("antiproton_dca_jet", "antiproton_dca_jet", HistType::kTH2F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {200, -1.0, 1.0, "DCA_{xy} (cm)"}}); + registryData.add("antiproton_dca_ue", "antiproton_dca_ue", HistType::kTH2F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {200, -1.0, 1.0, "DCA_{xy} (cm)"}}); + + // Antideuterons + registryData.add("antideuteron_jet_tpc", "antideuteron_jet_tpc", HistType::kTH2F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); + registryData.add("antideuteron_jet_tof", "antideuteron_jet_tof", HistType::kTH2F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TOF}"}}); + registryData.add("antideuteron_ue_tpc", "antideuteron_ue_tpc", HistType::kTH2F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); + registryData.add("antideuteron_ue_tof", "antideuteron_ue_tof", HistType::kTH2F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TOF}"}}); + + // Deuterons + registryData.add("deuteron_jet_tpc", "deuteron_jet_tpc", HistType::kTH2F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); + registryData.add("deuteron_jet_tof", "deuteron_jet_tof", HistType::kTH2F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TOF}"}}); + registryData.add("deuteron_ue_tpc", "deuteron_ue_tpc", HistType::kTH2F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); + registryData.add("deuteron_ue_tof", "deuteron_ue_tof", HistType::kTH2F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TOF}"}}); + + // Antihelium-3 + registryData.add("antihelium3_jet_tpc", "antihelium3_jet_tpc", HistType::kTH2F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); + registryData.add("antihelium3_ue_tpc", "antihelium3_ue_tpc", HistType::kTH2F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); + + // Helium-3 + registryData.add("helium3_jet_tpc", "helium3_jet_tpc", HistType::kTH2F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); + registryData.add("helium3_ue_tpc", "helium3_ue_tpc", HistType::kTH2F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); + + // nsigmaITS for antiproton candidates + registryData.add("antiproton_nsigma_its_data", "antiproton_nsigma_its_data", HistType::kTH2F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{ITS}"}}); + } + + // Generated antiproton spectra in jets and UE from MC truth + if (doprocessJetsMCgen) { + + // Event counter + registryMC.add("genEvents", "number of generated events in mc", HistType::kTH1F, {{10, 0, 10, "counter"}}); + + // Generated spectra of antiprotons + registryMC.add("antiproton_gen_jet", "antiproton_gen_jet", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antiproton_gen_ue", "antiproton_gen_ue", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); } - // monte carlo histograms - if (doprocessEfficiency) { - - // event counter MC - registryMC.add("number_of_events_mc", "number of events in mc", HistType::kTH1F, {{10, 0, 10, "counter"}}); - - // generated spectra (antiprotons) - registryMC.add("antiproton_gen_jet_unweighted", "antiproton_gen_jet_unweighted", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_gen_ue_unweighted", "antiproton_gen_ue_unweighted", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_gen_jet_weighted2d", "antiproton_gen_jet_weighted2d", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_gen_ue_weighted2d", "antiproton_gen_ue_weighted2d", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_gen_jet_weightedFinal", "antiproton_gen_jet_weightedFinal", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_gen_ue_weightedFinal", "antiproton_gen_ue_weightedFinal", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_gen_jet_antikt", "antiproton_gen_jet_antikt", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_gen_ue_antikt", "antiproton_gen_ue_antikt", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - - // generated spectra (antinuclei) - registryMC.add("deuteron_incl_gen", "deuteron_incl_gen", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antideuteron_incl_gen", "antideuteron_incl_gen", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("helium3_incl_gen", "helium3_incl_gen", HistType::kTH1F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antihelium3_incl_gen", "antihelium3_incl_gen", HistType::kTH1F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}}); - - // reconstructed TPC (antiprotons) - registryMC.add("antiproton_recTpc_jet_unweighted", "antiproton_recTpc_jet_unweighted", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_recTpc_ue_unweighted", "antiproton_recTpc_ue_unweighted", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_recTpc_jet_weighted2d", "antiproton_recTpc_jet_weighted2d", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_recTpc_ue_weighted2d", "antiproton_recTpc_ue_weighted2d", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_recTpc_jet_weightedFinal", "antiproton_recTpc_jet_weightedFinal", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_recTpc_ue_weightedFinal", "antiproton_recTpc_ue_weightedFinal", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_recTpc_jet_antikt", "antiproton_recTpc_jet_antikt", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_recTpc_ue_antikt", "antiproton_recTpc_ue_antikt", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - - // reconstructed TPC (antinuclei) - registryMC.add("antideuteron_incl_rec_tpc", "antideuteron_incl_rec_tpc", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("deuteron_incl_rec_tpc", "deuteron_incl_rec_tpc", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antihelium3_incl_rec_tpc", "antihelium3_incl_rec_tpc", HistType::kTH1F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("helium3_incl_rec_tpc", "helium3_incl_rec_tpc", HistType::kTH1F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}}); - - // reconstructed TOF (antiprotons) - registryMC.add("antiproton_recTof_jet_unweighted", "antiproton_recTof_jet_unweighted", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_recTof_ue_unweighted", "antiproton_recTof_ue_unweighted", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_recTof_jet_weighted2d", "antiproton_recTof_jet_weighted2d", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_recTof_ue_weighted2d", "antiproton_recTof_ue_weighted2d", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_recTof_jet_weightedFinal", "antiproton_recTof_jet_weightedFinal", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_recTof_ue_weightedFinal", "antiproton_recTof_ue_weightedFinal", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_recTof_jet_antikt", "antiproton_recTof_jet_antikt", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_recTof_ue_antikt", "antiproton_recTof_ue_antikt", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - - // reconstructed TOF (antinuclei) - registryMC.add("antideuteron_incl_rec_tof", "antideuteron_incl_rec_tof", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("deuteron_incl_rec_tof", "deuteron_incl_rec_tof", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); - - // fraction of primary antiprotons from MC (all unweighted for now) + // Reconstructed antiproton spectra in jets and UE (MC-matched) with TPC/TOF PID + if (doprocessJetsMCrec) { + + // Event counter + registryMC.add("recEvents", "number of reconstructed events in mc", HistType::kTH1F, {{20, 0, 20, "counter"}}); + + // Reconstructed spectra of antiprotons + registryMC.add("antiproton_rec_tpc_jet", "antiproton_rec_tpc_jet", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antiproton_rec_tof_jet", "antiproton_rec_tof_jet", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antiproton_rec_tpc_ue", "antiproton_rec_tpc_ue", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antiproton_rec_tof_ue", "antiproton_rec_tof_ue", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + + // Fraction of primary antiprotons registryMC.add("antiproton_prim_jet", "antiproton_prim_jet", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); registryMC.add("antiproton_incl_jet", "antiproton_incl_jet", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); registryMC.add("antiproton_prim_ue", "antiproton_prim_ue", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); registryMC.add("antiproton_incl_ue", "antiproton_incl_ue", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - // DCA Templates + // DCA templates registryMC.add("antiproton_prim_dca_jet", "antiproton_prim_dca_jet", HistType::kTH2F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {200, -1, 1, "DCA_{xy} (cm)"}}); registryMC.add("antiproton_prim_dca_ue", "antiproton_prim_dca_ue", HistType::kTH2F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {200, -1, 1, "DCA_{xy} (cm)"}}); registryMC.add("antiproton_all_dca_jet", "antiproton_all_dca_jet", HistType::kTH2F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {200, -1, 1, "DCA_{xy} (cm)"}}); registryMC.add("antiproton_all_dca_ue", "antiproton_all_dca_ue", HistType::kTH2F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {200, -1, 1, "DCA_{xy} (cm)"}}); - // antiproton reweighting - registryMC.add("antiproton_eta_pt_pythia", "antiproton_eta_pt_pythia", HistType::kTH2F, {{200, 0.0, 10.0, "#it{p}_{T} (GeV/#it{c})"}, {20, -1.0, 1.0, "#it{#eta}"}}); - registryMC.add("antiproton_eta_pt_jet", "antiproton_eta_pt_jet", HistType::kTH2F, {{200, 0.0, 10.0, "#it{p}_{T} (GeV/#it{c})"}, {20, -1.0, 1.0, "#it{#eta}"}}); - registryMC.add("antiproton_eta_pt_ue", "antiproton_eta_pt_ue", HistType::kTH2F, {{200, 0.0, 10.0, "#it{p}_{T} (GeV/#it{c})"}, {20, -1.0, 1.0, "#it{#eta}"}}); - registryMC.add("antiproton_forReweighting_jet_weighted2d", "antiproton_forReweighting_jet_weighted2d", HistType::kTH1F, {{5000, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_forReweighting_ue_weighted2d", "antiproton_forReweighting_ue_weighted2d", HistType::kTH1F, {{5000, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_forReweighting_jet_weightedFinal", "antiproton_forReweighting_jet_weightedFinal", HistType::kTH1F, {{5000, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_forReweighting_ue_weightedFinal", "antiproton_forReweighting_ue_weightedFinal", HistType::kTH1F, {{5000, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}}); + // nsigmaITS for antiproton candidates + registryMC.add("antiproton_nsigma_its_mc", "antiproton_nsigma_its_mc", HistType::kTH2F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{ITS}"}}); + + // nsigmaTOF for antiprotons + registryMC.add("antiproton_nsigma_tof_jet_mc", "antiproton_nsigma_tof_jet_mc", HistType::kTH2F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TOF}"}}); } - if (doprocessJetsMCrec) { - // detector response matrix - registryMC.add("detectorResponseMatrix", "detectorResponseMatrix", HistType::kTH2F, {{1000, 0.0, 100.0, "#it{p}_{T}^{rec} (GeV/#it{c})"}, {2000, -20.0, 20.0, "#it{p}_{T}^{gen} - #it{p}_{T}^{rec} (GeV/#it{c})"}}); - registryMC.add("generatedVsReconstructedPt", "generatedVsReconstructedPt", HistType::kTH2F, {{1000, 0.0, 100.0, "#it{p}_{T}^{rec} (GeV/#it{c})"}, {1000, 0.0, 100.0, "#it{p}_{T}^{gen} (GeV/#it{c})"}}); + // Efficiency of antinuclei + if (doprocessAntinucleiEfficiency) { + + // Event counter MC + registryMC.add("number_of_events_mc_nuclei_efficiency", "number of events in mc", HistType::kTH1F, {{20, 0, 20, "counter"}}); + + // Generated spectra of (anti)protons + registryMC.add("antip_gen_jet", "antip_gen_jet", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antip_gen_ue", "antip_gen_ue", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + + // Generated spectra of (anti)deuterons + registryMC.add("deuteron_gen_jet", "deuteron_gen_jet", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("deuteron_gen_ue", "deuteron_gen_ue", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_gen_jet", "antideuteron_gen_jet", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_gen_ue", "antideuteron_gen_ue", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + + // Generated spectra of (anti)helium3 + registryMC.add("helium3_gen_jet", "helium3_gen_jet", HistType::kTH1F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("helium3_gen_ue", "helium3_gen_ue", HistType::kTH1F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antihelium3_gen_jet", "antihelium3_gen_jet", HistType::kTH1F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antihelium3_gen_ue", "antihelium3_gen_ue", HistType::kTH1F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}}); + + // Reconstructed spectra of antiprotons + registryMC.add("antip_rec_tpc_jet", "antip_rec_tpc_jet", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antip_rec_tof_jet", "antip_rec_tof_jet", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antip_rec_tpc_ue", "antip_rec_tpc_ue", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antip_rec_tof_ue", "antip_rec_tof_ue", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + + // Reconstructed spectra of (anti)deuterons + registryMC.add("deuteron_rec_tpc_jet", "deuteron_rec_tpc_jet", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("deuteron_rec_tof_jet", "deuteron_rec_tof_jet", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("deuteron_rec_tpc_ue", "deuteron_rec_tpc_ue", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("deuteron_rec_tof_ue", "deuteron_rec_tof_ue", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_rec_tpc_jet", "antideuteron_rec_tpc_jet", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_rec_tof_jet", "antideuteron_rec_tof_jet", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_rec_tpc_ue", "antideuteron_rec_tpc_ue", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_rec_tof_ue", "antideuteron_rec_tof_ue", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + + // Reconstructed spectra of (anti)helium3 + registryMC.add("helium3_rec_tpc_jet", "helium3_rec_tpc_jet", HistType::kTH1F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("helium3_rec_tpc_ue", "helium3_rec_tpc_ue", HistType::kTH1F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antihelium3_rec_tpc_jet", "antihelium3_rec_tpc_jet", HistType::kTH1F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antihelium3_rec_tpc_ue", "antihelium3_rec_tpc_ue", HistType::kTH1F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}}); + } + + // Systematic uncertainties (Data) + if (doprocessSystData) { + registryData.add("number_of_events_data_syst", "event counter", HistType::kTH1F, {{20, 0, 20, "counter"}}); + + registryData.add("antiproton_tpc_syst", "antiproton_tpc_syst", HistType::kTH3F, {{50, 0, 50, "systematic uncertainty"}, {nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); + registryData.add("antiproton_tof_syst", "antiproton_tof_syst", HistType::kTH3F, {{50, 0, 50, "systematic uncertainty"}, {nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TOF}"}}); + registryData.add("antideuteron_tpc_syst", "antideuteron_tpc_syst", HistType::kTH3F, {{50, 0, 50, "systematic uncertainty"}, {nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); + registryData.add("antideuteron_tof_syst", "antideuteron_tof_syst", HistType::kTH3F, {{50, 0, 50, "systematic uncertainty"}, {nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TOF}"}}); + registryData.add("antihelium3_tpc_syst", "antihelium3_tpc_syst", HistType::kTH3F, {{50, 0, 50, "systematic uncertainty"}, {nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}}); } - // systematic uncertainties - if (doprocessSystematicsData) { - registryData.add("number_of_rejected_events_syst", "check on number of events rejected", HistType::kTH1F, {{10, 0, 10, "counter"}}); - registryData.add("antiproton_tpc_syst", "antiproton_tpc_syst", HistType::kTHnSparseF, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}, {10, 0, 10, "systematic uncertainty"}}); - registryData.add("antiproton_tof_syst", "antiproton_tof_syst", HistType::kTHnSparseF, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TOF}"}, {10, 0, 10, "systematic uncertainty"}}); - registryData.add("antideuteron_tpc_syst", "antideuteron_tpc_syst", HistType::kTHnSparseF, {{nbins, min * 2, max * 2, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TPC}"}, {10, 0, 10, "systematic uncertainty"}}); - registryData.add("antideuteron_tof_syst", "antideuteron_tof_syst", HistType::kTHnSparseF, {{nbins, min * 2, max * 2, "#it{p}_{T} (GeV/#it{c})"}, {400, -20.0, 20.0, "n#sigma_{TOF}"}, {10, 0, 10, "systematic uncertainty"}}); + // Systematic uncertainties (MC) + if (doprocessSystEff) { + + // Histograms for generated antiparticles + registryMC.add("antiproton_gen_syst", "antiproton_gen_syst", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_gen_syst", "antideuteron_gen_syst", HistType::kTH1F, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antihelium3_gen_syst", "antihelium3_gen_syst", HistType::kTH1F, {{nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}}); + + // Histograms for reconstructed antiparticles + registryMC.add("antiproton_rec_tpc_syst", "antiproton_rec_tpc_syst", HistType::kTH2F, {{50, 0, 50, "systematic uncertainty"}, {nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antiproton_rec_tof_syst", "antiproton_rec_tof_syst", HistType::kTH2F, {{50, 0, 50, "systematic uncertainty"}, {nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_rec_tpc_syst", "antideuteron_rec_tpc_syst", HistType::kTH2F, {{50, 0, 50, "systematic uncertainty"}, {nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antideuteron_rec_tof_syst", "antideuteron_rec_tof_syst", HistType::kTH2F, {{50, 0, 50, "systematic uncertainty"}, {nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antihelium3_rec_tpc_syst", "antihelium3_rec_tpc_syst", HistType::kTH2F, {{50, 0, 50, "systematic uncertainty"}, {nbins, 3 * min, 3 * max, "#it{p}_{T} (GeV/#it{c})"}}); + + // Histograms for primary antiprotons + registryMC.add("antiproton_incl_syst", "antiproton_incl_syst", HistType::kTH2F, {{50, 0, 50, "systematic uncertainty"}, {nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); + registryMC.add("antiproton_prim_syst", "antiproton_prim_syst", HistType::kTH2F, {{50, 0, 50, "systematic uncertainty"}, {nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); } - if (doprocessSystematicsEfficiency) { - registryMC.add("antiproton_incl_gen_syst", "antiproton_incl_gen_syst", HistType::kTH1F, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antideuteron_incl_gen_syst", "antideuteron_incl_gen_syst", HistType::kTH1F, {{nbins, min * 2, max * 2, "#it{p}_{T} (GeV/#it{c})"}}); - registryMC.add("antiproton_incl_prim_syst", "antiproton_incl_prim_syst", HistType::kTHnSparseF, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {10, 0, 10, "systematic uncertainty"}}); - registryMC.add("antiproton_incl_rec_tpc_syst", "antiproton_incl_rec_tpc_syst", HistType::kTHnSparseF, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {10, 0, 10, "systematic uncertainty"}}); - registryMC.add("antiproton_incl_rec_tof_syst", "antiproton_incl_rec_tof_syst", HistType::kTHnSparseF, {{nbins, min, max, "#it{p}_{T} (GeV/#it{c})"}, {10, 0, 10, "systematic uncertainty"}}); - registryMC.add("antideuteron_incl_rec_tpc_syst", "antideuteron_incl_rec_tpc_syst", HistType::kTHnSparseF, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}, {10, 0, 10, "systematic uncertainty"}}); - registryMC.add("antideuteron_incl_rec_tof_syst", "antideuteron_incl_rec_tof_syst", HistType::kTHnSparseF, {{nbins, 2 * min, 2 * max, "#it{p}_{T} (GeV/#it{c})"}, {10, 0, 10, "systematic uncertainty"}}); + // Correlation analysis + if (doprocessCorr) { + + // Axes definitions for multidimensional histogram binning + const AxisSpec multiplicityAxis{100, 0.0, 100.0, "multiplicity percentile"}; + const AxisSpec ptPerNucleonAxis{5, 0.4, 0.9, "{p}_{T}/A (GeV/#it{c})"}; + const AxisSpec nAntideuteronsAxis{10, 0.0, 10.0, "N_{#bar{d}}"}; + const AxisSpec nAntiprotonsAxis{10, 0.0, 10.0, "N_{#bar{p}}"}; + const AxisSpec nBarD2Axis{100, 0.0, 100.0, "N_{#bar{d}}^{i} #times N_{#bar{d}}^{j}"}; + const AxisSpec nBarP2Axis{100, 0.0, 100.0, "N_{#bar{p}}^{i} #times N_{#bar{p}}^{j}"}; + const AxisSpec nBarDnBarPAxis{100, 0.0, 100.0, "N_{#bar{d}}^{i} #times N_{#bar{p}}^{j}"}; + + // Event counter + registryCorr.add("eventCounter", "number of events", HistType::kTH1F, {{20, 0, 20, "counter"}}); + + // Correlation histograms: antiproton vs. antideuteron number vs. event multiplicity + registryCorr.add("rho_jet", "rho_jet", HistType::kTH3F, {nAntideuteronsAxis, nAntiprotonsAxis, multiplicityAxis}); + registryCorr.add("rho_ue", "rho_ue", HistType::kTH3F, {nAntideuteronsAxis, nAntiprotonsAxis, multiplicityAxis}); + registryCorr.add("rho_fullEvent", "rho_fullEvent", HistType::kTH3F, {nAntideuteronsAxis, nAntiprotonsAxis, multiplicityAxis}); + + // Correlation histograms: net antiproton vs. net antideuteron numbers + registryCorr.add("rho_netP_netD_jet", "rho_netP_netD_jet", HistType::kTH2F, {nAntideuteronsAxis, nAntiprotonsAxis}); + registryCorr.add("rho_netP_netD_ue", "rho_netP_netD_ue", HistType::kTH2F, {nAntideuteronsAxis, nAntiprotonsAxis}); + registryCorr.add("rho_netP_netD_fullEvent", "rho_netP_netD_fullEvent", HistType::kTH2F, {nAntideuteronsAxis, nAntiprotonsAxis}); + + // Efficiency histograms jet + registryCorr.add("q1d_jet", "q1d_jet", HistType::kTH2F, {nAntideuteronsAxis, ptPerNucleonAxis}); + registryCorr.add("q1p_jet", "q1p_jet", HistType::kTH2F, {nAntiprotonsAxis, ptPerNucleonAxis}); + registryCorr.add("q1d_square_jet", "q1d_square_jet", HistType::kTH3F, {ptPerNucleonAxis, ptPerNucleonAxis, nBarD2Axis}); + registryCorr.add("q1p_square_jet", "q1p_square_jet", HistType::kTH3F, {ptPerNucleonAxis, ptPerNucleonAxis, nBarP2Axis}); + registryCorr.add("q1d_q1p_jet", "q1d_q1p_jet", HistType::kTH3F, {ptPerNucleonAxis, ptPerNucleonAxis, nBarDnBarPAxis}); + + // Efficiency histograms UE + registryCorr.add("q1d_ue", "q1d_ue", HistType::kTH2F, {nAntideuteronsAxis, ptPerNucleonAxis}); + registryCorr.add("q1p_ue", "q1p_ue", HistType::kTH2F, {nAntiprotonsAxis, ptPerNucleonAxis}); + registryCorr.add("q1d_square_ue", "q1d_square_ue", HistType::kTH3F, {ptPerNucleonAxis, ptPerNucleonAxis, nBarD2Axis}); + registryCorr.add("q1p_square_ue", "q1p_square_ue", HistType::kTH3F, {ptPerNucleonAxis, ptPerNucleonAxis, nBarP2Axis}); + registryCorr.add("q1d_q1p_ue", "q1d_q1p_ue", HistType::kTH3F, {ptPerNucleonAxis, ptPerNucleonAxis, nBarDnBarPAxis}); + + // Efficiency histograms full event + registryCorr.add("q1d_fullEvent", "q1d_fullEvent", HistType::kTH2F, {nAntideuteronsAxis, ptPerNucleonAxis}); + registryCorr.add("q1p_fullEvent", "q1p_fullEvent", HistType::kTH2F, {nAntiprotonsAxis, ptPerNucleonAxis}); + registryCorr.add("q1d_square_fullEvent", "q1d_square_fullEvent", HistType::kTH3F, {ptPerNucleonAxis, ptPerNucleonAxis, nBarD2Axis}); + registryCorr.add("q1p_square_fullEvent", "q1p_square_fullEvent", HistType::kTH3F, {ptPerNucleonAxis, ptPerNucleonAxis, nBarP2Axis}); + registryCorr.add("q1d_q1p_fullEvent", "q1d_q1p_fullEvent", HistType::kTH3F, {ptPerNucleonAxis, ptPerNucleonAxis, nBarDnBarPAxis}); } } + // Compute two unit vectors perpendicular to p void getPerpendicularAxis(const TVector3& p, TVector3& u, double sign) { double px = p.X(); @@ -375,6 +465,7 @@ struct AntinucleiInJets { u.SetXYZ(ux, uy, pz); } + // Compute delta phi double getDeltaPhi(double a1, double a2) { double deltaPhi(0); @@ -390,6 +481,17 @@ struct AntinucleiInJets { return deltaPhi; } + // Find bin + int findBin(const std::vector& edges, double value) + { + auto it = std::upper_bound(edges.begin(), edges.end(), value); + int index = static_cast(it - edges.begin()) - 1; + if (index < 0 || index >= static_cast(edges.size()) - 1) { + return -1; // value is out of bounds + } + return index; + } + // ITS hit template bool hasITSHit(const TrackIts& track, int layer) @@ -398,20 +500,18 @@ struct AntinucleiInJets { return (track.itsClusterMap() & (1 << ibit)); } - // single-track selection for particles inside jets + // Single-track selection for particles inside jets template bool passedTrackSelectionForJetReconstruction(const JetTrack& track) { - - const int minTpcCr = 70; - const double maxChi2Tpc = 4.0; - const double maxChi2Its = 36.0; - const double maxPseudorapidity = 0.8; - const double minPtTrack = 0.1; - const double dcaxyMaxTrackPar0 = 0.0105; - const double dcaxyMaxTrackPar1 = 0.035; - const double dcaxyMaxTrackPar2 = 1.1; - const double dcazMaxTrack = 2.0; + static constexpr int MinTpcCr = 70; + static constexpr double MaxChi2Tpc = 4.0; + static constexpr double MaxChi2Its = 36.0; + static constexpr double MinPtTrack = 0.1; + static constexpr double DcaxyMaxTrackPar0 = 0.0105; + static constexpr double DcaxyMaxTrackPar1 = 0.035; + static constexpr double DcaxyMaxTrackPar2 = 1.1; + static constexpr double DcazMaxTrack = 2.0; if (!track.hasITS()) return false; @@ -419,24 +519,24 @@ struct AntinucleiInJets { return false; if (!track.hasTPC()) return false; - if (track.tpcNClsCrossedRows() < minTpcCr) + if (track.tpcNClsCrossedRows() < MinTpcCr) return false; - if (track.tpcChi2NCl() > maxChi2Tpc) + if (track.tpcChi2NCl() > MaxChi2Tpc) return false; - if (track.itsChi2NCl() > maxChi2Its) + if (track.itsChi2NCl() > MaxChi2Its) return false; - if (track.eta() < -maxPseudorapidity || track.eta() > maxPseudorapidity) + if (std::fabs(track.eta()) > maxEta) return false; - if (track.pt() < minPtTrack) + if (track.pt() < MinPtTrack) return false; - if (std::fabs(track.dcaXY()) > (dcaxyMaxTrackPar0 + dcaxyMaxTrackPar1 / std::pow(track.pt(), dcaxyMaxTrackPar2))) + if (std::fabs(track.dcaXY()) > (DcaxyMaxTrackPar0 + DcaxyMaxTrackPar1 / std::pow(track.pt(), DcaxyMaxTrackPar2))) return false; - if (std::fabs(track.dcaZ()) > dcazMaxTrack) + if (std::fabs(track.dcaZ()) > DcazMaxTrack) return false; return true; } - // single-track selection + // Single-track selection for antinuclei template bool passedTrackSelection(const AntinucleusTrack& track) { @@ -444,6 +544,8 @@ struct AntinucleiInJets { return false; if (!track.hasITS()) return false; + if ((!hasITSHit(track, 1)) && (!hasITSHit(track, 2)) && (!hasITSHit(track, 3))) + return false; if (track.itsNCls() < minItsNclusters) return false; if (!track.hasTPC()) @@ -462,6 +564,77 @@ struct AntinucleiInJets { return true; } + // Single-track selection for antinuclei candidates with systematic variations + template + bool passedTrackSelectionSyst(const AntinucleusTrack& track, int isyst) + { + // Define cut settings + static std::vector minItsNclustersSyst = { + 3, 7, 6, 6, 6, 4, 5, 6, 7, 4, + 4, 3, 6, 3, 7, 5, 4, 6, 5, 7, + 6, 5, 3, 5, 4, 3, 6, 6, 4, 7, + 3, 4, 3, 5, 7, 6, 6, 4, 3, 5, + 4, 7, 3, 6, 4, 5, 6, 3, 7, 5}; + + static std::vector minTpcNcrossedRowsSyst = { + 90, 108, 112, 119, 92, 111, 98, 105, 86, 117, + 118, 101, 87, 116, 82, 109, 80, 115, 89, 97, + 107, 120, 104, 94, 100, 93, 103, 84, 102, 85, + 108, 96, 113, 117, 91, 88, 99, 110, 106, 83, + 118, 95, 112, 114, 109, 89, 116, 92, 98, 120}; + + static std::vector maxChiSquareTpcSyst = { + 4.28, 4.81, 4.43, 4.02, 3.38, 3.58, 3.11, 4.17, 3.51, 4.53, + 4.90, 3.07, 3.20, 4.86, 4.62, 3.91, 3.98, 4.38, 3.66, 3.84, + 3.03, 3.14, 4.96, 4.07, 4.75, 4.32, 3.31, 3.78, 4.11, 3.23, + 3.87, 3.70, 4.99, 4.48, 4.69, 4.25, 3.93, 3.45, 4.58, 3.35, + 3.18, 3.60, 4.21, 3.75, 4.64, 4.35, 3.26, 3.42, 4.15, 3.09}; + + static std::vector maxChiSquareItsSyst = { + 42.84, 48.66, 39.27, 34.09, 43.73, 36.98, 30.23, 49.11, 37.67, 35.10, + 44.55, 46.79, 38.92, 40.66, 47.14, 33.46, 30.88, 41.32, 45.90, 39.68, + 31.42, 32.71, 43.17, 36.04, 49.80, 33.95, 31.89, 38.37, 48.08, 35.87, + 47.61, 44.02, 32.15, 46.21, 34.75, 40.17, 37.14, 30.55, 45.42, 42.30, + 41.79, 33.21, 39.12, 47.98, 36.52, 31.58, 49.44, 38.02, 35.56, 43.49}; + + static std::vector minEtaSyst = { + -0.804, -0.844, -0.751, -0.784, -0.819, -0.823, -0.768, -0.781, -0.845, -0.787, + -0.758, -0.828, -0.776, -0.842, -0.808, -0.763, -0.849, -0.770, -0.799, -0.754, + -0.825, -0.847, -0.806, -0.783, -0.796, -0.835, -0.777, -0.752, -0.838, -0.813, + -0.785, -0.802, -0.795, -0.846, -0.780, -0.829, -0.817, -0.773, -0.765, -0.789, + -0.800, -0.839, -0.758, -0.820, -0.833, -0.762, -0.792, -0.809, -0.827, -0.751}; + + static std::vector maxEtaSyst = { + 0.804, 0.844, 0.751, 0.784, 0.819, 0.823, 0.768, 0.781, 0.845, 0.787, + 0.758, 0.828, 0.776, 0.842, 0.808, 0.763, 0.849, 0.770, 0.799, 0.754, + 0.825, 0.847, 0.806, 0.783, 0.796, 0.835, 0.777, 0.752, 0.838, 0.813, + 0.785, 0.802, 0.795, 0.846, 0.780, 0.829, 0.817, 0.773, 0.765, 0.789, + 0.800, 0.839, 0.758, 0.820, 0.833, 0.762, 0.792, 0.809, 0.827, 0.751}; + + // Track Selection + if (requirePvContributor && !(track.isPVContributor())) + return false; + if (!track.hasITS()) + return false; + if (track.itsNCls() < minItsNclustersSyst[isyst]) + return false; + if (!track.hasTPC()) + return false; + if (track.tpcNClsCrossedRows() < minTpcNcrossedRowsSyst[isyst]) + return false; + if (track.tpcChi2NCl() > maxChiSquareTpcSyst[isyst]) + return false; + if (track.itsChi2NCl() > maxChiSquareItsSyst[isyst]) + return false; + if (track.eta() < minEtaSyst[isyst] || track.eta() > maxEtaSyst[isyst]) + return false; + if (track.pt() < minPt) + return false; + + return true; + } + + // Selection of high-purity antiproton sample template bool isHighPurityAntiproton(const AntiprotonTrack& track) { @@ -469,115 +642,120 @@ struct AntinucleiInJets { double nsigmaTPCPr = track.tpcNSigmaPr(); double nsigmaTOFPr = track.tofNSigmaPr(); double pt = track.pt(); - double ptThreshold = 0.5; - double nsigmaMaxPr = 2.0; + static constexpr double PtThreshold = 0.5; + static constexpr double NsigmaMaxPr = 2.0; - if (pt < ptThreshold && std::fabs(nsigmaTPCPr) < nsigmaMaxPr) + if (pt < PtThreshold && std::fabs(nsigmaTPCPr) < NsigmaMaxPr) return true; - if (pt >= ptThreshold && std::fabs(nsigmaTPCPr) < nsigmaMaxPr && track.hasTOF() && std::fabs(nsigmaTOFPr) < nsigmaMaxPr) + if (pt >= PtThreshold && std::fabs(nsigmaTPCPr) < NsigmaMaxPr && track.hasTOF() && std::fabs(nsigmaTOFPr) < NsigmaMaxPr) return true; return false; } - double getCorrectedPt(double ptRec, TH2* responseMatrix) + // Selection of (anti)protons + template + bool isProton(const ProtonTrack& track) { - if (!responseMatrix) { - LOGP(error, "Response matrix is null. Returning uncorrected pt."); - return ptRec; - } + // Constants + static constexpr double kPtThreshold = 0.6; + static constexpr double kNsigmaMax = 3.0; - int binX = responseMatrix->GetXaxis()->FindBin(ptRec); - if (binX < 1 || binX > responseMatrix->GetNbinsX()) { - LOGP(error, "Bin index out of range: binX = {}", binX); - return ptRec; // Return uncorrected pt if bin index is invalid - } - std::unique_ptr proj(responseMatrix->ProjectionY("proj", binX, binX)); + // PID variables and transverse momentum of the track + const double nsigmaTPC = track.tpcNSigmaPr(); + const double nsigmaTOF = track.tofNSigmaPr(); + const double pt = track.pt(); - // add a protection in case the projection is empty - if (proj->GetEntries() == 0) { - return ptRec; - } + // Apply TPC PID cut + if (std::abs(nsigmaTPC) > kNsigmaMax) + return false; - double deltaPt = proj->GetRandom(); - double ptGen = ptRec + deltaPt; + // Low-pt: TPC PID is sufficient + if (pt < kPtThreshold) + return true; - return ptGen; + // High-pt: require valid TOF match and pass TOF PID + return (track.hasTOF() && std::abs(nsigmaTOF) < kNsigmaMax); } - void getPtUnfoldingHistogram(o2::framework::Service const& ccdbObj, TString filepath, TString histoNamePtUnfolding) + // Selection of (anti)deuterons + template + bool isDeuteron(const DeuteronTrack& track) { - TList* l = ccdbObj->get(filepath.Data()); - if (!l) { - LOGP(error, "Could not open the file {}", Form("%s", filepath.Data())); - return; - } - TObject* obj = l->FindObject(Form("%s", histoNamePtUnfolding.Data())); - if (!obj || !obj->InheritsFrom(TH2F::Class())) { - LOGP(error, "Could not find a valid TH2F histogram {}", Form("%s", histoNamePtUnfolding.Data())); - return; - } - responseMatrix = static_cast(obj); - LOGP(info, "Opened histogram {}", Form("%s", histoNamePtUnfolding.Data())); + // Constants + static constexpr double kPtThreshold = 1.0; + static constexpr double kNsigmaMax = 3.0; + + // PID variables and transverse momentum of the track + const double nsigmaTPC = track.tpcNSigmaDe(); + const double nsigmaTOF = track.tofNSigmaDe(); + const double pt = track.pt(); + + // Apply TPC PID cut + if (std::abs(nsigmaTPC) > kNsigmaMax) + return false; + + // Low-pt: TPC PID is sufficient + if (pt < kPtThreshold) + return true; + + // High-pt: require valid TOF match and pass TOF PID + return (track.hasTOF() && std::abs(nsigmaTOF) < kNsigmaMax); } - void getReweightingHistograms(o2::framework::Service const& ccdbObj, TString filepath, TString histname_antip_jet, TString histname_antip_ue) + // Process Data + void processData(SelectedCollisions::iterator const& collision, AntiNucleiTracks const& tracks, aod::BCsWithTimestamps const&) { - TList* l = ccdbObj->get(filepath.Data()); - if (!l) { - LOGP(error, "Could not open the file {}", Form("%s", filepath.Data())); - return; - } - twoDweightsAntipJet = static_cast(l->FindObject(Form("%s_antiproton", histname_antip_jet.Data()))); - if (!twoDweightsAntipJet) { - LOGP(error, "Could not open histogram {}", Form("%s_antiproton", histname_antip_jet.Data())); + // Event counter: before event selection + registryData.fill(HIST("number_of_events_data"), 0.5); + + // Retrieve the bunch crossing information with timestamps from the collision + auto bc = collision.template bc_as(); + initCCDB(bc); + + // If skimmed processing is enabled, apply Zorro trigger selection + if (cfgSkimmedProcessing && !zorro.isSelected(collision.template bc_as().globalBC())) { return; } - twoDweightsAntipUe = static_cast(l->FindObject(Form("%s_antiproton", histname_antip_ue.Data()))); - if (!twoDweightsAntipUe) { - LOGP(error, "Could not open histogram {}", Form("%s_antiproton", histname_antip_ue.Data())); + registryData.fill(HIST("number_of_events_data"), 1.5); + + // Apply standard event selection + if (!collision.sel8() || std::fabs(collision.posZ()) > zVtx) return; - } - LOGP(info, "Opened histogram {}", Form("%s_antiproton", histname_antip_jet.Data())); - LOGP(info, "Opened histogram {}", Form("%s_antiproton", histname_antip_ue.Data())); - } - bool shouldRejectEvent() - { - static std::random_device rd; - static std::mt19937 gen(rd()); - static std::uniform_int_distribution<> dis(0, 99); - int randomNumber = dis(gen); - if (randomNumber > rejectionPercentage) { - return false; // accept event - } - return true; // reject event - } + // Event counter: after event selection + registryData.fill(HIST("number_of_events_data"), 2.5); - // Process Data - void processData(SelectedCollisions::iterator const& collision, FullNucleiTracks const& tracks) - { - if (rejectEvents) { - // event counter: before event rejection - registryData.fill(HIST("number_of_rejected_events"), 0.5); + // Reject events near the ITS Read-Out Frame border + if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) + return; + registryData.fill(HIST("number_of_events_data"), 3.5); - if (shouldRejectEvent()) - return; + // Reject events at the Time Frame border + if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) + return; + registryData.fill(HIST("number_of_events_data"), 4.5); - // event counter: after event rejection - registryData.fill(HIST("number_of_rejected_events"), 1.5); - } + // Require at least one ITS-TPC matched track + if (requireVtxITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) + return; + registryData.fill(HIST("number_of_events_data"), 5.5); - // event counter: before event selection - registryData.fill(HIST("number_of_events_data"), 0.5); + // Reject events with same-bunch pileup + if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + return; + registryData.fill(HIST("number_of_events_data"), 6.5); - // event selection - if (!collision.sel8() || std::fabs(collision.posZ()) > zVtx) + // Require consistent FT0 vs PV z-vertex + if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) return; + registryData.fill(HIST("number_of_events_data"), 7.5); - // event counter: after event selection - registryData.fill(HIST("number_of_events_data"), 1.5); + // Require TOF match for at least one vertex track + if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) + return; + registryData.fill(HIST("number_of_events_data"), 8.5); - // loop over reconstructed tracks + // Loop over reconstructed tracks int id(-1); std::vector fjParticles; for (auto const& track : tracks) { @@ -591,60 +769,61 @@ struct AntinucleiInJets { fjParticles.emplace_back(fourMomentum); } - // reject empty events - if (fjParticles.size() < 1) + // Reject empty events + if (fjParticles.empty()) return; - registryData.fill(HIST("number_of_events_data"), 2.5); + registryData.fill(HIST("number_of_events_data"), 9.5); - // cluster particles using the anti-kt algorithm + // Cluster particles using the anti-kt algorithm fastjet::JetDefinition jetDef(fastjet::antikt_algorithm, rJet); - fastjet::AreaDefinition areaDef(fastjet::active_area, fastjet::GhostedAreaSpec(1.0)); // active_area_explicit_ghosts + fastjet::AreaDefinition areaDef(fastjet::active_area, fastjet::GhostedAreaSpec(1.0)); fastjet::ClusterSequenceArea cs(fjParticles, jetDef, areaDef); std::vector jets = fastjet::sorted_by_pt(cs.inclusive_jets()); auto [rhoPerp, rhoMPerp] = backgroundSub.estimateRhoPerpCone(fjParticles, jets); - // loop over reconstructed jets + // Loop over reconstructed jets bool isAtLeastOneJetSelected = false; for (const auto& jet : jets) { - // jet must be fully contained in the acceptance + // Jet must be fully contained in the acceptance if ((std::fabs(jet.eta()) + rJet) > (maxEta - deltaEtaEdge)) continue; - // jet pt must be larger than threshold + // Jet pt must be larger than threshold auto jetForSub = jet; fastjet::PseudoJet jetMinusBkg = backgroundSub.doRhoAreaSub(jetForSub, rhoPerp, rhoMPerp); - // if (getCorrectedPt(jetMinusBkg.pt(), responseMatrix) < minJetPt) - registryData.fill(HIST("ptDistributionJet"), jet.pt()); - if (jetMinusBkg.pt() < minJetPt) continue; + + // Apply area cut if required + double normalizedJetArea = jet.area() / (PI * rJet * rJet); + if (applyAreaCut && normalizedJetArea > maxNormalizedJetArea) + continue; isAtLeastOneJetSelected = true; - // perpendicular cone + // Perpendicular cones double coneRadius = std::sqrt(jet.area() / PI); - TVector3 jetAxis(jet.px(), jet.py(), jet.pz()); // before or after subtraction of perpendicular cone? + TVector3 jetAxis(jet.px(), jet.py(), jet.pz()); TVector3 ueAxis1(0, 0, 0); TVector3 ueAxis2(0, 0, 0); getPerpendicularAxis(jetAxis, ueAxis1, +1); getPerpendicularAxis(jetAxis, ueAxis2, -1); - // Jet Area - registryData.fill(HIST("jetEffectiveArea"), jet.area() / (PI * rJet * rJet)); + // Fill histogram with jet effective area / piR^2 + registryData.fill(HIST("jetEffectiveAreaOverPiR2"), jet.area() / (PI * rJet * rJet)); - // get jet constituents + // Get jet constituents std::vector jetConstituents = jet.constituents(); - o2::aod::ITSResponse itsResponse; - // loop over jet constituents + // Loop over jet constituents for (const auto& particle : jetConstituents) { - // get corresponding track and apply track selection criteria + // Get corresponding track and apply track selection criteria auto const& track = tracks.iteratorAt(particle.user_index()); if (!passedTrackSelection(track)) continue; - // variables + // Define variables double nsigmaTPCPr = track.tpcNSigmaPr(); double nsigmaTOFPr = track.tofNSigmaPr(); double nsigmaTPCDe = track.tpcNSigmaDe(); @@ -654,12 +833,12 @@ struct AntinucleiInJets { double dcaxy = track.dcaXY(); double dcaz = track.dcaZ(); - // fill DCA distribution for antiprotons + // Fill DCA distribution for antiprotons if (track.sign() < 0 && isHighPurityAntiproton(track) && std::fabs(dcaz) < maxDcaz) { registryData.fill(HIST("antiproton_dca_jet"), pt, dcaxy); } - // DCA selections + // Apply DCA selections if (std::fabs(dcaxy) > maxDcaxy || std::fabs(dcaz) > maxDcaz) continue; @@ -669,6 +848,11 @@ struct AntinucleiInJets { double nSigmaITSdeut = static_cast(itsResponse.nSigmaITS(track)); double nSigmaITShel3 = static_cast(itsResponse.nSigmaITS(track)); + // Fill nsigmaITS for antiproton candidates + if (isHighPurityAntiproton(track)) { + registryData.fill(HIST("antiproton_nsigma_its_data"), pt, nSigmaITSprot); + } + if (applyItsPid && pt < ptMaxItsPidProt && (nSigmaITSprot < nSigmaItsMin || nSigmaITSprot > nSigmaItsMax)) { passedItsPidProt = false; } @@ -679,7 +863,7 @@ struct AntinucleiInJets { passedItsPidHel = false; } - // antimatter + // Fill histograms for antimatter if (track.sign() < 0) { if (passedItsPidProt) { registryData.fill(HIST("antiproton_jet_tpc"), pt, nsigmaTPCPr); @@ -696,33 +880,45 @@ struct AntinucleiInJets { } } - // matter + // Fill histograms for matter if (track.sign() > 0) { - if (passedItsPidDeut && nsigmaTPCDe > minNsigmaTpc && nsigmaTPCDe < maxNsigmaTpc && track.hasTOF()) - registryData.fill(HIST("deuteron_jet_tof"), pt, nsigmaTOFDe); + if (passedItsPidDeut) { + registryData.fill(HIST("deuteron_jet_tpc"), pt, nsigmaTPCDe); + if (nsigmaTPCDe > minNsigmaTpc && nsigmaTPCDe < maxNsigmaTpc && track.hasTOF()) + registryData.fill(HIST("deuteron_jet_tof"), pt, nsigmaTOFDe); + } if (passedItsPidHel) { registryData.fill(HIST("helium3_jet_tpc"), 2.0 * pt, nsigmaTPCHe); } } } - // underlying event + // Loop over tracks in the underlying event for (auto const& track : tracks) { - // get corresponding track and apply track selection criteria + // Get corresponding track and apply track selection criteria if (!passedTrackSelection(track)) continue; + // Calculate the angular distance between the track and underlying event axes in eta-phi space double deltaEtaUe1 = track.eta() - ueAxis1.Eta(); double deltaPhiUe1 = getDeltaPhi(track.phi(), ueAxis1.Phi()); double deltaRUe1 = std::sqrt(deltaEtaUe1 * deltaEtaUe1 + deltaPhiUe1 * deltaPhiUe1); double deltaEtaUe2 = track.eta() - ueAxis2.Eta(); double deltaPhiUe2 = getDeltaPhi(track.phi(), ueAxis2.Phi()); double deltaRUe2 = std::sqrt(deltaEtaUe2 * deltaEtaUe2 + deltaPhiUe2 * deltaPhiUe2); - if (deltaRUe1 > coneRadius && deltaRUe2 > coneRadius) + + // Determine the maximum allowed distance from UE axes for particle selection + double maxConeRadius = coneRadius; + if (applyAreaCut) { + maxConeRadius = std::sqrt(maxNormalizedJetArea) * rJet; + } + + // Reject tracks that lie outside the maxConeRadius from both UE axes + if (deltaRUe1 > maxConeRadius && deltaRUe2 > maxConeRadius) continue; - // variables + // Define variables double nsigmaTPCPr = track.tpcNSigmaPr(); double nsigmaTOFPr = track.tofNSigmaPr(); double nsigmaTPCDe = track.tpcNSigmaDe(); @@ -732,12 +928,12 @@ struct AntinucleiInJets { double dcaxy = track.dcaXY(); double dcaz = track.dcaZ(); - // fill DCA distribution for antiprotons + // Fill DCA distribution for antiprotons if (track.sign() < 0 && isHighPurityAntiproton(track) && std::fabs(dcaz) < maxDcaz) { registryData.fill(HIST("antiproton_dca_ue"), pt, dcaxy); } - // DCA selections + // Apply DCA selections if (std::fabs(dcaxy) > maxDcaxy || std::fabs(dcaz) > maxDcaz) continue; @@ -757,7 +953,7 @@ struct AntinucleiInJets { passedItsPidHel = false; } - // antimatter + // Fill histograms for antimatter if (track.sign() < 0) { if (passedItsPidProt) { registryData.fill(HIST("antiproton_ue_tpc"), pt, nsigmaTPCPr); @@ -774,33 +970,49 @@ struct AntinucleiInJets { } } - // matter + // Fill histograms for matter if (track.sign() > 0) { - if (passedItsPidDeut && nsigmaTPCDe > minNsigmaTpc && nsigmaTPCDe < maxNsigmaTpc && track.hasTOF()) - registryData.fill(HIST("deuteron_ue_tof"), pt, nsigmaTOFDe); - // helium3 + if (passedItsPidDeut) { + registryData.fill(HIST("deuteron_ue_tpc"), pt, nsigmaTPCDe); + if (nsigmaTPCDe > minNsigmaTpc && nsigmaTPCDe < maxNsigmaTpc && track.hasTOF()) + registryData.fill(HIST("deuteron_ue_tof"), pt, nsigmaTOFDe); + } if (passedItsPidHel) { registryData.fill(HIST("helium3_ue_tpc"), 2.0 * pt, nsigmaTPCHe); } } } } + // Event counter: events with at least one jet selected if (isAtLeastOneJetSelected) { - registryData.fill(HIST("number_of_events_data"), 3.5); + registryData.fill(HIST("number_of_events_data"), 10.5); } } PROCESS_SWITCH(AntinucleiInJets, processData, "Process Data", true); - void processMultEvents(SelectedCollisions::iterator const& collision, FullNucleiTracks const& tracks) + // Charged-particle multiplicity in events with selected jets (Run 3) or ptTrigger > threshold (Run 2-like) + void processMultEvents(SelectedCollisions::iterator const& collision, AntiNucleiTracks const& tracks) { - // event selection + // Apply event selection if (!collision.sel8() || std::fabs(collision.posZ()) > zVtx) return; + if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) + return; + if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) + return; + if (requireVtxITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) + return; + if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + return; + if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + return; + if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) + return; - // Leading Track + // Initialize variable to store the maximum pt in the event double ptMax(0.0); - // loop over reconstructed tracks + // Loop over reconstructed tracks int id(-1); std::vector fjParticles; for (auto const& track : tracks) { @@ -816,51 +1028,72 @@ struct AntinucleiInJets { fourMomentum.set_user_index(id); fjParticles.emplace_back(fourMomentum); } - // reject empty events + + // Reject empty events if (fjParticles.empty()) { return; } + // Fill charged-particle multiplicity for events with leading track having pt>threshold if (ptMax > ptLeadingMin) { registryMult.fill(HIST("multiplicityEvtsPtLeading"), fjParticles.size()); } - // cluster particles using the anti-kt algorithm + // Cluster particles using the anti-kt algorithm fastjet::JetDefinition jetDef(fastjet::antikt_algorithm, rJet); fastjet::AreaDefinition areaDef(fastjet::active_area, fastjet::GhostedAreaSpec(1.0)); fastjet::ClusterSequenceArea cs(fjParticles, jetDef, areaDef); std::vector jets = fastjet::sorted_by_pt(cs.inclusive_jets()); auto [rhoPerp, rhoMPerp] = backgroundSub.estimateRhoPerpCone(fjParticles, jets); - // loop over reconstructed jets + // Loop over reconstructed jets bool isAtLeastOneJetSelected = false; for (const auto& jet : jets) { - // jet must be fully contained in the acceptance + // Jet must be fully contained in the acceptance if ((std::fabs(jet.eta()) + rJet) > (maxEta - deltaEtaEdge)) continue; - // jet pt must be larger than threshold + // Jet pt must be larger than threshold auto jetForSub = jet; fastjet::PseudoJet jetMinusBkg = backgroundSub.doRhoAreaSub(jetForSub, rhoPerp, rhoMPerp); if (jetMinusBkg.pt() < minJetPt) continue; + + // Apply area cut if required + double normalizedJetArea = jet.area() / (PI * rJet * rJet); + if (applyAreaCut && normalizedJetArea > maxNormalizedJetArea) + continue; isAtLeastOneJetSelected = true; } + + // Fill histogram of charged-particle multiplicity for events containing at least one selected jet if (isAtLeastOneJetSelected) { registryMult.fill(HIST("multiplicityEvtsWithJet"), fjParticles.size()); } } - PROCESS_SWITCH(AntinucleiInJets, processMultEvents, "Process Mult Events", true); + PROCESS_SWITCH(AntinucleiInJets, processMultEvents, "Process Mult Events", false); // Process QC - void processQC(SelectedCollisions::iterator const& collision, FullNucleiTracks const& tracks) + void processQC(SelectedCollisions::iterator const& collision, AntiNucleiTracks const& tracks) { - // event selection + // Apply event selection if (!collision.sel8() || std::fabs(collision.posZ()) > zVtx) return; + if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) + return; + if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) + return; + if (requireVtxITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) + return; + if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + return; + if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + return; + if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) + return; - // loop over reconstructed tracks + // Loop over reconstructed tracks std::vector fjParticles; for (auto const& track : tracks) { if (!passedTrackSelectionForJetReconstruction(track)) @@ -871,41 +1104,43 @@ struct AntinucleiInJets { fjParticles.emplace_back(fourMomentum); } - // reject empty events - if (fjParticles.size() < 1) + // Reject empty events + if (fjParticles.empty()) return; - // cluster particles using the anti-kt algorithm + // Cluster particles using the anti-kt algorithm fastjet::JetDefinition jetDef(fastjet::antikt_algorithm, rJet); - fastjet::AreaDefinition areaDef(fastjet::active_area, fastjet::GhostedAreaSpec(1.0)); // active_area_explicit_ghosts + fastjet::AreaDefinition areaDef(fastjet::active_area, fastjet::GhostedAreaSpec(1.0)); fastjet::ClusterSequenceArea cs(fjParticles, jetDef, areaDef); std::vector jets = fastjet::sorted_by_pt(cs.inclusive_jets()); auto [rhoPerp, rhoMPerp] = backgroundSub.estimateRhoPerpCone(fjParticles, jets); - // loop over reconstructed jets + // Loop over reconstructed jets int njetsInAcc(0); int njetsHighPt(0); for (const auto& jet : jets) { - // jet must be fully contained in the acceptance + // Jet must be fully contained in the acceptance if ((std::fabs(jet.eta()) + rJet) > (maxEta - deltaEtaEdge)) continue; njetsInAcc++; registryQC.fill(HIST("sumPtJetCone"), jet.pt()); double ptJetBeforeSub = jet.pt(); - // jet pt must be larger than threshold + // Jet pt must be larger than threshold auto jetForSub = jet; fastjet::PseudoJet jetMinusBkg = backgroundSub.doRhoAreaSub(jetForSub, rhoPerp, rhoMPerp); double ptJetAfterSub = jetForSub.pt(); registryQC.fill(HIST("jetPtDifference"), ptJetAfterSub - ptJetBeforeSub); + registryQC.fill(HIST("ptDistributionJetCone"), ptJetBeforeSub); + registryQC.fill(HIST("ptDistributionJet"), ptJetAfterSub); - if (getCorrectedPt(jetMinusBkg.pt(), responseMatrix) < minJetPt) + if (jetMinusBkg.pt() < minJetPt) continue; njetsHighPt++; registryQC.fill(HIST("sumPtJet"), jet.pt()); - // jet properties and perpendicular cone + // Jet properties and perpendicular cone std::vector jetConstituents = jet.constituents(); TVector3 jetAxis(jet.px(), jet.py(), jet.pz()); double coneRadius = std::sqrt(jet.area() / PI); @@ -916,7 +1151,7 @@ struct AntinucleiInJets { registryQC.fill(HIST("NchJetCone"), static_cast(jetConstituents.size())); - // loop over jet constituents + // Loop over jet constituents for (const auto& particle : jetConstituents) { double deltaEta = particle.eta() - jetAxis.Eta(); @@ -925,7 +1160,7 @@ struct AntinucleiInJets { registryQC.fill(HIST("eta_phi_jet"), particle.eta(), particle.phi()); } - // loop over particles in perpendicular cones + // Loop over particles in perpendicular cones double nParticlesPerp(0); double ptPerp(0); for (auto const& track : tracks) { @@ -958,96 +1193,88 @@ struct AntinucleiInJets { } PROCESS_SWITCH(AntinucleiInJets, processQC, "Process QC", false); - void processEfficiency(SimCollisions const& collisions, MCTracks const& mcTracks, aod::McParticles const& mcParticles) + // Antinuclei reconstruction efficiency + void processAntinucleiEfficiency(RecCollisionsMc const& collisions, AntiNucleiTracksMc const& mcTracks, aod::McParticles const& mcParticles) { // Loop over all simulated collision events for (const auto& collision : collisions) { // Count all generated events before applying any event selection criteria - registryMC.fill(HIST("number_of_events_mc"), 0.5); + registryMC.fill(HIST("number_of_events_mc_nuclei_efficiency"), 0.5); // Apply event selection: require sel8 and vertex position within the allowed z range if (!collision.sel8() || std::fabs(collision.posZ()) > zVtx) continue; // Count events that pass the selection criteria - registryMC.fill(HIST("number_of_events_mc"), 1.5); + registryMC.fill(HIST("number_of_events_mc_nuclei_efficiency"), 1.5); + + // Reject events near the ITS Read-Out Frame border + if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) + continue; + registryMC.fill(HIST("number_of_events_mc_nuclei_efficiency"), 2.5); + + // Reject events at the Time Frame border + if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) + continue; + registryMC.fill(HIST("number_of_events_mc_nuclei_efficiency"), 3.5); + + // Require at least one ITS-TPC matched track + if (requireVtxITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) + continue; + registryMC.fill(HIST("number_of_events_mc_nuclei_efficiency"), 4.5); + + // Reject events with same-bunch pileup + if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + continue; + registryMC.fill(HIST("number_of_events_mc_nuclei_efficiency"), 5.5); + + // Require consistent FT0 vs PV z-vertex + if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + continue; + registryMC.fill(HIST("number_of_events_mc_nuclei_efficiency"), 6.5); + + // Require TOF match for at least one vertex track + if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) + continue; + registryMC.fill(HIST("number_of_events_mc_nuclei_efficiency"), 7.5); // Loop over all generated Monte Carlo particles for the selected event for (const auto& particle : mcParticles) { - // primary particles + // Select primary particles if (!particle.isPhysicalPrimary()) continue; - // Fill (eta, pT) distribution of generated antiprotons - if (particle.pdgCode() == kProtonBar) { - registryMC.fill(HIST("antiproton_eta_pt_pythia"), particle.pt(), particle.eta()); - } - // Select particles within the specified pseudorapidity interval if (particle.eta() < minEta || particle.eta() > maxEta) continue; - // Initialize weights for antiproton reweighting in Jet and UE cones - double wAntipJet2d(1.0), wAntipUe2d(1.0); - int ix = twoDweightsAntipJet->GetXaxis()->FindBin(particle.pt()); - int iy = twoDweightsAntipJet->GetYaxis()->FindBin(particle.eta()); - - // Retrieve 2D weights from histograms based on particle's (pT, eta) - wAntipJet2d = twoDweightsAntipJet->GetBinContent(ix, iy); - wAntipUe2d = twoDweightsAntipUe->GetBinContent(ix, iy); - - // Sanity checks: if (pT, eta) is out of histogram bounds, set default weight to 1.0 - if (ix == 0 || ix > twoDweightsAntipJet->GetNbinsX()) { - wAntipJet2d = 1.0; - wAntipUe2d = 1.0; - } - if (iy == 0 || iy > twoDweightsAntipJet->GetNbinsY()) { - wAntipJet2d = 1.0; - wAntipUe2d = 1.0; - } - - // Placeholder for 1D weight factors (e.g., for further corrections, still to be implemented) - double wAntipJetFinal(1.0), wAntipUeFinal(1.0); - // Process different particle species based on PDG code switch (particle.pdgCode()) { - case kProtonBar: - // Fill histograms with unweighted and weighted (2D and final) pT spectra for antiprotons - registryMC.fill(HIST("antiproton_gen_jet_unweighted"), particle.pt()); - registryMC.fill(HIST("antiproton_gen_ue_unweighted"), particle.pt()); - registryMC.fill(HIST("antiproton_gen_jet_weighted2d"), particle.pt(), wAntipJet2d); - registryMC.fill(HIST("antiproton_gen_ue_weighted2d"), particle.pt(), wAntipUe2d); - registryMC.fill(HIST("antiproton_gen_jet_weightedFinal"), particle.pt(), wAntipJetFinal); - registryMC.fill(HIST("antiproton_gen_ue_weightedFinal"), particle.pt(), wAntipUeFinal); - - // Fill additional histograms used for deriving or validating reweighting corrections - registryMC.fill(HIST("antiproton_forReweighting_jet_weighted2d"), particle.pt(), wAntipJet2d); - registryMC.fill(HIST("antiproton_forReweighting_ue_weighted2d"), particle.pt(), wAntipUe2d); - registryMC.fill(HIST("antiproton_forReweighting_jet_weightedFinal"), particle.pt(), wAntipJetFinal); - registryMC.fill(HIST("antiproton_forReweighting_ue_weightedFinal"), particle.pt(), wAntipUeFinal); + case PDG_t::kProtonBar: + registryMC.fill(HIST("antip_gen_jet"), particle.pt()); + registryMC.fill(HIST("antip_gen_ue"), particle.pt()); break; - - // Generated spectra for other light nuclei case o2::constants::physics::Pdg::kDeuteron: - registryMC.fill(HIST("deuteron_incl_gen"), particle.pt()); + registryMC.fill(HIST("deuteron_gen_jet"), particle.pt()); + registryMC.fill(HIST("deuteron_gen_ue"), particle.pt()); break; case -o2::constants::physics::Pdg::kDeuteron: - registryMC.fill(HIST("antideuteron_incl_gen"), particle.pt()); + registryMC.fill(HIST("antideuteron_gen_jet"), particle.pt()); + registryMC.fill(HIST("antideuteron_gen_ue"), particle.pt()); break; case o2::constants::physics::Pdg::kHelium3: - registryMC.fill(HIST("helium3_incl_gen"), particle.pt()); + registryMC.fill(HIST("helium3_gen_jet"), particle.pt()); + registryMC.fill(HIST("helium3_gen_ue"), particle.pt()); break; case -o2::constants::physics::Pdg::kHelium3: - registryMC.fill(HIST("antihelium3_incl_gen"), particle.pt()); + registryMC.fill(HIST("antihelium3_gen_jet"), particle.pt()); + registryMC.fill(HIST("antihelium3_gen_ue"), particle.pt()); break; } } - // ITS PID response utility - o2::aod::ITSResponse itsResponse; - // Loop over all reconstructed MC tracks for (auto const& track : mcTracks) { @@ -1056,9 +1283,7 @@ struct AntinucleiInJets { continue; // Cut on transverse and longitudinal distance of closest approach - if (std::fabs(track.dcaXY()) > maxDcaxy) - continue; - if (std::fabs(track.dcaZ()) > maxDcaz) + if (std::fabs(track.dcaXY()) > maxDcaxy || std::fabs(track.dcaZ()) > maxDcaz) continue; // Skip tracks that are not associated with a true MC particle @@ -1066,7 +1291,7 @@ struct AntinucleiInJets { continue; const auto particle = track.mcParticle(); - // select only physical primary particles + // Select only physical primary particles if (!particle.isPhysicalPrimary()) continue; @@ -1094,143 +1319,148 @@ struct AntinucleiInJets { passedItsPidHel = false; } - // Get correction weights as a function of (pt, eta) from external histograms - double wAntipJet2d(1.0), wAntipUe2d(1.0); - int ix = twoDweightsAntipJet->GetXaxis()->FindBin(particle.pt()); - int iy = twoDweightsAntipJet->GetYaxis()->FindBin(particle.eta()); - wAntipJet2d = twoDweightsAntipJet->GetBinContent(ix, iy); - wAntipUe2d = twoDweightsAntipUe->GetBinContent(ix, iy); - - // Edge protection: reset weights to 1 if out of histogram range - if (ix == 0 || ix > twoDweightsAntipJet->GetNbinsX()) { - wAntipJet2d = 1.0; - wAntipUe2d = 1.0; - } - if (iy == 0 || iy > twoDweightsAntipJet->GetNbinsY()) { - wAntipJet2d = 1.0; - wAntipUe2d = 1.0; - } - - // 1d weights (to be implemented) - double wAntipJetFinal(1.0), wAntipUeFinal(1.0); - - // antiprotons - if (particle.pdgCode() == kProtonBar) { - if (passedItsPidProt && nsigmaTPCPr > minNsigmaTpc && nsigmaTPCPr < maxNsigmaTpc) { - registryMC.fill(HIST("antiproton_recTpc_jet_unweighted"), track.pt()); - registryMC.fill(HIST("antiproton_recTpc_ue_unweighted"), track.pt()); - registryMC.fill(HIST("antiproton_recTpc_jet_weighted2d"), track.pt(), wAntipJet2d); - registryMC.fill(HIST("antiproton_recTpc_ue_weighted2d"), track.pt(), wAntipUe2d); - registryMC.fill(HIST("antiproton_recTpc_jet_weightedFinal"), track.pt(), wAntipJetFinal); - registryMC.fill(HIST("antiproton_recTpc_ue_weightedFinal"), track.pt(), wAntipUeFinal); + // Fill histograms of antiprotons + if (track.sign() < 0 && particle.pdgCode() == PDG_t::kProtonBar && passedItsPidProt) { + if (nsigmaTPCPr > minNsigmaTpc && nsigmaTPCPr < maxNsigmaTpc) { + registryMC.fill(HIST("antip_rec_tpc_jet"), track.pt()); + registryMC.fill(HIST("antip_rec_tpc_ue"), track.pt()); if (track.hasTOF() && nsigmaTOFPr > minNsigmaTof && nsigmaTOFPr < maxNsigmaTof) { - registryMC.fill(HIST("antiproton_recTof_jet_unweighted"), track.pt()); - registryMC.fill(HIST("antiproton_recTof_ue_unweighted"), track.pt()); - registryMC.fill(HIST("antiproton_recTof_jet_weighted2d"), track.pt(), wAntipJet2d); - registryMC.fill(HIST("antiproton_recTof_ue_weighted2d"), track.pt(), wAntipUe2d); - registryMC.fill(HIST("antiproton_recTof_jet_weightedFinal"), track.pt(), wAntipJetFinal); - registryMC.fill(HIST("antiproton_recTof_ue_weightedFinal"), track.pt(), wAntipUeFinal); + registryMC.fill(HIST("antip_rec_tof_jet"), track.pt()); + registryMC.fill(HIST("antip_rec_tof_ue"), track.pt()); } } } - // antideuterons - if (particle.pdgCode() == -o2::constants::physics::Pdg::kDeuteron && passedItsPidDeut) { + // Fill histograms of antideuterons + if (track.sign() < 0 && particle.pdgCode() == -o2::constants::physics::Pdg::kDeuteron && passedItsPidDeut) { if (nsigmaTPCDe > minNsigmaTpc && nsigmaTPCDe < maxNsigmaTpc) { - registryMC.fill(HIST("antideuteron_incl_rec_tpc"), track.pt()); - if (track.hasTOF() && nsigmaTOFDe > minNsigmaTof && nsigmaTOFDe < maxNsigmaTof) - registryMC.fill(HIST("antideuteron_incl_rec_tof"), track.pt()); + registryMC.fill(HIST("antideuteron_rec_tpc_jet"), track.pt()); + registryMC.fill(HIST("antideuteron_rec_tpc_ue"), track.pt()); + + if (track.hasTOF() && nsigmaTOFDe > minNsigmaTof && nsigmaTOFDe < maxNsigmaTof) { + registryMC.fill(HIST("antideuteron_rec_tof_jet"), track.pt()); + registryMC.fill(HIST("antideuteron_rec_tof_ue"), track.pt()); + } } } - // deuterons - if (particle.pdgCode() == o2::constants::physics::Pdg::kDeuteron && passedItsPidDeut) { + // Fill histograms of deuterons + if (track.sign() > 0 && particle.pdgCode() == o2::constants::physics::Pdg::kDeuteron && passedItsPidDeut) { if (nsigmaTPCDe > minNsigmaTpc && nsigmaTPCDe < maxNsigmaTpc) { - registryMC.fill(HIST("deuteron_incl_rec_tpc"), track.pt()); - if (track.hasTOF() && nsigmaTOFDe > minNsigmaTof && nsigmaTOFDe < maxNsigmaTof) - registryMC.fill(HIST("deuteron_incl_rec_tof"), track.pt()); + registryMC.fill(HIST("deuteron_rec_tpc_jet"), track.pt()); + registryMC.fill(HIST("deuteron_rec_tpc_ue"), track.pt()); + if (track.hasTOF() && nsigmaTOFDe > minNsigmaTof && nsigmaTOFDe < maxNsigmaTof) { + registryMC.fill(HIST("deuteron_rec_tof_jet"), track.pt()); + registryMC.fill(HIST("deuteron_rec_tof_ue"), track.pt()); + } } } - // antihelium3 - if (particle.pdgCode() == -o2::constants::physics::Pdg::kHelium3 && passedItsPidHel) { + // Fill histograms of antihelium3 + if (track.sign() < 0 && particle.pdgCode() == -o2::constants::physics::Pdg::kHelium3 && passedItsPidHel) { if (nsigmaTPCHe > minNsigmaTpc && nsigmaTPCHe < maxNsigmaTpc) { - registryMC.fill(HIST("antihelium3_incl_rec_tpc"), 2.0 * track.pt()); + registryMC.fill(HIST("antihelium3_rec_tpc_jet"), 2.0 * track.pt()); + registryMC.fill(HIST("antihelium3_rec_tpc_ue"), 2.0 * track.pt()); } } - // helium3 - if (particle.pdgCode() == o2::constants::physics::Pdg::kHelium3 && passedItsPidHel) { + // Fill histograms of helium3 + if (track.sign() > 0 && particle.pdgCode() == o2::constants::physics::Pdg::kHelium3 && passedItsPidHel) { if (nsigmaTPCHe > minNsigmaTpc && nsigmaTPCHe < maxNsigmaTpc) { - registryMC.fill(HIST("helium3_incl_rec_tpc"), 2.0 * track.pt()); + registryMC.fill(HIST("helium3_rec_tpc_jet"), 2.0 * track.pt()); + registryMC.fill(HIST("helium3_rec_tpc_ue"), 2.0 * track.pt()); } } } } } - PROCESS_SWITCH(AntinucleiInJets, processEfficiency, "process efficiency", false); + PROCESS_SWITCH(AntinucleiInJets, processAntinucleiEfficiency, "process antinuclei efficiency", false); - void processJetsMCgen(GenCollisions const& collisions, aod::McParticles const& mcParticles) + // Generated events + void processJetsMCgen(GenCollisionsMc const& collisions, aod::McParticles const& mcParticles) { - // Loop over all simulated collision events + // Loop over all simulated collisions for (const auto& collision : collisions) { - // Apply event selection: require vertex position within the allowed z range + // Event counter: before event selection + registryMC.fill(HIST("genEvents"), 0.5); + + // Apply event selection: require vertex position to be within the allowed z range if (std::fabs(collision.posZ()) > zVtx) continue; - // Loop over all MC particles and select physical primaries within acceptance + // Event counter: after event selection + registryMC.fill(HIST("genEvents"), 1.5); + + // Loop over all MC particles std::vector fjParticles; + std::vector protonMomentum; for (const auto& particle : mcParticles) { + + // Select physical primaries within acceptance if (!particle.isPhysicalPrimary()) continue; - double minPtParticle = 0.1; - if (particle.eta() < minEta || particle.eta() > maxEta || particle.pt() < minPtParticle) + static constexpr double MinPtParticle = 0.1; + if (particle.eta() < minEta || particle.eta() > maxEta || particle.pt() < MinPtParticle) continue; - // Build 4-momentum assuming charged pion mass + // Store 3-momentum vectors of antiprotons for further analysis + if (particle.pdgCode() == PDG_t::kProtonBar) { + TVector3 pVec(particle.px(), particle.py(), particle.pz()); + protonMomentum.push_back(pVec); + } + + // 4-momentum representation of a particle double energy = std::sqrt(particle.p() * particle.p() + MassPionCharged * MassPionCharged); fastjet::PseudoJet fourMomentum(particle.px(), particle.py(), particle.pz(), energy); fourMomentum.set_user_index(particle.pdgCode()); fjParticles.emplace_back(fourMomentum); } - // Skip events with no particles - if (fjParticles.size() < 1) + // Reject empty events + if (fjParticles.empty()) continue; + registryMC.fill(HIST("genEvents"), 2.5); // Cluster MC particles into jets using anti-kt algorithm fastjet::JetDefinition jetDef(fastjet::antikt_algorithm, rJet); fastjet::AreaDefinition areaDef(fastjet::active_area, fastjet::GhostedAreaSpec(1.0)); fastjet::ClusterSequenceArea cs(fjParticles, jetDef, areaDef); std::vector jets = fastjet::sorted_by_pt(cs.inclusive_jets()); - - // Estimate background energy density (rho) in perpendicular cone auto [rhoPerp, rhoMPerp] = backgroundSub.estimateRhoPerpCone(fjParticles, jets); // Loop over clustered jets + bool isAtLeastOneJetSelected = false; for (const auto& jet : jets) { - // Jet must be fully contained in acceptance + // Jet must be fully contained in the acceptance if ((std::fabs(jet.eta()) + rJet) > (maxEta - deltaEtaEdge)) continue; - // Subtract background energy from jet + // Jet pt must be larger than threshold auto jetForSub = jet; fastjet::PseudoJet jetMinusBkg = backgroundSub.doRhoAreaSub(jetForSub, rhoPerp, rhoMPerp); - - // Apply jet pT threshold if (jetMinusBkg.pt() < minJetPt) continue; - // Analyze jet constituents and search for antiprotons + // Apply area cut if required + double normalizedJetArea = jet.area() / (PI * rJet * rJet); + if (applyAreaCut && normalizedJetArea > maxNormalizedJetArea) + continue; + isAtLeastOneJetSelected = true; + + // Analyze jet constituents std::vector jetConstituents = jet.constituents(); for (const auto& particle : jetConstituents) { - if (particle.user_index() != kProtonBar) + if (particle.user_index() != PDG_t::kProtonBar) continue; - registryMC.fill(HIST("antiproton_eta_pt_jet"), particle.pt(), particle.eta()); - registryMC.fill(HIST("antiproton_gen_jet_antikt"), particle.pt()); + + if (particle.eta() < minEta || particle.eta() > maxEta) + continue; + + // Fill histogram for generated antiprotons + registryMC.fill(HIST("antiproton_gen_jet"), particle.pt()); } // Set up two perpendicular cone axes for underlying event estimation @@ -1241,109 +1471,142 @@ struct AntinucleiInJets { getPerpendicularAxis(jetAxis, ueAxis2, -1); // Loop over MC particles to analyze underlying event region - for (const auto& particle : mcParticles) { - if (!particle.isPhysicalPrimary()) - continue; - double minPtParticle = 0.1; - if (particle.eta() < minEta || particle.eta() > maxEta || particle.pt() < minPtParticle) - continue; + for (const auto& protonVec : protonMomentum) { // Compute distance of particle from both perpendicular cone axes - double deltaEtaUe1 = particle.eta() - ueAxis1.Eta(); - double deltaPhiUe1 = getDeltaPhi(particle.phi(), ueAxis1.Phi()); + double deltaEtaUe1 = protonVec.Eta() - ueAxis1.Eta(); + double deltaPhiUe1 = getDeltaPhi(protonVec.Phi(), ueAxis1.Phi()); double deltaRUe1 = std::sqrt(deltaEtaUe1 * deltaEtaUe1 + deltaPhiUe1 * deltaPhiUe1); - double deltaEtaUe2 = particle.eta() - ueAxis2.Eta(); - double deltaPhiUe2 = getDeltaPhi(particle.phi(), ueAxis2.Phi()); + double deltaEtaUe2 = protonVec.Eta() - ueAxis2.Eta(); + double deltaPhiUe2 = getDeltaPhi(protonVec.Phi(), ueAxis2.Phi()); double deltaRUe2 = std::sqrt(deltaEtaUe2 * deltaEtaUe2 + deltaPhiUe2 * deltaPhiUe2); - // Select particles inside one of the perpendicular cones - if (deltaRUe1 > coneRadius && deltaRUe2 > coneRadius) - continue; + // Determine the maximum allowed distance from UE axes for particle selection + double maxConeRadius = coneRadius; + if (applyAreaCut) { + maxConeRadius = std::sqrt(maxNormalizedJetArea) * rJet; + } - // Select antiprotons based on PDG - if (particle.pdgCode() != kProtonBar) + // Reject tracks that lie outside the maxConeRadius from both UE axes + if (deltaRUe1 > maxConeRadius && deltaRUe2 > maxConeRadius) continue; - registryMC.fill(HIST("antiproton_eta_pt_ue"), particle.pt(), particle.eta()); - registryMC.fill(HIST("antiproton_gen_ue_antikt"), particle.pt()); + // Fill histogram for antiprotons in the UE + registryMC.fill(HIST("antiproton_gen_ue"), protonVec.Pt()); } } + if (isAtLeastOneJetSelected) { + registryMC.fill(HIST("genEvents"), 3.5); + } } } PROCESS_SWITCH(AntinucleiInJets, processJetsMCgen, "process jets mc gen", false); - void processJetsMCrec(SimCollisions const& collisions, MCTracks const& mcTracks, McParticles const&) + // Reconstructed events + void processJetsMCrec(RecCollisionsMc const& collisions, AntiNucleiTracksMc const& mcTracks, McParticles const&) { - // Initialize ITS PID response tool - o2::aod::ITSResponse itsResponse; - - // Loop over all simulated collision events + // Loop over all reconstructed collisions for (const auto& collision : collisions) { - // Apply event selection: require sel8 and vertex position within the allowed z range + // Event counter: before event selection + registryMC.fill(HIST("recEvents"), 0.5); + + // Apply event selection: require sel8 and vertex position to be within the allowed z range if (!collision.sel8() || std::fabs(collision.posZ()) > zVtx) continue; - // Prepare particle list for jet clustering + // Event counter: after event selection + registryMC.fill(HIST("recEvents"), 1.5); + + // Reject events near the ITS Read-Out Frame border + if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) + continue; + registryMC.fill(HIST("recEvents"), 2.5); + + // Reject events at the Time Frame border + if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) + continue; + registryMC.fill(HIST("recEvents"), 3.5); + + // Require at least one ITS-TPC matched track + if (requireVtxITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) + continue; + registryMC.fill(HIST("recEvents"), 4.5); + + // Reject events with same-bunch pileup + if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + continue; + registryMC.fill(HIST("recEvents"), 5.5); + + // Require consistent FT0 vs PV z-vertex + if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + continue; + registryMC.fill(HIST("recEvents"), 6.5); + + // Require TOF match for at least one vertex track + if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) + continue; + registryMC.fill(HIST("recEvents"), 7.5); + + // Loop over reconstructed tracks int id(-1); std::vector fjParticles; + std::vector antiprotonTrackIndex; for (auto const& track : mcTracks) { id++; + + // Get corresponding MC particle + if (!track.has_mcParticle()) + continue; + const auto mcparticle = track.mcParticle(); + + // Store track index for antiproton tracks + if (passedTrackSelection(track) && track.sign() < 0 && mcparticle.pdgCode() == PDG_t::kProtonBar) { + antiprotonTrackIndex.emplace_back(id); + } + + // Apply track selection for jet reconstruction if (!passedTrackSelectionForJetReconstruction(track)) continue; - // Build 4-momentum assuming charged pion mass + // 4-momentum representation of a particle fastjet::PseudoJet fourMomentum(track.px(), track.py(), track.pz(), track.energy(MassPionCharged)); fourMomentum.set_user_index(id); fjParticles.emplace_back(fourMomentum); } - // Skip events with no particles - if (fjParticles.size() < 1) + // Reject empty events + if (fjParticles.empty()) continue; + registryMC.fill(HIST("recEvents"), 8.5); - // Perform jet clustering using anti-kT algorithm with active area correction + // Cluster particles using the anti-kt algorithm fastjet::JetDefinition jetDef(fastjet::antikt_algorithm, rJet); fastjet::AreaDefinition areaDef(fastjet::active_area, fastjet::GhostedAreaSpec(1.0)); fastjet::ClusterSequenceArea cs(fjParticles, jetDef, areaDef); std::vector jets = fastjet::sorted_by_pt(cs.inclusive_jets()); - - // Estimate background energy density (rho) in perpendicular cone auto [rhoPerp, rhoMPerp] = backgroundSub.estimateRhoPerpCone(fjParticles, jets); // Loop over reconstructed jets + bool isAtLeastOneJetSelected = false; for (const auto& jet : jets) { - // Retrieve constituents of the current jet - std::vector jetConstituents = jet.constituents(); - - // Estimate generator-level jet pT by summing pT of matched MC particles - double jetPtGen(0); - for (const auto& particle : jetConstituents) { - auto const& track = mcTracks.iteratorAt(particle.user_index()); - if (!track.has_mcParticle()) - continue; - const auto mcparticle = track.mcParticle(); - jetPtGen += mcparticle.pt(); - } - - // Jet must be fully contained in acceptance + // Jet must be fully contained in the acceptance if ((std::fabs(jet.eta()) + rJet) > (maxEta - deltaEtaEdge)) continue; - // Fill detector response matrix - registryMC.fill(HIST("detectorResponseMatrix"), jet.pt(), jetPtGen - jet.pt()); - registryMC.fill(HIST("generatedVsReconstructedPt"), jet.pt(), jetPtGen); - - // Subtract estimated background contribution from jet 4-momentum + // Jet pt must be larger than threshold auto jetForSub = jet; fastjet::PseudoJet jetMinusBkg = backgroundSub.doRhoAreaSub(jetForSub, rhoPerp, rhoMPerp); - - // Apply jet pT threshold - // if (getCorrectedPt(jetMinusBkg.pt(), responseMatrix) < minJetPt) if (jetMinusBkg.pt() < minJetPt) continue; + // Apply area cut if required + double normalizedJetArea = jet.area() / (PI * rJet * rJet); + if (applyAreaCut && normalizedJetArea > maxNormalizedJetArea) + continue; + isAtLeastOneJetSelected = true; + // Set up two perpendicular cone axes for underlying event estimation double coneRadius = std::sqrt(jet.area() / PI); TVector3 jetAxis(jet.px(), jet.py(), jet.pz()); @@ -1351,80 +1614,120 @@ struct AntinucleiInJets { getPerpendicularAxis(jetAxis, ueAxis1, +1); getPerpendicularAxis(jetAxis, ueAxis2, -1); - // Analyze antiproton candidates among jet constituents + // Get jet constituents + std::vector jetConstituents = jet.constituents(); + + // Loop over jet constituents for (const auto& particle : jetConstituents) { + + // Get corresponding track and apply track selection criteria auto const& track = mcTracks.iteratorAt(particle.user_index()); + if (!passedTrackSelection(track)) + continue; + + // Antimatter selection + if (track.sign() > 0) + continue; + + // Get corresponding MC particle if (!track.has_mcParticle()) continue; const auto mcparticle = track.mcParticle(); + // Define variables + double nsigmaTPCPr = track.tpcNSigmaPr(); + double nsigmaTOFPr = track.tofNSigmaPr(); + double pt = track.pt(); + double dcaxy = track.dcaXY(); + double dcaz = track.dcaZ(); + + // Fill nsigmaTOF template + if (track.hasTOF() && std::fabs(dcaxy) < maxDcaxy && std::fabs(dcaz) < maxDcaz && mcparticle.isPhysicalPrimary() && nsigmaTPCPr > minNsigmaTpc && nsigmaTPCPr < maxNsigmaTpc && mcparticle.pdgCode() != PDG_t::kProtonBar) { + registryMC.fill(HIST("antiproton_nsigma_tof_jet_mc"), pt, nsigmaTOFPr); + } + + // Antiproton selection based on the PDG + if (mcparticle.pdgCode() != PDG_t::kProtonBar) + continue; + // Fill DCA templates - if (mcparticle.pdgCode() == kProtonBar && passedTrackSelection(track) && std::fabs(track.dcaZ()) < maxDcaz) { + if (std::fabs(dcaz) < maxDcaz) { if (mcparticle.isPhysicalPrimary()) { - registryMC.fill(HIST("antiproton_prim_dca_jet"), track.pt(), track.dcaXY()); + registryMC.fill(HIST("antiproton_prim_dca_jet"), pt, dcaxy); } else { - registryMC.fill(HIST("antiproton_all_dca_jet"), track.pt(), track.dcaXY()); + registryMC.fill(HIST("antiproton_all_dca_jet"), pt, dcaxy); } } - // Apply standard track quality and PID selection - if (!passedTrackSelection(track) || std::fabs(track.dcaXY()) > maxDcaxy || std::fabs(track.dcaZ()) > maxDcaz) - continue; - if (track.sign() > 0 || mcparticle.pdgCode() != kProtonBar) + // Apply DCA selections + if (std::fabs(dcaxy) > maxDcaxy || std::fabs(dcaz) > maxDcaz) continue; - // PID variables - double nsigmaTPCPr = track.tpcNSigmaPr(); - double nsigmaTOFPr = track.tofNSigmaPr(); + // nsigmaITS for antiprotons + double nSigmaITSprot = static_cast(itsResponse.nSigmaITS(track)); - // particle identification using the ITS cluster size - double pt = track.pt(); + // Fill nsigmaITS for antiproton candidates + if (isHighPurityAntiproton(track)) { + registryMC.fill(HIST("antiproton_nsigma_its_mc"), pt, nSigmaITSprot); + } + + // Particle identification using the ITS cluster size bool passedItsPidProt(true); - double nSigmaITSprot = static_cast(itsResponse.nSigmaITS(track)); if (applyItsPid && pt < ptMaxItsPidProt && (nSigmaITSprot < nSigmaItsMin || nSigmaITSprot > nSigmaItsMax)) { passedItsPidProt = false; } - // Inclusive antiproton spectrum - registryMC.fill(HIST("antiproton_incl_jet"), track.pt()); + // Fill inclusive antiproton spectrum + registryMC.fill(HIST("antiproton_incl_jet"), pt); // Select physical primary antiprotons if (!mcparticle.isPhysicalPrimary()) continue; - registryMC.fill(HIST("antiproton_prim_jet"), track.pt()); + + // Fill antiproton spectrum for physical primaries + registryMC.fill(HIST("antiproton_prim_jet"), pt); // Fill histograms (TPC and TOF) only for selected candidates if (passedItsPidProt && nsigmaTPCPr > minNsigmaTpc && nsigmaTPCPr < maxNsigmaTpc) { - registryMC.fill(HIST("antiproton_recTpc_jet_antikt"), track.pt()); + registryMC.fill(HIST("antiproton_rec_tpc_jet"), pt); if (track.hasTOF() && nsigmaTOFPr > minNsigmaTof && nsigmaTOFPr < maxNsigmaTof) { - registryMC.fill(HIST("antiproton_recTof_jet_antikt"), track.pt()); + registryMC.fill(HIST("antiproton_rec_tof_jet"), pt); } } } - // Analyze antiprotons in the Underlying Event (UE) using perpendicular cones - for (auto const& track : mcTracks) { + // Loop over tracks in the underlying event + for (auto const& index : antiprotonTrackIndex) { + + // retrieve track associated to index + auto const& track = mcTracks.iteratorAt(index); + // Get corresponding MC particle if (!track.has_mcParticle()) continue; const auto mcparticle = track.mcParticle(); - if (track.sign() > 0 || mcparticle.pdgCode() != kProtonBar) - continue; + + // Define variables + double nsigmaTPCPr = track.tpcNSigmaPr(); + double nsigmaTOFPr = track.tofNSigmaPr(); + double pt = track.pt(); + double dcaxy = track.dcaXY(); + double dcaz = track.dcaZ(); // Fill DCA templates - if (mcparticle.pdgCode() == kProtonBar && passedTrackSelection(track) && std::fabs(track.dcaZ()) < maxDcaz) { + if (std::fabs(dcaz) < maxDcaz) { if (mcparticle.isPhysicalPrimary()) { - registryMC.fill(HIST("antiproton_prim_dca_ue"), track.pt(), track.dcaXY()); + registryMC.fill(HIST("antiproton_prim_dca_ue"), pt, dcaxy); } else { - registryMC.fill(HIST("antiproton_all_dca_ue"), track.pt(), track.dcaXY()); + registryMC.fill(HIST("antiproton_all_dca_ue"), pt, dcaxy); } } - // Track Selection - if (!passedTrackSelection(track) || std::fabs(track.dcaXY()) > maxDcaxy || std::fabs(track.dcaZ()) > maxDcaz) + // Apply DCA selection + if (std::fabs(dcaxy) > maxDcaxy || std::fabs(dcaz) > maxDcaz) continue; - // Compute distance from UE cones + // Calculate the angular distance between the track and underlying event axes in eta-phi space double deltaEtaUe1 = track.eta() - ueAxis1.Eta(); double deltaPhiUe1 = getDeltaPhi(track.phi(), ueAxis1.Phi()); double deltaRUe1 = std::sqrt(deltaEtaUe1 * deltaEtaUe1 + deltaPhiUe1 * deltaPhiUe1); @@ -1432,65 +1735,544 @@ struct AntinucleiInJets { double deltaPhiUe2 = getDeltaPhi(track.phi(), ueAxis2.Phi()); double deltaRUe2 = std::sqrt(deltaEtaUe2 * deltaEtaUe2 + deltaPhiUe2 * deltaPhiUe2); - // Require particle to be within at least one UE cone - if (deltaRUe1 > coneRadius && deltaRUe2 > coneRadius) - continue; + // Determine the maximum allowed distance from UE axes for particle selection + double maxConeRadius = coneRadius; + if (applyAreaCut) { + maxConeRadius = std::sqrt(maxNormalizedJetArea) * rJet; + } - // PID variables - double nsigmaTPCPr = track.tpcNSigmaPr(); - double nsigmaTOFPr = track.tofNSigmaPr(); + // Reject tracks that lie outside the maxConeRadius from both UE axes + if (deltaRUe1 > maxConeRadius && deltaRUe2 > maxConeRadius) + continue; - // particle identification using the ITS cluster size - double pt = track.pt(); + // Particle identification using the ITS cluster size bool passedItsPidProt(true); double nSigmaITSprot = static_cast(itsResponse.nSigmaITS(track)); if (applyItsPid && pt < ptMaxItsPidProt && (nSigmaITSprot < nSigmaItsMin || nSigmaITSprot > nSigmaItsMax)) { passedItsPidProt = false; } - registryMC.fill(HIST("antiproton_incl_ue"), track.pt()); + // Fill inclusive antiproton spectrum + registryMC.fill(HIST("antiproton_incl_ue"), pt); + + // Select physical primary antiprotons if (!mcparticle.isPhysicalPrimary()) continue; - registryMC.fill(HIST("antiproton_prim_ue"), track.pt()); - // Fill histograms in UE + // Fill antiproton spectrum for physical primaries + registryMC.fill(HIST("antiproton_prim_ue"), pt); + + // Fill histograms (TPC and TOF) only for selected candidates if (passedItsPidProt && nsigmaTPCPr > minNsigmaTpc && nsigmaTPCPr < maxNsigmaTpc) { - registryMC.fill(HIST("antiproton_recTpc_ue_antikt"), track.pt()); + registryMC.fill(HIST("antiproton_rec_tpc_ue"), pt); if (track.hasTOF() && nsigmaTOFPr > minNsigmaTof && nsigmaTOFPr < maxNsigmaTof) { - registryMC.fill(HIST("antiproton_recTof_ue_antikt"), track.pt()); + registryMC.fill(HIST("antiproton_rec_tof_ue"), pt); } } } } + if (isAtLeastOneJetSelected) { + registryMC.fill(HIST("recEvents"), 9.5); + } } } PROCESS_SWITCH(AntinucleiInJets, processJetsMCrec, "process jets MC rec", false); - // Process Systematics - void processSystematicsData(SelectedCollisions::iterator const& collision, FullNucleiTracks const& tracks) + // Process real data with systematic variations of analysis parameters + void processSystData(SelectedCollisions::iterator const& collision, AntiNucleiTracks const& tracks) { - if (rejectEvents) { - // event counter: before event rejection - registryData.fill(HIST("number_of_rejected_events_syst"), 0.5); + // Event counter: before event selection + registryData.fill(HIST("number_of_events_data_syst"), 0.5); + + // Apply standard event selection + if (!collision.sel8() || std::fabs(collision.posZ()) > zVtx) + return; + + // Event counter: after event selection + registryData.fill(HIST("number_of_events_data_syst"), 1.5); + + // Reject events near the ITS Read-Out Frame border + if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) + return; + registryData.fill(HIST("number_of_events_data_syst"), 2.5); + + // Reject events at the Time Frame border + if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) + return; + registryData.fill(HIST("number_of_events_data_syst"), 3.5); + + // Require at least one ITS-TPC matched track + if (requireVtxITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) + return; + registryData.fill(HIST("number_of_events_data_syst"), 4.5); + + // Reject events with same-bunch pileup + if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + return; + registryData.fill(HIST("number_of_events_data_syst"), 5.5); + + // Require consistent FT0 vs PV z-vertex + if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + return; + registryData.fill(HIST("number_of_events_data_syst"), 6.5); + + // Require TOF match for at least one vertex track + if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) + return; + registryData.fill(HIST("number_of_events_data_syst"), 7.5); + + // Cut settings + static std::vector maxDcaxySyst = { + 0.071, 0.060, 0.066, 0.031, 0.052, 0.078, 0.045, 0.064, 0.036, 0.074, + 0.079, 0.043, 0.067, 0.059, 0.032, 0.070, 0.048, 0.077, 0.062, 0.034, + 0.057, 0.055, 0.073, 0.038, 0.050, 0.075, 0.041, 0.061, 0.033, 0.069, + 0.035, 0.044, 0.076, 0.049, 0.037, 0.054, 0.072, 0.046, 0.058, 0.040, + 0.068, 0.042, 0.056, 0.039, 0.047, 0.065, 0.051, 0.053, 0.063, 0.030}; + + static std::vector maxDcazSyst = { + 0.064, 0.047, 0.032, 0.076, 0.039, 0.058, 0.043, 0.069, 0.050, 0.035, + 0.074, 0.061, 0.045, 0.033, 0.068, 0.055, 0.037, 0.071, 0.042, 0.053, + 0.077, 0.038, 0.065, 0.049, 0.036, 0.059, 0.044, 0.067, 0.041, 0.034, + 0.073, 0.052, 0.040, 0.063, 0.046, 0.031, 0.070, 0.054, 0.037, 0.062, + 0.048, 0.035, 0.075, 0.051, 0.039, 0.066, 0.043, 0.060, 0.032, 0.056}; + + static std::vector nSigmaItsMinSyst = { + -2.9, -2.8, -3.0, -3.4, -2.7, -3.3, -3.0, -3.1, -3.4, -3.1, + -3.0, -2.8, -3.2, -2.6, -2.7, -3.4, -2.9, -3.0, -3.0, -2.7, + -2.9, -3.3, -3.0, -3.1, -3.2, -3.0, -2.9, -2.7, -3.3, -3.0, + -2.8, -3.3, -2.7, -3.3, -2.8, -3.4, -2.8, -3.4, -2.9, -3.1, + -3.2, -2.6, -3.1, -2.9, -3.1, -2.8, -2.9, -3.3, -3.0, -2.8}; + + static std::vector nSigmaItsMaxSyst = { + 2.9, 2.8, 3.0, 3.4, 2.7, 3.3, 3.0, 3.1, 3.4, 3.1, + 3.0, 2.8, 3.2, 2.6, 2.7, 3.4, 2.9, 3.0, 3.0, 2.7, + 2.9, 3.3, 3.0, 3.1, 3.2, 3.0, 2.9, 2.7, 3.3, 3.0, + 2.8, 3.3, 2.7, 3.3, 2.8, 3.4, 2.8, 3.4, 2.9, 3.1, + 3.2, 2.6, 3.1, 2.9, 3.1, 2.8, 2.9, 3.3, 3.0, 2.8}; + + static std::vector minNsigmaTpcSyst = { + -3.2, -2.9, -3.1, -2.9, -3.5, -2.6, -3.3, -3.0, -3.5, -2.7, + -3.0, -2.6, -3.3, -3.4, -2.8, -3.1, -2.6, -3.2, -3.1, -2.8, + -3.4, -2.7, -3.4, -2.9, -3.0, -2.5, -3.3, -2.8, -3.1, -2.7, + -3.4, -2.8, -3.3, -2.6, -3.1, -2.5, -3.4, -3.0, -3.2, -2.6, + -3.4, -2.8, -3.1, -2.6, -3.3, -2.7, -3.2, -2.7, -3.4, -2.9}; + + static std::vector maxNsigmaTpcSyst = { + 3.2, 2.9, 3.1, 2.9, 3.5, 2.6, 3.3, 3.0, 3.5, 2.7, + 3.0, 2.6, 3.3, 3.4, 2.8, 3.1, 2.6, 3.2, 3.1, 2.8, + 3.4, 2.7, 3.4, 2.9, 3.0, 2.5, 3.3, 2.8, 3.1, 2.7, + 3.4, 2.8, 3.3, 2.6, 3.1, 2.5, 3.4, 3.0, 3.2, 2.6, + 3.4, 2.8, 3.1, 2.6, 3.3, 2.7, 3.2, 2.7, 3.4, 2.9}; + + // Loop over reconstructed tracks + for (auto const& track : tracks) { + + // Select only antimatter + if (track.sign() > 0) + continue; + + // Loop over different cut settings + for (int isyst = 0; isyst < nSyst; isyst++) { + + // Apply track selection + if (!passedTrackSelectionSyst(track, isyst)) + continue; + + // Define variables + double nsigmaTPCPr = track.tpcNSigmaPr(); + double nsigmaTOFPr = track.tofNSigmaPr(); + double nsigmaTPCDe = track.tpcNSigmaDe(); + double nsigmaTOFDe = track.tofNSigmaDe(); + double nsigmaTPCHe = track.tpcNSigmaHe(); + double pt = track.pt(); + double dcaxy = track.dcaXY(); + double dcaz = track.dcaZ(); + + // Apply DCA selections + if (std::fabs(dcaxy) > maxDcaxySyst[isyst] || std::fabs(dcaz) > maxDcazSyst[isyst]) + continue; + + // Particle identification using the ITS cluster size (vary also PID ITS) + bool passedItsPidProt(true), passedItsPidDeut(true), passedItsPidHel(true); + double nSigmaITSprot = static_cast(itsResponse.nSigmaITS(track)); + double nSigmaITSdeut = static_cast(itsResponse.nSigmaITS(track)); + double nSigmaITShel3 = static_cast(itsResponse.nSigmaITS(track)); + + if (applyItsPid && pt < ptMaxItsPidProt && (nSigmaITSprot < nSigmaItsMinSyst[isyst] || nSigmaITSprot > nSigmaItsMaxSyst[isyst])) { + passedItsPidProt = false; + } + if (applyItsPid && pt < ptMaxItsPidDeut && (nSigmaITSdeut < nSigmaItsMinSyst[isyst] || nSigmaITSdeut > nSigmaItsMaxSyst[isyst])) { + passedItsPidDeut = false; + } + if (applyItsPid && (2.0 * pt) < ptMaxItsPidHel && (nSigmaITShel3 < nSigmaItsMinSyst[isyst] || nSigmaITShel3 > nSigmaItsMaxSyst[isyst])) { + passedItsPidHel = false; + } + + // Fill histograms + if (passedItsPidProt) { + registryData.fill(HIST("antiproton_tpc_syst"), isyst, pt, nsigmaTPCPr); + if (nsigmaTPCPr > minNsigmaTpcSyst[isyst] && nsigmaTPCPr < maxNsigmaTpcSyst[isyst] && track.hasTOF()) + registryData.fill(HIST("antiproton_tof_syst"), isyst, pt, nsigmaTOFPr); + } + if (passedItsPidDeut) { + registryData.fill(HIST("antideuteron_tpc_syst"), isyst, pt, nsigmaTPCDe); + if (nsigmaTPCDe > minNsigmaTpcSyst[isyst] && nsigmaTPCDe < maxNsigmaTpcSyst[isyst] && track.hasTOF()) + registryData.fill(HIST("antideuteron_tof_syst"), isyst, pt, nsigmaTOFDe); + } + if (passedItsPidHel) { + registryData.fill(HIST("antihelium3_tpc_syst"), isyst, 2.0 * pt, nsigmaTPCHe); + } + } + } + } + PROCESS_SWITCH(AntinucleiInJets, processSystData, "Process syst data", false); + + // Process MC with systematic variations of analysis parameters + void processSystEff(GenCollisionsMc const& genCollisions, RecCollisionsMc const& recCollisions, AntiNucleiTracksMc const& mcTracks, aod::McParticles const& mcParticles) + { + // Cut settings + static std::vector maxDcaxySyst = { + 0.071, 0.060, 0.066, 0.031, 0.052, 0.078, 0.045, 0.064, 0.036, 0.074, + 0.079, 0.043, 0.067, 0.059, 0.032, 0.070, 0.048, 0.077, 0.062, 0.034, + 0.057, 0.055, 0.073, 0.038, 0.050, 0.075, 0.041, 0.061, 0.033, 0.069, + 0.035, 0.044, 0.076, 0.049, 0.037, 0.054, 0.072, 0.046, 0.058, 0.040, + 0.068, 0.042, 0.056, 0.039, 0.047, 0.065, 0.051, 0.053, 0.063, 0.030}; + + static std::vector maxDcazSyst = { + 0.064, 0.047, 0.032, 0.076, 0.039, 0.058, 0.043, 0.069, 0.050, 0.035, + 0.074, 0.061, 0.045, 0.033, 0.068, 0.055, 0.037, 0.071, 0.042, 0.053, + 0.077, 0.038, 0.065, 0.049, 0.036, 0.059, 0.044, 0.067, 0.041, 0.034, + 0.073, 0.052, 0.040, 0.063, 0.046, 0.031, 0.070, 0.054, 0.037, 0.062, + 0.048, 0.035, 0.075, 0.051, 0.039, 0.066, 0.043, 0.060, 0.032, 0.056}; + + static std::vector nSigmaItsMinSyst = { + -2.9, -2.8, -3.0, -3.4, -2.7, -3.3, -3.0, -3.1, -3.4, -3.1, + -3.0, -2.8, -3.2, -2.6, -2.7, -3.4, -2.9, -3.0, -3.0, -2.7, + -2.9, -3.3, -3.0, -3.1, -3.2, -3.0, -2.9, -2.7, -3.3, -3.0, + -2.8, -3.3, -2.7, -3.3, -2.8, -3.4, -2.8, -3.4, -2.9, -3.1, + -3.2, -2.6, -3.1, -2.9, -3.1, -2.8, -2.9, -3.3, -3.0, -2.8}; + + static std::vector nSigmaItsMaxSyst = { + 2.9, 2.8, 3.0, 3.4, 2.7, 3.3, 3.0, 3.1, 3.4, 3.1, + 3.0, 2.8, 3.2, 2.6, 2.7, 3.4, 2.9, 3.0, 3.0, 2.7, + 2.9, 3.3, 3.0, 3.1, 3.2, 3.0, 2.9, 2.7, 3.3, 3.0, + 2.8, 3.3, 2.7, 3.3, 2.8, 3.4, 2.8, 3.4, 2.9, 3.1, + 3.2, 2.6, 3.1, 2.9, 3.1, 2.8, 2.9, 3.3, 3.0, 2.8}; + + static std::vector minNsigmaTpcSyst = { + -3.2, -2.9, -3.1, -2.9, -3.5, -2.6, -3.3, -3.0, -3.5, -2.7, + -3.0, -2.6, -3.3, -3.4, -2.8, -3.1, -2.6, -3.2, -3.1, -2.8, + -3.4, -2.7, -3.4, -2.9, -3.0, -2.5, -3.3, -2.8, -3.1, -2.7, + -3.4, -2.8, -3.3, -2.6, -3.1, -2.5, -3.4, -3.0, -3.2, -2.6, + -3.4, -2.8, -3.1, -2.6, -3.3, -2.7, -3.2, -2.7, -3.4, -2.9}; + + static std::vector maxNsigmaTpcSyst = { + 3.2, 2.9, 3.1, 2.9, 3.5, 2.6, 3.3, 3.0, 3.5, 2.7, + 3.0, 2.6, 3.3, 3.4, 2.8, 3.1, 2.6, 3.2, 3.1, 2.8, + 3.4, 2.7, 3.4, 2.9, 3.0, 2.5, 3.3, 2.8, 3.1, 2.7, + 3.4, 2.8, 3.3, 2.6, 3.1, 2.5, 3.4, 3.0, 3.2, 2.6, + 3.4, 2.8, 3.1, 2.6, 3.3, 2.7, 3.2, 2.7, 3.4, 2.9}; + + static std::vector minNsigmaTofSyst = { + -3.2, -2.9, -3.1, -2.9, -3.5, -2.6, -3.3, -3.0, -3.5, -2.7, + -3.0, -2.6, -3.3, -3.4, -2.8, -3.1, -2.6, -3.2, -3.1, -2.8, + -3.4, -2.7, -3.4, -2.9, -3.0, -2.5, -3.3, -2.8, -3.1, -2.7, + -3.4, -2.8, -3.3, -2.6, -3.1, -2.5, -3.4, -3.0, -3.2, -2.6, + -3.4, -2.8, -3.1, -2.6, -3.3, -2.7, -3.2, -2.7, -3.4, -2.9}; + + static std::vector maxNsigmaTofSyst = { + 3.9, 3.6, 3.8, 3.2, 3.2, 3.5, 3.1, 3.8, 3.5, 3.4, + 3.9, 3.8, 3.7, 3.0, 3.6, 3.1, 3.7, 3.4, 4.0, 3.0, + 3.7, 3.3, 3.9, 3.1, 3.3, 3.5, 3.6, 3.2, 3.5, 3.3, + 3.9, 3.0, 3.4, 3.2, 3.1, 3.9, 3.6, 3.1, 3.2, 4.0, + 3.1, 3.7, 3.6, 3.1, 3.3, 3.5, 3.3, 3.4, 3.1, 3.8}; + + // Loop over generated collisions + for (const auto& collision : genCollisions) { + + // Apply event selection: require vertex position to be within the allowed z range + if (std::fabs(collision.posZ()) > zVtx) + continue; + + // Loop over all generated Monte Carlo particles for the selected event + for (const auto& particle : mcParticles) { + + // Select primary particles + if (!particle.isPhysicalPrimary()) + continue; + + // Select particles within the specified pseudorapidity interval + if (particle.eta() < minEta || particle.eta() > maxEta) + continue; + + // Process different particle species based on PDG code + switch (particle.pdgCode()) { + case PDG_t::kProtonBar: + registryMC.fill(HIST("antiproton_gen_syst"), particle.pt()); + break; + case -o2::constants::physics::Pdg::kDeuteron: + registryMC.fill(HIST("antideuteron_gen_syst"), particle.pt()); + break; + case -o2::constants::physics::Pdg::kHelium3: + registryMC.fill(HIST("antihelium3_gen_syst"), particle.pt()); + break; + } + } + } + + // Loop over reconstructed collisions + for (const auto& collision : recCollisions) { + + // Apply standard event selection + if (!collision.sel8() || std::fabs(collision.posZ()) > zVtx) + continue; + + // Reject events near the ITS Read-Out Frame border + if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) + continue; + + // Reject events at the Time Frame border + if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) + continue; + + // Require at least one ITS-TPC matched track + if (requireVtxITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) + continue; + + // Reject events with same-bunch pileup + if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + continue; + + // Require consistent FT0 vs PV z-vertex + if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + continue; - if (shouldRejectEvent()) - return; + // Require TOF match for at least one vertex track + if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) + continue; + + // Loop over reconstructed tracks + for (auto const& track : mcTracks) { + + // Select only antimatter + if (track.sign() > 0) + continue; + + // Get corresponding MC particle + if (!track.has_mcParticle()) + continue; + const auto mcparticle = track.mcParticle(); + + // Loop over different cut settings + for (int isyst = 0; isyst < nSyst; isyst++) { + + // Apply track selection + if (!passedTrackSelectionSyst(track, isyst)) + continue; + + // Define variables + double nsigmaTPCPr = track.tpcNSigmaPr(); + double nsigmaTOFPr = track.tofNSigmaPr(); + double nsigmaTPCDe = track.tpcNSigmaDe(); + double nsigmaTOFDe = track.tofNSigmaDe(); + double nsigmaTPCHe = track.tpcNSigmaHe(); + double pt = track.pt(); + double dcaxy = track.dcaXY(); + double dcaz = track.dcaZ(); - // event counter: after event rejection - registryData.fill(HIST("number_of_rejected_events_syst"), 1.5); + // Apply DCA selections + if (std::fabs(dcaxy) > maxDcaxySyst[isyst] || std::fabs(dcaz) > maxDcazSyst[isyst]) + continue; + + // Fill inclusive antiproton spectrum + registryMC.fill(HIST("antiproton_incl_syst"), isyst, pt); + + // Select physical primary antiprotons + if (!mcparticle.isPhysicalPrimary()) + continue; + + // Fill antiproton spectrum for physical primaries + registryMC.fill(HIST("antiproton_prim_syst"), isyst, pt); + + // Particle identification using the ITS cluster size (vary also PID ITS) + bool passedItsPidProt(true), passedItsPidDeut(true), passedItsPidHel(true); + double nSigmaITSprot = static_cast(itsResponse.nSigmaITS(track)); + double nSigmaITSdeut = static_cast(itsResponse.nSigmaITS(track)); + double nSigmaITShel3 = static_cast(itsResponse.nSigmaITS(track)); + + if (applyItsPid && pt < ptMaxItsPidProt && (nSigmaITSprot < nSigmaItsMinSyst[isyst] || nSigmaITSprot > nSigmaItsMaxSyst[isyst])) { + passedItsPidProt = false; + } + if (applyItsPid && pt < ptMaxItsPidDeut && (nSigmaITSdeut < nSigmaItsMinSyst[isyst] || nSigmaITSdeut > nSigmaItsMaxSyst[isyst])) { + passedItsPidDeut = false; + } + if (applyItsPid && (2.0 * pt) < ptMaxItsPidHel && (nSigmaITShel3 < nSigmaItsMinSyst[isyst] || nSigmaITShel3 > nSigmaItsMaxSyst[isyst])) { + passedItsPidHel = false; + } + + // Fill histograms for antiprotons + if (passedItsPidProt && mcparticle.pdgCode() == PDG_t::kProtonBar && nsigmaTPCPr > minNsigmaTpcSyst[isyst] && nsigmaTPCPr < maxNsigmaTpcSyst[isyst]) { + registryMC.fill(HIST("antiproton_rec_tpc_syst"), isyst, pt); + if (track.hasTOF() && nsigmaTOFPr > minNsigmaTofSyst[isyst] && nsigmaTOFPr < maxNsigmaTofSyst[isyst]) + registryMC.fill(HIST("antiproton_rec_tof_syst"), isyst, pt); + } + // Fill histograms for antideuterons + if (passedItsPidDeut && mcparticle.pdgCode() == -o2::constants::physics::Pdg::kDeuteron && nsigmaTPCDe > minNsigmaTpcSyst[isyst] && nsigmaTPCDe < maxNsigmaTpcSyst[isyst]) { + registryMC.fill(HIST("antideuteron_rec_tpc_syst"), isyst, pt); + if (track.hasTOF() && nsigmaTOFDe > minNsigmaTofSyst[isyst] && nsigmaTOFDe < maxNsigmaTofSyst[isyst]) + registryMC.fill(HIST("antideuteron_rec_tof_syst"), isyst, pt); + } + // Fill histograms for antihelium3 + if (passedItsPidHel && mcparticle.pdgCode() == -o2::constants::physics::Pdg::kHelium3 && nsigmaTPCHe > minNsigmaTpcSyst[isyst] && nsigmaTPCHe < maxNsigmaTpcSyst[isyst]) { + registryMC.fill(HIST("antihelium3_rec_tpc_syst"), isyst, 2.0 * pt); + } + } + } } + } + PROCESS_SWITCH(AntinucleiInJets, processSystEff, "process syst mc", false); - const int nSystematics = 10; - int itsNclustersSyst[nSystematics] = {5, 6, 5, 4, 5, 3, 5, 6, 3, 4}; - float tpcNcrossedRowsSyst[nSystematics] = {100, 85, 80, 110, 95, 90, 105, 95, 100, 105}; - float dcaxySyst[nSystematics] = {0.05, 0.07, 0.10, 0.03, 0.06, 0.15, 0.08, 0.04, 0.09, 0.10}; - float dcazSyst[nSystematics] = {0.1, 0.15, 0.3, 0.075, 0.12, 0.18, 0.2, 0.1, 0.15, 0.2}; + // Process correlation + void processCorr(SelectedCollisions::iterator const& collision, AntiNucleiTracks const& tracks) + { + // Event counter: before event selection + registryCorr.fill(HIST("eventCounter"), 0.5); - // event selection + // Apply standard event selection if (!collision.sel8() || std::fabs(collision.posZ()) > zVtx) return; - // loop over reconstructed tracks + // Event counter: after event selection + registryCorr.fill(HIST("eventCounter"), 1.5); + + // Reject events near the ITS Read-Out Frame border + if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) + return; + registryCorr.fill(HIST("eventCounter"), 2.5); + + // Reject events at the Time Frame border + if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) + return; + registryCorr.fill(HIST("eventCounter"), 3.5); + + // Require at least one ITS-TPC matched track + if (requireVtxITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) + return; + registryCorr.fill(HIST("eventCounter"), 4.5); + + // Reject events with same-bunch pileup + if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + return; + registryCorr.fill(HIST("eventCounter"), 5.5); + + // Require consistent FT0 vs PV z-vertex + if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + return; + registryCorr.fill(HIST("eventCounter"), 6.5); + + // Require TOF match for at least one vertex track + if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) + return; + registryCorr.fill(HIST("eventCounter"), 7.5); + + // Multiplicity percentile + const float multiplicity = collision.centFT0M(); + + // pt/A bins + std::vector ptOverAbins = {0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}; + const int nBins = ptOverAbins.size() - 1; + + // Particle counters + std::vector nAntiprotonFullEvent(nBins, 0); + std::vector nAntideuteronFullEvent(nBins, 0); + int nTotProtonFullEvent(0); + int nTotDeuteronFullEvent(0); + int nTotAntiprotonFullEvent(0); + int nTotAntideuteronFullEvent(0); + + // Loop over reconstructed tracks + for (auto const& track : tracks) { + + // Apply track selection + if (!passedTrackSelection(track)) + continue; + + // Apply DCA selections + if (std::fabs(track.dcaXY()) > maxDcaxy || std::fabs(track.dcaZ()) > maxDcaz) + continue; + + // Particle identification using the ITS cluster size + bool passedItsPidProt(true), passedItsPidDeut(true); + double nSigmaITSprot = static_cast(itsResponse.nSigmaITS(track)); + double nSigmaITSdeut = static_cast(itsResponse.nSigmaITS(track)); + + if (applyItsPid && track.pt() < ptMaxItsPidProt && (nSigmaITSprot < nSigmaItsMin || nSigmaITSprot > nSigmaItsMax)) { + passedItsPidProt = false; + } + if (applyItsPid && track.pt() < ptMaxItsPidDeut && (nSigmaITSdeut < nSigmaItsMin || nSigmaITSdeut > nSigmaItsMax)) { + passedItsPidDeut = false; + } + + // Kinematic range selection + if (isProton(track) && passedItsPidProt) { + if (track.pt() < ptOverAbins[0] || track.pt() >= ptOverAbins[nBins]) { + continue; + } + } else if (isDeuteron(track) && passedItsPidDeut) { + double ptPerNucleon = 0.5 * track.pt(); + if (ptPerNucleon < ptOverAbins[0] || ptPerNucleon >= ptOverAbins[nBins]) { + continue; + } + } else { + continue; + } + + // (Anti)protons + if (isProton(track) && passedItsPidProt) { + if (track.sign() > 0) { + nTotProtonFullEvent++; + } else if (track.sign() < 0) { + nTotAntiprotonFullEvent++; + int ibin = findBin(ptOverAbins, track.pt()); + nAntiprotonFullEvent[ibin]++; + } + } + + // (Anti)deuterons + if (isDeuteron(track) && passedItsPidDeut) { + const double ptPerNucleon = 0.5 * track.pt(); + + if (track.sign() > 0) { + nTotDeuteronFullEvent++; + } else if (track.sign() < 0) { + nTotAntideuteronFullEvent++; + int ibin = findBin(ptOverAbins, ptPerNucleon); + nAntideuteronFullEvent[ibin]++; + } + } + } + + // Fill correlation histograms + int netProtonFullEvent = nTotProtonFullEvent - nTotAntiprotonFullEvent; + int netDeuteronFullEvent = nTotDeuteronFullEvent - nTotAntideuteronFullEvent; + registryCorr.fill(HIST("rho_fullEvent"), nTotAntideuteronFullEvent, nTotAntiprotonFullEvent, multiplicity); + registryCorr.fill(HIST("rho_netP_netD_fullEvent"), netDeuteronFullEvent, netProtonFullEvent); + + // Fill efficiency histograms + for (int i = 0; i < nBins; i++) { + double ptAcenteri = 0.5 * (ptOverAbins[i] + ptOverAbins[i + 1]); + + registryCorr.fill(HIST("q1d_fullEvent"), nAntideuteronFullEvent[i], ptAcenteri); + registryCorr.fill(HIST("q1p_fullEvent"), nAntiprotonFullEvent[i], ptAcenteri); + for (int j = 0; j < nBins; j++) { + double ptAcenterj = 0.5 * (ptOverAbins[j] + ptOverAbins[j + 1]); + registryCorr.fill(HIST("q1d_square_fullEvent"), ptAcenteri, ptAcenterj, nAntideuteronFullEvent[i] * nAntideuteronFullEvent[j]); + registryCorr.fill(HIST("q1p_square_fullEvent"), ptAcenteri, ptAcenterj, nAntiprotonFullEvent[i] * nAntiprotonFullEvent[j]); + registryCorr.fill(HIST("q1d_q1p_fullEvent"), ptAcenteri, ptAcenterj, nAntideuteronFullEvent[i] * nAntiprotonFullEvent[j]); + } + } + + // Loop over reconstructed tracks (refactoring: this part can be incorporated above) int id(-1); std::vector fjParticles; for (auto const& track : tracks) { @@ -1504,228 +2286,254 @@ struct AntinucleiInJets { fjParticles.emplace_back(fourMomentum); } - // reject empty events - if (fjParticles.size() < 1) + // Reject empty events + if (fjParticles.empty()) return; + registryCorr.fill(HIST("eventCounter"), 8.5); - // cluster particles using the anti-kt algorithm + // Cluster particles using the anti-kt algorithm fastjet::JetDefinition jetDef(fastjet::antikt_algorithm, rJet); - fastjet::AreaDefinition areaDef(fastjet::active_area, fastjet::GhostedAreaSpec(1.0)); // active_area_explicit_ghosts + fastjet::AreaDefinition areaDef(fastjet::active_area, fastjet::GhostedAreaSpec(1.0)); fastjet::ClusterSequenceArea cs(fjParticles, jetDef, areaDef); std::vector jets = fastjet::sorted_by_pt(cs.inclusive_jets()); auto [rhoPerp, rhoMPerp] = backgroundSub.estimateRhoPerpCone(fjParticles, jets); - // loop over reconstructed jets + // Loop over reconstructed jets + bool isAtLeastOneJetSelected = false; for (const auto& jet : jets) { - // jet must be fully contained in the acceptance + // Jet must be fully contained in the acceptance if ((std::fabs(jet.eta()) + rJet) > (maxEta - deltaEtaEdge)) continue; - // jet pt must be larger than threshold + // Jet pt must be larger than threshold auto jetForSub = jet; fastjet::PseudoJet jetMinusBkg = backgroundSub.doRhoAreaSub(jetForSub, rhoPerp, rhoMPerp); - if (getCorrectedPt(jetMinusBkg.pt(), responseMatrix) < minJetPt) + if (jetMinusBkg.pt() < minJetPt) continue; - // get jet constituents + // Apply area cut if required + double normalizedJetArea = jet.area() / (PI * rJet * rJet); + if (applyAreaCut && normalizedJetArea > maxNormalizedJetArea) + continue; + isAtLeastOneJetSelected = true; + + // Perpendicular cones + double coneRadius = std::sqrt(jet.area() / PI); + TVector3 jetAxis(jet.px(), jet.py(), jet.pz()); + TVector3 ueAxis1(0, 0, 0); + TVector3 ueAxis2(0, 0, 0); + getPerpendicularAxis(jetAxis, ueAxis1, +1); + getPerpendicularAxis(jetAxis, ueAxis2, -1); + + // Get jet constituents std::vector jetConstituents = jet.constituents(); - o2::aod::ITSResponse itsResponse; - // loop over jet constituents + // Particle counters + std::vector nAntiprotonJet(nBins, 0); + std::vector nAntideuteronJet(nBins, 0); + int nTotProtonJet(0); + int nTotDeuteronJet(0); + int nTotAntiprotonJet(0); + int nTotAntideuteronJet(0); + + // Loop over jet constituents for (const auto& particle : jetConstituents) { - for (int i = 0; i < nSystematics; i++) { - // get corresponding track and apply track selection criteria - auto const& track = tracks.iteratorAt(particle.user_index()); - // variables - double nsigmaTPCPr = track.tpcNSigmaPr(); - double nsigmaTOFPr = track.tofNSigmaPr(); - double nsigmaTPCDe = track.tpcNSigmaDe(); - double nsigmaTOFDe = track.tofNSigmaDe(); - double pt = track.pt(); - double dcaxy = track.dcaXY(); - double dcaz = track.dcaZ(); + // Get corresponding track and apply track selection criteria + auto const& track = tracks.iteratorAt(particle.user_index()); + if (!passedTrackSelection(track)) + continue; - if (requirePvContributor && !(track.isPVContributor())) - continue; - if (!track.hasITS()) - continue; - if (track.itsNCls() < itsNclustersSyst[i]) - continue; - if (!track.hasTPC()) - continue; - if (track.tpcNClsCrossedRows() < tpcNcrossedRowsSyst[i]) - continue; - if (track.tpcChi2NCl() > maxChiSquareTpc) - continue; - if (track.itsChi2NCl() > maxChiSquareIts) - continue; - if (track.eta() < minEta || track.eta() > maxEta) - continue; - if (track.pt() < minPt) - continue; - if (std::fabs(dcaxy) > dcaxySyst[i]) - continue; - if (std::fabs(dcaz) > dcazSyst[i]) - continue; + // Apply DCA selections + if (std::fabs(track.dcaXY()) > maxDcaxy || std::fabs(track.dcaZ()) > maxDcaz) + continue; - bool passedItsPidProt(false), passedItsPidDeut(false); - if (itsResponse.nSigmaITS(track) > nSigmaItsMin && itsResponse.nSigmaITS(track) < nSigmaItsMax) { - passedItsPidProt = true; - } - if (itsResponse.nSigmaITS(track) > nSigmaItsMin && itsResponse.nSigmaITS(track) < nSigmaItsMax) { - passedItsPidDeut = true; + // Particle identification using the ITS cluster size + bool passedItsPidProt(true), passedItsPidDeut(true); + double nSigmaITSprot = static_cast(itsResponse.nSigmaITS(track)); + double nSigmaITSdeut = static_cast(itsResponse.nSigmaITS(track)); + + if (applyItsPid && track.pt() < ptMaxItsPidProt && (nSigmaITSprot < nSigmaItsMin || nSigmaITSprot > nSigmaItsMax)) { + passedItsPidProt = false; + } + if (applyItsPid && track.pt() < ptMaxItsPidDeut && (nSigmaITSdeut < nSigmaItsMin || nSigmaITSdeut > nSigmaItsMax)) { + passedItsPidDeut = false; + } + + // Kinematic range selection + if (isProton(track) && passedItsPidProt) { + if (track.pt() < ptOverAbins[0] || track.pt() >= ptOverAbins[nBins]) { + continue; } - if (!applyItsPid) { - passedItsPidProt = true; - passedItsPidDeut = true; + } else if (isDeuteron(track) && passedItsPidDeut) { + double ptPerNucleon = 0.5 * track.pt(); + if (ptPerNucleon < ptOverAbins[0] || ptPerNucleon >= ptOverAbins[nBins]) { + continue; } - if (pt > ptMaxItsPidProt) - passedItsPidProt = true; - if (pt > ptMaxItsPidDeut) - passedItsPidDeut = true; - - // antimatter - if (track.sign() < 0) { - if (passedItsPidProt) { - registryData.fill(HIST("antiproton_tpc_syst"), pt, nsigmaTPCPr, i); - if (nsigmaTPCPr > minNsigmaTpc && nsigmaTPCPr < maxNsigmaTpc && track.hasTOF()) - registryData.fill(HIST("antiproton_tof_syst"), pt, nsigmaTOFPr, i); - } - if (passedItsPidDeut) { - registryData.fill(HIST("antideuteron_tpc_syst"), pt, nsigmaTPCDe, i); - if (nsigmaTPCDe > minNsigmaTpc && nsigmaTPCDe < maxNsigmaTpc && track.hasTOF()) - registryData.fill(HIST("antideuteron_tof_syst"), pt, nsigmaTOFDe, i); - } + } else { + continue; + } + + // (Anti)protons + if (isProton(track) && passedItsPidProt) { + if (track.sign() > 0) { + nTotProtonJet++; + } else if (track.sign() < 0) { + nTotAntiprotonJet++; + int ibin = findBin(ptOverAbins, track.pt()); + nAntiprotonJet[ibin]++; } } - } - } - } - PROCESS_SWITCH(AntinucleiInJets, processSystematicsData, "Process Systematics", false); - void processSystematicsEfficiency(SimCollisions const& collisions, MCTracks const& mcTracks, aod::McParticles const& mcParticles) - { - const int nSystematics = 10; - int itsNclustersSyst[nSystematics] = {5, 6, 5, 4, 5, 3, 5, 6, 3, 4}; - float tpcNcrossedRowsSyst[nSystematics] = {100, 85, 80, 110, 95, 90, 105, 95, 100, 105}; - float dcaxySyst[nSystematics] = {0.05, 0.07, 0.10, 0.03, 0.06, 0.15, 0.08, 0.04, 0.09, 0.10}; - float dcazSyst[nSystematics] = {0.1, 0.15, 0.3, 0.075, 0.12, 0.18, 0.2, 0.1, 0.15, 0.2}; + // (Anti)deuterons + if (isDeuteron(track) && passedItsPidDeut) { + const double ptPerNucleon = 0.5 * track.pt(); - for (const auto& collision : collisions) { + if (track.sign() > 0) { + nTotDeuteronJet++; + } else if (track.sign() < 0) { + nTotAntideuteronJet++; + int ibin = findBin(ptOverAbins, ptPerNucleon); + nAntideuteronJet[ibin]++; + } + } + } // end of loop over constituents + + // Fill correlation histograms + int netProtonJet = nTotProtonJet - nTotAntiprotonJet; + int netDeuteronJet = nTotDeuteronJet - nTotAntideuteronJet; + registryCorr.fill(HIST("rho_jet"), nTotAntideuteronJet, nTotAntiprotonJet, multiplicity); + registryCorr.fill(HIST("rho_netP_netD_jet"), netDeuteronJet, netProtonJet); + + // Fill efficiency histograms + for (int i = 0; i < nBins; i++) { + double ptAcenteri = 0.5 * (ptOverAbins[i] + ptOverAbins[i + 1]); + + registryCorr.fill(HIST("q1d_jet"), nAntideuteronJet[i], ptAcenteri); + registryCorr.fill(HIST("q1p_jet"), nAntiprotonJet[i], ptAcenteri); + for (int j = 0; j < nBins; j++) { + double ptAcenterj = 0.5 * (ptOverAbins[j] + ptOverAbins[j + 1]); + registryCorr.fill(HIST("q1d_square_jet"), ptAcenteri, ptAcenterj, nAntideuteronJet[i] * nAntideuteronJet[j]); + registryCorr.fill(HIST("q1p_square_jet"), ptAcenteri, ptAcenterj, nAntiprotonJet[i] * nAntiprotonJet[j]); + registryCorr.fill(HIST("q1d_q1p_jet"), ptAcenteri, ptAcenterj, nAntideuteronJet[i] * nAntiprotonJet[j]); + } + } - if (!collision.sel8() || std::fabs(collision.posZ()) > zVtx) - continue; + // Particle counters + std::vector nAntiprotonUE(nBins, 0); + std::vector nAntideuteronUE(nBins, 0); + int nTotProtonUE(0); + int nTotDeuteronUE(0); + int nTotAntiprotonUE(0); + int nTotAntideuteronUE(0); - // generated - for (const auto& particle : mcParticles) { + // Loop over tracks in the underlying event + for (auto const& track : tracks) { - if (!particle.isPhysicalPrimary()) + // Get corresponding track and apply track selection criteria + if (!passedTrackSelection(track)) continue; - if (particle.eta() < minEta || particle.eta() > maxEta) + // Apply DCA selections + if (std::fabs(track.dcaXY()) > maxDcaxy || std::fabs(track.dcaZ()) > maxDcaz) continue; - switch (particle.pdgCode()) { - case kProtonBar: - registryMC.fill(HIST("antiproton_incl_gen_syst"), particle.pt()); - break; - case -o2::constants::physics::Pdg::kDeuteron: - registryMC.fill(HIST("antideuteron_incl_gen_syst"), particle.pt()); - break; - } - } - - // ITS pid using cluster size - o2::aod::ITSResponse itsResponse; + // Calculate the angular distance between the track and underlying event axes in eta-phi space + double deltaEtaUe1 = track.eta() - ueAxis1.Eta(); + double deltaPhiUe1 = getDeltaPhi(track.phi(), ueAxis1.Phi()); + double deltaRUe1 = std::sqrt(deltaEtaUe1 * deltaEtaUe1 + deltaPhiUe1 * deltaPhiUe1); + double deltaEtaUe2 = track.eta() - ueAxis2.Eta(); + double deltaPhiUe2 = getDeltaPhi(track.phi(), ueAxis2.Phi()); + double deltaRUe2 = std::sqrt(deltaEtaUe2 * deltaEtaUe2 + deltaPhiUe2 * deltaPhiUe2); - // Reconstructed Tracks - for (auto const& track : mcTracks) { + // Determine the maximum allowed distance from UE axes for particle selection + double maxConeRadius = coneRadius; + if (applyAreaCut) { + maxConeRadius = std::sqrt(maxNormalizedJetArea) * rJet; + } - // Get MC Particle - if (!track.has_mcParticle()) + // Reject tracks that lie outside the maxConeRadius from both UE axes + if (deltaRUe1 > maxConeRadius && deltaRUe2 > maxConeRadius) continue; - const auto particle = track.mcParticle(); - // Variables - double nsigmaTPCPr = track.tpcNSigmaPr(); - double nsigmaTOFPr = track.tofNSigmaPr(); - double nsigmaTPCDe = track.tpcNSigmaDe(); - double nsigmaTOFDe = track.tofNSigmaDe(); - double dcaxy = track.dcaXY(); - double dcaz = track.dcaZ(); + // Particle identification using the ITS cluster size + bool passedItsPidProt(true), passedItsPidDeut(true); + double nSigmaITSprot = static_cast(itsResponse.nSigmaITS(track)); + double nSigmaITSdeut = static_cast(itsResponse.nSigmaITS(track)); - for (int i = 0; i < nSystematics; i++) { + if (applyItsPid && track.pt() < ptMaxItsPidProt && (nSigmaITSprot < nSigmaItsMin || nSigmaITSprot > nSigmaItsMax)) { + passedItsPidProt = false; + } + if (applyItsPid && track.pt() < ptMaxItsPidDeut && (nSigmaITSdeut < nSigmaItsMin || nSigmaITSdeut > nSigmaItsMax)) { + passedItsPidDeut = false; + } - // Track Selection - if (requirePvContributor && !(track.isPVContributor())) - continue; - if (!track.hasITS()) - continue; - if (track.itsNCls() < itsNclustersSyst[i]) - continue; - if (!track.hasTPC()) - continue; - if (track.tpcNClsCrossedRows() < tpcNcrossedRowsSyst[i]) - continue; - if (track.tpcChi2NCl() > maxChiSquareTpc) + // Kinematic range selection + if (isProton(track) && passedItsPidProt) { + if (track.pt() < ptOverAbins[0] || track.pt() >= ptOverAbins[nBins]) { continue; - if (track.itsChi2NCl() > maxChiSquareIts) - continue; - if (track.eta() < minEta || track.eta() > maxEta) - continue; - if (track.pt() < minPt) - continue; - if (std::fabs(dcaxy) > dcaxySyst[i]) - continue; - if (std::fabs(dcaz) > dcazSyst[i]) - continue; - - // particle identification using the ITS cluster size - bool passedItsPidProt(false), passedItsPidDeut(false); - if (itsResponse.nSigmaITS(track) > nSigmaItsMin && itsResponse.nSigmaITS(track) < nSigmaItsMax) { - passedItsPidProt = true; } - if (itsResponse.nSigmaITS(track) > nSigmaItsMin && itsResponse.nSigmaITS(track) < nSigmaItsMax) { - passedItsPidDeut = true; + } else if (isDeuteron(track) && passedItsPidDeut) { + double ptPerNucleon = 0.5 * track.pt(); + if (ptPerNucleon < ptOverAbins[0] || ptPerNucleon >= ptOverAbins[nBins]) { + continue; } - if (!applyItsPid) { - passedItsPidProt = true; - passedItsPidDeut = true; + } else { + continue; + } + + // (Anti)protons + if (isProton(track) && passedItsPidProt) { + if (track.sign() > 0) { + nTotProtonUE++; + } else if (track.sign() < 0) { + nTotAntiprotonUE++; + int ibin = findBin(ptOverAbins, track.pt()); + nAntiprotonUE[ibin]++; } - if (track.pt() > ptMaxItsPidProt) - passedItsPidProt = true; - if (track.pt() > ptMaxItsPidDeut) - passedItsPidDeut = true; - if (!particle.isPhysicalPrimary()) - continue; + } - if (particle.pdgCode() == kProtonBar) - registryMC.fill(HIST("antiproton_incl_prim_syst"), track.pt(), i); + // (Anti)deuterons + if (isDeuteron(track) && passedItsPidDeut) { + const double ptPerNucleon = 0.5 * track.pt(); - // antiprotons - if (particle.pdgCode() == kProtonBar && passedItsPidProt) { - if (nsigmaTPCPr > minNsigmaTpc && nsigmaTPCPr < maxNsigmaTpc) { - registryMC.fill(HIST("antiproton_incl_rec_tpc_syst"), track.pt(), i); - if (track.hasTOF() && nsigmaTOFPr > minNsigmaTof && nsigmaTOFPr < maxNsigmaTof) - registryMC.fill(HIST("antiproton_incl_rec_tof_syst"), track.pt(), i); - } + if (track.sign() > 0) { + nTotDeuteronUE++; + } else if (track.sign() < 0) { + nTotAntideuteronUE++; + int ibin = findBin(ptOverAbins, ptPerNucleon); + nAntideuteronUE[ibin]++; } + } + } - // antideuterons - if (particle.pdgCode() == -o2::constants::physics::Pdg::kDeuteron && passedItsPidDeut) { - if (nsigmaTPCDe > minNsigmaTpc && nsigmaTPCDe < maxNsigmaTpc) { - registryMC.fill(HIST("antideuteron_incl_rec_tpc_syst"), track.pt(), i); - if (track.hasTOF() && nsigmaTOFDe > minNsigmaTof && nsigmaTOFDe < maxNsigmaTof) - registryMC.fill(HIST("antideuteron_incl_rec_tof_syst"), track.pt(), i); - } - } + // Fill correlation histograms + int netProtonUE = nTotProtonUE - nTotAntiprotonUE; + int netDeuteronUE = nTotDeuteronUE - nTotAntideuteronUE; + registryCorr.fill(HIST("rho_ue"), nTotAntideuteronUE, nTotAntiprotonUE, multiplicity); + registryCorr.fill(HIST("rho_netP_netD_ue"), netDeuteronUE, netProtonUE); + + // Fill efficiency histograms + for (int i = 0; i < nBins; i++) { + double ptAcenteri = 0.5 * (ptOverAbins[i] + ptOverAbins[i + 1]); + + registryCorr.fill(HIST("q1d_ue"), nAntideuteronUE[i], ptAcenteri); + registryCorr.fill(HIST("q1p_ue"), nAntiprotonUE[i], ptAcenteri); + for (int j = 0; j < nBins; j++) { + double ptAcenterj = 0.5 * (ptOverAbins[j] + ptOverAbins[j + 1]); + registryCorr.fill(HIST("q1d_square_ue"), ptAcenteri, ptAcenterj, nAntideuteronUE[i] * nAntideuteronUE[j]); + registryCorr.fill(HIST("q1p_square_ue"), ptAcenteri, ptAcenterj, nAntiprotonUE[i] * nAntiprotonUE[j]); + registryCorr.fill(HIST("q1d_q1p_ue"), ptAcenteri, ptAcenterj, nAntideuteronUE[i] * nAntiprotonUE[j]); } } } + // Event counter: events with at least one jet selected + if (isAtLeastOneJetSelected) { + registryCorr.fill(HIST("eventCounter"), 9.5); + } } - PROCESS_SWITCH(AntinucleiInJets, processSystematicsEfficiency, "process efficiency for systematics", false); + PROCESS_SWITCH(AntinucleiInJets, processCorr, "Process Correlation analysis", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/Tasks/Nuspex/spectraCharged.cxx b/PWGLF/Tasks/Nuspex/chargedParticles.cxx similarity index 70% rename from PWGLF/Tasks/Nuspex/spectraCharged.cxx rename to PWGLF/Tasks/Nuspex/chargedParticles.cxx index 94e3b30dc4a..42bbb437a89 100644 --- a/PWGLF/Tasks/Nuspex/spectraCharged.cxx +++ b/PWGLF/Tasks/Nuspex/chargedParticles.cxx @@ -9,44 +9,71 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -// task for charged particle pt spectra vs multiplicity analysis with 2d unfolding for run3+ -// mimics https://github.com/alisw/AliPhysics/blob/master/PWGLF/SPECTRA/ChargedHadrons/MultDepSpec/AliMultDepSpecAnalysisTask.cxx - -#include "Framework/HistogramRegistry.h" -#include "ReconstructionDataFormats/Track.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Common/DataModel/EventSelection.h" +/// \file chargedParticles.cxx +/// \brief Task for analysis of charged particle pt spectra vs multiplicity with 2d unfolding. +/// \author Mario Krüger + +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" #include "Common/DataModel/TrackSelectionTables.h" -#include "TDatabasePDG.h" + +#include +#include +#include +#include +#include + +#include +#include using namespace o2; using namespace o2::framework; +using aod::track::TrackSelectionFlags; //-------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------- // Task declaration //-------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------- -struct chargedSpectra { +struct ChargedParticles { HistogramRegistry histos; Service pdg; - // task settings that can be steered via hyperloop Configurable isRun3{"isRun3", true, "is Run3 dataset"}; Configurable maxMultMeas{"maxMultMeas", 100, "max measured multiplicity"}; Configurable maxMultTrue{"maxMultTrue", 100, "max true multiplicity"}; Configurable etaCut{"etaCut", 0.8f, "eta cut"}; Configurable ptMinCut{"ptMinCut", 0.15f, "pt min cut"}; Configurable ptMaxCut{"ptMaxCut", 10.f, "pt max cut"}; - Configurable normINELGT0{"normINELGT0", false, "normalize INEL>0 according to MC"}; + enum : uint32_t { + kSystNominal = 100, + kSystDownChi2PerClusterITS, + kSystUpChi2PerClusterITS, + kSystDownChi2PerClusterTPC, + kSystUpChi2PerClusterTPC, + kSystDownTPCCrossedRowsOverNCls, + kSystUpTPCCrossedRowsOverNCls, + kSystDownDCAxy = 111, + kSystUpDCAxy, + kSystDownDCAz, + kSystUpDCAz, + kSystITSHits, + kSystDownTPCCrossedRows, + kSystUpTPCCrossedRows + }; + Configurable systMode{"systMode", kSystNominal, "variation for systematic uncertainties"}; + uint16_t trackSelMask{TrackSelectionFlags::kGlobalTrackWoPtEta}; // track selection bitmask (without cut that is being varied) + uint16_t cutVarFlag{0}; + TrackSelection trackSel; + TrackSelection::TrackCuts trackSelFlag; + // helper struct to store transient properties - struct varContainer { + struct VarContainer { uint32_t multMeas{0u}; uint32_t multTrue{0u}; bool isAcceptedEvent{false}; @@ -54,7 +81,8 @@ struct chargedSpectra { bool isINELGT0EventMC{false}; bool isChargedPrimary{false}; }; - varContainer vars; + VarContainer vars; + static constexpr float kMaxVtxZ = 10.f; void init(InitContext const&); @@ -70,43 +98,29 @@ struct chargedSpectra { template void initEventMC(const C& collision, const P& particles); - template - void processMeas(const C& collision, const T& tracks); + template + void processMeas(const T& tracks); - template - void processTrue(const C& collision, const P& particles); + template + void processTrue(const P& particles); using CollisionTableData = soa::Join; - using TrackTableData = soa::Join; + using TrackTableData = soa::Join; void processData(CollisionTableData::iterator const& collision, TrackTableData const& tracks); - PROCESS_SWITCH(chargedSpectra, processData, "process data", false); + PROCESS_SWITCH(ChargedParticles, processData, "process data", false); using CollisionTableMCTrue = aod::McCollisions; using CollisionTableMC = soa::SmallGroups>; - using TrackTableMC = soa::Join; + using TrackTableMC = soa::Join; using ParticleTableMC = aod::McParticles; Preslice perCollision = aod::track::collisionId; void processMC(CollisionTableMCTrue::iterator const& mcCollision, CollisionTableMC const& collisions, TrackTableMC const& tracks, ParticleTableMC const& particles); - PROCESS_SWITCH(chargedSpectra, processMC, "process mc", true); - - // TODO: - Milestone - express most of the selections on events and tracks in a declarative way to improve performance - /* - add - Filter xy; - soa::Filtered - - For the collision and track tables (data and MC): - - collision z pos < 10cm - - trigger condition + event selection - - track selection + is in kine range - - For the MC tables we need to keep everything that EITHER fulfils the conditions in data OR in MC to get correct efficiencies and contamination! - */ + PROCESS_SWITCH(ChargedParticles, processMC, "process mc", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - return WorkflowSpec{adaptAnalysisTask(cfgc)}; + return WorkflowSpec{adaptAnalysisTask(cfgc)}; } //-------------------------------------------------------------------------------------------------- @@ -120,7 +134,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) * Initialise the task and add histograms. */ //************************************************************************************************** -void chargedSpectra::init(InitContext const&) +void ChargedParticles::init(InitContext const&) { std::vector ptBinEdges = {0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, @@ -162,6 +176,62 @@ void chargedSpectra::init(InitContext const&) histos.add("multPtSpec_trk_meas_evtcont", "", kTH2D, {multMeasAxis, ptMeasAxis}); // tracks from events that are measured, but do not belong to the desired class of events histos.add("multPtSpec_trk_inter", "", kTH2D, {multTrueAxis, ptMeasAxis}); } + + trackSel = getGlobalTrackSelection(); + if (systMode == kSystDownChi2PerClusterITS) { + trackSel.SetMaxChi2PerClusterITS(25.); + cutVarFlag = TrackSelectionFlags::kITSChi2NDF; + trackSelFlag = TrackSelection::TrackCuts::kITSChi2NDF; + } else if (systMode == kSystUpChi2PerClusterITS) { + trackSel.SetMaxChi2PerClusterITS(49.); + cutVarFlag = TrackSelectionFlags::kITSChi2NDF; + trackSelFlag = TrackSelection::TrackCuts::kITSChi2NDF; + } else if (systMode == kSystDownChi2PerClusterTPC) { + trackSel.SetMaxChi2PerClusterTPC(3.0); + cutVarFlag = TrackSelectionFlags::kTPCChi2NDF; + trackSelFlag = TrackSelection::TrackCuts::kTPCChi2NDF; + } else if (systMode == kSystUpChi2PerClusterTPC) { + trackSel.SetMaxChi2PerClusterTPC(5.0); + cutVarFlag = TrackSelectionFlags::kTPCChi2NDF; + trackSelFlag = TrackSelection::TrackCuts::kTPCChi2NDF; + } else if (systMode == kSystDownTPCCrossedRowsOverNCls) { + trackSel.SetMinNCrossedRowsOverFindableClustersTPC(0.7); + cutVarFlag = TrackSelectionFlags::kTPCCrossedRowsOverNCls; + trackSelFlag = TrackSelection::TrackCuts::kTPCCrossedRowsOverNCls; + } else if (systMode == kSystUpTPCCrossedRowsOverNCls) { + trackSel.SetMinNCrossedRowsOverFindableClustersTPC(0.9); + cutVarFlag = TrackSelectionFlags::kTPCCrossedRowsOverNCls; + trackSelFlag = TrackSelection::TrackCuts::kTPCCrossedRowsOverNCls; + } else if (systMode == kSystDownDCAxy) { + trackSel.SetMaxDcaXYPtDep([](float pt) { return 4. / 7. * (0.0105f + 0.0350f / std::pow(pt, 1.1f)); }); + cutVarFlag = TrackSelectionFlags::kDCAxy; + trackSelFlag = TrackSelection::TrackCuts::kDCAxy; + } else if (systMode == kSystUpDCAxy) { + trackSel.SetMaxDcaXYPtDep([](float pt) { return 10. / 7. * (0.0105f + 0.0350f / std::pow(pt, 1.1f)); }); + cutVarFlag = TrackSelectionFlags::kDCAxy; + trackSelFlag = TrackSelection::TrackCuts::kDCAxy; + } else if (systMode == kSystDownDCAz) { + trackSel.SetMaxDcaZ(1.0); + cutVarFlag = TrackSelectionFlags::kDCAz; + trackSelFlag = TrackSelection::TrackCuts::kDCAz; + } else if (systMode == kSystUpDCAz) { + trackSel.SetMaxDcaZ(5.0); + cutVarFlag = TrackSelectionFlags::kDCAz; + trackSelFlag = TrackSelection::TrackCuts::kDCAz; + } else if (systMode == kSystITSHits) { + trackSel.ResetITSRequirements(); + cutVarFlag = TrackSelectionFlags::kITSHits; + trackSelFlag = TrackSelection::TrackCuts::kITSHits; + } else if (systMode == kSystDownTPCCrossedRows) { + trackSel.SetMinNCrossedRowsTPC(60); + cutVarFlag = TrackSelectionFlags::kTPCCrossedRows; + trackSelFlag = TrackSelection::TrackCuts::kTPCCrossedRows; + } else if (systMode == kSystUpTPCCrossedRows) { + trackSel.SetMinNCrossedRowsTPC(80); + cutVarFlag = TrackSelectionFlags::kTPCCrossedRows; + trackSelFlag = TrackSelection::TrackCuts::kTPCCrossedRows; + } + trackSelMask &= (~cutVarFlag); } //************************************************************************************************** @@ -169,10 +239,10 @@ void chargedSpectra::init(InitContext const&) * Entrypoint to processes data. */ //************************************************************************************************** -void chargedSpectra::processData(CollisionTableData::iterator const& collision, TrackTableData const& tracks) +void ChargedParticles::processData(CollisionTableData::iterator const& collision, TrackTableData const& tracks) { initEvent(collision, tracks); - processMeas(collision, tracks); + processMeas(tracks); } //************************************************************************************************** @@ -180,7 +250,7 @@ void chargedSpectra::processData(CollisionTableData::iterator const& collision, * Entrypoint to processes mc. */ //************************************************************************************************** -void chargedSpectra::processMC(CollisionTableMCTrue::iterator const& mcCollision, CollisionTableMC const& collisions, TrackTableMC const& tracks, ParticleTableMC const& particles) +void ChargedParticles::processMC(CollisionTableMCTrue::iterator const& mcCollision, CollisionTableMC const& collisions, TrackTableMC const& tracks, ParticleTableMC const& particles) { histos.fill(HIST("collision_ambiguity"), collisions.size()); @@ -198,14 +268,14 @@ void chargedSpectra::processMC(CollisionTableMCTrue::iterator const& mcCollision if (collisions.size() == 0) { vars.isAcceptedEvent = false; } else { - for (auto& collision : collisions) { + for (const auto& collision : collisions) { auto curTracks = tracks.sliceBy(perCollision, collision.globalIndex()); initEvent(collision, curTracks); - processMeas(collision, curTracks); + processMeas(curTracks); break; // for now look only at first collision... } } - processTrue(mcCollision, particles); + processTrue(particles); } //************************************************************************************************** @@ -214,7 +284,7 @@ void chargedSpectra::processMC(CollisionTableMCTrue::iterator const& mcCollision */ //************************************************************************************************** template -bool chargedSpectra::initParticle(const P& particle) +bool ChargedParticles::initParticle(const P& particle) { vars.isChargedPrimary = false; auto pdgParticle = pdg->GetParticle(particle.pdgCode()); @@ -241,7 +311,7 @@ bool chargedSpectra::initParticle(const P& particle) */ //************************************************************************************************** template -bool chargedSpectra::initTrack(const T& track) +bool ChargedParticles::initTrack(const T& track) { if (std::abs(track.eta()) >= etaCut) { return false; @@ -249,7 +319,11 @@ bool chargedSpectra::initTrack(const T& track) if (track.pt() <= ptMinCut || track.pt() >= ptMaxCut) { return false; } - if (!track.isGlobalTrackWoPtEta()) { + if (!TrackSelectionFlags::checkFlag(track.trackCutFlag(), trackSelMask)) { + return false; + } + // for systematic variation of standard selections, check if the varied cut is passed + if (cutVarFlag && !trackSel.IsSelected(track, trackSelFlag)) { return false; } return true; @@ -261,17 +335,17 @@ bool chargedSpectra::initTrack(const T& track) */ //************************************************************************************************** template -void chargedSpectra::initEvent(const C& collision, const T& tracks) +void ChargedParticles::initEvent(const C& collision, const T& tracks) { vars.multMeas = 0; - for (auto& track : tracks) { + for (const auto& track : tracks) { if (initTrack(track)) { ++vars.multMeas; } } vars.isAcceptedEvent = false; - if (std::abs(collision.posZ()) < 10.f) { + if (std::abs(collision.posZ()) < kMaxVtxZ) { if (isRun3 ? collision.sel8() : collision.sel7()) { if ((isRun3 || doprocessMC) ? true : collision.alias_bit(kINT7)) { vars.isAcceptedEvent = true; @@ -286,18 +360,18 @@ void chargedSpectra::initEvent(const C& collision, const T& tracks) */ //************************************************************************************************** template -void chargedSpectra::initEventMC(const C& collision, const P& particles) +void ChargedParticles::initEventMC(const C& collision, const P& particles) { vars.isINELGT0EventMC = false; // will be set to true in case a charged particle within eta +-1 is found vars.multTrue = 0; - for (auto& particle : particles) { + for (const auto& particle : particles) { if (!initParticle(particle) || !vars.isChargedPrimary) { continue; } ++vars.multTrue; } bool isGoodEventClass = (normINELGT0) ? vars.isINELGT0EventMC : (vars.multTrue > 0); - vars.isAcceptedEventMC = isGoodEventClass && (std::abs(collision.posZ()) < 10.f); + vars.isAcceptedEventMC = isGoodEventClass && (std::abs(collision.posZ()) < kMaxVtxZ); } //************************************************************************************************** @@ -305,8 +379,8 @@ void chargedSpectra::initEventMC(const C& collision, const P& particles) * Function to processes MC truth info. Assumes initEvent and initEventMC have been called previously. */ //************************************************************************************************** -template -void chargedSpectra::processTrue(const C& /*collision*/, const P& particles) +template +void ChargedParticles::processTrue(const P& particles) { if (!vars.isAcceptedEventMC) { return; @@ -314,7 +388,7 @@ void chargedSpectra::processTrue(const C& /*collision*/, const P& particles) histos.fill(HIST("multDist_evt_gen"), vars.multTrue); - for (auto& particle : particles) { + for (const auto& particle : particles) { if (initParticle(particle) && vars.isChargedPrimary) { histos.fill(HIST("multPtSpec_prim_gen"), vars.multTrue, particle.pt()); if (!vars.isAcceptedEvent) { @@ -329,8 +403,8 @@ void chargedSpectra::processTrue(const C& /*collision*/, const P& particles) * Function to process reconstructed data and MC. Assumes initEvent (and initEventMC in case of MC) have been called previously. */ //************************************************************************************************** -template -void chargedSpectra::processMeas(const C& /*collision*/, const T& tracks) +template +void ChargedParticles::processMeas(const T& tracks) { if (!vars.isAcceptedEvent) { return; @@ -345,8 +419,7 @@ void chargedSpectra::processMeas(const C& /*collision*/, const T& tracks) } std::vector foundParticles; - for (auto& track : tracks) { - + for (const auto& track : tracks) { if (!initTrack(track)) { continue; } @@ -390,7 +463,7 @@ void chargedSpectra::processMeas(const C& /*collision*/, const T& tracks) } std::unordered_set uniqueIndices(foundParticles.begin(), foundParticles.end()); - for (auto mcParticleID : uniqueIndices) { + for (const auto& mcParticleID : uniqueIndices) { histos.fill(HIST("track_ambiguity"), std::count(foundParticles.begin(), foundParticles.end(), mcParticleID)); } } diff --git a/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx new file mode 100644 index 00000000000..d688f0c8e72 --- /dev/null +++ b/PWGLF/Tasks/Nuspex/dedxPidAnalysis.cxx @@ -0,0 +1,852 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +/// +/// \author Paola Vargas Torres (paola.vargas.torres@cern.ch) +/// \since January 8, 2025 +/// \file dedxPidAnalysis.cxx +/// \brief Analysis to do PID + +#include "PWGLF/DataModel/LFStrangenessTables.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include "TF1.h" + +using namespace o2; +using namespace o2::framework; +using namespace constants::physics; + +using PIDTracks = soa::Join< + aod::Tracks, aod::TracksExtra, aod::TrackSelectionExtension, aod::TracksDCA, aod::TrackSelection, + aod::pidTOFFullPi, aod::pidTOFFullPr, aod::pidTOFFullEl, aod::pidTOFbeta>; + +using SelectedCollisions = soa::Join; + +struct DedxPidAnalysis { + + // dE/dx for all charged particles + HistogramRegistry registryDeDx{ + "registryDeDx", + {}, + OutputObjHandlingPolicy::AnalysisObject, + true, + true}; + // Constant values + static constexpr int kEtaIntervals = 8; + static constexpr int kParticlesType = 4; + float tpcCut = 0.6; + float pionMin = 0.35; + float pionMax = 0.45; + float elTofCut = 0.1; + float pionTofCut = 1.0; + float invMassCut = 0.01; + float invMassCutGamma = 0.0015; + float magField = 1; + float pTcut = 2.0; + + // Configurable Parameters + // Tracks cuts + Configurable minTPCnClsFound{"minTPCnClsFound", 70.0f, + "min number of found TPC clusters"}; + Configurable minNCrossedRowsTPC{"minNCrossedRowsTPC", 70.0f, "min number of found TPC crossed rows"}; + Configurable maxChi2TPC{"maxChi2TPC", 4.0f, + "max chi2 per cluster TPC"}; + Configurable maxChi2ITS{"maxChi2ITS", 36.0f, + "max chi2 per cluster ITS"}; + Configurable maxZDistanceToIP{"maxZDistanceToIP", 10.0f, + "max z distance to IP"}; + Configurable etaMin{"etaMin", -0.8f, "etaMin"}; + Configurable etaMax{"etaMax", +0.8f, "etaMax"}; + Configurable minNCrossedRowsOverFindableClustersTPC{"minNCrossedRowsOverFindableClustersTPC", 0.8f, "Additional cut on the minimum value of the ratio between crossed rows and findable clusters in the TPC"}; + Configurable maxDCAz{"maxDCAz", 2.f, "maxDCAz"}; + // v0 cuts + Configurable v0cospaMin{"v0cospaMin", 0.998f, "Minimum V0 CosPA"}; + Configurable minimumV0Radius{"minimumV0Radius", 0.5f, + "Minimum V0 Radius"}; + Configurable maximumV0Radius{"maximumV0Radius", 100.0f, + "Maximum V0 Radius"}; + Configurable dcaV0DaughtersMax{"dcaV0DaughtersMax", 0.5f, + "Maximum DCA Daughters"}; + Configurable nsigmaTOFmax{"nsigmaTOFmax", 3.0f, "Maximum nsigma TOF"}; + Configurable minMassK0s{"minMassK0s", 0.4f, "Minimum Mass K0s"}; + Configurable maxMassK0s{"maxMassK0s", 0.6f, "Maximum Mass K0s"}; + Configurable minMassLambda{"minMassLambda", 1.1f, + "Minimum Mass Lambda"}; + Configurable maxMassLambda{"maxMassLambda", 1.2f, + "Maximum Mass Lambda"}; + Configurable minMassGamma{"minMassGamma", 0.000922f, + "Minimum Mass Gamma"}; + Configurable maxMassGamma{"maxMassGamma", 0.002022f, + "Maximum Mass Gamma"}; + Configurable nclCut{"nclCut", 135.0f, + "ncl Cut"}; + Configurable calibrationMode{"calibrationMode", false, "calibration mode"}; + Configurable additionalCuts{"additionalCuts", true, "additional cuts"}; + // Histograms names + static constexpr std::string_view kDedxvsMomentumPos[kParticlesType] = {"dEdx_vs_Momentum_all_Pos", "dEdx_vs_Momentum_Pi_v0_Pos", "dEdx_vs_Momentum_Pr_v0_Pos", "dEdx_vs_Momentum_El_v0_Pos"}; + static constexpr std::string_view kDedxvsMomentumNeg[kParticlesType] = {"dEdx_vs_Momentum_all_Neg", "dEdx_vs_Momentum_Pi_v0_Neg", "dEdx_vs_Momentum_Pr_v0_Neg", "dEdx_vs_Momentum_El_v0_Neg"}; + static constexpr std::string_view kNclDedxMomentumNegBefore[kEtaIntervals] = {"Ncl_vs_dEdx_vs_Momentum_Neg_1_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_2_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_3_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_4_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_5_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_6_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_7_Before", "Ncl_vs_dEdx_vs_Momentum_Neg_8_Before"}; + static constexpr std::string_view kNclDedxMomentumPosBefore[kEtaIntervals] = {"Ncl_vs_dEdx_vs_Momentum_Pos_1_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_2_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_3_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_4_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_5_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_6_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_7_Before", "Ncl_vs_dEdx_vs_Momentum_Pos_8_Before"}; + static constexpr std::string_view kNclDedxMomentumNegAfter[kEtaIntervals] = {"Ncl_vs_dEdx_vs_Momentum_Neg_1_After", "Ncl_vs_dEdx_vs_Momentum_Neg_2_After", "Ncl_vs_dEdx_vs_Momentum_Neg_3_After", "Ncl_vs_dEdx_vs_Momentum_Neg_4_After", "Ncl_vs_dEdx_vs_Momentum_Neg_5_After", "Ncl_vs_dEdx_vs_Momentum_Neg_6_After", "Ncl_vs_dEdx_vs_Momentum_Neg_7_After", "Ncl_vs_dEdx_vs_Momentum_Neg_8_After"}; + static constexpr std::string_view kNclDedxMomentumPosAfter[kEtaIntervals] = {"Ncl_vs_dEdx_vs_Momentum_Pos_1_After", "Ncl_vs_dEdx_vs_Momentum_Pos_2_After", "Ncl_vs_dEdx_vs_Momentum_Pos_3_After", "Ncl_vs_dEdx_vs_Momentum_Pos_4_After", "Ncl_vs_dEdx_vs_Momentum_Pos_5_After", "Ncl_vs_dEdx_vs_Momentum_Pos_6_After", "Ncl_vs_dEdx_vs_Momentum_Pos_7_After", "Ncl_vs_dEdx_vs_Momentum_Pos_8_After"}; + static constexpr double EtaCut[kEtaIntervals + 1] = {-0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8}; + Configurable> calibrationFactorNeg{"calibrationFactorNeg", {50.4011, 50.4764, 50.186, 49.2955, 48.8222, 49.4273, 49.9292, 50.0556}, "negative calibration factors"}; + Configurable> calibrationFactorPos{"calibrationFactorPos", {50.5157, 50.6359, 50.3198, 49.3345, 48.9197, 49.4931, 50.0188, 50.1406}, "positive calibration factors"}; + ConfigurableAxis binP{"binP", {VARIABLE_WIDTH, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0}, ""}; + + // phi cut fits + TF1* fphiCutHigh = nullptr; + TF1* fphiCutLow = nullptr; + + TrackSelection myTrackSelection() + { + TrackSelection selectedTracks; + selectedTracks.SetPtRange(0.1f, 1e10f); + selectedTracks.SetEtaRange(etaMin, etaMax); + selectedTracks.SetRequireITSRefit(true); + selectedTracks.SetRequireTPCRefit(true); + selectedTracks.SetMinNCrossedRowsTPC(minNCrossedRowsTPC); + selectedTracks.SetMinNCrossedRowsOverFindableClustersTPC(minNCrossedRowsOverFindableClustersTPC); + selectedTracks.SetMaxChi2PerClusterTPC(maxChi2TPC); + selectedTracks.SetRequireHitsInITSLayers(1, {0, 1}); + selectedTracks.SetMaxChi2PerClusterITS(maxChi2ITS); + selectedTracks.SetMaxDcaXYPtDep([](float pt) { return 0.0105f + 0.0350f / std::pow(pt, 1.1f); }); + selectedTracks.SetMaxDcaZ(maxDCAz); + selectedTracks.SetRequireGoldenChi2(true); + + return selectedTracks; + } + + TrackSelection mySelectionPrim; + + void init(InitContext const&) + { + AxisSpec dedxAxis{100, 0.0, 100.0, "dE/dx (a. u.)"}; + AxisSpec ptAxis = {binP, "pT (GeV/c)"}; + AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; + AxisSpec pAxis = {binP, "#it{p}/Z (GeV/c)"}; + fphiCutLow = new TF1("StandardPhiCutLow", "0.119297/x/x+pi/18.0-0.000379693", 0, 50); + fphiCutHigh = new TF1("StandardPhiCutHigh", "0.16685/x+pi/18.0+0.00981942", 0, 50); + if (calibrationMode) { + // MIP for pions + registryDeDx.add( + "hdEdx_vs_eta_Neg_Pi", "dE/dx", HistType::kTH2F, + {{etaAxis}, {dedxAxis}}); + registryDeDx.add( + "hdEdx_vs_eta_Pos_Pi", "dE/dx", HistType::kTH2F, + {{etaAxis}, {dedxAxis}}); + // MIP for electrons + registryDeDx.add( + "hdEdx_vs_eta_vs_p_Neg_El", "dE/dx", HistType::kTH3F, + {{etaAxis}, {dedxAxis}, {pAxis}}); + registryDeDx.add( + "hdEdx_vs_eta_vs_p_Pos_El", "dE/dx", HistType::kTH3F, + {{etaAxis}, {dedxAxis}, {pAxis}}); + // Pions from TOF + registryDeDx.add( + "hdEdx_vs_eta_vs_p_Neg_TOF", "dE/dx", HistType::kTH3F, + {{etaAxis}, {dedxAxis}, {pAxis}}); + registryDeDx.add( + "hdEdx_vs_eta_vs_p_Pos_TOF", "dE/dx", HistType::kTH3F, + {{etaAxis}, {dedxAxis}, {pAxis}}); + + } else { + // MIP for pions + registryDeDx.add( + "hdEdx_vs_eta_Neg_calibrated_Pi", "dE/dx", HistType::kTH2F, + {{etaAxis}, {dedxAxis}}); + + registryDeDx.add( + "hdEdx_vs_eta_Pos_calibrated_Pi", "dE/dx", HistType::kTH2F, + {{etaAxis}, {dedxAxis}}); + + // MIP for electrons + registryDeDx.add( + "hdEdx_vs_eta_vs_p_Neg_calibrated_El", "dE/dx", HistType::kTH3F, + {{etaAxis}, {dedxAxis}, {pAxis}}); + + registryDeDx.add( + "hdEdx_vs_eta_vs_p_Pos_calibrated_El", "dE/dx", HistType::kTH3F, + {{etaAxis}, {dedxAxis}, {pAxis}}); + + // Pions from TOF + registryDeDx.add( + "hdEdx_vs_eta_vs_p_Neg_calibrated_TOF", "dE/dx", HistType::kTH3F, + {{etaAxis}, {dedxAxis}, {pAxis}}); + + registryDeDx.add( + "hdEdx_vs_eta_vs_p_Pos_calibrated_TOF", "dE/dx", HistType::kTH3F, + {{etaAxis}, {dedxAxis}, {pAxis}}); + + // pt vs p + registryDeDx.add( + "hp_vs_pt_all_Neg", "p_vs_pT", HistType::kTH2F, + {{ptAxis}, {pAxis}}); + registryDeDx.add( + "hp_vs_pt_all_Pos", "p_vs_pT", HistType::kTH2F, + {{ptAxis}, {pAxis}}); + + // De/Dx for ch and v0 particles + for (int i = 0; i < kParticlesType; ++i) { + registryDeDx.add(kDedxvsMomentumPos[i].data(), "dE/dx", HistType::kTH3F, + {{pAxis}, {dedxAxis}, {etaAxis}}); + registryDeDx.add(kDedxvsMomentumNeg[i].data(), "dE/dx", HistType::kTH3F, + {{pAxis}, {dedxAxis}, {etaAxis}}); + } + } + + registryDeDx.add( + "hdEdx_vs_phi", "dE/dx", HistType::kTH2F, + {{100, 0.0, 6.4, "#phi"}, {dedxAxis}}); + + // phi cut + registryDeDx.add( + "hpt_vs_phi_Ncl_After", "phi cut", HistType::kTH3F, + {{ptAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl}"}}); + + registryDeDx.add( + "hpt_vs_phi_Ncl_Before", "phi cut", HistType::kTH3F, + {{ptAxis}, {100, 0.0, 0.4, "#varphi^{'}"}, {100, 0, 160, "N_{cl}"}}); + + // Ncl vs de/dx + + for (int i = 0; i < kEtaIntervals; ++i) { + registryDeDx.add(kNclDedxMomentumPosBefore[i].data(), "Ncl vs dE/dx vs Momentum Positive before", HistType::kTH3F, + {{100, 0, 160, "N_{cl}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add(kNclDedxMomentumNegBefore[i].data(), "Ncl vs dE/dx vs Momentum Negative before", HistType::kTH3F, + {{100, 0, 160, "N_{cl}"}, {dedxAxis}, {pAxis}}); + + registryDeDx.add(kNclDedxMomentumPosAfter[i].data(), "Ncl vs dE/dx vs Momentum Positive after", HistType::kTH3F, + {{100, 0, 160, "N_{cl}"}, {dedxAxis}, {pAxis}}); + registryDeDx.add(kNclDedxMomentumNegAfter[i].data(), "Ncl vs dE/dx vs Momentum Negative after", HistType::kTH3F, + {{100, 0, 160, "N_{cl}"}, {dedxAxis}, {pAxis}}); + } + + // beta plot + registryDeDx.add( + "hbeta_vs_p_Neg", "beta", HistType::kTH2F, + {{pAxis}, {100, 0.0, 1.1, "#beta"}}); + + registryDeDx.add( + "hbeta_vs_p_Pos", "beta", HistType::kTH2F, + {{pAxis}, {100, 0.0, 1.1, "#beta"}}); + + // Event Counter + registryDeDx.add("histRecVtxZData", "collision z position", HistType::kTH1F, {{100, -20.0, +20.0, "z_{vtx} (cm)"}}); + + mySelectionPrim = myTrackSelection(); + } + + // Single-Track Selection + template + bool passedSingleTrackSelection(const T1& track, const C& /*collision*/) + { + // Single-Track Selections + if (!track.hasTPC()) + return false; + if (track.tpcNClsFound() < minTPCnClsFound) + return false; + if (track.tpcNClsCrossedRows() < minNCrossedRowsTPC) + return false; + if (track.tpcChi2NCl() > maxChi2TPC) + return false; + if (track.eta() < etaMin || track.eta() > etaMax) + return false; + + return true; + } + + // General V0 Selections + template + bool passedV0Selection(const T1& v0, const C& /*collision*/) + { + if (v0.v0cosPA() < v0cospaMin) + return false; + if (v0.v0radius() < minimumV0Radius || v0.v0radius() > maximumV0Radius) + return false; + + return true; + } + + // K0s Selections + template + bool passedK0Selection(const T1& v0, const T2& ntrack, const T2& ptrack, + const C& collision) + { + // Single-Track Selections + if (!passedSingleTrackSelection(ptrack, collision)) + return false; + if (!passedSingleTrackSelection(ntrack, collision)) + return false; + + if (ptrack.tpcInnerParam() > tpcCut) { + if (!ptrack.hasTOF()) + return false; + if (std::abs(ptrack.tofNSigmaPi()) > nsigmaTOFmax) + return false; + } + + if (ntrack.tpcInnerParam() > tpcCut) { + if (!ntrack.hasTOF()) + return false; + if (std::abs(ntrack.tofNSigmaPi()) > nsigmaTOFmax) + return false; + } + + // Invariant-Mass Selection + if (v0.mK0Short() < minMassK0s || v0.mK0Short() > maxMassK0s) + return false; + + return true; + } + + // Lambda Selections + template + bool passedLambdaSelection(const T1& v0, const T2& ntrack, const T2& ptrack, + const C& collision) + { + // Single-Track Selections + if (!passedSingleTrackSelection(ptrack, collision)) + return false; + if (!passedSingleTrackSelection(ntrack, collision)) + return false; + + if (ptrack.tpcInnerParam() > tpcCut) { + if (!ptrack.hasTOF()) + return false; + if (std::abs(ptrack.tofNSigmaPr()) > nsigmaTOFmax) + return false; + } + + if (ntrack.tpcInnerParam() > tpcCut) { + if (!ntrack.hasTOF()) + return false; + if (std::abs(ntrack.tofNSigmaPi()) > nsigmaTOFmax) + return false; + } + + // Invariant-Mass Selection + if (v0.mLambda() < minMassLambda || v0.mLambda() > maxMassLambda) + return false; + + return true; + } + + // AntiLambda Selections + template + bool passedAntiLambdaSelection(const T1& v0, const T2& ntrack, + const T2& ptrack, const C& collision) + { + + // Single-Track Selections + if (!passedSingleTrackSelection(ptrack, collision)) + return false; + if (!passedSingleTrackSelection(ntrack, collision)) + return false; + + if (ptrack.tpcInnerParam() > tpcCut) { + if (!ptrack.hasTOF()) + return false; + if (std::abs(ptrack.tofNSigmaPi()) > nsigmaTOFmax) + return false; + } + + if (ntrack.tpcInnerParam() > tpcCut) { + if (!ntrack.hasTOF()) + return false; + if (std::abs(ntrack.tofNSigmaPr()) > nsigmaTOFmax) + return false; + } + + // Invariant-Mass Selection + if (v0.mAntiLambda() < minMassLambda || v0.mAntiLambda() > maxMassLambda) + return false; + + return true; + } + + // Gamma Selections + template + bool passedGammaSelection(const T1& v0, const T2& ntrack, const T2& ptrack, + const C& collision) + { + // Single-Track Selections + if (!passedSingleTrackSelection(ptrack, collision)) + return false; + if (!passedSingleTrackSelection(ntrack, collision)) + return false; + + if (ptrack.tpcInnerParam() > tpcCut) { + if (!ptrack.hasTOF()) + return false; + if (std::abs(ptrack.tofNSigmaEl()) > nsigmaTOFmax) + return false; + } + + if (ntrack.tpcInnerParam() > tpcCut) { + if (!ntrack.hasTOF()) + return false; + if (std::abs(ntrack.tofNSigmaEl()) > nsigmaTOFmax) + return false; + } + + // Invariant-Mass Selection + if (v0.mGamma() < minMassGamma || v0.mGamma() > maxMassGamma) + return false; + + return true; + } + + // Phi cut + template + bool passedPhiCut(const T& trk, float magField, const TF1& fphiCutLow, const TF1& fphiCutHigh) + { + float pt = trk.pt(); + float phi = trk.phi(); + int charge = trk.sign(); + float eta = trk.eta(); + auto nTPCCl = trk.tpcNClsFindable() - trk.tpcNClsFindableMinusFound(); + float sigP = trk.sign() * trk.tpcInnerParam(); + + if (pt < pTcut) + return true; + + if (magField < 0) // for negatve polarity field + phi = o2::constants::math::TwoPI - phi; + if (charge < 0) // for negatve charge + phi = o2::constants::math::TwoPI - phi; + + // to center gap in the middle + phi += o2::constants::math::PI / 18.0f; + phi = std::fmod(phi, o2::constants::math::PI / 9.0f); + + registryDeDx.fill(HIST("hpt_vs_phi_Ncl_Before"), pt, phi, nTPCCl); + + // cut phi + if (phi < fphiCutHigh.Eval(pt) && phi > fphiCutLow.Eval(pt)) + return false; // reject track + + if (eta > EtaCut[0] && eta < EtaCut[1]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[0]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[1] && eta < EtaCut[2]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[1]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[2] && eta < EtaCut[3]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[2]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[3] && eta < EtaCut[4]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[3]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[4] && eta < EtaCut[5]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[4]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[5] && eta < EtaCut[6]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[5]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[6] && eta < EtaCut[7]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[6]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[7] && eta < EtaCut[8]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegBefore[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosBefore[7]), nTPCCl, trk.tpcSignal(), sigP); + } + } + + // cut Ncl + if (nTPCCl < nclCut) + return false; + + registryDeDx.fill(HIST("hpt_vs_phi_Ncl_After"), pt, phi, nTPCCl); + + if (eta > EtaCut[0] && eta < EtaCut[1]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[0]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[0]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[1] && eta < EtaCut[2]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[1]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[1]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[2] && eta < EtaCut[3]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[2]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[2]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[3] && eta < EtaCut[4]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[3]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[3]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[4] && eta < EtaCut[5]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[4]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[4]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[5] && eta < EtaCut[6]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[5]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[5]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[6] && eta < EtaCut[7]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[6]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[6]), nTPCCl, trk.tpcSignal(), sigP); + } + } else if (eta > EtaCut[7] && eta < EtaCut[8]) { + if (sigP < 0) { + registryDeDx.fill(HIST(kNclDedxMomentumNegAfter[7]), nTPCCl, trk.tpcSignal(), std::abs(sigP)); + } else { + registryDeDx.fill(HIST(kNclDedxMomentumPosAfter[7]), nTPCCl, trk.tpcSignal(), sigP); + } + } + + return true; + } + + // Phi cut Secondaries + template + bool passedPhiCutSecondaries(const T& trk, float magField, const TF1& fphiCutLow, const TF1& fphiCutHigh) + { + float pt = trk.pt(); + float phi = trk.phi(); + int charge = trk.sign(); + auto nTPCCl = trk.tpcNClsFindable() - trk.tpcNClsFindableMinusFound(); + + if (pt < pTcut) + return true; + + if (magField < 0) // for negatve polarity field + phi = o2::constants::math::TwoPI - phi; + if (charge < 0) // for negatve charge + phi = o2::constants::math::TwoPI - phi; + + // to center gap in the middle + phi += o2::constants::math::PI / 18.0f; + phi = std::fmod(phi, o2::constants::math::PI / 9.0f); + + // cut phi + if (phi < fphiCutHigh.Eval(pt) && phi > fphiCutLow.Eval(pt)) + return false; // reject track + + // cut Ncl + if (nTPCCl < nclCut) + return false; + + return true; + } + + // Process Data + void process(SelectedCollisions::iterator const& collision, + aod::V0Datas const& fullV0s, PIDTracks const& tracks) + { + // Event Selection + if (!collision.sel8()) + return; + + if (additionalCuts) { + if (!collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) + return; + + if (!collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) + return; + + if (std::abs(collision.posZ()) >= maxZDistanceToIP) + return; + + if (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) + return; + } + + // Event Counter + registryDeDx.fill(HIST("histRecVtxZData"), collision.posZ()); + + // Kaons + for (const auto& trk : tracks) { + + // track Selection + if (!passedSingleTrackSelection(trk, collision)) + continue; + + if (!mySelectionPrim.IsSelected(trk)) + continue; + + // phi and Ncl cut + if (!passedPhiCut(trk, magField, *fphiCutLow, *fphiCutHigh)) + continue; + + float signedP = trk.sign() * trk.tpcInnerParam(); + + // MIP calibration for pions + if (trk.tpcInnerParam() >= pionMin && trk.tpcInnerParam() <= pionMax) { + if (calibrationMode) { + if (signedP < 0) { + registryDeDx.fill(HIST("hdEdx_vs_eta_Neg_Pi"), trk.eta(), trk.tpcSignal()); + } else { + registryDeDx.fill(HIST("hdEdx_vs_eta_Pos_Pi"), trk.eta(), trk.tpcSignal()); + } + + } else { + for (int i = 0; i < kEtaIntervals; ++i) { + if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { + if (signedP < 0) { + registryDeDx.fill(HIST("hdEdx_vs_eta_Neg_calibrated_Pi"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i)); + } else { + registryDeDx.fill(HIST("hdEdx_vs_eta_Pos_calibrated_Pi"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorPos->at(i)); + } + } + } + } + } + // Beta from TOF + if (signedP < 0) { + registryDeDx.fill(HIST("hbeta_vs_p_Neg"), std::abs(signedP), trk.beta()); + } else { + registryDeDx.fill(HIST("hbeta_vs_p_Pos"), signedP, trk.beta()); + } + // Electrons from TOF + if (std::abs(trk.beta() - 1) < elTofCut) { // beta cut + if (calibrationMode) { + if (signedP < 0) { + registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Neg_El"), trk.eta(), trk.tpcSignal(), std::abs(signedP)); + } else { + registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Pos_El"), trk.eta(), trk.tpcSignal(), signedP); + } + } else { + for (int i = 0; i < kEtaIntervals; ++i) { + if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { + if (signedP < 0) { + registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Neg_calibrated_El"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), std::abs(signedP)); + } else { + registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Pos_calibrated_El"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorPos->at(i), signedP); + } + } + } + } + } + // pions from TOF + if (trk.beta() > pionTofCut && trk.beta() < pionTofCut + 0.05) { // beta cut + if (calibrationMode) { + if (signedP < 0) { + registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Neg_TOF"), trk.eta(), trk.tpcSignal(), std::abs(signedP)); + } else { + registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Pos_TOF"), trk.eta(), trk.tpcSignal(), signedP); + } + } else { + for (int i = 0; i < kEtaIntervals; ++i) { + if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { + if (signedP < 0) { + registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Neg_calibrated_TOF"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), std::abs(signedP)); + } else { + registryDeDx.fill(HIST("hdEdx_vs_eta_vs_p_Pos_calibrated_TOF"), trk.eta(), trk.tpcSignal() * 50 / calibrationFactorPos->at(i), signedP); + } + } + } + } + } + + registryDeDx.fill(HIST("hdEdx_vs_phi"), trk.phi(), trk.tpcSignal()); + + if (!calibrationMode) { + for (int i = 0; i < kEtaIntervals; ++i) { + if (trk.eta() > EtaCut[i] && trk.eta() < EtaCut[i + 1]) { + if (signedP > 0) { + registryDeDx.fill(HIST(kDedxvsMomentumPos[0]), signedP, trk.tpcSignal() * 50 / calibrationFactorPos->at(i), trk.eta()); + registryDeDx.fill(HIST("hp_vs_pt_all_Pos"), trk.pt(), signedP); + } else { + registryDeDx.fill(HIST(kDedxvsMomentumNeg[0]), std::abs(signedP), trk.tpcSignal() * 50 / calibrationFactorNeg->at(i), trk.eta()); + registryDeDx.fill(HIST("hp_vs_pt_all_Neg"), trk.pt(), std::abs(signedP)); + } + } + } + } + } + + // Loop over Reconstructed V0s + if (!calibrationMode) { + for (const auto& v0 : fullV0s) { + + // Standard V0 Selections + if (!passedV0Selection(v0, collision)) { + continue; + } + + if (v0.dcaV0daughters() > dcaV0DaughtersMax) { + continue; + } + + // Positive and Negative Tracks + const auto& posTrack = v0.posTrack_as(); + const auto& negTrack = v0.negTrack_as(); + + if (!posTrack.passedTPCRefit()) + continue; + if (!negTrack.passedTPCRefit()) + continue; + // phi and Ncl cut + if (!passedPhiCutSecondaries(posTrack, magField, *fphiCutLow, *fphiCutHigh)) + continue; + + if (!passedPhiCutSecondaries(negTrack, magField, *fphiCutLow, *fphiCutHigh)) + continue; + + float signedPpos = posTrack.sign() * posTrack.tpcInnerParam(); + float signedPneg = negTrack.sign() * negTrack.tpcInnerParam(); + + float pxPos = posTrack.px(); + float pyPos = posTrack.py(); + float pzPos = posTrack.pz(); + + float pxNeg = negTrack.px(); + float pyNeg = negTrack.py(); + float pzNeg = negTrack.pz(); + + const float gammaMass = 2 * MassElectron; // GeV/c^2 + + // K0s Selection + if (passedK0Selection(v0, negTrack, posTrack, collision)) { + float ePosPi = posTrack.energy(MassPionCharged); + float eNegPi = negTrack.energy(MassPionCharged); + + float invMass = std::sqrt((eNegPi + ePosPi) * (eNegPi + ePosPi) - ((pxNeg + pxPos) * (pxNeg + pxPos) + (pyNeg + pyPos) * (pyNeg + pyPos) + (pzNeg + pzPos) * (pzNeg + pzPos))); + + if (std::abs(invMass - MassK0Short) > invMassCut) { + continue; + } + + for (int i = 0; i < kEtaIntervals; ++i) { + if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { + registryDeDx.fill(HIST(kDedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); + } + if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { + registryDeDx.fill(HIST(kDedxvsMomentumPos[1]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); + } + } + } + + // Lambda Selection + if (passedLambdaSelection(v0, negTrack, posTrack, collision)) { + + float ePosPr = posTrack.energy(MassProton); + float eNegPi = negTrack.energy(MassPionCharged); + + float invMass = std::sqrt((eNegPi + ePosPr) * (eNegPi + ePosPr) - ((pxNeg + pxPos) * (pxNeg + pxPos) + (pyNeg + pyPos) * (pyNeg + pyPos) + (pzNeg + pzPos) * (pzNeg + pzPos))); + + if (std::abs(invMass - MassLambda) > invMassCut) { + continue; + } + + for (int i = 0; i < kEtaIntervals; ++i) { + if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { + registryDeDx.fill(HIST(kDedxvsMomentumNeg[1]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); + } + if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { + registryDeDx.fill(HIST(kDedxvsMomentumPos[2]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); + } + } + } + + // AntiLambda Selection + if (passedAntiLambdaSelection(v0, negTrack, posTrack, collision)) { + + float ePosPi = posTrack.energy(MassPionCharged); + float eNegPr = negTrack.energy(MassProton); + + float invMass = std::sqrt((eNegPr + ePosPi) * (eNegPr + ePosPi) - ((pxNeg + pxPos) * (pxNeg + pxPos) + (pyNeg + pyPos) * (pyNeg + pyPos) + (pzNeg + pzPos) * (pzNeg + pzPos))); + + if (std::abs(invMass - MassLambda) > invMassCut) { + continue; + } + + for (int i = 0; i < kEtaIntervals; ++i) { + if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { + registryDeDx.fill(HIST(kDedxvsMomentumNeg[2]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); + } + if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { + registryDeDx.fill(HIST(kDedxvsMomentumPos[1]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); + } + } + } + + // Gamma Selection + if (passedGammaSelection(v0, negTrack, posTrack, collision)) { + + float ePosEl = posTrack.energy(MassElectron); + float eNegEl = negTrack.energy(MassElectron); + + float invMass = std::sqrt((eNegEl + ePosEl) * (eNegEl + ePosEl) - ((pxNeg + pxPos) * (pxNeg + pxPos) + (pyNeg + pyPos) * (pyNeg + pyPos) + (pzNeg + pzPos) * (pzNeg + pzPos))); + + if (std::abs(invMass - gammaMass) > invMassCutGamma) { + continue; + } + + for (int i = 0; i < kEtaIntervals; ++i) { + if (negTrack.eta() > EtaCut[i] && negTrack.eta() < EtaCut[i + 1]) { + registryDeDx.fill(HIST(kDedxvsMomentumNeg[3]), std::abs(signedPneg), negTrack.tpcSignal() * 50 / calibrationFactorNeg->at(i), negTrack.eta()); + } + if (posTrack.eta() > EtaCut[i] && posTrack.eta() < EtaCut[i + 1]) { + registryDeDx.fill(HIST(kDedxvsMomentumPos[3]), signedPpos, posTrack.tpcSignal() * 50 / calibrationFactorPos->at(i), posTrack.eta()); + } + } + } + } + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/Tasks/Nuspex/he3LambdaDerivedAnalysis.cxx b/PWGLF/Tasks/Nuspex/he3LambdaDerivedAnalysis.cxx index 6d8f95d4ba2..7929f4eaa9c 100644 --- a/PWGLF/Tasks/Nuspex/he3LambdaDerivedAnalysis.cxx +++ b/PWGLF/Tasks/Nuspex/he3LambdaDerivedAnalysis.cxx @@ -64,7 +64,7 @@ struct he3LambdaDerivedAnalysis { hNsigmaProton = mRegistry.add("hNsigmaProton", "nSigma TPC for Proton", {HistType::kTH2D, {{100, -10., 10.}, {200, -5, 5.}}}); } - void processSameEvent(o2::aod::LFEvents::iterator const& collision, o2::aod::LFHe3 const& he3s, o2::aod::LFLambda const& lambdas) + void processSameEvent(o2::aod::LFEvents::iterator const& collision, o2::aod::LFHe3_000 const& he3s, o2::aod::LFLambda_000 const& lambdas) { std::vector he3Candidates; he3Candidates.reserve(he3s.size()); diff --git a/PWGLF/Tasks/Nuspex/nucleitpcpbpb.cxx b/PWGLF/Tasks/Nuspex/nucleitpcpbpb.cxx index d69d0b97b93..78edc84586b 100644 --- a/PWGLF/Tasks/Nuspex/nucleitpcpbpb.cxx +++ b/PWGLF/Tasks/Nuspex/nucleitpcpbpb.cxx @@ -67,15 +67,26 @@ constexpr double kBetheBlochDefault[nParticles][nBetheParams]{ {5.393020, 7.859534, 0.004048, 2.323197, 1.609307, 0.09}, // triton {-126.557359, -0.858569, 1.111643, 1.210323, 2.656374, 0.09}, // helion {-126.557359, -0.858569, 1.111643, 1.210323, 2.656374, 0.09}}; // alpha -const int nTrkSettings = 19; -static const std::vector trackPIDsettingsNames{"useBBparams", "minITSnCls", "minITSnClscos", "minTPCnCls", "maxTPCchi2", "minTPCchi2", "maxITSchi2", "minRigidity", "maxRigidity", "maxTPCnSigma", "TOFrequiredabove", "minTOFmass", "maxTOFmass", "maxDcaXY", "maxDcaZ", "minITSclsSize", "maxITSclsSize", "minTPCnClsCrossedRows", "minReqClusterITSib"}; +const int nTrkSettings = 14; +static const std::vector trackPIDsettingsNames{"useBBparams", "minITSnCls", "minITSnClscos", "minTPCnCls", "maxTPCchi2", "minTPCchi2", "maxITSchi2", "maxTPCnSigma", "maxDcaXY", "maxDcaZ", "minITSclsSize", "maxITSclsSize", "minTPCnClsCrossedRows", "minReqClusterITSib"}; constexpr double kTrackPIDSettings[nParticles][nTrkSettings]{ - {0, 0, 4, 60, 4.0, 0.5, 100, 0.15, 1.2, 2.5, -1, 0, 100, 2., 2., 0., 1000, 70, 1}, - {1, 0, 4, 70, 4.0, 0.5, 100, 0.20, 4.0, 3.0, -1, 0, 100, 2., 2., 0., 1000, 70, 1}, - {1, 0, 4, 70, 4.0, 0.5, 100, 0.50, 5.0, 3.0, -1, 0, 100, 2., 2., 0., 1000, 70, 1}, - {1, 0, 4, 70, 4.0, 0.5, 100, 0.50, 5.0, 3.0, -1, 0, 100, 2., 2., 0., 1000, 70, 1}, - {1, 0, 4, 75, 4.0, 0.5, 100, 0.50, 5.0, 5.0, -1, 0, 100, 2., 2., 0., 1000, 70, 1}, - {1, 0, 4, 70, 4.0, 0.5, 100, 0.50, 5.0, 5.0, -1, 0, 100, 2., 2., 0., 1000, 70, 1}}; + {0, 0, 4, 60, 4.0, 0.5, 100, 2.5, 2., 2., 0., 1000, 70, 1}, + {1, 0, 4, 70, 4.0, 0.5, 100, 3.0, 2., 2., 0., 1000, 70, 1}, + {1, 0, 4, 70, 4.0, 0.5, 100, 3.0, 2., 2., 0., 1000, 70, 1}, + {1, 0, 4, 70, 4.0, 0.5, 100, 3.0, 2., 2., 0., 1000, 70, 1}, + {1, 0, 4, 75, 4.0, 0.5, 100, 5.0, 2., 2., 0., 1000, 70, 1}, + {1, 0, 4, 70, 4.0, 0.5, 100, 5.0, 2., 2., 0., 1000, 70, 1}}; + +const int nTrkSettings2 = 4; +static const std::vector trackPIDsettingsNames2{"useITSnsigma", "minITSnsigma", "maxITSnsigma", "fillsparsh"}; +constexpr double kTrackPIDSettings2[nParticles][nTrkSettings2]{ + {1, -5, 4, 0}, + {1, -5, 4, 0}, + {1, -5, 4, 0}, + {1, -5, 4, 1}, + {1, -5, 4, 1}, + {1, -5, 4, 1}}; + struct PrimParticles { TString name; int pdgCode, charge; @@ -92,8 +103,6 @@ struct PrimParticles { } }; // struct PrimParticles //---------------------------------------------------------------------------------------------------------------- -std::vector> hDeDx; -std::vector> hNsigmaPt; std::vector> hmass; } // namespace //---------------------------------------------------------------------------------------------------------------- @@ -130,21 +139,16 @@ struct NucleitpcPbPb { Configurable cfgminReqClusterITSibRequire{"cfgminReqClusterITSibRequire", true, " Require min number of clusters required in ITS inner barrel"}; Configurable cfgmaxITSchi2Require{"cfgmaxITSchi2Require", true, "Require maxITSchi2 Cut"}; Configurable cfgmaxTPCnSigmaRequire{"cfgmaxTPCnSigmaRequire", true, "Require maxTPCnSigma Cut"}; - Configurable cfgmaxITSnSigmaRequire{"cfgmaxITSnSigmaRequire", true, "Require maxITSnSigma Cut for helium"}; Configurable cfgminGetMeanItsClsSizeRequire{"cfgminGetMeanItsClsSizeRequire", true, "Require minGetMeanItsClsSize Cut"}; Configurable cfgmaxGetMeanItsClsSizeRequire{"cfgmaxGetMeanItsClsSizeRequire", true, "Require maxGetMeanItsClsSize Cut"}; - Configurable cfgRigidityCutRequire{"cfgRigidityCutRequire", true, "Require Rigidity Cut"}; - Configurable cfgmassRequire{"cfgmassRequire", true, "Require mass Cuts"}; Configurable cfgDCAwithptRequire{"cfgDCAwithptRequire", true, "Require DCA cuts with pt dependance"}; Configurable cfgDCAnopt{"cfgDCAnopt", true, "Require DCA cuts without pt dependance"}; - Configurable cfgTwicemass{"cfgTwicemass", true, "multiply mass by its charge"}; Configurable cfgRequirebetaplot{"cfgRequirebetaplot", true, "Require beta plot"}; - Configurable cfgRequireMCposZ{"cfgRequireMCposZ", true, "Require beta plot"}; Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {kBetheBlochDefault[0], nParticles, nBetheParams, particleNames, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for light nuclei"}; Configurable> cfgTrackPIDsettings{"cfgTrackPIDsettings", {kTrackPIDSettings[0], nParticles, nTrkSettings, particleNames, trackPIDsettingsNames}, "track selection and PID criteria"}; - Configurable cfgFillDeDxWithCut{"cfgFillDeDxWithCut", true, "Fill with cut beth bloch"}; - Configurable cfgFillnsigma{"cfgFillnsigma", false, "Fill n-sigma histograms"}; + Configurable> cfgTrackPIDsettings2{"cfgTrackPIDsettings2", {kTrackPIDSettings2[0], nParticles, nTrkSettings2, particleNames, trackPIDsettingsNames2}, "track selection and PID criteria"}; + Configurable cfgFillhspectra{"cfgFillhspectra", true, "fill data sparsh"}; Configurable cfgFillmass{"cfgFillmass", false, "Fill mass histograms"}; Configurable centcut{"centcut", 80.0f, "centrality cut"}; Configurable cfgCutRapidity{"cfgCutRapidity", 0.5f, "Rapidity range"}; @@ -152,7 +156,6 @@ struct NucleitpcPbPb { Configurable cfgZvertexRequire{"cfgZvertexRequire", true, "Pos Z cut require"}; Configurable cfgZvertexRequireMC{"cfgZvertexRequireMC", true, "Pos Z cut require for generated particles"}; Configurable cfgsel8Require{"cfgsel8Require", true, "sel8 cut require"}; - Configurable cfgITSnsigma{"cfgITSnsigma", 5, "Max ITS nsigma value"}; Configurable cfgtpcNClsFound{"cfgtpcNClsFound", 100.0f, "min. no. of tpcNClsFound"}; Configurable cfgitsNCls{"cfgitsNCls", 2.0f, "min. no. of itsNCls"}; o2::track::TrackParametrizationWithError mTrackParCov; @@ -169,6 +172,13 @@ struct NucleitpcPbPb { ConfigurableAxis axisrapidity{"axisrapidity", {100, -2, 2}, "rapidity"}; ConfigurableAxis axismass{"axismass", {100, -10, 10}, "mass^{2}"}; ConfigurableAxis nsigmaAxis{"nsigmaAxis", {160, -20, 20}, "n#sigma_{#pi^{+}}"}; + ConfigurableAxis speciesBitAxis{"speciesBitAxis", {8, -0.5, 7.5}, "particle type 0: pion, 1: proton, 2: deuteron, 3: triton, 4:He3, 5:He4"}; + ConfigurableAxis axisDCA{"axisDCA", {400, -10., 10.}, "DCA axis"}; + ConfigurableAxis axisTPCcls{"axisTPCcls", {400, 0., 200.}, "TPCcls axis"}; + ConfigurableAxis axisITScls{"axisITScls", {400, 0., 200.}, "ITScls axis"}; + ConfigurableAxis axisITSchi2{"axisITSchi2", {400, 0., 100.}, "ITSchi2 axis"}; + ConfigurableAxis axisTPCchi2{"axisTPCchi2", {400, 0., 100.}, "TPCchi2 axis"}; + // CCDB Service ccdb; Configurable bField{"bField", -999, "bz field, -999 is automatic"}; @@ -211,31 +221,20 @@ struct NucleitpcPbPb { } histos.add("histeta", "histeta", kTH1F, {axiseta}); histos.add("Tofsignal", "Tofsignal", kTH2F, {axisRigidity, {4000, 0.2, 1.2, "#beta"}}); - histos.add("histDcaZVsPtData_particle", "dcaZ vs Pt (particle)", HistType::kTH2F, {{1000, 0, 20}, {1000, -2.5, 2.5, "dca"}}); - histos.add("histDcaXYVsPtData_particle", "dcaXY vs Pt (particle)", HistType::kTH2F, {{1000, 0, 20}, {1000, -2.0, 2.0, "dca"}}); - histos.add("histDcaZVsPtData_antiparticle", "dcaZ vs Pt (antiparticle)", HistType::kTH2F, {{1000, 0, 20}, {1000, -2.5, 2.5, "dca"}}); - histos.add("histDcaXYVsPtData_antiparticle", "dcaXY vs Pt (antiparticle)", HistType::kTH2F, {{1000, 0, 20}, {1000, -2.0, 2.0, "dca"}}); - hDeDx.resize(2 * nParticles + 2); - hNsigmaPt.resize(2 * nParticles + 2); + histos.add("Tpcsignal", "Tpcsignal", kTH2F, {axisRigidity, axisdEdx}); + hmass.resize(2 * nParticles + 2); - for (int i = 0; i < nParticles + 1; i++) { - TString histName = i < nParticles ? primaryParticles[i].name : "all"; - if (cfgFillDeDxWithCut) { - hDeDx[2 * i] = histos.add(Form("dedx/histdEdx_%s_Cuts", histName.Data()), ";p_{TPC}/z (GeV/#it{c}); d#it{E}/d#it{x}", HistType::kTH2F, {axisRigidity, axisdEdx}); - } - } + for (int i = 0; i < nParticles; i++) { TString histName = primaryParticles[i].name; - if (cfgFillnsigma) { - hNsigmaPt[2 * i] = histos.add(Form("histnsigmaTPC_%s", histName.Data()), ";p_T{TPC} (GeV/#it{c}); TPCnsigma", HistType::kTH2F, {ptAxis, nsigmaAxis}); - hNsigmaPt[2 * i + 1] = histos.add(Form("histnsigmaTPC_anti_%s", histName.Data()), ";p_T{TPC} (GeV/#it{c}); TPCnsigma", HistType::kTH2F, {ptAxis, nsigmaAxis}); - } if (cfgFillmass) { hmass[2 * i] = histos.add(Form("histmass_pt/histmass_%s", histName.Data()), ";p_T{TPC} (GeV/#it{c}); mass^{2}", HistType::kTH2F, {ptAxis, axismass}); hmass[2 * i + 1] = histos.add(Form("histmass_ptanti/histmass_%s", histName.Data()), ";p_T{TPC} (GeV/#it{c}); mass^{2}", HistType::kTH2F, {ptAxis, axismass}); } } + histos.add("hSpectra", " ", HistType::kTHnSparseF, {speciesBitAxis, ptAxis, nsigmaAxis, {5, -2.5, 2.5}, axisCent, axisRigidity, axisdEdx, axisDCA, axisDCA, nsigmaAxis}); + if (doprocessMC) { histomc.add("histVtxZgen", "histVtxZgen", kTH1F, {axisVtxZ}); histomc.add("ImptParameter", "ImptParameter", kTH1F, {axisImpt}); @@ -259,88 +258,6 @@ struct NucleitpcPbPb { } } //---------------------------------------------------------------------------------------------------------------- - void findprimaryParticles(aod::TrackAssoc const& tracksByColl, TracksFull const& tracks) - { - for (const auto& trackId : tracksByColl) { - const auto& track = tracks.rawIteratorAt(trackId.trackId()); - if (!track.isPVContributor() && cfgUsePVcontributors) - continue; - if (!track.hasITS() && cfgITSrequire) - continue; - if (!track.hasTPC() && cfgTPCrequire) - continue; - if (!track.passedITSRefit() && cfgPassedITSRefit) - continue; - if (!track.passedTPCRefit() && cfgPassedTPCRefit) - continue; - if (std::abs(track.eta()) > cfgCutEta && cfgetaRequire) - continue; - for (size_t i = 0; i < primaryParticles.size(); i++) { - if (std::abs(getRapidity(track, i)) > cfgCutRapidity && cfgRapidityRequire) - continue; - if (track.tpcNClsFound() < cfgTrackPIDsettings->get(i, "minTPCnCls") && cfgTPCNClsfoundRequire) - continue; - if (((track.tpcNClsCrossedRows() < cfgTrackPIDsettings->get(i, "minTPCnClsCrossedRows")) || track.tpcNClsCrossedRows() < 0.8 * track.tpcNClsFindable()) && cfgTPCNClsCrossedRowsRequire) // o2-linter: disable=magic-number (To be checked) - continue; - if (track.tpcChi2NCl() > cfgTrackPIDsettings->get(i, "maxTPCchi2") && cfgmaxTPCchi2Require) - continue; - if (track.tpcChi2NCl() < cfgTrackPIDsettings->get(i, "minTPCchi2") && cfgminTPCchi2Require) - continue; - if (track.itsNCls() < cfgTrackPIDsettings->get(i, "minITSnCls") && cfgminITSnClsRequire) - continue; - double cosheta = std::cosh(track.eta()); - if ((track.itsNCls() / cosheta) < cfgTrackPIDsettings->get(i, "minITSnClscos") && cfgminITSnClscosRequire) - continue; - if ((track.itsNClsInnerBarrel() < cfgTrackPIDsettings->get(i, "minReqClusterITSib")) && cfgminReqClusterITSibRequire) - continue; - if (track.itsChi2NCl() > cfgTrackPIDsettings->get(i, "maxITSchi2") && cfgmaxITSchi2Require) - continue; - if (getMeanItsClsSize(track) < cfgTrackPIDsettings->get(i, "minITSclsSize") && cfgminGetMeanItsClsSizeRequire) - continue; - if (getMeanItsClsSize(track) > cfgTrackPIDsettings->get(i, "maxITSclsSize") && cfgmaxGetMeanItsClsSizeRequire) - continue; - if ((getRigidity(track) < cfgTrackPIDsettings->get(i, "minRigidity") || getRigidity(track) > cfgTrackPIDsettings->get(i, "maxRigidity")) && cfgRigidityCutRequire) - continue; - float ptMomn; - setTrackParCov(track, mTrackParCov); - mTrackParCov.setPID(track.pidForTracking()); - ptMomn = (i == he3 || i == he4) ? 2 * mTrackParCov.getPt() : mTrackParCov.getPt(); - bool insideDCAxy = (std::abs(track.dcaXY()) <= (cfgTrackPIDsettings->get(i, "maxDcaXY") * (0.0105f + 0.0350f / std::pow(ptMomn, 1.1f)))); // o2-linter: disable=magic-number (To be checked) - if ((!(insideDCAxy) || std::abs(track.dcaZ()) > dcazSigma(ptMomn, cfgTrackPIDsettings->get(i, "maxDcaZ"))) && cfgDCAwithptRequire) - continue; - if (track.sign() > 0) { - histos.fill(HIST("histDcaZVsPtData_particle"), ptMomn, track.dcaZ()); - histos.fill(HIST("histDcaXYVsPtData_particle"), ptMomn, track.dcaXY()); - } - if (track.sign() < 0) { - histos.fill(HIST("histDcaZVsPtData_antiparticle"), ptMomn, track.dcaZ()); - histos.fill(HIST("histDcaXYVsPtData_antiparticle"), ptMomn, track.dcaXY()); - } - float tpcNsigma = getTPCnSigma(track, primaryParticles.at(i)); - if ((std::abs(tpcNsigma) > cfgTrackPIDsettings->get(i, "maxTPCnSigma")) && cfgmaxTPCnSigmaRequire) - continue; - float itsSigma = getITSnSigma(track, primaryParticles.at(i)); - if ((std::abs(itsSigma) > cfgITSnsigma) && cfgmaxITSnSigmaRequire) - continue; - fillnsigma(track, i); - filldedx(track, i); - // TOF selection - if (!track.hasTOF() && cfgTrackPIDsettings->get(i, "TOFrequiredabove") < 1) - continue; - float beta{o2::pid::tof::Beta::GetBeta(track)}; - float charge{1.f + static_cast(i == he3 || i == he4)}; - float tofMasses = getRigidity(track) * charge * std::sqrt(1.f / (beta * beta) - 1.f); - if ((getRigidity(track) > cfgTrackPIDsettings->get(i, "TOFrequiredabove") && (tofMasses < cfgTrackPIDsettings->get(i, "minTOFmass") || tofMasses > cfgTrackPIDsettings->get(i, "maxTOFmass"))) && cfgmassRequire) - continue; - fillhmass(track, i); - if (cfgRequirebetaplot) { - histos.fill(HIST("Tofsignal"), getRigidity(track) * track.sign(), o2::pid::tof::Beta::GetBeta(track)); - } - filldedx(track, nParticles); - } - histos.fill(HIST("histeta"), track.eta()); - } // track loop - } //---------------------------------------------------------------------------------------------------------------- void processData(CollisionsFull const& collisions, TracksFull const& tracks, aod::BCsWithTimestamps const&, aod::TrackAssoc const& tracksColl) { @@ -365,9 +282,86 @@ struct NucleitpcPbPb { histos.fill(HIST("histCentFTOC_cut"), collision.centFT0C()); const uint64_t collIdx = collision.globalIndex(); auto tracksByColl = tracksColl.sliceBy(perCollision, collIdx); - findprimaryParticles(tracksByColl, tracks); - if (!collHasCandidate) - continue; + ///////////////////////////////////////////////////////////////////////////////// + for (const auto& trackId : tracksByColl) { + const auto& track = tracks.rawIteratorAt(trackId.trackId()); + if (!track.isPVContributor() && cfgUsePVcontributors) + continue; + if (!track.hasITS() && cfgITSrequire) + continue; + if (!track.hasTPC() && cfgTPCrequire) + continue; + if (!track.passedITSRefit() && cfgPassedITSRefit) + continue; + if (!track.passedTPCRefit() && cfgPassedTPCRefit) + continue; + if (std::abs(track.eta()) > cfgCutEta && cfgetaRequire) + continue; + for (size_t i = 0; i < primaryParticles.size(); i++) { + + float ptMomn; + setTrackParCov(track, mTrackParCov); + mTrackParCov.setPID(track.pidForTracking()); + ptMomn = (i == he3 || i == he4) ? 2 * mTrackParCov.getPt() : mTrackParCov.getPt(); + int sign = 0; + if (track.sign() > 0) { + sign = 1; + } + if (track.sign() < 0) { + sign = -1; + } // <- This redeclares a new local variable! + if (std::abs(getRapidity(track, i)) > cfgCutRapidity && cfgRapidityRequire) + continue; + if (track.tpcNClsFound() < cfgTrackPIDsettings->get(i, "minTPCnCls") && cfgTPCNClsfoundRequire) + continue; + if (((track.tpcNClsCrossedRows() < cfgTrackPIDsettings->get(i, "minTPCnClsCrossedRows")) || track.tpcNClsCrossedRows() < 0.8 * track.tpcNClsFindable()) && cfgTPCNClsCrossedRowsRequire) // o2-linter: disable=magic-number (To be checked) + continue; + if (track.tpcChi2NCl() > cfgTrackPIDsettings->get(i, "maxTPCchi2") && cfgmaxTPCchi2Require) + continue; + if (track.tpcChi2NCl() < cfgTrackPIDsettings->get(i, "minTPCchi2") && cfgminTPCchi2Require) + continue; + if (track.itsNCls() < cfgTrackPIDsettings->get(i, "minITSnCls") && cfgminITSnClsRequire) + continue; + double cosheta = std::cosh(track.eta()); + if ((track.itsNCls() / cosheta) < cfgTrackPIDsettings->get(i, "minITSnClscos") && cfgminITSnClscosRequire) + continue; + if ((track.itsNClsInnerBarrel() < cfgTrackPIDsettings->get(i, "minReqClusterITSib")) && cfgminReqClusterITSibRequire) + continue; + if (track.itsChi2NCl() > cfgTrackPIDsettings->get(i, "maxITSchi2") && cfgmaxITSchi2Require) + continue; + if (getMeanItsClsSize(track) < cfgTrackPIDsettings->get(i, "minITSclsSize") && cfgminGetMeanItsClsSizeRequire) + continue; + if (getMeanItsClsSize(track) > cfgTrackPIDsettings->get(i, "maxITSclsSize") && cfgmaxGetMeanItsClsSizeRequire) + continue; + + bool insideDCAxy = (std::abs(track.dcaXY()) <= (cfgTrackPIDsettings->get(i, "maxDcaXY") * (0.0105f + 0.0350f / std::pow(ptMomn, 1.1f)))); // o2-linter: disable=magic-number (To be checked) + if ((!(insideDCAxy) || std::abs(track.dcaZ()) > dcazSigma(ptMomn, cfgTrackPIDsettings->get(i, "maxDcaZ"))) && cfgDCAwithptRequire) + continue; + + float tpcNsigma = getTPCnSigma(track, primaryParticles.at(i)); + if ((std::abs(tpcNsigma) > cfgTrackPIDsettings->get(i, "maxTPCnSigma")) && cfgmaxTPCnSigmaRequire) + continue; + float itsSigma = getITSnSigma(track, primaryParticles.at(i)); + + if (itsSigma < cfgTrackPIDsettings2->get(i, "minITSnsigma") && cfgTrackPIDsettings2->get(i, "useITSnsigma") < 1) + continue; + if (itsSigma > cfgTrackPIDsettings2->get(i, "maxITSnsigma") && cfgTrackPIDsettings2->get(i, "useITSnsigma") < 1) + continue; + + fillhmass(track, i); + if (cfgFillhspectra && cfgTrackPIDsettings2->get(i, "fillsparsh") == 1) { + histos.fill(HIST("hSpectra"), i, ptMomn, tpcNsigma, sign, collision.centFT0C(), getRigidity(track) * track.sign(), track.tpcSignal(), track.dcaZ(), track.dcaXY(), itsSigma); + } + if (cfgRequirebetaplot) { + histos.fill(HIST("Tofsignal"), getRigidity(track) * track.sign(), o2::pid::tof::Beta::GetBeta(track)); + } + } + if (track.tpcNClsFound() > cfgtpcNClsFound || track.itsNCls() > cfgitsNCls) { + histos.fill(HIST("Tpcsignal"), getRigidity(track) * track.sign(), track.tpcSignal()); + } + histos.fill(HIST("histeta"), track.eta()); + } // track loop + /////////////////////////////////////////////// } } PROCESS_SWITCH(NucleitpcPbPb, processData, "data analysis", false); @@ -473,6 +467,18 @@ struct NucleitpcPbPb { for (size_t i = 0; i < primaryParticles.size(); i++) { if (std::abs(pdg) != std::abs(particlePdgCodes.at(i))) continue; + + float ptMomn; + setTrackParCov(track, mTrackParCov); + mTrackParCov.setPID(track.pidForTracking()); + ptMomn = (i == he3 || i == he4) ? 2 * mTrackParCov.getPt() : mTrackParCov.getPt(); + int sign = 0; + if (track.sign() > 0) { + sign = 1; + } + if (track.sign() < 0) { + sign = -1; + } // <- This redeclares a new local variable! if (std::abs(getRapidity(track, i)) > cfgCutRapidity && cfgRapidityRequire) continue; if (track.tpcNClsFound() < cfgTrackPIDsettings->get(i, "minTPCnCls") && cfgTPCNClsfoundRequire) @@ -496,43 +502,29 @@ struct NucleitpcPbPb { continue; if (getMeanItsClsSize(track) > cfgTrackPIDsettings->get(i, "maxITSclsSize") && cfgmaxGetMeanItsClsSizeRequire) continue; - if ((getRigidity(track) < cfgTrackPIDsettings->get(i, "minRigidity") || getRigidity(track) > cfgTrackPIDsettings->get(i, "maxRigidity")) && cfgRigidityCutRequire) - continue; - float ptMomn; - setTrackParCov(track, mTrackParCov); - mTrackParCov.setPID(track.pidForTracking()); - ptMomn = (i == he3 || i == he4) ? 2 * mTrackParCov.getPt() : mTrackParCov.getPt(); + bool insideDCAxy = (std::abs(track.dcaXY()) <= (cfgTrackPIDsettings->get(i, "maxDcaXY") * (0.0105f + 0.0350f / std::pow(ptMomn, 1.1f)))); // o2-linter: disable=magic-number (To be checked) if ((!(insideDCAxy) || std::abs(track.dcaZ()) > dcazSigma(ptMomn, cfgTrackPIDsettings->get(i, "maxDcaZ"))) && cfgDCAwithptRequire) continue; - if (track.sign() > 0) { - histos.fill(HIST("histDcaZVsPtData_particle"), ptMomn, track.dcaZ()); - histos.fill(HIST("histDcaXYVsPtData_particle"), ptMomn, track.dcaXY()); - } - if (track.sign() < 0) { - histos.fill(HIST("histDcaZVsPtData_antiparticle"), ptMomn, track.dcaZ()); - histos.fill(HIST("histDcaXYVsPtData_antiparticle"), ptMomn, track.dcaXY()); - } + float tpcNsigma = getTPCnSigma(track, primaryParticles.at(i)); if ((std::abs(tpcNsigma) > cfgTrackPIDsettings->get(i, "maxTPCnSigma")) && cfgmaxTPCnSigmaRequire) continue; float itsSigma = getITSnSigma(track, primaryParticles.at(i)); - if ((std::abs(itsSigma) > cfgITSnsigma) && cfgmaxITSnSigmaRequire) - continue; - fillnsigma(track, i); - filldedx(track, i); - if (!track.hasTOF() && cfgTrackPIDsettings->get(i, "TOFrequiredabove") < 1) + + if (itsSigma < cfgTrackPIDsettings2->get(i, "minITSnsigma") && cfgTrackPIDsettings2->get(i, "useITSnsigma") < 1) continue; - float beta{o2::pid::tof::Beta::GetBeta(track)}; - float charge{1.f + static_cast(i == he3 || i == he4)}; - float tofMasses = getRigidity(track) * charge * std::sqrt(1.f / (beta * beta) - 1.f); - if ((getRigidity(track) > cfgTrackPIDsettings->get(i, "TOFrequiredabove") && (tofMasses < cfgTrackPIDsettings->get(i, "minTOFmass") || tofMasses > cfgTrackPIDsettings->get(i, "maxTOFmass"))) && cfgmassRequire) + if (itsSigma > cfgTrackPIDsettings2->get(i, "maxITSnsigma") && cfgTrackPIDsettings2->get(i, "useITSnsigma") < 1) continue; + fillhmass(track, i); + if (cfgFillhspectra && cfgTrackPIDsettings2->get(i, "fillsparsh") == 1) { + histos.fill(HIST("hSpectra"), i, ptMomn, tpcNsigma, sign, collision.centFT0C(), getRigidity(track) * track.sign(), track.tpcSignal(), track.dcaZ(), track.dcaXY(), itsSigma); + } if (cfgRequirebetaplot) { histos.fill(HIST("Tofsignal"), getRigidity(track) * track.sign(), o2::pid::tof::Beta::GetBeta(track)); } - filldedx(track, nParticles); + /*----------------------------------------------------------------------------------------------------------------*/ float ptReco; mTrackParCov.setPID(track.pidForTracking()); @@ -631,42 +623,8 @@ struct NucleitpcPbPb { } //---------------------------------------------------------------------------------------------------------------- template - void filldedx(T const& track, int species) - { - const float rigidity = getRigidity(track); - if (track.tpcNClsFound() < cfgtpcNClsFound || track.itsNCls() < cfgitsNCls) - return; - if (cfgFillDeDxWithCut) { - hDeDx[2 * species]->Fill(track.sign() * rigidity, track.tpcSignal()); - } - } - //---------------------------------------------------------------------------------------------------------------- - template - void fillnsigma(T const& track, int species) - { - if (track.tpcNClsFound() < cfgtpcNClsFound || track.itsNCls() < cfgitsNCls) - return; - if (cfgFillnsigma) { - int i = species; - const float tpcNsigma = getTPCnSigma(track, primaryParticles.at(i)); - float ptMomn; - setTrackParCov(track, mTrackParCov); - mTrackParCov.setPID(track.pidForTracking()); - ptMomn = (i == he3 || i == he4) ? 2 * mTrackParCov.getPt() : mTrackParCov.getPt(); - if (track.sign() > 0) { - hNsigmaPt[2 * species]->Fill(ptMomn, tpcNsigma); - } - if (track.sign() < 0) { - hNsigmaPt[2 * species + 1]->Fill(ptMomn, tpcNsigma); - } - } - } - //---------------------------------------------------------------------------------------------------------------- - template void fillhmass(T const& track, int species) { - if (track.tpcNClsFound() < cfgtpcNClsFound || track.itsNCls() < cfgitsNCls) - return; if (!track.hasTOF() || !cfgFillmass) return; float beta{o2::pid::tof::Beta::GetBeta(track)}; diff --git a/PWGLF/Tasks/QC/strangepidqa.cxx b/PWGLF/Tasks/QC/strangepidqa.cxx index c2bd9d89774..2dd9c58b4e7 100644 --- a/PWGLF/Tasks/QC/strangepidqa.cxx +++ b/PWGLF/Tasks/QC/strangepidqa.cxx @@ -54,11 +54,13 @@ struct strangepidqa { 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}, "p_{T} (GeV/c)"}; ConfigurableAxis axisRadius{"axisRadius", {200, 0.0f, 100.0f}, "V0 radius (cm)"}; - AxisSpec centAxis = {100, 0.0f, 100.0f, "mult percentile"}; + ConfigurableAxis centAxis{"centAxis", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 50.0f, 70.0f, 100.0f}, "FT0C centrality"}; + AxisSpec massAxisXi = {200, 1.222f, 1.422f, "Inv. Mass (GeV/c^{2})"}; AxisSpec massAxisOmega = {200, 1.572f, 1.772f, "Inv. Mass (GeV/c^{2})"}; // Invariant Mass + ConfigurableAxis axisK0ShortMass{"axisK0ShortMass", {200, 0.497f - 0.050f, 0.497f + 0.050f}, "M_{K0s} (GeV/c^{2})"}; ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.08f, 1.16f}, "M_{#Lambda} (GeV/c^{2})"}; // time axes @@ -117,6 +119,9 @@ struct strangepidqa { Configurable tofNsigmaOmLaPr{"tpcNsigmaOmLaPr", 1e+5, "TOF NSigma proton <- lambda <- Omega (>10 is no cut)"}; Configurable tofNsigmaOmLaPi{"tpcNsigmaOmLaPi", 1e+5, "TOF NSigma pion <- lambda <- Omega (>10 is no cut)"}; Configurable tofNsigmaOmKa{"tpcNsigmaOmKa", 1e+5, "TOF NSigma Kaon <- Omega (>10 is no cut)"}; + + Configurable tofNsigmaCompatibility{"tofNsigmaCompatibility", 4, "compatibility check for V0s"}; + Configurable tofNsigmaCompatibilityCascades{"tofNsigmaCompatibilityCascades", 4, "compatibility check for cascades"}; //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* void init(InitContext const&) @@ -215,6 +220,21 @@ struct strangepidqa { histos.add("h2dTimeVsLengthProtonProng", "h2dTimeVsLengthProtonProng", {HistType::kTH2F, {axisLength, axisTime}}); histos.add("h2dTimeVsLengthPionProng", "h2dTimeVsLengthPionProng", {HistType::kTH2F, {axisLength, axisTime}}); + histos.add("h1dMassK0Short", "h1dMassK0Short", {HistType::kTH1F, {axisK0ShortMass}}); + histos.add("h1dMassLambda", "h1dMassLambda", {HistType::kTH1F, {axisLambdaMass}}); + histos.add("h1dMassAntiLambda", "h1dMassAntiLambda", {HistType::kTH1F, {axisLambdaMass}}); + histos.add("h1dMassCompatibleK0Short", "h1dMassCompatibleK0Short", {HistType::kTH1F, {axisK0ShortMass}}); + histos.add("h1dMassCompatibleLambda", "h1dMassCompatibleLambda", {HistType::kTH1F, {axisLambdaMass}}); + histos.add("h1dMassCompatibleAntiLambda", "h1dMassCompatibleAntiLambda", {HistType::kTH1F, {axisLambdaMass}}); + + histos.add("h3dMassK0Short", "h3dMassK0Short", {HistType::kTH3F, {centAxis, axisPt, axisK0ShortMass}}); + histos.add("h3dMassLambda", "h3dMassLambda", {HistType::kTH3F, {centAxis, axisPt, axisLambdaMass}}); + histos.add("h3dMassAntiLambda", "h3dMassAntiLambda", {HistType::kTH3F, {centAxis, axisPt, axisLambdaMass}}); + + histos.add("h3dMassCompatibleK0Short", "h3dMassCompatibleK0Short", {HistType::kTH3F, {centAxis, axisPt, axisK0ShortMass}}); + histos.add("h3dMassCompatibleLambda", "h3dMassCompatibleLambda", {HistType::kTH3F, {centAxis, axisPt, axisLambdaMass}}); + histos.add("h3dMassCompatibleAntiLambda", "h3dMassCompatibleAntiLambda", {HistType::kTH3F, {centAxis, axisPt, axisLambdaMass}}); + // --- ASSOCIATED --- // V0 Radius if (doprocessSim) { @@ -243,17 +263,29 @@ struct strangepidqa { } if (doprocessCascades) { + histos.add("h1dMassXiMinus", "h1dMassXiMinus", {HistType::kTH1F, {massAxisXi}}); + histos.add("h1dMassXiPlus", "h1dMassXiPlus", {HistType::kTH1F, {massAxisXi}}); + histos.add("h1dMassOmegaMinus", "h1dMassOmegaMinus", {HistType::kTH1F, {massAxisOmega}}); + histos.add("h1dMassOmegaPlus", "h1dMassOmegaPlus", {HistType::kTH1F, {massAxisOmega}}); + histos.add("h1dMassCompatibleXiMinus", "h1dMassCompatibleXiMinus", {HistType::kTH1F, {massAxisXi}}); + histos.add("h1dMassCompatibleXiPlus", "h1dMassCompatibleXiPlus", {HistType::kTH1F, {massAxisXi}}); + histos.add("h1dMassCompatibleOmegaMinus", "h1dMassCompatibleOmegaMinus", {HistType::kTH1F, {massAxisOmega}}); + histos.add("h1dMassCompatibleOmegaPlus", "h1dMassCompatibleOmegaPlus", {HistType::kTH1F, {massAxisOmega}}); + histos.add("h3dMassXiMinus", "h3dMassXiMinus", {HistType::kTH3F, {centAxis, axisPt, massAxisXi}}); histos.add("h3dMassXiPlus", "h3dMassXiPlus", {HistType::kTH3F, {centAxis, axisPt, massAxisXi}}); histos.add("h3dMassOmegaMinus", "h3dMassOmegaMinus", {HistType::kTH3F, {centAxis, axisPt, massAxisOmega}}); histos.add("h3dMassOmegaPlus", "h3dMassOmegaPlus", {HistType::kTH3F, {centAxis, axisPt, massAxisOmega}}); + + histos.add("h3dMassCompatibleXiMinus", "h3dMassCompatibleXiMinus", {HistType::kTH3F, {centAxis, axisPt, massAxisXi}}); + histos.add("h3dMassCompatibleXiPlus", "h3dMassCompatibleXiPlus", {HistType::kTH3F, {centAxis, axisPt, massAxisXi}}); + histos.add("h3dMassCompatibleOmegaMinus", "h3dMassCompatibleOmegaMinus", {HistType::kTH3F, {centAxis, axisPt, massAxisOmega}}); + histos.add("h3dMassCompatibleOmegaPlus", "h3dMassCompatibleOmegaPlus", {HistType::kTH3F, {centAxis, axisPt, massAxisOmega}}); } } - void processReal(soa::Join::iterator const& coll, soa::Join const& v0s) + void processReal(soa::Join::iterator const& coll, soa::Join const& v0s, soa::Join const&) { - histos.fill(HIST("hEventVertexZ"), coll.posZ()); - if (coll.centFT0C() > maxCentrality || coll.centFT0C() < minCentrality) return; @@ -262,6 +294,39 @@ struct strangepidqa { if (TMath::Abs(lambda.eta()) > 0.5) continue; + auto negExtra = lambda.negTrackExtra_as>(); + auto posExtra = lambda.posTrackExtra_as>(); + + if (TMath::Abs(posExtra.tpcNSigmaPr()) < tpcNsigmaProton && TMath::Abs(negExtra.tpcNSigmaPi()) < tpcNsigmaPion) { + // lambda case + histos.fill(HIST("h3dMassLambda"), coll.centFT0C(), lambda.pt(), lambda.mLambda()); + histos.fill(HIST("h1dMassLambda"), lambda.mLambda()); + if (lambda.tofLambdaCompatibility(tofNsigmaCompatibility.value)) { + histos.fill(HIST("h3dMassCompatibleLambda"), coll.centFT0C(), lambda.pt(), lambda.mLambda()); + histos.fill(HIST("h1dMassCompatibleLambda"), lambda.mLambda()); + } + } + + if (TMath::Abs(posExtra.tpcNSigmaPi()) < tpcNsigmaProton && TMath::Abs(negExtra.tpcNSigmaPr()) < tpcNsigmaPion) { + // lambda case + histos.fill(HIST("h3dMassAntiLambda"), coll.centFT0C(), lambda.pt(), lambda.mAntiLambda()); + histos.fill(HIST("h1dMassAntiLambda"), lambda.mAntiLambda()); + if (lambda.tofAntiLambdaCompatibility(tofNsigmaCompatibility.value)) { + histos.fill(HIST("h3dMassCompatibleAntiLambda"), coll.centFT0C(), lambda.pt(), lambda.mAntiLambda()); + histos.fill(HIST("h1dMassCompatibleAntiLambda"), lambda.mAntiLambda()); + } + } + + if (TMath::Abs(posExtra.tpcNSigmaPi()) < tpcNsigmaPion && TMath::Abs(negExtra.tpcNSigmaPr()) < tpcNsigmaPion) { + // lambda case + histos.fill(HIST("h3dMassK0Short"), coll.centFT0C(), lambda.pt(), lambda.mK0Short()); + histos.fill(HIST("h1dMassK0Short"), lambda.mK0Short()); + if (lambda.tofK0ShortCompatibility(tofNsigmaCompatibility.value)) { + histos.fill(HIST("h3dMassCompatibleK0Short"), coll.centFT0C(), lambda.pt(), lambda.mK0Short()); + histos.fill(HIST("h1dMassCompatibleK0Short"), lambda.mK0Short()); + } + } + histos.fill(HIST("h2dLambdaMassVsTOFCut"), lambda.mLambda(), TMath::Abs(lambda.posTOFDeltaTLaPr())); histos.fill(HIST("h2dLambdaMassVsTOFCutMeson"), lambda.mLambda(), TMath::Abs(lambda.negTOFDeltaTLaPi())); @@ -378,6 +443,8 @@ struct strangepidqa { void processCascades(soa::Join::iterator const& col, soa::Filtered> const& Cascades, soa::Join const&) { histos.fill(HIST("hEventCentrality"), col.centFT0C()); + if (col.centFT0C() > maxCentrality || col.centFT0C() < minCentrality) + return; for (auto& casc : Cascades) { // major selections here @@ -397,42 +464,38 @@ struct strangepidqa { if (casc.sign() < 0) { if (TMath::Abs(posExtra.tpcNSigmaPr()) < tpcNsigmaProton && TMath::Abs(negExtra.tpcNSigmaPi()) < tpcNsigmaPion && TMath::Abs(bachExtra.tpcNSigmaPi()) < tpcNsigmaBachelor) { - if (tofNsigmaXiLaPr < 100 && fabs(casc.tofNSigmaXiLaPr()) > tofNsigmaXiLaPr) - continue; - if (tofNsigmaXiLaPi < 100 && fabs(casc.tofNSigmaXiLaPi()) > tofNsigmaXiLaPi) - continue; - if (tofNsigmaXiPi < 100 && fabs(casc.tofNSigmaXiPi()) > tofNsigmaXiPi) - continue; histos.fill(HIST("h3dMassXiMinus"), col.centFT0C(), casc.pt(), casc.mXi()); + histos.fill(HIST("h1dMassXiMinus"), casc.mXi()); + if (casc.tofXiCompatibility(tofNsigmaCompatibilityCascades.value)) { + histos.fill(HIST("h3dMassCompatibleXiMinus"), col.centFT0C(), casc.pt(), casc.mXi()); + histos.fill(HIST("h1dMassCompatibleXiMinus"), casc.mXi()); + } } if (TMath::Abs(posExtra.tpcNSigmaPr()) < tpcNsigmaProton && TMath::Abs(negExtra.tpcNSigmaPi()) < tpcNsigmaPion && TMath::Abs(bachExtra.tpcNSigmaKa()) < tpcNsigmaBachelor) { - if (tofNsigmaOmLaPr < 100 && fabs(casc.tofNSigmaOmLaPr()) > tofNsigmaOmLaPr) - continue; - if (tofNsigmaOmLaPi < 100 && fabs(casc.tofNSigmaOmLaPi()) > tofNsigmaOmLaPi) - continue; - if (tofNsigmaOmKa < 100 && fabs(casc.tofNSigmaOmKa()) > tofNsigmaOmKa) - continue; histos.fill(HIST("h3dMassOmegaMinus"), col.centFT0C(), casc.pt(), casc.mOmega()); + histos.fill(HIST("h1dMassOmegaMinus"), casc.mOmega()); + if (casc.tofOmegaCompatibility(tofNsigmaCompatibilityCascades.value)) { + histos.fill(HIST("h3dMassCompatibleOmegaMinus"), col.centFT0C(), casc.pt(), casc.mOmega()); + histos.fill(HIST("h1dMassCompatibleOmegaMinus"), casc.mOmega()); + } } } else { if (TMath::Abs(posExtra.tpcNSigmaPi()) < tpcNsigmaPion && TMath::Abs(negExtra.tpcNSigmaPr()) < tpcNsigmaProton && TMath::Abs(bachExtra.tpcNSigmaPi()) < tpcNsigmaBachelor) { - if (tofNsigmaXiLaPr < 100 && fabs(casc.tofNSigmaXiLaPr()) > tofNsigmaXiLaPr) - continue; - if (tofNsigmaXiLaPi < 100 && fabs(casc.tofNSigmaXiLaPi()) > tofNsigmaXiLaPi) - continue; - if (tofNsigmaXiPi < 100 && fabs(casc.tofNSigmaXiPi()) > tofNsigmaXiPi) - continue; histos.fill(HIST("h3dMassXiPlus"), col.centFT0C(), casc.pt(), casc.mXi()); + histos.fill(HIST("h1dMassXiPlus"), casc.mXi()); + if (casc.tofXiCompatibility(tofNsigmaCompatibilityCascades.value)) { + histos.fill(HIST("h3dMassCompatibleXiPlus"), col.centFT0C(), casc.pt(), casc.mXi()); + histos.fill(HIST("h1dMassCompatibleXiPlus"), casc.mXi()); + } } if (TMath::Abs(posExtra.tpcNSigmaPi()) < tpcNsigmaPion && TMath::Abs(negExtra.tpcNSigmaPr()) < tpcNsigmaProton && TMath::Abs(bachExtra.tpcNSigmaKa()) < tpcNsigmaBachelor) { - if (tofNsigmaOmLaPr < 100 && fabs(casc.tofNSigmaOmLaPr()) > tofNsigmaOmLaPr) - continue; - if (tofNsigmaOmLaPi < 100 && fabs(casc.tofNSigmaOmLaPi()) > tofNsigmaOmLaPi) - continue; - if (tofNsigmaOmKa < 100 && fabs(casc.tofNSigmaOmKa()) > tofNsigmaOmKa) - continue; histos.fill(HIST("h3dMassOmegaPlus"), col.centFT0C(), casc.pt(), casc.mOmega()); + histos.fill(HIST("h1dMassOmegaPlus"), casc.mOmega()); + if (casc.tofOmegaCompatibility(tofNsigmaCompatibilityCascades.value)) { + histos.fill(HIST("h3dMassCompatibleOmegaPlus"), col.centFT0C(), casc.pt(), casc.mOmega()); + histos.fill(HIST("h1dMassCompatibleOmegaPlus"), casc.mOmega()); + } } } } diff --git a/PWGLF/Tasks/Resonances/CMakeLists.txt b/PWGLF/Tasks/Resonances/CMakeLists.txt index a1fea7646a2..27aad7c24c3 100644 --- a/PWGLF/Tasks/Resonances/CMakeLists.txt +++ b/PWGLF/Tasks/Resonances/CMakeLists.txt @@ -19,6 +19,11 @@ o2physics_add_dpl_workflow(phianalysis PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(cksspinalignder + SOURCES cksspinalignder.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(k892analysis SOURCES k892analysis.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -169,6 +174,11 @@ o2physics_add_dpl_workflow(xi1530analysisqa PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(initializereventqa + SOURCES initializereventqa.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(kaonkaonanalysis SOURCES kaonkaonanalysis.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -229,12 +239,17 @@ o2physics_add_dpl_workflow(double-resonance-scan PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(kstar-in-oo +o2physics_add_dpl_workflow(kstarinoo SOURCES kstarInOO.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(phioo +o2physics_add_dpl_workflow(phioo SOURCES phiOO.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) \ No newline at end of file + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(phispectrapbpbqa + SOURCES phispectrapbpbqa.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGLF/Tasks/Resonances/chk892pp.cxx b/PWGLF/Tasks/Resonances/chk892pp.cxx index 410643d6c6b..419a8ea69b6 100644 --- a/PWGLF/Tasks/Resonances/chk892pp.cxx +++ b/PWGLF/Tasks/Resonances/chk892pp.cxx @@ -15,66 +15,60 @@ /// /// \author Su-Jeong Ji -#include -#include #include +#include +#include +#include +#include #include -#include #include #include -#include -#include -#include // FIXME -#include // FIXME - -#include -#include -#include -#include -#include -#include +// #include // FIXME +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/Utils/collisionCuts.h" -#include "TRandom3.h" -#include "TF1.h" -#include "TVector2.h" -#include "Math/Vector3D.h" -#include "Math/Vector4D.h" -#include "Math/GenVector/Boost.h" -#include +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" +#include "CommonConstants/MathConstants.h" +#include "CommonConstants/PhysicsConstants.h" +#include "DCAFitter/DCAFitterN.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" #include "Framework/HistogramRegistry.h" -#include "Framework/StepTHn.h" #include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/ASoAHelpers.h" #include "Framework/StaticFor.h" -#include "DCAFitter/DCAFitterN.h" - -#include "Common/DataModel/PIDResponse.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/EventSelection.h" - -#include "Common/Core/trackUtilities.h" -#include "Common/Core/TrackSelection.h" -#include "Common/Core/RecoDecay.h" - -#include "CommonConstants/PhysicsConstants.h" -#include "CommonConstants/MathConstants.h" - +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" #include "ReconstructionDataFormats/Track.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DataFormatsParameters/GRPMagField.h" - -#include "CCDB/CcdbApi.h" -#include "CCDB/BasicCCDBManager.h" +#include "Math/GenVector/Boost.h" +#include "Math/RotationZ.h" +#include "Math/Vector3D.h" +#include "Math/Vector4D.h" +#include "TF1.h" +#include "TRandom3.h" +#include "TVector2.h" +#include +#include // FIXME -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/Utils/collisionCuts.h" +#include +#include +#include +#include +#include +#include using namespace o2; using namespace o2::framework; @@ -105,6 +99,7 @@ struct Chk892pp { using MCEventCandidates = soa::Join; using MCTrackCandidates = soa::Join; using MCV0Candidates = soa::Join; + using LorentzVectorSetXYZM = ROOT::Math::LorentzVector>; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -159,7 +154,7 @@ struct Chk892pp { Configurable cfgMinOccupancy{"cfgMinOccupancy", -100, "maximum occupancy of tracks in neighbouring collisions in a given time range"}; Configurable cfgNCollinTR{"cfgNCollinTR", false, "Additional selection for the number of coll in time range"}; */ - Configurable cfgCentEst{"cfgCentEst", 1, "Centrality estimator, 1: FT0C, 2: FT0M"}; + Configurable cfgCentEst{"cfgCentEst", 2, "Centrality estimator, 1: FT0C, 2: FT0M"}; /// PID Selections, pion struct : ConfigurableGroup { @@ -289,6 +284,10 @@ struct Chk892pp { histos.add("QA/before/VtxZ", "Centrality distribution", {HistType::kTH1D, {vtxzAxis}}); histos.add("QA/before/hEvent", "Number of Events", HistType::kTH1F, {{1, 0.5, 1.5}}); + if (BkgEstimationConfig.cfgFillRotBkg) { + histos.add("QA/RotBkg/hRotBkg", "Rotated angle of rotated background", HistType::kTH1F, {{360, 0.0, o2::constants::math::TwoPI}}); + } + // Bachelor pion histos.add("QA/before/trkbpionDCAxy", "DCAxy distribution of bachelor pion candidates", HistType::kTH1D, {dcaxyAxis}); histos.add("QA/before/trkbpionDCAz", "DCAz distribution of bachelor pion candidates", HistType::kTH1D, {dcazAxis}); @@ -364,6 +363,7 @@ struct Chk892pp { histos.add("QA/before/KstarRapidity", "Rapidity distribution of chK(892)", HistType::kTH1D, {yAxis}); histos.add("hInvmass_Kstar", "Invariant mass of unlike-sign chK(892)", HistType::kTHnSparseD, {axisType, centAxis, ptAxis, invMassAxisReso}); histos.add("hInvmass_Kstar_Mix", "Invariant mass of unlike-sign chK(892) from mixed event", HistType::kTHnSparseD, {axisType, centAxis, ptAxis, invMassAxisReso}); + histos.add("hInvmass_K0s", "Invariant mass of unlike-sign K0s", HistType::kTHnSparseD, {centAxis, ptAxis, invMassAxisK0s}); // Mass QA (quick check) histos.add("QA/before/kstarinvmass", "Invariant mass of unlike-sign chK(892)", HistType::kTH1D, {invMassAxisReso}); @@ -437,15 +437,19 @@ struct Chk892pp { histos.print(); } + const int kCentFT0C = 1; + const int kCentFT0M = 2; + const float kInvalidCentrality = -999.f; + template float getCentrality(CollisionType const& collision) { - if (cfgCentEst == 1) { + if (cfgCentEst == kCentFT0C) { return collision.multFT0C(); - } else if (cfgCentEst == 2) { + } else if (cfgCentEst == kCentFT0M) { return collision.multFT0M(); } else { - return -999; + return kInvalidCentrality; } } @@ -666,16 +670,16 @@ struct Chk892pp { if (std::abs(motherbTrack.pdgCode()) != kKstarPlus) // Are you charged Kstar's daughter? return false; // Apply first since it's more restrictive - if (std::abs(motherkV0.pdgCode()) != 310) // Is it K0s? + if (std::abs(motherkV0.pdgCode()) != kPDGK0s) // Is it K0s? return false; // Check if K0s's mother is K0 (311) auto motherK0 = motherkV0.template mothers_as(); - if (std::abs(motherK0.pdgCode()) != 311) + if (std::abs(motherK0.pdgCode()) != kPDGK0) return false; // Check if K0's mother is Kstar (323) auto motherKstar = motherK0.template mothers_as(); - if (std::abs(motherKstar.pdgCode()) != 323) + if (std::abs(motherKstar.pdgCode()) != kKstarPlus) return false; // Check if bTrack and K0 have the same mother (global index) @@ -692,11 +696,11 @@ struct Chk892pp { { histos.fill(HIST("QA/before/CentDist"), lCentrality); - TLorentzVector lDecayDaughter1, lDecayDaughter2, lResoSecondary, lDecayDaughter_bach, lResoKstar, lDaughterRot, lResonanceRot; + LorentzVectorSetXYZM lDecayDaughter1, lDecayDaughter2, lResoSecondary, lDecayDaughter_bach, lResoKstar, lDaughterRot, lResonanceRot; std::vector trackIndicies = {}; std::vector k0sIndicies = {}; - for (auto& bTrack : dTracks1) { + for (const auto& bTrack : dTracks1) { auto trkbpt = bTrack.pt(); auto istrkbhasTOF = bTrack.hasTOF(); auto trkbNSigmaPiTPC = bTrack.tpcNSigmaPi(); @@ -733,7 +737,7 @@ struct Chk892pp { trackIndicies.push_back(bTrack.index()); } - for (auto& k0sCand : dTracks2) { + for (const auto& k0sCand : dTracks2) { auto posDauTrack = k0sCand.template posTrack_as(); auto negDauTrack = k0sCand.template negTrack_as(); @@ -838,14 +842,14 @@ struct Chk892pp { k0sIndicies.push_back(k0sCand.index()); } - for (auto& trackIndex : trackIndicies) { - for (auto& k0sIndex : k0sIndicies) { + for (const auto& trackIndex : trackIndicies) { + for (const auto& k0sIndex : k0sIndicies) { auto bTrack = dTracks1.rawIteratorAt(trackIndex); auto k0sCand = dTracks2.rawIteratorAt(k0sIndex); auto trkkMass = k0sCand.mK0Short(); - lDecayDaughter_bach.SetXYZM(bTrack.px(), bTrack.py(), bTrack.pz(), MassPionCharged); - lResoSecondary.SetXYZM(k0sCand.px(), k0sCand.py(), k0sCand.pz(), trkkMass); + lDecayDaughter_bach = LorentzVectorSetXYZM(bTrack.px(), bTrack.py(), bTrack.pz(), MassPionCharged); + lResoSecondary = LorentzVectorSetXYZM(k0sCand.px(), k0sCand.py(), k0sCand.pz(), trkkMass); lResoKstar = lResoSecondary + lDecayDaughter_bach; // QA plots @@ -870,11 +874,17 @@ struct Chk892pp { histos.fill(HIST("QA/RotBkg/hRotBkg"), lRotAngle); if (BkgEstimationConfig.cfgRotPion) { lDaughterRot = lDecayDaughter_bach; - lDaughterRot.RotateZ(lRotAngle); + // lDaughterRot.RotateZ(lRotAngle); + ROOT::Math::RotationZ rot(lRotAngle); + auto p3 = rot * lDaughterRot.Vect(); + lDaughterRot = LorentzVectorSetXYZM(p3.X(), p3.Y(), p3.Z(), lDaughterRot.M()); lResonanceRot = lDaughterRot + lResoSecondary; } else { lDaughterRot = lResoSecondary; - lDaughterRot.RotateZ(lRotAngle); + // lDaughterRot.RotateZ(lRotAngle); + ROOT::Math::RotationZ rot(lRotAngle); + auto p3 = rot * lDaughterRot.Vect(); + lDaughterRot = LorentzVectorSetXYZM(p3.X(), p3.Y(), p3.Z(), lDaughterRot.M()); lResonanceRot = lDecayDaughter_bach + lDaughterRot; } typeKstar = bTrack.sign() > 0 ? BinType::kKstarP_Rot : BinType::kKstarN_Rot; diff --git a/PWGLF/Tasks/Resonances/cksspinalignder.cxx b/PWGLF/Tasks/Resonances/cksspinalignder.cxx new file mode 100644 index 00000000000..ae29ab6a6fc --- /dev/null +++ b/PWGLF/Tasks/Resonances/cksspinalignder.cxx @@ -0,0 +1,279 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file cksspinalignder.cxx +/// \brief Analysis task for ChargedKStar spin alignment +/// +/// \author prottay.das@cern.ch + +#include "PWGLF/DataModel/LFCKSSpinalignmentTables.h" + +#include "Common/Core/RecoDecay.h" +#include "Common/Core/trackUtilities.h" + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/BinningPolicy.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" +#include + +#include +#include +#include +#include + +#include + +#include // for std::fabs +#include +// #include +#include +#include // <<< CHANGED: for dedup sets +#include +#include +#include +#include // <<< CHANGED: for seenMap +#include +#include + +// o2 includes. +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +struct cksspinalignder { + + struct : ConfigurableGroup { + Configurable cfgURL{"cfgURL", "http://alice-ccdb.cern.ch", "Address of the CCDB to browse"}; + Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "Latest acceptable timestamp of creation for the object"}; + } cfgCcdbParam; + + // event sel///////// + Configurable centMin{"centMin", 0, "Minimum Centrality"}; + Configurable centMax{"centMax", 80, "Maximum Centrality"}; + // V0 selection //////////// + Configurable cosPA{"cosPA", 0.995, "Cosine Pointing Angle"}; + Configurable radiusMin{"radiusMin", 1.2, "Minimum V0 radius"}; + Configurable radiusMax{"radiusMax", 100, "Maximum V0 radius"}; + Configurable dcaPion{"dcaPion", 0.1, "DCA Pion"}; + Configurable dcaDaughters{"dcaDaughters", 1.0, "DCA between daughters"}; + Configurable lifetimeMax{"lifetimeMax", 20, "Maximum V0 lifetime"}; + Configurable ptMin{"ptMin", 0.5, "V0 Pt minimum"}; + Configurable ptMax{"ptMax", 10.0, "V0 Pt maximum"}; + Configurable v0eta{"v0eta", 0.8, "Eta cut on lambda"}; + // pion sel///////// + Configurable nsigmaCutTPC{"nsigmaCutTPC", 3.0, "N sigma TPC cut for bachelor pions"}; + Configurable nsigmaCutTOF{"nsigmaCutTOF", 3.0, "N sigma TOF cut for bachelor pions"}; + Configurable usePID{"usePID", false, "Flag for using PID selection"}; + + // Event Mixing + Configurable nEvtMixing{"nEvtMixing", 5, "Number of events to mix"}; + ConfigurableAxis cfgVtxBins{"cfgVtxBins", {10, -10, 10}, "Mixing bins - z-vertex"}; + ConfigurableAxis cfgMultBins{"cfgMultBins", {8, 0.0, 80}, "Mixing bins - centrality"}; + + // THnsparse bining + ConfigurableAxis configThnAxisInvMass{"configThnAxisInvMass", {50, 1.09, 1.14}, "#it{M} (GeV/#it{c}^{2})"}; + ConfigurableAxis configThnAxisPt{"configThnAxisPt", {100, 0.0, 10.0}, "#it{p}_{T}"}; + ConfigurableAxis configThnAxisSA{"configThnAxisSA", {20, -1.0, 1.0}, "cos#it{#theta *}"}; + ConfigurableAxis configThnAxisCentrality{"configThnAxisCentrality", {8, 0.0, 80.0}, "Centrality"}; + + // Enable access to the CCDB for the offset and correction constants and save them in dedicated variables. + Service ccdb; + o2::ccdb::CcdbApi ccdbApi; + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + void init(o2::framework::InitContext&) + { + + histos.add("hCentrality", "Centrality distribution", kTH1F, {{80, 0, 80}}); + histos.add("hKShortMass", "hKShortMass", kTH1F, {{100, 0.45, 0.55}}); + + histos.add("hSparsesame", "hSparsesame", kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisSA, configThnAxisCentrality}); + histos.add("hSparsemix", "hSparsemix", kTHnSparseF, {configThnAxisInvMass, configThnAxisPt, configThnAxisSA, configThnAxisCentrality}); + + ccdb->setURL(cfgCcdbParam.cfgURL); + ccdbApi.init("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + } + + template + bool selectionV0(T const& candidate) + { + auto kshortPt = std::sqrt(candidate.kShortPx() * candidate.kShortPx() + candidate.kShortPy() * candidate.kShortPy()); + auto px = candidate.kShortPx(); + auto py = candidate.kShortPy(); + auto pz = candidate.kShortPz(); + auto p = std::sqrt(px * px + py * py + pz * pz); + auto kshortEta = 0.5 * std::log((p + pz) / (p - pz)); + + if (std::abs(kshortEta) > v0eta) { + return false; + } + if (candidate.v0Cospa() < cosPA) { + return false; + } + if (candidate.v0Radius() > radiusMax) { + return false; + } + if (candidate.v0Radius() < radiusMin) { + return false; + } + if (candidate.dcaBetweenDaughter() > dcaDaughters) { + return false; + } + if (std::abs(candidate.dcaPositive()) < dcaPion && std::abs(candidate.dcaNegative()) < dcaPion) { + return false; + } + if (candidate.v0Lifetime() > lifetimeMax) { + return false; + } + if (kshortPt < ptMin) { + return false; + } + if (kshortPt > ptMax) { + return false; + } + return true; + } + + template + bool selectionPID(const T& candidate) + { + auto px = candidate.pionBachPx(); + auto py = candidate.pionBachPy(); + auto pz = candidate.pionBachPz(); + auto p = std::sqrt(px * px + py * py + pz * pz); + float lowmom = 0.5; + if (p < lowmom) { + if (!candidate.pionBachTOFHit() && std::abs(candidate.pionBachTPC()) < nsigmaCutTPC) { + return true; + } else if (candidate.pionBachTOFHit() && std::sqrt(candidate.pionBachTPC() * candidate.pionBachTPC() + candidate.pionBachTOF() * candidate.pionBachTOF()) < nsigmaCutTOF) { + return true; + } + } else if (candidate.pionBachTOFHit() && std::sqrt(candidate.pionBachTPC() * candidate.pionBachTPC() + candidate.pionBachTOF() * candidate.pionBachTOF()) < nsigmaCutTOF) { + return true; + } + return false; + } + + std::tuple computePtEtaPhi(float px, float py, float pz) + { + float pt = std::sqrt(px * px + py * py); + float p = std::sqrt(px * px + py * py + pz * pz); + float eta = (p != std::abs(pz)) ? 0.5 * std::log((p + pz) / (p - pz)) : 0.0f; // avoid division by zero + float phi = RecoDecay::constrainAngle(std::atan2(py, px)); + return {pt, eta, phi}; + } + + ROOT::Math::PtEtaPhiMVector kshort, pion, chkstar; + ROOT::Math::PtEtaPhiMVector kshortmix, pionmix, chkstarmix; + ROOT::Math::PxPyPzMVector fourVecDauCM, fourVecDauCMmix; + ROOT::Math::XYZVector threeVecDauCM, eventplaneVecNorm, threeVecDauCMmix, eventplaneVecNormmix; + + Filter centralityFilter = (nabs(aod::kshortpionevent::cent) < centMax && nabs(aod::kshortpionevent::cent) > centMin); + + using EventCandidates = soa::Filtered; + + void processSameData(EventCandidates::iterator const& collision, aod::KShortTracks const& V0s, aod::PionTracks const& piontracks) + { + auto centrality = collision.cent(); + histos.fill(HIST("hCentrality"), centrality); + + auto psiFT0C = collision.psiFT0C(); + + for (const auto& v0 : V0s) { + if (!selectionV0(v0)) { + continue; + } + auto [kshortPt, kshortEta, kshortPhi] = computePtEtaPhi(v0.kShortPx(), v0.kShortPy(), v0.kShortPz()); + kshort = ROOT::Math::PtEtaPhiMVector(kshortPt, kshortEta, kshortPhi, v0.kShortMass()); + histos.fill(HIST("hKShortMass"), kshort.M()); + + for (const auto& piontrack : piontracks) { + auto [pionPt, pionEta, pionPhi] = computePtEtaPhi(piontrack.pionBachPx(), piontrack.pionBachPy(), piontrack.pionBachPz()); + pion = ROOT::Math::PtEtaPhiMVector(pionPt, pionEta, pionPhi, o2::constants::physics::MassPionCharged); + + if (piontrack.pionBachIndex() == v0.pionIndex1() || piontrack.pionBachIndex() == v0.pionIndex2()) + continue; // checking if bachelor pion is khort daughter or not -> skip further processing if such is the case + + if (usePID && !selectionPID(piontrack)) + continue; // checking PID + + chkstar = kshort + pion; + + ROOT::Math::Boost boost{chkstar.BoostToCM()}; + fourVecDauCM = boost(kshort); + threeVecDauCM = fourVecDauCM.Vect(); + eventplaneVecNorm = ROOT::Math::XYZVector(std::sin(2.0 * psiFT0C), -std::cos(2.0 * psiFT0C), 0); + auto cosThetaStar = eventplaneVecNorm.Dot(threeVecDauCM) / std::sqrt(threeVecDauCM.Mag2()) / std::sqrt(eventplaneVecNorm.Mag2()); + + histos.fill(HIST("hSparsesame"), chkstar.M(), chkstar.Pt(), cosThetaStar, centrality); + } + } + } + PROCESS_SWITCH(cksspinalignder, processSameData, "Process same data", true); + + // Processing Event Mixing + SliceCache cache; + using BinningType = ColumnBinningPolicy; + BinningType colBinning{{cfgVtxBins, cfgMultBins}, true}; + Preslice tracksPerCollisionV0 = aod::kshortpionpair::kshortpioneventId; + Preslice tracksPerCollisionBach = aod::kshortpionpair::kshortpioneventId; + + void processMixedData(EventCandidates const& collisions, aod::KShortTracks const& V0s, aod::PionTracks const& piontracks) + { + for (const auto& [collision1, collision2] : selfCombinations(colBinning, nEvtMixing, -1, collisions, collisions)) { + if (collision1.index() == collision2.index()) { + continue; + } + auto centrality = collision1.cent(); + auto psiFT0Cmix = collision1.psiFT0C(); + + auto groupV0 = V0s.sliceBy(tracksPerCollisionV0, collision1.index()); + auto groupPion = piontracks.sliceBy(tracksPerCollisionBach, collision2.index()); + for (const auto& [t1, t2] : soa::combinations(o2::soa::CombinationsFullIndexPolicy(groupV0, groupPion))) { + if (!selectionV0(t1)) + continue; + auto [kshortPtmix, kshortEtamix, kshortPhimix] = computePtEtaPhi(t1.kShortPx(), t1.kShortPy(), t1.kShortPz()); + kshortmix = ROOT::Math::PtEtaPhiMVector(kshortPtmix, kshortEtamix, kshortPhimix, t1.kShortMass()); + + auto [pionPtmix, pionEtamix, pionPhimix] = computePtEtaPhi(t2.pionBachPx(), t2.pionBachPy(), t2.pionBachPz()); + if (usePID && !selectionPID(t2)) + continue; // checking PID + pionmix = ROOT::Math::PtEtaPhiMVector(pionPtmix, pionEtamix, pionPhimix, o2::constants::physics::MassPionCharged); + + chkstarmix = kshortmix + pionmix; + + ROOT::Math::Boost boost{chkstarmix.BoostToCM()}; + fourVecDauCMmix = boost(kshortmix); + threeVecDauCMmix = fourVecDauCMmix.Vect(); + eventplaneVecNormmix = ROOT::Math::XYZVector(std::sin(2.0 * psiFT0Cmix), -std::cos(2.0 * psiFT0Cmix), 0); + auto cosThetaStarmix = eventplaneVecNormmix.Dot(threeVecDauCMmix) / std::sqrt(threeVecDauCMmix.Mag2()) / std::sqrt(eventplaneVecNormmix.Mag2()); + + histos.fill(HIST("hSparsemix"), chkstarmix.M(), chkstarmix.Pt(), cosThetaStarmix, centrality); + } + } + } + PROCESS_SWITCH(cksspinalignder, processMixedData, "Process mixed data", true); +}; +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/Tasks/Resonances/f0980pbpbanalysis.cxx b/PWGLF/Tasks/Resonances/f0980pbpbanalysis.cxx index 96abd0ca43a..4279f99bbc0 100644 --- a/PWGLF/Tasks/Resonances/f0980pbpbanalysis.cxx +++ b/PWGLF/Tasks/Resonances/f0980pbpbanalysis.cxx @@ -135,6 +135,7 @@ struct F0980pbpbanalysis { ConfigurableAxis massAxis{"massAxis", {400, 0.2, 2.2}, "Invariant mass axis"}; ConfigurableAxis ptAxis{"ptAxis", {VARIABLE_WIDTH, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.8, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 10.0, 13.0, 20.0}, "Transverse momentum Binning"}; ConfigurableAxis centAxis{"centAxis", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 100}, "Centrality interval"}; + ConfigurableAxis epAxis{"epAxis", {6, 0.0, o2::constants::math::TwoPI}, "EP axis"}; // for event mixing SliceCache cache; @@ -591,7 +592,6 @@ struct F0980pbpbanalysis { void init(o2::framework::InitContext&) { - AxisSpec epAxis = {6, 0.0, o2::constants::math::TwoPI}; AxisSpec qaCentAxis = {110, 0, 110}; AxisSpec qaVzAxis = {100, -20, 20}; AxisSpec qaPIDAxis = {100, -10, 10}; diff --git a/PWGLF/Tasks/Resonances/higherMassResonances.cxx b/PWGLF/Tasks/Resonances/higherMassResonances.cxx index 61ef930a7c2..7b13c8e0596 100644 --- a/PWGLF/Tasks/Resonances/higherMassResonances.cxx +++ b/PWGLF/Tasks/Resonances/higherMassResonances.cxx @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -52,6 +51,7 @@ #include #include #include +#include #include #include @@ -70,50 +70,57 @@ struct HigherMassResonances { HistogramRegistry hglue{"hglueball", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; HistogramRegistry hMChists{"hMChists", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - struct RCTCut : ConfigurableGroup { + struct : ConfigurableGroup { Configurable requireRCTFlagChecker{"requireRCTFlagChecker", true, "Check event quality in run condition table"}; Configurable cfgEvtRCTFlagCheckerLabel{"cfgEvtRCTFlagCheckerLabel", "CBT_hadronPID", "Evt sel: RCT flag checker label"}; Configurable cfgEvtRCTFlagCheckerZDCCheck{"cfgEvtRCTFlagCheckerZDCCheck", false, "Evt sel: RCT flag checker ZDC check"}; Configurable cfgEvtRCTFlagCheckerLimitAcceptAsBad{"cfgEvtRCTFlagCheckerLimitAcceptAsBad", true, "Evt sel: RCT flag checker treat Limited Acceptance As Bad"}; - - RCTFlagsChecker rctChecker; + } rctCut; + RCTFlagsChecker rctChecker; + + enum MultEstimator { + kFT0M, + kFT0A, + kFT0C, + kFV0A, + kFV0C, + kFV0M, + kNEstimators // useful if you want to iterate or size things }; - RCTCut rctCut; struct : ConfigurableGroup { // PID and QA Configurable qAv0{"qAv0", false, "qAv0"}; Configurable qAPID{"qAPID", true, "qAPID"}; - // Configurable qAv0Daughters{"qAv0Daughters", false, "QA of v0 daughters"}; Configurable qAevents{"qAevents", false, "QA of events"}; - // Configurable invMass1D{"invMass1D", false, "1D invariant mass histograms"}; Configurable correlation2Dhist{"correlation2Dhist", true, "Lamda K0 mass correlation"}; - Configurable cDCAv0topv{"cDCAv0topv", false, "DCA V0 to PV"}; - // Configurable armcut{"armcut", false, "arm cut"}; - Configurable globalTracks{"globalTracks", false, "Global tracks"}; + Configurable isApplyDCAv0topv{"isApplyDCAv0topv", false, "DCA V0 to PV"}; Configurable hasTPC{"hasTPC", false, "TPC"}; - Configurable selectTWOKsOnly{"selectTWOKsOnly", true, "Select only events with two K0s"}; - Configurable applyPairRapidityRec{"applyPairRapidityRec", false, "Apply pair rapidity cut on reconstructed mother (after already applying rapidity cut on generated mother)"}; - Configurable applyPairRapidityGen{"applyPairRapidityGen", false, "Apply pair rapidity cut on generated mother (before applying rapidity cut on reconstructed mother)"}; + Configurable isselectTWOKsOnly{"isselectTWOKsOnly", true, "Select only events with two K0s"}; + Configurable isapplyPairRapidityRec{"isapplyPairRapidityRec", false, "Apply pair rapidity cut on reconstructed mother (after already applying rapidity cut on generated mother)"}; + Configurable isapplyPairRapidityGen{"isapplyPairRapidityGen", false, "Apply pair rapidity cut on generated mother (before applying rapidity cut on reconstructed mother)"}; + Configurable cSelectMultEstimator{"cSelectMultEstimator", 0, "Select multiplicity estimator: 0 - FT0M, 1 - FT0A, 2 - FT0C"}; + Configurable configOccCut{"configOccCut", 1000, "Occupancy cut"}; + Configurable isVertexTOFMatched{"isVertexTOFMatched", false, "Vertex TOF Matched"}; + Configurable isNoCollInTimeRangeStandard{"isNoCollInTimeRangeStandard", false, "No collision in time range standard"}; // Configurables for event selection + // Configurable isINELgt0{"isINELgt0", true, "INEL>0 selection"}; + Configurable isTriggerTVX{"isTriggerTVX", false, "TriggerTVX"}; + Configurable isGoodZvtxFT0vsPV{"isGoodZvtxFT0vsPV", false, "IsGoodZvtxFT0vsPV"}; + Configurable isApplyOccCut{"isApplyOccCut", true, "Apply occupancy cut"}; Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; - Configurable cfgETAcut{"cfgETAcut", 0.8f, "Track ETA cut"}; Configurable timFrameEvsel{"timFrameEvsel", true, "TPC Time frame boundary cut"}; - // Configurable piluprejection{"piluprejection", false, "Pileup rejection"}; - // Configurable goodzvertex{"goodzvertex", false, "removes collisions with large differences between z of PV by tracks and z of PV from FT0 A-C time difference."}; - // Configurable itstpctracks{"itstpctracks", false, "selects collisions with at least one ITS-TPC track,"}; - // Configurable additionalEvsel{"additionalEvsel", false, "Additional event selcection"}; - // Configurable applyOccupancyCut{"applyOccupancyCut", false, "Apply occupancy cut"}; - // Configurable occupancyCut{"occupancyCut", 1000, "Mimimum Occupancy cut"}; + Configurable isNoSameBunchPileup{"isNoSameBunchPileup", true, "kNoSameBunchPileup"}; + Configurable isAllLayersGoodITS{"isAllLayersGoodITS", true, "Require all ITS layers to be good"}; + Configurable isNoTimeFrameBorder{"isNoTimeFrameBorder", true, "kNoTimeFrameBorder"}; + Configurable isNoITSROFrameBorder{"isNoITSROFrameBorder", true, "kNoITSROFrameBorder"}; // Configurable parameters for V0 selection Configurable confV0DCADaughMax{"confV0DCADaughMax", 1.0f, "DCA b/w V0 daughters"}; Configurable v0settingDcapostopv{"v0settingDcapostopv", 0.06, "DCA Pos To PV"}; Configurable v0settingDcanegtopv{"v0settingDcanegtopv", 0.06, "DCA Neg To PV"}; - Configurable cMaxV0DCA{"cMaxV0DCA", 1, "DCA V0 to PV"}; - // Configurable isStandarv0{"isStandarv0", false, "Standard V0"}; - // Configurable ConfDaughDCAMin{"ConfDaughDCAMin", 0.06f, "V0 Daugh sel: Max. DCA Daugh to PV (cm)"}; // same as DCA pos to pv and neg to pv + Configurable cMaxV0DCA{"cMaxV0DCA", 0.3, "DCA V0 to PV"}; Configurable confV0PtMin{"confV0PtMin", 0.f, "Minimum transverse momentum of V0"}; Configurable confV0CPAMin{"confV0CPAMin", 0.97f, "Minimum CPA of V0"}; Configurable confV0TranRadV0Min{"confV0TranRadV0Min", 0.5f, "Minimum transverse radius"}; @@ -123,27 +130,27 @@ struct HigherMassResonances { Configurable cWidthKs0{"cWidthKs0", 0.005, "Width of KS0"}; Configurable confDaughEta{"confDaughEta", 0.8f, "V0 Daugh sel: max eta"}; Configurable confDaughTPCnclsMin{"confDaughTPCnclsMin", 70.f, "V0 Daugh sel: Min. nCls TPC"}; - Configurable confDaughPIDCuts{"confDaughPIDCuts", 5, "PID selections for KS0 daughters"}; - // Configurable confarmcut{"confarmcut", 0.2f, "Armenteros cut"}; + Configurable confDaughPIDCutTPC{"confDaughPIDCutTPC", 5, "PID selections for KS0 daughters"}; + Configurable confDaughPIDCutTOF{"confDaughPIDCutTOF", 5, "PID selections for KS0 daughters in TOF"}; Configurable confKsrapidity{"confKsrapidity", 0.5f, "Rapidity cut on K0s"}; - // Configurable lowmasscutks0{"lowmasscutks0", 0.497 - 4 * 0.005, "Low mass cut on K0s"}; - // Configurable highmasscutks0{"highmasscutks0", 0.497 + 4 * 0.005, "High mass cut on K0s"}; - Configurable applyAngSepCut{"applyAngSepCut", false, "Apply angular separation cut"}; Configurable angSepCut{"angSepCut", 0.01f, "Angular separation cut"}; + Configurable isapplyAngSepCut{"isapplyAngSepCut", false, "Apply angular separation cut"}; + Configurable isStandardV0{"isStandardV0", false, "Standard V0 selection"}; + Configurable isApplyEtaCutK0s{"isApplyEtaCutK0s", false, "Apply eta cut on K0s daughters"}; + Configurable cfgETAcut{"cfgETAcut", 0.8f, "Track ETA cut"}; // Configurable for track selection and multiplicity Configurable cfgPTcut{"cfgPTcut", 0.2f, "Track PT cut"}; Configurable cfgNmixedEvents{"cfgNmixedEvents", 5, "Number of mixed events"}; - Configurable cfgMultFOTM{"cfgMultFOTM", true, "Use FOTM multiplicity if pp else use 0 here for PbPb (FT0C)"}; ConfigurableAxis binsCent{"binsCent", {VARIABLE_WIDTH, 0., 5., 10., 30., 50., 70., 100., 110., 150.}, "Binning of the centrality axis"}; // Configurable for MC Configurable isMC{"isMC", false, "Is MC"}; - Configurable allGenCollisions{"allGenCollisions", true, "To fill all generated collisions for the signal loss calculations"}; - Configurable cTVXEvsel{"cTVXEvsel", true, "Triggger selection"}; - Configurable avoidsplitrackMC{"avoidsplitrackMC", false, "avoid split track in MC"}; + Configurable isallGenCollisions{"isallGenCollisions", true, "To fill all generated collisions for the signal loss calculations"}; + Configurable iscTVXEvsel{"iscTVXEvsel", true, "Triggger selection"}; + Configurable isavoidsplitrackMC{"isavoidsplitrackMC", false, "avoid split track in MC"}; + Configurable isapplyRapidityMC{"isapplyRapidityMC", true, "Apply rapidity cut on generated and reconstructed particles"}; Configurable selectMCparticles{"selectMCparticles", 1, "0: f0(1710), 1: f2(1525), 2: a2(1320), 3: f0(1370), 4: f0(1500)"}; - Configurable apply_rapidityMC{"apply_rapidityMC", true, "Apply rapidity cut on generated and reconstructed particles"}; std::vector pdgCodes = {10331, 335, 115, 10221, 9030221}; // output THnSparses @@ -154,10 +161,8 @@ struct HigherMassResonances { Configurable cRotations{"cRotations", 3, "Number of random rotations in the rotational background"}; // Other cuts on Ks and glueball - // Configurable rapidityks{"rapidityks", true, "rapidity cut on K0s"}; - Configurable applyCompetingcut{"applyCompetingcut", false, "Competing cascade rejection cut"}; + Configurable isapplyCompetingcut{"isapplyCompetingcut", false, "Competing cascade rejection cut"}; Configurable competingcascrejlambda{"competingcascrejlambda", 0.005, "rejecting competing cascade lambda"}; - // Configurable competingcascrejlambdaanti{"competingcascrejlambdaanti", 0.005, "rejecting competing cascade anti-lambda"}; // If one of the pions is misidentified as a proton, then instead of Ks we reconstruct lambda, therefore the competing cascade rejection cut is applied in which if the reconstrcted mass of a pion and proton (which we are assuming to be misidentified as proton) is close to lambda or anti-lambda, then the track is rejected Configurable tpcCrossedrows{"tpcCrossedrows", 70, "TPC crossed rows"}; Configurable tpcCrossedrowsOverfcls{"tpcCrossedrowsOverfcls", 0.8, "TPC crossed rows over findable clusters"}; @@ -168,9 +173,12 @@ struct HigherMassResonances { ConfigurableAxis ksMassBins{"ksMassBins", {200, 0.45f, 0.55f}, "K0s invariant mass axis"}; ConfigurableAxis cGlueMassBins{"cGlueMassBins", {200, 0.9f, 3.0f}, "Glueball invariant mass axis"}; ConfigurableAxis cPtBins{"cPtBins", {200, 0.0f, 20.0f}, "Glueball pT axis"}; - // ConfigurableAxis axisdEdx{"axisdEdx", {20000, 0.0f, 200.0f}, "dE/dx (a.u.)"}; - // ConfigurableAxis axisPtfordEbydx{"axisPtfordEbydx", {2000, 0, 20}, "pT (GeV/c)"}; - // ConfigurableAxis axisMultdist{"axisMultdist", {3500, 0, 70000}, "Multiplicity distribution"}; + + // fixed variables + float rapidityMotherData = 0.5; + float beamEnergy = 13600.0; + double beamMomentum = std::sqrt(beamEnergy * beamEnergy / 4 - o2::constants::physics::MassProton * o2::constants::physics::MassProton); // GeV + int noOfDaughters = 2; } config; // Service PDGdatabase; @@ -182,23 +190,19 @@ struct HigherMassResonances { ROOT::Math::PxPyPzMVector daughter1, daughter2, daughterRot, daughterRotCM, mother, motherRot, fourVecDauCM, fourVecDauCM1; ROOT::Math::PxPyPzEVector mother1; ROOT::Math::XYZVector randomVec, beamVec, normalVec; - ROOT::Math::XYZVectorF v1_CM, zaxis_HE, yaxis_HE, xaxis_HE; + ROOT::Math::XYZVectorF v1CM, zaxisHE, yaxisHE, xaxisHE; // ROOT::Math::XYZVector threeVecDauCM, helicityVec, randomVec, beamVec, normalVec; - ROOT::Math::XYZVector zBeam; // ẑ: beam direction in lab frame - double BeamMomentum = std::sqrt(13600 * 13600 / 4 - 0.938 * 0.938); // GeV - ROOT::Math::PxPyPzEVector Beam1{0., 0., -BeamMomentum, 13600. / 2.}; - ROOT::Math::PxPyPzEVector Beam2{0., 0., BeamMomentum, 13600. / 2.}; - ROOT::Math::XYZVectorF Beam1_CM, Beam2_CM; + ROOT::Math::XYZVector zBeam; // ẑ: beam direction in lab frame + ROOT::Math::PxPyPzEVector beam1{0., 0., -config.beamMomentum, 13600. / 2.}; + ROOT::Math::PxPyPzEVector beam2{0., 0., config.beamMomentum, 13600. / 2.}; + ROOT::Math::XYZVectorF beam1CM, beam2CM; // const double massK0s = o2::constants::physics::MassK0Short; bool isMix = false; void init(InitContext const&) { - rctCut.rctChecker.init( - rctCut.cfgEvtRCTFlagCheckerLabel, - rctCut.cfgEvtRCTFlagCheckerZDCCheck, - rctCut.cfgEvtRCTFlagCheckerLimitAcceptAsBad); + rctChecker.init(rctCut.cfgEvtRCTFlagCheckerLabel, rctCut.cfgEvtRCTFlagCheckerZDCCheck, rctCut.cfgEvtRCTFlagCheckerLimitAcceptAsBad); // Axes AxisSpec k0ShortMassAxis = {config.ksMassBins, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; @@ -212,8 +216,6 @@ struct HigherMassResonances { // THnSparses std::array sparses = {config.activateTHnSparseCosThStarHelicity, config.activateTHnSparseCosThStarProduction, config.activateTHnSparseCosThStarBeam, config.activateTHnSparseCosThStarRandom}; - // std::array sparses = {config.activateTHnSparseCosThStarHelicity}; - if (std::accumulate(sparses.begin(), sparses.end(), 0) == 0) { LOGP(fatal, "No output THnSparses enabled"); } else { @@ -235,31 +237,71 @@ struct HigherMassResonances { if (config.qAevents) { rEventSelection.add("hVertexZRec", "hVertexZRec", {HistType::kTH1F, {vertexZAxis}}); rEventSelection.add("hmultiplicity", "multiplicity percentile distribution", {HistType::kTH1F, {{150, 0.0f, 150.0f}}}); - // rEventSelection.add("multdist_FT0M", "FT0M Multiplicity distribution", kTH1F, {config.axisMultdist}); - // rEventSelection.add("multdist_FT0A", "FT0A Multiplicity distribution", kTH1F, {config.axisMultdist}); - // rEventSelection.add("multdist_FT0C", "FT0C Multiplicity distribution", kTH1F, {config.axisMultdist}); - // rEventSelection.add("hNcontributor", "Number of primary vertex contributor", kTH1F, {{2000, 0.0f, 10000.0f}}); + hglue.add("htrackscheck_v0", "htrackscheck_v0", kTH1I, {{15, 0, 15}}); + hglue.add("htrackscheck_v0_daughters", "htrackscheck_v0_daughters", kTH1I, {{15, 0, 15}}); + hMChists.add("events_check", "No. of events in the generated MC", kTH1I, {{20, 0, 20}}); + hMChists.add("events_checkrec", "No. of events in the reconstructed MC", kTH1I, {{25, 0, 25}}); + + rEventSelection.add("hEventCut", "No. of event after cuts", kTH1I, {{20, 0, 20}}); + std::shared_ptr hCutFlow = rEventSelection.get(HIST("hEventCut")); + hCutFlow->GetXaxis()->SetBinLabel(1, "All Events"); + hCutFlow->GetXaxis()->SetBinLabel(2, "|Vz| < cut"); + hCutFlow->GetXaxis()->SetBinLabel(3, "sel8"); + hCutFlow->GetXaxis()->SetBinLabel(4, "kNoTimeFrameBorder"); + hCutFlow->GetXaxis()->SetBinLabel(5, "kNoITSROFrameBorder"); + hCutFlow->GetXaxis()->SetBinLabel(6, "kNoSameBunchPileup"); + hCutFlow->GetXaxis()->SetBinLabel(7, "kIsGoodITSLayersAll"); + hCutFlow->GetXaxis()->SetBinLabel(8, "Occupancy Cut"); + hCutFlow->GetXaxis()->SetBinLabel(9, "rctChecker"); + hCutFlow->GetXaxis()->SetBinLabel(10, "kIsTriggerTVX"); + hCutFlow->GetXaxis()->SetBinLabel(11, "kIsGoodZvtxFT0vsPV"); + hCutFlow->GetXaxis()->SetBinLabel(12, "IsINELgt0"); + hCutFlow->GetXaxis()->SetBinLabel(13, "isVertexITSTPC"); + hCutFlow->GetXaxis()->SetBinLabel(14, "isVertexTOFMatched"); + + std::shared_ptr hv0label = rEventSelection.get(HIST("htrackscheck_v0")); + hv0label->GetXaxis()->SetBinLabel(1, "All Tracks"); + hv0label->GetXaxis()->SetBinLabel(2, "DCA V0 to PV"); + hv0label->GetXaxis()->SetBinLabel(3, "y K0s"); + hv0label->GetXaxis()->SetBinLabel(4, "Min V0 pT"); + hv0label->GetXaxis()->SetBinLabel(5, "Daughter DCA"); + hv0label->GetXaxis()->SetBinLabel(6, "CosPA"); + hv0label->GetXaxis()->SetBinLabel(7, "Decay Radius"); + hv0label->GetXaxis()->SetBinLabel(8, "Lifetime"); + hv0label->GetXaxis()->SetBinLabel(9, "CompetingCascade"); + hv0label->GetXaxis()->SetBinLabel(10, "Standard V0"); + hv0label->GetXaxis()->SetBinLabel(11, "Mass Tolerance"); + + std::shared_ptr hv0DauLabel = rEventSelection.get(HIST("htrackscheck_v0_daughters")); + hv0DauLabel->GetXaxis()->SetBinLabel(1, "AllDau Tracks"); + hv0DauLabel->GetXaxis()->SetBinLabel(2, "has TPC"); + hv0DauLabel->GetXaxis()->SetBinLabel(3, "TPC CrossedRows"); + hv0DauLabel->GetXaxis()->SetBinLabel(4, "TPC CRFC"); + hv0DauLabel->GetXaxis()->SetBinLabel(5, "TPC Chi2NCL"); + hv0DauLabel->GetXaxis()->SetBinLabel(6, "Charge"); + hv0DauLabel->GetXaxis()->SetBinLabel(7, "Eta"); + hv0DauLabel->GetXaxis()->SetBinLabel(8, "PID TPC"); + + std::shared_ptr hv0labelmcrec = rEventSelection.get(HIST("events_checkrec")); + hv0labelmcrec->GetXaxis()->SetBinLabel(1, "All Tracks"); + hv0labelmcrec->GetXaxis()->SetBinLabel(2, "V0Daughter Sel."); + hv0labelmcrec->GetXaxis()->SetBinLabel(3, "V0 Sel."); + hv0labelmcrec->GetXaxis()->SetBinLabel(4, "V0 PDG"); + hv0labelmcrec->GetXaxis()->SetBinLabel(5, "Mother PDG"); + hv0labelmcrec->GetXaxis()->SetBinLabel(6, "Same Mother"); + hv0labelmcrec->GetXaxis()->SetBinLabel(7, "Split Track"); + hv0labelmcrec->GetXaxis()->SetBinLabel(8, "Global Index"); + hv0labelmcrec->GetXaxis()->SetBinLabel(9, "Generator"); + hv0labelmcrec->GetXaxis()->SetBinLabel(10, "Rapidity"); } hglue.add("h3glueInvMassDS", "h3glueInvMassDS", kTHnSparseF, {multiplicityAxis, ptAxis, glueballMassAxis, thnAxisPOL, thnAxisPhi}, true); hglue.add("h3glueInvMassME", "h3glueInvMassME", kTHnSparseF, {multiplicityAxis, ptAxis, glueballMassAxis, thnAxisPOL, thnAxisPhi}, true); hglue.add("h3glueInvMassRot", "h3glueInvMassRot", kTHnSparseF, {multiplicityAxis, ptAxis, glueballMassAxis, thnAxisPOL, thnAxisPhi}, true); - hglue.add("heventscheck", "heventscheck", kTH1I, {{10, 0, 10}}); - hglue.add("htrackscheck_v0", "htrackscheck_v0", kTH1I, {{15, 0, 15}}); - hglue.add("htrackscheck_v0_daughters", "htrackscheck_v0_daughters", kTH1I, {{15, 0, 15}}); // K0s topological/PID cuts if (config.correlation2Dhist) { rKzeroShort.add("mass_lambda_kshort_before", "mass under lambda hypotheses and Kshort mass", kTH2F, {{100, 0.2, 0.8}, {100, 0.9, 1.5}}); - // rKzeroShort.add("mass_lambda_kshort_after1", "mass under lambda hypotheses and Kshort mass", kTH2F, {{100, 0.2, 0.8}, {100, 0.9, 1.5}}); - // rKzeroShort.add("mass_lambda_kshort_after2", "mass under lambda hypotheses and Kshort mass", kTH2F, {{100, 0.2, 0.8}, {100, 0.9, 1.5}}); - // rKzeroShort.add("mass_lambda_kshort_after3", "mass under lambda hypotheses and Kshort mass", kTH2F, {{100, 0.2, 0.8}, {100, 0.9, 1.5}}); - // rKzeroShort.add("mass_lambda_kshort_after4", "mass under lambda hypotheses and Kshort mass", kTH2F, {{100, 0.2, 0.8}, {100, 0.9, 1.5}}); - // rKzeroShort.add("mass_lambda_kshort_after5", "mass under lambda hypotheses and Kshort mass", kTH2F, {{100, 0.2, 0.8}, {100, 0.9, 1.5}}); - // rKzeroShort.add("mass_lambda_kshort_after6", "mass under lambda hypotheses and Kshort mass", kTH2F, {{100, 0.2, 0.8}, {100, 0.9, 1.5}}); - // rKzeroShort.add("mass_lambda_kshort_after7", "mass under lambda hypotheses and Kshort mass", kTH2F, {{100, 0.2, 0.8}, {100, 0.9, 1.5}}); - // rKzeroShort.add("mass_lambda_kshort_after8", "mass under lambda hypotheses and Kshort mass", kTH2F, {{100, 0.2, 0.8}, {100, 0.9, 1.5}}); - // rKzeroShort.add("mass_lambda_kshort_after9", "mass under lambda hypotheses and Kshort mass", kTH2F, {{100, 0.2, 0.8}, {100, 0.9, 1.5}}); rKzeroShort.add("mass_lambda_kshort_after10", "mass under lambda hypotheses and Kshort mass", kTH2F, {{100, 0.2, 0.8}, {100, 0.9, 1.5}}); } if (config.qAv0) { @@ -272,25 +314,6 @@ struct HigherMassResonances { rKzeroShort.add("hV0CosPA", "hV0CosPA", {HistType::kTH1F, {{100, 0.96f, 1.1f}}}); rKzeroShort.add("hLT", "hLT", {HistType::kTH1F, {{100, 0.0f, 50.0f}}}); rKzeroShort.add("angularSeparation", "Angular distribution between two K0s vs pT", {HistType::kTH1F, {{200, 0.0f, 4.0f}}}); - // rKzeroShort.add("Mass_lambda", "Mass under lambda hypothesis", kTH1F, {glueballMassAxis}); - // rKzeroShort.add("mass_AntiLambda", "Mass under anti-lambda hypothesis", kTH1F, {glueballMassAxis}); - // rKzeroShort.add("mass_Gamma", "Mass under Gamma hypothesis", kTH1F, {glueballMassAxis}); - - // rKzeroShort.add("mass_Hypertriton", "Mass under hypertriton hypothesis", kTH1F, {glueballMassAxis}); - // rKzeroShort.add("mass_AnitHypertriton", "Mass under anti-hypertriton hypothesis", kTH1F, {glueballMassAxis}); - // rKzeroShort.add("rapidity", "Rapidity distribution", kTH1F, {{100, -1.0f, 1.0f}}); - // rKzeroShort.add("hv0radius", "hv0radius", kTH1F, {{100, 0.0f, 200.0f}}); - // rKzeroShort.add("hDCApostopv", "DCA positive daughter to PV", kTH1F, {{1000, -10.0f, 10.0f}}); - // rKzeroShort.add("hDCAnegtopv", "DCA negative daughter to PV", kTH1F, {{1000, -10.0f, 10.0f}}); - // rKzeroShort.add("hcDCAv0topv", "DCA V0 to PV", kTH1F, {{60, -3.0f, 3.0f}}); - // rKzeroShort.add("halpha", "Armenteros alpha", kTH1F, {{100, -5.0f, 5.0f}}); - // rKzeroShort.add("hqtarmbyalpha", "qtarm/alpha", kTH1F, {{100, 0.0f, 1.0f}}); - // rKzeroShort.add("hpsipair", "psi pair angle", kTH1F, {{100, -5.0f, 5.0f}}); - - // // Topological histograms (before the selection) - // rKzeroShort.add("hDCAV0Daughters_before", "DCA between v0 daughters before the selection", {HistType::kTH1F, {{60, -3.0f, 3.0f}}}); - // rKzeroShort.add("hV0CosPA_before", "hV0CosPA_before", {HistType::kTH1F, {{200, 0.91f, 1.1f}}}); - // rKzeroShort.add("hLT_before", "hLT_before", {HistType::kTH1F, {{100, 0.0f, 50.0f}}}); } rKzeroShort.add("NksProduced", "Number of K0s produced", kTH1I, {{15, -0.5, 14.5}}); @@ -301,29 +324,16 @@ struct HigherMassResonances { rKzeroShort.add("hNSigmaNegPionK0s_after", "hNSigmaNegPionK0s_after", {HistType::kTH2F, {{ptAxis}, {100, -5.f, 5.f}}}); // rKzeroShort.add("dE_by_dx_TPC", "dE/dx signal in the TPC as a function of pT", kTH2F, {config.axisPtfordEbydx, config.axisdEdx}); } - // if (config.qAv0Daughters) { - // rKzeroShort.add("negative_pt", "Negative daughter pT", kTH1F, {ptAxis}); - // rKzeroShort.add("positive_pt", "Positive daughter pT", kTH1F, {ptAxis}); - // rKzeroShort.add("negative_eta", "Negative daughter eta", kTH1F, {{100, -1.0f, 1.0f}}); - // rKzeroShort.add("positive_eta", "Positive daughter eta", kTH1F, {{100, -1.0f, 1.0f}}); - // rKzeroShort.add("negative_phi", "Negative daughter phi", kTH1F, {{70, 0.0f, 7.0f}}); - // rKzeroShort.add("positive_phi", "Positive daughter phi", kTH1F, {{70, 0.0f, 7.0f}}); - // } // For MC if (config.isMC) { - hMChists.add("events_check", "No. of events in the generated MC", kTH1I, {{20, 0, 20}}); - hMChists.add("events_checkrec", "No. of events in the reconstructed MC", kTH1I, {{25, 0, 25}}); hMChists.add("Genf1710", "Gen f_{0}(1710)", kTHnSparseF, {multiplicityAxis, ptAxis, thnAxisPOL}); hMChists.add("Genf17102", "Gen f_{0}(1710)", kTHnSparseF, {multiplicityAxis, ptAxis, thnAxisPOL}); hMChists.add("Recf1710_pt1", "Rec f_{0}(1710) p_{T}", kTHnSparseF, {multiplicityAxis, ptAxis, glueballMassAxis, thnAxisPOL}); hMChists.add("Recf1710_pt2", "Rec f_{0}(1710) p_{T}", kTHnSparseF, {multiplicityAxis, ptAxis, glueballMassAxis, thnAxisPOL}); - // hMChists.add("Recf1710_p", "Rec f_{0}(1710) p", kTH1F, {ptAxis}); hMChists.add("h1Recsplit", "Rec p_{T}2", kTH1F, {ptAxis}); - // hMChists.add("Recf1710_mass", "Rec f_{0}(1710) mass", kTH1F, {glueballMassAxis}); hMChists.add("Genf1710_mass", "Gen f_{0}(1710) mass", kTH1F, {glueballMassAxis}); hMChists.add("Genf1710_mass2", "Gen f_{0}(1710) mass", kTH1F, {glueballMassAxis}); - // hMChists.add("Genf1710_pt2", "Gen f_{0}(1710) p_{T}", kTH1F, {ptAxis}); hMChists.add("GenPhi", "Gen Phi", kTH1F, {{70, 0.0, 7.0f}}); hMChists.add("GenPhi2", "Gen Phi", kTH1F, {{70, 0.0, 7.0f}}); hMChists.add("GenEta", "Gen Eta", kTHnSparseF, {{150, -1.5f, 1.5f}}); @@ -338,41 +348,85 @@ struct HigherMassResonances { hMChists.add("RecRapidity2", "Rec Rapidity", kTH1F, {{100, -1.0f, 1.0f}}); hMChists.add("Rec_Multiplicity", "Multiplicity in MC", kTH1F, {multiplicityAxis}); hMChists.add("MC_mult_after_event_sel", "Multiplicity in MC", kTH1F, {multiplicityAxis}); - // hMChists.add("GenPx", "Gen Px", kTH1F, {{100, -10.0f, 10.0f}}); - // hMChists.add("GenPy", "Gen Py", kTH1F, {{100, -10.0f, 10.0f}}); - // hMChists.add("GenPz", "Gen Pz", kTH1F, {{100, -10.0f, 10.0f}}); } } - template - bool eventselection(Collision const& collision) + template + bool selectionEvent(const Coll& collision, bool fillHist = true) { - hglue.fill(HIST("heventscheck"), 1.5); + if (fillHist) + rEventSelection.fill(HIST("hEventCut"), 0); - if (config.timFrameEvsel && (!collision.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision.selection_bit(aod::evsel::kNoITSROFrameBorder))) { + if (std::abs(collision.posZ()) > config.cutzvertex) return false; - } - hglue.fill(HIST("heventscheck"), 2.5); + if (fillHist) + rEventSelection.fill(HIST("hEventCut"), 1); - if (!collision.sel8()) { + if (!collision.sel8()) return false; - } - hglue.fill(HIST("heventscheck"), 3.5); + if (fillHist) + rEventSelection.fill(HIST("hEventCut"), 2); + + if (config.isNoTimeFrameBorder && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) + return false; + if (fillHist) + rEventSelection.fill(HIST("hEventCut"), 3); - // if (config.piluprejection && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + if (config.isNoITSROFrameBorder && !collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) + return false; + if (fillHist) + rEventSelection.fill(HIST("hEventCut"), 4); + + if (config.isNoSameBunchPileup && (!collision.selection_bit(aod::evsel::kNoSameBunchPileup))) + return false; + if (fillHist) + rEventSelection.fill(HIST("hEventCut"), 5); + + if (config.isAllLayersGoodITS && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) + return false; + if (fillHist) + rEventSelection.fill(HIST("hEventCut"), 6); + + // if (config.isNoCollInTimeRangeStandard && (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard))) // return false; - // } - // hglue.fill(HIST("heventscheck"), 4.5); - // if (config.goodzvertex && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + if (config.isApplyOccCut && (std::abs(collision.trackOccupancyInTimeRange()) > config.configOccCut)) + return false; + if (fillHist) + rEventSelection.fill(HIST("hEventCut"), 7); + + if (rctCut.requireRCTFlagChecker && !rctChecker(collision)) + return false; + if (fillHist) + rEventSelection.fill(HIST("hEventCut"), 8); + + if (config.isTriggerTVX && !collision.selection_bit(aod::evsel::kIsTriggerTVX)) + return false; + if (fillHist) + rEventSelection.fill(HIST("hEventCut"), 9); + + if (config.isGoodZvtxFT0vsPV && !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) + return false; + if (fillHist) + rEventSelection.fill(HIST("hEventCut"), 10); + + // if (config.isINELgt0 && !collision.isInelGt0()) { // return false; // } - // hglue.fill(HIST("heventscheck"), 5.5); + // if (fillHist) + rEventSelection.fill(HIST("hEventCut"), 11); - // if (config.itstpctracks && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { + // if (config.isVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { // return false; // } - // hglue.fill(HIST("heventscheck"), 6.5); + if (fillHist) + rEventSelection.fill(HIST("hEventCut"), 12); + + if (config.isVertexTOFMatched && !collision.selection_bit(aod::evsel::kIsVertexTOFmatched)) { + return false; + } + if (fillHist) + rEventSelection.fill(HIST("hEventCut"), 13); return true; } @@ -389,126 +443,91 @@ struct HigherMassResonances { const float cpav0 = candidate.v0cosPA(); float ctauK0s = candidate.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short; - float lowmasscutks0 = 0.497 - config.cWidthKs0 * config.cSigmaMassKs0; - float highmasscutks0 = 0.497 + config.cWidthKs0 * config.cSigmaMassKs0; - // float decayLength = candidate.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * RecoDecay::sqrtSumOfSquares(candidate.px(), candidate.py(), candidate.pz()); + float lowmasscutks0 = o2::constants::physics::MassKPlus - config.cWidthKs0 * config.cSigmaMassKs0; + float highmasscutks0 = o2::constants::physics::MassKPlus + config.cWidthKs0 * config.cSigmaMassKs0; if (config.qAv0) { rKzeroShort.fill(HIST("hMassK0Shortbefore"), candidate.mK0Short(), candidate.pt()); rKzeroShort.fill(HIST("hLT"), ctauK0s); rKzeroShort.fill(HIST("hDCAV0Daughters"), candidate.dcaV0daughters()); rKzeroShort.fill(HIST("hV0CosPA"), candidate.v0cosPA()); - // rKzeroShort.fill(HIST("Mass_lambda"), candidate.mLambda()); - // rKzeroShort.fill(HIST("mass_AntiLambda"), candidate.mAntiLambda()); - // rKzeroShort.fill(HIST("mass_Gamma"), candidate.mGamma()); - // rKzeroShort.fill(HIST("mass_Hypertriton"), candidate.mHypertriton()); - // rKzeroShort.fill(HIST("mass_AnitHypertriton"), candidate.mAntiHypertriton()); - // rKzeroShort.fill(HIST("rapidity"), candidate.yK0Short()); - // rKzeroShort.fill(HIST("hv0radius"), candidate.v0radius()); - // rKzeroShort.fill(HIST("hDCApostopv"), candidate.dcapostopv()); - // rKzeroShort.fill(HIST("hDCAnegtopv"), candidate.dcanegtopv()); - // rKzeroShort.fill(HIST("hcDCAv0topv"), candidate.dcav0topv()); - // rKzeroShort.fill(HIST("halpha"), candidate.alpha()); - // rKzeroShort.fill(HIST("hqtarmbyalpha"), arm); - // rKzeroShort.fill(HIST("hpsipair"), candidate.psipair()); } if (config.correlation2Dhist) rKzeroShort.fill(HIST("mass_lambda_kshort_before"), candidate.mK0Short(), candidate.mLambda()); hglue.fill(HIST("htrackscheck_v0"), 0.5); - if (config.cDCAv0topv && std::fabs(candidate.dcav0topv()) > config.cMaxV0DCA) { + if (config.isApplyDCAv0topv && std::fabs(candidate.dcav0topv()) > config.cMaxV0DCA) { return false; } hglue.fill(HIST("htrackscheck_v0"), 1.5); - // if (config.correlation2Dhist) - // rKzeroShort.fill(HIST("mass_lambda_kshort_after1"), candidate.mK0Short(), candidate.mLambda()); - // if (config.rapidityks && std::abs(candidate.yK0Short()) >= config.confKsrapidity) { - // return false; - // } - if (std::abs(candidate.yK0Short()) >= config.confKsrapidity) { + if (std::abs(candidate.rapidity(0)) >= config.confKsrapidity) { return false; } hglue.fill(HIST("htrackscheck_v0"), 2.5); - // if (config.correlation2Dhist) - // rKzeroShort.fill(HIST("mass_lambda_kshort_after2"), candidate.mK0Short(), candidate.mLambda()); if (pT < config.confV0PtMin) { return false; } hglue.fill(HIST("htrackscheck_v0"), 3.5); - // if (config.correlation2Dhist) - // rKzeroShort.fill(HIST("mass_lambda_kshort_after3"), candidate.mK0Short(), candidate.mLambda()); if (dcaDaughv0 > config.confV0DCADaughMax) { return false; } hglue.fill(HIST("htrackscheck_v0"), 4.5); - // if (config.correlation2Dhist) - // rKzeroShort.fill(HIST("mass_lambda_kshort_after4"), candidate.mK0Short(), candidate.mLambda()); if (cpav0 < config.confV0CPAMin) { return false; } hglue.fill(HIST("htrackscheck_v0"), 5.5); - // if (config.correlation2Dhist) - // rKzeroShort.fill(HIST("mass_lambda_kshort_after5"), candidate.mK0Short(), candidate.mLambda()); if (tranRad < config.confV0TranRadV0Min) { return false; } hglue.fill(HIST("htrackscheck_v0"), 6.5); - // if (config.correlation2Dhist) - // rKzeroShort.fill(HIST("mass_lambda_kshort_after6"), candidate.mK0Short(), candidate.mLambda()); if (tranRad > config.confV0TranRadV0Max) { return false; } hglue.fill(HIST("htrackscheck_v0"), 7.5); - // if (config.correlation2Dhist) - // rKzeroShort.fill(HIST("mass_lambda_kshort_after7"), candidate.mK0Short(), candidate.mLambda()); if (std::fabs(ctauK0s) > config.cMaxV0LifeTime) { return false; } hglue.fill(HIST("htrackscheck_v0"), 8.5); - // if (config.correlation2Dhist) - // rKzeroShort.fill(HIST("mass_lambda_kshort_after8"), candidate.mK0Short(), candidate.mLambda()); - - // if (config.armcut && arm < config.confarmcut) { - // return false; - // } - hglue.fill(HIST("htrackscheck_v0"), 9.5); - // if (config.correlation2Dhist) - // rKzeroShort.fill(HIST("mass_lambda_kshort_after9"), candidate.mK0Short(), candidate.mLambda()); - // if (config.applyCompetingcut && (std::abs(candidate.mLambda() - PDGdatabase->Mass(3122)) <= config.competingcascrejlambda || std::abs(candidate.mAntiLambda() - PDGdatabase->Mass(-3122)) <= config.competingcascrejlambdaanti)) - if (config.applyCompetingcut && (std::abs(candidate.mLambda() - o2::constants::physics::MassLambda0) <= config.competingcascrejlambda || std::abs(candidate.mAntiLambda() - o2::constants::physics::MassLambda0) <= config.competingcascrejlambda)) { + if (config.isapplyCompetingcut && (std::abs(candidate.mLambda() - o2::constants::physics::MassLambda0) <= config.competingcascrejlambda || std::abs(candidate.mAntiLambda() - o2::constants::physics::MassLambda0) <= config.competingcascrejlambda)) { return false; } - hglue.fill(HIST("htrackscheck_v0"), 10.5); + hglue.fill(HIST("htrackscheck_v0"), 9.5); + if (config.correlation2Dhist) rKzeroShort.fill(HIST("mass_lambda_kshort_after10"), candidate.mK0Short(), candidate.mLambda()); if (config.qAv0) { rKzeroShort.fill(HIST("hMassK0ShortSelected"), candidate.mK0Short(), candidate.pt()); - // rKzeroShort.fill(HIST("mass_lambda_kshort_after"), candidate.mK0Short(), candidate.mLambda()); } + if (config.isStandardV0 && candidate.v0Type() != 1) { + return false; // Only standard V0s are selected + } + hglue.fill(HIST("htrackscheck_v0"), 10.5); + if (candidate.mK0Short() < lowmasscutks0 || candidate.mK0Short() > highmasscutks0) { return false; } + hglue.fill(HIST("htrackscheck_v0"), 11.5); + return true; } template - bool isSelectedV0Daughter(T const& track, float charge, double nsigmaV0Daughter, V0s const& /*candidate*/) + bool isSelectedV0Daughter(T const& track, float charge, double nsigmaV0DaughterTPC, V0s const& /*candidate*/) { if (config.qAPID) { // Filling the PID of the V0 daughters in the region of the K0 peak. (charge == 1) ? rKzeroShort.fill(HIST("hNSigmaPosPionK0s_before"), track.tpcInnerParam(), track.tpcNSigmaPi()) : rKzeroShort.fill(HIST("hNSigmaNegPionK0s_before"), track.tpcInnerParam(), track.tpcNSigmaPi()); - // rKzeroShort.fill(HIST("dE_by_dx_TPC"), track.p(), track.tpcSignal()); } const auto eta = track.eta(); const auto tpcNClsF = track.tpcNClsFound(); @@ -520,24 +539,18 @@ struct HigherMassResonances { return false; hglue.fill(HIST("htrackscheck_v0_daughters"), 1.5); - if (!config.globalTracks) { - if (track.tpcNClsCrossedRows() < config.tpcCrossedrows) - return false; - hglue.fill(HIST("htrackscheck_v0_daughters"), 2.5); + if (track.tpcNClsCrossedRows() < config.tpcCrossedrows) + return false; + hglue.fill(HIST("htrackscheck_v0_daughters"), 2.5); - if (track.tpcCrossedRowsOverFindableCls() < config.tpcCrossedrowsOverfcls) - return false; - hglue.fill(HIST("htrackscheck_v0_daughters"), 3.5); + if (track.tpcCrossedRowsOverFindableCls() < config.tpcCrossedrowsOverfcls) + return false; + hglue.fill(HIST("htrackscheck_v0_daughters"), 3.5); - if (tpcNClsF < config.confDaughTPCnclsMin) { - return false; - } - hglue.fill(HIST("htrackscheck_v0_daughters"), 4.5); - } else { - if (!track.isGlobalTrack()) - return false; - hglue.fill(HIST("htrackscheck_v0_daughters"), 4.5); + if (tpcNClsF < config.confDaughTPCnclsMin) { + return false; } + hglue.fill(HIST("htrackscheck_v0_daughters"), 4.5); if (charge < 0 && sign > 0) { return false; @@ -554,11 +567,13 @@ struct HigherMassResonances { } hglue.fill(HIST("htrackscheck_v0_daughters"), 7.5); - if (std::abs(nsigmaV0Daughter) > config.confDaughPIDCuts) { + if (std::abs(nsigmaV0DaughterTPC) > config.confDaughPIDCutTPC) { return false; } hglue.fill(HIST("htrackscheck_v0_daughters"), 8.5); + // if (std::abs()) + if (config.qAPID) { (charge == 1) ? rKzeroShort.fill(HIST("hNSigmaPosPionK0s_after"), track.tpcInnerParam(), track.tpcNSigmaPi()) : rKzeroShort.fill(HIST("hNSigmaNegPionK0s_after"), track.tpcInnerParam(), track.tpcNSigmaPi()); } @@ -580,7 +595,7 @@ struct HigherMassResonances { if (config.qAv0) { rKzeroShort.fill(HIST("angularSeparation"), angle); } - if (config.applyAngSepCut && angle > config.angSepCut) { + if (config.isapplyAngSepCut && angle > config.angSepCut) { return false; } return true; @@ -595,11 +610,11 @@ struct HigherMassResonances { Filter preFilterV0 = (nabs(aod::v0data::dcapostopv) > config.v0settingDcapostopv && nabs(aod::v0data::dcanegtopv) > config.v0settingDcanegtopv); // Defining the type of the daughter tracks - using EventCandidates = soa::Filtered>; + using EventCandidates = soa::Filtered>; using TrackCandidates = soa::Filtered>; using V0TrackCandidate = aod::V0Datas; // For Monte Carlo - using EventCandidatesMC = soa::Join; + using EventCandidatesMC = soa::Join; using TrackCandidatesMC = soa::Filtered>; using V0TrackCandidatesMC = soa::Filtered>; // zBeam direction in lab frame @@ -615,8 +630,8 @@ struct HigherMassResonances { fourVecDauCM = boost(daughter1); // boost the frame of daughter to the center of mass frame // threeVecDauCM = fourVecDauCM.Vect(); // get the 3 vector of daughter in the frame of mother - Beam1_CM = ROOT::Math::XYZVectorF((boost(Beam1).Vect()).Unit()); - Beam2_CM = ROOT::Math::XYZVectorF((boost(Beam2).Vect()).Unit()); + beam1CM = ROOT::Math::XYZVectorF((boost(beam1).Vect()).Unit()); + beam2CM = ROOT::Math::XYZVectorF((boost(beam2).Vect()).Unit()); // define y = zBeam x z: Normal to the production plane // ẑ: mother direction in lab, boosted into mother's rest frame @@ -634,32 +649,33 @@ struct HigherMassResonances { // auto p_proj_y = threeVecDauCM.Dot(y_axis); // // Calculate φ in [-π, π] - // auto angle_phi = std::atan2(p_proj_y, p_proj_x); // φ in radians + // auto anglePhi = std::atan2(p_proj_y, p_proj_x); // φ in radians - v1_CM = ROOT::Math::XYZVectorF(boost(daughter1).Vect()).Unit(); + v1CM = ROOT::Math::XYZVectorF(boost(daughter1).Vect()).Unit(); // ROOT::Math::XYZVectorF v2_CM{(boost(daughter1).Vect()).Unit()}; // using positive sign convention for the first track - // ROOT::Math::XYZVectorF v_CM = (t1.sign() > 0 ? v1_CM : v2_CM); // here selected decay daughter momentum is intested. here you can choose one decay daughter no need to check both case as it is neutral particle for our case + // ROOT::Math::XYZVectorF v_CM = (t1.sign() > 0 ? v1CM : v2_CM); // here selected decay daughter momentum is intested. here you can choose one decay daughter no need to check both case as it is neutral particle for our case // Helicity frame - zaxis_HE = ROOT::Math::XYZVectorF(mother.Vect()).Unit(); - yaxis_HE = ROOT::Math::XYZVectorF(Beam1_CM.Cross(Beam2_CM)).Unit(); - xaxis_HE = ROOT::Math::XYZVectorF(yaxis_HE.Cross(zaxis_HE)).Unit(); + zaxisHE = ROOT::Math::XYZVectorF(mother.Vect()).Unit(); + yaxisHE = ROOT::Math::XYZVectorF(beam1CM.Cross(beam2CM)).Unit(); + xaxisHE = ROOT::Math::XYZVectorF(yaxisHE.Cross(zaxisHE)).Unit(); - // CosThetaHE = zaxis_HE.Dot(v_CM); + // CosThetaHE = zaxisHE.Dot(v_CM); - auto angle_phi = TMath::ATan2(yaxis_HE.Dot(v1_CM), xaxis_HE.Dot(v1_CM)); - if (angle_phi < 0) { - angle_phi += 2 * TMath::Pi(); // ensure phi is in [0, 2pi] - } + auto anglePhi = std::atan2(yaxisHE.Dot(v1CM), xaxisHE.Dot(v1CM)); + anglePhi = RecoDecay::constrainAngle(anglePhi, 0.0); + // if (anglePhi < 0) { + // anglePhi += o2::constants::math::TwoPI; // ensure phi is in [0, 2pi] + // } - // if (std::abs(mother.Rapidity()) < 0.5) { + // if (std::abs(mother.Rapidity()) < config.rapidityMotherData) { if (config.activateTHnSparseCosThStarHelicity) { // helicityVec = mother.Vect(); // 3 vector of mother in COM frame // auto cosThetaStarHelicity = helicityVec.Dot(threeVecDauCM) / (std::sqrt(threeVecDauCM.Mag2()) * std::sqrt(helicityVec.Mag2())); auto cosThetaStarHelicity = mother.Vect().Dot(fourVecDauCM.Vect()) / (std::sqrt(fourVecDauCM.Vect().Mag2()) * std::sqrt(mother.Vect().Mag2())); if (!isMix) { - if (std::abs(mother.Rapidity()) < 0.5) { - hglue.fill(HIST("h3glueInvMassDS"), multiplicity, mother.Pt(), mother.M(), cosThetaStarHelicity, angle_phi); + if (std::abs(mother.Rapidity()) < config.rapidityMotherData) { + hglue.fill(HIST("h3glueInvMassDS"), multiplicity, mother.Pt(), mother.M(), cosThetaStarHelicity, anglePhi); } for (int i = 0; i < config.cRotations; i++) { @@ -673,50 +689,50 @@ struct HigherMassResonances { daughterRotCM = boost2(daughterRot); auto cosThetaStarHelicityRot = motherRot.Vect().Dot(daughterRotCM.Vect()) / (std::sqrt(daughterRotCM.Vect().Mag2()) * std::sqrt(motherRot.Vect().Mag2())); - if (motherRot.Rapidity() < 0.5) - hglue.fill(HIST("h3glueInvMassRot"), multiplicity, motherRot.Pt(), motherRot.M(), cosThetaStarHelicityRot, angle_phi); + if (motherRot.Rapidity() < config.rapidityMotherData) + hglue.fill(HIST("h3glueInvMassRot"), multiplicity, motherRot.Pt(), motherRot.M(), cosThetaStarHelicityRot, anglePhi); } } else { - if (std::abs(mother.Rapidity()) < 0.5) { - hglue.fill(HIST("h3glueInvMassME"), multiplicity, mother.Pt(), mother.M(), cosThetaStarHelicity, angle_phi); + if (std::abs(mother.Rapidity()) < config.rapidityMotherData) { + hglue.fill(HIST("h3glueInvMassME"), multiplicity, mother.Pt(), mother.M(), cosThetaStarHelicity, anglePhi); } } } else if (config.activateTHnSparseCosThStarProduction) { normalVec = ROOT::Math::XYZVector(mother.Py(), -mother.Px(), 0.f); auto cosThetaStarProduction = normalVec.Dot(fourVecDauCM.Vect()) / (std::sqrt(fourVecDauCM.Vect().Mag2()) * std::sqrt(normalVec.Mag2())); if (!isMix) { - if (std::abs(mother.Rapidity()) < 0.5) { - hglue.fill(HIST("h3glueInvMassDS"), multiplicity, mother.Pt(), mother.M(), cosThetaStarProduction, angle_phi); + if (std::abs(mother.Rapidity()) < config.rapidityMotherData) { + hglue.fill(HIST("h3glueInvMassDS"), multiplicity, mother.Pt(), mother.M(), cosThetaStarProduction, anglePhi); } for (int i = 0; i < config.cRotations; i++) { theta2 = rn->Uniform(o2::constants::math::PI - o2::constants::math::PI / config.rotationalCut, o2::constants::math::PI + o2::constants::math::PI / config.rotationalCut); motherRot = ROOT::Math::PxPyPzMVector(mother.Px() * std::cos(theta2) - mother.Py() * std::sin(theta2), mother.Px() * std::sin(theta2) + mother.Py() * std::cos(theta2), mother.Pz(), mother.M()); - if (std::abs(motherRot.Rapidity()) < 0.5) { - hglue.fill(HIST("h3glueInvMassRot"), multiplicity, motherRot.Pt(), motherRot.M(), cosThetaStarProduction, angle_phi); + if (std::abs(motherRot.Rapidity()) < config.rapidityMotherData) { + hglue.fill(HIST("h3glueInvMassRot"), multiplicity, motherRot.Pt(), motherRot.M(), cosThetaStarProduction, anglePhi); } } } else { - if (std::abs(mother.Rapidity()) < 0.5) { - hglue.fill(HIST("h3glueInvMassME"), multiplicity, mother.Pt(), mother.M(), cosThetaStarProduction, angle_phi); + if (std::abs(mother.Rapidity()) < config.rapidityMotherData) { + hglue.fill(HIST("h3glueInvMassME"), multiplicity, mother.Pt(), mother.M(), cosThetaStarProduction, anglePhi); } } } else if (config.activateTHnSparseCosThStarBeam) { beamVec = ROOT::Math::XYZVector(0.f, 0.f, 1.f); auto cosThetaStarBeam = beamVec.Dot(fourVecDauCM.Vect()) / std::sqrt(fourVecDauCM.Vect().Mag2()); if (!isMix) { - if (std::abs(mother.Rapidity()) < 0.5) { - hglue.fill(HIST("h3glueInvMassDS"), multiplicity, mother.Pt(), mother.M(), cosThetaStarBeam, angle_phi); + if (std::abs(mother.Rapidity()) < config.rapidityMotherData) { + hglue.fill(HIST("h3glueInvMassDS"), multiplicity, mother.Pt(), mother.M(), cosThetaStarBeam, anglePhi); } for (int i = 0; i < config.cRotations; i++) { theta2 = rn->Uniform(o2::constants::math::PI - o2::constants::math::PI / config.rotationalCut, o2::constants::math::PI + o2::constants::math::PI / config.rotationalCut); motherRot = ROOT::Math::PxPyPzMVector(mother.Px() * std::cos(theta2) - mother.Py() * std::sin(theta2), mother.Px() * std::sin(theta2) + mother.Py() * std::cos(theta2), mother.Pz(), mother.M()); - if (std::abs(motherRot.Rapidity()) < 0.5) { - hglue.fill(HIST("h3glueInvMassRot"), multiplicity, motherRot.Pt(), motherRot.M(), cosThetaStarBeam, angle_phi); + if (std::abs(motherRot.Rapidity()) < config.rapidityMotherData) { + hglue.fill(HIST("h3glueInvMassRot"), multiplicity, motherRot.Pt(), motherRot.M(), cosThetaStarBeam, anglePhi); } } } else { - if (std::abs(mother.Rapidity()) < 0.5) { - hglue.fill(HIST("h3glueInvMassME"), multiplicity, mother.Pt(), mother.M(), cosThetaStarBeam, angle_phi); + if (std::abs(mother.Rapidity()) < config.rapidityMotherData) { + hglue.fill(HIST("h3glueInvMassME"), multiplicity, mother.Pt(), mother.M(), cosThetaStarBeam, anglePhi); } } } else if (config.activateTHnSparseCosThStarRandom) { @@ -726,19 +742,19 @@ struct HigherMassResonances { randomVec = ROOT::Math::XYZVector(std::sin(thetaRandom) * std::cos(phiRandom), std::sin(thetaRandom) * std::sin(phiRandom), std::cos(thetaRandom)); auto cosThetaStarRandom = randomVec.Dot(fourVecDauCM.Vect()) / std::sqrt(fourVecDauCM.Vect().Mag2()); if (!isMix) { - if (std::abs(mother.Rapidity()) < 0.5) { - hglue.fill(HIST("h3glueInvMassDS"), multiplicity, mother.Pt(), mother.M(), cosThetaStarRandom, angle_phi); + if (std::abs(mother.Rapidity()) < config.rapidityMotherData) { + hglue.fill(HIST("h3glueInvMassDS"), multiplicity, mother.Pt(), mother.M(), cosThetaStarRandom, anglePhi); } for (int i = 0; i < config.cRotations; i++) { theta2 = rn->Uniform(o2::constants::math::PI - o2::constants::math::PI / config.rotationalCut, o2::constants::math::PI + o2::constants::math::PI / config.rotationalCut); motherRot = ROOT::Math::PxPyPzMVector(mother.Px() * std::cos(theta2) - mother.Py() * std::sin(theta2), mother.Px() * std::sin(theta2) + mother.Py() * std::cos(theta2), mother.Pz(), mother.M()); - if (std::abs(motherRot.Rapidity()) < 0.5) { - hglue.fill(HIST("h3glueInvMassRot"), multiplicity, motherRot.Pt(), motherRot.M(), cosThetaStarRandom, angle_phi); + if (std::abs(motherRot.Rapidity()) < config.rapidityMotherData) { + hglue.fill(HIST("h3glueInvMassRot"), multiplicity, motherRot.Pt(), motherRot.M(), cosThetaStarRandom, anglePhi); } } } else { - if (std::abs(mother.Rapidity()) < 0.5) { - hglue.fill(HIST("h3glueInvMassME"), multiplicity, mother.Pt(), mother.M(), cosThetaStarRandom, angle_phi); + if (std::abs(mother.Rapidity()) < config.rapidityMotherData) { + hglue.fill(HIST("h3glueInvMassME"), multiplicity, mother.Pt(), mother.M(), cosThetaStarRandom, anglePhi); } } } @@ -747,20 +763,26 @@ struct HigherMassResonances { void processSE(EventCandidates::iterator const& collision, TrackCandidates const& /*tracks*/, aod::V0Datas const& V0s) { - hglue.fill(HIST("heventscheck"), 0.5); multiplicity = 0.0; - if (config.cfgMultFOTM) { + + if (config.cSelectMultEstimator == kFT0M) { multiplicity = collision.centFT0M(); - } else { + } else if (config.cSelectMultEstimator == kFT0A) { + multiplicity = collision.centFT0A(); + } else if (config.cSelectMultEstimator == kFT0C) { multiplicity = collision.centFT0C(); - } - if (!eventselection(collision)) { - return; + } else if (config.cSelectMultEstimator == kFV0A) { + multiplicity = collision.centFV0A(); + } else { + multiplicity = collision.centFT0M(); // default } - if (rctCut.requireRCTFlagChecker && !rctCut.rctChecker(collision)) { + if (!selectionEvent(collision, true)) { return; } + // if (rctCut.requireRCTFlagChecker && !rctCut.rctChecker(collision)) { + // return; + // } // auto occupancyNumber = collision.trackOccupancyInTimeRange(); // if (applyOccupancyCut && occupancyNumber < occupancyCut) { @@ -809,26 +831,25 @@ struct HigherMassResonances { continue; } + if (postrack1.hasTOF() && negtrack1.hasTOF() && postrack2.hasTOF() && negtrack2.hasTOF()) { + double nTOFSigmaPos1{postrack1.tofNSigmaPi()}; + double nTOFSigmaNeg1{negtrack1.tofNSigmaPi()}; + double nTOFSigmaPos2{postrack2.tofNSigmaPi()}; + double nTOFSigmaNeg2{negtrack2.tofNSigmaPi()}; + if ((std::abs(nTOFSigmaPos1) > config.confDaughPIDCutTPC) || (std::abs(nTOFSigmaNeg1) > config.confDaughPIDCutTPC) || + (std::abs(nTOFSigmaPos2) > config.confDaughPIDCutTPC) || (std::abs(nTOFSigmaNeg2) > config.confDaughPIDCutTPC)) { + continue; + } + } + if (std::find(v0indexes.begin(), v0indexes.end(), v1.globalIndex()) == v0indexes.end()) { v0indexes.push_back(v1.globalIndex()); } - // if (!(std::find(v0indexes.begin(), v0indexes.end(), v2.globalIndex()) != v0indexes.end())) { - // v0indexes.push_back(v2.globalIndex()); - // } if (v2.globalIndex() <= v1.globalIndex()) { continue; } - // if (config.qAv0Daughters) { - // rKzeroShort.fill(HIST("negative_pt"), negtrack1.pt()); - // rKzeroShort.fill(HIST("positive_pt"), postrack1.pt()); - // rKzeroShort.fill(HIST("negative_eta"), negtrack1.eta()); - // rKzeroShort.fill(HIST("positive_eta"), postrack1.eta()); - // rKzeroShort.fill(HIST("negative_phi"), negtrack1.phi()); - // rKzeroShort.fill(HIST("positive_phi"), postrack1.phi()); - // } - if (postrack1.globalIndex() == postrack2.globalIndex()) { continue; } @@ -840,6 +861,10 @@ struct HigherMassResonances { continue; } + if (config.isApplyEtaCutK0s && (v1.eta() < config.confDaughEta || v2.eta() < config.confDaughEta)) { + continue; + } + if (config.qAv0) { rKzeroShort.fill(HIST("hMasscorrelationbefore"), v1.mK0Short(), v2.mK0Short()); } @@ -850,12 +875,12 @@ struct HigherMassResonances { mother = daughter1 + daughter2; // invariant mass of Kshort pair isMix = false; - if (!config.selectTWOKsOnly) + if (!config.isselectTWOKsOnly) fillInvMass(mother, multiplicity, daughter1, daughter2, isMix); } int sizeofv0indexes = v0indexes.size(); rKzeroShort.fill(HIST("NksProduced"), sizeofv0indexes); - if (config.selectTWOKsOnly && sizeofv0indexes == 2 && allConditionsMet) { + if (config.isselectTWOKsOnly && sizeofv0indexes == config.noOfDaughters && allConditionsMet) { fillInvMass(mother, multiplicity, daughter1, daughter2, false); } v0indexes.clear(); @@ -864,317 +889,43 @@ struct HigherMassResonances { using EventCandidatesDerivedData = soa::Join; using V0CandidatesDerivedData = soa::Join; - using dauTracks = soa::Join; - - void processSEderived(EventCandidatesDerivedData::iterator const& collision, TrackCandidates const& /*tracks*/, aod::V0Datas const& V0s) - { - hglue.fill(HIST("heventscheck"), 0.5); - multiplicity = 0.0; - if (config.cfgMultFOTM) { - multiplicity = collision.centFT0M(); - } else { - multiplicity = collision.centFT0C(); - } - if (!eventselection(collision)) { - return; - } - - if (rctCut.requireRCTFlagChecker && !rctCut.rctChecker(collision)) { - return; - } - - // auto occupancyNumber = collision.trackOccupancyInTimeRange(); - // if (applyOccupancyCut && occupancyNumber < occupancyCut) { - // return; - // } - - if (config.qAevents) { - rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); - rEventSelection.fill(HIST("hmultiplicity"), multiplicity); - // rEventSelection.fill(HIST("multdist_FT0M"), collision.multFT0M()); - // rEventSelection.fill(HIST("multdist_FT0A"), collision.multFT0A()); - // rEventSelection.fill(HIST("multdist_FT0C"), collision.multFT0C()); - // rEventSelection.fill(HIST("hNcontributor"), collision.numContrib()); - } - - std::vector v0indexes; - bool allConditionsMet = 0; - - for (const auto& [v1, v2] : combinations(CombinationsFullIndexPolicy(V0s, V0s))) { - - if (v1.size() == 0 || v2.size() == 0) { - continue; - } - - if (!selectionV0(collision, v1, multiplicity)) { - continue; - } - if (!selectionV0(collision, v2, multiplicity)) { - continue; - } - - auto postrack1 = v1.template posTrack_as(); - auto negtrack1 = v1.template negTrack_as(); - auto postrack2 = v2.template posTrack_as(); - auto negtrack2 = v2.template negTrack_as(); - - double nTPCSigmaPos1{postrack1.tpcNSigmaPi()}; - double nTPCSigmaNeg1{negtrack1.tpcNSigmaPi()}; - double nTPCSigmaPos2{postrack2.tpcNSigmaPi()}; - double nTPCSigmaNeg2{negtrack2.tpcNSigmaPi()}; - - if (!(isSelectedV0Daughter(negtrack1, -1, nTPCSigmaNeg1, v1) && isSelectedV0Daughter(postrack1, 1, nTPCSigmaPos1, v1))) { - continue; - } - if (!(isSelectedV0Daughter(postrack2, 1, nTPCSigmaPos2, v2) && isSelectedV0Daughter(negtrack2, -1, nTPCSigmaNeg2, v2))) { - continue; - } - - if (std::find(v0indexes.begin(), v0indexes.end(), v1.globalIndex()) == v0indexes.end()) { - v0indexes.push_back(v1.globalIndex()); - } - // if (!(std::find(v0indexes.begin(), v0indexes.end(), v2.globalIndex()) != v0indexes.end())) { - // v0indexes.push_back(v2.globalIndex()); - // } + using DauTracks = soa::Join; - if (v2.globalIndex() <= v1.globalIndex()) { - continue; - } + ConfigurableAxis axisVertex{"axisVertex", {20, -10, 10}, "vertex axis for ME mixing"}; + // ConfigurableAxis axisMultiplicityClass{"axisMultiplicityClass", {10, 0, 100}, "multiplicity percentile for ME mixing"}; + ConfigurableAxis axisMultiplicity{"axisMultiplicity", {2000, 0, 10000}, "TPC multiplicity axis for ME mixing"}; - // if (config.qAv0Daughters) { - // rKzeroShort.fill(HIST("negative_pt"), negtrack1.pt()); - // rKzeroShort.fill(HIST("positive_pt"), postrack1.pt()); - // rKzeroShort.fill(HIST("negative_eta"), negtrack1.eta()); - // rKzeroShort.fill(HIST("positive_eta"), postrack1.eta()); - // rKzeroShort.fill(HIST("negative_phi"), negtrack1.phi()); - // rKzeroShort.fill(HIST("positive_phi"), postrack1.phi()); - // } - - if (postrack1.globalIndex() == postrack2.globalIndex()) { - continue; - } - if (negtrack1.globalIndex() == negtrack2.globalIndex()) { - continue; - } - - if (!applyAngSep(v1, v2)) { - continue; - } - - if (config.qAv0) { - rKzeroShort.fill(HIST("hMasscorrelationbefore"), v1.mK0Short(), v2.mK0Short()); - } - allConditionsMet = 1; - daughter1 = ROOT::Math::PxPyPzMVector(v1.px(), v1.py(), v1.pz(), o2::constants::physics::MassK0Short); // Kshort - daughter2 = ROOT::Math::PxPyPzMVector(v2.px(), v2.py(), v2.pz(), o2::constants::physics::MassK0Short); // Kshort - - mother = daughter1 + daughter2; // invariant mass of Kshort pair - isMix = false; - - if (!config.selectTWOKsOnly) - fillInvMass(mother, multiplicity, daughter1, daughter2, isMix); - } - int sizeofv0indexes = v0indexes.size(); - rKzeroShort.fill(HIST("NksProduced"), sizeofv0indexes); - if (config.selectTWOKsOnly && sizeofv0indexes == 2 && allConditionsMet) { - fillInvMass(mother, multiplicity, daughter1, daughter2, false); - } - v0indexes.clear(); - } - PROCESS_SWITCH(HigherMassResonances, processSEderived, "same event process in strangeness derived data", true); + // using BinningTypeTPCMultiplicity = ColumnBinningPolicy; + using BinningTypeFT0M = ColumnBinningPolicy; + using BinningTypeFT0A = ColumnBinningPolicy; + using BinningTypeFT0C = ColumnBinningPolicy; + using BinningTypeFV0A = ColumnBinningPolicy; - ConfigurableAxis mevz = {"mevz", {10, -10., 10.}, "mixed event vertex z binning"}; - ConfigurableAxis memult = {"memult", {20, 0, 100}, "mixed event multiplicity binning"}; + BinningTypeFT0M binningOnFT0M{{axisVertex, axisMultiplicity}, true}; + BinningTypeFT0A binningOnFT0A{{axisVertex, axisMultiplicity}, true}; + BinningTypeFT0C binningOnFT0C{{axisVertex, axisMultiplicity}, true}; + BinningTypeFV0A binningOnFV0A{{axisVertex, axisMultiplicity}, true}; - // Processing Event Mixing using BinningType = ColumnBinningPolicy; - BinningType colBinning{{mevz, memult}, true}; + BinningType colBinning{{axisVertex, axisMultiplicity}, true}; // for derived data only Preslice tracksPerCollisionV0Mixed = o2::aod::v0data::straCollisionId; // for derived data only - void processMEderived(EventCandidatesDerivedData const& collisions, TrackCandidates const& /*tracks*/, V0CandidatesDerivedData const& v0s) - { - // auto tracksTuple = std::make_tuple(v0s); - // BinningTypeVertexContributor binningOnPositions1{{mevz, memult}, true}; - // BinningTypeCentralityM binningOnPositions2{{mevz, memult}, true}; - - // SameKindPair pair1{binningOnPositions1, config.cfgNmixedEvents, -1, collisions, tracksTuple, &cache}; // for PbPb - // SameKindPair pair2{binningOnPositions2, config.cfgNmixedEvents, -1, collisions, tracksTuple, &cache}; // for pp - - // if (config.cfgMultFOTM) { - for (const auto& [c1, c2] : selfCombinations(colBinning, config.cfgNmixedEvents, -1, collisions, collisions)) // two different centrality c1 and c2 and tracks corresponding to them - { - - multiplicity = 0.0; - multiplicity = c1.centFT0M(); - - if (!eventselection(c1) || !eventselection(c2)) { - continue; - } - // auto occupancyNumber = c1.trackOccupancyInTimeRange(); - // auto occupancyNumber2 = c2.trackOccupancyInTimeRange(); - // if (applyOccupancyCut && (occupancyNumber < occupancyCut || occupancyNumber2 < occupancyCut)) { - // return; - // } - - if (rctCut.requireRCTFlagChecker && !rctCut.rctChecker(c1)) { - return; - } - if (rctCut.requireRCTFlagChecker && !rctCut.rctChecker(c2)) { - return; - } - auto groupV01 = v0s.sliceBy(tracksPerCollisionV0Mixed, c1.index()); - auto groupV02 = v0s.sliceBy(tracksPerCollisionV0Mixed, c2.index()); - for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(groupV01, groupV02))) { - - if (t1.size() == 0 || t2.size() == 0) { - continue; - } - - if (!selectionV0(c1, t1, multiplicity)) - continue; - if (!selectionV0(c2, t2, multiplicity)) - continue; - - auto postrack1 = t1.template posTrackExtra_as(); - auto negtrack1 = t1.template negTrackExtra_as(); - auto postrack2 = t2.template posTrackExtra_as(); - auto negtrack2 = t2.template negTrackExtra_as(); - - if (postrack1.globalIndex() == postrack2.globalIndex()) { - continue; - } - if (negtrack1.globalIndex() == negtrack2.globalIndex()) { - continue; - } - double nTPCSigmaPos1{postrack1.tpcNSigmaPi()}; - double nTPCSigmaNeg1{negtrack1.tpcNSigmaPi()}; - double nTPCSigmaPos2{postrack2.tpcNSigmaPi()}; - double nTPCSigmaNeg2{negtrack2.tpcNSigmaPi()}; - - if (!isSelectedV0Daughter(postrack1, 1, nTPCSigmaPos1, t1)) { - continue; - } - if (!isSelectedV0Daughter(postrack2, 1, nTPCSigmaPos2, t2)) { - continue; - } - if (!isSelectedV0Daughter(negtrack1, -1, nTPCSigmaNeg1, t1)) { - continue; - } - if (!isSelectedV0Daughter(negtrack2, -1, nTPCSigmaNeg2, t2)) { - continue; - } - - daughter1 = ROOT::Math::PxPyPzMVector(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassK0Short); // Kshort - daughter2 = ROOT::Math::PxPyPzMVector(t2.px(), t2.py(), t2.pz(), o2::constants::physics::MassK0Short); // Kshort - - mother = daughter1 + daughter2; // invariant mass of Kshort pair - isMix = true; - fillInvMass(mother, multiplicity, daughter1, daughter2, isMix); - } - } - // } - // else { - // for (const auto& [c1, tracks1, c2, tracks2] : pair1) // two different centrality c1 and c2 and tracks corresponding to them - // { - // multiplicity = 0.0f; - // multiplicity = c1.centFT0C(); - - // if (!eventselection(c1) || !eventselection(c2)) { - // continue; - // } - // // auto occupancyNumber = c1.trackOccupancyInTimeRange(); - // // auto occupancyNumber2 = c2.trackOccupancyInTimeRange(); - // // if (applyOccupancyCut && (occupancyNumber < occupancyCut || occupancyNumber2 < occupancyCut)) { - // // return; - // // } - - // for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { - // if (t1.size() == 0 || t2.size() == 0) { - // continue; - // } - - // if (!selectionV0(c1, t1, multiplicity)) - // continue; - // if (!selectionV0(c2, t2, multiplicity)) - // continue; - - // auto postrack1 = t1.template posTrack_as(); - // auto negtrack1 = t1.template negTrack_as(); - // auto postrack2 = t2.template posTrack_as(); - // auto negtrack2 = t2.template negTrack_as(); - // if (postrack1.globalIndex() == postrack2.globalIndex()) { - // continue; - // } - // if (negtrack1.globalIndex() == negtrack2.globalIndex()) { - // continue; - // } - // double nTPCSigmaPos1{postrack1.tpcNSigmaPi()}; - // double nTPCSigmaNeg1{negtrack1.tpcNSigmaPi()}; - // double nTPCSigmaPos2{postrack2.tpcNSigmaPi()}; - // double nTPCSigmaNeg2{negtrack2.tpcNSigmaPi()}; - - // if (!isSelectedV0Daughter(postrack1, 1, nTPCSigmaPos1, t1)) { - // continue; - // } - // if (!isSelectedV0Daughter(postrack2, 1, nTPCSigmaPos2, t2)) { - // continue; - // } - // if (!isSelectedV0Daughter(negtrack1, -1, nTPCSigmaNeg1, t1)) { - // continue; - // } - // if (!isSelectedV0Daughter(negtrack2, -1, nTPCSigmaNeg2, t2)) { - // continue; - // } - // daughter1 = ROOT::Math::PxPyPzMVector(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassK0Short); // Kshort - // daughter2 = ROOT::Math::PxPyPzMVector(t2.px(), t2.py(), t2.pz(), o2::constants::physics::MassK0Short); // Kshort - - // mother = daughter1 + daughter2; // invariant mass of Kshort pair - // isMix = true; - // fillInvMass(mother, multiplicity, daughter1, daughter2, isMix); - // } - // } - // } - } - PROCESS_SWITCH(HigherMassResonances, processMEderived, "mixed event process in derived data", true); - - array pvec0; - array pvec1; - // use any one of 3 alias depending on the dataset. If pp then FT0M and if pbpb then FTOC - using BinningTypeTPCMultiplicity = ColumnBinningPolicy; - using BinningTypeCentralityM = ColumnBinningPolicy; - using BinningTypeVertexContributor = ColumnBinningPolicy; - void processME(EventCandidates const& collisions, TrackCandidates const& /*tracks*/, V0TrackCandidate const& v0s) { auto tracksTuple = std::make_tuple(v0s); - BinningTypeVertexContributor binningOnPositions1{{mevz, memult}, true}; - BinningTypeCentralityM binningOnPositions2{{mevz, memult}, true}; + SameKindPair pair1{binningOnFT0M, config.cfgNmixedEvents, -1, collisions, tracksTuple, &cache}; + SameKindPair pair2{binningOnFT0A, config.cfgNmixedEvents, -1, collisions, tracksTuple, &cache}; + SameKindPair pair3{binningOnFT0C, config.cfgNmixedEvents, -1, collisions, tracksTuple, &cache}; + SameKindPair pair4{binningOnFV0A, config.cfgNmixedEvents, -1, collisions, tracksTuple, &cache}; - SameKindPair pair1{binningOnPositions1, config.cfgNmixedEvents, -1, collisions, tracksTuple, &cache}; // for PbPb - SameKindPair pair2{binningOnPositions2, config.cfgNmixedEvents, -1, collisions, tracksTuple, &cache}; // for pp + auto runMixing = [&](auto& pair, auto multiplicityGetter) { + for (const auto& [c1, tracks1, c2, tracks2] : pair) { - if (config.cfgMultFOTM) { - for (const auto& [c1, tracks1, c2, tracks2] : pair2) // two different centrality c1 and c2 and tracks corresponding to them - { - - multiplicity = 0.0; - multiplicity = c1.centFT0M(); + multiplicity = multiplicityGetter(c1); - if (!eventselection(c1) || !eventselection(c2)) { + if (!selectionEvent(c1, false) || !selectionEvent(c2, false)) { continue; } - // auto occupancyNumber = c1.trackOccupancyInTimeRange(); - // auto occupancyNumber2 = c2.trackOccupancyInTimeRange(); - // if (applyOccupancyCut && (occupancyNumber < occupancyCut || occupancyNumber2 < occupancyCut)) { - // return; - // } - - if (rctCut.requireRCTFlagChecker && !rctCut.rctChecker(c1)) { - return; - } - if (rctCut.requireRCTFlagChecker && !rctCut.rctChecker(c2)) { - return; - } for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { @@ -1223,66 +974,16 @@ struct HigherMassResonances { fillInvMass(mother, multiplicity, daughter1, daughter2, isMix); } } - } else { - for (const auto& [c1, tracks1, c2, tracks2] : pair1) // two different centrality c1 and c2 and tracks corresponding to them - { - multiplicity = 0.0f; - multiplicity = c1.centFT0C(); - - if (!eventselection(c1) || !eventselection(c2)) { - continue; - } - // auto occupancyNumber = c1.trackOccupancyInTimeRange(); - // auto occupancyNumber2 = c2.trackOccupancyInTimeRange(); - // if (applyOccupancyCut && (occupancyNumber < occupancyCut || occupancyNumber2 < occupancyCut)) { - // return; - // } - - for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { - if (t1.size() == 0 || t2.size() == 0) { - continue; - } - - if (!selectionV0(c1, t1, multiplicity)) - continue; - if (!selectionV0(c2, t2, multiplicity)) - continue; - - auto postrack1 = t1.template posTrack_as(); - auto negtrack1 = t1.template negTrack_as(); - auto postrack2 = t2.template posTrack_as(); - auto negtrack2 = t2.template negTrack_as(); - if (postrack1.globalIndex() == postrack2.globalIndex()) { - continue; - } - if (negtrack1.globalIndex() == negtrack2.globalIndex()) { - continue; - } - double nTPCSigmaPos1{postrack1.tpcNSigmaPi()}; - double nTPCSigmaNeg1{negtrack1.tpcNSigmaPi()}; - double nTPCSigmaPos2{postrack2.tpcNSigmaPi()}; - double nTPCSigmaNeg2{negtrack2.tpcNSigmaPi()}; - - if (!isSelectedV0Daughter(postrack1, 1, nTPCSigmaPos1, t1)) { - continue; - } - if (!isSelectedV0Daughter(postrack2, 1, nTPCSigmaPos2, t2)) { - continue; - } - if (!isSelectedV0Daughter(negtrack1, -1, nTPCSigmaNeg1, t1)) { - continue; - } - if (!isSelectedV0Daughter(negtrack2, -1, nTPCSigmaNeg2, t2)) { - continue; - } - daughter1 = ROOT::Math::PxPyPzMVector(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassK0Short); // Kshort - daughter2 = ROOT::Math::PxPyPzMVector(t2.px(), t2.py(), t2.pz(), o2::constants::physics::MassK0Short); // Kshort - - mother = daughter1 + daughter2; // invariant mass of Kshort pair - isMix = true; - fillInvMass(mother, multiplicity, daughter1, daughter2, isMix); - } - } + }; + // Call mixing based on selected estimator + if (config.cSelectMultEstimator == kFT0M) { + runMixing(pair1, [](const auto& c) { return c.centFT0M(); }); + } else if (config.cSelectMultEstimator == kFT0A) { + runMixing(pair2, [](const auto& c) { return c.centFT0A(); }); + } else if (config.cSelectMultEstimator == kFT0C) { + runMixing(pair3, [](const auto& c) { return c.centFT0C(); }); + } else if (config.cSelectMultEstimator == kFV0A) { + runMixing(pair4, [](const auto& c) { return c.centFV0A(); }); } } PROCESS_SWITCH(HigherMassResonances, processME, "mixed event process", true); @@ -1290,8 +991,8 @@ struct HigherMassResonances { int counter = 0; float multiplicityGen = 0.0; std::vector passKs; - ROOT::Math::PxPyPzMVector lResonance_gen1; - ROOT::Math::PxPyPzEVector lResonance_gen; + ROOT::Math::PxPyPzMVector lResonanceGen1; + ROOT::Math::PxPyPzEVector lResonanceGen; void processGen(aod::McCollision const& mcCollision, aod::McParticles const& mcParticles, const soa::SmallGroups& collisions) { @@ -1299,45 +1000,36 @@ struct HigherMassResonances { return; } hMChists.fill(HIST("events_check"), 0.5); - if (std::abs(mcCollision.posZ()) < config.cutzvertex) { - hMChists.fill(HIST("events_check"), 1.5); - } - // int Nchinel = 0; - // for (const auto& mcParticle : mcParticles) { - // auto pdgcode = std::abs(mcParticle.pdgCode()); - // if (mcParticle.isPhysicalPrimary() && (pdgcode == 211 || pdgcode == 321 || pdgcode == 2212 || pdgcode == 11 || pdgcode == 13)) { - // if (std::abs(mcParticle.eta()) < 1.0) { - // Nchinel = Nchinel + 1; - // } - // } - // } - // if (Nchinel > 0 && std::abs(mcCollision.posZ()) < config.cutzvertex) - hMChists.fill(HIST("events_check"), 2.5); std::vector selectedEvents(collisions.size()); int nevts = 0; - multiplicityGen = 0.0; + multiplicityGen = -999.0; for (const auto& collision : collisions) { - if (std::abs(collision.mcCollision().posZ()) > config.cutzvertex) { - continue; - } - if (config.timFrameEvsel && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { - continue; + // multiplicityGen = collision.centFT0M(); + if (config.cSelectMultEstimator == kFT0M) { + multiplicityGen = collision.centFT0M(); + } else if (config.cSelectMultEstimator == kFT0A) { + multiplicityGen = collision.centFT0A(); + } else if (config.cSelectMultEstimator == kFT0C) { + multiplicityGen = collision.centFT0C(); + } else if (config.cSelectMultEstimator == kFV0A) { + multiplicityGen = collision.centFV0A(); + } else { + multiplicityGen = collision.centFT0M(); // default } - if (config.cTVXEvsel && (!collision.selection_bit(aod::evsel::kIsTriggerTVX))) { + + if (!selectionEvent(collision, true)) { continue; } - multiplicityGen = collision.centFT0M(); - selectedEvents[nevts++] = collision.mcCollision_as().globalIndex(); } selectedEvents.resize(nevts); hMChists.fill(HIST("events_check"), 3.5); const auto evtReconstructedAndSelected = std::find(selectedEvents.begin(), selectedEvents.end(), mcCollision.globalIndex()) != selectedEvents.end(); - if (!config.allGenCollisions && !evtReconstructedAndSelected) { // Check that the event is reconstructed and that the reconstructed events pass the selection + if (!config.isallGenCollisions && !evtReconstructedAndSelected) { // Check that the event is reconstructed and that the reconstructed events pass the selection return; } hMChists.fill(HIST("events_check"), 4.5); @@ -1349,17 +1041,13 @@ struct HigherMassResonances { } hMChists.fill(HIST("events_check"), 5.5); - if (config.apply_rapidityMC && std::abs(mcParticle.y()) >= 0.5) { + if (config.isapplyRapidityMC && std::abs(mcParticle.y()) >= config.rapidityMotherData) { continue; } hMChists.fill(HIST("events_check"), 6.5); - // if (counter < 1e3) - // std::cout << "px " << mcParticle.px() << " py " << mcParticle.py() << " pz " << mcParticle.pz() << " y " << mcParticle.y() << std::endl; - // counter++; - auto kDaughters = mcParticle.daughters_as(); - if (kDaughters.size() != 2) { + if (kDaughters.size() != config.noOfDaughters) { continue; } hMChists.fill(HIST("events_check"), 7.5); @@ -1371,44 +1059,44 @@ struct HigherMassResonances { continue; } hMChists.fill(HIST("events_check"), 8.5); - if (std::abs(kCurrentDaughter.pdgCode()) == 310) { + if (std::abs(kCurrentDaughter.pdgCode()) == PDG_t::kK0Short) { passKs.push_back(true); hMChists.fill(HIST("events_check"), 9.5); if (passKs.size() == 1) { daughter1 = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), o2::constants::physics::MassK0Short); - } else if (passKs.size() == 2) { + } else if (static_cast(passKs.size()) == config.noOfDaughters) { daughter2 = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), o2::constants::physics::MassK0Short); } } } - if (passKs.size() == 2) { - lResonance_gen = ROOT::Math::PxPyPzEVector(mcParticle.pt(), mcParticle.eta(), mcParticle.phi(), mcParticle.e()); - lResonance_gen1 = daughter1 + daughter2; + if (static_cast(passKs.size()) == config.noOfDaughters) { + lResonanceGen = ROOT::Math::PxPyPzEVector(mcParticle.pt(), mcParticle.eta(), mcParticle.phi(), mcParticle.e()); + lResonanceGen1 = daughter1 + daughter2; - ROOT::Math::Boost boost{lResonance_gen.BoostToCM()}; - ROOT::Math::Boost boost1{lResonance_gen1.BoostToCM()}; + ROOT::Math::Boost boost{lResonanceGen.BoostToCM()}; + ROOT::Math::Boost boost1{lResonanceGen1.BoostToCM()}; fourVecDauCM = boost(daughter1); fourVecDauCM1 = boost1(daughter1); - auto helicity_gen = lResonance_gen.Vect().Dot(fourVecDauCM.Vect()) / (std::sqrt(fourVecDauCM.Vect().Mag2()) * std::sqrt(lResonance_gen.Vect().Mag2())); - auto helicity_gen1 = lResonance_gen1.Vect().Dot(fourVecDauCM1.Vect()) / (std::sqrt(fourVecDauCM1.Vect().Mag2()) * std::sqrt(lResonance_gen1.Vect().Mag2())); + auto helicityGen = lResonanceGen.Vect().Dot(fourVecDauCM.Vect()) / (std::sqrt(fourVecDauCM.Vect().Mag2()) * std::sqrt(lResonanceGen.Vect().Mag2())); + auto helicityGen1 = lResonanceGen1.Vect().Dot(fourVecDauCM1.Vect()) / (std::sqrt(fourVecDauCM1.Vect().Mag2()) * std::sqrt(lResonanceGen1.Vect().Mag2())); - hMChists.fill(HIST("Genf1710"), multiplicityGen, lResonance_gen.pt(), helicity_gen); - hMChists.fill(HIST("Genf1710_mass"), lResonance_gen.M()); + hMChists.fill(HIST("Genf1710"), multiplicityGen, lResonanceGen.pt(), helicityGen); + hMChists.fill(HIST("Genf1710_mass"), lResonanceGen.M()); hMChists.fill(HIST("GenRapidity"), mcParticle.y()); hMChists.fill(HIST("GenEta"), mcParticle.eta()); hMChists.fill(HIST("GenPhi"), mcParticle.phi()); - if (config.applyPairRapidityGen && std::abs(lResonance_gen1.Y()) >= 0.5) { + if (config.isapplyPairRapidityGen && std::abs(lResonanceGen1.Rapidity()) >= config.rapidityMotherData) { continue; } - hMChists.fill(HIST("Genf17102"), multiplicityGen, lResonance_gen1.pt(), helicity_gen1); - hMChists.fill(HIST("Genf1710_mass2"), lResonance_gen1.M()); - hMChists.fill(HIST("GenRapidity2"), lResonance_gen1.Y()); - hMChists.fill(HIST("GenEta2"), lResonance_gen1.Eta()); - hMChists.fill(HIST("GenPhi2"), lResonance_gen1.Phi()); + hMChists.fill(HIST("Genf17102"), multiplicityGen, lResonanceGen1.pt(), helicityGen1); + hMChists.fill(HIST("Genf1710_mass2"), lResonanceGen1.M()); + hMChists.fill(HIST("GenRapidity2"), lResonanceGen1.Rapidity()); + hMChists.fill(HIST("GenEta2"), lResonanceGen1.Eta()); + hMChists.fill(HIST("GenPhi2"), lResonanceGen1.Phi()); } passKs.clear(); // clear the vector for the next iteration } @@ -1423,42 +1111,35 @@ struct HigherMassResonances { return; } - auto multiplicity = collision.centFT0M(); - hMChists.fill(HIST("Rec_Multiplicity"), multiplicity); - - hMChists.fill(HIST("events_checkrec"), 0.5); - if (!collision.has_mcCollision()) { - return; + auto multiplicity = -999.0; + if (config.cSelectMultEstimator == kFT0M) { + multiplicity = collision.centFT0M(); + } else if (config.cSelectMultEstimator == kFT0A) { + multiplicity = collision.centFT0A(); + } else if (config.cSelectMultEstimator == kFT0C) { + multiplicity = collision.centFT0C(); + } else if (config.cSelectMultEstimator == kFV0A) { + multiplicity = collision.centFV0A(); + } else { + multiplicity = collision.centFT0M(); // default } - hMChists.fill(HIST("events_checkrec"), 1.5); - // // if (std::abs(collision.mcCollision().posZ()) > config.cutzvertex || !collision.sel8()) { - if (std::abs(collision.mcCollision().posZ()) > config.cutzvertex) { + + if (!selectionEvent(collision, false)) { return; } - hMChists.fill(HIST("events_checkrec"), 2.5); - - // if (config.timFrameEvsel && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { - // return; - // } - // hMChists.fill(HIST("events_checkrec"), 3.5); - // if (config.cTVXEvsel && (!collision.selection_bit(aod::evsel::kIsTriggerTVX))) { - // return; - // } + hMChists.fill(HIST("Rec_Multiplicity"), multiplicity); - if (!collision.sel8()) { + if (!collision.has_mcCollision()) { return; } - hMChists.fill(HIST("events_checkrec"), 4.5); + hMChists.fill(HIST("MC_mult_after_event_sel"), multiplicity); eventCounter++; - // auto oldindex = -999; for (const auto& v01 : V0s) { for (const auto& v02 : V0s) { - hMChists.fill(HIST("events_checkrec"), 5.5); - if (v02.index() <= v01.index()) { continue; } @@ -1466,7 +1147,7 @@ struct HigherMassResonances { if (!v01.has_mcParticle() || !v02.has_mcParticle()) { continue; } - hMChists.fill(HIST("events_checkrec"), 6.5); + hMChists.fill(HIST("events_checkrec"), 0.5); auto postrack1 = v01.template posTrack_as(); auto negtrack1 = v01.template negTrack_as(); @@ -1476,11 +1157,9 @@ struct HigherMassResonances { if (!postrack1.has_mcParticle() || !postrack2.has_mcParticle()) continue; // Checking that the daughter tracks come from particles and are not fake - hMChists.fill(HIST("events_checkrec"), 7.5); if (!negtrack1.has_mcParticle() || !negtrack2.has_mcParticle()) continue; - hMChists.fill(HIST("events_checkrec"), 8.5); double nTPCSigmaPos1[1]{postrack1.tpcNSigmaPi()}; double nTPCSigmaNeg1[1]{negtrack1.tpcNSigmaPi()}; @@ -1490,17 +1169,16 @@ struct HigherMassResonances { if (!isSelectedV0Daughter(postrack1, 1, nTPCSigmaPos1[0], v01) || !isSelectedV0Daughter(postrack2, 1, nTPCSigmaPos2[0], v02)) { continue; } - hMChists.fill(HIST("events_checkrec"), 9.5); if (!isSelectedV0Daughter(negtrack1, -1, nTPCSigmaNeg1[0], v01) || !isSelectedV0Daughter(negtrack2, -1, nTPCSigmaNeg2[0], v02)) { continue; } - hMChists.fill(HIST("events_checkrec"), 10.5); + hMChists.fill(HIST("events_checkrec"), 1.5); if (!selectionV0(collision, v01, multiplicity) || !selectionV0(collision, v02, multiplicity)) { continue; } - hMChists.fill(HIST("events_checkrec"), 11.5); + hMChists.fill(HIST("events_checkrec"), 2.5); auto mctrackv01 = v01.mcParticle(); auto mctrackv02 = v02.mcParticle(); @@ -1508,10 +1186,10 @@ struct HigherMassResonances { int trackv0PDG1 = std::abs(mctrackv01.pdgCode()); int trackv0PDG2 = std::abs(mctrackv02.pdgCode()); - if (std::abs(trackv0PDG1) != 310 || std::abs(trackv0PDG2) != 310) { + if (std::abs(trackv0PDG1) != PDG_t::kK0Short || std::abs(trackv0PDG2) != PDG_t::kK0Short) { continue; } - hMChists.fill(HIST("events_checkrec"), 12.5); + hMChists.fill(HIST("events_checkrec"), 3.5); for (const auto& mothertrack1 : mctrackv01.mothers_as()) { @@ -1525,17 +1203,15 @@ struct HigherMassResonances { for (const auto& mothertrack2 : mctrackv02.mothers_as()) { - hMChists.fill(HIST("events_checkrec"), 13.5); - if (mothertrack1.pdgCode() != config.pdgCodes[config.selectMCparticles]) { continue; } - hMChists.fill(HIST("events_checkrec"), 14.5); + hMChists.fill(HIST("events_checkrec"), 4.5); if (mothertrack1.pdgCode() != mothertrack2.pdgCode()) { continue; } - hMChists.fill(HIST("events_checkrec"), 15.5); + hMChists.fill(HIST("events_checkrec"), 5.5); gindex2.push_back(mothertrack2.globalIndex()); if (gindex2.size() > 1) { @@ -1543,24 +1219,24 @@ struct HigherMassResonances { continue; } } - hMChists.fill(HIST("events_checkrec"), 16.5); + hMChists.fill(HIST("events_checkrec"), 6.5); if (mothertrack1.globalIndex() != mothertrack2.globalIndex()) { continue; } - hMChists.fill(HIST("events_checkrec"), 17.5); + hMChists.fill(HIST("events_checkrec"), 7.5); if (!mothertrack1.producedByGenerator()) { continue; } - hMChists.fill(HIST("events_checkrec"), 18.5); + hMChists.fill(HIST("events_checkrec"), 8.5); - if (config.apply_rapidityMC && std::abs(mothertrack1.y()) >= 0.5) { + if (config.isapplyRapidityMC && std::abs(mothertrack1.y()) >= config.rapidityMotherData) { continue; } - hMChists.fill(HIST("events_checkrec"), 19.5); + hMChists.fill(HIST("events_checkrec"), 9.5); - // if (config.avoidsplitrackMC && oldindex == mothertrack1.globalIndex()) { + // if (config.isavoidsplitrackMC && oldindex == mothertrack1.globalIndex()) { // hMChists.fill(HIST("h1Recsplit"), mothertrack1.pt()); // continue; // } @@ -1578,21 +1254,21 @@ struct HigherMassResonances { fourVecDauCM = boost(daughter1); fourVecDauCM1 = boost1(daughter1); - auto helicity_rec = mother.Vect().Dot(fourVecDauCM.Vect()) / (std::sqrt(fourVecDauCM.Vect().Mag2()) * std::sqrt(mother.Vect().Mag2())); + auto helicityRec = mother.Vect().Dot(fourVecDauCM.Vect()) / (std::sqrt(fourVecDauCM.Vect().Mag2()) * std::sqrt(mother.Vect().Mag2())); - auto helicity_rec2 = mother1.Vect().Dot(fourVecDauCM1.Vect()) / (std::sqrt(fourVecDauCM1.Vect().Mag2()) * std::sqrt(mother1.Vect().Mag2())); + auto helicityRec2 = mother1.Vect().Dot(fourVecDauCM1.Vect()) / (std::sqrt(fourVecDauCM1.Vect().Mag2()) * std::sqrt(mother1.Vect().Mag2())); - hMChists.fill(HIST("Recf1710_pt1"), multiplicity, mothertrack1.pt(), mother1.M(), helicity_rec2); + hMChists.fill(HIST("Recf1710_pt1"), multiplicity, mothertrack1.pt(), mother1.M(), helicityRec2); hMChists.fill(HIST("RecRapidity"), mothertrack1.y()); hMChists.fill(HIST("RecPhi"), mothertrack1.phi()); hMChists.fill(HIST("RecEta"), mothertrack1.eta()); - if (config.applyPairRapidityRec && std::abs(mother.Y()) >= 0.5) { + if (config.isapplyPairRapidityRec && std::abs(mother.Rapidity()) >= config.rapidityMotherData) { continue; } - hMChists.fill(HIST("Recf1710_pt2"), multiplicity, mother.Pt(), mother.M(), helicity_rec); - hMChists.fill(HIST("RecRapidity2"), mother.Y()); + hMChists.fill(HIST("Recf1710_pt2"), multiplicity, mother.Pt(), mother.M(), helicityRec); + hMChists.fill(HIST("RecRapidity2"), mother.Rapidity()); hMChists.fill(HIST("RecPhi2"), mother.Phi()); hMChists.fill(HIST("RecEta2"), mother.Eta()); } @@ -1603,6 +1279,181 @@ struct HigherMassResonances { } } PROCESS_SWITCH(HigherMassResonances, processRec, "Process Reconstructed", false); + + void processSEderived(EventCandidatesDerivedData::iterator const& collision, TrackCandidates const& /*tracks*/, aod::V0Datas const& V0s) + { + if (config.cSelectMultEstimator == kFT0M) { + multiplicity = collision.centFT0M(); + } else if (config.cSelectMultEstimator == kFT0A) { + multiplicity = collision.centFT0A(); + } else if (config.cSelectMultEstimator == kFT0C) { + multiplicity = collision.centFT0C(); + } else if (config.cSelectMultEstimator == kFV0A) { + multiplicity = collision.centFV0A(); + } else { + multiplicity = collision.centFT0M(); // default + } + + if (!selectionEvent(collision, true)) { + return; + } + + if (config.qAevents) { + rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); + rEventSelection.fill(HIST("hmultiplicity"), multiplicity); + } + + std::vector v0indexes; + bool allConditionsMet = 0; + + for (const auto& [v1, v2] : combinations(CombinationsFullIndexPolicy(V0s, V0s))) { + + if (v1.size() == 0 || v2.size() == 0) { + continue; + } + + if (!selectionV0(collision, v1, multiplicity)) { + continue; + } + if (!selectionV0(collision, v2, multiplicity)) { + continue; + } + + auto postrack1 = v1.template posTrack_as(); + auto negtrack1 = v1.template negTrack_as(); + auto postrack2 = v2.template posTrack_as(); + auto negtrack2 = v2.template negTrack_as(); + + double nTPCSigmaPos1{postrack1.tpcNSigmaPi()}; + double nTPCSigmaNeg1{negtrack1.tpcNSigmaPi()}; + double nTPCSigmaPos2{postrack2.tpcNSigmaPi()}; + double nTPCSigmaNeg2{negtrack2.tpcNSigmaPi()}; + + if (!(isSelectedV0Daughter(negtrack1, -1, nTPCSigmaNeg1, v1) && isSelectedV0Daughter(postrack1, 1, nTPCSigmaPos1, v1))) { + continue; + } + if (!(isSelectedV0Daughter(postrack2, 1, nTPCSigmaPos2, v2) && isSelectedV0Daughter(negtrack2, -1, nTPCSigmaNeg2, v2))) { + continue; + } + + if (std::find(v0indexes.begin(), v0indexes.end(), v1.globalIndex()) == v0indexes.end()) { + v0indexes.push_back(v1.globalIndex()); + } + // if (!(std::find(v0indexes.begin(), v0indexes.end(), v2.globalIndex()) != v0indexes.end())) { + // v0indexes.push_back(v2.globalIndex()); + // } + + if (v2.globalIndex() <= v1.globalIndex()) { + continue; + } + + // if (config.qAv0Daughters) { + // rKzeroShort.fill(HIST("negative_pt"), negtrack1.pt()); + // rKzeroShort.fill(HIST("positive_pt"), postrack1.pt()); + // rKzeroShort.fill(HIST("negative_eta"), negtrack1.eta()); + // rKzeroShort.fill(HIST("positive_eta"), postrack1.eta()); + // rKzeroShort.fill(HIST("negative_phi"), negtrack1.phi()); + // rKzeroShort.fill(HIST("positive_phi"), postrack1.phi()); + // } + + if (postrack1.globalIndex() == postrack2.globalIndex()) { + continue; + } + if (negtrack1.globalIndex() == negtrack2.globalIndex()) { + continue; + } + + if (!applyAngSep(v1, v2)) { + continue; + } + + if (config.qAv0) { + rKzeroShort.fill(HIST("hMasscorrelationbefore"), v1.mK0Short(), v2.mK0Short()); + } + allConditionsMet = 1; + daughter1 = ROOT::Math::PxPyPzMVector(v1.px(), v1.py(), v1.pz(), o2::constants::physics::MassK0Short); // Kshort + daughter2 = ROOT::Math::PxPyPzMVector(v2.px(), v2.py(), v2.pz(), o2::constants::physics::MassK0Short); // Kshort + + mother = daughter1 + daughter2; // invariant mass of Kshort pair + isMix = false; + + if (!config.isselectTWOKsOnly) + fillInvMass(mother, multiplicity, daughter1, daughter2, isMix); + } + int sizeofv0indexes = v0indexes.size(); + rKzeroShort.fill(HIST("NksProduced"), sizeofv0indexes); + if (config.isselectTWOKsOnly && sizeofv0indexes == config.noOfDaughters && allConditionsMet) { + fillInvMass(mother, multiplicity, daughter1, daughter2, false); + } + v0indexes.clear(); + } + PROCESS_SWITCH(HigherMassResonances, processSEderived, "same event process in strangeness derived data", false); + + void processMEderived(EventCandidatesDerivedData const& collisions, TrackCandidates const& /*tracks*/, V0CandidatesDerivedData const& v0s) + { + + for (const auto& [c1, c2] : selfCombinations(colBinning, config.cfgNmixedEvents, -1, collisions, collisions)) // two different centrality c1 and c2 and tracks corresponding to them + { + + multiplicity = 0.0; + multiplicity = c1.centFT0M(); + + if (!selectionEvent(c1, false) || !selectionEvent(c2, false)) { + continue; + } + + auto groupV01 = v0s.sliceBy(tracksPerCollisionV0Mixed, c1.index()); + auto groupV02 = v0s.sliceBy(tracksPerCollisionV0Mixed, c2.index()); + for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(groupV01, groupV02))) { + + if (t1.size() == 0 || t2.size() == 0) { + continue; + } + + if (!selectionV0(c1, t1, multiplicity)) + continue; + if (!selectionV0(c2, t2, multiplicity)) + continue; + + auto postrack1 = t1.template posTrackExtra_as(); + auto negtrack1 = t1.template negTrackExtra_as(); + auto postrack2 = t2.template posTrackExtra_as(); + auto negtrack2 = t2.template negTrackExtra_as(); + + if (postrack1.globalIndex() == postrack2.globalIndex()) { + continue; + } + if (negtrack1.globalIndex() == negtrack2.globalIndex()) { + continue; + } + double nTPCSigmaPos1{postrack1.tpcNSigmaPi()}; + double nTPCSigmaNeg1{negtrack1.tpcNSigmaPi()}; + double nTPCSigmaPos2{postrack2.tpcNSigmaPi()}; + double nTPCSigmaNeg2{negtrack2.tpcNSigmaPi()}; + + if (!isSelectedV0Daughter(postrack1, 1, nTPCSigmaPos1, t1)) { + continue; + } + if (!isSelectedV0Daughter(postrack2, 1, nTPCSigmaPos2, t2)) { + continue; + } + if (!isSelectedV0Daughter(negtrack1, -1, nTPCSigmaNeg1, t1)) { + continue; + } + if (!isSelectedV0Daughter(negtrack2, -1, nTPCSigmaNeg2, t2)) { + continue; + } + + daughter1 = ROOT::Math::PxPyPzMVector(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassK0Short); // Kshort + daughter2 = ROOT::Math::PxPyPzMVector(t2.px(), t2.py(), t2.pz(), o2::constants::physics::MassK0Short); // Kshort + + mother = daughter1 + daughter2; // invariant mass of Kshort pair + isMix = true; + fillInvMass(mother, multiplicity, daughter1, daughter2, isMix); + } + } + } + PROCESS_SWITCH(HigherMassResonances, processMEderived, "mixed event process in derived data", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/Tasks/Resonances/initializereventqa.cxx b/PWGLF/Tasks/Resonances/initializereventqa.cxx new file mode 100644 index 00000000000..076163e6ef0 --- /dev/null +++ b/PWGLF/Tasks/Resonances/initializereventqa.cxx @@ -0,0 +1,473 @@ +// Copyright 2019-2025 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +/// \file initializereventqa.cxx +/// \brief QA for the event-loss and signal-loss correction at the generator level for the ResonanceInitializer in pp collisions (referred to TableProducer/Strangeness/cascqaanalysis.cxx) +/// +/// Following the discussions at the two PAG meetings (https://indico.cern.ch/event/1518979, https://indico.cern.ch/event/1575984) +/// we have introduced an auxiliary task that, when the resonanceInitializer.cxx is used, +/// computes the event-loss and signal-loss correction factors at the generator level. +/// With minor configuration tuning for a truth-tagging, +/// we expect it to be applicable to most analyses that rely on the initializer. +/// +/// \author Minjae Kim (minjae.kim@cern.ch) + +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/cascqaanalysis.h" +#include "PWGLF/DataModel/mcCentrality.h" +#include "PWGLF/Utils/inelGt.h" + +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "Framework/AnalysisTask.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" + +#include "TRandom2.h" +#include + +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +using TrkPidInfo = soa::Join; +using DauTracks = soa::Join; + +struct Initializereventqa { + + // Templates used, new hedder wil be added + Produces mycascades; + Produces myMCcascades; + + HistogramRegistry registry{"registry"}; + + // Axes + ConfigurableAxis ptAxis{"ptAxis", {400, 0.0f, 20.0f}, "#it{p}_{T} (GeV/#it{c})"}; + ConfigurableAxis rapidityAxis{"rapidityAxis", {200, -2.0f, 2.0f}, "y"}; + ConfigurableAxis centFT0MAxis{"centFT0MAxis", + {VARIABLE_WIDTH, 0.0, 1.0, 5.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0, 70.0, 100.0, 110.0}, + "FT0M (%)"}; + ConfigurableAxis eventTypeAxis{"eventTypeAxis", {2, -0.5f, 1.5f}, "Event Type"}; + + ConfigurableAxis nAssocCollAxis{"nAssocCollAxis", {5, -0.5f, 4.5f}, "N_{assoc.}"}; + ConfigurableAxis nChargedFT0MGenAxis{"nChargedFT0MGenAxis", {300, 0, 300}, "N_{FT0M, gen.}"}; + ConfigurableAxis multNTracksAxis{"multNTracksAxis", {500, 0, 500}, "N_{tracks}"}; + ConfigurableAxis signalFT0MAxis{"signalFT0MAxis", {4000, 0, 40000}, "FT0M amplitude"}; + ConfigurableAxis signalFV0AAxis{"signalFV0AAxis", {4000, 0, 40000}, "FV0A amplitude"}; + ConfigurableAxis nCandidates{"nCandidates", {30, -0.5, 29.5}, "N_{cand.}"}; + + // Event selection criteria + Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; + Configurable isZvtxcut{"isZvtxcut", 1, "Select collisions with Accepted z-vertex"}; + Configurable isVertexITSTPC{"isVertexITSTPC", 0, "Select collisions with at least one ITS-TPC track"}; + Configurable isNoSameBunchPileup{"isNoSameBunchPileup", 0, "Same found-by-T0 bunch crossing rejection"}; + Configurable isGoodZvtxFT0vsPV{"isGoodZvtxFT0vsPV", 0, "z of PV by tracks and z of PV from FT0 A-C time difference cut"}; + Configurable isVertexTOFmatched{"isVertexTOFmatched", 0, "Is Vertex TOF matched"}; + + Configurable isTriggerTVX{"isTriggerTVX", 1, "TVX trigger"}; + Configurable isNoTimeFrameBorder{"isNoTimeFrameBorder", 1, "TF border cut"}; + Configurable isNoITSROFrameBorder{"isNoITSROFrameBorder", 1, "ITS ROF border cut"}; + Configurable isNoCollInTimeRangeNarrow{"isNoCollInTimeRangeNarrow", 0, "No collisions in +-2us window"}; + + // QA histograms for the multiplicity estimation + Configurable multQA{"multQA", 1, "0 - not to do QA, 1 - do the QA"}; + + // Selection for signal-loss corrections + Configurable isDaughterCheck{"isDaughterCheck", 1, "Check if the candidate has the correct daughters when it is considered"}; + + Configurable cfgRapidityCut{"cfgRapidityCut", 0.5, "Rapidity cut for the truth particle"}; + + Configurable pdgTruthMother{"pdgTruthMother", 3324, "pdgcode for the truth mother particle, e.g. Xi(1530) (3324)"}; + Configurable pdgTruthDaughter1{"pdgTruthDaughter1", 3312, "pdgcode for the first daughter particle, e.g. Xi-3312"}; + Configurable pdgTruthDaughter2{"pdgTruthDaughter2", 211, "pdgcode for the second daughter particle, e.g. Xi-3312"}; + + // Necessary for particle charges + Service pdgDB; + + SliceCache cache; + + // Struct to select on event type + typedef struct CollisionIndexAndType { + int64_t index; + uint8_t typeFlag; + } CollisionIndexAndType; + + void init(InitContext const&) + { + TString hNEventsMCLabels[5] = {"All", "z vrtx", "INEL", "INEL>0", "Associated with rec. collision"}; + TString hNEventsLabels[12] = {"All", "kIsTriggerTVX", "kNoTimeFrameBorder", "kNoITSROFrameBorder", "kIsVertexITSTPC", "kNoSameBunchPileup", "kIsGoodZvtxFT0vsPV", "isVertexTOFmatched", "kNoCollInTimeRangeNarrow", "z vrtx", "INEL", "INEL>0"}; + + registry.add("hNEvents", "hNEvents", {HistType::kTH1D, {{12, 0.f, 12.f}}}); + + for (int n = 1; n <= registry.get(HIST("hNEvents"))->GetNbinsX(); n++) { + registry.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(n, hNEventsLabels[n - 1]); + } + registry.add("hZCollision", "hZCollision", {HistType::kTH1D, {{200, -20.f, 20.f}}}); + + registry.add("fakeEvents", "fakeEvents", {HistType::kTH1F, {{1, -0.5f, 0.5f}}}); + + registry.add("hNEventsMC", "hNEventsMC", {HistType::kTH1D, {{5, 0.0f, 5.0f}}}); + for (int n = 1; n <= registry.get(HIST("hNEventsMC"))->GetNbinsX(); n++) { + registry.get(HIST("hNEventsMC"))->GetXaxis()->SetBinLabel(n, hNEventsMCLabels[n - 1]); + } + registry.add("hZCollisionGen", "hZCollisionGen", {HistType::kTH1D, {{200, -20.f, 20.f}}}); + registry.add("hCentFT0MNAssocMCCollisions", "hCentFT0MNAssocMCCollisions", {HistType::kTH3D, {centFT0MAxis, nAssocCollAxis, eventTypeAxis}}); + registry.add("hCentFT0MNAssocMCCollisionsSameType", "hCentFT0MNAssocMCCollisionsSameType", {HistType::kTH3D, {centFT0MAxis, nAssocCollAxis, eventTypeAxis}}); + registry.add("hNchFT0MNAssocMCCollisions", "hNchFT0MNAssocMCCollisions", {HistType::kTH3D, {nChargedFT0MGenAxis, nAssocCollAxis, eventTypeAxis}}); + registry.add("hNchFT0MNAssocMCCollisionsSameType", "hNchFT0MNAssocMCCollisionsSameType", {HistType::kTH3D, {nChargedFT0MGenAxis, nAssocCollAxis, eventTypeAxis}}); + registry.add("hNContributorsCorrelation", "hNContributorsCorrelation", {HistType::kTH2F, {{250, -0.5f, 249.5f, "Secondary Contributor"}, {250, -0.5f, 249.5f, "Main Contributor"}}}); + registry.add("hNchFT0MGenEvType", "hNchFT0MGenEvType", {HistType::kTH2D, {nChargedFT0MGenAxis, eventTypeAxis}}); + registry.add("hCentFT0M_genMC", "hCentFT0M_genMC", {HistType::kTH2D, {centFT0MAxis, eventTypeAxis}}); + + registry.add("hCentFT0M_rec", "hCentFT0M_rec", {HistType::kTH2D, {centFT0MAxis, eventTypeAxis}}); + registry.add("hCentFT0M_corr", "hCentFT0M_Corr", {HistType::kTH2D, {centFT0MAxis, centFT0MAxis}}); + + if (multQA) { + registry.add("hNchFT0Mglobal", "hNchFT0Mglobal", {HistType::kTH3D, {nChargedFT0MGenAxis, multNTracksAxis, eventTypeAxis}}); + registry.add("hNchFT0MPVContr", "hNchFT0MPVContr", {HistType::kTH3D, {nChargedFT0MGenAxis, multNTracksAxis, eventTypeAxis}}); + registry.add("hFT0MpvContr", "hFT0MpvContr", {HistType::kTH3D, {centFT0MAxis, multNTracksAxis, eventTypeAxis}}); + registry.add("hFT0Mglobal", "hFT0Mglobal", {HistType::kTH3D, {centFT0MAxis, multNTracksAxis, eventTypeAxis}}); + registry.add("hFT0MsignalPVContr", "hFT0MsignalPVContr", {HistType::kTH3D, {signalFT0MAxis, multNTracksAxis, eventTypeAxis}}); + } + + registry.add("h3ResonanceTruth", "pT distribution of True Resonance", kTHnSparseF, {eventTypeAxis, ptAxis, centFT0MAxis}); + registry.add("h3ResonanceTruthAnti", "pT distribution of True Resonance Anti", kTHnSparseF, {eventTypeAxis, ptAxis, centFT0MAxis}); + } + float pvEta1 = 1.0f; + float globalEta05 = 0.5f; + + Partition pvContribTracksIUEta1 = (nabs(aod::track::eta) < pvEta1) && ((aod::track::flags & static_cast(o2::aod::track::PVContributor)) == static_cast(o2::aod::track::PVContributor)); + Partition globalTracksIUEta05 = (nabs(aod::track::eta) < globalEta05) && (requireGlobalTrackInFilter()); + + template + uint16_t getGenNchInFT0Mregion(TMcParticles particles) + { + float region1FT0 = -3.3f; + float region2FT0 = -2.1f; + float region3FT0 = 3.5f; + float region4FT0 = 4.9f; + // Particle counting in FITFT0: -3.3<η<-2.1; 3.5<η<4.9 + uint16_t nchFT0 = 0; + for (const auto& mcParticle : particles) { + if (!mcParticle.isPhysicalPrimary()) { + continue; + } + const auto& pdgInfo = pdgDB->GetParticle(mcParticle.pdgCode()); + if (!pdgInfo) { + continue; + } + if (pdgInfo->Charge() == 0) { + continue; + } + if (mcParticle.eta() < region1FT0 || mcParticle.eta() > region4FT0 || (mcParticle.eta() > region2FT0 && mcParticle.eta() < region3FT0)) { + continue; // select on T0M Nch region + } + nchFT0++; // increment + } + return nchFT0; + } + + template + bool acceptEvent(TCollision const& collision, bool isFillEventSelectionQA) + { + if (isFillEventSelectionQA) { + registry.fill(HIST("hNEvents"), 0.5); + } + + // kIsTriggerTVX selection + if (isTriggerTVX && !collision.selection_bit(aod::evsel::kIsTriggerTVX)) { + return false; + } + + if (isFillEventSelectionQA) { + registry.fill(HIST("hNEvents"), 1.5); + } + + // kNoTimeFrameBorder selection + if (isNoTimeFrameBorder && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { + return false; + } + + if (isFillEventSelectionQA) { + registry.fill(HIST("hNEvents"), 2.5); + } + + // kNoITSROFrameBorder selection + if (isNoITSROFrameBorder && !collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + return false; + } + + if (isFillEventSelectionQA) { + registry.fill(HIST("hNEvents"), 3.5); + } + + // kIsVertexITSTPC selection + if (isVertexITSTPC && !collision.selection_bit(aod::evsel::kIsVertexITSTPC)) { + return false; + } + if (isFillEventSelectionQA) { + registry.fill(HIST("hNEvents"), 4.5); + } + // kNoSameBunchPileup selection + if (isNoSameBunchPileup && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { + return false; + } + if (isFillEventSelectionQA) { + registry.fill(HIST("hNEvents"), 5.5); + } + // kIsGoodZvtxFT0vsPV selection + if (isGoodZvtxFT0vsPV && !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { + return false; + } + if (isFillEventSelectionQA) { + registry.fill(HIST("hNEvents"), 6.5); + } + // isVertexTOFmatched selection + if (isVertexTOFmatched && !collision.selection_bit(aod::evsel::kIsVertexTOFmatched)) { + return false; + } + if (isFillEventSelectionQA) { + registry.fill(HIST("hNEvents"), 7.5); + } + // kNoCollInTimeRangeNarrow selection + if (isNoCollInTimeRangeNarrow && !collision.selection_bit(aod::evsel::kNoCollInTimeRangeNarrow)) { + return false; + } + if (isFillEventSelectionQA) { + registry.fill(HIST("hNEvents"), 8.5); + } + + // Z vertex selection + if (isZvtxcut && std::fabs(collision.posZ()) > cutzvertex) { + return false; + } + if (isFillEventSelectionQA) { + registry.fill(HIST("hNEvents"), 9.5); + registry.fill(HIST("hZCollision"), collision.posZ()); + } + + return true; + } + + template + void fillMCParticles(TotalMCParts const& mcParticles, MultMCGen const& multiplicity, evtType const& eventType) + { + for (auto const& mcPart : mcParticles) { + + if (std::abs(mcPart.pdgCode()) != pdgTruthMother || std::abs(mcPart.y()) >= cfgRapidityCut) + continue; + std::vector daughterPDGs; + if (mcPart.has_daughters()) { + auto daughter01 = mcParticles.rawIteratorAt(mcPart.daughtersIds()[0] - mcParticles.offset()); + auto daughter02 = mcParticles.rawIteratorAt(mcPart.daughtersIds()[1] - mcParticles.offset()); + daughterPDGs = {daughter01.pdgCode(), daughter02.pdgCode()}; + } else { + daughterPDGs = {-1, -1}; + } + + if (isDaughterCheck) { + bool pass1 = std::abs(daughterPDGs[0]) == pdgTruthDaughter1 || std::abs(daughterPDGs[1]) == pdgTruthDaughter1; + bool pass2 = std::abs(daughterPDGs[0]) == pdgTruthDaughter2 || std::abs(daughterPDGs[1]) == pdgTruthDaughter2; + if (!pass1 || !pass2) + continue; + } + if (mcPart.pdgCode() > 0) // Consider INELt0 or INEL + registry.fill(HIST("h3ResonanceTruth"), eventType, mcPart.pt(), multiplicity); + else + registry.fill(HIST("h3ResonanceTruthAnti"), eventType, mcPart.pt(), multiplicity); + + daughterPDGs.clear(); + } + } + void processData(soa::Join::iterator const& collision, + DauTracks const&) + { + if (!acceptEvent(collision, 1)) { + return; + } + + int evType = 0; + registry.fill(HIST("hNEvents"), 10.5); // INEL + if (collision.isInelGt0()) { + evType += 1; + registry.fill(HIST("hNEvents"), 11.5); // INEL>0 + } + + auto tracksGroupedPVcontr = pvContribTracksIUEta1->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + int nTracksPVcontr = tracksGroupedPVcontr.size(); + + auto tracksGroupedGlobal = globalTracksIUEta05->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + int nTracksGlobal = tracksGroupedGlobal.size(); + + registry.fill(HIST("hCentFT0M_rec"), collision.centFT0M(), evType); + + if (multQA) { + registry.fill(HIST("hFT0MpvContr"), collision.centFT0M(), nTracksPVcontr, evType); + registry.fill(HIST("hFT0Mglobal"), collision.centFT0M(), nTracksGlobal, evType); + registry.fill(HIST("hFT0MsignalPVContr"), collision.multFT0A() + collision.multFT0C(), nTracksPVcontr, evType); + } + } + + Preslice perMcCollision = aod::mcparticle::mcCollisionId; + void processMCrec(soa::Join::iterator const& collision, + soa::Join const&, + DauTracks const&, + aod::McParticles const& mcParticles) + { + if (!acceptEvent(collision, 1)) { + return; + } + + if (!collision.has_mcCollision()) { + registry.fill(HIST("fakeEvents"), 0); // no assoc. MC collisions + return; + } + + const auto& mcCollision = collision.mcCollision_as>(); + + auto tracksGroupedPVcontr = pvContribTracksIUEta1->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + int nTracksPVcontr = tracksGroupedPVcontr.size(); + + auto tracksGroupedGlobal = globalTracksIUEta05->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + int nTracksGlobal = tracksGroupedGlobal.size(); + + // N charged in FT0M region in corresponding gen. MC collision + auto mcPartSlice = mcParticles.sliceBy(perMcCollision, collision.mcCollision_as>().globalIndex()); + uint16_t nchFT0 = getGenNchInFT0Mregion(mcPartSlice); + + int evType = 0; + registry.fill(HIST("hNEvents"), 10.5); // reco INEL + if (collision.isInelGt0()) { + evType += 1; + registry.fill(HIST("hNEvents"), 11.5); // reco INEL>0 + } + + registry.fill(HIST("hCentFT0M_rec"), mcCollision.centFT0M(), evType); // correction only reco level in this stage + registry.fill(HIST("hCentFT0M_corr"), mcCollision.centFT0M(), mcCollision.centFT0M(), evType); + + if (multQA) { + registry.fill(HIST("hNchFT0MPVContr"), nchFT0, nTracksPVcontr, evType); + registry.fill(HIST("hFT0MpvContr"), mcCollision.centFT0M(), nTracksPVcontr, evType); + registry.fill(HIST("hFT0Mglobal"), mcCollision.centFT0M(), nTracksGlobal, evType); + registry.fill(HIST("hNchFT0Mglobal"), nchFT0, nTracksGlobal, evType); + registry.fill(HIST("hFT0MsignalPVContr"), collision.multFT0A() + collision.multFT0C(), nTracksPVcontr, evType); + } + } + + void processMCgen(soa::Join::iterator const& mcCollision, + aod::McParticles const& mcParticles, + const soa::SmallGroups>& collisions) + { + auto cent = mcCollision.centFT0M(); + + registry.fill(HIST("hNEventsMC"), 0.5); + + if (isZvtxcut && std::fabs(mcCollision.posZ()) > cutzvertex) { + return; + } + registry.fill(HIST("hZCollisionGen"), mcCollision.posZ()); + registry.fill(HIST("hNEventsMC"), 1.5); + + int evType = 0; + registry.fill(HIST("hNEventsMC"), 2.5); + if (pwglf::isINELgtNmc(mcParticles, 0, pdgDB)) { // Truth INEL>0 + evType++; + registry.fill(HIST("hNEventsMC"), 3.5); + } + + fillMCParticles(mcParticles, cent, evType); + + registry.fill(HIST("hCentFT0M_genMC"), cent, evType); + + uint16_t nchFT0 = getGenNchInFT0Mregion(mcParticles); + registry.fill(HIST("hNchFT0MGenEvType"), nchFT0, evType); + + std::vector selectedEvents(collisions.size()); + std::vector numberOfContributors; + int nevts = 0; + int nAssocColl = 0; + const int nContSize = 2; + for (const auto& collision : collisions) { + CollisionIndexAndType collWithType = {0, 0x0}; + if (!acceptEvent(collision, 0)) { + continue; + } + collWithType.index = collision.mcCollision_as>().globalIndex(); + collWithType.typeFlag |= o2::aod::myMCcascades::EvFlags::EvINEL; + + if (collision.isInelGt0()) { // reco INEL>0 + collWithType.typeFlag |= o2::aod::myMCcascades::EvFlags::EvINELgt0; + } + selectedEvents[nevts++] = collWithType; + if (collision.mcCollision_as>().globalIndex() == mcCollision.globalIndex()) { + nAssocColl++; + numberOfContributors.push_back(collision.numContrib()); + } + } + selectedEvents.resize(nevts); + + registry.fill(HIST("hCentFT0MNAssocMCCollisions"), cent, nAssocColl, evType); + registry.fill(HIST("hNchFT0MNAssocMCCollisions"), nchFT0, nAssocColl, evType); + + if (numberOfContributors.size() == nContSize) { + std::sort(numberOfContributors.begin(), numberOfContributors.end()); + registry.fill(HIST("hNContributorsCorrelation"), numberOfContributors[0], numberOfContributors[1]); + } + + auto isAssocToINEL = [&mcCollision](CollisionIndexAndType i) { return (i.index == mcCollision.globalIndex()) && ((i.typeFlag & o2::aod::myMCcascades::EvFlags::EvINEL) == o2::aod::myMCcascades::EvFlags::EvINEL); }; + auto isAssocToINELgt0 = [&mcCollision](CollisionIndexAndType i) { return (i.index == mcCollision.globalIndex()) && ((i.typeFlag & o2::aod::myMCcascades::EvFlags::EvINELgt0) == o2::aod::myMCcascades::EvFlags::EvINELgt0); }; + // number of reconstructed INEL events that have the same global index as mcCollision + const auto evtReconstructedAndINEL = std::count_if(selectedEvents.begin(), selectedEvents.end(), isAssocToINEL); + // number of reconstructed INEL > 0 events that have the same global index as mcCollision + const auto evtReconstructedAndINELgt0 = std::count_if(selectedEvents.begin(), selectedEvents.end(), isAssocToINELgt0); + switch (evType) { + case 0: { + registry.fill(HIST("hCentFT0MNAssocMCCollisionsSameType"), cent, evtReconstructedAndINEL, evType); + registry.fill(HIST("hNchFT0MNAssocMCCollisionsSameType"), nchFT0, evtReconstructedAndINEL, evType); + break; + } + case 1: { + registry.fill(HIST("hCentFT0MNAssocMCCollisionsSameType"), cent, evtReconstructedAndINELgt0, evType); + registry.fill(HIST("hNchFT0MNAssocMCCollisionsSameType"), nchFT0, evtReconstructedAndINELgt0, evType); + break; + } + default: + LOGF(fatal, "incorrect evType in event task"); + break; + } + + if (evtReconstructedAndINELgt0) { // N INEL>0 reconstructed events associated with the MC collision + registry.fill(HIST("hNEventsMC"), 4.5); + } + } + PROCESS_SWITCH(Initializereventqa, processData, "Process Run 3 data", false); + PROCESS_SWITCH(Initializereventqa, processMCrec, "Process Run 3 mc, Reconstructed", true); + PROCESS_SWITCH(Initializereventqa, processMCgen, "Process Run 3 mc, genereated", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + }; +} diff --git a/PWGLF/Tasks/Resonances/kstarInOO.cxx b/PWGLF/Tasks/Resonances/kstarInOO.cxx index dc70ae02010..d17c9e87110 100644 --- a/PWGLF/Tasks/Resonances/kstarInOO.cxx +++ b/PWGLF/Tasks/Resonances/kstarInOO.cxx @@ -60,7 +60,7 @@ using namespace o2::framework::expressions; struct kstarInOO { SliceCache cache; Preslice perCollision = aod::track::collisionId; - HistogramRegistry OOhistos{"OOhistos", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; //================================== //|| @@ -69,109 +69,133 @@ struct kstarInOO { //================================== // Event Selection - Configurable cfg_Event_Selections{"cfg_Event_Selections", "sel8", "choose event selection"}; - Configurable cfg_Event_VtxCut{"cfg_Event_VtxCut", 10.0, "V_z cut selection"}; - - ConfigurableAxis cfg_CentAxis{"cfg_CentAxis", {VARIABLE_WIDTH, 0.0, 1.0, 5.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 110.0}, "Binning of the centrality axis"}; + Configurable cfgEventVtxCut{"cfgEventVtxCut", 10.0, "V_z cut selection"}; + ConfigurableAxis cfgCentAxis{"cfgCentAxis", {VARIABLE_WIDTH, 0.0, 1.0, 5.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 110.0}, "Binning of the centrality axis"}; // Track Selection // General - Configurable cfg_Track_Selections{"cfg_Track_Selections", "globalTracks", "set track selections"}; - Configurable cfg_Track_MinPt{"cfg_Track_MinPt", 0.15, "set track min pT"}; - Configurable cfg_Track_MaxEta{"cfg_Track_MaxEta", 0.9, "set track max Eta"}; - Configurable cfg_Track_MaxDCArToPVcut{"cfg_Track_MaxDCArToPVcut", 0.5, "Track DCAr cut to PV Maximum"}; - Configurable cfg_Track_MaxDCAzToPVcut{"cfg_Track_MaxDCAzToPVcut", 2.0, "Track DCAz cut to PV Maximum"}; - Configurable cfg_Track_PrimaryTrack{"cfg_Track_PrimaryTrack", true, "Primary track selection"}; // kGoldenChi2 | kDCAxy | kDCAz - Configurable cfg_Track_ConnectedToPV{"cfg_Track_ConnectedToPV", true, "PV contributor track selection"}; // PV Contriuibutor - Configurable cfg_Track_GlobalWoDCATrack{"cfg_Track_GlobalWoDCATrack", true, "Global track selection without DCA"}; // kQualityTracks (kTrackType | kTPCNCls | kTPCCrossedRows | kTPCCrossedRowsOverNCls | kTPCChi2NDF | kTPCRefit | kITSNCls | kITSChi2NDF | kITSRefit | kITSHits) | kInAcceptanceTracks (kPtRange | kEtaRange) + Configurable cfgTrackMinPt{"cfgTrackMinPt", 0.15, "set track min pT"}; + Configurable cfgTrackMaxEta{"cfgTrackMaxEta", 0.9, "set track max Eta"}; + Configurable cfgTrackMaxDCArToPVcut{"cfgTrackMaxDCArToPVcut", 0.5, "Track DCAr cut to PV Maximum"}; + Configurable cfgTrackMaxDCAzToPVcut{"cfgTrackMaxDCAzToPVcut", 2.0, "Track DCAz cut to PV Maximum"}; + Configurable cfgTrackPrimaryTrack{"cfgTrackPrimaryTrack", true, "Primary track selection"}; // kGoldenChi2 | kDCAxy | kDCAz + Configurable cfgTrackConnectedToPV{"cfgTrackConnectedToPV", true, "PV contributor track selection"}; // PV Contriuibutor + Configurable cfgGlobalTrack{"cfgGlobalTrack", false, "Global track selection"}; // kGoldenChi2 | kDCAxy | kDCAz + Configurable cfgTrackGlobalWoDCATrack{"cfgTrackGlobalWoDCATrack", true, "Global track selection without DCA"}; // kQualityTracks (kTrackType | kTPCNCls | kTPCCrossedRows | kTPCCrossedRowsOverNCls | kTPCChi2NDF | kTPCRefit | kITSNCls | kITSChi2NDF | kITSRefit | kITSHits) | kInAcceptanceTracks (kPtRange | kEtaRange) // TPC - Configurable cfg_Track_nFindableTPCClusters{"cfg_Track_FindableTPCClusters", 50, "nFindable TPC Clusters"}; - Configurable cfg_Track_nTPCCrossedRows{"cfg_Track_TPCCrossedRows", 70, "nCrossed TPC Rows"}; - Configurable cfg_Track_nRowsOverFindable{"cfg_Track_RowsOverFindable", 1.2, "nRowsOverFindable TPC CLusters"}; - Configurable cfg_Track_nTPCChi2{"cfg_Track_TPCChi2", 4.0, "nTPC Chi2 per Cluster"}; + Configurable cfgTracknFindableTPCClusters{"cfgTrackFindableTPCClusters", 50, "nFindable TPC Clusters"}; + Configurable cfgTracknTPCCrossedRows{"cfgTrackTPCCrossedRows", 70, "nCrossed TPC Rows"}; + Configurable cfgTracknRowsOverFindable{"cfgTrackRowsOverFindable", 1.2, "nRowsOverFindable TPC CLusters"}; + Configurable cfgTracknTPCChi2{"cfgTrackTPCChi2", 4.0, "nTPC Chi2 per Cluster"}; // ITS - Configurable cfg_Track_nITSChi2{"cfg_Track_ITSChi2", 36.0, "nITS Chi2 per Cluster"}; + Configurable cfgTracknITSChi2{"cfgTrackITSChi2", 36.0, "nITS Chi2 per Cluster"}; // PID - Configurable cfg_Track_TPCPID{"cfg_Track_TPCPID", true, "Enables TPC PID"}; - Configurable cfg_Track_TOFPID{"cfg_Track_TOFPID", true, "Enables TOF PID"}; - Configurable cfg_Track_TPCPID_nSig{"cfg_Track_TPCPID_nSig", 4.0, "nTPC PID sigma"}; - Configurable cfg_Track_TOFPID_nSig{"cfg_Track_TOFPID_nSig", 4.0, "nTOF PID sigma"}; + Configurable cfgTrackTPCPID{"cfgTrackTPCPID", true, "Enables TPC PID"}; + Configurable cfgTrackTOFPID{"cfgTrackTOFPID", true, "Enables TOF PID"}; + Configurable cfgTrackTPCPIDnSig{"cfgTrackTPCPIDnSig", 4.0, "nTPC PID sigma"}; + Configurable cfgTrackTOFPIDnSig{"cfgTrackTOFPIDnSig", 4.0, "nTOF PID sigma"}; Configurable cDebugLevel{"cDebugLevel", 0, "Resolution of Debug"}; // Mixing - ConfigurableAxis cfg_bins_MixMult{"cfg_bins_Cent", {VARIABLE_WIDTH, 0.0, 1.0, 5.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 110.0}, "Binning of the centrality axis"}; - ConfigurableAxis cfg_bins_MixVtx{"cfg_bins_MixVtx", {VARIABLE_WIDTH, -10.0f, -5.f, 0.f, 5.f, 10.f}, "Mixing bins - z-vertex"}; - Configurable cfg_Mix_NMixedEvents{"cfg_Mix_NMixedEvents", 10, "Number of mixed events per event"}; + ConfigurableAxis cfgBinsMixMult{"cfgBinsCent", {VARIABLE_WIDTH, 0.0, 1.0, 5.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 110.0}, "Binning of the centrality axis"}; + ConfigurableAxis cfgBinsMixVtx{"cfgBinsMixVtx", {VARIABLE_WIDTH, -10.0f, -5.f, 0.f, 5.f, 10.f}, "Mixing bins - z-vertex"}; + Configurable cfgMixNMixedEvents{"cfgMixNMixedEvents", 10, "Number of mixed events per event"}; + + // MCGen + Configurable cfgForceGenReco{"cfgForceGenReco", false, "Only consider events which are reconstructed (neglect event-loss)"}; + // Configurable cfgForceBR{"cfgForceBR", false, "Only consider K*0->K(pm)pi(mp)"}; + // Configurable cfgForceKaonAcceptence{"cfgForceKaonAcceptence", false, "Only consider K*0's whose daughters decay inside acceptence (no signal loss)"}; + // Configurable cfgForcePionAcceptence{"cfgForcePionAcceptence", false, "Only consider K*0's whose daughters decay inside acceptence (no signal loss)"}; // Pair - Configurable cfg_MinvNBins{"cfg_MinvNBins", 300, "Number of bins for Minv axis"}; - Configurable cfg_MinvMin{"cfg_MinvMin", 0.60, "Minimum Minv value"}; - Configurable cfg_MinvMax{"cfg_MinvMax", 1.20, "Maximum Minv value"}; + Configurable cfgMinvNBins{"cfgMinvNBins", 300, "Number of bins for Minv axis"}; + Configurable cfgMinvMin{"cfgMinvMin", 0.60, "Minimum Minv value"}; + Configurable cfgMinvMax{"cfgMinvMax", 1.20, "Maximum Minv value"}; // Histogram - Configurable cfg_Event_CutQA{"cfg_Event_CutsQA", false, "Enable Event QA Hists"}; - Configurable cfg_Track_CutQA{"cfg_Track_CutQA", false, "Enable Track QA Hists"}; - - // std::vector eventSelectionBits; + Configurable cfgEventCutQA{"cfgEventCutsQA", false, "Enable Event QA Hists"}; + Configurable cfgTrackCutQA{"cfgTrackCutQA", false, "Enable Track QA Hists"}; + Configurable cfgDataHistos{"cfgDataHistos", false, "Enable Data Hists"}; + Configurable cfgMcHistos{"cfgMcHistos", false, "Enable MC Hists"}; void init(o2::framework::InitContext&) { // HISTOGRAMS const AxisSpec axisEta{30, -1.5, +1.5, "#eta"}; const AxisSpec axisPhi{200, -1, +7, "#phi"}; - const AxisSpec PtAxis = {200, 0, 20.0}; - const AxisSpec PIDAxis = {120, -6, 6}; - const AxisSpec MinvAxis = {cfg_MinvNBins, cfg_MinvMin, cfg_MinvMax}; + const AxisSpec ptAxis = {200, 0, 20.0}; + const AxisSpec pidAxis = {120, -6, 6}; + const AxisSpec minvAxis = {cfgMinvNBins, cfgMinvMin, cfgMinvMax}; - if (cfg_Event_CutQA) { - OOhistos.add("hPosZ_BC", "PosZ_Bc", kTH1F, {{100, 0.0, 15.0}}); - OOhistos.add("hPosZ_AC", "PosZ_AC", kTH1F, {{100, 0.0, 15.0}}); + if (cfgEventCutQA) { + histos.add("hPosZ_BC", "hPosZ_Bc", kTH1F, {{100, 0.0, 15.0}}); + histos.add("hPosZ_AC", "hPosZ_AC", kTH1F, {{100, 0.0, 15.0}}); } - if (cfg_Track_CutQA) { - OOhistos.add("h_rawpT", "h_rawpT", kTH1F, {{1000, 0.0, 10.0}}); - OOhistos.add("h_rawpT_Kaon", "h_rawpT_Kaon", kTH1F, {{1000, 0.0, 10.0}}); - OOhistos.add("h_rawpT_Pion", "h_rawpT_Pion", kTH1F, {{1000, 0.0, 10.0}}); - OOhistos.add("h_eta", "h_eta", kTH1F, {axisEta}); - OOhistos.add("h_phi", "h_phi", kTH1F, {axisPhi}); - - OOhistos.add("QA_nSigma_pion_TPC", "QA_nSigma_pion_TPC", {HistType::kTH2F, {PtAxis, PIDAxis}}); - OOhistos.add("QA_nSigma_pion_TOF", "QA_nSigma_pion_TOF", {HistType::kTH2F, {PtAxis, PIDAxis}}); - OOhistos.add("QA_pion_TPC_TOF", "QA_pion_TPC_TOF", {HistType::kTH2F, {PIDAxis, PIDAxis}}); - OOhistos.add("QA_nSigma_kaon_TPC", "QA_nSigma_kaon_TPC", {HistType::kTH2F, {PtAxis, PIDAxis}}); - OOhistos.add("QA_nSigma_kaon_TOF", "QA_nSigma_kaon_TOF", {HistType::kTH2F, {PtAxis, PIDAxis}}); - OOhistos.add("QA_kaon_TPC_TOF", "QA_kaon_TPC_TOF", {HistType::kTH2F, {PIDAxis, PIDAxis}}); + if (cfgTrackCutQA) { + // histos.add("h_eta", "h_eta", kTH1F, {axisEta}); + // histos.add("h_phi", "h_phi", kTH1F, {axisPhi}); + + histos.add("QA_nSigma_pion_TPC_BC", "QA_nSigma_pion_TPC_BC", {HistType::kTH2F, {ptAxis, pidAxis}}); + histos.add("QA_nSigma_pion_TOF_BC", "QA_nSigma_pion_TOF_BC", {HistType::kTH2F, {ptAxis, pidAxis}}); + histos.add("QA_pion_TPC_TOF_BC", "QA_pion_TPC_TOF_BC", {HistType::kTH2F, {pidAxis, pidAxis}}); + + histos.add("QA_nSigma_pion_TPC_AC", "QA_nSigma_pion_TPC_AC", {HistType::kTH2F, {ptAxis, pidAxis}}); + histos.add("QA_nSigma_pion_TOF_AC", "QA_nSigma_pion_TOF_AC", {HistType::kTH2F, {ptAxis, pidAxis}}); + histos.add("QA_pion_TPC_TOF_AC", "QA_pion_TPC_TOF_AC", {HistType::kTH2F, {pidAxis, pidAxis}}); + + histos.add("QA_nSigma_kaon_TPC_BC", "QA_nSigma_kaon_TPC_BC", {HistType::kTH2F, {ptAxis, pidAxis}}); + histos.add("QA_nSigma_kaon_TOF_BC", "QA_nSigma_kaon_TOF_BC", {HistType::kTH2F, {ptAxis, pidAxis}}); + histos.add("QA_kaon_TPC_TOF_BC", "QA_kaon_TPC_TOF_BC", {HistType::kTH2F, {pidAxis, pidAxis}}); + + histos.add("QA_nSigma_kaon_TPC_AC", "QA_nSigma_kaon_TPC_AC", {HistType::kTH2F, {ptAxis, pidAxis}}); + histos.add("QA_nSigma_kaon_TOF_AC", "QA_nSigma_kaon_TOF_AC", {HistType::kTH2F, {ptAxis, pidAxis}}); + histos.add("QA_kaon_TPC_TOF_AC", "QA_kaon_TPC_TOF_AC", {HistType::kTH2F, {pidAxis, pidAxis}}); } - // MC histos - OOhistos.add("hMC_USS", "hMC_USS", kTHnSparseF, {cfg_CentAxis, PtAxis, MinvAxis}); - OOhistos.add("hMC_LSS", "hMC_LSS", kTHnSparseF, {cfg_CentAxis, PtAxis, MinvAxis}); - OOhistos.add("hMC_USS_Mix", "hMC_USS_Mix", kTHnSparseF, {cfg_CentAxis, PtAxis, MinvAxis}); - OOhistos.add("hMC_LSS_Mix", "hMC_LSS_Mix", kTHnSparseF, {cfg_CentAxis, PtAxis, MinvAxis}); + if (cfgDataHistos) { + histos.add("nEvents", "nEvents", kTH1F, {{4, 0.0, 4.0}}); + histos.add("nEvents_Mix", "nEvents_Mix", kTH1F, {{4, 0.0, 4.0}}); - // OOhistos.add("hMC_pt_Pion", "hMC_pt_Pion", kTH1F, {PtAxis}); - // OOhistos.add("hMC_pt_Kaon", "hMC_pt_Kaon", kTH1F, {PtAxis}); - // OOhistos.add("hMC_pt_Proton", "hMC_pt_Proton", kTH1F, {PtAxis}); + histos.add("hUSS", "hUSS", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); + histos.add("hLSS", "hLSS", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); + histos.add("hUSS_Mix", "hUSS_Mix", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); + histos.add("hLSS_Mix", "hLSS_Mix", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); + } - // Event Histograms - OOhistos.add("nEvents_MC", "nEvents_MC", kTH1F, {{4, 0.0, 4.0}}); - OOhistos.add("nEvents_MC_Mix", "nEvents_MC_Mix", kTH1F, {{4, 0.0, 4.0}}); + if (cfgMcHistos) { + histos.add("nEvents_MC", "nEvents_MC", kTH1F, {{4, 0.0, 4.0}}); + histos.add("nEvents_MC_Mix", "nEvents_MC_Mix", kTH1F, {{4, 0.0, 4.0}}); + histos.add("nEvents_MC_True", "nEvents_MC_True", kTH1F, {{4, 0.0, 4.0}}); + + histos.add("hMC_USS", "hMC_USS", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); + histos.add("hMC_LSS", "hMC_LSS", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); + histos.add("hMC_USS_Mix", "hMC_USS_Mix", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); + histos.add("hMC_LSS_Mix", "hMC_LSS_Mix", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); + histos.add("hMC_USS_True", "hMC_USS_True", kTHnSparseF, {cfgCentAxis, ptAxis, minvAxis}); + histos.add("hMC_kstar_True", "hMC_kstar_True", kTHnSparseF, {cfgCentAxis, ptAxis}); + } } // end of init using EventCandidates = soa::Join; //, aod::CentFT0Ms, aod::CentFT0As + using EventCandidatesTrue = aod::McCollisions; + using TrackCandidates = soa::Join; - using TrackCandidates_MC = soa::Join; + using TrackCandidatesMC = soa::Join; // For Mixed Event using BinningType = ColumnBinningPolicy; - Partition Kaon_MC = nabs(aod::pidtpc::tpcNSigmaKa) <= cfg_Track_TPCPID_nSig; - Partition Pion_MC = nabs(aod::pidtpc::tpcNSigmaPi) <= cfg_Track_TPCPID_nSig; + Partition kaon = !cfgTrackTPCPID || (nabs(aod::pidtpc::tpcNSigmaKa) <= cfgTrackTPCPIDnSig); + Partition pion = !cfgTrackTPCPID || (nabs(aod::pidtpc::tpcNSigmaPi) <= cfgTrackTPCPIDnSig); + + Partition kaonMC = !cfgTrackTPCPID || (nabs(aod::pidtpc::tpcNSigmaKa) <= cfgTrackTPCPIDnSig); + Partition pionMC = !cfgTrackTPCPID || (nabs(aod::pidtpc::tpcNSigmaPi) <= cfgTrackTPCPIDnSig); double massKa = o2::constants::physics::MassKPlus; double massPi = o2::constants::physics::MassPiMinus; @@ -184,9 +208,12 @@ struct kstarInOO { template bool eventSelection(const EventType event) { + if (cfgEventCutQA) + histos.fill(HIST("hPosZ_BC"), event.posZ()); + if (!event.sel8()) return false; - if (std::abs(event.posZ()) > cfg_Event_VtxCut) + if (std::abs(event.posZ()) > cfgEventVtxCut) return false; if (!event.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) return false; @@ -199,46 +226,52 @@ struct kstarInOO { if (!event.selection_bit(aod::evsel::kNoCollInTimeRangeStandard)) return false; + if (cfgEventCutQA) + histos.fill(HIST("hPosZ_AC"), event.posZ()); + return true; }; template bool trackSelection(const TracksType track) { - if (track.pt() < cfg_Track_MinPt) + if (track.pt() < cfgTrackMinPt) return false; - if (std::abs(track.eta()) > cfg_Track_MaxEta) + if (std::abs(track.eta()) > cfgTrackMaxEta) return false; - if (std::abs(track.dcaXY()) > cfg_Track_MaxDCArToPVcut) + if (cfgGlobalTrack && !track.isGlobalTrack()) return false; - if (std::abs(track.dcaZ()) > cfg_Track_MaxDCAzToPVcut) + if (std::abs(track.dcaXY()) > cfgTrackMaxDCArToPVcut) return false; - if (cfg_Track_PrimaryTrack && !track.isPrimaryTrack()) + if (std::abs(track.dcaZ()) > cfgTrackMaxDCAzToPVcut) return false; - if (cfg_Track_GlobalWoDCATrack && !track.isGlobalTrackWoDCA()) + if (cfgTrackPrimaryTrack && !track.isPrimaryTrack()) return false; - if (track.tpcNClsFindable() < cfg_Track_nFindableTPCClusters) + if (cfgTrackGlobalWoDCATrack && !track.isGlobalTrackWoDCA()) return false; - if (track.tpcNClsCrossedRows() < cfg_Track_nTPCCrossedRows) + if (track.tpcNClsFindable() < cfgTracknFindableTPCClusters) return false; - if (track.tpcCrossedRowsOverFindableCls() > cfg_Track_nRowsOverFindable) + if (track.tpcNClsCrossedRows() < cfgTracknTPCCrossedRows) return false; - if (track.tpcChi2NCl() > cfg_Track_nTPCChi2) + if (track.tpcCrossedRowsOverFindableCls() > cfgTracknRowsOverFindable) return false; - if (track.itsChi2NCl() > cfg_Track_nITSChi2) + if (track.tpcChi2NCl() > cfgTracknTPCChi2) return false; - if (cfg_Track_ConnectedToPV && !track.isPVContributor()) + if (track.itsChi2NCl() > cfgTracknITSChi2) + return false; + + if (cfgTrackConnectedToPV && !track.isPVContributor()) return false; return true; @@ -249,26 +282,32 @@ struct kstarInOO { { bool tpcPIDPassed{false}, tofPIDPassed{false}; // TPC - if (cfg_Track_CutQA) { - OOhistos.fill(HIST("QA_nSigma_kaon_TPC"), candidate.pt(), candidate.tpcNSigmaKa()); - OOhistos.fill(HIST("QA_nSigma_kaon_TOF"), candidate.pt(), candidate.tofNSigmaKa()); - OOhistos.fill(HIST("QA_kaon_TPC_TOF"), candidate.tpcNSigmaKa(), candidate.tofNSigmaKa()); + if (cfgTrackCutQA) { + histos.fill(HIST("QA_nSigma_kaon_TPC_BC"), candidate.pt(), candidate.tpcNSigmaKa()); + histos.fill(HIST("QA_nSigma_kaon_TOF_BC"), candidate.pt(), candidate.tofNSigmaKa()); + histos.fill(HIST("QA_kaon_TPC_TOF_BC"), candidate.tpcNSigmaKa(), candidate.tofNSigmaKa()); } - if (std::abs(candidate.tpcNSigmaKa()) < cfg_Track_TPCPID_nSig) + if (std::abs(candidate.tpcNSigmaKa()) < cfgTrackTPCPIDnSig) tpcPIDPassed = true; // TOF if (candidate.hasTOF()) { - if (std::abs(candidate.tofNSigmaKa()) < cfg_Track_TOFPID_nSig) - tofPIDPassed = true; - else + if (std::abs(candidate.tofNSigmaKa()) < cfgTrackTOFPIDnSig) { tofPIDPassed = true; + } + } else { + tofPIDPassed = true; } // TPC & TOF - if (tpcPIDPassed && tofPIDPassed) + if (tpcPIDPassed && tofPIDPassed) { + if (cfgTrackCutQA) { + histos.fill(HIST("QA_nSigma_kaon_TPC_AC"), candidate.pt(), candidate.tpcNSigmaKa()); + histos.fill(HIST("QA_nSigma_kaon_TOF_AC"), candidate.pt(), candidate.tofNSigmaKa()); + histos.fill(HIST("QA_kaon_TPC_TOF_AC"), candidate.tpcNSigmaKa(), candidate.tofNSigmaKa()); + } return true; - + } return false; } @@ -277,57 +316,150 @@ struct kstarInOO { { bool tpcPIDPassed{false}, tofPIDPassed{false}; // TPC - if (cfg_Track_CutQA) { - OOhistos.fill(HIST("QA_nSigma_pion_TPC"), candidate.pt(), candidate.tpcNSigmaPi()); - OOhistos.fill(HIST("QA_nSigma_pion_TOF"), candidate.pt(), candidate.tofNSigmaPi()); - OOhistos.fill(HIST("QA_pion_TPC_TOF"), candidate.tpcNSigmaPi(), candidate.tofNSigmaPi()); + if (cfgTrackCutQA) { + histos.fill(HIST("QA_nSigma_pion_TPC_BC"), candidate.pt(), candidate.tpcNSigmaPi()); + histos.fill(HIST("QA_nSigma_pion_TOF_BC"), candidate.pt(), candidate.tofNSigmaPi()); + histos.fill(HIST("QA_pion_TPC_TOF_BC"), candidate.tpcNSigmaPi(), candidate.tofNSigmaPi()); } - - if (std::abs(candidate.tpcNSigmaPi()) < cfg_Track_TPCPID_nSig) + if (std::abs(candidate.tpcNSigmaPi()) < cfgTrackTPCPIDnSig) tpcPIDPassed = true; if (candidate.hasTOF()) { - if (std::abs(candidate.tofNSigmaPi()) < cfg_Track_TOFPID_nSig) - tofPIDPassed = true; - else + if (std::abs(candidate.tofNSigmaPi()) < cfgTrackTOFPIDnSig) { tofPIDPassed = true; + } + } else { + tofPIDPassed = true; } // TPC & TOF - if (tpcPIDPassed && tofPIDPassed) + if (tpcPIDPassed && tofPIDPassed) { + if (cfgTrackCutQA) { + histos.fill(HIST("QA_nSigma_pion_TPC_AC"), candidate.pt(), candidate.tpcNSigmaPi()); + histos.fill(HIST("QA_nSigma_pion_TOF_AC"), candidate.pt(), candidate.tofNSigmaPi()); + histos.fill(HIST("QA_pion_TPC_TOF_AC"), candidate.tpcNSigmaPi(), candidate.tofNSigmaPi()); + } return true; - + } return false; } template - void TrackSlicing_MC(const CollisionType& collision1, const TracksType&, const CollisionType& collision2, const TracksType&, const bool IsMix) + void TrackSlicing(const CollisionType& collision1, const TracksType&, const CollisionType& collision2, const TracksType&, const bool IsMix) { - auto tracks1 = Kaon_MC->sliceByCached(aod::track::collisionId, collision1.globalIndex(), cache); - auto tracks2 = Pion_MC->sliceByCached(aod::track::collisionId, collision2.globalIndex(), cache); + auto tracks1 = kaon->sliceByCached(aod::track::collisionId, collision1.globalIndex(), cache); + auto tracks2 = pion->sliceByCached(aod::track::collisionId, collision2.globalIndex(), cache); auto centrality = collision1.centFT0C(); - for (auto& [trk1, trk2] : combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { + for (const auto& [trk1, trk2] : combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { + + if (!trackSelection(trk1) || !trackSelection(trk2)) + continue; + if (!trackPIDKaon(trk1) || !trackPIDPion(trk2)) + continue; + auto [KstarPt, Minv] = minvReconstruction(trk1, trk2); if (Minv < 0) continue; double conjugate = trk1.sign() * trk2.sign(); - if (!IsMix) { - if (conjugate < 0) { - OOhistos.fill(HIST("hMC_USS"), centrality, KstarPt, Minv); - } else if (conjugate > 0) { - OOhistos.fill(HIST("hMC_LSS"), centrality, KstarPt, Minv); + if (cfgDataHistos) { + if (!IsMix) { + if (conjugate < 0) { + histos.fill(HIST("hUSS"), centrality, KstarPt, Minv); + } else if (conjugate > 0) { + histos.fill(HIST("hLSS"), centrality, KstarPt, Minv); + } + } else { + if (conjugate < 0) { + histos.fill(HIST("hUSS_Mix"), centrality, KstarPt, Minv); + } else if (conjugate > 0) { + histos.fill(HIST("hLSS_Mix"), centrality, KstarPt, Minv); + } } - } else { - if (conjugate < 0) { - OOhistos.fill(HIST("hMC_USS_Mix"), centrality, KstarPt, Minv); - } else if (conjugate > 0) { - OOhistos.fill(HIST("hMC_LSS_Mix"), centrality, KstarPt, Minv); + } // cfgDataHistos + } // for + } // TrackSlicing + + template + void TrackSlicingMC(const CollisionType& collision1, const TracksType&, const CollisionType& collision2, const TracksType&, const bool IsMix) + { + auto tracks1 = kaonMC->sliceByCached(aod::track::collisionId, collision1.globalIndex(), cache); + auto tracks2 = pionMC->sliceByCached(aod::track::collisionId, collision2.globalIndex(), cache); + auto centrality = collision1.centFT0C(); + + for (const auto& [trk1, trk2] : combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { + + if (!trackSelection(trk1) || !trackSelection(trk2)) + continue; + if (!trackPIDKaon(trk1) || !trackPIDPion(trk2)) + continue; + + auto [KstarPt, Minv] = minvReconstruction(trk1, trk2); + if (Minv < 0) + continue; + + double conjugate = trk1.sign() * trk2.sign(); + if (cfgMcHistos) { + if (!IsMix) { + if (conjugate < 0) { + histos.fill(HIST("hMC_USS"), centrality, KstarPt, Minv); + } else if (conjugate > 0) { + histos.fill(HIST("hMC_LSS"), centrality, KstarPt, Minv); + } + } else { + if (conjugate < 0) { + histos.fill(HIST("hMC_USS_Mix"), centrality, KstarPt, Minv); + } else if (conjugate > 0) { + histos.fill(HIST("hMC_LSS_Mix"), centrality, KstarPt, Minv); + } } + } // cfgMcHistos + + //====================== + // Gen MC + if (!trk1.has_mcParticle() || !trk2.has_mcParticle()) + continue; + auto particle1 = trk1.mcParticle(); + auto particle2 = trk2.mcParticle(); + if (std::fabs(particle1.pdgCode()) != 321) + continue; // Not Kaon + if (std::fabs(particle2.pdgCode()) != 211) + continue; // Not Pion + + if (!particle1.has_mothers()) { + continue; + } + if (!particle2.has_mothers()) + continue; + + std::vector mothers1{}; + std::vector mothers1PDG{}; + for (auto& particle1_mom : particle1.template mothers_as()) { + mothers1.push_back(particle1_mom.globalIndex()); + mothers1PDG.push_back(particle1_mom.pdgCode()); } - } - } + + std::vector mothers2{}; + std::vector mothers2PDG{}; + for (auto& particle2_mom : particle2.template mothers_as()) { + mothers2.push_back(particle2_mom.globalIndex()); + mothers2PDG.push_back(particle2_mom.pdgCode()); + } + + if (mothers1PDG[0] != 313) + continue; // mother not K*0 + if (mothers2PDG[0] != 313) + continue; // mothers not K*0 + + if (mothers1[0] != mothers2[0]) + continue; // Kaon and pion not from the same K*0 + + if (cfgMcHistos) { + histos.fill(HIST("hMC_USS_True"), centrality, KstarPt, Minv); + } + } // for + } // TrackSlicingMC template std::pair minvReconstruction(const TracksType& trk1, const TracksType& trk2) @@ -336,50 +468,128 @@ struct kstarInOO { if (!trackSelection(trk1) || !trackSelection(trk2)) return {-1.0, -1.0}; + if (!trackPIDKaon(trk1) || !trackPIDPion(trk2)) return {-1.0, -1.0}; if (trk1.globalIndex() == trk2.globalIndex()) { - // std::cout<<"This happens"< cfg_Track_MaxEta) + if (std::abs(lResonance.Eta()) > cfgTrackMaxEta) return {-1.0, -1.0}; return {lResonance.Pt(), lResonance.M()}; } + //======================================================= + //| + //| DATA STUFF (SE) + //| + //======================================================= + + int nEvents = 0; + void processDataSameEvent(EventCandidates::iterator const& collision, TrackCandidates const& tracks) + { + if (cDebugLevel > 0) { + nEvents++; + if ((nEvents + 1) % 10000 == 0) { + std::cout << "Processed Data Events: " << nEvents << std::endl; + } + } + + auto goodEv = eventSelection(collision); + if (cfgDataHistos) { + histos.fill(HIST("nEvents"), 0.5); + } + if (!goodEv) + return; + + bool INELgt0 = false; + for (const auto& track : tracks) { + if (std::fabs(track.eta()) < cfgTrackMaxEta) { + INELgt0 = true; + break; + } + } + if (!INELgt0) + return; + if (cfgDataHistos) { + histos.fill(HIST("nEvents"), 1.5); + } + TrackSlicing(collision, tracks, collision, tracks, false); + + } // processSameEvents + PROCESS_SWITCH(kstarInOO, processDataSameEvent, "process Data Same Event", false); + + //======================================================= + //| + //| DATA STUFF (ME) + //| + //======================================================= + + int nEventsMix = 0; + void processDataMixedEvent(EventCandidates const& collisions, TrackCandidates const& tracks) + { + auto tracksTuple = std::make_tuple(tracks); + BinningType colBinning{{cfgBinsMixVtx, cfgBinsMixMult}, true}; // true is for 'ignore overflows' (true by default) + SameKindPair pairs{colBinning, cfgMixNMixedEvents, -1, collisions, tracksTuple, &cache}; + for (const auto& [collision1, tracks1, collision2, tracks2] : pairs) { + if (cDebugLevel > 0) { + nEventsMix++; + if ((nEventsMix + 1) % 10000 == 0) { + std::cout << "Processed DATA Mixed Events : " << nEventsMix << std::endl; + } + } + auto goodEv1 = eventSelection(collision1); + auto goodEv2 = eventSelection(collision2); + if (cfgDataHistos) { + histos.fill(HIST("nEvents_Mix"), 0.5); + } + + if (!goodEv1 || !goodEv2) + continue; + + if (cfgDataHistos) { + histos.fill(HIST("nEvents_Mix"), 1.5); + } + TrackSlicing(collision1, tracks1, collision2, tracks2, true); + } + } + PROCESS_SWITCH(kstarInOO, processDataMixedEvent, "process DATA Mixed Event", false); + //======================================================= //| //| MC STUFF (SE) //| //======================================================= - int nEvents_MC = 0; - void processSameEvent_MC(EventCandidates::iterator const& collision, TrackCandidates_MC const& tracks, aod::McParticles const&) + int nEventsMC = 0; + void processMCSameEvent(EventCandidates::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const&) { if (cDebugLevel > 0) { - nEvents_MC++; - if ((nEvents_MC + 1) % 10000 == 0) { - double histmem = OOhistos.getSize(); + nEventsMC++; + if ((nEventsMC + 1) % 10000 == 0) { + double histmem = histos.getSize(); std::cout << histmem << std::endl; - std::cout << "process_SameEvent_MC: " << nEvents_MC << std::endl; + std::cout << "process MC Same Event : " << nEventsMC << std::endl; } } auto goodEv = eventSelection(collision); - OOhistos.fill(HIST("nEvents_MC"), 0.5); + if (cfgMcHistos) { + histos.fill(HIST("nEvents_MC"), 0.5); + } if (!goodEv) return; bool INELgt0 = false; for (const auto& track : tracks) { - if (std::fabs(track.eta()) < cfg_Track_MaxEta) { + if (std::fabs(track.eta()) < cfgTrackMaxEta) { INELgt0 = true; break; } @@ -387,11 +597,13 @@ struct kstarInOO { if (!INELgt0) return; - OOhistos.fill(HIST("nEvents_MC"), 1.5); - TrackSlicing_MC(collision, tracks, collision, tracks, false); + if (cfgMcHistos) { + histos.fill(HIST("nEvents_MC"), 1.5); + } + TrackSlicingMC(collision, tracks, collision, tracks, false); } // processSameEvents_MC - PROCESS_SWITCH(kstarInOO, processSameEvent_MC, "process Same Event MC", true); + PROCESS_SWITCH(kstarInOO, processMCSameEvent, "process MC Same Event", false); //======================================================= //| @@ -399,32 +611,87 @@ struct kstarInOO { //| //======================================================= - int nEvents_MC_Mix = 0; - void processMixedEvent_MC(EventCandidates const& collisions, TrackCandidates_MC const& tracks, aod::McParticles const&) + int nEventsMCMix = 0; + void processMCMixedEvent(EventCandidates const& collisions, TrackCandidatesMC const& tracks, aod::McParticles const&) { auto tracksTuple = std::make_tuple(tracks); - BinningType colBinning{{cfg_bins_MixVtx, cfg_bins_MixMult}, true}; // true is for 'ignore overflows' (true by default) - SameKindPair pairs{colBinning, cfg_Mix_NMixedEvents, -1, collisions, tracksTuple, &cache}; + BinningType colBinning{{cfgBinsMixVtx, cfgBinsMixMult}, true}; // true is for 'ignore overflows' (true by default) + SameKindPair pairs{colBinning, cfgMixNMixedEvents, -1, collisions, tracksTuple, &cache}; for (const auto& [collision1, tracks1, collision2, tracks2] : pairs) { if (cDebugLevel > 0) { - nEvents_MC_Mix++; - if ((nEvents_MC_Mix + 1) % 10000 == 0) { - std::cout << "Processed Mixed Events: " << nEvents_MC_Mix << std::endl; + nEventsMCMix++; + if ((nEventsMCMix + 1) % 10000 == 0) { + std::cout << "Processed MC Mixed Events : " << nEventsMCMix << std::endl; } } auto goodEv1 = eventSelection(collision1); auto goodEv2 = eventSelection(collision2); - OOhistos.fill(HIST("nEvents_MC_Mix"), 0.5); + if (cfgMcHistos) { + histos.fill(HIST("nEvents_MC_Mix"), 0.5); + } if (!goodEv1 || !goodEv2) continue; - OOhistos.fill(HIST("nEvents_MC_Mix"), 1.5); - - TrackSlicing_MC(collision1, tracks1, collision2, tracks2, true); + if (cfgMcHistos) { + histos.fill(HIST("nEvents_MC_Mix"), 1.5); + } + TrackSlicingMC(collision1, tracks1, collision2, tracks2, true); } // mixing } // processMixedEvent_MC - PROCESS_SWITCH(kstarInOO, processMixedEvent_MC, "process Mixed Event MC", false); + PROCESS_SWITCH(kstarInOO, processMCMixedEvent, "process MC Mixed Event", false); + + //======================================================= + //| + //| GENERATED MC STUFF (TRUE) + //| + //======================================================= + + int nEventsTrue = 0; + void processMCTrue(EventCandidatesTrue::iterator const& collision, soa::SmallGroups> const& recocolls, aod::McParticles const& particles) + { + if (cDebugLevel > 0) { + ++nEventsTrue; + if ((nEventsTrue & 10000) == 0) { + std::cout << "Processed MC True Events : " << nEventsTrue << std::endl; + } + } + + if (fabs(collision.posZ()) > cfgEventVtxCut) + return; + + if (recocolls.size() <= 0) { // not reconstructed + if (cfgForceGenReco) { + return; + } + } + + double centrality = -1; + for (auto& recocoll : recocolls) { + centrality = recocoll.centFT0C(); + auto goodEv = eventSelection(recocoll); + + if (cfgMcHistos) { + histos.fill(HIST("nEvents_MC_True"), 0.5); + } + if (!goodEv) + continue; + } // for + + for (auto& particle : particles) { + if (particle.pdgCode() != 313) + continue; // Not K*0 + if (std::fabs(particle.eta()) > cfgTrackMaxEta) + continue; + + if (cfgMcHistos) { + histos.fill(HIST("hMC_kstar_True"), centrality, particle.pt()); + } + + } // loop over particles + + } // processMCTrue + PROCESS_SWITCH(kstarInOO, processMCTrue, "process MC True", false); void processEventsDummy(EventCandidates::iterator const&, TrackCandidates const&) { diff --git a/PWGLF/Tasks/Resonances/kstarqa.cxx b/PWGLF/Tasks/Resonances/kstarqa.cxx index 078fc6916bf..b4a6e3a2ee4 100644 --- a/PWGLF/Tasks/Resonances/kstarqa.cxx +++ b/PWGLF/Tasks/Resonances/kstarqa.cxx @@ -16,6 +16,8 @@ // #include #include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/mcCentrality.h" +#include "PWGLF/Utils/inelGt.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/trackUtilities.h" @@ -82,6 +84,7 @@ struct Kstarqa { Configurable isAllLayersGoodITS{"isAllLayersGoodITS", true, "Require all ITS layers to be good"}; Configurable isNoTimeFrameBorder{"isNoTimeFrameBorder", true, "kNoTimeFrameBorder"}; Configurable isNoITSROFrameBorder{"isNoITSROFrameBorder", true, "kNoITSROFrameBorder"}; + Configurable isApplyParticleMID{"isApplyParticleMID", true, "Apply particle misidentification"}; Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; Configurable configOccCut{"configOccCut", 1000., "Occupancy cut"}; @@ -93,17 +96,72 @@ struct Kstarqa { Configurable rotationalCut{"rotationalCut", 10, "Cut value (Rotation angle pi - pi/cut and pi + pi/cut)"}; Configurable cfgCutPT{"cfgCutPT", 0.2f, "PT cut on daughter track"}; - Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta cut on daughter track"}; - Configurable cfgCutDCAxy{"cfgCutDCAxy", 2.0f, "DCAxy range for tracks"}; + Configurable cfgCutEtaMax{"cfgCutEtaMax", 0.8f, "Eta cut on daughter track"}; + // Configurable cfgCutEtaMin{"cfgCutEtaMin", 0.0f, "Eta cut on daughter track"}; + Configurable cfgCutDCAxyMax{"cfgCutDCAxyMax", 2.0f, "DCAxy range for tracks"}; + // Configurable cfgCutDCAxyMin{"cfgCutDCAxyMin", 0.0f, "DCAxy range for tracks"}; Configurable cfgCutDCAz{"cfgCutDCAz", 2.0f, "DCAz range for tracks"}; + Configurable ctrackRapidity{"ctrackRapidity", 0.3f, "Cut on track rapidity"}; Configurable cfgNoMixedEvents{"cfgNoMixedEvents", 5, "Number of mixed events per event"}; Configurable cfgITScluster{"cfgITScluster", 0, "Number of ITS cluster"}; Configurable cfgTPCcluster{"cfgTPCcluster", 70, "Number of TPC cluster"}; Configurable cfgRCRFC{"cfgRCRFC", 0.8f, "Crossed Rows to Findable Clusters"}; Configurable cfgITSChi2NCl{"cfgITSChi2NCl", 36.0, "ITS Chi2/NCl"}; - Configurable cfgTPCChi2NCl{"cfgTPCChi2NCl", 4.0, "TPC Chi2/NCl"}; + Configurable cfgTPCChi2NClMax{"cfgTPCChi2NClMax", 4.0, "TPC Chi2/NCl"}; + Configurable cfgTPCChi2NClMin{"cfgTPCChi2NClMin", 0.0, "TPC Chi2/NCl"}; + Configurable cfgUseITSTPCRefit{"cfgUseITSTPCRefit", false, "Require ITS Refit"}; + Configurable isVertexITSTPC{"isVertexITSTPC", false, "Vertex ITS TPC"}; + Configurable isVertexTOFMatched{"isVertexTOFMatched", false, "Vertex TOF Matched"}; + Configurable isNoCollInTimeRangeStandard{"isNoCollInTimeRangeStandard", false, "No collision in time range standard"}; + Configurable isApplyPtDepDCAxyCut{"isApplyPtDepDCAxyCut", false, "Apply pT dependent DCAxy cut"}; + Configurable isGoldenChi2{"isGoldenChi2", false, "Apply golden chi2 cut"}; + + // cuts on mother + Configurable isApplyCutsOnMother{"isApplyCutsOnMother", false, "Enable additional cuts on Kstar mother"}; + Configurable cMaxPtMotherCut{"cMaxPtMotherCut", 15.0, "Maximum pt of mother cut"}; + Configurable cMaxMinvMotherCut{"cMaxMinvMotherCut", 1.5, "Maximum mass of mother cut"}; + Configurable rapidityMotherData{"rapidityMotherData", 0.5, "Maximum rapidity of mother"}; + Configurable isPDGCheckMC{"isPDGCheckMC", true, "Check PDG code in MC (false for MC closure test)"}; + + // PID selections + Configurable nsigmaCutTPCPi{"nsigmaCutTPCPi", 3.0, "TPC Nsigma cut for pions"}; + Configurable nsigmaCutTPCKa{"nsigmaCutTPCKa", 3.0, "TPC Nsigma cut for kaons"}; + Configurable nsigmaCutTOFPi{"nsigmaCutTOFPi", 3.0, "TOF Nsigma cut for pions"}; + Configurable nsigmaCutTOFKa{"nsigmaCutTOFKa", 3.0, "TOF Nsigma cut for kaons"}; + Configurable nsigmaCutTPCPr{"nsigmaCutTPCPr", 3.0, "TPC Nsigma cut for protons (for MID)"}; + Configurable nsigmaCutTOFPr{"nsigmaCutTOFPr", 3.0, "TOF Nsigma cut for protons (for MID)"}; + Configurable nsigmaCutCombinedKa{"nsigmaCutCombinedKa", 3.0, "Combined Nsigma cut for kaon"}; + Configurable nsigmaCutCombinedPi{"nsigmaCutCombinedPi", 3.0, "Combined Nsigma cut for pion"}; + Configurable nsigmaCutCombinedMIDKa{"nsigmaCutCombinedMIDKa", 3.0, "Combined Nsigma cut for kaon in MID"}; + Configurable nsigmaCutCombinedMIDPi{"nsigmaCutCombinedMIDPi", 3.0, "Combined Nsigma cut for pion in MID"}; + Configurable nsigmaCutTPCMIDPi{"nsigmaCutTPCMIDPi", 1.0, "MID Nsigma cut for pion in TPC"}; + Configurable nsigmaCutTPCMIDKa{"nsigmaCutTPCMIDKa", 1.0, "MID Nsigma cut for kaon in TPC"}; + Configurable nsigmaCutTOFMIDPi{"nsigmaCutTOFMIDPi", 1.0, "MID Nsigma cut for pion in TOF"}; + Configurable nsigmaCutTOFMIDKa{"nsigmaCutTOFMIDKa", 1.0, "MID Nsigma cut for kaon in TOF"}; + + // Other fixed variables + float lowPtCutPID = 0.5; + int noOfDaughters = 2; + // float rapidityMotherData = 0.5; + } selectionConfig; + enum MultEstimator { + kFT0M, + kFT0A, + kFT0C, + kFV0A, + kFV0C, + kFV0M, + kNEstimators // useful if you want to iterate or size things + }; + + enum PIDParticle { + kPion, + kKaon, + kProton + }; + // Histograms are defined with HistogramRegistry HistogramRegistry rEventSelection{"eventSelection", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; HistogramRegistry hInvMass{"hInvMass", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; @@ -119,7 +177,7 @@ struct Kstarqa { Configurable onlyTOFHIT{"onlyTOFHIT", false, "accept only TOF hit tracks at high pt"}; Configurable onlyTPC{"onlyTPC", true, "only TPC tracks"}; Configurable cRotations{"cRotations", 3, "Number of random rotations in the rotational background"}; - Configurable cSelectMultEstimator{"cSelectMultEstimator", 0, "Select multiplicity estimator: 0 - FT0M, 1 - FT0A, 2 - FT0C"}; + Configurable cSelectMultEstimator{"cSelectMultEstimator", 0, "Select multiplicity estimator: 0 - FT0M, 1 - FT0A, 2 - FT0C, 3 - FV0A"}; Configurable applyRecMotherRapidity{"applyRecMotherRapidity", true, "Apply rapidity cut on reconstructed mother track"}; Configurable applypTdepPID{"applypTdepPID", false, "Apply pT dependent PID"}; @@ -129,14 +187,6 @@ struct Kstarqa { Configurable cFakeTrackCutKa{"cFakeTrackCutKa", 0.5, "Cut based on momentum difference in global and TPC tracks for Kaons"}; Configurable cFakeTrackCutPi{"cFakeTrackCutPi", 0.5, "Cut based on momentum difference in global and TPC tracks for Pions"}; - // PID selections - Configurable nsigmaCutTPCPi{"nsigmaCutTPCPi", 3.0, "TPC Nsigma cut for pions"}; - Configurable nsigmaCutTPCKa{"nsigmaCutTPCKa", 3.0, "TPC Nsigma cut for kaons"}; - Configurable nsigmaCutTOFPi{"nsigmaCutTOFPi", 3.0, "TOF Nsigma cut for pions"}; - Configurable nsigmaCutTOFKa{"nsigmaCutTOFKa", 3.0, "TOF Nsigma cut for kaons"}; - Configurable nsigmaCutCombinedKa{"nsigmaCutCombinedKa", 3.0, "Combined Nsigma cut for kaon"}; - Configurable nsigmaCutCombinedPi{"nsigmaCutCombinedPi", 3.0, "Combined Nsigma cut for pion"}; - // Configurable for histograms Configurable avoidsplitrackMC{"avoidsplitrackMC", true, "avoid split track in MC"}; Configurable cAllGenCollisions{"cAllGenCollisions", false, "To fill all generated collisions for the signal loss calculations"}; @@ -147,6 +197,7 @@ struct Kstarqa { ConfigurableAxis configThnAxisPOL{"configThnAxisPOL", {20, -1.0, 1.0}, "Costheta axis"}; ConfigurableAxis invMassKstarAxis{"invMassKstarAxis", {300, 0.7f, 1.3f}, "Kstar invariant mass axis"}; ConfigurableAxis ptAxisKstar{"ptAxisKstar", {200, 0.0f, 20.0f}, "Kstar pT axis"}; + ConfigurableAxis binsImpactPar{"binsImpactPar", {100, 0, 25}, "Binning of the impact parameter axis"}; // Event plane configurables Configurable boostDaugter1{"boostDaugter1", false, "Boost daughter Kaon in the COM frame"}; @@ -167,14 +218,15 @@ struct Kstarqa { AxisSpec invmassAxis = {invMassKstarAxis, "Invariant mass (GeV/#it{c}^{2})"}; AxisSpec thnAxisPOL{configThnAxisPOL, "cos(#theta)"}; AxisSpec multiplicityAxis = {binsMultPlot, "Multiplicity Axis"}; + AxisSpec impactParAxis = {binsImpactPar, "Impact Parameter (cm)"}; // Histograms // Event selection rEventSelection.add("hVertexZRec", "hVertexZRec", {HistType::kTH1F, {vertexZAxis}}); rEventSelection.add("hMultiplicity", "Multiplicity percentile", kTH1F, {{110, 0, 110}}); - rEventSelection.add("hEventCutFlow", "No. of event after cuts", kTH1I, {{20, 0, 20}}); - std::shared_ptr hCutFlow = rEventSelection.get(HIST("hEventCutFlow")); + rEventSelection.add("hEventCut", "No. of event after cuts", kTH1I, {{20, 0, 20}}); + std::shared_ptr hCutFlow = rEventSelection.get(HIST("hEventCut")); hCutFlow->GetXaxis()->SetBinLabel(1, "All Events"); hCutFlow->GetXaxis()->SetBinLabel(2, "|Vz| < cut"); hCutFlow->GetXaxis()->SetBinLabel(3, "sel8"); @@ -186,6 +238,9 @@ struct Kstarqa { hCutFlow->GetXaxis()->SetBinLabel(9, "rctChecker"); hCutFlow->GetXaxis()->SetBinLabel(10, "kIsTriggerTVX"); hCutFlow->GetXaxis()->SetBinLabel(11, "kIsGoodZvtxFT0vsPV"); + hCutFlow->GetXaxis()->SetBinLabel(12, "IsINELgt0"); + hCutFlow->GetXaxis()->SetBinLabel(13, "isVertexITSTPC"); + hCutFlow->GetXaxis()->SetBinLabel(14, "isVertexTOFMatched"); // for primary tracksbinsMultPlot if (cQAplots) { @@ -250,18 +305,69 @@ struct Kstarqa { // MC histograms hInvMass.add("hk892GenpT", "pT distribution of True MC K(892)0", kTHnSparseF, {ptAxis, multiplicityAxis}); hInvMass.add("hk892GenpT2", "pT distribution of True MC K(892)0", kTHnSparseF, {ptAxis, multiplicityAxis}); + hInvMass.add("hk892GenpTCalib1", "pT distribution of True MC K(892)0", kTHnSparseF, {ptAxis, multiplicityAxis}); + hInvMass.add("hk892GenpTCalib2", "pT distribution of True MC K(892)0", kTHnSparseF, {ptAxis, multiplicityAxis}); hInvMass.add("h1KstarRecMass", "Invariant mass of kstar meson", kTH1F, {invmassAxis}); hInvMass.add("h2KstarRecpt1", "pT of kstar meson", kTHnSparseF, {ptAxis, multiplicityAxis, invmassAxis}); - hInvMass.add("h2KstarRecpt2", "pT of generated kstar meson", kTHnSparseF, {ptAxis, multiplicityAxis, invmassAxis}); + hInvMass.add("h2KstarRecpt2", "pT of kstar meson", kTHnSparseF, {ptAxis, multiplicityAxis, invmassAxis}); + hInvMass.add("h2KstarRecptCalib1", "pT of kstar meson", kTHnSparseF, {ptAxis, multiplicityAxis, invmassAxis}); + hInvMass.add("h2KstarRecptCalib2", "pT of kstar meson", kTHnSparseF, {ptAxis, multiplicityAxis, invmassAxis}); hInvMass.add("h1genmass", "Invariant mass of generated kstar meson", kTH1F, {invmassAxis}); hInvMass.add("h1GenMult", "Multiplicity generated", kTH1F, {multiplicityAxis}); + hInvMass.add("h1GenMult2", "Multiplicity generated (direct)", kTH1F, {multiplicityAxis}); hInvMass.add("h1RecMult", "Multiplicity reconstructed", kTH1F, {multiplicityAxis}); - rEventSelection.add("events_check_data", "No. of events in the data", kTH1I, {{20, 0, 20}}); - rEventSelection.add("events_check", "No. of events in the generated MC", kTH1I, {{20, 0, 20}}); - rEventSelection.add("events_checkrec", "No. of events in the reconstructed MC", kTH1I, {{20, 0, 20}}); + hInvMass.add("h1RecMult2", "Multiplicity reconstructed", kTH1F, {multiplicityAxis}); hInvMass.add("h1KSRecsplit", "KS meson Rec split", kTH1F, {{100, 0.0f, 10.0f}}); - hInvMass.add("kstargenBeforeEvtSel", "Kstar generated before event selection", kTH1F, {ptAxis}); - hInvMass.add("kstargenAfterEvtSel", "Kstar generated after event selection", kTH1F, {ptAxis}); + hInvMass.add("MCcorrections/hSignalLossDenominator", "Kstar generated before event selection", kTH2F, {{ptAxis}, {multiplicityAxis}}); + hInvMass.add("MCcorrections/hSignalLossNumerator", "Kstar generated after event selection", kTH2F, {{ptAxis}, {multiplicityAxis}}); + // hInvMass.add("hAllGenCollisionsImpact", "All generated collisions vs impact parameter", kTH1F, {multiplicityAxis}); + hInvMass.add("hAllGenCollisions", "All generated events", kTH1F, {multiplicityAxis}); + hInvMass.add("hAllGenCollisions1Rec", "All gen events with at least one rec event", kTH1F, {multiplicityAxis}); + hInvMass.add("hAllKstarGenCollisisons", "All generated Kstar in events with rapidity in 0.5", kTH2F, {{multiplicityAxis}, {ptAxis}}); + hInvMass.add("hAllKstarGenCollisisons1Rec", "All generated Kstar in events with at least one rec event in rapidity in 0.5", kTH2F, {{multiplicityAxis}, {ptAxis}}); + hInvMass.add("hAllRecCollisions", "All reconstructed events", kTH1F, {multiplicityAxis}); + hInvMass.add("hAllRecCollisionsCalib", "All reconstructed events", kTH1F, {multiplicityAxis}); + hInvMass.add("MCcorrections/hImpactParameterRec", "Impact parameter in reconstructed MC", kTH1F, {impactParAxis}); + hInvMass.add("MCcorrections/MultiplicityRec", "Multiplicity in reconstructed MC", kTH1F, {multiplicityAxis}); + hInvMass.add("MCcorrections/hImpactParameterGen", "Impact parameter in generated MC", kTH1F, {impactParAxis}); + hInvMass.add("MCcorrections/MultiplicityGen", "Multiplicity in generated MC", kTH1F, {multiplicityAxis}); + hInvMass.add("MCcorrections/hImpactParametervsMultiplicity", "Impact parameter vs multiplicity in reconstructed MC", kTH2F, {{impactParAxis}, {multiplicityAxis}}); + rEventSelection.add("tracksCheckData", "No. of events in the data", kTH1I, {{10, 0, 10}}); + rEventSelection.add("eventsCheckGen", "No. of events in the generated MC", kTH1I, {{10, 0, 10}}); + rEventSelection.add("recMCparticles", "No. of events in the reconstructed MC", kTH1I, {{20, 0, 20}}); + rEventSelection.add("hOccupancy", "Occupancy distribution", kTH1F, {{1000, 0, 15000}}); + + std::shared_ptr hrecLabel = rEventSelection.get(HIST("recMCparticles")); + hrecLabel->GetXaxis()->SetBinLabel(1, "All tracks"); + hrecLabel->GetXaxis()->SetBinLabel(2, "has_MC"); + hrecLabel->GetXaxis()->SetBinLabel(3, "Track selection"); + hrecLabel->GetXaxis()->SetBinLabel(4, "StrictlyUpperIndex"); + hrecLabel->GetXaxis()->SetBinLabel(5, "Unlike Sign"); + hrecLabel->GetXaxis()->SetBinLabel(6, "Physical Primary"); + hrecLabel->GetXaxis()->SetBinLabel(7, "Track PDG"); + hrecLabel->GetXaxis()->SetBinLabel(8, "Global Index"); + hrecLabel->GetXaxis()->SetBinLabel(9, "Generator"); + hrecLabel->GetXaxis()->SetBinLabel(10, "Mother y"); + hrecLabel->GetXaxis()->SetBinLabel(11, "Mother PDG"); + hrecLabel->GetXaxis()->SetBinLabel(12, "Track PID"); + hrecLabel->GetXaxis()->SetBinLabel(13, "Track MID"); + hrecLabel->GetXaxis()->SetBinLabel(14, "Track y"); + hrecLabel->GetXaxis()->SetBinLabel(15, "Split tracks"); + + std::shared_ptr hDataTracks = rEventSelection.get(HIST("tracksCheckData")); + hDataTracks->GetXaxis()->SetBinLabel(1, "All tracks"); + hDataTracks->GetXaxis()->SetBinLabel(2, "Track selection"); + hDataTracks->GetXaxis()->SetBinLabel(3, "PID Cut"); + hDataTracks->GetXaxis()->SetBinLabel(4, "Remove Fake Tracks"); + hDataTracks->GetXaxis()->SetBinLabel(5, "Rapidity Cut"); + hDataTracks->GetXaxis()->SetBinLabel(6, "MID"); + hDataTracks->GetXaxis()->SetBinLabel(7, "Global Index"); + + std::shared_ptr hGenTracks = rEventSelection.get(HIST("eventsCheckGen")); + hGenTracks->GetXaxis()->SetBinLabel(1, "All events"); + hGenTracks->GetXaxis()->SetBinLabel(2, "INELgt0+vtz"); + hGenTracks->GetXaxis()->SetBinLabel(3, "INELgt0"); + hGenTracks->GetXaxis()->SetBinLabel(4, "Event Reconstructed"); // Multplicity distribution if (cQAevents) { @@ -282,66 +388,78 @@ struct Kstarqa { bool selectionEvent(const Coll& collision, bool fillHist = true) { if (fillHist) - rEventSelection.fill(HIST("hEventCutFlow"), 0); + rEventSelection.fill(HIST("hEventCut"), 0); if (std::abs(collision.posZ()) > selectionConfig.cutzvertex) return false; if (fillHist) - rEventSelection.fill(HIST("hEventCutFlow"), 1); + rEventSelection.fill(HIST("hEventCut"), 1); if (!collision.sel8()) return false; if (fillHist) - rEventSelection.fill(HIST("hEventCutFlow"), 2); + rEventSelection.fill(HIST("hEventCut"), 2); if (selectionConfig.isNoTimeFrameBorder && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) return false; if (fillHist) - rEventSelection.fill(HIST("hEventCutFlow"), 3); + rEventSelection.fill(HIST("hEventCut"), 3); if (selectionConfig.isNoITSROFrameBorder && !collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) return false; if (fillHist) - rEventSelection.fill(HIST("hEventCutFlow"), 4); + rEventSelection.fill(HIST("hEventCut"), 4); if (selectionConfig.isNoSameBunchPileup && (!collision.selection_bit(aod::evsel::kNoSameBunchPileup))) return false; if (fillHist) - rEventSelection.fill(HIST("hEventCutFlow"), 5); + rEventSelection.fill(HIST("hEventCut"), 5); if (selectionConfig.isAllLayersGoodITS && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) return false; if (fillHist) - rEventSelection.fill(HIST("hEventCutFlow"), 6); + rEventSelection.fill(HIST("hEventCut"), 6); - if (selectionConfig.isApplyOccCut && (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard))) + if (selectionConfig.isNoCollInTimeRangeStandard && (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard))) return false; if (selectionConfig.isApplyOccCut && (std::abs(collision.trackOccupancyInTimeRange()) > selectionConfig.configOccCut)) return false; if (fillHist) - rEventSelection.fill(HIST("hEventCutFlow"), 7); + rEventSelection.fill(HIST("hEventCut"), 7); if (rctCut.requireRCTFlagChecker && !rctChecker(collision)) return false; if (fillHist) - rEventSelection.fill(HIST("hEventCutFlow"), 8); + rEventSelection.fill(HIST("hEventCut"), 8); if (selectionConfig.isTriggerTVX && !collision.selection_bit(aod::evsel::kIsTriggerTVX)) return false; if (fillHist) - rEventSelection.fill(HIST("hEventCutFlow"), 9); + rEventSelection.fill(HIST("hEventCut"), 9); if (selectionConfig.isGoodZvtxFT0vsPV && !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) return false; if (fillHist) - rEventSelection.fill(HIST("hEventCutFlow"), 10); + rEventSelection.fill(HIST("hEventCut"), 10); if (selectionConfig.isINELgt0 && !collision.isInelGt0()) { return false; } if (fillHist) - rEventSelection.fill(HIST("hEventCutFlow"), 11); + rEventSelection.fill(HIST("hEventCut"), 11); + + if (selectionConfig.isVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { + return false; + } + if (fillHist) + rEventSelection.fill(HIST("hEventCut"), 12); + + if (selectionConfig.isVertexTOFMatched && !collision.selection_bit(aod::evsel::kIsVertexTOFmatched)) { + return false; + } + if (fillHist) + rEventSelection.fill(HIST("hEventCut"), 13); return true; } @@ -349,14 +467,48 @@ struct Kstarqa { template bool selectionTrack(const T& candidate) { - if (selectionConfig.isGlobalTracks && !(candidate.isGlobalTrackWoDCA() && candidate.isPVContributor() && std::abs(candidate.dcaXY()) < selectionConfig.cfgCutDCAxy && std::abs(candidate.dcaZ()) < selectionConfig.cfgCutDCAz && candidate.itsNCls() > selectionConfig.cfgITScluster && candidate.tpcNClsFound() > selectionConfig.cfgTPCcluster && std::abs(candidate.eta()) < selectionConfig.cfgCutEta && std::abs(candidate.pt()) > selectionConfig.cfgCutPT)) { - return false; + if (selectionConfig.isGlobalTracks) { + if (!candidate.isGlobalTrackWoDCA()) + return false; + if (std::abs(candidate.pt()) < selectionConfig.cfgCutPT) + return false; + // if (std::abs(candidate.eta()) > selectionConfig.cfgCutEtaMax || std::abs(candidate.eta()) < selectionConfig.cfgCutEtaMin) + if (std::abs(candidate.eta()) > selectionConfig.cfgCutEtaMax) + return false; + if (!selectionConfig.isApplyPtDepDCAxyCut) { + // if (std::abs(candidate.dcaXY()) > selectionConfig.cfgCutDCAxyMax || std::abs(candidate.dcaXY()) < selectionConfig.cfgCutDCAxyMin) + if (std::abs(candidate.dcaXY()) > selectionConfig.cfgCutDCAxyMax) + return false; + } else { + if (std::abs(candidate.dcaXY()) > (0.0105 + 0.035 / std::pow(candidate.pt(), 1.1))) + return false; + } + if (selectionConfig.isGoldenChi2 && !candidate.passedGoldenChi2()) + return false; + if (std::abs(candidate.dcaZ()) > selectionConfig.cfgCutDCAz) + return false; + if (candidate.tpcCrossedRowsOverFindableCls() < selectionConfig.cfgRCRFC) + return false; + if (candidate.itsNCls() < selectionConfig.cfgITScluster) + return false; + if (candidate.tpcNClsFound() < selectionConfig.cfgTPCcluster) + return false; + if (candidate.itsChi2NCl() >= selectionConfig.cfgITSChi2NCl) + return false; + if (candidate.tpcChi2NCl() >= selectionConfig.cfgTPCChi2NClMax || candidate.tpcChi2NCl() < selectionConfig.cfgTPCChi2NClMin) + return false; + if (selectionConfig.cfgPVContributor && !candidate.isPVContributor()) + return false; + if (selectionConfig.cfgUseITSTPCRefit && (!(o2::aod::track::ITSrefit) || !(o2::aod::track::TPCrefit))) + return false; } else if (!selectionConfig.isGlobalTracks) { if (std::abs(candidate.pt()) < selectionConfig.cfgCutPT) return false; - if (std::abs(candidate.eta()) > selectionConfig.cfgCutEta) + // if (std::abs(candidate.eta()) > selectionConfig.cfgCutEtaMax || std::abs(candidate.eta()) < selectionConfig.cfgCutEtaMin) + if (std::abs(candidate.eta()) > selectionConfig.cfgCutEtaMax) return false; - if (std::abs(candidate.dcaXY()) > selectionConfig.cfgCutDCAxy) + // if (std::abs(candidate.dcaXY()) > selectionConfig.cfgCutDCAxyMax || std::abs(candidate.dcaXY()) < selectionConfig.cfgCutDCAxyMin) + if (std::abs(candidate.dcaXY()) > selectionConfig.cfgCutDCAxyMax) return false; if (std::abs(candidate.dcaZ()) > selectionConfig.cfgCutDCAz) return false; @@ -368,7 +520,7 @@ struct Kstarqa { return false; if (candidate.itsChi2NCl() >= selectionConfig.cfgITSChi2NCl) return false; - if (candidate.tpcChi2NCl() >= selectionConfig.cfgTPCChi2NCl) + if (candidate.tpcChi2NCl() >= selectionConfig.cfgTPCChi2NClMax || candidate.tpcChi2NCl() < selectionConfig.cfgTPCChi2NClMin) return false; if (selectionConfig.cfgPVContributor && !candidate.isPVContributor()) return false; @@ -396,51 +548,154 @@ struct Kstarqa { template bool selectionPID(const T& candidate, int PID) { - if (PID == 0) { + if (PID == PIDParticle::kPion) { + if (onlyTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < selectionConfig.nsigmaCutTOFPi && candidate.beta() > cBetaCutTOF) { + return true; + } + } else if (onlyTOFHIT) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < selectionConfig.nsigmaCutTOFPi && candidate.beta() > cBetaCutTOF) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi) { + return true; + } + } else if (onlyTPC) { + if (std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi) { + return true; + } + } else { + if (candidate.hasTOF() && (candidate.tofNSigmaPi() * candidate.tofNSigmaPi() + candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi()) < (selectionConfig.nsigmaCutCombinedPi * selectionConfig.nsigmaCutCombinedPi) && candidate.beta() > cBetaCutTOF) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi) { + return true; + } + } + } else if (PID == PIDParticle::kKaon) { + if (onlyTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < selectionConfig.nsigmaCutTOFKa && candidate.beta() > cBetaCutTOF) { + return true; + } + } else if (onlyTOFHIT) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < selectionConfig.nsigmaCutTOFKa && candidate.beta() > cBetaCutTOF) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa) { + return true; + } + } else if (onlyTPC) { + if (std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa) { + return true; + } + } else { + if (candidate.hasTOF() && (candidate.tofNSigmaKa() * candidate.tofNSigmaKa() + candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa()) < (selectionConfig.nsigmaCutCombinedKa * selectionConfig.nsigmaCutCombinedKa) && candidate.beta() > cBetaCutTOF) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa) { + return true; + } + } + } else if (PID == PIDParticle::kProton) { // for proton + if (onlyTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPr()) < selectionConfig.nsigmaCutTOFPr && candidate.beta() > cBetaCutTOF) { + return true; + } + } else if (onlyTOFHIT) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPr()) < selectionConfig.nsigmaCutTOFPr && candidate.beta() > cBetaCutTOF) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPr()) < selectionConfig.nsigmaCutTPCPr) { + return true; + } + } else if (onlyTPC) { + if (std::abs(candidate.tpcNSigmaPr()) < selectionConfig.nsigmaCutTPCPr) { + return true; + } + } else { + if (candidate.hasTOF() && (candidate.tofNSigmaPr() * candidate.tofNSigmaPr() + candidate.tpcNSigmaPr() * candidate.tpcNSigmaPr()) < (selectionConfig.nsigmaCutTOFPr * selectionConfig.nsigmaCutTOFPr) && candidate.beta() > cBetaCutTOF) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPr()) < selectionConfig.nsigmaCutTPCPr) { + return true; + } + } + } + return false; + } + + template + bool selectionMID(const T& candidate, int PID) + { + if (PID == PIDParticle::kPion) { + if (onlyTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < selectionConfig.nsigmaCutTOFMIDPi && candidate.beta() > cBetaCutTOF) { + return true; + } + } else if (onlyTOFHIT) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < selectionConfig.nsigmaCutTOFMIDPi && candidate.beta() > cBetaCutTOF) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCMIDPi) { + return true; + } + } else if (onlyTPC) { + if (std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCMIDPi) { + return true; + } + } else { + if (candidate.hasTOF() && (candidate.tofNSigmaPi() * candidate.tofNSigmaPi() + candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi()) < (selectionConfig.nsigmaCutCombinedMIDPi * selectionConfig.nsigmaCutCombinedMIDPi) && candidate.beta() > cBetaCutTOF) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCMIDPi) { + return true; + } + } + } else if (PID == PIDParticle::kKaon) { if (onlyTOF) { - if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < nsigmaCutTOFPi && candidate.beta() > cBetaCutTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < selectionConfig.nsigmaCutTOFMIDKa && candidate.beta() > cBetaCutTOF) { return true; } } else if (onlyTOFHIT) { - if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < nsigmaCutTOFPi && candidate.beta() > cBetaCutTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < selectionConfig.nsigmaCutTOFMIDKa && candidate.beta() > cBetaCutTOF) { return true; } - if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPCPi) { + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCMIDKa) { return true; } } else if (onlyTPC) { - if (std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPCPi) { + if (std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCMIDKa) { return true; } } else { - if (candidate.hasTOF() && (candidate.tofNSigmaPi() * candidate.tofNSigmaPi() + candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi()) < (nsigmaCutCombinedPi * nsigmaCutCombinedPi) && candidate.beta() > cBetaCutTOF) { + if (candidate.hasTOF() && (candidate.tofNSigmaKa() * candidate.tofNSigmaKa() + candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa()) < (selectionConfig.nsigmaCutCombinedMIDKa * selectionConfig.nsigmaCutCombinedMIDKa) && candidate.beta() > cBetaCutTOF) { return true; } - if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPCPi) { + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCMIDKa) { return true; } } - } else if (PID == 1) { + } else if (PID == PIDParticle::kProton) { // for proton if (onlyTOF) { - if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < nsigmaCutTOFKa && candidate.beta() > cBetaCutTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPr()) < selectionConfig.nsigmaCutTOFPr && candidate.beta() > cBetaCutTOF) { return true; } } else if (onlyTOFHIT) { - if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < nsigmaCutTOFKa && candidate.beta() > cBetaCutTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPr()) < selectionConfig.nsigmaCutTOFPr && candidate.beta() > cBetaCutTOF) { return true; } - if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPCKa) { + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPr()) < selectionConfig.nsigmaCutTPCPr) { return true; } } else if (onlyTPC) { - if (std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPCKa) { + if (std::abs(candidate.tpcNSigmaPr()) < selectionConfig.nsigmaCutTPCPr) { return true; } } else { - if (candidate.hasTOF() && (candidate.tofNSigmaKa() * candidate.tofNSigmaKa() + candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa()) < (nsigmaCutCombinedKa * nsigmaCutCombinedKa) && candidate.beta() > cBetaCutTOF) { + if (candidate.hasTOF() && (candidate.tofNSigmaPr() * candidate.tofNSigmaPr() + candidate.tpcNSigmaPr() * candidate.tpcNSigmaPr()) < (selectionConfig.nsigmaCutTOFPr * selectionConfig.nsigmaCutTOFPr) && candidate.beta() > cBetaCutTOF) { return true; } - if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPCKa) { + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPr()) < selectionConfig.nsigmaCutTPCPr) { return true; } } @@ -451,24 +706,34 @@ struct Kstarqa { template bool selectionPIDNew(const T& candidate, int PID) { - if (PID == 0) { - if (candidate.pt() < 0.5 && std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPCPi) { + if (PID == PIDParticle::kPion) { + if (candidate.pt() < selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi) { + return true; + } + if (candidate.pt() >= selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi && candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < selectionConfig.nsigmaCutTOFPi) { + return true; + } + if (candidate.pt() >= selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaPi()) < selectionConfig.nsigmaCutTPCPi && !candidate.hasTOF()) { + return true; + } + } else if (PID == PIDParticle::kKaon) { + if (candidate.pt() < selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa) { return true; } - if (candidate.pt() >= 0.5 && std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPCPi && candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < nsigmaCutTOFPi) { + if (candidate.pt() >= selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa && candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < selectionConfig.nsigmaCutTOFKa) { return true; } - if (candidate.pt() >= 0.5 && std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPCPi && !candidate.hasTOF()) { + if (candidate.pt() >= selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaKa()) < selectionConfig.nsigmaCutTPCKa && !candidate.hasTOF()) { return true; } - } else if (PID == 1) { - if (candidate.pt() < 0.5 && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPCKa) { + } else if (PID == PIDParticle::kProton) { // for proton + if (candidate.pt() < selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaPr()) < selectionConfig.nsigmaCutTPCPr) { return true; } - if (candidate.pt() >= 0.5 && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPCKa && candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < nsigmaCutTOFKa) { + if (candidate.pt() >= selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaPr()) < selectionConfig.nsigmaCutTPCPr && candidate.hasTOF() && std::abs(candidate.tofNSigmaPr()) < selectionConfig.nsigmaCutTOFPr) { return true; } - if (candidate.pt() >= 0.5 && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPCKa && !candidate.hasTOF()) { + if (candidate.pt() >= selectionConfig.lowPtCutPID && std::abs(candidate.tpcNSigmaPr()) < selectionConfig.nsigmaCutTPCPr && !candidate.hasTOF()) { return true; } } @@ -476,86 +741,6 @@ struct Kstarqa { return false; } - // template - // bool cMIDselectionPID(const T& candidate, int PID) - // { - // if (PID == 0) { - // if (onlyTOF) { - // if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < 3.0) { - // return true; - // } - // } else if (onlyTOFHIT) { - // if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < 3.0) { - // return true; - // } - // if (!candidate.hasTOF() && - // std::abs(candidate.tpcNSigmaPi()) < 3.0) { - // return true; - // } - // } else if (onlyTPC) { - // if (std::abs(candidate.tpcNSigmaPi()) < 3.0) { - // return true; - // } - // } else { - // if (candidate.hasTOF() && (candidate.tofNSigmaPi() * candidate.tofNSigmaPi() + candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi()) < (3.0 * 3.0)) { - // return true; - // } - // if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < 3.0) { - // return true; - // } - // } - // } else if (PID == 1) { - // if (onlyTOF) { - // if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < 3.0) { - // return true; - // } - // } else if (onlyTOFHIT) { - // if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < 3.0) { - // return true; - // } - // if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < 3.0) { - // return true; - // } - // } else if (onlyTPC) { - // if (std::abs(candidate.tpcNSigmaKa()) < 3.0) { - // return true; - // } - // } else { - // if (candidate.hasTOF() && (candidate.tofNSigmaKa() * candidate.tofNSigmaKa() + candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa()) < (3.0 * 3.0)) { - // return true; - // } - // if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < 3.0) { - // return true; - // } - // } - // } else if (PID == 2) { - // if (onlyTOF) { - // if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPr()) < 3.0) { - // return true; - // } - // } else if (onlyTOFHIT) { - // if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPr()) < 3.0) { - // return true; - // } - // if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPr()) < 3.0) { - // return true; - // } - // } else if (onlyTPC) { - // if (std::abs(candidate.tpcNSigmaPr()) < 3.0) { - // return true; - // } - // } else { - // if (candidate.hasTOF() && (candidate.tofNSigmaPr() * candidate.tofNSigmaPr() + candidate.tpcNSigmaPr() * candidate.tpcNSigmaPr()) < (3.0 * 3.0)) { - // return true; - // } - // if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPr()) < 3.0) { - // return true; - // } - // } - // } - // return false; - // } - std::array pvec0; std::array pvec1; @@ -565,15 +750,20 @@ struct Kstarqa { // Filter eventFilter = (o2::aod::evsel::sel8 == true); Filter posZFilter = (nabs(o2::aod::collision::posZ) < selectionConfig.cutzvertex); - Filter acceptanceFilter = (nabs(aod::track::eta) < selectionConfig.cfgCutEta && nabs(aod::track::pt) > selectionConfig.cfgCutPT); - Filter fDCAcutFilter = (nabs(aod::track::dcaXY) < selectionConfig.cfgCutDCAxy) && (nabs(aod::track::dcaZ) < selectionConfig.cfgCutDCAz); + // Filter acceptanceFilter = (nabs(aod::track::eta) < selectionConfig.cfgCutEtaMax && nabs(aod::track::pt) > selectionConfig.cfgCutPT) && (nabs(aod::track::eta) > selectionConfig.cfgCutEtaMin); + Filter acceptanceFilter = (nabs(aod::track::eta) < selectionConfig.cfgCutEtaMax && nabs(aod::track::pt) > selectionConfig.cfgCutPT); + // Filter fDCAcutFilter = (nabs(aod::track::dcaXY) < selectionConfig.cfgCutDCAxyMax) && (nabs(aod::track::dcaZ) < selectionConfig.cfgCutDCAz) && (nabs(aod::track::dcaXY) > selectionConfig.cfgCutDCAxyMin); + Filter fDCAcutFilter = (nabs(aod::track::dcaXY) < selectionConfig.cfgCutDCAxyMax) && (nabs(aod::track::dcaZ) < selectionConfig.cfgCutDCAz); - using EventCandidates = soa::Join; // aod::CentNGlobals, aod::CentNTPVs, aod::CentMFTs - using EventCandidatesMix = soa::Filtered>; // aod::CentNGlobals, aod::CentNTPVs, aod::CentMFTs - using TrackCandidates = soa::Filtered>; - using EventCandidatesMC = soa::Join; + using EventCandidates = soa::Filtered>; // aod::CentNGlobals, aod::CentNTPVs, aod::CentMFTs + using EventCandidatesMix = soa::Filtered>; // aod::CentNGlobals, aod::CentNTPVs, aod::CentMFTs + using TrackCandidates = soa::Filtered>; + using EventCandidatesMC = soa::Join; + // using EventCandidatesMC = soa::Filtered>; - using TrackCandidatesMC = soa::Filtered>; + using TrackCandidatesMC = soa::Filtered>; + // using EventMCGenerated = soa::Join; // aod::CentNGlobals, aod::CentNTPVs, aod::CentMFTs + using EventMCGenerated = soa::Join; //*********Varibles declaration*************** float multiplicity{-1.0}, theta2; @@ -588,13 +778,13 @@ struct Kstarqa { ROOT::Math::Boost boost{mother.BoostToCM()}; // boost mother to center of mass frame fourVecDauCM = boost(daughterSelected); // boost the frame of daughter same as mother - // if (std::abs(mother.Rapidity()) < 0.5) { + // if (std::abs(mother.Rapidity()) < selectionConfig.rapidityMotherData) { if (activateTHnSparseCosThStarHelicity) { auto cosThetaStarHelicity = mother.Vect().Dot(fourVecDauCM.Vect()) / (std::sqrt(fourVecDauCM.Vect().Mag2()) * std::sqrt(mother.Vect().Mag2())); if (track1.sign() * track2.sign() < 0) { if (!isMix) { - if (std::abs(mother.Rapidity()) < 0.5) { + if (std::abs(mother.Rapidity()) < selectionConfig.rapidityMotherData) { hInvMass.fill(HIST("h3KstarInvMassUnlikeSign"), multiplicity, mother.Pt(), mother.M(), cosThetaStarHelicity); } @@ -610,15 +800,15 @@ struct Kstarqa { auto cosThetaStarHelicityRot = motherRot.Vect().Dot(daughterRotCM.Vect()) / (std::sqrt(daughterRotCM.Vect().Mag2()) * std::sqrt(motherRot.Vect().Mag2())); - if (calcRotational && motherRot.Rapidity() < 0.5) + if (calcRotational && std::abs(motherRot.Rapidity()) < selectionConfig.rapidityMotherData) hInvMass.fill(HIST("h3KstarInvMassRotated"), multiplicity, motherRot.Pt(), motherRot.M(), cosThetaStarHelicityRot); } - } else if (isMix && std::abs(mother.Rapidity()) < 0.5) { + } else if (isMix && std::abs(mother.Rapidity()) < selectionConfig.rapidityMotherData) { hInvMass.fill(HIST("h3KstarInvMassMixed"), multiplicity, mother.Pt(), mother.M(), cosThetaStarHelicity); } } else { if (!isMix) { - if (calcLikeSign && std::abs(mother.Rapidity()) < 0.5) { + if (calcLikeSign && std::abs(mother.Rapidity()) < selectionConfig.rapidityMotherData) { if (track1.sign() > 0 && track2.sign() > 0) { hInvMass.fill(HIST("h3KstarInvMasslikeSignPP"), multiplicity, mother.Pt(), mother.M(), cosThetaStarHelicity); } else if (track1.sign() < 0 && track2.sign() < 0) { @@ -634,7 +824,7 @@ struct Kstarqa { if (track1.sign() * track2.sign() < 0) { if (!isMix) { - if (std::abs(mother.Rapidity()) < 0.5) { + if (std::abs(mother.Rapidity()) < selectionConfig.rapidityMotherData) { hInvMass.fill(HIST("h3KstarInvMassUnlikeSign"), multiplicity, mother.Pt(), mother.M(), cosThetaStarProduction); } for (int i = 0; i < cRotations; i++) { @@ -642,15 +832,15 @@ struct Kstarqa { daughterRot = ROOT::Math::PxPyPzMVector(daughter1.Px() * std::cos(theta2) - daughter1.Py() * std::sin(theta2), daughter1.Px() * std::sin(theta2) + daughter1.Py() * std::cos(theta2), daughter1.Pz(), daughter1.M()); motherRot = daughterRot + daughter2; - if (calcRotational && std::abs(motherRot.Rapidity()) < 0.5) + if (calcRotational && std::abs(motherRot.Rapidity()) < selectionConfig.rapidityMotherData) hInvMass.fill(HIST("h3KstarInvMassRotated"), multiplicity, motherRot.Pt(), motherRot.M(), cosThetaStarProduction); } - } else if (isMix && std::abs(mother.Rapidity()) < 0.5) { + } else if (isMix && std::abs(mother.Rapidity()) < selectionConfig.rapidityMotherData) { hInvMass.fill(HIST("h3KstarInvMassMixed"), multiplicity, mother.Pt(), mother.M(), cosThetaStarProduction); } } else { if (!isMix) { - if (calcLikeSign && std::abs(mother.Rapidity()) < 0.5) { + if (calcLikeSign && std::abs(mother.Rapidity()) < selectionConfig.rapidityMotherData) { if (track1.sign() > 0 && track2.sign() > 0) { hInvMass.fill(HIST("h3KstarInvMasslikeSignPP"), multiplicity, mother.Pt(), mother.M(), cosThetaStarProduction); } else if (track1.sign() < 0 && track2.sign() < 0) { @@ -665,7 +855,7 @@ struct Kstarqa { if (track1.sign() * track2.sign() < 0) { if (!isMix) { - if (std::abs(mother.Rapidity()) < 0.5) { + if (std::abs(mother.Rapidity()) < selectionConfig.rapidityMotherData) { hInvMass.fill(HIST("h3KstarInvMassUnlikeSign"), multiplicity, mother.Pt(), mother.M(), cosThetaStarBeam); } for (int i = 0; i < cRotations; i++) { @@ -673,14 +863,14 @@ struct Kstarqa { daughterRot = ROOT::Math::PxPyPzMVector(daughter1.Px() * std::cos(theta2) - daughter1.Py() * std::sin(theta2), daughter1.Px() * std::sin(theta2) + daughter1.Py() * std::cos(theta2), daughter1.Pz(), daughter1.M()); motherRot = daughterRot + daughter2; - if (calcRotational && std::abs(motherRot.Rapidity()) < 0.5) + if (calcRotational && std::abs(motherRot.Rapidity()) < selectionConfig.rapidityMotherData) hInvMass.fill(HIST("h3KstarInvMassRotated"), multiplicity, motherRot.Pt(), motherRot.M(), cosThetaStarBeam); } - } else if (isMix && std::abs(mother.Rapidity()) < 0.5) { + } else if (isMix && std::abs(mother.Rapidity()) < selectionConfig.rapidityMotherData) { hInvMass.fill(HIST("h3KstarInvMassMixed"), multiplicity, mother.Pt(), mother.M(), cosThetaStarBeam); } } else { - if (calcLikeSign && std::abs(mother.Rapidity()) < 0.5) { + if (calcLikeSign && std::abs(mother.Rapidity()) < selectionConfig.rapidityMotherData) { if (track1.sign() > 0 && track2.sign() > 0) { hInvMass.fill(HIST("h3KstarInvMasslikeSignPP"), multiplicity, mother.Pt(), mother.M(), cosThetaStarBeam); } else if (track1.sign() < 0 && track2.sign() < 0) { @@ -697,7 +887,7 @@ struct Kstarqa { if (track1.sign() * track2.sign() < 0) { if (!isMix) { - if (std::abs(mother.Rapidity()) < 0.5) { + if (std::abs(mother.Rapidity()) < selectionConfig.rapidityMotherData) { hInvMass.fill(HIST("h3KstarInvMassUnlikeSign"), multiplicity, mother.Pt(), mother.M(), cosThetaStarRandom); } for (int i = 0; i < cRotations; i++) { @@ -705,15 +895,15 @@ struct Kstarqa { daughterRot = ROOT::Math::PxPyPzMVector(daughter1.Px() * std::cos(theta2) - daughter1.Py() * std::sin(theta2), daughter1.Px() * std::sin(theta2) + daughter1.Py() * std::cos(theta2), daughter1.Pz(), daughter1.M()); motherRot = daughterRot + daughter2; - if (calcRotational && std::abs(motherRot.Rapidity()) < 0.5) + if (calcRotational && std::abs(motherRot.Rapidity()) < selectionConfig.rapidityMotherData) hInvMass.fill(HIST("h3KstarInvMassRotated"), multiplicity, motherRot.Pt(), motherRot.M(), cosThetaStarRandom); } - } else if (isMix && std::abs(mother.Rapidity()) < 0.5) { + } else if (isMix && std::abs(mother.Rapidity()) < selectionConfig.rapidityMotherData) { hInvMass.fill(HIST("h3KstarInvMassMixed"), multiplicity, mother.Pt(), mother.M(), cosThetaStarRandom); } } else { if (!isMix) { - if (calcLikeSign && std::abs(mother.Rapidity()) < 0.5) { + if (calcLikeSign && std::abs(mother.Rapidity()) < selectionConfig.rapidityMotherData) { if (track1.sign() > 0 && track2.sign() > 0) { hInvMass.fill(HIST("h3KstarInvMasslikeSignPP"), multiplicity, mother.Pt(), mother.M(), cosThetaStarRandom); } else if (track1.sign() < 0 && track2.sign() < 0) { @@ -727,16 +917,13 @@ struct Kstarqa { } // int counter = 0; - void processSE(EventCandidates::iterator const& collision, TrackCandidates const& tracks, aod::BCs const&) { - rEventSelection.fill(HIST("events_check_data"), 0.5); // if (cTVXEvsel && (!collision.selection_bit(aod::evsel::kIsTriggerTVX))) { // return; // } - // rEventSelection.fill(HIST("events_check_data"), 1.5); // if (timFrameEvsel && (!collision.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision.selection_bit(aod::evsel::kNoITSROFrameBorder))) { // return; @@ -745,27 +932,27 @@ struct Kstarqa { // if (!collision.sel8()) { // return; // } - // rEventSelection.fill(HIST("events_check_data"), 2.5); + int occupancy = collision.trackOccupancyInTimeRange(); + rEventSelection.fill(HIST("hOccupancy"), occupancy); if (!selectionEvent(collision, true)) { return; } - rEventSelection.fill(HIST("events_check_data"), 3.5); - multiplicity = -1; - if (cSelectMultEstimator == 0) { + if (cSelectMultEstimator == kFT0M) { multiplicity = collision.centFT0M(); - } else if (cSelectMultEstimator == 1) { + } else if (cSelectMultEstimator == kFT0A) { multiplicity = collision.centFT0A(); - } else if (cSelectMultEstimator == 2) { + } else if (cSelectMultEstimator == kFT0C) { multiplicity = collision.centFT0C(); - } else if (cSelectMultEstimator == 3) { + } else if (cSelectMultEstimator == kFV0A) { multiplicity = collision.centFV0A(); } else { - multiplicity = collision.centFT0M(); + multiplicity = collision.centFT0M(); // default } + /* else if (cSelectMultEstimator == 4) { multiplicity = collision.centMFT(); } */ @@ -787,13 +974,17 @@ struct Kstarqa { } for (const auto& [track1, track2] : combinations(CombinationsFullIndexPolicy(tracks, tracks))) { + rEventSelection.fill(HIST("tracksCheckData"), 0.5); if (!selectionTrack(track1)) { continue; } if (!selectionTrack(track2)) { continue; } - rEventSelection.fill(HIST("events_check_data"), 4.5); + rEventSelection.fill(HIST("tracksCheckData"), 1.5); + + if (track1.globalIndex() == track2.globalIndex()) + continue; if (cQAplots) { hPID.fill(HIST("Before/hNsigmaTPC_Ka_before"), track1.pt(), track1.tpcNSigmaKa()); @@ -825,11 +1016,6 @@ struct Kstarqa { } } - rEventSelection.fill(HIST("events_check_data"), 5.5); - // if (counter < 1e4) - // std::cout << "TOF beta value is " << track1.beta() << std::endl; - // counter++; - if (cQAevents) { rEventSelection.fill(HIST("hDcaxy"), track1.dcaXY()); rEventSelection.fill(HIST("hDcaz"), track1.dcaZ()); @@ -846,23 +1032,33 @@ struct Kstarqa { if (applypTdepPID && !selectionPIDNew(track2, 0)) // Track 2 is checked with Pion continue; - rEventSelection.fill(HIST("events_check_data"), 6.5); + rEventSelection.fill(HIST("tracksCheckData"), 2.5); if (cFakeTrack && isFakeTrack(track1, 1)) // Kaon continue; if (cFakeTrack && isFakeTrack(track2, 0)) // Pion continue; + rEventSelection.fill(HIST("tracksCheckData"), 3.5); + + if (std::abs(track1.rapidity(o2::track::PID::getMass(o2::track::PID::Kaon))) > selectionConfig.ctrackRapidity) + continue; - // if (cMID) { - // if (cMIDselectionPID(track1, 0)) // Kaon misidentified as pion - // continue; - // if (cMIDselectionPID(track1, 2)) // Kaon misidentified as proton - // continue; - // if (cMIDselectionPID(track2, 1)) // Pion misidentified as kaon - // continue; - // } + if (std::abs(track2.rapidity(o2::track::PID::getMass(o2::track::PID::Pion))) > selectionConfig.ctrackRapidity) + continue; + rEventSelection.fill(HIST("tracksCheckData"), 4.5); + + if (selectionConfig.isApplyParticleMID) { + if (selectionMID(track1, 0)) // Kaon misidentified as pion + continue; + if (selectionMID(track1, 2)) // Kaon misidentified as proton + continue; + if (selectionMID(track2, 1)) // Pion misidentified as kaon + continue; + if (selectionMID(track2, 2)) // Pion misidentified as proton + continue; + } - rEventSelection.fill(HIST("events_check_data"), 7.5); + rEventSelection.fill(HIST("tracksCheckData"), 5.5); if (cQAplots) { hPID.fill(HIST("After/hDcaxyPi"), track2.dcaXY()); @@ -884,15 +1080,19 @@ struct Kstarqa { hPID.fill(HIST("After/hNsigma_TPC_TOF_Pi_after"), track2.tpcNSigmaPi(), track2.tofNSigmaPi()); } - if (track1.globalIndex() == track2.globalIndex()) - continue; - - rEventSelection.fill(HIST("events_check_data"), 8.5); + rEventSelection.fill(HIST("tracksCheckData"), 6.5); daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); daughter2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); mother = daughter1 + daughter2; // Kstar meson + if (selectionConfig.isApplyCutsOnMother) { + if (mother.Pt() >= selectionConfig.cMaxPtMotherCut) // excluding candidates in overflow + continue; + if (mother.M() >= selectionConfig.cMaxMinvMotherCut) // excluding candidates in overflow + continue; + } + hOthers.fill(HIST("hKstar_Rap"), mother.Rapidity()); hOthers.fill(HIST("hKstar_Eta"), mother.Eta()); @@ -908,21 +1108,36 @@ struct Kstarqa { ConfigurableAxis axisMultiplicity{"axisMultiplicity", {2000, 0, 10000}, "TPC multiplicity axis for ME mixing"}; // using BinningTypeTPCMultiplicity = ColumnBinningPolicy; - using BinningTypeCentralityM = ColumnBinningPolicy; - using BinningTypeVertexContributor = ColumnBinningPolicy; + using BinningTypeFT0M = ColumnBinningPolicy; using BinningTypeFT0A = ColumnBinningPolicy; + using BinningTypeFT0C = ColumnBinningPolicy; using BinningTypeFV0A = ColumnBinningPolicy; - BinningTypeVertexContributor binningOnPositions{{axisVertex, axisMultiplicity}, true}; - BinningTypeCentralityM binningOnCentrality{{axisVertex, axisMultiplicity}, true}; + using BinningTypeMCFT0M = ColumnBinningPolicy; + using BinningTypeMCFT0A = ColumnBinningPolicy; + using BinningTypeMCFT0C = ColumnBinningPolicy; + using BinningTypeMCFV0A = ColumnBinningPolicy; + + BinningTypeFT0M binningOnFT0M{{axisVertex, axisMultiplicity}, true}; BinningTypeFT0A binningOnFT0A{{axisVertex, axisMultiplicity}, true}; + BinningTypeFT0C binningOnFT0C{{axisVertex, axisMultiplicity}, true}; BinningTypeFV0A binningOnFV0A{{axisVertex, axisMultiplicity}, true}; - SameKindPair pair1{binningOnPositions, selectionConfig.cfgNoMixedEvents, -1, &cache}; - SameKindPair pair2{binningOnCentrality, selectionConfig.cfgNoMixedEvents, -1, &cache}; - SameKindPair pair3{binningOnFT0A, selectionConfig.cfgNoMixedEvents, -1, &cache}; + BinningTypeMCFT0M binningOnMCFT0M{{axisVertex, axisMultiplicity}, true}; + BinningTypeMCFT0A binningOnMCFT0A{{axisVertex, axisMultiplicity}, true}; + BinningTypeMCFT0C binningOnMCFT0C{{axisVertex, axisMultiplicity}, true}; + BinningTypeMCFV0A binningOnMCFV0A{{axisVertex, axisMultiplicity}, true}; + + SameKindPair pair1{binningOnFT0M, selectionConfig.cfgNoMixedEvents, -1, &cache}; + SameKindPair pair2{binningOnFT0A, selectionConfig.cfgNoMixedEvents, -1, &cache}; + SameKindPair pair3{binningOnFT0C, selectionConfig.cfgNoMixedEvents, -1, &cache}; SameKindPair pair4{binningOnFV0A, selectionConfig.cfgNoMixedEvents, -1, &cache}; + SameKindPair pairmc1{binningOnMCFT0M, selectionConfig.cfgNoMixedEvents, -1, &cache}; + SameKindPair pairmc2{binningOnMCFT0A, selectionConfig.cfgNoMixedEvents, -1, &cache}; + SameKindPair pairmc3{binningOnMCFT0C, selectionConfig.cfgNoMixedEvents, -1, &cache}; + SameKindPair pairmc4{binningOnMCFV0A, selectionConfig.cfgNoMixedEvents, -1, &cache}; + void processME(EventCandidatesMix const&, TrackCandidates const&) { // Map estimator to pair and multiplicity accessor @@ -944,13 +1159,35 @@ struct Kstarqa { if (!selectionPID(t1, 1) || !selectionPID(t2, 0)) continue; + if (std::abs(t1.rapidity(o2::track::PID::getMass(o2::track::PID::Kaon))) > selectionConfig.ctrackRapidity) + continue; + + if (std::abs(t2.rapidity(o2::track::PID::getMass(o2::track::PID::Pion))) > selectionConfig.ctrackRapidity) + continue; + + if (cFakeTrack && isFakeTrack(t1, 1)) // Kaon + continue; + if (cFakeTrack && isFakeTrack(t2, 0)) // Pion + continue; + + if (selectionConfig.isApplyParticleMID) { + if (selectionMID(t1, 0)) // Kaon misidentified as pion + continue; + if (selectionMID(t1, 2)) // Kaon misidentified as proton + continue; + if (selectionMID(t2, 1)) // Pion misidentified as kaon + continue; + if (selectionMID(t2, 2)) // Pion misidentified as proton + continue; + } + daughter1 = ROOT::Math::PxPyPzMVector(t1.px(), t1.py(), t1.pz(), massKa); daughter2 = ROOT::Math::PxPyPzMVector(t2.px(), t2.py(), t2.pz(), massPi); mother = daughter1 + daughter2; isMix = true; - if (std::abs(mother.Rapidity()) < 0.5) { + if (std::abs(mother.Rapidity()) < selectionConfig.rapidityMotherData) { fillInvMass(daughter1, daughter2, mother, multiplicity, isMix, t1, t2); } } @@ -958,236 +1195,573 @@ struct Kstarqa { }; // Call mixing based on selected estimator - if (cSelectMultEstimator == 0) { + if (cSelectMultEstimator == kFT0M) { runMixing(pair1, [](const auto& c) { return c.centFT0M(); }); - } else if (cSelectMultEstimator == 1) { + } else if (cSelectMultEstimator == kFT0A) { runMixing(pair2, [](const auto& c) { return c.centFT0A(); }); - } else if (cSelectMultEstimator == 2) { + } else if (cSelectMultEstimator == kFT0C) { runMixing(pair3, [](const auto& c) { return c.centFT0C(); }); - } else if (cSelectMultEstimator == 3) { + } else if (cSelectMultEstimator == kFV0A) { runMixing(pair4, [](const auto& c) { return c.centFV0A(); }); } } - PROCESS_SWITCH(Kstarqa, processME, "Process Mixed event", true); - void processGen(aod::McCollision const& mcCollision, aod::McParticles const& mcParticles, const soa::SmallGroups& collisions) + void processMEMC(EventCandidatesMC const&, TrackCandidatesMC const&, aod::McParticles const&, aod::McCollisions const&) { - rEventSelection.fill(HIST("events_check"), 0.5); - if (std::abs(mcCollision.posZ()) < selectionConfig.cutzvertex) { - rEventSelection.fill(HIST("events_check"), 1.5); - } + auto runMixing = [&](auto& pair, auto multiplicityGetter) { + for (const auto& [c1, tracks1, c2, tracks2] : pair) { - int nChInel = 0; - for (const auto& mcParticle : mcParticles) { - auto pdgcode = std::abs(mcParticle.pdgCode()); - if (mcParticle.isPhysicalPrimary() && (pdgcode == PDG_t::kPiPlus || pdgcode == PDG_t::kKPlus || pdgcode == PDG_t::kProton || pdgcode == std::abs(PDG_t::kElectron) || pdgcode == std::abs(PDG_t::kMuonMinus))) { - if (std::abs(mcParticle.eta()) < 1.0) { - nChInel = nChInel + 1; + if (!selectionEvent(c1, false) || !selectionEvent(c2, false)) { + continue; } - } - } - if (nChInel > 0 && std::abs(mcCollision.posZ()) < selectionConfig.cutzvertex) - rEventSelection.fill(HIST("events_check"), 2.5); - std::vector selectedEvents(collisions.size()); - int nevts = 0; - multiplicity = -1.0; - for (const auto& collision : collisions) { - // if (!collision.sel8() || std::abs(collision.mcCollision().posZ()) > selectionConfig.cutzvertex) { - if (std::abs(collision.mcCollision().posZ()) > selectionConfig.cutzvertex) { - continue; - } - if (!collision.sel8()) { - continue; - } - if (selectionConfig.isNoTimeFrameBorder && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { - continue; - } - if (selectionConfig.isTriggerTVX && !collision.selection_bit(aod::evsel::kIsTriggerTVX)) { - continue; - } - if (selectionConfig.isINELgt0 && !collision.isInelGt0()) { - continue; - } - if (selectionConfig.isNoSameBunchPileup && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { - continue; - } - if (selectionConfig.isGoodZvtxFT0vsPV && !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { - continue; - } - multiplicity = collision.centFT0M(); - hInvMass.fill(HIST("h1GenMult"), multiplicity); - selectedEvents[nevts++] = collision.mcCollision_as().globalIndex(); - } - selectedEvents.resize(nevts); - rEventSelection.fill(HIST("events_check"), 3.5); + if (!c1.has_mcCollision() || !c2.has_mcCollision()) { + continue; // skip if no MC collision associated + } - const auto evtReconstructedAndSelected = std::find(selectedEvents.begin(), selectedEvents.end(), mcCollision.globalIndex()) != selectedEvents.end(); + multiplicity = multiplicityGetter(c1); + // multiplicity = c1.centFT0M(); // default, can be changed later - if (!cAllGenCollisions && !evtReconstructedAndSelected) { // Check that the event is reconstructed and that the reconstructed events pass the selection - return; - } - rEventSelection.fill(HIST("events_check"), 4.5); + for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { + if (!selectionTrack(t1) || !selectionTrack(t2)) + continue; + if (!selectionPID(t1, 1) || !selectionPID(t2, 0)) + continue; - for (const auto& mcParticle : mcParticles) { - if (std::abs(mcParticle.y()) >= 0.5) { - continue; - } - rEventSelection.fill(HIST("events_check"), 5.5); + if (selectionConfig.isApplyParticleMID) { + if (selectionMID(t1, 0)) // Kaon misidentified as pion + continue; + if (selectionMID(t1, 2)) // Kaon misidentified as proton + continue; + if (selectionMID(t2, 1)) // Pion misidentified as kaon + continue; + if (selectionMID(t2, 2)) // Pion misidentified as proton + continue; + } - if (std::abs(mcParticle.pdgCode()) != o2::constants::physics::kK0Star892) { - continue; - } - rEventSelection.fill(HIST("events_check"), 6.5); + if (!t1.has_mcParticle() || !t2.has_mcParticle()) { + continue; // skip if no MC particle associated + } - auto kDaughters = mcParticle.daughters_as(); - if (kDaughters.size() != 2) { - continue; - } - rEventSelection.fill(HIST("events_check"), 7.5); + if (std::abs(t1.rapidity(o2::track::PID::getMass(o2::track::PID::Kaon))) > selectionConfig.ctrackRapidity) + continue; - auto passkaon = false; - auto passpion = false; - for (const auto& kCurrentDaughter : kDaughters) { - if (!kCurrentDaughter.isPhysicalPrimary()) { - continue; - } - rEventSelection.fill(HIST("events_check"), 8.5); + if (std::abs(t2.rapidity(o2::track::PID::getMass(o2::track::PID::Pion))) > selectionConfig.ctrackRapidity) + continue; - if (std::abs(kCurrentDaughter.pdgCode()) == PDG_t::kKPlus) { - passkaon = true; - daughter1 = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); + const auto mctrack1 = t1.mcParticle(); + const auto mctrack2 = t2.mcParticle(); - } else if (std::abs(kCurrentDaughter.pdgCode()) == PDG_t::kPiPlus) { - passpion = true; - daughter2 = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massPi); - } - } - if (passkaon && passpion) { - mother = daughter1 + daughter2; // Kstar meson - hInvMass.fill(HIST("hk892GenpT"), mcParticle.pt(), multiplicity); - hInvMass.fill(HIST("hk892GenpT2"), mother.Pt(), multiplicity); - hInvMass.fill(HIST("h1genmass"), mother.M()); - } - } - } - PROCESS_SWITCH(Kstarqa, processGen, "Process Generated", false); - /* - void processEvtLossSigLossMC(aod::McCollisions::iterator const&, aod::McParticles const& mcParticles, const soa::SmallGroups& recCollisions) - { - - bool isSel = false; - // auto multiplicity1 = -999.; - for (const auto& RecCollision : recCollisions) { - if (!selectionEvent(RecCollision, false)) - continue; + if (!mctrack1.isPhysicalPrimary()) { + continue; + } - // if (cSelectMultEstimator == 0) { - // multiplicity1 = RecCollision.centFT0M(); - // } else if (cSelectMultEstimator == 1) { - // multiplicity1 = RecCollision.centFT0A(); - // } else if (cSelectMultEstimator == 2) { - // multiplicity1 = RecCollision.centFT0C(); - // } else { - // multiplicity1 = RecCollision.centFT0M(); - // } + if (!mctrack2.isPhysicalPrimary()) { + continue; + } - isSel = true; - } + daughter1 = ROOT::Math::PxPyPzMVector(t1.px(), t1.py(), t1.pz(), massKa); + daughter2 = ROOT::Math::PxPyPzMVector(t2.px(), t2.py(), t2.pz(), massPi); + mother = daughter1 + daughter2; - // Generated MC - for (const auto& mcPart : mcParticles) { - if (std::abs(mcPart.y()) >= 0.5 || std::abs(mcPart.pdgCode()) != o2::constants::physics::kK0Star892) - continue; + isMix = true; - // signal loss estimation - hInvMass.fill(HIST("kstargenBeforeEvtSel"), mcPart.pt()); - if (isSel) { - hInvMass.fill(HIST("kstargenAfterEvtSel"), mcPart.pt()); + if (std::abs(mother.Rapidity()) < selectionConfig.rapidityMotherData) { + fillInvMass(daughter1, daughter2, mother, multiplicity, isMix, t1, t2); + } } - } // end loop on gen particles - } - PROCESS_SWITCH(Kstarqa, processEvtLossSigLossMC, "Process Signal Loss, Event Loss", false); - */ - void processRec(EventCandidatesMC::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const&, aod::McCollisions const& /*mcCollisions*/) - { - - rEventSelection.fill(HIST("events_checkrec"), 0.5); + } + }; + // Call mixing based on selected estimator + if (cSelectMultEstimator == kFT0M) { + runMixing(pairmc1, [](const auto& c) { return c.centFT0M(); }); + } else if (cSelectMultEstimator == kFT0A) { + runMixing(pairmc2, [](const auto& c) { return c.centFT0A(); }); + } else if (cSelectMultEstimator == kFT0C) { + runMixing(pairmc3, [](const auto& c) { return c.centFT0C(); }); + } else if (cSelectMultEstimator == kFV0A) { + runMixing(pairmc4, [](const auto& c) { return c.centFV0A(); }); + } + } + PROCESS_SWITCH(Kstarqa, processMEMC, "Process mixed-event in MC", true); + void processSEMC(EventCandidatesMC::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const&, aod::McCollisions const& /*mcCollisions*/) + { + auto oldindex = -999; if (!collision.has_mcCollision()) { return; } - rEventSelection.fill(HIST("events_checkrec"), 1.5); + int occupancy = collision.trackOccupancyInTimeRange(); + rEventSelection.fill(HIST("hOccupancy"), occupancy); - if (selectionConfig.isINELgt0 && !collision.isInelGt0()) { + if (!selectionEvent(collision, false)) { return; } - // if (std::abs(collision.mcCollision().posZ()) > selectionConfig.cutzvertex || !collision.sel8()) { - if (std::abs(collision.mcCollision().posZ()) > selectionConfig.cutzvertex) { + multiplicity = -1; + + if (cSelectMultEstimator == kFT0M) { + multiplicity = collision.centFT0M(); + } else if (cSelectMultEstimator == kFT0A) { + multiplicity = collision.centFT0A(); + } else if (cSelectMultEstimator == kFT0C) { + multiplicity = collision.centFT0C(); + } else if (cSelectMultEstimator == kFV0A) { + multiplicity = collision.centFV0A(); + } else { + multiplicity = collision.centFT0M(); // default + } + + // Fill the event counter + if (cQAevents) { + rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); + rEventSelection.fill(HIST("hMultiplicity"), multiplicity); + rEventSelection.fill(HIST("multdist_FT0M"), collision.multFT0M()); + // rEventSelection.fill(HIST("multdist_FT0A"), collision.multFT0A()); + // rEventSelection.fill(HIST("multdist_FT0C"), collision.multFT0C()); + // rEventSelection.fill(HIST("hNcontributor"), collision.numContrib()); + } + + for (const auto& [track1, track2] : combinations(CombinationsFullIndexPolicy(tracks, tracks))) { + rEventSelection.fill(HIST("tracksCheckData"), 0.5); + if (!selectionTrack(track1)) { + continue; + } + if (!selectionTrack(track2)) { + continue; + } + + const auto mctrack1 = track1.mcParticle(); + const auto mctrack2 = track2.mcParticle(); + + if (!track1.has_mcParticle() || !track2.has_mcParticle()) { + continue; // skip if no MC particle associated + } + + if (!mctrack1.isPhysicalPrimary()) { + continue; + } + + if (!mctrack2.isPhysicalPrimary()) { + continue; + } + rEventSelection.fill(HIST("tracksCheckData"), 1.5); + + if (cQAplots) { + hPID.fill(HIST("Before/hNsigmaTPC_Ka_before"), track1.pt(), track1.tpcNSigmaKa()); + hPID.fill(HIST("Before/hNsigmaTOF_Ka_before"), track1.pt(), track1.tofNSigmaKa()); + hPID.fill(HIST("Before/hNsigmaTPC_Pi_before"), track2.pt(), track2.tpcNSigmaPi()); + hPID.fill(HIST("Before/hNsigmaTOF_Pi_before"), track2.pt(), track2.tofNSigmaPi()); + hPID.fill(HIST("Before/hNsigma_TPC_TOF_Ka_before"), track1.tpcNSigmaKa(), track1.tofNSigmaKa()); + hPID.fill(HIST("Before/hNsigma_TPC_TOF_Pi_before"), track2.tpcNSigmaPi(), track2.tofNSigmaPi()); + + hPID.fill(HIST("Before/hTPCnsigKa_mult_pt"), track1.tpcNSigmaKa(), multiplicity, track1.pt()); + hPID.fill(HIST("Before/hTPCnsigPi_mult_pt"), track2.tpcNSigmaPi(), multiplicity, track2.pt()); + hPID.fill(HIST("Before/hTOFnsigKa_mult_pt"), track1.tofNSigmaKa(), multiplicity, track1.pt()); + hPID.fill(HIST("Before/hTOFnsigPi_mult_pt"), track2.tofNSigmaKa(), multiplicity, track2.pt()); + + hOthers.fill(HIST("hCRFC_before"), track1.tpcCrossedRowsOverFindableCls()); + hOthers.fill(HIST("dE_by_dx_TPC"), track1.p(), track1.tpcSignal()); + hOthers.fill(HIST("hphi"), track1.phi()); + + if (track1.sign() < 0) { + hPID.fill(HIST("Before/h1PID_TPC_neg_kaon"), track1.tpcNSigmaKa()); + hPID.fill(HIST("Before/h1PID_TPC_neg_pion"), track2.tpcNSigmaPi()); + hPID.fill(HIST("Before/h1PID_TOF_neg_kaon"), track1.tofNSigmaKa()); + hPID.fill(HIST("Before/h1PID_TOF_neg_pion"), track2.tofNSigmaPi()); + } else { + hPID.fill(HIST("Before/h1PID_TPC_pos_kaon"), track1.tpcNSigmaKa()); + hPID.fill(HIST("Before/h1PID_TPC_pos_pion"), track2.tpcNSigmaPi()); + hPID.fill(HIST("Before/h1PID_TOF_pos_kaon"), track1.tofNSigmaKa()); + hPID.fill(HIST("Before/h1PID_TOF_pos_pion"), track2.tofNSigmaPi()); + } + } + + if (cQAevents) { + rEventSelection.fill(HIST("hDcaxy"), track1.dcaXY()); + rEventSelection.fill(HIST("hDcaz"), track1.dcaZ()); + } + + // since we are using combinations full index policy, so repeated pairs are allowed, so we can check one with Kaon and other with pion + if (!applypTdepPID && !selectionPID(track1, 1)) // Track 1 is checked with Kaon + continue; + if (!applypTdepPID && !selectionPID(track2, 0)) // Track 2 is checked with Pion + continue; + rEventSelection.fill(HIST("tracksCheckData"), 2.5); + + if (applypTdepPID && !selectionPIDNew(track1, 1)) // Track 1 is checked with Kaon + continue; + if (applypTdepPID && !selectionPIDNew(track2, 0)) // Track 2 is checked with Pion + continue; + rEventSelection.fill(HIST("tracksCheckData"), 3.5); + + if (selectionConfig.isApplyParticleMID) { + if (selectionMID(track1, 0)) // Kaon misidentified as pion + continue; + if (selectionMID(track1, 2)) // Kaon misidentified as proton + continue; + if (selectionMID(track2, 1)) // Pion misidentified as kaon + continue; + if (selectionMID(track2, 2)) // Pion misidentified as proton + continue; + } + + rEventSelection.fill(HIST("tracksCheckData"), 4.5); + if (std::abs(track1.rapidity(o2::track::PID::getMass(o2::track::PID::Kaon))) > selectionConfig.ctrackRapidity) + continue; + + if (std::abs(track2.rapidity(o2::track::PID::getMass(o2::track::PID::Pion))) > selectionConfig.ctrackRapidity) + continue; + + // if (cFakeTrack && isFakeTrack(track1, 1)) // Kaon + // continue; + // if (cFakeTrack && isFakeTrack(track2, 0)) // Pion + // continue; + rEventSelection.fill(HIST("tracksCheckData"), 5.5); + + if (cQAplots) { + hPID.fill(HIST("After/hDcaxyPi"), track2.dcaXY()); + hPID.fill(HIST("After/hDcaxyKa"), track1.dcaXY()); + hPID.fill(HIST("After/hDcazPi"), track2.dcaZ()); + hPID.fill(HIST("After/hDcazKa"), track1.dcaZ()); + + hPID.fill(HIST("After/hTPCnsigKa_mult_pt"), track1.tpcNSigmaKa(), multiplicity, track1.pt()); + hPID.fill(HIST("After/hTPCnsigPi_mult_pt"), track2.tpcNSigmaPi(), multiplicity, track2.pt()); + hPID.fill(HIST("After/hTOFnsigKa_mult_pt"), track1.tofNSigmaKa(), multiplicity, track1.pt()); + hPID.fill(HIST("After/hTOFnsigPi_mult_pt"), track2.tofNSigmaKa(), multiplicity, track2.pt()); + hOthers.fill(HIST("hEta_after"), track1.eta()); + hOthers.fill(HIST("hCRFC_after"), track1.tpcCrossedRowsOverFindableCls()); + hPID.fill(HIST("After/hNsigmaKaonTPC_after"), track1.pt(), track1.tpcNSigmaKa()); + hPID.fill(HIST("After/hNsigmaKaonTOF_after"), track1.pt(), track1.tofNSigmaKa()); + hPID.fill(HIST("After/hNsigmaPionTPC_after"), track2.pt(), track2.tpcNSigmaPi()); + hPID.fill(HIST("After/hNsigmaPionTOF_after"), track2.pt(), track2.tofNSigmaPi()); + hPID.fill(HIST("After/hNsigma_TPC_TOF_Ka_after"), track1.tpcNSigmaKa(), track1.tofNSigmaKa()); + hPID.fill(HIST("After/hNsigma_TPC_TOF_Pi_after"), track2.tpcNSigmaPi(), track2.tofNSigmaPi()); + } + + if (track1.globalIndex() == track2.globalIndex()) + continue; + + rEventSelection.fill(HIST("tracksCheckData"), 6.5); + + for (const auto& mothertrack1 : mctrack1.mothers_as()) { + for (const auto& mothertrack2 : mctrack2.mothers_as()) { + + if (mothertrack1.globalIndex() != mothertrack2.globalIndex()) { + continue; + } + + if (!mothertrack1.producedByGenerator()) { + continue; + } + + if (selectionConfig.isApplyCutsOnMother) { + if (mothertrack1.pt() >= selectionConfig.cMaxPtMotherCut) // excluding candidates in overflow + continue; + if ((std::sqrt(mothertrack1.e() * mothertrack1.e() - mothertrack1.p() * mothertrack1.p())) >= selectionConfig.cMaxMinvMotherCut) // excluding candidates in overflow + continue; + } + + if (avoidsplitrackMC && oldindex == mothertrack1.globalIndex()) { + continue; + } + rEventSelection.fill(HIST("recMCparticles"), 11.5); + + oldindex = mothertrack1.globalIndex(); + + daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); + daughter2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); + mother = daughter1 + daughter2; // Kstar meson + + if (selectionConfig.isApplyCutsOnMother) { + if (mother.Pt() >= selectionConfig.cMaxPtMotherCut) // excluding candidates in overflow + continue; + if (mother.M() >= selectionConfig.cMaxMinvMotherCut) // excluding candidates in overflow + continue; + } + + hOthers.fill(HIST("hKstar_Rap"), mother.Rapidity()); + hOthers.fill(HIST("hKstar_Eta"), mother.Eta()); + + isMix = false; + fillInvMass(daughter1, daughter2, mother, multiplicity, isMix, track1, track2); + } + } + } + } + PROCESS_SWITCH(Kstarqa, processSEMC, "Process same event in MC", true); + + Service pdgDB; + + void processGen(EventMCGenerated::iterator const& mcCollision, aod::McParticles const& mcParticles, const soa::SmallGroups& collisions) + // void processGen(aod::McCollision const& mcCollision, aod::McParticles const& mcParticles, const soa::SmallGroups& collisions) + { + rEventSelection.fill(HIST("eventsCheckGen"), 0.5); + + int nChInel = 0; + for (const auto& mcParticle : mcParticles) { + auto pdgcode = std::abs(mcParticle.pdgCode()); + if (mcParticle.isPhysicalPrimary() && (pdgcode == PDG_t::kPiPlus || pdgcode == PDG_t::kKPlus || pdgcode == PDG_t::kProton || pdgcode == std::abs(PDG_t::kElectron) || pdgcode == std::abs(PDG_t::kMuonMinus))) { + if (std::abs(mcParticle.eta()) < 1.0) { + nChInel = nChInel + 1; + } + } + } + if (nChInel > 0 && std::abs(mcCollision.posZ()) < selectionConfig.cutzvertex) + rEventSelection.fill(HIST("eventsCheckGen"), 1.5); + + std::vector selectedEvents(collisions.size()); + int nevts = 0; + multiplicity = -1.0; + // float impactParameter = mcCollision.impactParameter(); + + bool isINELgt0true = false; + + if (pwglf::isINELgtNmc(mcParticles, 0, pdgDB)) { + isINELgt0true = true; + } + if (selectionConfig.isINELgt0 && !isINELgt0true) { return; } - rEventSelection.fill(HIST("events_checkrec"), 2.5); - if (selectionConfig.isNoTimeFrameBorder && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { + // if (selectionConfig.isINELgt0 && !mcCollision.isInelGt0()) { + // return; + // } + rEventSelection.fill(HIST("eventsCheckGen"), 2.5); + + for (const auto& collision : collisions) { + if (!selectionEvent(collision, true)) { + continue; + } + multiplicity = collision.centFT0M(); + + if (cSelectMultEstimator == kFT0M) { + multiplicity = collision.centFT0M(); + } else if (cSelectMultEstimator == kFT0A) { + multiplicity = collision.centFT0A(); + } else if (cSelectMultEstimator == kFT0C) { + multiplicity = collision.centFT0C(); + } else if (cSelectMultEstimator == kFV0A) { + multiplicity = collision.centFV0A(); + } else { + multiplicity = collision.centFT0M(); // default + } + hInvMass.fill(HIST("h1GenMult"), multiplicity); + + int occupancy = collision.trackOccupancyInTimeRange(); + rEventSelection.fill(HIST("hOccupancy"), occupancy); + + selectedEvents[nevts++] = collision.mcCollision_as().globalIndex(); + } + selectedEvents.resize(nevts); + + for (const auto& mcParticle : mcParticles) { + if (std::abs(mcParticle.y()) < selectionConfig.rapidityMotherData && std::abs(mcParticle.pdgCode()) == o2::constants::physics::kK0Star892) { + hInvMass.fill(HIST("hAllKstarGenCollisisons"), multiplicity, mcParticle.pt()); + } + } + + const auto evtReconstructedAndSelected = std::find(selectedEvents.begin(), selectedEvents.end(), mcCollision.globalIndex()) != selectedEvents.end(); + hInvMass.fill(HIST("hAllGenCollisions"), multiplicity); + if (!cAllGenCollisions && !evtReconstructedAndSelected) { // Check that the event is reconstructed and that the reconstructed events pass the selection return; } - rEventSelection.fill(HIST("events_checkrec"), 3.5); + double genMultiplicity = mcCollision.centFT0M(); + hInvMass.fill(HIST("h1GenMult2"), genMultiplicity); + hInvMass.fill(HIST("hAllGenCollisions1Rec"), multiplicity); + rEventSelection.fill(HIST("eventsCheckGen"), 3.5); + + for (const auto& mcParticle : mcParticles) { + + if (std::abs(mcParticle.y()) >= selectionConfig.rapidityMotherData) { + continue; + } + + if (selectionConfig.isApplyCutsOnMother) { + if (mcParticle.pt() >= selectionConfig.cMaxPtMotherCut) // excluding candidates in overflow + continue; + if ((std::sqrt(mcParticle.e() * mcParticle.e() - mcParticle.p() * mcParticle.p())) >= selectionConfig.cMaxMinvMotherCut) // excluding candidates in overflow + continue; + } + + if (std::abs(mcParticle.pdgCode()) != o2::constants::physics::kK0Star892) { + continue; + } + hInvMass.fill(HIST("hAllKstarGenCollisisons1Rec"), multiplicity, mcParticle.pt()); + + auto kDaughters = mcParticle.daughters_as(); + if (kDaughters.size() != selectionConfig.noOfDaughters) { + continue; + } + + auto passkaon = false; + auto passpion = false; + for (const auto& kCurrentDaughter : kDaughters) { + if (!kCurrentDaughter.isPhysicalPrimary()) { + continue; + } + + if (std::abs(kCurrentDaughter.pdgCode()) == PDG_t::kKPlus) { + passkaon = true; + daughter1 = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); + + } else if (std::abs(kCurrentDaughter.pdgCode()) == PDG_t::kPiPlus) { + passpion = true; + daughter2 = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massPi); + } + } + if (passkaon && passpion) { + mother = daughter1 + daughter2; // Kstar meson + hInvMass.fill(HIST("hk892GenpT"), mcParticle.pt(), multiplicity); + hInvMass.fill(HIST("hk892GenpT2"), mother.Pt(), multiplicity); + hInvMass.fill(HIST("hk892GenpTCalib1"), mcParticle.pt(), genMultiplicity); + hInvMass.fill(HIST("hk892GenpTCalib2"), mother.Pt(), genMultiplicity); + hInvMass.fill(HIST("h1genmass"), mother.M()); + } + } + } + PROCESS_SWITCH(Kstarqa, processGen, "Process Generated", false); + + void processEvtLossSigLossMC(EventMCGenerated::iterator const& mcCollision, aod::McParticles const& mcParticles, const soa::SmallGroups& recCollisions) + // void processEvtLossSigLossMC(aod::McCollisions::iterator const& mcCollision, aod::McParticles const& mcParticles, const soa::SmallGroups& recCollisions) + { + // if (selectionConfig.isINELgt0 && !mcCollision.isInelGt0()) { + // return; + // } - if (selectionConfig.isTriggerTVX && !collision.selection_bit(aod::evsel::kIsTriggerTVX)) { + bool isINELgt0true = false; + + if (pwglf::isINELgtNmc(mcParticles, 0, pdgDB)) { + isINELgt0true = true; + } + if (selectionConfig.isINELgt0 && !isINELgt0true) { return; } - rEventSelection.fill(HIST("events_checkrec"), 4.5); - if (!collision.sel8()) { + auto impactPar = mcCollision.impactParameter(); + multiplicity = -1; + multiplicity = mcCollision.centFT0M(); + hInvMass.fill(HIST("MCcorrections/hImpactParameterGen"), impactPar); + hInvMass.fill(HIST("MCcorrections/MultiplicityGen"), multiplicity); + + bool isSelectedEvent = false; + auto multiplicity1 = -999.; + for (const auto& RecCollision : recCollisions) { + if (!selectionEvent(RecCollision, false)) + continue; + // multiplicity1 = RecCollision.centFT0M(); + + if (cSelectMultEstimator == kFT0M) { + multiplicity1 = RecCollision.centFT0M(); + } else if (cSelectMultEstimator == kFT0A) { + multiplicity1 = RecCollision.centFT0A(); + } else if (cSelectMultEstimator == kFT0C) { + multiplicity1 = RecCollision.centFT0C(); + } else if (cSelectMultEstimator == kFV0A) { + multiplicity1 = RecCollision.centFV0A(); + } else { + multiplicity1 = RecCollision.centFT0M(); // default + } + + isSelectedEvent = true; + } + + // Event loss + if (isSelectedEvent) { + hInvMass.fill(HIST("MCcorrections/hImpactParameterRec"), impactPar); + hInvMass.fill(HIST("MCcorrections/MultiplicityRec"), multiplicity); + hInvMass.fill(HIST("MCcorrections/hImpactParametervsMultiplicity"), impactPar, multiplicity1); + } + + // Generated MC + for (const auto& mcPart : mcParticles) { + if (std::abs(mcPart.y()) >= selectionConfig.rapidityMotherData || std::abs(mcPart.pdgCode()) != o2::constants::physics::kK0Star892) + continue; + + // signal loss estimation + hInvMass.fill(HIST("MCcorrections/hSignalLossDenominator"), mcPart.pt(), multiplicity); + if (isSelectedEvent) { + hInvMass.fill(HIST("MCcorrections/hSignalLossNumerator"), mcPart.pt(), multiplicity); + } + } // end loop on gen particles + } + PROCESS_SWITCH(Kstarqa, processEvtLossSigLossMC, "Process Signal Loss, Event Loss", false); + + void processRec(EventCandidatesMC::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const&, aod::McCollisions const&) + { + + if (!collision.has_mcCollision()) { return; } - if (selectionConfig.isNoSameBunchPileup && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { + double multiplicityRec = -1.0; + // multiplicityRec = collision.mcCollision_as().centFT0M(); + const auto& mcCollisionRec = collision.mcCollision_as(); + multiplicityRec = mcCollisionRec.centFT0M(); + + if (selectionConfig.isINELgt0 && !collision.isInelGt0()) { return; } - if (selectionConfig.isGoodZvtxFT0vsPV && !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { + // multiplicity = collision.centFT0M(); + + multiplicity = -1.0; + + if (cSelectMultEstimator == kFT0M) { + multiplicity = collision.centFT0M(); + } else if (cSelectMultEstimator == kFT0A) { + multiplicity = collision.centFT0A(); + } else if (cSelectMultEstimator == kFT0C) { + multiplicity = collision.centFT0C(); + } else if (cSelectMultEstimator == kFV0A) { + multiplicity = collision.centFV0A(); + } else { + multiplicity = collision.centFT0M(); // default + } + + hInvMass.fill(HIST("hAllRecCollisions"), multiplicity); + hInvMass.fill(HIST("hAllRecCollisionsCalib"), multiplicityRec); + + if (!selectionEvent(collision, false)) { return; } - multiplicity = collision.centFT0M(); hInvMass.fill(HIST("h1RecMult"), multiplicity); + hInvMass.fill(HIST("h1RecMult2"), multiplicityRec); auto oldindex = -999; for (const auto& track1 : tracks) { if (!selectionTrack(track1)) { continue; } - rEventSelection.fill(HIST("events_checkrec"), 5.5); if (!track1.has_mcParticle()) { continue; } - rEventSelection.fill(HIST("events_checkrec"), 6.5); auto track1ID = track1.index(); for (const auto& track2 : tracks) { + rEventSelection.fill(HIST("recMCparticles"), 0.5); if (!track2.has_mcParticle()) { continue; } - rEventSelection.fill(HIST("events_checkrec"), 7.5); + rEventSelection.fill(HIST("recMCparticles"), 1.5); if (!selectionTrack(track2)) { continue; } - rEventSelection.fill(HIST("events_checkrec"), 8.5); + rEventSelection.fill(HIST("recMCparticles"), 2.5); auto track2ID = track2.index(); if (track2ID <= track1ID) { continue; } - rEventSelection.fill(HIST("events_checkrec"), 9.5); + rEventSelection.fill(HIST("recMCparticles"), 3.5); if (track1.sign() * track2.sign() >= 0) { continue; } - rEventSelection.fill(HIST("events_checkrec"), 10.5); + rEventSelection.fill(HIST("recMCparticles"), 4.5); const auto mctrack1 = track1.mcParticle(); const auto mctrack2 = track2.mcParticle(); @@ -1226,69 +1800,116 @@ struct Kstarqa { if (!mctrack1.isPhysicalPrimary()) { continue; } - rEventSelection.fill(HIST("events_checkrec"), 11.5); if (!mctrack2.isPhysicalPrimary()) { continue; } - rEventSelection.fill(HIST("events_checkrec"), 12.5); + rEventSelection.fill(HIST("recMCparticles"), 5.5); // if (!(track1PDG == PDG_t::kKPlus && track2PDG == PDG_t::kPiPlus)) { // continue; // } - if ((track1PDG != PDG_t::kPiPlus) && (track1PDG != PDG_t::kKPlus)) { + if (selectionConfig.isPDGCheckMC && (track1PDG != PDG_t::kKPlus) && (track1PDG != PDG_t::kPiPlus)) { continue; } - if ((track2PDG != PDG_t::kPiPlus) && (track2PDG != PDG_t::kKPlus)) { + if (selectionConfig.isPDGCheckMC && (track2PDG != PDG_t::kKPlus) && (track2PDG != PDG_t::kPiPlus)) { continue; } - rEventSelection.fill(HIST("events_checkrec"), 13.5); - rEventSelection.fill(HIST("events_checkrec"), 14.5); + rEventSelection.fill(HIST("recMCparticles"), 6.5); for (const auto& mothertrack1 : mctrack1.mothers_as()) { for (const auto& mothertrack2 : mctrack2.mothers_as()) { - if (mothertrack1.pdgCode() != mothertrack2.pdgCode()) { + if (selectionConfig.isPDGCheckMC && (mothertrack1.pdgCode() != mothertrack2.pdgCode())) { continue; } - rEventSelection.fill(HIST("events_checkrec"), 15.5); if (mothertrack1.globalIndex() != mothertrack2.globalIndex()) { continue; } - rEventSelection.fill(HIST("events_checkrec"), 16.5); + rEventSelection.fill(HIST("recMCparticles"), 7.5); if (!mothertrack1.producedByGenerator()) { continue; } - rEventSelection.fill(HIST("events_checkrec"), 17.5); + rEventSelection.fill(HIST("recMCparticles"), 8.5); - if (std::abs(mothertrack1.y()) >= 0.5) { + if (std::abs(mothertrack1.y()) >= selectionConfig.rapidityMotherData) { continue; } - rEventSelection.fill(HIST("events_checkrec"), 18.5); + rEventSelection.fill(HIST("recMCparticles"), 9.5); - if (std::abs(mothertrack1.pdgCode()) != o2::constants::physics::kK0Star892) { + if (selectionConfig.isPDGCheckMC && (std::abs(mothertrack1.pdgCode()) != o2::constants::physics::kK0Star892)) { continue; } + rEventSelection.fill(HIST("recMCparticles"), 10.5); - if (track1PDG == PDG_t::kPiPlus) { + if (selectionConfig.isPDGCheckMC && (track1PDG == PDG_t::kPiPlus)) { if (!applypTdepPID && !(selectionPID(track1, 0) && selectionPID(track2, 1))) { // pion and kaon continue; } else if (applypTdepPID && !(selectionPIDNew(track1, 0) && selectionPIDNew(track2, 1))) { // pion and kaon continue; } - } else { + rEventSelection.fill(HIST("recMCparticles"), 11.5); + if (selectionConfig.isApplyParticleMID) { + if (selectionMID(track2, 0)) // Kaon misidentified as pion + continue; + if (selectionMID(track2, 2)) // Kaon misidentified as proton + continue; + if (selectionMID(track1, 1)) // Pion misidentified as kaon + continue; + if (selectionMID(track1, 2)) // Pion misidentified as proton + continue; + } + rEventSelection.fill(HIST("recMCparticles"), 12.5); + + if (std::abs(track1.rapidity(o2::track::PID::getMass(o2::track::PID::Pion))) > selectionConfig.ctrackRapidity) + continue; + + if (std::abs(track2.rapidity(o2::track::PID::getMass(o2::track::PID::Kaon))) > selectionConfig.ctrackRapidity) + continue; + rEventSelection.fill(HIST("recMCparticles"), 13.5); + + } else if (selectionConfig.isPDGCheckMC && (track1PDG == PDG_t::kKPlus)) { if (!applypTdepPID && !(selectionPID(track1, 1) && selectionPID(track2, 0))) { // kaon and pion continue; } else if (applypTdepPID && !(selectionPIDNew(track1, 1) && selectionPIDNew(track2, 0))) { // kaon and pion continue; } + rEventSelection.fill(HIST("recMCparticles"), 11.5); + + if (selectionConfig.isApplyParticleMID) { + if (selectionMID(track1, 0)) // Kaon misidentified as pion + continue; + if (selectionMID(track1, 2)) // Kaon misidentified as proton + continue; + if (selectionMID(track2, 1)) // Pion misidentified as kaon + continue; + if (selectionMID(track2, 2)) // Pion misidentified as proton + continue; + } + rEventSelection.fill(HIST("recMCparticles"), 12.5); + + if (std::abs(track1.rapidity(o2::track::PID::getMass(o2::track::PID::Kaon))) > selectionConfig.ctrackRapidity) + continue; + + if (std::abs(track2.rapidity(o2::track::PID::getMass(o2::track::PID::Pion))) > selectionConfig.ctrackRapidity) + continue; + rEventSelection.fill(HIST("recMCparticles"), 13.5); + } + + if (selectionConfig.isApplyCutsOnMother) { + if (mothertrack1.pt() >= selectionConfig.cMaxPtMotherCut) // excluding candidates in overflow + continue; + if ((std::sqrt(mothertrack1.e() * mothertrack1.e() - mothertrack1.p() * mothertrack1.p())) >= selectionConfig.cMaxMinvMotherCut) // excluding candidates in overflow + continue; } if (avoidsplitrackMC && oldindex == mothertrack1.globalIndex()) { hInvMass.fill(HIST("h1KSRecsplit"), mothertrack1.pt()); continue; } + rEventSelection.fill(HIST("recMCparticles"), 14.5); + oldindex = mothertrack1.globalIndex(); if (track1.sign() * track2.sign() < 0) { daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); @@ -1296,13 +1917,15 @@ struct Kstarqa { mother = daughter1 + daughter2; // Kstar meson hInvMass.fill(HIST("h2KstarRecpt2"), mothertrack1.pt(), multiplicity, std::sqrt(mothertrack1.e() * mothertrack1.e() - mothertrack1.p() * mothertrack1.p())); + hInvMass.fill(HIST("h2KstarRecptCalib2"), mothertrack1.pt(), multiplicityRec, std::sqrt(mothertrack1.e() * mothertrack1.e() - mothertrack1.p() * mothertrack1.p())); - if (applyRecMotherRapidity && mother.Rapidity() >= 0) { + if (applyRecMotherRapidity && mother.Rapidity() >= selectionConfig.rapidityMotherData) { continue; } hInvMass.fill(HIST("h1KstarRecMass"), mother.M()); hInvMass.fill(HIST("h2KstarRecpt1"), mother.Pt(), multiplicity, mother.M()); + hInvMass.fill(HIST("h2KstarRecptCalib1"), mother.Pt(), multiplicityRec, mother.M()); } } } @@ -1310,6 +1933,256 @@ struct Kstarqa { } } PROCESS_SWITCH(Kstarqa, processRec, "Process Reconstructed", false); + + void processRec2(EventCandidatesMC::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const&, aod::McCollisions const& /*mcCollisions*/) + { + + if (!collision.has_mcCollision()) { + return; + } + + if (selectionConfig.isINELgt0 && !collision.isInelGt0()) { + return; + } + // multiplicity = collision.centFT0M(); + + multiplicity = -1.0; + + if (cSelectMultEstimator == kFT0M) { + multiplicity = collision.centFT0M(); + } else if (cSelectMultEstimator == kFT0A) { + multiplicity = collision.centFT0A(); + } else if (cSelectMultEstimator == kFT0C) { + multiplicity = collision.centFT0C(); + } else if (cSelectMultEstimator == kFV0A) { + multiplicity = collision.centFV0A(); + } else { + multiplicity = collision.centFT0M(); // default + } + + hInvMass.fill(HIST("hAllRecCollisions"), multiplicity); + + if (!selectionEvent(collision, false)) { + return; + } + + // // if (std::abs(collision.mcCollision().posZ()) > selectionConfig.cutzvertex || !collision.sel8()) { + // if (std::abs(collision.mcCollision().posZ()) > selectionConfig.cutzvertex) { + // return; + // } + + // if (selectionConfig.isNoTimeFrameBorder && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { + // return; + // } + + // if (selectionConfig.isTriggerTVX && !collision.selection_bit(aod::evsel::kIsTriggerTVX)) { + // return; + // } + + // if (!collision.sel8()) { + // return; + // } + + // if (selectionConfig.isNoSameBunchPileup && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { + // return; + // } + // if (selectionConfig.isGoodZvtxFT0vsPV && !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { + // return; + // } + + // multiplicity = collision.centFT0M(); + + multiplicity = -1.0; + + if (cSelectMultEstimator == kFT0M) { + multiplicity = collision.centFT0M(); + } else if (cSelectMultEstimator == kFT0A) { + multiplicity = collision.centFT0A(); + } else if (cSelectMultEstimator == kFT0C) { + multiplicity = collision.centFT0C(); + } else if (cSelectMultEstimator == kFV0A) { + multiplicity = collision.centFV0A(); + } else { + multiplicity = collision.centFT0M(); // default + } + + hInvMass.fill(HIST("h1RecMult"), multiplicity); + + auto oldindex = -999; + for (const auto& track1 : tracks) { + if (!selectionTrack(track1)) { + continue; + } + + if (!track1.has_mcParticle()) { + continue; + } + + auto track1ID = track1.index(); + for (const auto& track2 : tracks) { + rEventSelection.fill(HIST("recMCparticles"), 0.5); + if (!track2.has_mcParticle()) { + continue; + } + rEventSelection.fill(HIST("recMCparticles"), 1.5); + + if (!selectionTrack(track2)) { + continue; + } + rEventSelection.fill(HIST("recMCparticles"), 2.5); + + auto track2ID = track2.index(); + if (track2ID == track1ID) { + continue; + } + rEventSelection.fill(HIST("recMCparticles"), 3.5); + + if (track1.sign() * track2.sign() >= 0) { + continue; + } + rEventSelection.fill(HIST("recMCparticles"), 4.5); + + const auto mctrack1 = track1.mcParticle(); + const auto mctrack2 = track2.mcParticle(); + int track1PDG = std::abs(mctrack1.pdgCode()); + int track2PDG = std::abs(mctrack2.pdgCode()); + + if (cQAplots && (mctrack2.pdgCode() == PDG_t::kPiPlus)) { // pion + hPID.fill(HIST("Before/h1PID_TPC_pos_pion"), track2.tpcNSigmaPi()); + hPID.fill(HIST("Before/h1PID_TOF_pos_pion"), track2.tofNSigmaPi()); + hPID.fill(HIST("Before/hNsigmaTPC_Pi_before"), track2.pt(), track2.tpcNSigmaPi()); + hPID.fill(HIST("Before/hNsigmaTOF_Pi_before"), track2.pt(), track2.tofNSigmaPi()); + } + if (cQAplots && (mctrack2.pdgCode() == PDG_t::kKPlus)) { // kaon + hPID.fill(HIST("Before/h1PID_TPC_pos_kaon"), track2.tpcNSigmaKa()); + hPID.fill(HIST("Before/h1PID_TOF_pos_kaon"), track2.tofNSigmaKa()); + hPID.fill(HIST("Before/hNsigmaTPC_Ka_before"), track2.pt(), track2.tpcNSigmaKa()); + hPID.fill(HIST("Before/hNsigmaTOF_Ka_before"), track2.pt(), track2.tofNSigmaKa()); + } + if (cQAplots && (mctrack2.pdgCode() == -PDG_t::kPiMinus)) { // negative track pion + hPID.fill(HIST("Before/h1PID_TPC_neg_pion"), track2.tpcNSigmaPi()); + hPID.fill(HIST("Before/h1PID_TOF_neg_pion"), track2.tofNSigmaPi()); + hPID.fill(HIST("Before/hNsigmaTPC_Pi_before"), track2.pt(), track2.tpcNSigmaPi()); + hPID.fill(HIST("Before/hNsigmaTOF_Pi_before"), track2.pt(), track2.tofNSigmaPi()); + } + if (cQAplots && (mctrack2.pdgCode() == -PDG_t::kKMinus)) { // negative track kaon + hPID.fill(HIST("Before/h1PID_TPC_neg_kaon"), track2.tpcNSigmaKa()); + hPID.fill(HIST("Before/h1PID_TOF_neg_kaon"), track2.tofNSigmaKa()); + hPID.fill(HIST("Before/hNsigmaTPC_Ka_before"), track2.pt(), track2.tpcNSigmaKa()); + hPID.fill(HIST("Before/hNsigmaTOF_Ka_before"), track2.pt(), track2.tofNSigmaKa()); + } + if (cQAplots && (std::abs(mctrack1.pdgCode()) == PDG_t::kKPlus && std::abs(mctrack2.pdgCode()) == PDG_t::kPiPlus)) { + hPID.fill(HIST("Before/hNsigma_TPC_TOF_Ka_before"), track1.tpcNSigmaKa(), track1.tofNSigmaKa()); + hPID.fill(HIST("Before/hNsigma_TPC_TOF_Pi_before"), track2.tpcNSigmaPi(), track2.tofNSigmaPi()); + } + + if (!mctrack1.isPhysicalPrimary()) { + continue; + } + + if (!mctrack2.isPhysicalPrimary()) { + continue; + } + rEventSelection.fill(HIST("recMCparticles"), 5.5); + + // if (!(track1PDG == PDG_t::kKPlus && track2PDG == PDG_t::kPiPlus)) { + // continue; + // } + if (selectionConfig.isPDGCheckMC && (track1PDG != PDG_t::kKPlus)) { + continue; + } + if (selectionConfig.isPDGCheckMC && (track2PDG != PDG_t::kPiPlus)) { + continue; + } + rEventSelection.fill(HIST("recMCparticles"), 6.5); + + for (const auto& mothertrack1 : mctrack1.mothers_as()) { + for (const auto& mothertrack2 : mctrack2.mothers_as()) { + if (selectionConfig.isPDGCheckMC && (mothertrack1.pdgCode() != mothertrack2.pdgCode())) { + continue; + } + + if (mothertrack1.globalIndex() != mothertrack2.globalIndex()) { + continue; + } + rEventSelection.fill(HIST("recMCparticles"), 7.5); + + if (!mothertrack1.producedByGenerator()) { + continue; + } + rEventSelection.fill(HIST("recMCparticles"), 8.5); + + if (std::abs(mothertrack1.y()) >= selectionConfig.rapidityMotherData) { + continue; + } + rEventSelection.fill(HIST("recMCparticles"), 9.5); + + if (selectionConfig.isPDGCheckMC && (std::abs(mothertrack1.pdgCode()) != o2::constants::physics::kK0Star892)) { + continue; + } + rEventSelection.fill(HIST("recMCparticles"), 10.5); + + if (!applypTdepPID && !(selectionPID(track1, 1) && selectionPID(track2, 0))) { + continue; + } else if (applypTdepPID && !(selectionPIDNew(track1, 1) && selectionPIDNew(track2, 0))) { + continue; + } + rEventSelection.fill(HIST("recMCparticles"), 11.5); + + if (selectionConfig.isApplyParticleMID) { + if (selectionMID(track1, 0)) // Kaon misidentified as pion + continue; + if (selectionMID(track1, 2)) // Kaon misidentified as proton + continue; + if (selectionMID(track2, 1)) // Pion misidentified as kaon + continue; + if (selectionMID(track2, 2)) // Pion misidentified as proton + continue; + } + rEventSelection.fill(HIST("recMCparticles"), 12.5); + + if (std::abs(track1.rapidity(o2::track::PID::getMass(o2::track::PID::Kaon))) > selectionConfig.ctrackRapidity) + continue; + + if (std::abs(track2.rapidity(o2::track::PID::getMass(o2::track::PID::Pion))) > selectionConfig.ctrackRapidity) + continue; + + rEventSelection.fill(HIST("recMCparticles"), 13.5); + + if (selectionConfig.isApplyCutsOnMother) { + if (mothertrack1.pt() >= selectionConfig.cMaxPtMotherCut) // excluding candidates in overflow + continue; + if ((std::sqrt(mothertrack1.e() * mothertrack1.e() - mothertrack1.p() * mothertrack1.p())) >= selectionConfig.cMaxMinvMotherCut) // excluding candidates in overflow + continue; + } + + if (avoidsplitrackMC && oldindex == mothertrack1.globalIndex()) { + hInvMass.fill(HIST("h1KSRecsplit"), mothertrack1.pt()); + continue; + } + rEventSelection.fill(HIST("recMCparticles"), 14.5); + + oldindex = mothertrack1.globalIndex(); + if (track1.sign() * track2.sign() < 0) { + daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); + daughter2 = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massPi); + mother = daughter1 + daughter2; // Kstar meson + + hInvMass.fill(HIST("h2KstarRecpt2"), mothertrack1.pt(), multiplicity, std::sqrt(mothertrack1.e() * mothertrack1.e() - mothertrack1.p() * mothertrack1.p())); + + if (applyRecMotherRapidity && mother.Rapidity() >= selectionConfig.rapidityMotherData) { + continue; + } + + hInvMass.fill(HIST("h1KstarRecMass"), mother.M()); + hInvMass.fill(HIST("h2KstarRecpt1"), mother.Pt(), multiplicity, mother.M()); + } + } + } + } + } + } + PROCESS_SWITCH(Kstarqa, processRec2, "Process Reconstructed 2", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/Tasks/Resonances/lambda1520_PbPb.cxx b/PWGLF/Tasks/Resonances/lambda1520_PbPb.cxx index d032d0c90aa..830722b4bbf 100644 --- a/PWGLF/Tasks/Resonances/lambda1520_PbPb.cxx +++ b/PWGLF/Tasks/Resonances/lambda1520_PbPb.cxx @@ -555,7 +555,7 @@ struct lambdaAnalysis_pb { { auto mult = collision.cent(); - histos.fill(HIST("Event/h1d_ft0_mult_percentile"), mult); + histos.fill(HIST("Event/h1d_ft0_mult_percentile"), mult, 100); fillDataHistos(tracks, tracks, mult); // get MC pT-spectra diff --git a/PWGLF/Tasks/Resonances/phianalysisrun3_PbPb.cxx b/PWGLF/Tasks/Resonances/phianalysisrun3_PbPb.cxx index 018814b1581..b1d5e088685 100644 --- a/PWGLF/Tasks/Resonances/phianalysisrun3_PbPb.cxx +++ b/PWGLF/Tasks/Resonances/phianalysisrun3_PbPb.cxx @@ -83,8 +83,8 @@ struct phianalysisrun3_PbPb { Configurable cfgCutEta{"cfgCutEta", 0.8, "Eta cut on daughter track"}; Configurable cfgCutDCAxy{"cfgCutDCAxy", 2.0f, "DCAxy range for tracks"}; Configurable cfgCutDCAz{"cfgCutDCAz", 2.0f, "DCAz range for tracks"}; - Configurable nsigmaCutTPC{"nsigmacutTPC", 2.0, "Value of the TPC Nsigma cut"}; - Configurable nsigmaCutTOF{"nsigmacutTOF", 2.0, "Value of the TOF Nsigma cut"}; + Configurable nsigmacutTPC{"nsigmacutTPC", 2.0f, "Value of the TPC Nsigma cut"}; + Configurable nsigmacutTOF{"nsigmacutTOF", 2.0f, "Value of the TOF Nsigma cut"}; Configurable nsigmaCutCombined{"nsigmaCutCombined", 3.0, "Value of the TOF Nsigma cut"}; Configurable cfgNoMixedEvents{"cfgNoMixedEvents", 5, "Number of mixed events per event"}; Configurable fillOccupancy{"fillOccupancy", true, "fill Occupancy"}; @@ -93,21 +93,25 @@ struct phianalysisrun3_PbPb { Configurable additionalEvSel2{"additionalEvSel2", true, "Additional evsel2"}; Configurable additionalEvSel3{"additionalEvSel3", true, "Additional evsel3"}; Configurable additionalEvSel4{"additionalEvSel4", true, "Additional evsel4"}; + Configurable additionalEvSel5{"additionalEvSel5", true, "Additional evsel5"}; + Configurable additionalEvSel6{"additionalEvSel6", true, "Additional evsel6"}; Configurable cfgMultFT0{"cfgMultFT0", true, "cfgMultFT0"}; Configurable iscustomDCAcut{"iscustomDCAcut", false, "iscustomDCAcut"}; Configurable ismanualDCAcut{"ismanualDCAcut", true, "ismanualDCAcut"}; Configurable ispTdepPID{"ispTdepPID", true, "pT dependent PID"}; Configurable cfgITScluster{"cfgITScluster", 0, "Number of ITS cluster"}; Configurable confRapidity{"confRapidity", 0.5, "Rapidity cut"}; + Configurable rapiditycut1{"rapiditycut1", -1.0f, "Rapidity cut lower"}; + Configurable rapiditycut2{"rapiditycut2", 1.0f, "Rapidity cut upper"}; Configurable timFrameEvsel{"timFrameEvsel", false, "TPC Time frame boundary cut"}; Configurable isDeepAngle{"isDeepAngle", false, "Deep Angle cut"}; Configurable cfgDeepAngle{"cfgDeepAngle", 0.04, "Deep Angle cut value"}; Configurable nBkgRotations{"nBkgRotations", 3, "Number of rotated copies (background) per each original candidate"}; Configurable fillRotation{"fillRotation", true, "fill rotation"}; - Configurable confMinRot{"confMinRot", 5.0 * TMath::Pi() / 6.0, "Minimum of rotation"}; - Configurable confMaxRot{"confMaxRot", 7.0 * TMath::Pi() / 6.0, "Maximum of rotation"}; - Configurable PDGcheck{"PDGcheck", true, "PDGcheck"}; - Configurable Reco{"Reco", true, "Reco"}; + Configurable confMinRot{"confMinRot", 5.0f * TMath::Pi() / 6.0f, "Minimum of rotation"}; + Configurable confMaxRot{"confMaxRot", 7.0f * TMath::Pi() / 6.0f, "Maximum of rotation"}; + Configurable pdgcheck{"pdgcheck", true, "pdgcheck"}; + Configurable reco{"reco", true, "reco"}; ConfigurableAxis binsImpactPar{"binsImpactPar", {VARIABLE_WIDTH, 0, 3.5, 5.67, 7.45, 8.85, 10.0, 11.21, 12.26, 13.28, 14.23, 15.27}, "Binning of the impact parameter axis"}; ConfigurableAxis binsPt{"binsPt", {VARIABLE_WIDTH, 0.0, 0.1, 0.2, 0.3, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 10.0, 12.0}, "Binning of the pT axis"}; ConfigurableAxis binsCent{"binsCent", {VARIABLE_WIDTH, 0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 110.0}, "Binning of the centrality axis"}; @@ -167,12 +171,25 @@ struct phianalysisrun3_PbPb { histos.add("h1Phi1massrec", "Phi meson Rec", kTH1F, {{200, 0.9, 1.1}}); histos.add("h1Phipt", "Phi meson Rec", kTH1F, {{200, 0.0f, 20.0f}}); histos.add("hOccupancy1", "Occupancy distribution", kTH1F, {{500, 0, 50000}}); + histos.add("h1PhifinalRec", "Phi meson Rec", kTH1F, {{200, 0.0f, 20.0f}}); + histos.add("h1Phifinalgenmass", "Phi meson gen mass", kTH1F, {{200, 0.9, 1.1}}); + histos.add("h3PhifinalRec", "Phi meson Rec", kTH3F, {{200, 0.0f, 20.0f}, {200, 0.0, 200.0}, {200, 0.9, 1.1}}); + histos.add("h1PhifinalGen", "Phi meson Gen", kTH1F, {{200, 0.0f, 20.0f}}); + histos.add("h2PhifinalGen", "Phi meson Gen", kTH2F, {{200, 0.0f, 20.0f}, {200, 0.0, 200.0}}); + histos.add("hMC1", "MC Event statistics", kTH1F, {{15, 0.0f, 15.0f}}); + histos.add("Centrec1", "MC Centrality", kTH1F, {{200, 0.0, 200.0}}); + histos.add("Centgen1", "MC Centrality", kTH1F, {{200, 0.0, 200.0}}); + histos.add("h1PhiRecsplit1", "Phi meson Rec split", kTH1F, {{200, 0.0f, 20.0f}}); histos.add("hImpactParameterGen", "Impact parameter of generated MC events", kTH1F, {impactParAxis}); histos.add("hImpactParameterRec", "Impact parameter of generated MC events", kTH1F, {impactParAxis}); histos.add("hImpactParameterGenCen", "Impact parameter of generated MC events", kTH2F, {impactParAxis, centAxis}); histos.add("hImpactParameterRecCen", "Impact parameter of generated MC events", kTH2F, {impactParAxis, centAxis}); histos.add("TOF_Nsigma_MC", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); histos.add("TPC_Nsigma_MC", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); + histos.add("TOF_Nsigma1_MC", "TOF NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TOF}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); + histos.add("TPC_Nsigma1_MC", "TPC NSigma for Kaon;#it{p}_{T} (GeV/#it{c});#sigma_{TPC}^{Kaon};", {HistType::kTH3D, {{200, -12, 12}, {200, 0.0, 200.0}, {200, 0.0f, 20.0f}}}); + histos.add("trkDCAxy", "DCAxy distribution of positive kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); + histos.add("trkDCAz", "DCAxy distribution of negative kaon track candidates", HistType::kTH1F, {{150, -1.0f, 1.0f}}); if (doprocessEvtLossSigLossMC) { histos.add("QAevent/hImpactParameterGen", "Impact parameter of generated MC events", kTH1F, {impactParAxis}); histos.add("QAevent/hImpactParameterRec", "Impact parameter of selected MC events", kTH1F, {impactParAxis}); @@ -255,10 +272,10 @@ struct phianalysisrun3_PbPb { if (!isNoTOF && candidate.hasTOF() && (candidate.tofNSigmaKa() * candidate.tofNSigmaKa() + candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa()) < (nsigmaCutCombined * nsigmaCutCombined)) { return true; } - if (!isNoTOF && !candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { + if (!isNoTOF && !candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < nsigmacutTPC) { return true; } - if (isNoTOF && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { + if (isNoTOF && std::abs(candidate.tpcNSigmaKa()) < nsigmacutTPC) { return true; } return false; @@ -266,10 +283,10 @@ struct phianalysisrun3_PbPb { template bool selectionPIDpTdependent(const T& candidate) { - if (!candidate.hasTOF() && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC) { + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < nsigmacutTPC) { return true; } - if (candidate.hasTOF() && TMath::Abs(candidate.tpcNSigmaKa()) < nsigmaCutTPC && TMath::Abs(candidate.tofNSigmaKa()) < nsigmaCutTOF) { + if (candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < nsigmacutTPC && std::abs(candidate.tofNSigmaKa()) < nsigmacutTOF) { return true; } return false; @@ -279,17 +296,32 @@ struct phianalysisrun3_PbPb { { if (std::abs(collision.posZ()) > cfgCutVertex) return false; + if (!collision.sel8()) return false; - if (additionalEvSel2 && (!collision.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) + + if (additionalEvSel1 && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) + return false; + + if (additionalEvSel2 && !collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) + return false; + + if (additionalEvSel3 && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) + return false; + + if (additionalEvSel4 && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) + return false; + if (additionalEvSel5 && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) return false; - if (additionalEvSel3 && (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard))) + if (additionalEvSel6 && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) return false; int occupancy = collision.trackOccupancyInTimeRange(); if (fillOccupancy && (occupancy > cfgCutOccupancy)) return false; + return true; } + // deep angle cut on pair to remove photon conversion template bool selectionPair(const T1& candidate1, const T2& candidate2) @@ -301,26 +333,37 @@ struct phianalysisrun3_PbPb { pz2 = candidate2.pz(); p1 = candidate1.p(); p2 = candidate2.p(); - angle = TMath::ACos((pt1 * pt2 + pz1 * pz2) / (p1 * p2)); + angle = std::acos((pt1 * pt2 + pz1 * pz2) / (p1 * p2)); if (isDeepAngle && angle < cfgDeepAngle) { return false; } return true; } template - void FillinvMass(const T1& candidate1, const T2& candidate2, float multiplicity, bool unlike, bool mix, float massd1, float massd2) + void fillinvMass(const T1& candidate1, const T2& candidate2, float multiplicity, bool unlike, bool mix, float massd1, float massd2) { - pvec0 = array{candidate1.px(), candidate1.py(), candidate1.pz()}; - pvec1 = array{candidate2.px(), candidate2.py(), candidate2.pz()}; - auto arrMom = array{pvec0, pvec1}; + pvec0 = std::array{candidate1.px(), candidate1.py(), candidate1.pz()}; + pvec1 = std::array{candidate2.px(), candidate2.py(), candidate2.pz()}; + auto arrMom = std::array, 2>{pvec0, pvec1}; + int track1Sign = candidate1.sign(); int track2Sign = candidate2.sign(); - mass = RecoDecay::m(arrMom, array{massd1, massd2}); - pT = RecoDecay::pt(array{candidate1.px() + candidate2.px(), candidate1.py() + candidate2.py()}); - rapidity = RecoDecay::y(array{candidate1.px() + candidate2.px(), candidate1.py() + candidate2.py(), candidate1.pz() + candidate2.pz()}, mass); + mass = RecoDecay::m(arrMom, std::array{massd1, massd2}); + + pT = RecoDecay::pt(std::array{ + candidate1.px() + candidate2.px(), + candidate1.py() + candidate2.py()}); + + rapidity = RecoDecay::y(std::array{ + candidate1.px() + candidate2.px(), + candidate1.py() + candidate2.py(), + candidate1.pz() + candidate2.pz()}, + mass); + + constexpr int kOppositeCharge = 0; // default filling - if (std::abs(rapidity) < 0.5 && track1Sign * track2Sign < 0) { + if (rapidity > rapiditycut1 && rapidity < rapiditycut2 && track1Sign * track2Sign < kOppositeCharge) { if (unlike) { histos.fill(HIST("h3PhiInvMassUnlikeSign"), multiplicity, pT, mass); histos.fill(HIST("h2PhiRapidity"), pT, rapidity); @@ -332,13 +375,13 @@ struct phianalysisrun3_PbPb { } Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; Filter acceptanceFilter = (nabs(aod::track::eta) < cfgCutEta && nabs(aod::track::pt) > cfgCutPT); - Filter DCAcutFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + Filter dcacutFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz); using EventCandidates = soa::Filtered>; using TrackCandidates = soa::Filtered>; // using EventCandidatesMC = soa::Join; - using EventCandidatesMC = soa::Join; + using EventCandidatesMC = soa::Join; using TrackCandidatesMC = soa::Filtered>; @@ -359,7 +402,7 @@ struct phianalysisrun3_PbPb { using BinningTypeVertexContributor2 = ColumnBinningPolicy; using BinningTypeVertexContributor3 = ColumnBinningPolicy; using BinningTypeVertexContributor4 = ColumnBinningPolicy; - ROOT::Math::PxPyPzMVector PhiMesonMother, KaonPlus, KaonMinus; + ROOT::Math::PxPyPzMVector phiMesonMother, kaonPlus, kaonMinus; void processSameEvent(EventCandidates::iterator const& collision, TrackCandidates const& tracks, aod::BCs const&) { histos.fill(HIST("hEvtSelInfo"), 0.5); @@ -387,26 +430,39 @@ struct phianalysisrun3_PbPb { return; } histos.fill(HIST("hEvtSelInfo"), 6.5); + if (additionalEvSel5 && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return; + } + histos.fill(HIST("hEvtSelInfo"), 7.5); + if (additionalEvSel6 && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + return; + } + histos.fill(HIST("hEvtSelInfo"), 8.5); int occupancy = collision.trackOccupancyInTimeRange(); if (fillOccupancy && (occupancy > cfgCutOccupancy)) { return; } - histos.fill(HIST("hEvtSelInfo"), 7.5); + histos.fill(HIST("hEvtSelInfo"), 9.5); float multiplicity{-1}; - if (centestimator == 0) { + const int kCentFT0C = 0; + const int kCentFT0A = 1; + const int kCentFT0M = 2; + const int kCentFV0A = 3; + + if (centestimator == kCentFT0C) { multiplicity = collision.centFT0C(); - } else if (centestimator == 1) { + } else if (centestimator == kCentFT0A) { multiplicity = collision.centFT0A(); - } else if (centestimator == 2) { + } else if (centestimator == kCentFT0M) { multiplicity = collision.centFT0M(); - } else if (centestimator == 3) { + } else if (centestimator == kCentFV0A) { multiplicity = collision.centFV0A(); } histos.fill(HIST("hCentrality"), multiplicity); histos.fill(HIST("hVtxZ"), collision.posZ()); histos.fill(HIST("hOccupancy"), occupancy); - for (auto track1 : tracks) { + for (const auto& track1 : tracks) { if (!selectionTrack(track1)) { continue; } @@ -433,7 +489,7 @@ struct phianalysisrun3_PbPb { } auto track1ID = track1.globalIndex(); - for (auto track2 : tracks) { + for (const auto& track2 : tracks) { if (!selectionTrack(track2)) { continue; } @@ -467,7 +523,7 @@ struct phianalysisrun3_PbPb { histos.fill(HIST("QAafter/TOF_TPC_Mapka_all_neg"), track1.tofNSigmaKa(), track1.tpcNSigmaKa()); } - FillinvMass(track1, track2, multiplicity, unlike, mix, massKa, massKa); + fillinvMass(track1, track2, multiplicity, unlike, mix, massKa, massKa); } if (ispTdepPID && selectionPIDpTdependent(track1) && selectionPIDpTdependent(track2)) { @@ -491,7 +547,7 @@ struct phianalysisrun3_PbPb { histos.fill(HIST("QAafter/TOF_TPC_Mapka_all_neg"), track1.tofNSigmaKa(), track1.tpcNSigmaKa()); } - FillinvMass(track1, track2, multiplicity, unlike, mix, massKa, massKa); + fillinvMass(track1, track2, multiplicity, unlike, mix, massKa, massKa); } } } @@ -504,7 +560,7 @@ struct phianalysisrun3_PbPb { //////// currently mixing the event with similar TPC multiplicity //////// BinningTypeVertexContributor1 binningOnPositions{{axisVertex, axisMultiplicity}, true}; SameKindPair pair{binningOnPositions, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; - for (auto& [c1, tracks1, c2, tracks2] : pair) { + for (const auto& [c1, tracks1, c2, tracks2] : pair) { if (rctCut.requireRCTFlagChecker && !rctChecker(c1)) { continue; } @@ -529,6 +585,12 @@ struct phianalysisrun3_PbPb { if (additionalEvSel4 && (!c1.selection_bit(aod::evsel::kIsGoodITSLayersAll) || !c2.selection_bit(aod::evsel::kIsGoodITSLayersAll))) { continue; } + if (additionalEvSel5 && (!c1.selection_bit(aod::evsel::kNoCollInTimeRangeStandard) || !c2.selection_bit(aod::evsel::kNoCollInTimeRangeStandard))) { + continue; + } + if (additionalEvSel6 && (!c1.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !c2.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { + continue; + } int occupancy1 = c1.trackOccupancyInTimeRange(); int occupancy2 = c2.trackOccupancyInTimeRange(); @@ -537,7 +599,7 @@ struct phianalysisrun3_PbPb { } float multiplicity; multiplicity = c1.centFT0C(); - for (auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { + for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { bool unlike = false; bool mix = true; if (!selectionTrack(t1)) { @@ -550,10 +612,10 @@ struct phianalysisrun3_PbPb { continue; } if (!ispTdepPID && selectionPID(t1) && selectionPID(t2)) { - FillinvMass(t1, t2, multiplicity, unlike, mix, massKa, massKa); + fillinvMass(t1, t2, multiplicity, unlike, mix, massKa, massKa); } if (ispTdepPID && selectionPIDpTdependent(t1) && selectionPIDpTdependent(t2)) { - FillinvMass(t1, t2, multiplicity, unlike, mix, massKa, massKa); + fillinvMass(t1, t2, multiplicity, unlike, mix, massKa, massKa); } } } @@ -565,7 +627,7 @@ struct phianalysisrun3_PbPb { //////// currently mixing the event with similar TPC multiplicity //////// BinningTypeVertexContributor2 binningOnPositions{{axisVertex, axisMultiplicity}, true}; SameKindPair pair{binningOnPositions, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; - for (auto& [c1, tracks1, c2, tracks2] : pair) { + for (const auto& [c1, tracks1, c2, tracks2] : pair) { if (rctCut.requireRCTFlagChecker && !rctChecker(c1)) { continue; } @@ -590,6 +652,12 @@ struct phianalysisrun3_PbPb { if (additionalEvSel4 && (!c1.selection_bit(aod::evsel::kIsGoodITSLayersAll) || !c2.selection_bit(aod::evsel::kIsGoodITSLayersAll))) { continue; } + if (additionalEvSel5 && (!c1.selection_bit(aod::evsel::kNoCollInTimeRangeStandard) || !c2.selection_bit(aod::evsel::kNoCollInTimeRangeStandard))) { + continue; + } + if (additionalEvSel6 && (!c1.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !c2.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { + continue; + } int occupancy1 = c1.trackOccupancyInTimeRange(); int occupancy2 = c2.trackOccupancyInTimeRange(); @@ -598,7 +666,7 @@ struct phianalysisrun3_PbPb { } float multiplicity; multiplicity = c1.centFT0A(); - for (auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { + for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { bool unlike = false; bool mix = true; if (!selectionTrack(t1)) { @@ -611,10 +679,10 @@ struct phianalysisrun3_PbPb { continue; } if (!ispTdepPID && selectionPID(t1) && selectionPID(t2)) { - FillinvMass(t1, t2, multiplicity, unlike, mix, massKa, massKa); + fillinvMass(t1, t2, multiplicity, unlike, mix, massKa, massKa); } if (ispTdepPID && selectionPIDpTdependent(t1) && selectionPIDpTdependent(t2)) { - FillinvMass(t1, t2, multiplicity, unlike, mix, massKa, massKa); + fillinvMass(t1, t2, multiplicity, unlike, mix, massKa, massKa); } } } @@ -627,7 +695,7 @@ struct phianalysisrun3_PbPb { //////// currently mixing the event with similar TPC multiplicity //////// BinningTypeVertexContributor3 binningOnPositions{{axisVertex, axisMultiplicity}, true}; SameKindPair pair{binningOnPositions, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; - for (auto& [c1, tracks1, c2, tracks2] : pair) { + for (const auto& [c1, tracks1, c2, tracks2] : pair) { if (rctCut.requireRCTFlagChecker && !rctChecker(c1)) { continue; } @@ -652,6 +720,12 @@ struct phianalysisrun3_PbPb { if (additionalEvSel4 && (!c1.selection_bit(aod::evsel::kIsGoodITSLayersAll) || !c2.selection_bit(aod::evsel::kIsGoodITSLayersAll))) { continue; } + if (additionalEvSel5 && (!c1.selection_bit(aod::evsel::kNoCollInTimeRangeStandard) || !c2.selection_bit(aod::evsel::kNoCollInTimeRangeStandard))) { + continue; + } + if (additionalEvSel6 && (!c1.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !c2.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { + continue; + } int occupancy1 = c1.trackOccupancyInTimeRange(); int occupancy2 = c2.trackOccupancyInTimeRange(); @@ -660,7 +734,7 @@ struct phianalysisrun3_PbPb { } float multiplicity; multiplicity = c1.centFT0M(); - for (auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { + for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { bool unlike = false; bool mix = true; if (!selectionTrack(t1)) { @@ -673,10 +747,10 @@ struct phianalysisrun3_PbPb { continue; } if (!ispTdepPID && selectionPID(t1) && selectionPID(t2)) { - FillinvMass(t1, t2, multiplicity, unlike, mix, massKa, massKa); + fillinvMass(t1, t2, multiplicity, unlike, mix, massKa, massKa); } if (ispTdepPID && selectionPIDpTdependent(t1) && selectionPIDpTdependent(t2)) { - FillinvMass(t1, t2, multiplicity, unlike, mix, massKa, massKa); + fillinvMass(t1, t2, multiplicity, unlike, mix, massKa, massKa); } } } @@ -689,7 +763,7 @@ struct phianalysisrun3_PbPb { //////// currently mixing the event with similar TPC multiplicity //////// BinningTypeVertexContributor4 binningOnPositions{{axisVertex, axisMultiplicity}, true}; SameKindPair pair{binningOnPositions, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; - for (auto& [c1, tracks1, c2, tracks2] : pair) { + for (const auto& [c1, tracks1, c2, tracks2] : pair) { if (rctCut.requireRCTFlagChecker && !rctChecker(c1)) { continue; } @@ -714,6 +788,12 @@ struct phianalysisrun3_PbPb { if (additionalEvSel4 && (!c1.selection_bit(aod::evsel::kIsGoodITSLayersAll) || !c2.selection_bit(aod::evsel::kIsGoodITSLayersAll))) { continue; } + if (additionalEvSel5 && (!c1.selection_bit(aod::evsel::kNoCollInTimeRangeStandard) || !c2.selection_bit(aod::evsel::kNoCollInTimeRangeStandard))) { + continue; + } + if (additionalEvSel6 && (!c1.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !c2.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { + continue; + } int occupancy1 = c1.trackOccupancyInTimeRange(); int occupancy2 = c2.trackOccupancyInTimeRange(); @@ -722,7 +802,7 @@ struct phianalysisrun3_PbPb { } float multiplicity; multiplicity = c1.centFV0A(); - for (auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { + for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { bool unlike = false; bool mix = true; if (!selectionTrack(t1)) { @@ -735,10 +815,10 @@ struct phianalysisrun3_PbPb { continue; } if (!ispTdepPID && selectionPID(t1) && selectionPID(t2)) { - FillinvMass(t1, t2, multiplicity, unlike, mix, massKa, massKa); + fillinvMass(t1, t2, multiplicity, unlike, mix, massKa, massKa); } if (ispTdepPID && selectionPIDpTdependent(t1) && selectionPIDpTdependent(t2)) { - FillinvMass(t1, t2, multiplicity, unlike, mix, massKa, massKa); + fillinvMass(t1, t2, multiplicity, unlike, mix, massKa, massKa); } } } @@ -766,7 +846,8 @@ struct phianalysisrun3_PbPb { histos.fill(HIST("hCentrality"), multiplicity); histos.fill(HIST("hVtxZ"), collision.posZ()); histos.fill(HIST("hOccupancy"), occupancy); - for (auto track1 : tracks) { + for (const auto& track1 : tracks) { + if (!selectionTrack(track1)) { continue; } @@ -777,7 +858,7 @@ struct phianalysisrun3_PbPb { histos.fill(HIST("QAbefore/TOF_TPC_Mapka_all"), track1.tofNSigmaKa(), track1.tpcNSigmaKa()); auto track1ID = track1.globalIndex(); - for (auto track2 : tracks) { + for (const auto& track2 : tracks) { if (!selectionTrack(track2)) { continue; } @@ -795,14 +876,14 @@ struct phianalysisrun3_PbPb { continue; } if (track1.sign() * track2.sign() < 0) { - KaonPlus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); - KaonMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); + kaonPlus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); + kaonMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); } - PhiMesonMother = KaonPlus + KaonMinus; - if (TMath::Abs(PhiMesonMother.Rapidity()) > confRapidity) { + phiMesonMother = kaonPlus + kaonMinus; + if (std::abs(phiMesonMother.Rapidity()) > confRapidity) { continue; } - histos.fill(HIST("h3PhiInvMassSame"), multiplicity, PhiMesonMother.pt(), PhiMesonMother.M()); + histos.fill(HIST("h3PhiInvMassSame"), multiplicity, phiMesonMother.pt(), phiMesonMother.M()); if (fillRotation) { for (int nrotbkg = 0; nrotbkg < nBkgRotations; nrotbkg++) { auto anglestart = confMinRot; @@ -812,14 +893,14 @@ struct phianalysisrun3_PbPb { if (track1.sign() * track2.sign() < 0) { auto rotkaonPx = track1.px() * std::cos(rotangle) - track1.py() * std::sin(rotangle); auto rotkaonPy = track1.px() * std::sin(rotangle) + track1.py() * std::cos(rotangle); - KaonPlus = ROOT::Math::PxPyPzMVector(rotkaonPx, rotkaonPy, track1.pz(), massKa); - KaonMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); + kaonPlus = ROOT::Math::PxPyPzMVector(rotkaonPx, rotkaonPy, track1.pz(), massKa); + kaonMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); } - PhiMesonMother = KaonPlus + KaonMinus; - if (TMath::Abs(PhiMesonMother.Rapidity()) > confRapidity) { + phiMesonMother = kaonPlus + kaonMinus; + if (std::abs(phiMesonMother.Rapidity()) > confRapidity) { continue; } - histos.fill(HIST("h3PhiInvMassRot"), multiplicity, PhiMesonMother.pt(), PhiMesonMother.M()); + histos.fill(HIST("h3PhiInvMassRot"), multiplicity, phiMesonMother.pt(), phiMesonMother.M()); } } } @@ -838,7 +919,7 @@ struct phianalysisrun3_PbPb { histos.fill(HIST("hMC"), 2); return; } - for (auto& RecCollision : RecCollisions) { + for (const auto& RecCollision : RecCollisions) { histos.fill(HIST("hMC"), 3); if (!RecCollision.sel8()) { histos.fill(HIST("hMC"), 4); @@ -855,16 +936,16 @@ struct phianalysisrun3_PbPb { if (fillOccupancy && (occupancy > cfgCutOccupancy)) { continue; } - if (TMath::Abs(RecCollision.posZ()) > cfgCutVertex) { + if (std::abs(RecCollision.posZ()) > cfgCutVertex) { histos.fill(HIST("hMC"), 6); continue; } histos.fill(HIST("hMC"), 7); auto centrality = RecCollision.centFT0C(); auto oldindex = -999; - auto Rectrackspart = RecTracks.sliceBy(perCollision, RecCollision.globalIndex()); + auto rectrackspart = RecTracks.sliceBy(perCollision, RecCollision.globalIndex()); // loop over reconstructed particle - for (auto track1 : Rectrackspart) { + for (const auto& track1 : rectrackspart) { if (!selectionTrack(track1)) { continue; } @@ -878,7 +959,7 @@ struct phianalysisrun3_PbPb { continue; } auto track1ID = track1.index(); - for (auto track2 : Rectrackspart) { + for (const auto& track2 : rectrackspart) { auto track2ID = track2.index(); if (track2ID <= track1ID) { continue; @@ -903,29 +984,29 @@ struct phianalysisrun3_PbPb { } const auto mctrack1 = track1.mcParticle(); const auto mctrack2 = track2.mcParticle(); - int track1PDG = TMath::Abs(mctrack1.pdgCode()); - int track2PDG = TMath::Abs(mctrack2.pdgCode()); + int track1PDG = std::abs(mctrack1.pdgCode()); + int track2PDG = std::abs(mctrack2.pdgCode()); if (!mctrack1.isPhysicalPrimary()) { continue; } if (!mctrack2.isPhysicalPrimary()) { continue; } - if (!(track1PDG == 321 && track2PDG == 321)) { + if (!(track1PDG == PDG_t::kKPlus && track2PDG == PDG_t::kKPlus)) { continue; } - for (auto& mothertrack1 : mctrack1.mothers_as()) { - for (auto& mothertrack2 : mctrack2.mothers_as()) { + for (const auto& mothertrack1 : mctrack1.mothers_as()) { + for (const auto& mothertrack2 : mctrack2.mothers_as()) { if (mothertrack1.pdgCode() != mothertrack2.pdgCode()) { continue; } if (mothertrack1 != mothertrack2) { continue; } - if (TMath::Abs(mothertrack1.y()) > confRapidity) { + if (std::abs(mothertrack1.y()) > confRapidity) { continue; } - if (PDGcheck && TMath::Abs(mothertrack1.pdgCode()) != 333) { + if (pdgcheck && std::abs(mothertrack1.pdgCode()) != o2::constants::physics::kPhi) { continue; } if (!ispTdepPID && (!selectionPID(track1) || !selectionPID(track2))) { @@ -940,65 +1021,68 @@ struct phianalysisrun3_PbPb { } oldindex = mothertrack1.globalIndex(); if (track1.sign() * track2.sign() < 0) { - KaonPlus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); - KaonMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); + kaonPlus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); + kaonMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); } - PhiMesonMother = KaonPlus + KaonMinus; + phiMesonMother = kaonPlus + kaonMinus; - if (TMath::Abs(PhiMesonMother.Rapidity()) > confRapidity) { + if (std::abs(phiMesonMother.Rapidity()) > confRapidity) { continue; } - histos.fill(HIST("h1PhiRec1"), PhiMesonMother.pt()); - histos.fill(HIST("h2PhiRec2"), PhiMesonMother.pt(), centrality); - histos.fill(HIST("h1Phimassrec"), PhiMesonMother.M()); - histos.fill(HIST("h3PhiRec3"), PhiMesonMother.pt(), centrality, PhiMesonMother.M()); + histos.fill(HIST("h1PhiRec1"), phiMesonMother.pt()); + histos.fill(HIST("h2PhiRec2"), phiMesonMother.pt(), centrality); + histos.fill(HIST("h1Phimassrec"), phiMesonMother.M()); + histos.fill(HIST("h3PhiRec3"), phiMesonMother.pt(), centrality, phiMesonMother.M()); histos.fill(HIST("Centrec"), centrality); } } } } // loop over generated particle - for (auto& mcParticle : GenParticles) { - if (TMath::Abs(mcParticle.y()) > confRapidity) { + for (const auto& mcParticle : GenParticles) { + if (std::abs(mcParticle.y()) > confRapidity) { continue; } - if (PDGcheck && mcParticle.pdgCode() != 333) { + if (pdgcheck && mcParticle.pdgCode() != o2::constants::physics::kPhi) { continue; } auto kDaughters = mcParticle.daughters_as(); - if (kDaughters.size() != 2) { + const size_t kExpectedDaughterCount = 2; + + if (kDaughters.size() != kExpectedDaughterCount) { + continue; } auto daughtp = false; auto daughtm = false; - for (auto kCurrentDaughter : kDaughters) { + for (const auto& kCurrentDaughter : kDaughters) { if (!kCurrentDaughter.isPhysicalPrimary()) { continue; } - if (kCurrentDaughter.pdgCode() == +321) { - if (genacceptancecut && kCurrentDaughter.pt() > cfgCutPT && TMath::Abs(kCurrentDaughter.eta()) < cfgCutEta) { + if (kCurrentDaughter.pdgCode() == PDG_t::kKPlus) { + if (genacceptancecut && kCurrentDaughter.pt() > cfgCutPT && std::abs(kCurrentDaughter.eta()) < cfgCutEta) { daughtp = true; } if (!genacceptancecut) { daughtp = true; } - KaonPlus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); - } else if (kCurrentDaughter.pdgCode() == -321) { - if (genacceptancecut && kCurrentDaughter.pt() > cfgCutPT && TMath::Abs(kCurrentDaughter.eta()) < cfgCutEta) { + kaonPlus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); + } else if (kCurrentDaughter.pdgCode() == PDG_t::kKMinus) { + if (genacceptancecut && kCurrentDaughter.pt() > cfgCutPT && std::abs(kCurrentDaughter.eta()) < cfgCutEta) { daughtm = true; } if (!genacceptancecut) { daughtm = true; } - KaonMinus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); + kaonMinus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); } } if (daughtp && daughtm) { - PhiMesonMother = KaonPlus + KaonMinus; - histos.fill(HIST("h1PhiGen"), PhiMesonMother.pt()); - histos.fill(HIST("h2PhiGen2"), PhiMesonMother.pt(), centrality); + phiMesonMother = kaonPlus + kaonMinus; + histos.fill(HIST("h1PhiGen"), phiMesonMother.pt()); + histos.fill(HIST("h2PhiGen2"), phiMesonMother.pt(), centrality); histos.fill(HIST("Centgen"), centrality); - histos.fill(HIST("h1Phimassgen"), PhiMesonMother.M()); + histos.fill(HIST("h1Phimassgen"), phiMesonMother.M()); } } } // rec collision loop @@ -1014,7 +1098,7 @@ struct phianalysisrun3_PbPb { } float imp = mcCollision.impactParameter(); histos.fill(HIST("hImpactParameterGen"), imp); - std::vector SelectedEvents(collisions.size()); + std::vector selectedEvents(collisions.size()); int nevts = 0; auto multiplicity = 0; for (const auto& collision : collisions) { @@ -1034,51 +1118,57 @@ struct phianalysisrun3_PbPb { histos.fill(HIST("hVtxZgen"), collision.mcCollision().posZ()); histos.fill(HIST("hImpactParameterGenCen"), imp, multiplicity); - SelectedEvents[nevts++] = collision.mcCollision_as().globalIndex(); + selectedEvents[nevts++] = collision.mcCollision_as().globalIndex(); histos.fill(HIST("hMC"), 2.5); } - SelectedEvents.resize(nevts); + selectedEvents.resize(nevts); - const auto evtReconstructedAndSelected = std::find(SelectedEvents.begin(), SelectedEvents.end(), mcCollision.globalIndex()) != SelectedEvents.end(); + const auto evtReconstructedAndSelected = std::find(selectedEvents.begin(), selectedEvents.end(), mcCollision.globalIndex()) != selectedEvents.end(); histos.fill(HIST("EL1"), imp); histos.fill(HIST("EL2"), multiplicity); - if (Reco && !evtReconstructedAndSelected) { // Check that the event is reconstructed and that the reconstructed events pass the selection + if (reco && !evtReconstructedAndSelected) { // Check that the event is reconstructed and that the reconstructed events pass the selection return; } histos.fill(HIST("ES1"), imp); histos.fill(HIST("ES2"), multiplicity); - for (auto& mcParticle : mcParticles) { - if (std::abs(mcParticle.y()) >= 0.5) { + for (const auto& mcParticle : mcParticles) { + const double kMaxAcceptedRapidity = 0.5; + + if (std::abs(mcParticle.y()) >= kMaxAcceptedRapidity) { + continue; } - if (PDGcheck && mcParticle.pdgCode() != 333) { + if (pdgcheck && mcParticle.pdgCode() != o2::constants::physics::kPhi) { continue; } auto kDaughters = mcParticle.daughters_as(); - if (kDaughters.size() != 2) { + const size_t kExpectedNumberOfDaughters = 2; + + if (kDaughters.size() != kExpectedNumberOfDaughters) { + continue; } auto daughtp = false; auto daughtm = false; - for (auto kCurrentDaughter : kDaughters) { + for (const auto& kCurrentDaughter : kDaughters) { if (!kCurrentDaughter.isPhysicalPrimary()) { continue; } - if (kCurrentDaughter.pdgCode() == +321) { + if (kCurrentDaughter.pdgCode() == PDG_t::kKPlus) { daughtp = true; - KaonPlus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); - } else if (kCurrentDaughter.pdgCode() == -321) { + kaonPlus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); + } else if (kCurrentDaughter.pdgCode() == PDG_t::kKMinus) { daughtm = true; - KaonMinus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); + kaonMinus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); } } if (daughtp && daughtm) { - PhiMesonMother = KaonPlus + KaonMinus; - histos.fill(HIST("h1PhiGen"), PhiMesonMother.pt()); - histos.fill(HIST("h2PhiGen2"), PhiMesonMother.pt(), multiplicity); - histos.fill(HIST("h2PhiGen1"), PhiMesonMother.pt(), imp); - histos.fill(HIST("h1Phimassgen"), PhiMesonMother.M()); - histos.fill(HIST("h3PhiGen3"), PhiMesonMother.pt(), multiplicity, PhiMesonMother.M()); + phiMesonMother = kaonPlus + kaonMinus; + histos.fill(HIST("h1PhiGen"), phiMesonMother.pt()); + histos.fill(HIST("h2PhiGen2"), phiMesonMother.pt(), multiplicity); + histos.fill(HIST("h2PhiGen1"), phiMesonMother.pt(), imp); + histos.fill(HIST("h1Phimassgen"), phiMesonMother.M()); + histos.fill(HIST("h3PhiGen3"), phiMesonMother.pt(), multiplicity, phiMesonMother.M()); } } } @@ -1107,7 +1197,7 @@ struct phianalysisrun3_PbPb { histos.fill(HIST("ES3"), imp); histos.fill(HIST("ES4"), multiplicity); auto oldindex = -999; - for (auto track1 : tracks) { + for (const auto& track1 : tracks) { if (!selectionTrack(track1)) { continue; } @@ -1115,7 +1205,7 @@ struct phianalysisrun3_PbPb { continue; } auto track1ID = track1.index(); - for (auto track2 : tracks) { + for (const auto& track2 : tracks) { if (!track2.has_mcParticle()) { continue; } @@ -1142,7 +1232,7 @@ struct phianalysisrun3_PbPb { if (!mctrack2.isPhysicalPrimary()) { continue; } - if (!(track1PDG == 321 && track2PDG == 321)) { + if (!(track1PDG == PDG_t::kKPlus && track2PDG == PDG_t::kKPlus)) { continue; } daughter1 = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); @@ -1151,8 +1241,8 @@ struct phianalysisrun3_PbPb { phiMother = daughter1 + daughter2; histos.fill(HIST("h1Phi1massrec"), phiMother.M()); histos.fill(HIST("h3Phi1Rec3"), phiMother.pt(), multiplicity, phiMother.M()); - for (auto& mothertrack1 : mctrack1.mothers_as()) { - for (auto& mothertrack2 : mctrack2.mothers_as()) { + for (const auto& mothertrack1 : mctrack1.mothers_as()) { + for (const auto& mothertrack2 : mctrack2.mothers_as()) { if (mothertrack1.pdgCode() != mothertrack2.pdgCode()) { continue; } @@ -1162,10 +1252,13 @@ struct phianalysisrun3_PbPb { if (!mothertrack1.producedByGenerator()) { continue; } - if (std::abs(mothertrack1.y()) >= 0.5) { + const double kMaxRapidityCut = 0.5; + + if (std::abs(mothertrack1.y()) >= kMaxRapidityCut) { continue; } - if (PDGcheck && std::abs(mothertrack1.pdgCode()) != 333) { + + if (pdgcheck && std::abs(mothertrack1.pdgCode()) != o2::constants::physics::kPhi) { continue; } if (!ispTdepPID && (!selectionPID(track1) || !selectionPID(track2))) { @@ -1183,18 +1276,18 @@ struct phianalysisrun3_PbPb { } oldindex = mothertrack1.globalIndex(); if (track1.sign() * track2.sign() < 0) { - KaonPlus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); - KaonMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); + kaonPlus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); + kaonMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); } - PhiMesonMother = KaonPlus + KaonMinus; + phiMesonMother = kaonPlus + kaonMinus; - if (TMath::Abs(PhiMesonMother.Rapidity()) > confRapidity) { + if (std::abs(phiMesonMother.Rapidity()) > confRapidity) { continue; } - histos.fill(HIST("h1PhiRec1"), PhiMesonMother.pt()); - histos.fill(HIST("h2PhiRec2"), PhiMesonMother.pt(), multiplicity); - histos.fill(HIST("h1Phimassrec"), PhiMesonMother.M()); - histos.fill(HIST("h3PhiRec3"), PhiMesonMother.pt(), multiplicity, PhiMesonMother.M()); + histos.fill(HIST("h1PhiRec1"), phiMesonMother.pt()); + histos.fill(HIST("h2PhiRec2"), phiMesonMother.pt(), multiplicity); + histos.fill(HIST("h1Phimassrec"), phiMesonMother.M()); + histos.fill(HIST("h3PhiRec3"), phiMesonMother.pt(), multiplicity, phiMesonMother.M()); } } } @@ -1207,10 +1300,22 @@ struct phianalysisrun3_PbPb { if (!collision.sel8()) { return; } - if (additionalEvSel2 && (!collision.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { + if (additionalEvSel1 && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { return; } - if (additionalEvSel3 && (!collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard))) { + if (additionalEvSel2 && !collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + return; + } + if (additionalEvSel3 && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { + return; + } + if (additionalEvSel4 && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + return; + } + if (additionalEvSel5 && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return; + } + if (additionalEvSel6 && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { return; } int occupancy = collision.trackOccupancyInTimeRange(); @@ -1219,12 +1324,12 @@ struct phianalysisrun3_PbPb { } float multiplicity{-1}; multiplicity = collision.centFT0C(); - for (auto track1 : tracks) { + for (const auto& track1 : tracks) { if (!selectionTrack(track1)) { continue; } auto track1ID = track1.globalIndex(); - for (auto track2 : tracks) { + for (const auto& track2 : tracks) { if (!selectionTrack(track2)) { continue; } @@ -1242,15 +1347,15 @@ struct phianalysisrun3_PbPb { continue; } if (track1.sign() * track2.sign() < 0) { - KaonPlus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); - KaonMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); + kaonPlus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); + kaonMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); } - PhiMesonMother = KaonPlus + KaonMinus; - if (TMath::Abs(PhiMesonMother.Rapidity()) > confRapidity) { + phiMesonMother = kaonPlus + kaonMinus; + if (std::abs(phiMesonMother.Rapidity()) > confRapidity) { continue; } - histos.fill(HIST("h3PhiInvMassSameMC"), multiplicity, PhiMesonMother.pt(), PhiMesonMother.M()); - histos.fill(HIST("h1Phimasssame"), PhiMesonMother.M()); + histos.fill(HIST("h3PhiInvMassSameMC"), multiplicity, phiMesonMother.pt(), phiMesonMother.M()); + histos.fill(HIST("h1Phimasssame"), phiMesonMother.M()); if (fillRotation) { for (int nrotbkg = 0; nrotbkg < nBkgRotations; nrotbkg++) { auto anglestart = confMinRot; @@ -1260,15 +1365,15 @@ struct phianalysisrun3_PbPb { if (track1.sign() * track2.sign() < 0) { auto rotkaonPx = track1.px() * std::cos(rotangle) - track1.py() * std::sin(rotangle); auto rotkaonPy = track1.px() * std::sin(rotangle) + track1.py() * std::cos(rotangle); - KaonPlus = ROOT::Math::PxPyPzMVector(rotkaonPx, rotkaonPy, track1.pz(), massKa); - KaonMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); + kaonPlus = ROOT::Math::PxPyPzMVector(rotkaonPx, rotkaonPy, track1.pz(), massKa); + kaonMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); } - PhiMesonMother = KaonPlus + KaonMinus; - if (TMath::Abs(PhiMesonMother.Rapidity()) > confRapidity) { + phiMesonMother = kaonPlus + kaonMinus; + if (std::abs(phiMesonMother.Rapidity()) > confRapidity) { continue; } - histos.fill(HIST("h3PhiInvMassRotMC"), multiplicity, PhiMesonMother.pt(), PhiMesonMother.M()); - histos.fill(HIST("h1Phimassrot"), PhiMesonMother.M()); + histos.fill(HIST("h3PhiInvMassRotMC"), multiplicity, phiMesonMother.pt(), phiMesonMother.M()); + histos.fill(HIST("h1Phimassrot"), phiMesonMother.M()); } } } @@ -1283,23 +1388,29 @@ struct phianalysisrun3_PbPb { BinningTypeVertexContributor1 binningOnPositions{{axisVertex, axisMultiplicity}, true}; SameKindPair pairs{binningOnPositions, cfgNoMixedEvents, -1, recCollisions, tracksTuple, &cache}; - for (auto& [c1, tracks1, c2, tracks2] : pairs) { + for (const auto& [c1, tracks1, c2, tracks2] : pairs) { if (!c1.sel8()) { continue; } if (!c2.sel8()) { continue; } - if (additionalEvSel2 && (!c1.selection_bit(aod::evsel::kNoSameBunchPileup) || !c1.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { + if (additionalEvSel1 && (!c1.selection_bit(aod::evsel::kNoTimeFrameBorder) || !c2.selection_bit(aod::evsel::kNoTimeFrameBorder))) { + continue; + } + if (additionalEvSel2 && (!c1.selection_bit(aod::evsel::kNoITSROFrameBorder) || !c2.selection_bit(aod::evsel::kNoITSROFrameBorder))) { continue; } - if (additionalEvSel2 && (!c2.selection_bit(aod::evsel::kNoSameBunchPileup) || !c2.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { + if (additionalEvSel3 && (!c1.selection_bit(aod::evsel::kNoSameBunchPileup) || !c2.selection_bit(aod::evsel::kNoSameBunchPileup))) { continue; } - if (additionalEvSel3 && (!c1.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard))) { + if (additionalEvSel4 && (!c1.selection_bit(aod::evsel::kIsGoodITSLayersAll) || !c2.selection_bit(aod::evsel::kIsGoodITSLayersAll))) { continue; } - if (additionalEvSel3 && (!c2.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard))) { + if (additionalEvSel5 && (!c1.selection_bit(aod::evsel::kNoCollInTimeRangeStandard) || !c2.selection_bit(aod::evsel::kNoCollInTimeRangeStandard))) { + continue; + } + if (additionalEvSel6 && (!c1.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !c2.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV))) { continue; } int occupancy1 = c1.trackOccupancyInTimeRange(); @@ -1311,7 +1422,7 @@ struct phianalysisrun3_PbPb { continue; } auto multiplicity = c1.centFT0C(); - for (auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { + for (const auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { histos.fill(HIST("hMC"), 6.5); if (!selectionTrack(t1)) { continue; @@ -1329,19 +1440,259 @@ struct phianalysisrun3_PbPb { continue; } if (t1.sign() * t2.sign() < 0) { - KaonPlus = ROOT::Math::PxPyPzMVector(t1.px(), t1.py(), t1.pz(), massKa); - KaonMinus = ROOT::Math::PxPyPzMVector(t2.px(), t2.py(), t2.pz(), massKa); + kaonPlus = ROOT::Math::PxPyPzMVector(t1.px(), t1.py(), t1.pz(), massKa); + kaonMinus = ROOT::Math::PxPyPzMVector(t2.px(), t2.py(), t2.pz(), massKa); } - PhiMesonMother = KaonPlus + KaonMinus; - if (TMath::Abs(PhiMesonMother.Rapidity()) > confRapidity) { + phiMesonMother = kaonPlus + kaonMinus; + if (std::abs(phiMesonMother.Rapidity()) > confRapidity) { continue; } - histos.fill(HIST("h3PhiInvMassMixedMC"), multiplicity, PhiMesonMother.pt(), PhiMesonMother.M()); - histos.fill(HIST("h1Phimassmix"), PhiMesonMother.M()); + histos.fill(HIST("h3PhiInvMassMixedMC"), multiplicity, phiMesonMother.pt(), phiMesonMother.M()); + histos.fill(HIST("h1Phimassmix"), phiMesonMother.M()); } } } PROCESS_SWITCH(phianalysisrun3_PbPb, processMixedEventMC, "Process Mixed event MC", true); + void processGen1(aod::McCollision const& mcCollision, aod::McParticles& mcParticles, const soa::SmallGroups& collisions) + { + histos.fill(HIST("hMC1"), 0.5); + if (std::abs(mcCollision.posZ()) < cfgCutVertex) { + histos.fill(HIST("hMC1"), 1.5); + } + std::vector selectedEvents(collisions.size()); + int nevts = 0; + auto multiplicity = -1.0; + histos.fill(HIST("hMC1"), 2.5); + for (const auto& collision : collisions) { + if (!collision.sel8() || std::abs(collision.mcCollision().posZ()) > cfgCutVertex) { + continue; + } + histos.fill(HIST("hMC1"), 3.5); + if (additionalEvSel1 && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { + continue; + } + histos.fill(HIST("hMC1"), 4.5); + if (additionalEvSel2 && !collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + continue; + } + histos.fill(HIST("hMC1"), 5.5); + if (additionalEvSel3 && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { + continue; + } + histos.fill(HIST("hMC1"), 6.5); + if (additionalEvSel4 && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + continue; + } + histos.fill(HIST("hMC1"), 7.5); + if (additionalEvSel5 && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + continue; + } + histos.fill(HIST("hMC1"), 8.5); + if (additionalEvSel6 && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + continue; + } + histos.fill(HIST("hMC1"), 9.5); + int occupancy = collision.trackOccupancyInTimeRange(); + if (fillOccupancy && (occupancy > cfgCutOccupancy)) { + continue; + } + histos.fill(HIST("hMC1"), 10.5); + const int kCentFT0C = 0; + const int kCentFT0A = 1; + const int kCentFT0M = 2; + const int kCentFV0A = 3; + + if (centestimator == kCentFT0C) { + multiplicity = collision.centFT0C(); + } else if (centestimator == kCentFT0A) { + multiplicity = collision.centFT0A(); + } else if (centestimator == kCentFT0M) { + multiplicity = collision.centFT0M(); + } else if (centestimator == kCentFV0A) { + multiplicity = collision.centFV0A(); + } + histos.fill(HIST("Centgen1"), multiplicity); + selectedEvents[nevts++] = collision.mcCollision_as().globalIndex(); + } + selectedEvents.resize(nevts); + const auto evtReconstructedAndSelected = std::find(selectedEvents.begin(), selectedEvents.end(), mcCollision.globalIndex()) != selectedEvents.end(); + histos.fill(HIST("hMC1"), 11.5); + if (!evtReconstructedAndSelected) { // Check that the event is reconstructed and that the reconstructed events pass the selection + return; + } + histos.fill(HIST("hMC1"), 12.5); + for (const auto& mcParticle : mcParticles) { + + if (mcParticle.y() < rapiditycut1 || mcParticle.y() > rapiditycut2) { + continue; + } + + if (mcParticle.pdgCode() != o2::constants::physics::kPhi) { + continue; + } + auto kDaughters = mcParticle.daughters_as(); + const size_t kExpectedNumberOfDaughters = 2; + + if (kDaughters.size() != kExpectedNumberOfDaughters) { + + continue; + } + auto daughtp = false; + auto daughtm = false; + for (const auto& kCurrentDaughter : kDaughters) { + if (!kCurrentDaughter.isPhysicalPrimary()) { + continue; + } + if (kCurrentDaughter.pdgCode() == PDG_t::kKPlus) { + daughtp = true; + } else if (kCurrentDaughter.pdgCode() == PDG_t::kKMinus) { + daughtm = true; + } + } + if (daughtp && daughtm) { + histos.fill(HIST("h1PhifinalGen"), mcParticle.pt()); + histos.fill(HIST("h2PhifinalGen"), mcParticle.pt(), multiplicity); + } + } + } + + PROCESS_SWITCH(phianalysisrun3_PbPb, processGen1, "Process Generated", false); + void processRec1(EventCandidatesMC::iterator const& collision, TrackCandidatesMC const& tracks, aod::McParticles const& /*mcParticles*/, aod::McCollisions const& /*mcCollisions*/) + { + if (!collision.has_mcCollision()) { + return; + } + if (std::abs(collision.mcCollision().posZ()) > cfgCutVertex || !collision.sel8()) { + return; + } + if (additionalEvSel1 && !collision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { + return; + } + + if (additionalEvSel2 && !collision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + return; + } + + if (additionalEvSel3 && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { + return; + } + + if (additionalEvSel4 && !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + return; + } + if (additionalEvSel5 && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { + return; + } + if (additionalEvSel6 && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + return; + } + int occupancy = collision.trackOccupancyInTimeRange(); + if (fillOccupancy && (occupancy > cfgCutOccupancy)) { + return; + } + const int kCentFT0C = 0; + const int kCentFT0A = 1; + const int kCentFT0M = 2; + const int kCentFV0A = 3; + auto multiplicity = -1.0; + if (centestimator == kCentFT0C) { + multiplicity = collision.centFT0C(); + } else if (centestimator == kCentFT0A) { + multiplicity = collision.centFT0A(); + } else if (centestimator == kCentFT0M) { + multiplicity = collision.centFT0M(); + } else if (centestimator == kCentFV0A) { + multiplicity = collision.centFV0A(); + } + histos.fill(HIST("Centrec1"), multiplicity); + histos.fill(HIST("hMC1"), 13.5); + auto oldindex = -999; + for (const auto& track1 : tracks) { + if (!selectionTrack(track1)) { + continue; + } + if (!track1.has_mcParticle()) { + continue; + } + auto track1ID = track1.index(); + for (const auto& track2 : tracks) { + if (!track2.has_mcParticle()) { + continue; + } + if (!selectionTrack(track2)) { + continue; + } + auto track2ID = track2.index(); + if (track2ID <= track1ID) { + continue; + } + if (!selectionPair(track1, track2)) { + continue; + } + if (track1.sign() * track2.sign() > 0) { + continue; + } + const auto mctrack1 = track1.mcParticle(); + const auto mctrack2 = track2.mcParticle(); + int track1PDG = std::abs(mctrack1.pdgCode()); + int track2PDG = std::abs(mctrack2.pdgCode()); + if (!mctrack1.isPhysicalPrimary()) { + continue; + } + if (!mctrack2.isPhysicalPrimary()) { + continue; + } + if (!(track1PDG == PDG_t::kKPlus && track2PDG == PDG_t::kKPlus)) { + continue; + } + for (const auto& mothertrack1 : mctrack1.mothers_as()) { + for (const auto& mothertrack2 : mctrack2.mothers_as()) { + if (mothertrack1.pdgCode() != mothertrack2.pdgCode()) { + continue; + } + if (mothertrack1.globalIndex() != mothertrack2.globalIndex()) { + continue; + } + if (!mothertrack1.producedByGenerator()) { + continue; + } + if (mothertrack1.y() < rapiditycut1 || mothertrack1.y() > rapiditycut2) { + continue; + } + if (std::abs(mothertrack1.pdgCode()) != o2::constants::physics::kPhi) { + continue; + } + if (!(selectionPID(track1) && selectionPID(track2))) { + continue; + } + histos.fill(HIST("TPC_Nsigma1_MC"), track1.tpcNSigmaKa(), multiplicity, track1.pt()); + histos.fill(HIST("TOF_Nsigma1_MC"), track1.tofNSigmaKa(), multiplicity, track1.pt()); + histos.fill(HIST("trkDCAxy"), track1.dcaXY()); + histos.fill(HIST("trkDCAz"), track1.dcaZ()); + if (avoidsplitrackMC && oldindex == mothertrack1.globalIndex()) { + histos.fill(HIST("h1PhiRecsplit1"), mothertrack1.pt()); + continue; + } + oldindex = mothertrack1.globalIndex(); + std::array pvec0 = {track1.px(), track1.py(), track1.pz()}; + std::array pvec1 = {track2.px(), track2.py(), track2.pz()}; + std::array, 2> arrMomrec = {pvec0, pvec1}; + + auto motherP = mothertrack1.p(); + auto motherE = mothertrack1.e(); + genMass = std::sqrt(motherE * motherE - motherP * motherP); + recMass = RecoDecay::m(arrMomrec, array{massKa, massKa}); + + histos.fill(HIST("h1PhifinalRec"), mothertrack1.pt()); + histos.fill(HIST("h3PhifinalRec"), mothertrack1.pt(), multiplicity, recMass); + histos.fill(HIST("h1Phifinalgenmass"), genMass); + } + } + } + } + } + + PROCESS_SWITCH(phianalysisrun3_PbPb, processRec1, "Process Reconstructed", false); void processEvtLossSigLossMC(aod::McCollisions::iterator const& mcCollision, aod::McParticles const& mcParticles, const soa::SmallGroups& recCollisions) { @@ -1365,7 +1716,10 @@ struct phianalysisrun3_PbPb { // Generated MC for (const auto& mcPart : mcParticles) { - if (std::abs(mcPart.y()) >= 0.5 || std::abs(mcPart.pdgCode()) != 333) + const double kMaxRapidity = 0.5; + + if (std::abs(mcPart.y()) >= kMaxRapidity || std::abs(mcPart.pdgCode()) != o2::constants::physics::kPhi) + continue; // signal loss estimation diff --git a/PWGLF/Tasks/Resonances/phipbpb.cxx b/PWGLF/Tasks/Resonances/phipbpb.cxx index 521e505ebd2..5ab2cc0e35e 100644 --- a/PWGLF/Tasks/Resonances/phipbpb.cxx +++ b/PWGLF/Tasks/Resonances/phipbpb.cxx @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -230,6 +231,12 @@ struct phipbpb { histos.add("hVtxZ", "Vertex distribution in Z;Z (cm)", kTH1F, {{400, -20.0, 20.0}}); if (!fillv1) { + + histos.add("hKaonpIsotropic", "hKaonpIsotropic", HistType::kTHnSparseD, {{8, 0.0, 80.0}, {100, 0.0, 10.0}, {8, -0.8, 0.8}, {36, 0.0, TMath::Pi()}}); + histos.add("hKaonpData", "hKaonpData", HistType::kTHnSparseD, {{8, 0.0, 80.0}, {100, 0.0, 10.0}, {8, -0.8, 0.8}, {36, 0.0, TMath::Pi()}}); + histos.add("hKaonmIsotropic", "hKaonmIsotropic", HistType::kTHnSparseD, {{8, 0.0, 80.0}, {100, 0.0, 10.0}, {8, -0.8, 0.8}, {36, 0.0, TMath::Pi()}}); + histos.add("hKaonmData", "hKaonmData", HistType::kTHnSparseD, {{8, 0.0, 80.0}, {100, 0.0, 10.0}, {8, -0.8, 0.8}, {36, 0.0, TMath::Pi()}}); + histos.add("hTPCglobalmomcorr", "Momentum correlation", kTH3F, {{200, -10.0f, 10.0f}, {200, -10.0f, 10.0f}, {8, 0.0f, 80.0f}}); histos.add("hpTvsRapidity", "pT vs Rapidity", kTH2F, {{100, 0.0f, 10.0f}, {300, -1.5f, 1.5f}}); histos.add("hFTOCvsTPCNoCut", "Mult correlation FT0C vs. TPC without any cut", kTH2F, {{80, 0.0f, 80.0f}, {100, -0.5f, 5999.5f}}); @@ -501,6 +508,24 @@ struct phipbpb { return false; } + void fillHisoWithTGenPS(const ROOT::Math::PxPyPzMVector& Pphi_lab, double psi2, double ptMin, double etaMax, double centrality) + { + TLorentzVector parent; + double masses[2] = {0.493, 0.493}; + parent.SetPxPyPzE(Pphi_lab.Px(), Pphi_lab.Py(), Pphi_lab.Pz(), Pphi_lab.E()); + TGenPhaseSpace gen; + gen.SetDecay(parent, 2, masses); + gen.Generate(); + + TLorentzVector* K1 = gen.GetDecay(0); + TLorentzVector* K2 = gen.GetDecay(1); + + if (K1->Pt() > ptMin && std::abs(K1->Eta()) < etaMax) + histos.fill(HIST("hKaonpIsotropic"), centrality, K1->Pt(), K1->Eta(), GetPhiInRange(K1->Phi() - psi2)); + if (K2->Pt() > ptMin && std::abs(K2->Eta()) < etaMax) + histos.fill(HIST("hKaonmIsotropic"), centrality, K2->Pt(), K2->Eta(), GetPhiInRange(K2->Phi() - psi2)); + } + ConfigurableAxis axisVertex{"axisVertex", {20, -10, 10}, "vertex axis for bin"}; ConfigurableAxis axisMultiplicityClass{"axisMultiplicityClass", {20, 0, 100}, "multiplicity percentile for bin"}; ConfigurableAxis axisEPAngle{"axisEPAngle", {6, -TMath::Pi() / 2, TMath::Pi() / 2}, "event plane angle"}; @@ -728,6 +753,11 @@ struct phipbpb { histos.fill(HIST("hSparseV2SameEventCosDeltaPhi"), PhiMesonMother.M(), PhiMesonMother.Pt(), v2, centrality); histos.fill(HIST("hSparseV2SameEventCos2DeltaPhi"), PhiMesonMother.M(), PhiMesonMother.Pt(), v2acc, centrality); } + + histos.fill(HIST("hKaonpData"), centrality, KaonPlus.Pt(), KaonPlus.Eta(), GetPhiInRange(KaonPlus.Phi() - psiFT0C)); + histos.fill(HIST("hKaonmData"), centrality, KaonMinus.Pt(), KaonMinus.Eta(), GetPhiInRange(KaonMinus.Phi() - psiFT0C)); + fillHisoWithTGenPS(PhiMesonMother, psiFT0C, cfgCutPT, cfgCutEta, centrality); + histos.fill(HIST("hSparseV2SameEventCosDeltaPhiSquare"), PhiMesonMother.M(), PhiMesonMother.Pt(), v2 * v2, centrality); histos.fill(HIST("hSparseV2SameEventCosDeltaPhiCube"), PhiMesonMother.M(), PhiMesonMother.Pt(), v2 * v2 * v2, centrality); histos.fill(HIST("hSparseV2SameEventSinDeltaPhi"), PhiMesonMother.M(), PhiMesonMother.Pt(), v2sin * QFT0C, centrality); diff --git a/PWGLF/Tasks/Resonances/phispectrapbpbqa.cxx b/PWGLF/Tasks/Resonances/phispectrapbpbqa.cxx new file mode 100644 index 00000000000..4ea692e246e --- /dev/null +++ b/PWGLF/Tasks/Resonances/phispectrapbpbqa.cxx @@ -0,0 +1,710 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// Phi meson spin alignment task +// sourav.kundu@cern.ch + +#include "PWGMM/Mult/DataModel/Index.h" // for Particles2Tracks table + +#include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" +#include "CommonConstants/PhysicsConstants.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/ConfigParamSpec.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/DCA.h" +#include "ReconstructionDataFormats/Track.h" +#include "ReconstructionDataFormats/V0.h" + +#include "Math/GenVector/Boost.h" +#include "Math/Vector3D.h" +#include "Math/Vector4D.h" +#include "TF1.h" +#include "TRandom3.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using std::array; +struct phispectrapbpbqa { + double bz = 0.; + + // Enable access to the CCDB for the offset and correction constants and save them in dedicated variables. + Service ccdb; + o2::ccdb::CcdbApi ccdbApi; + Service pdg; + struct : ConfigurableGroup { + Configurable cfgURL{"cfgURL", "http://alice-ccdb.cern.ch", "Address of the CCDB to browse"}; + Configurable nolaterthan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "Latest acceptable timestamp of creation for the object"}; + } cfgCcdbParam; + TH3D* hTPCCallib; + TH3D* hTOFCallib; + + Configurable ConfPathTPC{"ConfPathTPC", "Users/s/skundu/My/Object/PIDcallib/TPC", "Weight path TPC"}; + Configurable ConfPathTOF{"ConfPathTOF", "Users/s/skundu/My/Object/PIDcallib/TOF", "Weight path TOF"}; + + // events + Configurable cfgNoMixedEvents{"cfgNoMixedEvents", 10, "Number of event mixing"}; + ConfigurableAxis axisVertex{"axisVertex", {20, -10, 10}, "vertex axis for bin"}; + // ConfigurableAxis axisMultiplicityClass{"axisMultiplicityClass", {8, 0, 80}, "multiplicity percentile for bin"}; + + Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; + Configurable cfgCutCentrality{"cfgCutCentrality", 80.0f, "Accepted maximum Centrality"}; + + // track + Configurable cfgCutPT{"cfgCutPT", 0.2, "PT cut on daughter track"}; + Configurable cfgCutCharge{"cfgCutCharge", 0.0, "cut on Charge"}; + Configurable cfgCutEta{"cfgCutEta", 0.8, "Eta cut on daughter track"}; + + Configurable cfgITScluster{"cfgITScluster", 4, "Number of ITS cluster"}; + Configurable cfgTPCcluster{"cfgTPCcluster", 80, "Number of TPC cluster"}; + Configurable cfgTPCcrossedRows{"cfgTPCcrossedRows", 90, "Number of TPC crossed Rows"}; + + Configurable cfgUpdatePID{"cfgUpdatePID", false, "Update PID callibration"}; + Configurable applyPID{"applyPID", true, "Apply PID"}; + Configurable isDeepAngle{"isDeepAngle", false, "Deep Angle cut"}; + Configurable cfgDeepAngle{"cfgDeepAngle", 0.04, "Deep Angle cut value"}; + Configurable timeFrameMC{"timeFrameMC", false, "time frame cut in MC"}; + Configurable readOutFrameMC{"readOutFrameMC", true, "ITS read out frame cut in MC"}; + Configurable ispTdepPID{"ispTdepPID", false, "pT dependent PID"}; + Configurable cfgCutTOFBeta{"cfgCutTOFBeta", 0.5, "cut TOF beta"}; + Configurable nsigmaCutTPC{"nsigmacutTPC", 2.0, "Value of the TPC Nsigma cut"}; + Configurable nsigmaCutCombined{"nsigmaCutCombined", 2.0, "Value of the Combined TPC-TOF Nsigma cut"}; + ConfigurableAxis axisOccupancy{"axisOccupancy", {VARIABLE_WIDTH, -1.0, 200.0, 500.0, 1000.0, 2000.0f, 4000.0, 10000.0f, 100000.0f}, "occupancy axis"}; + struct : ConfigurableGroup { + ConfigurableAxis configThnAxisInvMass{"configThnAxisInvMass", {90, 0.98, 1.07}, "#it{M} (GeV/#it{c}^{2})"}; + ConfigurableAxis configThnAxisPt{"configThnAxisPt", {100, 0.0, 10.}, "#it{p}_{T} (GeV/#it{c})"}; + ConfigurableAxis configThnAxisCentrality{"configThnAxisCentrality", {8, 0., 80}, "Centrality"}; + ConfigurableAxis configThnAxisSector{"configThnAxisSector", {2, 0.0, 2.0}, "TPC sector"}; + + } cnfgaxis; + Configurable isMC{"isMC", false, "use MC"}; + Configurable avoidsplitrackMC{"avoidsplitrackMC", false, "avoid split track in MC"}; + + Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; + Filter centralityFilter = nabs(aod::cent::centFT0C) < cfgCutCentrality; + Filter acceptanceFilter = (nabs(aod::track::eta) < cfgCutEta && nabs(aod::track::pt) > cfgCutPT); + // Filter PIDcutFilter = nabs(aod::pidtpc::tpcNSigmaKa) < nsigmaCutTPC; + // Filter DCAcutFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + + using EventCandidates = soa::Filtered>; + using TrackCandidates = soa::Filtered>; + + using CollisionMCTrueTable = aod::McCollisions; + using TrackMCTrueTable = aod::McParticles; + + using CollisionMCRecTableCentFT0C = soa::SmallGroups>; + using TrackMCRecTable = soa::Join; + using FilTrackMCRecTable = soa::Filtered; + Preslice perCollision = aod::track::collisionId; + + SliceCache cache; + Partition posTracks = aod::track::signed1Pt > cfgCutCharge; + Partition negTracks = aod::track::signed1Pt < cfgCutCharge; + + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + // Event selection cuts - Alex + // TF1* fMultPVCutLow = nullptr; + + void init(o2::framework::InitContext&) + { + + histos.add("hphiSE", "hphiSE", HistType::kTHnSparseF, {cnfgaxis.configThnAxisInvMass, cnfgaxis.configThnAxisPt, cnfgaxis.configThnAxisCentrality, axisOccupancy, cnfgaxis.configThnAxisSector}, true); + histos.add("hphiME", "hphiME", HistType::kTHnSparseF, {cnfgaxis.configThnAxisInvMass, cnfgaxis.configThnAxisPt, cnfgaxis.configThnAxisCentrality, axisOccupancy, cnfgaxis.configThnAxisSector}, true); + histos.add("hphiGen", "hphiGen", HistType::kTHnSparseF, {cnfgaxis.configThnAxisInvMass, cnfgaxis.configThnAxisPt, cnfgaxis.configThnAxisCentrality, axisOccupancy}, true); + + histos.add("hNsigmaTPC", "NsigmaKaon TPC", HistType::kTHnSparseF, {{200, -10.0f, 10.0f}, {100, 0.0, 10.0}, axisOccupancy, cnfgaxis.configThnAxisCentrality}); + histos.add("hNsigmaTOF", "NsigmaKaon TOF", HistType::kTHnSparseF, {{200, -10.0f, 10.0f}, {100, 0.0, 10.0}, axisOccupancy, cnfgaxis.configThnAxisCentrality}); + + histos.add("hPhiMommentum", "hPhiMommentum", kTH3F, {{36, 0, 6.283}, {200, -10.0, 10.0}, axisOccupancy}); + + histos.add("hNsigmaTPCAfterCut", "NsigmaKaon TPC After Cut", kTH3F, {{200, -10.0f, 10.0f}, {100, 0.0, 10.0}, axisOccupancy}); + histos.add("hNsigmaTOFAfterCut", "NsigmaKaon TOF After Cut", kTH3F, {{200, -10.0f, 10.0f}, {100, 0.0, 10.0}, axisOccupancy}); + + histos.add("hNsigmaKaonTOFTPC", "NsigmaKaon TOFTPC distribution", kTH3F, {{200, -10.0f, 10.0f}, {200, -10.0f, 10.0f}, {100, 0.0, 10.0}}); + + histos.add("hdcaxy", "DCA xy dist.", kTH2F, {{1000, -1.0f, 1.0f}, {200, -10.0, 10.0}}); + histos.add("hdcaz", "DCA z dist.", kTH2F, {{1000, -1.0f, 1.0f}, {200, -10.0, 10.0}}); + + histos.add("hCentrality", "hCentrality", kTH1F, {{8, 0.0f, 80.0f}}); + histos.add("hVtxZ", "hVtxZ", kTH1F, {{8, 0.0f, 80.0f}}); + histos.add("hOccupancy", "hOccupancy", kTH2F, {axisOccupancy, cnfgaxis.configThnAxisCentrality}); + histos.add("hMC", "hMC", kTH1F, {{20, 0.0f, 20.0f}}); + histos.add("h1PhiRecsplit", "h1PhiRecsplit", kTH1F, {{100, 0.0f, 10.0f}}); + + ccdb->setURL(cfgCcdbParam.cfgURL); + ccdbApi.init("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + if (cfgUpdatePID) { + hTPCCallib = ccdb->getForTimeStamp(ConfPathTPC.value, cfgCcdbParam.nolaterthan.value); + hTOFCallib = ccdb->getForTimeStamp(ConfPathTOF.value, cfgCcdbParam.nolaterthan.value); + } + } + + double massKa = o2::constants::physics::MassKPlus; + + int getMagneticField(uint64_t timestamp) + { + // Get the magnetic field + static o2::parameters::GRPMagField* grpo = nullptr; + if (grpo == nullptr) { + grpo = ccdb->getForTimeStamp("/GLO/Config/GRPMagField", timestamp); + if (grpo == nullptr) { + LOGF(fatal, "GRP object not found for timestamp %llu", timestamp); + return 0; + } + LOGF(info, "Retrieved GRP for timestamp %llu with magnetic field of %d kG", timestamp, grpo->getNominalL3Field()); + } + return grpo->getNominalL3Field(); + } + + template + bool selectionTrack(const T& candidate) + { + if (!(candidate.isGlobalTrack() && candidate.isPVContributor() && candidate.itsNCls() > cfgITScluster && candidate.tpcNClsFound() > cfgTPCcluster && candidate.tpcNClsCrossedRows() > cfgTPCcrossedRows)) { + return false; + } + return true; + } + + template + bool selectionPIDpTdependent(const T& candidate, double nsigmaTPC, double nsigmaTOF) + { + if (candidate.p() < 0.7 && TMath::Abs(nsigmaTPC) < nsigmaCutTPC) { + return true; + } + if (candidate.p() >= 0.7 && candidate.hasTOF() && candidate.beta() > cfgCutTOFBeta && TMath::Sqrt(nsigmaTPC * nsigmaTPC + nsigmaTOF * nsigmaTOF) < nsigmaCutCombined) { + return true; + } + return false; + } + + template + bool selectionPID(const T& candidate, double nsigmaTPC, double nsigmaTOF) + { + if (candidate.p() < 0.7 && TMath::Abs(nsigmaTPC) < nsigmaCutTPC) { + return true; + } + if (candidate.p() >= 0.7 && candidate.hasTOF() && candidate.beta() > cfgCutTOFBeta && TMath::Sqrt(nsigmaTPC * nsigmaTPC + nsigmaTOF * nsigmaTOF) < nsigmaCutCombined) { + return true; + } + if (candidate.p() >= 0.7 && !candidate.hasTOF() && TMath::Abs(nsigmaTPC) < nsigmaCutTPC) { + return true; + } + return false; + } + + // deep angle cut on pair to remove photon conversion + template + bool selectionPair(const T1& candidate1, const T2& candidate2) + { + double pt1, pt2, pz1, pz2, p1, p2, angle; + pt1 = candidate1.pt(); + pt2 = candidate2.pt(); + pz1 = candidate1.pz(); + pz2 = candidate2.pz(); + p1 = candidate1.p(); + p2 = candidate2.p(); + angle = TMath::ACos((pt1 * pt2 + pz1 * pz2) / (p1 * p2)); + if (isDeepAngle && angle < cfgDeepAngle) { + return false; + } + return true; + } + + // Keep a track only if its azimuth is NOT inside the periodic boundary window. + // phi : track azimuth (radians) at your chosen reference radius (e.g. Rout ~ 247 cm) + // badHalfWidth : half-width of the bad strip near each boundary (rad). Your example: 0.15 + // nSectors : 18 for ALICE TPC + bool keepTrackNoTPCBoundary(float phi, + float badWidth = 0.15f, + int nSectors = 18) + { + constexpr float TwoPi = 6.283185307179586f; + float ph = std::fmod(phi, TwoPi); + if (ph < 0.f) + ph += TwoPi; // wrap phi into [0, 2π) + + const float secW = TwoPi / static_cast(nSectors); // ≈ 0.349 rad + + float rel = std::fmod(ph, secW); // position inside sector [0, secW) + + return rel > badWidth; // keep if NOT inside boundary strip [0, badWidth] + } + + using BinningTypeVertexContributor = ColumnBinningPolicy; + ROOT::Math::PxPyPzMVector PhiMesonMother, KaonPlus, KaonMinus, fourVecDauCM; + int currentRunNumber = -999; + int lastRunNumber = -999; + void processSameEvent(EventCandidates::iterator const& collision, TrackCandidates const&, aod::BCsWithTimestamps const&) + { + if (!collision.sel8() || !collision.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision.selection_bit(aod::evsel::kNoITSROFrameBorder) || !collision.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard) || !collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + return; + } + auto centrality = collision.centFT0C(); + int occupancy = collision.trackOccupancyInTimeRange(); + histos.fill(HIST("hCentrality"), centrality); + histos.fill(HIST("hVtxZ"), collision.posZ()); + auto bc = collision.template bc_as(); + currentRunNumber = collision.bc_as().runNumber(); + if (currentRunNumber != lastRunNumber) { + bz = getMagneticField(bc.timestamp()); + } + lastRunNumber = currentRunNumber; + auto posThisColl = posTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto negThisColl = negTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + + int Npostrack = 0; + histos.fill(HIST("hOccupancy"), occupancy, centrality); + for (auto track1 : posThisColl) { + if (!selectionTrack(track1)) { + continue; + } + histos.fill(HIST("hdcaxy"), track1.dcaXY(), track1.p() / track1.sign()); + histos.fill(HIST("hdcaz"), track1.dcaZ(), track1.p() / track1.sign()); + double nSigmaTPC = track1.tpcNSigmaKa(); + double nSigmaTOF = track1.tofNSigmaKa(); + if (!track1.hasTOF()) { + nSigmaTOF = -9999.99; + } + + if (cfgUpdatePID) { + // update PID + nSigmaTPC = (nSigmaTPC - hTPCCallib->GetBinContent(hTPCCallib->FindBin(track1.p(), centrality, occupancy))) / hTPCCallib->GetBinError(hTPCCallib->FindBin(track1.p(), centrality, occupancy)); + if (track1.hasTOF()) { + nSigmaTOF = (nSigmaTOF - hTOFCallib->GetBinContent(hTOFCallib->FindBin(track1.p(), centrality, occupancy))) / hTOFCallib->GetBinError(hTOFCallib->FindBin(track1.p(), centrality, occupancy)); + } + } + if (track1.p() < 0.6) { + histos.fill(HIST("hNsigmaTPC"), nSigmaTPC, track1.p(), occupancy, centrality); + } else if (track1.p() > 0.6 && track1.hasTOF() && std::abs(nSigmaTOF) < 2.5) { + histos.fill(HIST("hNsigmaTPC"), nSigmaTPC, track1.p(), occupancy, centrality); + } + if (track1.hasTOF()) { + histos.fill(HIST("hNsigmaTOF"), nSigmaTOF, track1.p(), occupancy, centrality); + } + if (applyPID) { + if (ispTdepPID && !selectionPIDpTdependent(track1, nSigmaTPC, nSigmaTOF)) { + continue; + } + if (!ispTdepPID && !selectionPID(track1, nSigmaTPC, nSigmaTOF)) { + continue; + } + } + histos.fill(HIST("hNsigmaTPCAfterCut"), nSigmaTPC, track1.p(), occupancy); + histos.fill(HIST("hNsigmaTOFAfterCut"), nSigmaTOF, track1.p(), occupancy); + if (track1.hasTOF()) { + histos.fill(HIST("hNsigmaKaonTOFTPC"), nSigmaTOF, nSigmaTPC, track1.p()); + } + Npostrack = Npostrack + 1; + + // 1) φ at a chosen radius (e.g., outer pad rows ~247 cm) + histos.fill(HIST("hPhiMommentum"), track1.phi(), track1.p(), occupancy); + + for (auto track2 : negThisColl) { + if (track1.sign() * track2.sign() > 0.0) { + continue; + } + if (!selectionTrack(track2)) { + continue; + } + if (Npostrack == 1) { + histos.fill(HIST("hdcaxy"), track2.dcaXY(), track2.p() / track2.sign()); + histos.fill(HIST("hdcaz"), track2.dcaZ(), track2.p() / track2.sign()); + } + double nSigmaTPC2 = track2.tpcNSigmaKa(); + double nSigmaTOF2 = track2.tofNSigmaKa(); + if (!track2.hasTOF()) { + nSigmaTOF2 = -9999.9; + } + if (cfgUpdatePID) { + // update PID + nSigmaTPC2 = (nSigmaTPC2 - hTPCCallib->GetBinContent(hTPCCallib->FindBin(track2.p(), centrality, occupancy))) / hTPCCallib->GetBinError(hTPCCallib->FindBin(track2.p(), centrality, occupancy)); + if (track2.hasTOF()) { + nSigmaTOF2 = (nSigmaTOF2 - hTOFCallib->GetBinContent(hTOFCallib->FindBin(track2.p(), centrality, occupancy))) / hTOFCallib->GetBinError(hTOFCallib->FindBin(track2.p(), centrality, occupancy)); + } + } + if (Npostrack == 1) { + if (track2.p() < 0.6) { + histos.fill(HIST("hNsigmaTPC"), nSigmaTPC2, track2.p(), occupancy, centrality); + } else if (track2.p() > 0.6 && track2.hasTOF() && std::abs(nSigmaTOF2) < 2.5) { + histos.fill(HIST("hNsigmaTPC"), nSigmaTPC2, track2.p(), occupancy, centrality); + } + if (track2.hasTOF()) { + histos.fill(HIST("hNsigmaTOF"), nSigmaTOF2, track2.p(), occupancy, centrality); + } + } + if (applyPID) { + if (ispTdepPID && !selectionPIDpTdependent(track2, nSigmaTPC2, nSigmaTOF2)) { + continue; + } + if (!ispTdepPID && !selectionPID(track2, nSigmaTPC2, nSigmaTOF2)) { + continue; + } + } + if (Npostrack == 1) { + histos.fill(HIST("hNsigmaTPCAfterCut"), nSigmaTPC2, track2.p(), occupancy); + histos.fill(HIST("hNsigmaTOFAfterCut"), nSigmaTOF2, track2.p(), occupancy); + if (track2.hasTOF()) { + histos.fill(HIST("hNsigmaKaonTOFTPC"), nSigmaTOF2, nSigmaTPC2, track2.p()); + } + } + if (Npostrack == 1) { + histos.fill(HIST("hPhiMommentum"), track2.phi(), track2.p(), occupancy); + } + auto track1ID = track1.globalIndex(); + auto track2ID = track2.globalIndex(); + if (track2ID == track1ID) { + continue; + } + if (!selectionPair(track1, track2)) { + continue; + } + bool crossed1 = keepTrackNoTPCBoundary(track1.phi(), 0.15, 18); + bool crossed2 = keepTrackNoTPCBoundary(track2.phi(), 0.15, 18); + float passsector = -999.0; + if (crossed1 && crossed2) { + passsector = 1.5; + } else { + passsector = 0.5; + } + + KaonPlus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); + KaonMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); + PhiMesonMother = KaonPlus + KaonMinus; + + if (TMath::Abs(PhiMesonMother.Rapidity()) < 0.5) { + histos.fill(HIST("hphiSE"), PhiMesonMother.M(), PhiMesonMother.Pt(), centrality, occupancy, passsector); + } + } + } + } + PROCESS_SWITCH(phispectrapbpbqa, processSameEvent, "Process Same event", true); + + void processMixedEventOpti(EventCandidates const& collisions, TrackCandidates const& tracks) + { + auto tracksTuple = std::make_tuple(tracks); + BinningTypeVertexContributor binningOnPositions{{axisVertex, cnfgaxis.configThnAxisCentrality, axisOccupancy}, true}; + SameKindPair pair{binningOnPositions, cfgNoMixedEvents, -1, collisions, tracksTuple, &cache}; + for (auto& [collision1, tracks1, collision2, tracks2] : pair) { + if (!collision1.sel8() || !collision1.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision1.selection_bit(aod::evsel::kNoITSROFrameBorder) || !collision1.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision1.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !collision1.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard) || !collision1.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + continue; + } + if (!collision2.sel8() || !collision2.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision2.selection_bit(aod::evsel::kNoITSROFrameBorder) || !collision2.selection_bit(aod::evsel::kNoSameBunchPileup) || !collision2.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !collision2.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard) || !collision2.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + continue; + } + int occupancy = collision1.trackOccupancyInTimeRange(); + auto centrality = collision1.centFT0C(); + for (auto& [track1, track2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { + if (track1.sign() * track2.sign() > 0) { + continue; + } + if (!selectionTrack(track1)) { + continue; + } + if (!selectionTrack(track2)) { + continue; + } + // PID track 1 + double nSigmaTPC = track1.tpcNSigmaKa(); + double nSigmaTOF = track1.tofNSigmaKa(); + if (!track1.hasTOF()) { + nSigmaTOF = -9999.99; + } + if (cfgUpdatePID) { + nSigmaTPC = (nSigmaTPC - hTPCCallib->GetBinContent(hTPCCallib->FindBin(track1.p(), centrality, occupancy))) / hTPCCallib->GetBinError(hTPCCallib->FindBin(track1.p(), centrality, occupancy)); + if (track1.hasTOF()) { + nSigmaTOF = (nSigmaTOF - hTOFCallib->GetBinContent(hTOFCallib->FindBin(track1.p(), centrality, occupancy))) / hTOFCallib->GetBinError(hTOFCallib->FindBin(track1.p(), centrality, occupancy)); + } + } + // PID track 2 + double nSigmaTPC2 = track2.tpcNSigmaKa(); + double nSigmaTOF2 = track2.tofNSigmaKa(); + if (!track2.hasTOF()) { + nSigmaTOF2 = -9999.99; + } + if (cfgUpdatePID) { + nSigmaTPC2 = (nSigmaTPC2 - hTPCCallib->GetBinContent(hTPCCallib->FindBin(track2.p(), centrality, occupancy))) / hTPCCallib->GetBinError(hTPCCallib->FindBin(track2.p(), centrality, occupancy)); + if (track2.hasTOF()) { + nSigmaTOF2 = (nSigmaTOF2 - hTOFCallib->GetBinContent(hTOFCallib->FindBin(track2.p(), centrality, occupancy))) / hTOFCallib->GetBinError(hTOFCallib->FindBin(track2.p(), centrality, occupancy)); + } + } + if (applyPID) { + if (ispTdepPID && !selectionPIDpTdependent(track1, nSigmaTPC, nSigmaTOF)) { + continue; + } + if (!ispTdepPID && !selectionPID(track1, nSigmaTPC, nSigmaTOF)) { + continue; + } + + if (ispTdepPID && !selectionPIDpTdependent(track2, nSigmaTPC2, nSigmaTOF2)) { + continue; + } + if (!ispTdepPID && !selectionPID(track2, nSigmaTPC2, nSigmaTOF2)) { + continue; + } + } + if (!selectionPair(track1, track2)) { + continue; + } + bool crossed1 = keepTrackNoTPCBoundary(track1.phi(), 0.15, 18); + bool crossed2 = keepTrackNoTPCBoundary(track2.phi(), 0.15, 18); + float passsector = -999.0; + if (crossed1 && crossed2) { + passsector = 1.5; + } else { + passsector = 0.5; + } + KaonPlus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); + KaonMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); + PhiMesonMother = KaonPlus + KaonMinus; + if (TMath::Abs(PhiMesonMother.Rapidity()) < 0.5) { + histos.fill(HIST("hphiME"), PhiMesonMother.M(), PhiMesonMother.Pt(), centrality, occupancy, passsector); + } + } + } + } + PROCESS_SWITCH(phispectrapbpbqa, processMixedEventOpti, "Process Mixed event new", true); + + void processMC(CollisionMCTrueTable::iterator const&, CollisionMCRecTableCentFT0C const& RecCollisions, TrackMCTrueTable const& GenParticles, FilTrackMCRecTable const& RecTracks) + { + histos.fill(HIST("hMC"), 0); + if (RecCollisions.size() == 0) { + histos.fill(HIST("hMC"), 1); + return; + } + if (RecCollisions.size() > 1) { + histos.fill(HIST("hMC"), 2); + return; + } + for (auto& RecCollision : RecCollisions) { + if (!RecCollision.sel8()) { + histos.fill(HIST("hMC"), 3); + continue; + } + if (!RecCollision.selection_bit(aod::evsel::kNoSameBunchPileup) || !RecCollision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV) || !RecCollision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard) || !RecCollision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { + histos.fill(HIST("hMC"), 4); + continue; + } + if (TMath::Abs(RecCollision.posZ()) > cfgCutVertex) { + histos.fill(HIST("hMC"), 6); + continue; + } + + if (timeFrameMC && !RecCollision.selection_bit(aod::evsel::kNoTimeFrameBorder)) { + histos.fill(HIST("hMC"), 7); + continue; + } + if (readOutFrameMC && RecCollision.selection_bit(aod::evsel::kNoITSROFrameBorder)) { + histos.fill(HIST("hMC"), 8); + continue; + } + + histos.fill(HIST("hMC"), 9); + auto centrality = RecCollision.centFT0C(); + int occupancy = RecCollision.trackOccupancyInTimeRange(); + histos.fill(HIST("hOccupancy"), occupancy, centrality); + + auto oldindex = -999; + auto Rectrackspart = RecTracks.sliceBy(perCollision, RecCollision.globalIndex()); + // loop over reconstructed particle + for (auto track1 : Rectrackspart) { + if (!selectionTrack(track1)) { + continue; + } + if (!track1.has_mcParticle()) { + continue; + } + auto track1ID = track1.index(); + for (auto track2 : Rectrackspart) { + auto track2ID = track2.index(); + if (track2ID <= track1ID) { + continue; + } + if (!selectionTrack(track2)) { + continue; + } + if (!track2.has_mcParticle()) { + continue; + } + if (!selectionPair(track1, track2)) { + continue; + } + if (track1.sign() * track2.sign() > 0) { + continue; + } + // PID track 1 + double nSigmaTPC = track1.tpcNSigmaKa(); + double nSigmaTOF = track1.tofNSigmaKa(); + if (!track1.hasTOF()) { + nSigmaTOF = -9999.99; + } + if (cfgUpdatePID) { + nSigmaTPC = (nSigmaTPC - hTPCCallib->GetBinContent(hTPCCallib->FindBin(track1.p(), centrality, occupancy))) / hTPCCallib->GetBinError(hTPCCallib->FindBin(track1.p(), centrality, occupancy)); + if (track1.hasTOF()) { + nSigmaTOF = (nSigmaTOF - hTOFCallib->GetBinContent(hTOFCallib->FindBin(track1.p(), centrality, occupancy))) / hTOFCallib->GetBinError(hTOFCallib->FindBin(track1.p(), centrality, occupancy)); + } + } + // PID track 2 + double nSigmaTPC2 = track2.tpcNSigmaKa(); + double nSigmaTOF2 = track2.tofNSigmaKa(); + if (!track2.hasTOF()) { + nSigmaTOF2 = -9999.99; + } + if (cfgUpdatePID) { + nSigmaTPC2 = (nSigmaTPC2 - hTPCCallib->GetBinContent(hTPCCallib->FindBin(track2.p(), centrality, occupancy))) / hTPCCallib->GetBinError(hTPCCallib->FindBin(track2.p(), centrality, occupancy)); + if (track2.hasTOF()) { + nSigmaTOF2 = (nSigmaTOF2 - hTOFCallib->GetBinContent(hTOFCallib->FindBin(track2.p(), centrality, occupancy))) / hTOFCallib->GetBinError(hTOFCallib->FindBin(track2.p(), centrality, occupancy)); + } + } + if (applyPID) { + if (ispTdepPID && !selectionPIDpTdependent(track1, nSigmaTPC, nSigmaTOF)) { + continue; + } + if (!ispTdepPID && !selectionPID(track1, nSigmaTPC, nSigmaTOF)) { + continue; + } + + if (ispTdepPID && !selectionPIDpTdependent(track2, nSigmaTPC2, nSigmaTOF2)) { + continue; + } + if (!ispTdepPID && !selectionPID(track2, nSigmaTPC2, nSigmaTOF2)) { + continue; + } + } + + const auto mctrack1 = track1.mcParticle(); + const auto mctrack2 = track2.mcParticle(); + int track1PDG = TMath::Abs(mctrack1.pdgCode()); + int track2PDG = TMath::Abs(mctrack2.pdgCode()); + if (!mctrack1.isPhysicalPrimary()) { + continue; + } + if (!mctrack2.isPhysicalPrimary()) { + continue; + } + if (!(track1PDG == 321 && track2PDG == 321)) { + continue; + } + for (auto& mothertrack1 : mctrack1.mothers_as()) { + for (auto& mothertrack2 : mctrack2.mothers_as()) { + if (mothertrack1.pdgCode() != mothertrack2.pdgCode()) { + continue; + } + if (mothertrack1 != mothertrack2) { + continue; + } + if (TMath::Abs(mothertrack1.pdgCode()) != 333) { + continue; + } + if (avoidsplitrackMC && oldindex == mothertrack1.globalIndex()) { + histos.fill(HIST("h1PhiRecsplit"), mothertrack1.pt()); + continue; + } + oldindex = mothertrack1.globalIndex(); + bool crossed1 = keepTrackNoTPCBoundary(track1.phi(), 0.15, 18); + bool crossed2 = keepTrackNoTPCBoundary(track2.phi(), 0.15, 18); + float passsector = -999.0; + if (crossed1 && crossed2) { + passsector = 1.5; + } else { + passsector = 0.5; + } + KaonPlus = ROOT::Math::PxPyPzMVector(track1.px(), track1.py(), track1.pz(), massKa); + KaonMinus = ROOT::Math::PxPyPzMVector(track2.px(), track2.py(), track2.pz(), massKa); + PhiMesonMother = KaonPlus + KaonMinus; + if (TMath::Abs(PhiMesonMother.Rapidity()) < 0.5) { + histos.fill(HIST("hphiSE"), PhiMesonMother.M(), PhiMesonMother.Pt(), centrality, occupancy, passsector); + } + } + } + } + } + // loop over generated particle + for (auto& mcParticle : GenParticles) { + if (TMath::Abs(mcParticle.y()) > 0.5) { + continue; + } + if (mcParticle.pdgCode() != 333) { + continue; + } + auto kDaughters = mcParticle.daughters_as(); + if (kDaughters.size() != 2) { + continue; + } + auto daughtp = false; + auto daughtm = false; + for (auto kCurrentDaughter : kDaughters) { + if (!kCurrentDaughter.isPhysicalPrimary()) { + continue; + } + if (kCurrentDaughter.pdgCode() == +321) { + if (kCurrentDaughter.pt() > cfgCutPT && TMath::Abs(kCurrentDaughter.eta()) < cfgCutEta) { + daughtp = true; + } + KaonPlus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); + } else if (kCurrentDaughter.pdgCode() == -321) { + if (kCurrentDaughter.pt() > cfgCutPT && TMath::Abs(kCurrentDaughter.eta()) < cfgCutEta) { + daughtm = true; + } + KaonMinus = ROOT::Math::PxPyPzMVector(kCurrentDaughter.px(), kCurrentDaughter.py(), kCurrentDaughter.pz(), massKa); + } + } + if (daughtp && daughtm) { + PhiMesonMother = KaonPlus + KaonMinus; + if (TMath::Abs(PhiMesonMother.Rapidity()) < 0.5) { + histos.fill(HIST("hphiGen"), PhiMesonMother.M(), PhiMesonMother.Pt(), centrality, occupancy); + } + } + } + } // rec collision loop + + } // process MC + PROCESS_SWITCH(phispectrapbpbqa, processMC, "Process MC", false); +}; +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc, TaskName{"phispectrapbpbqa"})}; +} diff --git a/PWGLF/Tasks/Resonances/xi1530Analysisqa.cxx b/PWGLF/Tasks/Resonances/xi1530Analysisqa.cxx index 42773fa2947..07ed10a9460 100644 --- a/PWGLF/Tasks/Resonances/xi1530Analysisqa.cxx +++ b/PWGLF/Tasks/Resonances/xi1530Analysisqa.cxx @@ -14,21 +14,25 @@ /// /// \author Min-jae Kim , Bong-Hwi Lim // #include -#include "Math/Vector4D.h" -#include "TF1.h" -#include "TRandom3.h" +#include "PWGLF/DataModel/LFResonanceTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/mcCentrality.h" +#include "PWGLF/Utils/inelGt.h" -#include "Common/DataModel/PIDResponse.h" +#include "Common/Core/RecoDecay.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/EventSelection.h" -#include "Framework/AnalysisTask.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/runDataProcessing.h" -#include "PWGLF/DataModel/LFResonanceTables.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "Common/DataModel/PIDResponse.h" + #include "CommonConstants/PhysicsConstants.h" -#include "Common/Core/RecoDecay.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisTask.h" #include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" + +#include "Math/Vector4D.h" +#include "TF1.h" +#include "TRandom3.h" using namespace o2; using namespace o2::framework; @@ -36,7 +40,7 @@ using namespace o2::framework::expressions; using namespace o2::soa; using namespace o2::constants::physics; using LorentzVectorPtEtaPhiMass = ROOT::Math::PtEtaPhiMVector; -// Service pdgDB; +Service pdgDB; enum { kData = 0, @@ -57,6 +61,10 @@ struct Xi1530Analysisqa { SliceCache cache; Preslice perRCol = aod::resodaughter::resoCollisionId; Preslice perCollision = aod::track::collisionId; + Preslice perResoCollision = + aod::resodaughter::resoCollisionId; + Preslice perResoCollisionCasc = + aod::resodaughter::resoCollisionId; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; using ResoMCCols = soa::Join; @@ -65,7 +73,7 @@ struct Xi1530Analysisqa { // Associated with histograms ConfigurableAxis binsPt{"binsPt", {VARIABLE_WIDTH, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4.0, 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9, 5.0, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 5.9, 6.0, 6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 6.7, 6.8, 6.9, 7.0, 7.1, 7.2, 7.3, 7.4, 7.5, 7.6, 7.7, 7.8, 7.9, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7, 8.8, 8.9, 9.0, 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7, 9.8, 9.9, 10.0, 10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9, 11.0, 11.1, 11.2, 11.3, 11.4, 11.5, 11.6, 11.7, 11.8, 11.9, 12.0, 12.1, 12.2, 12.3, 12.4, 12.5, 12.6, 12.7, 12.8, 12.9, 13.0, 13.1, 13.2, 13.3, 13.4, 13.5, 13.6, 13.7, 13.8, 13.9, 14.0, 14.1, 14.2, 14.3, 14.4, 14.5, 14.6, 14.7, 14.8, 14.9, 15.0}, "Binning of the pT axis"}; ConfigurableAxis binsPtQA{"binsPtQA", {VARIABLE_WIDTH, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0, 5.2, 5.4, 5.6, 5.8, 6.0, 6.2, 6.4, 6.6, 6.8, 7.0, 7.2, 7.4, 7.6, 7.8, 8.0, 8.2, 8.4, 8.6, 8.8, 9.0, 9.2, 9.4, 9.6, 9.8, 10.0}, "Binning of the pT axis"}; - ConfigurableAxis binsCent{"binsCent", {VARIABLE_WIDTH, 0.0, 1.0, 5.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 110.0}, "Binning of the centrality axis"}; + ConfigurableAxis binsCent{"binsCent", {VARIABLE_WIDTH, 0.0, 1.0, 5.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0, 70.0, 100.0, 110.0}, "Binning of the centrality axis"}; Configurable cInvMassStart{"cInvMassStart", 1.4, "Invariant mass start"}; Configurable cInvMassEnd{"cInvMassEnd", 3.0, "Invariant mass end"}; @@ -98,8 +106,8 @@ struct Xi1530Analysisqa { Configurable cfgTPCRows{"cfgTPCRows", 80, "Minimum Number of TPC Crossed Rows "}; Configurable cfgRatioTPCRowsOverFindableCls{"cfgRatioTPCRowsOverFindableCls", 0.8, "Minimum of TPC Crossed Rows to Findable Clusters"}; // Minmimum - Configurable cfgUseTPCRefit{"cfgUseTPCRefit", true, "Require TPC Refit"}; - Configurable cfgUseITSRefit{"cfgUseITSRefit", true, "Require ITS Refit"}; + // Configurable cfgUseTPCRefit{"cfgUseTPCRefit", true, "Require TPC Refit"}; //refit is included in global track selection + // Configurable cfgUseITSRefit{"cfgUseITSRefit", true, "Require ITS Refit"}; Configurable cfgHasTOF{"cfgHasTOF", false, "Require TOF"}; @@ -200,7 +208,6 @@ struct Xi1530Analysisqa { // MC Event selection // Configurable cZvertCutMC{"cZvertCutMC", 10.0, "MC Z-vertex cut"}; - Configurable cIsPhysicalPrimaryMC{"cIsPhysicalPrimaryMC", true, "Physical primary selection for a MC Parent"}; //*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*// @@ -209,8 +216,10 @@ struct Xi1530Analysisqa { Configurable cMaxPtMotherCut{"cMaxPtMotherCut", 9.0, "Maximum pt of mother cut"}; Configurable cMaxMinvMotherCut{"cMaxMinvMotherCut", 3.0, "Maximum Minv of mother cut"}; - Configurable cMicroTrack{"cMicroTrack", false, "Using Micro track for first pion"}; - Configurable studyStableXi{"studyStableXi", true, "Study stable Xi"}; + Configurable studyStableXi{"studyStableXi", false, "Study stable Xi"}; + + Configurable cMCCent{"cMCCent", true, "Using calibrated MC centrality (for FT0M)"}; + Configurable cRecoINELgt0{"cRecoINELgt0", true, "check if INEL>0 for reco events"}; TRandom* rn = new TRandom(); //*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*//*// @@ -251,11 +260,11 @@ struct Xi1530Analysisqa { // event histograms histos.add("QAevent/hEvtCounterSameE", "Number of analyzed Same Events", HistType::kTH1F, {{1, 0.5, 1.5}}); histos.add("QAevent/hVertexZSameE", "Collision Vertex Z position", HistType::kTH1F, {{100, -15., 15.}}); - histos.add("QAevent/hMultiplicityPercentSameE", "Multiplicity percentile of collision", HistType::kTH1F, {{120, 0.0f, 120.0f}}); + histos.add("QAevent/hMultiplicityPercentSameE", "Multiplicity percentile of collision", HistType::kTH1F, {centAxis}); histos.add("QAevent/hEvtCounterMixedE", "Number of analyzed Mixed Events", HistType::kTH1F, {{1, 0.5, 1.5}}); histos.add("QAevent/hVertexZMixedE", "Collision Vertex Z position", HistType::kTH1F, {{100, -15., 15.}}); - histos.add("QAevent/hMultiplicityPercentMixedE", "Multiplicity percentile of collision", HistType::kTH1F, {{120, 0.0f, 120.0f}}); + histos.add("QAevent/hMultiplicityPercentMixedE", "Multiplicity percentile of collision", HistType::kTH1F, {centAxis}); } if (invMass1D) { @@ -456,10 +465,10 @@ struct Xi1530Analysisqa { } if (cfgHasTOF && !track.hasTOF()) return false; - if (cfgUseITSRefit && !track.passedITSRefit()) - return false; - if (cfgUseTPCRefit && !track.passedTPCRefit()) - return false; + // if (cfgUseITSRefit && !track.passedITSRefit()) + // return false; + // if (cfgUseTPCRefit && !track.passedTPCRefit()) + // return false; if (cfgPVContributor && !track.isPVContributor()) return false; if (cfgPrimaryTrack && !track.isPrimaryTrack()) @@ -467,7 +476,7 @@ struct Xi1530Analysisqa { return true; } - bool hasSubsystemInfo(float Nsigma) // this will be replaced // .hasXX() was not appied in resocascade yet + bool hasSubsystemInfo(float Nsigma) { return std::abs(Nsigma) < cPIDBound; } @@ -492,7 +501,7 @@ struct Xi1530Analysisqa { return true; } - // Secondary track selection for cascades // need to more information, + // Secondary track selection for cascades // // Topological cuts for cascades template @@ -663,20 +672,20 @@ struct Xi1530Analysisqa { return lConsistentWithXi && lConsistentWithLambda; } - template - void fillHistograms(const CollisionType& collision, const TracksType& dTracks1, const TracksTypeCasc& dTracks2) // Order: ResoColl, ResoTrack, ResoCascTrack + template + void fillHistograms(const CollisionType& collision, const CenMult& multiplicity, const TracksType& dTracks1, const TracksTypeCasc& dTracks2) // Order: ResoColl, ResoTrack, ResoCascTrack { - auto multiplicity = collision.cent(); + // auto multiplicity = collision.cent(); { if constexpr (!IsMix) { histos.fill(HIST("QAevent/hVertexZSameE"), collision.posZ()); - histos.fill(HIST("QAevent/hMultiplicityPercentSameE"), collision.cent()); + histos.fill(HIST("QAevent/hMultiplicityPercentSameE"), multiplicity); histos.fill(HIST("TestME/hCollisionIndexSameE"), collision.globalIndex()); histos.fill(HIST("TestME/hnTrksSameE"), dTracks1.size()); } else { histos.fill(HIST("QAevent/hVertexZMixedE"), collision.posZ()); - histos.fill(HIST("QAevent/hMultiplicityPercentMixedE"), collision.cent()); + histos.fill(HIST("QAevent/hMultiplicityPercentMixedE"), multiplicity); histos.fill(HIST("TestME/hCollisionIndexMixedE"), collision.globalIndex()); histos.fill(HIST("TestME/hnTrksMixedE"), dTracks1.size()); } @@ -742,7 +751,7 @@ struct Xi1530Analysisqa { float trk2NSigmaPiNegTOF = trk2.daughterTOFNSigmaNegPi(); if constexpr (!IsMix) { - //// QA plots before the selection // need to pt for cascade tracks + //// QA plots before the selection // // --- PID QA if (pidPlots) { histos.fill(HIST("QAbefore/TPC_Nsigma_pi_first_all"), multiplicity, trk1ptPi, trk1NSigmaPiTPC); @@ -750,7 +759,6 @@ struct Xi1530Analysisqa { histos.fill(HIST("QAbefore/TOF_Nsigma_pi_first_all"), multiplicity, trk1ptPi, trk1NSigmaPiTOF); histos.fill(HIST("QAbefore/TOF_TPC_Map_pi_first_all"), trk1NSigmaPiTOF, trk1NSigmaPiTPC); } - // hasSubsystemInfo is Temporary, it will be replaced. histos.fill(HIST("QAbefore/TPC_Nsigma_pi_bachelor_all"), multiplicity, 0, trk2NSigmaPiBachelorTPC); // can't take pt information for the cascade secondary if (hasSubsystemInfo(trk2NSigmaPiBachelorTOF)) { @@ -819,10 +827,6 @@ struct Xi1530Analysisqa { if (!casctopCut(trk2)) continue; - // TPCncluster distributions - // histos.fill(HIST("TPCncluster/TPCnclusterpifirst"), trk1.tpcNClsFound()); - // histos.fill(HIST("TPCncluster/TPCnclusterPhipifirst"), trk1.tpcNClsFound(), trk1.phi()); - if constexpr (!IsMix) { //// QA plots after the selection // --- PID QA @@ -1048,25 +1052,74 @@ struct Xi1530Analysisqa { } } - void processData(aod::ResoCollision const& resoCollision, aod::ResoTracks const& resoTracks, aod::ResoCascades const& cascTracks) + void processData(aod::ResoCollision const& resoCollision, + aod::ResoCollisionColls const& collisionIndex, + soa::Join const& collisions, + aod::ResoTracks const& resoTracks, + aod::ResoCascades const& cascTracks) { + auto linkRow = collisionIndex.iteratorAt(resoCollision.globalIndex()); + auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision + + auto coll = collisions.iteratorAt(collId); // Take original collision matched with resoCollision + + if (cRecoINELgt0 && !coll.isInelGt0()) // Check reco INELgt0 (at least one PV track in |eta| < 1) about the collision + return; histos.fill(HIST("QAevent/hEvtCounterSameE"), 1.0); - fillHistograms(resoCollision, resoTracks, cascTracks); + auto multiplicity = resoCollision.cent(); + fillHistograms(resoCollision, multiplicity, resoTracks, cascTracks); } + // Reconstructed level MC for the track void processMC(ResoMCCols::iterator const& resoCollision, + aod::ResoCollisionColls const& resoCollisionIndex, + soa::Join const& collisionsMC, soa::Join const& cascTracks, - soa::Join const& resoTracks) + soa::Join const& resoTracks, + soa::Join const&) { if (!resoCollision.isInAfterAllCuts() || (std::abs(resoCollision.posZ()) > cZvertCutMC)) // MC event selection, all cuts missing vtx cut return; - fillHistograms(resoCollision, resoTracks, cascTracks); + + auto linkRow = resoCollisionIndex.iteratorAt(resoCollision.globalIndex()); + const int collId = linkRow.collisionId(); + + auto coll = collisionsMC.iteratorAt(collId); + + if (cRecoINELgt0 && !coll.isInelGt0()) + return; + + auto mcColl = coll.mcCollision_as>(); + + auto multiplicityReco = resoCollision.cent(); // Reco level multiplicity per. + auto multiplicityGen = mcColl.centFT0M(); // Gen level multiplicity per. + + float multiplicity = cMCCent ? multiplicityGen : multiplicityReco; + + fillHistograms(resoCollision, multiplicity, resoTracks, cascTracks); } - void processMCTrue(ResoMCCols::iterator const& resoCollision, aod::ResoMCParents const& resoParents) + // Truth level MC for the track with reco event + void processMCTrue(ResoMCCols::iterator const& resoCollision, + aod::ResoCollisionColls const& resoCollisionIndex, + aod::ResoMCParents const& resoParents, + aod::ResoCollisionCandidatesMC const& collisionsMC, + soa::Join const&) { - auto multiplicity = resoCollision.cent(); + + auto linkRow = resoCollisionIndex.iteratorAt(resoCollision.globalIndex()); + const int collId = linkRow.collisionId(); + + auto coll = collisionsMC.iteratorAt(collId); + + auto mcColl = coll.mcCollision_as>(); + + auto multiplicityReco = resoCollision.cent(); // Reco level multiplicity per. + auto multiplicityGen = mcColl.centFT0M(); // Gen level multiplicity per. + + float multiplicity = cMCCent ? multiplicityGen : multiplicityReco; + for (const auto& part : resoParents) { // loop over all pre-filtered MC particles if (std::abs(part.pdgCode()) != kXiStar || std::abs(part.y()) >= cfgRapidityCut) continue; @@ -1076,9 +1129,6 @@ struct Xi1530Analysisqa { if (!pass1 || !pass2) continue; - if (cIsPhysicalPrimaryMC && !part.isPhysicalPrimary()) - continue; - if (part.pdgCode() > 0) // INELt0 or INEL histos.fill(HIST("h3Xi1530Gen"), -1, part.pt(), multiplicity); else @@ -1115,11 +1165,23 @@ struct Xi1530Analysisqa { } } - void processDataMicro(aod::ResoCollision const& resoCollision, aod::ResoMicroTracks const& resomicrotracks, aod::ResoCascades const& cascTracks) + void processDataMicro(aod::ResoCollision const& resoCollision, + aod::ResoCollisionColls const& collisionIndex, + soa::Join const& collisions, + aod::ResoMicroTracks const& resomicrotracks, + aod::ResoCascades const& cascTracks) { + auto linkRow = collisionIndex.iteratorAt(resoCollision.globalIndex()); + auto collId = linkRow.collisionId(); // Take original collision global index matched with resoCollision + + auto coll = collisions.iteratorAt(collId); // Take original collision matched with resoCollision + + if (cRecoINELgt0 && !coll.isInelGt0()) // Check reco INELgt0 (at least one PV track in |eta| < 1) about the collision + return; histos.fill(HIST("QAevent/hEvtCounterSameE"), 1.0); - fillHistograms(resoCollision, resomicrotracks, cascTracks); + auto multiplicity = resoCollision.cent(); + fillHistograms(resoCollision, multiplicity, resomicrotracks, cascTracks); } using BinningTypeVtxZT0M = ColumnBinningPolicy; @@ -1137,16 +1199,21 @@ struct Xi1530Analysisqa { for (const auto& [collision1, tracks1, collision2, tracks2] : pairs) { histos.fill(HIST("QAevent/hEvtCounterMixedE"), 1.0); - fillHistograms(collision1, tracks1, tracks2); + auto multiplicity = collision1.cent(); + fillHistograms(collision1, multiplicity, tracks1, tracks2); } } void processDataDF(aod::ResoCollisionDF const& resoCollision, aod::ResoTrackDFs const& resotracks, aod::ResoCascadeDFs const& cascTracks) { - - fillHistograms(resoCollision, resotracks, cascTracks); + auto multiplicity = resoCollision.cent(); + fillHistograms(resoCollision, multiplicity, resotracks, cascTracks); } - void processMEMicro(aod::ResoCollisions const& resoCollisions, aod::ResoMicroTracks const& resomicrotracks, aod::ResoCascades const& cascTracks) + void processMEMicro(aod::ResoCollisions const& resoCollisions, + aod::ResoCollisionColls const& collisionIndex, + soa::Join const& collisions, + aod::ResoMicroTracks const& resomicrotracks, + aod::ResoCascades const& cascTracks) { auto tracksTuple = std::make_tuple(resomicrotracks, cascTracks); @@ -1155,8 +1222,18 @@ struct Xi1530Analysisqa { for (const auto& [collision1, tracks1, collision2, tracks2] : pairs) { + const auto rcIdx = collision1.globalIndex(); + + const auto linkRow = collisionIndex.iteratorAt(rcIdx); + const auto collId = linkRow.collisionId(); + + auto coll = collisions.iteratorAt(collId); + if (cRecoINELgt0 && !coll.isInelGt0()) // Check reco INELgt0 (at least one PV track in |eta| < 1) about the collision + continue; + histos.fill(HIST("QAevent/hEvtCounterMixedE"), 1.0); - fillHistograms(collision1, tracks1, tracks2); + auto multiplicity = collision1.cent(); + fillHistograms(collision1, multiplicity, tracks1, tracks2); } } diff --git a/PWGLF/Tasks/Strangeness/CMakeLists.txt b/PWGLF/Tasks/Strangeness/CMakeLists.txt index 99908fd6661..100b8667aab 100644 --- a/PWGLF/Tasks/Strangeness/CMakeLists.txt +++ b/PWGLF/Tasks/Strangeness/CMakeLists.txt @@ -29,11 +29,6 @@ o2physics_add_dpl_workflow(cascadeanalysis PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(sigmaminus-task - SOURCES sigmaminustask.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - o2physics_add_dpl_workflow(cascadeanalysismc SOURCES cascadeanalysisMC.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore @@ -160,3 +155,8 @@ o2physics_add_dpl_workflow(lambdatwopartpolarization SOURCES lambdaTwoPartPolarization.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(cascadeanalysislightions + SOURCES cascadeAnalysisLightIonsDerivedData.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGLF/Tasks/Strangeness/cascadeAnalysisLightIonsDerivedData.cxx b/PWGLF/Tasks/Strangeness/cascadeAnalysisLightIonsDerivedData.cxx new file mode 100644 index 00000000000..5d7178c60e5 --- /dev/null +++ b/PWGLF/Tasks/Strangeness/cascadeAnalysisLightIonsDerivedData.cxx @@ -0,0 +1,1030 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +/// \file cascadeAnalysisLightIonsDerivedData.cxx +/// \brief analysis of cascades (Xi, antiXi, Omega, antiOmega) in light-ion collisions using derived data +/// +/// \author Sara Pucillo (sara.pucillo@cern.ch), Alberto Caliva (alberto.caliva@cern.ch) +// + +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" + +#include "Common/CCDB/ctpRateFetcher.h" +#include "Common/Core/RecoDecay.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CommonConstants/MathConstants.h" +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/Track.h" + +#include +#include +#include +#include +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::constants::math; +using namespace o2::constants::physics; +using std::array; + +using SelCollisions = soa::Join; +using SimCollisions = soa::Join; +using CascadeCandidates = soa::Join; +using CascadeMCCandidates = soa::Join; +using DaughterTracks = soa::Join; +using CollisionMCTrueTable = soa::Join; +using CascadeMCCores = soa::Join; + +struct CascadeAnalysisLightIonsDerivedData { + + // Instantiate the CCDB service and API interface + // CCDB options + struct : ConfigurableGroup { + std::string prefix = "ccdbConfigurations"; // JSON group name + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; + Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; + Configurable geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"}; + Configurable mVtxPath{"mVtxPath", "GLO/Calib/MeanVertex", "Path of the mean vertex file"}; + } ccdbConfigurations; + + o2::ccdb::CcdbApi ccdbApi; + Service ccdb; + int mRunNumber; + + // Define histogram registries + HistogramRegistry registryData{"registryData", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry registryMC{"registryMC", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry registryQC{"registryQC", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + // Global analysis parameters + Configurable zVtx{"zVtx", 10.0, "Maximum zVertex"}; + Configurable deltaEtaEdge{"deltaEtaEdge", 0.05, "eta gap from the edge"}; + Configurable nBins{"nBins", 100, "N bins in all QC histos"}; + + // Event selections parameters + Configurable applySel8{"applySel8", true, "0 - no, 1 - yes"}; + Configurable applyVtxZ{"applyVtxZ", true, "0 - no, 1 - yes"}; + Configurable rejectITSROFBorder{"rejectITSROFBorder", true, "reject events at ITS ROF border"}; + Configurable rejectTFBorder{"rejectTFBorder", true, "reject events at TF border"}; + Configurable requireVertexITSTPC{"requireVertexITSTPC", false, "require events with at least one ITS-TPC track"}; + Configurable requireIsGoodZvtxFT0VsPV{"requireIsGoodZvtxFT0VsPV", false, "require is good Zvtx FT0 vs PV"}; + Configurable requireIsVertexTOFmatched{"requireIsVertexTOFmatched", false, "require events with at least one of vertex contributors matched to TOF"}; + Configurable requireIsVertexTRDmatched{"requireIsVertexTRDmatched", false, "require events with at least one of vertex contributors matched to TRD"}; + Configurable rejectSameBunchPileup{"rejectSameBunchPileup", true, "reject collisions in case of pileup with another collision in the same foundBC"}; + + // Track analysis Parameters + Configurable minITSnCls{"minITSnCls", 4.0f, "min number of ITS clusters"}; + Configurable minTPCnClsFound{"minTPCnClsFound", 80.0f, "min number of found TPC clusters"}; + Configurable minNCrossedRowsTPC{"minNCrossedRowsTPC", 80.0f, "min number of TPC crossed rows"}; + Configurable etaMin{"etaMin", -0.8f, "eta min"}; + Configurable etaMax{"etaMax", +0.8f, "eta max"}; + Configurable rapcut{"rapcut", +0.5f, "rapidity cut"}; + Configurable maxChi2TPC{"maxChi2TPC", 4.0f, "max chi2 per cluster TPC"}; + Configurable requireITS{"requireITS", false, "require ITS hit"}; + Configurable requireTOF{"requireTOF", false, "require TOF hit"}; + + // Configurable parameters for PID selection + Configurable nsigmaTPCmin{"nsigmaTPCmin", -5.0f, "Minimum nsigma TPC"}; + Configurable nsigmaTPCmax{"nsigmaTPCmax", +5.0f, "Maximum nsigma TPC"}; + + // Configurable parameters for TOF PID selection + Configurable nsigmaTOFmin{"nsigmaTOFmin", -3.0f, "Minimum nsigma TOF"}; + Configurable nsigmaTOFmax{"nsigmaTOFmax", +3.0f, "Maximum nsigma TOF"}; + + // Topological Parameters + Configurable dcanegtoPVmin{"dcanegtoPVmin", 0.1f, "Minimum DCA Neg To PV"}; + Configurable dcapostoPVmin{"dcapostoPVmin", 0.1f, "Minimum DCA Pos To PV"}; + Configurable dcabachtopvMin{"dcabachtopvMin", 0.1f, "Minimum DCA bachelor to PV"}; + Configurable dcaV0DaughtersMax{"dcaV0DaughtersMax", 0.7f, "Maximum DCA Daughters"}; + Configurable dcaV0topvMin{"dcaV0topvMin", 0.02f, "Minimum DCA V0 to PV"}; + Configurable dcaCascDaughtersMax{"dcaCascDaughtersMax", 0.8f, "Maximum DCA Daughters"}; + Configurable v0cospaMin{"v0cospaMin", 0.99f, "Minimum V0 CosPA"}; + Configurable casccospaMin{"casccospaMin", 0.99f, "Minimum Cascade CosPA"}; + Configurable minimumV0Radius{"minimumV0Radius", 2.5f, "Minimum V0 Radius"}; + Configurable minimumCascRadius{"minimumCascRadius", 1.1f, "Minimum Cascade Radius"}; + Configurable v0masswindow{"v0masswindow", 0.005, "v0 mass window"}; + Configurable competingmassrej{"competingmassrej", 0.008, "Competing mass rejection"}; + // Axes parameters + ConfigurableAxis centEstimatorHistBin{"centEstimatorHistBin", {501, -0.5, 500.5}, ""}; + ConfigurableAxis centralityBinning{"centralityBinning", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, ""}; + ConfigurableAxis axisNch{"axisNch", {500, 0.0f, +1000.0f}, "Number of charged particles"}; + + // Centrality estimator + Configurable centralityEstimator{"centralityEstimator", 0, "0 = FT0C, 1 = FTOM, 2 = FV0A, 3 = NGlobal"}; + + // List of estimators + enum Option { kFT0C, + kFT0M, + kFV0A, + kNGlobal }; + + // For manual sliceBy + PresliceUnsorted> perMcCollision = aod::v0data::straMCCollisionId; + + void init(InitContext const&) + { + // setting CCDB service + ccdb->setURL(ccdbConfigurations.ccdbUrl); + ccdb->setCaching(true); + ccdb->setFatalWhenNull(false); + ccdb->setLocalObjectValidityChecking(); + ccdb->setCreatedNotAfter( + std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + .count()); + + // Axes and Binning + AxisSpec axisCentEstimator = {centEstimatorHistBin, "CentEstimator", "CentEstimatorAxis"}; + AxisSpec centAxis = {centralityBinning, "Centrality", "CentralityAxis"}; + const AxisSpec vertexZAxis = {nBins, -15., 15., "vrtx_{Z} [cm]"}; + const AxisSpec etaAxis{18, -0.9, 0.9, "#eta"}; + const AxisSpec ptAxis{100, 0.0, 10.0, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec invMassXiAxis{200, 1.28, 1.36, "m_{p#pi#pi} (GeV/#it{c}^{2})"}; + const AxisSpec invMassOmegaAxis{200, 1.63, 1.71, "m_{p#piK} (GeV/#it{c}^{2})"}; + const AxisSpec nsigmaTOFAxis{200, -10, 10, "n#sigma_{TOF}"}; + const AxisSpec nsigmaTPCAxis{200, -10, 10, "n#sigma_{TPC}"}; + + // Histograms for data + if (doprocessData) { + registryData.add("number_of_events_data", "number of events in data", HistType::kTH1D, {{20, -0.5f, +19.5f}}); + registryData.get(HIST("number_of_events_data"))->GetXaxis()->SetBinLabel(1, "All collisions"); + registryData.get(HIST("number_of_events_data"))->GetXaxis()->SetBinLabel(2, "sel8 cut"); + registryData.get(HIST("number_of_events_data"))->GetXaxis()->SetBinLabel(3, "posZ cut"); + registryData.get(HIST("number_of_events_data"))->GetXaxis()->SetBinLabel(4, "kNoITSROFrameBorder"); + registryData.get(HIST("number_of_events_data"))->GetXaxis()->SetBinLabel(5, "kNoTimeFrameBorder"); + registryData.get(HIST("number_of_events_data"))->GetXaxis()->SetBinLabel(6, "kIsVertexITSTPC"); + registryData.get(HIST("number_of_events_data"))->GetXaxis()->SetBinLabel(7, "kIsGoodZvtxFT0vsPV"); + registryData.get(HIST("number_of_events_data"))->GetXaxis()->SetBinLabel(8, "kIsVertexTOFmatched"); + registryData.get(HIST("number_of_events_data"))->GetXaxis()->SetBinLabel(9, "kIsVertexTRDmatched"); + registryData.get(HIST("number_of_events_data"))->GetXaxis()->SetBinLabel(10, "kNoSameBunchPileup"); + + // QC Histograms + registryQC.add("hVertexZdata", "hVertexZdata", HistType::kTH1F, {vertexZAxis}); + registryQC.add("hv0cosPAdata", "hv0cosPAdata", HistType::kTH1F, {{nBins, 0.95f, 1.f}}); + registryQC.add("hcasccosPAdata", "hcasccosPAdata", HistType::kTH1F, {{nBins, 0.95f, 1.f}}); + registryQC.add("hv0radiusdata", "hv0radiusdata", HistType::kTH1F, {{nBins, 0.0f, 5.0f}}); + registryQC.add("hcascradiusdata", "hcascradiusdata", HistType::kTH1F, {{nBins, 0.0f, 5.0f}}); + registryQC.add("hdcaV0daughtersdata", "hdcaV0daughtersdata", HistType::kTH1F, {{nBins, 0.0f, 1.5f}}); + registryQC.add("hdcacascdaughtersdata", "hdcacascdaughtersdata", HistType::kTH1F, {{nBins, 0.0f, 1.5f}}); + registryQC.add("hdcapostopvdata", "hdcapostopvdata", HistType::kTH1F, {{nBins, 0.0f, 2.0f}}); + registryQC.add("hdcanegtopvdata", "hdcanegtopvdata", HistType::kTH1F, {{nBins, 0.0f, 2.0f}}); + registryQC.add("hdcabachtopvdata", "hdcabachtopvdata", HistType::kTH1F, {{nBins, 0.0f, 2.0f}}); + registryQC.add("hdcav0topvdata", "hdcav0topvdata", HistType::kTH1F, {{nBins, 0.0f, 2.0f}}); + + // Multiplicity Histograms + registryData.add("hCentEstimator", "hCentEstimator", HistType::kTH1D, {axisCentEstimator}); + registryData.add("hCentralityVsNch", "hCentralityVsNch", HistType::kTH2D, {axisCentEstimator, axisNch}); + + // Histograms for xi (data) + registryData.add("hMassXipos", "hMassXipos", HistType::kTH3F, {centAxis, ptAxis, invMassXiAxis}); + registryData.add("hMassXineg", "hMassXineg", HistType::kTH3F, {centAxis, ptAxis, invMassXiAxis}); + registryData.add("hMassXiposSelected", "hMassXiposSelected", HistType::kTH3F, {centAxis, ptAxis, invMassXiAxis}); + registryData.add("hMassXinegSelected", "hMassXinegSelected", HistType::kTH3F, {centAxis, ptAxis, invMassXiAxis}); + + // Histograms for omega (data) + registryData.add("hMassOmegapos", "hMassOmegapos", HistType::kTH3F, {centAxis, ptAxis, invMassOmegaAxis}); + registryData.add("hMassOmeganeg", "hMassOmeganeg", HistType::kTH3F, {centAxis, ptAxis, invMassOmegaAxis}); + registryData.add("hMassOmegaposSelected", "hMassOmegaposSelected", HistType::kTH3F, {centAxis, ptAxis, invMassOmegaAxis}); + registryData.add("hMassOmeganegSelected", "hMassOmeganegSelected", HistType::kTH3F, {centAxis, ptAxis, invMassOmegaAxis}); + } + + if (doprocessMonteCarloRec) { + // Histograms for mc reconstructed + registryMC.add("number_of_events_mc_rec", "number of events in mc_rec", HistType::kTH1D, {{20, -0.5f, +19.5f}}); + registryMC.get(HIST("number_of_events_mc_rec"))->GetXaxis()->SetBinLabel(1, "All collisions"); + registryMC.get(HIST("number_of_events_mc_rec"))->GetXaxis()->SetBinLabel(2, "sel8 cut"); + registryMC.get(HIST("number_of_events_mc_rec"))->GetXaxis()->SetBinLabel(3, "posZ cut"); + registryMC.get(HIST("number_of_events_mc_rec"))->GetXaxis()->SetBinLabel(4, "kNoITSROFrameBorder"); + registryMC.get(HIST("number_of_events_mc_rec"))->GetXaxis()->SetBinLabel(5, "kNoTimeFrameBorder"); + registryMC.get(HIST("number_of_events_mc_rec"))->GetXaxis()->SetBinLabel(6, "kIsVertexITSTPC"); + registryMC.get(HIST("number_of_events_mc_rec"))->GetXaxis()->SetBinLabel(7, "kIsGoodZvtxFT0vsPV"); + registryMC.get(HIST("number_of_events_mc_rec"))->GetXaxis()->SetBinLabel(8, "kIsVertexTOFmatched"); + registryMC.get(HIST("number_of_events_mc_rec"))->GetXaxis()->SetBinLabel(9, "kIsVertexTRDmatched"); + registryMC.get(HIST("number_of_events_mc_rec"))->GetXaxis()->SetBinLabel(10, "kNoSameBunchPileup"); + + // QC Histograms + registryQC.add("hVertexZRec", "hVertexZRec", HistType::kTH1F, {{vertexZAxis}}); + registryQC.add("hv0cosPARec", "hv0cosPARec", HistType::kTH1F, {{nBins, 0.95f, 1.f}}); + registryQC.add("hcasccosPARec", "hcasccosPARec", HistType::kTH1F, {{nBins, 0.95f, 1.f}}); + registryQC.add("hv0radiusRec", "hv0radiusRec", HistType::kTH1F, {{nBins, 0.0f, 5.0f}}); + registryQC.add("hcascradiusRec", "hcascradiusRec", HistType::kTH1F, {{nBins, 0.0f, 5.0f}}); + registryQC.add("hdcaV0daughtersRec", "hdcaV0daughtersRec", HistType::kTH1F, {{nBins, 0.0f, 1.5f}}); + registryQC.add("hdcacascdaughtersRec", "hdcacascdaughtersRec", HistType::kTH1F, {{nBins, 0.0f, 1.5f}}); + registryQC.add("hdcapostopvRec", "hdcapostopvRec", HistType::kTH1F, {{nBins, 0.0f, 2.0f}}); + registryQC.add("hdcanegtopvRec", "hdcanegtopvRec", HistType::kTH1F, {{nBins, 0.0f, 2.0f}}); + registryQC.add("hdcabachtopvRec", "hdcabachtopvRec", HistType::kTH1F, {{nBins, 0.0f, 2.0f}}); + registryQC.add("hdcav0topvRec", "hdcav0topvRec", HistType::kTH1F, {{nBins, 0.0f, 2.0f}}); + + // Multiplicity Histograms + registryMC.add("hCentEstimator_truerec", "hCentEstimator_truerec", HistType::kTH1D, {axisCentEstimator}); + registryMC.add("hCentralityVsNch_truerec", "hCentralityVsNch_truerec", HistType::kTH2D, {axisCentEstimator, axisNch}); + + // Histograms for xi (mc) + registryMC.add("hMassXipos_truerec", "hMassXipos_truerec", HistType::kTH3F, {centAxis, ptAxis, invMassXiAxis}); + registryMC.add("hMassXineg_truerec", "hMassXineg_truerec", HistType::kTH3F, {centAxis, ptAxis, invMassXiAxis}); + registryMC.add("hMassXiposSelected_truerec", "hMassXiposSelected_truerec", HistType::kTH3F, {centAxis, ptAxis, invMassXiAxis}); + registryMC.add("hMassXinegSelected_truerec", "hMassXinegSelected_truerec", HistType::kTH3F, {centAxis, ptAxis, invMassXiAxis}); + + // Histograms for omega (mc) + registryMC.add("hMassOmegapos_truerec", "hMassOmegapos_truerec", HistType::kTH3F, {centAxis, ptAxis, invMassOmegaAxis}); + registryMC.add("hMassOmeganeg_truerec", "hMassOmeganeg_truerec", HistType::kTH3F, {centAxis, ptAxis, invMassOmegaAxis}); + registryMC.add("hMassOmegaposSelected_truerec", "hMassOmegaposSelected_truerec", HistType::kTH3F, {centAxis, ptAxis, invMassOmegaAxis}); + registryMC.add("hMassOmeganegSelected_truerec", "hMassOmeganegSelected_truerec", HistType::kTH3F, {centAxis, ptAxis, invMassOmegaAxis}); + } + + if (doprocessMonteCarloGen) { + // Histograms for mc generated + // QC Histograms + registryQC.add("hVertexZGen", "hVertexZGen", HistType::kTH1F, {{vertexZAxis}}); + // Histograms for xi (mc) + registryMC.add("h2dGenXiMinusVsMultMC_RecoedEvt", "h2dGenXiMinusVsMultMC_RecoedEvt", HistType::kTH2F, {axisNch, ptAxis}); + registryMC.add("h2dGenXiPlusVsMultMC_RecoedEvt", "h2dGenXiPlusVsMultMC_RecoedEvt", HistType::kTH2F, {axisNch, ptAxis}); + registryMC.add("h2dGenXiMinusVsMultMC", "h2dGenXiMinusVsMultMC", HistType::kTH2F, {axisNch, ptAxis}); + registryMC.add("h2dGenXiPlusVsMultMC", "h2dGenXiPlusVsMultMC", HistType::kTH2F, {axisNch, ptAxis}); + + // Histograms for omega (mc) + registryMC.add("h2dGenOmegaMinusVsMultMC_RecoedEvt", "h2dGenOmegaMinusVsMultMC_RecoedEvt", HistType::kTH2F, {axisNch, ptAxis}); + registryMC.add("h2dGenOmegaPlusVsMultMC_RecoedEvt", "h2dGenOmegaPlusVsMultMC_RecoedEvt", HistType::kTH2F, {axisNch, ptAxis}); + registryMC.add("h2dGenOmegaMinusVsMultMC", "h2dGenOmegaMinusVsMultMC", HistType::kTH2F, {axisNch, ptAxis}); + registryMC.add("h2dGenOmegaPlusVsMultMC", "h2dGenOmegaPlusVsMultMC", HistType::kTH2F, {axisNch, ptAxis}); + + // Histograms for event loss/splitting + registryMC.add("hGenEvents", "hGenEvents", HistType::kTH2F, {{axisNch}, {2, -0.5f, +1.5f}}); + registryMC.get(HIST("hGenEvents"))->GetYaxis()->SetBinLabel(1, "All gen. events"); + registryMC.get(HIST("hGenEvents"))->GetYaxis()->SetBinLabel(2, "Gen. with at least 1 rec. events"); + registryMC.add("hGenEventCentrality", "hGenEventCentrality", kTH1D, {{101, 0.0f, 101.0f}}); + + registryMC.add("hCentralityVsNcoll_beforeEvSel", "hCentralityVsNcoll_beforeEvSel", HistType::kTH2F, {centAxis, {50, -0.5f, 49.5f}}); + registryMC.add("hCentralityVsNcoll_afterEvSel", "hCentralityVsNcoll_afterEvSel", HistType::kTH2F, {centAxis, {50, -0.5f, 49.5f}}); + + registryMC.add("hCentralityVsMultMC", "hCentralityVsMultMC", HistType::kTH2F, {{101, 0.0f, 101.0f}, axisNch}); + } + } + + // ______________________________________________________ + // Return slicing output + template + auto getGroupedCollisions(TCollisions const& collisions, int globalIndex) + { + return collisions.sliceBy(perMcCollision, globalIndex); + } + + template + void initCCDB(TCollision collision) + { + if (mRunNumber == collision.runNumber()) { + return; + } + + mRunNumber = collision.runNumber(); + } + + // Find ITS hit + // template + // bool hasITSHitOnLayer(const TrackIts& track, int layer) + // { + // int ibit = layer - 1; + // return (track.itsClusterMap() & (1 << ibit)); + // } + + // Single-Track Selection + template + bool passedSingleTrackSelection(const Track& track) + { + if (requireITS && (!track.hasITS())) + return false; + if (requireITS && track.itsNCls() < minITSnCls) + return false; + if (!track.hasTPC()) + return false; + if (track.tpcNClsFound() < minTPCnClsFound) + return false; + if (track.tpcNClsCrossedRows() < minNCrossedRowsTPC) + return false; + if (track.tpcChi2NCl() > maxChi2TPC) + return false; + if (requireTOF && (!track.hasTOF())) + return false; + return true; + } + + // Xi Selection + template + bool passedXiSelection(const Xi& casc, const TrackPos& ptrack, + const TrackNeg& ntrack, const TrackBac& btrack, + const Coll& coll) + { + if (!passedSingleTrackSelection(ptrack)) + return false; + if (!passedSingleTrackSelection(ntrack)) + return false; + if (!passedSingleTrackSelection(btrack)) + return false; + + if (std::abs(casc.yXi()) > rapcut) + return false; + + // Xi+ Selection (Xi+ -> antiL + pi+) + if (casc.sign() > 0) { + + // PID Selections (TPC) + if (ntrack.tpcNSigmaPr() < nsigmaTPCmin || + ntrack.tpcNSigmaPr() > nsigmaTPCmax) + return false; + if (ptrack.tpcNSigmaPi() < nsigmaTPCmin || + ptrack.tpcNSigmaPi() > nsigmaTPCmax) + return false; + + // PID Selections (TOF) + if (requireTOF) { + if (casc.tofNSigmaXiLaPr() < nsigmaTOFmin || + casc.tofNSigmaXiLaPr() > nsigmaTOFmax) + return false; + if (casc.tofNSigmaXiLaPi() < nsigmaTOFmin || + casc.tofNSigmaXiLaPi() > nsigmaTOFmax) + return false; + } + } + + // Xi- Selection (Xi- -> L + pi-) + if (casc.sign() < 0) { + + // PID Selections (TPC) + if (ptrack.tpcNSigmaPr() < nsigmaTPCmin || + ptrack.tpcNSigmaPr() > nsigmaTPCmax) + return false; + if (ntrack.tpcNSigmaPi() < nsigmaTPCmin || + ntrack.tpcNSigmaPi() > nsigmaTPCmax) + return false; + + // PID Selections (TOF) + if (requireTOF) { + if (casc.tofNSigmaXiLaPr() < nsigmaTOFmin || + casc.tofNSigmaXiLaPr() > nsigmaTOFmax) + return false; + if (casc.tofNSigmaXiLaPi() < nsigmaTOFmin || + casc.tofNSigmaXiLaPi() > nsigmaTOFmax) + return false; + } + } + + if (casc.v0cosPA(coll.posX(), coll.posY(), coll.posZ()) < v0cospaMin) + return false; + if (casc.v0radius() < minimumV0Radius) + return false; + if (std::fabs(casc.dcaV0daughters()) > dcaV0DaughtersMax) + return false; + if (std::fabs(casc.dcapostopv()) < dcapostoPVmin) + return false; + if (std::fabs(casc.dcanegtopv()) < dcanegtoPVmin) + return false; + + if (casc.casccosPA(coll.posX(), coll.posY(), coll.posZ()) < casccospaMin) + return false; + if (casc.cascradius() < minimumCascRadius) + return false; + if (std::fabs(casc.dcabachtopv()) < dcabachtopvMin) + return false; + if (std::fabs(casc.dcav0topv(coll.posX(), coll.posY(), coll.posZ())) < + dcaV0topvMin) + return false; + if (std::fabs(casc.dcacascdaughters()) > dcaCascDaughtersMax) + return false; + + // V0 mass window + if (std::abs(casc.mLambda() - o2::constants::physics::MassLambda0) > + v0masswindow) + return false; + + // reject candidates compatible with omega + if (std::abs(casc.mOmega() - o2::constants::physics::MassOmegaMinus) < + competingmassrej) + return false; + + // PID Selection on bachelor + if (btrack.tpcNSigmaPi() < nsigmaTPCmin || + btrack.tpcNSigmaPi() > nsigmaTPCmax) + return false; + + // PID Selections (TOF) + if (requireTOF) { + if (casc.tofNSigmaXiPi() < nsigmaTOFmin || + casc.tofNSigmaXiPi() > nsigmaTOFmax) + return false; + } + return true; + } + + // Omega Selection + template + bool passedOmegaSelection(const Omega& casc, const TrackPos& ptrack, + const TrackNeg& ntrack, const TrackBac& btrack, + const Coll& coll) + { + if (!passedSingleTrackSelection(ptrack)) + return false; + if (!passedSingleTrackSelection(ntrack)) + return false; + if (!passedSingleTrackSelection(btrack)) + return false; + + if (std::abs(casc.yOmega()) > rapcut) + return false; + + // Omega+ Selection (Omega+ -> antiL + K+) + if (casc.sign() > 0) { + // PID Selections (TPC) + if (ntrack.tpcNSigmaPr() < nsigmaTPCmin || + ntrack.tpcNSigmaPr() > nsigmaTPCmax) + return false; + if (ptrack.tpcNSigmaPi() < nsigmaTPCmin || + ptrack.tpcNSigmaPi() > nsigmaTPCmax) + return false; + + // PID Selections (TOF) + if (requireTOF) { + if (casc.tofNSigmaOmLaPr() < nsigmaTOFmin || + casc.tofNSigmaOmLaPr() > nsigmaTOFmax) + return false; + if (casc.tofNSigmaOmLaPi() < nsigmaTOFmin || + casc.tofNSigmaOmLaPi() > nsigmaTOFmax) + return false; + } + } + + // Omega- Selection (Omega- -> L + K-) + if (casc.sign() < 0) { + // PID Selections (TPC) + if (ptrack.tpcNSigmaPr() < nsigmaTPCmin || + ptrack.tpcNSigmaPr() > nsigmaTPCmax) + return false; + if (ntrack.tpcNSigmaPi() < nsigmaTPCmin || + ntrack.tpcNSigmaPi() > nsigmaTPCmax) + return false; + + // PID Selections (TOF) + if (requireTOF) { + if (casc.tofNSigmaOmLaPr() < nsigmaTOFmin || + casc.tofNSigmaOmLaPr() > nsigmaTOFmax) + return false; + if (casc.tofNSigmaOmLaPi() < nsigmaTOFmin || + casc.tofNSigmaOmLaPi() > nsigmaTOFmax) + return false; + } + } + + if (casc.v0cosPA(coll.posX(), coll.posY(), coll.posZ()) < v0cospaMin) + return false; + if (casc.v0radius() < minimumV0Radius) + return false; + if (std::fabs(casc.dcaV0daughters()) > dcaV0DaughtersMax) + return false; + if (std::fabs(casc.dcapostopv()) < dcapostoPVmin) + return false; + if (std::fabs(casc.dcanegtopv()) < dcanegtoPVmin) + return false; + + if (casc.casccosPA(coll.posX(), coll.posY(), coll.posZ()) < casccospaMin) + return false; + if (casc.cascradius() < minimumCascRadius) + return false; + if (std::fabs(casc.dcabachtopv()) < dcabachtopvMin) + return false; + if (std::fabs(casc.dcav0topv(coll.posX(), coll.posY(), coll.posZ())) < + dcaV0topvMin) + return false; + if (std::fabs(casc.dcacascdaughters()) > dcaCascDaughtersMax) + return false; + + // V0 mass window + if (std::abs(casc.mLambda() - o2::constants::physics::MassLambda0) > + v0masswindow) + return false; + + // Reject candidates compatible with Xi + if (std::abs(casc.mXi() - o2::constants::physics::MassXiMinus) < + competingmassrej) + return false; + + // PID Selection on bachelor + if (btrack.tpcNSigmaKa() < nsigmaTPCmin || + btrack.tpcNSigmaKa() > nsigmaTPCmax) + return false; + + // PID Selections (TOF) + if (requireTOF) { + if (casc.tofNSigmaOmKa() < nsigmaTOFmin || + casc.tofNSigmaOmKa() > nsigmaTOFmax) + return false; + } + return true; + } + + // Return the list of indices to the recoed collision associated to a given MC collision. + template + std::vector getListOfRecoCollIndices(TMCollisions const& mcCollisions, TCollisions const& collisions) + { + std::vector listBestCollisionIdx(mcCollisions.size()); + for (auto const& mcCollision : mcCollisions) { + auto groupedCollisions = getGroupedCollisions(collisions, mcCollision.globalIndex()); + int biggestNContribs = -1; + int bestCollisionIndex = -1; + for (auto const& collision : groupedCollisions) { + // event selections + if (applySel8 && !collision.sel8()) + continue; + + if (applyVtxZ && std::fabs(collision.posZ()) > zVtx) + continue; + + if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { + continue; + } + + if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { + continue; + } + + if (requireVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { + continue; + } + + if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + continue; + } + + if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { + continue; + } + + if (requireIsVertexTRDmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)) { + continue; + } + + if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + continue; + } + + // Find the collision with the biggest nbr of PV contributors + // Follows what was done here: https://github.com/AliceO2Group/O2Physics/blob/master/Common/TableProducer/mcCollsExtra.cxx#L93 + if (biggestNContribs < collision.multPVTotalContributors()) { + biggestNContribs = collision.multPVTotalContributors(); + bestCollisionIndex = collision.globalIndex(); + } + } + listBestCollisionIdx[mcCollision.globalIndex()] = bestCollisionIndex; + } + return listBestCollisionIdx; + } + + // Fill generated event information (for event loss/splitting estimation) + template + void fillGeneratedEventProperties(TMCCollisions const& mcCollisions, TCollisions const& collisions) + { + std::vector listBestCollisionIdx(mcCollisions.size()); + for (auto const& mcCollisions : mcCollisions) { + // event selections + if (applyVtxZ && std::fabs(mcCollisions.posZ()) > zVtx) + return; + + registryMC.fill(HIST("hGenEvents"), mcCollisions.multMCNParticlesEta05(), 0 /* all gen. events*/); + + auto groupedCollisions = getGroupedCollisions(collisions, mcCollisions.globalIndex()); + // Check if there is at least one of the reconstructed collisions associated to this MC collision + // If so, we consider it + bool atLeastOne = false; + int biggestNContribs = -1; + int nCollisions = 0; + float multiplicitydata = -1.0f; + for (auto const& collision : groupedCollisions) { + // event selections + if (applySel8 && !collision.sel8()) + continue; + + if (applyVtxZ && std::fabs(collision.posZ()) > zVtx) + continue; + + if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { + continue; + } + + if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { + continue; + } + + if (requireVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { + continue; + } + + if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + continue; + } + + if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { + continue; + } + + if (requireIsVertexTRDmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)) { + continue; + } + + if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + continue; + } + + if (biggestNContribs < collision.multPVTotalContributors()) { + biggestNContribs = collision.multPVTotalContributors(); + if (centralityEstimator == Option::kFT0C) + multiplicitydata = collision.centFT0C(); + if (centralityEstimator == Option::kFT0M) + multiplicitydata = collision.centFT0M(); + if (centralityEstimator == Option::kFV0A) + multiplicitydata = collision.centFV0A(); + if (centralityEstimator == Option::kNGlobal) + multiplicitydata = collision.centNGlobal(); + } + nCollisions++; + + atLeastOne = true; + } + + registryMC.fill(HIST("hCentralityVsNcoll_beforeEvSel"), multiplicitydata, groupedCollisions.size()); + registryMC.fill(HIST("hCentralityVsNcoll_afterEvSel"), multiplicitydata, nCollisions); + registryMC.fill(HIST("hCentralityVsMultMC"), multiplicitydata, mcCollisions.multMCNParticlesEta05()); + + registryQC.fill(HIST("hVertexZGen"), mcCollisions.posZ()); + + if (atLeastOne) { + registryMC.fill(HIST("hGenEvents"), mcCollisions.multMCNParticlesEta05(), 1 /* at least 1 rec. event*/); + + registryMC.fill(HIST("hGenEventCentrality"), multiplicitydata); + } + } + return; + } + + void processData(SelCollisions::iterator const& collision, + CascadeCandidates const& fullCascades, + DaughterTracks const&) + { + // Fill event counter before event selection + registryData.fill(HIST("number_of_events_data"), 0); + + // Initialize CCDB objects using the BC info + initCCDB(collision); + + // event selections + if (applySel8 && !collision.sel8()) + return; + registryData.fill(HIST("number_of_events_data"), 1); + if (applyVtxZ && std::fabs(collision.posZ()) > zVtx) + return; + registryData.fill(HIST("number_of_events_data"), 2); + + if (rejectITSROFBorder && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { + return; + } + registryData.fill(HIST("number_of_events_data"), 3 /* Not at ITS ROF border */); + + if (rejectTFBorder && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { + return; + } + registryData.fill(HIST("number_of_events_data"), 4 /* Not at TF border */); + + if (requireVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { + return; + } + registryData.fill(HIST("number_of_events_data"), 5 /* Contains at least one ITS-TPC track */); + + if (requireIsGoodZvtxFT0VsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + return; + } + registryData.fill(HIST("number_of_events_data"), 6 /* PV position consistency check */); + + if (requireIsVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { + return; + } + registryData.fill(HIST("number_of_events_data"), 7 /* PV with at least one contributor matched with TOF */); + + if (requireIsVertexTRDmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)) { + return; + } + registryData.fill(HIST("number_of_events_data"), 8 /* PV with at least one contributor matched with TRD */); + + if (rejectSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + return; + } + registryData.fill(HIST("number_of_events_data"), 9 /* Not at same bunch pile-up */); + + // Store the Zvtx + registryQC.fill(HIST("hVertexZdata"), std::fabs(collision.posZ())); + + // Store the event multiplicity using different estimators + float multiplicity = -1.0f; + + if (centralityEstimator == Option::kFT0C) + multiplicity = collision.centFT0C(); + if (centralityEstimator == Option::kFT0M) + multiplicity = collision.centFT0M(); + if (centralityEstimator == Option::kFV0A) + multiplicity = collision.centFV0A(); + if (centralityEstimator == Option::kNGlobal) + multiplicity = collision.centNGlobal(); + + registryData.fill(HIST("hCentEstimator"), multiplicity); + registryData.fill(HIST("hCentralityVsNch"), multiplicity, collision.multNTracksPVeta1()); + + // Loop over cascades + for (const auto& casc : fullCascades) { + if (etaMin > casc.bacheloreta() || casc.bacheloreta() > etaMax || + etaMin > casc.negativeeta() || casc.negativeeta() > etaMax || + etaMin > casc.positiveeta() || casc.positiveeta() > etaMax) + continue; // remove acceptance that's badly reproduced by MC / superfluous in future + + // Get cascade daughters + auto bach = casc.bachTrackExtra_as(); + auto pos = casc.posTrackExtra_as(); + auto neg = casc.negTrackExtra_as(); + + // ------------------------------------- Store selctions distribution for QC + registryQC.fill(HIST("hv0cosPAdata"), casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ())); + registryQC.fill(HIST("hcasccosPAdata"), casc.casccosPA(collision.posX(), collision.posY(), collision.posZ())); + registryQC.fill(HIST("hv0radiusdata"), casc.v0radius()); + registryQC.fill(HIST("hcascradiusdata"), casc.cascradius()); + registryQC.fill(HIST("hdcaV0daughtersdata"), casc.dcaV0daughters()); + registryQC.fill(HIST("hdcacascdaughtersdata"), casc.dcacascdaughters()); + registryQC.fill(HIST("hdcapostopvdata"), casc.dcapostopv()); + registryQC.fill(HIST("hdcanegtopvdata"), casc.dcanegtopv()); + registryQC.fill(HIST("hdcabachtopvdata"), casc.dcabachtopv()); + registryQC.fill(HIST("hdcav0topvdata"), casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ())); + + // ------------------------------------- Store selctions distribution for analysis + if (casc.sign() < 0) { + registryData.fill(HIST("hMassXineg"), multiplicity, casc.pt(), casc.mXi()); + registryData.fill(HIST("hMassOmeganeg"), multiplicity, casc.pt(), casc.mOmega()); + } + if (casc.sign() > 0) { + registryData.fill(HIST("hMassXipos"), multiplicity, casc.pt(), casc.mXi()); + registryData.fill(HIST("hMassOmegapos"), multiplicity, casc.pt(), casc.mOmega()); + } + + if (casc.sign() < 0 && passedXiSelection(casc, pos, neg, bach, collision)) { + registryData.fill(HIST("hMassXinegSelected"), multiplicity, casc.pt(), casc.mXi()); + } + if (casc.sign() < 0 && passedOmegaSelection(casc, pos, neg, bach, collision)) { + registryData.fill(HIST("hMassOmeganegSelected"), multiplicity, casc.pt(), casc.mOmega()); + } + if (casc.sign() > 0 && passedXiSelection(casc, pos, neg, bach, collision)) { + registryData.fill(HIST("hMassXiposSelected"), multiplicity, casc.pt(), casc.mXi()); + } + if (casc.sign() > 0 && passedOmegaSelection(casc, pos, neg, bach, collision)) { + registryData.fill(HIST("hMassOmegaposSelected"), multiplicity, casc.pt(), casc.mOmega()); + } + } + } + + PROCESS_SWITCH(CascadeAnalysisLightIonsDerivedData, processData, "Process data", true); + + void processMonteCarloRec(SimCollisions const& RecCols, CascadeMCCandidates const& fullCascades, DaughterTracks const&) + { + for (const auto& RecCol : RecCols) { + // Fill event counter before event selection + registryMC.fill(HIST("number_of_events_mc_rec"), 0); + + // Initialize CCDB objects using the BC info + initCCDB(RecCol); + + // event selections + if (applySel8 && !RecCol.sel8()) + continue; + registryMC.fill(HIST("number_of_events_mc_rec"), 1); + + if (applyVtxZ && std::fabs(RecCol.posZ()) > zVtx) + continue; + registryMC.fill(HIST("number_of_events_mc_rec"), 2); + + if (rejectITSROFBorder && !RecCol.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) { + continue; + } + registryMC.fill(HIST("number_of_events_mc_rec"), 3 /* Not at ITS ROF border */); + + if (rejectTFBorder && !RecCol.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) { + continue; + } + registryMC.fill(HIST("number_of_events_mc_rec"), 4 /* Not at TF border */); + + if (requireVertexITSTPC && !RecCol.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) { + continue; + } + registryMC.fill(HIST("number_of_events_mc_rec"), 5 /* Contains at least one ITS-TPC track */); + + if (requireIsGoodZvtxFT0VsPV && !RecCol.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) { + continue; + } + registryMC.fill(HIST("number_of_events_mc_rec"), 6 /* PV position consistency check */); + + if (requireIsVertexTOFmatched && !RecCol.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) { + continue; + } + registryMC.fill(HIST("number_of_events_mc_rec"), 7 /* PV with at least one contributor matched with TOF */); + + if (requireIsVertexTRDmatched && !RecCol.selection_bit(o2::aod::evsel::kIsVertexTRDmatched)) { + continue; + } + registryMC.fill(HIST("number_of_events_mc_rec"), 8 /* PV with at least one contributor matched with TRD */); + + if (rejectSameBunchPileup && !RecCol.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) { + continue; + } + registryMC.fill(HIST("number_of_events_mc_rec"), 9 /* Not at same bunch pile-up */); + + // Store the Zvtx + registryQC.fill(HIST("hVertexZRec"), RecCol.posZ()); + + // Store the event multiplicity using different estimators + float multiplicityMcRec = -1.0f; + + if (centralityEstimator == Option::kFT0C) + multiplicityMcRec = RecCol.centFT0C(); + if (centralityEstimator == Option::kFT0M) + multiplicityMcRec = RecCol.centFT0M(); + if (centralityEstimator == Option::kFV0A) + multiplicityMcRec = RecCol.centFV0A(); + if (centralityEstimator == Option::kNGlobal) + multiplicityMcRec = RecCol.centNGlobal(); + + registryMC.fill(HIST("hCentEstimator_truerec"), multiplicityMcRec); + registryMC.fill(HIST("hCentralityVsNch_truerec"), multiplicityMcRec, RecCol.multNTracksPVeta1()); + + for (const auto& casc : fullCascades) { + if (etaMin > casc.bacheloreta() || casc.bacheloreta() > etaMax || + etaMin > casc.negativeeta() || casc.negativeeta() > etaMax || + etaMin > casc.positiveeta() || casc.positiveeta() > etaMax) + continue; // remove acceptance that's badly reproduced by MC / superfluous in future + + if (!casc.has_cascMCCore()) + continue; + + auto cascMC = casc.template cascMCCore_as(); + + auto bach = casc.bachTrackExtra_as(); + auto pos = casc.posTrackExtra_as(); + auto neg = casc.negTrackExtra_as(); + + int pdgParent = cascMC.pdgCode(); + bool isPhysPrim = cascMC.isPhysicalPrimary(); + if (pdgParent == 0) + continue; + if (!isPhysPrim) + continue; + + float ptmc = RecoDecay::sqrtSumOfSquares(cascMC.pxMC(), cascMC.pyMC()); + + // ------------------------------------- Store selctions distribution for QC + registryQC.fill(HIST("hv0cosPARec"), casc.v0cosPA(RecCol.posX(), RecCol.posY(), RecCol.posZ())); + registryQC.fill(HIST("hcasccosPARec"), casc.casccosPA(RecCol.posX(), RecCol.posY(), RecCol.posZ())); + registryQC.fill(HIST("hv0radiusRec"), casc.v0radius()); + registryQC.fill(HIST("hcascradiusRec"), casc.cascradius()); + registryQC.fill(HIST("hdcaV0daughtersRec"), casc.dcaV0daughters()); + registryQC.fill(HIST("hdcacascdaughtersRec"), casc.dcacascdaughters()); + registryQC.fill(HIST("hdcapostopvRec"), casc.dcapostopv()); + registryQC.fill(HIST("hdcanegtopvRec"), casc.dcanegtopv()); + registryQC.fill(HIST("hdcabachtopvRec"), casc.dcabachtopv()); + registryQC.fill(HIST("hdcav0topvRec"), casc.dcav0topv(RecCol.posX(), RecCol.posY(), RecCol.posZ())); + + // ------------------------------------- Store selctions distribution for analysis + if (casc.sign() < 0) { + if (pdgParent == kXiMinus) { + registryMC.fill(HIST("hMassXineg_truerec"), multiplicityMcRec, ptmc, casc.mXi()); + } + if (pdgParent == kOmegaMinus) { + registryMC.fill(HIST("hMassOmeganeg_truerec"), multiplicityMcRec, ptmc, casc.mOmega()); + } + } + + if (casc.sign() > 0) { + if (pdgParent == kXiPlusBar) { + registryMC.fill(HIST("hMassXipos_truerec"), multiplicityMcRec, ptmc, casc.mXi()); + } + if (pdgParent == kOmegaPlusBar) { + registryMC.fill(HIST("hMassOmegapos_truerec"), multiplicityMcRec, ptmc, casc.mOmega()); + } + } + + if (casc.sign() < 0 && pdgParent == kXiMinus && passedXiSelection(casc, pos, neg, bach, RecCol)) { + registryMC.fill(HIST("hMassXinegSelected_truerec"), multiplicityMcRec, ptmc, casc.mXi()); + } + if (casc.sign() < 0 && pdgParent == kOmegaMinus && passedOmegaSelection(casc, pos, neg, bach, RecCol)) { + registryMC.fill(HIST("hMassOmeganegSelected_truerec"), multiplicityMcRec, ptmc, casc.mOmega()); + } + if (casc.sign() > 0 && pdgParent == kXiPlusBar && passedXiSelection(casc, pos, neg, bach, RecCol)) { + registryMC.fill(HIST("hMassXiposSelected_truerec"), multiplicityMcRec, ptmc, casc.mXi()); + } + if (casc.sign() > 0 && pdgParent == kOmegaPlusBar && passedOmegaSelection(casc, pos, neg, bach, RecCol)) { + registryMC.fill(HIST("hMassOmegaposSelected_truerec"), multiplicityMcRec, ptmc, casc.mOmega()); + } + } // casc loop + } // rec.collision loop + } + + PROCESS_SWITCH(CascadeAnalysisLightIonsDerivedData, processMonteCarloRec, "Process MC Rec", false); + + void processMonteCarloGen(CollisionMCTrueTable const& mcCollisions, + CascadeMCCores const& CascMCCores, + SimCollisions const& RecCols) + { + // Fill generated event information (for event loss/splitting estimation) + fillGeneratedEventProperties(mcCollisions, RecCols); + std::vector listBestCollisionIdx = getListOfRecoCollIndices(mcCollisions, RecCols); + for (auto const& cascMC : CascMCCores) { + int pdgParent = cascMC.pdgCode(); + bool isPhysPrim = cascMC.isPhysicalPrimary(); + if (pdgParent == 0) + continue; + if (!isPhysPrim) + continue; + + float ptmc = RecoDecay::sqrtSumOfSquares(cascMC.pxMC(), cascMC.pyMC()); + + auto mcCollision = cascMC.template straMCCollision_as(); + + // event selections + if (applyVtxZ && std::abs(mcCollision.posZ()) > zVtx) + return; + + // Store the Zvtx + registryQC.fill(HIST("hVertexZGen"), mcCollision.posZ()); + + // float centrality = 100.5f; + + if (listBestCollisionIdx[mcCollision.globalIndex()] > -1) { + // auto collision = RecCols.iteratorAt(listBestCollisionIdx[mcCollision.globalIndex()]); + // if (centralityEstimator == Option::kFT0C) centrality = collision.centFT0C(); + // if (centralityEstimator == Option::kFT0M) centrality = collision.centFT0M(); + // if (centralityEstimator == Option::kFV0A) centrality = collision.centFV0A(); + // if (centralityEstimator == Option::kNGlobal) centrality = collision.centNGlobal(); + + if (cascMC.pdgCode() == kXiMinus && std::abs(cascMC.rapidityMC(0)) < rapcut) { + registryMC.fill(HIST("h2dGenXiMinusVsMultMC_RecoedEvt"), mcCollision.multMCNParticlesEta05(), ptmc); + } + if (cascMC.pdgCode() == kXiPlusBar && std::abs(cascMC.rapidityMC(0)) < rapcut) { + registryMC.fill(HIST("h2dGenXiPlusVsMultMC_RecoedEvt"), mcCollision.multMCNParticlesEta05(), ptmc); + } + if (cascMC.pdgCode() == kOmegaMinus && std::abs(cascMC.rapidityMC(2)) < rapcut) { + registryMC.fill(HIST("h2dGenOmegaMinusVsMultMC_RecoedEvt"), mcCollision.multMCNParticlesEta05(), ptmc); + } + if (cascMC.pdgCode() == kOmegaPlusBar && std::abs(cascMC.rapidityMC(2)) < rapcut) { + registryMC.fill(HIST("h2dGenOmegaPlusVsMultMC_RecoedEvt"), mcCollision.multMCNParticlesEta05(), ptmc); + } + } + + if (cascMC.pdgCode() == kXiMinus && std::abs(cascMC.rapidityMC(0)) < rapcut) { + registryMC.fill(HIST("h2dGenXiMinusVsMultMC"), mcCollision.multMCNParticlesEta05(), ptmc); + } + if (cascMC.pdgCode() == kXiPlusBar && std::abs(cascMC.rapidityMC(0)) < rapcut) { + registryMC.fill(HIST("h2dGenXiPlusVsMultMC"), mcCollision.multMCNParticlesEta05(), ptmc); + } + if (cascMC.pdgCode() == kOmegaMinus && std::abs(cascMC.rapidityMC(2)) < rapcut) { + registryMC.fill(HIST("h2dGenOmegaMinusVsMultMC"), mcCollision.multMCNParticlesEta05(), ptmc); + } + if (cascMC.pdgCode() == kOmegaPlusBar && std::abs(cascMC.rapidityMC(2)) < rapcut) { + registryMC.fill(HIST("h2dGenOmegaPlusVsMultMC"), mcCollision.multMCNParticlesEta05(), ptmc); + } + } // cascMC loop + } + + PROCESS_SWITCH(CascadeAnalysisLightIonsDerivedData, processMonteCarloGen, "Process MC Gen", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/Tasks/Strangeness/cascadecorrelations.cxx b/PWGLF/Tasks/Strangeness/cascadecorrelations.cxx index d1382b57370..c062c2f1a0d 100644 --- a/PWGLF/Tasks/Strangeness/cascadecorrelations.cxx +++ b/PWGLF/Tasks/Strangeness/cascadecorrelations.cxx @@ -86,6 +86,7 @@ using LabeledCascades = soa::Join; struct CascadeSelector { Service ccdb; + Service pdgDB; Produces cascflags; @@ -99,6 +100,8 @@ struct CascadeSelector { Configurable INEL{"INEL", 0, "Number of charged tracks within |eta| < 1 has to be greater than value"}; Configurable maxVertexZ{"maxVertexZ", 10., "Maximum value of z coordinate of PV"}; Configurable etaCascades{"etaCascades", 0.8, "min/max of eta for cascades"}; + Configurable doCompetingMassCut{"doCompetingMassCut", true, "Switch to apply a competing mass cut for the Omega's"}; + Configurable competingMassWindow{"competingMassWindow", 0.01, "Mass window for the competing mass cut"}; // Tracklevel Configurable tpcNsigmaBachelor{"tpcNsigmaBachelor", 3, "TPC NSigma bachelor"}; @@ -302,7 +305,7 @@ struct CascadeSelector { if (!gen.isPhysicalPrimary()) return; int genpdg = gen.pdgCode(); - if ((flag < 3 && TMath::Abs(genpdg) == 3312) || (flag > 1 && TMath::Abs(genpdg) == 3334)) { + if ((flag < 3 && std::abs(genpdg) == 3312) || (flag > 1 && std::abs(genpdg) == 3334)) { // if casc is consistent with Xi and has matched gen Xi OR cand is consistent with Omega and has matched gen omega // have to do this in case we reco true Xi with only Omega hypothesis (or vice versa) (very unlikely) registry.fill(HIST("truerec/hV0Radius"), rec.v0radius()); @@ -413,18 +416,18 @@ struct CascadeSelector { casc.v0cosPA(pvx, pvy, pvz) < v0setting_cospa || casc.casccosPA(pvx, pvy, pvz) < cascadesetting_cospa || casc.dcav0topv(pvx, pvy, pvz) < cascadesetting_mindcav0topv || - TMath::Abs(casc.mLambda() - 1.115683) > cascadesetting_v0masswindow) + std::abs(casc.mLambda() - 1.115683) > cascadesetting_v0masswindow) return 0; // It failed at least one topo selection registry.fill(HIST("hSelectionStatus"), 4); // passes topo // registry.fill(HIST("hMassXi3"), casc.mXi(), casc.pt()); - if (TMath::Abs(posTrack.eta()) > etaTracks || TMath::Abs(negTrack.eta()) > etaTracks || TMath::Abs(bachTrack.eta()) > etaTracks) + if (std::abs(posTrack.eta()) > etaTracks || std::abs(negTrack.eta()) > etaTracks || std::abs(bachTrack.eta()) > etaTracks) return 0; registry.fill(HIST("hSelectionStatus"), 5); // passes track eta - if (TMath::Abs(casc.eta()) > etaCascades) + if (std::abs(casc.eta()) > etaCascades) return 0; registry.fill(HIST("hSelectionStatus"), 6); // passes candidate eta @@ -435,28 +438,40 @@ struct CascadeSelector { // Lambda check if (casc.sign() < 0) { // Proton check: - if (TMath::Abs(posTrack.tpcNSigmaPr()) > tpcNsigmaProton) + if (std::abs(posTrack.tpcNSigmaPr()) > tpcNsigmaProton) return 0; // Pion check: - if (TMath::Abs(negTrack.tpcNSigmaPi()) > tpcNsigmaPion) + if (std::abs(negTrack.tpcNSigmaPi()) > tpcNsigmaPion) return 0; } else { // Proton check: - if (TMath::Abs(negTrack.tpcNSigmaPr()) > tpcNsigmaProton) + if (std::abs(negTrack.tpcNSigmaPr()) > tpcNsigmaProton) return 0; // Pion check: - if (TMath::Abs(posTrack.tpcNSigmaPi()) > tpcNsigmaPion) + if (std::abs(posTrack.tpcNSigmaPi()) > tpcNsigmaPion) return 0; } registry.fill(HIST("hSelectionStatus"), 7); // passes V0 daughters PID // registry.fill(HIST("hMassXi4"), casc.mXi(), casc.pt()); - // Bachelor check - if (TMath::Abs(bachTrack.tpcNSigmaPi()) < tpcNsigmaBachelor) { - if (TMath::Abs(bachTrack.tpcNSigmaKa()) < tpcNsigmaBachelor) { - // consistent with both! + // setting selection flag based on bachelor PID (and competing mass cut for omega's) + int flag = 0; + if (std::abs(bachTrack.tpcNSigmaPi()) < tpcNsigmaBachelor) + flag = 1; + if (std::abs(bachTrack.tpcNSigmaKa()) < tpcNsigmaBachelor && (!doCompetingMassCut || std::abs(pdgDB->Mass(3312) - casc.mXi()) > competingMassWindow)) + flag = 3 - flag; // 3 if only consistent with omega, 2 if consistent with both + + switch (flag) { + case 1: // only Xi + registry.fill(HIST("hSelectionStatus"), 8); // passes bach PID + if (casc.sign() < 0) { + registry.fill(HIST("hMassXiMinus"), casc.mXi(), casc.pt(), casc.yXi()); + } else { + registry.fill(HIST("hMassXiPlus"), casc.mXi(), casc.pt(), casc.yXi()); + } + break; + case 2: // Xi or Omega registry.fill(HIST("hSelectionStatus"), 8); // passes bach PID - // registry.fill(HIST("hMassXi5"), casc.mXi(), casc.pt()); if (casc.sign() < 0) { registry.fill(HIST("hMassXiMinus"), casc.mXi(), casc.pt(), casc.yXi()); registry.fill(HIST("hMassOmegaMinus"), casc.mOmega(), casc.pt(), casc.yOmega()); @@ -464,27 +479,19 @@ struct CascadeSelector { registry.fill(HIST("hMassXiPlus"), casc.mXi(), casc.pt(), casc.yXi()); registry.fill(HIST("hMassOmegaPlus"), casc.mOmega(), casc.pt(), casc.yOmega()); } - return 2; - } - registry.fill(HIST("hSelectionStatus"), 8); // passes bach PID - // registry.fill(HIST("hMassXi5"), casc.mXi(), casc.pt()); - if (casc.sign() < 0) { - registry.fill(HIST("hMassXiMinus"), casc.mXi(), casc.pt(), casc.yXi()); - } else { - registry.fill(HIST("hMassXiPlus"), casc.mXi(), casc.pt(), casc.yXi()); - } - return 1; - } else if (TMath::Abs(bachTrack.tpcNSigmaKa()) < tpcNsigmaBachelor) { - registry.fill(HIST("hSelectionStatus"), 8); // passes bach PID - if (casc.sign() < 0) { - registry.fill(HIST("hMassOmegaMinus"), casc.mOmega(), casc.pt(), casc.yOmega()); - } else { - registry.fill(HIST("hMassOmegaPlus"), casc.mOmega(), casc.pt(), casc.yOmega()); - } - return 3; + break; + case 3: // only Omega + registry.fill(HIST("hSelectionStatus"), 8); // passes bach PID + if (casc.sign() < 0) { + registry.fill(HIST("hMassOmegaMinus"), casc.mOmega(), casc.pt(), casc.yOmega()); + } else { + registry.fill(HIST("hMassOmegaPlus"), casc.mOmega(), casc.pt(), casc.yOmega()); + } + break; } - // if we reach here, the bachelor was neither pion nor kaon - return 0; + + return flag; + } // processCandidate void processGenMC(aod::McCollision const&, soa::SmallGroups> const& collisions, aod::McParticles const& mcParticles) @@ -495,7 +502,7 @@ struct CascadeSelector { for (auto const& mcPart : mcParticles) { if (!mcPart.isPhysicalPrimary()) continue; - if (TMath::Abs(mcPart.eta()) > etaCascades) + if (std::abs(mcPart.eta()) > etaCascades) continue; switch (mcPart.pdgCode()) { @@ -532,7 +539,7 @@ struct CascadeSelector { for (auto const& mcPart : mcParticles) { if (!mcPart.isPhysicalPrimary()) continue; - if (TMath::Abs(mcPart.eta()) > etaCascades) + if (std::abs(mcPart.eta()) > etaCascades) continue; switch (mcPart.pdgCode()) { @@ -857,30 +864,30 @@ struct CascadeCorrelations { double weightTrigg = 1.; double weightAssoc = 1.; - if (trigger.isSelected() <= 2 && TMath::Abs(trigger.yXi()) < maxRapidity) { // trigger Xi + if (trigger.isSelected() <= 2 && std::abs(trigger.yXi()) < maxRapidity) { // trigger Xi if (doEfficiencyCorrection) weightTrigg = trigger.sign() < 0 ? getEfficiency(hEffXiMin, trigger.pt()) : getEfficiency(hEffXiPlus, trigger.pt()); - if (assoc.isSelected() <= 2 && TMath::Abs(assoc.yXi()) < maxRapidity) { // assoc Xi + if (assoc.isSelected() <= 2 && std::abs(assoc.yXi()) < maxRapidity) { // assoc Xi if (doEfficiencyCorrection) weightAssoc = assoc.sign() < 0 ? getEfficiency(hEffXiMin, assoc.pt()) : getEfficiency(hEffXiPlus, assoc.pt()); registry.fill(HIST("hXiXi"), dphi, trigger.yXi() - assoc.yXi(), trigger.sign(), assoc.sign(), trigger.pt(), assoc.pt(), invMassXiTrigg, invMassXiAssoc, collision.posZ(), collision.multFT0M(), weightTrigg * weightAssoc); } - if (assoc.isSelected() >= 2 && TMath::Abs(assoc.yOmega()) < maxRapidity) { // assoc Omega + if (assoc.isSelected() >= 2 && std::abs(assoc.yOmega()) < maxRapidity) { // assoc Omega if (doEfficiencyCorrection) weightAssoc = assoc.sign() < 0 ? getEfficiency(hEffOmegaMin, assoc.pt()) : getEfficiency(hEffOmegaPlus, assoc.pt()); registry.fill(HIST("hXiOm"), dphi, trigger.yXi() - assoc.yOmega(), trigger.sign(), assoc.sign(), trigger.pt(), assoc.pt(), invMassXiTrigg, invMassOmAssoc, collision.posZ(), collision.multFT0M(), weightTrigg * weightAssoc); } } - if (trigger.isSelected() >= 2 && TMath::Abs(trigger.yOmega()) < maxRapidity) { // trigger Omega + if (trigger.isSelected() >= 2 && std::abs(trigger.yOmega()) < maxRapidity) { // trigger Omega if (doEfficiencyCorrection) weightTrigg = trigger.sign() < 0 ? getEfficiency(hEffOmegaMin, trigger.pt()) : getEfficiency(hEffOmegaPlus, trigger.pt()); - if (assoc.isSelected() <= 2 && TMath::Abs(assoc.yXi()) < maxRapidity) { // assoc Xi + if (assoc.isSelected() <= 2 && std::abs(assoc.yXi()) < maxRapidity) { // assoc Xi if (doEfficiencyCorrection) weightAssoc = assoc.sign() < 0 ? getEfficiency(hEffXiMin, assoc.pt()) : getEfficiency(hEffXiPlus, assoc.pt()); // if Omega-Xi, fill the Xi-Omega histogram (flip the trigger/assoc and dphy,dy signs) registry.fill(HIST("hXiOm"), RecoDecay::constrainAngle(assoc.phi() - trigger.phi(), -PIHalf), -(trigger.yOmega() - assoc.yXi()), assoc.sign(), trigger.sign(), assoc.pt(), trigger.pt(), invMassXiAssoc, invMassOmTrigg, collision.posZ(), collision.multFT0M(), weightTrigg * weightAssoc); } - if (assoc.isSelected() >= 2 && TMath::Abs(assoc.yOmega()) < maxRapidity) { // assoc Omega + if (assoc.isSelected() >= 2 && std::abs(assoc.yOmega()) < maxRapidity) { // assoc Omega if (doEfficiencyCorrection) weightAssoc = assoc.sign() < 0 ? getEfficiency(hEffOmegaMin, assoc.pt()) : getEfficiency(hEffOmegaPlus, assoc.pt()); registry.fill(HIST("hOmOm"), dphi, trigger.yOmega() - assoc.yOmega(), trigger.sign(), assoc.sign(), trigger.pt(), assoc.pt(), invMassOmTrigg, invMassOmAssoc, collision.posZ(), collision.multFT0M(), weightTrigg * weightAssoc); @@ -904,7 +911,7 @@ struct CascadeCorrelations { for (auto const& [col1, cascades1, col2, cascades2] : pair) { if (!col1.sel8() || !col2.sel8()) continue; - if (TMath::Abs(col1.posZ()) > zVertexCut || TMath::Abs(col2.posZ()) > zVertexCut) + if (std::abs(col1.posZ()) > zVertexCut || std::abs(col2.posZ()) > zVertexCut) continue; if (col1.globalIndex() == col2.globalIndex()) { registry.fill(HIST("hMEQA"), 0.5); @@ -943,30 +950,30 @@ struct CascadeCorrelations { double weightTrigg = 1.; double weightAssoc = 1.; - if (trigger.isSelected() <= 2 && TMath::Abs(trigger.yXi()) < maxRapidity) { // trigger Xi + if (trigger.isSelected() <= 2 && std::abs(trigger.yXi()) < maxRapidity) { // trigger Xi if (doEfficiencyCorrection) weightTrigg = trigger.sign() < 0 ? getEfficiency(hEffXiMin, trigger.pt()) : getEfficiency(hEffXiPlus, trigger.pt()); - if (assoc.isSelected() <= 2 && TMath::Abs(assoc.yXi()) < maxRapidity) { // assoc Xi + if (assoc.isSelected() <= 2 && std::abs(assoc.yXi()) < maxRapidity) { // assoc Xi if (doEfficiencyCorrection) weightAssoc = assoc.sign() < 0 ? getEfficiency(hEffXiMin, assoc.pt()) : getEfficiency(hEffXiPlus, assoc.pt()); registry.fill(HIST("MixedEvents/hMEXiXi"), dphi, trigger.yXi() - assoc.yXi(), trigger.sign(), assoc.sign(), trigger.pt(), assoc.pt(), invMassXiTrigg, invMassXiAssoc, col1.posZ(), col1.multFT0M(), weightTrigg * weightAssoc); } - if (assoc.isSelected() >= 2 && TMath::Abs(assoc.yOmega()) < maxRapidity) { // assoc Omega + if (assoc.isSelected() >= 2 && std::abs(assoc.yOmega()) < maxRapidity) { // assoc Omega if (doEfficiencyCorrection) weightAssoc = assoc.sign() < 0 ? getEfficiency(hEffOmegaMin, assoc.pt()) : getEfficiency(hEffOmegaPlus, assoc.pt()); registry.fill(HIST("MixedEvents/hMEXiOm"), dphi, trigger.yXi() - assoc.yOmega(), trigger.sign(), assoc.sign(), trigger.pt(), assoc.pt(), invMassXiTrigg, invMassOmAssoc, col1.posZ(), col1.multFT0M(), weightTrigg * weightAssoc); } } - if (trigger.isSelected() >= 2 && TMath::Abs(trigger.yOmega()) < maxRapidity) { // trigger Omega + if (trigger.isSelected() >= 2 && std::abs(trigger.yOmega()) < maxRapidity) { // trigger Omega if (doEfficiencyCorrection) weightTrigg = trigger.sign() < 0 ? getEfficiency(hEffOmegaMin, trigger.pt()) : getEfficiency(hEffOmegaPlus, trigger.pt()); - if (assoc.isSelected() <= 2 && TMath::Abs(assoc.yXi()) < maxRapidity) { // assoc Xi + if (assoc.isSelected() <= 2 && std::abs(assoc.yXi()) < maxRapidity) { // assoc Xi if (doEfficiencyCorrection) weightAssoc = assoc.sign() < 0 ? getEfficiency(hEffXiMin, assoc.pt()) : getEfficiency(hEffXiPlus, assoc.pt()); // if Omega-Xi, fill the Xi-Omega histogram (flip the trigger/assoc and dphy,dy signs) registry.fill(HIST("MixedEvents/hMEXiOm"), RecoDecay::constrainAngle(assoc.phi() - trigger.phi(), -PIHalf), -(trigger.yOmega() - assoc.yXi()), assoc.sign(), trigger.sign(), assoc.pt(), trigger.pt(), invMassXiAssoc, invMassOmTrigg, col1.posZ(), col1.multFT0M(), weightTrigg * weightAssoc); } - if (assoc.isSelected() >= 2 && TMath::Abs(assoc.yOmega()) < maxRapidity) { // assoc Omega + if (assoc.isSelected() >= 2 && std::abs(assoc.yOmega()) < maxRapidity) { // assoc Omega if (doEfficiencyCorrection) weightAssoc = assoc.sign() < 0 ? getEfficiency(hEffOmegaMin, assoc.pt()) : getEfficiency(hEffOmegaPlus, assoc.pt()); registry.fill(HIST("MixedEvents/hMEOmOm"), dphi, trigger.yOmega() - assoc.yOmega(), trigger.sign(), assoc.sign(), trigger.pt(), assoc.pt(), invMassOmTrigg, invMassOmAssoc, col1.posZ(), col1.multFT0M(), weightTrigg * weightAssoc); @@ -1028,7 +1035,7 @@ struct CascadeCorrelations { if (!trigger.isPhysicalPrimary() || !assoc.isPhysicalPrimary()) continue; // require the cascades to be primaries - if (TMath::Abs(trigger.eta()) > etaGenCascades) + if (std::abs(trigger.eta()) > etaGenCascades) continue; // only apply eta cut to trigger - trigger normalization still valid without introducing 2-particle-acceptance effects double dphi = RecoDecay::constrainAngle(trigger.phi() - assoc.phi(), -PIHalf); diff --git a/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx b/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx index 95a25f589e3..5cab36540c3 100644 --- a/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx @@ -76,6 +76,7 @@ struct Derivedcascadeanalysis { ConfigurableAxis axisIR{"axisIR", {510, -1, 50}, "Binning for the interaction rate (kHz)"}; Configurable isXi{"isXi", 1, "Apply cuts for Xi identification"}; + Configurable ispO{"ispO", 0, "Analyse p--O collisions"}; Configurable useCentralityFT0M{"useCentralityFT0M", 0, "If true, use centFT0M"}; Configurable useCentralityFT0A{"useCentralityFT0A", 0, "If true, use centFT0A"}; Configurable useCentralityFT0Cvar1{"useCentralityFT0Cvar1", 0, "If true, use centFT0FT0Cvar1"}; @@ -119,6 +120,18 @@ struct Derivedcascadeanalysis { Configurable maxOccupancy{"maxOccupancy", -1, "Maximal occupancy"}; Configurable minOccupancyFT0{"minOccupancyFT0", -1, "Minimal occupancy"}; Configurable maxOccupancyFT0{"maxOccupancyFT0", -1, "Maximal occupancy"}; + Configurable globalTracksCorrelpar0Low{"globalTracksCorrelpar0Low", 81, "[0]*exp([1]*centrality)+[2], mean minus 3*sigma"}; + Configurable globalTracksCorrelpar1Low{"globalTracksCorrelpar1Low", -0.0431016, "[0]*exp([1]*centrality)+[2], mean minus 3*sigma"}; + Configurable globalTracksCorrelpar2Low{"globalTracksCorrelpar2Low", -6, "[0]*exp([1]*centrality)+[2], mean minus 3*sigma"}; + Configurable globalTracksCorrelpar0High{"globalTracksCorrelpar0High", 226, "[0]*exp([1]*centrality)+[2], mean minus 3*sigma"}; + Configurable globalTracksCorrelpar1High{"globalTracksCorrelpar1High", -0.0181686, "[0]*exp([1]*centrality)+[2], mean plus 3*sigma"}; + Configurable globalTracksCorrelpar2High{"globalTracksCorrelpar2High", -22, "[0]*exp([1]*centrality)+[2], mean plus 3*sigma"}; + Configurable pvContribCorrelpar0Low{"pvContribCorrelpar0Low", 152, "[0]*exp([1]*centrality)+[2], mean minus 3*sigma"}; + Configurable pvContribCorrelpar1Low{"pvContribCorrelpar1Low", -0.0431016, "[0]*exp([1]*centrality)+[2], mean minus 3*sigma"}; + Configurable pvContribCorrelpar2Low{"pvContribCorrelpar2Low", -15.3776, "[0]*exp([1]*centrality)+[2], mean minus 3*sigma"}; + Configurable pvContribCorrelpar0High{"pvContribCorrelpar0High", 384.861, "[0]*exp([1]*centrality)+[2], mean minus 3*sigma"}; + Configurable pvContribCorrelpar1High{"pvContribCorrelpar1High", -0.0181686, "[0]*exp([1]*centrality)+[2], mean plus 3*sigma"}; + Configurable pvContribCorrelpar2High{"pvContribCorrelpar2High", -39, "[0]*exp([1]*centrality)+[2], mean plus 3*sigma"}; } eventSelectionRun3Flags; struct : ConfigurableGroup { @@ -219,6 +232,8 @@ struct Derivedcascadeanalysis { Configurable rejcomp{"rejcomp", 0.008, "Competing Cascade rejection"}; Configurable masswin{"masswin", 0.05, "Mass window limit"}; Configurable rapCut{"rapCut", 0.5, "Rapidity acceptance"}; + Configurable minRapCut{"minRapCut", -0.845, "minimal rapidity acceptance in case of p--o"}; + Configurable maxRapCut{"maxRapCut", 0.155, "maximal rapidity acceptance in case of p--o"}; Configurable etaDauCut{"etaDauCut", 0.8, "Pseudorapidity acceptance of the cascade daughters"}; Configurable minITSclusters{"minITSclusters", 3, "minimal number of ITS hits for the daughter tracks"}; } candidateSelectionValues; @@ -302,6 +317,10 @@ struct Derivedcascadeanalysis { histos.add("hNCrossedRowsPositive", "", kTH1F, {{400, -200, 200}}); histos.add("hNCrossedRowsBachelor", "", kTH1F, {{400, -200, 200}}); + histos.add("hPseudorapPosDaughter", "", kTH1F, {{50, -1, 1}}); + histos.add("hPseudorapNegDaughter", "", kTH1F, {{50, -1, 1}}); + histos.add("hPseudorapBachelor", "", kTH1F, {{50, -1, 1}}); + histos.add("hEventNchCorrelationAfCuts", "hEventNchCorrelationAfCuts", kTH2F, {{5000, 0, 5000}, {5000, 0, 2500}}); histos.add("hEventPVcontributorsVsCentrality", "hEventPVcontributorsVsCentrality", kTH2F, {{100, 0, 100}, {5000, 0, 5000}}); histos.add("hEventGlobalTracksVsCentrality", "hEventGlobalTracksVsCentrality", kTH2F, {{100, 0, 100}, {2500, 0, 2500}}); @@ -660,9 +679,9 @@ struct Derivedcascadeanalysis { histos.fill(HIST("hEventSelection"), 11.5 /* Not at TF border */); if (eventSelectionRun3Flags.doMultiplicityCorrCut) { - if (coll.multNTracksGlobal() < (1343.3 * std::exp(-0.0443259 * centrality) - 50) || coll.multNTracksGlobal() > (2098.9 * std::exp(-0.0332444 * centrality))) + if (coll.multNTracksGlobal() < (eventSelectionRun3Flags.globalTracksCorrelpar0Low * std::exp(eventSelectionRun3Flags.globalTracksCorrelpar1Low * centrality) + eventSelectionRun3Flags.globalTracksCorrelpar2Low) || coll.multNTracksGlobal() > (eventSelectionRun3Flags.globalTracksCorrelpar0High * std::exp(eventSelectionRun3Flags.globalTracksCorrelpar1High * centrality) + eventSelectionRun3Flags.globalTracksCorrelpar2High)) return false; - if (coll.multNTracksPVeta1() < (3703 * std::exp(-0.0455483 * centrality) - 150) || coll.multNTracksPVeta1() > (4937.33 * std::exp(-0.0372668 * centrality) + 20)) + if (coll.multNTracksPVeta1() < (eventSelectionRun3Flags.pvContribCorrelpar0Low * std::exp(eventSelectionRun3Flags.pvContribCorrelpar1Low * centrality) + eventSelectionRun3Flags.pvContribCorrelpar2Low) || coll.multNTracksPVeta1() > (eventSelectionRun3Flags.pvContribCorrelpar0High * std::exp(eventSelectionRun3Flags.pvContribCorrelpar1High * centrality) + eventSelectionRun3Flags.pvContribCorrelpar2High)) return false; } if (fillHists) @@ -826,13 +845,17 @@ struct Derivedcascadeanalysis { float cut = candidateSelectionValues.masswin; histos.fill(HIST("hCutValue"), 1, cut); cut = candidateSelectionValues.rapCut; + if (ispO) + cut = candidateSelectionValues.maxRapCut; histos.fill(HIST("hCutValue"), 2, cut); if (isXi) { if (std::abs(casc.mXi() - o2::constants::physics::MassXiMinus) > candidateSelectionValues.masswin) { return false; } histos.fill(HIST("hCandidate"), ++counter); - if (std::abs(casc.yXi()) > candidateSelectionValues.rapCut) + if (ispO && (casc.yXi() < candidateSelectionValues.minRapCut || casc.yXi() > candidateSelectionValues.maxRapCut)) + return false; + else if (std::abs(casc.yXi()) > candidateSelectionValues.rapCut) return false; histos.fill(HIST("hCandidate"), ++counter); } else { @@ -840,7 +863,9 @@ struct Derivedcascadeanalysis { return false; } histos.fill(HIST("hCandidate"), ++counter); - if (std::abs(casc.yOmega()) > candidateSelectionValues.rapCut) + if (ispO && (casc.yOmega() < candidateSelectionValues.minRapCut || casc.yOmega() > candidateSelectionValues.maxRapCut)) + return false; + else if (std::abs(casc.yOmega()) > candidateSelectionValues.rapCut) return false; histos.fill(HIST("hCandidate"), ++counter); } @@ -1120,11 +1145,11 @@ struct Derivedcascadeanalysis { auto cascMC = casc.template cascMCCore_as>(); ptmc = RecoDecay::sqrtSumOfSquares(cascMC.pxMC(), cascMC.pyMC()); - if (cascMC.isPhysicalPrimary() && ((isXi && std::abs(cascMC.pdgCode()) == 3312) || (!isXi && std::abs(cascMC.pdgCode()) == 3334))) + if (cascMC.isPhysicalPrimary() && ((isXi && std::abs(cascMC.pdgCode()) == PDG_t::kXiMinus) || (!isXi && std::abs(cascMC.pdgCode()) == PDG_t::kOmegaMinus))) isTrueMCCascade = true; - if (isTrueMCCascade && ((isPositive && cascMC.pdgCodePositive() == 211 && cascMC.pdgCodeNegative() == -2212) || (isNegative && cascMC.pdgCodePositive() == 2212 && cascMC.pdgCodeNegative() == -211))) + if (isTrueMCCascade && ((isPositive && cascMC.pdgCodePositive() == PDG_t::kPiPlus && cascMC.pdgCodeNegative() == PDG_t::kProtonBar) || (isNegative && cascMC.pdgCodePositive() == PDG_t::kProton && cascMC.pdgCodeNegative() == PDG_t::kPiMinus))) isCorrectLambdaDecay = true; - if (isTrueMCCascade && isCorrectLambdaDecay && ((isXi && std::abs(cascMC.pdgCodeBachelor()) == 211) || (!isXi && std::abs(cascMC.pdgCodeBachelor()) == 321))) + if (isTrueMCCascade && isCorrectLambdaDecay && ((isXi && std::abs(cascMC.pdgCodeBachelor()) == PDG_t::kPiPlus) || (!isXi && std::abs(cascMC.pdgCodeBachelor()) == PDG_t::kKPlus))) isTrueMCCascadeDecay = true; if (qaFlags.doBefSelCheck && isTrueMCCascade) { @@ -1161,6 +1186,10 @@ struct Derivedcascadeanalysis { continue; histos.fill(HIST("hCandidate"), ++counter); + histos.fill(HIST("hPseudorapPosDaughter"), poseta); + histos.fill(HIST("hPseudorapNegDaughter"), negeta); + histos.fill(HIST("hPseudorapBachelor"), bacheta); + if (candidateSelectionFlags.doCascadeCosPaCut) { if (!isCosPAAccepted(casc, coll.posX(), coll.posY(), coll.posZ(), candidateSelectionFlags.doPtDepCosPaCut, true)) continue; @@ -1429,12 +1458,14 @@ struct Derivedcascadeanalysis { float ptmc = RecoDecay::sqrtSumOfSquares(cascMC.pxMC(), cascMC.pyMC()); float ymc = 1e3; - if (std::abs(cascMC.pdgCode()) == 3312) + if (std::abs(cascMC.pdgCode()) == PDG_t::kXiMinus) ymc = RecoDecay::y(std::array{cascMC.pxMC(), cascMC.pyMC(), cascMC.pzMC()}, o2::constants::physics::MassXiMinus); - else if (std::abs(cascMC.pdgCode()) == 3334) + else if (std::abs(cascMC.pdgCode()) == PDG_t::kOmegaMinus) ymc = RecoDecay::y(std::array{cascMC.pxMC(), cascMC.pyMC(), cascMC.pzMC()}, o2::constants::physics::MassOmegaMinus); - if (std::abs(ymc) > candidateSelectionValues.rapCut) + if (ispO && (ymc > candidateSelectionValues.maxRapCut || ymc < candidateSelectionValues.minRapCut)) + continue; + else if (std::abs(ymc) > candidateSelectionValues.rapCut) continue; auto mcCollision = cascMC.template straMCCollision_as>(); @@ -1471,7 +1502,7 @@ struct Derivedcascadeanalysis { nChEta1 = collision.multNTracksPVeta1(); } - if (cascMC.pdgCode() == 3312 && isXi) { + if (cascMC.pdgCode() == PDG_t::kXiMinus && isXi) { histos.fill(HIST("h2dGenXiMinus"), centrality, ptmc); histos.fill(HIST("h2dGenXiMinusVsNch"), nChEta1, ptmc); histos.fill(HIST("h2dGenXiMinusEta"), RecoDecay::eta(std::array{cascMC.pxMC(), cascMC.pyMC(), cascMC.pzMC()})); @@ -1484,7 +1515,7 @@ struct Derivedcascadeanalysis { histos.fill(HIST("h2dGenXiMinusVsCentIR"), ptmc, centrality, intRate); histos.fill(HIST("h2dGenXiMinusVsNchVsOccupancy"), ptmc, nChEta1, occupancy); } - if (cascMC.pdgCode() == -3312 && isXi) { + if (cascMC.pdgCode() == PDG_t::kXiPlusBar && isXi) { histos.fill(HIST("h2dGenXiPlus"), centrality, ptmc); histos.fill(HIST("h2dGenXiPlusVsNch"), nChEta1, ptmc); histos.fill(HIST("h2dGenXiPlusVsMultMCVsCentrality"), mcCollision.multMCNParticlesEta05(), centrality, ptmc); @@ -1493,7 +1524,7 @@ struct Derivedcascadeanalysis { histos.fill(HIST("h2dGenXiPlusVsNchVsOccupancy"), ptmc, nChEta1, occupancy); histos.fill(HIST("h2dGenXiPlusVsCentIR"), ptmc, centrality, intRate); } - if (cascMC.pdgCode() == 3334 && !isXi) { + if (cascMC.pdgCode() == PDG_t::kOmegaMinus && !isXi) { histos.fill(HIST("h2dGenOmegaMinus"), centrality, ptmc); histos.fill(HIST("h2dGenOmegaMinusVsNch"), nChEta1, ptmc); histos.fill(HIST("h2dGenOmegaMinusEta"), RecoDecay::eta(std::array{cascMC.pxMC(), cascMC.pyMC(), cascMC.pzMC()})); @@ -1506,7 +1537,7 @@ struct Derivedcascadeanalysis { histos.fill(HIST("h2dGenOmegaMinusVsNchVsOccupancy"), ptmc, nChEta1, occupancy); histos.fill(HIST("h2dGenOmegaMinusVsCentIR"), ptmc, centrality, intRate); } - if (cascMC.pdgCode() == -3334 && !isXi) { + if (cascMC.pdgCode() == PDG_t::kOmegaPlusBar && !isXi) { histos.fill(HIST("h2dGenOmegaPlus"), centrality, ptmc); histos.fill(HIST("h2dGenOmegaPlusVsNch"), nChEta1, ptmc); histos.fill(HIST("h2dGenOmegaPlusVsMultMCVsCentrality"), mcCollision.multMCNParticlesEta05(), centrality, ptmc); diff --git a/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx b/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx index 544ed23807a..fb3255fb412 100644 --- a/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx @@ -83,6 +83,14 @@ using V0McCandidates = soa::Join(1) << static_cast(nbit))) #define BITCHECK(var, nbit) ((var) & (static_cast(1) << static_cast(nbit))) +enum CentEstimator { + kCentFT0C = 0, + kCentFT0M, + kCentFT0CVariant1, + kCentMFT, + kCentNGlobal +}; + struct derivedlambdakzeroanalysis { HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -96,6 +104,7 @@ struct derivedlambdakzeroanalysis { Configurable doPPAnalysis{"doPPAnalysis", false, "if in pp, set to true"}; Configurable irSource{"irSource", "T0VTX", "Estimator of the interaction rate (Recommended: pp --> T0VTX, Pb-Pb --> ZNC hadronic)"}; + Configurable centralityEstimator{"centralityEstimator", kCentFT0C, "Run 3 centrality estimator (0:CentFT0C, 1:CentFT0M, 3:CentFT0CVariant1, 4:CentMFT, 5:CentNGlobal)"}; struct : ConfigurableGroup { Configurable requireSel8{"requireSel8", true, "require sel8 event selection"}; @@ -194,6 +203,7 @@ struct derivedlambdakzeroanalysis { Configurable doTPCQA{"doTPCQA", false, "do TPC QA histograms"}; Configurable doTOFQA{"doTOFQA", false, "do TOF QA histograms"}; Configurable doDetectPropQA{"doDetectPropQA", 0, "do Detector/ITS map QA: 0: no, 1: 4D, 2: 5D with mass; 3: plain in 3D"}; + Configurable doEtaPhiQA{"doEtaPhiQA", false, "do Eta/Phi QA histograms"}; Configurable doPlainTopoQA{"doPlainTopoQA", true, "do simple 1D QA of candidates"}; Configurable qaMinPt{"qaMinPt", 0.0f, "minimum pT for QA plots"}; @@ -273,7 +283,7 @@ struct derivedlambdakzeroanalysis { ConfigurableAxis axisPtCoarse{"axisPtCoarse", {VARIABLE_WIDTH, 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 7.0f, 10.0f, 15.0f}, "pt axis for QA"}; ConfigurableAxis axisK0Mass{"axisK0Mass", {200, 0.4f, 0.6f}, ""}; ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.101f, 1.131f}, ""}; - ConfigurableAxis axisCentrality{"axisCentrality", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f}, "Centrality"}; + ConfigurableAxis axisCentrality{"axisCentrality", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f}, "Centrality (%)"}; ConfigurableAxis axisNch{"axisNch", {500, 0.0f, +5000.0f}, "Number of charged particles"}; ConfigurableAxis axisIRBinning{"axisIRBinning", {500, 0, 50}, "Binning for the interaction rate (kHz)"}; @@ -706,6 +716,11 @@ struct derivedlambdakzeroanalysis { histos.add("K0Short/h3dPositiveTPCcrossedRows", "h3dPositiveTPCcrossedRows", kTH3D, {axisCentrality, axisPtCoarse, axisTPCrows}); histos.add("K0Short/h3dNegativeTPCcrossedRows", "h3dNegativeTPCcrossedRows", kTH3D, {axisCentrality, axisPtCoarse, axisTPCrows}); } + if (doEtaPhiQA) { + histos.add("K0Short/h5dV0PhiVsEta", "h5dV0PhiVsEta", kTHnD, {axisCentrality, axisPtCoarse, axisK0Mass, axisPhi, axisEta}); + histos.add("K0Short/h5dPosPhiVsNegPhi", "h5dPosPhiVsEta", kTHnD, {axisCentrality, axisPtCoarse, axisK0Mass, axisPhi, axisPhi}); + histos.add("K0Short/h5dPosEtaVsNegEta", "h5dNegPhiVsEta", kTHnD, {axisCentrality, axisPtCoarse, axisK0Mass, axisEta, axisEta}); + } } if (analyseLambda) { histos.add("h2dNbrOfLambdaVsCentrality", "h2dNbrOfLambdaVsCentrality", kTH2D, {axisCentrality, {10, -0.5f, 9.5f}}); @@ -773,6 +788,11 @@ struct derivedlambdakzeroanalysis { histos.add("Lambda/h3dPositiveTPCcrossedRows", "h3dPositiveTPCcrossedRows", kTH3D, {axisCentrality, axisPtCoarse, axisTPCrows}); histos.add("Lambda/h3dNegativeTPCcrossedRows", "h3dNegativeTPCcrossedRows", kTH3D, {axisCentrality, axisPtCoarse, axisTPCrows}); } + if (doEtaPhiQA) { + histos.add("Lambda/h5dV0PhiVsEta", "h5dV0PhiVsEta", kTHnD, {axisCentrality, axisPtCoarse, axisLambdaMass, axisPhi, axisEta}); + histos.add("Lambda/h5dPosPhiVsNegPhi", "h5dPosPhiVsEta", kTHnD, {axisCentrality, axisPtCoarse, axisLambdaMass, axisPhi, axisPhi}); + histos.add("Lambda/h5dPosEtaVsNegEta", "h5dNegPhiVsEta", kTHnD, {axisCentrality, axisPtCoarse, axisLambdaMass, axisEta, axisEta}); + } } if (analyseAntiLambda) { histos.add("h2dNbrOfAntiLambdaVsCentrality", "h2dNbrOfAntiLambdaVsCentrality", kTH2D, {axisCentrality, {10, -0.5f, 9.5f}}); @@ -840,6 +860,11 @@ struct derivedlambdakzeroanalysis { histos.add("AntiLambda/h3dPositiveTPCcrossedRows", "h3dPositiveTPCcrossedRows", kTH3D, {axisCentrality, axisPtCoarse, axisTPCrows}); histos.add("AntiLambda/h3dNegativeTPCcrossedRows", "h3dNegativeTPCcrossedRows", kTH3D, {axisCentrality, axisPtCoarse, axisTPCrows}); } + if (doEtaPhiQA) { + histos.add("AntiLambda/h5dV0PhiVsEta", "h5dV0PhiVsEta", kTHnD, {axisCentrality, axisPtCoarse, axisLambdaMass, axisPhi, axisEta}); + histos.add("AntiLambda/h5dPosPhiVsNegPhi", "h5dPosPhiVsEta", kTHnD, {axisCentrality, axisPtCoarse, axisLambdaMass, axisPhi, axisPhi}); + histos.add("AntiLambda/h5dPosEtaVsNegEta", "h5dNegPhiVsEta", kTHnD, {axisCentrality, axisPtCoarse, axisLambdaMass, axisEta, axisEta}); + } } if (analyseLambda && calculateFeeddownMatrix && (doprocessMonteCarloRun3 || doprocessMonteCarloRun2)) @@ -859,7 +884,6 @@ struct derivedlambdakzeroanalysis { histos.add("K0Short/h4dDCADaughters", "h4dDCADaughters", kTHnD, {axisCentrality, axisPtCoarse, axisK0Mass, axisDCAdau}); histos.add("K0Short/h4dPointingAngle", "h4dPointingAngle", kTHnD, {axisCentrality, axisPtCoarse, axisK0Mass, axisPointingAngle}); histos.add("K0Short/h4dV0Radius", "h4dV0Radius", kTHnD, {axisCentrality, axisPtCoarse, axisK0Mass, axisV0Radius}); - histos.add("K0Short/h4dV0PhiVsEta", "h4dV0PhiVsEta", kTHnD, {axisPtCoarse, axisK0Mass, axisPhi, axisEta}); } if (analyseLambda) { histos.add("Lambda/h4dPosDCAToPV", "h4dPosDCAToPV", kTHnD, {axisCentrality, axisPtCoarse, axisLambdaMass, axisDCAtoPV}); @@ -867,7 +891,6 @@ struct derivedlambdakzeroanalysis { histos.add("Lambda/h4dDCADaughters", "h4dDCADaughters", kTHnD, {axisCentrality, axisPtCoarse, axisLambdaMass, axisDCAdau}); histos.add("Lambda/h4dPointingAngle", "h4dPointingAngle", kTHnD, {axisCentrality, axisPtCoarse, axisLambdaMass, axisPointingAngle}); histos.add("Lambda/h4dV0Radius", "h4dV0Radius", kTHnD, {axisCentrality, axisPtCoarse, axisLambdaMass, axisV0Radius}); - histos.add("Lambda/h4dV0PhiVsEta", "h4dV0PhiVsEta", kTHnD, {axisPtCoarse, axisK0Mass, axisPhi, axisEta}); } if (analyseAntiLambda) { histos.add("AntiLambda/h4dPosDCAToPV", "h4dPosDCAToPV", kTHnD, {axisCentrality, axisPtCoarse, axisLambdaMass, axisDCAtoPV}); @@ -875,7 +898,6 @@ struct derivedlambdakzeroanalysis { histos.add("AntiLambda/h4dDCADaughters", "h4dDCADaughters", kTHnD, {axisCentrality, axisPtCoarse, axisLambdaMass, axisDCAdau}); histos.add("AntiLambda/h4dPointingAngle", "h4dPointingAngle", kTHnD, {axisCentrality, axisPtCoarse, axisLambdaMass, axisPointingAngle}); histos.add("AntiLambda/h4dV0Radius", "h4dV0Radius", kTHnD, {axisCentrality, axisPtCoarse, axisLambdaMass, axisV0Radius}); - histos.add("AntiLambda/h4dV0PhiVsEta", "h4dV0PhiVsEta", kTHnD, {axisPtCoarse, axisK0Mass, axisPhi, axisEta}); } } @@ -971,6 +993,25 @@ struct derivedlambdakzeroanalysis { histos.print(); } + // ______________________________________________________ + // Return slicing output + template + auto getCentralityRun3(TCollision const& collision) + { + if (centralityEstimator == kCentFT0C) + return collision.centFT0C(); + else if (centralityEstimator == kCentFT0M) + return collision.centFT0M(); + else if (centralityEstimator == kCentFT0CVariant1) + return collision.centFT0CVariant1(); + else if (centralityEstimator == kCentMFT) + return collision.centMFT(); + else if (centralityEstimator == kCentNGlobal) + return collision.centNGlobal(); + + return -1.f; + } + // ______________________________________________________ // Return slicing output template @@ -1073,34 +1114,34 @@ struct derivedlambdakzeroanalysis { // TOF PID in DeltaT // Positive track - if (std::fabs(v0.posTOFDeltaTLaPr()) < v0Selections.maxDeltaTimeProton) + if (!posTrackExtra.hasTOF() || std::fabs(v0.posTOFDeltaTLaPr()) < v0Selections.maxDeltaTimeProton) BITSET(bitMap, selTOFDeltaTPositiveProtonLambda); - if (std::fabs(v0.posTOFDeltaTLaPi()) < v0Selections.maxDeltaTimePion) + if (!posTrackExtra.hasTOF() || std::fabs(v0.posTOFDeltaTLaPi()) < v0Selections.maxDeltaTimePion) BITSET(bitMap, selTOFDeltaTPositivePionLambda); - if (std::fabs(v0.posTOFDeltaTK0Pi()) < v0Selections.maxDeltaTimePion) + if (!posTrackExtra.hasTOF() || std::fabs(v0.posTOFDeltaTK0Pi()) < v0Selections.maxDeltaTimePion) BITSET(bitMap, selTOFDeltaTPositivePionK0Short); // Negative track - if (std::fabs(v0.negTOFDeltaTLaPr()) < v0Selections.maxDeltaTimeProton) + if (!negTrackExtra.hasTOF() || std::fabs(v0.negTOFDeltaTLaPr()) < v0Selections.maxDeltaTimeProton) BITSET(bitMap, selTOFDeltaTNegativeProtonLambda); - if (std::fabs(v0.negTOFDeltaTLaPi()) < v0Selections.maxDeltaTimePion) + if (!negTrackExtra.hasTOF() || std::fabs(v0.negTOFDeltaTLaPi()) < v0Selections.maxDeltaTimePion) BITSET(bitMap, selTOFDeltaTNegativePionLambda); - if (std::fabs(v0.negTOFDeltaTK0Pi()) < v0Selections.maxDeltaTimePion) + if (!negTrackExtra.hasTOF() || std::fabs(v0.negTOFDeltaTK0Pi()) < v0Selections.maxDeltaTimePion) BITSET(bitMap, selTOFDeltaTNegativePionK0Short); // TOF PID in NSigma // Positive track - if (std::fabs(v0.tofNSigmaLaPr()) < v0Selections.tofPidNsigmaCutLaPr) + if (!posTrackExtra.hasTOF() || std::fabs(v0.tofNSigmaLaPr()) < v0Selections.tofPidNsigmaCutLaPr) BITSET(bitMap, selTOFNSigmaPositiveProtonLambda); - if (std::fabs(v0.tofNSigmaALaPi()) < v0Selections.tofPidNsigmaCutLaPi) + if (!posTrackExtra.hasTOF() || std::fabs(v0.tofNSigmaALaPi()) < v0Selections.tofPidNsigmaCutLaPi) BITSET(bitMap, selTOFNSigmaPositivePionLambda); - if (std::fabs(v0.tofNSigmaK0PiPlus()) < v0Selections.tofPidNsigmaCutK0Pi) + if (!posTrackExtra.hasTOF() || std::fabs(v0.tofNSigmaK0PiPlus()) < v0Selections.tofPidNsigmaCutK0Pi) BITSET(bitMap, selTOFNSigmaPositivePionK0Short); // Negative track - if (std::fabs(v0.tofNSigmaALaPr()) < v0Selections.tofPidNsigmaCutLaPr) + if (!negTrackExtra.hasTOF() || std::fabs(v0.tofNSigmaALaPr()) < v0Selections.tofPidNsigmaCutLaPr) BITSET(bitMap, selTOFNSigmaNegativeProtonLambda); - if (std::fabs(v0.tofNSigmaLaPi()) < v0Selections.tofPidNsigmaCutLaPi) + if (!negTrackExtra.hasTOF() || std::fabs(v0.tofNSigmaLaPi()) < v0Selections.tofPidNsigmaCutLaPi) BITSET(bitMap, selTOFNSigmaNegativePionLambda); - if (std::fabs(v0.tofNSigmaK0PiMinus()) < v0Selections.tofPidNsigmaCutK0Pi) + if (!negTrackExtra.hasTOF() || std::fabs(v0.tofNSigmaK0PiMinus()) < v0Selections.tofPidNsigmaCutK0Pi) BITSET(bitMap, selTOFNSigmaNegativePionK0Short); // ITS only tag @@ -1468,6 +1509,11 @@ struct derivedlambdakzeroanalysis { histos.fill(HIST("K0Short/h3dPosTOFdeltaTvsTrackPt"), centrality, v0.positivept(), v0.posTOFDeltaTK0Pi()); histos.fill(HIST("K0Short/h3dNegTOFdeltaTvsTrackPt"), centrality, v0.negativept(), v0.negTOFDeltaTK0Pi()); } + if (doEtaPhiQA) { + histos.fill(HIST("K0Short/h5dV0PhiVsEta"), centrality, pt, v0.mK0Short(), v0.phi(), v0.eta()); + histos.fill(HIST("K0Short/h5dPosPhiVsNegPhi"), centrality, pt, v0.mK0Short(), v0.positivephi(), v0.negativephi()); + histos.fill(HIST("K0Short/h5dPosEtaVsNegEta"), centrality, pt, v0.mK0Short(), v0.positiveeta(), v0.negativeeta()); + } nK0Shorts++; } if (passLambdaSelections && analyseLambda) { @@ -1542,6 +1588,11 @@ struct derivedlambdakzeroanalysis { histos.fill(HIST("Lambda/h3dPosTOFdeltaTvsTrackPt"), centrality, v0.positivept(), v0.posTOFDeltaTLaPr()); histos.fill(HIST("Lambda/h3dNegTOFdeltaTvsTrackPt"), centrality, v0.negativept(), v0.negTOFDeltaTLaPi()); } + if (doEtaPhiQA) { + histos.fill(HIST("Lambda/h5dV0PhiVsEta"), centrality, pt, v0.mLambda(), v0.phi(), v0.eta()); + histos.fill(HIST("Lambda/h5dPosPhiVsNegPhi"), centrality, pt, v0.mLambda(), v0.positivephi(), v0.negativephi()); + histos.fill(HIST("Lambda/h5dPosEtaVsNegEta"), centrality, pt, v0.mLambda(), v0.positiveeta(), v0.negativeeta()); + } nLambdas++; } if (passAntiLambdaSelections && analyseAntiLambda) { @@ -1616,6 +1667,11 @@ struct derivedlambdakzeroanalysis { histos.fill(HIST("AntiLambda/h3dPosTOFdeltaTvsTrackPt"), centrality, v0.positivept(), v0.posTOFDeltaTLaPi()); histos.fill(HIST("AntiLambda/h3dNegTOFdeltaTvsTrackPt"), centrality, v0.negativept(), v0.negTOFDeltaTLaPr()); } + if (doEtaPhiQA) { + histos.fill(HIST("AntiLambda/h5dV0PhiVsEta"), centrality, pt, v0.mAntiLambda(), v0.phi(), v0.eta()); + histos.fill(HIST("AntiLambda/h5dPosPhiVsNegPhi"), centrality, pt, v0.mAntiLambda(), v0.positivephi(), v0.negativephi()); + histos.fill(HIST("AntiLambda/h5dPosEtaVsNegEta"), centrality, pt, v0.mAntiLambda(), v0.positiveeta(), v0.negativeeta()); + } nAntiLambdas++; } @@ -1633,11 +1689,7 @@ struct derivedlambdakzeroanalysis { histos.fill(HIST("K0Short/h4dPointingAngle"), centrality, pt, v0.mK0Short(), std::acos(v0.v0cosPA())); if (verifyMask(selMap, maskTopoNoDCAV0Dau | maskK0ShortSpecific)) histos.fill(HIST("K0Short/h4dDCADaughters"), centrality, pt, v0.mK0Short(), v0.dcaV0daughters()); - - if (passK0ShortSelections) - histos.fill(HIST("K0Short/h4dV0PhiVsEta"), pt, v0.mK0Short(), v0.phi(), v0.eta()); } - if (analyseLambda) { if (verifyMask(selMap, maskTopoNoV0Radius | maskLambdaSpecific)) histos.fill(HIST("Lambda/h4dV0Radius"), centrality, pt, v0.mLambda(), v0.v0radius()); @@ -1649,9 +1701,6 @@ struct derivedlambdakzeroanalysis { histos.fill(HIST("Lambda/h4dPointingAngle"), centrality, pt, v0.mLambda(), std::acos(v0.v0cosPA())); if (verifyMask(selMap, maskTopoNoDCAV0Dau | maskLambdaSpecific)) histos.fill(HIST("Lambda/h4dDCADaughters"), centrality, pt, v0.mLambda(), v0.dcaV0daughters()); - - if (passLambdaSelections) - histos.fill(HIST("Lambda/h4dV0PhiVsEta"), pt, v0.mLambda(), v0.phi(), v0.eta()); } if (analyseAntiLambda) { if (verifyMask(selMap, maskTopoNoV0Radius | maskAntiLambdaSpecific)) @@ -1664,9 +1713,6 @@ struct derivedlambdakzeroanalysis { histos.fill(HIST("AntiLambda/h4dPointingAngle"), centrality, pt, v0.mAntiLambda(), std::acos(v0.v0cosPA())); if (verifyMask(selMap, maskTopoNoDCAV0Dau | maskAntiLambdaSpecific)) histos.fill(HIST("AntiLambda/h4dDCADaughters"), centrality, pt, v0.mAntiLambda(), v0.dcaV0daughters()); - - if (passAntiLambdaSelections) - histos.fill(HIST("AntiLambda/h4dV0PhiVsEta"), pt, v0.mAntiLambda(), v0.phi(), v0.eta()); } } // end systematics / qa } @@ -2016,7 +2062,7 @@ struct derivedlambdakzeroanalysis { void fillReconstructedEventProperties(TCollision const& collision, float& centrality, float& collisionOccupancy, double& interactionRate, int& gapSide, int& selGapSide) { if constexpr (requires { collision.centFT0C(); }) { // check if we are in Run 3 - centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + centrality = getCentralityRun3(collision); collisionOccupancy = eventSelections.useFT0CbasedOccupancy ? collision.ft0cOccupancyInTimeRange() : collision.trackOccupancyInTimeRange(); // Fetch interaction rate only if required (in order to limit ccdb calls) interactionRate = !irSource.value.empty() ? rateFetcher.fetch(ccdb.service, collision.timestamp(), collision.runNumber(), irSource) * 1.e-3 : -1; @@ -2098,7 +2144,7 @@ struct derivedlambdakzeroanalysis { if constexpr (run3) { // check if we are in Run 3 if (biggestNContribs < collision.multPVTotalContributors()) { biggestNContribs = collision.multPVTotalContributors(); - centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + centrality = getCentralityRun3(collision); } } else { // we are in Run 2: there should be only one collision in groupedCollisions centrality = eventSelections.useSPDTrackletsCent ? collision.centRun2SPDTracklets() : collision.centRun2V0M(); @@ -2337,7 +2383,7 @@ struct derivedlambdakzeroanalysis { if (listBestCollisionIdx[mcCollision.globalIndex()] > -1) { auto collision = collisions.iteratorAt(listBestCollisionIdx[mcCollision.globalIndex()]); if constexpr (requires { collision.centFT0C(); }) { // check if we are in Run 3 - centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + centrality = getCentralityRun3(collision); } else { // no, we are in Run 2 centrality = eventSelections.useSPDTrackletsCent ? collision.centRun2SPDTracklets() : collision.centRun2V0M(); } @@ -2402,7 +2448,7 @@ struct derivedlambdakzeroanalysis { if (listBestCollisionIdx[mcCollision.globalIndex()] > -1) { auto collision = collisions.iteratorAt(listBestCollisionIdx[mcCollision.globalIndex()]); if constexpr (requires { collision.centFT0C(); }) { // check if we are in Run 3 - centrality = doPPAnalysis ? collision.centFT0M() : collision.centFT0C(); + centrality = getCentralityRun3(collision); } else { // no, we are in Run 2 centrality = eventSelections.useSPDTrackletsCent ? collision.centRun2SPDTracklets() : collision.centRun2V0M(); } diff --git a/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx b/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx index 09dbb89bb22..95e0671ea26 100644 --- a/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx +++ b/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx @@ -62,7 +62,7 @@ struct HStrangeCorrelation { HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; // event filtering - Configurable zorroMask{"zorroMask", "", "zorro trigger class to select on (empty: none)"}; + Configurable zorroMask{"zorroMask", "", "zorro trigger class to select on (empty: none)"}; Zorro zorro; OutputObj zorroSummary{"zorroSummary"}; diff --git a/PWGLF/Tasks/Strangeness/lambdaTwoPartPolarization.cxx b/PWGLF/Tasks/Strangeness/lambdaTwoPartPolarization.cxx index 29635eb8b45..43e10b719b8 100644 --- a/PWGLF/Tasks/Strangeness/lambdaTwoPartPolarization.cxx +++ b/PWGLF/Tasks/Strangeness/lambdaTwoPartPolarization.cxx @@ -127,6 +127,9 @@ struct lambdaTwoPartPolarization { ConfigurableAxis detaAxis{"dyAxis", {20, -1, 1}, "relative rapidity axis"}; ConfigurableAxis dphiAxis{"dphiAxis", {20, -constants::math::PI * 0.5, constants::math::PI * 1.5}, "relative azimuth axis"}; + ConfigurableAxis cosSigAxis{"cosSigAxis", {110, -1.05, 1.05}, "Signal cosine axis"}; + ConfigurableAxis cosAccAxis{"cosAccAxis", {110, -7.05, 7.05}, "Accepatance cosine axis"}; + TF1* fMultPVCutLow = nullptr; TF1* fMultPVCutHigh = nullptr; @@ -158,8 +161,8 @@ struct lambdaTwoPartPolarization { histos.add("QA/nsigma_tpc_pt_mpi", "", {HistType::kTH2F, {ptAxis, pidAxis}}); } - histos.add("Ana/Signal", "", {HistType::kTHnSparseF, {ptAxis, ptAxis, detaAxis, dphiAxis, centAxis}}); - histos.add("Ana/Acceptance", "", {HistType::kTHnSparseF, {ptAxis, centAxis, RapAxis}}); + histos.add("Ana/Signal", "", {HistType::kTHnSparseF, {ptAxis, ptAxis, detaAxis, dphiAxis, centAxis, cosSigAxis}}); + histos.add("Ana/Acceptance", "", {HistType::kTHnSparseF, {ptAxis, centAxis, RapAxis, cosAccAxis}}); fMultPVCutLow = new TF1("fMultPVCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.5*([4]+[5]*x+[6]*x*x+[7]*x*x*x+[8]*x*x*x*x)", 0, 100); fMultPVCutLow->SetParameters(2834.66, -87.0127, 0.915126, -0.00330136, 332.513, -12.3476, 0.251663, -0.00272819, 1.12242e-05); @@ -179,6 +182,8 @@ struct lambdaTwoPartPolarization { ROOT::Math::PxPyPzMVector ProtonVec1, PionVec1, LambdaVec1, ProtonBoostedVec1, PionBoostedVec1; ROOT::Math::PxPyPzMVector ProtonVec2, PionVec2, LambdaVec2, ProtonBoostedVec2, PionBoostedVec2; + int V01Tag; + int V02Tag; double costhetastar1; double costhetastar2; @@ -289,10 +294,12 @@ struct lambdaTwoPartPolarization { if (LambdaTag) { ProtonVec1 = ROOT::Math::PxPyPzMVector(v01.pxpos(), v01.pypos(), v01.pzpos(), massPr); PionVec1 = ROOT::Math::PxPyPzMVector(v01.pxneg(), v01.pyneg(), v01.pzneg(), massPi); + V01Tag = 0; } if (aLambdaTag) { ProtonVec1 = ROOT::Math::PxPyPzMVector(v01.pxneg(), v01.pyneg(), v01.pzneg(), massPr); PionVec1 = ROOT::Math::PxPyPzMVector(v01.pxpos(), v01.pypos(), v01.pzpos(), massPi); + V01Tag = 1; } LambdaVec1 = ProtonVec1 + PionVec1; LambdaVec1.SetM(massLambda); @@ -334,10 +341,12 @@ struct lambdaTwoPartPolarization { if (LambdaTag) { ProtonVec2 = ROOT::Math::PxPyPzMVector(v02.pxpos(), v02.pypos(), v02.pzpos(), massPr); PionVec2 = ROOT::Math::PxPyPzMVector(v02.pxneg(), v02.pyneg(), v02.pzneg(), massPi); + V02Tag = 0; } if (aLambdaTag) { ProtonVec2 = ROOT::Math::PxPyPzMVector(v02.pxneg(), v02.pyneg(), v02.pzneg(), massPr); PionVec2 = ROOT::Math::PxPyPzMVector(v02.pxpos(), v02.pypos(), v02.pzpos(), massPi); + V02Tag = 1; } LambdaVec2 = ProtonVec2 + PionVec2; LambdaVec2.SetM(massLambda); @@ -353,6 +362,10 @@ struct lambdaTwoPartPolarization { weight *= cfgEffCor ? 1.0 / EffMap->GetBinContent(EffMap->GetXaxis()->FindBin(v02.pt()), EffMap->GetYaxis()->FindBin(centrality)) : 1.; weight *= cfgAccCor ? 1.0 / AccMap->GetBinContent(AccMap->GetXaxis()->FindBin(v02.pt()), AccMap->GetYaxis()->FindBin(v02.yLambda())) : 1.; + if (V01Tag != V02Tag) { + weight *= -1.0; + } + dphi = TVector2::Phi_0_2pi(v01.phi() - v02.phi()); if (dphi > constants::math::PI * 1.5) { dphi -= constants::math::PI * 2.0; diff --git a/PWGLF/Tasks/Strangeness/lambdapolsp.cxx b/PWGLF/Tasks/Strangeness/lambdapolsp.cxx index 7377271460e..1399d4d293c 100644 --- a/PWGLF/Tasks/Strangeness/lambdapolsp.cxx +++ b/PWGLF/Tasks/Strangeness/lambdapolsp.cxx @@ -78,10 +78,16 @@ using v0Candidates = soa::Join; struct lambdapolsp { + struct : ConfigurableGroup { + Configurable cfgURL{"cfgURL", "http://alice-ccdb.cern.ch", "Address of the CCDB to browse"}; + Configurable nolaterthan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "Latest acceptable timestamp of creation for the object"}; + } cfgCcdbParam; + int mRunNumber; Service ccdb; Service pdg; - + o2::ccdb::CcdbApi ccdbApi; + TH1D* hwgtAL; // fill output Configurable additionalEvSel{"additionalEvSel", false, "additionalEvSel"}; Configurable additionalEvSel2{"additionalEvSel2", false, "additionalEvSel2"}; @@ -93,6 +99,7 @@ struct lambdapolsp { Configurable cfgMaxOccupancy{"cfgMaxOccupancy", 1000, "maximum occupancy of tracks in neighbouring collisions in a given time range"}; Configurable cfgMinOccupancy{"cfgMinOccupancy", 0, "maximum occupancy of tracks in neighbouring collisions in a given time range"}; Configurable sys{"sys", 1, "flag to select systematic source"}; + Configurable centestim{"centestim", 0, "flag to select centrality estimator"}; Configurable dosystematic{"dosystematic", false, "flag to perform systematic study"}; Configurable needetaaxis{"needetaaxis", false, "flag to use last axis"}; struct : ConfigurableGroup { @@ -141,8 +148,10 @@ struct lambdapolsp { Configurable ConfDaughPIDCuts{"ConfDaughPIDCuts", 3, "PID selections for Lambda daughters"}; Configurable usesubdet{"usesubdet", false, "use subdet"}; Configurable useAccCorr{"useAccCorr", false, "use acceptance correction"}; + Configurable useyldwgt{"useyldwgt", false, "use yield weight"}; Configurable ConfAccPathL{"ConfAccPathL", "Users/p/prottay/My/Object/From379780/Fulldata/NewPbPbpass4_28032025/acccorrL", "Path to acceptance correction for Lambda"}; Configurable ConfAccPathAL{"ConfAccPathAL", "Users/p/prottay/My/Object/From379780/Fulldata/NewPbPbpass4_28032025/acccorrAL", "Path to acceptance correction for AntiLambda"}; + Configurable ConfWgtPathAL{"ConfWgtPathAL", "Users/p/prottay/My/Object/From379780/Fulldata/NewPbPbpass4_10082025/yieldweight2050", "Path to yield weight correction for AntiLambda"}; struct : ConfigurableGroup { Configurable QxyNbins{"QxyNbins", 100, "Number of bins in QxQy histograms"}; @@ -191,6 +200,19 @@ struct lambdapolsp { Configurable nMix{"nMix", 5, "number of event mixing"}; } meGrp; + struct : ConfigurableGroup { + ConfigurableAxis axisCosine{"axisCosine", {100, 0, 1}, "cosine axis"}; + ConfigurableAxis axisRadius{"axisRadius", {200, 0, 100}, "radius axis"}; + ConfigurableAxis axisDca{"axisDca", {100, -5, 5}, "dca axis"}; + ConfigurableAxis axisLT{"axisLT", {50, 0, 50}, "lifetime axis"}; + ConfigurableAxis axisCR{"axisCR", {40, 0, 200}, "CR axis"}; + ConfigurableAxis axisnsig{"axisnsig", {100, -10, 10}, "nsigma axis"}; + ConfigurableAxis axispt{"axispt", {100, 0, 10}, "pt axis"}; + Configurable filldist{"filldist", true, "fill topo distr"}; + Configurable lowmasscut{"lowmasscut", 1.11, "low mass cut"}; + Configurable highmasscut{"highmasscut", 1.12, "high mass cut"}; + } distGrp; + RCTFlagsChecker rctChecker; SliceCache cache; @@ -324,7 +346,7 @@ struct lambdapolsp { if (!checkwithpub) { // histos.add("hVtxZ", "Vertex distribution in Z;Z (cm)", kTH1F, {{20, -10.0, 10.0}}); histos.add("hpRes", "hpRes", HistType::kTHnSparseF, {axisGrp.configcentAxis, thnAxisres}); - histos.add("hpResSin", "hpResSin", HistType::kTHnSparseF, {axisGrp.configcentAxis, thnAxisres}); + // histos.add("hpResSin", "hpResSin", HistType::kTHnSparseF, {axisGrp.configcentAxis, thnAxisres}); /*histos.add("hpCosPsiA", "hpCosPsiA", HistType::kTHnSparseF, {axisGrp.configcentAxis, thnAxisres}); histos.add("hpCosPsiC", "hpCosPsiC", HistType::kTHnSparseF, {axisGrp.configcentAxis, thnAxisres}); histos.add("hpSinPsiA", "hpSinPsiA", HistType::kTHnSparseF, {axisGrp.configcentAxis, thnAxisres}); @@ -356,12 +378,16 @@ struct lambdapolsp { if (usesubdet) { histos.add("hSparseLambdaPolA", "hSparseLambdaPolA", HistType::kTHnSparseF, runaxes, true); histos.add("hSparseLambdaPolC", "hSparseLambdaPolC", HistType::kTHnSparseF, runaxes, true); + histos.add("hSparseLambdaPolAwgt", "hSparseLambdaPolAwgt", HistType::kTHnSparseF, runaxes, true); + histos.add("hSparseLambdaPolCwgt", "hSparseLambdaPolCwgt", HistType::kTHnSparseF, runaxes, true); } histos.add("hSparseAntiLambdaPol", "hSparseAntiLambdaPol", HistType::kTHnSparseF, runaxes, true); histos.add("hSparseAntiLambdaPolwgt", "hSparseAntiLambdaPolwgt", HistType::kTHnSparseF, runaxes, true); if (usesubdet) { histos.add("hSparseAntiLambdaPolA", "hSparseAntiLambdaPolA", HistType::kTHnSparseF, runaxes, true); histos.add("hSparseAntiLambdaPolC", "hSparseAntiLambdaPolC", HistType::kTHnSparseF, runaxes, true); + histos.add("hSparseAntiLambdaPolAwgt", "hSparseAntiLambdaPolAwgt", HistType::kTHnSparseF, runaxes, true); + histos.add("hSparseAntiLambdaPolCwgt", "hSparseAntiLambdaPolCwgt", HistType::kTHnSparseF, runaxes, true); } histos.add("hSparseLambda_corr1a", "hSparseLambda_corr1a", HistType::kTHnSparseF, runaxes, true); histos.add("hSparseLambda_corr1b", "hSparseLambda_corr1b", HistType::kTHnSparseF, runaxes, true); @@ -375,6 +401,40 @@ struct lambdapolsp { histos.add("hSparseAntiLambda_corr2a", "hSparseAntiLambda_corr2a", HistType::kTHnSparseF, runaxes, true); // histos.add("hSparseAntiLambda_corr2b", "hSparseAntiLambda_corr2b", HistType::kTHnSparseF, runaxes, true); } + + if (distGrp.filldist) { + histos.add("hcosinelambda", "hcosinelambda", HistType::kTH1D, {distGrp.axisCosine}, true); + histos.add("hdcabwv0daughlambda", "hdcabwv0daughlambda", HistType::kTH1D, {distGrp.axisDca}, true); + histos.add("hlifetimelambda", "hlifetimelambda", HistType::kTH1D, {distGrp.axisLT}, true); + histos.add("hradiuslambda", "hradiuslambda", HistType::kTH1D, {distGrp.axisRadius}, true); + histos.add("hdcaposlambda", "hdcaposlambda", HistType::kTH1D, {distGrp.axisDca}, true); + histos.add("hdcaneglambda", "hdcaneglambda", HistType::kTH1D, {distGrp.axisDca}, true); + histos.add("htpcCRlambda", "htpcCRlambda", HistType::kTH1D, {distGrp.axisCR}, true); + histos.add("htpcposlambda", "htpcposlambda", HistType::kTH1D, {distGrp.axisnsig}, true); + histos.add("htpcneglambda", "htpcneglambda", HistType::kTH1D, {distGrp.axisnsig}, true); + histos.add("hptposlambda", "hptposlambda", HistType::kTH1D, {distGrp.axispt}, true); + histos.add("hptneglambda", "hptneglambda", HistType::kTH1D, {distGrp.axispt}, true); + + histos.add("hcosineantilambda", "hcosineantilambda", HistType::kTH1D, {distGrp.axisCosine}, true); + histos.add("hdcabwv0daughantilambda", "hdcabwv0daughantilambda", HistType::kTH1D, {distGrp.axisDca}, true); + histos.add("hlifetimeantilambda", "hlifetimeantilambda", HistType::kTH1D, {distGrp.axisLT}, true); + histos.add("hradiusantilambda", "hradiusantilambda", HistType::kTH1D, {distGrp.axisRadius}, true); + histos.add("hdcaposantilambda", "hdcaposantilambda", HistType::kTH1D, {distGrp.axisDca}, true); + histos.add("hdcanegantilambda", "hdcanegantilambda", HistType::kTH1D, {distGrp.axisDca}, true); + histos.add("htpcCRantilambda", "htpcCRantilambda", HistType::kTH1D, {distGrp.axisCR}, true); + histos.add("htpcposantilambda", "htpcposantilambda", HistType::kTH1D, {distGrp.axisnsig}, true); + histos.add("htpcnegantilambda", "htpcnegantilambda", HistType::kTH1D, {distGrp.axisnsig}, true); + histos.add("hptposantilambda", "hptposantilambda", HistType::kTH1D, {distGrp.axispt}, true); + histos.add("hptnegantilambda", "hptnegantilambda", HistType::kTH1D, {distGrp.axispt}, true); + } + + ccdb->setURL(cfgCcdbParam.cfgURL); + ccdbApi.init("http://alice-ccdb.cern.ch"); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + LOGF(info, "Getting alignment offsets from the CCDB..."); + hwgtAL = ccdb->getForTimeStamp(ConfWgtPathAL.value, cfgCcdbParam.nolaterthan.value); } template @@ -433,7 +493,7 @@ struct lambdapolsp { } template - bool isSelectedV0Daughter(V0 const& candidate, T const& track, int pid) + bool isSelectedV0Daughter(V0 const& candidate, T const& track, int pid, int pid2) { // const auto eta = track.eta(); // const auto pt = track.pt(); @@ -444,6 +504,7 @@ struct lambdapolsp { /*if (TMath::Abs(eta) > ConfDaughEta) { return false; }*/ + if (tpcNClsF < ConfDaughTPCnclsMin) { return false; } @@ -467,10 +528,10 @@ struct lambdapolsp { return false; } - if (pid == 0 && (TMath::Abs(candidate.dcapostopv()) < cMinV0DCAPr || TMath::Abs(candidate.dcanegtopv()) < cMinV0DCAPi)) { + if (pid2 == 0 && (TMath::Abs(candidate.dcapostopv()) < cMinV0DCAPr || TMath::Abs(candidate.dcanegtopv()) < cMinV0DCAPi)) { return false; } - if (pid == 1 && (TMath::Abs(candidate.dcapostopv()) < cMinV0DCAPi || TMath::Abs(candidate.dcanegtopv()) < cMinV0DCAPr)) { + if (pid2 == 1 && (TMath::Abs(candidate.dcapostopv()) < cMinV0DCAPi || TMath::Abs(candidate.dcanegtopv()) < cMinV0DCAPr)) { return false; } @@ -502,6 +563,7 @@ struct lambdapolsp { if (posTrackExtra.tpcNClsCrossedRows() < cfgTPCcluster || negTrackExtra.tpcNClsCrossedRows() < cfgTPCcluster) { return false; } + if (posTrackExtra.tpcNClsFound() < ConfDaughTPCnclsMin || negTrackExtra.tpcNClsFound() < ConfDaughTPCnclsMin) { return false; } @@ -548,12 +610,14 @@ struct lambdapolsp { if (posTrackExtra.tpcNClsCrossedRows() < cfgTPCcluster || negTrackExtra.tpcNClsCrossedRows() < cfgTPCcluster) { return false; } + if (posTrackExtra.tpcNClsFound() < ConfDaughTPCnclsMin || negTrackExtra.tpcNClsFound() < ConfDaughTPCnclsMin) { return false; } if (posTrackExtra.tpcCrossedRowsOverFindableCls() < rcrfc || negTrackExtra.tpcCrossedRowsOverFindableCls() < rcrfc) { return false; } + // check TPC PID if (((std::abs(posTrackExtra.tpcNSigmaPi()) > ConfDaughPIDCuts) || (std::abs(negTrackExtra.tpcNSigmaPi()) > ConfDaughPIDCuts))) { return false; @@ -598,7 +662,7 @@ struct lambdapolsp { void fillHistograms(bool tag1, bool tag2, const ROOT::Math::PxPyPzMVector& particle, const ROOT::Math::PxPyPzMVector& daughter, double psiZDCC, double psiZDCA, double psiZDC, double centrality, - double candmass, double candpt, float desbinvalue, double acvalue) + double candmass, double candpt, float desbinvalue, double acvalue, double wgtfactor) { TRandom3 randPhi(0); @@ -627,92 +691,102 @@ struct lambdapolsp { // PolA = PolA / acvalue; // Pol = Pol / acvalue; auto Polwgt = Pol / acvalue; + auto PolAwgt = PolA / acvalue; + auto PolCwgt = PolC / acvalue; // Fill histograms using constructed names if (tag2) { if (needetaaxis) { if (usesubdet) { - histos.fill(HIST("hSparseAntiLambdaCosPsiA"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDCA))), centrality, desbinvalue); - histos.fill(HIST("hSparseAntiLambdaCosPsiC"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDCC))), centrality, desbinvalue); - histos.fill(HIST("hSparseAntiLambdaSinPsiA"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDCA))), centrality, desbinvalue); - histos.fill(HIST("hSparseAntiLambdaSinPsiC"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDCC))), centrality, desbinvalue); + histos.fill(HIST("hSparseAntiLambdaCosPsiA"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDCA))), centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseAntiLambdaCosPsiC"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDCC))), centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseAntiLambdaSinPsiA"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDCA))), centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseAntiLambdaSinPsiC"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDCC))), centrality, desbinvalue, wgtfactor); } - histos.fill(HIST("hSparseAntiLambdaCosPsi"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDC))), centrality, desbinvalue); - histos.fill(HIST("hSparseAntiLambdaSinPsi"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDC))), centrality, desbinvalue); + histos.fill(HIST("hSparseAntiLambdaCosPsi"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDC))), centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseAntiLambdaSinPsi"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDC))), centrality, desbinvalue, wgtfactor); if (usesubdet) { - histos.fill(HIST("hSparseAntiLambdaPolA"), candmass, candpt, PolA, centrality, desbinvalue); - histos.fill(HIST("hSparseAntiLambdaPolC"), candmass, candpt, PolC, centrality, desbinvalue); + histos.fill(HIST("hSparseAntiLambdaPolA"), candmass, candpt, PolA, centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseAntiLambdaPolC"), candmass, candpt, PolC, centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseAntiLambdaPolAwgt"), candmass, candpt, PolAwgt, centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseAntiLambdaPolCwgt"), candmass, candpt, PolCwgt, centrality, desbinvalue, wgtfactor); } - histos.fill(HIST("hSparseAntiLambdaPol"), candmass, candpt, Pol, centrality, desbinvalue); - histos.fill(HIST("hSparseAntiLambdaPolwgt"), candmass, candpt, Polwgt, centrality, desbinvalue); - histos.fill(HIST("hSparseAntiLambda_corr1a"), candmass, candpt, sinPhiStar, centrality, desbinvalue); - histos.fill(HIST("hSparseAntiLambda_corr1b"), candmass, candpt, cosPhiStar, centrality, desbinvalue); - // histos.fill(HIST("hSparseAntiLambda_corr1c"), candmass, candpt, phiphiStar, centrality, desbinvalue); - histos.fill(HIST("hSparseAntiLambda_corr2a"), candmass, candpt, sinThetaStar, centrality, desbinvalue); - // histos.fill(HIST("hSparseAntiLambda_corr2b"), candmass, candpt, sinThetaStarcosphiphiStar, centrality, desbinvalue); + histos.fill(HIST("hSparseAntiLambdaPol"), candmass, candpt, Pol, centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseAntiLambdaPolwgt"), candmass, candpt, Polwgt, centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseAntiLambda_corr1a"), candmass, candpt, sinPhiStar, centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseAntiLambda_corr1b"), candmass, candpt, cosPhiStar, centrality, desbinvalue, wgtfactor); + // histos.fill(HIST("hSparseAntiLambda_corr1c"), candmass, candpt, phiphiStar, centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseAntiLambda_corr2a"), candmass, candpt, sinThetaStar, centrality, desbinvalue, wgtfactor); + // histos.fill(HIST("hSparseAntiLambda_corr2b"), candmass, candpt, sinThetaStarcosphiphiStar, centrality, desbinvalue, wgtfactor); } else { if (usesubdet) { - histos.fill(HIST("hSparseAntiLambdaCosPsiA"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDCA))), centrality); - histos.fill(HIST("hSparseAntiLambdaCosPsiC"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDCC))), centrality); - histos.fill(HIST("hSparseAntiLambdaSinPsiA"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDCA))), centrality); - histos.fill(HIST("hSparseAntiLambdaSinPsiC"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDCC))), centrality); + histos.fill(HIST("hSparseAntiLambdaCosPsiA"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDCA))), centrality, wgtfactor); + histos.fill(HIST("hSparseAntiLambdaCosPsiC"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDCC))), centrality, wgtfactor); + histos.fill(HIST("hSparseAntiLambdaSinPsiA"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDCA))), centrality, wgtfactor); + histos.fill(HIST("hSparseAntiLambdaSinPsiC"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDCC))), centrality, wgtfactor); } - histos.fill(HIST("hSparseAntiLambdaCosPsi"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDC))), centrality); - histos.fill(HIST("hSparseAntiLambdaSinPsi"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDC))), centrality); + histos.fill(HIST("hSparseAntiLambdaCosPsi"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDC))), centrality, wgtfactor); + histos.fill(HIST("hSparseAntiLambdaSinPsi"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDC))), centrality, wgtfactor); if (usesubdet) { - histos.fill(HIST("hSparseAntiLambdaPolA"), candmass, candpt, PolA, centrality); - histos.fill(HIST("hSparseAntiLambdaPolC"), candmass, candpt, PolC, centrality); + histos.fill(HIST("hSparseAntiLambdaPolA"), candmass, candpt, PolA, centrality, wgtfactor); + histos.fill(HIST("hSparseAntiLambdaPolC"), candmass, candpt, PolC, centrality, wgtfactor); + histos.fill(HIST("hSparseAntiLambdaPolAwgt"), candmass, candpt, PolAwgt, centrality, wgtfactor); + histos.fill(HIST("hSparseAntiLambdaPolCwgt"), candmass, candpt, PolCwgt, centrality, wgtfactor); } - histos.fill(HIST("hSparseAntiLambdaPol"), candmass, candpt, Pol, centrality); - histos.fill(HIST("hSparseAntiLambdaPolwgt"), candmass, candpt, Polwgt, centrality); - histos.fill(HIST("hSparseAntiLambda_corr1a"), candmass, candpt, sinPhiStar, centrality); - histos.fill(HIST("hSparseAntiLambda_corr1b"), candmass, candpt, cosPhiStar, centrality); - // histos.fill(HIST("hSparseAntiLambda_corr1c"), candmass, candpt, phiphiStar, centrality); - histos.fill(HIST("hSparseAntiLambda_corr2a"), candmass, candpt, sinThetaStar, centrality); - // histos.fill(HIST("hSparseAntiLambda_corr2b"), candmass, candpt, sinThetaStarcosphiphiStar, centrality); + histos.fill(HIST("hSparseAntiLambdaPol"), candmass, candpt, Pol, centrality, wgtfactor); + histos.fill(HIST("hSparseAntiLambdaPolwgt"), candmass, candpt, Polwgt, centrality, wgtfactor); + histos.fill(HIST("hSparseAntiLambda_corr1a"), candmass, candpt, sinPhiStar, centrality, wgtfactor); + histos.fill(HIST("hSparseAntiLambda_corr1b"), candmass, candpt, cosPhiStar, centrality, wgtfactor); + // histos.fill(HIST("hSparseAntiLambda_corr1c"), candmass, candpt, phiphiStar, centrality, wgtfactor); + histos.fill(HIST("hSparseAntiLambda_corr2a"), candmass, candpt, sinThetaStar, centrality, wgtfactor); + // histos.fill(HIST("hSparseAntiLambda_corr2b"), candmass, candpt, sinThetaStarcosphiphiStar, centrality, wgtfactor); } } if (tag1) { if (needetaaxis) { if (usesubdet) { - histos.fill(HIST("hSparseLambdaCosPsiA"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDCA))), centrality, desbinvalue); - histos.fill(HIST("hSparseLambdaCosPsiC"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDCC))), centrality, desbinvalue); - histos.fill(HIST("hSparseLambdaSinPsiA"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDCA))), centrality, desbinvalue); - histos.fill(HIST("hSparseLambdaSinPsiC"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDCC))), centrality, desbinvalue); + histos.fill(HIST("hSparseLambdaCosPsiA"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDCA))), centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseLambdaCosPsiC"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDCC))), centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseLambdaSinPsiA"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDCA))), centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseLambdaSinPsiC"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDCC))), centrality, desbinvalue, wgtfactor); } - histos.fill(HIST("hSparseLambdaCosPsi"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDC))), centrality, desbinvalue); - histos.fill(HIST("hSparseLambdaSinPsi"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDC))), centrality, desbinvalue); + histos.fill(HIST("hSparseLambdaCosPsi"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDC))), centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseLambdaSinPsi"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDC))), centrality, desbinvalue, wgtfactor); if (usesubdet) { - histos.fill(HIST("hSparseLambdaPolA"), candmass, candpt, PolA, centrality, desbinvalue); - histos.fill(HIST("hSparseLambdaPolC"), candmass, candpt, PolC, centrality, desbinvalue); + histos.fill(HIST("hSparseLambdaPolA"), candmass, candpt, PolA, centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseLambdaPolC"), candmass, candpt, PolC, centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseLambdaPolAwgt"), candmass, candpt, PolAwgt, centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseLambdaPolCwgt"), candmass, candpt, PolCwgt, centrality, desbinvalue, wgtfactor); } - histos.fill(HIST("hSparseLambdaPol"), candmass, candpt, Pol, centrality, desbinvalue); - histos.fill(HIST("hSparseLambdaPolwgt"), candmass, candpt, Polwgt, centrality, desbinvalue); - histos.fill(HIST("hSparseLambda_corr1a"), candmass, candpt, sinPhiStar, centrality, desbinvalue); - histos.fill(HIST("hSparseLambda_corr1b"), candmass, candpt, cosPhiStar, centrality, desbinvalue); - // histos.fill(HIST("hSparseLambda_corr1c"), candmass, candpt, phiphiStar, centrality, desbinvalue); - histos.fill(HIST("hSparseLambda_corr2a"), candmass, candpt, sinThetaStar, centrality, desbinvalue); - // histos.fill(HIST("hSparseLambda_corr2b"), candmass, candpt, sinThetaStarcosphiphiStar, centrality, desbinvalue); + histos.fill(HIST("hSparseLambdaPol"), candmass, candpt, Pol, centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseLambdaPolwgt"), candmass, candpt, Polwgt, centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseLambda_corr1a"), candmass, candpt, sinPhiStar, centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseLambda_corr1b"), candmass, candpt, cosPhiStar, centrality, desbinvalue, wgtfactor); + // histos.fill(HIST("hSparseLambda_corr1c"), candmass, candpt, phiphiStar, centrality, desbinvalue, wgtfactor); + histos.fill(HIST("hSparseLambda_corr2a"), candmass, candpt, sinThetaStar, centrality, desbinvalue, wgtfactor); + // histos.fill(HIST("hSparseLambda_corr2b"), candmass, candpt, sinThetaStarcosphiphiStar, centrality, desbinvalue, wgtfactor); } else { if (usesubdet) { - histos.fill(HIST("hSparseLambdaCosPsiA"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDCA))), centrality); - histos.fill(HIST("hSparseLambdaCosPsiC"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDCC))), centrality); - histos.fill(HIST("hSparseLambdaSinPsiA"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDCA))), centrality); - histos.fill(HIST("hSparseLambdaSinPsiC"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDCC))), centrality); + histos.fill(HIST("hSparseLambdaCosPsiA"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDCA))), centrality, wgtfactor); + histos.fill(HIST("hSparseLambdaCosPsiC"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDCC))), centrality, wgtfactor); + histos.fill(HIST("hSparseLambdaSinPsiA"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDCA))), centrality, wgtfactor); + histos.fill(HIST("hSparseLambdaSinPsiC"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDCC))), centrality, wgtfactor); } - histos.fill(HIST("hSparseLambdaCosPsi"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDC))), centrality); - histos.fill(HIST("hSparseLambdaSinPsi"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDC))), centrality); + histos.fill(HIST("hSparseLambdaCosPsi"), candmass, candpt, (TMath::Cos(GetPhiInRange(psiZDC))), centrality, wgtfactor); + histos.fill(HIST("hSparseLambdaSinPsi"), candmass, candpt, (TMath::Sin(GetPhiInRange(psiZDC))), centrality, wgtfactor); if (usesubdet) { - histos.fill(HIST("hSparseLambdaPolA"), candmass, candpt, PolA, centrality); - histos.fill(HIST("hSparseLambdaPolC"), candmass, candpt, PolC, centrality); + histos.fill(HIST("hSparseLambdaPolA"), candmass, candpt, PolA, centrality, wgtfactor); + histos.fill(HIST("hSparseLambdaPolC"), candmass, candpt, PolC, centrality, wgtfactor); + histos.fill(HIST("hSparseLambdaPolAwgt"), candmass, candpt, PolAwgt, centrality, wgtfactor); + histos.fill(HIST("hSparseLambdaPolCwgt"), candmass, candpt, PolCwgt, centrality, wgtfactor); } - histos.fill(HIST("hSparseLambdaPol"), candmass, candpt, Pol, centrality); - histos.fill(HIST("hSparseLambdaPolwgt"), candmass, candpt, Polwgt, centrality); - histos.fill(HIST("hSparseLambda_corr1a"), candmass, candpt, sinPhiStar, centrality); - histos.fill(HIST("hSparseLambda_corr1b"), candmass, candpt, cosPhiStar, centrality); - // histos.fill(HIST("hSparseLambda_corr1c"), candmass, candpt, phiphiStar, centrality); - histos.fill(HIST("hSparseLambda_corr2a"), candmass, candpt, sinThetaStar, centrality); - // histos.fill(HIST("hSparseLambda_corr2b"), candmass, candpt, sinThetaStarcosphiphiStar, centrality); + histos.fill(HIST("hSparseLambdaPol"), candmass, candpt, Pol, centrality, wgtfactor); + histos.fill(HIST("hSparseLambdaPolwgt"), candmass, candpt, Polwgt, centrality, wgtfactor); + histos.fill(HIST("hSparseLambda_corr1a"), candmass, candpt, sinPhiStar, centrality, wgtfactor); + histos.fill(HIST("hSparseLambda_corr1b"), candmass, candpt, cosPhiStar, centrality, wgtfactor); + // histos.fill(HIST("hSparseLambda_corr1c"), candmass, candpt, phiphiStar, centrality, wgtfactor); + histos.fill(HIST("hSparseLambda_corr2a"), candmass, candpt, sinThetaStar, centrality, wgtfactor); + // histos.fill(HIST("hSparseLambda_corr2b"), candmass, candpt, sinThetaStarcosphiphiStar, centrality, wgtfactor); } } } @@ -749,7 +823,16 @@ struct lambdapolsp { if (!collision.sel8()) { return; } - auto centrality = collision.centFT0C(); + double centrality = -999.; + if (centestim == 0) + centrality = collision.centFT0C(); + else if (centestim == 1) + centrality = collision.centFT0M(); + else if (centestim == 2) + centrality = collision.centFT0A(); + else if (centestim == 3) + centrality = collision.centFV0A(); + // histos.fill(HIST("hCentrality0"), centrality); if (!collision.triggereventsp()) { return; @@ -812,7 +895,7 @@ struct lambdapolsp { if (!checkwithpub) { // histos.fill(HIST("hVtxZ"), collision.posZ()); histos.fill(HIST("hpRes"), centrality, (TMath::Cos(GetPhiInRange(psiZDCA - psiZDCC)))); - histos.fill(HIST("hpResSin"), centrality, (TMath::Sin(GetPhiInRange(psiZDCA - psiZDCC)))); + // histos.fill(HIST("hpResSin"), centrality, (TMath::Sin(GetPhiInRange(psiZDCA - psiZDCC)))); /*histos.fill(HIST("hpCosPsiA"), centrality, (TMath::Cos(GetPhiInRange(psiZDCA)))); histos.fill(HIST("hpCosPsiC"), centrality, (TMath::Cos(GetPhiInRange(psiZDCC)))); histos.fill(HIST("hpSinPsiA"), centrality, (TMath::Sin(GetPhiInRange(psiZDCA)))); @@ -980,10 +1063,10 @@ struct lambdapolsp { continue; } - if (isSelectedV0Daughter(v0, postrack, 0) && isSelectedV0Daughter(v0, negtrack, 1)) { + if (isSelectedV0Daughter(v0, postrack, 0, 0) && isSelectedV0Daughter(v0, negtrack, 1, 0)) { LambdaTag = 1; } - if (isSelectedV0Daughter(v0, negtrack, 0) && isSelectedV0Daughter(v0, postrack, 1)) { + if (isSelectedV0Daughter(v0, negtrack, 0, 1) && isSelectedV0Daughter(v0, postrack, 1, 1)) { aLambdaTag = 1; } @@ -1022,6 +1105,14 @@ struct lambdapolsp { accprofileL = ccdb->getForTimeStamp(ConfAccPathL.value, bc.timestamp()); accprofileAL = ccdb->getForTimeStamp(ConfAccPathAL.value, bc.timestamp()); } + int binxwgt; + double wgtvalue; + if (useyldwgt) { + binxwgt = hwgtAL->GetXaxis()->FindBin(v0.pt()); + wgtvalue = hwgtAL->GetBinContent(binxwgt); + } else { + wgtvalue = 1.0; + } float desbinvalue = 0.0; if (dosystematic) { @@ -1080,7 +1171,7 @@ struct lambdapolsp { int binx = accprofileL->GetXaxis()->FindBin(v0.eta()); int biny = accprofileL->GetYaxis()->FindBin(v0.pt()); double acvalue = accprofileL->GetBinContent(binx, biny); - fillHistograms(taga, tagb, Lambda, Proton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mLambda(), v0.pt(), desbinvalue, acvalue); + fillHistograms(taga, tagb, Lambda, Proton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mLambda(), v0.pt(), desbinvalue, acvalue, 1.0); } tagb = aLambdaTag; @@ -1090,17 +1181,31 @@ struct lambdapolsp { int binx = accprofileAL->GetXaxis()->FindBin(v0.eta()); int biny = accprofileAL->GetYaxis()->FindBin(v0.pt()); double acvalue = accprofileAL->GetBinContent(binx, biny); - fillHistograms(taga, tagb, AntiLambda, AntiProton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mAntiLambda(), v0.pt(), desbinvalue, acvalue); + fillHistograms(taga, tagb, AntiLambda, AntiProton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mAntiLambda(), v0.pt(), desbinvalue, acvalue, 1.0); } } } else { + if (LambdaTag) { Lambda = Proton + AntiPion; tagb = 0; int binx = accprofileL->GetXaxis()->FindBin(v0.eta()); int biny = accprofileL->GetYaxis()->FindBin(v0.pt()); double acvalue = accprofileL->GetBinContent(binx, biny); - fillHistograms(taga, tagb, Lambda, Proton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mLambda(), v0.pt(), v0.eta(), acvalue); + if (distGrp.filldist && aLambdaTag == 0 && Lambda.M() > distGrp.lowmasscut && Lambda.M() < distGrp.highmasscut) { + histos.fill(HIST("hcosinelambda"), v0.v0cosPA()); + histos.fill(HIST("hdcabwv0daughlambda"), v0.dcaV0daughters()); + histos.fill(HIST("hlifetimelambda"), TMath::Abs(v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * massLambda)); + histos.fill(HIST("hradiuslambda"), v0.v0radius()); + histos.fill(HIST("htpcCRlambda"), postrack.tpcNClsCrossedRows()); + histos.fill(HIST("hdcaposlambda"), v0.dcapostopv()); + histos.fill(HIST("hdcaneglambda"), v0.dcanegtopv()); + histos.fill(HIST("htpcposlambda"), postrack.tpcNSigmaPr()); + histos.fill(HIST("htpcneglambda"), negtrack.tpcNSigmaPi()); + histos.fill(HIST("hptposlambda"), Proton.Pt()); + histos.fill(HIST("hptneglambda"), AntiPion.Pt()); + } + fillHistograms(taga, tagb, Lambda, Proton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mLambda(), v0.pt(), v0.eta(), acvalue, 1.0); } tagb = aLambdaTag; @@ -1110,7 +1215,20 @@ struct lambdapolsp { int binx = accprofileAL->GetXaxis()->FindBin(v0.eta()); int biny = accprofileAL->GetYaxis()->FindBin(v0.pt()); double acvalue = accprofileAL->GetBinContent(binx, biny); - fillHistograms(taga, tagb, AntiLambda, AntiProton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mAntiLambda(), v0.pt(), v0.eta(), acvalue); + if (distGrp.filldist && LambdaTag == 0 && AntiLambda.M() > distGrp.lowmasscut && AntiLambda.M() < distGrp.highmasscut) { + histos.fill(HIST("hcosineantilambda"), v0.v0cosPA()); + histos.fill(HIST("hdcabwv0daughantilambda"), v0.dcaV0daughters()); + histos.fill(HIST("hlifetimeantilambda"), TMath::Abs(v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * massLambda)); + histos.fill(HIST("hradiusantilambda"), v0.v0radius()); + histos.fill(HIST("htpcCRantilambda"), postrack.tpcNClsCrossedRows()); + histos.fill(HIST("hdcaposantilambda"), v0.dcapostopv()); + histos.fill(HIST("hdcanegantilambda"), v0.dcanegtopv()); + histos.fill(HIST("htpcposantilambda"), postrack.tpcNSigmaPi()); + histos.fill(HIST("htpcnegantilambda"), negtrack.tpcNSigmaPr()); + histos.fill(HIST("hptposantilambda"), Pion.Pt()); + histos.fill(HIST("hptnegantilambda"), AntiProton.Pt()); + } + fillHistograms(taga, tagb, AntiLambda, AntiProton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mAntiLambda(), v0.pt(), v0.eta(), acvalue, wgtvalue); } } } @@ -1127,7 +1245,18 @@ struct lambdapolsp { if (!collision.sel8()) { return; } - auto centrality = collision.centFT0C(); + double centrality = -999.; + if (centestim == 0) + centrality = collision.centFT0C(); + else if (centestim == 1) + centrality = collision.centFT0M(); + else if (centestim == 2) + centrality = collision.centFT0A(); + else if (centestim == 3) + centrality = collision.centFV0A(); + + auto runnumber = collision.runNumber(); + // auto centrality = collision.centFT0C(); if (!collision.triggereventsp()) { // provided by StraZDCSP return; } @@ -1161,6 +1290,16 @@ struct lambdapolsp { accprofileAL = ccdb->getForTimeStamp(ConfAccPathAL.value, bc.timestamp()); } */ + auto timestamps = ccdb->getRunDuration(runnumber, true); /// fatalise if timestamps are not found + int64_t sorTimestamp = timestamps.first; // timestamp of the SOR/SOX/STF in ms + int64_t eorTimestamp = timestamps.second; // timestamp of the EOR/EOX/ETF in ms + int64_t ts = eorTimestamp / 2 + sorTimestamp / 2; // timestamp of the middle of the run + + if (useAccCorr) { + accprofileL = ccdb->getForTimeStamp(ConfAccPathL.value, ts); + accprofileAL = ccdb->getForTimeStamp(ConfAccPathAL.value, ts); + } + //___________________________________________________________________________________________________ // retrieve further info provided by StraZDCSP auto qxZDCA = collision.qxZDCA(); @@ -1193,7 +1332,7 @@ struct lambdapolsp { if (!checkwithpub) { // histos.fill(HIST("hVtxZ"), collision.posZ()); histos.fill(HIST("hpRes"), centrality, (TMath::Cos(GetPhiInRange(psiZDCA - psiZDCC)))); - histos.fill(HIST("hpResSin"), centrality, (TMath::Sin(GetPhiInRange(psiZDCA - psiZDCC)))); + // histos.fill(HIST("hpResSin"), centrality, (TMath::Sin(GetPhiInRange(psiZDCA - psiZDCC)))); /*histos.fill(HIST("hpCosPsiA"), centrality, (TMath::Cos(GetPhiInRange(psiZDCA)))); histos.fill(HIST("hpCosPsiC"), centrality, (TMath::Cos(GetPhiInRange(psiZDCC)))); histos.fill(HIST("hpSinPsiA"), centrality, (TMath::Sin(GetPhiInRange(psiZDCA)))); @@ -1262,7 +1401,7 @@ struct lambdapolsp { if (analyzeK0s && K0sTag) { K0s = Pion + AntiPion; double acvalue = 1.0; - fillHistograms(tagc, 0, K0s, Pion, psiZDCC, psiZDCA, psiZDC, centrality, v0.mK0Short(), v0.pt(), v0.eta(), acvalue); + fillHistograms(tagc, 0, K0s, Pion, psiZDCC, psiZDCA, psiZDC, centrality, v0.mK0Short(), v0.pt(), v0.eta(), acvalue, 1.0); } if (analyzeLambda && dosystematic) { @@ -1319,7 +1458,7 @@ struct lambdapolsp { Lambda = Proton + AntiPion; tagb = 0; double acvalue = 1.0; - fillHistograms(taga, tagb, Lambda, Proton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mLambda(), v0.pt(), desbinvalue, acvalue); + fillHistograms(taga, tagb, Lambda, Proton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mLambda(), v0.pt(), desbinvalue, acvalue, 1.0); } tagb = aLambdaTag; @@ -1327,23 +1466,29 @@ struct lambdapolsp { AntiLambda = AntiProton + Pion; taga = 0; double acvalue = 1.0; - fillHistograms(taga, tagb, AntiLambda, AntiProton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mAntiLambda(), v0.pt(), desbinvalue, acvalue); + fillHistograms(taga, tagb, AntiLambda, AntiProton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mAntiLambda(), v0.pt(), desbinvalue, acvalue, 1.0); } } } else { if (analyzeLambda && LambdaTag) { Lambda = Proton + AntiPion; tagb = 0; - double acvalue = 1.0; - fillHistograms(taga, tagb, Lambda, Proton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mLambda(), v0.pt(), v0.eta(), acvalue); + int binx = accprofileL->GetXaxis()->FindBin(v0.eta()); + int biny = accprofileL->GetYaxis()->FindBin(v0.pt()); + double acvalue = accprofileL->GetBinContent(binx, biny); + // double acvalue = 1.0; + fillHistograms(taga, tagb, Lambda, Proton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mLambda(), v0.pt(), v0.eta(), acvalue, 1.0); } tagb = aLambdaTag; if (analyzeLambda && aLambdaTag) { AntiLambda = AntiProton + Pion; taga = 0; - double acvalue = 1.0; - fillHistograms(taga, tagb, AntiLambda, AntiProton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mAntiLambda(), v0.pt(), v0.eta(), acvalue); + int binx = accprofileAL->GetXaxis()->FindBin(v0.eta()); + int biny = accprofileAL->GetYaxis()->FindBin(v0.pt()); + double acvalue = accprofileAL->GetBinContent(binx, biny); + // double acvalue = 1.0; + fillHistograms(taga, tagb, AntiLambda, AntiProton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mAntiLambda(), v0.pt(), v0.eta(), acvalue, 1.0); } } } @@ -1443,7 +1588,7 @@ struct lambdapolsp { } histos.fill(HIST("hpRes"), centrality, (TMath::Cos(GetPhiInRange(psiZDCA - psiZDCC)))); - histos.fill(HIST("hpResSin"), centrality, (TMath::Sin(GetPhiInRange(psiZDCA - psiZDCC)))); + // histos.fill(HIST("hpResSin"), centrality, (TMath::Sin(GetPhiInRange(psiZDCA - psiZDCC)))); for (const auto& v0 : groupV0) { @@ -1475,7 +1620,7 @@ struct lambdapolsp { Lambda = Proton + AntiPion; tagb = 0; double acvalue = 1.0; - fillHistograms(taga, tagb, Lambda, Proton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mLambda(), v0.pt(), v0.eta(), acvalue); + fillHistograms(taga, tagb, Lambda, Proton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mLambda(), v0.pt(), v0.eta(), acvalue, 1.0); } tagb = aLambdaTag; @@ -1483,7 +1628,7 @@ struct lambdapolsp { AntiLambda = AntiProton + Pion; taga = 0; double acvalue = 1.0; - fillHistograms(taga, tagb, AntiLambda, AntiProton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mAntiLambda(), v0.pt(), v0.eta(), acvalue); + fillHistograms(taga, tagb, AntiLambda, AntiProton, psiZDCC, psiZDCA, psiZDC, centrality, v0.mAntiLambda(), v0.pt(), v0.eta(), acvalue, 1.0); } } } @@ -1545,7 +1690,6 @@ struct lambdapolsp { if (additionalEvSel4 && !collision2.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) { continue; } - auto centrality = collision1.centFT0C(); auto qxZDCA = collision1.qxZDCA(); auto qxZDCC = collision1.qxZDCC(); @@ -1567,7 +1711,7 @@ struct lambdapolsp { histos.fill(HIST("hCentrality"), centrality); histos.fill(HIST("hpRes"), centrality, (TMath::Cos(GetPhiInRange(psiZDCA - psiZDCC)))); - histos.fill(HIST("hpResSin"), centrality, (TMath::Sin(GetPhiInRange(psiZDCA - psiZDCC)))); + // histos.fill(HIST("hpResSin"), centrality, (TMath::Sin(GetPhiInRange(psiZDCA - psiZDCC)))); // V0s from collision1 to match kinematics auto v0sCol1 = V0s.sliceBy(tracksPerCollisionV0Mixed, collision1.index()); @@ -1628,7 +1772,7 @@ struct lambdapolsp { Lambda = Proton + AntiPion; tagb = 0; double acvalue = 1.0; - fillHistograms(taga, tagb, Lambda, Proton, psiZDCC, psiZDCA, psiZDC, centrality, v0_2.mLambda(), v0_2.pt(), v0_2.eta(), acvalue); + fillHistograms(taga, tagb, Lambda, Proton, psiZDCC, psiZDCA, psiZDC, centrality, v0_2.mLambda(), v0_2.pt(), v0_2.eta(), acvalue, 1.0); } tagb = aLambdaTag; @@ -1636,7 +1780,7 @@ struct lambdapolsp { AntiLambda = AntiProton + Pion; taga = 0; double acvalue = 1.0; - fillHistograms(taga, tagb, AntiLambda, AntiProton, psiZDCC, psiZDCA, psiZDC, centrality, v0_2.mAntiLambda(), v0_2.pt(), v0_2.eta(), acvalue); + fillHistograms(taga, tagb, AntiLambda, AntiProton, psiZDCC, psiZDCA, psiZDC, centrality, v0_2.mAntiLambda(), v0_2.pt(), v0_2.eta(), acvalue, 1.0); } } } @@ -1767,11 +1911,11 @@ struct lambdapolsp { continue; if (LambdaTag1) { double acvalue = 1.0; - fillHistograms(1, 0, LambdaTag1dummy, proton_mix, psiZDCC, psiZDCA, psiZDC, centrality, v0_evt1.mLambda(), v0_evt1.pt(), v0_evt1.eta(), acvalue); + fillHistograms(1, 0, LambdaTag1dummy, proton_mix, psiZDCC, psiZDCA, psiZDC, centrality, v0_evt1.mLambda(), v0_evt1.pt(), v0_evt1.eta(), acvalue, 1.0); } if (aLambdaTag1) { double acvalue = 1.0; - fillHistograms(0, 1, AntiLambdaTag1dummy, antiproton_mix, psiZDCC, psiZDCA, psiZDC, centrality, v0_evt1.mAntiLambda(), v0_evt1.pt(), v0_evt1.eta(), acvalue); + fillHistograms(0, 1, AntiLambdaTag1dummy, antiproton_mix, psiZDCC, psiZDCA, psiZDC, centrality, v0_evt1.mAntiLambda(), v0_evt1.pt(), v0_evt1.eta(), acvalue, 1.0); } } } diff --git a/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx b/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx index 5db586eb880..3a350f5b6d0 100644 --- a/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx +++ b/PWGLF/Tasks/Strangeness/lambdaspincorrderived.cxx @@ -68,10 +68,12 @@ struct lambdaspincorrderived { TH3D* hweight1; TH3D* hweight2; TH3D* hweight3; + TH3D* hweight4; Configurable ConfWeightPathLL{"ConfWeightPathLL", "Users/s/skundu/My/Object/spincorr/cent010LL", "Weight path"}; Configurable ConfWeightPathALAL{"ConfWeightPathALAL", "Users/s/skundu/My/Object/spincorr/cent010LL", "Weight path"}; Configurable ConfWeightPathLAL{"ConfWeightPathLAL", "Users/s/skundu/My/Object/spincorr/cent010LL", "Weight path"}; + Configurable ConfWeightPathALL{"ConfWeightPathALL", "Users/s/skundu/My/Object/spincorr/cent010LL", "Weight path"}; // event sel///////// Configurable centMin{"centMin", 0, "Minimum Centrality"}; @@ -121,18 +123,22 @@ struct lambdaspincorrderived { histos.add("hLambdaSameForLL", "hLambdaSameForLL", HistType::kTH3D, {{50, 0.0, 5.0}, {32, -0.8, 0.8}, {72, 0.0, 2.0 * TMath::Pi()}}, true); histos.add("hLambdaSameForLAL", "hLambdaSameForLAL", HistType::kTH3D, {{50, 0.0, 5.0}, {32, -0.8, 0.8}, {72, 0.0, 2.0 * TMath::Pi()}}, true); + histos.add("hLambdaSameForALL", "hLambdaSameForALL", HistType::kTH3D, {{50, 0.0, 5.0}, {32, -0.8, 0.8}, {72, 0.0, 2.0 * TMath::Pi()}}, true); histos.add("hAntiLambdaSameForALAL", "hAntiLambdaSameForALAL", HistType::kTH3D, {{50, 0.0, 5.0}, {32, -0.8, 0.8}, {72, 0.0, 2.0 * TMath::Pi()}}, true); histos.add("hLambdaMixForLL", "hLambdaMixForLL", HistType::kTH3D, {{50, 0.0, 5.0}, {32, -0.8, 0.8}, {72, 0.0, 2.0 * TMath::Pi()}}, true); histos.add("hLambdaMixForLAL", "hLambdaMixForLAL", HistType::kTH3D, {{50, 0.0, 5.0}, {32, -0.8, 0.8}, {72, 0.0, 2.0 * TMath::Pi()}}, true); + histos.add("hLambdaMixForALL", "hLambdaMixForALL", HistType::kTH3D, {{50, 0.0, 5.0}, {32, -0.8, 0.8}, {72, 0.0, 2.0 * TMath::Pi()}}, true); histos.add("hAntiLambdaMixForALAL", "hAntiLambdaMixForALAL", HistType::kTH3D, {{50, 0.0, 5.0}, {32, -0.8, 0.8}, {72, 0.0, 2.0 * TMath::Pi()}}, true); histos.add("hSparseLambdaLambda", "hSparseLambdaLambda", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisCentrality, configThnAxisR}, true); histos.add("hSparseLambdaAntiLambda", "hSparseLambdaAntiLambda", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisCentrality, configThnAxisR}, true); + histos.add("hSparseAntiLambdaLambda", "hSparseAntiLambdLambda", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisCentrality, configThnAxisR}, true); histos.add("hSparseAntiLambdaAntiLambda", "hSparseAntiLambdaAntiLambda", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisCentrality, configThnAxisR}, true); histos.add("hSparseLambdaLambdaMixed", "hSparseLambdaLambdaMixed", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisCentrality, configThnAxisR}, true); histos.add("hSparseLambdaAntiLambdaMixed", "hSparseLambdaAntiLambdaMixed", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisCentrality, configThnAxisR}, true); + histos.add("hSparseAntiLambdaLambdaMixed", "hSparseAntiLambdaLambdaMixed", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisCentrality, configThnAxisR}, true); histos.add("hSparseAntiLambdaAntiLambdaMixed", "hSparseAntiLambdaAntiLambdaMixed", HistType::kTHnSparseF, {configThnAxisInvMass, configThnAxisInvMass, configThnAxisPol, configThnAxisCentrality, configThnAxisR}, true); ccdb->setURL(cfgCcdbParam.cfgURL); @@ -142,8 +148,9 @@ struct lambdaspincorrderived { ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); LOGF(info, "Getting alignment offsets from the CCDB..."); hweight1 = ccdb->getForTimeStamp(ConfWeightPathLL.value, cfgCcdbParam.nolaterthan.value); - hweight2 = ccdb->getForTimeStamp(ConfWeightPathALAL.value, cfgCcdbParam.nolaterthan.value); - hweight3 = ccdb->getForTimeStamp(ConfWeightPathLAL.value, cfgCcdbParam.nolaterthan.value); + hweight2 = ccdb->getForTimeStamp(ConfWeightPathLAL.value, cfgCcdbParam.nolaterthan.value); + hweight3 = ccdb->getForTimeStamp(ConfWeightPathALL.value, cfgCcdbParam.nolaterthan.value); + hweight4 = ccdb->getForTimeStamp(ConfWeightPathALAL.value, cfgCcdbParam.nolaterthan.value); } template @@ -252,9 +259,12 @@ struct lambdaspincorrderived { if (tag1 == 0 && tag2 == 0) { histos.fill(HIST("hSparseLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR, mixpairweight); histos.fill(HIST("hLambdaSameForLL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic), mixpairweight); - } else if ((tag1 == 0 && tag2 == 1) || (tag1 == 1 && tag2 == 0)) { + } else if (tag1 == 0 && tag2 == 1) { histos.fill(HIST("hSparseLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR, mixpairweight); histos.fill(HIST("hLambdaSameForLAL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic), mixpairweight); + } else if (tag1 == 1 && tag2 == 0) { + histos.fill(HIST("hSparseAntiLambdaLambda"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR, mixpairweight); + histos.fill(HIST("hLambdaSameForALL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic), mixpairweight); } else if (tag1 == 1 && tag2 == 1) { histos.fill(HIST("hSparseAntiLambdaAntiLambda"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR, mixpairweight); histos.fill(HIST("hAntiLambdaSameForALAL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic), mixpairweight); @@ -263,21 +273,26 @@ struct lambdaspincorrderived { double weight1 = mixpairweight; double weight2 = mixpairweight; double weight3 = mixpairweight; + double weight4 = mixpairweight; if (useweight) { weight1 = mixpairweight * hweight1->GetBinContent(hweight1->FindBin(particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic))); weight2 = mixpairweight * hweight2->GetBinContent(hweight2->FindBin(particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic))); weight3 = mixpairweight * hweight3->GetBinContent(hweight3->FindBin(particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic))); + weight4 = mixpairweight * hweight4->GetBinContent(hweight4->FindBin(particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic))); } histos.fill(HIST("hPtYMix"), particle1.Pt(), particle1.Rapidity()); if (tag1 == 0 && tag2 == 0) { histos.fill(HIST("hSparseLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR, weight1); histos.fill(HIST("hLambdaMixForLL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic), weight1); - } else if ((tag1 == 0 && tag2 == 1) || (tag1 == 1 && tag2 == 0)) { + } else if (tag1 == 0 && tag2 == 1) { histos.fill(HIST("hSparseLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR, weight2); histos.fill(HIST("hLambdaMixForLAL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic), weight2); + } else if (tag1 == 1 && tag2 == 0) { + histos.fill(HIST("hSparseAntiLambdaLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR, weight3); + histos.fill(HIST("hLambdaMixForALL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic), weight3); } else if (tag1 == 1 && tag2 == 1) { - histos.fill(HIST("hSparseAntiLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR, weight3); - histos.fill(HIST("hAntiLambdaMixForALAL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic), weight3); + histos.fill(HIST("hSparseAntiLambdaAntiLambdaMixed"), particle1.M(), particle2.M(), cosThetaDiff, centrality, deltaR, weight4); + histos.fill(HIST("hAntiLambdaMixForALAL"), particle1.Pt(), particle1.Eta(), RecoDecay::constrainAngle(particle1.Phi(), 0.0F, harmonic), weight4); } } } @@ -325,7 +340,7 @@ struct lambdaspincorrderived { fillHistograms(0, 1, lambda, lambda2, proton, proton2, centrality, 0, 1.0); } if (v0.v0Status() == 1 && v02.v0Status() == 0) { - fillHistograms(1, 0, lambda2, lambda, proton2, proton, centrality, 0, 1.0); + fillHistograms(1, 0, lambda, lambda2, proton, proton2, centrality, 0, 1.0); } if (v0.v0Status() == 1 && v02.v0Status() == 1) { fillHistograms(1, 1, lambda, lambda2, proton, proton2, centrality, 0, 1.0); @@ -397,7 +412,7 @@ struct lambdaspincorrderived { fillHistograms(0, 1, lambda, lambda2, proton, proton2, centrality, 1, 1.0); } if (t3.v0Status() == 1 && t2.v0Status() == 0) { - fillHistograms(1, 0, lambda2, lambda, proton2, proton, centrality, 1, 1.0); + fillHistograms(1, 0, lambda, lambda2, proton, proton2, centrality, 1, 1.0); } if (t3.v0Status() == 1 && t2.v0Status() == 1) { fillHistograms(1, 1, lambda, lambda2, proton, proton2, centrality, 1, 1.0); @@ -477,7 +492,7 @@ struct lambdaspincorrderived { fillHistograms(0, 1, lambda, lambda2, proton, proton2, centrality, 1, invN); } if (t3.v0Status() == 1 && t2.v0Status() == 0) { - fillHistograms(1, 0, lambda2, lambda, proton2, proton, centrality, 1, invN); + fillHistograms(1, 0, lambda, lambda2, proton, proton2, centrality, 1, invN); } if (t3.v0Status() == 1 && t2.v0Status() == 1) { fillHistograms(1, 1, lambda, lambda2, proton, proton2, centrality, 1, invN); diff --git a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx index ca6ba09680d..a59ea761daf 100644 --- a/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx +++ b/PWGLF/Tasks/Strangeness/phik0shortanalysis.cxx @@ -78,6 +78,12 @@ enum { kSpNotPrimary }; +enum { + kNoGenpTVar = 0, + kGenpTup, + kGenpTdown +}; + struct Phik0shortanalysis { // Histograms are defined with HistogramRegistry HistogramRegistry dataEventHist{"dataEventHist", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; @@ -121,6 +127,7 @@ struct Phik0shortanalysis { Configurable cfgMinAbsCharge{"cfgMinAbsCharge", 3.0f, "Cut on absolute charge"}; Configurable cfgGlobalWoDCATrack{"cfgGlobalWoDCATrack", true, "Global track selection without DCA"}; Configurable cfgPVContributor{"cfgPVContributor", true, "PV contributor track selection"}; + Configurable cMinChargedParticlePtcut{"cMinChargedParticlePtcut", 0.1f, "Track minimum pt cut"}; Configurable cMinKaonPtcut{"cMinKaonPtcut", 0.15f, "Track minimum pt cut"}; Configurable etaMax{"etaMax", 0.8f, "eta max"}; Configurable pTToUseTOF{"pTToUseTOF", 0.5f, "pT above which use TOF"}; @@ -148,17 +155,23 @@ struct Phik0shortanalysis { Configurable maxChi2TPC{"maxChi2TPC", 4.0f, "max chi2 per cluster TPC"}; Configurable minITSnCls{"minITSnCls", 4, "min number of ITS clusters"}; Configurable maxChi2ITS{"maxChi2ITS", 36.0f, "max chi2 per cluster ITS"}; + + Configurable applyExtraPhiCuts{"applyExtraPhiCuts", false, "Enable extra phi cut"}; + Configurable> extraPhiCuts{"extraPhiCuts", {3.07666f, 3.12661f, 0.03f, 6.253f}, "Extra phi cuts"}; } trackConfigs; // Configurables on phi pT bins Configurable> binspTPhi{"binspTPhi", {0.4, 0.8, 1.4, 2.0, 2.8, 4.0, 6.0, 10.0}, "pT bin limits for Phi"}; - Configurable minPhiPt{"minPhiPt", 0.4f, "Minimum pT for Phi"}; - Configurable maxPhiPt{"maxPhiPt", 10.0f, "Maximum pT for Phi"}; - // Configurables on phi mass - Configurable nBinsMPhi{"nBinsMPhi", 13, "N bins in cfgmassPhiaxis"}; - Configurable lowMPhi{"lowMPhi", 1.0095f, "Upper limits on Phi mass for signal extraction"}; - Configurable upMPhi{"upMPhi", 1.029f, "Upper limits on Phi mass for signal extraction"}; + // Configurables on phi selection + struct : ConfigurableGroup { + Configurable nBinsMPhi{"nBinsMPhi", 13, "N bins in cfgmassPhiaxis"}; + Configurable lowMPhi{"lowMPhi", 1.0095f, "Upper limits on Phi mass for signal extraction"}; + Configurable upMPhi{"upMPhi", 1.029f, "Upper limits on Phi mass for signal extraction"}; + + Configurable minPhiPt{"minPhiPt", 0.4f, "Minimum pT for Phi"}; + Configurable maxPhiPt{"maxPhiPt", 10.0f, "Maximum pT for Phi"}; + } phiConfigs; // Configurables for V0 selection struct : ConfigurableGroup { @@ -175,11 +188,10 @@ struct Phik0shortanalysis { Configurable ctauK0s{"ctauK0s", 20.0f, "C tau K0s(cm)"}; Configurable paramArmenterosCut{"paramArmenterosCut", 0.2f, "parameter Armenteros Cut"}; Configurable v0rejK0s{"v0rejK0s", 0.005f, "V0 rej K0s"}; - } v0Configs; - // Configurables on K0S mass - Configurable lowMK0S{"lowMK0S", 0.48f, "Lower limit on K0Short mass"}; - Configurable upMK0S{"upMK0S", 0.52f, "Upper limit on K0Short mass"}; + Configurable lowMK0S{"lowMK0S", 0.48f, "Lower limit on K0Short mass"}; + Configurable upMK0S{"upMK0S", 0.52f, "Upper limit on K0Short mass"}; + } v0Configs; // Configurable on K0S pT bins Configurable> binspTK0S{"binspTK0S", {0.1, 0.5, 0.8, 1.2, 1.6, 2.0, 2.5, 3.0, 4.0, 6.0}, "pT bin limits for K0S"}; @@ -212,7 +224,8 @@ struct Phik0shortanalysis { // Configurables for dN/deta with phi computation Configurable furtherCheckonMcCollision{"furtherCheckonMcCollision", true, "Further check on MC collisions"}; - Configurable filterOnMcPhi{"filterOnMcPhi", true, "Filter on MC Phi"}; + Configurable filterOnGenPhi{"filterOnGenPhi", true, "Filter on MC Phi"}; + Configurable filterOnRecoPhiWPDG{"filterOnRecoPhiWPDG", true, "Filter on Reco Phi with WPDG"}; // Configurable for event mixing Configurable cfgNoMixedEvents{"cfgNoMixedEvents", 5, "Number of mixed events per event"}; @@ -312,13 +325,14 @@ struct Phik0shortanalysis { { // Axes AxisSpec massPhiAxis = {200, 0.9f, 1.2f, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; - AxisSpec sigmassPhiAxis = {nBinsMPhi, lowMPhi, upMPhi, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; + AxisSpec sigmassPhiAxis = {phiConfigs.nBinsMPhi, phiConfigs.lowMPhi, phiConfigs.upMPhi, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; AxisSpec massK0SAxis = {200, 0.45f, 0.55f, "#it{M}_{inv} [GeV/#it{c}^{2}]"}; AxisSpec nSigmaPiAxis = {100, -10.0f, 10.0f, "N#sigma #pi"}; - AxisSpec vertexZAxis = {100, -15.f, 15.f, "vrtx_{Z} [cm]"}; + AxisSpec vertexZAxis = {100, -cutZVertex, cutZVertex, "vrtx_{Z} [cm]"}; AxisSpec etaAxis = {16, -trackConfigs.etaMax, trackConfigs.etaMax, "#eta"}; AxisSpec yAxis = {deltaYConfigs.nBinsY, -deltaYConfigs.cfgYAcceptance, deltaYConfigs.cfgYAcceptance, "#it{y}"}; AxisSpec deltayAxis = {deltaYConfigs.nBinsDeltaY, -1.0f, 1.0f, "#Delta#it{y}"}; + AxisSpec phiAxis = {629, 0, o2::constants::math::TwoPI, "#phi"}; AxisSpec multAxis = {120, 0.0f, 120.0f, "centFT0M"}; AxisSpec binnedmultAxis{(std::vector)binsMult, "centFT0M"}; AxisSpec pTPhiAxis = {120, 0.0f, 12.0f, "#it{p}_{T} (GeV/#it{c})"}; @@ -345,7 +359,7 @@ struct Phik0shortanalysis { dataEventHist.add("h2VertexZvsMult", "Vertex Z vs Multiplicity Percentile", kTH2F, {vertexZAxis, binnedmultAxis}); // Eta distribution for dN/deta values estimation in Data - dataEventHist.add("h4EtaDistribution", "Eta vs multiplicity in Data", kTHnSparseF, {vertexZAxis, binnedmultAxis, etaAxis, {3, -0.5f, 2.5f}}); + dataEventHist.add("h5EtaDistribution", "Eta vs multiplicity in Data", kTHnSparseF, {vertexZAxis, binnedmultAxis, etaAxis, phiAxis, {3, -0.5f, 2.5f}}); // Number of MC events per selection for Rec and Gen mcEventHist.add("hRecMCEventSelection", "hRecMCEventSelection", kTH1F, {{9, -0.5f, 8.5f}}); @@ -372,21 +386,23 @@ struct Phik0shortanalysis { mcEventHist.add("hRecoMCMultiplicityPercent", "RecoMC Multiplicity Percentile", kTH1F, {binnedmultAxis}); mcEventHist.add("hRecoMCMultiplicityPercentWithPhi", "RecoMC Multiplicity Percentile in Events with a Phi Candidate", kTH1F, {binnedmultAxis}); mcEventHist.add("h2RecoMCVertexZvsMult", "RecoMC Vertex Z vs Multiplicity Percentile", kTH2F, {vertexZAxis, binnedmultAxis}); + mcEventHist.add("hSplitVertexZ", "Split in z-vtx", kTH1F, {{100, -5.0f, 5.0f}}); mcEventHist.add("hGenMCVertexZ", "hGenMCVertexZ", kTH1F, {vertexZAxis}); mcEventHist.add("hGenMCMultiplicityPercent", "GenMC Multiplicity Percentile", kTH1F, {binnedmultAxis}); mcEventHist.add("hGenMCAssocRecoMultiplicityPercent", "GenMC AssocReco Multiplicity Percentile", kTH1F, {binnedmultAxis}); + mcEventHist.add("h2GenMCAssocRecoVertexZvsMult", "GenMC AssocReco Vertex Z vs Multiplicity Percentile", kTH2F, {vertexZAxis, binnedmultAxis}); mcEventHist.add("hGenMCRecoMultiplicityPercent", "GenMCReco Multiplicity Percentile", kTH1F, {binnedmultAxis}); mcEventHist.add("h2GenMCRecoVertexZvsMult", "GenMCReco Vertex Z vs Multiplicity Percentile", kTH2F, {vertexZAxis, binnedmultAxis}); // Eta distribution for dN/deta values estimation in MC - mcEventHist.add("h5RecoMCEtaDistribution", "Eta vs multiplicity in MCReco", kTHnSparseF, {vertexZAxis, binnedmultAxis, etaAxis, {3, -0.5f, 2.5f}, {6, -0.5f, 5.5f}}); - mcEventHist.add("h5RecoCheckMCEtaDistribution", "Eta vs multiplicity in MCReco Check", kTHnSparseF, {vertexZAxis, binnedmultAxis, etaAxis, {3, -0.5f, 2.5f}, {6, -0.5f, 5.5f}}); + mcEventHist.add("h6RecoMCEtaDistribution", "Eta vs multiplicity in MCReco", kTHnSparseF, {vertexZAxis, binnedmultAxis, etaAxis, phiAxis, {6, -0.5f, 5.5f}, {3, -0.5f, 2.5f}}); + mcEventHist.add("h6RecoCheckMCEtaDistribution", "Eta vs multiplicity in MCReco Check", kTHnSparseF, {vertexZAxis, binnedmultAxis, etaAxis, phiAxis, {6, -0.5f, 5.5f}, {3, -0.5f, 2.5f}}); - mcEventHist.add("h2GenMCEtaDistribution", "Eta vs multiplicity in MCGen", kTH2F, {binnedmultAxis, etaAxis}); - mcEventHist.add("h2GenMCEtaDistributionAssocReco", "Eta vs multiplicity in MCGen Assoc Reco", kTH2F, {binnedmultAxis, etaAxis}); - mcEventHist.add("h4GenMCEtaDistributionReco", "Eta vs multiplicity in MCGen Reco", kTHnSparseF, {vertexZAxis, binnedmultAxis, etaAxis, {6, -0.5f, 5.5f}}); - mcEventHist.add("h4GenMCEtaDistributionRecoCheck", "Eta vs multiplicity in MCGen Reco Check", kTHnSparseF, {vertexZAxis, binnedmultAxis, etaAxis, {6, -0.5f, 5.5f}}); + mcEventHist.add("h5GenMCEtaDistribution", "Eta vs multiplicity in MCGen", kTHnSparseF, {binnedmultAxis, etaAxis, phiAxis, {6, -0.5f, 5.5f}, {3, -0.5f, 2.5f}}); + mcEventHist.add("h6GenMCEtaDistributionAssocReco", "Eta vs multiplicity in MCGen Assoc Reco", kTHnSparseF, {vertexZAxis, binnedmultAxis, etaAxis, phiAxis, {6, -0.5f, 5.5f}, {3, -0.5f, 2.5f}}); + mcEventHist.add("h6GenMCEtaDistributionReco", "Eta vs multiplicity in MCGen Reco", kTHnSparseF, {vertexZAxis, binnedmultAxis, etaAxis, phiAxis, {6, -0.5f, 5.5f}, {3, -0.5f, 2.5f}}); + mcEventHist.add("h6GenMCEtaDistributionRecoCheck", "Eta vs multiplicity in MCGen Reco Check", kTHnSparseF, {vertexZAxis, binnedmultAxis, etaAxis, phiAxis, {6, -0.5f, 5.5f}, {3, -0.5f, 2.5f}}); // Phi topological/PID cuts dataPhiHist.add("h2DauTracksPhiDCAxyPreCutData", "Dcaxy distribution vs pt before DCAxy cut", kTH2F, {{100, 0.0, 5.0, "#it{p}_{T} (GeV/#it{c})"}, {2000, -0.05, 0.05, "DCA_{xy} (cm)"}}); @@ -927,7 +943,7 @@ struct Phik0shortanalysis { } template - bool eventHasPhi(const T1& posTracks, const T2& negTracks) + bool eventHasRecoPhi(const T1& posTracks, const T2& negTracks) { int nPhi = 0; @@ -946,9 +962,9 @@ struct Phik0shortanalysis { continue; // condition to avoid double counting of pair ROOT::Math::PxPyPzMVector recPhi = recMother(track1, track2, massKa, massKa); - if (recPhi.Pt() < minPhiPt || recPhi.Pt() > maxPhiPt) + if (recPhi.Pt() < phiConfigs.minPhiPt) continue; - if (recPhi.M() < lowMPhi || recPhi.M() > upMPhi) + if (recPhi.M() < phiConfigs.lowMPhi || recPhi.M() > phiConfigs.upMPhi) continue; if (std::abs(recPhi.Rapidity()) > deltaYConfigs.cfgYAcceptance) continue; @@ -962,19 +978,95 @@ struct Phik0shortanalysis { return false; } + template + bool eventHasRecoPhiWPDG(const T1& posTracks, const T2& negTracks) + { + int nPhi = 0; + + for (const auto& track1 : posTracks) { + if (!selectionTrackResonance(track1, false) || !selectionPIDKaonpTdependent(track1)) + continue; // topological and PID selection + + auto track1ID = track1.globalIndex(); + + if (!track1.has_mcParticle()) + continue; + auto mcTrack1 = track1.template mcParticle_as(); + if (mcTrack1.pdgCode() != PDG_t::kKPlus || !mcTrack1.isPhysicalPrimary()) + continue; + + for (const auto& track2 : negTracks) { + if (!selectionTrackResonance(track2, false) || !selectionPIDKaonpTdependent(track2)) + continue; // topological and PID selection + + auto track2ID = track2.globalIndex(); + if (track2ID == track1ID) + continue; // condition to avoid double counting of pair + + if (!track2.has_mcParticle()) + continue; + auto mcTrack2 = track2.template mcParticle_as(); + if (mcTrack2.pdgCode() != PDG_t::kKMinus || !mcTrack2.isPhysicalPrimary()) + continue; + + float pTMother = -1.0f; + float yMother = -1.0f; + bool isMCMotherPhi = false; + for (const auto& motherOfMcTrack1 : mcTrack1.template mothers_as()) { + for (const auto& motherOfMcTrack2 : mcTrack2.template mothers_as()) { + if (motherOfMcTrack1.pdgCode() != motherOfMcTrack2.pdgCode()) + continue; + if (motherOfMcTrack1.globalIndex() != motherOfMcTrack2.globalIndex()) + continue; + if (motherOfMcTrack1.pdgCode() != o2::constants::physics::Pdg::kPhi) + continue; + + pTMother = motherOfMcTrack1.pt(); + yMother = motherOfMcTrack1.y(); + isMCMotherPhi = true; + } + } + + if (!isMCMotherPhi) + continue; + if (pTMother < phiConfigs.minPhiPt || std::abs(yMother) > deltaYConfigs.cfgYAcceptance) + continue; + + nPhi++; + } + } + + if (nPhi > 0) + return true; + return false; + } + template - bool eventHasMCPhi(const T& mcParticles) + bool eventHasGenPhi(const T& mcParticles) { int nPhi = 0; for (const auto& mcParticle : mcParticles) { if (mcParticle.pdgCode() != o2::constants::physics::Pdg::kPhi) continue; - if (mcParticle.pt() < minPhiPt || mcParticle.pt() > maxPhiPt) + if (mcParticle.pt() < phiConfigs.minPhiPt) continue; if (std::abs(mcParticle.y()) > deltaYConfigs.cfgYAcceptance) continue; + auto kDaughters = mcParticle.template daughters_as(); + if (kDaughters.size() != 2) + continue; + bool isPosKaon = false, isNegKaon = false; + for (const auto& kDaughter : kDaughters) { + if (kDaughter.pdgCode() == PDG_t::kKPlus) + isPosKaon = true; + if (kDaughter.pdgCode() == PDG_t::kKMinus) + isNegKaon = true; + } + if (!isPosKaon || !isNegKaon) + continue; + nPhi++; } @@ -1208,7 +1300,7 @@ struct Phik0shortanalysis { continue; // condition to avoid double counting of pair ROOT::Math::PxPyPzMVector recPhi = recMother(track1, track2, massKa, massKa); - if (recPhi.Pt() < minPhiPt || recPhi.Pt() > maxPhiPt) + if (recPhi.Pt() < phiConfigs.minPhiPt || recPhi.Pt() > phiConfigs.maxPhiPt) continue; if (std::abs(recPhi.Rapidity()) > deltaYConfigs.cfgYAcceptance) continue; @@ -1242,7 +1334,7 @@ struct Phik0shortanalysis { dataK0SHist.fill(HIST("hV0CosPA"), v0.v0cosPA()); // Filling the PID of the V0 daughters in the region of the K0 peak - if (lowMK0S < v0.mK0Short() && v0.mK0Short() < upMK0S) { + if (v0Configs.lowMK0S < v0.mK0Short() && v0.mK0Short() < v0Configs.upMK0S) { dataK0SHist.fill(HIST("hNSigmaPosPionFromK0S"), posDaughterTrack.tpcInnerParam(), posDaughterTrack.tpcNSigmaPi()); dataK0SHist.fill(HIST("hNSigmaNegPionFromK0S"), negDaughterTrack.tpcInnerParam(), negDaughterTrack.tpcNSigmaPi()); } @@ -1347,9 +1439,9 @@ struct Phik0shortanalysis { continue; // condition to avoid double counting of pair ROOT::Math::PxPyPzMVector recPhi = recMother(track1, track2, massKa, massKa); - if (recPhi.Pt() < minPhiPt || recPhi.Pt() > maxPhiPt) + if (recPhi.Pt() < phiConfigs.minPhiPt || recPhi.Pt() > phiConfigs.maxPhiPt) continue; - if (recPhi.M() < lowMPhi || recPhi.M() > upMPhi) + if (recPhi.M() < phiConfigs.lowMPhi || recPhi.M() > phiConfigs.upMPhi) continue; if (std::abs(recPhi.Rapidity()) > deltaYConfigs.cfgYAcceptance) continue; @@ -1434,9 +1526,9 @@ struct Phik0shortanalysis { continue; // condition to avoid double counting of pair ROOT::Math::PxPyPzMVector recPhi = recMother(track1, track2, massKa, massKa); - if (recPhi.Pt() < minPhiPt || recPhi.Pt() > maxPhiPt) + if (recPhi.Pt() < phiConfigs.minPhiPt || recPhi.Pt() > phiConfigs.maxPhiPt) continue; - if (recPhi.M() < lowMPhi || recPhi.M() > upMPhi) + if (recPhi.M() < phiConfigs.lowMPhi || recPhi.M() > phiConfigs.upMPhi) continue; if (std::abs(recPhi.Rapidity()) > deltaYConfigs.cfgYAcceptance) continue; @@ -1540,7 +1632,7 @@ struct Phik0shortanalysis { continue; ROOT::Math::PxPyPzMVector recPhi = recMother(track1, track2, massKa, massKa); - if (recPhi.Pt() < minPhiPt || recPhi.Pt() > maxPhiPt) + if (recPhi.Pt() < phiConfigs.minPhiPt || recPhi.Pt() > phiConfigs.maxPhiPt) continue; mcPhiHist.fill(HIST("h3PhiRapiditySmearing"), genmultiplicity, recPhi.Rapidity(), mcMotherPhi.y()); @@ -1682,7 +1774,7 @@ struct Phik0shortanalysis { for (const auto& mcParticle : mcParticlesThisColl) { if (mcParticle.pdgCode() != o2::constants::physics::Pdg::kPhi) continue; - if (mcParticle.pt() < minPhiPt || mcParticle.pt() > maxPhiPt) + if (mcParticle.pt() < phiConfigs.minPhiPt || mcParticle.pt() > phiConfigs.maxPhiPt) continue; if (std::abs(mcParticle.y()) > deltaYConfigs.cfgYAcceptance) continue; @@ -1760,7 +1852,7 @@ struct Phik0shortanalysis { for (const auto& mcParticle : mcParticlesThisColl) { if (mcParticle.pdgCode() != o2::constants::physics::Pdg::kPhi) continue; - if (mcParticle.pt() < minPhiPt || mcParticle.pt() > maxPhiPt) + if (mcParticle.pt() < phiConfigs.minPhiPt || mcParticle.pt() > phiConfigs.maxPhiPt) continue; if (std::abs(mcParticle.y()) > deltaYConfigs.cfgYAcceptance) continue; @@ -1788,7 +1880,7 @@ struct Phik0shortanalysis { for (const auto& mcParticle : mcParticlesThisColl) { if (mcParticle.pdgCode() != o2::constants::physics::Pdg::kPhi) continue; - if (mcParticle.pt() < minPhiPt || mcParticle.pt() > maxPhiPt) + if (mcParticle.pt() < phiConfigs.minPhiPt || mcParticle.pt() > phiConfigs.maxPhiPt) continue; if (std::abs(mcParticle.y()) > deltaYConfigs.cfgYAcceptance) continue; @@ -1849,7 +1941,7 @@ struct Phik0shortanalysis { continue; // condition to avoid double counting of pair ROOT::Math::PxPyPzMVector recPhi = recMother(track1, track2, massKa, massKa); - if (recPhi.Pt() < minPhiPt || recPhi.Pt() > maxPhiPt) + if (recPhi.Pt() < phiConfigs.minPhiPt || recPhi.Pt() > phiConfigs.maxPhiPt) continue; if (std::abs(recPhi.Rapidity()) > deltaYConfigs.cfgYAcceptance) continue; @@ -2025,9 +2117,9 @@ struct Phik0shortanalysis { } ROOT::Math::PxPyPzMVector recPhi = recMother(track1, track2, massKa, massKa); - if (recPhi.Pt() < minPhiPt || recPhi.Pt() > maxPhiPt) + if (recPhi.Pt() < phiConfigs.minPhiPt || recPhi.Pt() > phiConfigs.maxPhiPt) continue; - if (recPhi.M() < lowMPhi || recPhi.M() > upMPhi) + if (recPhi.M() < phiConfigs.lowMPhi || recPhi.M() > phiConfigs.upMPhi) continue; if (std::abs(recPhi.Rapidity()) > deltaYConfigs.cfgYAcceptance) continue; @@ -2147,9 +2239,9 @@ struct Phik0shortanalysis { } ROOT::Math::PxPyPzMVector recPhi = recMother(track1, track2, massKa, massKa); - if (recPhi.Pt() < minPhiPt || recPhi.Pt() > maxPhiPt) + if (recPhi.Pt() < phiConfigs.minPhiPt || recPhi.Pt() > phiConfigs.maxPhiPt) continue; - if (recPhi.M() < lowMPhi || recPhi.M() > upMPhi) + if (recPhi.M() < phiConfigs.lowMPhi || recPhi.M() > phiConfigs.upMPhi) continue; if (std::abs(recPhi.Rapidity()) > deltaYConfigs.cfgYAcceptance) continue; @@ -2365,7 +2457,7 @@ struct Phik0shortanalysis { if (!isPosKaon || !isNegKaon) continue; } - if (mcParticle2.pt() < minPhiPt || mcParticle2.pt() > maxPhiPt) + if (mcParticle2.pt() < phiConfigs.minPhiPt || mcParticle2.pt() > phiConfigs.maxPhiPt) continue; if (std::abs(mcParticle2.y()) > deltaYConfigs.cfgYAcceptance) continue; @@ -2442,7 +2534,7 @@ struct Phik0shortanalysis { if (!isPosKaon || !isNegKaon) continue; } - if (mcParticle2.pt() < minPhiPt || mcParticle2.pt() > maxPhiPt) + if (mcParticle2.pt() < phiConfigs.minPhiPt || mcParticle2.pt() > phiConfigs.maxPhiPt) continue; if (std::abs(mcParticle2.y()) > deltaYConfigs.cfgYAcceptance) continue; @@ -2478,18 +2570,22 @@ struct Phik0shortanalysis { auto negThisColl = negFiltTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); // Check if the event contains a phi candidate - if (!eventHasPhi(posThisColl, negThisColl)) + if (!eventHasRecoPhi(posThisColl, negThisColl)) return; dataEventHist.fill(HIST("hMultiplicityPercent"), collision.centFT0M()); dataEventHist.fill(HIST("h2VertexZvsMult"), collision.posZ(), collision.centFT0M()); for (const auto& track : filteredTracks) { - dataEventHist.fill(HIST("h4EtaDistribution"), collision.posZ(), collision.centFT0M(), track.eta(), kGlobalplusITSonly); + if (trackConfigs.applyExtraPhiCuts && ((track.phi() > trackConfigs.extraPhiCuts->at(0) && track.phi() < trackConfigs.extraPhiCuts->at(1)) || + track.phi() <= trackConfigs.extraPhiCuts->at(2) || track.phi() >= trackConfigs.extraPhiCuts->at(3))) + continue; + + dataEventHist.fill(HIST("h5EtaDistribution"), collision.posZ(), collision.centFT0M(), track.eta(), track.phi(), kGlobalplusITSonly); if (track.hasTPC()) { - dataEventHist.fill(HIST("h4EtaDistribution"), collision.posZ(), collision.centFT0M(), track.eta(), kGlobalonly); + dataEventHist.fill(HIST("h5EtaDistribution"), collision.posZ(), collision.centFT0M(), track.eta(), track.phi(), kGlobalonly); } else { - dataEventHist.fill(HIST("h4EtaDistribution"), collision.posZ(), collision.centFT0M(), track.eta(), kITSonly); + dataEventHist.fill(HIST("h5EtaDistribution"), collision.posZ(), collision.centFT0M(), track.eta(), track.phi(), kITSonly); } } } @@ -2508,13 +2604,16 @@ struct Phik0shortanalysis { if (furtherCheckonMcCollision && (std::abs(mcCollision.posZ()) > cutZVertex || !pwglf::isINELgtNmc(mcParticlesThisColl, 0, pdgDB))) return; - if (filterOnMcPhi && !eventHasMCPhi(mcParticlesThisColl)) + if (filterOnGenPhi && !eventHasGenPhi(mcParticlesThisColl)) return; mcEventHist.fill(HIST("hRecoMCMultiplicityPercent"), mcCollision.centFT0M()); mcEventHist.fill(HIST("h2RecoMCVertexZvsMult"), collision.posZ(), mcCollision.centFT0M()); for (const auto& track : filteredMCTracks) { + if (trackConfigs.applyExtraPhiCuts && ((track.phi() > trackConfigs.extraPhiCuts->at(0) && track.phi() < trackConfigs.extraPhiCuts->at(1)) || + track.phi() <= trackConfigs.extraPhiCuts->at(2) || track.phi() >= trackConfigs.extraPhiCuts->at(3))) + continue; if (!track.has_mcParticle()) continue; @@ -2522,25 +2621,32 @@ struct Phik0shortanalysis { if (!mcTrack.isPhysicalPrimary() || std::abs(mcTrack.eta()) > trackConfigs.etaMax) continue; - mcEventHist.fill(HIST("h5RecoMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), kGlobalplusITSonly, kSpAll); + mcEventHist.fill(HIST("h6RecoMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kGlobalplusITSonly); if (track.hasTPC()) { - mcEventHist.fill(HIST("h5RecoMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), kGlobalonly, kSpAll); + mcEventHist.fill(HIST("h6RecoMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kGlobalonly); } else { - mcEventHist.fill(HIST("h5RecoMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), kITSonly, kSpAll); + mcEventHist.fill(HIST("h6RecoMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kITSonly); } int pid = fromPDGToEnum(mcTrack.pdgCode()); - mcEventHist.fill(HIST("h5RecoMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), kGlobalplusITSonly, pid); + mcEventHist.fill(HIST("h6RecoMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), pid, kGlobalplusITSonly); } for (const auto& mcParticle : mcParticlesThisColl) { if (!isGenParticleCharged(mcParticle)) continue; - mcEventHist.fill(HIST("h4GenMCEtaDistributionReco"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), kSpAll); + mcEventHist.fill(HIST("h6GenMCEtaDistributionReco"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kNoGenpTVar); + if (mcParticle.pt() < trackConfigs.cMinChargedParticlePtcut) { + mcEventHist.fill(HIST("h6GenMCEtaDistributionReco"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup, -10.0f * mcParticle.pt() + 2.0f); + mcEventHist.fill(HIST("h6GenMCEtaDistributionReco"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown, 5.0f * mcParticle.pt() + 0.5f); + } else { + mcEventHist.fill(HIST("h6GenMCEtaDistributionReco"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup); + mcEventHist.fill(HIST("h6GenMCEtaDistributionReco"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown); + } int pid = fromPDGToEnum(mcParticle.pdgCode()); - mcEventHist.fill(HIST("h4GenMCEtaDistributionReco"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), pid); + mcEventHist.fill(HIST("h6GenMCEtaDistributionReco"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), pid, kNoGenpTVar); } } @@ -2548,21 +2654,35 @@ struct Phik0shortanalysis { void processdNdetaWPhiMCGen(MCCollisions::iterator const& mcCollision, soa::SmallGroups const& collisions, FilteredMCTracks const& filteredMCTracks, aod::McParticles const& mcParticles) { - if (std::abs(mcCollision.posZ()) > cutZVertex) - return; if (!pwglf::isINELgtNmc(mcParticles, 0, pdgDB)) return; - if (filterOnMcPhi && !eventHasMCPhi(mcParticles)) + if (filterOnGenPhi && !eventHasGenPhi(mcParticles)) return; uint64_t numberAssocColl = 0; + std::vector zVtxs; + for (const auto& collision : collisions) { if (acceptEventQA(collision, false)) { + auto filteredMCTracksThisColl = filteredMCTracks.sliceBy(preslices.perColl, collision.globalIndex()); + + Partition posFiltMCTracks = aod::track::signed1Pt > trackConfigs.cfgCutCharge; + posFiltMCTracks.bindTable(filteredMCTracksThisColl); + Partition negFiltMCTracks = aod::track::signed1Pt < trackConfigs.cfgCutCharge; + negFiltMCTracks.bindTable(filteredMCTracksThisColl); + + if (filterOnRecoPhiWPDG && !eventHasRecoPhiWPDG(posFiltMCTracks, negFiltMCTracks)) + continue; + mcEventHist.fill(HIST("hGenMCRecoMultiplicityPercent"), mcCollision.centFT0M()); mcEventHist.fill(HIST("h2GenMCRecoVertexZvsMult"), collision.posZ(), mcCollision.centFT0M()); - auto filteredMCTracksThisColl = filteredMCTracks.sliceBy(preslices.perColl, collision.globalIndex()); + zVtxs.push_back(collision.posZ()); + for (const auto& track : filteredMCTracksThisColl) { + if (trackConfigs.applyExtraPhiCuts && ((track.phi() > trackConfigs.extraPhiCuts->at(0) && track.phi() < trackConfigs.extraPhiCuts->at(1)) || + track.phi() <= trackConfigs.extraPhiCuts->at(2) || track.phi() >= trackConfigs.extraPhiCuts->at(3))) + continue; if (!track.has_mcParticle()) continue; @@ -2570,25 +2690,32 @@ struct Phik0shortanalysis { if (!mcTrack.isPhysicalPrimary() || std::abs(mcTrack.eta()) > trackConfigs.etaMax) continue; - mcEventHist.fill(HIST("h5RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), kGlobalplusITSonly, kSpAll); + mcEventHist.fill(HIST("h6RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kGlobalplusITSonly); if (track.hasTPC()) { - mcEventHist.fill(HIST("h5RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), kGlobalonly, kSpAll); + mcEventHist.fill(HIST("h6RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kGlobalonly); } else { - mcEventHist.fill(HIST("h5RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), kITSonly, kSpAll); + mcEventHist.fill(HIST("h6RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), kSpAll, kITSonly); } int pid = fromPDGToEnum(mcTrack.pdgCode()); - mcEventHist.fill(HIST("h5RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), kGlobalplusITSonly, pid); + mcEventHist.fill(HIST("h6RecoCheckMCEtaDistribution"), collision.posZ(), mcCollision.centFT0M(), mcTrack.eta(), mcTrack.phi(), pid, kGlobalplusITSonly); } for (const auto& mcParticle : mcParticles) { if (!isGenParticleCharged(mcParticle)) continue; - mcEventHist.fill(HIST("h4GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), kSpAll); + mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kNoGenpTVar); + if (mcParticle.pt() < trackConfigs.cMinChargedParticlePtcut) { + mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup, -10.0f * mcParticle.pt() + 2.0f); + mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown, 5.0f * mcParticle.pt() + 0.5f); + } else { + mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup); + mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown); + } int pid = fromPDGToEnum(mcParticle.pdgCode()); - mcEventHist.fill(HIST("h4GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), pid); + mcEventHist.fill(HIST("h6GenMCEtaDistributionRecoCheck"), collision.posZ(), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), pid, kNoGenpTVar); } numberAssocColl++; @@ -2596,16 +2723,48 @@ struct Phik0shortanalysis { } mcEventHist.fill(HIST("hGenMCMultiplicityPercent"), mcCollision.centFT0M()); - if (numberAssocColl > 0) + + if (numberAssocColl > 0) { + float zVtxRef = zVtxs[0]; + if (zVtxs.size() > 1) { + for (size_t i = 1; i < zVtxs.size(); ++i) { + mcEventHist.fill(HIST("hSplitVertexZ"), zVtxs[i] - zVtxRef); + } + } + mcEventHist.fill(HIST("hGenMCAssocRecoMultiplicityPercent"), mcCollision.centFT0M()); + mcEventHist.fill(HIST("h2GenMCAssocRecoVertexZvsMult"), zVtxRef, mcCollision.centFT0M()); + } for (const auto& mcParticle : mcParticles) { if (!isGenParticleCharged(mcParticle)) continue; - mcEventHist.fill(HIST("h2GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta()); - if (numberAssocColl > 0) - mcEventHist.fill(HIST("h2GenMCEtaDistributionAssocReco"), mcCollision.centFT0M(), mcParticle.eta()); + int pid = fromPDGToEnum(mcParticle.pdgCode()); + + mcEventHist.fill(HIST("h5GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kNoGenpTVar); + if (mcParticle.pt() < trackConfigs.cMinChargedParticlePtcut) { + mcEventHist.fill(HIST("h5GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup, -10.0f * mcParticle.pt() + 2.0f); + mcEventHist.fill(HIST("h5GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown, 5.0f * mcParticle.pt() + 0.5f); + } else { + mcEventHist.fill(HIST("h5GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup); + mcEventHist.fill(HIST("h5GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown); + } + mcEventHist.fill(HIST("h5GenMCEtaDistribution"), mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), pid, kNoGenpTVar); + + if (numberAssocColl > 0) { + float zVtxRef = zVtxs[0]; + + mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kNoGenpTVar); + if (mcParticle.pt() < trackConfigs.cMinChargedParticlePtcut) { + mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup, -10.0f * mcParticle.pt() + 2.0f); + mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown, 5.0f * mcParticle.pt() + 0.5f); + } else { + mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTup); + mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), kSpAll, kGenpTdown); + } + mcEventHist.fill(HIST("h6GenMCEtaDistributionAssocReco"), zVtxRef, mcCollision.centFT0M(), mcParticle.eta(), mcParticle.phi(), pid, kNoGenpTVar); + } } } @@ -2649,7 +2808,7 @@ struct Phik0shortanalysis { continue; // condition to avoid double counting of pair ROOT::Math::PxPyPzMVector recPhi = recMother(track1, track2, massKa, massKa); - if (recPhi.Pt() < minPhiPt || recPhi.Pt() > maxPhiPt) + if (recPhi.Pt() < phiConfigs.minPhiPt || recPhi.Pt() > phiConfigs.maxPhiPt) continue; if (std::abs(recPhi.Rapidity()) > deltaYConfigs.cfgYAcceptance) continue; @@ -2685,7 +2844,7 @@ struct Phik0shortanalysis { dataK0SHist.fill(HIST("hV0CosPA"), v0.v0cosPA()); // Filling the PID of the V0 daughters in the region of the K0 peak - if (lowMK0S < v0.mK0Short() && v0.mK0Short() < upMK0S) { + if (v0Configs.lowMK0S < v0.mK0Short() && v0.mK0Short() < v0Configs.upMK0S) { dataK0SHist.fill(HIST("hNSigmaPosPionFromK0S"), posDaughterTrack.tpcInnerParam(), posDaughterTrack.tpcNSigmaPi()); dataK0SHist.fill(HIST("hNSigmaNegPionFromK0S"), negDaughterTrack.tpcInnerParam(), negDaughterTrack.tpcNSigmaPi()); } @@ -2767,7 +2926,7 @@ struct Phik0shortanalysis { continue; // condition to avoid double counting of pair ROOT::Math::PxPyPzMVector recPhi = recMother(track1, track2, massKa, massKa); - if (recPhi.Pt() < minPhiPt || recPhi.Pt() > maxPhiPt) + if (recPhi.Pt() < phiConfigs.minPhiPt || recPhi.Pt() > phiConfigs.maxPhiPt) continue; if (std::abs(recPhi.Rapidity()) > deltaYConfigs.cfgYAcceptance) continue; @@ -2912,7 +3071,7 @@ struct Phik0shortanalysis { if (!isMCMotherPhi) continue; - if (pTMother < minPhiPt || std::abs(yMother) > deltaYConfigs.cfgYAcceptance) + if (pTMother < phiConfigs.minPhiPt || std::abs(yMother) > deltaYConfigs.cfgYAcceptance) continue; mcPhiHist.fill(HIST("h3PhiMCRecoNewProc"), genmultiplicity, pTMother, yMother); @@ -2983,7 +3142,7 @@ struct Phik0shortanalysis { continue; // Phi selection - if (mcParticle.pdgCode() == o2::constants::physics::Pdg::kPhi && mcParticle.pt() >= minPhiPt) + if (mcParticle.pdgCode() == o2::constants::physics::Pdg::kPhi && mcParticle.pt() >= phiConfigs.minPhiPt) mcPhiHist.fill(HIST("h3PhiMCGenRecoCheckNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); // K0S selection @@ -3019,7 +3178,7 @@ struct Phik0shortanalysis { continue; // Phi selection - if (mcParticle.pdgCode() == o2::constants::physics::Pdg::kPhi && mcParticle.pt() >= minPhiPt) + if (mcParticle.pdgCode() == o2::constants::physics::Pdg::kPhi && mcParticle.pt() >= phiConfigs.minPhiPt) mcPhiHist.fill(HIST("h3PhiMCGenRecoNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); // K0S selection @@ -3048,7 +3207,7 @@ struct Phik0shortanalysis { continue; // Phi selection - if (mcParticle.pdgCode() == o2::constants::physics::Pdg::kPhi && mcParticle.pt() >= minPhiPt) { + if (mcParticle.pdgCode() == o2::constants::physics::Pdg::kPhi && mcParticle.pt() >= phiConfigs.minPhiPt) { mcPhiHist.fill(HIST("h3PhiMCGenNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); if (numberAssocColl > 0) mcPhiHist.fill(HIST("h3PhiMCGenAssocRecoNewProc"), genmultiplicity, mcParticle.pt(), mcParticle.y()); @@ -3094,7 +3253,7 @@ struct Phik0shortanalysis { continue; ROOT::Math::PxPyPzMVector recPhi = recMother(posTrack1, negTrack1, massKa, massKa); - if (recPhi.Pt() < minPhiPt) + if (recPhi.Pt() < phiConfigs.minPhiPt) continue; if (std::abs(recPhi.Rapidity()) > deltaYConfigs.cfgYAcceptance) continue; @@ -3145,7 +3304,7 @@ struct Phik0shortanalysis { continue; ROOT::Math::PxPyPzMVector recPhi = recMother(posTrack1, negTrack1, massKa, massKa); - if (recPhi.Pt() < minPhiPt) + if (recPhi.Pt() < phiConfigs.minPhiPt) continue; if (std::abs(recPhi.Rapidity()) > deltaYConfigs.cfgYAcceptance) continue; diff --git a/PWGLF/Tasks/Strangeness/sigmaminustask.cxx b/PWGLF/Tasks/Strangeness/sigmaminustask.cxx deleted file mode 100644 index ac588fb8597..00000000000 --- a/PWGLF/Tasks/Strangeness/sigmaminustask.cxx +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. - -/// \file sigmaminustask.cxx -/// \brief Example of a simple task for the analysis of the Sigma-minus -/// \author Francesco Mazzaschi - -#include "PWGLF/DataModel/LFKinkDecayTables.h" - -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/PIDResponse.h" - -#include "Framework/AnalysisTask.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/PID.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; - -using TracksFull = soa::Join; -using CollisionsFull = soa::Join; -using CollisionsFullMC = soa::Join; - -struct sigmaminustask { - // Histograms are defined with HistogramRegistry - HistogramRegistry rEventSelection{"eventSelection", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry rSigmaMinus{"sigmaminus", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - - // Configurable for event selection - Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; - Configurable cutNSigmaPi{"cutNSigmaPi", 4, "NSigmaTPCPion"}; - - Preslice mPerCol = aod::track::collisionId; - - void init(InitContext const&) - { - // Axes - const AxisSpec ptAxis{50, -10, 10, "#it{p}_{T} (GeV/#it{c})"}; - const AxisSpec nSigmaPiAxis{100, -5, 5, "n#sigma_{#pi}"}; - const AxisSpec sigmaMassAxis{100, 1.1, 1.4, "m (GeV/#it{c}^{2})"}; - const AxisSpec xiMassAxis{100, 1.2, 1.6, "m_{#Xi} (GeV/#it{c}^{2})"}; - const AxisSpec pdgAxis{10001, -5000, 5000, "PDG code"}; - const AxisSpec vertexZAxis{100, -15., 15., "vrtx_{Z} [cm]"}; - - // Event selection - rEventSelection.add("hVertexZRec", "hVertexZRec", {HistType::kTH1F, {vertexZAxis}}); - // Sigma-minus reconstruction - rSigmaMinus.add("h2MassSigmaMinusPt", "h2MassSigmaMinusPt", {HistType::kTH2F, {ptAxis, sigmaMassAxis}}); - rSigmaMinus.add("h2SigmaMassVsXiMass", "h2SigmaMassVsXiMass", {HistType::kTH2F, {xiMassAxis, sigmaMassAxis}}); - rSigmaMinus.add("h2NSigmaPiPt", "h2NSigmaPiPt", {HistType::kTH2F, {ptAxis, nSigmaPiAxis}}); - - if (doprocessMC) { - // Add MC histograms if needed - rSigmaMinus.add("h2MassPtMCRec", "h2MassPtMCRec", {HistType::kTH2F, {ptAxis, sigmaMassAxis}}); - rSigmaMinus.add("h2MassPtMCGen", "h2MassPtMCGen", {HistType::kTH2F, {ptAxis, sigmaMassAxis}}); - } - } - - void processData(CollisionsFull::iterator const& collision, aod::KinkCands const& KinkCands, TracksFull const&) - { - if (std::abs(collision.posZ()) > cutzvertex || !collision.sel8()) { - return; - } - rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); - for (const auto& kinkCand : KinkCands) { - auto dauTrack = kinkCand.trackDaug_as(); - if (abs(dauTrack.tpcNSigmaPi()) > cutNSigmaPi) { - continue; - } - rSigmaMinus.fill(HIST("h2MassSigmaMinusPt"), kinkCand.mothSign() * kinkCand.ptMoth(), kinkCand.mSigmaMinus()); - rSigmaMinus.fill(HIST("h2SigmaMassVsXiMass"), kinkCand.mXiMinus(), kinkCand.mSigmaMinus()); - rSigmaMinus.fill(HIST("h2NSigmaPiPt"), kinkCand.mothSign() * kinkCand.ptMoth(), dauTrack.tpcNSigmaPi()); - } - } - PROCESS_SWITCH(sigmaminustask, processData, "Data processing", true); - - void processMC(CollisionsFullMC const& collisions, aod::KinkCands const& KinkCands, aod::McTrackLabels const& trackLabelsMC, aod::McParticles const& particlesMC, TracksFull const&) - { - for (const auto& collision : collisions) { - if (std::abs(collision.posZ()) > cutzvertex || !collision.sel8()) { - continue; - } - - rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); - auto kinkCandPerColl = KinkCands.sliceBy(mPerCol, collision.globalIndex()); - for (const auto& kinkCand : kinkCandPerColl) { - auto dauTrack = kinkCand.trackDaug_as(); - auto mothTrack = kinkCand.trackMoth_as(); - if (dauTrack.sign() != mothTrack.sign()) { - LOG(info) << "Skipping kink candidate with opposite sign daughter and mother: " << kinkCand.globalIndex(); - continue; // Skip if the daughter has the opposite sign as the mother - } - if (abs(dauTrack.tpcNSigmaPi()) > cutNSigmaPi) { - continue; - } - - rSigmaMinus.fill(HIST("h2MassSigmaMinusPt"), kinkCand.mothSign() * kinkCand.ptMoth(), kinkCand.mSigmaMinus()); - rSigmaMinus.fill(HIST("h2SigmaMassVsXiMass"), kinkCand.mXiMinus(), kinkCand.mSigmaMinus()); - rSigmaMinus.fill(HIST("h2NSigmaPiPt"), kinkCand.mothSign() * kinkCand.ptMoth(), dauTrack.tpcNSigmaPi()); - // do MC association - auto mcLabSigma = trackLabelsMC.rawIteratorAt(mothTrack.globalIndex()); - auto mcLabPiDau = trackLabelsMC.rawIteratorAt(dauTrack.globalIndex()); - if (mcLabSigma.has_mcParticle() && mcLabPiDau.has_mcParticle()) { - auto mcTrackSigma = mcLabSigma.mcParticle_as(); - auto mcTrackPiDau = mcLabPiDau.mcParticle_as(); - if (!mcTrackPiDau.has_mothers()) { - continue; - } - for (auto& piMother : mcTrackPiDau.mothers_as()) { - if (piMother.globalIndex() != mcTrackSigma.globalIndex()) { - continue; - } - if (std::abs(mcTrackSigma.pdgCode()) != 3112 || std::abs(mcTrackPiDau.pdgCode()) != 211) { - continue; - } - rSigmaMinus.fill(HIST("h2MassPtMCRec"), kinkCand.mothSign() * kinkCand.ptMoth(), kinkCand.mSigmaMinus()); - } - } - } - } - for (const auto& mcPart : particlesMC) { - if (std::abs(mcPart.pdgCode()) != 3112 || std::abs(mcPart.y()) > 0.5) { - continue; - } - if (!mcPart.has_daughters()) { - continue; // Skip if no daughters - } - bool hasSigmaDaughter = false; - for (const auto& daughter : mcPart.daughters_as()) { - if (std::abs(daughter.pdgCode()) == 211) { // Sigma PDG code - hasSigmaDaughter = true; - break; // Found a pi daughter, exit loop - } - } - if (!hasSigmaDaughter) { - continue; // Skip if no pi daughter found - } - float mcMass = std::sqrt(mcPart.e() * mcPart.e() - mcPart.p() * mcPart.p()); - int sigmaSign = mcPart.pdgCode() > 0 ? 1 : -1; // Determine the sign of the Sigma - rSigmaMinus.fill(HIST("h2MassPtMCGen"), sigmaSign * mcPart.pt(), mcMass); - } - } - PROCESS_SWITCH(sigmaminustask, processMC, "MC processing", false); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; -} diff --git a/PWGLF/Tasks/Strangeness/strangenessderivedbinnedinfo.cxx b/PWGLF/Tasks/Strangeness/strangenessderivedbinnedinfo.cxx index 025341d279f..728d8c6675b 100644 --- a/PWGLF/Tasks/Strangeness/strangenessderivedbinnedinfo.cxx +++ b/PWGLF/Tasks/Strangeness/strangenessderivedbinnedinfo.cxx @@ -75,8 +75,8 @@ using std::array; using namespace o2::aod::rctsel; using DauTracks = soa::Join; -using V0Candidates = soa::Join; -using CascadeCandidates = soa::Join; +using V0Candidates = soa::Join; +using CascadeCandidates = soa::Join; struct strangenessderivedbinnedinfo { HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -124,6 +124,17 @@ struct strangenessderivedbinnedinfo { Configurable maxIR{"maxIR", -1, "maximum IR collisions"}; } eventSelections; + static constexpr float defaultSqrtScalingParameters[1][4] = {{0.1, 0.1, 0, 128}}; + + // preselection options + struct : ConfigurableGroup { + std::string prefix = "encodingOpts"; + Configurable useSqrtEncodingForOccupancy{"useSqrtEncodingForOccupancy", false, "Store sqrt(occupancy) instead of occupancy"}; + Configurable useSqrtEncodingForRadius{"useSqrtEncodingForRadius", false, "Store sqrt(radius) instead of radius"}; + Configurable useSqrtScalingForEncodingPt{"useSqrtScalingForEncodingPt", false, "Store sqrt scaling(pT) instead of pT"}; + Configurable> sqrtScalingParameters{"sqrtScalingParameters", {defaultSqrtScalingParameters[0], 4, {"sigma0", "sigma1", "clampMin", "clampMax"}}, "Sqrt scaling parameters"}; + } encodingOpts; + struct : ConfigurableGroup { Configurable v0TypeSelection{"v0Selections.v0TypeSelection", 1, "select on a certain V0 type (leave negative if no selection desired)"}; @@ -240,10 +251,28 @@ struct strangenessderivedbinnedinfo { ConfigurableAxis axisEta{"axisEta", {10, -1.0f, 1.0f}, "Pseudo-rapidity #eta"}; ConfigurableAxis axisRadius{"axisRadius", {10, 0.0f, 250.0f}, "Decay radius (cm)"}; ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f, 1.5f, 2.0f, 2.5f, 3.0f, 4.0f, 5.0f, 7.0f, 9.0f, 11.0f, 15.0f, 30.0f}, "#it{p}_{T} (GeV/#it{c})"}; + ConfigurableAxis axisAlphaV0{"axisAlphaV0", {1, -1.0f, 1.f}, "V0 #alpha Armenteros"}; + ConfigurableAxis axisPtArmV0{"axisPtArmV0", {1, 0.0f, 10.f}, "V0 #it{p}_{T} Armenteros"}; // PDG database Service pdgDB; + // Sqrt scaling function + // Author: Marian Ivanov + int codeSqrtScaling(float val, float sigma0, float sigma1, int clampMin, int clampMax) + { + float code_f = std::asinh((sigma1 * val) / sigma0) / sigma0; + return std::clamp(static_cast(std::round(code_f)), clampMin, clampMax); + } + + // Function to decode the sqrt scaling + // Author: Marian Ivanov + float decodeSqrtScaling(int code, float sigma0, float sigma1) + { + float code_f = static_cast(code); + return (sigma0 / sigma1) * std::sinh(sigma0 * code_f); + } + void init(InitContext const&) { if (analyseK0Short + analyseLambda + analyseAntiLambda + analyseXi + analyseOmega > 1) { @@ -285,7 +314,16 @@ struct strangenessderivedbinnedinfo { histos.add("hEventCentrality", "hEventCentrality", kTH1F, {{100, 0.0f, +100.0f}}); histos.add("hEventOccupancy", "hEventOccupancy", kTH1F, {axisOccupancy}); - histos.add("h7dCentOccQoverPtMassRadiusPhiEta", "h7dCentOccQoverPtMassRadiusPhiEta", kTHnSparseF, {axisCentrality, axisOccupancy, axisPt, axisMass, axisRadius, axisPhi, axisEta}); + histos.add("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc", "h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc", kTHnSparseF, {axisMass, axisPt, axisPhi, axisEta, axisPtArmV0, axisAlphaV0, axisRadius, axisCentrality, axisOccupancy}); + histos.get(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"))->GetAxis(0)->SetName("Mass"); + histos.get(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"))->GetAxis(1)->SetName("Pt"); + histos.get(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"))->GetAxis(2)->SetName("Phi"); + histos.get(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"))->GetAxis(3)->SetName("Eta"); + histos.get(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"))->GetAxis(4)->SetName("V0PtArm"); + histos.get(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"))->GetAxis(5)->SetName("V0Alpha"); + histos.get(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"))->GetAxis(6)->SetName("Radius"); + histos.get(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"))->GetAxis(7)->SetName("Centrality"); + histos.get(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"))->GetAxis(8)->SetName("Occupancy"); if (cfgSkimmedProcessing) { zorroSummary.setObject(zorro.getZorroSummary()); @@ -470,6 +508,8 @@ struct strangenessderivedbinnedinfo { } else { centrality = collision.centFT0C(); occupancy = eventSelections.useFT0CbasedOccupancy ? collision.ft0cOccupancyInTimeRange() : collision.trackOccupancyInTimeRange(); + if (encodingOpts.useSqrtEncodingForOccupancy) + occupancy = std::sqrt(occupancy); } histos.fill(HIST("hEventCentrality"), centrality); histos.fill(HIST("hEventOccupancy"), occupancy); @@ -761,14 +801,17 @@ struct strangenessderivedbinnedinfo { if (v0.v0Type() != v0Selections.v0TypeSelection && v0Selections.v0TypeSelection > -1) continue; // skip V0s that are not standard + float pT = encodingOpts.useSqrtScalingForEncodingPt ? codeSqrtScaling(v0.pt(), encodingOpts.sqrtScalingParameters->get("sigma0"), encodingOpts.sqrtScalingParameters->get("sigma1"), encodingOpts.sqrtScalingParameters->get("clampMin"), encodingOpts.sqrtScalingParameters->get("clampMax")) : v0.pt(); + float decayRadius = encodingOpts.useSqrtEncodingForRadius ? std::sqrt(v0.v0radius()) : v0.v0radius(); + if (analyseK0Short && isV0Selected(v0, collision, v0.yK0Short())) { - histos.fill(HIST("h7dCentOccQoverPtMassRadiusPhiEta"), centrality, occupancy, v0.pt(), v0.mK0Short(), v0.v0radius(), v0.phi(), v0.eta()); + histos.fill(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"), v0.mK0Short(), pT, v0.phi(), v0.eta(), v0.qtarm(), v0.alpha(), decayRadius, centrality, occupancy); } if (analyseLambda && isV0Selected(v0, collision, v0.yLambda())) { - histos.fill(HIST("h7dCentOccQoverPtMassRadiusPhiEta"), centrality, occupancy, v0.pt(), v0.mLambda(), v0.v0radius(), v0.phi(), v0.eta()); + histos.fill(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"), v0.mLambda(), pT, v0.phi(), v0.eta(), v0.qtarm(), v0.alpha(), decayRadius, centrality, occupancy); } if (analyseAntiLambda && isV0Selected(v0, collision, v0.yLambda())) { - histos.fill(HIST("h7dCentOccQoverPtMassRadiusPhiEta"), centrality, occupancy, v0.pt(), v0.mAntiLambda(), v0.v0radius(), v0.phi(), v0.eta()); + histos.fill(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"), v0.mAntiLambda(), pT, v0.phi(), v0.eta(), v0.qtarm(), v0.alpha(), decayRadius, centrality, occupancy); } } // end v0 loop } @@ -780,11 +823,14 @@ struct strangenessderivedbinnedinfo { std::abs(cascade.bacheloreta()) > cascSelections.daughterEtaCut) continue; // remove acceptance that's badly reproduced by MC / superfluous in future + float pT = encodingOpts.useSqrtScalingForEncodingPt ? codeSqrtScaling(cascade.pt(), encodingOpts.sqrtScalingParameters->get("sigma0"), encodingOpts.sqrtScalingParameters->get("sigma1"), encodingOpts.sqrtScalingParameters->get("clampMin"), encodingOpts.sqrtScalingParameters->get("clampMax")) : cascade.pt(); + float decayRadius = encodingOpts.useSqrtEncodingForRadius ? std::sqrt(cascade.cascradius()) : cascade.cascradius(); + if (analyseXi && isCascadeSelected(cascade, collision, cascade.yXi())) { - histos.fill(HIST("h7dCentOccQoverPtMassRadiusPhiEta"), centrality, occupancy, cascade.pt(), cascade.m(1), cascade.cascradius(), cascade.phi(), cascade.eta()); + histos.fill(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"), cascade.m(1), pT, cascade.phi(), cascade.eta(), 0., 0., decayRadius, centrality, occupancy); } if (analyseOmega && isCascadeSelected(cascade, collision, cascade.yOmega())) { - histos.fill(HIST("h7dCentOccQoverPtMassRadiusPhiEta"), centrality, occupancy, cascade.pt(), cascade.m(2), cascade.cascradius(), cascade.phi(), cascade.eta()); + histos.fill(HIST("h9dMassPtPhiEtaPtArmV0AlphaV0RadiusCentOcc"), cascade.m(2), pT, cascade.phi(), cascade.eta(), 0., 0., decayRadius, centrality, occupancy); } } // end cascade loop } diff --git a/PWGLF/Tasks/Strangeness/v0ptinvmassplots.cxx b/PWGLF/Tasks/Strangeness/v0ptinvmassplots.cxx index b6a459fab70..d91e8ae5f49 100644 --- a/PWGLF/Tasks/Strangeness/v0ptinvmassplots.cxx +++ b/PWGLF/Tasks/Strangeness/v0ptinvmassplots.cxx @@ -225,9 +225,9 @@ struct V0PtInvMassPlots { rPtAnalysis.add("hNEvents", "hNEvents", {HistType::kTH1D, {{10, 0.f, 10.f}}}); rPtAnalysis.add("hNRecEvents_Data", "hNRecEvents_Data", {HistType::kTH1D, {{1, 0.f, 1.f}}}); rPtAnalysis.add("hNV0s", "hNV0s", {HistType::kTH1D, {{10, 0.f, 10.f}}}); - rPtAnalysis.add("hNK0sh", "hNK0sh", {HistType::kTH1D, {{10, 0.f, 10.f}}}); - rPtAnalysis.add("hNLambda", "hNLambda", {HistType::kTH1D, {{10, 0.f, 10.f}}}); - rPtAnalysis.add("hNAntilambda", "hNAntilambda", {HistType::kTH1D, {{10, 0.f, 10.f}}}); + rPtAnalysis.add("hNK0sh", "hNK0sh", {HistType::kTH1D, {{11, 0.f, 11.f}}}); + rPtAnalysis.add("hNLambda", "hNLambda", {HistType::kTH1D, {{11, 0.f, 11.f}}}); + rPtAnalysis.add("hNAntilambda", "hNAntilambda", {HistType::kTH1D, {{11, 0.f, 11.f}}}); rPtAnalysis.add("hVertexZRec", "hVertexZRec", {HistType::kTH1F, {vertexZAxis}}); rPtAnalysis.add("hArmenterosPodolanskiPlot", "hArmenterosPodolanskiPlot", {HistType::kTH2F, {{armenterosasymAxis}, {armenterosQtAxis}}}); @@ -339,42 +339,42 @@ struct V0PtInvMassPlots { } rPtAnalysis.fill(HIST("hNEvents"), 1.5); rPtAnalysis.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(2, "sel 8"); - if (!(collision.selection_bit(aod::evsel::kNoTimeFrameBorder) && doNoTimeFrameBorder)) { + if (!(doNoTimeFrameBorder && collision.selection_bit(aod::evsel::kNoTimeFrameBorder))) { return false; } rPtAnalysis.fill(HIST("hNEvents"), 2.5); rPtAnalysis.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(3, "NoTimeFrameBorder"); - if (!(collision.selection_bit(aod::evsel::kNoITSROFrameBorder) && doNoITSROFrameBorder)) { + if (!(doNoITSROFrameBorder && collision.selection_bit(aod::evsel::kNoITSROFrameBorder))) { return false; } rPtAnalysis.fill(HIST("hNEvents"), 3.5); rPtAnalysis.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(4, "NoITSROFrameBorder"); - if (!(collision.selection_bit(aod::evsel::kIsTriggerTVX) && doIsTriggerTVX)) { + if (!(doIsTriggerTVX && collision.selection_bit(aod::evsel::kIsTriggerTVX))) { return false; } rPtAnalysis.fill(HIST("hNEvents"), 4.5); rPtAnalysis.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(5, "IsTriggerTVX"); - if (!(std::abs(collision.posZ()) < cutZVertex && docutZVertex)) { + if (!(docutZVertex && std::abs(collision.posZ()) < cutZVertex)) { return false; } rPtAnalysis.fill(HIST("hNEvents"), 5.5); rPtAnalysis.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(6, "cutZVertex"); - if (!(collision.selection_bit(aod::evsel::kIsVertexTOFmatched) && doIsVertexTOFmatched)) { + if (!(doIsVertexTOFmatched && collision.selection_bit(aod::evsel::kIsVertexTOFmatched))) { return false; } rPtAnalysis.fill(HIST("hNEvents"), 6.5); rPtAnalysis.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(7, "IsVertexTOFmatched"); - if (!(collision.selection_bit(aod::evsel::kNoSameBunchPileup) && doNoSameBunchPileup)) { + if (!(doNoSameBunchPileup && collision.selection_bit(aod::evsel::kNoSameBunchPileup))) { return false; } rPtAnalysis.fill(HIST("hNEvents"), 7.5); rPtAnalysis.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(8, "NoSameBunchPileup"); - if (!(collision.selection_bit(aod::evsel::kIsVertexITSTPC) && doIsVertexITSTPC)) { + if (!(doIsVertexITSTPC && collision.selection_bit(aod::evsel::kIsVertexITSTPC))) { return false; } rPtAnalysis.fill(HIST("hNEvents"), 8.5); rPtAnalysis.get(HIST("hNEvents"))->GetXaxis()->SetBinLabel(9, "IsVertexITSTPC"); - if (!(collision.isInelGt0() && doisInelGt0)) { + if (!(doisInelGt0 && collision.isInelGt0())) { return false; } rPtAnalysis.fill(HIST("hNEvents"), 9.5); @@ -394,27 +394,21 @@ struct V0PtInvMassPlots { rPtAnalysis.fill(HIST("hNV0s"), 0.5); rPtAnalysis.get(HIST("hNV0s"))->GetXaxis()->SetBinLabel(1, "All V0s"); - if (std::abs(v0.y()) > rapidityCut && doRapidityCut) { // V0 Rapidity Cut + if (doDaughterPseudorapidityCut && (std::abs(posDaughterTrack.eta()) > etadau && std::abs(negDaughterTrack.eta()) > etadau)) { // Daughters Pseudorapidity Cut return false; } rPtAnalysis.fill(HIST("hNV0s"), 1.5); - rPtAnalysis.get(HIST("hNV0s"))->GetXaxis()->SetBinLabel(2, "Rapidity"); - if ((std::abs(posDaughterTrack.eta()) > etadau && std::abs(negDaughterTrack.eta()) > etadau) && doDaughterPseudorapidityCut) { // Daughters Pseudorapidity Cut + rPtAnalysis.get(HIST("hNV0s"))->GetXaxis()->SetBinLabel(2, "Dau Pseudorapidity"); + if (!doisITSAfterburner && (posDaughterTrack.isITSAfterburner() || negDaughterTrack.isITSAfterburner())) { // ITS After Burner on daughter tracks return false; } rPtAnalysis.fill(HIST("hNV0s"), 2.5); - rPtAnalysis.get(HIST("hNV0s"))->GetXaxis()->SetBinLabel(3, "Dau Pseudorapidity"); - if ((posDaughterTrack.isITSAfterburner() || negDaughterTrack.isITSAfterburner()) && !doisITSAfterburner) { // ITS After Burner on daughter tracks + rPtAnalysis.get(HIST("hNV0s"))->GetXaxis()->SetBinLabel(3, "ITS Afterburner"); + if (doitsMinHits && posDaughterTrack.itsNCls() <= itsMinHits && negDaughterTrack.itsNCls() <= itsMinHits) { // Minimum hits in the ITS return false; - } - rPtAnalysis.fill(HIST("hNV0s"), 3.5); - rPtAnalysis.get(HIST("hNV0s"))->GetXaxis()->SetBinLabel(4, "ITS Afterburner"); - if (posDaughterTrack.itsNCls() <= itsMinHits && negDaughterTrack.itsNCls() <= itsMinHits && doitsMinHits) { // Minimum hits in the ITS - return false; - rPtAnalysis.fill(HIST("hNV0s"), 4.5); - rPtAnalysis.get(HIST("hNV0s"))->GetXaxis()->SetBinLabel(5, "ITS Min Hits"); + rPtAnalysis.fill(HIST("hNV0s"), 3.5); + rPtAnalysis.get(HIST("hNV0s"))->GetXaxis()->SetBinLabel(4, "ITS Min Hits"); // Cut Plots - rPtAnalysis.fill(HIST("V0Rapidity"), v0.y()); rPtAnalysis.fill(HIST("hV0EtaDaughters"), v0.template posTrack_as().eta()); rPtAnalysis.fill(HIST("hV0EtaDaughters"), v0.template negTrack_as().eta()); } @@ -431,60 +425,67 @@ struct V0PtInvMassPlots { rPtAnalysis.fill(HIST("hNK0sh"), 0.5); rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(1, "All"); rPtAnalysis.fill(HIST("hMassK0ShortvsCuts"), 0.5, v0.mK0Short()); - if ((std::abs(posDaughterTrack.tpcNSigmaPi()) > nSigmaTPCPion && std::abs(negDaughterTrack.tpcNSigmaPi()) > nSigmaTPCPion) && doK0shTPCPID) { // TPC PID for two pions + + if (doRapidityCut && std::abs(v0.rapidity(0)) > rapidityCut) { // V0 Rapidity Cut return false; } rPtAnalysis.fill(HIST("hNK0sh"), 1.5); - rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(2, "TPC_PID"); + rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(2, "Rapidity"); rPtAnalysis.fill(HIST("hMassK0ShortvsCuts"), 1.5, v0.mK0Short()); - if (std::abs(v0.mLambda() - o2::constants::physics::MassLambda0) < compv0masscut && std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0) < compv0masscut && doK0shcomptmasscut) { // Kzero competitive v0 mass cut (cut out Lambdas and Anti-Lambdas) + if (doK0shTPCPID && (std::abs(posDaughterTrack.tpcNSigmaPi()) > nSigmaTPCPion && std::abs(negDaughterTrack.tpcNSigmaPi()) > nSigmaTPCPion)) { // TPC PID for two pions return false; } rPtAnalysis.fill(HIST("hNK0sh"), 2.5); - rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(3, "Compt_Mass"); + rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(3, "TPC_PID"); rPtAnalysis.fill(HIST("hMassK0ShortvsCuts"), 2.5, v0.mK0Short()); - if (v0.v0radius() > kaonshmaxct && doK0shMaxct) { // K0sh max ct + if (doK0shcomptmasscut && std::abs(v0.mLambda() - o2::constants::physics::MassLambda0) < compv0masscut && std::abs(v0.mAntiLambda() - o2::constants::physics::MassLambda0) < compv0masscut) { // Kzero competitive v0 mass cut (cut out Lambdas and Anti-Lambdas) return false; } rPtAnalysis.fill(HIST("hNK0sh"), 3.5); - rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(4, "Max_ct"); + rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(4, "Compt_Mass"); rPtAnalysis.fill(HIST("hMassK0ShortvsCuts"), 3.5, v0.mK0Short()); - if (v0.qtarm() < (k0shparamArmenterosCut * std::abs(v0.alpha())) && doK0shArmenterosCut) { // K0sh Armenteros Cut + if (doK0shMaxct && v0.v0radius() > kaonshmaxct) { // K0sh max ct return false; } rPtAnalysis.fill(HIST("hNK0sh"), 4.5); - rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(5, "Armenteros"); + rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(5, "Max_ct"); rPtAnalysis.fill(HIST("hMassK0ShortvsCuts"), 4.5, v0.mK0Short()); - if (v0.v0cosPA() < kaonshSettingcosPA && doK0shcosPACut) { // K0sh cosPA Topological Cut + if (doK0shArmenterosCut && v0.qtarm() < (k0shparamArmenterosCut * std::abs(v0.alpha()))) { // K0sh Armenteros Cut return false; } rPtAnalysis.fill(HIST("hNK0sh"), 5.5); - rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(6, "cosPA"); + rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(6, "Armenteros"); rPtAnalysis.fill(HIST("hMassK0ShortvsCuts"), 5.5, v0.mK0Short()); - if (v0.dcaV0daughters() > kaonshSettingdcav0dau && doK0shDCAdauCut) { // K0sh DCAdaughters Topological Cut + if (doK0shcosPACut && v0.v0cosPA() < kaonshSettingcosPA) { // K0sh cosPA Topological Cut return false; } rPtAnalysis.fill(HIST("hNK0sh"), 6.5); - rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(7, "DCAdau"); + rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(7, "cosPA"); rPtAnalysis.fill(HIST("hMassK0ShortvsCuts"), 6.5, v0.mK0Short()); - if (v0.v0radius() < kaonshSettingradius && doK0shv0radiusCut) { // K0sh v0radius Topological Cut + if (doK0shDCAdauCut && v0.dcaV0daughters() > kaonshSettingdcav0dau) { // K0sh DCAdaughters Topological Cut return false; } rPtAnalysis.fill(HIST("hNK0sh"), 7.5); - rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(8, "v0radius"); + rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(8, "DCAdau"); rPtAnalysis.fill(HIST("hMassK0ShortvsCuts"), 7.5, v0.mK0Short()); - if (std::abs(v0.dcapostopv()) < kaonshSettingdcapostopv && doK0shdcaposdautopv) { // K0sh DCAPosDaughterToPV Topological Cut + if (doK0shv0radiusCut && v0.v0radius() < kaonshSettingradius) { // K0sh v0radius Topological Cut return false; } rPtAnalysis.fill(HIST("hNK0sh"), 8.5); - rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(9, "DCAPosDautoPV"); + rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(9, "v0radius"); rPtAnalysis.fill(HIST("hMassK0ShortvsCuts"), 8.5, v0.mK0Short()); - if (std::abs(v0.dcanegtopv()) < kaonshSettingdcanegtopv && doK0shdcanegdautopv) { // K0sh DCANegDaughterToPV Topological Cut + if (doK0shdcaposdautopv && std::abs(v0.dcapostopv()) < kaonshSettingdcapostopv) { // K0sh DCAPosDaughterToPV Topological Cut return false; } rPtAnalysis.fill(HIST("hNK0sh"), 9.5); - rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(10, "DCANegDautoPV"); + rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(10, "DCAPosDautoPV"); rPtAnalysis.fill(HIST("hMassK0ShortvsCuts"), 9.5, v0.mK0Short()); + if (doK0shdcanegdautopv && std::abs(v0.dcanegtopv()) < kaonshSettingdcanegtopv) { // K0sh DCANegDaughterToPV Topological Cut + return false; + } + rPtAnalysis.fill(HIST("hNK0sh"), 10.5); + rPtAnalysis.get(HIST("hNK0sh"))->GetXaxis()->SetBinLabel(11, "DCANegDautoPV"); + rPtAnalysis.fill(HIST("hMassK0ShortvsCuts"), 10.5, v0.mK0Short()); // Cut Plots rPtAnalysis.fill(HIST("hArmenterosPodolanskiPlotK0sh"), v0.alpha(), v0.qtarm()); @@ -495,6 +496,7 @@ struct V0PtInvMassPlots { rPtAnalysis.fill(HIST("hK0shDCAV0Daughters"), v0.dcaV0daughters()); rPtAnalysis.fill(HIST("hK0shDCAPosDaughter"), v0.dcapostopv()); rPtAnalysis.fill(HIST("hK0shDCANegDaughter"), v0.dcanegtopv()); + rPtAnalysis.fill(HIST("V0Rapidity"), v0.rapidity(0)); return true; } @@ -508,60 +510,67 @@ struct V0PtInvMassPlots { rPtAnalysis.fill(HIST("hNLambda"), 0.5); rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(1, "All"); rPtAnalysis.fill(HIST("hMassLambdavsCuts"), 0.5, v0.mLambda()); - if (std::abs(posDaughterTrack.tpcNSigmaPr()) > nSigmaTPCProton && std::abs(negDaughterTrack.tpcNSigmaPi()) > nSigmaTPCPion && doLambdaTPCPID) { // TPC PID on daughter pion and proton for Lambda + + if (doRapidityCut && std::abs(v0.rapidity(1)) > rapidityCut) { // V0 Rapidity Cut return false; } rPtAnalysis.fill(HIST("hNLambda"), 1.5); - rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(2, "TPC_PID"); + rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(2, "Rapidity"); rPtAnalysis.fill(HIST("hMassLambdavsCuts"), 1.5, v0.mLambda()); - if (std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short) < compv0masscut && doLambdacomptmasscut) { // Lambda competitive v0 mass cut (cut out Kaons) + if (doLambdaTPCPID && std::abs(posDaughterTrack.tpcNSigmaPr()) > nSigmaTPCProton && std::abs(negDaughterTrack.tpcNSigmaPi()) > nSigmaTPCPion) { // TPC PID on daughter pion and proton for Lambda return false; } rPtAnalysis.fill(HIST("hNLambda"), 2.5); - rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(3, "Compt_Mass"); + rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(3, "TPC_PID"); rPtAnalysis.fill(HIST("hMassLambdavsCuts"), 2.5, v0.mLambda()); - if (v0.v0radius() > lambdamaxct && doLambdaMaxct) { // Lambda max ct + if (doLambdacomptmasscut && std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short) < compv0masscut) { // Lambda competitive v0 mass cut (cut out Kaons) return false; } rPtAnalysis.fill(HIST("hNLambda"), 3.5); - rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(4, "Max_ct"); + rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(4, "Compt_Mass"); rPtAnalysis.fill(HIST("hMassLambdavsCuts"), 3.5, v0.mLambda()); - if (v0.qtarm() < (lambdaparamArmenterosCut * std::abs(v0.alpha())) && doLambdaArmenterosCut) { // Lambda Armenteros Cut + if (doLambdaMaxct && v0.v0radius() > lambdamaxct) { // Lambda max ct return false; } rPtAnalysis.fill(HIST("hNLambda"), 4.5); - rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(5, "Armenteros"); + rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(5, "Max_ct"); rPtAnalysis.fill(HIST("hMassLambdavsCuts"), 4.5, v0.mLambda()); - if (v0.v0cosPA() < lambdaSettingcosPA && doLambdacosPACut) { // Lambda cosPA Topological Cut + if (doLambdaArmenterosCut && v0.qtarm() < (lambdaparamArmenterosCut * std::abs(v0.alpha()))) { // Lambda Armenteros Cut return false; } rPtAnalysis.fill(HIST("hNLambda"), 5.5); - rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(6, "cosPA"); + rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(6, "Armenteros"); rPtAnalysis.fill(HIST("hMassLambdavsCuts"), 5.5, v0.mLambda()); - if (v0.dcaV0daughters() > lambdaSettingdcav0dau && doLambdaDCAdauCut) { // Lambda DCAdaughters Topological Cut + if (doLambdacosPACut && v0.v0cosPA() < lambdaSettingcosPA) { // Lambda cosPA Topological Cut return false; } rPtAnalysis.fill(HIST("hNLambda"), 6.5); - rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(7, "DCAdau"); + rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(7, "cosPA"); rPtAnalysis.fill(HIST("hMassLambdavsCuts"), 6.5, v0.mLambda()); - if (v0.v0radius() < lambdaSettingradius && doLambdav0radiusCut) { // Lambda v0radius Topological Cut + if (doLambdaDCAdauCut && v0.dcaV0daughters() > lambdaSettingdcav0dau) { // Lambda DCAdaughters Topological Cut return false; } rPtAnalysis.fill(HIST("hNLambda"), 7.5); - rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(8, "v0radius"); + rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(8, "DCAdau"); rPtAnalysis.fill(HIST("hMassLambdavsCuts"), 7.5, v0.mLambda()); - if (std::abs(v0.dcapostopv()) < lambdaSettingdcapostopv && doLambdadcaposdautopv) { // Lambda DCAPosDaughterToPV Topological Cut + if (doLambdav0radiusCut && v0.v0radius() < lambdaSettingradius) { // Lambda v0radius Topological Cut return false; } rPtAnalysis.fill(HIST("hNLambda"), 8.5); - rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(9, "DCAPosDautoPV"); + rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(9, "v0radius"); rPtAnalysis.fill(HIST("hMassLambdavsCuts"), 8.5, v0.mLambda()); - if (std::abs(v0.dcanegtopv()) < lambdaSettingdcanegtopv && doLambdadcanegdautopv) { // Lambda DCANegDaughterToPV Topological Cut + if (doLambdadcaposdautopv && std::abs(v0.dcapostopv()) < lambdaSettingdcapostopv) { // Lambda DCAPosDaughterToPV Topological Cut return false; } rPtAnalysis.fill(HIST("hNLambda"), 9.5); - rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(10, "DCANegDautoPV"); + rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(10, "DCAPosDautoPV"); rPtAnalysis.fill(HIST("hMassLambdavsCuts"), 9.5, v0.mLambda()); + if (doLambdadcanegdautopv && std::abs(v0.dcanegtopv()) < lambdaSettingdcanegtopv) { // Lambda DCANegDaughterToPV Topological Cut + return false; + } + rPtAnalysis.fill(HIST("hNLambda"), 10.5); + rPtAnalysis.get(HIST("hNLambda"))->GetXaxis()->SetBinLabel(11, "DCANegDautoPV"); + rPtAnalysis.fill(HIST("hMassLambdavsCuts"), 10.5, v0.mLambda()); // Cut Plots rPtAnalysis.fill(HIST("hArmenterosPodolanskiPlotLambda"), v0.alpha(), v0.qtarm()); @@ -572,6 +581,7 @@ struct V0PtInvMassPlots { rPtAnalysis.fill(HIST("hLambdaDCAV0Daughters"), v0.dcaV0daughters()); rPtAnalysis.fill(HIST("hLambdaDCAPosDaughter"), v0.dcapostopv()); rPtAnalysis.fill(HIST("hLambdaDCANegDaughter"), v0.dcanegtopv()); + rPtAnalysis.fill(HIST("V0Rapidity"), v0.rapidity(1)); return true; } @@ -585,60 +595,67 @@ struct V0PtInvMassPlots { rPtAnalysis.fill(HIST("hNAntilambda"), 0.5); rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(1, "All"); rPtAnalysis.fill(HIST("hMassAntilambdavsCuts"), 0.5, v0.mAntiLambda()); - if (std::abs(negDaughterTrack.tpcNSigmaPr()) > nSigmaTPCProton && std::abs(posDaughterTrack.tpcNSigmaPi()) > nSigmaTPCPion) { // TPC PID on daughter pion and proton for AntiLambda + + if (doRapidityCut && std::abs(v0.rapidity(2)) > rapidityCut) { // V0 Rapidity Cut return false; } rPtAnalysis.fill(HIST("hNAntilambda"), 1.5); - rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(2, "TPC_PID"); + rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(2, "Rapidity"); rPtAnalysis.fill(HIST("hMassAntilambdavsCuts"), 1.5, v0.mAntiLambda()); - if (std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short) < compv0masscut && doAntilambdacomptmasscut) { // Antilambda competitive v0 mass cut (cut out Kaons) + if (doAntilambdaTPCPID && std::abs(negDaughterTrack.tpcNSigmaPr()) > nSigmaTPCProton && std::abs(posDaughterTrack.tpcNSigmaPi()) > nSigmaTPCPion) { // TPC PID on daughter pion and proton for AntiLambda return false; } rPtAnalysis.fill(HIST("hNAntilambda"), 2.5); - rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(3, "Compt_Mass"); + rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(3, "TPC_PID"); rPtAnalysis.fill(HIST("hMassAntilambdavsCuts"), 2.5, v0.mAntiLambda()); - if (v0.v0radius() > antilambdamaxct && doAntilambdaMaxct) { // Antilambda max ct + if (doAntilambdacomptmasscut && std::abs(v0.mK0Short() - o2::constants::physics::MassK0Short) < compv0masscut) { // Antilambda competitive v0 mass cut (cut out Kaons) return false; } rPtAnalysis.fill(HIST("hNAntilambda"), 3.5); - rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(4, "Max_ct"); + rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(4, "Compt_Mass"); rPtAnalysis.fill(HIST("hMassAntilambdavsCuts"), 3.5, v0.mAntiLambda()); - if (v0.qtarm() < (antilambdaparamArmenterosCut * std::abs(v0.alpha())) && doAntilambdaArmenterosCut) { // Antilambda Armenteros Cut + if (doAntilambdaMaxct && v0.v0radius() > antilambdamaxct) { // Antilambda max ct return false; } rPtAnalysis.fill(HIST("hNAntilambda"), 4.5); - rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(5, "Armenteros"); + rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(5, "Max_ct"); rPtAnalysis.fill(HIST("hMassAntilambdavsCuts"), 4.5, v0.mAntiLambda()); - if (v0.v0cosPA() < antilambdaSettingcosPA && doAntilambdacosPACut) { // Antilambda cosPA Topological Cut + if (doAntilambdaArmenterosCut && v0.qtarm() < (antilambdaparamArmenterosCut * std::abs(v0.alpha()))) { // Antilambda Armenteros Cut return false; } rPtAnalysis.fill(HIST("hNAntilambda"), 5.5); - rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(6, "cosPA"); + rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(6, "Armenteros"); rPtAnalysis.fill(HIST("hMassAntilambdavsCuts"), 5.5, v0.mAntiLambda()); - if (v0.dcaV0daughters() > antilambdaSettingdcav0dau && doAntilambdaDCAdauCut) { // Antilambda DCAdaughters Topological Cut + if (doAntilambdacosPACut && v0.v0cosPA() < antilambdaSettingcosPA) { // Antilambda cosPA Topological Cut return false; } rPtAnalysis.fill(HIST("hNAntilambda"), 6.5); - rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(7, "DCAdau"); + rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(7, "cosPA"); rPtAnalysis.fill(HIST("hMassAntilambdavsCuts"), 6.5, v0.mAntiLambda()); - if (v0.v0radius() < antilambdaSettingradius && doAntilambdav0radiusCut) { // Antilambda v0radius Topological Cut + if (doAntilambdaDCAdauCut && v0.dcaV0daughters() > antilambdaSettingdcav0dau) { // Antilambda DCAdaughters Topological Cut return false; } rPtAnalysis.fill(HIST("hNAntilambda"), 7.5); - rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(8, "v0radius"); + rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(8, "DCAdau"); rPtAnalysis.fill(HIST("hMassAntilambdavsCuts"), 7.5, v0.mAntiLambda()); - if (std::abs(v0.dcapostopv()) < antilambdaSettingdcapostopv && doAntilambdadcaposdautopv) { // Antilambda DCAPosDaughterToPV Topological Cut + if (doAntilambdav0radiusCut && v0.v0radius() < antilambdaSettingradius) { // Antilambda v0radius Topological Cut return false; } rPtAnalysis.fill(HIST("hNAntilambda"), 8.5); - rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(9, "DCAPosDautoPV"); + rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(9, "v0radius"); rPtAnalysis.fill(HIST("hMassAntilambdavsCuts"), 8.5, v0.mAntiLambda()); - if (std::abs(v0.dcanegtopv()) < antilambdaSettingdcanegtopv && doAntilambdadcanegdautopv) { // Antilambda DCANegDaughterToPV Topological Cut + if (doAntilambdadcaposdautopv && std::abs(v0.dcapostopv()) < antilambdaSettingdcapostopv) { // Antilambda DCAPosDaughterToPV Topological Cut return false; } rPtAnalysis.fill(HIST("hNAntilambda"), 9.5); - rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(10, "DCANegDautoPV"); + rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(10, "DCAPosDautoPV"); rPtAnalysis.fill(HIST("hMassAntilambdavsCuts"), 9.5, v0.mAntiLambda()); + if (doAntilambdadcanegdautopv && std::abs(v0.dcanegtopv()) < antilambdaSettingdcanegtopv) { // Antilambda DCANegDaughterToPV Topological Cut + return false; + } + rPtAnalysis.fill(HIST("hNAntilambda"), 10.5); + rPtAnalysis.get(HIST("hNAntilambda"))->GetXaxis()->SetBinLabel(11, "DCANegDautoPV"); + rPtAnalysis.fill(HIST("hMassAntilambdavsCuts"), 10.5, v0.mAntiLambda()); // Cut plots rPtAnalysis.fill(HIST("hArmenterosPodolanskiPlotAntilambda"), v0.alpha(), v0.qtarm()); @@ -649,6 +666,7 @@ struct V0PtInvMassPlots { rPtAnalysis.fill(HIST("hAntilambdaDCAV0Daughters"), v0.dcaV0daughters()); rPtAnalysis.fill(HIST("hAntilambdaDCAPosDaughter"), v0.dcapostopv()); rPtAnalysis.fill(HIST("hAntilambdaDCANegDaughter"), v0.dcanegtopv()); + rPtAnalysis.fill(HIST("V0Rapidity"), v0.rapidity(2)); return true; } @@ -745,7 +763,7 @@ struct V0PtInvMassPlots { void recMCProcess(soa::Join::iterator const& collision, soa::Join const& V0s, DaughterTracks const&, // no need to define a variable for tracks, if we don't access them directly - aod::McParticles const& mcParticles) + aod::McParticles const& /*mcParticles*/) { // tokenise strings into individual values pthistos::kaonPtBins = o2::utils::Str::tokenize(kzeroSettingPtBinsString, ','); @@ -767,43 +785,11 @@ struct V0PtInvMassPlots { } rMCCorrections.fill(HIST("hNRecEvents_MC"), 0.5); // Event Split Numenator - // v0 Signal Splitting Numenator Start - for (const auto& mcParticle : mcParticles) { - if (mcParticle.isPhysicalPrimary()) { - if (std::abs(mcParticle.y()) < rapidityCut) { - if (mcParticle.pdgCode() == kK0Short) { // kzero matched - rMCCorrections.fill(HIST("hK0ShSplitNumenatorPtSpectrum"), mcParticle.pt()); - } - if (mcParticle.pdgCode() == kLambda0) { // lambda matched - rMCCorrections.fill(HIST("hLambdaSplitNumenatorPtSpectrum"), mcParticle.pt()); - } - if (mcParticle.pdgCode() == kLambda0Bar) { // antilambda matched - rMCCorrections.fill(HIST("hAntilambdaSplitNumenatorPtSpectrum"), mcParticle.pt()); - } - } - } - } - // V0 Signal Splitting Numenator End - for (const auto& v0 : V0s) { // Checking that the V0 is a true K0s/Lambdas/Antilambdas and then filling the parameter histograms and the invariant mass plots for different cuts (which are taken from namespace) if (v0.has_mcParticle()) { auto v0mcParticle = v0.mcParticle(); - // signal splitting demoninator - if (v0mcParticle.isPhysicalPrimary()) { - if (v0mcParticle.pdgCode() == kK0Short) { // kzero matched - rMCCorrections.fill(HIST("hK0ShSplitDenominatorPtSpectrum"), v0mcParticle.pt()); - } - if (v0mcParticle.pdgCode() == kLambda0) { // lambda matched - rMCCorrections.fill(HIST("hLambdaSplitDenominatorPtSpectrum"), v0mcParticle.pt()); - } - if (v0mcParticle.pdgCode() == kLambda0Bar) { // antilambda matched - rMCCorrections.fill(HIST("hAntilambdaSplitDenominatorPtSpectrum"), v0mcParticle.pt()); - } - } - // signal splitting demoninator end - if (!acceptV0(v0)) { // V0 Selections continue; } diff --git a/PWGLF/Utils/decay3bodyBuilderHelper.h b/PWGLF/Utils/decay3bodyBuilderHelper.h index 1343bd61552..49131c16040 100644 --- a/PWGLF/Utils/decay3bodyBuilderHelper.h +++ b/PWGLF/Utils/decay3bodyBuilderHelper.h @@ -74,15 +74,11 @@ struct decay3bodyCandidate { int sign; float momentum[3]; float position[3]; - // std::array momentum = {0.0f, 0.0f, 0.0f}; - // std::array position = {0.0f, 0.0f, 0.0f}; - // float dcaToPV = 0.0f; - // float dcaxyToPV = 0.0f; float chi2 = 0.0f; float trackedClSize = 0.0f; float cosPA = 0.0f; // cosine of pointing angle float ctau = 0.0f; // ctau of the candidate - float daughterDCAatSV = 0.0f; // quadratic sum of DCA between daughters at SV + float daughterDCAtoSVaverage = 0.0f; // average of quadratic sum of daughter DCAs to SV std::array daughterDCAtoSV = {0.0f, 0.0f, 0.0f}; // 0 - pos, 1 - neg, 2 - bach // covariance matrix @@ -148,7 +144,7 @@ class decay3bodyBuilderHelper double minTOFnSigmaDeuteron; double maxTOFnSigmaDeuteron; float minPDeuteronUseTOF; - float maxDCADauAtSV; + float maxDCADauToSVaverage; // candidate float maxRapidity; float minPt; @@ -188,6 +184,7 @@ class decay3bodyBuilderHelper bool useKFParticle = false, bool kfSetTopologicalConstraint = false, bool useSelections = true, + bool useChi2Selection = true, bool useTPCforPion = false, bool acceptTPCOnly = false, bool askOnlyITSMatch = true, @@ -342,18 +339,6 @@ class decay3bodyBuilderHelper auto trackPionPt = std::sqrt(decay3body.momPion[0] * decay3body.momPion[0] + decay3body.momPion[1] * decay3body.momPion[1]); auto trackDeuteronPt = std::sqrt(decay3body.momDeuteron[0] * decay3body.momDeuteron[0] + decay3body.momDeuteron[1] * decay3body.momDeuteron[1]); - // DCA between daughters at SV - decay3body.daughterDCAatSV = std::hypot( - std::hypot(decay3body.posProton[0] - decay3body.posPion[0], - decay3body.posProton[1] - decay3body.posPion[1], - decay3body.posProton[2] - decay3body.posPion[2]), - std::hypot(decay3body.posProton[0] - decay3body.posDeuteron[0], - decay3body.posProton[1] - decay3body.posDeuteron[1], - decay3body.posProton[2] - decay3body.posDeuteron[2]), - std::hypot(decay3body.posPion[0] - decay3body.posProton[0], - decay3body.posPion[1] - decay3body.posProton[1], - decay3body.posPion[2] - decay3body.posProton[2])); - // daughter DCA to SV // proton daughter decay3body.daughterDCAtoSV[0] = std::hypot( @@ -371,6 +356,12 @@ class decay3bodyBuilderHelper decay3body.posDeuteron[1] - decay3body.position[1], decay3body.posDeuteron[2] - decay3body.position[2]); + // DCA daughters to SV average of quadratic sum + decay3body.daughterDCAtoSVaverage = (decay3body.daughterDCAtoSV[0] * decay3body.daughterDCAtoSV[0] + + decay3body.daughterDCAtoSV[1] * decay3body.daughterDCAtoSV[1] + + decay3body.daughterDCAtoSV[2] * decay3body.daughterDCAtoSV[2]) / + 3; + //_____________________________________________________ // selections after vertex fit if (useSelections) { @@ -392,7 +383,7 @@ class decay3bodyBuilderHelper } // daughter DCAs at SV - if (decay3body.daughterDCAatSV > decay3bodyselections.maxDCADauAtSV) { + if (decay3body.daughterDCAtoSVaverage > decay3bodyselections.maxDCADauToSVaverage) { decay3body = {}; return false; } @@ -418,7 +409,7 @@ class decay3bodyBuilderHelper } // vertex chi2 - if (decay3body.chi2 > decay3bodyselections.maxChi2) { + if (useChi2Selection && decay3body.chi2 > decay3bodyselections.maxChi2) { decay3body = {}; return false; } diff --git a/PWGLF/Utils/pidTOFGeneric.h b/PWGLF/Utils/pidTOFGeneric.h new file mode 100644 index 00000000000..3e7dfd58c23 --- /dev/null +++ b/PWGLF/Utils/pidTOFGeneric.h @@ -0,0 +1,496 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// +/// \file pidTOFGeneric.h +/// \brief Utilities to recalculate secondary tracks TOF PID +/// \author Yuanzhe Wang +/// + +#ifndef PWGLF_UTILS_PIDTOFGENERIC_H_ +#define PWGLF_UTILS_PIDTOFGENERIC_H_ +#include "CollisionTypeHelper.h" +#include "MetadataHelper.h" +#include "TableHelper.h" + +#include "Common/Core/PID/PIDTOF.h" + +#include "CommonDataFormat/InteractionRecord.h" + +#include +#include + +namespace o2::aod +{ + +namespace pidtofgeneric +{ + +// Configuration common to all tasks, copied from pidTOFMerge.cxx but add metadataInfo as a member variable +struct TOFCalibConfig { + template + void init(const CfgType& opt) + { + mUrl = opt.cfgUrl.value; + mPathGrpLhcIf = opt.cfgPathGrpLhcIf.value; + mTimestamp = opt.cfgTimestamp.value; + mTimeShiftCCDBPathPos = opt.cfgTimeShiftCCDBPathPos.value; + mTimeShiftCCDBPathNeg = opt.cfgTimeShiftCCDBPathNeg.value; + mTimeShiftCCDBPathPosMC = opt.cfgTimeShiftCCDBPathPosMC.value; + mTimeShiftCCDBPathNegMC = opt.cfgTimeShiftCCDBPathNegMC.value; + mParamFileName = opt.cfgParamFileName.value; + mParametrizationPath = opt.cfgParametrizationPath.value; + mReconstructionPass = opt.cfgReconstructionPass.value; + mReconstructionPassDefault = opt.cfgReconstructionPassDefault.value; + mFatalOnPassNotAvailable = opt.cfgFatalOnPassNotAvailable.value; + mEnableTimeDependentResponse = opt.cfgEnableTimeDependentResponse.value; + mCollisionSystem = opt.cfgCollisionSystem.value; + mAutoSetProcessFunctions = opt.cfgAutoSetProcessFunctions.value; + } + + template + void getCfg(o2::framework::InitContext& initContext, const std::string name, VType& v, const std::string task) + { + if (!getTaskOptionValue(initContext, task, name, v, false)) { + LOG(fatal) << "Could not get " << name << " from " << task << " task"; + } + } + + void inheritFromBaseTask(o2::framework::InitContext& initContext, const std::string task = "tof-signal") + { + mInitMode = 2; + getCfg(initContext, "ccdb-url", mUrl, task); + getCfg(initContext, "ccdb-path-grplhcif", mPathGrpLhcIf, task); + getCfg(initContext, "ccdb-timestamp", mTimestamp, task); + getCfg(initContext, "timeShiftCCDBPathPos", mTimeShiftCCDBPathPos, task); + getCfg(initContext, "timeShiftCCDBPathNeg", mTimeShiftCCDBPathNeg, task); + getCfg(initContext, "timeShiftCCDBPathPosMC", mTimeShiftCCDBPathPosMC, task); + getCfg(initContext, "timeShiftCCDBPathNegMC", mTimeShiftCCDBPathNegMC, task); + getCfg(initContext, "paramFileName", mParamFileName, task); + getCfg(initContext, "parametrizationPath", mParametrizationPath, task); + getCfg(initContext, "reconstructionPass", mReconstructionPass, task); + getCfg(initContext, "reconstructionPassDefault", mReconstructionPassDefault, task); + getCfg(initContext, "fatalOnPassNotAvailable", mFatalOnPassNotAvailable, task); + getCfg(initContext, "enableTimeDependentResponse", mEnableTimeDependentResponse, task); + getCfg(initContext, "collisionSystem", mCollisionSystem, task); + getCfg(initContext, "autoSetProcessFunctions", mAutoSetProcessFunctions, task); + } + // @brief Set up the configuration from the calibration object from the init function of the task + template + void initSetup(o2::pid::tof::TOFResoParamsV3& mRespParamsV3, + CCDBObject ccdb) + { + mInitMode = 1; + // First we set the CCDB manager + ccdb->setURL(mUrl); + ccdb->setTimestamp(mTimestamp); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + // Not later than now objects + ccdb->setCreatedNotAfter(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + + // Then the information about the metadata + if (mReconstructionPass == "metadata") { + LOG(info) << "Getting pass from metadata"; + if (metadataInfo.isMC()) { + mReconstructionPass = metadataInfo.get("AnchorPassName"); + } else { + mReconstructionPass = metadataInfo.get("RecoPassName"); + } + LOG(info) << "Passed autodetect mode for pass. Taking '" << mReconstructionPass << "'"; + } + LOG(info) << "Using parameter collection, starting from pass '" << mReconstructionPass << "'"; + + if (!mParamFileName.empty()) { // Loading the parametrization from file + LOG(info) << "Loading exp. sigma parametrization from file " << mParamFileName << ", using param: " << mParametrizationPath << " and pass " << mReconstructionPass; + o2::tof::ParameterCollection paramCollection; + paramCollection.loadParamFromFile(mParamFileName, mParametrizationPath); + LOG(info) << "+++ Loaded parameter collection from file +++"; + if (!paramCollection.retrieveParameters(mRespParamsV3, mReconstructionPass)) { + if (mFatalOnPassNotAvailable) { + LOG(fatal) << "Pass '" << mReconstructionPass << "' not available in the retrieved object from file"; + } else { + LOG(warning) << "Pass '" << mReconstructionPass << "' not available in the retrieved object from file, fetching '" << mReconstructionPassDefault << "'"; + if (!paramCollection.retrieveParameters(mRespParamsV3, mReconstructionPassDefault)) { + paramCollection.print(); + LOG(fatal) << "Cannot get default pass for calibration " << mReconstructionPassDefault; + } else { + if (metadataInfo.isRun3()) { + mRespParamsV3.setResolutionParametrization(paramCollection.getPars(mReconstructionPassDefault)); + } else { + mRespParamsV3.setResolutionParametrizationRun2(paramCollection.getPars(mReconstructionPassDefault)); + } + mRespParamsV3.setMomentumChargeShiftParameters(paramCollection.getPars(mReconstructionPassDefault)); + } + } + } else { // Pass is available, load non standard parameters + if (metadataInfo.isRun3()) { + mRespParamsV3.setResolutionParametrization(paramCollection.getPars(mReconstructionPass)); + } else { + mRespParamsV3.setResolutionParametrizationRun2(paramCollection.getPars(mReconstructionPass)); + } + mRespParamsV3.setMomentumChargeShiftParameters(paramCollection.getPars(mReconstructionPass)); + } + } else if (!mEnableTimeDependentResponse) { // Loading it from CCDB + LOG(info) << "Loading initial exp. sigma parametrization from CCDB, using path: " << mParametrizationPath << " for timestamp " << mTimestamp; + o2::tof::ParameterCollection* paramCollection = ccdb->template getSpecific(mParametrizationPath, mTimestamp); + if (!paramCollection->retrieveParameters(mRespParamsV3, mReconstructionPass)) { // Attempt at loading the parameters with the pass defined + if (mFatalOnPassNotAvailable) { + LOG(fatal) << "Pass '" << mReconstructionPass << "' not available in the retrieved CCDB object"; + } else { + LOG(warning) << "Pass '" << mReconstructionPass << "' not available in the retrieved CCDB object, fetching '" << mReconstructionPassDefault << "'"; + if (!paramCollection->retrieveParameters(mRespParamsV3, mReconstructionPassDefault)) { + paramCollection->print(); + LOG(fatal) << "Cannot get default pass for calibration " << mReconstructionPassDefault; + } else { + if (metadataInfo.isRun3()) { + mRespParamsV3.setResolutionParametrization(paramCollection->getPars(mReconstructionPassDefault)); + } else { + mRespParamsV3.setResolutionParametrizationRun2(paramCollection->getPars(mReconstructionPassDefault)); + } + mRespParamsV3.setMomentumChargeShiftParameters(paramCollection->getPars(mReconstructionPassDefault)); + } + } + } else { // Pass is available, load non standard parameters + if (metadataInfo.isRun3()) { + mRespParamsV3.setResolutionParametrization(paramCollection->getPars(mReconstructionPass)); + } else { + mRespParamsV3.setResolutionParametrizationRun2(paramCollection->getPars(mReconstructionPass)); + } + mRespParamsV3.setMomentumChargeShiftParameters(paramCollection->getPars(mReconstructionPass)); + } + } + + // Loading additional calibration objects + std::map metadata; + if (!mReconstructionPass.empty()) { + metadata["RecoPassName"] = mReconstructionPass; + } + + auto updateTimeShift = [&](const std::string& nameShift, bool isPositive) { + if (nameShift.empty()) { + return; + } + const bool isFromFile = nameShift.find(".root") != std::string::npos; + if (isFromFile) { + LOG(info) << "Initializing the time shift for " << (isPositive ? "positive" : "negative") << " from file '" << nameShift << "'"; + mRespParamsV3.setTimeShiftParameters(nameShift, "ccdb_object", isPositive); + } else if (!mEnableTimeDependentResponse) { // If the response is fixed fetch it at the init time + LOG(info) << "Initializing the time shift for " << (isPositive ? "positive" : "negative") + << " from ccdb '" << nameShift << "' and timestamp " << mTimestamp + << " and pass '" << mReconstructionPass << "'"; + ccdb->setFatalWhenNull(false); + mRespParamsV3.setTimeShiftParameters(ccdb->template getSpecific(nameShift, mTimestamp, metadata), isPositive); + ccdb->setFatalWhenNull(true); + } + LOG(info) << " test getTimeShift at 0 " << (isPositive ? "pos" : "neg") << ": " + << mRespParamsV3.getTimeShift(0, isPositive); + }; + + const std::string nameShiftPos = metadataInfo.isMC() ? mTimeShiftCCDBPathPosMC : mTimeShiftCCDBPathPos; + updateTimeShift(nameShiftPos, true); + const std::string nameShiftNeg = metadataInfo.isMC() ? mTimeShiftCCDBPathNegMC : mTimeShiftCCDBPathNeg; + updateTimeShift(nameShiftNeg, false); + + // Calibration object is defined + LOG(info) << "Parametrization at init time:"; + mRespParamsV3.printFullConfig(); + } + + template + void processSetup(o2::pid::tof::TOFResoParamsV3& mRespParamsV3, + CCDBObject ccdb, + const BcType& bc) + { + LOG(debug) << "Processing setup for run number " << bc.runNumber() << " from run " << mLastRunNumber; + // First we check if this run number was already processed + if (mLastRunNumber == bc.runNumber()) { + return; + } + LOG(info) << "Updating the parametrization from last run " << mLastRunNumber << " to " << bc.runNumber() << " and timestamp from " << mTimestamp << " " << bc.timestamp(); + mLastRunNumber = bc.runNumber(); + mTimestamp = bc.timestamp(); + + // Check the beam type + if (mCollisionSystem == -1) { + o2::parameters::GRPLHCIFData* grpo = ccdb->template getSpecific(mPathGrpLhcIf, + mTimestamp); + mCollisionSystem = CollisionSystemType::getCollisionTypeFromGrp(grpo); + } else { + LOG(debug) << "Not setting collisions system as already set to " << mCollisionSystem << " " << CollisionSystemType::getCollisionSystemName(mCollisionSystem); + } + + if (!mEnableTimeDependentResponse) { + return; + } + LOG(info) << "Updating parametrization from path '" << mParametrizationPath << "' and timestamp " << mTimestamp << " and reconstruction pass '" << mReconstructionPass << "' for run number " << bc.runNumber(); + if (mParamFileName.empty()) { // Not loading if parametrization was taken from file + LOG(info) << "Updating parametrization from ccdb"; + const o2::tof::ParameterCollection* paramCollection = ccdb->template getSpecific(mParametrizationPath, mTimestamp); + if (!paramCollection->retrieveParameters(mRespParamsV3, mReconstructionPass)) { + if (mFatalOnPassNotAvailable) { + LOGF(fatal, "Pass '%s' not available in the retrieved CCDB object", mReconstructionPass.data()); + } else { + LOGF(warning, "Pass '%s' not available in the retrieved CCDB object, fetching '%s'", mReconstructionPass.data(), mReconstructionPassDefault.data()); + if (!paramCollection->retrieveParameters(mRespParamsV3, mReconstructionPassDefault)) { + paramCollection->print(); + LOG(fatal) << "Cannot get default pass for calibration " << mReconstructionPassDefault; + } else { // Found the default case + if (metadataInfo.isRun3()) { + mRespParamsV3.setResolutionParametrization(paramCollection->getPars(mReconstructionPassDefault)); + } else { + mRespParamsV3.setResolutionParametrizationRun2(paramCollection->getPars(mReconstructionPassDefault)); + } + mRespParamsV3.setMomentumChargeShiftParameters(paramCollection->getPars(mReconstructionPassDefault)); + } + } + } else { // Found the non default case + if (metadataInfo.isRun3()) { + mRespParamsV3.setResolutionParametrization(paramCollection->getPars(mReconstructionPass)); + } else { + mRespParamsV3.setResolutionParametrizationRun2(paramCollection->getPars(mReconstructionPass)); + } + mRespParamsV3.setMomentumChargeShiftParameters(paramCollection->getPars(mReconstructionPass)); + } + } + + // Loading additional calibration objects + std::map metadata; + if (!mReconstructionPass.empty()) { + metadata["RecoPassName"] = mReconstructionPass; + } + + auto updateTimeShift = [&](const std::string& nameShift, bool isPositive) { + if (nameShift.empty()) { + return; + } + const bool isFromFile = nameShift.find(".root") != std::string::npos; + if (isFromFile) { + return; + } + LOG(info) << "Updating the time shift for " << (isPositive ? "positive" : "negative") + << " from ccdb '" << nameShift << "' and timestamp " << mTimestamp + << " and pass '" << mReconstructionPass << "'"; + ccdb->setFatalWhenNull(false); + mRespParamsV3.setTimeShiftParameters(ccdb->template getSpecific(nameShift, mTimestamp, metadata), isPositive); + ccdb->setFatalWhenNull(true); + LOG(info) << " test getTimeShift at 0 " << (isPositive ? "pos" : "neg") << ": " + << mRespParamsV3.getTimeShift(0, isPositive); + }; + + updateTimeShift(metadataInfo.isMC() ? mTimeShiftCCDBPathPosMC : mTimeShiftCCDBPathPos, true); + updateTimeShift(metadataInfo.isMC() ? mTimeShiftCCDBPathNegMC : mTimeShiftCCDBPathNeg, false); + + LOG(info) << "Parametrization at setup time:"; + mRespParamsV3.printFullConfig(); + } + + bool autoSetProcessFunctions() const { return mAutoSetProcessFunctions; } + int collisionSystem() const { return mCollisionSystem; } + + o2::common::core::MetadataHelper metadataInfo; // additional member variable to store metadata information compared to pidTOFMerge.cxx + + private: + int mLastRunNumber = -1; // Last run number for which the calibration was loaded + int mInitMode = 0; // 0: no init, 1: init, 2: inherit + + // Configurable options + std::string mUrl; + std::string mPathGrpLhcIf; + int64_t mTimestamp; + std::string mTimeShiftCCDBPathPos; + std::string mTimeShiftCCDBPathNeg; + std::string mTimeShiftCCDBPathPosMC; + std::string mTimeShiftCCDBPathNegMC; + std::string mParamFileName; + std::string mParametrizationPath; + std::string mReconstructionPass; + std::string mReconstructionPassDefault; + bool mFatalOnPassNotAvailable; + bool mEnableTimeDependentResponse; + int mCollisionSystem; + bool mAutoSetProcessFunctions; +}; + +static constexpr float kCSPEED = TMath::C() * 1.0e2f * 1.0e-12f; // c in cm/ps + +template +class TofPidNewCollision +{ + public: + TofPidNewCollision() = default; + ~TofPidNewCollision() = default; + + o2::pid::tof::TOFResoParamsV3 mRespParamsV3; + o2::track::PID::ID pidType; + + template + using ResponseImplementation = o2::pid::tof::ExpTimes; + static constexpr auto responseEl = ResponseImplementation(); + static constexpr auto responseMu = ResponseImplementation(); + static constexpr auto responsePi = ResponseImplementation(); + static constexpr auto responseKa = ResponseImplementation(); + static constexpr auto responsePr = ResponseImplementation(); + static constexpr auto responseDe = ResponseImplementation(); + static constexpr auto responseTr = ResponseImplementation(); + static constexpr auto responseHe = ResponseImplementation(); + static constexpr auto responseAl = ResponseImplementation(); + + void SetParams(o2::pid::tof::TOFResoParamsV3 const& para) + { + mRespParamsV3.setParameters(para); + } + + void SetPidType(o2::track::PID::ID pidId) + { + pidType = pidId; + } + + template + float GetTOFNSigma(o2::track::PID::ID pidId, const ParamType& parameters, TTrack const& track, TCollision const& originalcol, TCollision const& correctedcol, bool EnableBCAO2D = true); + + template + float GetTOFNSigma(const ParamType& parameters, TTrack const& track, TCollision const& originalcol, TCollision const& correctedcol, bool EnableBCAO2D = true); + + template + float GetTOFNSigma(const ParamType& parameters, TTrack const& track); + template + float GetTOFNSigma(o2::track::PID::ID pidId, const ParamType& parameters, TTrack const& track); + + template + float CalculateTOFNSigma(o2::track::PID::ID pidId, const ParamType& parameters, TTrack const& track, double tofsignal, double evTime, double evTimeErr) + { + + float expSigma, tofNsigma = -999; + + switch (pidId) { + case 0: + expSigma = responseEl.GetExpectedSigma(parameters, track, tofsignal, evTimeErr); + tofNsigma = (tofsignal - evTime - responseEl.GetCorrectedExpectedSignal(parameters, track)) / expSigma; + break; + case 1: + expSigma = responseMu.GetExpectedSigma(parameters, track, tofsignal, evTimeErr); + tofNsigma = (tofsignal - evTime - responseMu.GetCorrectedExpectedSignal(parameters, track)) / expSigma; + break; + case 2: + expSigma = responsePi.GetExpectedSigma(parameters, track, tofsignal, evTimeErr); + tofNsigma = (tofsignal - evTime - responsePi.GetCorrectedExpectedSignal(parameters, track)) / expSigma; + break; + case 3: + expSigma = responseKa.GetExpectedSigma(parameters, track, tofsignal, evTimeErr); + tofNsigma = (tofsignal - evTime - responseKa.GetCorrectedExpectedSignal(parameters, track)) / expSigma; + break; + case 4: + expSigma = responsePr.GetExpectedSigma(parameters, track, tofsignal, evTimeErr); + tofNsigma = (tofsignal - evTime - responsePr.GetCorrectedExpectedSignal(parameters, track)) / expSigma; + break; + case 5: + expSigma = responseDe.GetExpectedSigma(parameters, track, tofsignal, evTimeErr); + tofNsigma = (tofsignal - evTime - responseDe.GetCorrectedExpectedSignal(parameters, track)) / expSigma; + break; + case 6: + expSigma = responseTr.GetExpectedSigma(parameters, track, tofsignal, evTimeErr); + tofNsigma = (tofsignal - evTime - responseTr.GetCorrectedExpectedSignal(parameters, track)) / expSigma; + break; + case 7: + expSigma = responseHe.GetExpectedSigma(parameters, track, tofsignal, evTimeErr); + tofNsigma = (tofsignal - evTime - responseHe.GetCorrectedExpectedSignal(parameters, track)) / expSigma; + break; + case 8: + expSigma = responseAl.GetExpectedSigma(parameters, track, tofsignal, evTimeErr); + tofNsigma = (tofsignal - evTime - responseAl.GetCorrectedExpectedSignal(parameters, track)) / expSigma; + break; + default: + LOG(fatal) << "Wrong particle ID in TofPidSecondary class"; + return -999; + } + + return tofNsigma; + } +}; + +template +template +float TofPidNewCollision::GetTOFNSigma(o2::track::PID::ID pidId, const ParamType& parameters, TTrack const& track, TCollision const& originalcol, TCollision const& correctedcol, bool EnableBCAO2D) +{ + + if (!track.has_collision() || !track.hasTOF()) { + return -999; + } + + float mMassHyp = o2::track::pid_constants::sMasses2Z[track.pidForTracking()]; + float expTime = track.length() * std::sqrt((mMassHyp * mMassHyp) + (track.tofExpMom() * track.tofExpMom())) / (kCSPEED * track.tofExpMom()); // L*E/(p*c) = L/v + + float evTime = correctedcol.evTime(); + float evTimeErr = correctedcol.evTimeErr(); + float tofsignal = track.trackTime() * 1000 + expTime; // in ps + + if (originalcol.globalIndex() == correctedcol.globalIndex()) { + evTime = track.evTimeForTrack(); + evTimeErr = track.evTimeErrForTrack(); + } else { + if (EnableBCAO2D) { + auto originalbc = originalcol.template bc_as(); + auto correctedbc = correctedcol.template bc_as(); + o2::InteractionRecord originalIR = o2::InteractionRecord::long2IR(originalbc.globalBC()); + o2::InteractionRecord correctedIR = o2::InteractionRecord::long2IR(correctedbc.globalBC()); + tofsignal += originalIR.differenceInBCNS(correctedIR) * 1000; + } else { + auto originalbc = originalcol.template foundBC_as(); + auto correctedbc = correctedcol.template foundBC_as(); + o2::InteractionRecord originalIR = o2::InteractionRecord::long2IR(originalbc.globalBC()); + o2::InteractionRecord correctedIR = o2::InteractionRecord::long2IR(correctedbc.globalBC()); + tofsignal += originalIR.differenceInBCNS(correctedIR) * 1000; + } + } + + float tofNsigma = CalculateTOFNSigma(pidId, parameters, track, tofsignal, evTime, evTimeErr); + return tofNsigma; +} + +template +template +float TofPidNewCollision::GetTOFNSigma(const ParamType& parameters, TTrack const& track, TCollision const& originalcol, TCollision const& correctedcol, bool EnableBCAO2D) +{ + return GetTOFNSigma(pidType, parameters, track, originalcol, correctedcol, EnableBCAO2D); +} + +template +template +float TofPidNewCollision::GetTOFNSigma(o2::track::PID::ID pidId, const ParamType& parameters, TTrack const& track) +{ + + if (!track.has_collision() || !track.hasTOF()) { + return -999; + } + + float mMassHyp = o2::track::pid_constants::sMasses2Z[track.pidForTracking()]; + float expTime = track.length() * std::sqrt((mMassHyp * mMassHyp) + (track.tofExpMom() * track.tofExpMom())) / (kCSPEED * track.tofExpMom()); // L*E/(p*c) = L/v + + float evTime = track.evTimeForTrack(); + float evTimeErr = track.evTimeErrForTrack(); + float tofsignal = track.trackTime() * 1000 + expTime; // in ps + + float tofNsigma = CalculateTOFNSigma(pidId, parameters, track, tofsignal, evTime, evTimeErr); + return tofNsigma; +} + +template +template +float TofPidNewCollision::GetTOFNSigma(const ParamType& parameters, TTrack const& track) +{ + return GetTOFNSigma(pidType, parameters, track); +} + +} // namespace pidtofgeneric +} // namespace o2::aod + +#endif // PWGLF_UTILS_PIDTOFGENERIC_H_ diff --git a/PWGLF/Utils/strangenessBuilderModule.h b/PWGLF/Utils/strangenessBuilderModule.h index 41d995fbb44..fc33a44f40c 100644 --- a/PWGLF/Utils/strangenessBuilderModule.h +++ b/PWGLF/Utils/strangenessBuilderModule.h @@ -894,7 +894,7 @@ class BuilderModule posTrackPar.setPID(o2::track::PID::Electron); negTrackPar.setPID(o2::track::PID::Electron); if (!mVDriftMgr.moveTPCTrack(collision, pTrack, posTrackPar)) { - return; + continue; } } if (isNegTPCOnly) { @@ -902,7 +902,7 @@ class BuilderModule posTrackPar.setPID(o2::track::PID::Electron); negTrackPar.setPID(o2::track::PID::Electron); if (!mVDriftMgr.moveTPCTrack(collision, nTrack, negTrackPar)) { - return; + continue; } } } // end TPC drift treatment @@ -1338,6 +1338,12 @@ class BuilderModule for (size_t iv0 = 0; iv0 < v0List.size(); iv0++) { const auto& v0 = v0List[sorted_v0[iv0]]; + if (!v0BuilderOpts.generatePhotonCandidates.value && v0.v0Type > 1) { + // skip photons if not requested + products.v0dataLink(-1, -1); + continue; + } + if (!baseOpts.mEnabledTables[kV0CoresBase] && v0Map[iv0] == -2) { // this v0 hasn't been used by cascades and we're not generating V0s, so skip it products.v0dataLink(-1, -1); @@ -1370,7 +1376,8 @@ class BuilderModule auto const& collision = collisions.rawIteratorAt(v0.collisionId); if (!mVDriftMgr.moveTPCTrack(collision, posTrack, posTrackPar)) { - return; + products.v0dataLink(-1, -1); + continue; } } @@ -1382,12 +1389,13 @@ class BuilderModule auto const& collision = collisions.rawIteratorAt(v0.collisionId); if (!mVDriftMgr.moveTPCTrack(collision, negTrack, negTrackPar)) { - return; + products.v0dataLink(-1, -1); + continue; } } } - if (!straHelper.buildV0Candidate(v0.collisionId, pvX, pvY, pvZ, posTrack, negTrack, posTrackPar, negTrackPar, v0.isCollinearV0, baseOpts.mEnabledTables[kV0Covs], true)) { + if (!straHelper.buildV0Candidate(v0.collisionId, pvX, pvY, pvZ, posTrack, negTrack, posTrackPar, negTrackPar, v0.isCollinearV0, baseOpts.mEnabledTables[kV0Covs], v0BuilderOpts.generatePhotonCandidates)) { products.v0dataLink(-1, -1); continue; } @@ -1647,6 +1655,8 @@ class BuilderModule } } // enabled tables check } // constexpr requires check + } else { + products.v0dataLink(-1, -1); } } diff --git a/PWGMM/Mult/Tasks/dndetaMFTPbPb.cxx b/PWGMM/Mult/Tasks/dndetaMFTPbPb.cxx index f8e01e36a7e..7a8c4cfb23e 100644 --- a/PWGMM/Mult/Tasks/dndetaMFTPbPb.cxx +++ b/PWGMM/Mult/Tasks/dndetaMFTPbPb.cxx @@ -57,6 +57,8 @@ using namespace o2::constants::physics; using namespace o2::constants::math; using namespace pwgmm::mult; +auto static constexpr kMinCharge = 3.f; + AxisSpec ptAxis = {1001, -0.005, 10.005}; AxisSpec multAxis = {701, -0.5, 700.5, "N_{trk}"}; AxisSpec zAxis = {60, -30., 30.}; @@ -66,6 +68,17 @@ AxisSpec phiAxis = {629, 0, TwoPI, "Rad", "#phi"}; AxisSpec etaAxis = {20, -4., -2.}; AxisSpec centAxis{100, 0, 100, "centrality"}; AxisSpec chiSqAxis = {100, 0., 1000.}; +AxisSpec nclsAxis{10, 0.5, 10.5, "# clusters"}; + +enum TrkSel { + trkSelNCls, + trkSelChi2Ncl, + trkSelEta, + trkSelPhiCut, + trkSelPt, + trkSelCA, + nTrkSel +}; struct DndetaMFTPbPb { SliceCache cache; @@ -91,77 +104,49 @@ struct DndetaMFTPbPb { struct : ConfigurableGroup { Configurable usephiCut{"usephiCut", false, "use azimuthal angle cut"}; - Configurable phiCut{"phiCut", 0.1f, - "Cut on azimuthal angle of MFT tracks"}; + Configurable phiCut{"phiCut", 0.1f, "Cut on azimuthal angle of MFT tracks"}; Configurable minPhi{"minPhi", 0.f, ""}; Configurable maxPhi{"maxPhi", 6.2832, ""}; Configurable minEta{"minEta", -3.6f, ""}; Configurable maxEta{"maxEta", -2.5f, ""}; - Configurable minNclusterMft{"minNclusterMft", 5, - "minimum number of MFT clusters"}; + Configurable minNclusterMft{"minNclusterMft", 5, "minimum number of MFT clusters"}; Configurable useChi2Cut{"useChi2Cut", false, "use track chi2 cut"}; Configurable maxChi2NCl{"maxChi2NCl", 1000.f, "maximum chi2 per MFT clusters"}; + Configurable usePtCut{"usePtCut", false, "use track pT cut"}; Configurable minPt{"minPt", 0., "minimum pT of the MFT tracks"}; - Configurable requireCA{ - "requireCA", false, "Use Cellular Automaton track-finding algorithm"}; + Configurable requireCA{"requireCA", false, "Use Cellular Automaton track-finding algorithm"}; Configurable maxDCAxy{"maxDCAxy", 2.0f, "Cut on dcaXY"}; } trackCuts; struct : ConfigurableGroup { - Configurable maxZvtx{"maxZvtx", 10.0f, "Cut on z-vtx"}; - Configurable useZDiffCut{"useZDiffCut", false, - "use Zvtx reco-mc diff. cut"}; - Configurable maxZvtxDiff{ - "maxZvtxDiff", 1.0f, - "max allowed Z vtx difference for reconstruced collisions (cm)"}; + Configurable maxZvtx{"maxZvtx", 10.0f, "maximum cut on z-vtx (cm)"}; + Configurable minZvtx{"minZvtx", -10.0f, "minimum cut on z-vtx (cm)"}; + Configurable useZDiffCut{"useZDiffCut", false, "use Zvtx reco-mc diff. cut"}; + Configurable maxZvtxDiff{"maxZvtxDiff", 1.0f, "max allowed Z vtx difference for reconstruced collisions (cm)"}; Configurable requireIsGoodZvtxFT0VsPV{"requireIsGoodZvtxFT0VsPV", true, "require events with PV position along z consistent (within 1 cm) between PV reconstructed using tracks and PV using FT0 A-C time difference"}; Configurable requireRejectSameBunchPileup{"requireRejectSameBunchPileup", true, "reject collisions in case of pileup with another collision in the same foundBC"}; - Configurable requireNoCollInTimeRangeStrict{"requireNoCollInTimeRangeStrict", true, " requireNoCollInTimeRangeStrict"}; - Configurable requireNoCollInRofStrict{"requireNoCollInRofStrict", true, "requireNoCollInRofStrict"}; + Configurable requireNoCollInTimeRangeStrict{"requireNoCollInTimeRangeStrict", false, " requireNoCollInTimeRangeStrict"}; + Configurable requireNoCollInRofStrict{"requireNoCollInRofStrict", false, "requireNoCollInRofStrict"}; Configurable requireNoCollInRofStandard{"requireNoCollInRofStandard", false, "requireNoCollInRofStandard"}; - Configurable requireNoHighMultCollInPrevRof{"requireNoHighMultCollInPrevRof", true, "requireNoHighMultCollInPrevRof"}; - Configurable requireNoCollInTimeRangeStd{ - "requireNoCollInTimeRangeStd", false, - "reject collisions corrupted by the cannibalism, with other collisions " - "within +/- 10 microseconds"}; - Configurable requireNoCollInTimeRangeNarrow{ - "requireNoCollInTimeRangeNarrow", false, - "reject collisions corrupted by the cannibalism, with other collisions " - "within +/- 10 microseconds"}; - Configurable occupancyEstimator{ - "occupancyEstimator", 1, - "Occupancy estimator: 1 = trackOccupancyInTimeRange, 2 = " - "ft0cOccupancyInTimeRange"}; - Configurable minOccupancy{ - "minOccupancy", -1, "minimum occupancy from neighbouring collisions"}; - Configurable maxOccupancy{ - "maxOccupancy", -1, "maximum occupancy from neighbouring collisions"}; + Configurable requireNoHighMultCollInPrevRof{"requireNoHighMultCollInPrevRof", false, "requireNoHighMultCollInPrevRof"}; + Configurable requireNoCollInTimeRangeStd{"requireNoCollInTimeRangeStd", true, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; + Configurable requireNoCollInTimeRangeNarrow{"requireNoCollInTimeRangeNarrow", false, "reject collisions corrupted by the cannibalism, with other collisions within +/- 10 microseconds"}; + Configurable occupancyEstimator{"occupancyEstimator", 1, "Occupancy estimator: 1 = trackOccupancyInTimeRange, 2 = ft0cOccupancyInTimeRange"}; + Configurable minOccupancy{"minOccupancy", -1, "minimum occupancy from neighbouring collisions"}; + Configurable maxOccupancy{"maxOccupancy", -1, "maximum occupancy from neighbouring collisions"}; Configurable minIR{"minIR", -1, "minimum IR (kHz) collisions"}; Configurable maxIR{"maxIR", -1, "maximum IR (kHz) collisions"}; } eventCuts; - ConfigurableAxis occupancyBins{"occupancyBins", - {VARIABLE_WIDTH, 0.0f, 250.0f, 500.0f, 750.0f, - 1000.0f, 1500.0f, 2000.0f, 3000.0f, 4500.0f, - 6000.0f, 8000.0f, 10000.0f, 50000.0f}, - "Occupancy"}; - ConfigurableAxis centralityBins{ - "centralityBins", - {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, - "Centrality"}; + ConfigurableAxis occupancyBins{"occupancyBins", {VARIABLE_WIDTH, 0.0f, 250.0f, 500.0f, 750.0f, 1000.0f, 1500.0f, 2000.0f, 3000.0f, 4500.0f, 6000.0f, 8000.0f, 10000.0f, 50000.0f}, "Occupancy"}; + ConfigurableAxis centralityBins{"centralityBins", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, "Centrality"}; ConfigurableAxis irBins{"irBins", {500, 0, 50}, "Interaction rate (kHz)"}; Service pdg; Service ccdb; - Configurable ccdbNoLaterThan{ - "ccdbNoLaterThan", - std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count(), - "latest acceptable timestamp of creation for the object"}; - Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", - "url of the ccdb repository"}; + Configurable ccdbNoLaterThan{"ccdbNoLaterThan", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; int mRunNumber{-1}; uint64_t mSOR{0}; @@ -234,7 +219,7 @@ struct DndetaMFTPbPb { "be enabled!"); } - auto hev = registry.add("hEvtSel", "hEvtSel", HistType::kTH1F, + auto hev = registry.add("Events/hEvtSel", "hEvtSel", HistType::kTH1F, {{14, -0.5f, +13.5f}}); hev->GetXaxis()->SetBinLabel(1, "All collisions"); hev->GetXaxis()->SetBinLabel(2, "Ev. sel."); @@ -250,6 +235,14 @@ struct DndetaMFTPbPb { hev->GetXaxis()->SetBinLabel(12, "Below min occup."); hev->GetXaxis()->SetBinLabel(13, "Above max occup."); + registry.add("Tracks/hTrkSel", "Number of tracks; Cut; #Tracks Passed Cut", {HistType::kTH1D, {{nTrkSel, 0, nTrkSel}}}); + registry.get(HIST("Tracks/hTrkSel"))->GetXaxis()->SetBinLabel(trkSelNCls + 1, "Ncl cut"); + registry.get(HIST("Tracks/hTrkSel"))->GetXaxis()->SetBinLabel(trkSelChi2Ncl + 1, "#chi^{2}/Ncl cut"); + registry.get(HIST("Tracks/hTrkSel"))->GetXaxis()->SetBinLabel(trkSelEta + 1, "#eta cut"); + registry.get(HIST("Tracks/hTrkSel"))->GetXaxis()->SetBinLabel(trkSelPhiCut + 1, "#varphi cut"); + registry.get(HIST("Tracks/hTrkSel"))->GetXaxis()->SetBinLabel(trkSelPt + 1, "#it{p}_{T} cut"); + registry.get(HIST("Tracks/hTrkSel"))->GetXaxis()->SetBinLabel(trkSelCA + 1, "Tracking algorithm (CA)"); + auto hBcSel = registry.add("hBcSel", "hBcSel", HistType::kTH1F, {{3, -0.5f, +2.5f}}); hBcSel->GetXaxis()->SetBinLabel(1, "Good BCs"); @@ -290,7 +283,7 @@ struct DndetaMFTPbPb { qaregistry.add( {"Tracks/NclustersEta", "; nClusters; #eta; occupancy", - {HistType::kTHnSparseF, {{7, 4, 10}, etaAxis, occupancyAxis}}}); + {HistType::kTHnSparseF, {nclsAxis, etaAxis, occupancyAxis}}}); qaregistry.add({"Tracks/NchSel", "; N_{ch}; occupancy", {HistType::kTH2F, {multAxis, occupancyAxis}}}); @@ -311,7 +304,7 @@ struct DndetaMFTPbPb { qaregistry.add( {"Tracks/NclustersEtaBest", "; nClusters; #eta; occupancy", - {HistType::kTHnSparseF, {{7, 4, 10}, etaAxis, occupancyAxis}}}); + {HistType::kTHnSparseF, {nclsAxis, etaAxis, occupancyAxis}}}); qaregistry.add( {"Tracks/DCAXYPt", "; p_{T} (GeV/c) ; DCA_{XY} (cm); occupancy", @@ -389,7 +382,7 @@ struct DndetaMFTPbPb { qaregistry.add({"Tracks/Centrality/NclustersEta", "; nClusters; #eta; centrality; occupancy", {HistType::kTHnSparseF, - {{7, 4, 10}, etaAxis, centralityAxis, occupancyAxis}}}); + {nclsAxis, etaAxis, centralityAxis, occupancyAxis}}}); if (doprocessDatawBestTracksCentFT0C || doprocessDatawBestTracksCentFT0CVariant1 || @@ -412,7 +405,7 @@ struct DndetaMFTPbPb { {"Tracks/Centrality/NclustersEtaBest", "; nClusters; #eta; centrality; occupancy", {HistType::kTHnSparseF, - {{7, 4, 10}, etaAxis, centralityAxis, occupancyAxis}}}); + {nclsAxis, etaAxis, centralityAxis, occupancyAxis}}}); qaregistry.add({"Tracks/Centrality/TrackAmbDegree", "; N_{coll}^{comp}; centrality; occupancy", {HistType::kTHnSparseF, @@ -744,20 +737,21 @@ struct DndetaMFTPbPb { template bool isTrackSelected(const T& track) { - if (track.eta() < trackCuts.minEta || track.eta() > trackCuts.maxEta) + if (track.nClusters() < trackCuts.minNclusterMft) { return false; + } + registry.fill(HIST("Tracks/hTrkSel"), trkSelNCls); if (trackCuts.useChi2Cut) { float nclMft = std::max(2.0f * track.nClusters() - 5.0f, 1.0f); float mftChi2NCl = track.chi2() / nclMft; if (mftChi2NCl > trackCuts.maxChi2NCl) return false; } - if (trackCuts.requireCA && !track.isCA()) - return false; - if (track.nClusters() < trackCuts.minNclusterMft) - return false; - if (track.pt() < trackCuts.minPt) + registry.fill(HIST("Tracks/hTrkSel"), trkSelChi2Ncl); + if (track.eta() < trackCuts.minEta || track.eta() > trackCuts.maxEta) { return false; + } + registry.fill(HIST("Tracks/hTrkSel"), trkSelEta); if (trackCuts.usephiCut) { float phi = track.phi(); o2::math_utils::bringTo02Pi(phi); @@ -771,6 +765,15 @@ struct DndetaMFTPbPb { (phi < ((PIHalf - 0.1) * PI) + trackCuts.phiCut))) return false; } + registry.fill(HIST("Tracks/hTrkSel"), trkSelPhiCut); + if (trackCuts.usePtCut && track.pt() < trackCuts.minPt) { + return false; + } + registry.fill(HIST("Tracks/hTrkSel"), trkSelPt); + if (trackCuts.requireCA && !track.isCA()) { + return false; + } + registry.fill(HIST("Tracks/hTrkSel"), trkSelCA); return true; } @@ -938,69 +941,69 @@ struct DndetaMFTPbPb { bool isGoodEvent(C const& collision) { if constexpr (fillHis) { - registry.fill(HIST("hEvtSel"), 0); + registry.fill(HIST("Events/hEvtSel"), 0); } if (!collision.sel8()) { return false; } if constexpr (fillHis) { - registry.fill(HIST("hEvtSel"), 1); + registry.fill(HIST("Events/hEvtSel"), 1); } if (eventCuts.requireIsGoodZvtxFT0VsPV && !collision.selection_bit(aod::evsel::kIsGoodZvtxFT0vsPV)) { return false; } if constexpr (fillHis) { - registry.fill(HIST("hEvtSel"), 2); + registry.fill(HIST("Events/hEvtSel"), 2); } if (eventCuts.requireRejectSameBunchPileup && !collision.selection_bit(aod::evsel::kNoSameBunchPileup)) { return false; } if constexpr (fillHis) { - registry.fill(HIST("hEvtSel"), 3); + registry.fill(HIST("Events/hEvtSel"), 3); } - if (std::abs(collision.posZ()) >= eventCuts.maxZvtx) { + if (collision.posZ() <= eventCuts.minZvtx || collision.posZ() >= eventCuts.maxZvtx) { return false; } if constexpr (fillHis) { - registry.fill(HIST("hEvtSel"), 4); + registry.fill(HIST("Events/hEvtSel"), 4); } if (eventCuts.requireNoCollInTimeRangeStd && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard)) { return false; } if constexpr (fillHis) { - registry.fill(HIST("hEvtSel"), 5); + registry.fill(HIST("Events/hEvtSel"), 5); } if (eventCuts.requireNoCollInTimeRangeNarrow && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeNarrow)) { return false; } if constexpr (fillHis) { - registry.fill(HIST("hEvtSel"), 6); + registry.fill(HIST("Events/hEvtSel"), 6); } if (eventCuts.requireNoCollInTimeRangeStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStrict)) { return false; } if constexpr (fillHis) { - registry.fill(HIST("hEvtSel"), 7); + registry.fill(HIST("Events/hEvtSel"), 7); } if (eventCuts.requireNoCollInRofStrict && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStrict)) { return false; } if constexpr (fillHis) { - registry.fill(HIST("hEvtSel"), 8); + registry.fill(HIST("Events/hEvtSel"), 8); } if (eventCuts.requireNoCollInRofStandard && !collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard)) { return false; } if constexpr (fillHis) { - registry.fill(HIST("hEvtSel"), 9); + registry.fill(HIST("Events/hEvtSel"), 9); } if (eventCuts.requireNoHighMultCollInPrevRof && !collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof)) { return false; } if constexpr (fillHis) { - registry.fill(HIST("hEvtSel"), 10); + registry.fill(HIST("Events/hEvtSel"), 10); } if (eventCuts.minOccupancy >= 0 && getOccupancy(collision, eventCuts.occupancyEstimator) < @@ -1008,7 +1011,7 @@ struct DndetaMFTPbPb { return false; } if constexpr (fillHis) { - registry.fill(HIST("hEvtSel"), 11); + registry.fill(HIST("Events/hEvtSel"), 11); } if (eventCuts.maxOccupancy >= 0 && getOccupancy(collision, eventCuts.occupancyEstimator) > @@ -1016,7 +1019,7 @@ struct DndetaMFTPbPb { return false; } if constexpr (fillHis) { - registry.fill(HIST("hEvtSel"), 12); + registry.fill(HIST("Events/hEvtSel"), 12); } return true; } @@ -1030,7 +1033,7 @@ struct DndetaMFTPbPb { if (p != nullptr) { charge = p->Charge(); } - return std::abs(charge) >= 3.; + return std::abs(charge) >= kMinCharge; } template @@ -1340,27 +1343,27 @@ struct DndetaMFTPbPb { bool gtZeroColl = false; int gtOneColl = 0; - float cgen = -1; + float cGen = -1; if constexpr (has_reco_cent) { - float crec_min = 105.f; + float crecMin = 105.f; for (const auto& collision : collisions) { if (isGoodEvent(collision)) { float c = getRecoCent(collision); - if (c < crec_min) { - crec_min = c; + if (c < crecMin) { + crecMin = c; } } } - if (cgen < 0) - cgen = crec_min; + if (cGen < 0) + cGen = crecMin; } - float occgen = -1.; + float occGen = -1.; for (const auto& collision : collisions) { if (isGoodEvent(collision)) { float o = getOccupancy(collision, eventCuts.occupancyEstimator); - if (o > occgen) { - occgen = o; + if (o > occGen) { + occGen = o; } } } @@ -1418,9 +1421,9 @@ struct DndetaMFTPbPb { } if constexpr (has_reco_cent) { - registry.fill(HIST("Events/Centrality/EvtEffGen"), 3., cgen, occgen); + registry.fill(HIST("Events/Centrality/EvtEffGen"), 3., cGen, occGen); } else { - registry.fill(HIST("Events/EvtEffGen"), 3., occgen); + registry.fill(HIST("Events/EvtEffGen"), 3., occGen); } auto perCollMCsample = mcSample->sliceByCached( @@ -1430,7 +1433,7 @@ struct DndetaMFTPbPb { if (gtOneColl > 1) { if constexpr (has_reco_cent) { - qaregistry.fill(HIST("Events/Centrality/SplitMult"), nchrg, zvtxMC, cgen); + qaregistry.fill(HIST("Events/Centrality/SplitMult"), nchrg, zvtxMC, cGen); } else { qaregistry.fill(HIST("Events/SplitMult"), nchrg, zvtxMC); } @@ -1439,17 +1442,17 @@ struct DndetaMFTPbPb { auto nCharged = countPart(particles); if constexpr (has_reco_cent) { registry.fill(HIST("Events/Centrality/NtrkZvtxGen_t"), nCharged, zvtxMC, - cgen); + cGen); } else { registry.fill(HIST("Events/NtrkZvtxGen_t"), nCharged, zvtxMC); } - fillHistMC>(particles, cgen, occgen, zvtxMC, gtZeroColl); + fillHistMC>(particles, cGen, occGen, zvtxMC, gtZeroColl); if (collisions.size() == 0) { if constexpr (has_reco_cent) { qaregistry.fill(HIST("Events/Centrality/NotFoundEventZvtx"), - mcCollision.posZ(), cgen); + mcCollision.posZ(), cGen); } else { qaregistry.fill(HIST("Events/NotFoundEventZvtx"), mcCollision.posZ()); } @@ -1543,27 +1546,27 @@ struct DndetaMFTPbPb { FiltBestTracks const& besttracks) { bool gtZeroColl = false; - float cgen = -1; + float cGen = -1; if constexpr (has_reco_cent) { - float crec_min = 105.f; + float crecMin = 105.f; for (const auto& collision : collisions) { if (isGoodEvent(collision)) { float c = getRecoCent(collision); - if (c < crec_min) { - crec_min = c; + if (c < crecMin) { + crecMin = c; } } } - if (cgen < 0) - cgen = crec_min; + if (cGen < 0) + cGen = crecMin; } - float occgen = -1.; + float occGen = -1.; for (const auto& collision : collisions) { if (isGoodEvent(collision)) { float o = getOccupancy(collision, eventCuts.occupancyEstimator); - if (o > occgen) { - occgen = o; + if (o > occGen) { + occGen = o; } } } @@ -1606,26 +1609,26 @@ struct DndetaMFTPbPb { } if constexpr (has_reco_cent) { - registry.fill(HIST("Events/Centrality/EvtEffGen"), 3., cgen, occgen); + registry.fill(HIST("Events/Centrality/EvtEffGen"), 3., cGen, occGen); } else { - registry.fill(HIST("Events/EvtEffGen"), 3., occgen); + registry.fill(HIST("Events/EvtEffGen"), 3., occGen); } auto zvtxMC = mcCollision.posZ(); auto nCharged = countPart(particles); if constexpr (has_reco_cent) { registry.fill(HIST("Events/Centrality/NtrkZvtxGen_t"), nCharged, zvtxMC, - cgen); + cGen); } else { registry.fill(HIST("Events/NtrkZvtxGen_t"), nCharged, zvtxMC); } - fillHistMC>(particles, cgen, occgen, zvtxMC, gtZeroColl); + fillHistMC>(particles, cGen, occGen, zvtxMC, gtZeroColl); if (collisions.size() == 0) { if constexpr (has_reco_cent) { qaregistry.fill(HIST("Events/Centrality/NotFoundEventZvtx"), - mcCollision.posZ(), cgen); + mcCollision.posZ(), cGen); } else { qaregistry.fill(HIST("Events/NotFoundEventZvtx"), mcCollision.posZ()); } diff --git a/PWGMM/UE/Tasks/dedxAnalysis.cxx b/PWGMM/UE/Tasks/dedxAnalysis.cxx index b87e9c30478..11aea4031be 100644 --- a/PWGMM/UE/Tasks/dedxAnalysis.cxx +++ b/PWGMM/UE/Tasks/dedxAnalysis.cxx @@ -146,8 +146,8 @@ struct DedxAnalysis { AxisSpec ptAxis = {binP, "pT (GeV/c)"}; AxisSpec etaAxis{8, -0.8, 0.8, "#eta"}; AxisSpec pAxis = {binP, "#it{p}/Z (GeV/c)"}; - fphiCutLow = new TF1("StandardPhiCutLow", "0.1/x/x+pi/18.0-0.025", 0, 50); - fphiCutHigh = new TF1("StandardPhiCutHigh", "0.12/x+pi/18.0+0.035", 0, 50); + fphiCutLow = new TF1("StandardPhiCutLow", "0.119297/x/x+pi/18.0-0.000379693", 0, 50); + fphiCutHigh = new TF1("StandardPhiCutHigh", "0.16685/x+pi/18.0+0.00981942", 0, 50); if (calibrationMode) { // MIP for pions registryDeDx.add( diff --git a/PWGUD/Core/SGSelector.h b/PWGUD/Core/SGSelector.h index b9fc3ecf2e7..2c5868df303 100644 --- a/PWGUD/Core/SGSelector.h +++ b/PWGUD/Core/SGSelector.h @@ -31,19 +31,22 @@ template struct SelectionResult { - int value; // The original integer return value - BC* bc; // Pointer to the BC object + int value; // The original integer return value + const BC* bc; // Pointer to the BC object }; namespace o2::aod::sgselector { enum TrueGap : int { - NoGap = -1, - SingleGapA = 0, - SingleGapC = 1, - DoubleGap = 2 + NoGap = -1, // no gap due to change of threshold(s) in any of FV0, FT0A, ZNA, FT0C, ZNC + SingleGapA = 0, // initially single gap at A side event + SingleGapC = 1, // initially single gap at C side event + DoubleGap = 2, // initially double gap event + NoUpc = 3, // initially no UPC event with default thresholds (FT0A=150, FT0C=50) + TrkOutOfRange = 4, // to many tracks (>100 default) + BadDoubleGap = 5 // unknows status of double gap check with changed thresholds }; -} +} // namespace o2::aod::sgselector class SGSelector { @@ -51,21 +54,21 @@ class SGSelector SGSelector() : myRCTChecker{"CBT"}, myRCTCheckerHadron{"CBT_hadronPID"}, myRCTCheckerZDC{"CBT", true}, myRCTCheckerHadronZDC{"CBT_hadronPID", true} {} template - int Print(SGCutParHolder /*diffCuts*/, CC& collision, BCs& /*bcRange*/, TCs& /*tracks*/, FWs& /*fwdtracks*/) + int Print(SGCutParHolder const& /*diffCuts*/, CC const& collision, BCs const& /*bcRange*/, TCs const& /*tracks*/, FWs const& /*fwdtracks*/) { LOGF(info, "Size of array %i", collision.size()); return 1; } template - SelectionResult IsSelected(SGCutParHolder diffCuts, CC& collision, BCs& bcRange, BC& oldbc) + SelectionResult IsSelected(SGCutParHolder const& diffCuts, CC const& collision, BCs const& bcRange, BC const& oldbc) { // LOGF(info, "Collision %f", collision.collisionTime()); // LOGF(info, "Number of close BCs: %i", bcRange.size()); SelectionResult result; result.bc = &oldbc; if (collision.numContrib() < diffCuts.minNTracks() || collision.numContrib() > diffCuts.maxNTracks()) { - result.value = 4; + result.value = o2::aod::sgselector::TrkOutOfRange; // 4 return result; } auto newbc = oldbc; @@ -91,9 +94,9 @@ class SGSelector newbc = bc; gC = false; } - } + } // end of loop over bc range if (!gA && !gC) { - result.value = 3; + result.value = o2::aod::sgselector::NoUpc; // gap = 3 return result; } if (gA && gC) { // loop once again for so-called DG events to get the most active FT0 BC @@ -120,7 +123,8 @@ class SGSelector result.bc = &newbc; // LOGF(info, "Old BC: %i, New BC: %i",oldbc.globalBC(), newbc.globalBC()); result.bc = &newbc; - result.value = gA && gC ? 2 : (gA ? 0 : 1); + // result.value = gA && gC ? 2 : (gA ? 0 : 1); + result.value = gA && gC ? o2::aod::sgselector::DoubleGap : (gA ? o2::aod::sgselector::SingleGapA : o2::aod::sgselector::SingleGapC); return result; } template @@ -134,17 +138,17 @@ class SGSelector } template - int trueGap(CC& collision, float fv0, float ft0a, float ft0c, float zdc_cut) + int trueGap(CC const& collision, const float fv0, const float ft0a, const float ft0c, const float zdc_cut) { - float fit_cut[3] = {fv0, ft0a, ft0c}; + const float fit_cut[3] = {fv0, ft0a, ft0c}; int gap = collision.gapSide(); int true_gap = gap; - float FV0A, FT0A, FT0C, ZNA, ZNC; - FV0A = collision.totalFV0AmplitudeA(); - FT0A = collision.totalFT0AmplitudeA(); - FT0C = collision.totalFT0AmplitudeC(); - ZNA = collision.energyCommonZNA(); - ZNC = collision.energyCommonZNC(); + // float FV0A, FT0A, FT0C, ZNA, ZNC; + const float FV0A = collision.totalFV0AmplitudeA(); + const float FT0A = collision.totalFT0AmplitudeA(); + const float FT0C = collision.totalFT0AmplitudeC(); + const float ZNA = collision.energyCommonZNA(); + const float ZNC = collision.energyCommonZNC(); if (gap == o2::aod::sgselector::SingleGapA) { // gap == 0 if (FV0A > fit_cut[0] || FT0A > fit_cut[1] || ZNA > zdc_cut) true_gap = o2::aod::sgselector::NoGap; // -1 @@ -152,23 +156,25 @@ class SGSelector if (FT0C > fit_cut[2] || ZNC > zdc_cut) true_gap = o2::aod::sgselector::NoGap; // -1 } else if (gap == o2::aod::sgselector::DoubleGap) { // gap == 2 - if ((FV0A > fit_cut[0] || FT0A > fit_cut[1] || ZNA > zdc_cut) && (FT0C > fit_cut[2] || ZNC > zdc_cut)) + if ((FV0A > fit_cut[0] || FT0A > fit_cut[1] || ZNA > zdc_cut) && (FT0C > fit_cut[2] || ZNC > zdc_cut)) { true_gap = o2::aod::sgselector::NoGap; // -1 - else if ((FV0A > fit_cut[0] || FT0A > fit_cut[1] || ZNA > zdc_cut) && (FT0C <= fit_cut[2] && ZNC <= zdc_cut)) + } else if ((FV0A > fit_cut[0] || FT0A > fit_cut[1] || ZNA > zdc_cut) && (FT0C <= fit_cut[2] && ZNC <= zdc_cut)) { true_gap = o2::aod::sgselector::SingleGapC; // 1 - else if ((FV0A <= fit_cut[0] && FT0A <= fit_cut[1] && ZNA <= zdc_cut) && (FT0C > fit_cut[2] || ZNC > zdc_cut)) + } else if ((FV0A <= fit_cut[0] && FT0A <= fit_cut[1] && ZNA <= zdc_cut) && (FT0C > fit_cut[2] || ZNC > zdc_cut)) { true_gap = o2::aod::sgselector::SingleGapA; // 0 - else if (FV0A <= fit_cut[0] && FT0A <= fit_cut[1] && ZNA <= zdc_cut && FT0C <= fit_cut[2] && ZNC <= zdc_cut) + } else if (FV0A <= fit_cut[0] && FT0A <= fit_cut[1] && ZNA <= zdc_cut && FT0C <= fit_cut[2] && ZNC <= zdc_cut) { true_gap = o2::aod::sgselector::DoubleGap; // 2 - else + } else { LOGF(info, "Something wrong with DG"); + true_gap = o2::aod::sgselector::BadDoubleGap; // 5 + } } return true_gap; } // check CBT flags template - bool isCBTOk(CC& collision) + bool isCBTOk(CC const& collision) { if (myRCTChecker(collision)) return true; @@ -177,7 +183,7 @@ class SGSelector // check CBT+hadronPID flags template - bool isCBTHadronOk(CC& collision) + bool isCBTHadronOk(CC const& collision) { if (myRCTCheckerHadron(collision)) return true; @@ -186,7 +192,7 @@ class SGSelector // check CBT+ZDC flags template - bool isCBTZdcOk(CC& collision) + bool isCBTZdcOk(CC const& collision) { if (myRCTCheckerZDC(collision)) return true; @@ -195,7 +201,7 @@ class SGSelector // check CBT+hadronPID+ZDC flags template - bool isCBTHadronZdcOk(CC& collision) + bool isCBTHadronZdcOk(CC const& collision) { if (myRCTCheckerHadronZDC(collision)) return true; diff --git a/PWGUD/TableProducer/SGCandProducer.cxx b/PWGUD/TableProducer/SGCandProducer.cxx index 37fba3120db..df466cb95b3 100644 --- a/PWGUD/TableProducer/SGCandProducer.cxx +++ b/PWGUD/TableProducer/SGCandProducer.cxx @@ -217,8 +217,8 @@ struct SGCandProducer { // Cross sections in ub. Using dummy -1 if lumi estimator is not reliable float csTCE = 10.36e6; - float csZEM = 415.2e6; // see AN: https://alice-notes.web.cern.ch/node/1515 - float csZNC = 214.5e6; // see AN: https://alice-notes.web.cern.ch/node/1515 + const float csZEM = 415.2e6; // see AN: https://alice-notes.web.cern.ch/node/1515 + const float csZNC = 214.5e6; // see AN: https://alice-notes.web.cern.ch/node/1515 if (runNumber > 543437 && runNumber < 543514) { csTCE = 8.3e6; } @@ -326,14 +326,14 @@ struct SGCandProducer { getHist(TH1, histdir + "/Stat")->Fill(8., 1.); // - int trs = collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard) ? 1 : 0; - int trofs = collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard) ? 1 : 0; - int hmpr = collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof) ? 1 : 0; - int tfb = collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder) ? 1 : 0; - int itsROFb = collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder) ? 1 : 0; - int sbp = collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup) ? 1 : 0; - int zVtxFT0vPv = collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV) ? 1 : 0; - int vtxITSTPC = collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC) ? 1 : 0; + const int trs = collision.selection_bit(o2::aod::evsel::kNoCollInTimeRangeStandard) ? 1 : 0; + const int trofs = collision.selection_bit(o2::aod::evsel::kNoCollInRofStandard) ? 1 : 0; + const int hmpr = collision.selection_bit(o2::aod::evsel::kNoHighMultCollInPrevRof) ? 1 : 0; + const int tfb = collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder) ? 1 : 0; + const int itsROFb = collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder) ? 1 : 0; + const int sbp = collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup) ? 1 : 0; + const int zVtxFT0vPv = collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV) ? 1 : 0; + const int vtxITSTPC = collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC) ? 1 : 0; auto bc = collision.template foundBC_as(); double ir = 0.; const uint64_t ts = bc.timestamp(); @@ -363,14 +363,14 @@ struct SGCandProducer { return; } upchelpers::FITInfo fitInfo{}; - uint8_t chFT0A = 0; - uint8_t chFT0C = 0; - uint8_t chFDDA = 0; - uint8_t chFDDC = 0; - uint8_t chFV0A = 0; - int occ = collision.trackOccupancyInTimeRange(); + const uint8_t chFT0A = 0; + const uint8_t chFT0C = 0; + const uint8_t chFDDA = 0; + const uint8_t chFDDC = 0; + const uint8_t chFV0A = 0; + const int occ = collision.trackOccupancyInTimeRange(); udhelpers::getFITinfo(fitInfo, newbc, bcs, ft0s, fv0as, fdds); - int upc_flag = (collision.flags() & dataformats::Vertex>::Flags::UPCMode) ? 1 : 0; + const int upc_flag = (collision.flags() & dataformats::Vertex>::Flags::UPCMode) ? 1 : 0; // update SG candidates tables outputCollisions(bc.globalBC(), bc.runNumber(), collision.posX(), collision.posY(), collision.posZ(), upc_flag, diff --git a/PWGUD/TableProducer/fwdTrackPropagation.cxx b/PWGUD/TableProducer/fwdTrackPropagation.cxx index cc6ba621690..52fa510b176 100644 --- a/PWGUD/TableProducer/fwdTrackPropagation.cxx +++ b/PWGUD/TableProducer/fwdTrackPropagation.cxx @@ -99,7 +99,7 @@ struct FwdTrackPropagation { if (run != fRun) { fRun = run; - std::map metadata; + std::map metadata; auto soreor = o2::ccdb::BasicCCDBManager::getRunDuration(fCCDBApi, run); auto ts = soreor.first; auto grpmag = fCCDBApi.retrieveFromTFileAny("GLO/Config/GRPMagField", metadata, ts); diff --git a/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx b/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx index 97068a4c9a9..0f4cbd0be70 100644 --- a/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx +++ b/PWGUD/Tasks/exclusiveRhoTo4Pi.cxx @@ -36,6 +36,7 @@ #include #include +#include #include using namespace std; @@ -44,6 +45,12 @@ using namespace o2::aod; using namespace o2::framework; using namespace o2::framework::expressions; +using PtEtaPhiMVector = ROOT::Math::PtEtaPhiMVector; +using Boost = ROOT::Math::Boost; +using XYZVectorF = ROOT::Math::XYZVectorF; +using PxPyPzEVector = ROOT::Math::PxPyPzEVector; +using PxPyPzMVector = ROOT::Math::PxPyPzMVector; + namespace o2::aod { namespace branch @@ -151,11 +158,15 @@ DECLARE_SOA_COLUMN(FourPionEta, fourPionEta, double); DECLARE_SOA_COLUMN(FourPionPhi, fourPionPhi, double); DECLARE_SOA_COLUMN(FourPionRapidity, fourPionRapidity, double); DECLARE_SOA_COLUMN(FourPionMass, fourPionMass, double); -// Four Pion Phi Pair 1, Pair 2, CosTheta Pair 1, CosTheta Pair 2 +// Collin-Soper Angles DECLARE_SOA_COLUMN(FourPionPhiPair1, fourPionPhiPair1, double); DECLARE_SOA_COLUMN(FourPionPhiPair2, fourPionPhiPair2, double); +DECLARE_SOA_COLUMN(FourPionPhiPair3, fourPionPhiPair3, double); +DECLARE_SOA_COLUMN(FourPionPhiPair4, fourPionPhiPair4, double); DECLARE_SOA_COLUMN(FourPionCosThetaPair1, fourPionCosThetaPair1, double); DECLARE_SOA_COLUMN(FourPionCosThetaPair2, fourPionCosThetaPair2, double); +DECLARE_SOA_COLUMN(FourPionCosThetaPair3, fourPionCosThetaPair3, double); +DECLARE_SOA_COLUMN(FourPionCosThetaPair4, fourPionCosThetaPair4, double); } // namespace branch DECLARE_SOA_TABLE(SignalData, "AOD", "signalData", @@ -262,8 +273,12 @@ DECLARE_SOA_TABLE(SignalData, "AOD", "signalData", branch::FourPionMass, branch::FourPionPhiPair1, branch::FourPionPhiPair2, + branch::FourPionPhiPair3, + branch::FourPionPhiPair4, branch::FourPionCosThetaPair1, - branch::FourPionCosThetaPair2); + branch::FourPionCosThetaPair2, + branch::FourPionCosThetaPair3, + branch::FourPionCosThetaPair4); DECLARE_SOA_TABLE(BkgroundData, "AOD", "bkgroundData", branch::RunNumber, @@ -376,7 +391,10 @@ struct ExclusiveRhoTo4Pi { int numPiPlus = 2; int numPiMinus = 2; float zeroPointEight = 0.8; - std::vector trackSelectionParams; + double mRho0 = 0.77526; // GeV/c^2 + // Run Numbers + static int runNos[113]; + static int numRunNums; // Derived Data Produces sigFromData; Produces bkgFromData; @@ -405,7 +423,7 @@ struct ExclusiveRhoTo4Pi { Configurable useTPCtracksOnly{"useTPCtracksOnly", true, "only use tracks with hit in TPC"}; Configurable itsChi2NClsCut{"itsChi2NClsCut", 36, "ITS Chi2NCls"}; Configurable tpcChi2NClsCut{"tpcChi2NClsCut", 4.0, "TPC Chi2NCls"}; - Configurable tpcNClsFindableCut{"tpcNClsFindableCut", 70, "Min TPC Findable Clusters"}; + Configurable tpcNClsFindableCut{"tpcNClsFindableCut", 70, "Min TPC Findable Clusters"}; // Configurable PID parameters Configurable useTOF{"useTOF", true, "if track has TOF use TOF"}; Configurable nSigmaTPCcut{"nSigmaTPCcut", 3, "TPC cut"}; @@ -416,7 +434,7 @@ struct ExclusiveRhoTo4Pi { Configurable rhoMassMin{"rhoMassMin", 1, "Min Mass of rho"}; Configurable rhoMassMax{"rhoMassMax", 2.5, "Max Mass of rho"}; // Axis Configurations - ConfigurableAxis pTAxis{"pTAxis", {1000, 0, 2}, "Axis for pT histograms"}; + ConfigurableAxis pTAxis{"pTAxis", {1000, 0, 1}, "Axis for pT histograms"}; ConfigurableAxis etaAxis{"etaAxis", {1000, -1.1, 1.1}, "Axis for Eta histograms"}; ConfigurableAxis rapidityAxis{"rapidityAxis", {1000, -2.5, 2.5}, "Axis for Rapidity histograms"}; ConfigurableAxis invMassAxis{"invMassAxis", {1000, 1, 2.5}, "Axis for Phi histograms"}; @@ -426,8 +444,16 @@ struct ExclusiveRhoTo4Pi { void init(InitContext const&) { // QA plots: Event and Track Counter - histosCounter.add("EventsCounts_vs_runNo", "Number of Selected 4-Pion Events per Run; Run Number; Number of Events", kTH2F, {{1355, 544013, 545367}, {20, 0, 20}}); - histosCounter.add("TracksCounts_vs_runNo", "Number of Selected Tracks per Run; Run Number; Number of Tracks", kTH2F, {{1355, 544013, 545367}, {20, 0, 20}}); + histosCounter.add("EventsCounts_vs_runNo", "Number of Selected 4-Pion Events per Run; Run Number; Number of Events", kTH2F, {{113, 0, 113}, {12, 0, 12}}); + histosCounter.add("TracksCounts_vs_runNo", "Number of Selected Tracks per Run; Run Number; Number of Tracks", kTH2F, {{113, 0, 113}, {14, 0, 14}}); + histosCounter.add("fourPionCounts_0c", "Four Pion Counts; Run Number; Events", kTH1F, {{113, 0, 113}}); + histosCounter.add("fourPionCounts_0c_within_mass", "Four Pion Counts within mass range; Run Number; Events", kTH1F, {{113, 0, 113}}); + histosCounter.add("fourPionCounts_0c_within_rap", "Four Pion Counts; Run Number; Events", kTH1F, {{113, 0, 113}}); + histosCounter.add("fourPionCounts_0c_selected", "Four Pion Counts; Run Number; Events", kTH1F, {{113, 0, 113}}); + histosCounter.add("fourPionCounts_n0c", "Four Pion Counts; Run Number; Events", kTH1F, {{113, 0, 113}}); + histosCounter.add("fourPionCounts_n0c_within_mass", "Four Pion Counts within mass range; Run Number; Events", kTH1F, {{113, 0, 113}}); + histosCounter.add("fourPionCounts_n0c_within_rap", "Four Pion Counts; Run Number; Events", kTH1F, {{113, 0, 113}}); + histosCounter.add("fourPionCounts_n0c_selected", "Four Pion Counts; Run Number; Events", kTH1F, {{113, 0, 113}}); // QA plots: event selection histosData.add("UPCmode", "UPC mode; Events", kTH1F, {{5, 0, 5}}); histosData.add("FT0A", "T0A amplitude", kTH1F, {{500, 0.0, 500.0}}); @@ -440,14 +466,14 @@ struct ExclusiveRhoTo4Pi { histosData.add("vertexX", "Vertex X; Vertex X [cm]; Counts", kTH1F, {{2000, -0.05, 0.05}}); histosData.add("vertexY", "Vertex Y; Vertex Y [cm]; Counts", kTH1F, {{2000, -0.05, 0.05}}); histosData.add("vertexZ", "Vertex Z; Vertex Z [cm]; Counts", kTH1F, {{2000, -15, 15}}); - histosData.add("GapSide", "Gap Side;Gap Side; Events", kTH1F, {{4, -1.5, 2.5}}); - histosData.add("TrueGapSide", "True Gap Side; True Gap Side; Events", kTH1F, {{4, -1.5, 2.5}}); + histosData.add("GapSide", "Gap Side;Gap Side; Events", kTH1F, {{4, 0, 4}}); + histosData.add("TrueGapSide", "True Gap Side; True Gap Side; Events", kTH1F, {{4, 0, 4}}); histosData.add("occupancy", "Occupancy; Occupancy; Counts", kTH1F, {{20000, 0, 20000}}); // QA plots: tracks - histosData.add("dcaXY_all", "dcaXY; dcaXY [cm]; Counts", kTH1F, {{5000, -1, 1}}); - histosData.add("dcaXY_pions", "dcaXY_pions; dcaXY of Pions [cm]; Counts", kTH1F, {{5000, -1, 1}}); - histosData.add("dcaZ_all", "dcaZ; dcaZ [cm]; Counts", kTH1F, {{5000, -1, 1}}); - histosData.add("dcaZ_pions", "dcaZ_pions; dcaZ of Pions [cm]; Counts", kTH1F, {{5000, -1, 1}}); + histosData.add("dcaXY_all", "dcaXY; dcaXY [cm]; Counts", kTH1F, {{2000, -0.1, 0.1}}); + histosData.add("dcaXY_pions", "dcaXY_pions; dcaXY of Pions [cm]; Counts", kTH1F, {{2000, -0.1, 0.1}}); + histosData.add("dcaZ_all", "dcaZ; dcaZ [cm]; Counts", kTH1F, {{2000, -0.1, 0.1}}); + histosData.add("dcaZ_pions", "dcaZ_pions; dcaZ of Pions [cm]; Counts", kTH1F, {{2000, -0.1, 0.1}}); histosData.add("itsChi2NCl_all", "ITS Chi2/NCl; Chi2/NCl; Counts", kTH1F, {{250, 0, 50}}); histosData.add("itsChi2_all", "ITS Chi2; ITS Chi2; Counts", kTH1F, {{500, 0, 50}}); histosData.add("tpcChi2NCl_all", "TPC Chi2/NCl; Chi2/NCl; Counts", kTH1F, {{250, 0, 50}}); @@ -522,20 +548,9 @@ struct ExclusiveRhoTo4Pi { histosData.add("fourpion_mass_non_0_charge_domA", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for p_{T} < 0.15 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {invMassAxis}); // pT < 0.15GeV histosData.add("fourpion_mass_non_0_charge_domB", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for 0.15< p_{T} < 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {invMassAxis}); // 0.15GeV < pT < 0.8GeV histosData.add("fourpion_mass_non_0_charge_domC", "Invariant Mass Distribution of non 0 charge Events with PID Selection of Pi for p_{T} > 0.80 GeV/c; m(#pi^{+}#pi^{-}#pi^{+}#pi^{-}) [GeV/c]", kTH1F, {invMassAxis}); // 0.8GeV < pT - // Collin Soper Theta and Phi - histosData.add("collin_soper_phi_1", "#phi Distribution; #phi; Events", kTH1F, {phiAxis}); - histosData.add("collin_soper_phi_2", "#phi Distribution; #phi; Events", kTH1F, {phiAxis}); - histosData.add("collin_soper_costheta_1", "#theta Distribution;cos(#theta); Counts", kTH1F, {cosThetaAxis}); - histosData.add("collin_soper_costheta_2", "#theta Distribution;cos(#theta); Counts", kTH1F, {cosThetaAxis}); - histosData.add("phi_vs_costheta_1", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {phiAxis, cosThetaAxis}); - histosData.add("phi_vs_costheta_2", "Phi vs cosTheta; #phi; cos(#theta)", kTH2F, {phiAxis, cosThetaAxis}); // Collin Soper Theta and Phi after selection - histosData.add("collin_soper_phi_small_mass", "#phi Distribution; #phi; Events", kTH1F, {phiAxis}); - histosData.add("collin_soper_phi_large_mass", "#phi Distribution; #phi; Events", kTH1F, {phiAxis}); - histosData.add("collin_soper_costheta_small_mass", "#theta Distribution;cos(#theta); Counts", kTH1F, {cosThetaAxis}); - histosData.add("collin_soper_costheta_large_mass", "#theta Distribution;cos(#theta); Counts", kTH1F, {cosThetaAxis}); - histosData.add("phi_vs_costheta_small_mass", "Phi vs cosTheta for small mass; #phi; cos(#theta)", kTH2F, {phiAxis, cosThetaAxis}); - histosData.add("phi_vs_costheta_large_mass", "Phi vs cosTheta for large mass; #phi; cos(#theta)", kTH2F, {phiAxis, cosThetaAxis}); + histosData.add("CSphi_vs_CScosTheta", "Phi vs cosTheta for small mass; #phi; cos(#theta)", kTH2F, {phiAxis, cosThetaAxis}); + setHistBinLabels(); } // End of init function //--------------------------------------------------------------------------------------------------------------------------------------------- @@ -547,6 +562,9 @@ struct ExclusiveRhoTo4Pi { Filter bcSelectionCuts = (o2::aod::udcollision::sbp == sbpCut) && (o2::aod::udcollision::itsROFb == itsROFbCut) && (o2::aod::udcollision::vtxITSTPC == vtxITSTPCcut) && (o2::aod::udcollision::tfb == tfbCut); // Track Cuts Filter onlyPVtracks = o2::aod::udtrack::isPVContributor == useOnlyPVtracks; + Filter tpcchi2nclsFilter = o2::aod::track::tpcChi2NCl <= tpcChi2NClsCut; + Filter itschi2nclsFilter = o2::aod::track::itsChi2NCl <= itsChi2NClsCut; + Filter tpcCuts = (nabs(o2::aod::pidtpc::tpcNSigmaPi) <= nSigmaTPCcut); //--------------------------------------------------------------------------------------------------------------------------------------------- using UDtracks = soa::Join; @@ -554,6 +572,9 @@ struct ExclusiveRhoTo4Pi { void processData(soa::Filtered::iterator const& collision, soa::Filtered const& tracks) { + + int runIndex = getRunNumberIndex(collision.runNumber()); + // Check if the Event is reconstructed in UPC mode if (ifCheckUPCmode && (collision.flags() != 1)) { return; @@ -601,7 +622,7 @@ struct ExclusiveRhoTo4Pi { int numPionMinusTracks = static_cast(selectedPionMinusTracks.size()); for (int i = 0; i < numSelectedTracks; i++) { - ROOT::Math::PxPyPzMVector selectedTrackVector(selectedTracks[i].px(), selectedTracks[i].py(), selectedTracks[i].pz(), o2::constants::physics::MassPionCharged); + PxPyPzMVector selectedTrackVector(selectedTracks[i].px(), selectedTracks[i].py(), selectedTracks[i].pz(), o2::constants::physics::MassPionCharged); histosData.fill(HIST("pT_track_all"), selectedTrackVector.Pt()); histosData.fill(HIST("eta_track_all"), selectedTrackVector.Eta()); histosData.fill(HIST("phi_track_all"), selectedTrackVector.Phi()); @@ -622,7 +643,7 @@ struct ExclusiveRhoTo4Pi { } // End of loop over tracks with selection only for (int i = 0; i < numSelectedPionTracks; i++) { - ROOT::Math::PxPyPzMVector selectedPionTrackVector(selectedPionTracks[i].px(), selectedPionTracks[i].py(), selectedPionTracks[i].pz(), o2::constants::physics::MassPionCharged); + PxPyPzMVector selectedPionTrackVector(selectedPionTracks[i].px(), selectedPionTracks[i].py(), selectedPionTracks[i].pz(), o2::constants::physics::MassPionCharged); histosData.fill(HIST("pT_track_pions"), selectedPionTrackVector.Pt()); histosData.fill(HIST("eta_track_pions"), selectedPionTrackVector.Eta()); @@ -664,12 +685,12 @@ struct ExclusiveRhoTo4Pi { // Selecting Events with net charge = 0 if (numPionMinusTracks == numPiMinus && numPiPlusTracks == numPiPlus) { - ROOT::Math::PtEtaPhiMVector k1, k2, k3, k4, k1234, k13, k14, k23, k24; + PtEtaPhiMVector k1, k2, k3, k4, k1234, k13, k14, k23, k24; - ROOT::Math::PxPyPzMVector p1(selectedPionPlusTracks[0].px(), selectedPionPlusTracks[0].py(), selectedPionPlusTracks[0].pz(), o2::constants::physics::MassPionCharged); - ROOT::Math::PxPyPzMVector p2(selectedPionPlusTracks[1].px(), selectedPionPlusTracks[1].py(), selectedPionPlusTracks[1].pz(), o2::constants::physics::MassPionCharged); - ROOT::Math::PxPyPzMVector p3(selectedPionMinusTracks[0].px(), selectedPionMinusTracks[0].py(), selectedPionMinusTracks[0].pz(), o2::constants::physics::MassPionCharged); - ROOT::Math::PxPyPzMVector p4(selectedPionMinusTracks[1].px(), selectedPionMinusTracks[1].py(), selectedPionMinusTracks[1].pz(), o2::constants::physics::MassPionCharged); + PxPyPzMVector p1(selectedPionPlusTracks[0].px(), selectedPionPlusTracks[0].py(), selectedPionPlusTracks[0].pz(), o2::constants::physics::MassPionCharged); + PxPyPzMVector p2(selectedPionPlusTracks[1].px(), selectedPionPlusTracks[1].py(), selectedPionPlusTracks[1].pz(), o2::constants::physics::MassPionCharged); + PxPyPzMVector p3(selectedPionMinusTracks[0].px(), selectedPionMinusTracks[0].py(), selectedPionMinusTracks[0].pz(), o2::constants::physics::MassPionCharged); + PxPyPzMVector p4(selectedPionMinusTracks[1].px(), selectedPionMinusTracks[1].py(), selectedPionMinusTracks[1].pz(), o2::constants::physics::MassPionCharged); histosData.fill(HIST("pT_track_pions_contributed"), p1.Pt()); histosData.fill(HIST("pT_track_pions_contributed"), p2.Pt()); @@ -696,7 +717,7 @@ struct ExclusiveRhoTo4Pi { k3.SetCoordinates(p3.Pt(), p3.Eta(), p3.Phi(), o2::constants::physics::MassPionCharged); k4.SetCoordinates(p4.Pt(), p4.Eta(), p4.Phi(), o2::constants::physics::MassPionCharged); - ROOT::Math::PxPyPzMVector p1234 = p1 + p2 + p3 + p4; + PxPyPzMVector p1234 = p1 + p2 + p3 + p4; k1234 = k1 + k2 + k3 + k4; k13 = k1 + k3; @@ -710,10 +731,14 @@ struct ExclusiveRhoTo4Pi { histosData.fill(HIST("fourpion_rap_0_charge"), p1234.Rapidity()); histosData.fill(HIST("fourpion_mass_0_charge"), p1234.M()); - double fourPiPhiPair1 = phiCollinsSoperFrame(k13, k24, k1234); - double fourPiPhiPair2 = phiCollinsSoperFrame(k14, k23, k1234); - double fourPiCosThetaPair1 = cosThetaCollinsSoperFrame(k13, k24, k1234); - double fourPiCosThetaPair2 = cosThetaCollinsSoperFrame(k14, k23, k1234); + double fourPiPhiPair1 = collinSoperPhi(k13, k1234); + double fourPiPhiPair2 = collinSoperPhi(k14, k1234); + double fourPiPhiPair3 = collinSoperPhi(k23, k1234); + double fourPiPhiPair4 = collinSoperPhi(k24, k1234); + double fourPiCosThetaPair1 = collinSoperCosTheta(k13, k1234); + double fourPiCosThetaPair2 = collinSoperCosTheta(k14, k1234); + double fourPiCosThetaPair3 = collinSoperCosTheta(k23, k1234); + double fourPiCosThetaPair4 = collinSoperCosTheta(k24, k1234); sigFromData( // run number @@ -768,7 +793,14 @@ struct ExclusiveRhoTo4Pi { // Four Mass p1234.M(), // Four Collins Soper Phi and CosTheta - fourPiPhiPair1, fourPiPhiPair2, fourPiCosThetaPair1, fourPiCosThetaPair2); + fourPiPhiPair1, fourPiPhiPair2, fourPiPhiPair3, fourPiPhiPair4, + fourPiCosThetaPair1, fourPiCosThetaPair2, fourPiCosThetaPair3, fourPiCosThetaPair4); + + histosCounter.fill(HIST("fourPionCounts_0c"), runIndex); + + if (rhoMassMin < p1234.M() && p1234.M() < rhoMassMax) { + histosCounter.fill(HIST("fourPionCounts_0c_within_mass"), runIndex); + } if (std::fabs(p1234.Rapidity()) < rhoRapCut) { histosData.fill(HIST("fourpion_pT_0_charge_within_rap"), p1234.Pt()); @@ -776,38 +808,34 @@ struct ExclusiveRhoTo4Pi { histosData.fill(HIST("fourpion_phi_0_charge_within_rap"), p1234.Phi()); histosData.fill(HIST("fourpion_rap_0_charge_within_rap"), p1234.Rapidity()); histosData.fill(HIST("fourpion_mass_0_charge_within_rap"), p1234.M()); + histosCounter.fill(HIST("fourPionCounts_0c_within_rap"), runIndex); if (p1234.Pt() < rhoPtCut) { - // Fill the Invariant Mass Histogram - histosData.fill(HIST("fourpion_mass_0_charge_domA"), p1234.M()); - // Two Pion Masses - histosData.fill(HIST("twopion_mass_1"), (p1 + p3).M()); - histosData.fill(HIST("twopion_mass_2"), (p1 + p4).M()); - histosData.fill(HIST("twopion_mass_3"), (p2 + p3).M()); - histosData.fill(HIST("twopion_mass_4"), (p2 + p4).M()); - // Fill the Collins-Soper Frame histograms - histosData.fill(HIST("collin_soper_phi_1"), fourPiPhiPair1); - histosData.fill(HIST("collin_soper_phi_2"), fourPiPhiPair2); - histosData.fill(HIST("collin_soper_costheta_1"), fourPiCosThetaPair1); - histosData.fill(HIST("collin_soper_costheta_2"), fourPiCosThetaPair2); - histosData.fill(HIST("phi_vs_costheta_1"), fourPiPhiPair1, fourPiCosThetaPair1); - histosData.fill(HIST("phi_vs_costheta_2"), fourPiPhiPair2, fourPiCosThetaPair2); - // Small Mass CosTheta and Phi - if ((k13.M() + k24.M()) > (k14.M() + k23.M())) { - histosData.fill(HIST("collin_soper_phi_large_mass"), fourPiPhiPair1); - histosData.fill(HIST("collin_soper_costheta_large_mass"), fourPiCosThetaPair1); - histosData.fill(HIST("phi_vs_costheta_large_mass"), fourPiPhiPair1, fourPiCosThetaPair1); - histosData.fill(HIST("collin_soper_phi_small_mass"), fourPiPhiPair2); - histosData.fill(HIST("collin_soper_costheta_small_mass"), fourPiCosThetaPair2); - histosData.fill(HIST("phi_vs_costheta_small_mass"), fourPiPhiPair2, fourPiCosThetaPair2); - } else { - histosData.fill(HIST("collin_soper_phi_small_mass"), fourPiPhiPair1); - histosData.fill(HIST("collin_soper_costheta_small_mass"), fourPiCosThetaPair1); - histosData.fill(HIST("phi_vs_costheta_small_mass"), fourPiPhiPair1, fourPiCosThetaPair1); - histosData.fill(HIST("collin_soper_phi_large_mass"), fourPiPhiPair2); - histosData.fill(HIST("collin_soper_costheta_large_mass"), fourPiCosThetaPair2); - histosData.fill(HIST("phi_vs_costheta_large_mass"), fourPiPhiPair2, fourPiCosThetaPair2); - } - } + if (rhoMassMin < p1234.M() && p1234.M() < rhoMassMax) { + // Selected Four Pion Events + histosCounter.fill(HIST("fourPionCounts_0c_selected"), runIndex); + // Fill the Invariant Mass Histogram + histosData.fill(HIST("fourpion_mass_0_charge_domA"), p1234.M()); + // Two Pion Masses + histosData.fill(HIST("twopion_mass_1"), (p1 + p3).M()); + histosData.fill(HIST("twopion_mass_2"), (p1 + p4).M()); + histosData.fill(HIST("twopion_mass_3"), (p2 + p3).M()); + histosData.fill(HIST("twopion_mass_4"), (p2 + p4).M()); + // Fill the Collins-Soper Frame histograms + double mDiff13 = std::abs((k13.M() - mRho0)); + double mDiff14 = std::abs((k14.M() - mRho0)); + double mDiff23 = std::abs((k23.M() - mRho0)); + double mDiff24 = std::abs((k24.M() - mRho0)); + if ((mDiff13 < mDiff14) && (mDiff13 < mDiff23) && (mDiff13 < mDiff24)) { + histosData.fill(HIST("CSphi_vs_CScosTheta"), fourPiPhiPair1, fourPiCosThetaPair1); + } else if ((mDiff14 < mDiff13) && (mDiff14 < mDiff23) && (mDiff14 < mDiff24)) { + histosData.fill(HIST("CSphi_vs_CScosTheta"), fourPiPhiPair2, fourPiCosThetaPair2); + } else if ((mDiff23 < mDiff13) && (mDiff23 < mDiff14) && (mDiff23 < mDiff24)) { + histosData.fill(HIST("CSphi_vs_CScosTheta"), fourPiPhiPair3, fourPiCosThetaPair3); + } else if ((mDiff24 < mDiff13) && (mDiff24 < mDiff14) && (mDiff24 < mDiff23)) { + histosData.fill(HIST("CSphi_vs_CScosTheta"), fourPiPhiPair4, fourPiCosThetaPair4); + } + } // End of Pt selection for rho mass + } // End of Pt selection for rho mass if (p1234.Pt() > rhoPtCut && p1234.Pt() < zeroPointEight) { histosData.fill(HIST("fourpion_mass_0_charge_domB"), p1234.M()); } @@ -820,11 +848,11 @@ struct ExclusiveRhoTo4Pi { // Selecting Events with net charge != 0 for estimation of background if (numPionMinusTracks != numPiMinus && numPiPlusTracks != numPiPlus) { - ROOT::Math::PxPyPzMVector p1(selectedPionTracks[0].px(), selectedPionTracks[0].py(), selectedPionTracks[0].pz(), o2::constants::physics::MassPionCharged); - ROOT::Math::PxPyPzMVector p2(selectedPionTracks[1].px(), selectedPionTracks[1].py(), selectedPionTracks[1].pz(), o2::constants::physics::MassPionCharged); - ROOT::Math::PxPyPzMVector p3(selectedPionTracks[2].px(), selectedPionTracks[2].py(), selectedPionTracks[2].pz(), o2::constants::physics::MassPionCharged); - ROOT::Math::PxPyPzMVector p4(selectedPionTracks[3].px(), selectedPionTracks[3].py(), selectedPionTracks[3].pz(), o2::constants::physics::MassPionCharged); - ROOT::Math::PxPyPzMVector p1234 = p1 + p2 + p3 + p4; + PxPyPzMVector p1(selectedPionTracks[0].px(), selectedPionTracks[0].py(), selectedPionTracks[0].pz(), o2::constants::physics::MassPionCharged); + PxPyPzMVector p2(selectedPionTracks[1].px(), selectedPionTracks[1].py(), selectedPionTracks[1].pz(), o2::constants::physics::MassPionCharged); + PxPyPzMVector p3(selectedPionTracks[2].px(), selectedPionTracks[2].py(), selectedPionTracks[2].pz(), o2::constants::physics::MassPionCharged); + PxPyPzMVector p4(selectedPionTracks[3].px(), selectedPionTracks[3].py(), selectedPionTracks[3].pz(), o2::constants::physics::MassPionCharged); + PxPyPzMVector p1234 = p1 + p2 + p3 + p4; histosData.fill(HIST("fourpion_pT_non_0_charge"), p1234.Pt()); histosData.fill(HIST("fourpion_eta_non_0_charge"), p1234.Eta()); @@ -885,14 +913,20 @@ struct ExclusiveRhoTo4Pi { // Four Mass p1234.M()); + histosCounter.fill(HIST("fourPionCounts_n0c"), runIndex); + if (rhoMassMin < p1234.M() && p1234.M() < rhoMassMax) { + histosCounter.fill(HIST("fourPionCounts_n0c_within_mass"), runIndex); + } if (std::fabs(p1234.Rapidity()) < rhoRapCut) { histosData.fill(HIST("fourpion_pT_non_0_charge_within_rap"), p1234.Pt()); histosData.fill(HIST("fourpion_eta_non_0_charge_within_rap"), p1234.Eta()); histosData.fill(HIST("fourpion_phi_non_0_charge_within_rap"), p1234.Phi()); histosData.fill(HIST("fourpion_rap_non_0_charge_within_rap"), p1234.Rapidity()); histosData.fill(HIST("fourpion_mass_non_0_charge_within_rap"), p1234.M()); + histosCounter.fill(HIST("fourPionCounts_n0c_within_rap"), runIndex); if (p1234.Pt() < rhoPtCut) { histosData.fill(HIST("fourpion_mass_non_0_charge_domA"), p1234.M()); + histosCounter.fill(HIST("fourPionCounts_n0c_selected"), runIndex); } if (p1234.Pt() > rhoPtCut && p1234.Pt() < zeroPointEight) { histosData.fill(HIST("fourpion_mass_non_0_charge_domB"), p1234.M()); @@ -904,102 +938,106 @@ struct ExclusiveRhoTo4Pi { } // End of Analysis for non 0 charge events } // End of 4 Pion Analysis Process function for Pass5 Data - void processCounter(UDCollisions::iterator const& collision, UDtracks const& tracks) + void processEventCounter(UDCollisions::iterator const& collision) { - histosCounter.fill(HIST("EventsCounts_vs_runNo"), collision.runNumber(), 0); + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 0); // UPC mode if (ifCheckUPCmode && collision.flags() != 1) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), collision.runNumber(), 1); + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 1); // vtxITSTPC if (collision.vtxITSTPC() != vtxITSTPCcut) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), collision.runNumber(), 2); + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 2); // sbp if (collision.sbp() != sbpCut) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), collision.runNumber(), 3); + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 3); // itsROFb if (collision.itsROFb() != itsROFbCut) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), collision.runNumber(), 4); + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 4); // tfb if (collision.tfb() != tfbCut) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), collision.runNumber(), 5); + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 5); // FT0A if (collision.totalFT0AmplitudeA() > ft0aCut) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), collision.runNumber(), 6); + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 6); // FT0C if (collision.totalFT0AmplitudeC() > ft0cCut) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), collision.runNumber(), 7); + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 7); // FV0A if (collision.totalFV0AmplitudeA() > fv0Cut) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), collision.runNumber(), 8); + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 8); // ZDC if (collision.energyCommonZNA() > zdcCut || collision.energyCommonZNC() > zdcCut) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), collision.runNumber(), 9); + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 9); // numContributors if (collision.numContrib() != numPVContrib) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), collision.runNumber(), 10); + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 10); // vertexZ if (std::abs(collision.posZ()) > vZCut) { return; } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), collision.runNumber(), 11); - - std::vector selectedPionTracks; - std::vector selectedPionPlusTracks; - std::vector selectedPionMinusTracks; + histosCounter.fill(HIST("EventsCounts_vs_runNo"), getRunNumberIndex(collision.runNumber()), 11); + } // End of processCounter function + void processTrackCounter(soa::Filtered::iterator const& collision, UDtracks const& tracks) + { + int runIndex = getRunNumberIndex(collision.runNumber()); + // Check if the Event is reconstructed in UPC mode + if (ifCheckUPCmode && (collision.flags() != 1)) { + return; + } for (const auto& track : tracks) { - histosCounter.fill(HIST("TracksCounts_vs_runNo"), collision.runNumber(), 0); - ROOT::Math::PxPyPzMVector trackVector(track.px(), track.py(), track.pz(), o2::constants::physics::MassPionCharged); + histosCounter.fill(HIST("TracksCounts_vs_runNo"), runIndex, 0); + PxPyPzMVector trackVector(track.px(), track.py(), track.pz(), o2::constants::physics::MassPionCharged); // is PV contributor if (track.isPVContributor() != useOnlyPVtracks) { continue; } - histosCounter.fill(HIST("TracksCounts_vs_runNo"), collision.runNumber(), 1); + histosCounter.fill(HIST("TracksCounts_vs_runNo"), runIndex, 1); // pt cut if (trackVector.Pt() < pTcut) { continue; } - histosCounter.fill(HIST("TracksCounts_vs_runNo"), collision.runNumber(), 2); + histosCounter.fill(HIST("TracksCounts_vs_runNo"), runIndex, 2); // eta cut if (std::abs(trackVector.Eta()) > etaCut) { continue; } - histosCounter.fill(HIST("TracksCounts_vs_runNo"), collision.runNumber(), 3); + histosCounter.fill(HIST("TracksCounts_vs_runNo"), runIndex, 3); // DCA Z cut if (std::abs(track.dcaZ()) > dcaZcut) { continue; } - histosCounter.fill(HIST("TracksCounts_vs_runNo"), collision.runNumber(), 4); + histosCounter.fill(HIST("TracksCounts_vs_runNo"), runIndex, 4); // DCA XY cut float maxDCAxy = 0.0105 + 0.035 / std::pow(trackVector.Pt(), 1.1); if (dcaXYcut == 0 && (std::fabs(track.dcaXY()) > maxDCAxy)) { @@ -1007,128 +1045,87 @@ struct ExclusiveRhoTo4Pi { } else if (dcaXYcut != 0 && (std::fabs(track.dcaXY()) > dcaXYcut)) { continue; } - histosCounter.fill(HIST("TracksCounts_vs_runNo"), collision.runNumber(), 5); + histosCounter.fill(HIST("TracksCounts_vs_runNo"), runIndex, 5); // ITS Track only if (useITStracksOnly && !track.hasITS()) { continue; } - histosCounter.fill(HIST("TracksCounts_vs_runNo"), collision.runNumber(), 6); + histosCounter.fill(HIST("TracksCounts_vs_runNo"), runIndex, 6); // TPC Track only if (useTPCtracksOnly && !track.hasTPC()) { continue; } - histosCounter.fill(HIST("TracksCounts_vs_runNo"), collision.runNumber(), 7); + histosCounter.fill(HIST("TracksCounts_vs_runNo"), runIndex, 7); // ITS Chi2 N Clusters cut if (track.hasITS() && track.itsChi2NCl() > itsChi2NClsCut) { continue; } - histosCounter.fill(HIST("TracksCounts_vs_runNo"), collision.runNumber(), 8); + histosCounter.fill(HIST("TracksCounts_vs_runNo"), runIndex, 8); // TPC Chi2 N Clusters cut if (track.hasTPC() && track.tpcChi2NCl() > tpcChi2NClsCut) { continue; } - histosCounter.fill(HIST("TracksCounts_vs_runNo"), collision.runNumber(), 9); + histosCounter.fill(HIST("TracksCounts_vs_runNo"), runIndex, 9); // TPC N Clusters Findable cut if (track.hasTPC() && track.tpcNClsFindable() < tpcNClsFindableCut) { continue; } - histosCounter.fill(HIST("TracksCounts_vs_runNo"), collision.runNumber(), 10); + histosCounter.fill(HIST("TracksCounts_vs_runNo"), runIndex, 10); // Selection PID Pion if (selectionPIDPion(track, useTOF, nSigmaTPCcut, nSigmaTOFcut)) { - histosCounter.fill(HIST("TracksCounts_vs_runNo"), collision.runNumber(), 11); - selectedPionTracks.push_back(track); + histosCounter.fill(HIST("TracksCounts_vs_runNo"), runIndex, 11); if (track.sign() == 1) { - histosCounter.fill(HIST("TracksCounts_vs_runNo"), collision.runNumber(), 12); - selectedPionPlusTracks.push_back(track); + histosCounter.fill(HIST("TracksCounts_vs_runNo"), runIndex, 12); } if (track.sign() == -1) { - histosCounter.fill(HIST("TracksCounts_vs_runNo"), collision.runNumber(), 13); - selectedPionMinusTracks.push_back(track); + histosCounter.fill(HIST("TracksCounts_vs_runNo"), runIndex, 13); } } // End of Selection PID Pion } // End of loop over tracks - - int numSelectedPionTracks = static_cast(selectedPionTracks.size()); - int numPiPlusTracks = static_cast(selectedPionPlusTracks.size()); - int numPionMinusTracks = static_cast(selectedPionMinusTracks.size()); - // Events with 4 pions - if (numSelectedPionTracks != numFourPionTracks) { - return; - } - histosCounter.fill(HIST("EventsCounts_vs_runNo"), collision.runNumber(), 12); - - // Selecting Events with net charge = 0 - if (numPionMinusTracks == numPiMinus && numPiPlusTracks == numPiPlus) { - histosCounter.fill(HIST("EventsCounts_vs_runNo"), collision.runNumber(), 13); - ROOT::Math::PxPyPzMVector p1(selectedPionPlusTracks[0].px(), selectedPionPlusTracks[0].py(), selectedPionPlusTracks[0].pz(), o2::constants::physics::MassPionCharged); - ROOT::Math::PxPyPzMVector p2(selectedPionPlusTracks[1].px(), selectedPionPlusTracks[1].py(), selectedPionPlusTracks[1].pz(), o2::constants::physics::MassPionCharged); - ROOT::Math::PxPyPzMVector p3(selectedPionMinusTracks[0].px(), selectedPionMinusTracks[0].py(), selectedPionMinusTracks[0].pz(), o2::constants::physics::MassPionCharged); - ROOT::Math::PxPyPzMVector p4(selectedPionMinusTracks[1].px(), selectedPionMinusTracks[1].py(), selectedPionMinusTracks[1].pz(), o2::constants::physics::MassPionCharged); - ROOT::Math::PxPyPzMVector p1234 = p1 + p2 + p3 + p4; - - if ((p1234.Pt() < rhoPtCut) && (std::abs(p1234.Rapidity()) < rhoRapCut)) { - histosCounter.fill(HIST("EventsCounts_vs_runNo"), collision.runNumber(), 14); - if ((rhoMassMin < p1234.M()) && (p1234.M() < rhoMassMax)) { - histosCounter.fill(HIST("EventsCounts_vs_runNo"), collision.runNumber(), 15); - } - } - } // End of Zero Charge Events - - if (numPionMinusTracks != numPiMinus && numPiPlusTracks != numPiPlus) { - histosCounter.fill(HIST("EventsCounts_vs_runNo"), collision.runNumber(), 16); - } // End of Non Zero Charge Events - } // End of processCounter function - PROCESS_SWITCH(ExclusiveRhoTo4Pi, processData, "The Process for 4 Pion Analysis from data", true); - PROCESS_SWITCH(ExclusiveRhoTo4Pi, processCounter, "The Process for 4 Pion Analysis from data", true); + PROCESS_SWITCH(ExclusiveRhoTo4Pi, processData, "Data Analysis Function", true); + PROCESS_SWITCH(ExclusiveRhoTo4Pi, processEventCounter, "Event Counter Function", true); + PROCESS_SWITCH(ExclusiveRhoTo4Pi, processTrackCounter, "Track Counter Function", true); - double cosThetaCollinsSoperFrame(ROOT::Math::PtEtaPhiMVector pair1, ROOT::Math::PtEtaPhiMVector pair2, ROOT::Math::PtEtaPhiMVector fourpion) + double collinSoperPhi(PtEtaPhiMVector twoPionVector, PtEtaPhiMVector fourPionVector) { + // Half of the energy per pair of the colliding nucleons. double halfSqrtSnn = 2680.; double massOfLead208 = 193.6823; double momentumBeam = std::sqrt(halfSqrtSnn * halfSqrtSnn * 208 * 208 - massOfLead208 * massOfLead208); - ROOT::Math::PxPyPzEVector pProjCM(0., 0., -momentumBeam, halfSqrtSnn * 208); // projectile - ROOT::Math::PxPyPzEVector pTargCM(0., 0., momentumBeam, halfSqrtSnn * 208); // target - ROOT::Math::PtEtaPhiMVector v1 = pair1; - ROOT::Math::PtEtaPhiMVector v2 = pair2; - ROOT::Math::PtEtaPhiMVector v12 = fourpion; + PxPyPzEVector pProjCM(0., 0., -momentumBeam, halfSqrtSnn * 208); // projectile + PxPyPzEVector pTargCM(0., 0., momentumBeam, halfSqrtSnn * 208); // target // Boost to center of mass frame - ROOT::Math::Boost boostv12{v12.BoostToCM()}; - ROOT::Math::XYZVectorF v1CM{(boostv12(v1).Vect()).Unit()}; - ROOT::Math::XYZVectorF v2CM{(boostv12(v2).Vect()).Unit()}; - ROOT::Math::XYZVectorF beam1CM{(boostv12(pProjCM).Vect()).Unit()}; - ROOT::Math::XYZVectorF beam2CM{(boostv12(pTargCM).Vect()).Unit()}; + Boost boosTo4PiCM{fourPionVector.BoostToCM()}; + XYZVectorF twoPionVectorCM{(boosTo4PiCM(twoPionVector).Vect()).Unit()}; + XYZVectorF beam1CM{(boosTo4PiCM(pProjCM).Vect()).Unit()}; + XYZVectorF beam2CM{(boosTo4PiCM(pTargCM).Vect()).Unit()}; // Axes - ROOT::Math::XYZVectorF zaxisCS{((beam1CM.Unit() - beam2CM.Unit()).Unit())}; - double cosThetaCS = zaxisCS.Dot((v1CM)); - return cosThetaCS; + XYZVectorF zaxisCS{((beam1CM.Unit() - beam2CM.Unit()).Unit())}; + XYZVectorF yaxisCS{(beam1CM.Cross(beam2CM)).Unit()}; + XYZVectorF xaxisCS{(yaxisCS.Cross(zaxisCS)).Unit()}; + double phi = std::atan2(yaxisCS.Dot(twoPionVectorCM), xaxisCS.Dot(twoPionVectorCM)); + return phi; } - double phiCollinsSoperFrame(ROOT::Math::PtEtaPhiMVector pair1, ROOT::Math::PtEtaPhiMVector pair2, ROOT::Math::PtEtaPhiMVector fourpion) + double collinSoperCosTheta(PtEtaPhiMVector twoPionVector, PtEtaPhiMVector fourPionVector) { // Half of the energy per pair of the colliding nucleons. double halfSqrtSnn = 2680.; double massOfLead208 = 193.6823; double momentumBeam = std::sqrt(halfSqrtSnn * halfSqrtSnn * 208 * 208 - massOfLead208 * massOfLead208); - ROOT::Math::PxPyPzEVector pProjCM(0., 0., -momentumBeam, halfSqrtSnn * 208); // projectile - ROOT::Math::PxPyPzEVector pTargCM(0., 0., momentumBeam, halfSqrtSnn * 208); // target - ROOT::Math::PtEtaPhiMVector v1 = pair1; - ROOT::Math::PtEtaPhiMVector v2 = pair2; - ROOT::Math::PtEtaPhiMVector v12 = fourpion; + PxPyPzEVector pProjCM(0., 0., -momentumBeam, halfSqrtSnn * 208); // projectile + PxPyPzEVector pTargCM(0., 0., momentumBeam, halfSqrtSnn * 208); // target // Boost to center of mass frame - ROOT::Math::Boost boostv12{v12.BoostToCM()}; - ROOT::Math::XYZVectorF v1CM{(boostv12(v1).Vect()).Unit()}; - ROOT::Math::XYZVectorF v2CM{(boostv12(v2).Vect()).Unit()}; - ROOT::Math::XYZVectorF beam1CM{(boostv12(pProjCM).Vect()).Unit()}; - ROOT::Math::XYZVectorF beam2CM{(boostv12(pTargCM).Vect()).Unit()}; + Boost boosTo4PiCM{fourPionVector.BoostToCM()}; + XYZVectorF twoPionVectorCM{(boosTo4PiCM(twoPionVector).Vect()).Unit()}; + XYZVectorF beam1CM{(boosTo4PiCM(pProjCM).Vect()).Unit()}; + XYZVectorF beam2CM{(boosTo4PiCM(pTargCM).Vect()).Unit()}; // Axes - ROOT::Math::XYZVectorF zaxisCS{((beam1CM.Unit() - beam2CM.Unit()).Unit())}; - ROOT::Math::XYZVectorF yaxisCS{(beam1CM.Cross(beam2CM)).Unit()}; - ROOT::Math::XYZVectorF xaxisCS{(yaxisCS.Cross(zaxisCS)).Unit()}; - - double phi = std::atan2(yaxisCS.Dot(v1CM), xaxisCS.Dot(v1CM)); - return phi; + XYZVectorF zaxisCS{((beam1CM.Unit() - beam2CM.Unit()).Unit())}; + double cosThetaCS = zaxisCS.Dot(twoPionVectorCM); + return cosThetaCS; } template @@ -1143,8 +1140,7 @@ struct ExclusiveRhoTo4Pi { float tpcchi2nclscut, float tpcnclsfindablecut) { - - ROOT::Math::PxPyPzMVector trackVector(track.px(), track.py(), track.pz(), o2::constants::physics::MassPionCharged); + PxPyPzMVector trackVector(track.px(), track.py(), track.pz(), o2::constants::physics::MassPionCharged); // pt cut if (trackVector.Pt() < ptcut) { return false; @@ -1187,8 +1183,79 @@ struct ExclusiveRhoTo4Pi { // All cuts passed return true; } // End of Track Selection function + + int getRunNumberIndex(int runNumber) + { + for (int i = 0; i < numRunNums; ++i) { + if (runNos[i] == runNumber) { + return i; + } + } + return -1; // Not found + } // End of getRunNumberIndex function + + void setHistBinLabels() + { + + std::string eventLabels[12] = { + "No Cuts", "UPC mode", "vtxITSTPC=1", "sbp=1", "itsROFb=1", "tfb=1", + "FT0A <= 50", "FT0C <= 50", "FV0A <= 50", "ZDC <= 0", + "n PV Contrib = 4", "V_{z} < 10cm"}; + + int numEventCuts = 12; + + std::string trackLabels[14] = { + "No Cuts", "isPVContributor", "pT > 0.15 GeV/c", "|#eta| < 0.9", "DCA Z < 2 cm", + "DCA XY cut", "hasITS", "hasTPC", "itsChi2NCl < 36", "tpcChi2NCl < 4", + "tpcNClsFindable < 70", "#pi tracks", "#pi^{+} tracks", "#pi^{-} tracks"}; + int numTrackCuts = 14; + + auto h1 = histosCounter.get(HIST("EventsCounts_vs_runNo")); + auto h2 = histosCounter.get(HIST("TracksCounts_vs_runNo")); + auto h3 = histosCounter.get(HIST("fourPionCounts_0c")); + auto h4 = histosCounter.get(HIST("fourPionCounts_0c_within_rap")); + auto h5 = histosCounter.get(HIST("fourPionCounts_0c_selected")); + auto h6 = histosCounter.get(HIST("fourPionCounts_n0c")); + auto h7 = histosCounter.get(HIST("fourPionCounts_n0c_within_rap")); + auto h8 = histosCounter.get(HIST("fourPionCounts_n0c_selected")); + + for (int i = 0; i < numRunNums; ++i) { + h1->GetXaxis()->SetBinLabel(i + 1, std::to_string(runNos[i]).c_str()); + h2->GetXaxis()->SetBinLabel(i + 1, std::to_string(runNos[i]).c_str()); + h3->GetXaxis()->SetBinLabel(i + 1, std::to_string(runNos[i]).c_str()); + h4->GetXaxis()->SetBinLabel(i + 1, std::to_string(runNos[i]).c_str()); + h5->GetXaxis()->SetBinLabel(i + 1, std::to_string(runNos[i]).c_str()); + h6->GetXaxis()->SetBinLabel(i + 1, std::to_string(runNos[i]).c_str()); + h7->GetXaxis()->SetBinLabel(i + 1, std::to_string(runNos[i]).c_str()); + h8->GetXaxis()->SetBinLabel(i + 1, std::to_string(runNos[i]).c_str()); + } + for (int i = 0; i < numEventCuts; ++i) { + h1->GetYaxis()->SetBinLabel(i + 1, eventLabels[i].c_str()); + } + for (int i = 0; i < numTrackCuts; ++i) { + h2->GetYaxis()->SetBinLabel(i + 1, trackLabels[i].c_str()); + } + + } // end of setHistBinLabels function + }; // End of Struct exclusiveRhoTo4Pi +int ExclusiveRhoTo4Pi::runNos[113] = { + 544013, 544028, 544032, 544091, 544095, 544098, 544116, 544121, 544122, 544123, + 544124, 544184, 544185, 544389, 544390, 544391, 544392, 544451, 544454, 544474, + 544475, 544476, 544477, 544490, 544491, 544492, 544508, 544510, 544511, 544512, + 544514, 544515, 544518, 544548, 544549, 544550, 544551, 544564, 544565, 544567, + 544568, 544580, 544582, 544583, 544585, 544614, 544640, 544652, 544653, 544672, + 544674, 544692, 544693, 544694, 544696, 544739, 544742, 544754, 544767, 544794, + 544795, 544797, 544813, 544868, 544886, 544887, 544896, 544911, 544913, 544914, + 544917, 544931, 544947, 544961, 544963, 544964, 544968, 544991, 544992, 545004, + 545008, 545009, 545041, 545042, 545044, 545047, 545060, 545062, 545063, 545064, + 545066, 545086, 545103, 545117, 545171, 545184, 545185, 545210, 545222, 545223, + 545246, 545249, 545262, 545289, 545291, 545294, 545295, 545296, 545311, 545312, + 545332, 545345, 545367}; + +int ExclusiveRhoTo4Pi::numRunNums = 113; + WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ diff --git a/PWGUD/Tasks/sginclusivePhiKstarSD.cxx b/PWGUD/Tasks/sginclusivePhiKstarSD.cxx index dad2b4d7a7d..4e139f0b763 100644 --- a/PWGUD/Tasks/sginclusivePhiKstarSD.cxx +++ b/PWGUD/Tasks/sginclusivePhiKstarSD.cxx @@ -104,6 +104,7 @@ struct SginclusivePhiKstarSD { Configurable qa{"qa", true, ""}; Configurable rapidityGap{"rapidityGap", true, ""}; + Configurable exclusive{"exclusive", false, "for double gap side "}; Configurable phi{"phi", true, ""}; Configurable rho{"rho", true, ""}; @@ -124,9 +125,10 @@ struct SginclusivePhiKstarSD { // Configurable axes for histogram ConfigurableAxis dcaAxisConfig{"dcaAxisConfig", {600, -0.3f, 0.3f}, "DCAxy & DCAz axis"}; ConfigurableAxis etaAxisConfig{"etaAxisConfig", {400, -1.0f, 1.0f}, "Pseudorapidity & Rapidity axis"}; - ConfigurableAxis VrtxXAxisConfig{"VrtxXAxisConfig", {400, -0.1f, 0.1f}, "Vertex X axis"}; - ConfigurableAxis VrtxYAxisConfig{"VrtxYAxisConfig", {200, -0.05f, 0.05f}, "Vertex Y axis"}; - ConfigurableAxis VrtxZAxisConfig{"VrtxZAxisConfig", {600, -15.0f, 15.0f}, "Vertex Z axis"}; + ConfigurableAxis vrtxXAxisConfig{"vrtxXAxisConfig", {400, -0.1f, 0.1f}, "Vertex X axis"}; + ConfigurableAxis vrtxYAxisConfig{"vrtxYAxisConfig", {200, -0.05f, 0.05f}, "Vertex Y axis"}; + ConfigurableAxis vrtxZAxisConfig{"vrtxZAxisConfig", {600, -15.0f, 15.0f}, "Vertex Z axis"}; + // ConfigurableAxis VrtxZAxisConfig{"VrtxZAxisConfig", {600, -15.0f, 15.0f}, "Vertex Z axis"}; void init(InitContext const& context) { @@ -135,9 +137,9 @@ struct SginclusivePhiKstarSD { AxisSpec dcazAxis = {dcaAxisConfig, "DCAz (cm)"}; AxisSpec etaAxis = {etaAxisConfig, "#eta"}; AxisSpec rapAxis = {etaAxisConfig, "y"}; - AxisSpec VrtxXAxis = {VrtxXAxisConfig, "Vertex X (cm)"}; - AxisSpec VrtxYAxis = {VrtxYAxisConfig, "Vertex Y (cm)"}; - AxisSpec VrtxZAxis = {VrtxZAxisConfig, "Vertex Z (cm)"}; + AxisSpec VrtxXAxis = {vrtxXAxisConfig, "Vertex X (cm)"}; + AxisSpec VrtxYAxis = {vrtxYAxisConfig, "Vertex Y (cm)"}; + AxisSpec VrtxZAxis = {vrtxZAxisConfig, "Vertex Z (cm)"}; registry.add("GapSide", "Gap Side; Entries", kTH1F, {{4, -1.5, 2.5}}); registry.add("TrueGapSide", "Gap Side; Entries", kTH1F, {{4, -1.5, 2.5}}); @@ -251,9 +253,6 @@ struct SginclusivePhiKstarSD { registry.add("hRap_ka", "Rapidity of selected Kaons; y; Counts", kTH1F, {rapAxis}); if (rapidityGap) { - registry.add("mult_0", "mult0", kTH1F, {{150, 0, 150}}); - registry.add("mult_1", "mult1", kTH1F, {{150, 0, 150}}); - registry.add("mult_2", "mult2", kTH1F, {{150, 0, 150}}); registry.add("event_rap_gap", "rap_gap", kTH1F, {{15, 0, 15.0}}); registry.add("rap_mult1", "rap_mult1", kTH1F, {{150, 0, 150}}); registry.add("rap_mult2", "rap_mult2", kTH1F, {{150, 0, 150}}); @@ -270,6 +269,10 @@ struct SginclusivePhiKstarSD { registry.add("gap_mult1", "Mult 1", kTH1F, {{100, 0.0, 100.0}}); registry.add("gap_mult2", "Mult 2", kTH1F, {{100, 0.0, 100.0}}); + registry.add("mult_0", "mult0", kTH1F, {{150, 0, 150}}); + registry.add("mult_1", "mult1", kTH1F, {{150, 0, 150}}); + registry.add("mult_2", "mult2", kTH1F, {{150, 0, 150}}); + // Multiplicity plot if (rapidityGap && phi) { registry.add("os_kk_mass_rap", "phi mass1", kTH3F, {{220, 0.98, 1.2}, {80, -2.0, 2.0}, {100, 0, 10}}); @@ -761,6 +764,15 @@ struct SginclusivePhiKstarSD { } } } + if (gapSide == 0) { + registry.fill(HIST("mult_0"), mult0); + } + if (gapSide == 1) { + registry.fill(HIST("mult_1"), mult1); + } + if (gapSide == 2) { + registry.fill(HIST("mult_2"), mult2); + } if (qa) { if (gapSide == 0) { registry.fill(HIST("V0A_0"), collision.totalFV0AmplitudeA()); @@ -768,7 +780,6 @@ struct SginclusivePhiKstarSD { registry.fill(HIST("FT0C_0"), collision.totalFT0AmplitudeC()); registry.fill(HIST("ZDC_A_0"), collision.energyCommonZNA()); registry.fill(HIST("ZDC_C_0"), collision.energyCommonZNC()); - registry.fill(HIST("mult_0"), mult0); } if (gapSide == 1) { registry.fill(HIST("V0A_1"), collision.totalFV0AmplitudeA()); @@ -776,7 +787,6 @@ struct SginclusivePhiKstarSD { registry.fill(HIST("FT0C_1"), collision.totalFT0AmplitudeC()); registry.fill(HIST("ZDC_A_1"), collision.energyCommonZNA()); registry.fill(HIST("ZDC_C_1"), collision.energyCommonZNC()); - registry.fill(HIST("mult_1"), mult1); } if (gapSide == 2) { registry.fill(HIST("V0A"), collision.totalFV0AmplitudeA()); @@ -784,7 +794,6 @@ struct SginclusivePhiKstarSD { registry.fill(HIST("FT0C"), collision.totalFT0AmplitudeC()); registry.fill(HIST("ZDC_A"), collision.energyCommonZNA()); registry.fill(HIST("ZDC_C"), collision.energyCommonZNC()); - registry.fill(HIST("mult_2"), mult2); } if (rapidityGap) { if (trackgapC > 0 && trackgapA == 0 && trackextra == 0) { @@ -1063,7 +1072,7 @@ struct SginclusivePhiKstarSD { if (gapSide == 1) { registry.fill(HIST("os_KK_pT_1"), v01.M(), v01.Rapidity(), v01.Pt()); } - if (gapSide == 2) { + if (exclusive && gapSide == 2 && mult2 == 2) { registry.fill(HIST("os_KK_pT_2"), v01.M(), v01.Rapidity(), v01.Pt()); } } @@ -1075,7 +1084,7 @@ struct SginclusivePhiKstarSD { if (gapSide == 1) { registry.fill(HIST("os_KK_ls_pT_1"), v01.M(), v01.Rapidity(), v01.Pt()); } - if (gapSide == 2) { + if (exclusive && gapSide == 2 && mult2 == 2) { registry.fill(HIST("os_KK_ls_pT_2"), v01.M(), v01.Rapidity(), v01.Pt()); } } @@ -1101,7 +1110,7 @@ struct SginclusivePhiKstarSD { if (gapSide == 1) { registry.fill(HIST("os_KK_rot_pT_1"), v01.M(), v01.Rapidity(), v01.Pt()); } - if (gapSide == 2) { + if (exclusive && gapSide == 2 && mult2 == 2) { registry.fill(HIST("os_KK_rot_pT_2"), v01.M(), v01.Rapidity(), v01.Pt()); } } @@ -1114,9 +1123,9 @@ struct SginclusivePhiKstarSD { continue; if (t0.globalIndex() == t1.globalIndex()) continue; - if (rho && selectionPIDProton(t0, useTof, nsigmaTpcCut, nsigmaTofCut) && selectionPIDPion1(t1)) { + if (rho && selectionPIDProton(t0, useTof, nsigmaTpcCut, nsigmaTofCut) && selectionPIDKaon1(t1)) { v0.SetCoordinates(t0.px(), t0.py(), t0.pz(), o2::constants::physics::MassProton); - v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassPionCharged); + v1.SetCoordinates(t1.px(), t1.py(), t1.pz(), o2::constants::physics::MassKaonCharged); v01 = v0 + v1; // Opposite sign pairs if (t0.sign() != t1.sign()) { @@ -1126,7 +1135,7 @@ struct SginclusivePhiKstarSD { if (gapSide == 1) { registry.fill(HIST("os_pp_pT_1"), v01.M(), v01.Rapidity(), v01.Pt()); } - if (gapSide == 2) { + if (exclusive && gapSide == 2 && mult2 == 2) { registry.fill(HIST("os_pp_pT_2"), v01.M(), v01.Rapidity(), v01.Pt()); } } // same sign pair @@ -1137,7 +1146,7 @@ struct SginclusivePhiKstarSD { if (gapSide == 1) { registry.fill(HIST("os_pp_ls_pT_1"), v01.M(), v01.Rapidity(), v01.Pt()); } - if (gapSide == 2) { + if (exclusive && gapSide == 2 && mult2 == 2) { registry.fill(HIST("os_pp_ls_pT_2"), v01.M(), v01.Rapidity(), v01.Pt()); } } @@ -1156,7 +1165,7 @@ struct SginclusivePhiKstarSD { if (gapSide == 1) { registry.fill(HIST("os_pk_pT_1"), v01.M(), v01.Rapidity(), v01.Pt()); } - if (gapSide == 2) { + if (exclusive && gapSide == 2 && mult2 == 2) { registry.fill(HIST("os_pk_pT_2"), v01.M(), v01.Rapidity(), v01.Pt()); } } // same sign pair @@ -1167,7 +1176,7 @@ struct SginclusivePhiKstarSD { if (gapSide == 1) { registry.fill(HIST("os_pk_ls_pT_1"), v01.M(), v01.Rapidity(), v01.Pt()); } - if (gapSide == 2) { + if (exclusive && gapSide == 2 && mult2 == 2) { registry.fill(HIST("os_pk_ls_pT_2"), v01.M(), v01.Rapidity(), v01.Pt()); } } @@ -1192,7 +1201,7 @@ struct SginclusivePhiKstarSD { if (gapSide == 1) { registry.fill(HIST("os_pk_rot_pT_1"), v01.M(), v01.Rapidity(), v01.Pt()); } - if (gapSide == 2) { + if (exclusive && gapSide == 2 && mult2 == 2) { registry.fill(HIST("os_pk_rot_pT_2"), v01.M(), v01.Rapidity(), v01.Pt()); } } diff --git a/PWGUD/Tasks/upcRhoPrimeAnalysis.cxx b/PWGUD/Tasks/upcRhoPrimeAnalysis.cxx index d4048806854..c1ebc114efa 100644 --- a/PWGUD/Tasks/upcRhoPrimeAnalysis.cxx +++ b/PWGUD/Tasks/upcRhoPrimeAnalysis.cxx @@ -12,322 +12,416 @@ /// \brief Task for analysis of rho' in UPCs using UD tables (from SG producer). /// \author Cesar Ramirez, cesar.ramirez@cern.ch -#include // Para std::string -#include // Para std::vector +#include "PWGUD/Core/UPCTauCentralBarrelHelperRL.h" +#include "PWGUD/DataModel/UDTables.h" + +#include "Common/DataModel/PIDResponse.h" -#include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" -#include "Math/Vector4D.h" // similiar to TLorentzVector (which is now legacy apparently) -#include +#include "Math/Vector4D.h" +#include "TH1F.h" +#include "TH2F.h" -#include "Common/DataModel/PIDResponse.h" - -#include "PWGUD/DataModel/UDTables.h" -#include "PWGUD/Core/UPCTauCentralBarrelHelperRL.h" +#include "random" +#include +#include +#include using namespace o2; using namespace o2::framework; -using namespace o2::framework::expressions; -using FullUDSgCollision = soa::Join::iterator; -using FullUDTracks = soa::Join; +// Define UD tables +using UDtracks = soa::Join; +using UDCollisions = soa::Join; namespace o2::aod { namespace fourpi { - -// for event -DECLARE_SOA_COLUMN(RunNumber, runNumber, int32_t); - -// for rho prime -DECLARE_SOA_COLUMN(M, m, double); -DECLARE_SOA_COLUMN(Pt, pt, double); -DECLARE_SOA_COLUMN(Eta, eta, double); -DECLARE_SOA_COLUMN(Phi, phi, double); - -// for vertex -DECLARE_SOA_COLUMN(PosX, posX, double); -DECLARE_SOA_COLUMN(PosY, posY, double); -DECLARE_SOA_COLUMN(PosZ, posZ, double); - -// for other -DECLARE_SOA_COLUMN(TotalCharge, totalCharge, int); - -// info detec -DECLARE_SOA_COLUMN(TotalFT0AmplitudeA, totalFT0AmplitudeA, float); -DECLARE_SOA_COLUMN(TotalFT0AmplitudeC, totalFT0AmplitudeC, float); -DECLARE_SOA_COLUMN(TotalFV0AmplitudeA, totalFV0AmplitudeA, float); -DECLARE_SOA_COLUMN(TotalFDDAmplitudeA, totalFDDAmplitudeA, float); -DECLARE_SOA_COLUMN(TotalFDDAmplitudeC, totalFDDAmplitudeC, float); -DECLARE_SOA_COLUMN(TimeFT0A, timeFT0A, float); -DECLARE_SOA_COLUMN(TimeFT0C, timeFT0C, float); -DECLARE_SOA_COLUMN(TimeFV0A, timeFV0A, float); -DECLARE_SOA_COLUMN(TimeFDDA, timeFDDA, float); -DECLARE_SOA_COLUMN(TimeFDDC, timeFDDC, float); - -// for pion tracks -DECLARE_SOA_COLUMN(NumContrib, numContrib, int32_t); -DECLARE_SOA_COLUMN(Sign, sign, std::vector); -DECLARE_SOA_COLUMN(TrackPt, trackPt, std::vector); -DECLARE_SOA_COLUMN(TrackEta, trackEta, std::vector); -DECLARE_SOA_COLUMN(TrackPhi, trackPhi, std::vector); -DECLARE_SOA_COLUMN(TPCNSigmaEl, tpcNSigmaEl, std::vector); -DECLARE_SOA_COLUMN(TPCNSigmaPi, tpcNSigmaPi, std::vector); -DECLARE_SOA_COLUMN(TPCNSigmaKa, tpcNSigmaKa, std::vector); -DECLARE_SOA_COLUMN(TPCNSigmaPr, tpcNSigmaPr, std::vector); -DECLARE_SOA_COLUMN(TrackID, trackID, std::vector); - -// for others -DECLARE_SOA_COLUMN(IsReconstructedWithUPC, isReconstructedWithUPC, bool); -DECLARE_SOA_COLUMN(TimeZNA, timeZNA, float); -DECLARE_SOA_COLUMN(TimeZNC, timeZNC, float); -DECLARE_SOA_COLUMN(EnergyCommonZNA, energyCommonZNA, float); -DECLARE_SOA_COLUMN(EnergyCommonZNC, energyCommonZNC, float); - +// Declare columns +DECLARE_SOA_COLUMN(RunNumber, runNumber, int32_t); // Run number for event identification +DECLARE_SOA_COLUMN(M, m, double); // Invariant mass of the system +DECLARE_SOA_COLUMN(Pt, pt, double); // Transverse momentum of the system +DECLARE_SOA_COLUMN(Eta, eta, double); // Pseudorapidity of the system +DECLARE_SOA_COLUMN(Phi, phi, double); // Azimuthal angle of the system +DECLARE_SOA_COLUMN(PosX, posX, double); // Vertex X position +DECLARE_SOA_COLUMN(PosY, posY, double); // Vertex Y position +DECLARE_SOA_COLUMN(PosZ, posZ, double); // Vertex Z position +DECLARE_SOA_COLUMN(TotalCharge, totalCharge, int); // Total charge of selected tracks +DECLARE_SOA_COLUMN(TotalFT0AmplitudeA, totalFT0AmplitudeA, float); // FT0A amplitude +DECLARE_SOA_COLUMN(TotalFT0AmplitudeC, totalFT0AmplitudeC, float); // FT0C amplitude +DECLARE_SOA_COLUMN(TotalFV0AmplitudeA, totalFV0AmplitudeA, float); // FV0A amplitude +DECLARE_SOA_COLUMN(NumContrib, numContrib, int32_t); // Number of primary vertex contributors +DECLARE_SOA_COLUMN(Sign, sign, std::vector); // Track charges +DECLARE_SOA_COLUMN(TrackPt, trackPt, std::vector); // Track pT values +DECLARE_SOA_COLUMN(TrackEta, trackEta, std::vector); // Track eta values +DECLARE_SOA_COLUMN(TrackPhi, trackPhi, std::vector); // Track phi values +DECLARE_SOA_COLUMN(TPCNSigmaEl, tpcNSigmaEl, std::vector); // TPC nσ for electrons +DECLARE_SOA_COLUMN(TPCNSigmaPi, tpcNSigmaPi, std::vector); // TPC nσ for pions +DECLARE_SOA_COLUMN(TPCNSigmaKa, tpcNSigmaKa, std::vector); // TPC nσ for kaons +DECLARE_SOA_COLUMN(TPCNSigmaPr, tpcNSigmaPr, std::vector); // TPC nσ for protons +DECLARE_SOA_COLUMN(TrackID, trackID, std::vector); // Track identifiers +DECLARE_SOA_COLUMN(IsReconstructedWithUPC, isReconstructedWithUPC, bool); // UPC mode reconstruction flag +DECLARE_SOA_COLUMN(TimeZNA, timeZNA, float); // ZNA timing +DECLARE_SOA_COLUMN(TimeZNC, timeZNC, float); // ZNC timing +DECLARE_SOA_COLUMN(EnergyCommonZNA, energyCommonZNA, float); // ZNA energy +DECLARE_SOA_COLUMN(EnergyCommonZNC, energyCommonZNC, float); // ZNC energy +DECLARE_SOA_COLUMN(IsChargeZero, isChargeZero, bool); // Neutral system flag +DECLARE_SOA_COLUMN(OccupancyInTime, occupancyInTime, int); // Occupancy in time +DECLARE_SOA_COLUMN(HadronicRate, hadronicRate, double); // Hadronic interaction rate } // namespace fourpi -DECLARE_SOA_TABLE(SYSTEMTREE, "AOD", "SystemTree", fourpi::RunNumber, fourpi::M, fourpi::Pt, fourpi::Eta, fourpi::Phi, - fourpi::PosX, fourpi::PosY, fourpi::PosZ, fourpi::TotalCharge, fourpi::TotalFT0AmplitudeA, fourpi::TotalFT0AmplitudeC, fourpi::TotalFV0AmplitudeA, - fourpi::TotalFDDAmplitudeA, fourpi::TotalFDDAmplitudeC, fourpi::TimeFT0A, fourpi::TimeFT0C, fourpi::TimeFV0A, fourpi::TimeFDDA, fourpi::TimeFDDC, - fourpi::NumContrib, fourpi::Sign, fourpi::TrackPt, fourpi::TrackEta, fourpi::TrackPhi, - fourpi::TPCNSigmaEl, fourpi::TPCNSigmaPi, fourpi::TPCNSigmaKa, fourpi::TPCNSigmaPr, fourpi::TrackID, fourpi::IsReconstructedWithUPC, - fourpi::TimeZNA, fourpi::TimeZNC, fourpi::EnergyCommonZNA, fourpi::EnergyCommonZNC); +// Define the output +DECLARE_SOA_TABLE(SYSTEMTREE, "AOD", "SystemTree", + fourpi::RunNumber, fourpi::M, fourpi::Pt, fourpi::Eta, fourpi::Phi, + fourpi::PosX, fourpi::PosY, fourpi::PosZ, fourpi::TotalCharge, + fourpi::TotalFT0AmplitudeA, fourpi::TotalFT0AmplitudeC, fourpi::TotalFV0AmplitudeA, + fourpi::NumContrib, + fourpi::Sign, fourpi::TrackPt, fourpi::TrackEta, fourpi::TrackPhi, + fourpi::TPCNSigmaEl, fourpi::TPCNSigmaPi, fourpi::TPCNSigmaKa, fourpi::TPCNSigmaPr, + fourpi::TrackID, fourpi::IsReconstructedWithUPC, + fourpi::TimeZNA, fourpi::TimeZNC, fourpi::EnergyCommonZNA, fourpi::EnergyCommonZNC, + fourpi::IsChargeZero, fourpi::OccupancyInTime, fourpi::HadronicRate); } // namespace o2::aod struct upcRhoPrimeAnalysis { Produces systemTree; - double PcEtaCut = 0.9; // physics coordination recommendation - + // System selection configuration + Configurable systemYCut{"systemYCut", 0.5, "Max Rapidity of rho prime"}; + Configurable systemPtCut{"systemPtCut", 0.1, "Min Pt of rho prime"}; + Configurable systemMassMinCut{"systemMassMinCut", 0.8, "Min Mass of rho prime"}; + Configurable systemMassMaxCut{"systemMassMaxCut", 2.2, "Max Mass of rho prime"}; + Configurable etaCut{"etaCut", 0.9, "Track Pseudorapidity"}; + + // Event selection configuration + Configurable vZCut{"vZCut", 10.0, "Cut on vertex Z position"}; + Configurable numPVContrib{"numPVContrib", 4, "Number of PV contributors"}; + Configurable fv0Cut{"fv0Cut", 50.0, "FV0 amplitude cut"}; + Configurable ft0aCut{"ft0aCut", 50.0, "FT0A amplitude cut"}; + Configurable ft0cCut{"ft0cCut", 50.0, "FT0C amplitude cut"}; + Configurable zdcCut{"zdcCut", 0.0, "ZDC energy cut"}; + Configurable sbpCut{"sbpCut", true, "SBP cut"}; + Configurable itsROFbCut{"itsROFbCut", true, "ITS ROFb cut"}; + Configurable vtxITSTPCcut{"vtxITSTPCcut", true, "Vertex ITS-TPC cut"}; + Configurable tfbCut{"tfbCut", true, "TFB cut"}; Configurable specifyGapSide{"specifyGapSide", true, "specify gap side for SG/DG produced data"}; Configurable gapSide{"gapSide", 2, "gap side for SG produced data"}; - Configurable requireTof{"requireTof", false, "require TOF signal"}; - - Configurable collisionsPosZMaxCut{"collisionsPosZMaxCut", 10.0, "max Z position cut on collisions"}; - Configurable ZNcommonEnergyCut{"ZNcommonEnergyCut", 0.0, "ZN common energy cut"}; - Configurable ZNtimeCut{"ZNtimeCut", 2.0, "ZN time cut"}; - - Configurable tracksTpcNSigmaPiCut{"tracksTpcNSigmaPiCut", 3.0, "TPC nSigma pion cut"}; - Configurable tracksDcaMaxCut{"tracksDcaMaxCut", 1.0, "max DCA cut on tracks"}; - - Configurable systemMassMinCut{"systemMassMinCut", 0.5, "min M cut for reco system"}; - Configurable systemMassMaxCut{"systemMassMaxCut", 1.2, "max M cut for reco system"}; - Configurable systemPtCut{"systemPtMaxCut", 0.1, "max pT cut for reco system"}; - Configurable systemYCut{"systemYCut", 0.9, "rapiditiy cut for reco system"}; - - ConfigurableAxis mAxis{"mAxis", {1000, 0.0, 10.0}, "m (GeV/#it{c}^{2})"}; - ConfigurableAxis mCutAxis{"mCutAxis", {70, 0.5, 1.2}, "m (GeV/#it{c}^{2})"}; - ConfigurableAxis ptAxis{"ptAxis", {1000, 0.0, 10.0}, "p_{T} (GeV/#it{c})"}; - ConfigurableAxis ptCutAxis{"ptCutAxis", {300, 0.0, 0.3}, "p_{T} (GeV/#it{c})"}; - ConfigurableAxis pt2Axis{"pt2Axis", {300, 0.0, 0.09}, "p_{T}^{2} (GeV^{2}/#it{c}^{2})"}; - ConfigurableAxis etaAxis{"etaAxis", {180, -0.9, 0.9}, "#eta"}; - ConfigurableAxis yAxis{"yAxis", {180, -0.9, 0.9}, "y"}; - ConfigurableAxis phiAxis{"phiAxis", {180, 0.0, o2::constants::math::TwoPI}, "#phi"}; - ConfigurableAxis phiAsymmAxis{"phiAsymmAxis", {182, -o2::constants::math::PI, o2::constants::math::PI}, "#phi"}; - ConfigurableAxis momentumFromPhiAxis{"momentumFromPhiAxis", {400, -0.1, 0.1}, "p (GeV/#it{c})"}; - ConfigurableAxis ptQuantileAxis{"ptQuantileAxis", {0, 0.0181689, 0.0263408, 0.0330488, 0.0390369, 0.045058, 0.0512604, 0.0582598, 0.066986, 0.0788085, 0.1}, "p_{T} (GeV/#it{c})"}; - - HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; - - void init(o2::framework::InitContext&) - { - // selection counter - std::vector selectionCounterLabels = {"all tracks", "PV contributor", "ITS + TPC hit", "TOF requirement", "DCA cut", "#eta cut", "2D TPC n#sigma_{#pi} cut"}; - - // 4PI SYSTEM - // registry.add("4pi/hM", ";m (GeV/#it{c}^{2});counts", kTH1D, {mAxis}); - // registry.add("4pi/hPt", ";p_{T} (GeV/#it{c});counts", kTH1D, {ptAxis}); - // registry.add("4pi/hEta", ";Eta (1);counts", kTH1D, {etaAxis}); - // registry.add("4pi/hPhi", ";Phi ();counts", kTH1D, {phiAxis}); - } - template - bool collisionPassesCuts(const C& collision) // collision cuts + // Track selection configuration + Configurable useOnlyPVtracks{"useOnlyPVtracks", true, "Use only PV tracks"}; + Configurable tpcChi2NClsCut{"tpcChi2NClsCut", 5.0, "TPC chi2/N clusters cut"}; + Configurable itsChi2NClsCut{"itsChi2NClsCut", 36.0, "ITS chi2/N clusters cut"}; + Configurable nSigmaTPCcut{"nSigmaTPCcut", 5.0, "TPC nSigma cut"}; + Configurable dcaXYcut{"dcaXYcut", 0, "dcaXY cut"}; + Configurable dcaZcut{"dcaZcut", 2, "dcaZ cut"}; + Configurable minTPCFindableClusters{"minTPCFindableClusters", 70, "Minimum number of findable TPC clusters"}; + + // Define histogram registry + HistogramRegistry registry{ + "registry", + {// Event flow histograms + {"Events/Flow", "Event flow;Cut;Counts", {HistType::kTH1F, {{9, 0, 9}}}}, + {"Events/VertexZ", "Vertex Z;z (cm);Counts", {HistType::kTH1F, {{200, -20, 20}}}}, + {"Events/NumContrib", "Number of contributors;N_{contrib};Counts", {HistType::kTH1F, {{100, 0, 100}}}}, + {"Events/FV0Amplitude", "FV0 amplitude;Amplitude;Counts", {HistType::kTH1F, {{200, 0, 200}}}}, + {"Events/FT0AmplitudeA", "FT0A amplitude;Amplitude;Counts", {HistType::kTH1F, {{200, 0, 200}}}}, + {"Events/FT0AmplitudeC", "FT0C amplitude;Amplitude;Counts", {HistType::kTH1F, {{200, 0, 200}}}}, + {"Events/ZDCEnergy", "ZDC energy;Energy (TeV);Counts", {HistType::kTH1F, {{200, 0, 2}}}}, + + // Track quality histograms + {"Tracks/Pt", "Track p_{T};p_{T} (GeV/c);Counts", {HistType::kTH1F, {{200, 0, 2}}}}, + {"Tracks/Eta", "Track #eta;#eta;Counts", {HistType::kTH1F, {{200, -2, 2}}}}, + {"Tracks/TPCNSigmaPi", "TPC n#sigma for #pi;n#sigma;Counts", {HistType::kTH1F, {{200, -10, 10}}}}, + {"Tracks/TPCChi2NCl", "TPC #chi^{2}/N_{cls};#chi^{2}/N_{cls};Counts", {HistType::kTH1F, {{200, 0, 20}}}}, + {"Tracks/ITSChi2NCl", "ITS #chi^{2}/N_{cls};#chi^{2}/N_{cls};Counts", {HistType::kTH1F, {{200, 0, 50}}}}, + {"Tracks/RejectionReasons", "Track rejection reasons;Reason;Counts", {HistType::kTH1F, {{12, 0, 12}}}}, + {"Tracks/DCASpectrum", "Track DCA spectrum;DCA (cm);Counts", {HistType::kTH1F, {{100, 0, 5}}}}, + {"Tracks/ChargeDistribution", "Track charge distribution;Charge;Counts", {HistType::kTH1F, {{3, -1.5, 1.5}}}}, + {"Tracks/TPCClusters", "TPC clusters findable;N_{clusters};Counts", {HistType::kTH1F, {{100, 0, 200}}}}, + + // System kinematics histograms + {"System/hM", ";m (GeV/#it{c}^{2});counts", {HistType::kTH1F, {{1000, 0.0, 10.0}}}}, + {"System/hPt", ";p_{T} (GeV/#it{c});counts", {HistType::kTH1F, {{1000, 0.0, 10.0}}}}, + {"System/hEta", ";#eta;counts", {HistType::kTH1F, {{180, -0.9, 0.9}}}}, + {"System/hPhi", ";#phi;counts", {HistType::kTH1F, {{180, 0.0, 6.28}}}}, + {"System/hY", ";y;counts", {HistType::kTH1F, {{180, -0.9, 0.9}}}}, + + // Comparison histograms + {"Cuts/MBefore", "Mass before cuts;m (GeV/c^{2});Counts", {HistType::kTH1F, {{1000, 0, 10}}}}, + {"Cuts/MAfter", "Mass after cuts;m (GeV/c^{2});Counts", {HistType::kTH1F, {{1000, 0, 10}}}}, + {"Cuts/PtBefore", "p_{T} before cuts;p_{T} (GeV/c);Counts", {HistType::kTH1F, {{1000, 0, 1}}}}, + {"Cuts/PtAfter", "p_{T} after cuts;p_{T} (GeV/c);Counts", {HistType::kTH1F, {{1000, 0, 10}}}}}}; + + void init(InitContext&) { - if (std::abs(collision.posZ()) > collisionsPosZMaxCut) - return false; - if (specifyGapSide && collision.gapSide() != gapSide) - return false; - return true; + // Configure event flow histogram labels + auto hFlow = registry.get(HIST("Events/Flow")); + hFlow->GetXaxis()->SetBinLabel(1, "All events"); + hFlow->GetXaxis()->SetBinLabel(2, "ITS-TPC cut"); + hFlow->GetXaxis()->SetBinLabel(3, "SBP cut"); + hFlow->GetXaxis()->SetBinLabel(4, "ITS ROFb cut"); + hFlow->GetXaxis()->SetBinLabel(5, "TFB cut"); + hFlow->GetXaxis()->SetBinLabel(6, "Gap Side cut"); + hFlow->GetXaxis()->SetBinLabel(7, "PV contrib cut"); + hFlow->GetXaxis()->SetBinLabel(8, "Z vtx cut"); + hFlow->GetXaxis()->SetBinLabel(9, "4 tracks cut"); + + // Configure track rejection reasons histogram labels + auto hReject = registry.get(HIST("Tracks/RejectionReasons")); + hReject->GetXaxis()->SetBinLabel(1, "All Tracks"); + hReject->GetXaxis()->SetBinLabel(2, "PV Contributor"); + hReject->GetXaxis()->SetBinLabel(3, "Has ITS+TPC"); + hReject->GetXaxis()->SetBinLabel(4, "pT > 0.1 GeV/c"); + hReject->GetXaxis()->SetBinLabel(5, "TPC chi2/cluster"); + hReject->GetXaxis()->SetBinLabel(6, "ITS chi2/cluster"); + hReject->GetXaxis()->SetBinLabel(7, "TPC clusters findable"); + hReject->GetXaxis()->SetBinLabel(8, "TPC nSigmaPi"); + hReject->GetXaxis()->SetBinLabel(9, "Eta acceptance"); + hReject->GetXaxis()->SetBinLabel(10, "DCAz cut"); + hReject->GetXaxis()->SetBinLabel(11, "DCAxy cut"); + hReject->GetXaxis()->SetBinLabel(12, "Accepted Tracks"); } - template - bool trackPassesCuts(const T& track) // track cuts (PID done separately) + void process(UDCollisions::iterator const& collision, UDtracks const& tracks) { - if (!track.isPVContributor()) - return false; - if (!track.hasITS() || !track.hasTPC()) - return false; - if (requireTof && !track.hasTOF()) - return false; - if (std::abs(track.dcaZ()) > tracksDcaMaxCut || std::abs(track.dcaXY()) > (0.0182 + 0.0350 / std::pow(track.pt(), 1.01))) // Run 2 dynamic DCA cut - return false; - if (std::abs(eta(track.px(), track.py(), track.pz())) > PcEtaCut) - return false; - return true; - } + // Count all processed events + registry.fill(HIST("Events/Flow"), 0); + + // Fill basic event diagnostics + registry.fill(HIST("Events/VertexZ"), collision.posZ()); + registry.fill(HIST("Events/NumContrib"), collision.numContrib()); + registry.fill(HIST("Events/FV0Amplitude"), collision.totalFV0AmplitudeA()); + registry.fill(HIST("Events/FT0AmplitudeA"), collision.totalFT0AmplitudeA()); + registry.fill(HIST("Events/FT0AmplitudeC"), collision.totalFT0AmplitudeC()); + registry.fill(HIST("Events/ZDCEnergy"), collision.energyCommonZNA()); + registry.fill(HIST("Events/ZDCEnergy"), collision.energyCommonZNC()); + + // Apply event selection cuts in sequence + if (collision.vtxITSTPC() != vtxITSTPCcut) + return; + registry.fill(HIST("Events/Flow"), 1); - template - bool tracksPassPiPID(const T& cutTracks) // n-dimensional PID cut - { - double radius = 0.0; - for (const auto& track : cutTracks) - radius += std::pow(track.tpcNSigmaPi(), 2); - return radius < std::pow(tracksTpcNSigmaPiCut, 2); - } + if (collision.sbp() != sbpCut) + return; + registry.fill(HIST("Events/Flow"), 2); - template - double tracksTotalCharge(const T& cutTracks) // total charge of selected tracks - { - double charge = 0.0; - for (const auto& track : cutTracks) - charge += track.sign(); - return charge; - } + if (collision.itsROFb() != itsROFbCut) + return; + registry.fill(HIST("Events/Flow"), 3); - bool systemPassCuts(const ROOT::Math::PxPyPzMVector& system) // system cuts - { - if (system.M() < systemMassMinCut || system.M() > systemMassMaxCut) - return false; - if (system.Pt() > systemPtCut) - return false; - if (std::abs(system.Rapidity()) > systemYCut) - return false; - return true; - } + if (collision.tfb() != tfbCut) + return; + registry.fill(HIST("Events/Flow"), 4); - ROOT::Math::PxPyPzMVector reconstructSystem(const std::vector& cutTracks4Vecs) // reconstruct system from 4-vectors - { - ROOT::Math::PxPyPzMVector system; - for (const auto& track4Vec : cutTracks4Vecs) - system += track4Vec; - return system; - } + if (specifyGapSide && collision.gapSide() != gapSide) + return; + if (collision.totalFV0AmplitudeA() > fv0Cut) + return; + if (collision.totalFT0AmplitudeA() > ft0aCut) + return; + if (collision.totalFT0AmplitudeC() > ft0cCut) + return; + if (collision.energyCommonZNA() > zdcCut || collision.energyCommonZNC() > zdcCut) + return; + registry.fill(HIST("Events/Flow"), 5); - double deltaPhi(const ROOT::Math::PxPyPzMVector& p1, const ROOT::Math::PxPyPzMVector& p2) - { - double dPhi = p1.Phi() - p2.Phi(); - if (dPhi > o2::constants::math::PI) - dPhi -= o2::constants::math::TwoPI; - else if (dPhi < -o2::constants::math::PI) - dPhi += o2::constants::math::TwoPI; - return dPhi; // calculate delta phi in (-pi, pi) - } + if (collision.numContrib() != numPVContrib) + return; + registry.fill(HIST("Events/Flow"), 6); - double getPhiRandom(const std::vector& cutTracks4Vecs) // decay phi anisotropy - { // two possible definitions of phi: randomize the tracks - std::vector indices = {0, 1}; - unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); // get time-based seed - std::shuffle(indices.begin(), indices.end(), std::default_random_engine(seed)); // shuffle indices - // calculate phi - ROOT::Math::PxPyPzMVector pOne = cutTracks4Vecs[indices[0]]; - ROOT::Math::PxPyPzMVector pTwo = cutTracks4Vecs[indices[1]]; - ROOT::Math::PxPyPzMVector pPlus = pOne + pTwo; - ROOT::Math::PxPyPzMVector pMinus = pOne - pTwo; - return deltaPhi(pPlus, pMinus); - } + if (std::abs(collision.posZ()) > vZCut) + return; + registry.fill(HIST("Events/Flow"), 7); - template - double getPhiCharge(const T& cutTracks, const std::vector& cutTracks4Vecs) - { // two possible definitions of phi: charge-based assignment - ROOT::Math::PxPyPzMVector pOne, pTwo; - if (cutTracks[0].sign() > 0) { - pOne = cutTracks4Vecs[0]; - pTwo = cutTracks4Vecs[1]; - } else { - pOne = cutTracks4Vecs[1]; - pTwo = cutTracks4Vecs[0]; - } - ROOT::Math::PxPyPzMVector pPlus = pOne + pTwo; - ROOT::Math::PxPyPzMVector pMinus = pOne - pTwo; - return deltaPhi(pPlus, pMinus); - } + std::vector posPions; + std::vector negPions; + posPions.reserve(2); + negPions.reserve(2); - void processReco(FullUDSgCollision const& collision, FullUDTracks const& tracks) - { + // Loop over all tracks in the event + for (const auto& track : tracks) { + registry.fill(HIST("Tracks/RejectionReasons"), 0); // Count all tracks - if (!collisionPassesCuts(collision)) - return; + // Track selection criteria applied in sequence: + if (useOnlyPVtracks && !track.isPVContributor()) { + registry.fill(HIST("Tracks/RejectionReasons"), 1); + continue; + } - // vectors for storing selected tracks and their 4-vectors - std::vector cutTracks; - std::vector cutTracks4Vecs; + if (!track.hasITS() || !track.hasTPC()) { + registry.fill(HIST("Tracks/RejectionReasons"), 2); + continue; + } - // int trackCounter = 0; - for (const auto& track : tracks) { + // Fill track spectra + registry.fill(HIST("Tracks/Pt"), track.pt()); + registry.fill(HIST("Tracks/Eta"), eta(track.px(), track.py(), track.pz())); + registry.fill(HIST("Tracks/TPCNSigmaPi"), track.tpcNSigmaPi()); + registry.fill(HIST("Tracks/TPCChi2NCl"), track.tpcChi2NCl()); + registry.fill(HIST("Tracks/ITSChi2NCl"), track.itsChi2NCl()); + registry.fill(HIST("Tracks/DCASpectrum"), std::hypot(track.dcaXY(), track.dcaZ())); + registry.fill(HIST("Tracks/ChargeDistribution"), track.sign()); + registry.fill(HIST("Tracks/TPCClusters"), track.tpcNClsFindable()); + + if (track.pt() <= 0.1f) { + registry.fill(HIST("Tracks/RejectionReasons"), 3); + continue; + } - if (!trackPassesCuts(track)) + if (track.tpcChi2NCl() > tpcChi2NClsCut) { + registry.fill(HIST("Tracks/RejectionReasons"), 4); continue; - // trackCounter++; - cutTracks.push_back(track); - cutTracks4Vecs.push_back(ROOT::Math::PxPyPzMVector(track.px(), track.py(), track.pz(), o2::constants::physics::MassPionCharged)); // apriori assume pion mass - } + } + if (track.itsChi2NCl() > itsChi2NClsCut) { + registry.fill(HIST("Tracks/RejectionReasons"), 5); + continue; + } - if (!tracksPassPiPID(cutTracks)) - return; - // reonstruct system and calculate total charge, save commonly used values into variables - ROOT::Math::PxPyPzMVector system = reconstructSystem(cutTracks4Vecs); - int totalCharge = tracksTotalCharge(cutTracks); - int nTracks = cutTracks.size(); - double mass = system.M(); - double pT = system.Pt(); - // double pTsquare = pT * pT; - double rapidity = system.Rapidity(); - double systemPhi = system.Phi() + o2::constants::math::PI; - - if (nTracks == 4 && tracksTotalCharge(cutTracks) == 0) { // 4pi system - - std::vector vTrackPt, vTrackEta, vTrackPhi; - std::vector vSign, vTrackID; - std::vector vTpcNSigmaEl, vTpcNSigmaPi, vTpcNSigmaKa, vTpcNSigmaPr; - - for (size_t i = 0; i < cutTracks.size(); i++) { - - double tPt = cutTracks[i].pt(); - double tEta = eta(cutTracks[i].px(), cutTracks[i].py(), cutTracks[i].pz()); - double tPhi = phi(cutTracks[i].px(), cutTracks[i].py()); - - vTrackPt.push_back(tPt); - vTrackEta.push_back(tEta); - vTrackPhi.push_back(tPhi); - vSign.push_back(cutTracks[i].sign()); - vTpcNSigmaEl.push_back(cutTracks[i].tpcNSigmaEl()); - vTpcNSigmaPi.push_back(cutTracks[i].tpcNSigmaPi()); - vTpcNSigmaKa.push_back(cutTracks[i].tpcNSigmaKa()); - vTpcNSigmaPr.push_back(cutTracks[i].tpcNSigmaPr()); - - vTrackID.push_back(i); + if (track.tpcNClsFindable() < minTPCFindableClusters) { + registry.fill(HIST("Tracks/RejectionReasons"), 6); + continue; } - bool isReconstructedWithUPC = false; + if (std::abs(track.tpcNSigmaPi()) > nSigmaTPCcut) { + registry.fill(HIST("Tracks/RejectionReasons"), 7); + continue; + } - if (collision.flags() == 1) { - isReconstructedWithUPC = true; - } else { - isReconstructedWithUPC = false; + float trackEta = eta(track.px(), track.py(), track.pz()); + if (std::abs(trackEta) > etaCut) { + registry.fill(HIST("Tracks/RejectionReasons"), 8); + continue; } - systemTree(collision.runNumber(), mass, pT, rapidity, systemPhi, collision.posX(), collision.posY(), collision.posZ(), totalCharge, - collision.totalFT0AmplitudeA(), collision.totalFT0AmplitudeC(), collision.timeFV0A(), collision.totalFDDAmplitudeA(), collision.totalFDDAmplitudeC(), - collision.timeFT0A(), collision.timeFT0C(), collision.timeFV0A(), collision.timeFDDA(), collision.timeFDDC(), - collision.numContrib(), vSign, vTrackPt, vTrackEta, vTrackPhi, vTpcNSigmaEl, vTpcNSigmaPi, vTpcNSigmaKa, vTpcNSigmaPr, vTrackID, isReconstructedWithUPC, - collision.timeZNA(), collision.timeZNC(), collision.energyCommonZNA(), collision.energyCommonZNC()); + if (std::abs(track.dcaZ()) > dcaZcut) { + registry.fill(HIST("Tracks/RejectionReasons"), 9); + continue; + } + + float maxDCAxy = 0.0105 + 0.035 / std::pow(track.pt(), 1.1); + if (dcaXYcut == 0 && (std::fabs(track.dcaXY()) > maxDCAxy)) { + registry.fill(HIST("Tracks/RejectionReasons"), 10); + continue; + } else if (dcaXYcut != 0 && (std::fabs(track.dcaXY()) > dcaXYcut)) { + registry.fill(HIST("Tracks/RejectionReasons"), 10); + continue; + } + + // Track passed all selection criteria + registry.fill(HIST("Tracks/RejectionReasons"), 11); + + if (track.sign() > 0 && posPions.size() < 2) { + posPions.push_back(track); + } else if (track.sign() < 0 && negPions.size() < 2) { + negPions.push_back(track); + } + + if (posPions.size() == 2 && negPions.size() == 2) + break; + } - // registry.fill(HIST("4pi/hM"), mass); - // registry.fill(HIST("4pi/hPt"), pT); - // registry.fill(HIST("4pi/hEta"), rapiditiy); - // registry.fill(HIST("4pi/hPhi"), system); + if (posPions.size() != 2 || negPions.size() != 2) { + return; + } + registry.fill(HIST("Events/Flow"), 8); + + std::vector selectedTracks; + selectedTracks.insert(selectedTracks.end(), posPions.begin(), posPions.end()); + selectedTracks.insert(selectedTracks.end(), negPions.begin(), negPions.end()); + + // Reconstruct the 4-pion system + ROOT::Math::PxPyPzMVector fourPionSystem; + std::vector pionFourVectors; + + for (const auto& track : selectedTracks) { + ROOT::Math::PxPyPzMVector pionVec( + track.px(), track.py(), track.pz(), + o2::constants::physics::MassPionCharged); + fourPionSystem += pionVec; + pionFourVectors.push_back(pionVec); + } + + // Fill pre-cut system histograms + registry.fill(HIST("Cuts/MBefore"), fourPionSystem.M()); + registry.fill(HIST("Cuts/PtBefore"), fourPionSystem.Pt()); + + // Apply system-level kinematic cuts + if (fourPionSystem.M() < systemMassMinCut || fourPionSystem.M() > systemMassMaxCut) + return; + if (fourPionSystem.Pt() > systemPtCut) + return; + if (std::abs(fourPionSystem.Rapidity()) > systemYCut) + return; + + // Fill post-cut system histograms + registry.fill(HIST("Cuts/MAfter"), fourPionSystem.M()); + registry.fill(HIST("Cuts/PtAfter"), fourPionSystem.Pt()); + registry.fill(HIST("System/hM"), fourPionSystem.M()); + registry.fill(HIST("System/hPt"), fourPionSystem.Pt()); + registry.fill(HIST("System/hEta"), fourPionSystem.Eta()); + registry.fill(HIST("System/hPhi"), fourPionSystem.Phi() + o2::constants::math::PI); + registry.fill(HIST("System/hY"), fourPionSystem.Rapidity()); + + std::vector trackPts, trackEtas, trackPhis; + std::vector trackSigns, trackIDs; + std::vector tpcNSigmasEl, tpcNSigmasPi, tpcNSigmasKa, tpcNSigmasPr; + + for (size_t i = 0; i < selectedTracks.size(); i++) { + const auto& track = selectedTracks[i]; + trackPts.push_back(track.pt()); + trackEtas.push_back(eta(track.px(), track.py(), track.pz())); + trackPhis.push_back(phi(track.px(), track.py())); + trackSigns.push_back(track.sign()); + tpcNSigmasEl.push_back(track.tpcNSigmaEl()); + tpcNSigmasPi.push_back(track.tpcNSigmaPi()); + tpcNSigmasKa.push_back(track.tpcNSigmaKa()); + tpcNSigmasPr.push_back(track.tpcNSigmaPr()); + trackIDs.push_back(i); } - // std::cout<<"Hello World"<(cfgc)}; + adaptAnalysisTask(cfgc)}; } diff --git a/PWGUD/Tasks/upcTauTau13topo.cxx b/PWGUD/Tasks/upcTauTau13topo.cxx index 0d18b316b8b..676181f8de0 100644 --- a/PWGUD/Tasks/upcTauTau13topo.cxx +++ b/PWGUD/Tasks/upcTauTau13topo.cxx @@ -17,24 +17,25 @@ // copts="--configuration json://tautauConfig.json -b" // o2-analysis-ud-tautau13topo $copts > output.log -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" // #include "TDatabasePDG.h" // not recommended in o2 #include "Framework/O2DatabasePDGPlugin.h" -#include "TLorentzVector.h" +// #include "TLorentzVector.h" +#include "Math/Vector4D.h" // #include "Common/DataModel/EventSelection.h" // #include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/PIDResponse.h" -#include "PWGUD/DataModel/UDTables.h" -#include "PWGUD/Core/UDHelpers.h" #include "PWGUD/Core/DGPIDSelector.h" #include "PWGUD/Core/SGSelector.h" +#include "PWGUD/Core/UDHelpers.h" +#include "PWGUD/DataModel/UDTables.h" #include "Common/Core/RecoDecay.h" +#include "Common/DataModel/PIDResponse.h" // #include #include "TPDGCode.h" @@ -52,7 +53,8 @@ namespace tau_tree DECLARE_SOA_COLUMN(RunNumber, runNumber, int32_t); DECLARE_SOA_COLUMN(Bc, bc, int); DECLARE_SOA_COLUMN(TotalTracks, totalTracks, int); -DECLARE_SOA_COLUMN(NumContrib, numContrib, int); +DECLARE_SOA_COLUMN(NumContrib, numContrib, int8_t); +DECLARE_SOA_COLUMN(RctOk, rctOk, int); // DECLARE_SOA_COLUMN(GlobalNonPVtracks, globalNonPVtracks, int); // DECLARE_SOA_COLUMN(PosX, posX, float); // DECLARE_SOA_COLUMN(PosY, posY, float); @@ -63,14 +65,14 @@ DECLARE_SOA_COLUMN(HadronicRate, hadronicRate, double); DECLARE_SOA_COLUMN(Trs, trs, bool); DECLARE_SOA_COLUMN(Trofs, trofs, bool); DECLARE_SOA_COLUMN(Hmpr, hmpr, bool); -// DECLARE_SOA_COLUMN(Tfb, tfb, int); -// DECLARE_SOA_COLUMN(ItsRofb, itsRofb, int); -// DECLARE_SOA_COLUMN(Sbp, sbp, int); -// DECLARE_SOA_COLUMN(ZvtxFT0vsPv, zvtxFT0vsPv, int); -// DECLARE_SOA_COLUMN(VtxITSTPC, vtxITSTPC, int); +DECLARE_SOA_COLUMN(Tfb, tfb, bool); +DECLARE_SOA_COLUMN(ItsRofb, itsRofb, bool); +DECLARE_SOA_COLUMN(Sbp, sbp, bool); +DECLARE_SOA_COLUMN(ZvtxFT0vsPv, zvtxFT0vsPv, bool); +DECLARE_SOA_COLUMN(VtxITSTPC, vtxITSTPC, bool); DECLARE_SOA_COLUMN(ZdcAenergy, zdcAenergy, float); DECLARE_SOA_COLUMN(ZdcCenergy, zdcCenergy, float); -DECLARE_SOA_COLUMN(Qtot, qtot, int16_t); +DECLARE_SOA_COLUMN(Qtot, qtot, int8_t); // FIT info DECLARE_SOA_COLUMN(TotalFT0AmplitudeA, totalFT0AmplitudeA, float); DECLARE_SOA_COLUMN(TotalFT0AmplitudeC, totalFT0AmplitudeC, float); @@ -82,20 +84,23 @@ DECLARE_SOA_COLUMN(TotalFV0AmplitudeA, totalFV0AmplitudeA, float); DECLARE_SOA_COLUMN(TrkPx, trkPx, float[4]); DECLARE_SOA_COLUMN(TrkPy, trkPy, float[4]); DECLARE_SOA_COLUMN(TrkPz, trkPz, float[4]); -// DECLARE_SOA_COLUMN(TrkSign, trkSign, int[4]); -// DECLARE_SOA_COLUMN(TrkDCAxy, trkDCAxy, float[4]); -// DECLARE_SOA_COLUMN(TrkDCAz, trkDCAz, float[4]); +DECLARE_SOA_COLUMN(TrkSign, trkSign, int8_t[4]); +DECLARE_SOA_COLUMN(TrkDCAxy, trkDCAxy, float[4]); +DECLARE_SOA_COLUMN(TrkDCAz, trkDCAz, float[4]); DECLARE_SOA_COLUMN(TrkTPCcr, trkTPCcr, int[4]); +DECLARE_SOA_COLUMN(TrkTPCfind, trkTPCfind, int[4]); +DECLARE_SOA_COLUMN(TrkTPCchi2, trkTPCchi2, float[4]); +DECLARE_SOA_COLUMN(TrkITSchi2, trkITSchi2, float[4]); +DECLARE_SOA_COLUMN(TrkITScl, trkITScl, int[4]); + DECLARE_SOA_COLUMN(TrkTPCsignal, trkTPCsignal, float[4]); DECLARE_SOA_COLUMN(TrkTPCnSigmaEl, trkTPCnSigmaEl, float[4]); -// DECLARE_SOA_COLUMN(TrkTPCnSigmaMu, trkTPCnSigmaMu, float[4]); DECLARE_SOA_COLUMN(TrkTPCnSigmaPi, trkTPCnSigmaPi, float[4]); DECLARE_SOA_COLUMN(TrkTPCnSigmaKa, trkTPCnSigmaKa, float[4]); DECLARE_SOA_COLUMN(TrkTPCnSigmaPr, trkTPCnSigmaPr, float[4]); DECLARE_SOA_COLUMN(TrkTPCnSigmaMu, trkTPCnSigmaMu, float[4]); DECLARE_SOA_COLUMN(TrkTOFbeta, trkTOFbeta, float[4]); DECLARE_SOA_COLUMN(TrkTOFnSigmaEl, trkTOFnSigmaEl, float[4]); -// DECLARE_SOA_COLUMN(TrkTOFnSigmaMu, trkTOFnSigmaMu, float[4]); DECLARE_SOA_COLUMN(TrkTOFnSigmaPi, trkTOFnSigmaPi, float[4]); DECLARE_SOA_COLUMN(TrkTOFnSigmaKa, trkTOFnSigmaKa, float[4]); DECLARE_SOA_COLUMN(TrkTOFnSigmaPr, trkTOFnSigmaPr, float[4]); @@ -105,19 +110,21 @@ DECLARE_SOA_COLUMN(TrkTOFchi2, trkTOFchi2, float[4]); } // end of namespace tau_tree DECLARE_SOA_TABLE(TauFourTracks, "AOD", "TAUFOURTRACK", tau_tree::RunNumber, tau_tree::Bc, tau_tree::TotalTracks, tau_tree::NumContrib, + tau_tree::RctOk, // tau_tree::GlobalNonPVtracks, // tau_tree::PosX, tau_tree::PosY, tau_tree::PosZ, tau_tree::FlagUPC, tau_tree::OccupancyInTime, tau_tree::HadronicRate, tau_tree::ZdcAenergy, tau_tree::ZdcCenergy, tau_tree::Qtot, tau_tree::Trs, tau_tree::Trofs, tau_tree::Hmpr, - // tau_tree::Tfb, tau_tree::ItsRofb, tau_tree::Sbp, tau_tree::ZvtxFT0vsPv, tau_tree::VtxITSTPC, + tau_tree::Tfb, tau_tree::ItsRofb, tau_tree::Sbp, tau_tree::ZvtxFT0vsPv, tau_tree::VtxITSTPC, tau_tree::TotalFT0AmplitudeA, tau_tree::TotalFT0AmplitudeC, tau_tree::TotalFV0AmplitudeA, // tau_tree::TimeFT0A, tau_tree::TimeFT0C, tau_tree::TimeFV0A, tau_tree::TrkPx, tau_tree::TrkPy, tau_tree::TrkPz, - // tau_tree::TrkSign, - // tau_tree::TrkDCAxy, tau_tree::TrkDCAz, + tau_tree::TrkSign, + tau_tree::TrkDCAxy, tau_tree::TrkDCAz, tau_tree::TrkTPCcr, + tau_tree::TrkTPCfind, tau_tree::TrkTPCchi2, tau_tree::TrkITSchi2, tau_tree::TrkITScl, tau_tree::TrkTPCsignal, tau_tree::TrkTPCnSigmaEl, tau_tree::TrkTPCnSigmaPi, tau_tree::TrkTPCnSigmaKa, tau_tree::TrkTPCnSigmaPr, tau_tree::TrkTPCnSigmaMu, tau_tree::TrkTOFbeta, tau_tree::TrkTOFnSigmaEl, tau_tree::TrkTOFnSigmaPi, tau_tree::TrkTOFnSigmaKa, tau_tree::TrkTOFnSigmaPr, tau_tree::TrkTOFnSigmaMu, tau_tree::TrkTOFchi2); @@ -138,7 +145,7 @@ struct TauTau13topo { ConfigurableAxis ptAxis{"ptAxis", {120, 0., 4.}, "#it{p} (GeV/#it{c})"}; // ConfigurableAxis etaAxis{"etaAxis", {100, -2., 2.}, "#eta"}; ConfigurableAxis dedxAxis{"dedxAxis", {100, 20., 160.}, "dE/dx"}; - ConfigurableAxis minvAxis{"minvAxis", {100, 0.4, 3.5}, "M_{inv} (GeV/#it{c}^{2})"}; + ConfigurableAxis minvAxis{"minvAxis", {100, 0.5, 5.0}, "M_{inv} (GeV/#it{c}^{2})"}; ConfigurableAxis phiAxis{"phiAxis", {120, 0., 3.2}, "#phi"}; // ConfigurableAxis vectorAxis{"vectorAxis", {100, 0., 2.}, "A_{V}"}; // ConfigurableAxis scalarAxis{"scalarAxis", {100, -1., 1.}, "A_{S}"}; @@ -215,6 +222,7 @@ struct TauTau13topo { const AxisSpec scalarAxis{100, -1., 1., "A_{S}"}; const AxisSpec axisZDC{50, -1., 14., "#it{E} (TeV)"}; const AxisSpec axisInvMass4trk{160, 0.5, 8.5, "#it{M}^{4trk}_{inv} (GeV/#it{c}^{2})"}; + const AxisSpec acoAxis{100, 0., 1., "A^{1+3}"}; if (doprocessDataSG) { registry.add("global/RunNumber", "Run number; Run; Collisions", {HistType::kTH1F, {{150, 544013, 545367}}}); @@ -805,22 +813,92 @@ struct TauTau13topo { registry.add("pidTOF/h3piTOFchi2Cut23", "tof chi2;chi2 TOF;events", {HistType::kTH1F, {{100, 0., 10.}}}); // registry.add("pidTOF/h3piTOFchi2Cut36", "tof chi2;chi2 TOF;events", {HistType::kTH1F, {{100, 0., 10.}}}); // registry.add("pidTOF/h3piTOFchi2Cut37", "tof chi2;chi2 TOF;events", {HistType::kTH1F, {{100, 0., 10.}}}); + + // histograms mass3pi vs acoponarity + registry.add("control/cut0/h3piMassVsAco", "3#pi mass vs acoplanarity, up to 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry.add("control/cut20/h3piMassVsAco", "3#pi mass vs acoplanarity, up to 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry.add("control/cut33/h3piMassVsAco", "3#pi mass vs acoplanarity, up to 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry.add("control/cut21/h3piMassVsAco", "3#pi mass vs acoplanarity, up to 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry.add("control/cut24/h3piMassVsAco", "3#pi mass vs acoplanarity, up to 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry.add("control/cut25/h3piMassVsAco", "3#pi mass vs acoplanarity, up to 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry.add("control/cut28/h3piMassVsAco", "3#pi mass vs acoplanarity, up to 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry.add("control/cut22/h3piMassVsAco", "3#pi mass vs acoplanarity, up to 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry.add("control/cut29/h3piMassVsAco", "3#pi mass vs acoplanarity, up to 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry.add("control/cut26/h3piMassVsAco", "3#pi mass vs acoplanarity, up to 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry.add("control/cut34/h3piMassVsAco", "3#pi mass vs acoplanarity, up to 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry.add("control/cut30/h3piMassVsAco", "3#pi mass vs acoplanarity, up to 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry.add("control/cut27/h3piMassVsAco", "3#pi mass vs acoplanarity, up to 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry.add("control/cut35/h3piMassVsAco", "3#pi mass vs acoplanarity, up to 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry.add("control/cut23/h3piMassVsAco", "3#pi mass vs acoplanarity, up to 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + } // end of data histograms // MC part // histograms filled by processSimpleMCSG // CollisionMC histograms - if (doprocessEfficiencyMCSG) { - registry1MC.add("globalMC/hGeneratorID", ";Generator ID;events", {HistType::kTH1F, {{100, 0., 1000.}}}); + if (doprocessEfficiencyMCSG || doprocessSimpleMCSG) { registryMC.add("globalMC/hMCZvertex", ";V_{Z}^{MC} (cm);events", {HistType::kTH1F, {{100, -25., 25.}}}); - registryMC.add("globalMC/hMCefficiency", ";Cut Number;events", {HistType::kTH1F, {{20, 0., 20.}}}); + registryMC.add("globalMC/hMCefficiency", ";Cut Number;events", {HistType::kTH1F, {{28, -8., 20.}}}); + + // efficiency el + registryMC.add("efficiencyMCEl/effiEl", ";Efficiency e3#pi;events", {HistType::kTH1F, {{70, 0., 70.}}}); + // efficiency pi + registryMC.add("efficiencyMCPi/effiPi", ";Efficiency #pi3#pi;events", {HistType::kTH1F, {{20, 0., 20.}}}); + // efficiency mu + registryMC.add("efficiencyMCMu/effiMu", ";Efficiency #mu3#pi;events", {HistType::kTH1F, {{20, 0., 20.}}}); + } + + if (doprocessSimpleMCSG) { registryMC.add("globalMC/hMCnPart", ";N_{part};Type;events", {HistType::kTH2F, {{25, 0., 25.}, {10, 0, 10}}}); + registryMC.add("globalMC/hMCetaGen", ";#eta^{gen};N^{MC particles}", {HistType::kTH1F, {{100, -5., 5.}}}); registryMC.add("globalMC/hMCphiGen", ";#phi^{gen};N^{MC particles}", {HistType::kTH1F, {{100, 0., 6.4}}}); registryMC.add("globalMC/hMCyGen", ";y^{gen};N^{MC particles}", {HistType::kTH1F, {{100, -5., 5.}}}); registryMC.add("globalMC/hMCptGen", ";p_{T}^{gen};N^{MC particles}", {HistType::kTH1F, {{100, 0., 4.}}}); + // tau + registryMC.add("tauMC/hNtaus", ";N^{#tau};N_events ", {HistType::kTH1F, {{6, -1., 5.}}}); + + registryMC.add("tauMC/hMCeta", ";#eta^{#tau};N^{#tau} ", {HistType::kTH1F, {{100, -5., 5.}}}); + registryMC.add("tauMC/hMCy", ";y^{#tau};N^{#tau}", {HistType::kTH1F, {{100, -5., 5.}}}); + registryMC.add("tauMC/hMCphi", ";#phi^{#tau};N^{#tau}", {HistType::kTH1F, {{100, 0., 6.4}}}); + registryMC.add("tauMC/hMCpt", ";#it{p}_{T}^{#tau};N^{#tau}", {HistType::kTH1F, {{100, 0., 10.}}}); + + registryMC.add("tauMC/hMCdeltaeta", ";#Delta#eta^{#tau};events ", {HistType::kTH1F, {{100, -5., 5.}}}); + registryMC.add("tauMC/hMCdeltaphi", ";#Delta#phi^{#tau}(deg.);events", {HistType::kTH1F, {{100, 131., 181}}}); + + // electron + registryMC.add("electronMC/hMCeta", ";#eta^{e};N^{e}", {HistType::kTH1F, {{100, -5., 5.}}}); + registryMC.add("electronMC/hMCy", ";y^{e};N^{e}", {HistType::kTH1F, {{100, -5., 5.}}}); + registryMC.add("electronMC/hMCphi", ";#phi^{e};N^{e}", {HistType::kTH1F, {{100, 0., 6.4}}}); + registryMC.add("electronMC/hMCpt", ";#it{p}_{T}^{e};N^{e}", {HistType::kTH1F, {{400, 0., 10.}}}); + + // muon + registryMC.add("muonMC/hMCeta", ";#eta^{#mu};N^{#mu}", {HistType::kTH1F, {{100, -5., 5.}}}); + registryMC.add("muonMC/hMCy", ";y^{#mu};N^{#mu}", {HistType::kTH1F, {{100, -5., 5.}}}); + registryMC.add("muonMC/hMCphi", ";#phi^{#mu};N^{#mu}", {HistType::kTH1F, {{100, 0., 6.4}}}); + registryMC.add("muonMC/hMCpt", ";#it{p}_{T}^{#mu};N^{#mu}", {HistType::kTH1F, {{400, 0., 10.}}}); + + // pion + registryMC.add("pionMC/hMCeta", ";#eta^{#pi};N^{#pi}", {HistType::kTH1F, {{100, -5., 5.}}}); + registryMC.add("pionMC/hMCy", ";y^{#pi};N^{#pi}", {HistType::kTH1F, {{100, -5., 5.}}}); + registryMC.add("pionMC/hMCphi", ";#phi^{#pi};N^{#pi}", {HistType::kTH1F, {{100, 0., 6.4}}}); + registryMC.add("pionMC/hMCpt", ";#it{p}_{T}^{#pi};N^{#pi}", {HistType::kTH1F, {{400, 0., 10.}}}); + + // efficiency mu + registryMC.add("efficiencyMCMu/hpTmuon", ";p_{T}^{#mu, gen} (GeV/c);events", {HistType::kTH1F, {{200, 0., 5.}}}); + + // efficiency pi + registryMC.add("efficiencyMCPi/hpTpi", ";p_{T}^{#pi, gen} (GeV/c);events", {HistType::kTH1F, {{200, 0., 5.}}}); + + // efficiency el + registryMC.add("efficiencyMCEl/hpTelec", ";p_{T}^{e, gen} (GeV/c);events", {HistType::kTH1F, {axispt}}); + } + + if (doprocessEfficiencyMCSG) { // MC reconstructed with information from MC true + registry1MC.add("globalMC/hGeneratorID", ";Generator ID;events", {HistType::kTH1F, {{100, 0., 1000.}}}); + registryMC.add("globalMCrec/hMCetaGenCol", ";#eta^{genCol};events", {HistType::kTH1F, {{100, -5., 5.}}}); registryMC.add("globalMCrec/hMCphiGenCol", ";#phi^{genCol};events", {HistType::kTH1F, {{100, 0., 6.4}}}); registryMC.add("globalMCrec/hMCyGenCol", ";y^{genCol};events", {HistType::kTH1F, {{100, -5., 5.}}}); @@ -1461,33 +1539,6 @@ struct TauTau13topo { registryMC.add("controlMCcomb/cut35/hPtSpectrumEl", ";p_{T}^{comb} (GeV/c);entries", {HistType::kTH1F, {axispt}}); // zrobic hpTspectrumEl dla cut 0,20-35: registry.get(HIST("global/hFinalPtSpectrumEl"))->Fill(tmpPt[i]); - // tau - registryMC.add("tauMC/hMCeta", ";#eta^{#tau};N^{#tau} ", {HistType::kTH1F, {{100, -5., 5.}}}); - registryMC.add("tauMC/hMCy", ";y^{#tau};N^{#tau}", {HistType::kTH1F, {{100, -5., 5.}}}); - registryMC.add("tauMC/hMCphi", ";#phi^{#tau};N^{#tau}", {HistType::kTH1F, {{100, 0., 6.4}}}); - registryMC.add("tauMC/hMCpt", ";#it{p}_{T}^{#tau};N^{#tau}", {HistType::kTH1F, {{100, 0., 10.}}}); - - registryMC.add("tauMC/hMCdeltaeta", ";#Delta#eta^{#tau};events ", {HistType::kTH1F, {{100, -5., 5.}}}); - registryMC.add("tauMC/hMCdeltaphi", ";#Delta#phi^{#tau}(deg.);events", {HistType::kTH1F, {{100, 131., 181}}}); - - // electron - registryMC.add("electronMC/hMCeta", ";#eta^{e};N^{e}", {HistType::kTH1F, {{100, -5., 5.}}}); - registryMC.add("electronMC/hMCy", ";y^{e};N^{e}", {HistType::kTH1F, {{100, -5., 5.}}}); - registryMC.add("electronMC/hMCphi", ";#phi^{e};N^{e}", {HistType::kTH1F, {{100, 0., 6.4}}}); - registryMC.add("electronMC/hMCpt", ";#it{p}_{T}^{e};N^{e}", {HistType::kTH1F, {{400, 0., 10.}}}); - - // efficiency mu - registryMC.add("efficiencyMCMu/effiMu", ";Efficiency #mu3#pi;events", {HistType::kTH1F, {{20, 0., 20.}}}); - registryMC.add("efficiencyMCMu/hpTmuon", ";p_{T}^{#mu, gen} (GeV/c);events", {HistType::kTH1F, {{200, 0., 5.}}}); - - // efficiency pi - registryMC.add("efficiencyMCPi/effiPi", ";Efficiency #pi3#pi;events", {HistType::kTH1F, {{20, 0., 20.}}}); - registryMC.add("efficiencyMCPi/hpTpi", ";p_{T}^{#pi, gen} (GeV/c);events", {HistType::kTH1F, {{200, 0., 5.}}}); - - // efficiency el - registryMC.add("efficiencyMCEl/effiEl", ";Efficiency e3#pi;events", {HistType::kTH1F, {{70, 0., 70.}}}); - registryMC.add("efficiencyMCEl/hpTelec", ";p_{T}^{e, gen} (GeV/c);events", {HistType::kTH1F, {axispt}}); - // efficiency el registryMC.add("efficiencyMCEl/hMCdeltaAlphaEpi", ";#Delta#alpha^{e-#pi(3x), gen} (rad);events", {HistType::kTH1F, {{100, -0.1, 3.2}}}); registryMC.add("efficiencyMCEl/hMCdeltaAlphaPiPi", ";#Delta#alpha^{#pi-#pi(3x), gen} (rad);events", {HistType::kTH1F, {{100, -0.1, 3.2}}}); @@ -1506,6 +1557,40 @@ struct TauTau13topo { registryMC.add("efficiencyMCEl/hMCinvmass3pi", ";M_{inv}^{3#pi true} (GeV/c^{2}) ;events", {HistType::kTH1F, {{100, 0.4, 2.4}}}); registryMC.add("efficiencyMCEl/hMCdeltaphi13", ";#Delta#phi^{1-3 true} ;events", {HistType::kTH1F, {{100, 0., 3.2}}}); + // histograms mass3pi vs acoponarity MC true + registry1MC.add("controlMCtrue/cut0/h3piMassVsAco", "3#pi mass vs acoplanarity MC sig ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCtrue/cut20/h3piMassVsAco", "3#pi mass vs acoplanarity MC sig ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCtrue/cut33/h3piMassVsAco", "3#pi mass vs acoplanarity MC sig ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCtrue/cut21/h3piMassVsAco", "3#pi mass vs acoplanarity MC sig ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCtrue/cut24/h3piMassVsAco", "3#pi mass vs acoplanarity MC sig ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCtrue/cut25/h3piMassVsAco", "3#pi mass vs acoplanarity MC sig ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCtrue/cut28/h3piMassVsAco", "3#pi mass vs acoplanarity MC sig ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCtrue/cut22/h3piMassVsAco", "3#pi mass vs acoplanarity MC sig ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCtrue/cut29/h3piMassVsAco", "3#pi mass vs acoplanarity MC sig ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCtrue/cut26/h3piMassVsAco", "3#pi mass vs acoplanarity MC sig ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCtrue/cut34/h3piMassVsAco", "3#pi mass vs acoplanarity MC sig ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCtrue/cut30/h3piMassVsAco", "3#pi mass vs acoplanarity MC sig ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCtrue/cut27/h3piMassVsAco", "3#pi mass vs acoplanarity MC sig ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCtrue/cut35/h3piMassVsAco", "3#pi mass vs acoplanarity MC sig ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCtrue/cut23/h3piMassVsAco", "3#pi mass vs acoplanarity MC sig ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + + // histograms mass3pi vs acoponarity MC comb + registry1MC.add("controlMCcomb/cut0/h3piMassVsAco", "3#pi mass vs acoplanarity MC comb ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCcomb/cut20/h3piMassVsAco", "3#pi mass vs acoplanarity MC comb ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCcomb/cut33/h3piMassVsAco", "3#pi mass vs acoplanarity MC comb ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCcomb/cut21/h3piMassVsAco", "3#pi mass vs acoplanarity MC comb ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCcomb/cut24/h3piMassVsAco", "3#pi mass vs acoplanarity MC comb ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCcomb/cut25/h3piMassVsAco", "3#pi mass vs acoplanarity MC comb ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCcomb/cut28/h3piMassVsAco", "3#pi mass vs acoplanarity MC comb ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCcomb/cut22/h3piMassVsAco", "3#pi mass vs acoplanarity MC comb ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCcomb/cut29/h3piMassVsAco", "3#pi mass vs acoplanarity MC comb ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCcomb/cut26/h3piMassVsAco", "3#pi mass vs acoplanarity MC comb ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCcomb/cut34/h3piMassVsAco", "3#pi mass vs acoplanarity MC comb ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCcomb/cut30/h3piMassVsAco", "3#pi mass vs acoplanarity MC comb ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCcomb/cut27/h3piMassVsAco", "3#pi mass vs acoplanarity MC comb ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCcomb/cut35/h3piMassVsAco", "3#pi mass vs acoplanarity MC comb ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + registry1MC.add("controlMCcomb/cut23/h3piMassVsAco", "3#pi mass vs acoplanarity MC comb ;M_{inv}^{3#pi} (GeV/c^{2});A^{1+3};entries", {HistType::kTH2F, {minvAxis, acoAxis}}); + } // end of MC histograms processEfficiencyMCSG if (doprocessDoSkim) { @@ -1514,31 +1599,31 @@ struct TauTau13topo { } // end of init method - float eta(float px, float py, float pz) - // Just a simple function to return pseudorapidity - { - float arg = -2.; // outside valid range for std::atanh - float mom = std::sqrt(px * px + py * py + pz * pz); - if (mom != 0) - arg = pz / mom; - if (-1. < arg && arg < 1.) - return std::atanh(arg); // definition of eta - return -999.; - } + // float eta(float px, float py, float pz) + // // Just a simple function to return pseudorapidity + // { + // float arg = -2.; // outside valid range for std::atanh + // float mom = std::sqrt(px * px + py * py + pz * pz); + // if (mom != 0) + // arg = pz / mom; + // if (-1. < arg && arg < 1.) + // return std::atanh(arg); // definition of eta + // return -999.; + // } - float phi(float px, float py) - // Just a simple function to return azimuthal angle from 0 to 2pi - { - if (px != 0) - return (std::atan2(py, px) + o2::constants::math::PI); - return -999.; - } + // float phi(float px, float py) + // // Just a simple function to return azimuthal angle from 0 to 2pi + // { + // if (px != 0) + // return (std::atan2(py, px) + o2::constants::math::PI); + // return -999.; + // } - float pt(float px, float py) - // Just a simple function to return pt - { - return std::sqrt(px * px + py * py); - } + // float pt(float px, float py) + // // Just a simple function to return pt + // { + // return std::sqrt(px * px + py * py); + // } float rapidity(float energy, float pz) // Just a simple function to return track rapidity @@ -1557,13 +1642,14 @@ struct TauTau13topo { return angle; } - float invariantMass(float E, float px, float py, float pz) - // Just a simple function to return invariant mass - { - return std::sqrt(E * E - px * px - py * py - pz * pz); - } + // float invariantMass(float E, float px, float py, float pz) + // // Just a simple function to return invariant mass + // { + // return std::sqrt(E * E - px * px - py * py - pz * pz); + // } - float calculateDeltaPhi(TLorentzVector p, TLorentzVector p1) + // float calculateDeltaPhi(TLorentzVector p, TLorentzVector p1) + float calculateDeltaPhi(ROOT::Math::LorentzVector> p, ROOT::Math::LorentzVector> p1) { // float delta = p.Phi(); float delta = RecoDecay::constrainAngle(p.Phi()); @@ -1616,8 +1702,10 @@ struct TauTau13topo { // helper function to calculate scalar asymmetry float scalarAsymMC(auto particle1, auto particle2) { - auto pt1 = pt(particle1.px(), particle1.py()); - auto pt2 = pt(particle2.px(), particle2.py()); + // auto pt1 = pt(particle1.px(), particle1.py()); + auto pt1 = RecoDecay::pt(particle1.px(), particle1.py()); + // auto pt2 = pt(particle2.px(), particle2.py()); + auto pt2 = RecoDecay::pt(particle2.px(), particle2.py()); auto delta = pt1 - pt2; return std::abs(delta) / (pt1 + pt2); } @@ -1651,6 +1739,8 @@ struct TauTau13topo { registry.get(HIST("control/cut") + HIST(kHistoname[mode]) + HIST("/hTPCnCrossedRows"))->Fill(nCRtpc); registry.get(HIST("control/cut") + HIST(kHistoname[mode]) + HIST("/hPtSpectrumEl"))->Fill(ptelec); registry.get(HIST("control/cut") + HIST(kHistoname[mode]) + HIST("/hTofChi2El"))->Fill(tofchi2); + float aco = 1. - pi3deltaPhi / o2::constants::math::PI; + registry.get(HIST("control/cut") + HIST(kHistoname[mode]) + HIST("/h3piMassVsAco"))->Fill(pi3invMass, aco); } // fill control histograms per track in MC true @@ -1671,6 +1761,8 @@ struct TauTau13topo { registryMC.get(HIST("controlMCtrue/cut") + HIST(kHistoname[mode]) + HIST("/hPtSpectrumEl"))->Fill(ptelec); // registryMC.get(HIST("controlMCtrue/cut") + HIST(kHistoname[mode]) + HIST("/h13EtaSum"))->Fill(pi3etasum); registry1MC.get(HIST("controlMCtrue/cut") + HIST(kHistoname[mode]) + HIST("/hTofChi2El"))->Fill(tofchi2); + float aco = 1. - pi3deltaPhi / o2::constants::math::PI; + registry1MC.get(HIST("controlMCtrue/cut") + HIST(kHistoname[mode]) + HIST("/h3piMassVsAco"))->Fill(pi3invMass, aco); } // fill control histograms per track in MC true @@ -1691,6 +1783,8 @@ struct TauTau13topo { registryMC.get(HIST("controlMCcomb/cut") + HIST(kHistoname[mode]) + HIST("/hPtSpectrumEl"))->Fill(ptelec); // registryMC.get(HIST("controlMCtrue/cut") + HIST(kHistoname[mode]) + HIST("/h13EtaSum"))->Fill(pi3etasum); registry1MC.get(HIST("controlMCcomb/cut") + HIST(kHistoname[mode]) + HIST("/hTofChi2El"))->Fill(tofchi2); + float aco = 1. - pi3deltaPhi / o2::constants::math::PI; + registry1MC.get(HIST("controlMCcomb/cut") + HIST(kHistoname[mode]) + HIST("/h3piMassVsAco"))->Fill(pi3invMass, aco); } template @@ -1778,7 +1872,7 @@ struct TauTau13topo { } else { isGlobalTrack = false; } - if (std::abs(eta(track.px(), track.py(), track.pz())) < 0.8) { + if (std::abs(RecoDecay::eta(std::array{track.px(), track.py(), track.pz()})) < 0.8) { registry.get(HIST("global/hTrackEfficiencyPVGlobal"))->Fill(8., 1.); } else { isGlobalTrack = false; @@ -1919,6 +2013,45 @@ struct TauTau13topo { return true; } + // check ITS clusters, how many -1,0,1,7 + 10 if 0,1,2 layers were fired + // analysis track quality check + template + int numberOfItsClustersCheck(T track) + { + if (!track.hasITS()) + return -1; + int nITSbits = 0; + int firstThreeLayers = 0; + uint32_t clusterSizes = track.itsClusterSizes(); + for (int layer = 0; layer < 7; layer++) { + if ((clusterSizes >> (layer * 4)) & 0xf) { + nITSbits++; + if (layer < 3) + firstThreeLayers++; + } + } // end of loop over ITS bits + if (firstThreeLayers == 3) + nITSbits += 10; + + return nITSbits; + } + + // RCT check + template + int isGoodRCTflag(C const& coll) + { + if (sgSelector.isCBTHadronZdcOk(coll)) + return 4; + else if (sgSelector.isCBTHadronOk(coll)) + return 3; + else if (sgSelector.isCBTZdcOk(coll)) + return 2; + else if (sgSelector.isCBTOk(coll)) + return 1; + else + return 0; + } + // using UDCollisionsFull = soa::Join; // using UDCollisionFull = UDCollisionsFull::iterator; using UDTracksFull = soa::Join; @@ -1930,9 +2063,6 @@ struct TauTau13topo { Filter pVContributorFilter = aod::udtrack::isPVContributor == true; using PVTracks = soa::Filtered; - // using LabeledTracks = soa::Join; - using LabeledTracks = soa::Join; - Preslice perCollision = aod::udtrack::udCollisionId; // PVContributors in MC handling // Filter pVContributorFilterMC = aod::udtrack::isPVContributor == true; // using PVTracksMC = soa::Filtered; @@ -2010,7 +2140,8 @@ struct TauTau13topo { int nEtaIn15 = 0; int nITSbits = -1; int npT100 = 0; - TLorentzVector p; + // TLorentzVector p; + ROOT::Math::LorentzVector> p; // auto const pionMass = MassPiPlus; // auto const electronMass = MassElectron; bool flagGlobalCheck = true; @@ -2019,7 +2150,8 @@ struct TauTau13topo { // loop over PV contributors for (const auto& trk : PVContributors) { qtot += trk.sign(); - p.SetXYZM(trk.px(), trk.py(), trk.pz(), MassPiPlus); + // p.SetXYZM(trk.px(), trk.py(), trk.pz(), MassPiPlus); + p.SetXYZT(trk.px(), trk.py(), trk.pz(), RecoDecay::e(trk.px(), trk.py(), trk.pz(), MassPiPlus)); registry.get(HIST("global/hTrackPtPV"))->Fill(p.Pt()); if (std::abs(p.Eta()) < trkEtacut) nEtaIn15++; // 1.5 is a default @@ -2093,7 +2225,9 @@ struct TauTau13topo { registry.get(HIST("global1/hNTracks"))->Fill(dgtracks.size()); registry.get(HIST("global1/hNTracksPV"))->Fill(PVContributors.size()); for (const auto& trk : PVContributors) { - p.SetXYZM(trk.px(), trk.py(), trk.pz(), MassPiPlus); + // p.SetXYZM(trk.px(), trk.py(), trk.pz(), MassPiPlus); + // p.SetXYZT(trk.px(), trk.py(), trk.pz(), energy(trk.px(), trk.py(), trk.pz(), MassPiPlus)); + p.SetXYZT(trk.px(), trk.py(), trk.pz(), RecoDecay::e(trk.px(), trk.py(), trk.pz(), MassPiPlus)); registry.get(HIST("global1/hTrackPtPV"))->Fill(p.Pt()); registry.get(HIST("global1/hTrackEtaPhiPV"))->Fill(p.Eta(), p.Phi()); } @@ -2253,23 +2387,27 @@ struct TauTau13topo { // 12 34 | 01 23 |//1 //6 | 0 5 |counter<3?counter:5-counter counter<3?0:1 // 13 24 | 02 13 |//2 //5 | 1 4 | // 14 23 | 03 12 |//3 //4 | 2 3 | - TLorentzVector p1, p2; - TLorentzVector gammaPair[3][2]; - float invMass2El[3][2]; + // TLorentzVector p1, p2; + ROOT::Math::LorentzVector> p1, p2; + // TLorentzVector gammaPair[3][2]; + ROOT::Math::LorentzVector> gammaPair[3][2]; + float invMass2El[3][2]; // inv. mass squared int counterTmp = 0; bool flagIMGam2ePV[4] = {true, true, true, true}; for (const auto& trk : PVContributors) { - p.SetXYZM(trk.px(), trk.py(), trk.pz(), MassElectron); + // p.SetXYZM(trk.px(), trk.py(), trk.pz(), MassElectron); + p.SetXYZT(trk.px(), trk.py(), trk.pz(), RecoDecay::e(trk.px(), trk.py(), trk.pz(), MassElectron)); for (const auto& trk1 : PVContributors) { if (trk.index() >= trk1.index()) continue; if (trk1.hasTPC()) nPiHasTPC[trk.index()]++; - p1.SetXYZM(trk1.px(), trk1.py(), trk1.pz(), MassElectron); - invMass2El[(counterTmp < 3 ? counterTmp : 5 - counterTmp)][(counterTmp < 3 ? 0 : 1)] = (p + p1).Mag2(); + // p1.SetXYZM(trk1.px(), trk1.py(), trk1.pz(), MassElectron); + p1.SetXYZT(trk1.px(), trk1.py(), trk1.pz(), RecoDecay::e(trk1.px(), trk1.py(), trk1.pz(), MassElectron)); + invMass2El[(counterTmp < 3 ? counterTmp : 5 - counterTmp)][(counterTmp < 3 ? 0 : 1)] = (p + p1).mag2(); gammaPair[(counterTmp < 3 ? counterTmp : 5 - counterTmp)][(counterTmp < 3 ? 0 : 1)] = (p + p1); - registry.get(HIST("control/cut0/hInvMass2ElAll"))->Fill((p + p1).Mag2()); + registry.get(HIST("control/cut0/hInvMass2ElAll"))->Fill((p + p1).mag2()); counterTmp++; if ((p + p1).M() < 0.015) { flagIMGam2ePV[trk.index()] = false; @@ -2279,15 +2417,17 @@ struct TauTau13topo { } // end of loop over PVContributors // first loop to add all the tracks together - p = TLorentzVector(0., 0., 0., 0.); + // p = TLorentzVector(0., 0., 0., 0.); + p.SetXYZT(0., 0., 0., 0.); for (const auto& trk : PVContributors) { - p1.SetXYZM(trk.px(), trk.py(), trk.pz(), MassPiPlus); + // p1.SetXYZM(trk.px(), trk.py(), trk.pz(), MassPiPlus); + p1.SetXYZT(trk.px(), trk.py(), trk.pz(), RecoDecay::e(trk.px(), trk.py(), trk.pz(), MassPiPlus)); p += p1; scalarPtsum += trk.pt(); } // end of loop over PVContributors float pttot = p.Pt(); - float mass4pi = p.Mag(); + float mass4pi = p.mag(); TVector3 v1(0, 0, 0); TVector3 vtmp(0, 0, 0); @@ -2309,9 +2449,11 @@ struct TauTau13topo { registry.get(HIST("global/hTrkCheck"))->Fill(tmpTrkCheck); // inv mass of 3pi + 1e - p1.SetXYZM(trk.px(), trk.py(), trk.pz(), MassPiPlus); - p2.SetXYZM(trk.px(), trk.py(), trk.pz(), MassElectron); - mass3pi1e[counterTmp] = (p - p1 + p2).Mag(); + // p1.SetXYZM(trk.px(), trk.py(), trk.pz(), MassPiPlus); + p1.SetXYZT(trk.px(), trk.py(), trk.pz(), RecoDecay::e(trk.px(), trk.py(), trk.pz(), MassPiPlus)); + // p2.SetXYZM(trk.px(), trk.py(), trk.pz(), MassElectron); + p2.SetXYZT(trk.px(), trk.py(), trk.pz(), RecoDecay::e(trk.px(), trk.py(), trk.pz(), MassElectron)); + mass3pi1e[counterTmp] = (p - p1 + p2).mag(); v1.SetXYZ(trk.px(), trk.py(), trk.pz()); for (const auto& trk1 : PVContributors) { @@ -2358,14 +2500,15 @@ struct TauTau13topo { trkTime[counterTmp] = trk.trackTime(); trkTimeRes[counterTmp] = trk.trackTimeRes(); - p1.SetXYZM(trk.px(), trk.py(), trk.pz(), MassPiPlus); + // p1.SetXYZM(trk.px(), trk.py(), trk.pz(), MassPiPlus); + p1.SetXYZT(trk.px(), trk.py(), trk.pz(), RecoDecay::e(trk.px(), trk.py(), trk.pz(), MassPiPlus)); tmpMomentum[counterTmp] = p1.P(); tmpPt[counterTmp] = p1.Pt(); tmpDedx[counterTmp] = trk.tpcSignal(); tmpTofNsigmaEl[counterTmp] = trk.tofNSigmaEl(); deltaPhiTmp = calculateDeltaPhi(p - p1, p1); - pi3invMass[counterTmp] = (p - p1).Mag(); + pi3invMass[counterTmp] = (p - p1).mag(); pi3pt[counterTmp] = (p - p1).Pt(); pi3deltaPhi[counterTmp] = deltaPhiTmp; pi3assymav[counterTmp] = (p1.Pt() - (scalarPtsum - p1.Pt()) / 3.) / (p1.Pt() + (scalarPtsum - p1.Pt()) / 3.); @@ -3174,19 +3317,22 @@ struct TauTau13topo { void processSimpleMCSG(aod::McCollision const& mcCollision, aod::McParticles const& mcParticles) { registryMC.get(HIST("globalMC/hMCZvertex"))->Fill(mcCollision.posZ()); - registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(0., 1.); + registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(-8., 1.); registryMC.get(HIST("efficiencyMCEl/effiEl"))->Fill(0., 1.); registryMC.get(HIST("efficiencyMCMu/effiMu"))->Fill(0., 1.); registryMC.get(HIST("efficiencyMCPi/effiPi"))->Fill(0., 1.); // check how many physical primaries - // int countPrim = 0; - int countGen = 0; - int countBoth = 0; - int countCharged = 0; - int countChargedFromTau = 0; + int countPrim = 0; + int countGen = 0; // generator + int countBoth = 0; // generator + primary + int countCharged = 0; // generator + primary + charged + int countChargedFromTau = 0; // generator + primary + charged + from tau int countTau = 0; + int countChargedOnly = 0; // charged only + int countChargedOnlyFromTau = 0; // charged only and from tau + float etaTau[2]; float phiTau[2]; @@ -3216,10 +3362,13 @@ struct TauTau13topo { // loop over MC particles for (const auto& mcParticle : mcParticles) { + if (verbose) { + LOGF(info, " mcParticle pdg %d, gen %d, prim %d, bkg %d, process %d", mcParticle.pdgCode(), mcParticle.producedByGenerator(), mcParticle.isPhysicalPrimary(), mcParticle.fromBackgroundEvent(), mcParticle.getProcess()); + } // primaries - // if (mcParticle.isPhysicalPrimary()) { - // countPrim++; - // } + if (mcParticle.isPhysicalPrimary()) { + countPrim++; + } // // MC particles produced by generator only // @@ -3227,7 +3376,8 @@ struct TauTau13topo { countGen++; if (mcParticle.isPhysicalPrimary()) { countBoth++; - if (mcParticle.pdgCode() != 22 && std::abs(mcParticle.pdgCode()) != 12 && std::abs(mcParticle.pdgCode()) != 14 && std::abs(mcParticle.pdgCode()) != 16 && mcParticle.pdgCode() != 130 && mcParticle.pdgCode() != 111) { + // if (mcParticle.pdgCode() != 22 && std::abs(mcParticle.pdgCode()) != 12 && std::abs(mcParticle.pdgCode()) != 14 && std::abs(mcParticle.pdgCode()) != 16 && mcParticle.pdgCode() != 130 && mcParticle.pdgCode() != 111) { + if (mcParticle.pdgCode() != kGamma && std::abs(mcParticle.pdgCode()) != kNuE && std::abs(mcParticle.pdgCode()) != kNuMu && std::abs(mcParticle.pdgCode()) != kNuTau && mcParticle.pdgCode() != kK0Long && mcParticle.pdgCode() != kPi0) { countCharged++; registryMC.get(HIST("globalMC/hMCetaGen"))->Fill(mcParticle.eta()); @@ -3237,18 +3387,41 @@ struct TauTau13topo { if (mcParticle.has_mothers()) { auto const& mother = mcParticle.mothers_first_as(); - if (std::abs(mother.pdgCode()) == 15) { + // if (std::abs(mother.pdgCode()) == 15) { + if (std::abs(mother.pdgCode()) == kTauMinus) { countChargedFromTau++; } // mother is tau } // mc particle has mother } // veto neutral particles - } // physicsl primary + } // physics primary } // generator produced by + // special case only for UPCgen, charged but not taus + if (std::abs(mcParticle.pdgCode()) != kTauMinus && mcParticle.pdgCode() != kGamma && std::abs(mcParticle.pdgCode()) != kNuE && std::abs(mcParticle.pdgCode()) != kNuMu && std::abs(mcParticle.pdgCode()) != kNuTau && mcParticle.pdgCode() != kK0Long && mcParticle.pdgCode() != kPi0) { + countChargedOnly++; + // case for UPCgen when all particles are not pimaries + if (!mcParticle.isPhysicalPrimary()) { + // all charged particles, not only from 1+3 topo + registryMC.get(HIST("globalMC/hMCetaGen"))->Fill(mcParticle.eta()); + registryMC.get(HIST("globalMC/hMCphiGen"))->Fill(mcParticle.phi()); + registryMC.get(HIST("globalMC/hMCyGen"))->Fill(mcParticle.y()); + registryMC.get(HIST("globalMC/hMCptGen"))->Fill(mcParticle.pt()); + } // end of UPCgen case + + if (mcParticle.has_mothers()) { + auto const& mother = mcParticle.mothers_first_as(); + if (std::abs(mother.pdgCode()) == kTauMinus) { // 15 + countChargedOnlyFromTau++; + } // mother is tau + } // mc particle has mother + } // veto neutral particles + // end of special case only for UPCgen + // // tau+/- // - if (std::abs(mcParticle.pdgCode()) == 15) { // tau+/- + // if (std::abs(mcParticle.pdgCode()) == 15) { // tau+/- + if (std::abs(mcParticle.pdgCode()) == kTauMinus) { // 15 = tau+/- countTau++; if (countTau <= 2) { etaTau[countTau - 1] = mcParticle.eta(); @@ -3265,16 +3438,18 @@ struct TauTau13topo { if (mcParticle.has_daughters()) { for (const auto& daughter : mcParticle.daughters_as()) { // pions from tau - if (std::abs(daughter.pdgCode()) == 211) { // 211 = pi+ + if (std::abs(daughter.pdgCode()) == kPiPlus) { // 211 = pi+ pionCounter++; tmpPionIndex = daughter.index(); // returns index of daughter of tau, not in the event, not in the MC particles if (std::abs(daughter.eta()) > 0.9) partFromTauInEta = false; } // end of pion check + // electron from tau - if (std::abs(daughter.pdgCode()) == 11) { // 11 = electron - if (daughter.pdgCode() == 11) + if (std::abs(daughter.pdgCode()) == kElectron) { // 11 = electron + if (daughter.pdgCode() == kElectron) flagElPlusElMinus = true; + registryMC.get(HIST("electronMC/hMCeta"))->Fill(daughter.eta()); registryMC.get(HIST("electronMC/hMCphi"))->Fill(daughter.phi()); registryMC.get(HIST("electronMC/hMCy"))->Fill(daughter.y()); @@ -3287,10 +3462,17 @@ struct TauTau13topo { if (std::abs(daughter.eta()) > 0.9) partFromTauInEta = false; } // end of electron check + // muon from tau - if (std::abs(daughter.pdgCode()) == 13) { - if (daughter.pdgCode() == 13) + if (std::abs(daughter.pdgCode()) == kMuonMinus) { // 13 + if (daughter.pdgCode() == kMuonMinus) // 13 flagMuPlusMuMinus = true; + + registryMC.get(HIST("muonMC/hMCeta"))->Fill(daughter.eta()); + registryMC.get(HIST("muonMC/hMCphi"))->Fill(daughter.phi()); + registryMC.get(HIST("muonMC/hMCy"))->Fill(daughter.y()); + registryMC.get(HIST("muonMC/hMCpt"))->Fill(daughter.pt()); + muonFound = !muonFound; partPt = static_cast(daughter.pt()); // LOGF(info,"mu pt %f",daughter.pt()); @@ -3298,6 +3480,7 @@ struct TauTau13topo { partFromTauInEta = false; } // end of muon check } // end of loop over daughters + if (pionCounter == 3) { threePionsFound = true; } // end of 3pi check @@ -3305,8 +3488,14 @@ struct TauTau13topo { singlePionFound = true; singlePionIndex = tmpPionIndex; auto mcPartTmp = mcParticle.daughters_as().begin() + singlePionIndex; - if (mcPartTmp.pdgCode() == -211) + if (mcPartTmp.pdgCode() == kPiMinus) // -211 flagPiPlusPiMinus = true; + + registryMC.get(HIST("pionMC/hMCeta"))->Fill(mcPartTmp.eta()); + registryMC.get(HIST("pionMC/hMCphi"))->Fill(mcPartTmp.phi()); + registryMC.get(HIST("pionMC/hMCy"))->Fill(mcPartTmp.y()); + registryMC.get(HIST("pionMC/hMCpt"))->Fill(mcPartTmp.pt()); + partPt = static_cast(mcPartTmp.pt()); // motherOfSinglePionIndex = mcParticle.index(); if (std::abs(mcPartTmp.eta()) > 0.9) @@ -3319,6 +3508,7 @@ struct TauTau13topo { // LOGF(info,"pt after %f",partPt); // tau related things + registryMC.get(HIST("tauMC/hNtaus"))->Fill(countTau); if (countTau == 2) { registryMC.get(HIST("tauMC/hMCdeltaeta"))->Fill(etaTau[0] - etaTau[1]); registryMC.get(HIST("tauMC/hMCdeltaphi"))->Fill(calculateDeltaPhi(phiTau[0], phiTau[1]) * 180. / o2::constants::math::PI); @@ -3368,45 +3558,97 @@ struct TauTau13topo { registryMC.get(HIST("globalMC/hMCnPart"))->Fill(countBoth, 2); registryMC.get(HIST("globalMC/hMCnPart"))->Fill(countCharged, 3); registryMC.get(HIST("globalMC/hMCnPart"))->Fill(countChargedFromTau, 4); - if (countChargedFromTau != 4) - return; - registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(1., 1.); - if (electronFound && flagElPlusElMinus) - registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(2., 1.); // e- - else if (electronFound && !flagElPlusElMinus) - registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(3., 1.); // e+ - if (muonFound && flagMuPlusMuMinus) - registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(4., 1.); // mu- - else if (muonFound && !flagMuPlusMuMinus) - registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(5., 1.); // mu+ - if (singlePionFound && flagPiPlusPiMinus) - registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(6., 1.); // pi- - else if (singlePionFound && !flagPiPlusPiMinus) - registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(7., 1.); // pi+ + registryMC.get(HIST("globalMC/hMCnPart"))->Fill(countPrim, 5); + registryMC.get(HIST("globalMC/hMCnPart"))->Fill(countChargedOnly, 6); + registryMC.get(HIST("globalMC/hMCnPart"))->Fill(countChargedOnlyFromTau, 7); - if (!tauInRapidity) - return; - registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(8., 1.); - if (!partFromTauInEta) - return; - registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(9., 1.); + if (countChargedFromTau == 2 || countChargedOnlyFromTau == 2) { + // 2 tracks candidates + registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(-7., 1.); + } + if (countChargedFromTau == 6 || countChargedOnlyFromTau == 6) { + // 6 tracks candidates + registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(-6., 1.); + } + // if (countChargedFromTau != 4) + // return; + if (countChargedFromTau == 4 || countChargedOnlyFromTau == 4) { + // 4 tracks candidates + registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(-5., 1.); // 4 tracks + if (electronFound && flagElPlusElMinus) + registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(-4., 1.); // e- + else if (electronFound && !flagElPlusElMinus) + registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(-3., 1.); // e+ + if (muonFound && flagMuPlusMuMinus) + registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(-2., 1.); // mu- + else if (muonFound && !flagMuPlusMuMinus) + registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(-1., 1.); // mu+ + if (singlePionFound && flagPiPlusPiMinus) + registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(0., 1.); // pi- + else if (singlePionFound && !flagPiPlusPiMinus) + registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(1., 1.); // pi+ + + if (!tauInRapidity) + return; + registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(2., 1.); + if (!partFromTauInEta) + return; + registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(3., 1.); + + if (electronFound && flagElPlusElMinus) + registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(4., 1.); // e- + else if (electronFound && !flagElPlusElMinus) + registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(5., 1.); // e+ + if (muonFound && flagMuPlusMuMinus) + registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(6., 1.); // mu- + else if (muonFound && !flagMuPlusMuMinus) + registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(7., 1.); // mu+ + if (singlePionFound && flagPiPlusPiMinus) + registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(8., 1.); // pi- + else if (singlePionFound && !flagPiPlusPiMinus) + registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(9., 1.); // pi+ + + } // end of 4 tracks candidate events } // end of processSimpleMCSG + // using LabeledTracks = soa::Join; + using LabeledTracks = soa::Join; + Preslice perCollision = aod::udtrack::udCollisionId; + // ZDC is not reproduced in MC, it is for a consistency + using FullMcUdCollisions = soa::Join; + // using FullMcUdCollisions = soa::Join; + // PresliceUnsorted colPerMcCollision = aod::udcollision::udMcCollisionId; + // PresliceUnsorted partPerMcCollision = aod::udmcparticle::udMcCollisionId; + void processEfficiencyMCSG(aod::UDMcCollision const& mcCollision, + // void processEfficiencyMCSG(aod::UDMcCollisions const& mcCollisions, // soa::SmallGroups> const& collisions, - soa::SmallGroups> const& collisions, + // soa::SmallGroups> const& collisions, + soa::SmallGroups const& collisions, + // FullMcUdCollisions const& collisionsFull, LabeledTracks const& tracks, aod::UDMcParticles const& mcParticles) + // aod::UDMcParticles const& mcParts) { + // LOGF(info, " Per DF: UDMcParticles size %d, UDMcCollisions size %d, FullMcUdCollisions size %d", mcParts.size(), mcCollisions.size(), collisionsFull.size()); + // LOGF(info, " Per DF: UDMcParticles size %d, UDMcCollisions size %d, FullMcUdCollisions size %d", mcParts.size(), mcCollisions.size(), collisions.size()); + LOGF(info, " UDMcCollision size %d, SmallGroups FullMcUdCollisions size %d, UDtracks %d, UDMcParticles %d", mcCollision.size(), collisions.size(), tracks.size(), mcParticles.size()); + + // loop over generated collisions + // for (const auto &mcCollision : mcCollisions) { + // LOGF(info, " Per mcCollision not sliced: UDMcParticles size %d, FullMcUdCollisions size %d", mcParts.size(), collisionsFull.size()); + if (verbose) { LOGF(info, " GeneratorIDtot %d", mcCollision.generatorsID()); // below is not implemented in UDMcCollisions // LOGF(info," GeneratorIDtot %d, GenID %d, subGenID %d, source %d", mcCollision.generatorsID(), mcCollision.getGeneratorId(), mcCollision.getSubGeneratorId(), mcCollision.getSourceId()); } + // registry1MC.get(HIST("globalMC/hGeneratorID"))->Fill(mcCollision.getGeneratorID()); registry1MC.get(HIST("globalMC/hGeneratorID"))->Fill(mcCollision.generatorsID()); registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(10., 1.); if (!(generatorIDMC < 0)) { // do not check generatorsID process if generatorIDMC < 0 + // if (mcCollision.getGeneratorID() != generatorIDMC) if (mcCollision.generatorsID() != generatorIDMC) return; } @@ -3424,26 +3666,38 @@ struct TauTau13topo { bool tauInRapidity = true; bool partFromTauInEta = true; - TLorentzVector tmp(0., 0., 0., 0.); + // TLorentzVector tmp(0., 0., 0., 0.); + ROOT::Math::LorentzVector> tmp(0., 0., 0., 0.); + + // get reconstructed collisions associated to generated collision + // auto const& collisions = collisionsFull.sliceBy(colPerMcCollision, mcCollision.globalIndex()); + // LOGF(info, " per mcCollisions sliced collisions.size %d", collisions.size()); + + // get MC particles associated to generated collision + // auto const& mcParticles = mcParts.sliceBy(partPerMcCollision, mcCollision.globalIndex()); + // LOGF(info, " per mcCollisions sliced mcParticles.size %d", mcParticles.size()); for (const auto& mcParticle : mcParticles) { + // LOGF(info, " mcParticle pdg %d", mcParticle.pdgCode()); if (mcParticle.isPhysicalPrimary()) { - if (mcParticle.pdgCode() != 22 && std::abs(mcParticle.pdgCode()) != 12 && std::abs(mcParticle.pdgCode()) != 14 && std::abs(mcParticle.pdgCode()) != 16 && mcParticle.pdgCode() != 130 && mcParticle.pdgCode() != 111) { + // if (mcParticle.pdgCode() != 22 && std::abs(mcParticle.pdgCode()) != 12 && std::abs(mcParticle.pdgCode()) != 14 && std::abs(mcParticle.pdgCode()) != 16 && mcParticle.pdgCode() != 130 && mcParticle.pdgCode() != 111) { + if (mcParticle.pdgCode() != kGamma && std::abs(mcParticle.pdgCode()) != kNuE && std::abs(mcParticle.pdgCode()) != kNuMu && std::abs(mcParticle.pdgCode()) != kNuTau && mcParticle.pdgCode() != kK0Long && mcParticle.pdgCode() != kPi0) { if (mcParticle.has_mothers()) { auto const& mother = mcParticle.mothers_first_as(); + // LOGF(info, " mcParticle has mother %d",mother.pdgCode()); tmp.SetPxPyPzE(mother.px(), mother.py(), mother.pz(), mother.e()); - if (std::abs(mother.pdgCode()) == 15) { + if (std::abs(mother.pdgCode()) == kTauMinus) { // 15 if (std::abs(rapidity(mother.e(), mother.pz())) > 0.9) // if (std::abs(tmp.Rapidity()) > 0.9) tauInRapidity = false; - if (std::abs(eta(mcParticle.px(), mcParticle.py(), mcParticle.pz())) > 0.9) + if (std::abs(RecoDecay::eta(std::array{mcParticle.px(), mcParticle.py(), mcParticle.pz()})) > 0.9) // if (std::abs(tmp.Eta()) > 0.9) partFromTauInEta = false; - if (std::abs(mcParticle.pdgCode()) == 11) { + if (std::abs(mcParticle.pdgCode()) == kElectron) { // 11 index1ProngMC = mcParticle.index(); is1ProngElectronMC = true; - } else if (std::abs(mcParticle.pdgCode()) == 13) { + } else if (std::abs(mcParticle.pdgCode()) == kMuonMinus) { // 13 index1ProngMC = mcParticle.index(); // is1ProngMuonMC = true; } @@ -3457,16 +3711,15 @@ struct TauTau13topo { } count++; if (collisions.size() > 0) { - registryMC.get(HIST("globalMCrec/hMCetaGenCol"))->Fill(eta(mcParticle.px(), mcParticle.py(), mcParticle.pz())); - registryMC.get(HIST("globalMCrec/hMCphiGenCol"))->Fill(phi(mcParticle.px(), mcParticle.py())); + registryMC.get(HIST("globalMCrec/hMCetaGenCol"))->Fill(RecoDecay::eta(std::array{mcParticle.px(), mcParticle.py(), mcParticle.pz()})); + registryMC.get(HIST("globalMCrec/hMCphiGenCol"))->Fill(RecoDecay::phi(mcParticle.px(), mcParticle.py())); registryMC.get(HIST("globalMCrec/hMCyGenCol"))->Fill(rapidity(mcParticle.e(), mcParticle.pz())); - registryMC.get(HIST("globalMCrec/hMCptGenCol"))->Fill(pt(mcParticle.px(), mcParticle.py())); + registryMC.get(HIST("globalMCrec/hMCptGenCol"))->Fill(RecoDecay::pt(mcParticle.px(), mcParticle.py())); } } // mother is tau } // has mothers } // charged particles } // end if isPhysicalPrimary - } // end loop over mcParticle registryMC.get(HIST("globalMC/hMCefficiency"))->Fill(11., 1.); @@ -3492,10 +3745,10 @@ struct TauTau13topo { // // motherIndex[i] = (tmpMC.mothers_first_as()).globalIndex(); // } int motherIndex1Pi = motherIndex[0]; - int motherIndexNew = -1; + int motherIndexNew = 3; // was -1 int nDifferences = 0; for (int i = 1; i < 4; i++) { - if (motherIndex1Pi != motherIndex[i]) { // the same mother index + if (motherIndex1Pi != motherIndex[i]) { // the same mother (tau) index nDifferences++; motherIndexNew = i; } @@ -3508,8 +3761,8 @@ struct TauTau13topo { // if (!onlyPi) LOGF(info, "ERROR: should be 4 pions, but they are not!"); } // end of special check for pi + 3pi - int index3ProngMC[3]; - if (index1ProngMC > 0) { // electron or muon case + 3pi + int index3ProngMC[3] = {0, 0, 0}; // initialised of request + if (index1ProngMC > 0) { // electron or muon case + 3pi int index3pi = 0; for (int i = 0; i < 4; i++) { if (index1ProngMC == indexProngMC[i]) @@ -3527,7 +3780,8 @@ struct TauTau13topo { auto const& tmpPion2MC = mcParticles.begin() + index3ProngMC[1]; auto const& tmpPion3MC = mcParticles.begin() + index3ProngMC[2]; - if (std::abs(tmpPion1MC.pdgCode()) == 211 && std::abs(tmpPion2MC.pdgCode()) == 211 && std::abs(tmpPion3MC.pdgCode()) == 211) + // if (std::abs(tmpPion1MC.pdgCode()) == 211 && std::abs(tmpPion2MC.pdgCode()) == 211 && std::abs(tmpPion3MC.pdgCode()) == 211) + if (std::abs(tmpPion1MC.pdgCode()) == kPiPlus && std::abs(tmpPion2MC.pdgCode()) == kPiPlus && std::abs(tmpPion3MC.pdgCode()) == kPiPlus) // 211 211 211 is3prong3PiMC = true; // @@ -3547,13 +3801,13 @@ struct TauTau13topo { registryMC.get(HIST("efficiencyMCEl/hMCdeltaAlphaEpi"))->Fill(deltaAlpha2); registryMC.get(HIST("efficiencyMCEl/hMCdeltaAlphaEpi"))->Fill(deltaAlpha3); // - registryMC.get(HIST("efficiencyMCEl/hMCdeltaPhiEpi"))->Fill(calculateDeltaPhi(phi(tmp1ProngMC.px(), tmp1ProngMC.py()), phi(tmpPion1MC.px(), tmpPion1MC.py()))); - registryMC.get(HIST("efficiencyMCEl/hMCdeltaPhiEpi"))->Fill(calculateDeltaPhi(phi(tmp1ProngMC.px(), tmp1ProngMC.py()), phi(tmpPion2MC.px(), tmpPion2MC.py()))); - registryMC.get(HIST("efficiencyMCEl/hMCdeltaPhiEpi"))->Fill(calculateDeltaPhi(phi(tmp1ProngMC.px(), tmp1ProngMC.py()), phi(tmpPion3MC.px(), tmpPion3MC.py()))); + registryMC.get(HIST("efficiencyMCEl/hMCdeltaPhiEpi"))->Fill(calculateDeltaPhi(RecoDecay::phi(tmp1ProngMC.px(), tmp1ProngMC.py()), RecoDecay::phi(tmpPion1MC.px(), tmpPion1MC.py()))); + registryMC.get(HIST("efficiencyMCEl/hMCdeltaPhiEpi"))->Fill(calculateDeltaPhi(RecoDecay::phi(tmp1ProngMC.px(), tmp1ProngMC.py()), RecoDecay::phi(tmpPion2MC.px(), tmpPion2MC.py()))); + registryMC.get(HIST("efficiencyMCEl/hMCdeltaPhiEpi"))->Fill(calculateDeltaPhi(RecoDecay::phi(tmp1ProngMC.px(), tmp1ProngMC.py()), RecoDecay::phi(tmpPion3MC.px(), tmpPion3MC.py()))); // - registryMC.get(HIST("efficiencyMCEl/hMCdeltaPhiPipi"))->Fill(calculateDeltaPhi(phi(tmpPion1MC.px(), tmpPion1MC.py()), phi(tmpPion2MC.px(), tmpPion2MC.py()))); - registryMC.get(HIST("efficiencyMCEl/hMCdeltaPhiPipi"))->Fill(calculateDeltaPhi(phi(tmpPion1MC.px(), tmpPion1MC.py()), phi(tmpPion3MC.px(), tmpPion3MC.py()))); - registryMC.get(HIST("efficiencyMCEl/hMCdeltaPhiPipi"))->Fill(calculateDeltaPhi(phi(tmpPion2MC.px(), tmpPion2MC.py()), phi(tmpPion3MC.px(), tmpPion3MC.py()))); + registryMC.get(HIST("efficiencyMCEl/hMCdeltaPhiPipi"))->Fill(calculateDeltaPhi(RecoDecay::phi(tmpPion1MC.px(), tmpPion1MC.py()), RecoDecay::phi(tmpPion2MC.px(), tmpPion2MC.py()))); + registryMC.get(HIST("efficiencyMCEl/hMCdeltaPhiPipi"))->Fill(calculateDeltaPhi(RecoDecay::phi(tmpPion1MC.px(), tmpPion1MC.py()), RecoDecay::phi(tmpPion3MC.px(), tmpPion3MC.py()))); + registryMC.get(HIST("efficiencyMCEl/hMCdeltaPhiPipi"))->Fill(calculateDeltaPhi(RecoDecay::phi(tmpPion2MC.px(), tmpPion2MC.py()), RecoDecay::phi(tmpPion3MC.px(), tmpPion3MC.py()))); // auto deltaAlphaPi1 = deltaAlpha(tmpPion1MC, tmpPion2MC); @@ -3566,13 +3820,13 @@ struct TauTau13topo { float energyInCone = 0; float angleLimit = 0.5; if (deltaAlpha1 < angleLimit) { - energyInCone += pt(tmpPion1MC.px(), tmpPion1MC.py()); + energyInCone += RecoDecay::pt(tmpPion1MC.px(), tmpPion1MC.py()); } if (deltaAlpha2 < angleLimit) { - energyInCone += pt(tmpPion2MC.px(), tmpPion2MC.py()); + energyInCone += RecoDecay::pt(tmpPion2MC.px(), tmpPion2MC.py()); } if (deltaAlpha3 < angleLimit) { - energyInCone += pt(tmpPion3MC.px(), tmpPion3MC.py()); + energyInCone += RecoDecay::pt(tmpPion3MC.px(), tmpPion3MC.py()); } registryMC.get(HIST("efficiencyMCEl/hMCvirtCal"))->Fill(energyInCone); // @@ -3585,17 +3839,19 @@ struct TauTau13topo { registryMC.get(HIST("efficiencyMCEl/hMCVector"))->Fill(vectorAsym(tmp1ProngMC, tmpPion3MC)); // add eta phi - registryMC.get(HIST("efficiencyMCEl/hMCptEl"))->Fill(pt(tmp1ProngMC.px(), tmp1ProngMC.py())); + registryMC.get(HIST("efficiencyMCEl/hMCptEl"))->Fill(RecoDecay::pt(tmp1ProngMC.px(), tmp1ProngMC.py())); float px3pi = tmpPion1MC.px() + tmpPion2MC.px() + tmpPion3MC.px(); float py3pi = tmpPion1MC.py() + tmpPion2MC.py() + tmpPion3MC.py(); float pz3pi = tmpPion1MC.pz() + tmpPion2MC.pz() + tmpPion3MC.pz(); float en3pi = tmpPion1MC.e() + tmpPion2MC.e() + tmpPion3MC.e(); - registryMC.get(HIST("efficiencyMCEl/hMCpt4trk"))->Fill(pt(tmp1ProngMC.px() + px3pi, tmp1ProngMC.py() + py3pi)); - registryMC.get(HIST("efficiencyMCEl/hMCinvmass4pi"))->Fill(invariantMass(tmp1ProngMC.e() + en3pi, tmp1ProngMC.px() + px3pi, tmp1ProngMC.py() + py3pi, tmp1ProngMC.pz() + pz3pi)); - registryMC.get(HIST("efficiencyMCEl/hMCinvmass3pi"))->Fill(invariantMass(en3pi, px3pi, py3pi, pz3pi)); - registryMC.get(HIST("efficiencyMCEl/hMCdeltaphi13"))->Fill(calculateDeltaPhi(phi(tmp1ProngMC.px(), tmp1ProngMC.py()), phi(px3pi, py3pi))); + registryMC.get(HIST("efficiencyMCEl/hMCpt4trk"))->Fill(RecoDecay::pt(tmp1ProngMC.px() + px3pi, tmp1ProngMC.py() + py3pi)); + // registryMC.get(HIST("efficiencyMCEl/hMCinvmass4pi"))->Fill(invariantMass(tmp1ProngMC.e() + en3pi, tmp1ProngMC.px() + px3pi, tmp1ProngMC.py() + py3pi, tmp1ProngMC.pz() + pz3pi)); + registryMC.get(HIST("efficiencyMCEl/hMCinvmass4pi"))->Fill(RecoDecay::m(std::array{(tmp1ProngMC.px() + px3pi), (tmp1ProngMC.py() + py3pi), (tmp1ProngMC.pz() + pz3pi)}, (tmp1ProngMC.e() + en3pi))); + // registryMC.get(HIST("efficiencyMCEl/hMCinvmass3pi"))->Fill(invariantMass(en3pi, px3pi, py3pi, pz3pi)); + registryMC.get(HIST("efficiencyMCEl/hMCinvmass3pi"))->Fill(RecoDecay::m(std::array{px3pi, py3pi, pz3pi}, en3pi)); + registryMC.get(HIST("efficiencyMCEl/hMCdeltaphi13"))->Fill(calculateDeltaPhi(RecoDecay::phi(tmp1ProngMC.px(), tmp1ProngMC.py()), RecoDecay::phi(px3pi, py3pi))); // reconstructed event if (collisions.size() < 1) @@ -3724,7 +3980,7 @@ struct TauTau13topo { nPVTracks++; trackCharge += track.sign(); // if (std::abs(eta(track.px(),track.py(),track.pz())) >= trkEtacut) allInEtaAcceptance = false; - if (std::abs(eta(track.px(), track.py(), track.pz())) < trkEtacut) + if (std::abs(RecoDecay::eta(std::array{track.px(), track.py(), track.pz()})) < trkEtacut) nTrkInEtaRange++; if (track.pt() > 0.1) nTrkAbovePtThreshold++; @@ -3857,8 +4113,10 @@ struct TauTau13topo { registryMC.get(HIST("global1MCrec/hNTracks"))->Fill(groupedTracks.size()); registryMC.get(HIST("global1MCrec/hNTracksPV"))->Fill(nPVTracks); - TLorentzVector p, p1; - p.SetXYZM(0., 0., 0., 0.); + // TLorentzVector p, p1; + ROOT::Math::LorentzVector> p, p1; + // p.SetXYZM(0., 0., 0., 0.); + p.SetXYZT(0., 0., 0., 0.); TVector3 v1(0, 0, 0); TVector3 v2(0, 0, 0); float scalarPtsum = 0; @@ -3888,17 +4146,20 @@ struct TauTau13topo { flagVcalPV[i] = true; } } // end of second loop - float tmpEtaData = eta(tmptrack.px(), tmptrack.py(), tmptrack.pz()); - float tmpPhiData = phi(tmptrack.px(), tmptrack.py()); + float tmpEtaData = RecoDecay::eta(std::array{tmptrack.px(), tmptrack.py(), tmptrack.pz()}); + float tmpPhiData = RecoDecay::phi(tmptrack.px(), tmptrack.py()); registryMC.get(HIST("global1MCrec/hTrackEtaPhiPV"))->Fill(tmpEtaData, tmpPhiData); registryMC.get(HIST("global1MCrec/hTrackPtPV"))->Fill(tmptrack.pt()); - p1.SetXYZM(v1.X(), v1.Y(), v1.Z(), MassPiPlus); // in case of ghost + // p1.SetXYZM(v1.X(), v1.Y(), v1.Z(), MassPiPlus); // in case of ghost + p1.SetXYZT(v1.X(), v1.Y(), v1.Z(), RecoDecay::e(v1.X(), v1.Y(), v1.Z(), MassPiPlus)); // in case of ghost if (trackMCId[i] >= 0) { - p1.SetXYZM(v1.X(), v1.Y(), v1.Z(), (std::abs(tmptrack.udMcParticle().pdgCode()) == 211 ? MassPiPlus : MassElectron)); - float tmpPt = pt(tmptrack.udMcParticle().px(), tmptrack.udMcParticle().py()); - float tmpEta = eta(tmptrack.udMcParticle().px(), tmptrack.udMcParticle().py(), tmptrack.udMcParticle().pz()); - float tmpPhi = phi(tmptrack.udMcParticle().px(), tmptrack.udMcParticle().py()); + // p1.SetXYZM(v1.X(), v1.Y(), v1.Z(), (std::abs(tmptrack.udMcParticle().pdgCode()) == 211 ? MassPiPlus : MassElectron)); + // p1.SetXYZT(v1.X(), v1.Y(), v1.Z(), energy(v1.X(), v1.Y(), v1.Z(), (std::abs(tmptrack.udMcParticle().pdgCode()) == 211 ? MassPiPlus : MassElectron))); + p1.SetXYZT(v1.X(), v1.Y(), v1.Z(), RecoDecay::e(v1.X(), v1.Y(), v1.Z(), (std::abs(tmptrack.udMcParticle().pdgCode()) == kPiPlus ? MassPiPlus : MassElectron))); // 211 + float tmpPt = RecoDecay::pt(tmptrack.udMcParticle().px(), tmptrack.udMcParticle().py()); + float tmpEta = RecoDecay::eta(std::array{tmptrack.udMcParticle().px(), tmptrack.udMcParticle().py(), tmptrack.udMcParticle().pz()}); + float tmpPhi = RecoDecay::phi(tmptrack.udMcParticle().px(), tmptrack.udMcParticle().py()); registryMC.get(HIST("global1MCrec/hpTGenRecTracksPV"))->Fill(tmptrack.pt(), tmpPt); registryMC.get(HIST("global1MCrec/hDeltapTGenRecVsRecpTTracksPV"))->Fill(tmptrack.pt() - tmpPt, tmptrack.pt()); registryMC.get(HIST("global1MCrec/hEtaGenRecTracksPV"))->Fill(tmpEtaData, tmpEta); @@ -4010,7 +4271,7 @@ struct TauTau13topo { // // temporary control variables per event with combinatorics float pttot = p.Pt(); - float mass4pi = p.Mag(); + float mass4pi = p.mag(); int counterTmp = 0; float nSigmaEl[4]; @@ -4053,9 +4314,11 @@ struct TauTau13topo { auto const tmptrack = groupedTracks.begin() + trackId[i]; // if (tmptrack.hasTOF()) trkHasTof[i] = true; v1.SetXYZ(tmptrack.px(), tmptrack.py(), tmptrack.pz()); - p1.SetXYZM(v1.X(), v1.Y(), v1.Z(), MassPiPlus); // in case of ghost + // p1.SetXYZM(v1.X(), v1.Y(), v1.Z(), MassPiPlus); // in case of ghost + p1.SetXYZT(v1.X(), v1.Y(), v1.Z(), RecoDecay::e(v1.X(), v1.Y(), v1.Z(), MassPiPlus)); // in case of ghost if (trackMCId[i] >= 0) { - p1.SetXYZM(v1.X(), v1.Y(), v1.Z(), (i == matchedElIndexToData ? MassElectron : MassPiPlus)); + // p1.SetXYZM(v1.X(), v1.Y(), v1.Z(), (i == matchedElIndexToData ? MassElectron : MassPiPlus)); + p1.SetXYZT(v1.X(), v1.Y(), v1.Z(), RecoDecay::e(v1.X(), v1.Y(), v1.Z(), (i == matchedElIndexToData ? MassElectron : MassPiPlus))); } nSigmaEl[counterTmp] = tmptrack.tpcNSigmaEl(); @@ -4097,7 +4360,7 @@ struct TauTau13topo { tmpTofNsigmaEl[counterTmp] = tmptrack.tofNSigmaEl(); deltaPhiTmp = calculateDeltaPhi(p - p1, p1); - pi3invMass[counterTmp] = (p - p1).Mag(); + pi3invMass[counterTmp] = (p - p1).mag(); pi3pt[counterTmp] = (p - p1).Pt(); pi3deltaPhi[counterTmp] = deltaPhiTmp; pi3assymav[counterTmp] = (p1.Pt() - (scalarPtsum - p1.Pt()) / 3.) / (p1.Pt() + (scalarPtsum - p1.Pt()) / 3.); @@ -4816,6 +5079,8 @@ struct TauTau13topo { } // end of loop over collisions } // end of electron + 3pi + // } // end of loop over mcCollisions + } // end of processEfficiencyMCSG // skimming: only 4 tracks selection @@ -4845,11 +5110,13 @@ struct TauTau13topo { int nEtaIn15 = 0; int npT100 = 0; // int qtot = 0; - int16_t qtot = 0; - TLorentzVector p; + int8_t qtot = 0; + // TLorentzVector p; + ROOT::Math::LorentzVector> p; for (const auto& trk : PVContributors) { qtot += trk.sign(); - p.SetXYZM(trk.px(), trk.py(), trk.pz(), MassPiPlus); + // p.SetXYZM(trk.px(), trk.py(), trk.pz(), MassPiPlus); + p.SetXYZT(trk.px(), trk.py(), trk.pz(), RecoDecay::e(trk.px(), trk.py(), trk.pz(), MassPiPlus)); if (std::abs(p.Eta()) < trkEtacut) nEtaIn15++; // 0.9 is a default if (trk.pt() > 0.1) @@ -4898,14 +5165,18 @@ struct TauTau13topo { return; registrySkim.get(HIST("skim/efficiency"))->Fill(7., 1.); + // RCT variable + int rct = 0; + rct = isGoodRCTflag(dgcand); + // // variables per track // int counterTmp = 0; float px[4], py[4], pz[4]; - // int sign[4]; - // float dcaZ[4]; - // float dcaXY[4]; + int8_t sign[4]; + float dcaZ[4]; + float dcaXY[4]; float tmpDedx[4]; float tmpTofNsigmaEl[4]; @@ -4919,11 +5190,13 @@ struct TauTau13topo { float nSigmaPr[4]; float nSigmaKa[4]; float nSigmaMu[4]; - // float chi2TPC[4]; - // float chi2ITS[4]; float chi2TOF[4] = {-1., -1., -1., -1.}; - // float nclTPCfind[4]; int nclTPCcrossedRows[4]; + int nclTPCfind[4]; + float nclTPCchi2[4]; + float trkITSchi2[4]; + int trkITScl[4]; + // double trkTime[4]; // float trkTimeRes[4]; float trkTofSignal[4]; @@ -4933,9 +5206,9 @@ struct TauTau13topo { px[counterTmp] = trk.px(); py[counterTmp] = trk.py(); pz[counterTmp] = trk.pz(); - // sign[counterTmp] = trk.sign(); - // dcaZ[counterTmp] = trk.dcaZ(); - // dcaXY[counterTmp] = trk.dcaXY(); + sign[counterTmp] = trk.sign(); + dcaZ[counterTmp] = trk.dcaZ(); + dcaXY[counterTmp] = trk.dcaXY(); tmpDedx[counterTmp] = trk.tpcSignal(); nSigmaEl[counterTmp] = trk.tpcNSigmaEl(); @@ -4951,13 +5224,16 @@ struct TauTau13topo { tmpTofNsigmaPr[counterTmp] = trk.tofNSigmaPr(); tmpTofNsigmaMu[counterTmp] = trk.tofNSigmaMu(); - // chi2TPC[counterTmp] = trk.tpcChi2NCl(); - // chi2ITS[counterTmp] = trk.itsChi2NCl(); if (trk.hasTOF()) chi2TOF[counterTmp] = trk.tofChi2(); // nclTPCfind[counterTmp] = trk.tpcNClsFindable(); nclTPCcrossedRows[counterTmp] = trk.tpcNClsCrossedRows(); + nclTPCfind[counterTmp] = trk.tpcNClsFindable(); + nclTPCchi2[counterTmp] = trk.tpcChi2NCl(); + trkITSchi2[counterTmp] = trk.itsChi2NCl(); + trkITScl[counterTmp] = numberOfItsClustersCheck(trk); + // trkTime[counterTmp] = trk.trackTime(); // trkTimeRes[counterTmp] = trk.trackTimeRes(); counterTmp++; @@ -4967,6 +5243,7 @@ struct TauTau13topo { dgcand.globalBC(), // is it necessary dgtracks.size(), dgcand.numContrib(), + rct, // dgcand.posX(), dgcand.posY(), dgcand.posZ(), dgcand.flags(), @@ -4975,12 +5252,12 @@ struct TauTau13topo { energyZNA, energyZNC, qtot, dgcand.trs(), dgcand.trofs(), dgcand.hmpr(), // to test it - // dgcand.tfb(), dgcand.itsROFb(), dgcand.sbp(), dgcand.zVtxFT0vPV(), dgcand.vtxITSTPC(), + dgcand.tfb(), dgcand.itsROFb(), dgcand.sbp(), dgcand.zVtxFT0vPV(), dgcand.vtxITSTPC(), dgcand.totalFT0AmplitudeA(), dgcand.totalFT0AmplitudeC(), dgcand.totalFV0AmplitudeA(), // dgcand.timeFT0A(), dgcand.timeFT0C(), dgcand.timeFV0A(), - px, py, pz, // sign, - // dcaXY, dcaZ, - nclTPCcrossedRows, + px, py, pz, sign, + dcaXY, dcaZ, + nclTPCcrossedRows, nclTPCfind, nclTPCchi2, trkITSchi2, trkITScl, tmpDedx, nSigmaEl, nSigmaPi, nSigmaKa, nSigmaPr, nSigmaMu, trkTofSignal, tmpTofNsigmaEl, tmpTofNsigmaPi, tmpTofNsigmaKa, tmpTofNsigmaPr, tmpTofNsigmaMu, chi2TOF); diff --git a/Scripts/o2_linter.py b/Scripts/o2_linter.py index af7de5f101b..2aa8fefb24f 100644 --- a/Scripts/o2_linter.py +++ b/Scripts/o2_linter.py @@ -248,7 +248,7 @@ def is_disabled(self, line: str, prefix_comment="//") -> bool: if self.name in line: self.n_disabled += 1 # Look for a comment with a reason for disabling. - if re.search(r" \([\w\s]{3,}\)", line): + if re.search(r" \(.{3,}\)", line): return True return False diff --git a/git b/git deleted file mode 100644 index e69de29bb2d..00000000000