diff --git a/Common/CCDB/CMakeLists.txt b/Common/CCDB/CMakeLists.txt index 0ae8e9fd0f7..63584528a38 100644 --- a/Common/CCDB/CMakeLists.txt +++ b/Common/CCDB/CMakeLists.txt @@ -12,9 +12,11 @@ o2physics_add_library(AnalysisCCDB SOURCES EventSelectionParams.cxx SOURCES TriggerAliases.cxx + SOURCES ctpRateFetcher.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore) o2physics_target_root_dictionary(AnalysisCCDB HEADERS EventSelectionParams.h HEADERS TriggerAliases.h + HEADERS ctpRateFetcher.h LINKDEF AnalysisCCDBLinkDef.h) diff --git a/Common/CCDB/ctpRateFetcher.cxx b/Common/CCDB/ctpRateFetcher.cxx new file mode 100644 index 00000000000..418fcc74b07 --- /dev/null +++ b/Common/CCDB/ctpRateFetcher.cxx @@ -0,0 +1,137 @@ +// 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. + +#include "ctpRateFetcher.h" + +#include +#include + +#include "CommonConstants/LHCConstants.h" +#include "DataFormatsCTP/Configuration.h" +#include "DataFormatsCTP/Scalers.h" +#include "DataFormatsParameters/GRPLHCIFData.h" +#include "CCDB/BasicCCDBManager.h" + +namespace o2 +{ + +using framework::Service; + +double ctpRateFetcher::fetch(Service& ccdb, uint64_t timeStamp, int runNumber, std::string sourceName) +{ + if (sourceName.find("ZNC") != std::string::npos) { + if (runNumber < 544448) { + return fetchCTPratesInputs(ccdb, timeStamp, runNumber, 26) / (sourceName.find("hadronic") != std::string::npos ? 28. : 1.); + } else { + return fetchCTPratesClasses(ccdb, timeStamp, runNumber, "C1ZNC-B-NOPF-CRU", 6) / (sourceName.find("hadronic") != std::string::npos ? 28. : 1.); + } + } else if (sourceName == "T0CE") { + return fetchCTPratesClasses(ccdb, timeStamp, runNumber, "CMTVXTCE-B-NOPF-CRU"); + } else if (sourceName == "T0SC") { + return fetchCTPratesClasses(ccdb, timeStamp, runNumber, "CMTVXTSC-B-NOPF-CRU"); + } else if (sourceName == "T0VTX") { + if (runNumber < 534202) { + return fetchCTPratesClasses(ccdb, timeStamp, runNumber, "minbias_TVX_L0"); // 2022 + } else { + return fetchCTPratesClasses(ccdb, timeStamp, runNumber, "CMTVX-B-NOPF-CRU"); + } + } + LOG(error) << "CTP rate for " << sourceName << " not available"; + return -1.; +} + +double ctpRateFetcher::fetchCTPratesClasses(Service& ccdb, uint64_t timeStamp, int runNumber, std::string className, int inputType) +{ + getCTPscalers(ccdb, timeStamp, runNumber); + getCTPconfig(ccdb, timeStamp, runNumber); + + std::vector ctpcls = mConfig->getCTPClasses(); + std::vector clslist = mConfig->getTriggerClassList(); + int classIndex = -1; + for (size_t i = 0; i < clslist.size(); i++) { + if (ctpcls[i].name == className) { + classIndex = i; + break; + } + } + if (classIndex == -1) { + LOG(fatal) << "Trigger class " << className << " not found in CTPConfiguration"; + } + + auto rate{mScalers->getRateGivenT(timeStamp, classIndex, inputType)}; + + return pileUpCorrection(rate.second); +} + +double ctpRateFetcher::fetchCTPratesInputs(Service& ccdb, uint64_t timeStamp, int runNumber, int input) +{ + getCTPscalers(ccdb, timeStamp, runNumber); + getLHCIFdata(ccdb, timeStamp, runNumber); + + std::vector recs = mScalers->getScalerRecordO2(); + if (recs[0].scalersInps.size() == 48) { + return pileUpCorrection(mScalers->getRateGivenT(timeStamp, input, 7).second); + } else { + LOG(error) << "Inputs not available"; + return -1.; + } +} + +void ctpRateFetcher::getCTPscalers(Service& ccdb, uint64_t timeStamp, int runNumber) +{ + if (runNumber == mRunNumber && mScalers != nullptr) { + return; + } + std::map metadata; + metadata["runNumber"] = std::to_string(runNumber); + mScalers = ccdb->getSpecific("CTP/Calib/Scalers", timeStamp, metadata); + if (mScalers == nullptr) { + LOG(fatal) << "CTPRunScalers not in database, timestamp:" << timeStamp; + } + mScalers->convertRawToO2(); +} + +void ctpRateFetcher::getLHCIFdata(Service& ccdb, uint64_t timeStamp, int runNumber) +{ + if (runNumber == mRunNumber && mLHCIFdata != nullptr) { + return; + } + std::map metadata; + mLHCIFdata = ccdb->getSpecific("GLO/Config/GRPLHCIF", timeStamp, metadata); + if (mLHCIFdata == nullptr) { + LOG(fatal) << "GRPLHCIFData not in database, timestamp:" << timeStamp; + } +} + +void ctpRateFetcher::getCTPconfig(Service& ccdb, uint64_t timeStamp, int runNumber) +{ + if (runNumber == mRunNumber && mConfig != nullptr) { + return; + } + std::map metadata; + metadata["runNumber"] = std::to_string(runNumber); + mConfig = ccdb->getSpecific("CTP/Config/Config", timeStamp, metadata); + if (mConfig == nullptr) { + LOG(fatal) << "CTPRunConfig not in database, timestamp:" << timeStamp; + } +} + +double ctpRateFetcher::pileUpCorrection(double triggerRate) +{ + auto bfilling = mLHCIFdata->getBunchFilling(); + std::vector bcs = bfilling.getFilledBCs(); + double nbc = bcs.size(); + double nTriggersPerFilledBC = triggerRate / nbc / constants::lhc::LHCRevFreq; + double mu = -std::log(1 - nTriggersPerFilledBC); + return mu * nbc * constants::lhc::LHCRevFreq; +} + +} // namespace o2 diff --git a/Common/CCDB/ctpRateFetcher.h b/Common/CCDB/ctpRateFetcher.h new file mode 100644 index 00000000000..c6dc3840f50 --- /dev/null +++ b/Common/CCDB/ctpRateFetcher.h @@ -0,0 +1,55 @@ +// 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 COMMON_CCDB_CTPRATEFETCHER_H_ +#define COMMON_CCDB_CTPRATEFETCHER_H_ + +#include + +#include "CCDB/BasicCCDBManager.h" +#include "Framework/AnalysisHelpers.h" + +namespace o2 +{ + +namespace ctp +{ +class CTPRunScalers; +class CTPConfiguration; +} // namespace ctp + +namespace parameters +{ +class GRPLHCIFData; +} + +class ctpRateFetcher +{ + public: + ctpRateFetcher() = default; + double fetch(framework::Service& ccdb, uint64_t timeStamp, int runNumber, std::string sourceName); + + private: + void getCTPconfig(framework::Service& ccdb, uint64_t timeStamp, int runNumber); + void getCTPscalers(framework::Service& ccdb, uint64_t timeStamp, int runNumber); + void getLHCIFdata(framework::Service& ccdb, uint64_t timeStamp, int runNumber); + double fetchCTPratesInputs(framework::Service& ccdb, uint64_t timeStamp, int runNumber, int input); + double fetchCTPratesClasses(framework::Service& ccdb, uint64_t timeStamp, int runNumber, std::string className, int inputType = 1); + double pileUpCorrection(double rate); + + int mRunNumber = -1; + ctp::CTPConfiguration* mConfig = nullptr; + ctp::CTPRunScalers* mScalers = nullptr; + parameters::GRPLHCIFData* mLHCIFdata = nullptr; +}; +} // namespace o2 + +#endif // COMMON_CCDB_CTPRATEFETCHER_H_ diff --git a/Common/Core/PID/PIDTOF.h b/Common/Core/PID/PIDTOF.h index dc4cf39edc6..2a54e28dfe6 100644 --- a/Common/Core/PID/PIDTOF.h +++ b/Common/Core/PID/PIDTOF.h @@ -323,7 +323,7 @@ class ExpTimes /// Gets the number of sigmas with respect the expected time /// \param parameters Detector response parameters /// \param track Track of interest - static float GetSeparation(const TOFResoParamsV2& parameters, const TrackType& track) { return GetSeparation(parameters, track, track.tofEvTime(), track.tofEvTimeErr()); } + static float GetSeparation(const TOFResoParamsV2& parameters, const TrackType& track) { return GetSeparation(parameters, track, track.tofEvTime(), GetExpectedSigma(parameters, track)); } }; /// \brief Class to convert the trackTime to the tofSignal used for PID diff --git a/Common/DataModel/PIDResponse.h b/Common/DataModel/PIDResponse.h index d64aced3c94..555e479eecd 100644 --- a/Common/DataModel/PIDResponse.h +++ b/Common/DataModel/PIDResponse.h @@ -388,7 +388,8 @@ enum PIDFlags : uint8_t { }; } -DECLARE_SOA_COLUMN(TOFFlags, tofFlags, uint8_t); //! Flag for the complementary TOF PID information +DECLARE_SOA_COLUMN(GoodTOFMatch, goodTOFMatch, bool); //! Bool for the TOF PID information on the single track information +DECLARE_SOA_COLUMN(TOFFlags, tofFlags, uint8_t); //! Flag for the complementary TOF PID information for the event time DECLARE_SOA_DYNAMIC_COLUMN(IsEvTimeDefined, isEvTimeDefined, //! True if the Event Time was computed with any method i.e. there is a usable event time [](uint8_t flags) -> bool { return (flags > 0); }); DECLARE_SOA_DYNAMIC_COLUMN(IsEvTimeTOF, isEvTimeTOF, //! True if the Event Time was computed with the TOF @@ -529,6 +530,9 @@ DEFINE_UNWRAP_NSIGMA_COLUMN(TOFNSigmaAl, tofNSigmaAl); //! Unwrapped (float) nsi DECLARE_SOA_TABLE(TOFSignal, "AOD", "TOFSignal", //! Table of the TOF signal pidtofsignal::TOFSignal); +DECLARE_SOA_TABLE(pidTOFFlags, "AOD", "pidTOFFlags", //! Table of the flags for TOF signal quality on the track level + pidflags::GoodTOFMatch); + DECLARE_SOA_TABLE(pidTOFbeta, "AOD", "pidTOFbeta", //! Table of the TOF beta pidtofbeta::Beta, pidtofbeta::BetaError); diff --git a/Common/TableProducer/PID/pidTOFBase.cxx b/Common/TableProducer/PID/pidTOFBase.cxx index b884ff1f971..c3cad0107e1 100644 --- a/Common/TableProducer/PID/pidTOFBase.cxx +++ b/Common/TableProducer/PID/pidTOFBase.cxx @@ -29,6 +29,7 @@ #include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/FT0Corrected.h" +#include "Common/DataModel/Multiplicity.h" #include "TableHelper.h" #include "pidTOFBase.h" @@ -47,14 +48,36 @@ void customize(std::vector& workflowOptions) #include "Framework/runDataProcessing.h" +/// Selection criteria for tracks used for TOF event time +float trackDistanceForGoodMatch = 999.f; +float trackDistanceForGoodMatchLowMult = 999.f; +int multiplicityThreshold = 0; +using Run3Trks = o2::soa::Join; +using Run3Cols = o2::soa::Join; +bool isTrackGoodMatchForTOFPID(const Run3Trks::iterator& tr, const Run3Cols& ev) +{ + if (!tr.hasTOF()) { + return false; + } + if (tr.has_collision() && tr.collision_as().multNTracksPVeta1() < multiplicityThreshold) { + return tr.tofChi2() < trackDistanceForGoodMatchLowMult; + } + return tr.tofChi2() < trackDistanceForGoodMatch; +} + /// Task to produce the TOF signal from the trackTime information struct tofSignal { o2::framework::Produces table; - bool enableTable = false; + o2::framework::Produces tableFlags; + bool enableTable = false; // Flag to check if the TOF signal table is requested or not + bool enableTableFlags = false; // Flag to check if the TOF signal flags table is requested or not // CCDB configuration Configurable url{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable timestamp{"ccdb-timestamp", -1, "timestamp of the object"}; Configurable timeShiftCCDBPath{"timeShiftCCDBPath", "", "Path of the TOF time shift vs eta. If empty none is taken"}; + Configurable distanceForGoodMatch{"distanceForGoodMatch", 999.f, "Maximum distance to consider a good match"}; + Configurable distanceForGoodMatchLowMult{"distanceForGoodMatchLowMult", 999.f, "Maximum distance to consider a good match for low multiplicity events"}; + Configurable multThreshold{"multThreshold", 0, "Multiplicity threshold to consider a low multiplicity event"}; void init(o2::framework::InitContext& initContext) { @@ -70,16 +93,30 @@ struct tofSignal { if (enableTable) { LOG(info) << "Table TOFSignal enabled!"; } + enableTableFlags = isTableRequiredInWorkflow(initContext, "pidTOFFlags"); + if (enableTableFlags) { + LOG(info) << "Table pidTOFFlags enabled!"; + } + trackDistanceForGoodMatch = distanceForGoodMatch; + trackDistanceForGoodMatchLowMult = distanceForGoodMatchLowMult; + multiplicityThreshold = multThreshold; + LOG(info) << "Configuring selections for good match: " << trackDistanceForGoodMatch << " low mult " << trackDistanceForGoodMatchLowMult << " mult. threshold " << multiplicityThreshold; } - using Trks = o2::soa::Join; - void processRun3(Trks const& tracks) + void processRun3(Run3Trks const& tracks, Run3Cols const& collisions) { if (!enableTable) { return; } table.reserve(tracks.size()); + if (enableTableFlags) { + tableFlags.reserve(tracks.size()); + } for (auto& t : tracks) { - table(o2::pid::tof::TOFSignal::GetTOFSignal(t)); + table(o2::pid::tof::TOFSignal::GetTOFSignal(t)); + if (!enableTableFlags) { + continue; + } + tableFlags(isTrackGoodMatchForTOFPID(t, collisions)); } } PROCESS_SWITCH(tofSignal, processRun3, "Process Run3 data i.e. input is TrackIU", true); @@ -91,8 +128,15 @@ struct tofSignal { return; } table.reserve(tracks.size()); + if (enableTableFlags) { + tableFlags.reserve(tracks.size()); + } for (auto& t : tracks) { table(o2::pid::tof::TOFSignal::GetTOFSignal(t)); + if (!enableTableFlags) { + continue; + } + tableFlags(true); } } PROCESS_SWITCH(tofSignal, processRun2, "Process Run2 data i.e. input is Tracks", false); diff --git a/Common/TableProducer/eventSelection.cxx b/Common/TableProducer/eventSelection.cxx index 2141c065768..eedcc8db1bd 100644 --- a/Common/TableProducer/eventSelection.cxx +++ b/Common/TableProducer/eventSelection.cxx @@ -308,10 +308,10 @@ struct BcSelectionTask { float csZEM = isPP ? -1. : 415.2e6; float csZNC = isPP ? -1. : 214.5e6; if (run > 543437 && run < 543514) { - csTCE = 8.3; + csTCE = 8.3e6; } if (run >= 543514) { - csTCE = 3.97; + csTCE = 3.97e6; } // Fill TVX (T0 vertex) counters diff --git a/Common/TableProducer/ft0CorrectedTable.cxx b/Common/TableProducer/ft0CorrectedTable.cxx index ba1e15c624a..530138ae623 100644 --- a/Common/TableProducer/ft0CorrectedTable.cxx +++ b/Common/TableProducer/ft0CorrectedTable.cxx @@ -8,20 +8,20 @@ // 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. -#include "Framework/ConfigParamSpec.h" - -using namespace o2; -using namespace o2::framework; +#include +#include "Common/DataModel/FT0Corrected.h" +#include "Framework/ConfigParamSpec.h" #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Common/DataModel/EventSelection.h" #include "Framework/AnalysisDataModel.h" #include "CommonConstants/LHCConstants.h" #include "CommonConstants/PhysicsConstants.h" -#include "Common/DataModel/FT0Corrected.h" #include "DataFormatsFT0/Digit.h" -#include + +using namespace o2; +using namespace o2::framework; using namespace o2::aod; struct FT0CorrectedTable { @@ -36,6 +36,7 @@ struct FT0CorrectedTable { float vertex_corr = vertexPV / o2::constants::physics::LightSpeedCm2NS; float t0A = 1e10; float t0C = 1e10; + constexpr float dummyTime = 30.; // Due to HW limitations time can be only within range (-25,25) ns, dummy time is around 32 ns if (collision.has_foundFT0()) { auto ft0 = collision.foundFT0(); std::bitset<8> triggers = ft0.triggerMask(); @@ -43,10 +44,10 @@ struct FT0CorrectedTable { bool orc = triggers[o2::ft0::Triggers::bitC]; LOGF(debug, "triggers OrA %i OrC %i ", ora, orc); LOGF(debug, " T0A = %f, T0C %f, vertex_corr %f", ft0.timeA(), ft0.timeC(), vertex_corr); - if (ora) { + if (ora && ft0.timeA() < dummyTime) { t0A = ft0.timeA() + vertex_corr; } - if (orc) { + if (orc && ft0.timeC() < dummyTime) { t0C = ft0.timeC() - vertex_corr; } } diff --git a/Common/TableProducer/qVectorsTable.cxx b/Common/TableProducer/qVectorsTable.cxx index 0e51ffdd6bb..dd42ed8408f 100644 --- a/Common/TableProducer/qVectorsTable.cxx +++ b/Common/TableProducer/qVectorsTable.cxx @@ -74,6 +74,8 @@ struct qVectorsTable { Configurable cfgCentEsti{"cfgCentEsti", 2, "Centrality estimator (Run3): 0 = FT0M, 1 = FT0A, 2 = FT0C, 3 = FV0A"}; + Configurable cfgCCDBConst{"cfgCCDBConst", 1, "Using constants in CCDB, 1 = CCDB, 2= Configurable"}; + // LOKI: We have here all centrality estimators for Run 3 (except FDDM and NTPV), // but the Q-vectors are calculated only for some of them. // FIXME: 6 correction factors for each centrality and 8 centrality intervals are hard-coded. @@ -147,30 +149,93 @@ struct qVectorsTable { LOGF(fatal, "Could not get the alignment parameters for FV0."); } - if (cfgFT0CCorr->size() < 48) { - LOGF(fatal, "No proper correction factor assigned for FT0C"); - } - if (cfgFT0ACorr->size() < 48) { - LOGF(fatal, "No proper correction factor assigned for FT0A"); - } - if (cfgFT0MCorr->size() < 48) { - LOGF(fatal, "No proper correction factor assigned for FT0M"); - } - if (cfgFV0ACorr->size() < 48) { - LOGF(fatal, "No proper correction factor assigned for FV0A"); - } - if (cfgBPosCorr->size() < 48) { - LOGF(fatal, "No proper correction factor assigned for positive TPC tracks"); + if (cfgCCDBConst == 1) { + if (!(ccdb->getForTimeStamp>("Analysis/EventPlane/QVecCorrections/FT0C", cfgCcdbParam.nolaterthan.value))->empty()) { + cfgCorr.push_back(*(ccdb->getForTimeStamp>("Analysis/EventPlane/QVecCorrections/FT0C", cfgCcdbParam.nolaterthan.value))); + } else { + if (cfgFT0CCorr->size() < 48) { + LOGF(fatal, "No proper correction factor assigned for FT0C"); + } else { + cfgCorr.push_back(cfgFT0CCorr); + } + } + + if (!(ccdb->getForTimeStamp>("Analysis/EventPlane/QVecCorrections/FT0A", cfgCcdbParam.nolaterthan.value))->empty()) { + cfgCorr.push_back(*(ccdb->getForTimeStamp>("Analysis/EventPlane/QVecCorrections/FT0A", cfgCcdbParam.nolaterthan.value))); + } else { + if (cfgFT0ACorr->size() < 48) { + LOGF(fatal, "No proper correction factor assigned for FT0A"); + } else { + cfgCorr.push_back(cfgFT0ACorr); + } + } + + if (!(ccdb->getForTimeStamp>("Analysis/EventPlane/QVecCorrections/FT0M", cfgCcdbParam.nolaterthan.value))->empty()) { + cfgCorr.push_back(*(ccdb->getForTimeStamp>("Analysis/EventPlane/QVecCorrections/FT0M", cfgCcdbParam.nolaterthan.value))); + } else { + if (cfgFT0MCorr->size() < 48) { + LOGF(fatal, "No proper correction factor assigned for FT0M"); + } else { + cfgCorr.push_back(cfgFT0MCorr); + } + } + + if (!(ccdb->getForTimeStamp>("Analysis/EventPlane/QVecCorrections/FT0C", cfgCcdbParam.nolaterthan.value))->empty()) { + cfgCorr.push_back(*(ccdb->getForTimeStamp>("Analysis/EventPlane/QVecCorrections/FT0C", cfgCcdbParam.nolaterthan.value))); + } else { + if (cfgFV0ACorr->size() < 48) { + LOGF(fatal, "No proper correction factor assigned for FV0A"); + } else { + cfgCorr.push_back(cfgFV0ACorr); + } + } // no FV0A + + if (!(ccdb->getForTimeStamp>("Analysis/EventPlane/QVecCorrections/BPos", cfgCcdbParam.nolaterthan.value))->empty()) { + cfgCorr.push_back(*(ccdb->getForTimeStamp>("Analysis/EventPlane/QVecCorrections/BPos", cfgCcdbParam.nolaterthan.value))); + } else { + if (cfgBPosCorr->size() < 48) { + LOGF(fatal, "No proper correction factor assigned for BPos"); + } else { + cfgCorr.push_back(cfgBPosCorr); + } + } + + if (!(ccdb->getForTimeStamp>("Analysis/EventPlane/QVecCorrections/BNeg", cfgCcdbParam.nolaterthan.value))->empty()) { + cfgCorr.push_back(*(ccdb->getForTimeStamp>("Analysis/EventPlane/QVecCorrections/BNeg", cfgCcdbParam.nolaterthan.value))); + } else { + if (cfgBNegCorr->size() < 48) { + LOGF(fatal, "No proper correction factor assigned for BNeg"); + } else { + cfgCorr.push_back(cfgBNegCorr); + } + } + } else if (cfgCCDBConst == 2) { + if (cfgFT0CCorr->size() < 48) { + LOGF(fatal, "No proper correction factor assigned for FT0C"); + } + if (cfgFT0ACorr->size() < 48) { + LOGF(fatal, "No proper correction factor assigned for FT0A"); + } + if (cfgFT0MCorr->size() < 48) { + LOGF(fatal, "No proper correction factor assigned for FT0M"); + } + if (cfgFV0ACorr->size() < 48) { + LOGF(fatal, "No proper correction factor assigned for FV0A"); + } + if (cfgBPosCorr->size() < 48) { + LOGF(fatal, "No proper correction factor assigned for positive TPC tracks"); + } + if (cfgBNegCorr->size() < 48) { + LOGF(fatal, "No proper correction factor assigned for negative TPC tracks"); + } // will be replaced with method that call constants from CCDB + + cfgCorr.push_back(cfgFT0CCorr); + cfgCorr.push_back(cfgFT0ACorr); + cfgCorr.push_back(cfgFT0MCorr); + cfgCorr.push_back(cfgFV0ACorr); + cfgCorr.push_back(cfgBPosCorr); + cfgCorr.push_back(cfgBNegCorr); } - if (cfgBNegCorr->size() < 48) { - LOGF(fatal, "No proper correction factor assigned for negative TPC tracks"); - } // will be replaced with method that call constants from CCDB - cfgCorr.push_back(cfgFT0CCorr); - cfgCorr.push_back(cfgFT0ACorr); - cfgCorr.push_back(cfgFT0MCorr); - cfgCorr.push_back(cfgFV0ACorr); - cfgCorr.push_back(cfgBPosCorr); - cfgCorr.push_back(cfgBNegCorr); /* // Debug printing. printf("Offset for FT0A: x = %.3f y = %.3f\n", (*offsetFT0)[0].getX(), (*offsetFT0)[0].getY()); diff --git a/Common/TableProducer/trackPropagation.cxx b/Common/TableProducer/trackPropagation.cxx index d0f64b15c9e..d99a6ecd766 100644 --- a/Common/TableProducer/trackPropagation.cxx +++ b/Common/TableProducer/trackPropagation.cxx @@ -13,23 +13,8 @@ // Task to add a table of track parameters propagated to the primary vertex // -#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 "CCDB/CcdbApi.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "CCDB/BasicCCDBManager.h" -#include "Framework/HistogramRegistry.h" -#include "DataFormatsCalibration/MeanVertexObject.h" -#include "CommonConstants/GeomConstants.h" #include "TableHelper.h" +#include "Common/Tools/TrackTuner.h" // 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. @@ -64,6 +49,7 @@ struct TrackPropagation { const o2::dataformats::MeanVertexObject* mMeanVtx = nullptr; o2::parameters::GRPMagField* grpmag = nullptr; o2::base::MatLayerCylSet* lut = nullptr; + TrackTuner trackTunerObj; Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; Configurable lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"}; @@ -71,23 +57,36 @@ struct TrackPropagation { Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; Configurable mVtxPath{"mVtxPath", "GLO/Calib/MeanVertex", "Path of the mean vertex file"}; Configurable minPropagationRadius{"minPropagationDistance", o2::constants::geom::XTPCInnerRef + 0.1, "Only tracks which are at a smaller radius will be propagated, defaults to TPC inner wall"}; + // for TrackTuner only (MC smearing) + Configurable useTrackTuner{"useTrackTuner", false, "Apply Improver/DCA corrections to MC"}; + Configurable trackTunerParams{"trackTunerParams", "debugInfo=0|updateTrackCovMat=1|updateCurvature=0|updatePulls=0|isInputFileFromCCDB=1|pathInputFile=Users/m/mfaggin/test/inputsTrackTuner/PbPb2022|nameInputFile=trackTuner_DataLHC22sPass5_McLHC22l1b2_run529397.root|usePvRefitCorrections=0|oneOverPtCurrent=0|oneOverPtUpgr=0", "TrackTuner parameter initialization (format: =|=)"}; + OutputObj trackTunedTracks{TH1D("trackTunedTracks", "", 1, 0.5, 1.5), OutputObjHandlingPolicy::AnalysisObject}; + + using TracksIUWithMc = soa::Join; + using TracksIU = soa::Join; void init(o2::framework::InitContext& initContext) { int nEnabledProcesses = 0; - if (doprocessStandard == true) { + if (doprocessStandard) { LOG(info) << "Enabling processStandard"; nEnabledProcesses++; } - if (doprocessCovariance == true) { + if (doprocessCovarianceMc) { + LOG(info) << "Enabling processCovarianceMc"; + nEnabledProcesses++; + } + + if (doprocessCovariance) { LOG(info) << "Enabling processCovariance"; nEnabledProcesses++; } - if (doprocessStandardWithPID == true) { + + if (doprocessStandardWithPID) { LOG(info) << "Enabling processStandardWithPID"; nEnabledProcesses++; } - if (doprocessCovarianceWithPID == true) { + if (doprocessCovarianceWithPID) { LOG(info) << "Enabling processCovarianceWithPID"; nEnabledProcesses++; } @@ -103,6 +102,12 @@ struct TrackPropagation { ccdb->setLocalObjectValidityChecking(); lut = o2::base::MatLayerCylSet::rectifyPtrFromFile(ccdb->get(lutPath)); + /// TrackTuner initialization + if (useTrackTuner) { + std::string outputStringParams = trackTunerObj.configParams(trackTunerParams); + trackTunerObj.getDcaGraphs(); + trackTunedTracks->SetTitle(outputStringParams.c_str()); + } } void initCCDB(aod::BCsWithTimestamps::iterator const& bc) @@ -125,8 +130,9 @@ struct TrackPropagation { o2::track::TrackParametrization mTrackPar; o2::track::TrackParametrizationWithError mTrackParCov; - template + template void fillTrackTables(TTrack const& tracks, + TParticle const& mcParticles, aod::Collisions const&, aod::BCsWithTimestamps const& bcs) { @@ -168,9 +174,26 @@ struct TrackPropagation { mTrackPar.setPID(track.pidForTracking()); } } + // auto trackParCov = getTrackParCov(track); aod::track::TrackTypeEnum trackType = (aod::track::TrackTypeEnum)track.trackType(); // Only propagate tracks which have passed the innermost wall of the TPC (e.g. skipping loopers etc). Others fill unpropagated. if (track.trackType() == aod::track::TrackIU && track.x() < minPropagationRadius) { + if constexpr (isMc && fillCovMat) { /// track tuner ok only if cov. matrix is used + if (useTrackTuner) { + // call track propagator + // this function reads many many things + // - reads track params + bool hasMcParticle = track.has_mcParticle(); + if (hasMcParticle) { + // LOG(info) << " MC particle exists... "; + // LOG(info) << "Inside trackPropagation: before calling tuneTrackParams trackParCov.getY(): " << trackParCov.getY(); + auto mcParticle = track.mcParticle(); + trackTunerObj.tuneTrackParams(mcParticle, mTrackParCov, matCorr, &mDcaInfoCov); + // LOG(info) << "Inside trackPropagation: after calling tuneTrackParams trackParCov.getY(): " << trackParCov.getY(); + trackTunedTracks->Fill(1); + } + } + } if (track.has_collision()) { auto const& collision = track.collision(); if constexpr (fillCovMat) { @@ -219,25 +242,33 @@ struct TrackPropagation { void processStandard(aod::StoredTracksIU const& tracks, aod::Collisions const& collisions, aod::BCsWithTimestamps const& bcs) { - fillTrackTables(tracks, collisions, bcs); + fillTrackTables(tracks, tracks, collisions, bcs); } PROCESS_SWITCH(TrackPropagation, processStandard, "Process without covariance", true); void processStandardWithPID(soa::Join const& tracks, aod::Collisions const& collisions, aod::BCsWithTimestamps const& bcs) { - fillTrackTables, /*fillCovMat =*/false, /*useTrkPid =*/true>(tracks, collisions, bcs); + fillTrackTables, /*Particle*/ soa::Join, /*isMc = */ false, /*fillCovMat =*/false, /*useTrkPid =*/true>(tracks, tracks, collisions, bcs); } PROCESS_SWITCH(TrackPropagation, processStandardWithPID, "Process without covariance and with PID in tracking", false); - void processCovariance(soa::Join const& tracks, aod::Collisions const& collisions, aod::BCsWithTimestamps const& bcs) + // ----------------------- + void processCovarianceMc(TracksIUWithMc const& tracks, aod::McParticles const& mcParticles, aod::Collisions const& collisions, aod::BCsWithTimestamps const& bcs) + { + fillTrackTables(tracks, mcParticles, collisions, bcs); + } + PROCESS_SWITCH(TrackPropagation, processCovarianceMc, "Process with covariance on MC", false); + + void processCovariance(TracksIU const& tracks, aod::Collisions const& collisions, aod::BCsWithTimestamps const& bcs) { - fillTrackTables, /*fillCovMat =*/true, /*useTrkPid =*/false>(tracks, collisions, bcs); + fillTrackTables(tracks, tracks, collisions, bcs); } PROCESS_SWITCH(TrackPropagation, processCovariance, "Process with covariance", false); + // ------------------------ void processCovarianceWithPID(soa::Join const& tracks, aod::Collisions const& collisions, aod::BCsWithTimestamps const& bcs) { - fillTrackTables, /*fillCovMat =*/true, /*useTrkPid =*/false>(tracks, collisions, bcs); + fillTrackTables, /*Particle*/ soa::Join, /*isMc = */ false, /*fillCovMat =*/true, /*useTrkPid =*/false>(tracks, tracks, collisions, bcs); } PROCESS_SWITCH(TrackPropagation, processCovarianceWithPID, "Process with covariance and with PID in tracking", false); }; diff --git a/Common/Tasks/qVectorsCorrection.cxx b/Common/Tasks/qVectorsCorrection.cxx index b639d1e77df..e91497b4fb8 100644 --- a/Common/Tasks/qVectorsCorrection.cxx +++ b/Common/Tasks/qVectorsCorrection.cxx @@ -168,10 +168,10 @@ struct qVectorsCorrection { histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecTwist"), vec.qvecRe()[DetId * 4 + 2], vec.qvecIm()[DetId * 4 + 2]); histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecFinal"), vec.qvecRe()[DetId * 4 + 3], vec.qvecIm()[DetId * 4 + 3]); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlUncor"), helperEP.GetEventPlane(vec.qvecRe()[DetId * 4], vec.qvecIm()[DetId * 4], 2)); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRectr"), helperEP.GetEventPlane(vec.qvecRe()[DetId * 4 + 1], vec.qvecIm()[DetId * 4 + 1], 2)); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlTwist"), helperEP.GetEventPlane(vec.qvecRe()[DetId * 4 + 2], vec.qvecIm()[DetId * 4 + 2], 2)); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlFinal"), helperEP.GetEventPlane(vec.qvecRe()[DetId * 4 + 3], vec.qvecIm()[DetId * 4 + 3], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlUncor"), helperEP.GetEventPlane(vec.qvecRe()[DetId * 4], vec.qvecIm()[DetId * 4], cfgnMod)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRectr"), helperEP.GetEventPlane(vec.qvecRe()[DetId * 4 + 1], vec.qvecIm()[DetId * 4 + 1], cfgnMod)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlTwist"), helperEP.GetEventPlane(vec.qvecRe()[DetId * 4 + 2], vec.qvecIm()[DetId * 4 + 2], cfgnMod)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlFinal"), helperEP.GetEventPlane(vec.qvecRe()[DetId * 4 + 3], vec.qvecIm()[DetId * 4 + 3], cfgnMod)); } if (vec.qvecAmp()[RefAId] > 1e-8) { @@ -180,10 +180,10 @@ struct qVectorsCorrection { histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefATwist"), vec.qvecRe()[RefAId * 4 + 2], vec.qvecIm()[RefAId * 4 + 2]); histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefAFinal"), vec.qvecRe()[RefAId * 4 + 3], vec.qvecIm()[RefAId * 4 + 3]); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefAUncor"), helperEP.GetEventPlane(vec.qvecRe()[RefAId * 4], vec.qvecIm()[RefAId * 4], 2)); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefARectr"), helperEP.GetEventPlane(vec.qvecRe()[RefAId * 4 + 1], vec.qvecIm()[RefAId * 4 + 1], 2)); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefATwist"), helperEP.GetEventPlane(vec.qvecRe()[RefAId * 4 + 2], vec.qvecIm()[RefAId * 4 + 2], 2)); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefAFinal"), helperEP.GetEventPlane(vec.qvecRe()[RefAId * 4 + 3], vec.qvecIm()[RefAId * 4 + 3], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefAUncor"), helperEP.GetEventPlane(vec.qvecRe()[RefAId * 4], vec.qvecIm()[RefAId * 4], cfgnMod)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefARectr"), helperEP.GetEventPlane(vec.qvecRe()[RefAId * 4 + 1], vec.qvecIm()[RefAId * 4 + 1], cfgnMod)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefATwist"), helperEP.GetEventPlane(vec.qvecRe()[RefAId * 4 + 2], vec.qvecIm()[RefAId * 4 + 2], cfgnMod)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefAFinal"), helperEP.GetEventPlane(vec.qvecRe()[RefAId * 4 + 3], vec.qvecIm()[RefAId * 4 + 3], cfgnMod)); } if (vec.qvecAmp()[RefBId] > 1e-8) { @@ -192,17 +192,17 @@ struct qVectorsCorrection { histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefBTwist"), vec.qvecRe()[RefBId * 4 + 2], vec.qvecIm()[RefBId * 4 + 2]); histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histQvecRefBFinal"), vec.qvecRe()[RefBId * 4 + 3], vec.qvecIm()[RefBId * 4 + 3]); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBUncor"), helperEP.GetEventPlane(vec.qvecRe()[RefBId * 4], vec.qvecIm()[RefBId * 4], 2)); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBRectr"), helperEP.GetEventPlane(vec.qvecRe()[RefBId * 4 + 1], vec.qvecIm()[RefBId * 4 + 1], 2)); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBTwist"), helperEP.GetEventPlane(vec.qvecRe()[RefBId * 4 + 2], vec.qvecIm()[RefBId * 4 + 2], 2)); - histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBFinal"), helperEP.GetEventPlane(vec.qvecRe()[RefBId * 4 + 3], vec.qvecIm()[RefBId * 4 + 3], 2)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBUncor"), helperEP.GetEventPlane(vec.qvecRe()[RefBId * 4], vec.qvecIm()[RefBId * 4], cfgnMod)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBRectr"), helperEP.GetEventPlane(vec.qvecRe()[RefBId * 4 + 1], vec.qvecIm()[RefBId * 4 + 1], cfgnMod)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBTwist"), helperEP.GetEventPlane(vec.qvecRe()[RefBId * 4 + 2], vec.qvecIm()[RefBId * 4 + 2], cfgnMod)); + histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlRefBFinal"), helperEP.GetEventPlane(vec.qvecRe()[RefBId * 4 + 3], vec.qvecIm()[RefBId * 4 + 3], cfgnMod)); } if (vec.qvecAmp()[DetId] > 1e-8 && vec.qvecAmp()[RefAId] > 1e-8 && vec.qvecAmp()[RefBId] > 1e-8) { histosQA.fill(HIST(qV::centClasses[cBin]) + HIST("histEvtPlResolution"), helperEP.GetResolution( - helperEP.GetEventPlane(vec.qvecRe()[RefAId * 4 + 3], vec.qvecIm()[RefAId * 4 + 3], 2), - helperEP.GetEventPlane(vec.qvecRe()[RefBId * 4 + 3], vec.qvecIm()[RefBId * 4 + 3], 2), - helperEP.GetEventPlane(vec.qvecRe()[DetId * 4 + 3], vec.qvecIm()[DetId * 4 + 3], 2), 2)); + helperEP.GetEventPlane(vec.qvecRe()[RefAId * 4 + 3], vec.qvecIm()[RefAId * 4 + 3], cfgnMod), + helperEP.GetEventPlane(vec.qvecRe()[RefBId * 4 + 3], vec.qvecIm()[RefBId * 4 + 3], cfgnMod), + helperEP.GetEventPlane(vec.qvecRe()[DetId * 4 + 3], vec.qvecIm()[DetId * 4 + 3], cfgnMod), cfgnMod)); } } diff --git a/Common/Tools/Multiplicity/multCalibrator.cxx b/Common/Tools/Multiplicity/multCalibrator.cxx index 2c898370156..51306f91160 100644 --- a/Common/Tools/Multiplicity/multCalibrator.cxx +++ b/Common/Tools/Multiplicity/multCalibrator.cxx @@ -168,7 +168,7 @@ Double_t multCalibrator::GetBoundaryForPercentile(TH1* histo, Double_t lPercenti // Anchor point changes: if anchored, start at the first bin that includes that Long_t lFirstBin = 1; - Double_t lHadronicTotal = histo->GetEntries(); + Double_t lHadronicTotal = histo->Integral(1, histo->GetNbinsX()); // histo->GetEntries(); if (fAnchorPointValue > 0) { lFirstBin = histo->FindBin(fAnchorPointValue + 1e-6); Double_t lAbove = histo->Integral(lFirstBin, histo->GetNbinsX()); diff --git a/Common/Tools/TrackTuner.h b/Common/Tools/TrackTuner.h new file mode 100644 index 00000000000..92c9ad225ec --- /dev/null +++ b/Common/Tools/TrackTuner.h @@ -0,0 +1,686 @@ +// 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 TrackTuner.h +/// \brief Helper class to "smear" track parameters in MC simulations +/// \author Andrea Rossi (andrea.rossi@cern.ch), INFN Padova, Italy +/// \author Himanshu Sharma (himanshu.sharma@cern.ch), INFN Padova, Italy +/// \author Mattia Faggin (mattia.faggin@cern.ch), CERN + +#ifndef COMMON_TOOLS_TRACKTUNER_H_ +#define COMMON_TOOLS_TRACKTUNER_H_ + +#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/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" +#include "Framework/RunningWorkflowInfo.h" +#include "ReconstructionDataFormats/DCA.h" +#include "ReconstructionDataFormats/Track.h" + +#include + +struct TrackTuner { + + /////////////////////////////// + /// parameters to be configured + bool debugInfo = false; + bool updateTrackCovMat = false; + bool updateCurvature = false; + bool updatePulls = false; + bool isInputFileFromCCDB = false; // query input file from CCDB or local folder + std::string pathInputFile = ""; // Path to file containing DCAxy, DCAz graphs from data (upgr) and MC (current) + std::string nameInputFile = ""; // Common Name of different files containing graphs, found in the above paths + bool usePvRefitCorrections = false; // establish whether to use corrections obtained with or w/o PV refit + float oneOverPtCurrent = 0.; // 1/pt old + float oneOverPtUpgr = 0.; // 1/pt new + /////////////////////////////// + + o2::ccdb::CcdbApi ccdbApi; + std::map metadata; + + std::unique_ptr grDcaXYResVsPtPionCurrent; + std::unique_ptr grDcaXYResVsPtPionUpgr; + + std::unique_ptr grDcaZResVsPtPionCurrent; + std::unique_ptr grDcaZResVsPtPionUpgr; + + std::unique_ptr grDcaXYMeanVsPtPionCurrent; + std::unique_ptr grDcaXYMeanVsPtPionUpgr; + + std::unique_ptr grDcaZMeanVsPtPionCurrent; + std::unique_ptr grDcaZMeanVsPtPionUpgr; + + std::unique_ptr grOneOverPtPionCurrent; + std::unique_ptr grOneOverPtPionUpgr; + + std::unique_ptr grDcaXYPullVsPtPionCurrent; + std::unique_ptr grDcaXYPullVsPtPionUpgr; + + std::unique_ptr grDcaZPullVsPtPionCurrent; + std::unique_ptr grDcaZPullVsPtPionUpgr; + + /// @brief Function to configure the TrackTuner parameters + /// @param inputString Input string with all parameter configuration. Format: =|= + /// @return String with the values of all parameters after configurations are listed, to cross check that everything worked well + std::string configParams(std::string inputString) + { + + std::string delimiter = "|"; + std::string assignmentSymbol = "="; + + LOG(info) << "[TrackTuner] === "; + LOG(info) << "[TrackTuner] === Parameter configuration via std::string"; + LOG(info) << "[TrackTuner] === Required format: \"" << assignmentSymbol << "" << delimiter << "" << assignmentSymbol << "" << delimiter << "" << assignmentSymbol << "\""; + LOG(info) << "[TrackTuner] === Delimiter symbol: \"" << delimiter << "\""; + LOG(info) << "[TrackTuner] === Assignment symbol: \"" << assignmentSymbol << "\""; + LOG(info) << "[TrackTuner] === "; + LOG(info) << "[TrackTuner]"; + LOG(info) << "[TrackTuner] >>> Original input string = \"" << inputString << "\""; + + /// Check the format of the input string + if (inputString.find(delimiter) == std::string::npos) { + // wrong delimiter symbol used + LOG(fatal) << "delimiter symbol \"" << delimiter << "\" not found in the configuration string. Fix it!"; + } + if (inputString.find(assignmentSymbol) == std::string::npos) { + // wrong assignment symbol used + LOG(fatal) << "assignment symbol \"" << assignmentSymbol << "\" not found in the configuration string. Fix it!"; + } + int spaces = std::count(inputString.begin(), inputString.end(), ' '); + if (spaces > 0) { + // white spaces to be removed + LOG(fatal) << spaces << " white spaces found in the configuration string. Remove them!"; + } + + /////////////////////////////////////////////////////////////////////////////////// + /// Parameters to be configured via the string + /// +++ to be manually updated every time one adds a new parameter to the TrackTuner.h +++ + enum Pars : uint8_t { DebugInfo = 0, + UpdateTrackCovMat, + UpdateCurvature, + UpdatePulls, + PathInputFile, + IsInputFileFromCCDB, + NameInputFile, + UsePvRefitCorrections, + OneOverPtCurrent, + OneOverPtUpgr, + NPars }; + std::map mapParNames = { + std::make_pair(DebugInfo, "debugInfo"), + std::make_pair(UpdateTrackCovMat, "updateTrackCovMat"), + std::make_pair(UpdateCurvature, "updateCurvature"), + std::make_pair(UpdatePulls, "updatePulls"), + std::make_pair(IsInputFileFromCCDB, "isInputFileFromCCDB"), + std::make_pair(PathInputFile, "pathInputFile"), + std::make_pair(NameInputFile, "nameInputFile"), + std::make_pair(UsePvRefitCorrections, "usePvRefitCorrections"), + std::make_pair(OneOverPtCurrent, "oneOverPtCurrent"), + std::make_pair(OneOverPtUpgr, "oneOverPtUpgr")}; + /////////////////////////////////////////////////////////////////////////////////// + LOG(info) << "[TrackTuner]"; + LOG(info) << "[TrackTuner] >>> Parameters before the custom settings"; + LOG(info) << "[TrackTuner] debugInfo = " << debugInfo; + LOG(info) << "[TrackTuner] updateTrackCovMat = " << updateTrackCovMat; + LOG(info) << "[TrackTuner] updateCurvature = " << updateCurvature; + LOG(info) << "[TrackTuner] updatePulls = " << updatePulls; + LOG(info) << "[TrackTuner] isInputFileFromCCDB = " << isInputFileFromCCDB; + LOG(info) << "[TrackTuner] pathInputFile = " << pathInputFile; + LOG(info) << "[TrackTuner] nameInputFile = " << nameInputFile; + LOG(info) << "[TrackTuner] usePvRefitCorrections = " << usePvRefitCorrections; + LOG(info) << "[TrackTuner] oneOverPtCurrent = " << oneOverPtCurrent; + LOG(info) << "[TrackTuner] oneOverPtUpgr = " << oneOverPtUpgr; + + // ############################################################################################## + // ######## split the original string, separating substrings delimited by "|" symbol ######## + + std::vector slices = {}; + + while (inputString.find(delimiter) != std::string::npos) { + /// we are not at the end of our string --> let's find out the next parameter to be configured! + slices.push_back(inputString.substr(0, inputString.find(delimiter))); // this gives us the substring until the next "|" character + inputString.erase(0, slices.back().length() + delimiter.length()); // erase the found substring for next iteration + } + /// at this point, the input string is erased until the last delimiter (included) + slices.push_back(inputString); // necessary to read the last parameter, after the last "|" symbol + + LOG(info) << "[TrackTuner]"; + LOG(info) << "[TrackTuner] >>> String slices:"; + for (std::string& s : slices) + LOG(info) << "[TrackTuner] " << s; + + /// check if the number of input parameters is correct + if (static_cast(slices.size()) != NPars) { + LOG(fatal) << "[TrackTuner] " << slices.size() << " parameters provided, while " << NPars << " are expected. Fix it!"; + } + + // ################################################################################################################### + // ######## each split is now a std::string "=" --> let's really configure each parameter ######## + + /// 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; }); + if (it == std::end(slices)) { + // parameter not found + LOG(fatal) << "\"" << mapParNames[iPar] << "\" not found in the configuration string"; + } + std::string str = *it; + if (str.find('=') == std::string::npos || str.back() == '=') { + // value of the parameter missing in the configuration string + LOG(fatal) << "Missing value for \"" << mapParNames[iPar] << "\" in the configuration string"; + } + return str.substr(str.find(assignmentSymbol) + 1, str.length()); + }; + + /// further lambda expression to handle bool initialization + auto setBoolFromString = [=](bool& b, 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) { + b = false; + } else { + LOG(fatal) << "[TrackTuner] Wrong bool initialization from configuration "; + } + }; + + std::string outputString = ""; + LOG(info) << "[TrackTuner] "; + LOG(info) << "[TrackTuner] >>> Parameters after the custom settings"; + // Configure debugInfo + setBoolFromString(debugInfo, getValueString(DebugInfo)); + LOG(info) << "[TrackTuner] debugInfo = " << debugInfo; + outputString += "debugInfo=" + std::to_string(debugInfo); + // Configure updateTrackCovMat + setBoolFromString(updateTrackCovMat, getValueString(UpdateTrackCovMat)); + LOG(info) << "[TrackTuner] updateTrackCovMat = " << updateTrackCovMat; + outputString += ", updateTrackCovMat=" + std::to_string(updateTrackCovMat); + // Configure updateCurvature + setBoolFromString(updateCurvature, getValueString(UpdateCurvature)); + LOG(info) << "[TrackTuner] updateCurvature = " << updateCurvature; + outputString += ", updateCurvature=" + std::to_string(updateCurvature); + // Configure updatePulls + setBoolFromString(updatePulls, getValueString(UpdatePulls)); + LOG(info) << "[TrackTuner] updatePulls = " << updatePulls; + outputString += ", updatePulls=" + std::to_string(updatePulls); + // Configure isInputFileFromCCDB + setBoolFromString(isInputFileFromCCDB, getValueString(IsInputFileFromCCDB)); + LOG(info) << "[TrackTuner] isInputFileFromCCDB = " << isInputFileFromCCDB; + outputString += ", isInputFileFromCCDB=" + std::to_string(isInputFileFromCCDB); + // Configure pathInputFile + pathInputFile = getValueString(PathInputFile); + outputString += ", pathInputFile=" + pathInputFile; + LOG(info) << "[TrackTuner] pathInputFile = " << pathInputFile; + // Configure nameInputFile + nameInputFile = getValueString(NameInputFile); + outputString += ", nameInputFile=" + nameInputFile; + LOG(info) << "[TrackTuner] nameInputFile = " << nameInputFile; + // Configure usePvRefitCorrections + setBoolFromString(usePvRefitCorrections, getValueString(UsePvRefitCorrections)); + outputString += ", usePvRefitCorrections=" + usePvRefitCorrections; + LOG(info) << "[TrackTuner] usePvRefitCorrections = " << usePvRefitCorrections; + // Configure oneOverPtCurr + oneOverPtCurrent = std::stof(getValueString(OneOverPtCurrent)); + outputString += ", oneOverPtCurrent=" + std::to_string(oneOverPtCurrent); + LOG(info) << "[TrackTuner] oneOverPtCurrent = " << oneOverPtCurrent; + // Configure oneOverPtUpgr + oneOverPtUpgr = std::stof(getValueString(OneOverPtUpgr)); + outputString += ", oneOverPtUpgr=" + std::to_string(oneOverPtUpgr); + LOG(info) << "[TrackTuner] oneOverPtUpgr = " << oneOverPtUpgr; + + return outputString; + } + + void getDcaGraphs() + { + std::string fullNameInputFile = ""; + + if (isInputFileFromCCDB) { + /// use input correction file from CCDB + + // properly init the ccdb + std::string tmpDir = "."; + ccdbApi.init("http://alice-ccdb.cern.ch"); + + // get the file from CCDB + if (!ccdbApi.retrieveBlob(pathInputFile.data(), tmpDir, metadata, 0, false, nameInputFile.data())) { + LOG(fatal) << "[TrackTuner] input file not found on CCDB, please check the pathInputFile and nameInputFile!"; + } + + // point to the file in the tmp local folder + fullNameInputFile = tmpDir + std::string("/") + nameInputFile; + } else { + /// use input correction file from local filesystem + fullNameInputFile = pathInputFile + std::string("/") + nameInputFile; + } + + /// open the input correction file + std::unique_ptr inputFile(TFile::Open(fullNameInputFile.c_str(), "READ")); + if (!inputFile.get()) { + LOG(fatal) << "Something wrong with the input file" << fullNameInputFile << " for dca correction. Fix it!"; + } + + // choose wheter to use corrections w/ PV refit or w/o it, and retrieve the proper TDirectory + std::string dir = "woPvRefit"; + if (usePvRefitCorrections) { + dir = "withPvRefit"; + } + TDirectory* td = dynamic_cast(inputFile->Get(dir.c_str())); + if (!td) { + LOG(fatal) << "TDirectory " << td << " not found in input file" << inputFile->GetName() << ". Fix it!"; + } + + std::string grDcaXYResNameCurr = "resCurrentDcaXY"; + std::string grDcaXYMeanNameCurr = "meanCurrentDcaXY"; + std::string grDcaXYPullNameCurr = "pullsCurrentDcaXY"; + std::string grDcaXYResNameUpgr = "resUpgrDcaXY"; + std::string grDcaXYMeanNameUpgr = "meanUpgrDcaXY"; + std::string grDcaXYPullNameUpgr = "pullsUpgrDcaXY"; + + grDcaXYResVsPtPionCurrent.reset(dynamic_cast(td->Get(grDcaXYResNameCurr.c_str()))); + grDcaXYResVsPtPionUpgr.reset(dynamic_cast(td->Get(grDcaXYResNameUpgr.c_str()))); + grDcaXYMeanVsPtPionCurrent.reset(dynamic_cast(td->Get(grDcaXYMeanNameCurr.c_str()))); + grDcaXYMeanVsPtPionUpgr.reset(dynamic_cast(td->Get(grDcaXYMeanNameUpgr.c_str()))); + grDcaXYPullVsPtPionCurrent.reset(dynamic_cast(td->Get(grDcaXYPullNameCurr.c_str()))); + grDcaXYPullVsPtPionUpgr.reset(dynamic_cast(td->Get(grDcaXYPullNameUpgr.c_str()))); + if (!grDcaXYResVsPtPionCurrent.get() || !grDcaXYResVsPtPionUpgr.get() || !grDcaXYMeanVsPtPionCurrent.get() || !grDcaXYMeanVsPtPionUpgr.get() || !grDcaXYPullVsPtPionCurrent.get() || !grDcaXYPullVsPtPionUpgr.get()) { + LOG(fatal) << "Something wrong with the names of the correction graphs for dcaXY. Fix it!"; + } + + std::string grDcaZResNameCurr = "resCurrentDcaZ"; + std::string grDcaZMeanNameCurr = "meanCurrentDcaZ"; + std::string grDcaZPullNameCurr = "pullsCurrentDcaZ"; + std::string grDcaZResNameUpgr = "resUpgrDcaZ"; + std::string grDcaZMeanNameUpgr = "meanUpgrDcaZ"; + std::string grDcaZPullNameUpgr = "pullsUpgrDcaZ"; + + grDcaZResVsPtPionCurrent.reset(dynamic_cast(td->Get(grDcaZResNameCurr.c_str()))); + grDcaZResVsPtPionUpgr.reset(dynamic_cast(td->Get(grDcaZResNameUpgr.c_str()))); + grDcaZMeanVsPtPionCurrent.reset(dynamic_cast(td->Get(grDcaZMeanNameCurr.c_str()))); + grDcaZMeanVsPtPionUpgr.reset(dynamic_cast(td->Get(grDcaZMeanNameUpgr.c_str()))); + grDcaZPullVsPtPionCurrent.reset(dynamic_cast(td->Get(grDcaZPullNameCurr.c_str()))); + grDcaZPullVsPtPionUpgr.reset(dynamic_cast(td->Get(grDcaZPullNameUpgr.c_str()))); + if (!grDcaZResVsPtPionCurrent.get() || !grDcaZResVsPtPionUpgr.get() || !grDcaZMeanVsPtPionCurrent.get() || !grDcaZMeanVsPtPionUpgr.get() || !grDcaZPullVsPtPionCurrent.get() || !grDcaZPullVsPtPionUpgr.get()) { + LOG(fatal) << "Something wrong with the names of the correction graphs for dcaZ. Fix it!"; + } + } + + template + void tuneTrackParams(T1 const& mcparticle, T2& trackParCov, T3 const& matCorr, T4 dcaInfoCov) + { + + double ptMC = mcparticle.pt(); + + double dcaXYResCurrent = 0.0; // sd0rpo=0.; + double dcaZResCurrent = 0.0; // sd0zo =0.; + + double dcaXYResUpgr = 0.0; // sd0rpn=0.; + double dcaZResUpgr = 0.0; // sd0zn =0.; + + // double OneOverPtCurrent = 0.0; // spt1o =0.; + // double OneOverPtUpgr = 0.0; // spt1n =0.; + + double dcaXYMeanCurrent = 0.0; // sd0mrpo=0.; + double dcaXYMeanUpgr = 0.0; // sd0mrpn=0.; + + double dcaXYPullCurrent = 1.0; + double dcaXYPullUpgr = 1.0; + + double dcaZPullCurrent = 1.0; + double dcaZPullUpgr = 1.0; + + dcaXYResCurrent = evalGraph(ptMC, grDcaXYResVsPtPionCurrent.get()); + dcaXYResUpgr = evalGraph(ptMC, grDcaXYResVsPtPionUpgr.get()); + + // dcaXYResCurrent = 1.0; + // dcaXYResUpgr = 1.5; + + dcaZResCurrent = evalGraph(ptMC, grDcaZResVsPtPionCurrent.get()); + dcaZResUpgr = evalGraph(ptMC, grDcaZResVsPtPionUpgr.get()); + + // dcaZResCurrent = 1.0; + // dcaZResUpgr = 1.0; + + // OneOverPtCurrent = evalGraph(ptMC, grOneOverPtPionCurrent.get() ); + // OneOverPtUpgr = evalGraph(ptMC, grOneOverPtPionUpgr.get() ); + + // OneOverPtCurrent = 1.0; + // OneOverPtUpgr = 2.0; + + dcaXYMeanCurrent = evalGraph(ptMC, grDcaXYMeanVsPtPionCurrent.get()); + dcaXYMeanUpgr = evalGraph(ptMC, grDcaXYMeanVsPtPionUpgr.get()); + + // dcaXYMeanCurrent = 0.0; + // dcaXYMeanUpgr = 0.0; + + dcaXYPullCurrent = evalGraph(ptMC, grDcaXYPullVsPtPionCurrent.get()); + dcaXYPullUpgr = evalGraph(ptMC, grDcaXYPullVsPtPionUpgr.get()); + + dcaZPullCurrent = evalGraph(ptMC, grDcaZPullVsPtPionCurrent.get()); + dcaZPullUpgr = evalGraph(ptMC, grDcaZPullVsPtPionUpgr.get()); + + // Unit conversion, is it required ?? + dcaXYResCurrent *= 1.e-4; + dcaZResCurrent *= 1.e-4; + + dcaXYResUpgr *= 1.e-4; + dcaZResUpgr *= 1.e-4; + + dcaXYMeanCurrent *= 1.e-4; + dcaXYMeanUpgr *= 1.e-4; + + // Apply the smearing + // --------------------------------------------- + // double pt1o =param [4]; + double trackParOneOverPtCurrent = trackParCov.getQ2Pt(); + int sign = trackParCov.getQ2Pt() / std::abs(trackParCov.getQ2Pt()); + // double pt1mc =parammc[4]; + double trackParOneOverPtMC = sign / mcparticle.pt(); + o2::dataformats::VertexBase vtxMC; + vtxMC.setPos({mcparticle.vx(), mcparticle.vy(), mcparticle.vz()}); + vtxMC.setCov(0, 0, 0, 0, 0, 0); // ??? or All ZEROs // == 1 cm2? wrt prop point + + if (debugInfo) { + // LOG(info) << " sign " << sign; + // LOG(info) << " trackParCov.getQ2Pt() " << trackParOneOverPtCurrent << " " << trackParCov.getQ2Pt(); + // LOG(info) << " sign/mcparticle.pt() " << trackParOneOverPtMC; + // LOG(info) << " (curvReco-curvMC)/curvMC " << (trackParOneOverPtCurrent - trackParOneOverPtMC)/trackParOneOverPtMC * 100.0 << "%"; + // LOG(info) << " trackParCov.getPtInv() " << trackParCov.getPtInv() << std::endl; + // LOG(info) << " 1/trackParCov.getPtInv() " << 1./trackParCov.getPtInv() << " & mcparticle.pt() " << mcparticle.pt(); + LOG(info) << mcparticle.pt() << " " << 1 / trackParCov.getPtInv() << " " << (trackParOneOverPtCurrent - trackParOneOverPtMC) / trackParOneOverPtMC * 100.0; + // LOG(info) << "Before Propagation to Production Point -> alpha: " << trackParCov.getAlpha() << ", DCAxy: " << trackParCov.getY() << ", DCAz: " << trackParCov.getZ(); + } + // propagate to DCA with respect to the Production point + o2::base::Propagator::Instance()->propagateToDCABxByBz(vtxMC, trackParCov, 2.f, matCorr, dcaInfoCov); + if (debugInfo) { + // LOG(info) << "After Propagation to Production Point -> alpha: " << trackParCov.getAlpha() << ", DCAxy: " << trackParCov.getY() << ", DCAz: " << trackParCov.getZ(); + LOG(info) << "track.y(): " << trackParCov.getY(); + } + + ////////////////////////////// DCAs modifications Start ///////////////////////////////// + + // double d0zo =param [1]; + double trackParDcaZCurrent = trackParCov.getZ(); + + // double d0rpo =param [0]; + double trackParDcaXYCurrent = trackParCov.getY(); + + float mcVxRotated = mcparticle.vx() * std::cos(trackParCov.getAlpha()) + mcparticle.vy() * std::sin(trackParCov.getAlpha()); // invert + float mcVyRotated = mcparticle.vy() * std::cos(trackParCov.getAlpha()) - mcparticle.vx() * std::sin(trackParCov.getAlpha()); + + if (debugInfo) { + // LOG(info) << "mcVy " << mcparticle.vy() << std::endl; + LOG(info) << "mcVxRotated " << mcVxRotated; + LOG(info) << "mcVyRotated " << mcVyRotated; + } + + // std::array arrayXYZ = { mcVxRotated, mcVyRotated , mcparticle.vz()}; + // std::array arrayPxPyPz = {mcparticle.px(), mcparticle.py(), mcparticle.pz()}; + + // const int matSize = 21; + // std::array arrayCovMatMC = {0.,0.,0.,0.,0., 0.,0.,0.,0.,0., 0.,0.,0.,0.,0., 0.,0.,0.,0.,0.,0. }; + // o2::track::TrackParametrizationWithError trackParCovMC{arrayXYZ, arrayPxPyPz, arrayCovMatMC, trackParCov.getSign()}; + + // double d0rpmc=parammc[0]; + // double trackParDcaXYMC = trackParCovMC.getY(); // here + + double trackParDcaXYMC = mcVyRotated; // here + // LOG(info) << "trackParCovMC.getY() " << trackParCovMC.getY() << std::endl; + + // double d0zmc =parammc[1]; + double trackParDcaZMC = mcparticle.vz(); + + // double dd0zo =d0zo-d0zmc; + double diffDcaZFromMCCurent = trackParDcaZCurrent - trackParDcaZMC; + + // double dd0zn =dd0zo *(sd0zo >0. ? (sd0zn /sd0zo ) : 1.); + double diffDcaZFromMCUpgr = diffDcaZFromMCCurent * (dcaZResCurrent > 0. ? (dcaZResUpgr / dcaZResCurrent) : 1.); + + // double d0zn =d0zmc+dd0zn; + double trackParDcaZUpgr = trackParDcaZMC + diffDcaZFromMCUpgr; + + // double dd0rpo=d0rpo-d0rpmc; + double diffDcaXYFromMCCurent = trackParDcaXYCurrent - trackParDcaXYMC; + + // double dd0rpn=dd0rpo*(sd0rpo>0. ? (sd0rpn/sd0rpo) : 1.); + double diffDcaXYFromMCUpgr = diffDcaXYFromMCCurent * (dcaXYResCurrent > 0. ? (dcaXYResUpgr / dcaXYResCurrent) : 1.); + + // double dd0mrpn=std::abs(sd0mrpn)-std::abs(sd0mrpo); + // double diffDcaXYMeanUpgMinusCur = std::abs(dcaXYMeanUpgr) - std::abs(dcaXYMeanCurrent) ; + double diffDcaXYMeanUpgMinusCur = dcaXYMeanUpgr - dcaXYMeanCurrent; + + // double d0rpn =d0rpmc+dd0rpn-dd0mrpn; + double trackParDcaXYUpgr = trackParDcaXYMC + diffDcaXYFromMCUpgr - diffDcaXYMeanUpgMinusCur; + + if (debugInfo) { + LOG(info) << dcaZResCurrent << ", " << dcaZResUpgr << ", diff(DcaZ - DcaZMC): " << diffDcaZFromMCCurent << ", diff upgraded: " << diffDcaZFromMCUpgr << ", DcaZ Upgr : " << trackParDcaZUpgr; + LOG(info) << dcaXYResCurrent << ", " << dcaXYResUpgr << ", diff(DcaY - DcaYMC): " << diffDcaXYFromMCCurent << ", diff upgraded: " << diffDcaXYFromMCUpgr << ", DcaY Upgr :" << trackParDcaXYUpgr; + } + + // option mimic data + // ---------------------- + // if(fMimicData){ + // // dd0mrpn=sd0mrpn-sd0mrpo; + // diffDcaXYMeanUpgMinusCur = dcaXYMeanUpgr - dcaXYMeanCurrent; + // // d0rpn = d0rpmc+dd0rpn+dd0mrpn; + // trackParDcaXYUpgr = diffDcaXYFromMCCurent + diffDcaXYFromMCUpgr + diffDcaXYMeanUpgMinusCur; + // } + + // setting updated track parameters + // -------------------------------- + // param[0]=d0rpn; + // double oldDCAxyValue = trackParCov.getY(); + trackParCov.setY(trackParDcaXYUpgr); + // trackParCov.setY(oldDCAxyValue); + // param[1]=d0zn ; + trackParCov.setZ(trackParDcaZUpgr); + + if (updateCurvature) { + // -------------------------------------- + // double dpt1o =pt1o-pt1mc; + double diffOneOverPtFromMCCurent = trackParOneOverPtCurrent - trackParOneOverPtMC; + + // double dpt1n =dpt1o *(spt1o >0. ? (spt1n /spt1o ) : 1.); + double diffOneOverPtFromMCUpgr = diffOneOverPtFromMCCurent * (oneOverPtCurrent > 0. ? (oneOverPtUpgr / oneOverPtCurrent) : 1.); + + // double pt1n = pt1mc+dpt1n; + double trackParOneOverPtUpgr = trackParOneOverPtMC + diffOneOverPtFromMCUpgr; + + // param[4]=pt1n ; + trackParCov.setQ2Pt(trackParOneOverPtUpgr); + } + // if(debugInfo){ + // LOG(info) << "Inside tuneTrackParams() before modifying trackParCov.getY(): " << trackParCov.getY() << " trackParOneOverPtMC = " << trackParOneOverPtMC << " diffOneOverPtFromMCUpgr = " << diffOneOverPtFromMCUpgr << std::endl; + //} + + // Updating Single Track Covariance matrices + + double sigmaY2 = 0.0; + double sigmaZY = 0.0; + double sigmaZ2 = 0.0; + double sigmaSnpY = 0.0; + double sigmaSnpZ = 0.0; + double sigmaTglY = 0.0; + double sigmaTglZ = 0.0; + double sigma1PtY = 0.0; + double sigma1PtZ = 0.0; + double sigma1PtSnp = 0.0; + double sigma1PtTgl = 0.0; + double sigma1Pt2 = 0.0; + + if (updateTrackCovMat) { + // if(sd0rpo>0.) covar[0]*=(sd0rpn/sd0rpo)*(sd0rpn/sd0rpo);//yy + sigmaY2 = trackParCov.getSigmaY2(); + if (dcaXYResCurrent > 0.) + sigmaY2 *= ((dcaXYResUpgr / dcaXYResCurrent) * (dcaXYResUpgr / dcaXYResCurrent)); + trackParCov.setCov(sigmaY2, 0); + + // if(sd0zo>0. && sd0rpo>0.)covar[1]*=(sd0rpn/sd0rpo)*(sd0zn/sd0zo);//yz + sigmaZY = trackParCov.getSigmaZY(); + if (dcaZResCurrent > 0. && dcaXYResCurrent > 0.) + sigmaZY *= ((dcaXYResUpgr / dcaXYResCurrent) * (dcaXYResUpgr / dcaXYResCurrent)); + trackParCov.setCov(sigmaZY, 1); + + // if(sd0zo>0.) covar[2]*=(sd0zn/sd0zo)*(sd0zn/sd0zo);//zz + sigmaZ2 = trackParCov.getSigmaZ2(); + if (dcaZResCurrent > 0.) + sigmaZ2 *= ((dcaZResUpgr / dcaZResCurrent) * (dcaZResUpgr / dcaZResCurrent)); + trackParCov.setCov(sigmaZ2, 2); + + // if(sd0rpo>0.) covar[3]*=(sd0rpn/sd0rpo);//yl + sigmaSnpY = trackParCov.getSigmaSnpY(); + if (dcaXYResCurrent > 0.) + sigmaSnpY *= ((dcaXYResUpgr / dcaXYResCurrent)); + trackParCov.setCov(sigmaSnpY, 3); + + // if(sd0zo>0.) covar[4]*=(sd0zn/sd0zo);//zl + sigmaSnpZ = trackParCov.getSigmaSnpZ(); + if (dcaZResCurrent > 0.) + sigmaSnpZ *= ((dcaZResUpgr / dcaZResCurrent)); + trackParCov.setCov(sigmaSnpZ, 4); + + // if(sd0rpo>0.) covar[6]*=(sd0rpn/sd0rpo);//ysenT + sigmaTglY = trackParCov.getSigmaTglY(); + if (dcaXYResCurrent > 0.) + sigmaTglY *= ((dcaXYResUpgr / dcaXYResCurrent)); + trackParCov.setCov(sigmaTglY, 6); + + // if(sd0zo>0.) covar[7]*=(sd0zn/sd0zo);//zsenT + sigmaTglZ = trackParCov.getSigmaTglZ(); + if (dcaZResCurrent > 0.) + sigmaTglZ *= ((dcaZResUpgr / dcaZResCurrent)); + trackParCov.setCov(sigmaTglZ, 7); + + // if(sd0rpo>0. && spt1o>0.)covar[10]*=(sd0rpn/sd0rpo)*(spt1n/spt1o);//ypt + sigma1PtY = trackParCov.getSigma1PtY(); + if (dcaXYResCurrent > 0. && oneOverPtCurrent > 0.) + sigma1PtY *= ((dcaXYResUpgr / dcaXYResCurrent) * (oneOverPtUpgr / oneOverPtCurrent)); + trackParCov.setCov(sigma1PtY, 10); + + // if(sd0zo>0. && spt1o>0.) covar[11]*=(sd0zn/sd0zo)*(spt1n/spt1o);//zpt + sigma1PtZ = trackParCov.getSigma1PtZ(); + if (dcaZResCurrent > 0. && oneOverPtCurrent > 0.) + sigma1PtZ *= ((dcaZResUpgr / dcaZResCurrent) * (oneOverPtUpgr / oneOverPtCurrent)); + trackParCov.setCov(sigma1PtZ, 11); + + // if(spt1o>0.) covar[12]*=(spt1n/spt1o);//sinPhipt + sigma1PtSnp = trackParCov.getSigma1PtSnp(); + if (oneOverPtCurrent > 0.) + sigma1PtSnp *= (oneOverPtUpgr / oneOverPtCurrent); + trackParCov.setCov(sigma1PtSnp, 12); + + // if(spt1o>0.) covar[13]*=(spt1n/spt1o);//tanTpt + sigma1PtTgl = trackParCov.getSigma1PtTgl(); + if (oneOverPtCurrent > 0.) + sigma1PtTgl *= (oneOverPtUpgr / oneOverPtCurrent); + trackParCov.setCov(sigma1PtTgl, 13); + + // if(spt1o>0.) covar[14]*=(spt1n/spt1o)*(spt1n/spt1o);//ptpt + sigma1Pt2 = trackParCov.getSigma1Pt2(); + if (oneOverPtCurrent > 0.) + sigma1Pt2 *= (oneOverPtUpgr / oneOverPtCurrent); + trackParCov.setCov(sigma1Pt2, 14); + } + + if (updatePulls) { + double ratioDCAxyPulls = dcaXYPullCurrent / dcaXYPullUpgr; + double ratioDCAzPulls = dcaZPullCurrent / dcaZPullUpgr; + + // covar[0]*=pullcorr*pullcorr;//yy + + sigmaY2 *= (ratioDCAxyPulls * ratioDCAxyPulls); + trackParCov.setCov(sigmaY2, 0); + + // covar[1]*=pullcorr;//yz + sigmaZY *= ratioDCAxyPulls; + trackParCov.setCov(sigmaZY, 1); + + sigmaZ2 *= (ratioDCAzPulls * ratioDCAzPulls); + trackParCov.setCov(sigmaZ2, 2); + + // covar[3]*=pullcorr;//yl + sigmaSnpY *= ratioDCAxyPulls; + trackParCov.setCov(sigmaSnpY, 3); + + sigmaSnpZ *= ratioDCAzPulls; + trackParCov.setCov(sigmaSnpZ, 4); + + // covar[6]*=pullcorr;//ysenT + sigmaTglY *= ratioDCAxyPulls; + trackParCov.setCov(sigmaTglY, 6); + + sigmaTglZ *= ratioDCAzPulls; + trackParCov.setCov(sigmaTglZ, 7); + + // covar[10]*=pullcorr;//ypt + sigma1PtY *= ratioDCAxyPulls; + trackParCov.setCov(sigma1PtY, 10); + + sigma1PtZ *= ratioDCAzPulls; + trackParCov.setCov(sigma1PtZ, 11); + } + } + + // to be declared + // --------------- + // int getPhiBin(double phi) const + // { + // double pi = TMath::Pi(); + // if (phi > 2. * pi || phi < 0.) + // return -1; + // if ((phi <= (pi / 4.)) || (phi > 7. * (pi / 4.))) + // return 0; + // if ((phi > (pi / 4.)) && (phi <= 3. * (pi / 4.))) + // return 1; + // if ((phi > 3. * (pi / 4.)) && (phi <= 5. * (pi / 4.))) + // return 2; + // if ((phi > (5. * pi / 4.)) && (phi <= 7. * (pi / 4.))) + // return 3; + // + // return -1; + // } + + double evalGraph(double x, const TGraphErrors* graph) const + { + + if (!graph) { + printf("\tevalGraph fails !\n"); + return 0.; + } + int nPoints = graph->GetN(); + double xMin = graph->GetX()[0]; + double xMax = graph->GetX()[nPoints - 1]; + if (x > xMax) + return graph->Eval(xMax); + if (x < xMin) + return graph->Eval(xMin); + return graph->Eval(x); + } +}; + +#endif // COMMON_TOOLS_TRACKTUNER_H_ diff --git a/DPG/Tasks/AOTEvent/eventSelectionQa.cxx b/DPG/Tasks/AOTEvent/eventSelectionQa.cxx index 16d6e30f15c..33b09fee4c5 100644 --- a/DPG/Tasks/AOTEvent/eventSelectionQa.cxx +++ b/DPG/Tasks/AOTEvent/eventSelectionQa.cxx @@ -798,7 +798,7 @@ struct EventSelectionQaTask { for (const auto& track : tracks) { auto mapAmbTrIdsIt = mapAmbTrIds.find(track.globalIndex()); int ambTrId = mapAmbTrIdsIt == mapAmbTrIds.end() ? -1 : mapAmbTrIdsIt->second; - int indexBc = ambTrId < 0 ? track.collision_as().bc_as().globalIndex() : ambTracks.iteratorAt(ambTrId).bc().begin().globalIndex(); + int indexBc = ambTrId < 0 ? track.collision_as().bc_as().globalIndex() : ambTracks.iteratorAt(ambTrId).bc_as().begin().globalIndex(); auto bc = bcs.iteratorAt(indexBc); int64_t globalBC = bc.globalBC() + floor(track.trackTime() / o2::constants::lhc::LHCBunchSpacingNS); diff --git a/DPG/Tasks/AOTTrack/MonitorFilterBit.cxx b/DPG/Tasks/AOTTrack/MonitorFilterBit.cxx index 0cea1860aef..a7d38d08385 100644 --- a/DPG/Tasks/AOTTrack/MonitorFilterBit.cxx +++ b/DPG/Tasks/AOTTrack/MonitorFilterBit.cxx @@ -19,13 +19,56 @@ #include "Framework/AnalysisTask.h" #include "Common/DataModel/TrackSelectionTables.h" #include "Common/Core/RecoDecay.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/ASoA.h" using namespace o2; using namespace o2::framework; using namespace o2::aod::track; +using namespace o2::aod::mctracklabel; +using namespace o2::framework::expressions; + +namespace o2::aod +{ + +namespace trackPairForEff +{ +DECLARE_SOA_COLUMN(PtTPCtr, ptTPCtr, float); +DECLARE_SOA_COLUMN(EtaTPCtr, etaTPCtr, float); +DECLARE_SOA_COLUMN(PhiTPCtr, phiTPCtr, float); +DECLARE_SOA_COLUMN(PtITStr, ptITStr, float); +DECLARE_SOA_COLUMN(EtaITStr, etaITStr, float); +DECLARE_SOA_COLUMN(PhiITStr, phiITStr, float); +DECLARE_SOA_COLUMN(NClustITS, nClustITS, uint8_t); +DECLARE_SOA_COLUMN(NClustTPC, nClustTPC, int16_t); +DECLARE_SOA_COLUMN(McPtIfisSamePart, mcPtIfisSamePart, float); +DECLARE_SOA_COLUMN(PairType, pairType, uint8_t); +} // namespace trackPairForEff +DECLARE_SOA_TABLE(TrackPairForEffPP, "AOD", "TRACKPAIREFFPP", + trackPairForEff::PtTPCtr, trackPairForEff::EtaTPCtr, trackPairForEff::PhiTPCtr, + trackPairForEff::PtITStr, trackPairForEff::EtaITStr, trackPairForEff::PhiITStr, + trackPairForEff::NClustITS, trackPairForEff::NClustTPC, trackPairForEff::McPtIfisSamePart, o2::soa::Marker<1>); +DECLARE_SOA_TABLE(TrackPairForEffNN, "AOD", "TRACKPAIREFFNN", + trackPairForEff::PtTPCtr, trackPairForEff::EtaTPCtr, trackPairForEff::PhiTPCtr, + trackPairForEff::PtITStr, trackPairForEff::EtaITStr, trackPairForEff::PhiITStr, + trackPairForEff::NClustITS, trackPairForEff::NClustTPC, trackPairForEff::McPtIfisSamePart, o2::soa::Marker<2>); +DECLARE_SOA_TABLE(TrackPairForEffPN, "AOD", "TRACKPAIREFFPN", + trackPairForEff::PtTPCtr, trackPairForEff::EtaTPCtr, trackPairForEff::PhiTPCtr, + trackPairForEff::PtITStr, trackPairForEff::EtaITStr, trackPairForEff::PhiITStr, + trackPairForEff::NClustITS, trackPairForEff::NClustTPC, trackPairForEff::McPtIfisSamePart, o2::soa::Marker<3>); +DECLARE_SOA_TABLE(TrackPairForEffNP, "AOD", "TRACKPAIREFFNP", + trackPairForEff::PtTPCtr, trackPairForEff::EtaTPCtr, trackPairForEff::PhiTPCtr, + trackPairForEff::PtITStr, trackPairForEff::EtaITStr, trackPairForEff::PhiITStr, + trackPairForEff::NClustITS, trackPairForEff::NClustTPC, trackPairForEff::McPtIfisSamePart, o2::soa::Marker<4>); +} // namespace o2::aod struct CheckFilterBit { + Produces trackPairForEffTablePP; + Produces trackPairForEffTableNN; + Produces trackPairForEffTableNP; + Produces trackPairForEffTablePN; + // Binning 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, 2.0, 5.0, 10.0, 20.0, 50.0}, ""}; ConfigurableAxis binsEta{"binsEta", {30, -1.5, 1.5}, ""}; @@ -36,6 +79,19 @@ struct CheckFilterBit { HistogramRegistry histos; Int_t ncollisionCounter = 0; + float fzero = 0.; + using Tracksextension = soa::Join; + using TracksextensionMC = soa::Join; + SliceCache cache; + Partition positiveTPConlyTracks = o2::aod::track::signed1Pt > fzero&& o2::aod::track::tpcNClsFindable > (uint8_t)0 && o2::aod::track::itsChi2NCl < (float_t)0; //&& (o2::aod::track::detectorMap & o2::aod::track::TPC) ==o2::aod::track::TPC && (o2::aod::track::detectorMap & o2::aod::track::ITS) ==0; + Partition negativeTPConlyTracks = o2::aod::track::signed1Pt < fzero && o2::aod::track::tpcNClsFindable > (uint8_t)0 && o2::aod::track::itsChi2NCl < (float_t)0; //&& (o2::aod::track::detectorMap & o2::aod::track::TPC) ==o2::aod::track::TPC && (o2::aod::track::detectorMap & o2::aod::track::ITS) ==0; + Partition positiveITSonlyTracks = o2::aod::track::signed1Pt > fzero&& o2::aod::track::tpcChi2NCl<(float_t)0 && o2::aod::track::itsChi2NCl>(float_t) 0; // && (o2::aod::track::detectorMap & o2::aod::track::TPC) ==0 && (o2::aod::track::detectorMap & o2::aod::track::ITS) ==o2::aod::track::ITS && o2::aod::track::passedITSNCls==true;// && o2::aod::track::itsNCls==7; + Partition negativeITSonlyTracks = o2::aod::track::signed1Pt < fzero && o2::aod::track::tpcChi2NCl < (float_t)0 && o2::aod::track::itsChi2NCl > (float_t)0; // && (o2::aod::track::detectorMap & o2::aod::track::TPC) ==0 &&(o2::aod::track::detectorMap & o2::aod::track::ITS) ==o2::aod::track::ITS && o2::aod::track::passedITSNCls==true;// && o2::aod::track::itsNCls==7; + + Partition positiveTPConlyTracksMC = o2::aod::track::signed1Pt > fzero&& o2::aod::track::tpcNClsFindable > (uint8_t)0 && o2::aod::track::itsChi2NCl < (float_t)0; //&& (o2::aod::track::detectorMap & o2::aod::track::TPC) ==o2::aod::track::TPC && (o2::aod::track::detectorMap & o2::aod::track::ITS) ==0; + Partition negativeTPConlyTracksMC = o2::aod::track::signed1Pt < fzero && o2::aod::track::tpcNClsFindable > (uint8_t)0 && o2::aod::track::itsChi2NCl < (float_t)0; //&& (o2::aod::track::detectorMap & o2::aod::track::TPC) ==o2::aod::track::TPC && (o2::aod::track::detectorMap & o2::aod::track::ITS) ==0; + Partition positiveITSonlyTracksMC = o2::aod::track::signed1Pt > fzero&& o2::aod::track::tpcChi2NCl<(float_t)0 && o2::aod::track::itsChi2NCl>(float_t) 0; // && (o2::aod::track::detectorMap & o2::aod::track::TPC) ==0 && (o2::aod::track::detectorMap & o2::aod::track::ITS) ==o2::aod::track::ITS && o2::aod::track::passedITSNCls==true;// && o2::aod::track::itsNCls==7; + Partition negativeITSonlyTracksMC = o2::aod::track::signed1Pt < fzero && o2::aod::track::tpcChi2NCl < (float_t)0 && o2::aod::track::itsChi2NCl > (float_t)0; // && (o2::aod::track::detectorMap & o2::aod::track::TPC) ==0 &&(o2::aod::track::detectorMap & o2::aod::track::ITS) ==o2::aod::track::ITS && o2::aod::track::passedITSNCls==true;// && o2::aod::track::itsNCls==7; void init(InitContext const&) { @@ -58,6 +114,8 @@ struct CheckFilterBit { histos.add("Tracks/Reco/histpt3DFB3", "FB3 tracks;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/Reco/histpt3DFB4", "FB4 tracks;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/Reco/histpt3DFB5", "FB5 tracks;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + histos.add("Tracks/Reco/histpt3DITSonly", "ITSonly tracks;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + histos.add("Tracks/Reco/histpt3DTPConly", "TPConly tracks;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/MCgen/histMCgenpt", "pt", kTH1D, {axisPt}); histos.add("Tracks/MCgen/histMCgen3dPhysPrimary", "MC Phys. Prim.;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); @@ -65,13 +123,26 @@ struct CheckFilterBit { histos.add("Tracks/MCgen/histMCgen3dChargedProdRad1mumto5mm", "MC Prod Rad_xy 1#mum to 5 mm ;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/MCgen/histMCgen3dChargedfromHFdecay", "MC Phys. Prim from HF decay ;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); - histos.add("Tracks/RecoMCPhysPrimCollMatch/histpt", "pt", kTH1D, {axisPt}); + histos.add("Tracks/RecoMCPhysPrimCollMatch/histpt", "pt;#it{p}_{T}^{MC} (GeV/#it{c})", kTH1D, {axisPt}); histos.add("Tracks/RecoMCPhysPrimCollMatch/histptFB0", "FB0;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/RecoMCPhysPrimCollMatch/histptFB1", "FB1;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/RecoMCPhysPrimCollMatch/histptFB2", "FB2;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/RecoMCPhysPrimCollMatch/histptFB3", "FB3;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/RecoMCPhysPrimCollMatch/histptFB4", "FB4;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/RecoMCPhysPrimCollMatch/histptFB5", "FB5;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + histos.add("Tracks/RecoMCPhysPrimCollMatch/histptITSonly", "ITSonly;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + histos.add("Tracks/RecoMCPhysPrimCollMatch/histptTPConly", "TPConly;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + + histos.add("Tracks/RecoMCPhysPrimCollMatch/histptMCFB0", "FB0;#it{p}_{T}^{MC} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + histos.add("Tracks/RecoMCPhysPrimCollMatch/histptMCFB1", "FB1;#it{p}_{T}^{MC} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + histos.add("Tracks/RecoMCPhysPrimCollMatch/histptMCFB2", "FB2;#it{p}_{T}^{MC} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + histos.add("Tracks/RecoMCPhysPrimCollMatch/histptMCFB3", "FB3;#it{p}_{T}^{MC} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + histos.add("Tracks/RecoMCPhysPrimCollMatch/histptMCFB4", "FB4;#it{p}_{T}^{MC} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + histos.add("Tracks/RecoMCPhysPrimCollMatch/histptMCFB5", "FB5;#it{p}_{T}^{MC} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + histos.add("Tracks/RecoMCPhysPrimCollMatch/histptMCITSonly", "ITSonly;#it{p}_{T}^{MC} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + histos.add("Tracks/RecoMCPhysPrimCollMatch/histptMCTPConly", "TPConly;#it{p}_{T}^{MC} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + histos.add("Tracks/RecoMCPhysPrimCollMatch/histptMCTPConlyWithClusters", "TPConlyWithClusters;#it{p}_{T}^{gen} (GeV/#it{c});#it{#eta};#it{#varphi};NclustTPC", HistType::kTHnF, {axisPt, axisEta, axisPhi, axisNclustTPC}); + histos.add("Tracks/RecoMCPhysPrimCollMatch/histptTPConlyWithClusters", "TPConlyWithClusters;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi};NclustTPC", HistType::kTHnF, {axisPt, axisEta, axisPhi, axisNclustTPC}); histos.add("Tracks/RecoMCRad1to15cmCollMatch/histptFB0", "FB0;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/RecoMCRad1to15cmCollMatch/histptFB1", "FB1;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); @@ -79,6 +150,8 @@ struct CheckFilterBit { histos.add("Tracks/RecoMCRad1to15cmCollMatch/histptFB3", "FB3;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/RecoMCRad1to15cmCollMatch/histptFB4", "FB4;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/RecoMCRad1to15cmCollMatch/histptFB5", "FB5;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + histos.add("Tracks/RecoMCRad1to15cmCollMatch/histptITSonly", "ITSonly;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + histos.add("Tracks/RecoMCRad1to15cmCollMatch/histptTPConly", "TPConly;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/RecoMCRad1mumto5mmCollMatch/histptFB0", "FB0;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/RecoMCRad1mumto5mmCollMatch/histptFB1", "FB1;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); @@ -86,6 +159,8 @@ struct CheckFilterBit { histos.add("Tracks/RecoMCRad1mumto5mmCollMatch/histptFB3", "FB3;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/RecoMCRad1mumto5mmCollMatch/histptFB4", "FB4;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/RecoMCRad1mumto5mmCollMatch/histptFB5", "FB5;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + histos.add("Tracks/RecoMCRad1mumto5mmCollMatch/histptITSonly", "ITSonly;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + histos.add("Tracks/RecoMCRad1mumto5mmCollMatch/histptTPConly", "TPConly;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/RecoMCfromHFdecayCollMatch/histptFB0", "FB0;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/RecoMCfromHFdecayCollMatch/histptFB1", "FB1;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); @@ -93,44 +168,186 @@ struct CheckFilterBit { histos.add("Tracks/RecoMCfromHFdecayCollMatch/histptFB3", "FB3;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/RecoMCfromHFdecayCollMatch/histptFB4", "FB4;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); histos.add("Tracks/RecoMCfromHFdecayCollMatch/histptFB5", "FB5;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + histos.add("Tracks/RecoMCfromHFdecayCollMatch/histptITSonly", "ITSonly;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); + histos.add("Tracks/RecoMCfromHFdecayCollMatch/histptTPConly", "TPConly;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi}", kTH3D, {axisPt, axisEta, axisPhi}); - // plotting variables - // HistogramConfigSpec defaultVariableHist({HistType::kTHnF, {axisPt, axisEta, axisPhi,axisNclustTPC}}); - // histos.add("nclustTPC", "Sigmas", defaultParticleHist); histos.add("Tracks/Reco/histNclustTPC", "N clusters TPC;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi};NclustTPCl;TPCITSmatching", HistType::kTHnF, {axisPt, axisEta, axisPhi, axisNclustTPC, binsTPCITSmatching}); histos.add("Tracks/RecoMCVariablesPrimary/histNclustTPC", "N clusters TPC;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{#varphi};NclustTPC;TPCITSmatching", HistType::kTHnF, {axisPt, axisEta, axisPhi, axisNclustTPC, binsTPCITSmatching}); } - void processData(soa::Join const& tracks) - { // test whether the name can be changed using the PROCESS_SWITCH method (see qaEventTrack class) + void FillDataHistoStd(const Tracksextension::iterator& track) + { + if (std::abs(track.eta()) < 0.9) { + histos.fill(HIST("Tracks/Reco/histptAll"), track.pt()); + } + histos.fill(HIST("Tracks/Reco/histpt3DAll"), track.pt(), track.eta(), track.phi()); + Int_t hasITS = 0; + if (track.itsNCls() > 0) + hasITS++; + if (track.itsNClsInnerBarrel() > 0) + hasITS++; + histos.fill(HIST("Tracks/Reco/histNclustTPC"), track.pt(), track.eta(), track.phi(), track.tpcNClsFound(), hasITS); + if (track.isGlobalTrack()) + histos.fill(HIST("Tracks/Reco/histpt3DFB0"), track.pt(), track.eta(), track.phi()); + if (track.trackCutFlagFb1()) + histos.fill(HIST("Tracks/Reco/histpt3DFB1"), track.pt(), track.eta(), track.phi()); + if (track.trackCutFlagFb2()) + histos.fill(HIST("Tracks/Reco/histpt3DFB2"), track.pt(), track.eta(), track.phi()); + if (track.trackCutFlagFb3()) + histos.fill(HIST("Tracks/Reco/histpt3DFB3"), track.pt(), track.eta(), track.phi()); + if (track.trackCutFlagFb4()) + histos.fill(HIST("Tracks/Reco/histpt3DFB4"), track.pt(), track.eta(), track.phi()); + if (track.trackCutFlagFb5()) + histos.fill(HIST("Tracks/Reco/histpt3DFB5"), track.pt(), track.eta(), track.phi()); + if (track.itsChi2NCl() > 0. && track.tpcChi2NCl() < 0.) + histos.fill(HIST("Tracks/Reco/histpt3DITSonly"), track.pt(), track.eta(), track.phi()); + if (track.itsChi2NCl() < 0. && track.tpcChi2NCl() > 0.) + histos.fill(HIST("Tracks/Reco/histpt3DTPConly"), track.pt(), track.eta(), track.phi()); + } + void processData(Tracksextension const& tracks) + { for (auto& track : tracks) { + FillDataHistoStd(track); + } + } + PROCESS_SWITCH(CheckFilterBit, processData, "process data", true); + + void processDataCombineTracks(o2::aod::Collision const& collision, Tracksextension const& tracks) + { + auto positiveITSonlyTracksThisColl = positiveITSonlyTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto negativeITSonlyTracksThisColl = negativeITSonlyTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto positiveTPConlyTracksThisColl = positiveTPConlyTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto negativeTPConlyTracksThisColl = negativeTPConlyTracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + + processPair(collision, positiveTPConlyTracksThisColl, positiveITSonlyTracksThisColl, negativeTPConlyTracksThisColl, negativeITSonlyTracksThisColl); + } + PROCESS_SWITCH(CheckFilterBit, processDataCombineTracks, "process data combined tracks", false); + + void processMCCombineTracks(soa::Join::iterator const& collision, TracksextensionMC const& tracks, aod::McParticles const& mcParticles) + { + + if (std::abs(collision.posZ()) > 10.) { + return; + } + + auto positiveITSonlyTracksThisColl = positiveITSonlyTracksMC->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto negativeITSonlyTracksThisColl = negativeITSonlyTracksMC->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto positiveTPConlyTracksThisColl = positiveTPConlyTracksMC->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto negativeTPConlyTracksThisColl = negativeTPConlyTracksMC->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + + processPair(collision, positiveTPConlyTracksThisColl, positiveITSonlyTracksThisColl, negativeTPConlyTracksThisColl, negativeITSonlyTracksThisColl); + } + PROCESS_SWITCH(CheckFilterBit, processMCCombineTracks, "process data combined tracks", true); + + template + void processPair(Tcollisions const& collision, const TpTPC& positiveTPConlyTracksThisColl, const TpITS& positiveITSonlyTracksThisColl, const TnTPC& negativeTPConlyTracksThisColl, const TnITS& negativeITSonlyTracksThisColl) + { + float issamemcpt = -9999.; + // run first over global tracks + /* for (auto& track : tracks) { + if (track.isGlobalTrack()) { + track.pt(); + } + else{ + track.pt(); + } + } + */ + for (auto& [track0, track1] : combinations(soa::CombinationsFullIndexPolicy(positiveITSonlyTracksThisColl, positiveTPConlyTracksThisColl))) { + issamemcpt = -9999.; + if constexpr (IS_MC) { + + if (track0.mcParticleId() == track1.mcParticleId()) { + if (track0.has_mcParticle()) { + /// the track is not fake + auto mcparticle = track0.mcParticle(); + auto mcCollID_recoColl = collision.mcCollisionId(); + auto mcCollID_particle = mcparticle.mcCollisionId(); + bool indexMatchOK = (mcCollID_recoColl == mcCollID_particle); - if (std::abs(track.eta()) < 0.9) { - histos.fill(HIST("Tracks/Reco/histptAll"), track.pt()); + int partpdg = std::abs(mcparticle.pdgCode()); + if (indexMatchOK && mcparticle.isPhysicalPrimary() && (partpdg == 211 || partpdg == 321 || partpdg == 2212 || partpdg == 11 || partpdg == 13)) { + issamemcpt = mcparticle.pt(); + } else { + issamemcpt = -mcparticle.pt(); + } + } + } + } + + trackPairForEffTablePP(track1.pt(), track1.eta(), track1.phi(), track0.pt(), track0.eta(), track0.phi(), track0.itsNCls(), track1.tpcNClsFound(), issamemcpt); + } + for (auto& [track0, track1] : combinations(soa::CombinationsFullIndexPolicy(negativeITSonlyTracksThisColl, negativeTPConlyTracksThisColl))) { + + issamemcpt = -9999.; + if constexpr (IS_MC) { + if (track0.mcParticleId() == track1.mcParticleId()) { + if (track0.has_mcParticle()) { + /// the track is not fake + auto mcparticle = track0.mcParticle(); + auto mcCollID_recoColl = collision.mcCollisionId(); + auto mcCollID_particle = mcparticle.mcCollisionId(); + bool indexMatchOK = (mcCollID_recoColl == mcCollID_particle); + + int partpdg = std::abs(mcparticle.pdgCode()); + if (indexMatchOK && mcparticle.isPhysicalPrimary() && (partpdg == 211 || partpdg == 321 || partpdg == 2212 || partpdg == 11 || partpdg == 13)) { + issamemcpt = mcparticle.pt(); + } else { + issamemcpt = -mcparticle.pt(); + } + } + } + } + + trackPairForEffTableNN(track1.pt(), track1.eta(), track1.phi(), track0.pt(), track0.eta(), track0.phi(), track0.itsNCls(), track1.tpcNClsFound(), issamemcpt); + } + for (auto& [track0, track1] : combinations(soa::CombinationsFullIndexPolicy(negativeITSonlyTracksThisColl, positiveTPConlyTracksThisColl))) { + issamemcpt = -9999.; + if constexpr (IS_MC) { + if (track0.mcParticleId() == track1.mcParticleId()) { + if (track0.has_mcParticle()) { + /// the track is not fake + auto mcparticle = track0.mcParticle(); + auto mcCollID_recoColl = collision.mcCollisionId(); + auto mcCollID_particle = mcparticle.mcCollisionId(); + bool indexMatchOK = (mcCollID_recoColl == mcCollID_particle); + + int partpdg = std::abs(mcparticle.pdgCode()); + if (indexMatchOK && mcparticle.isPhysicalPrimary() && (partpdg == 211 || partpdg == 321 || partpdg == 2212 || partpdg == 11 || partpdg == 13)) { + issamemcpt = mcparticle.pt(); + } else { + issamemcpt = -mcparticle.pt(); + } + } + } + } + + trackPairForEffTableNP(track1.pt(), track1.eta(), track1.phi(), track0.pt(), track0.eta(), track0.phi(), track0.itsNCls(), track1.tpcNClsFound(), issamemcpt); + } + for (auto& [track0, track1] : combinations(soa::CombinationsFullIndexPolicy(positiveITSonlyTracksThisColl, negativeTPConlyTracksThisColl))) { + issamemcpt = -9999.; + if constexpr (IS_MC) { + if (track0.mcParticleId() == track1.mcParticleId()) { + if (track0.has_mcParticle()) { + /// the track is not fake + auto mcparticle = track0.mcParticle(); + auto mcCollID_recoColl = collision.mcCollisionId(); + auto mcCollID_particle = mcparticle.mcCollisionId(); + bool indexMatchOK = (mcCollID_recoColl == mcCollID_particle); + + int partpdg = std::abs(mcparticle.pdgCode()); + if (indexMatchOK && mcparticle.isPhysicalPrimary() && (partpdg == 211 || partpdg == 321 || partpdg == 2212 || partpdg == 11 || partpdg == 13)) { + issamemcpt = mcparticle.pt(); + } else { + issamemcpt = -mcparticle.pt(); + } + } + } } - histos.fill(HIST("Tracks/Reco/histpt3DAll"), track.pt(), track.eta(), track.phi()); - Int_t hasITS = 0; - if (track.itsNCls() > 0) - hasITS++; - if (track.itsNClsInnerBarrel() > 0) - hasITS++; - histos.fill(HIST("Tracks/Reco/histNclustTPC"), track.pt(), track.eta(), track.phi(), track.tpcNClsFound(), hasITS); - if (track.isGlobalTrack()) - histos.fill(HIST("Tracks/Reco/histpt3DFB0"), track.pt(), track.eta(), track.phi()); - if (track.trackCutFlagFb1()) - histos.fill(HIST("Tracks/Reco/histpt3DFB1"), track.pt(), track.eta(), track.phi()); - if (track.trackCutFlagFb2()) - histos.fill(HIST("Tracks/Reco/histpt3DFB2"), track.pt(), track.eta(), track.phi()); - if (track.trackCutFlagFb3()) - histos.fill(HIST("Tracks/Reco/histpt3DFB3"), track.pt(), track.eta(), track.phi()); - if (track.trackCutFlagFb4()) - histos.fill(HIST("Tracks/Reco/histpt3DFB4"), track.pt(), track.eta(), track.phi()); - if (track.trackCutFlagFb5()) - histos.fill(HIST("Tracks/Reco/histpt3DFB5"), track.pt(), track.eta(), track.phi()); + trackPairForEffTablePN(track1.pt(), track1.eta(), track1.phi(), track0.pt(), track0.eta(), track0.phi(), track0.itsNCls(), track1.tpcNClsFound(), issamemcpt); } } - PROCESS_SWITCH(CheckFilterBit, processData, "process data", true); template int isFromStrangeDecay(const T& particlesMC, const typename T::iterator& particle) @@ -170,7 +387,7 @@ struct CheckFilterBit { return strangeness; } - void processRecoMC(soa::Join::iterator const& collision, soa::Join const& tracks, aod::McParticles const& mcParticles, aod::McCollisions const& mcCollisions) + void processRecoMC(soa::Join::iterator const& collision, TracksextensionMC const& tracks, aod::McParticles const& mcParticles, aod::McCollisions const& mcCollisions) { // this will loop over data (PV) collisions histos.fill(HIST("EventProp/histDatacollZ"), collision.posZ()); @@ -209,26 +426,47 @@ struct CheckFilterBit { histos.fill(HIST("Tracks/RecoMCVariablesPrimary/histNclustTPC"), track.pt(), track.eta(), track.phi(), track.tpcNClsFound(), hasITS); if (track.isGlobalTrack()) { histos.fill(HIST("Tracks/RecoMCPhysPrimCollMatch/histptFB0"), track.pt(), track.eta(), track.phi()); + histos.fill(HIST("Tracks/RecoMCPhysPrimCollMatch/histptMCFB0"), mcparticle.pt(), track.eta(), track.phi()); + } + if (track.itsChi2NCl() > 0. && track.tpcChi2NCl() < 0.) { + histos.fill(HIST("Tracks/RecoMCPhysPrimCollMatch/histptITSonly"), track.pt(), track.eta(), track.phi()); + histos.fill(HIST("Tracks/RecoMCPhysPrimCollMatch/histptMCITSonly"), mcparticle.pt(), track.eta(), track.phi()); + } else if (track.itsChi2NCl() < 0. && track.tpcChi2NCl() > 0.) { + histos.fill(HIST("Tracks/RecoMCPhysPrimCollMatch/histptTPConly"), track.pt(), track.eta(), track.phi()); + histos.fill(HIST("Tracks/RecoMCPhysPrimCollMatch/histptMCTPConly"), mcparticle.pt(), track.eta(), track.phi()); + + histos.fill(HIST("Tracks/RecoMCPhysPrimCollMatch/histptMCTPConlyWithClusters"), mcparticle.pt(), track.eta(), track.phi(), track.tpcNClsFound()); + histos.fill(HIST("Tracks/RecoMCPhysPrimCollMatch/histptTPConlyWithClusters"), track.pt(), track.eta(), track.phi(), track.tpcNClsFound()); } if (track.trackCutFlagFb1()) { histos.fill(HIST("Tracks/RecoMCPhysPrimCollMatch/histptFB1"), track.pt(), track.eta(), track.phi()); + histos.fill(HIST("Tracks/RecoMCPhysPrimCollMatch/histptMCFB1"), mcparticle.pt(), track.eta(), track.phi()); } if (track.trackCutFlagFb2()) { histos.fill(HIST("Tracks/RecoMCPhysPrimCollMatch/histptFB2"), track.pt(), track.eta(), track.phi()); + histos.fill(HIST("Tracks/RecoMCPhysPrimCollMatch/histptMCFB2"), mcparticle.pt(), track.eta(), track.phi()); } if (track.trackCutFlagFb3()) { histos.fill(HIST("Tracks/RecoMCPhysPrimCollMatch/histptFB3"), track.pt(), track.eta(), track.phi()); + histos.fill(HIST("Tracks/RecoMCPhysPrimCollMatch/histptMCFB3"), mcparticle.pt(), track.eta(), track.phi()); } if (track.trackCutFlagFb4()) { histos.fill(HIST("Tracks/RecoMCPhysPrimCollMatch/histptFB4"), track.pt(), track.eta(), track.phi()); + histos.fill(HIST("Tracks/RecoMCPhysPrimCollMatch/histptMCFB4"), mcparticle.pt(), track.eta(), track.phi()); } if (track.trackCutFlagFb5()) { histos.fill(HIST("Tracks/RecoMCPhysPrimCollMatch/histptFB5"), track.pt(), track.eta(), track.phi()); + histos.fill(HIST("Tracks/RecoMCPhysPrimCollMatch/histptMCFB5"), mcparticle.pt(), track.eta(), track.phi()); } if (isHF == RecoDecay::OriginType::Prompt || isHF == RecoDecay::OriginType::NonPrompt) { if (track.isGlobalTrack()) { histos.fill(HIST("Tracks/RecoMCfromHFdecayCollMatch/histptFB0"), track.pt(), track.eta(), track.phi()); } + if (track.itsChi2NCl() > 0. && track.tpcChi2NCl() < 0.) { + histos.fill(HIST("Tracks/RecoMCfromHFdecayCollMatch/histptITSonly"), track.pt(), track.eta(), track.phi()); + } else if (track.itsChi2NCl() < 0. && track.tpcChi2NCl() > 0.) { + histos.fill(HIST("Tracks/RecoMCfromHFdecayCollMatch/histptTPConly"), track.pt(), track.eta(), track.phi()); + } if (track.trackCutFlagFb1()) { histos.fill(HIST("Tracks/RecoMCfromHFdecayCollMatch/histptFB1"), track.pt(), track.eta(), track.phi()); } @@ -248,6 +486,11 @@ struct CheckFilterBit { } else if (prodRadius2 > 1. && prodRadius2 < 225. && isFromStrange) { if (track.isGlobalTrack()) histos.fill(HIST("Tracks/RecoMCRad1to15cmCollMatch/histptFB0"), track.pt(), track.eta(), track.phi()); + if (track.itsChi2NCl() > 0. && track.tpcChi2NCl() < 0.) { + histos.fill(HIST("Tracks/RecoMCRad1to15cmCollMatch/histptITSonly"), track.pt(), track.eta(), track.phi()); + } else if (track.itsChi2NCl() < 0. && track.tpcChi2NCl() > 0.) { + histos.fill(HIST("Tracks/RecoMCRad1to15cmCollMatch/histptTPConly"), track.pt(), track.eta(), track.phi()); + } if (track.trackCutFlagFb1()) histos.fill(HIST("Tracks/RecoMCRad1to15cmCollMatch/histptFB1"), track.pt(), track.eta(), track.phi()); if (track.trackCutFlagFb2()) @@ -262,6 +505,11 @@ struct CheckFilterBit { if (prodRadius2 > 1.e-8 && prodRadius2 < 0.25) { if (track.isGlobalTrack()) histos.fill(HIST("Tracks/RecoMCRad1mumto5mmCollMatch/histptFB0"), track.pt(), track.eta(), track.phi()); + if (track.itsChi2NCl() > 0. && track.tpcChi2NCl() < 0.) { + histos.fill(HIST("Tracks/RecoMCRad1mumto5mmCollMatch/histptITSonly"), track.pt(), track.eta(), track.phi()); + } else if (track.itsChi2NCl() < 0. && track.tpcChi2NCl() > 0.) { + histos.fill(HIST("Tracks/RecoMCRad1mumto5mmCollMatch/histptTPConly"), track.pt(), track.eta(), track.phi()); + } if (track.trackCutFlagFb1()) histos.fill(HIST("Tracks/RecoMCRad1mumto5mmCollMatch/histptFB1"), track.pt(), track.eta(), track.phi()); if (track.trackCutFlagFb2()) @@ -319,9 +567,3 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) }; } - -// void customize(std::vector& workflowOptions) -//{ -// ConfigParamSpec optionDoMC{"doMC", VariantType::Bool, false, {"Use MC info"}}; -// workflowOptions.push_back(optionDoMC); -// } diff --git a/DPG/Tasks/AOTTrack/PID/qaPIDTOF.cxx b/DPG/Tasks/AOTTrack/PID/qaPIDTOF.cxx index c6064c11906..eeb391a1a0a 100644 --- a/DPG/Tasks/AOTTrack/PID/qaPIDTOF.cxx +++ b/DPG/Tasks/AOTTrack/PID/qaPIDTOF.cxx @@ -135,6 +135,7 @@ struct tofPidQa { Configurable ptDeltaTEtaPhiMap{"ptDeltaTEtaPhiMap", 3.f, "Threshold in pT to build the map of the delta time as a function of eta and phi"}; Configurable splitSignalPerCharge{"splitSignalPerCharge", true, "Split the signal per charge (reduces memory footprint if off)"}; Configurable enableVsMomentumHistograms{"enableVsMomentumHistograms", false, "Enables plots vs momentum instead of just pT (reduces memory footprint if off)"}; + Configurable requireGoodMatchTracks{"requireGoodMatchTracks", false, "Require good match tracks"}; template void initPerParticle(const AxisSpec& pAxis, @@ -287,6 +288,7 @@ struct tofPidQa { h->GetXaxis()->SetBinLabel(3, "hasITS"); h->GetXaxis()->SetBinLabel(4, "hasTPC"); h->GetXaxis()->SetBinLabel(5, "hasTOF"); + h->GetXaxis()->SetBinLabel(6, "goodTOFMatch"); histos.add("event/vertexz", "", kTH1D, {vtxZAxis}); h = histos.add("event/particlehypo", "", kTH1D, {{10, 0, 10, "PID in tracking"}}); @@ -440,6 +442,12 @@ struct tofPidQa { } if constexpr (fillHistograms) { histos.fill(HIST("event/trackselection"), 5.f); + } + if (requireGoodMatchTracks.value && !track.goodTOFMatch()) { // Skipping tracks without good match + return false; + } + if constexpr (fillHistograms) { + histos.fill(HIST("event/trackselection"), 6.f); histos.fill(HIST("event/particlehypo"), track.pidForTracking()); if (track.has_collision()) { histos.fill(HIST("event/tofsignal"), track.p(), track.tofSignal()); @@ -469,7 +477,8 @@ struct tofPidQa { ((trackSelection.node() == 5) && requireInAcceptanceTracksInFilter()); using CollisionCandidate = soa::Filtered>::iterator; using TrackCandidates = soa::Join; + aod::pidEvTimeFlags, aod::TOFSignal, aod::TOFEvTime, + aod::pidTOFFlags>; void process(CollisionCandidate const& collision, soa::Filtered const& tracks) diff --git a/DPG/Tasks/AOTTrack/PID/qaPIDTOFBeta.cxx b/DPG/Tasks/AOTTrack/PID/qaPIDTOFBeta.cxx index dc44dee5798..a550dfbd120 100644 --- a/DPG/Tasks/AOTTrack/PID/qaPIDTOFBeta.cxx +++ b/DPG/Tasks/AOTTrack/PID/qaPIDTOFBeta.cxx @@ -47,6 +47,7 @@ struct tofPidBetaQa { ConfigurableAxis tofMassBins{"tofMassBins", {1000, 0, 3.f}, "Binning in the TOF mass plot"}; ConfigurableAxis tofBetaBins{"tofBetaBins", {4000, 0, 2.f}, "Binning in the TOF beta plot"}; ConfigurableAxis trackLengthBins{"trackLengthBins", {100, 0, 1000.f}, "Binning in track length plot"}; + Configurable requireGoodMatchTracks{"requireGoodMatchTracks", false, "Require good match tracks"}; void init(o2::framework::InitContext&) { @@ -58,6 +59,7 @@ struct tofPidBetaQa { const AxisSpec etaAxis{100, -2, 2, "#it{#eta}"}; const AxisSpec colTimeAxis{100, -2000, 2000, "Collision time (ps)"}; const AxisSpec lAxis{trackLengthBins, "Track length (cm)"}; + const AxisSpec tofChi2Axis{1000, 0, 20, "TOF residual (cm)"}; const AxisSpec ptResoAxis{100, 0, 0.1, "#sigma_{#it{p}_{T}}"}; const AxisSpec pAxisPosNeg{2 * nBinsP, -maxP, maxP, "#it{p}/z (GeV/#it{c})"}; AxisSpec ptAxis{nBinsP, minP, maxP, "#it{p}_{T} (GeV/#it{c})"}; @@ -173,6 +175,7 @@ struct tofPidBetaQa { } } + histos.add("event/tofchi2", "", HistType::kTH1F, {tofChi2Axis}); histos.add("event/eta", "", HistType::kTH1F, {etaAxis}); histos.add("event/length", "", HistType::kTH1F, {lAxis}); if (splitTrdTracks) { @@ -190,6 +193,7 @@ struct tofPidBetaQa { h->GetXaxis()->SetBinLabel(1, "Tracks read"); h->GetXaxis()->SetBinLabel(2, "hasTOF"); h->GetXaxis()->SetBinLabel(3, "isGlobalTrack"); + h->GetXaxis()->SetBinLabel(4, "goodTOFMatch"); } Filter eventFilter = (applyEvSel.node() == 0) || @@ -205,7 +209,8 @@ struct tofPidBetaQa { using CollisionCandidate = soa::Filtered>::iterator; using TrackCandidates = soa::Join; + aod::pidEvTimeFlags, aod::TOFSignal, aod::TOFEvTime, + aod::pidTOFFlags>; void process(CollisionCandidate const& collision, soa::Filtered const& tracks) { @@ -239,6 +244,11 @@ struct tofPidBetaQa { continue; } histos.fill(HIST("event/trackselection"), 3.f); + if (requireGoodMatchTracks.value && !track.goodTOFMatch()) { // Skipping tracks without good match + continue; + } + histos.fill(HIST("event/trackselection"), 4.f); + if (splitSignalPerCharge) { histos.fill(HIST("tofmass/inclusive"), track.p(), track.mass(), track.sign()); histos.fill(HIST("tofbeta/inclusive"), track.p(), track.beta(), track.sign()); @@ -283,6 +293,7 @@ struct tofPidBetaQa { } } histos.fill(HIST("event/length"), track.length()); + histos.fill(HIST("event/tofchi2"), track.tofChi2()); histos.fill(HIST("event/eta"), track.eta()); histos.fill(HIST("event/tofsignal"), track.p(), track.tofSignal()); histos.fill(HIST("event/pt"), track.pt()); diff --git a/DPG/Tasks/AOTTrack/PID/qaPIDTPC.cxx b/DPG/Tasks/AOTTrack/PID/qaPIDTPC.cxx index 638302674d4..4f805808110 100644 --- a/DPG/Tasks/AOTTrack/PID/qaPIDTPC.cxx +++ b/DPG/Tasks/AOTTrack/PID/qaPIDTPC.cxx @@ -50,6 +50,9 @@ struct tpcPidQa { static constexpr std::string_view hnsigma_pt[Np] = {"nsigma/pt/El", "nsigma/pt/Mu", "nsigma/pt/Pi", "nsigma/pt/Ka", "nsigma/pt/Pr", "nsigma/pt/De", "nsigma/pt/Tr", "nsigma/pt/He", "nsigma/pt/Al"}; + static constexpr std::string_view hnsigma_p_eta_Ncl[Np] = {"nsigma/sparsePinEtaNcl/El", "nsigma/sparsePinEtaNcl/Mu", "nsigma/sparsePinEtaNcl/Pi", + "nsigma/sparsePinEtaNcl/Ka", "nsigma/sparsePinEtaNcl/Pr", "nsigma/sparsePinEtaNcl/De", + "nsigma/sparsePinEtaNcl/Tr", "nsigma/sparsePinEtaNcl/He", "nsigma/sparsePinEtaNcl/Al"}; // With TOF static constexpr std::string_view hexpected_wTOF[Np] = {"wTOF/expected/El", "wTOF/expected/Mu", "wTOF/expected/Pi", @@ -76,6 +79,9 @@ struct tpcPidQa { static constexpr std::string_view hsignal_wTOF[Np] = {"wTOF/signal/El", "wTOF/signal/Mu", "wTOF/signal/Pi", "wTOF/signal/Ka", "wTOF/signal/Pr", "wTOF/signal/De", "wTOF/signal/Tr", "wTOF/signal/He", "wTOF/signal/Al"}; + static constexpr std::string_view hnsigma_p_eta_Ncl_wTOF[Np] = {"wTOF/nsigma/sparsePinEtaNcl/El", "wTOF/nsigma/sparsePinEtaNcl/Mu", "wTOF/nsigma/sparsePinEtaNcl/Pi", + "wTOF/nsigma/sparsePinEtaNcl/Ka", "wTOF/nsigma/sparsePinEtaNcl/Pr", "wTOF/nsigma/sparsePinEtaNcl/De", + "wTOF/nsigma/sparsePinEtaNcl/Tr", "wTOF/nsigma/sparsePinEtaNcl/He", "wTOF/nsigma/sparsePinEtaNcl/Al"}; HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -96,6 +102,8 @@ struct tpcPidQa { Configurable splitSignalPerCharge{"splitSignalPerCharge", true, "Split the signal per charge (reduces memory footprint if off)"}; Configurable enableDeDxPlot{"enableDeDxPlot", true, "Enables the dEdx plot (reduces memory footprint if off)"}; Configurable minTPCNcls{"minTPCNcls", 0, "Minimum number or TPC Clusters for tracks"}; + ConfigurableAxis tpcNclsBins{"tpcNclsBins", {16, 0, 160}, "Bining in number of cluster in TPC"}; + Configurable fillTHnSparses{"fillTHnSparses", false, "Flag to fill multidimensional histograms for nsigma vs pt, eta, Ncls"}; template void initPerParticle(const AxisSpec& pAxis, @@ -175,6 +183,14 @@ struct tpcPidQa { const AxisSpec expSigmaAxis{expSigmaBins, Form("Exp_{#sigma}^{TPC}(%s)", pT[id])}; histos.add(hexpsigma[id].data(), "", kTH2F, {pAxis, expSigmaAxis}); + const AxisSpec etaAxis{etaBins, "#it{#eta}"}; + const AxisSpec tpcnclsAxis{tpcNclsBins, "TPC #cls"}; + + HistogramConfigSpec particleSparseHists{HistType::kTHnSparseF, {pAxis, etaAxis, nSigmaAxis, tpcnclsAxis}}; + if (fillTHnSparses) { + histos.add(hnsigma_p_eta_Ncl[id].data(), axisTitle, particleSparseHists); + } + if (!enableTOFHistos) { // Returning if the plots with TOF are not requested return; } @@ -185,6 +201,12 @@ struct tpcPidQa { histos.add(hdelta_pt_neg_wTOF[id].data(), "With TOF Negative", kTH2F, {ptAxis, deltaAxis}); histos.add(hexpsigma_wTOF[id].data(), "With TOF", kTH2F, {pAxis, expSigmaAxis}); histos.add(hnsigma_wTOF[id].data(), Form("With TOF %s", axisTitle), kTH2F, {pAxis, nSigmaAxis}); + + HistogramConfigSpec particleSparseHists_wTOF{HistType::kTHnSparseF, {pAxis, etaAxis, nSigmaAxis, tpcnclsAxis}}; + if (fillTHnSparses) { + histos.add(hnsigma_p_eta_Ncl_wTOF[id].data(), Form("With TOF %s", axisTitle), particleSparseHists_wTOF); + } + if (splitSignalPerCharge) { histos.add(hnsigma_pt_wTOF[id].data(), Form("With TOF %s", axisTitle), kTH3F, {ptAxis, nSigmaAxis, chargeAxis}); histos.add(hsignal_wTOF[id].data(), "With TOF", kTH3F, {pAxis, dedxAxis, chargeAxis}); @@ -386,6 +408,11 @@ struct tpcPidQa { // Fill histograms histos.fill(HIST(hexpected[id]), t.tpcInnerParam(), t.tpcSignal() - diff); histos.fill(HIST(hdelta[id]), t.tpcInnerParam(), diff); + + if (fillTHnSparses) { + histos.fill(HIST(hnsigma_p_eta_Ncl[id]), t.p(), t.eta(), nsigma, t.tpcNClsFindable()); + } + if (splitSignalPerCharge) { histos.fill(HIST(hdelta_pt[id]), t.pt(), diff, t.sign()); } else { @@ -404,6 +431,9 @@ struct tpcPidQa { const auto& nsigmatof = o2::aod::pidutils::tofNSigma(t); if (std::abs(nsigmatof) < 3.f) { histos.fill(HIST(hnsigma_wTOF[id]), t.p(), nsigma); + if (fillTHnSparses) { + histos.fill(HIST(hnsigma_p_eta_Ncl_wTOF[id]), t.p(), t.eta(), nsigma, t.tpcNClsFindable()); + } if (splitSignalPerCharge) { histos.fill(HIST(hnsigma_pt_wTOF[id]), t.pt(), nsigma, t.sign()); histos.fill(HIST(hsignal_wTOF[id]), t.tpcInnerParam(), t.tpcSignal(), t.sign()); diff --git a/DPG/Tasks/AOTTrack/V0Cascades/perfK0sResolution.cxx b/DPG/Tasks/AOTTrack/V0Cascades/perfK0sResolution.cxx index ef22df6c07c..628ea1463f5 100644 --- a/DPG/Tasks/AOTTrack/V0Cascades/perfK0sResolution.cxx +++ b/DPG/Tasks/AOTTrack/V0Cascades/perfK0sResolution.cxx @@ -34,17 +34,25 @@ using SelectedCollisions = soa::Join; struct perfK0sResolution { ConfigurableAxis mBins{"mBins", {200, 0.4f, 0.6f}, "Mass binning"}; ConfigurableAxis pTBins{"pTBins", {200, 0.f, 10.f}, "pT binning"}; + ConfigurableAxis pTResBins{"pTResBins", {200, -1.2f, 1.2f}, "pT resolution binning"}; + ConfigurableAxis invpTResBins{"invpTResBins", {200, -1.2f, 1.2f}, "inv pT resolution binning"}; ConfigurableAxis etaBins{"etaBins", {2, -1.f, 1.f}, "eta binning"}; + ConfigurableAxis etaBinsDauthers{"etaBinsDauthers", {2, -1.f, 1.f}, "eta binning"}; ConfigurableAxis phiBins{"phiBins", {4, 0.f, 6.28f}, "phi binning"}; - HistogramRegistry registry{"K0sResolution"}; + HistogramRegistry rK0sResolution{"K0sResolution"}; void init(InitContext const&) { const AxisSpec mAxis{mBins, "#it{m} (GeV/#it{c}^{2})"}; const AxisSpec pTAxis{pTBins, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec pTResAxis{pTResBins, "#Delta#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec invpTResAxis{invpTResBins, "1/#it{p}_{T}-1/#it{p}_{T}^{MC} (GeV/#it{c})^{-1}"}; const AxisSpec etaAxis{etaBins, "#eta"}; + const AxisSpec etaAxisPosD{etaBinsDauthers, "#eta pos."}; + const AxisSpec etaAxisNegD{etaBinsDauthers, "#eta neg."}; const AxisSpec phiAxis{phiBins, "#phi"}; + const AxisSpec trueK0Axis{2, -0.5, 1.5, "True K0"}; int nProc = 0; if (doprocessData) { @@ -56,34 +64,48 @@ struct perfK0sResolution { nProc++; } - registry.add("h2_masspT", "h2_masspT", {HistType::kTH2F, {mAxis, pTAxis}}); - registry.add("h2_masseta", "h2_masseta", {HistType::kTH2F, {mAxis, etaAxis}}); - registry.add("h2_massphi", "h2_massphi", {HistType::kTH2F, {mAxis, phiAxis}}); + if (doprocessMC) { + rK0sResolution.add("h2_massPosPtRes", "h2_massPosPtRes", {HistType::kTH2F, {mAxis, pTResAxis}}); + rK0sResolution.add("h2_massNegPtRes", "h2_massNegPtRes", {HistType::kTH2F, {mAxis, pTResAxis}}); + } + rK0sResolution.add("h2_masspT", "h2_masspT", {HistType::kTH2F, {mAxis, pTAxis}}); + rK0sResolution.add("h2_masseta", "h2_masseta", {HistType::kTH2F, {mAxis, etaAxis}}); + rK0sResolution.add("h2_massphi", "h2_massphi", {HistType::kTH2F, {mAxis, phiAxis}}); + if (useMultidimHisto) { + if (doprocessMC) { + rK0sResolution.add("thn_mass", "thn_mass", kTHnSparseF, {mAxis, pTAxis, etaAxis, phiAxis, etaAxisPosD, etaAxisNegD, invpTResAxis, invpTResAxis, trueK0Axis}); + } else { + rK0sResolution.add("thn_mass", "thn_mass", kTHnSparseF, {mAxis, pTAxis, etaAxis, phiAxis, etaAxisPosD, etaAxisNegD}); + } + } } // Selection criteria - Configurable v0setting_cospa{"v0setting_cospa", 0.995, "V0 CosPA"}; + Configurable v0setting_cospa{"v0setting_cospa", 0.995, "V0 CosPA"}; // shoudl be double in future Configurable v0setting_dcav0dau{"v0setting_dcav0dau", 1., "DCA V0 Daughters"}; Configurable v0setting_dcapostopv{"v0setting_dcapostopv", 0.1, "DCA Pos To PV"}; Configurable v0setting_dcanegtopv{"v0setting_dcanegtopv", 0.1, "DCA Neg To PV"}; Configurable v0setting_radius{"v0setting_radius", 0.9, "V0 Radius"}; + Configurable v0setting_rapidity{"v0setting_rapidity", 0.5, "rapidity"}; + Configurable v0lifetime{"v0lifetime", 3., "n ctau"}; - Configurable rapidity{"rapidity", 0.5, "rapidity"}; Configurable nSigTPC{"nSigTPC", 10., "nSigTPC"}; Configurable trdSelectionPos{"trdSelectionPos", 0, "Flag for the TRD selection on positive daughters: -1 no TRD, 0 no selection, 1 TRD"}; Configurable trdSelectionNeg{"trdSelectionNeg", 0, "Flag for the TRD selection on negative daughters: -1 no TRD, 0 no selection, 1 TRD"}; Configurable tofSelectionPos{"tofSelectionPos", 0, "Flag for the TOF selection on positive daughters: -1 no TOF, 0 no selection, 1 TOF"}; Configurable tofSelectionNeg{"tofSelectionNeg", 0, "Flag for the TOF selection on negative daughters: -1 no TOF, 0 no selection, 1 TOF"}; + + Configurable useMultidimHisto{"useMultidimHisto", false, "use multidimentional histograms"}; + + // Configurable for event selection + Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; Configurable eventSelection{"eventSelection", true, "event selection"}; template bool acceptV0(const T1& v0, const T2& ntrack, const T2& ptrack, const C& collision) { // Apply selections on V0 - if (TMath::Abs(v0.yK0Short()) > rapidity) { - return false; - } - if (v0.v0cosPA() < v0setting_cospa) { + if (TMath::Abs(v0.yK0Short()) > v0setting_rapidity) { return false; } if (v0.v0radius() < v0setting_radius) { @@ -173,34 +195,38 @@ struct perfK0sResolution { return true; } - Filter v0Filter = nabs(aod::v0data::dcapostopv) > v0setting_dcapostopv&& nabs(aod::v0data::dcanegtopv) > v0setting_dcanegtopv&& aod::v0data::dcaV0daughters < v0setting_dcav0dau; + // Filters on V0s + Filter v0Filter = (nabs(aod::v0data::dcapostopv) > v0setting_dcapostopv && + nabs(aod::v0data::dcanegtopv) > v0setting_dcanegtopv && + aod::v0data::dcaV0daughters < v0setting_dcav0dau && + aod::v0data::v0cosPA > v0setting_cospa); - void processData(SelectedCollisions::iterator const& collision, soa::Filtered const& fullV0s, PIDTracks const& tracks) - { - if (eventSelection && !collision.sel8()) - return; + // Event selection + Filter eventFilter = (eventSelection && o2::aod::evsel::sel8 == true); + Filter posZFilter = (nabs(o2::aod::collision::posZ) < cutzvertex); + void processData(soa::Filtered::iterator const& collision, soa::Filtered const& fullV0s, PIDTracks const& tracks) + { for (auto& v0 : fullV0s) { - const auto& posTrack = v0.posTrack_as(); const auto& negTrack = v0.negTrack_as(); if (!acceptV0(v0, negTrack, posTrack, collision)) continue; - registry.fill(HIST("h2_masspT"), v0.mK0Short(), v0.pt()); - registry.fill(HIST("h2_masseta"), v0.mK0Short(), v0.eta()); - registry.fill(HIST("h2_massphi"), v0.mK0Short(), v0.phi()); + rK0sResolution.fill(HIST("h2_masspT"), v0.mK0Short(), v0.pt()); + rK0sResolution.fill(HIST("h2_masseta"), v0.mK0Short(), v0.eta()); + rK0sResolution.fill(HIST("h2_massphi"), v0.mK0Short(), v0.phi()); + if (useMultidimHisto) { + rK0sResolution.fill(HIST("thn_mass"), v0.mK0Short(), v0.pt(), v0.eta(), v0.phi(), posTrack.eta(), negTrack.eta()); + } } } PROCESS_SWITCH(perfK0sResolution, processData, "Process data", true); - void processMC(SelectedCollisions::iterator const& collision, soa::Filtered const& fullV0s, soa::Join const& tracks, aod::McParticles const&) + void processMC(soa::Filtered::iterator const& collision, soa::Filtered> const& fullV0s, + soa::Join const& tracks, aod::McParticles const&) { - if (eventSelection && !collision.sel8()) - return; - for (auto& v0 : fullV0s) { - const auto& posTrack = v0.posTrack_as>(); const auto& negTrack = v0.negTrack_as>(); if (!acceptV0(v0, negTrack, posTrack, collision)) @@ -211,15 +237,27 @@ struct perfK0sResolution { if (!negTrack.has_mcParticle()) { continue; } - if (posTrack.mcParticle().pdgCode() != PID::Pion || negTrack.mcParticle().pdgCode() != PID::Pion) { + if (posTrack.mcParticle().pdgCode() != 211 || negTrack.mcParticle().pdgCode() != -211) { continue; } - registry.fill(HIST("h2_masspT"), v0.mK0Short(), v0.pt()); - registry.fill(HIST("h2_masseta"), v0.mK0Short(), v0.eta()); - registry.fill(HIST("h2_massphi"), v0.mK0Short(), v0.phi()); + const bool isTrueK0s = (v0.has_mcParticle() && v0.mcParticle().pdgCode() == 310); + rK0sResolution.fill(HIST("h2_massPosPtRes"), v0.mK0Short(), v0.positivept() - posTrack.mcParticle().pt()); + rK0sResolution.fill(HIST("h2_massNegPtRes"), v0.mK0Short(), v0.negativept() - negTrack.mcParticle().pt()); + rK0sResolution.fill(HIST("h2_masspT"), v0.mK0Short(), v0.pt()); + rK0sResolution.fill(HIST("h2_masseta"), v0.mK0Short(), v0.eta()); + rK0sResolution.fill(HIST("h2_massphi"), v0.mK0Short(), v0.phi()); + if (useMultidimHisto) { + rK0sResolution.fill(HIST("thn_mass"), v0.mK0Short(), v0.pt(), v0.eta(), v0.phi(), posTrack.eta(), negTrack.eta(), + 1. / v0.positivept() - 1. / posTrack.mcParticle().pt(), + 1. / v0.negativept() - 1. / negTrack.mcParticle().pt(), + isTrueK0s); + } } } PROCESS_SWITCH(perfK0sResolution, processMC, "Process MC", false); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc)}; } +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/DPG/Tasks/AOTTrack/tagAndProbeDmesons.cxx b/DPG/Tasks/AOTTrack/tagAndProbeDmesons.cxx index 8e048bce237..e5cd93a3357 100644 --- a/DPG/Tasks/AOTTrack/tagAndProbeDmesons.cxx +++ b/DPG/Tasks/AOTTrack/tagAndProbeDmesons.cxx @@ -47,6 +47,7 @@ enum TagChannels : uint8_t { enum TrackTypes : uint8_t { GlobalWoDca = 0, + GlobalWoDcaWoItsIb, GlobalWoDcaWoIts, GlobalWoDcaWoTpc, NTrackTypes @@ -548,49 +549,62 @@ struct ProbeThirdTrack { { // ITS-TPC tracks (global tracks) trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetTrackType(o2::aod::track::TrackTypeEnum::Track); - trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetPtRange(0.1f, 1e10f); - trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetEtaRange(-0.8f, 0.8f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetPtRange(0.05f, 1e10f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetEtaRange(-1.f, 1.f); trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetRequireITSRefit(true); trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetRequireTPCRefit(true); - trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetRequireGoldenChi2(true); - trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetMinNCrossedRowsTPC(70); - trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetMinNCrossedRowsOverFindableClustersTPC(0.8f); - trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetMaxChi2PerClusterTPC(4.f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetMinNCrossedRowsTPC(50); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetMaxChi2PerClusterTPC(10.f); trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetRequireHitsInITSLayers(1, {0, 1, 2}); // one hit in any IB layer trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetMaxChi2PerClusterITS(36.f); trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDca].SetMaxDcaZ(2.f); + // TPC tracks (global tracks without ITS IB requirement) + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoItsIb].SetTrackType(o2::aod::track::TrackTypeEnum::Track); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoItsIb].SetPtRange(0.05f, 1e10f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoItsIb].SetEtaRange(-1.f, 1.f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoItsIb].SetRequireTPCRefit(true); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoItsIb].SetMinNCrossedRowsTPC(50); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoItsIb].SetMaxChi2PerClusterTPC(10.f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoItsIb].SetRequireHitsInITSLayers(3, {0, 1, 2, 3, 4, 5, 6}); // at least three hits in whatever layer + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoItsIb].SetMaxChi2PerClusterITS(36.f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoItsIb].SetMaxDcaZ(2.f); + // TPC tracks (global tracks without ITS requirements) trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetTrackType(o2::aod::track::TrackTypeEnum::Track); - trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetPtRange(0.1f, 1e10f); - trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetEtaRange(-0.8f, 0.8f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetPtRange(0.05f, 1e10f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetEtaRange(-1.f, 1.f); trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetRequireTPCRefit(true); - trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetRequireGoldenChi2(true); - trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetMinNCrossedRowsTPC(70); - trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetMinNCrossedRowsOverFindableClustersTPC(0.8f); - trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetMaxChi2PerClusterTPC(4.f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetMinNCrossedRowsTPC(50); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoIts].SetMaxChi2PerClusterTPC(10.f); // ITS tracks (global tracks without TPC requirements) trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoTpc].SetTrackType(o2::aod::track::TrackTypeEnum::Track); - trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoTpc].SetPtRange(0.1f, 1e10f); - trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoTpc].SetEtaRange(-0.8f, 0.8f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoTpc].SetPtRange(0.05f, 1e10f); + trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoTpc].SetEtaRange(-1.f, 1.f); trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoTpc].SetRequireITSRefit(true); trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoTpc].SetRequireHitsInITSLayers(1, {0, 1, 2}); // one hit in any SPD layer trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoTpc].SetMaxChi2PerClusterITS(36.f); trackSelector[aod::tagandprobe::TrackTypes::GlobalWoDcaWoTpc].SetMaxDcaZ(2.f); - const AxisSpec axisPtProbe{250, 0.f, 25.f}; - const AxisSpec axisPtTag{250, 0.f, 50.f}; - const AxisSpec axisPtD{50, 0.f, 50.f}; - std::array axisMass = {AxisSpec{450, 1.65f, 2.10f}, AxisSpec{450, 1.65f, 2.10f}, AxisSpec{350, 0.135f, 0.17f}, AxisSpec{350, 0.135f, 0.17f}}; - std::array axisMassTag = {AxisSpec{250, 0.f, 2.5f}, AxisSpec{200, constants::physics::MassPhi - 0.05f, constants::physics::MassPhi + 0.05f}, AxisSpec{400, constants::physics::MassD0 - 0.2f, constants::physics::MassD0 + 0.2f}, AxisSpec{400, constants::physics::MassD0 - 0.2f, constants::physics::MassD0 + 0.2f}}; - - std::string trackTypes[aod::tagandprobe::TrackTypes::NTrackTypes] = {"ItsTpc", "Tpc", "Its"}; + const AxisSpec axisPtProbe{{0.05f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.2f, 1.5f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 4.5f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.f, 12.f, 15.f, 20.f, 25.f, 30.f}}; + const AxisSpec axisPtTag{{0.05f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.2f, 1.5f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 4.5f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.f, 12.f, 15.f, 20.f, 25.f, 30.f}}; + const AxisSpec axisPtD{{0.f, 0.5f, 1.f, 1.5f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 4.5f, 5.0f, 5.5f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 8.5f, 9.0f, 9.5f, 10.f, 11.f, 12.f, 14.f, 16.f, 20.f, 24.f, 36.f, 50.f}}; + const AxisSpec axisEtaProbe{20, -1.f, 1.f}; + const AxisSpec axisNumCrossRowTpc{51, 49.5f, 100.5f}; + const AxisSpec axisTpcChi2PerClus{8, 2.f, 10.f}; + const AxisSpec axisNumCluIts{5, 2.5f, 7.5f}; + std::array axisMass = {AxisSpec{225, 1.65f, 2.10f}, AxisSpec{225, 1.65f, 2.10f}, AxisSpec{350, 0.135f, 0.17f}, AxisSpec{350, 0.135f, 0.17f}}; + std::array axisMassTag = {AxisSpec{125, 0.f, 2.5f}, AxisSpec{100, constants::physics::MassPhi - 0.05f, constants::physics::MassPhi + 0.05f}, AxisSpec{200, constants::physics::MassD0 - 0.2f, constants::physics::MassD0 + 0.2f}, AxisSpec{200, constants::physics::MassD0 - 0.2f, constants::physics::MassD0 + 0.2f}}; + + std::string trackTypes[aod::tagandprobe::TrackTypes::NTrackTypes] = {"ItsTpc", "ItsTpcNoIb", "Tpc", "Its"}; std::string tagChannels[aod::tagandprobe::TagChannels::NTagChannels] = {"DplusToKPiPi", "DsOrDplusToKKPi", "DstarPlusToDzeroPi", "DstarMinusToDzeroBarPi"}; for (int iChannel{0}; iChannel < aod::tagandprobe::TagChannels::NTagChannels; ++iChannel) { for (int iTrackType{0}; iTrackType < aod::tagandprobe::TrackTypes::NTrackTypes; ++iTrackType) { - histos[iChannel][iTrackType] = registry.add(Form("h%sVsPtProbeTag_%s", tagChannels[iChannel].data(), trackTypes[iTrackType].data()), "; #it{p}_{T}(D) (GeV/#it{c}); #it{p}_{T}(tag) (GeV/#it{c}); #it{p}_{T}(probe track) (GeV/#it{c}); #it{M}(D) (GeV/#it{c}^{2}); #it{M}(tag) (GeV/#it{c}^{2});", HistType::kTHnSparseF, {axisPtD, axisPtTag, axisPtProbe, axisMass[iChannel], axisMassTag[iChannel]}); + histos[iChannel][iTrackType] = registry.add(Form("h%sVsPtProbeTag_%s", tagChannels[iChannel].data(), trackTypes[iTrackType].data()), + "; #it{p}_{T}(D) (GeV/#it{c}); #it{p}_{T}(tag) (GeV/#it{c}); #it{p}_{T}(probe) (GeV/#it{c}); #it{p}_{T}^{TPC in}(probe) (GeV/#it{c}); #it{M}(D) (GeV/#it{c}^{2}); #it{M}(tag) (GeV/#it{c}^{2}); #it{#eta}(probe); #it{N}_{cross rows}^{TPC}(probe); #chi^{2}/#it{N}_{clusters}^{TPC}(probe); #it{N}_{clusters}^{ITS}(probe);", + HistType::kTHnSparseF, {axisPtD, axisPtTag, axisPtProbe, axisPtProbe, axisMass[iChannel], axisMassTag[iChannel], axisEtaProbe, axisNumCrossRowTpc, axisTpcChi2PerClus, axisNumCluIts}); } } } @@ -632,6 +646,11 @@ struct ProbeThirdTrack { continue; } auto ptTrackThird = trackThird.pt(); + auto ptTpcInnerTrackThird = trackThird.tpcInnerParam() / std::sqrt(1.f + trackThird.tgl() * trackThird.tgl()); + auto etaTrackThird = trackThird.eta(); + auto numTpcCrossRowTrackThird = trackThird.tpcNClsCrossedRows(); + auto numTpcChi2NumCluTrackThird = trackThird.tpcChi2NCl(); + auto numItsCluTrackThird = trackThird.itsNCls(); float invMass{-1.f}, invMassTag{-1.f}, ptTag{-1.f}, ptD{-1.f}; computeInvariantMass(trackFirst, trackSecond, trackThird, channel, ptTag, invMassTag, ptD, invMass); if ((channel == aod::tagandprobe::TagChannels::DstarPlusToDzeroPi || channel == aod::tagandprobe::TagChannels::DstarMinusToDzeroBarPi) && invMass > 0.17f) { @@ -641,7 +660,7 @@ struct ProbeThirdTrack { } for (int iTrackType{0}; iTrackType < aod::tagandprobe::TrackTypes::NTrackTypes; ++iTrackType) { if (trackSelector[iTrackType].IsSelected(trackThird)) { - histos[channel][iTrackType]->Fill(ptD, ptTag, ptTrackThird, invMass, invMassTag); + histos[channel][iTrackType]->Fill(ptD, ptTag, ptTrackThird, ptTpcInnerTrackThird, invMass, invMassTag, etaTrackThird, numTpcCrossRowTrackThird, numTpcChi2NumCluTrackThird, numItsCluTrackThird); } } } diff --git a/DPG/Tasks/TPC/tpcSkimsTableCreator.cxx b/DPG/Tasks/TPC/tpcSkimsTableCreator.cxx index 1a5a3da4620..a37ee579ccc 100644 --- a/DPG/Tasks/TPC/tpcSkimsTableCreator.cxx +++ b/DPG/Tasks/TPC/tpcSkimsTableCreator.cxx @@ -177,10 +177,10 @@ struct TreeWriterTpcV0 { /// Loop over v0 candidates for (auto v0 : v0s) { - auto posTrack = v0.posTrack_as(); - auto negTrack = v0.negTrack_as(); + auto posTrack = v0.posTrack_as>(); + auto negTrack = v0.negTrack_as>(); // gamma - if (static_cast(posTrack.pidbit() & (1 << 0))) { + if (static_cast(posTrack.pidbit() & (1 << 0)) && static_cast(negTrack.pidbit() & (1 << 0))) { if (downsampleTsalisCharged(posTrack.pt(), downsamplingTsalisElectrons, sqrtSNN, o2::track::pid_constants::sMasses[o2::track::PID::Electron])) { fillSkimmedV0Table(v0, posTrack, collision, posTrack.tpcNSigmaEl(), posTrack.tofNSigmaEl(), posTrack.tpcExpSignalEl(posTrack.tpcSignal()), o2::track::PID::Electron, runnumber, dwnSmplFactor_El); } @@ -189,7 +189,7 @@ struct TreeWriterTpcV0 { } } // Ks0 - if (static_cast(posTrack.pidbit() & (1 << 1))) { + if (static_cast(posTrack.pidbit() & (1 << 1)) && static_cast(negTrack.pidbit() & (1 << 1))) { if (downsampleTsalisCharged(posTrack.pt(), downsamplingTsalisPions, sqrtSNN, o2::track::pid_constants::sMasses[o2::track::PID::Pion])) { fillSkimmedV0Table(v0, posTrack, collision, posTrack.tpcNSigmaPi(), posTrack.tofNSigmaPi(), posTrack.tpcExpSignalPi(posTrack.tpcSignal()), o2::track::PID::Pion, runnumber, dwnSmplFactor_Pi); } @@ -198,7 +198,7 @@ struct TreeWriterTpcV0 { } } // Lambda - if (static_cast(posTrack.pidbit() & (1 << 2))) { + if (static_cast(posTrack.pidbit() & (1 << 2)) && static_cast(negTrack.pidbit() & (1 << 2))) { if (downsampleTsalisCharged(posTrack.pt(), downsamplingTsalisProtons, sqrtSNN, o2::track::pid_constants::sMasses[o2::track::PID::Proton])) { fillSkimmedV0Table(v0, posTrack, collision, posTrack.tpcNSigmaPr(), posTrack.tofNSigmaPr(), posTrack.tpcExpSignalPr(posTrack.tpcSignal()), o2::track::PID::Proton, runnumber, dwnSmplFactor_Pr); } @@ -207,7 +207,7 @@ struct TreeWriterTpcV0 { } } // Antilambda - if (static_cast(posTrack.pidbit() & (1 << 3))) { + if (static_cast(posTrack.pidbit() & (1 << 3)) && static_cast(negTrack.pidbit() & (1 << 3))) { if (downsampleTsalisCharged(posTrack.pt(), downsamplingTsalisPions, sqrtSNN, o2::track::pid_constants::sMasses[o2::track::PID::Pion])) { fillSkimmedV0Table(v0, posTrack, collision, posTrack.tpcNSigmaPi(), posTrack.tofNSigmaPi(), posTrack.tpcExpSignalPi(posTrack.tpcSignal()), o2::track::PID::Pion, runnumber, dwnSmplFactor_Pi); } diff --git a/EventFiltering/PWGCF/CFFilterAll.cxx b/EventFiltering/PWGCF/CFFilterAll.cxx index fb719a02bcf..af82533681a 100644 --- a/EventFiltering/PWGCF/CFFilterAll.cxx +++ b/EventFiltering/PWGCF/CFFilterAll.cxx @@ -139,6 +139,8 @@ static const float MomCorLimits[2][nMomCorCuts] = static const float PIDForTrackingTable[2][nTracks]{ {-1, 0.75}, {-1, 1.2}}; +static const float ITSCutsTable[1][nTracks] = { + {1, 1}}; static const float triggerSwitches[1][nAllTriggers]{ {1, 1, 1, 1, 1, 1}}; @@ -298,13 +300,13 @@ struct CFFilter { "ConfTrkTPCsClsMax", 160, "Maximum number of shared TPC clusters"}; - Configurable ConfTrkITSnclsMin{ + Configurable> ConfTrkITSnclsMin{ "ConfTrkITSnclsMin", - 0, + {CFTrigger::ITSCutsTable[0], 1, CFTrigger::nTracks, std::vector{"Cut"}, CFTrigger::SpeciesName}, "Minimum number of ITS clusters"}; - Configurable ConfTrkITSnclsIbMin{ - "ConfTrkITSnclsIbMin", - 0, + Configurable> ConfTrkITSnclsIBMin{ + "ConfTrkITSnclsIBMin", + {CFTrigger::ITSCutsTable[0], 1, CFTrigger::nTracks, std::vector{"Cut"}, CFTrigger::SpeciesName}, "Minimum number of ITS clusters in the inner barrel"}; Configurable ConfTrkDCAxyMax{ "ConfTrkDCAxyMax", @@ -898,10 +900,10 @@ struct CFFilter { if (tpcNClsS > ConfTrkTPCsClsMax) { return false; } - if (itsNCls < ConfTrkITSnclsMin) { + if (itsNCls < ConfTrkITSnclsMin->get(static_cast(0), partSpecies)) { return false; } - if (itsNClsIB < ConfTrkITSnclsIbMin) { + if (itsNClsIB < ConfTrkITSnclsIBMin->get(static_cast(0), partSpecies)) { return false; } if (std::abs(dcaXY) > ConfTrkDCAxyMax) { diff --git a/EventFiltering/PWGEM/EMPhotonFilter.cxx b/EventFiltering/PWGEM/EMPhotonFilter.cxx index 390646f6140..03c06c6ae84 100644 --- a/EventFiltering/PWGEM/EMPhotonFilter.cxx +++ b/EventFiltering/PWGEM/EMPhotonFilter.cxx @@ -32,8 +32,8 @@ using namespace o2::framework::expressions; using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; -// using MyPrimaryElectrons = soa::Join; -// using MyPrimaryElectron = MyPrimaryElectrons::iterator; +using MyPrimaryElectrons = soa::Join; +using MyPrimaryElectron = MyPrimaryElectrons::iterator; struct EMPhotonFilter { @@ -49,10 +49,7 @@ struct EMPhotonFilter { kPHOS_Pair = 2, kPHOS_Nbar = 3, kPCM_HighPtPhoton = 4, - kPCM_MatCalib = 5, - kPCM_EtaDalitz = 6, - kPCM_EtaGG = 7, - kPCM_EE = 8, + kPCM_EE = 5, kNtrg }; @@ -64,16 +61,33 @@ struct EMPhotonFilter { Configurable nNbar{"nNbar", 2, "Minimal number of nbar clusters"}; // for PCM - Configurable min_pt_tagging{"min_pt_tagging", 0.f, "min. pT for tagging"}; - Configurable max_mee_pi0_dalitz{"max_mee_pi0_dalitz", 0.12, "max. mee for pi0 dalitz decay"}; - Configurable min_meeg_pi0{"min_meeg_pi0", 0.04, "min. meeg for pi0"}; - Configurable max_meeg_pi0{"max_meeg_pi0", 0.24, "max. meeg for pi0"}; - Configurable max_mee_eta_dalitz{"max_mee_eta_dalitz", 0.5, "max. mee for eta dalitz decay"}; - Configurable min_meeg_eta{"min_meeg_eta", 0.35, "min. meeg for eta"}; - Configurable max_meeg_eta{"max_meeg_eta", 0.75, "max. meeg for eta"}; + Configurable minpt_v0{"minpt_v0", 0.1, "min pt for v0"}; + Configurable maxeta_v0{"maxeta_v0", 0.9, "eta acceptance for v0"}; + Configurable min_pt_pcm_photon{"min_pt_pcm_photon", 0.f, "min. pT for PCM photon"}; + Configurable minTPCNsigmaEl_v0{"minTPCNsigmaEl_v0", -3.5, "min. TPC n sigma for electron inclusion"}; + Configurable maxTPCNsigmaEl_v0{"maxTPCNsigmaEl_v0", +3.5, "max. TPC n sigma for electron inclusion"}; + Configurable max_dcatopv_xy_v0{"max_dcatopv_xy_v0", +1e+10, "max. DCAxy to PV for V0"}; + Configurable max_dcatopv_z_v0{"max_dcatopv_z_v0", +1e+10, "max. DCAz to PV for V0"}; + + // for prompt dielectron + Configurable minpt{"minpt", 0.2, "min pt for track"}; + Configurable maxeta{"maxeta", 0.9, "eta acceptance"}; + Configurable dca_3d_sigma_max{"dca_3d_sigma_max", 1.0f, "max DCA 3D in sigma"}; // for single track + Configurable mincrossedrows{"mincrossedrows", 80, "min crossed rows"}; + Configurable minTPCNsigmaEl_primary{"minTPCNsigmaEl_primary", -3.0, "min. TPC n sigma for electron inclusion"}; + Configurable maxTPCNsigmaEl_primary{"maxTPCNsigmaEl_primary", +4.0, "max. TPC n sigma for electron inclusion"}; + Configurable minTOFNsigmaEl_primary{"minTOFNsigmaEl_primary", -4.0, "min. TOF n sigma for electron inclusion"}; // require TOF + Configurable maxTOFNsigmaEl_primary{"maxTOFNsigmaEl_primary", +4.0, "max. TOF n sigma for electron inclusion"}; // require TOF + Configurable minTPCNsigmaPi{"minTPCNsigmaPi", -2.0, "min. TPC n sigma for pion exclusion"}; // set to -2 for lowB, -999 for nominalB + Configurable maxTPCNsigmaPi{"maxTPCNsigmaPi", 2.0, "max. TPC n sigma for pion exclusion"}; + Configurable min_pin_tof{"min_pin_tof", 0.4, "tof is required above this threshold in pin"}; Configurable slope{"slope", 0.0185, "slope for m vs. phiv"}; Configurable intercept{"intercept", -0.0280, "intercept for m vs. phiv"}; - Configurable min_pt_pcm_photon{"min_pt_pcm_photon", 4.f, "min. pT for PCM photon"}; + Configurable min_mee{"min_mee", 0.0, "min. mee"}; + Configurable max_mee{"max_mee", 0.5, "max. mee"}; + Configurable min_meeg{"min_meeg", 0.3, "min. meeg"}; + Configurable max_meeg{"max_meeg", 0.8, "max. meeg"}; + Configurable applyPF{"applyPF", false, "apply pre-filter for primary electron"}; // i.e. reject electron from photon conversion with phiv HistogramRegistry mHistManager{"events", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; @@ -92,14 +106,64 @@ struct EMPhotonFilter { scalers->GetXaxis()->SetBinLabel(10, "PHOS photon & pair"); scalers->GetXaxis()->SetBinLabel(11, "events with PHOS"); scalers->GetXaxis()->SetBinLabel(12, "PCM high p_{T} photon"); - scalers->GetXaxis()->SetBinLabel(13, "PCM Material budget calibration"); - scalers->GetXaxis()->SetBinLabel(14, "PCM #eta #rightarrow ee#gamma"); - scalers->GetXaxis()->SetBinLabel(15, "PCM #eta #rightarrow #gamma#gamma"); - scalers->GetXaxis()->SetBinLabel(16, "PCM DalitzEE #gamma-#gamma^{*} BEC"); + scalers->GetXaxis()->SetBinLabel(13, "PCM #gamma and dielectron"); + } + + template + bool isSelectedSecondary(TTrack const& track) + { + if (track.hasTPC() && (track.tpcNSigmaEl() < minTPCNsigmaEl_v0 || maxTPCNsigmaEl_v0 < track.tpcNSigmaEl())) { + return false; + } + return true; + } + template + bool isSelectedPrimary(TTrack const& track) + { + if (!track.hasITS() || !track.hasTPC()) { + return false; + } + + if (track.pt() < minpt || abs(track.eta()) > maxeta) { + return false; + } + + if (track.tpcNClsCrossedRows() < mincrossedrows) { + return false; + } + + if (track.tpcNSigmaEl() < minTPCNsigmaEl_primary || maxTPCNsigmaEl_primary < track.tpcNSigmaEl()) { + return false; + } + + if ((track.tofNSigmaEl() < minTOFNsigmaEl_primary || maxTOFNsigmaEl_primary < track.tofNSigmaEl()) && track.tpcInnerParam() > min_pin_tof) { + return false; + } + + if (minTPCNsigmaPi < track.tpcNSigmaPi() && track.tpcNSigmaPi() < maxTPCNsigmaPi) { + return false; + } + + if (applyPF && track.pfb() > 0) { + return false; + } + + float dca_3d = 999.f; + float det = track.cYY() * track.cZZ() - track.cZY() * track.cZY(); + if (det < 0) { + 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.); + } + if (dca_3d > dca_3d_sigma_max) { + return false; + } + return true; } Preslice perCollision_pcm = aod::v0photonkf::collisionId; - // Preslice perCollision_ee = aod::dalitzee::collisionId; + Preslice perCollision_ee = aod::dalitzee::collisionId; Preslice perCollision_phos = aod::calocluster::collisionId; // Preslice perCollision_emc = aod::skimmedcluster::collisionId; @@ -122,9 +186,14 @@ struct EMPhotonFilter { if constexpr (static_cast(system & EM_Filter_PhotonType::kPCM)) { auto photons1_per_coll = photons1.sliceBy(perCollision_pcm, collision.globalIndex()); - // auto dielectrons_per_coll = dielectrons.sliceBy(perCollision_ee, collision.globalIndex()); + auto dielectrons_per_coll = dielectrons.sliceBy(perCollision_ee, collision.globalIndex()); for (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)) { + continue; + } if (v0photon.pt() > min_pt_pcm_photon) { keepEvent[kPCM_HighPtPhoton] = true; mHistManager.fill(HIST("hEventCounter"), 12); @@ -132,67 +201,34 @@ struct EMPhotonFilter { } } // end of single v0 photon loop - // for (auto& [g1, g2] : combinations(CombinationsFullIndexPolicy(photons1_per_coll, dielectrons_per_coll))) { - // if (g2.pt() < min_pt_tagging) { // this is only to increase rejection factor - // continue; - // } - // if (g2.mass() > max_mee_pi0_dalitz) { // select only pi0 candidates - // continue; - // } - // if (g2.mass() < slope * g2.phiv() + intercept) { - // continue; - // } - // ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); - // ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), g2.mass()); - // ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - - // if (min_meeg_pi0 < v12.M() && v12.M() < max_meeg_pi0) { - // keepEvent[kPCM_MatCalib] = true; - // mHistManager.fill(HIST("hEventCounter"), 13); - // break; - // } - - // } // end of dielectron-photon pair loop - - // for (auto& [g1, g2] : combinations(CombinationsFullIndexPolicy(photons1_per_coll, dielectrons_per_coll))) { - // if (g2.mass() > max_mee_eta_dalitz) { // select only eta candidates - // continue; - // } - // if (g2.mass() < slope * g2.phiv() + intercept) { - // continue; - // } - - // ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); - // ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), g2.mass()); - // ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - - // if (min_meeg_eta < v12.M() && v12.M() < max_meeg_eta) { // eta -> eeg - // keepEvent[kPCM_EtaDalitz] = true; - // mHistManager.fill(HIST("hEventCounter"), 14); - // break; - // } - // } // end of dielectron-photon pair loop - - // for (auto& [g1, g2] : combinations(CombinationsStrictlyUpperIndexPolicy(photons1_per_coll, photons1_per_coll))) { - // ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); - // ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); - // ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - - // if (min_meeg_eta < v12.M() && v12.M() < max_meeg_eta) { // eta -> gg - // keepEvent[kPCM_EtaGG] = true; - // mHistManager.fill(HIST("hEventCounter"), 15); - // break; - // } - // } // end of photon-photon pair loop - - // for (auto& [g1, g2] : combinations(CombinationsFullIndexPolicy(photons1_per_coll, dielectrons_per_coll))) { - // if (g2.mass() < slope * g2.phiv() + intercept) { - // continue; - // } - // keepEvent[kPCM_EE] = true; - // mHistManager.fill(HIST("hEventCounter"), 16); - // break; - // } // end of dielectron-photon pair loop + for (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)) { + continue; + } + + auto pos_pv = g2.template posTrack_as(); + auto ele_pv = g2.template negTrack_as(); + if (!isSelectedPrimary(pos_pv) || !isSelectedPrimary(ele_pv)) { + continue; + } + if (g2.mass() < min_mee || max_mee < g2.mass()) { + continue; + } + if (g2.mass() < slope * g2.phiv() + intercept) { + continue; + } + + ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); + ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), g2.mass()); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + if (min_meeg < v12.M() && v12.M() < max_meeg) { + keepEvent[kPCM_EE] = true; + mHistManager.fill(HIST("hEventCounter"), 13); + break; + } + } // end of photon + dielectron pair loop } // end of PCM decision @@ -264,19 +300,25 @@ struct EMPhotonFilter { // if constexpr (static_cast(system & EM_Filter_PhotonType::kEMC)) { // // so far, do nothing. // } - tags(keepEvent[kPHOS_Photon], keepEvent[kPHOS_Nbar], keepEvent[kPCM_HighPtPhoton]); + + tags(keepEvent[kPHOS_Photon], keepEvent[kPHOS_Nbar], keepEvent[kPCM_HighPtPhoton], keepEvent[kPCM_EE]); } // end of collision loop } - // void process_PCM(MyCollisions const& collisions, aod::V0PhotonsKF const& v0photons, aod::V0Legs const& v0legs, aod::DalitzEEs const& dielectrons, MyPrimaryElectrons const& emprimaryelectrons) - void process_PCM(MyCollisions const& collisions, aod::V0PhotonsKF const& v0photons, aod::V0Legs const& v0legs) + 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) { const uint8_t system = EM_Filter_PhotonType::kPCM; - runFilter(collisions, v0photons, nullptr, nullptr, v0legs, nullptr, nullptr); + runFilter(collisions, v0photons, nullptr, nullptr, v0legs, dielectrons, emprimaryelectrons); } Filter phosCluFilter = (o2::aod::calocluster::e > 0.3f); - using CluCandidates = o2::soa::Filtered; + using CluCandidates = Filtered; void process_PHOS(MyCollisions const& collisions, CluCandidates const& clusters) { const uint8_t system = EM_Filter_PhotonType::kPHOS; @@ -289,18 +331,16 @@ struct EMPhotonFilter { runFilter(collisions, nullptr, nullptr, clusters, nullptr, nullptr, nullptr); } - // void process_PCM_PHOS(MyCollisions const& collisions, aod::V0PhotonsKF const& v0photons, aod::V0Legs const& v0legs, aod::DalitzEEs const& dielectrons, MyPrimaryElectrons const& emprimaryelectrons, CluCandidates const& clusters) - void process_PCM_PHOS(MyCollisions const& collisions, aod::V0PhotonsKF const& v0photons, aod::V0Legs const& v0legs, CluCandidates const& clusters) + void process_PCM_PHOS(MyCollisions const& collisions, filteredV0PhotonsKF 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); - runFilter(collisions, v0photons, clusters, nullptr, v0legs, nullptr, nullptr); + runFilter(collisions, v0photons, clusters, nullptr, v0legs, dielectrons, emprimaryelectrons); } void processDummy(MyCollisions const& collisions) { for (int i = 0; i < collisions.size(); i++) { - tags(false, false, false); + tags(false, false, false, false); } } diff --git a/EventFiltering/PWGEM/EMPhotonFilterQC.cxx b/EventFiltering/PWGEM/EMPhotonFilterQC.cxx index 65a0cbbce47..92ee1cd5c30 100644 --- a/EventFiltering/PWGEM/EMPhotonFilterQC.cxx +++ b/EventFiltering/PWGEM/EMPhotonFilterQC.cxx @@ -44,35 +44,25 @@ struct EMPhotonFilterQC { void addhistograms() { - auto hEventCounter = registry.add("hEventCounter", "hEventCounter", kTH1F, {{20, 0.5f, 20.5f}}); + auto hEventCounter = registry.add("hEventCounter", "hEventCounter", kTH1F, {{10, 0.5f, 10.5f}}); hEventCounter->GetXaxis()->SetBinLabel(1, "all"); hEventCounter->GetXaxis()->SetBinLabel(2, "sel8 && |Z_{vtx}| < 10 cm"); hEventCounter->GetXaxis()->SetBinLabel(3, "PCM High p_{T} photon"); hEventCounter->GetXaxis()->SetBinLabel(4, "PCM High p_{T} photon && sel8 && |Z_{vtx}| < 10 cm"); - hEventCounter->GetXaxis()->SetBinLabel(5, "PCM MB calibration"); - hEventCounter->GetXaxis()->SetBinLabel(6, "PCM MB calibration && sel8 && |Z_{vtx}| < 10 cm"); - hEventCounter->GetXaxis()->SetBinLabel(7, "PCM #eta #rightarrow ee#gamma"); - hEventCounter->GetXaxis()->SetBinLabel(8, "PCM #eta #rightarrow ee#gamma && sel8 && |Z_{vtx}| < 10 cm"); - hEventCounter->GetXaxis()->SetBinLabel(9, "PCM #eta #rightarrow #gamma#gamma"); - hEventCounter->GetXaxis()->SetBinLabel(10, "PCM #eta #rightarrow #gamma#gamma && sel8 && |Z_{vtx}| < 10 cm"); - hEventCounter->GetXaxis()->SetBinLabel(11, "PCM and ee"); - hEventCounter->GetXaxis()->SetBinLabel(12, "PCM and ee && sel8 && |Z_{vtx}| < 10 cm"); + hEventCounter->GetXaxis()->SetBinLabel(5, "PCM and dielectron"); + hEventCounter->GetXaxis()->SetBinLabel(6, "PCM and dielectron && sel8 && |Z_{vtx}| < 10 cm"); registry.add("PCM_HighPt/hPt", "pT of PCM photon;p_{T,#gamma} (GeV/c)", kTH1F, {{200, 0, 20}}); registry.add("PCM_HighPt/hEtaPhi", "#eta vs. #varphi of PCM photon", kTH2F, {{72, 0, TMath::TwoPi()}, {40, -2, +2}}); - registry.add("PCM_MBCalib/hMeePt", "mass ee#gamma;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c)", kTH2F, {{50, 0.f, 0.5f}, {100, 0, 10}}); - registry.add("PCM_MBCalib/hMeegPt", "mass ee#gamma;m_{ee#gamma} (GeV/c^{2});p_{T,#gamma} (GeV/c)", kTH2F, {{200, 0.f, 0.4f}, {100, 0, 10}}); - registry.add("PCM_EtaDalitz/hMeePt", "mass ee;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c)", kTH2F, {{400, 0.f, 4.f}, {100, 0, 10}}); - registry.add("PCM_EtaDalitz/hMeegPt", "mass ee#gamma;m_{ee#gamma} (GeV/c^{2});p_{T,ee#gamma} (GeV/c)", kTH2F, {{400, 0.f, 0.8f}, {100, 0, 10}}); - registry.add("PCM_EtaGG/hMggPt", "mass ee#gamma;m_{#gamma#gamma} (GeV/c^{2});p_{T,#gamma#gamma} (GeV/c)", kTH2F, {{400, 0.f, 0.8f}, {100, 0, 10}}); registry.add("PCM_EE/hMeePt", "mass ee;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c)", kTH2F, {{400, 0.f, 4.f}, {100, 0, 10}}); + registry.add("PCM_EE/hMeePhiV", "mass ee;#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", kTH2F, {{180, 0.f, TMath::Pi()}, {100, 0, 0.1}}); + registry.add("PCM_EE/hTPCdEdx", "n sigma TPC el vs. pin;p_{in} (GeV/c);n #sigma_{e}^{TPC}", kTH2F, {{1000, 0.f, 10.f}, {100, -5, 5}}); registry.add("PCM_EE/hMeegPt", "mass ee#gamma;m_{ee#gamma} (GeV/c^{2});p_{T,ee#gamma} (GeV/c)", kTH2F, {{400, 0.f, 0.8f}, {100, 0, 10}}); } Preslice perCollision_pcm = aod::v0photonkf::collisionId; - // Preslice perCollision_ee = aod::dalitzee::collisionId; - // void processPCM(MyCollisions const& collisions, aod::V0PhotonsKF const& v0photons, aod::DalitzEEs const& dielectrons) - void processPCM(MyCollisions const& collisions, aod::V0PhotonsKF const& v0photons) + Preslice perCollision_ee = aod::dalitzee::collisionId; + void processPCM(MyCollisions const& collisions, aod::V0PhotonsKF const& v0photons, aod::V0Legs const&, aod::DalitzEEs const& dielectrons, aod::EMPrimaryElectrons const&) { for (auto& collision : collisions) { registry.fill(HIST("hEventCounter"), 1); @@ -80,7 +70,7 @@ struct EMPhotonFilterQC { registry.fill(HIST("hEventCounter"), 2); } auto v0photons_coll = v0photons.sliceBy(perCollision_pcm, collision.globalIndex()); - // auto dielectrons_coll = dielectrons.sliceBy(perCollision_ee, collision.globalIndex()); + auto dielectrons_coll = dielectrons.sliceBy(perCollision_ee, collision.globalIndex()); if (collision.hasPCMHighPtPhoton()) { registry.fill(HIST("hEventCounter"), 3); @@ -93,65 +83,27 @@ struct EMPhotonFilterQC { } // end of v0 photon loop } - // if (collision.hasPCMMatCalib()) { - // registry.fill(HIST("hEventCounter"), 5); - // if (collision.sel8() && abs(collision.posZ()) < 10.f) { - // registry.fill(HIST("hEventCounter"), 6); - // } - // for (auto& [g1, g2] : combinations(CombinationsFullIndexPolicy(v0photons_coll, dielectrons_coll))) { - // registry.fill(HIST("PCM_MBCalib/hMeePt"), g2.mass(), g2.pt()); - // ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); - // ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), g2.mass()); - // ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - // registry.fill(HIST("PCM_MBCalib/hMeegPt"), v12.M(), g1.pt()); - // } // end of dielectron-photon pair loop - // } - - // if (collision.hasPCMEtaDalitz()) { - // registry.fill(HIST("hEventCounter"), 7); - // if (collision.sel8() && abs(collision.posZ()) < 10.f) { - // registry.fill(HIST("hEventCounter"), 8); - // } - // for (auto& dielectron : dielectrons_coll) { - // registry.fill(HIST("PCM_EtaDalitz/hMeePt"), dielectron.mass(), dielectron.pt()); - // } - // for (auto& [g1, g2] : combinations(CombinationsFullIndexPolicy(v0photons_coll, dielectrons_coll))) { - // ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); - // ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), g2.mass()); - // ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - // registry.fill(HIST("PCM_EtaDalitz/hMeegPt"), v12.M(), v12.Pt()); - // } // end of dielectron-photon pair loop - // } - - // if (collision.hasPCMEtaGG()) { - // registry.fill(HIST("hEventCounter"), 9); - // if (collision.sel8() && abs(collision.posZ()) < 10.f) { - // registry.fill(HIST("hEventCounter"), 10); - // } - // for (auto& [g1, g2] : combinations(CombinationsStrictlyUpperIndexPolicy(v0photons_coll, v0photons_coll))) { - // ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); - // ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); - // ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - // registry.fill(HIST("PCM_EtaGG/hMggPt"), v12.M(), v12.Pt()); - // } // end of dielectron-photon pair loop - // } - - // if (collision.hasPCMandEE()) { - // registry.fill(HIST("hEventCounter"), 11); - // if (collision.sel8() && abs(collision.posZ()) < 10.f) { - // registry.fill(HIST("hEventCounter"), 12); - // } - - // for (auto& dielectron : dielectrons_coll) { - // registry.fill(HIST("PCM_EE/hMeePt"), dielectron.mass(), dielectron.pt()); - // } - // for (auto& [g1, g2] : combinations(CombinationsFullIndexPolicy(v0photons_coll, dielectrons_coll))) { - // ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); - // ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), g2.mass()); - // ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; - // registry.fill(HIST("PCM_EE/hMeegPt"), v12.M(), v12.Pt()); - // } // end of dielectron-photon pair loop - // } + if (collision.hasPCMandEE()) { + registry.fill(HIST("hEventCounter"), 5); + if (collision.sel8() && abs(collision.posZ()) < 10.f) { + registry.fill(HIST("hEventCounter"), 6); + } + + for (auto& dielectron : dielectrons_coll) { + registry.fill(HIST("PCM_EE/hMeePt"), dielectron.mass(), dielectron.pt()); + registry.fill(HIST("PCM_EE/hMeePhiV"), dielectron.phiv(), dielectron.mass()); + auto pos_pv = dielectron.template posTrack_as(); + auto ele_pv = dielectron.template negTrack_as(); + registry.fill(HIST("PCM_EE/hTPCdEdx"), pos_pv.tpcInnerParam(), pos_pv.tpcNSigmaEl()); + registry.fill(HIST("PCM_EE/hTPCdEdx"), ele_pv.tpcInnerParam(), ele_pv.tpcNSigmaEl()); + } + for (auto& [g1, g2] : combinations(CombinationsFullIndexPolicy(v0photons_coll, dielectrons_coll))) { + ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); + ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), g2.mass()); + ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; + registry.fill(HIST("PCM_EE/hMeegPt"), v12.M(), v12.Pt()); + } // end of dielectron-photon pair loop + } } // end of collision loop } diff --git a/EventFiltering/PWGHF/HFFilter.cxx b/EventFiltering/PWGHF/HFFilter.cxx index 32cb1ca6c99..5f68e58fdf0 100644 --- a/EventFiltering/PWGHF/HFFilter.cxx +++ b/EventFiltering/PWGHF/HFFilter.cxx @@ -106,6 +106,8 @@ struct HfFilter { // Main struct for HF triggers Configurable onnxFileXicToPiKPConf{"onnxFileXicToPiKPConf", "", "ONNX file for ML model for Xic+ candidates"}; Configurable> thresholdBDTScoreXicToPiKP{"thresholdBDTScoreXicToPiKP", {hf_cuts_bdt_multiclass::cuts[0], hf_cuts_bdt_multiclass::nBinsPt, hf_cuts_bdt_multiclass::nCutBdtScores, hf_cuts_bdt_multiclass::labelsPt, hf_cuts_bdt_multiclass::labelsCutBdt}, "Threshold values for BDT output scores of Xic+ candidates"}; + Configurable acceptBdtBkgOnly{"acceptBdtBkgOnly", true, "Enable / disable selection based on BDT bkg score only"}; + // CCDB configuration o2::ccdb::CcdbApi ccdbApi; Service ccdb; @@ -411,9 +413,9 @@ struct HfFilter { // Main struct for HF triggers hBDTScoreNonPrompt[kD0]->Fill(scoresToFill[2]); } - isSignalTagged = TESTBIT(tagBDT, RecoDecay::OriginType::None); isCharmTagged = TESTBIT(tagBDT, RecoDecay::OriginType::Prompt); isBeautyTagged = TESTBIT(tagBDT, RecoDecay::OriginType::NonPrompt); + isSignalTagged = acceptBdtBkgOnly ? TESTBIT(tagBDT, RecoDecay::OriginType::None) : (isCharmTagged || isBeautyTagged); } if (!isSignalTagged) { @@ -734,9 +736,9 @@ struct HfFilter { // Main struct for HF triggers LOG(error) << "Error running model inference for " << charmParticleNames[iCharmPart + 1].data() << ": Unexpected input data type."; } - isSignalTagged[iCharmPart] = TESTBIT(tagBDT, RecoDecay::OriginType::None); isCharmTagged[iCharmPart] = TESTBIT(tagBDT, RecoDecay::OriginType::Prompt); isBeautyTagged[iCharmPart] = TESTBIT(tagBDT, RecoDecay::OriginType::NonPrompt); + isSignalTagged[iCharmPart] = acceptBdtBkgOnly ? TESTBIT(tagBDT, RecoDecay::OriginType::None) : (isCharmTagged[iCharmPart] || isBeautyTagged[iCharmPart]); if (activateQA > 1) { hBDTScoreBkg[iCharmPart + 1]->Fill(scoresToFill[iCharmPart][0]); diff --git a/EventFiltering/filterTables.h b/EventFiltering/filterTables.h index 1dfd08cc23f..5493f5c3b65 100644 --- a/EventFiltering/filterTables.h +++ b/EventFiltering/filterTables.h @@ -113,7 +113,7 @@ DECLARE_SOA_COLUMN(PCMHighPtPhoton, hasPCMHighPtPhoton, bool); //! PCM high pT p // DECLARE_SOA_COLUMN(PCMMatCalib, hasPCMMatCalib, bool); //! PCM material budget calibration // DECLARE_SOA_COLUMN(PCMEtaDalitz, hasPCMEtaDalitz, bool); //! PCM eta -> ee gamma // DECLARE_SOA_COLUMN(PCMEtaGG, hasPCMEtaGG, bool); //! PCM eta -> ee gamma -// DECLARE_SOA_COLUMN(PCMandEE, hasPCMandEE, bool); //! PCM and ee +DECLARE_SOA_COLUMN(PCMandEE, hasPCMandEE, bool); //! PCM and ee } // namespace filtering namespace decision @@ -196,7 +196,7 @@ using MultFilter = MultFilters::iterator; // photons DECLARE_SOA_TABLE(PhotonFilters, "AOD", "PhotonFilters", //! - filtering::PHOSPhoton, filtering::PHOSnbar, filtering::PCMHighPtPhoton); + filtering::PHOSPhoton, filtering::PHOSnbar, filtering::PCMHighPtPhoton, filtering::PCMandEE); using PhotonFilter = PhotonFilters::iterator; diff --git a/PWGCF/DataModel/CorrelationsDerived.h b/PWGCF/DataModel/CorrelationsDerived.h index 5f88fc15c6f..2542a2e416a 100644 --- a/PWGCF/DataModel/CorrelationsDerived.h +++ b/PWGCF/DataModel/CorrelationsDerived.h @@ -8,8 +8,8 @@ // 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 O2_ANALYSIS_CFDERIVED_H -#define O2_ANALYSIS_CFDERIVED_H +#ifndef PWGCF_DATAMODEL_CORRELATIONSDERIVED_H_ +#define PWGCF_DATAMODEL_CORRELATIONSDERIVED_H_ #include "Framework/ASoA.h" #include "Framework/AnalysisDataModel.h" @@ -79,6 +79,42 @@ using CFTrack = CFTracks::iterator; using CFTrackLabel = CFTrackLabels::iterator; using CFTracksWithLabel = soa::Join; 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 + +using CFCollRef = CFCollRefs::iterator; + +namespace cftrackref +{ +DECLARE_SOA_INDEX_COLUMN(Track, track); +} // namespace cftrackref +DECLARE_SOA_TABLE(CFTrackRefs, "AOD", "CFTRACKREF", o2::soa::Index<>, track::CollisionId, cftrackref::TrackId); //! Transient cf track index table + +using CFTrackRef = CFTrackRefs::iterator; +//------ + +namespace cf2prongtrack +{ +DECLARE_SOA_INDEX_COLUMN_FULL(CFTrackProng0, cfTrackProng0, int, CFTracks, "_0"); //! Index to prong 1 CFTrack +DECLARE_SOA_INDEX_COLUMN_FULL(CFTrackProng1, cfTrackProng1, int, CFTracks, "_1"); //! Index to prong 2 CFTrack +DECLARE_SOA_COLUMN(Pt, pt, float); //! pT (GeV/c) +DECLARE_SOA_COLUMN(Eta, eta, float); //! Pseudorapidity +DECLARE_SOA_COLUMN(Phi, phi, float); //! Phi angle +DECLARE_SOA_COLUMN(Decay, decay, uint8_t); //! Particle decay +enum ParticleDecay { + D0ToPiK, + JPsiToEE, + JPsiToMuMu +}; +} // namespace cf2prongtrack +DECLARE_SOA_TABLE(CF2ProngTracks, "AOD", "CF2PRONGTRACK", //! Reduced track table + o2::soa::Index<>, + cftrack::CFCollisionId, + cf2prongtrack::CFTrackProng0Id, + cf2prongtrack::CFTrackProng1Id, + cf2prongtrack::Pt, cf2prongtrack::Eta, cf2prongtrack::Phi, cf2prongtrack::Decay); +using CF2ProngTrack = CF2ProngTracks::iterator; } // namespace o2::aod -#endif // O2_ANALYSIS_CFDERIVED_H +#endif // PWGCF_DATAMODEL_CORRELATIONSDERIVED_H_ diff --git a/PWGCF/DataModel/FemtoDerived.h b/PWGCF/DataModel/FemtoDerived.h index 989405e5239..ef837eb5f61 100644 --- a/PWGCF/DataModel/FemtoDerived.h +++ b/PWGCF/DataModel/FemtoDerived.h @@ -27,6 +27,14 @@ namespace o2::aod /// FemtoDreamCollision namespace femtodreamcollision { +// Define different methods for the event mixing +enum CollisionBinning { + kMult, //! Bin collision in number of charged tracks for mixing + kMultPercentile, //! Bin collision in multiplicity percentile for mixing + kMultMultPercentile, //! Bin collision in number of charged tracks and multiplicity percentile for mixing + kNCollisionBinning +}; + DECLARE_SOA_COLUMN(MultV0M, multV0M, float); //! V0M multiplicity DECLARE_SOA_COLUMN(MultNtr, multNtr, int); //! multiplicity of charged tracks as defined in the producer DECLARE_SOA_COLUMN(Sphericity, sphericity, float); //! Sphericity of the event @@ -37,6 +45,8 @@ using BitMaskType = uint32_t; //! Definition of the data type for the collision DECLARE_SOA_COLUMN(BitMaskTrackOne, bitmaskTrackOne, BitMaskType); //! Bit for track one DECLARE_SOA_COLUMN(BitMaskTrackTwo, bitmaskTrackTwo, BitMaskType); //! Bit for track two DECLARE_SOA_COLUMN(BitMaskTrackThree, bitmaskTrackThree, BitMaskType); //! Bit for track three + +DECLARE_SOA_COLUMN(Downsample, downsample, bool); //! Flag for downsampling } // namespace femtodreamcollision DECLARE_SOA_TABLE(FDCollisions, "AOD", "FDCOLLISION", @@ -53,6 +63,9 @@ DECLARE_SOA_TABLE(FDColMasks, "AOD", "FDCOLMASK", femtodreamcollision::BitMaskTrackTwo, femtodreamcollision::BitMaskTrackThree); +DECLARE_SOA_TABLE(FDDownSample, "AOD", "FDDOWNSAMPLE", + femtodreamcollision::Downsample); + /// FemtoDreamTrack namespace femtodreamparticle { diff --git a/PWGCF/EbyEFluctuations/Tasks/CMakeLists.txt b/PWGCF/EbyEFluctuations/Tasks/CMakeLists.txt index 3c389200fbd..03cdbab35f8 100644 --- a/PWGCF/EbyEFluctuations/Tasks/CMakeLists.txt +++ b/PWGCF/EbyEFluctuations/Tasks/CMakeLists.txt @@ -15,7 +15,7 @@ o2physics_add_dpl_workflow(meanpt-fluctuations COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(mean-pt-fluc-id - SOURCES EbyEmeanPtFlucIdentified.cxx + SOURCES MeanPtFlucIdentified.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore COMPONENT_NAME Analysis) @@ -23,3 +23,8 @@ o2physics_add_dpl_workflow(netproton-cumulants SOURCES NetProtonCumulants.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(identified-meanpt-fluctuations + SOURCES IdentifiedMeanPtFluctuations.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/EbyEFluctuations/Tasks/EbyEmeanPtFlucIdentified.cxx b/PWGCF/EbyEFluctuations/Tasks/EbyEmeanPtFlucIdentified.cxx deleted file mode 100644 index 8721b374e9d..00000000000 --- a/PWGCF/EbyEFluctuations/Tasks/EbyEmeanPtFlucIdentified.cxx +++ /dev/null @@ -1,777 +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 EbyEmeanPtFluc.cxx -/// \brief Calculate EbyE fluctuations with cummulant method. -/// For charged particles and identified particles. -/// -/// \author Tanu Gahlaut - -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/PIDResponse.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/Centrality.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/HistogramSpec.h" -#include "TDatabasePDG.h" -#include "TLorentzVector.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; - -double massPi = TDatabasePDG::Instance()->GetParticle(211)->Mass(); -double massKa = TDatabasePDG::Instance()->GetParticle(321)->Mass(); -double massPr = TDatabasePDG::Instance()->GetParticle(2212)->Mass(); - -struct meanPtFlucId { - Configurable ptMax{"ptMax", 2.0, "maximum pT"}; - Configurable ptMin{"ptMin", 0.15, "minimum pT"}; - Configurable etaCut{"etaCut", 0.8, "Eta cut"}; - Configurable rapCut{"rapCut", 0.5, "Rapidity Cut"}; - Configurable dcaXYCut{"dcaXYCut", 0.12, "DCAxy cut"}; - Configurable dcaZCut{"dcaZCut", 1.0, "DCAz cut"}; - Configurable posZCut{"posZCut", 7.0, "cut for vertex Z"}; - Configurable nSigCut1{"nSigCut1", 1.0, "nSigma cut (1)"}; - Configurable nSigCut2{"nSigCut2", 2.0, "nSigma cut (2)"}; - Configurable nSigCut3{"nSigCut3", 3.0, "nSigma cut (3)"}; - Configurable nSigCut4{"nSigCut4", 4.0, "nSigma cut (4)"}; - Configurable nSigCut5{"nSigCut5", 5.0, "nSigma cut (5)"}; - Configurable nSigCut15{"nSigCut15", 1.5, "nSigma cut (1.5)"}; - Configurable nSigCut25{"nSigCut25", 2.5, "nSigma cut (2.5)"}; - Configurable piP1{"piP1", 0.65, "pion p (1)"}; - Configurable piP2{"piP2", 0.70, "pion p (2)"}; - Configurable piP3{"piP3", 1.40, "pion p (3)"}; - Configurable piP4{"piP4", 1.70, "pion p (4)"}; - Configurable kaP1{"kaP1", 0.20, "min kaon p (1)"}; - Configurable kaP2{"kaP2", 0.5, "kaon p (2)"}; - Configurable kaP3{"kaP3", 0.55, "kaon p (3)"}; - Configurable kaP4{"kaP4", 0.60, "kaon p (4)"}; - Configurable kaP5{"kaP5", 0.65, "kaon p (5)"}; - Configurable kaP6{"kaP6", 1.10, "kaon p (6)"}; - Configurable kaP7{"kaP7", 1.28, "kaon p (7)"}; - Configurable kaP8{"kaP8", 1.50, "kaon p (8)"}; - Configurable prP1{"prP1", 0.40, "min proton p (1)"}; - Configurable prP2{"prP2", 0.95, "proton p (2)"}; - Configurable prP3{"prP3", 1.00, "proton p (3)"}; - Configurable prP4{"prP4", 1.05, "proton p (4)"}; - Configurable prP5{"prP5", 1.13, "proton p (5)"}; - Configurable prP6{"prP6", 1.18, "proton p (6)"}; - - using MyAllTracks = soa::Join; - using MyAllCollisions = soa::Join; - - Filter collisionZFilter = nabs(aod::collision::posZ) < posZCut; - Filter collisionTrigger = o2::aod::evsel::sel8 == true; - Filter trackDCA = nabs(aod::track::dcaXY) < dcaXYCut && nabs(aod::track::dcaZ) < dcaZCut; - Filter trackEta = nabs(aod::track::eta) < etaCut; - Filter trackPt = aod::track::pt > ptMin&& aod::track::pt < ptMax; - Filter trackGobal = requireGlobalTrackInFilter(); - // Filter trackGobal = requirePrimaryTracksInFilter(); - using MyFilteredTracks = soa::Filtered; - using MyFilteredCollisions = soa::Filtered; - - HistogramRegistry hist{"hist", {}, OutputObjHandlingPolicy::AnalysisObject}; - void init(InitContext const&) - { - const AxisSpec axisEvents{5, 0, 5, "Counts"}; - const AxisSpec axisEta{100, -1., +1., "#eta"}; - const AxisSpec axisY{100, -1., +1., "Rapidity"}; - const AxisSpec axisPt{300, 0., 3., "p_{T} (GeV/c)"}; - const AxisSpec axisP{300, 0., 3., "p (GeV/c)"}; - const AxisSpec axisPart{500, 0., 5., " "}; - const AxisSpec axisMeanPt{100, 0., 3., "M(p_{T}) (GeV/c)"}; - const AxisSpec axisMult{100, 0, 100, "N_{ch}"}; - const AxisSpec axisMultTPC{200, 0, 800, "N_{TPC} "}; - const AxisSpec axisMultFT0M{150, 0, 15000, "N_{FT0M}"}; - const AxisSpec axisCentFT0M{50, 0, 101, "FT0M (%)"}; - const AxisSpec axisVtxZ{80, -20., 20., "V_{Z} (cm)"}; - const AxisSpec axisDCAz{100, -1.2, 1.2, "DCA_{Z} (cm)"}; - const AxisSpec axisDCAxy{100, -0.15, 0.15, "DCA_{XY} (cm)"}; - const AxisSpec axisTPCNsigma{500, -5., 5., "n #sigma_{TPC}"}; - const AxisSpec axisTOFNsigma{500, -5., 5., "n #sigma_{TOF}"}; - const AxisSpec axisTPCSignal{180, 20., 200., "#frac{dE}{dx}"}; - const AxisSpec axisTOFSignal{100, 0.2, 1.2, "TOF #beta"}; - const AxisSpec axisChi2{50, 0., 50., "Chi2"}; - const AxisSpec axisCrossedTPC{500, 0, 500, "Crossed TPC"}; - - // QA checks: - hist.add("QA/before/h_Counts", "Counts before cuts", kTH1D, {axisEvents}); - hist.add("QA/before/h_VtxZ", "V_{Z}", kTH1D, {axisVtxZ}); - - hist.add("QA/before/h_TPCChi2perCluster", "TPC #Chi^{2}/Cluster", kTH1D, {axisChi2}); - hist.add("QA/before/h_ITSChi2perCluster", "ITS #Chi^{2}/Cluster", kTH1D, {axisChi2}); - hist.add("QA/before/h_crossedTPC", "Crossed TPC", kTH1D, {axisCrossedTPC}); - - hist.add("QA/before/Charged/h_Eta_ch", "#eta Charged Particles", kTH1D, {axisEta}); - hist.add("QA/before/Charged/h_Pt_ch", "p_{T} Charged Particles", kTH1D, {axisPt}); - hist.add("QA/before/Charged/h2_DcaZ_ch", "DCA_{Z}", kTH2D, {{axisPt}, {axisDCAz}}); - hist.add("QA/before/Charged/h2_DcaXY_ch", "DCA_{XY}", kTH2D, {{axisPt}, {axisDCAxy}}); - - hist.add("QA/before/h2_TPCSignal_b", "TPC Signal (before)", kTH2D, {{axisP}, {axisTPCSignal}}); - hist.add("QA/before/h2_TOFSignal_b", "TOF Signal (before)", kTH2D, {{axisP}, {axisTOFSignal}}); - - hist.add("QA/before/Pion/h2_TPCNsigma_pi", "n #sigma_{TPC} (Pions)", - kTH2D, {{axisP}, {axisTPCNsigma}}); - hist.add("QA/before/Pion/h2_TOFNsigma_pi", "n #sigma_{TOF} (Pions)", - kTH2D, {{axisP}, {axisTOFNsigma}}); - hist.add("QA/before/Pion/h2_TpcTofNsigma_pi", "n #sigma_{TPC} vs n #sigma_{TOF} (Pions)", - kTH2D, {{{axisTPCNsigma}, {axisTOFNsigma}}}); - hist.add("QA/before/Kaon/h2_TPCNsigma_ka", "n #sigma_{TPC} Kaons", - kTH2D, {{axisP}, {axisTPCNsigma}}); - hist.add("QA/before/Kaon/h2_TOFNsigma_ka", "n #sigma_{TOF} Kaons", - kTH2D, {{axisP}, {axisTOFNsigma}}); - hist.add("QA/before/Kaon/h2_TpcTofNsigma_ka", "N_{TPC} igma vs n #sigma_{TOF} Kaons", - kTH2D, {{{axisTPCNsigma}, {axisTOFNsigma}}}); - hist.add("QA/before/Proton/h2_TPCNsigma_pr", "n #sigma_{TPC} Protons", - kTH2D, {{axisP}, {axisTPCNsigma}}); - hist.add("QA/before/Proton/h2_TOFNsigma_pr", "n #sigma_{TOF} Protons", - kTH2D, {{axisP}, {axisTOFNsigma}}); - hist.add("QA/before/Proton/h2_TpcTofNsigma_pr", "n #sigma_{TPC} vs n #sigma_{TOF} Protons", - kTH2D, {{{axisTPCNsigma}, {axisTOFNsigma}}}); - - // after - hist.add("QA/after/h_Counts", "Counts after cuts", kTH1D, {axisEvents}); - hist.add("QA/after/h_VtxZ", "V_{Z} (after)", kTH1D, {axisVtxZ}); - - hist.add("QA/after/h_NTPC", "N_{TPC}", kTH1D, {axisMultTPC}); - hist.add("QA/after/h_NFT0M", "FT0M Multiplicity", kTH1D, {axisMultFT0M}); - hist.add("QA/after/h_Cent", "FT0M (%)", kTH1D, {axisCentFT0M}); - hist.add("QA/after/h2_NTPC_NFT0M", "N_{TPC} vs N_{FT0M}", kTH2D, {{axisMultFT0M}, {axisMultTPC}}); - hist.add("QA/after/p_NTPC_NFT0M", "N_{TPC} vs N_{FT0M} (Profile)", kTProfile, {{axisMultFT0M}}); - hist.add("QA/after/p_NFT0M_NTPC", "N_{FT0M} vs N_{TPC} (Profile)", kTProfile, {{axisMultTPC}}); - hist.add("QA/after/h2_NTPC_Cent", "N_{TPC} vs FT0M(%)", kTH2D, {{axisCentFT0M}, {axisMultTPC}}); - hist.add("QA/after/p_NTPC_Cent", "N_{TPC} vs FT0M(%) (Profile)", kTProfile, {{axisCentFT0M}}); - hist.add("QA/after/h2_NTPC_Nch", "N_{ch} vs N_{TPC}", kTH2D, {{axisMultTPC}, {axisMult}}); - - hist.add("QA/after/h_TPCChi2perCluster", "TPC #Chi^{2}/Cluster (after)", kTH1D, {axisChi2}); - hist.add("QA/after/h_ITSChi2perCluster", "ITS #Chi^{2}/Cluster (after)", kTH1D, {axisChi2}); - hist.add("QA/after/h_crossedTPC", "Crossed TPC", kTH1D, {axisCrossedTPC}); - - hist.add("QA/after/Charged/h_Mult_ch", "Multiplicity Charged Prticles", kTH1D, {axisMult}); - hist.add("QA/after/Charged/h_Eta_ch", "#eta Charged Particles (after)", kTH1D, {axisEta}); - hist.add("QA/after/Charged/h_Pt_ch", "p_{T} Charged Particles (after)", kTH1D, {axisPt}); - hist.add("QA/after/Charged/h2_DcaZ_ch", "DCA_{Z} Charged Particles (after)", - kTH2D, {{axisPt}, {axisDCAz}}); - hist.add("QA/after/Charged/h2_DcaXY_ch", "DCA_{XY} Charged Particles (after)", - kTH2D, {{axisPt}, {axisDCAxy}}); - hist.add("QA/after/Charged/h2_Pt_Eta_ch", "p_{T} vs #eta (Charged Particles)", - kTH2D, {{axisEta}, {axisPt}}); - - hist.add("QA/after/h2_TPCSignal_a", "TPC Signal (after)", kTH2D, {{axisP}, {axisTPCSignal}}); - hist.add("QA/after/h2_TOFSignal_a", "TOF Signal (after)", kTH2D, {{axisP}, {axisTOFSignal}}); - - hist.add("QA/after/TPC/Pion/h_Pt_pi_TPC", "p_{T} (Pions) TPC", kTH1D, {axisPt}); - hist.add("QA/after/TPC/Kaon/h_Pt_ka_TPC", "p_{T} (Kaons) TPC", kTH1D, {axisPt}); - hist.add("QA/after/TPC/Proton/h_Pt_pr_TPC", "p_{T} (Protons) TPC ", kTH1D, {axisPt}); - hist.add("QA/after/TPC/Pion/h_rap_pi_TPC", "y (Pions) TPC ", kTH1D, {axisY}); - hist.add("QA/after/TPC/Kaon/h_rap_ka_TPC", "y (Kaons) TPC", kTH1D, {axisY}); - hist.add("QA/after/TPC/Proton/h_rap_pr_TPC", "y (Protons) TPC", kTH1D, {axisY}); - hist.add("QA/after/TPC/Pion/h2_TPCSignal_pi_b", "TPC Signal Pions", - kTH2D, {{axisP}, {axisTPCSignal}}); - hist.add("QA/after/TPC/Pion/h2_ExpTPCSignal_pi_b", "Expected TPC Signal Pions", - kTH2D, {{axisP}, {axisTPCSignal}}); - hist.add("QA/after/TPC/Kaon/h2_TPCSignal_ka_b", "TPC Signal Kaons", - kTH2D, {{axisP}, {axisTPCSignal}}); - hist.add("QA/after/TPC/Kaon/h2_ExpTPCSignal_ka_b", "Expected TPC Signal Kaons", - kTH2D, {{axisP}, {axisTPCSignal}}); - hist.add("QA/after/TPC/Proton/h2_TPCSignal_pr_b", "TPC Signal Protons", - kTH2D, {{axisP}, {axisTPCSignal}}); - hist.add("QA/after/TPC/Proton/h2_ExpTPCSignal_pr_b", "Expected TPC Signal Protons", - kTH2D, {{axisP}, {axisTPCSignal}}); - hist.add("QA/after/TOF/Pion/h_Pt_pi_TOF", "p_{T} (Pions) TPC+TOF", kTH1D, {axisPt}); - hist.add("QA/after/TOF/Kaon/h_Pt_ka_TOF", "p_{T} (Kaons) TPC+TOF", kTH1D, {axisPt}); - hist.add("QA/after/TOF/Proton/h_Pt_pr_TOF", "p_{T} (Protons) TPC+TOF", kTH1D, {axisPt}); - hist.add("QA/after/TOF/Pion/h_rap_pi_TOF", "y (Pions) TPC+TOF ", kTH1D, {axisY}); - hist.add("QA/after/TOF/Kaon/h_rap_ka_TOF", "y (Kaons) TPC+TOF", kTH1D, {axisY}); - hist.add("QA/after/TOF/Proton/h_rap_pr_TOF", "y (Protons) TPC+TOF", kTH1D, {axisY}); - hist.add("QA/after/TOF/Pion/h2_TOFSignal_pi_b", "TOF Signal Pions", - kTH2D, {{axisP}, {axisTOFSignal}}); - hist.add("QA/after/TOF/Pion/h2_ExpTOFSignal_pi_b", "Expected TOF Signal Pions", - kTH2D, {{axisP}, {axisTOFSignal}}); - hist.add("QA/after/TOF/Kaon/h2_TOFSignal_ka_b", "TOF Signal Kaons", - kTH2D, {{axisP}, {axisTOFSignal}}); - hist.add("QA/after/TOF/Kaon/h2_ExpTOFSignal_ka_b", "Expected TOF Signal Kaons", - kTH2D, {{axisP}, {axisTOFSignal}}); - hist.add("QA/after/TOF/Proton/h2_TOFSignal_pr_b", "TOF Signal Protons", - kTH2D, {{axisP}, {axisTOFSignal}}); - hist.add("QA/after/TOF/Proton/h2_ExpTOFSignal_pr_b", "Expected TOF Signal Protons", - kTH2D, {{axisP}, {axisTOFSignal}}); - - hist.add("QA/after/Pion/h_Mult_pi", "Multiplicity Pion", kTH1D, {axisMult}); - hist.add("QA/after/Pion/h_Pt_pi", "p_{T} (Pions) TPC and TPC+TOF", kTH1D, {axisPt}); - hist.add("QA/after/Pion/h_rap_pi", "y (Pions) TPC and TPC+TOF", kTH1D, {axisY}); - hist.add("QA/after/Pion/h2_Pt_rap_pi", "p_{T} vs y (Pions)", kTH2D, {{axisY}, {axisPt}}); - hist.add("QA/after/Pion/h2_DcaZ_pi", "DCA_{z} (Pions)", kTH2D, {{axisPt}, {axisDCAz}}); - hist.add("QA/after/Pion/h2_DcaXY_pi", "DCA_{xy} (Pions)", kTH2D, {{axisPt}, {axisDCAxy}}); - hist.add("QA/after/Pion/h2_TPCNsigma_pi", "n #sigma_{TPC} (Pions)", - kTH2D, {{axisP}, {axisTPCNsigma}}); - hist.add("QA/after/Pion/h2_TOFNsigma_pi", "n #sigma_{TOF} (Pions)", - kTH2D, {{axisP}, {axisTOFNsigma}}); - hist.add("QA/after/Pion/h2_TpcTofNsigma_pi", "n #sigma_{TPC} vs n #sigma_{TOF} (Pions)", - kTH2D, {{{axisTPCNsigma}, {axisTOFNsigma}}}); - hist.add("QA/after/Pion/h2_TPCSignal_pi_a", "TPC Signal Pions (after)", - kTH2D, {{axisP}, {axisTPCSignal}}); - hist.add("QA/after/Pion/h2_TOFSignal_pi_a", "TOF Signal Pions (after)", - kTH2D, {{axisP}, {axisTOFSignal}}); - hist.add("QA/after/Pion/h2_ExpTPCSignal_pi_a", "Expected TPC Signal Pions (after)", - kTH2D, {{axisP}, {axisTPCSignal}}); - hist.add("QA/after/Pion/h2_ExpTOFSignal_pi_a", "Expected TOF Signal Pions (after)", - kTH2D, {{axisP}, {axisTOFSignal}}); - - hist.add("QA/after/Kaon/h_Mult_ka", "Multiplicity Kaon", kTH1D, {axisMult}); - hist.add("QA/after/Kaon/h_Pt_ka", "p_{T} (Kaons) TPC and TPC+TOF", kTH1D, {axisPt}); - hist.add("QA/after/Kaon/h_rap_ka", "y (Kaons) TPC and TPC+TOF", kTH1D, {axisY}); - hist.add("QA/after/Kaon/h2_Pt_rap_ka", "p_{T} vs y (Kaons)", kTH2D, {{axisY}, {axisPt}}); - hist.add("QA/after/Kaon/h2_DcaZ_ka", "DCA_{z} Kaons", kTH2D, {{axisPt}, {axisDCAz}}); - hist.add("QA/after/Kaon/h2_DcaXY_ka", "DCA_{xy} Kaons", kTH2D, {{axisPt}, {axisDCAxy}}); - hist.add("QA/after/Kaon/h2_TPCNsigma_ka", "n #sigma_{TPC} Kaons", - kTH2D, {{axisP}, {axisTPCNsigma}}); - hist.add("QA/after/Kaon/h2_TOFNsigma_ka", "n #sigma_{TOF} Kaons", - kTH2D, {{axisP}, {axisTOFNsigma}}); - hist.add("QA/after/Kaon/h2_TpcTofNsigma_ka", "n #sigma_{TPC} vs n #sigma_{TOF} Kaons", - kTH2D, {{axisTPCNsigma}, {axisTOFNsigma}}); - hist.add("QA/after/Kaon/h2_TPCSignal_ka_a", "TPC Signal Kaons (after)", - kTH2D, {{axisP}, {axisTPCSignal}}); - hist.add("QA/after/Kaon/h2_TOFSignal_ka_a", "TOF Signal Kaons (after)", - kTH2D, {{axisP}, {axisTOFSignal}}); - hist.add("QA/after/Kaon/h2_ExpTPCSignal_ka_a", "Expected TPC Signal Kaons (after)", - kTH2D, {{axisP}, {axisTPCSignal}}); - hist.add("QA/after/Kaon/h2_ExpTOFSignal_ka_a", "Expected TOF Signal Kaons (after)", - kTH2D, {{axisP}, {axisTOFSignal}}); - - hist.add("QA/after/Proton/h_Mult_pr", "Multiplicity Proton", kTH1D, {axisMult}); - hist.add("QA/after/Proton/h_Pt_pr", "p_{T} (Protons) TPC and TPC+TOF", kTH1D, {axisPt}); - hist.add("QA/after/Proton/h_rap_pr", "y(Protons) TPC and TPC+TOF", kTH1D, {axisY}); - hist.add("QA/after/Proton/h2_Pt_rap_pr", "p_{T} vs y (Protons)", kTH2D, {{axisY}, {axisPt}}); - hist.add("QA/after/Proton/h2_DcaZ_pr", "DCA_{z} (Protons)", kTH2D, {{axisPt}, {axisDCAz}}); - hist.add("QA/after/Proton/h2_DcaXY_pr", "DCA_{xy} (Protons)", kTH2D, {{axisPt}, {axisDCAxy}}); - hist.add("QA/after/Proton/h2_TPCNsigma_pr", "n #sigma_{TPC} (Protons)", - kTH2D, {{axisP}, {axisTPCNsigma}}); - hist.add("QA/after/Proton/h2_TOFNsigma_pr", "n #sigma_{TOF} (Protons)", - kTH2D, {{axisP}, {axisTOFNsigma}}); - hist.add("QA/after/Proton/h2_TpcTofNsigma_pr", "n #sigma_{TPC} vs n #sigma_{TOF} (Protons)", - kTH2D, {{{axisTPCNsigma}, {axisTOFNsigma}}}); - hist.add("QA/after/Proton/h2_TPCSignal_pr_a", "TPC Signal Protons (after)", - kTH2D, {{axisP}, {axisTPCSignal}}); - hist.add("QA/after/Proton/h2_TOFSignal_pr_a", "TOF Signal Protons (after)", - kTH2D, {{axisP}, {axisTOFSignal}}); - hist.add("QA/after/Proton/h2_ExpTPCSignal_pr_a", "Expected TPC Signal Protons (after)", - kTH2D, {{axisP}, {axisTPCSignal}}); - hist.add("QA/after/Proton/h2_ExpTOFSignal_pr_a", "Expected TOF Signal Protons (after)", - kTH2D, {{axisP}, {axisTOFSignal}}); - - // Analysis: - // Charged Particles - hist.add("Analysis/Charged/h_Mult_ch", "Multiplicity of Charged Prticles", kTH1D, {axisMult}); - hist.add("Analysis/Charged/h_mean_Q1_ch", "mean p_{T} (Charged particles)", kTH1D, {axisMeanPt}); - hist.add("Analysis/Charged/p_mean_Q1_ch", "mean p_{T} (Charged particles)", kTProfile, {axisMult}); - hist.add("Analysis/Charged/h_mean_Q1_Mult_ch", "Mean p_{T} vs N_{ch} (Charged Particles)", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Charged/h_twopart_Mult_ch", "Twopart vs N_{ch} (Charged Particles)", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Charged/h_threepart_Mult_ch", "Threepart vs N_{ch} (Charged Particles)", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Charged/h_fourpart_Mult_ch", "Fourpart vs N_{ch} (Charged Particles)", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - - // Pions - hist.add("Analysis/Pion/h_Mult_pi", "Multiplicity Pion", kTH1D, {axisMult}); - hist.add("Analysis/Pion/h_mean_Q1_pi", "mean p_{T} Pion", kTH1D, {axisMeanPt}); - hist.add("Analysis/Pion/p_mean_Q1_pi", "mean p_{T} Pion", kTProfile, {axisMult}); - hist.add("Analysis/Pion/h_mean_Q1_Mult_pi", "mean_Q1_Mult Pion", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Pion/h_twopart_Mult_pi", "twopart_Mult Pion", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Pion/h_threepart_Mult_pi", "threepart_Mult Pion", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Pion/h_fourpart_Mult_pi", "fourpart_Mult Pion", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - - // Kaons - hist.add("Analysis/Kaon/h_Mult_ka", "Multiplicity Kaon", kTH1D, {axisMult}); - hist.add("Analysis/Kaon/h_mean_Q1_ka", "mean p_{T} Kaon", kTH1D, {axisMeanPt}); - hist.add("Analysis/Kaon/p_mean_Q1_ka", "mean p_{T} Kaon", kTProfile, {axisMult}); - hist.add("Analysis/Kaon/h_mean_Q1_Mult_ka", "mean_Q1_Mult Kaon", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Kaon/h_twopart_Mult_ka", "twopart_Mult Kaon", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Kaon/h_threepart_Mult_ka", "threepart_Mult Kaon", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Kaon/h_fourpart_Mult_ka", "fourpart_Mult Kaon", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - - // Protons - hist.add("Analysis/Proton/h_Mult_pr", "Multiplicity Proton", kTH1D, {axisMult}); - hist.add("Analysis/Proton/h_mean_Q1_pr", "mean p_{T} Proton", kTH1D, {axisMeanPt}); - hist.add("Analysis/Proton/p_mean_Q1_pr", "mean p_{T} Proton", kTProfile, {axisMult}); - hist.add("Analysis/Proton/h_mean_Q1_Mult_pr", "mean_Q1_Mult Proton", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Proton/h_twopart_Mult_pr", "twopart_Mult Proton", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Proton/h_threepart_Mult_pr", "threepart_Mult Proton", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Proton/h_fourpart_Mult_pr", "fourpart_Mult Proton", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - - // Additional QA - hist.add("Analysis/Charged/h_mean_Q1_Mult_ch_tof", "mean_Q1_Mult (Charged Particles) (TOF+TPC)", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Charged/h_twopart_Mult_ch_tof", "twopart_Mult (Charged Particles) (TOF+TPC)", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Pion/h_mean_Q1_Mult_pi_tof", "mean_Q1_Mult Pion (TOF+TPC)", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Pion/h_mean_Q1_Mult_pi_tpc", "mean_Q1_Mult Pion (TPC)", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Pion/h_twopart_Mult_pi_tof", "twopart_Mult Pion (TOF+TPC)", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Pion/h_twopart_Mult_pi_tpc", "twopart_Mult Pion (TPC)", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Proton/h_mean_Q1_Mult_pr_tof", "mean_Q1_Mult Proton (TOF+TPC)", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Proton/h_mean_Q1_Mult_pr_tpc", "mean_Q1_Mult Proton (TPC)", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Proton/h_twopart_Mult_pr_tof", "twopart_Mult Proton (TOF+TPC)", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Proton/h_twopart_Mult_pr_tpc", "twopart_Mult Proton (TPC)", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Kaon/h_mean_Q1_Mult_ka_tof", "mean_Q1_Mult Kaon (TOF+TPC)", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Kaon/h_mean_Q1_Mult_ka_tpc", "mean_Q1_Mult Kaon (TPC)", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Kaon/h_twopart_Mult_ka_tof", "twopart_Mult Kaon (TOF+TPC)", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - hist.add("Analysis/Kaon/h_twopart_Mult_ka_tpc", "twopart_Mult Kaon (TPC)", - kTHnSparseD, {{axisMultTPC}, {axisPart}, {axisMultFT0M}}); - } - - void process_QA(MyAllCollisions::iterator const& myCol, MyAllTracks const& myTracks) - { - for (auto& myTrack : myTracks) { - hist.fill(HIST("QA/before/Charged/h_Eta_ch"), myTrack.eta()); - hist.fill(HIST("QA/before/Charged/h_Pt_ch"), myTrack.pt()); - hist.fill(HIST("QA/before/h_TPCChi2perCluster"), myTrack.tpcChi2NCl()); - hist.fill(HIST("QA/before/h_ITSChi2perCluster"), myTrack.itsChi2NCl()); - hist.fill(HIST("QA/before/h_crossedTPC"), myTrack.tpcNClsCrossedRows()); - hist.fill(HIST("QA/before/Charged/h2_DcaXY_ch"), myTrack.pt(), myTrack.dcaXY()); - hist.fill(HIST("QA/before/Charged/h2_DcaZ_ch"), myTrack.pt(), myTrack.dcaZ()); - } - hist.fill(HIST("QA/before/h_VtxZ"), myCol.posZ()); - hist.fill(HIST("QA/before/h_Counts"), 2); - } - PROCESS_SWITCH(meanPtFlucId, process_QA, "process QA", true); - - void process(MyFilteredCollisions::iterator const& col, MyFilteredTracks const& tracks) - { - double Cent_FT0M = 0; - int N_Pi = 0, N_Ka = 0, N_Pr = 0; - int Nch = 0, NTPC = 0, N_FT0M = 0; - int N_Ka_tpc = 0, N_Pr_tpc = 0, N_Pi_tpc = 0; - int Nch_tof = 0, N_Ka_tof = 0, N_Pr_tof = 0, N_Pi_tof = 0; - double pt_ch = 0, Q1_ch = 0, Q2_ch = 0, Q3_ch = 0, Q4_ch = 0; - double pt_Pi = 0, Q1_Pi = 0, Q2_Pi = 0, Q3_Pi = 0, Q4_Pi = 0; - double pt_Pr = 0, Q1_Pr = 0, Q2_Pr = 0, Q3_Pr = 0, Q4_Pr = 0; - double pt_Ka = 0, Q1_Ka = 0, Q2_Ka = 0, Q3_Ka = 0, Q4_Ka = 0; - double Q1_tof = 0, Q1_Pi_tof = 0, Q1_Pr_tof = 0, Q1_Ka_tof = 0; - double Q1_Pi_tpc = 0, Q1_Pr_tpc = 0, Q1_Ka_tpc = 0; - double Q2_tof = 0, Q2_Pi_tof = 0, Q2_Pr_tof = 0, Q2_Ka_tof = 0; - double Q2_Pi_tpc = 0, Q2_Pr_tpc = 0, Q2_Ka_tpc = 0; - - for (auto& track : tracks) { - Nch++; - pt_ch = track.pt(); - Q1_ch += pt_ch; - Q2_ch += pt_ch * pt_ch; - Q3_ch += pt_ch * pt_ch * pt_ch; - Q4_ch += pt_ch * pt_ch * pt_ch * pt_ch; - - hist.fill(HIST("QA/after/Charged/h_Eta_ch"), track.eta()); - hist.fill(HIST("QA/after/Charged/h_Pt_ch"), track.pt()); - hist.fill(HIST("QA/after/Charged/h2_Pt_Eta_ch"), track.eta(), track.pt()); - hist.fill(HIST("QA/after/Charged/h2_DcaXY_ch"), track.pt(), track.dcaXY()); - hist.fill(HIST("QA/after/Charged/h2_DcaZ_ch"), track.pt(), track.dcaZ()); - - hist.fill(HIST("QA/after/h_TPCChi2perCluster"), track.tpcChi2NCl()); - hist.fill(HIST("QA/after/h_ITSChi2perCluster"), track.itsChi2NCl()); - hist.fill(HIST("QA/after/h_crossedTPC"), track.tpcNClsCrossedRows()); - - hist.fill(HIST("QA/before/h2_TOFSignal_b"), track.p(), track.beta()); - hist.fill(HIST("QA/before/h2_TPCSignal_b"), track.p(), track.tpcSignal()); - - hist.fill(HIST("QA/before/Pion/h2_TPCNsigma_pi"), track.p(), track.tpcNSigmaPi()); - hist.fill(HIST("QA/before/Pion/h2_TOFNsigma_pi"), track.p(), track.tofNSigmaPi()); - hist.fill(HIST("QA/before/Pion/h2_TpcTofNsigma_pi"), track.tpcNSigmaPi(), track.tofNSigmaPi()); - hist.fill(HIST("QA/before/Proton/h2_TPCNsigma_pr"), track.p(), track.tpcNSigmaPr()); - hist.fill(HIST("QA/before/Proton/h2_TOFNsigma_pr"), track.p(), track.tofNSigmaPr()); - hist.fill(HIST("QA/before/Proton/h2_TpcTofNsigma_pr"), track.tpcNSigmaPr(), track.tofNSigmaPr()); - hist.fill(HIST("QA/before/Kaon/h2_TPCNsigma_ka"), track.p(), track.tpcNSigmaKa()); - hist.fill(HIST("QA/before/Kaon/h2_TOFNsigma_ka"), track.p(), track.tofNSigmaKa()); - hist.fill(HIST("QA/before/Kaon/h2_TpcTofNsigma_ka"), track.tpcNSigmaKa(), track.tofNSigmaKa()); - - // ###################################################// - // TPC (Without p cuts) // - // ###################################################// - if (abs(track.tpcNSigmaPi()) < nSigCut3) { - if (abs(track.rapidity(massPi)) >= 0.5) - continue; - N_Pi_tpc++; - Q1_Pi_tpc += track.pt(); - Q2_Pi_tpc += track.pt() * track.pt(); - hist.fill(HIST("QA/after/TPC/Pion/h_Pt_pi_TPC"), track.pt()); - hist.fill(HIST("QA/after/TPC/Pion/h_rap_pi_TPC"), track.rapidity(massPi)); - hist.fill(HIST("QA/after/TPC/Pion/h2_TPCSignal_pi_b"), track.p(), track.tpcSignal()); - hist.fill(HIST("QA/after/TPC/Pion/h2_ExpTPCSignal_pi_b"), track.p(), track.tpcExpSignalPi(track.tpcSignal())); - } - if (abs(track.tpcNSigmaKa()) < nSigCut3) { - if (abs(track.rapidity(massKa)) >= 0.5) - continue; - N_Ka_tpc++; - Q1_Ka_tpc += track.pt(); - Q2_Ka_tpc += track.pt() * track.pt(); - hist.fill(HIST("QA/after/TPC/Kaon/h_Pt_ka_TPC"), track.pt()); - hist.fill(HIST("QA/after/TPC/Kaon/h_rap_ka_TPC"), track.rapidity(massKa)); - hist.fill(HIST("QA/after/TPC/Kaon/h2_TPCSignal_ka_b"), track.p(), track.tpcSignal()); - hist.fill(HIST("QA/after/TPC/Kaon/h2_ExpTPCSignal_ka_b"), track.p(), track.tpcExpSignalKa(track.tpcSignal())); - } - if (abs(track.tpcNSigmaPr()) < nSigCut3) { - if (abs(track.rapidity(massPr)) >= 0.5) - continue; - N_Pr_tpc++; - Q1_Pr_tpc += track.pt(); - Q2_Pr_tpc += track.pt() * track.pt(); - hist.fill(HIST("QA/after/TPC/Proton/h_Pt_pr_TPC"), track.pt()); - hist.fill(HIST("QA/after/TPC/Proton/h_rap_pr_TPC"), track.rapidity(massPr)); - hist.fill(HIST("QA/after/TPC/Proton/h2_TPCSignal_pr_b"), track.p(), track.tpcSignal()); - hist.fill(HIST("QA/after/TPC/Proton/h2_ExpTPCSignal_pr_b"), track.p(), track.tpcExpSignalPr(track.tpcSignal())); - } - - // ###################################################// - // TPC + TOF (Without p cuts) // - // ###################################################// - if (track.hasTOF()) { - Nch_tof++; - Q1_tof += track.pt(); - Q2_tof += track.pt() * track.pt(); - - if ((std::pow(track.tpcNSigmaPi(), 2) + std::pow(track.tofNSigmaPi(), 2)) < 6.0) { - if (abs(track.rapidity(massPi)) >= 0.5) - continue; - N_Pi_tof++; - Q1_Pi_tof += track.pt(); - Q2_Pi_tof += track.pt() * track.pt(); - hist.fill(HIST("QA/after/TOF/Pion/h_Pt_pi_TOF"), track.pt()); - hist.fill(HIST("QA/after/TOF/Pion/h_rap_pi_TOF"), track.rapidity(massPi)); - hist.fill(HIST("QA/after/TOF/Pion/h2_TOFSignal_pi_b"), track.p(), track.beta()); - hist.fill(HIST("QA/after/TOF/Pion/h2_ExpTOFSignal_pi_b"), track.p(), track.tofExpSignalPi(track.beta())); - } - if ((std::pow(track.tpcNSigmaKa(), 2) + std::pow(track.tofNSigmaKa(), 2)) < 6.0) { - if (abs(track.rapidity(massKa)) >= 0.5) - continue; - N_Ka_tof++; - Q1_Ka_tof += track.pt(); - Q2_Ka_tof += track.pt() * track.pt(); - hist.fill(HIST("QA/after/TOF/Kaon/h_Pt_ka_TOF"), track.pt()); - hist.fill(HIST("QA/after/TOF/Kaon/h_rap_ka_TOF"), track.rapidity(massKa)); - hist.fill(HIST("QA/after/TOF/Kaon/h2_TOFSignal_ka_b"), track.p(), track.beta()); - hist.fill(HIST("QA/after/TOF/Kaon/h2_ExpTOFSignal_ka_b"), track.p(), track.tofExpSignalKa(track.beta())); - } - if ((std::pow(track.tpcNSigmaPr(), 2) + std::pow(track.tofNSigmaPr(), 2)) < 6.0) { - if (abs(track.rapidity(massPr)) >= 0.5) - continue; - N_Pr_tof++; - Q1_Pr_tof += track.pt(); - Q2_Pr_tof += track.pt() * track.pt(); - hist.fill(HIST("QA/after/TOF/Proton/h_Pt_pr_TOF"), track.pt()); - hist.fill(HIST("QA/after/TOF/Proton/h_rap_pr_TOF"), track.rapidity(massPr)); - hist.fill(HIST("QA/after/TOF/Proton/h2_TOFSignal_pr_b"), track.p(), track.beta()); - hist.fill(HIST("QA/after/TOF/Proton/h2_ExpTOFSignal_pr_b"), track.p(), track.tofExpSignalPr(track.beta())); - } - } - - // ####################################################// - // TPC and TPC+TOF nSigma Cuts (with p cuts) // - // ####################################################// - // For Pions: - if ((track.hasTOF() == false && - ((abs(track.tpcNSigmaPi()) < nSigCut3 && track.p() <= piP1) || (abs(track.tpcNSigmaPi()) < nSigCut2 && track.p() > piP1 && track.p() <= piP2))) || - (track.hasTOF() && abs(track.tpcNSigmaPi()) < nSigCut4 && abs(track.tofNSigmaEl()) > nSigCut1 && - ((abs(track.tofNSigmaPi()) < nSigCut3 && track.p() <= piP3) || (abs(track.tofNSigmaPi()) < nSigCut25 && track.p() > piP3 && track.p() <= piP4) || (abs(track.tofNSigmaPi()) < nSigCut2 && track.p() > piP4)))) { - if (abs(track.rapidity(massPi)) >= 0.5) - continue; - N_Pi++; - pt_Pi = track.pt(); - Q1_Pi += pt_Pi; - Q2_Pi += pt_Pi * pt_Pi; - Q3_Pi += pt_Pi * pt_Pi * pt_Pi; - Q4_Pi += pt_Pi * pt_Pi * pt_Pi * pt_Pi; - hist.fill(HIST("QA/after/Pion/h_Pt_pi"), track.pt()); - hist.fill(HIST("QA/after/Pion/h_rap_pi"), track.rapidity(massPi)); - hist.fill(HIST("QA/after/Pion/h2_Pt_rap_pi"), track.rapidity(massPi), track.pt()); - hist.fill(HIST("QA/after/Pion/h2_DcaXY_pi"), track.pt(), track.dcaXY()); - hist.fill(HIST("QA/after/Pion/h2_DcaZ_pi"), track.pt(), track.dcaZ()); - hist.fill(HIST("QA/after/Pion/h2_TPCNsigma_pi"), track.p(), track.tpcNSigmaPi()); - hist.fill(HIST("QA/after/Pion/h2_TOFNsigma_pi"), track.p(), track.tofNSigmaPi()); - hist.fill(HIST("QA/after/Pion/h2_TpcTofNsigma_pi"), track.tpcNSigmaPi(), track.tofNSigmaPi()); - hist.fill(HIST("QA/after/h2_TOFSignal_a"), track.p(), track.beta()); - hist.fill(HIST("QA/after/Pion/h2_TOFSignal_pi_a"), track.p(), track.beta()); - hist.fill(HIST("QA/after/h2_TPCSignal_a"), track.p(), track.tpcSignal()); - hist.fill(HIST("QA/after/Pion/h2_TPCSignal_pi_a"), track.p(), track.tpcSignal()); - hist.fill(HIST("QA/after/Pion/h2_ExpTOFSignal_pi_a"), track.p(), track.tofExpSignalPi(track.beta())); - hist.fill(HIST("QA/after/Pion/h2_ExpTPCSignal_pi_a"), track.p(), track.tpcExpSignalPi(track.tpcSignal())); - } - - // For Kaons: - if ((track.hasTOF() == false && - ((abs(track.tpcNSigmaKa()) < nSigCut3 && track.pt() > kaP1 && track.p() <= kaP2) || (abs(track.tpcNSigmaKa()) < nSigCut25 && track.p() > kaP2 && track.p() <= kaP3) || (abs(track.tpcNSigmaKa()) < nSigCut2 && track.p() > kaP3 && track.p() <= kaP4) || (abs(track.tpcNSigmaKa()) < nSigCut15 && track.p() > kaP4 && track.p() <= kaP5))) || - (track.hasTOF() && abs(track.tpcNSigmaKa()) < nSigCut4 && abs(track.tofNSigmaEl()) > nSigCut1 && - ((abs(track.tofNSigmaKa()) < nSigCut3 && track.pt() > kaP1 && track.p() <= kaP6) || (abs(track.tofNSigmaKa()) < nSigCut2 && track.p() > kaP6 && track.p() <= kaP7) || (abs(track.tofNSigmaKa()) < nSigCut15 && track.p() > kaP7 && track.p() <= kaP8) || (abs(track.tofNSigmaKa()) < nSigCut1 && track.p() > kaP8)))) { - if (abs(track.rapidity(massKa)) >= 0.5) - continue; - pt_Ka = track.pt(); - Q1_Ka += pt_Ka; - Q2_Ka += pt_Ka * pt_Ka; - Q3_Ka += pt_Ka * pt_Ka * pt_Ka; - Q4_Ka += pt_Ka * pt_Ka * pt_Ka * pt_Ka; - N_Ka++; - hist.fill(HIST("QA/after/Kaon/h_Pt_ka"), track.pt()); - hist.fill(HIST("QA/after/Kaon/h_rap_ka"), track.rapidity(massKa)); - hist.fill(HIST("QA/after/Kaon/h2_Pt_rap_ka"), track.rapidity(massKa), track.pt()); - hist.fill(HIST("QA/after/Kaon/h2_DcaXY_ka"), track.pt(), track.dcaXY()); - hist.fill(HIST("QA/after/Kaon/h2_DcaZ_ka"), track.pt(), track.dcaZ()); - hist.fill(HIST("QA/after/Kaon/h2_TPCNsigma_ka"), track.p(), track.tpcNSigmaKa()); - hist.fill(HIST("QA/after/Kaon/h2_TOFNsigma_ka"), track.p(), track.tofNSigmaKa()); - hist.fill(HIST("QA/after/Kaon/h2_TpcTofNsigma_ka"), track.tpcNSigmaKa(), track.tofNSigmaKa()); - hist.fill(HIST("QA/after/h2_TOFSignal_a"), track.p(), track.beta()); - hist.fill(HIST("QA/after/Kaon/h2_TOFSignal_ka_a"), track.p(), track.beta()); - hist.fill(HIST("QA/after/h2_TPCSignal_a"), track.p(), track.tpcSignal()); - hist.fill(HIST("QA/after/Kaon/h2_TPCSignal_ka_a"), track.p(), track.tpcSignal()); - hist.fill(HIST("QA/after/Kaon/h2_ExpTOFSignal_ka_a"), track.p(), track.tofExpSignalKa(track.beta())); - hist.fill(HIST("QA/after/Kaon/h2_ExpTPCSignal_ka_a"), track.p(), track.tpcExpSignalKa(track.tpcSignal())); - } - - // For Protons: - if ((track.hasTOF() == false && - ((abs(track.tpcNSigmaPr()) < nSigCut3 && track.pt() > prP1 && track.p() <= prP2) || (abs(track.tpcNSigmaPr()) < nSigCut25 && track.p() > prP2 && track.p() <= prP3) || (abs(track.tpcNSigmaPr()) < nSigCut2 && track.p() > prP3 && track.p() <= prP4) || (abs(track.tpcNSigmaPr()) < nSigCut15 && track.p() > prP4 && track.p() <= prP5) || (abs(track.tpcNSigmaPr()) < nSigCut1 && track.p() > prP5 && track.p() <= prP6))) || - (track.hasTOF() && abs(track.tpcNSigmaPr()) < nSigCut4 && abs(track.tofNSigmaEl()) > nSigCut1 && abs(track.tofNSigmaPr()) < nSigCut3 && track.pt() > prP1)) { - if (abs(track.rapidity(massPr)) >= 0.5) - continue; - pt_Pr = track.pt(); - Q1_Pr += pt_Pr; - Q2_Pr += pt_Pr * pt_Pr; - Q3_Pr += pt_Pr * pt_Pr * pt_Pr; - Q4_Pr += pt_Pr * pt_Pr * pt_Pr * pt_Pr; - N_Pr++; - hist.fill(HIST("QA/after/Proton/h_Pt_pr"), track.pt()); - hist.fill(HIST("QA/after/Proton/h_rap_pr"), track.rapidity(massPr)); - hist.fill(HIST("QA/after/Proton/h2_DcaZ_pr"), track.pt(), track.dcaZ()); - hist.fill(HIST("QA/after/Proton/h2_DcaXY_pr"), track.pt(), track.dcaXY()); - hist.fill(HIST("QA/after/Proton/h2_Pt_rap_pr"), track.rapidity(massPr), track.pt()); - hist.fill(HIST("QA/after/Proton/h2_TPCNsigma_pr"), track.p(), track.tpcNSigmaPr()); - hist.fill(HIST("QA/after/Proton/h2_TOFNsigma_pr"), track.p(), track.tofNSigmaPr()); - hist.fill(HIST("QA/after/Proton/h2_TpcTofNsigma_pr"), track.tpcNSigmaPr(), track.tofNSigmaPr()); - hist.fill(HIST("QA/after/Proton/h2_TPCSignal_pr_a"), track.p(), track.tpcSignal()); - hist.fill(HIST("QA/after/h2_TPCSignal_a"), track.p(), track.tpcSignal()); - hist.fill(HIST("QA/after/h2_TOFSignal_a"), track.p(), track.beta()); - hist.fill(HIST("QA/after/Proton/h2_TOFSignal_pr_a"), track.p(), track.beta()); - hist.fill(HIST("QA/after/Proton/h2_ExpTOFSignal_pr_a"), track.p(), track.tofExpSignalPr(track.beta())); - hist.fill(HIST("QA/after/Proton/h2_ExpTPCSignal_pr_a"), track.p(), track.tpcExpSignalPr(track.tpcSignal())); - } - } - - NTPC = col.multTPC(); - N_FT0M = col.multFT0M(); - Cent_FT0M = col.centFT0M(); - hist.fill(HIST("QA/after/h_VtxZ"), col.posZ()); - hist.fill(HIST("QA/after/h_Counts"), 2); - hist.fill(HIST("QA/after/h_NTPC"), NTPC); - hist.fill(HIST("QA/after/h_Cent"), Cent_FT0M); - hist.fill(HIST("QA/after/h_NFT0M"), N_FT0M); - hist.fill(HIST("QA/after/h2_NTPC_NFT0M"), N_FT0M, NTPC); - hist.fill(HIST("QA/after/h2_NTPC_Cent"), Cent_FT0M, NTPC); - hist.fill(HIST("QA/after/p_NTPC_Cent"), Cent_FT0M, NTPC); - hist.fill(HIST("QA/after/p_NTPC_NFT0M"), N_FT0M, NTPC); - hist.fill(HIST("QA/after/p_NFT0M_NTPC"), NTPC, N_FT0M); - hist.fill(HIST("QA/after/h2_NTPC_Nch"), NTPC, Nch); - - hist.fill(HIST("Analysis/Charged/h_Mult_ch"), Nch); - hist.fill(HIST("Analysis/Pion/h_Mult_pi"), N_Pi); - hist.fill(HIST("Analysis/Kaon/h_Mult_ka"), N_Ka); - hist.fill(HIST("Analysis/Proton/h_Mult_pr"), N_Pr); - - hist.fill(HIST("QA/after/Charged/h_Mult_ch"), Nch); - hist.fill(HIST("QA/after/Pion/h_Mult_pi"), N_Pi); - hist.fill(HIST("QA/after/Kaon/h_Mult_ka"), N_Ka); - hist.fill(HIST("QA/after/Proton/h_Mult_pr"), N_Pr); - - // Charged Particles: - if (Nch > 1) { - auto Nch2 = static_cast(Nch) * (static_cast(Nch) - 1); - auto mean_Q1 = Q1_ch / static_cast(Nch); - auto twopart = ((Q1_ch * Q1_ch) - Q2_ch); - auto twopart1 = (twopart) / (Nch2); - hist.fill(HIST("Analysis/Charged/h_mean_Q1_ch"), mean_Q1); - hist.fill(HIST("Analysis/Charged/p_mean_Q1_ch"), NTPC, mean_Q1); - hist.fill(HIST("Analysis/Charged/h_mean_Q1_Mult_ch"), NTPC, mean_Q1, N_FT0M); - hist.fill(HIST("Analysis/Charged/h_twopart_Mult_ch"), NTPC, twopart1, N_FT0M); - } - - if (Nch > 2) { - auto Nch3 = static_cast(Nch) * (static_cast(Nch) - 1) * (static_cast(Nch) - 2); - auto threepart = ((Q1_ch * Q1_ch * Q1_ch) - (3 * Q2_ch * Q1_ch) + 2 * Q3_ch); - auto threepart1 = threepart / Nch3; - hist.fill(HIST("Analysis/Charged/h_threepart_Mult_ch"), NTPC, threepart1, N_FT0M); - } - - if (Nch > 3) { - auto Nch4 = static_cast(Nch) * (static_cast(Nch) - 1) * (static_cast(Nch) - 2) * (static_cast(Nch) - 3); - auto fourpart = ((Q1_ch * Q1_ch * Q1_ch * Q1_ch) - (6 * Q2_ch * Q1_ch * Q1_ch) + (3 * Q2_ch * Q2_ch) + (8 * Q3_ch * Q1_ch) - 6 * Q4_ch); - auto fourpart1 = fourpart / Nch4; - hist.fill(HIST("Analysis/Charged/h_fourpart_Mult_ch"), NTPC, fourpart1, N_FT0M); - } - - // Pions: - if (N_Pi > 1) { - auto Nch2_Pi = static_cast(N_Pi) * (static_cast(N_Pi) - 1); - auto mean_Q1_Pi = Q1_Pi / static_cast(N_Pi); - auto twopart_Pi = ((Q1_Pi * Q1_Pi) - Q2_Pi); - auto twopart1_Pi = (twopart_Pi) / (Nch2_Pi); - hist.fill(HIST("Analysis/Pion/h_mean_Q1_pi"), mean_Q1_Pi); - hist.fill(HIST("Analysis/Pion/p_mean_Q1_pi"), NTPC, mean_Q1_Pi); - hist.fill(HIST("Analysis/Pion/h_mean_Q1_Mult_pi"), NTPC, mean_Q1_Pi, N_FT0M); - hist.fill(HIST("Analysis/Pion/h_twopart_Mult_pi"), NTPC, twopart1_Pi, N_FT0M); - } - - if (N_Pi > 2) { - auto Nch3_Pi = static_cast(N_Pi) * (static_cast(N_Pi) - 1) * (static_cast(N_Pi) - 2); - auto threepart_Pi = ((Q1_Pi * Q1_Pi * Q1_Pi) - (3 * Q2_Pi * Q1_Pi) + 2 * Q3_Pi); - auto threepart1_Pi = threepart_Pi / Nch3_Pi; - hist.fill(HIST("Analysis/Pion/h_threepart_Mult_pi"), NTPC, threepart1_Pi, N_FT0M); - } - - if (N_Pi > 3) { - auto Nch4_Pi = static_cast(N_Pi) * (static_cast(N_Pi) - 1) * (static_cast(N_Pi) - 2) * (static_cast(N_Pi) - 3); - auto fourpart_Pi = ((Q1_Pi * Q1_Pi * Q1_Pi * Q1_Pi) - (6 * Q2_Pi * Q1_Pi * Q1_Pi) + (3 * Q2_Pi * Q2_Pi) + (8 * Q3_Pi * Q1_Pi) - 6 * Q4_Pi); - auto fourpart1_Pi = fourpart_Pi / Nch4_Pi; - hist.fill(HIST("Analysis/Pion/h_fourpart_Mult_pi"), NTPC, fourpart1_Pi, N_FT0M); - } - - // Kaons: - if (N_Ka > 1) { - auto Nch2_Ka = static_cast(N_Ka) * (static_cast(N_Ka) - 1); - auto mean_Q1_Ka = Q1_Ka / static_cast(N_Ka); - auto twopart_Ka = ((Q1_Ka * Q1_Ka) - Q2_Ka); - auto twopart1_Ka = (twopart_Ka) / (Nch2_Ka); - hist.fill(HIST("Analysis/Kaon/h_mean_Q1_ka"), mean_Q1_Ka); - hist.fill(HIST("Analysis/Kaon/p_mean_Q1_ka"), NTPC, mean_Q1_Ka); - hist.fill(HIST("Analysis/Kaon/h_mean_Q1_Mult_ka"), NTPC, mean_Q1_Ka, N_FT0M); - hist.fill(HIST("Analysis/Kaon/h_twopart_Mult_ka"), NTPC, twopart1_Ka, N_FT0M); - } - - if (N_Ka > 2) { - auto Nch3_Ka = static_cast(N_Ka) * (static_cast(N_Ka) - 1) * (static_cast(N_Ka) - 2); - auto threepart_Ka = ((Q1_Ka * Q1_Ka * Q1_Ka) - (3 * Q2_Ka * Q1_Ka) + 2 * Q3_Ka); - auto threepart1_Ka = threepart_Ka / Nch3_Ka; - hist.fill(HIST("Analysis/Kaon/h_threepart_Mult_ka"), NTPC, threepart1_Ka, N_FT0M); - } - - if (N_Ka > 3) { - auto Nch4_Ka = static_cast(N_Ka) * (static_cast(N_Ka) - 1) * (static_cast(N_Ka) - 2) * (static_cast(N_Ka) - 3); - auto fourpart_Ka = ((Q1_Ka * Q1_Ka * Q1_Ka * Q1_Ka) - (6 * Q2_Ka * Q1_Ka * Q1_Ka) + (3 * Q2_Ka * Q2_Ka) + (8 * Q3_Ka * Q1_Ka) - 6 * Q4_Ka); - auto fourpart1_Ka = fourpart_Ka / Nch4_Ka; - hist.fill(HIST("Analysis/Kaon/h_fourpart_Mult_ka"), NTPC, fourpart1_Ka, N_FT0M); - } - - // Protons: - if (N_Pr > 1) { - auto Nch2_Pr = static_cast(N_Pr) * (static_cast(N_Pr) - 1); - auto mean_Q1_Pr = Q1_Pr / static_cast(N_Pr); - auto twopart_Pr = ((Q1_Pr * Q1_Pr) - Q2_Pr); - auto twopart1_Pr = (twopart_Pr) / (Nch2_Pr); - hist.fill(HIST("Analysis/Proton/h_mean_Q1_pr"), mean_Q1_Pr); - hist.fill(HIST("Analysis/Proton/p_mean_Q1_pr"), NTPC, mean_Q1_Pr); - hist.fill(HIST("Analysis/Proton/h_mean_Q1_Mult_pr"), NTPC, mean_Q1_Pr, N_FT0M); - hist.fill(HIST("Analysis/Proton/h_twopart_Mult_pr"), NTPC, twopart1_Pr, N_FT0M); - } - - if (N_Pr > 2) { - auto Nch3_Pr = static_cast(N_Pr) * (static_cast(N_Pr) - 1) * (static_cast(N_Pr) - 2); - auto threepart_Pr = ((Q1_Pr * Q1_Pr * Q1_Pr) - (3 * Q2_Pr * Q1_Pr) + 2 * Q3_Pr); - auto threepart1_Pr = threepart_Pr / Nch3_Pr; - hist.fill(HIST("Analysis/Proton/h_threepart_Mult_pr"), NTPC, threepart1_Pr, N_FT0M); - } - - if (N_Pr > 3) { - auto Nch4_Pr = static_cast(N_Pr) * (static_cast(N_Pr) - 1) * (static_cast(N_Pr) - 2) * (static_cast(N_Pr) - 3); - auto fourpart_Pr = ((Q1_Pr * Q1_Pr * Q1_Pr * Q1_Pr) - (6 * Q2_Pr * Q1_Pr * Q1_Pr) + (3 * Q2_Pr * Q2_Pr) + (8 * Q3_Pr * Q1_Pr) - 6 * Q4_Pr); - auto fourpart1_Pr = fourpart_Pr / Nch4_Pr; - hist.fill(HIST("Analysis/Proton/h_fourpart_Mult_pr"), NTPC, fourpart1_Pr, Cent_FT0M); - } - - //----------------------------- TPC (No p cuts)---------------------------// - if (N_Pi_tpc > 1) { - double mean_Q1_Pi_tpc = Q1_Pi_tpc / static_cast(N_Pi_tpc); - double twopart_Pi_tpc = ((Q1_Pi_tpc * Q1_Pi_tpc) - Q2_Pi_tpc) / (static_cast(N_Pi_tpc) * (static_cast(N_Pi_tpc) - 1)); - hist.fill(HIST("Analysis/Pion/h_mean_Q1_Mult_pi_tpc"), NTPC, mean_Q1_Pi_tpc, N_FT0M); - hist.fill(HIST("Analysis/Pion/h_twopart_Mult_pi_tpc"), NTPC, twopart_Pi_tpc, N_FT0M); - } - if (N_Ka_tpc > 1) { - double mean_Q1_Ka_tpc = Q1_Ka_tpc / static_cast(N_Ka_tpc); - double twopart_Ka_tpc = ((Q1_Ka_tpc * Q1_Ka_tpc) - Q2_Ka_tpc) / (static_cast(N_Ka_tpc) * (static_cast(N_Ka_tpc) - 1)); - hist.fill(HIST("Analysis/Kaon/h_mean_Q1_Mult_ka_tpc"), NTPC, mean_Q1_Ka_tpc, N_FT0M); - hist.fill(HIST("Analysis/Kaon/h_twopart_Mult_ka_tpc"), NTPC, twopart_Ka_tpc, N_FT0M); - } - if (N_Pr_tpc > 1) { - double mean_Q1_Pr_tpc = Q1_Pr_tpc / static_cast(N_Pr_tpc); - double twopart_Pr_tpc = ((Q1_Pr_tpc * Q1_Pr_tpc) - Q2_Pr_tpc) / (static_cast(N_Pr_tpc) * (static_cast(N_Pr_tpc) - 1)); - hist.fill(HIST("Analysis/Proton/h_mean_Q1_Mult_pr_tpc"), NTPC, mean_Q1_Pr_tpc, N_FT0M); - hist.fill(HIST("Analysis/Proton/h_twopart_Mult_pr_tpc"), NTPC, twopart_Pr_tpc, N_FT0M); - } - - //-----------------------TPC + TOF (No p cuts)--------------------------// - if (Nch_tof > 1) { - double mean_Q1_tof = Q1_tof / static_cast(Nch_tof); - double twopart_tof = ((Q1_tof * Q1_tof) - Q2_tof) / (static_cast(Nch_tof) * (static_cast(Nch_tof) - 1)); - hist.fill(HIST("Analysis/Charged/h_mean_Q1_Mult_ch_tof"), NTPC, mean_Q1_tof, N_FT0M); - hist.fill(HIST("Analysis/Charged/h_twopart_Mult_ch_tof"), NTPC, twopart_tof, N_FT0M); - } - if (N_Pi_tof > 1) { - double mean_Q1_Pi_tof = Q1_Pi_tof / static_cast(N_Pi_tof); - double twopart_Pi_tof = ((Q1_Pi_tof * Q1_Pi_tof) - Q2_Pi_tof) / (static_cast(N_Pi_tof) * (static_cast(N_Pi_tof) - 1)); - hist.fill(HIST("Analysis/Pion/h_mean_Q1_Mult_pi_tof"), NTPC, mean_Q1_Pi_tof, N_FT0M); - hist.fill(HIST("Analysis/Pion/h_twopart_Mult_pi_tof"), NTPC, twopart_Pi_tof, N_FT0M); - } - if (N_Ka_tof > 1) { - double mean_Q1_Ka_tof = Q1_Ka_tof / static_cast(N_Ka_tof); - double twopart_Ka_tof = ((Q1_Ka_tof * Q1_Ka_tof) - Q2_Ka_tof) / (static_cast(N_Ka_tof) * (static_cast(N_Ka_tof) - 1)); - hist.fill(HIST("Analysis/Kaon/h_mean_Q1_Mult_ka_tof"), NTPC, mean_Q1_Ka_tof, N_FT0M); - hist.fill(HIST("Analysis/Kaon/h_twopart_Mult_ka_tof"), NTPC, twopart_Ka_tof, N_FT0M); - } - if (N_Pr_tof > 1) { - double mean_Q1_Pr_tof = Q1_Pr_tof / static_cast(N_Pr_tof); - double twopart_Pr_tof = ((Q1_Pr_tof * Q1_Pr_tof) - Q2_Pr_tof) / (static_cast(N_Pr_tof) * (static_cast(N_Pr_tof) - 1)); - hist.fill(HIST("Analysis/Proton/h_mean_Q1_Mult_pr_tof"), NTPC, mean_Q1_Pr_tof, N_FT0M); - hist.fill(HIST("Analysis/Proton/h_twopart_Mult_pr_tof"), NTPC, twopart_Pr_tof, N_FT0M); - } - } -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{adaptAnalysisTask(cfgc)}; -} diff --git a/PWGCF/EbyEFluctuations/Tasks/IdentifiedMeanPtFluctuations.cxx b/PWGCF/EbyEFluctuations/Tasks/IdentifiedMeanPtFluctuations.cxx new file mode 100644 index 00000000000..2727876e236 --- /dev/null +++ b/PWGCF/EbyEFluctuations/Tasks/IdentifiedMeanPtFluctuations.cxx @@ -0,0 +1,388 @@ +// 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 Sweta Singh (sweta.singh@cern.ch) + +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/Core/trackUtilities.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/Centrality.h" +#include "CommonConstants/MathConstants.h" +#include "Common/DataModel/FT0Corrected.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/RunningWorkflowInfo.h" +#include "PWGCF/Core/CorrelationContainer.h" +#include "PWGCF/Core/PairCuts.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace std; + +namespace o2::aod +{ +using MyCollisions = soa::Join; +using MyTracks = soa::Join; + +using MyCollision = MyCollisions::iterator; +using MyTrack = MyTracks::iterator; +} // namespace o2::aod + +struct IdentifiedMeanPtFluctuations { + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + void init(o2::framework::InitContext&) + { + AxisSpec vtxZAxis = {100, -20, 20, "Z (cm)"}; + AxisSpec dcaAxis = {1002, -5.01, 5.01, "DCA_{xy} (cm)"}; + AxisSpec ptAxis = {40, 0.0, 4.0, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec pAxis = {40, 0.0, 4.0, "#it{p} (GeV/#it{c})"}; + AxisSpec betaAxis = {200, 0.0, 2.0, "TOF_{#beta} (GeV/#it{c})"}; + AxisSpec dEdxAxis = {2000, 0.0, 200.0, "dE/dx (GeV/#it{c})"}; + AxisSpec etaAxis = {100, -1.5, 1.5, "#eta"}; + AxisSpec nSigmaTPCAxis = {100, -5., 5., "n#sigma_{TPC}^{proton}"}; + AxisSpec nSigmaTPCAxispid = {110, -5.5, 5.5, "n#sigma_{TPC}"}; + AxisSpec nSigmaTOFAxispid = {110, -5.5, 5.5, "n#sigma_{TOF}"}; + AxisSpec nChAxis = {2500, -0.5, 2499.5, "nCh"}; + AxisSpec centAxis = {20, 0., 100., "centrality"}; + AxisSpec subAxis = {30, 0., 30., "sample"}; + AxisSpec nchAxis = {3200, 0., 3200., "nch"}; + AxisSpec varAxis1 = {6000, 0., 6., "var1"}; + AxisSpec varAxis2 = {600, 0., 6., "var2"}; + + // QA Plots + histos.add("hZvtx_before_sel", "hZvtx_before_sel", kTH1F, {vtxZAxis}); + histos.add("hZvtx_after_sel", "hZvtx_after_sel", kTH1F, {vtxZAxis}); + histos.add("hZvtx_after_sel8", "hZvtx_after_sel8", kTH1F, {vtxZAxis}); + histos.add("hP", "hP", kTH1F, {pAxis}); + histos.add("hEta", ";hEta", kTH1F, {etaAxis}); + histos.add("hPt", ";#it{p}_{T} (GeV/#it{c})", kTH1F, {ptAxis}); + histos.add("hNsigmaTPC", "hNsigmaTPC", kTH2F, + {pAxis, nSigmaTPCAxis}); + histos.add("hPtDCAxy", "hPtDCAxy", kTH2F, {ptAxis, dcaAxis}); + histos.add("hPtDCAz", "hPtDCAz", kTH2F, {ptAxis, dcaAxis}); + histos.add("NSigamaTPCpion", "NSigamaTPCpion", kTH2F, {ptAxis, nSigmaTPCAxispid}); + histos.add("NSigamaTPCkaon", "NSigamaTPCkaon", kTH2F, {ptAxis, nSigmaTPCAxispid}); + histos.add("NSigamaTPCproton", "NSigamaTPCproton", kTH2F, {ptAxis, nSigmaTPCAxispid}); + + histos.add("NSigamaTOFpion", "NSigamaTOFpion", kTH2F, {ptAxis, nSigmaTOFAxispid}); + histos.add("NSigamaTOFkaon", "NSigamaTOFkaon", kTH2F, {ptAxis, nSigmaTOFAxispid}); + histos.add("NSigamaTOFproton", "NSigamaTOFproton", kTH2F, {ptAxis, nSigmaTOFAxispid}); + + histos.add("NSigamaTPCTOFpion", "NSigamaTPCTOFpion", kTH2F, {nSigmaTPCAxispid, nSigmaTOFAxispid}); + histos.add("NSigamaTPCTOFkaon", "NSigamaTPCTOFkaon", kTH2F, {nSigmaTPCAxispid, nSigmaTOFAxispid}); + histos.add("NSigamaTPCTOFproton", "NSigamaTPCTOFproton", kTH2F, {nSigmaTPCAxispid, nSigmaTOFAxispid}); + + histos.add("hPtPion", ";#it{p}_{T} (GeV/#it{c})", kTH1F, {ptAxis}); + histos.add("hPtKaon", ";#it{p}_{T} (GeV/#it{c})", kTH1F, {ptAxis}); + histos.add("hPtProton", ";#it{p}_{T} (GeV/#it{c})", kTH1F, {ptAxis}); + + histos.add("hEtaPion", ";hEta", kTH1F, {etaAxis}); + histos.add("hEtaKaon", ";hEta", kTH1F, {etaAxis}); + histos.add("hEtaProton", ";hEta", kTH1F, {etaAxis}); + + histos.add("hPtCh", "hPtCh", kTH2F, {nchAxis, ptAxis}); + histos.add("hPtChPion", "hPtChPion", kTH2F, {nchAxis, ptAxis}); + histos.add("hPtChKaon", "hPtChKaon", kTH2F, {nchAxis, ptAxis}); + histos.add("hPtChProton", "hPtChProton", kTH2F, {nchAxis, ptAxis}); + + histos.add("hMeanPtCh", "hMeanPtCh", kTH2F, {nChAxis, ptAxis}); + histos.add("hCent", "hCent", kTH2F, {nChAxis, centAxis}); + + histos.add("hVar1", "hVar1", kTH2F, {centAxis, varAxis1}); + histos.add("hVar2", "hVar2", kTH2F, {centAxis, varAxis2}); + histos.add("hVar", "hVar", kTH2F, {subAxis, centAxis}); + + histos.add("hVar1pi", "hVar1pi", kTH2F, {centAxis, varAxis1}); + histos.add("hVar2pi", "hVar2pi", kTH2F, {centAxis, varAxis2}); + histos.add("hVarpi", "hVarpi", kTH2F, {subAxis, centAxis}); + + histos.add("hVar1k", "hVar1k", kTH2F, {centAxis, varAxis1}); + histos.add("hVar2k", "hVar2k", kTH2F, {centAxis, varAxis2}); + histos.add("hVark", "hVark", kTH2F, {subAxis, centAxis}); + + histos.add("hVar1p", "hVar1p", kTH2F, {centAxis, varAxis1}); + histos.add("hVar2p", "hVar2p", kTH2F, {centAxis, varAxis2}); + histos.add("hVarp", "hVarp", kTH2F, {subAxis, centAxis}); + + //--------------------------------nch---------------------------------- + histos.add("hVar1x", "hVar1x", kTH2F, {nchAxis, varAxis1}); + histos.add("hVar2x", "hVar2x", kTH2F, {nchAxis, varAxis2}); + histos.add("hVarx", "hVarx", kTH2F, {subAxis, nchAxis}); + + histos.add("hVar1pix", "hVar1pix", kTH2F, {nchAxis, varAxis1}); + histos.add("hVar2pix", "hVar2pix", kTH2F, {nchAxis, varAxis2}); + histos.add("hVarpix", "hVarpix", kTH2F, {subAxis, nchAxis}); + + histos.add("hVar1kx", "hVar1kx", kTH2F, {nchAxis, varAxis1}); + histos.add("hVar2kx", "hVar2kx", kTH2F, {nchAxis, varAxis2}); + histos.add("hVarkx", "hVarkx", kTH2F, {subAxis, nchAxis}); + + histos.add("hVar1px", "hVar1px", kTH2F, {nchAxis, varAxis1}); + histos.add("hVar2px", "hVar2px", kTH2F, {nchAxis, varAxis2}); + histos.add("hVarpx", "hVarpx", kTH2F, {subAxis, nchAxis}); + + histos.add("ht", "ht", kTH1F, {centAxis}); + + histos.add("hCentrality", "hCentrality", kTH1F, {centAxis}); + + histos.add("hPEta", "hPEta", kTH2F, {pAxis, etaAxis}); + histos.add("hPtEta", "hPtEta", kTH2F, {ptAxis, etaAxis}); + histos.add("hPy", "hPy", kTH2F, {pAxis, etaAxis}); + histos.add("hPty", "hPty", kTH2F, {ptAxis, etaAxis}); + + histos.add("hTOFbeta", "hTOFbeta", kTH2F, {pAxis, betaAxis}); + histos.add("hdEdx", "hdEdx", kTH2F, {pAxis, dEdxAxis}); + } + + void process(aod::MyCollision const& coll, aod::MyTracks const& inputTracks) + + { + + histos.fill(HIST("hZvtx_before_sel"), coll.posZ()); + if (fabs(coll.posZ()) > 10.f) { + return; + } + histos.fill(HIST("hZvtx_after_sel"), coll.posZ()); + + if (!coll.sel8()) { + return; + } + histos.fill(HIST("hZvtx_after_sel8"), coll.posZ()); + + const auto cent = coll.centFT0C(); + histos.fill(HIST("hCentrality"), cent); + + float nCh = 0.; + float nChpi = 0.; + float nChk = 0.; + float nChp = 0.; + std::vector VMeanPt; + std::vector VMeanPtPion; + std::vector VMeanPtKaon; + std::vector VMeanPtProton; + + float Q1 = 0, Q2 = 0; + float Q1pi = 0, Q2pi = 0; + float Q1k = 0, Q2k = 0; + float Q1p = 0, Q2p = 0; + float var1, var2; + float var1pi, var2pi; + float var1k, var2k; + float var1p, var2p; + + int sample = histos.get(HIST("hZvtx_before_sel"))->GetEntries(); + sample = sample % 30; + + // Perfroming the track selection============================================================================================================== + for (auto track : inputTracks) { + // Loop over tracks + + if (!track.isGlobalTrack()) + return; + + if (!((fabs(track.eta()) < 0.8) && (fabs(track.dcaXY()) < 0.12) && (fabs(track.dcaZ()) < 1.) && (track.pt() > 0.15 && track.pt() < 2.))) { + continue; + } + + nCh += 1.; + + Q1 += track.pt(); + Q2 += (track.pt() * track.pt()); + + histos.fill(HIST("hP"), track.p()); + histos.fill(HIST("hPt"), track.pt()); + histos.fill(HIST("hEta"), track.eta()); + histos.fill(HIST("hPtDCAxy"), track.pt(), track.dcaXY()); + histos.fill(HIST("hPtDCAz"), track.pt(), track.dcaZ()); + + histos.fill(HIST("hPtEta"), track.pt(), track.eta()); + histos.fill(HIST("hPEta"), track.p(), track.eta()); + + VMeanPt.push_back(track.pt()); + + histos.fill(HIST("hNsigmaTPC"), track.p(), track.tpcNSigmaPr()); + + // only TPC tracks: Pion, Kaon, Proton + if (track.hasTPC() && abs(track.tpcNSigmaPi()) < 2.) + histos.fill(HIST("NSigamaTPCpion"), track.pt(), track.tpcNSigmaPi()); + if (track.hasTPC() && abs(track.tpcNSigmaKa()) < 2.) + histos.fill(HIST("NSigamaTPCkaon"), track.pt(), track.tpcNSigmaKa()); + if (track.hasTPC() && abs(track.tpcNSigmaPr()) < 2.) + histos.fill(HIST("NSigamaTPCproton"), track.pt(), track.tpcNSigmaPr()); + + // only TOF tracks: Pion, Kaon, Proton + if (track.hasTOF() && abs(track.tofNSigmaPi()) < 2.) + histos.fill(HIST("NSigamaTOFpion"), track.pt(), track.tofNSigmaPi()); + if (track.hasTOF() && abs(track.tofNSigmaKa()) < 2.) + histos.fill(HIST("NSigamaTOFkaon"), track.pt(), track.tofNSigmaKa()); + if (track.hasTOF() && abs(track.tofNSigmaPr()) < 2.) + histos.fill(HIST("NSigamaTOFproton"), track.pt(), track.tofNSigmaPr()); + + if (track.hasTPC()) + histos.fill(HIST("hdEdx"), track.p(), track.tpcSignal()); + if (track.hasTOF()) + histos.fill(HIST("hTOFbeta"), track.p(), track.beta()); + + // only TPC+TOF tracks: Pion, Kaon, Proton + if ((track.hasTPC() && abs(track.tpcNSigmaPi()) < 2.) && (track.hasTOF() && abs(track.tofNSigmaPi()) < 2.)) + histos.fill(HIST("NSigamaTPCTOFpion"), track.tpcNSigmaPi(), track.tofNSigmaPi()); + + if ((track.hasTPC() && abs(track.tpcNSigmaPi()) < 2. && (track.pt() > 0.2 && track.pt() < 0.5))) + histos.fill(HIST("hPtPion"), track.pt()); + + { + if ((track.hasTPC() && (track.pt() >= 0.5 && track.pt() < 2.0)) && (track.hasTOF() && abs(sqrt(track.tpcNSigmaPi()) * (track.tpcNSigmaPi()) + (track.tofNSigmaPi()) * (track.tofNSigmaPi())) < 2.)) { + + histos.fill(HIST("hPtPion"), track.pt()); + histos.fill(HIST("hEtaPion"), track.eta()); + + VMeanPtPion.push_back(track.pt()); + + for (ULong64_t jPi = 0; jPi < VMeanPtPion.size(); jPi++) { + histos.fill(HIST("hPtChPion"), nCh, VMeanPtPion[jPi]); + } + + nChpi += 1.; + Q1pi += track.pt(); + Q2pi += (track.pt() * track.pt()); + } + } + + if ((track.hasTPC() && abs(track.tpcNSigmaKa()) < 2.) && (track.hasTOF() && abs(track.tofNSigmaKa()) < 2.)) + histos.fill(HIST("NSigamaTPCTOFkaon"), track.tpcNSigmaKa(), track.tofNSigmaKa()); + + if ((track.hasTPC() && abs(track.tpcNSigmaKa()) < 2. && (track.pt() > 0.2 && track.pt() < 0.5))) + histos.fill(HIST("hPtKaon"), track.pt()); + { + if ((track.hasTPC() && (track.pt() >= 0.5 && track.pt() < 2.0)) && (track.hasTOF() && abs(sqrt(track.tpcNSigmaKa()) * (track.tpcNSigmaKa()) + (track.tofNSigmaKa()) * (track.tofNSigmaKa())) < 2.)) { + + histos.fill(HIST("hPtKaon"), track.pt()); + histos.fill(HIST("hEtaKaon"), track.eta()); + + VMeanPtKaon.push_back(track.pt()); + + for (ULong64_t jKa = 0; jKa < VMeanPtKaon.size(); jKa++) { + histos.fill(HIST("hPtChKaon"), nCh, VMeanPtKaon[jKa]); + } + + nChk += 1.; + Q1k += track.pt(); + Q2k += (track.pt() * track.pt()); + } + } + + if ((track.hasTPC() && abs(track.tpcNSigmaPr()) < 2.) && (track.hasTOF() && abs(track.tofNSigmaPr()) < 2.)) + histos.fill(HIST("NSigamaTPCTOFproton"), track.tpcNSigmaPr(), track.tofNSigmaPr()); + + if ((track.hasTPC() && abs(track.tpcNSigmaPr()) < 2. && (track.pt() > 0.4 && track.pt() < 0.6))) + histos.fill(HIST("hPtProton"), track.pt()); + { + if ((track.hasTPC() && (track.pt() >= 0.6 && track.pt() < 2.0)) && (track.hasTOF() && abs(sqrt(track.tpcNSigmaPr()) * (track.tpcNSigmaPr()) + (track.tofNSigmaPr()) * (track.tofNSigmaPr())) < 2.)) { + + histos.fill(HIST("hPtProton"), track.pt()); + histos.fill(HIST("hEtaProton"), track.eta()); + + VMeanPtProton.push_back(track.pt()); + + for (ULong64_t jPr = 0; jPr < VMeanPtProton.size(); jPr++) { + histos.fill(HIST("hPtChProton"), nCh, VMeanPtProton[jPr]); + } + + nChp += 1.; + Q1p += track.pt(); + Q2p += (track.pt() * track.pt()); + } + } + } + // Track loop ends! + VMeanPtPion.clear(); + VMeanPtKaon.clear(); + VMeanPtProton.clear(); + + if (nCh < 2) + return; + + //------------------ all charges------------------------------------- + var1 = (Q1 * Q1 - Q2) / (nCh * (nCh - 1)); + histos.fill(HIST("hVar1"), cent, var1); + var2 = (Q1 / nCh); + histos.fill(HIST("hVar2"), cent, var2); + histos.fill(HIST("hVar"), sample, cent); + + //---------------------- pions ---------------------------------------- + + var1pi = (Q1pi * Q1pi - Q2pi) / (nChpi * (nChpi - 1)); + histos.fill(HIST("hVar1pi"), cent, var1pi); + var2pi = (Q1pi / nChpi); + histos.fill(HIST("hVar2pi"), cent, var2pi); + + //----------------------- kaons --------------------------------------- + + var1k = (Q1k * Q1k - Q2k) / (nChk * (nChk - 1)); + histos.fill(HIST("hVar1k"), cent, var1k); + var2k = (Q1k / nChk); + histos.fill(HIST("hVar2k"), cent, var2k); + + //---------------------------- protons ---------------------------------- + + var1p = (Q1p * Q1p - Q2p) / (nChp * (nChp - 1)); + histos.fill(HIST("hVar1p"), cent, var1p); + var2p = (Q1p / nChp); + histos.fill(HIST("hVar2p"), cent, var2p); + + //-----------------------nch------------------------------------- + histos.fill(HIST("hVar1x"), nCh, var1); + histos.fill(HIST("hVar2x"), nCh, var2); + histos.fill(HIST("hVarx"), sample, nCh); + + histos.fill(HIST("hVar1pix"), nCh, var1pi); + histos.fill(HIST("hVar2pix"), nCh, var2pi); + histos.fill(HIST("hVarpix"), sample, nChpi); + + histos.fill(HIST("hVar1kx"), nCh, var1k); + histos.fill(HIST("hVar2kx"), nCh, var2k); + histos.fill(HIST("hVarkx"), sample, nChk); + + histos.fill(HIST("hVar1px"), nCh, var1p); + histos.fill(HIST("hVar2px"), nCh, var2p); + histos.fill(HIST("hVarpx"), sample, nChp); + + for (ULong64_t j = 0; j < VMeanPt.size(); j++) { + histos.fill(HIST("hPtCh"), nCh, VMeanPt[j]); + } + + VMeanPt.clear(); + + } // event loop ends! +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{adaptAnalysisTask(cfgc)}; + return workflow; +} diff --git a/PWGCF/EbyEFluctuations/Tasks/MeanPtFlucIdentified.cxx b/PWGCF/EbyEFluctuations/Tasks/MeanPtFlucIdentified.cxx new file mode 100644 index 00000000000..69fd424d532 --- /dev/null +++ b/PWGCF/EbyEFluctuations/Tasks/MeanPtFlucIdentified.cxx @@ -0,0 +1,560 @@ +// 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 MeanPtFlucIdentified.cxx +/// \brief Calculate EbyE fluctuations with moments method. +/// For charged particles and identified particles. +/// +/// \author Tanu Gahlaut + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/HistogramSpec.h" + +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/Centrality.h" + +#include "TDatabasePDG.h" +#include "TLorentzVector.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace std; + +double massPi = TDatabasePDG::Instance()->GetParticle(211)->Mass(); +double massKa = TDatabasePDG::Instance()->GetParticle(321)->Mass(); +double massPr = TDatabasePDG::Instance()->GetParticle(2212)->Mass(); + +struct meanPtFlucId { + Configurable nPtBins{"nPtBins", 300, ""}; + Configurable nPartBins{"nPartBins", 500, ""}; + Configurable nCentBins{"nCentBins", 101, ""}; + Configurable nEtaBins{"nEtaBins", 100, ""}; + Configurable ptMax{"ptMax", 2.0, "maximum pT"}; + Configurable ptMin{"ptMin", 0.15, "minimum pT"}; + Configurable etaCut{"etaCut", 0.8, "Eta cut"}; + Configurable rapCut{"rapCut", 0.5, "Rapidity Cut"}; + Configurable dcaXYCut{"dcaXYCut", 0.12, "DCAxy cut"}; + Configurable dcaZCut{"dcaZCut", 1.0, "DCAz cut"}; + Configurable posZCut{"posZCut", 10.0, "cut for vertex Z"}; + Configurable nSigCut1{"nSigCut1", 1.0, "nSigma cut (1)"}; + Configurable nSigCut2{"nSigCut2", 2.0, "nSigma cut (2)"}; + Configurable nSigCut3{"nSigCut3", 3.0, "nSigma cut (3)"}; + Configurable nSigCut4{"nSigCut4", 4.0, "nSigma cut (4)"}; + Configurable nSigCut5{"nSigCut5", 5.0, "nSigma cut (5)"}; + Configurable nSigCut15{"nSigCut15", 1.5, "nSigma cut (1.5)"}; + Configurable nSigCut25{"nSigCut25", 2.5, "nSigma cut (2.5)"}; + Configurable piP1{"piP1", 0.65, "pion p (1)"}; + Configurable piP2{"piP2", 0.70, "pion p (2)"}; + Configurable piP3{"piP3", 1.40, "pion p (3)"}; + Configurable piP4{"piP4", 1.70, "pion p (4)"}; + Configurable kaP1{"kaP1", 0.20, "min kaon p (1)"}; + Configurable kaP2{"kaP2", 0.5, "kaon p (2)"}; + Configurable kaP3{"kaP3", 0.55, "kaon p (3)"}; + Configurable kaP4{"kaP4", 0.60, "kaon p (4)"}; + Configurable kaP5{"kaP5", 0.65, "kaon p (5)"}; + Configurable kaP6{"kaP6", 1.10, "kaon p (6)"}; + Configurable kaP7{"kaP7", 1.28, "kaon p (7)"}; + Configurable kaP8{"kaP8", 1.50, "kaon p (8)"}; + Configurable prP1{"prP1", 0.40, "min proton p (1)"}; + Configurable prP2{"prP2", 0.95, "proton p (2)"}; + Configurable prP3{"prP3", 1.00, "proton p (3)"}; + Configurable prP4{"prP4", 1.05, "proton p (4)"}; + Configurable prP5{"prP5", 1.13, "proton p (5)"}; + Configurable prP6{"prP6", 1.18, "proton p (6)"}; + ConfigurableAxis multTPCBins{"multTPCBins", {150, 0, 150}, "TPC Multiplicity bins"}; + ConfigurableAxis multFT0MBins{"multFT0MBins", {150, 0, 10000}, "Forward Multiplicity bins"}; + ConfigurableAxis dcaXYBins{"dcaXYBins", {100, -0.15, 0.15}, "dcaXY bins"}; + ConfigurableAxis dcaZBins{"dcaZBins", {100, -1.2, 1.2}, "dcaZ bins"}; + + using MyAllTracks = soa::Join; + using MyRun2Collisions = soa::Join; + using MyRun3Collisions = soa::Join; + + HistogramRegistry hist{"hist", {}, OutputObjHandlingPolicy::AnalysisObject}; + void init(InitContext const&) + { + const AxisSpec axisEvents{5, 0, 5, "Counts"}; + const AxisSpec axisEta{nEtaBins, -1., +1., "#eta"}; + const AxisSpec axisY{nEtaBins, -1., +1., "Rapidity"}; + const AxisSpec axisPt{nPtBins, 0., 3., "p_{T} (GeV/c)"}; + const AxisSpec axisP{nPtBins, 0., 3., "p (GeV/c)"}; + const AxisSpec axisPart{nPartBins, 0., 5., " "}; + const AxisSpec axisMeanPt{100, 0., 3., "M(p_{T}) (GeV/c)"}; + const AxisSpec axisMult{100, 0, 100, "N_{ch}"}; + const AxisSpec axisMultTPC{multTPCBins, "N_{TPC} "}; + const AxisSpec axisMultFT0M{multFT0MBins, "N_{FT0M}"}; + const AxisSpec axisCentFT0M{nCentBins, 0, 101, "FT0M (%)"}; + const AxisSpec axisVtxZ{80, -20., 20., "V_{Z} (cm)"}; + const AxisSpec axisDCAz{dcaZBins, "DCA_{Z} (cm)"}; + const AxisSpec axisDCAxy{dcaXYBins, "DCA_{XY} (cm)"}; + const AxisSpec axisTPCNsigma{500, -5., 5., "n #sigma_{TPC}"}; + const AxisSpec axisTOFNsigma{500, -5., 5., "n #sigma_{TOF}"}; + const AxisSpec axisTPCSignal{180, 20., 200., "#frac{dE}{dx}"}; + const AxisSpec axisTOFSignal{100, 0.2, 1.2, "TOF #beta"}; + const AxisSpec axisChi2{50, 0., 50., "Chi2"}; + const AxisSpec axisCrossedTPC{500, 0, 500, "Crossed TPC"}; + + HistogramConfigSpec QnHist({HistType::kTHnSparseD, {axisMultTPC, axisPart, axisCentFT0M}}); + HistogramConfigSpec TOFnSigmaHist({HistType::kTH2D, {axisP, axisTOFNsigma}}); + HistogramConfigSpec TOFSignalHist({HistType::kTH2D, {axisP, axisTOFSignal}}); + HistogramConfigSpec TPCnSigmaHist({HistType::kTH2D, {axisP, axisTPCNsigma}}); + HistogramConfigSpec TPCSignalHist({HistType::kTH2D, {axisP, axisTPCSignal}}); + HistogramConfigSpec TPCTOFHist({HistType::kTH2D, {axisTPCNsigma, axisTOFNsigma}}); + + // QA Plots: + hist.add("QA/before/h_Counts", "Counts", kTH1D, {axisEvents}); + hist.add("QA/before/h_VtxZ", "V_{Z}", kTH1D, {axisVtxZ}); + hist.add("QA/before/h_TPCChi2perCluster", "TPC #Chi^{2}/Cluster", kTH1D, {axisChi2}); + hist.add("QA/before/h_ITSChi2perCluster", "ITS #Chi^{2}/Cluster", kTH1D, {axisChi2}); + hist.add("QA/before/h_crossedTPC", "Crossed TPC", kTH1D, {axisCrossedTPC}); + hist.add("QA/before/h_Pt", "p_{T}", kTH1D, {axisPt}); + hist.add("QA/before/h_Eta", "#eta ", kTH1D, {axisEta}); + hist.add("QA/before/h2_Pt_Eta", "p_{T} vs #eta ", kTH2D, {{axisEta}, {axisPt}}); + hist.add("QA/before/h2_DcaZ", "DCA_{Z}", kTH2D, {{axisPt}, {axisDCAz}}); + hist.add("QA/before/h2_DcaXY", "DCA_{XY}", kTH2D, {{axisPt}, {axisDCAxy}}); + hist.add("QA/before/h_NTPC", "N_{TPC}", kTH1D, {axisMultTPC}); + hist.add("QA/before/h_NFT0M", "FT0M Multiplicity", kTH1D, {axisMultFT0M}); + hist.add("QA/before/h_Cent", "FT0M (%)", kTH1D, {axisCentFT0M}); + hist.add("QA/before/h2_NTPC_Cent", "N_{TPC} vs FT0M(%)", kTH2D, {{axisCentFT0M}, {axisMultTPC}}); + hist.add("QA/before/h2_NTPC_NFT0M", "N_{TPC} vs N_{FT0M}", kTH2D, {{axisMultFT0M}, {axisMultTPC}}); + hist.add("QA/before/h2_TPCSignal", "TPC Signal", TPCSignalHist); + hist.add("QA/before/h2_TOFSignal", "TOF Signal", TOFSignalHist); + + hist.addClone("QA/before/", "QA/after/"); + + hist.add("QA/after/p_NTPC_NFT0M", "N_{TPC} vs N_{FT0M} (Profile)", kTProfile, {{axisMultFT0M}}); + hist.add("QA/after/p_NFT0M_NTPC", "N_{FT0M} vs N_{TPC} (Profile)", kTProfile, {{axisMultTPC}}); + hist.add("QA/after/p_NTPC_Cent", "N_{TPC} vs FT0M(%) (Profile)", kTProfile, {{axisCentFT0M}}); + hist.add("QA/after/h2_NTPC_Nch", "N_{ch} vs N_{TPC}", kTH2D, {{axisMultTPC}, {axisMult}}); + + hist.add("QA/Pion/h_Pt", "p_{T} (TPC & TPC+TOF)", kTH1D, {axisPt}); + hist.add("QA/Pion/h_rap", "y (TPC & TPC+TOF)", kTH1D, {axisY}); + hist.add("QA/Pion/h2_Pt_rap", "p_{T} vs y", kTH2D, {{axisY}, {axisPt}}); + hist.add("QA/Pion/h2_DcaZ", "DCA_{z}", kTH2D, {{axisPt}, {axisDCAz}}); + hist.add("QA/Pion/h2_DcaXY", "DCA_{xy}", kTH2D, {{axisPt}, {axisDCAxy}}); + hist.add("QA/Pion/before/h2_TPCNsigma", "n #sigma_{TPC}", TPCnSigmaHist); + hist.add("QA/Pion/before/h2_TOFNsigma", "n #sigma_{TOF}", TOFnSigmaHist); + hist.add("QA/Pion/before/h2_TpcTofNsigma", "n #sigma_{TPC} vs n #sigma_{TOF}", TPCTOFHist); + hist.add("QA/Pion/h2_TPCNsigma", "n #sigma_{TPC}", TPCnSigmaHist); + hist.add("QA/Pion/h2_TOFNsigma", "n #sigma_{TOF}", TOFnSigmaHist); + hist.add("QA/Pion/h2_TpcTofNsigma", "n #sigma_{TPC} vs n #sigma_{TOF}", TPCTOFHist); + hist.add("QA/Pion/h2_TPCSignal", "TPC Signal Pions", TPCSignalHist); + hist.add("QA/Pion/h2_TOFSignal", "TOF Signal Pions", TOFSignalHist); + hist.add("QA/Pion/h2_ExpTPCSignal", "Expected TPC Signal Pions", TPCSignalHist); + + hist.addClone("QA/Pion/", "QA/Kaon/"); + hist.addClone("QA/Pion/", "QA/Proton/"); + + // Analysis Plots: + hist.add("Analysis/Charged/h_Mult", "Multiplicity", kTH1D, {axisMult}); + hist.add("Analysis/Charged/h_mean_Q1", " ", kTH1D, {axisMeanPt}); + hist.add("Analysis/Charged/p_mean_Q1", " ", kTProfile, {axisMult}); + hist.add("Analysis/Charged/h_mean_Q1_Mult", " vs N_{ch} ", QnHist); + hist.add("Analysis/Charged/h_twopart_Mult", "Twopart vs N_{ch} ", QnHist); + hist.add("Analysis/Charged/h_threepart_Mult", "Threepart vs N_{ch} ", QnHist); + hist.add("Analysis/Charged/h_fourpart_Mult", "Fourpart vs N_{ch} ", QnHist); + + hist.addClone("Analysis/Charged/", "Analysis/Pion/"); + hist.addClone("Analysis/Charged/", "Analysis/Kaon/"); + hist.addClone("Analysis/Charged/", "Analysis/Proton/"); + } + + template + bool selRun2Col(T const& col) + { + if (std::abs(col.posZ()) > posZCut) + return false; + + if (!col.sel7()) + return false; + + if (!col.alias_bit(kINT7)) + return false; + + return true; + } + + template + bool selRun3Col(T const& col) + { + if (std::abs(col.posZ()) > posZCut) + return false; + + if (!col.sel8()) + return false; + + return true; + } + + template + bool selTrack(T const& track) + { + + if (track.pt() < ptMin) + return false; + + if (track.pt() > ptMax) + return false; + + if (std::abs(track.eta()) > etaCut) + return false; + + if (std::abs(track.dcaZ()) > dcaZCut) + return false; + + if (std::abs(track.dcaXY()) > dcaXYCut) + return false; + + if (!track.isGlobalTrack()) + return false; + + return true; + } + + template + bool selPions(T const& track) + { + if (((!track.hasTOF()) && + ((std::abs(track.tpcNSigmaPi()) < nSigCut3 && track.p() <= piP1) || (std::abs(track.tpcNSigmaPi()) < nSigCut2 && track.p() > piP1 && track.p() <= piP2))) || + (track.hasTOF() && std::abs(track.tpcNSigmaPi()) < nSigCut4 && std::abs(track.tofNSigmaEl()) > nSigCut1 && + ((std::abs(track.tofNSigmaPi()) < nSigCut3 && track.p() <= piP3) || (std::abs(track.tofNSigmaPi()) < nSigCut25 && track.p() > piP3 && track.p() <= piP4) || (std::abs(track.tofNSigmaPi()) < nSigCut2 && track.p() > piP4)))) { + if (abs(track.rapidity(massPi)) < 0.5) + return true; + } + + return false; + } + + template + bool selKaons(T const& track) + { + if (((!track.hasTOF()) && + ((std::abs(track.tpcNSigmaKa()) < nSigCut3 && track.pt() > kaP1 && track.p() <= kaP2) || (std::abs(track.tpcNSigmaKa()) < nSigCut25 && track.p() > kaP2 && track.p() <= kaP3) || (std::abs(track.tpcNSigmaKa()) < nSigCut2 && track.p() > kaP3 && track.p() <= kaP4) || (std::abs(track.tpcNSigmaKa()) < nSigCut15 && track.p() > kaP4 && track.p() <= kaP5))) || + (track.hasTOF() && std::abs(track.tpcNSigmaKa()) < nSigCut4 && std::abs(track.tofNSigmaEl()) > nSigCut1 && + ((std::abs(track.tofNSigmaKa()) < nSigCut3 && track.pt() > kaP1 && track.p() <= kaP6) || (std::abs(track.tofNSigmaKa()) < nSigCut2 && track.p() > kaP6 && track.p() <= kaP7) || (std::abs(track.tofNSigmaKa()) < nSigCut15 && track.p() > kaP7 && track.p() <= kaP8) || (std::abs(track.tofNSigmaKa()) < nSigCut1 && track.p() > kaP8)))) { + if (abs(track.rapidity(massKa)) < 0.5) + return true; + } + + return false; + } + + template + bool selProtons(T const& track) + { + if (((!track.hasTOF()) && + ((std::abs(track.tpcNSigmaPr()) < nSigCut3 && track.pt() > prP1 && track.p() <= prP2) || (std::abs(track.tpcNSigmaPr()) < nSigCut25 && track.p() > prP2 && track.p() <= prP3) || (std::abs(track.tpcNSigmaPr()) < nSigCut2 && track.p() > prP3 && track.p() <= prP4) || (std::abs(track.tpcNSigmaPr()) < nSigCut15 && track.p() > prP4 && track.p() <= prP5) || (std::abs(track.tpcNSigmaPr()) < nSigCut1 && track.p() > prP5 && track.p() <= prP6))) || + (track.hasTOF() && std::abs(track.tpcNSigmaPr()) < nSigCut4 && std::abs(track.tofNSigmaEl()) > nSigCut1 && std::abs(track.tofNSigmaPr()) < nSigCut3 && track.pt() > prP1)) { + if (abs(track.rapidity(massPr)) < 0.5) + return true; + } + + return false; + } + + void moments(double pt, double* Q1, double* Q2, double* Q3, double* Q4) + { + *Q1 += pt; + *Q2 += pt * pt; + *Q3 += pt * pt * pt; + *Q4 += pt * pt * pt * pt; + } + + void parts(double Q1, double Q2, double Q3, double Q4, int N, double* mean_Q1, double* twopart, double* threepart, double* fourpart) + { + if (N > 1) { + *mean_Q1 = Q1 / static_cast(N); + *twopart = ((Q1 * Q1) - Q2) / (static_cast(N) * (static_cast(N) - 1)); + } + if (N > 2) { + *threepart = ((Q1 * Q1 * Q1) - (3 * Q2 * Q1) + 2 * Q3) / (static_cast(N) * (static_cast(N) - 1) * (static_cast(N) - 2)); + } + if (N > 3) { + *fourpart = ((Q1 * Q1 * Q1 * Q1) - (6 * Q2 * Q1 * Q1) + (3 * Q2 * Q2) + (8 * Q3 * Q1) - 6 * Q4) / (static_cast(N) * (static_cast(N) - 1) * (static_cast(N) - 2) * (static_cast(N) - 3)); + } + } + + template + void FillHistos(T const& col, U const& tracks, double Cent_FT0M, double N_FT0M, int NTPC) + { + int N_Pi = 0, N_Ka = 0, N_Pr = 0; + int Nch = 0; + double pt_ch = 0, Q1_ch = 0, Q2_ch = 0, Q3_ch = 0, Q4_ch = 0; + double pt_Pi = 0, Q1_Pi = 0, Q2_Pi = 0, Q3_Pi = 0, Q4_Pi = 0; + double pt_Pr = 0, Q1_Pr = 0, Q2_Pr = 0, Q3_Pr = 0, Q4_Pr = 0; + double pt_Ka = 0, Q1_Ka = 0, Q2_Ka = 0, Q3_Ka = 0, Q4_Ka = 0; + double mean_Q1_Ch = 0, mean_Q1_Pi = 0, mean_Q1_Ka = 0, mean_Q1_Pr = 0; + double twopart_Ch = 0, twopart_Pi = 0, twopart_Ka = 0, twopart_Pr = 0; + double threepart_Ch = 0, threepart_Pi = 0, threepart_Ka = 0, threepart_Pr = 0; + double fourpart_Ch = 0, fourpart_Pi = 0, fourpart_Ka = 0, fourpart_Pr = 0; + + for (auto& track : tracks) { + if (!selTrack(track)) + continue; + + Nch++; + pt_ch = track.pt(); + moments(pt_ch, &Q1_ch, &Q2_ch, &Q3_ch, &Q4_ch); + + hist.fill(HIST("QA/after/h_Eta"), track.eta()); + hist.fill(HIST("QA/after/h_Pt"), track.pt()); + hist.fill(HIST("QA/after/h2_Pt_Eta"), track.eta(), track.pt()); + hist.fill(HIST("QA/after/h2_DcaXY"), track.pt(), track.dcaXY()); + hist.fill(HIST("QA/after/h2_DcaZ"), track.pt(), track.dcaZ()); + + hist.fill(HIST("QA/after/h_TPCChi2perCluster"), track.tpcChi2NCl()); + hist.fill(HIST("QA/after/h_ITSChi2perCluster"), track.itsChi2NCl()); + hist.fill(HIST("QA/after/h_crossedTPC"), track.tpcNClsCrossedRows()); + + hist.fill(HIST("QA/before/h2_TOFSignal"), track.p(), track.beta()); + hist.fill(HIST("QA/before/h2_TPCSignal"), track.p(), track.tpcSignal()); + + hist.fill(HIST("QA/Pion/before/h2_TPCNsigma"), track.p(), track.tpcNSigmaPi()); + hist.fill(HIST("QA/Pion/before/h2_TOFNsigma"), track.p(), track.tofNSigmaPi()); + hist.fill(HIST("QA/Pion/before/h2_TpcTofNsigma"), track.tpcNSigmaPi(), track.tofNSigmaPi()); + hist.fill(HIST("QA/Proton/before/h2_TPCNsigma"), track.p(), track.tpcNSigmaPr()); + hist.fill(HIST("QA/Proton/before/h2_TOFNsigma"), track.p(), track.tofNSigmaPr()); + hist.fill(HIST("QA/Proton/before/h2_TpcTofNsigma"), track.tpcNSigmaPr(), track.tofNSigmaPr()); + hist.fill(HIST("QA/Kaon/before/h2_TPCNsigma"), track.p(), track.tpcNSigmaKa()); + hist.fill(HIST("QA/Kaon/before/h2_TOFNsigma"), track.p(), track.tofNSigmaKa()); + hist.fill(HIST("QA/Kaon/before/h2_TpcTofNsigma"), track.tpcNSigmaKa(), track.tofNSigmaKa()); + + // For Pions: + if (selPions(track)) { + N_Pi++; + pt_Pi = track.pt(); + moments(pt_Pi, &Q1_Pi, &Q2_Pi, &Q3_Pi, &Q4_Pi); + hist.fill(HIST("QA/Pion/h_Pt"), track.pt()); + hist.fill(HIST("QA/Pion/h_rap"), track.rapidity(massPi)); + hist.fill(HIST("QA/Pion/h2_Pt_rap"), track.rapidity(massPi), track.pt()); + hist.fill(HIST("QA/Pion/h2_DcaXY"), track.pt(), track.dcaXY()); + hist.fill(HIST("QA/Pion/h2_DcaZ"), track.pt(), track.dcaZ()); + + hist.fill(HIST("QA/Pion/h2_TPCNsigma"), track.p(), track.tpcNSigmaPi()); + hist.fill(HIST("QA/Pion/h2_TOFNsigma"), track.p(), track.tofNSigmaPi()); + hist.fill(HIST("QA/Pion/h2_TpcTofNsigma"), track.tpcNSigmaPi(), track.tofNSigmaPi()); + hist.fill(HIST("QA/Pion/h2_TOFSignal"), track.p(), track.beta()); + hist.fill(HIST("QA/Pion/h2_TPCSignal"), track.p(), track.tpcSignal()); + hist.fill(HIST("QA/Pion/h2_ExpTPCSignal"), track.p(), track.tpcExpSignalPi(track.tpcSignal())); + hist.fill(HIST("QA/after/h2_TOFSignal"), track.p(), track.beta()); + hist.fill(HIST("QA/after/h2_TPCSignal"), track.p(), track.tpcSignal()); + } + + // For Kaons: + if (selKaons(track)) { + N_Ka++; + pt_Ka = track.pt(); + moments(pt_Ka, &Q1_Ka, &Q2_Ka, &Q3_Ka, &Q4_Ka); + hist.fill(HIST("QA/Kaon/h_Pt"), track.pt()); + hist.fill(HIST("QA/Kaon/h_rap"), track.rapidity(massKa)); + hist.fill(HIST("QA/Kaon/h2_Pt_rap"), track.rapidity(massKa), track.pt()); + hist.fill(HIST("QA/Kaon/h2_DcaXY"), track.pt(), track.dcaXY()); + hist.fill(HIST("QA/Kaon/h2_DcaZ"), track.pt(), track.dcaZ()); + + hist.fill(HIST("QA/Kaon/h2_TPCNsigma"), track.p(), track.tpcNSigmaKa()); + hist.fill(HIST("QA/Kaon/h2_TOFNsigma"), track.p(), track.tofNSigmaKa()); + hist.fill(HIST("QA/Kaon/h2_TpcTofNsigma"), track.tpcNSigmaKa(), track.tofNSigmaKa()); + hist.fill(HIST("QA/Kaon/h2_TOFSignal"), track.p(), track.beta()); + hist.fill(HIST("QA/Kaon/h2_TPCSignal"), track.p(), track.tpcSignal()); + hist.fill(HIST("QA/Kaon/h2_ExpTPCSignal"), track.p(), track.tpcExpSignalKa(track.tpcSignal())); + hist.fill(HIST("QA/after/h2_TOFSignal"), track.p(), track.beta()); + hist.fill(HIST("QA/after/h2_TPCSignal"), track.p(), track.tpcSignal()); + } + + // For Protons: + if (selProtons(track)) { + N_Pr++; + pt_Pr = track.pt(); + moments(pt_Pr, &Q1_Pr, &Q2_Pr, &Q3_Pr, &Q4_Pr); + hist.fill(HIST("QA/Proton/h_Pt"), track.pt()); + hist.fill(HIST("QA/Proton/h_rap"), track.rapidity(massPr)); + hist.fill(HIST("QA/Proton/h2_Pt_rap"), track.rapidity(massPr), track.pt()); + hist.fill(HIST("QA/Proton/h2_DcaZ"), track.pt(), track.dcaZ()); + hist.fill(HIST("QA/Proton/h2_DcaXY"), track.pt(), track.dcaXY()); + + hist.fill(HIST("QA/Proton/h2_TPCNsigma"), track.p(), track.tpcNSigmaPr()); + hist.fill(HIST("QA/Proton/h2_TOFNsigma"), track.p(), track.tofNSigmaPr()); + hist.fill(HIST("QA/Proton/h2_TpcTofNsigma"), track.tpcNSigmaPr(), track.tofNSigmaPr()); + hist.fill(HIST("QA/Proton/h2_TPCSignal"), track.p(), track.tpcSignal()); + hist.fill(HIST("QA/Proton/h2_TOFSignal"), track.p(), track.beta()); + hist.fill(HIST("QA/Proton/h2_ExpTPCSignal"), track.p(), track.tpcExpSignalPr(track.tpcSignal())); + hist.fill(HIST("QA/after/h2_TPCSignal"), track.p(), track.tpcSignal()); + hist.fill(HIST("QA/after/h2_TOFSignal"), track.p(), track.beta()); + } + } + + hist.fill(HIST("QA/after/h_VtxZ"), col.posZ()); + hist.fill(HIST("QA/after/h_Counts"), 2); + hist.fill(HIST("QA/after/h_NTPC"), NTPC); + hist.fill(HIST("QA/after/h_Cent"), Cent_FT0M); + hist.fill(HIST("QA/after/h_NFT0M"), N_FT0M); + hist.fill(HIST("QA/after/h2_NTPC_NFT0M"), N_FT0M, NTPC); + hist.fill(HIST("QA/after/h2_NTPC_Cent"), Cent_FT0M, NTPC); + hist.fill(HIST("QA/after/p_NTPC_Cent"), Cent_FT0M, NTPC); + hist.fill(HIST("QA/after/p_NTPC_NFT0M"), N_FT0M, NTPC); + hist.fill(HIST("QA/after/p_NFT0M_NTPC"), NTPC, N_FT0M); + hist.fill(HIST("QA/after/h2_NTPC_Nch"), NTPC, Nch); + + static constexpr std::string_view dire[] = {"Analysis/Charged/", "Analysis/Pion/", "Analysis/Kaon/", "Analysis/Proton/"}; + + hist.fill(HIST(dire[0]) + HIST("h_Mult"), Nch); + hist.fill(HIST(dire[1]) + HIST("h_Mult"), N_Pi); + hist.fill(HIST(dire[2]) + HIST("h_Mult"), N_Ka); + hist.fill(HIST(dire[3]) + HIST("h_Mult"), N_Pr); + + parts(Q1_ch, Q2_ch, Q3_ch, Q4_ch, Nch, &mean_Q1_Ch, &twopart_Ch, &threepart_Ch, &fourpart_Ch); + if (Nch > 0 && mean_Q1_Ch != 0) { + hist.fill(HIST(dire[0]) + HIST("h_mean_Q1"), mean_Q1_Ch); + hist.fill(HIST(dire[0]) + HIST("p_mean_Q1"), NTPC, mean_Q1_Ch); + hist.fill(HIST(dire[0]) + HIST("h_mean_Q1_Mult"), NTPC, mean_Q1_Ch, Cent_FT0M); + } + if (Nch > 1 && twopart_Ch != 0) + hist.fill(HIST(dire[0]) + HIST("h_twopart_Mult"), NTPC, twopart_Ch, Cent_FT0M); + + if (Nch > 2 && threepart_Ch != 0) + hist.fill(HIST(dire[0]) + HIST("h_threepart_Mult"), NTPC, threepart_Ch, Cent_FT0M); + + if (Nch > 3 && fourpart_Ch != 0) + hist.fill(HIST(dire[0]) + HIST("h_fourpart_Mult"), NTPC, fourpart_Ch, Cent_FT0M); + + parts(Q1_Pi, Q2_Pi, Q3_Pi, Q4_Pi, N_Pi, &mean_Q1_Pi, &twopart_Pi, &threepart_Pi, &fourpart_Pi); + if (N_Pi > 0 && mean_Q1_Pi != 0) { + hist.fill(HIST(dire[1]) + HIST("h_mean_Q1"), mean_Q1_Pi); + hist.fill(HIST(dire[1]) + HIST("p_mean_Q1"), NTPC, mean_Q1_Pi); + hist.fill(HIST(dire[1]) + HIST("h_mean_Q1_Mult"), NTPC, mean_Q1_Pi, Cent_FT0M); + } + if (N_Pi > 1 && twopart_Pi != 0) + hist.fill(HIST(dire[1]) + HIST("h_twopart_Mult"), NTPC, twopart_Pi, Cent_FT0M); + + if (N_Pi > 2 && threepart_Pi != 0) + hist.fill(HIST(dire[1]) + HIST("h_threepart_Mult"), NTPC, threepart_Pi, Cent_FT0M); + + if (N_Pi > 3 && fourpart_Pi != 0) + hist.fill(HIST(dire[1]) + HIST("h_fourpart_Mult"), NTPC, fourpart_Pi, Cent_FT0M); + + parts(Q1_Ka, Q2_Ka, Q3_Ka, Q4_Ka, N_Ka, &mean_Q1_Ka, &twopart_Ka, &threepart_Ka, &fourpart_Ka); + if (N_Ka > 0 && mean_Q1_Ka != 0) { + hist.fill(HIST(dire[2]) + HIST("h_mean_Q1"), mean_Q1_Ka); + hist.fill(HIST(dire[2]) + HIST("p_mean_Q1"), NTPC, mean_Q1_Ka); + hist.fill(HIST(dire[2]) + HIST("h_mean_Q1_Mult"), NTPC, mean_Q1_Ka, Cent_FT0M); + } + if (N_Ka > 1 && twopart_Ka != 0) + hist.fill(HIST(dire[2]) + HIST("h_twopart_Mult"), NTPC, twopart_Ka, Cent_FT0M); + + if (N_Ka > 2 && threepart_Ka != 0) + hist.fill(HIST(dire[2]) + HIST("h_threepart_Mult"), NTPC, threepart_Ka, Cent_FT0M); + + if (N_Ka > 3 && fourpart_Ka != 0) + hist.fill(HIST(dire[2]) + HIST("h_fourpart_Mult"), NTPC, fourpart_Ka, Cent_FT0M); + + parts(Q1_Pr, Q2_Pr, Q3_Pr, Q4_Pr, N_Pr, &mean_Q1_Pr, &twopart_Pr, &threepart_Pr, &fourpart_Pr); + if (N_Pr > 0 && mean_Q1_Pr != 0) { + hist.fill(HIST(dire[3]) + HIST("h_mean_Q1"), mean_Q1_Pr); + hist.fill(HIST(dire[3]) + HIST("p_mean_Q1"), NTPC, mean_Q1_Pr); + hist.fill(HIST(dire[3]) + HIST("h_mean_Q1_Mult"), NTPC, mean_Q1_Pr, N_FT0M); + } + if (N_Pr > 1 && twopart_Pr != 0) + hist.fill(HIST(dire[3]) + HIST("h_twopart_Mult"), NTPC, twopart_Pr, Cent_FT0M); + + if (N_Pr > 2 && threepart_Pr != 0) + hist.fill(HIST(dire[3]) + HIST("h_threepart_Mult"), NTPC, threepart_Pr, Cent_FT0M); + + if (N_Pr > 3 && fourpart_Pr != 0) + hist.fill(HIST(dire[3]) + HIST("h_fourpart_Mult"), NTPC, fourpart_Pr, Cent_FT0M); + } + void process_Run2(MyRun2Collisions::iterator const& col, MyAllTracks const& tracks) + { + double Cent_V0M = 0, N_FV0M = 0; + int NTPC = 0; + + // Before Collision and Track Cuts: + for (auto& myTrack : tracks) { + hist.fill(HIST("QA/before/h_Eta"), myTrack.eta()); + hist.fill(HIST("QA/before/h_Pt"), myTrack.pt()); + hist.fill(HIST("QA/before/h2_Pt_Eta"), myTrack.eta(), myTrack.pt()); + hist.fill(HIST("QA/before/h_TPCChi2perCluster"), myTrack.tpcChi2NCl()); + hist.fill(HIST("QA/before/h_ITSChi2perCluster"), myTrack.itsChi2NCl()); + hist.fill(HIST("QA/before/h_crossedTPC"), myTrack.tpcNClsCrossedRows()); + hist.fill(HIST("QA/before/h2_DcaXY"), myTrack.pt(), myTrack.dcaXY()); + hist.fill(HIST("QA/before/h2_DcaZ"), myTrack.pt(), myTrack.dcaZ()); + } + hist.fill(HIST("QA/before/h_VtxZ"), col.posZ()); + hist.fill(HIST("QA/before/h_Counts"), 2); + + hist.fill(HIST("QA/before/h_NTPC"), col.multTPC()); + hist.fill(HIST("QA/before/h_Cent"), col.centRun2V0M()); + hist.fill(HIST("QA/before/h_NFT0M"), col.multFV0M()); + hist.fill(HIST("QA/before/h2_NTPC_NFT0M"), col.multFV0M(), col.multTPC()); + hist.fill(HIST("QA/before/h2_NTPC_Cent"), col.centRun2V0M(), col.multTPC()); + + // After Collision and Track Cuts: + if (selRun2Col(col)) { + Cent_V0M = col.centRun2V0M(); + N_FV0M = col.multFV0M(); + for (auto& track : tracks) { + if (track.hasTPC() && track.hasITS()) + NTPC++; + } + FillHistos(col, tracks, Cent_V0M, N_FV0M, NTPC); + } + } + PROCESS_SWITCH(meanPtFlucId, process_Run2, "Process for Run2", false); + + void process_Run3(MyRun3Collisions::iterator const& col, MyAllTracks const& tracks) + { + double N_FT0M = 0, Cent_FT0M = 0; + int NTPC = 0; + // Before Collision and Track Cuts: + for (auto& myTrack : tracks) { + hist.fill(HIST("QA/before/h_Eta"), myTrack.eta()); + hist.fill(HIST("QA/before/h_Pt"), myTrack.pt()); + hist.fill(HIST("QA/before/h2_Pt_Eta"), myTrack.eta(), myTrack.pt()); + hist.fill(HIST("QA/before/h_TPCChi2perCluster"), myTrack.tpcChi2NCl()); + hist.fill(HIST("QA/before/h_ITSChi2perCluster"), myTrack.itsChi2NCl()); + hist.fill(HIST("QA/before/h_crossedTPC"), myTrack.tpcNClsCrossedRows()); + hist.fill(HIST("QA/before/h2_DcaXY"), myTrack.pt(), myTrack.dcaXY()); + hist.fill(HIST("QA/before/h2_DcaZ"), myTrack.pt(), myTrack.dcaZ()); + } + hist.fill(HIST("QA/before/h_VtxZ"), col.posZ()); + hist.fill(HIST("QA/before/h_Counts"), 2); + + hist.fill(HIST("QA/before/h_NTPC"), col.multTPC()); + hist.fill(HIST("QA/before/h_Cent"), col.centFT0C()); + hist.fill(HIST("QA/before/h_NFT0M"), col.multFT0M()); + hist.fill(HIST("QA/before/h2_NTPC_NFT0M"), col.multFT0M(), col.multTPC()); + hist.fill(HIST("QA/before/h2_NTPC_Cent"), col.centFT0C(), col.multTPC()); + + // After Collision and Track Cuts: + if (selRun3Col(col)) { + N_FT0M = col.multFT0C(); + Cent_FT0M = col.centFT0C(); + NTPC = col.multNTracksHasTPC(); + FillHistos(col, tracks, Cent_FT0M, N_FT0M, NTPC); + } + } + PROCESS_SWITCH(meanPtFlucId, process_Run3, "Process for Run3", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx b/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx index f9a5b74fe2e..99ed000b01a 100644 --- a/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/MeanptFluctuations.cxx @@ -10,8 +10,11 @@ // or submit itself to any jurisdiction. #include +#include +#include #include #include + #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" #include "Framework/ASoAHelpers.h" @@ -22,12 +25,16 @@ #include "Common/Core/TrackSelection.h" #include "Common/DataModel/TrackSelectionTables.h" #include "Common/DataModel/Centrality.h" +#include "Common/DataModel/Multiplicity.h" #include "TList.h" #include "TProfile.h" #include "TProfile2D.h" +#include "TH2D.h" +#include "TH1D.h" #include "TRandom3.h" #include "TMath.h" +#include "TF1.h" namespace o2::aod { @@ -47,14 +54,19 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +#define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; + struct MeanptFluctuations_QA_QnTable { Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable cfgCutPtLower{"cfgCutPtLower", 0.2f, "Lower pT cut"}; Configurable cfgCutPtUpper{"cfgCutPtUpper", 3.0f, "Higher pT cut"}; Configurable cfgCutTpcChi2NCl{"cfgCutTpcChi2NCl", 2.5f, "Maximum TPCchi2NCl"}; - // Configurable cfgCutTrackDcaXY{"cfgCutTrackDcaXY", 0.1f, "Maximum DcaXY"}; + // Configurable cfgCutTrackDcaXY{"cfgCutTrackDcaXY", 0.2f, "Maximum DcaXY"}; Configurable cfgCutTrackDcaZ{"cfgCutTrackDcaZ", 2.0f, "Maximum DcaZ"}; + ConfigurableAxis nchAxis{"nchAxis", {5000, 0.5, 5000.5}, ""}; + + O2_DEFINE_CONFIGURABLE(cfgUse22sEventCut, bool, true, "Use 22s event cut on mult correlations") // Filter command*********** Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex; @@ -69,10 +81,17 @@ struct MeanptFluctuations_QA_QnTable { 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>; + // Event selection cuts - Alex + TF1* fMultPVCutLow = nullptr; + TF1* fMultPVCutHigh = nullptr; + TF1* fMultCutLow = nullptr; + TF1* fMultCutHigh = nullptr; + TF1* fMultMultPVCut = nullptr; + // Equivalent of the AliRoot task UserCreateOutputObjects void init(o2::framework::InitContext&) { @@ -95,6 +114,56 @@ struct MeanptFluctuations_QA_QnTable { histos.add("hDcaXY", ";#it{dca}_{XY}", kTH1F, {{1000, -5, 5}}); histos.add("hDcaZ", ";#it{dca}_{Z}", kTH1F, {{1000, -5, 5}}); histos.add("hMeanPt", "", kTProfile, {centAxis}); + histos.add("Hist2D_globalTracks_PVTracks", "", {HistType::kTH2D, {nchAxis, nchAxis}}); + histos.add("Hist2D_cent_nch", "", {HistType::kTH2D, {nchAxis, centAxis}}); + + // Event selection - Alex + if (cfgUse22sEventCut) { + 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); + + fMultCutLow = new TF1("fMultCutLow", "[0]+[1]*x+[2]*x*x+[3]*x*x*x - 2.5*([4]+[5]*x)", 0, 100); + fMultCutLow->SetParameters(1893.94, -53.86, 0.502913, -0.0015122, 109.625, -1.19253); + fMultCutHigh = new TF1("fMultCutHigh", "[0]+[1]*x+[2]*x*x+[3]*x*x*x + 3.*([4]+[5]*x)", 0, 100); + fMultCutHigh->SetParameters(1893.94, -53.86, 0.502913, -0.0015122, 109.625, -1.19253); + fMultMultPVCut = new TF1("fMultMultPVCut", "[0]+[1]*x+[2]*x*x", 0, 5000); + fMultMultPVCut->SetParameters(-0.1, 0.785, -4.7e-05); + } + + } //! end init function + + template + bool eventSelected(TCollision collision, const int& multTrk, const float& centrality) + { + if (collision.alias_bit(kTVXinTRD)) { + // TRD triggered + return 0; + } + float vtxz = -999; + if (collision.numContrib() > 1) { + vtxz = collision.posZ(); + float zRes = TMath::Sqrt(collision.covZZ()); + if (zRes > 0.25 && collision.numContrib() < 20) + vtxz = -999; + } + auto multNTracksPV = collision.multNTracksPV(); + + if ((vtxz > cfgCutVertex) || (vtxz < -1.0 * cfgCutVertex)) + return 0; + 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 > fMultMultPVCut->Eval(multNTracksPV)) + return 0; + + return 1; } Produces mult_ptQn; @@ -102,8 +171,17 @@ struct MeanptFluctuations_QA_QnTable { // void process(aod::Collision const& coll, aod::Tracks const& inputTracks) void process(aodCollisions::iterator const& coll, aod::BCsWithTimestamps const&, aodTracks const& inputTracks) { + if (!coll.sel8()) + return; + + const auto CentralityFT0C = coll.centFT0C(); + if (cfgUse22sEventCut && !eventSelected(coll, inputTracks.size(), CentralityFT0C)) + return; + histos.fill(HIST("hZvtx_after_sel"), coll.posZ()); histos.fill(HIST("hCentrality"), coll.centFT0C()); + histos.fill(HIST("Hist2D_globalTracks_PVTracks"), coll.multNTracksPV(), inputTracks.size()); + histos.fill(HIST("Hist2D_cent_nch"), inputTracks.size(), CentralityFT0C); // variables double cent = coll.centFT0C(); @@ -150,6 +228,7 @@ struct MeanptFluctuations_analysis { 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; using FilteredMultPtQn = soa::Filtered; @@ -173,6 +252,8 @@ struct MeanptFluctuations_analysis { registry.add("Prof_var_t1", "", {HistType::kTProfile2D, {centAxis, multAxis}}); registry.add("Prof_skew_t1", "", {HistType::kTProfile2D, {centAxis, multAxis}}); registry.add("Prof_kurt_t1", "", {HistType::kTProfile2D, {centAxis, multAxis}}); + registry.add("Hist2D_Nch_centrality", "", {HistType::kTH2D, {centAxis, multAxis}}); + registry.add("Hist2D_meanpt_centrality", "", {HistType::kTH2D, {centAxis, meanpTAxis}}); // initial array Subsample.resize(cfgNSubsample); @@ -203,11 +284,13 @@ struct MeanptFluctuations_analysis { skewness_term1 = (TMath::Power(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 = (TMath::Power(event_ptqn.q1(), 4.0f) - (6.0f * event_ptqn.q4()) + (8.0f * event_ptqn.q1() * event_ptqn.q3()) - (6.0f * TMath::Power(event_ptqn.q1(), 2.0f) * event_ptqn.q2()) + (3.0f * TMath::Power(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)); - // filling profiles for central values + // 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); // selecting subsample and filling profiles float l_Random = fRndm->Rndm(); diff --git a/PWGCF/EbyEFluctuations/Tasks/NetProtonCumulants.cxx b/PWGCF/EbyEFluctuations/Tasks/NetProtonCumulants.cxx index a9ac365cc8e..a18b0b97df9 100644 --- a/PWGCF/EbyEFluctuations/Tasks/NetProtonCumulants.cxx +++ b/PWGCF/EbyEFluctuations/Tasks/NetProtonCumulants.cxx @@ -79,7 +79,7 @@ struct NetProtonCumulants_Table_QA { // 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}; + std::vector centBining = {0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90}; AxisSpec centAxis = {centBining, "centrality (%)"}; AxisSpec netProtonAxis = {2001, -1000.5, 1000.5, "net-proton number"}; @@ -130,8 +130,16 @@ struct NetProtonCumulants_Table_QA { const float combNSigmaPr = std::sqrt(pow(track.tpcNSigmaPr(), 2.0) + pow(track.tofNSigmaPr(), 2.0)); const float combNSigmaPi = std::sqrt(pow(track.tpcNSigmaPi(), 2.0) + pow(track.tofNSigmaPi(), 2.0)); const float combNSigmaKa = std::sqrt(pow(track.tpcNSigmaKa(), 2.0) + pow(track.tofNSigmaKa(), 2.0)); - if (!(combNSigmaPr > combNSigmaPi) && !(combNSigmaPr > combNSigmaKa)) { - if (track.tpcNSigmaPr() < cfgnSigmaCut) { + + int flag2 = 0; + if (combNSigmaPr < 3.0) + flag2 += 1; + if (combNSigmaPi < 3.0) + flag2 += 1; + if (combNSigmaKa < 3.0) + flag2 += 1; + if (!(flag2 > 1) && !(combNSigmaPr > combNSigmaPi) && !(combNSigmaPr > combNSigmaKa)) { + if (combNSigmaPr < cfgnSigmaCut) { flag = 1; } } diff --git a/PWGCF/Femto3D/Core/femto3dPairTask.h b/PWGCF/Femto3D/Core/femto3dPairTask.h index 0feebd0f7f9..43baeb6a9bc 100755 --- a/PWGCF/Femto3D/Core/femto3dPairTask.h +++ b/PWGCF/Femto3D/Core/femto3dPairTask.h @@ -70,27 +70,25 @@ float GetKstarFrom4vectors(TLorentzVector& first4momentum, TLorentzVector& secon return 0.5 * abs(fourmomentadiff.Mag()); } else { TLorentzVector fourmomentasum = first4momentum + second4momentum; + TLorentzVector fourmomentadif = first4momentum - second4momentum; - first4momentum.Boost((-1) * fourmomentasum.BoostVector()); - second4momentum.Boost((-1) * fourmomentasum.BoostVector()); + fourmomentadif.Boost((-1) * fourmomentasum.BoostVector()); - TVector3 qinv = first4momentum.Vect() - second4momentum.Vect(); - return 0.5 * abs(qinv.Mag()); + return 0.5 * abs(fourmomentadif.Vect().Mag()); } } //==================================================================================== -TVector3 Get3dKstarFrom4vectors(TLorentzVector& first4momentum, TLorentzVector& second4momentum) +TVector3 GetQLCMSFrom4vectors(TLorentzVector& first4momentum, TLorentzVector& second4momentum) { TLorentzVector fourmomentasum = first4momentum + second4momentum; - first4momentum.Boost(0.0, 0.0, (-1) * fourmomentasum.BoostVector().Z()); // boost to LCMS - second4momentum.Boost(0.0, 0.0, (-1) * fourmomentasum.BoostVector().Z()); // boost to LCMS + TLorentzVector fourmomentadif = first4momentum - second4momentum; - TVector3 qinv = first4momentum.Vect() - second4momentum.Vect(); - qinv.RotateZ((-1) * fourmomentasum.Phi()); // rotate so the X axis is along pair's kT + fourmomentadif.Boost(0.0, 0.0, (-1) * fourmomentasum.BoostVector().Z()); // boost to LCMS + fourmomentadif.RotateZ((-1) * fourmomentasum.Phi()); // rotate so the X axis is along pair's kT - return 0.5 * qinv; + return fourmomentadif.Vect(); } //==================================================================================== @@ -144,6 +142,8 @@ class FemtoPair void SetMagField2(const float& magfield2) { _magfield2 = magfield2; } void SetPDG1(const int& PDG1) { _PDG1 = PDG1; } void SetPDG2(const int& PDG2) { _PDG2 = PDG2; } + int GetPDG1() { return _PDG1; } + int GetPDG2() { return _PDG2; } void ResetPair(); void ResetAll(); @@ -151,7 +151,7 @@ class FemtoPair TrackType* GetSecondParticle() const { return _second; } bool IsIdentical() { return _isidentical; } - bool IsClosePair(const float& deta = 0.01, const float& dphi = 0.01, const float& radius = 1.2); + bool IsClosePair(const float& deta = 0.01, const float& dphi = 0.01, const float& radius = 1.2) const; float GetEtaDiff() const { if (_first != NULL && _second != NULL) @@ -167,7 +167,7 @@ class FemtoPair return 1000; } float GetKstar() const; - TVector3 Get3dKstar() const; + TVector3 GetQLCMS() const; float GetKt() const; float GetMt() const; // test @@ -199,11 +199,11 @@ void FemtoPair::ResetAll() } template -bool FemtoPair::IsClosePair(const float& deta, const float& dphi, const float& radius) +bool FemtoPair::IsClosePair(const float& deta, const float& dphi, const float& radius) const { if (_first == NULL || _second == NULL) return true; - if (!(_magfield1 * _magfield2)) + if (_magfield1 * _magfield2 == 0) return true; if (abs(GetEtaDiff()) < deta && abs(GetPhiStarDiff(radius)) < dphi) return true; @@ -216,9 +216,9 @@ float FemtoPair::GetKstar() const { if (_first == NULL || _second == NULL) return -1000; - if (!(_magfield1 * _magfield2)) + if (_magfield1 * _magfield2 == 0) return -1000; - if (!(_PDG1 * _PDG2)) + if (_PDG1 * _PDG2 == 0) return -1000; TLorentzVector first4momentum; @@ -230,13 +230,13 @@ float FemtoPair::GetKstar() const } template -TVector3 FemtoPair::Get3dKstar() const +TVector3 FemtoPair::GetQLCMS() const { if (_first == NULL || _second == NULL) return TVector3(-1000, -1000, -1000); - if (!(_magfield1 * _magfield2)) + if (_magfield1 * _magfield2 == 0) return TVector3(-1000, -1000, -1000); - if (!(_PDG1 * _PDG2)) + if (_PDG1 * _PDG2 == 0) return TVector3(-1000, -1000, -1000); TLorentzVector first4momentum; @@ -244,7 +244,7 @@ TVector3 FemtoPair::Get3dKstar() const TLorentzVector second4momentum; second4momentum.SetPtEtaPhiM(_second->pt(), _second->eta(), _second->phi(), particle_mass(_PDG2)); - return Get3dKstarFrom4vectors(first4momentum, second4momentum); + return GetQLCMSFrom4vectors(first4momentum, second4momentum); } template @@ -252,9 +252,9 @@ float FemtoPair::GetKt() const { if (_first == NULL || _second == NULL) return -1000; - if (!(_magfield1 * _magfield2)) + if (_magfield1 * _magfield2 == 0) return -1000; - if (!(_PDG1 * _PDG2)) + if (_PDG1 * _PDG2 == 0) return -1000; return 0.5 * std::sqrt(std::pow(_first->px() + _second->px(), 2) + std::pow(_first->py() + _second->py(), 2)); @@ -265,9 +265,9 @@ float FemtoPair::GetMt() const { if (_first == NULL || _second == NULL) return -1000; - if (!(_magfield1 * _magfield2)) + if (_magfield1 * _magfield2 == 0) return -1000; - if (!(_PDG1 * _PDG2)) + if (_PDG1 * _PDG2 == 0) return -1000; TLorentzVector first4momentum; diff --git a/PWGCF/Femto3D/DataModel/singletrackselector.h b/PWGCF/Femto3D/DataModel/singletrackselector.h index 3db909f2911..8d21d0ba4a4 100755 --- a/PWGCF/Femto3D/DataModel/singletrackselector.h +++ b/PWGCF/Femto3D/DataModel/singletrackselector.h @@ -187,6 +187,13 @@ DECLARE_SOA_COLUMN(TPCInnerParam, tpcInnerParam, float); // Momentum at inner wa DECLARE_SOA_COLUMN(TPCSignal, tpcSignal, float); // dE/dx TPC DECLARE_SOA_COLUMN(Beta, beta, float); // TOF beta +DECLARE_SOA_DYNAMIC_COLUMN(Rapidity, rapidity, //! Track rapidity, computed under the mass assumption given as input + [](float p, float eta, float mass) -> float { + const auto pz = p * std::tanh(eta); + const auto energy = std::sqrt(p * p + mass * mass); + return 0.5f * log((energy + pz) / (energy - pz)); + }); + } // namespace singletrackselector DECLARE_SOA_TABLE_FULL(SingleTrackSels, "SelTracks", "AOD", "SINGLETRACKSEL", // Table of the variables for single track selection. @@ -229,6 +236,7 @@ DECLARE_SOA_TABLE_FULL(SingleTrackSels, "SelTracks", "AOD", "SINGLETRACKSEL", // singletrackselector::TOFNSigmaDe, singletrackselector::TPCNSigmaDe, + singletrackselector::Rapidity, singletrackselector::Energy, singletrackselector::Pt, singletrackselector::Px, diff --git a/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx b/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx index b7af638d6d5..499ec2ea1bb 100755 --- a/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx +++ b/PWGCF/Femto3D/TableProducer/singleTrackSelector.cxx @@ -64,6 +64,8 @@ struct singleTrackSelector { Configurable _dcaXY{"dcaXY", 1000.f, "Maximum dca of track in xy"}; Configurable _dcaZ{"dcaZ", 1000.f, "Maximum dca of track in xy"}; Configurable _maxTofChi2{"maxTofChi2", 10.f, "Maximum TOF Chi2 value -> to remove mismatched tracks"}; + Configurable _vertexZ{"VertexZ", 15.0, "abs vertexZ value limit"}; + Configurable> _centCut{"centCut", std::pair{0.f, 100.f}, "[min., max.] centrality range to keep events within"}; using Trks = soa::Join -15.f)); + Filter vertexFilter = nabs(o2::aod::collision::posZ) < _vertexZ; Filter trackFilter = ((o2::aod::track::itsChi2NCl <= 36.f) && (o2::aod::track::itsChi2NCl >= 0.f) && (o2::aod::track::tpcChi2NCl >= 0.f) && (o2::aod::track::tpcChi2NCl <= 4.f)); Filter pFilter = o2::aod::track::p > _min_P&& o2::aod::track::p < _max_P; @@ -222,29 +224,33 @@ struct singleTrackSelector { auto bc = collision.bc_as(); initCCDB(bc); - int multValue = -1; + float centValue = collision.centRun2V0M(); + if (centValue >= _centCut.value.first && centValue <= _centCut.value.second) { - switch (multTableToUse) { - case 0: - multValue = collision.multTPC(); - break; - case 1: - multValue = collision.multNTracksPV(); - break; - case 2: - multValue = collision.multNTracksPVeta1(); - break; - default: - LOGF(fatal, "Invalid flag for mult. estimator has been choosen. Please check."); - break; - } + int multValue = -1; + + switch (multTableToUse) { + case 0: + multValue = collision.multTPC(); + break; + case 1: + multValue = collision.multNTracksPV(); + break; + case 2: + multValue = collision.multNTracksPVeta1(); + break; + default: + LOGF(fatal, "Invalid flag for mult. estimator has been choosen. Please check."); + break; + } - tableRowColl(multValue, - collision.centRun2V0M(), - collision.posZ(), - d_bz); + tableRowColl(multValue, + centValue, + collision.posZ(), + d_bz); - fillTrackTables(tracks); + fillTrackTables(tracks); + } } PROCESS_SWITCH(singleTrackSelector, processDataRun2, "process data Run2", false); @@ -254,7 +260,6 @@ struct singleTrackSelector { initCCDB(bc); float centValue = -100.0f; - int multValue = -1; switch (centTableToUse) { case 0: @@ -279,28 +284,31 @@ struct singleTrackSelector { LOGF(fatal, "Invalid flag for cent./mult.perc. estimator has been choosen. Please check."); break; } + if (centValue >= _centCut.value.first && centValue <= _centCut.value.second) { + int multValue = -1; - switch (multTableToUse) { - case 0: - multValue = collision.multTPC(); - break; - case 1: - multValue = collision.multNTracksPV(); - break; - case 2: - multValue = collision.multNTracksPVeta1(); - break; - default: - LOGF(fatal, "Invalid flag for mult. estimator has been choosen. Please check."); - break; - } + switch (multTableToUse) { + case 0: + multValue = collision.multTPC(); + break; + case 1: + multValue = collision.multNTracksPV(); + break; + case 2: + multValue = collision.multNTracksPVeta1(); + break; + default: + LOGF(fatal, "Invalid flag for mult. estimator has been choosen. Please check."); + break; + } - tableRowColl(multValue, - centValue, - collision.posZ(), - d_bz); + tableRowColl(multValue, + centValue, + collision.posZ(), + d_bz); - fillTrackTables(tracks); + fillTrackTables(tracks); + } } PROCESS_SWITCH(singleTrackSelector, processDataRun3, "process data Run3", true); @@ -309,29 +317,32 @@ struct singleTrackSelector { auto bc = collision.bc_as(); initCCDB(bc); - int multValue = -1; + float centValue = collision.centRun2V0M(); + if (centValue >= _centCut.value.first && centValue <= _centCut.value.second) { + int multValue = -1; - switch (multTableToUse) { - case 0: - multValue = collision.multTPC(); - break; - case 1: - multValue = collision.multNTracksPV(); - break; - case 2: - multValue = collision.multNTracksPVeta1(); - break; - default: - LOGF(fatal, "Invalid flag for mult. estimator has been choosen. Please check."); - break; - } + switch (multTableToUse) { + case 0: + multValue = collision.multTPC(); + break; + case 1: + multValue = collision.multNTracksPV(); + break; + case 2: + multValue = collision.multNTracksPVeta1(); + break; + default: + LOGF(fatal, "Invalid flag for mult. estimator has been choosen. Please check."); + break; + } - tableRowColl(multValue, - collision.centRun2V0M(), - collision.posZ(), - d_bz); + tableRowColl(multValue, + centValue, + collision.posZ(), + d_bz); - fillTrackTables(tracks); + fillTrackTables(tracks); + } } PROCESS_SWITCH(singleTrackSelector, processMCRun2, "process MC Run2", false); @@ -341,7 +352,6 @@ struct singleTrackSelector { initCCDB(bc); float centValue = -100.0f; - int multValue = -1; switch (centTableToUse) { case 0: @@ -367,27 +377,31 @@ struct singleTrackSelector { break; } - switch (multTableToUse) { - case 0: - multValue = collision.multTPC(); - break; - case 1: - multValue = collision.multNTracksPV(); - break; - case 2: - multValue = collision.multNTracksPVeta1(); - break; - default: - LOGF(fatal, "Invalid flag for mult. estimator has been choosen. Please check."); - break; - } + if (centValue >= _centCut.value.first && centValue <= _centCut.value.second) { + int multValue = -1; - tableRowColl(multValue, - centValue, - collision.posZ(), - d_bz); + switch (multTableToUse) { + case 0: + multValue = collision.multTPC(); + break; + case 1: + multValue = collision.multNTracksPV(); + break; + case 2: + multValue = collision.multNTracksPVeta1(); + break; + default: + LOGF(fatal, "Invalid flag for mult. estimator has been choosen. Please check."); + break; + } + + tableRowColl(multValue, + centValue, + collision.posZ(), + d_bz); - fillTrackTables(tracks); + fillTrackTables(tracks); + } } PROCESS_SWITCH(singleTrackSelector, processMCRun3, "process MC Run3", false); }; diff --git a/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx b/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx index 0ea964acd6c..056560f8a4a 100755 --- a/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx +++ b/PWGCF/Femto3D/Tasks/femto3dPairTask.cxx @@ -13,6 +13,10 @@ /// \author Sofia Tomassini, Gleb Romanenko, Nicolò Jacazio /// \since 31 May 2023 +#include +#include // std::random_shuffle +#include +#include #include #include #include @@ -84,7 +88,15 @@ struct FemtoCorrelations { ConfigurableAxis CFkStarBinning{"CFkStarBinning", {500, 0.005, 5.005}, "k* binning of the CF (Nbins, lowlimit, uplimit)"}; Configurable _fill3dCF{"fill3dCF", false, "flag for filling 3D LCMS histos: true -- fill; false -- not"}; - ConfigurableAxis CF3DkStarBinning{"CF3DkStarBinning", {100, -0.25, 0.25}, "k* binning of the CF 3D in LCMS (Nbins, lowlimit, uplimit)"}; + ConfigurableAxis CF3DqLCMSBinning{"CF3DqLCMSBinning", {60, -0.3, 0.3}, "q_out/side/long binning of the CF 3D in LCMS (Nbins, lowlimit, uplimit)"}; + // the next configarable is responsible for skipping (pseudo)randomly chosen ($value -1) pairs of events in the mixing process + // migth be useful (for the sake of execution time and the output file size ...) in case of too many events per DF since in the SE thacks are mixed in N_ev and in the ME 0.5*N_ev*(N_ev - 1) + // note that in the SE number of pairs per event = 0.5*N_trks*(N_trks - 1) BUT in the ME its = N_trks^2 so final differense in the SE & ME pairs histos will be more + // P.S.: the explanation might be not very clear (sorry for that) as well as the name of the variable so, feel free to change it! + // P.P.S. the chosen way of optimizing the mixing midgt not be the correct one -- feel free to propose the right one! + // P.P.P.S. choose wisely.... + // P.P.P.P.S this way is still being testing i might be reconsidered; might change in the future, keep looking at the source code + Configurable _MEreductionFactor{"MEreductionFactor", 1, "only one (pseudo)randomly choosen event out per pair $value events will be processed and contribute to the final mixing (if < 1 -> all the possible event pairs (per vertex¢ bin) will be processed); implemented for the sake of efficiency; look at the source code;"}; bool IsIdentical; @@ -128,7 +140,7 @@ struct FemtoCorrelations { std::vector>> SEhistos_3D; std::vector>> MEhistos_3D; - std::vector>> kStarVSkStar3D; + std::vector>> qLCMSvskStar; void init(o2::framework::InitContext&) { @@ -179,19 +191,19 @@ struct FemtoCorrelations { if (_fill3dCF) { std::vector> SEperMult_3D; std::vector> MEperMult_3D; - std::vector> kStarVSkStar3DperMult; + std::vector> qLCMSvskStarperMult; for (int j = 0; j < _kTbins.value.size() - 1; j++) { - auto hSE_3D = registry.add(Form("Cent%i/SE_3D_cent%i_kT%i", i, i, j), Form("SE_3D_cent%i_kT%i", i, j), kTH3F, {{CF3DkStarBinning, "k*_out (GeV/c)"}, {CF3DkStarBinning, "k*_side (GeV/c)"}, {CF3DkStarBinning, "k*_long (GeV/c)"}}); - auto hME_3D = registry.add(Form("Cent%i/ME_3D_cent%i_kT%i", i, i, j), Form("ME_3D_cent%i_kT%i", i, j), kTH3F, {{CF3DkStarBinning, "k*_out (GeV/c)"}, {CF3DkStarBinning, "k*_side (GeV/c)"}, {CF3DkStarBinning, "k*_long (GeV/c)"}}); - auto hkStarVSkStar3D = registry.add(Form("Cent%i/kStarVSkStar3D_cent%i_kT%i", i, i, j), Form("kStarVSkStar3D_3D_cent%i_kT%i", i, j), kTH3F, {{CF3DkStarBinning, "k*_out (GeV/c)"}, {CF3DkStarBinning, "k*_side (GeV/c)"}, {CF3DkStarBinning, "k*_long (GeV/c)"}}); + auto hSE_3D = registry.add(Form("Cent%i/SE_3D_cent%i_kT%i", i, i, j), Form("SE_3D_cent%i_kT%i", i, j), kTH3F, {{CF3DqLCMSBinning, "q_out (GeV/c)"}, {CF3DqLCMSBinning, "q_side (GeV/c)"}, {CF3DqLCMSBinning, "q_long (GeV/c)"}}); + auto hME_3D = registry.add(Form("Cent%i/ME_3D_cent%i_kT%i", i, i, j), Form("ME_3D_cent%i_kT%i", i, j), kTH3F, {{CF3DqLCMSBinning, "q_out (GeV/c)"}, {CF3DqLCMSBinning, "q_side (GeV/c)"}, {CF3DqLCMSBinning, "q_long (GeV/c)"}}); + auto hqLCMSvskStar = registry.add(Form("Cent%i/qLCMSvskStar_cent%i_kT%i", i, i, j), Form("qLCMSvskStar_cent%i_kT%i", i, j), kTH3F, {{CF3DqLCMSBinning, "q_out (GeV/c)"}, {CF3DqLCMSBinning, "q_side (GeV/c)"}, {CF3DqLCMSBinning, "q_long (GeV/c)"}}); SEperMult_3D.push_back(std::move(hSE_3D)); MEperMult_3D.push_back(std::move(hME_3D)); - kStarVSkStar3DperMult.push_back(std::move(hkStarVSkStar3D)); + qLCMSvskStarperMult.push_back(std::move(hqLCMSvskStar)); } SEhistos_3D.push_back(std::move(SEperMult_3D)); MEhistos_3D.push_back(std::move(MEperMult_3D)); - kStarVSkStar3D.push_back(std::move(kStarVSkStar3DperMult)); + qLCMSvskStar.push_back(std::move(qLCMSvskStarperMult)); } } @@ -223,7 +235,7 @@ struct FemtoCorrelations { Pair->SetPair(tracks[ii], tracks[iii]); float pair_kT = Pair->GetKt(); - if (pair_kT < *_kTbins.value.begin() || pair_kT > *(_kTbins.value.end() - 1)) + if (pair_kT < *_kTbins.value.begin() || pair_kT >= *(_kTbins.value.end() - 1)) continue; int kTbin = o2::aod::singletrackselector::getBinIndex(pair_kT, _kTbins); @@ -242,8 +254,8 @@ struct FemtoCorrelations { SEhistos_1D[multBin][kTbin]->Fill(Pair->GetKstar()); // close pair rejection and fillig the SE histo if (_fill3dCF) { - TVector3 KstarLCMS = Pair->Get3dKstar(); - SEhistos_3D[multBin][kTbin]->Fill(KstarLCMS.X(), KstarLCMS.Y(), KstarLCMS.Z()); + TVector3 qLCMS = Pair->GetQLCMS(); + SEhistos_3D[multBin][kTbin]->Fill(qLCMS.X(), qLCMS.Y(), qLCMS.Z()); } } Pair->ResetPair(); @@ -269,7 +281,7 @@ struct FemtoCorrelations { Pair->SetPair(ii, iii); float pair_kT = Pair->GetKt(); - if (pair_kT < *_kTbins.value.begin() || pair_kT > *(_kTbins.value.end() - 1)) + if (pair_kT < *_kTbins.value.begin() || pair_kT >= *(_kTbins.value.end() - 1)) continue; int kTbin = o2::aod::singletrackselector::getBinIndex(pair_kT, _kTbins); @@ -289,16 +301,16 @@ struct FemtoCorrelations { mThistos[multBin][kTbin]->Fill(Pair->GetMt()); // test if (_fill3dCF) { - TVector3 KstarLCMS = Pair->Get3dKstar(); - SEhistos_3D[multBin][kTbin]->Fill(KstarLCMS.X(), KstarLCMS.Y(), KstarLCMS.Z()); + TVector3 qLCMS = Pair->GetQLCMS(); + SEhistos_3D[multBin][kTbin]->Fill(qLCMS.X(), qLCMS.Y(), qLCMS.Z()); } } else { MEhistos_1D[multBin][kTbin]->Fill(Pair->GetKstar()); if (_fill3dCF) { - TVector3 KstarLCMS = Pair->Get3dKstar(); - MEhistos_3D[multBin][kTbin]->Fill(KstarLCMS.X(), KstarLCMS.Y(), KstarLCMS.Z()); - kStarVSkStar3D[multBin][kTbin]->Fill(KstarLCMS.X(), KstarLCMS.Y(), KstarLCMS.Z(), Pair->GetKstar()); + TVector3 qLCMS = Pair->GetQLCMS(); + MEhistos_3D[multBin][kTbin]->Fill(qLCMS.X(), qLCMS.Y(), qLCMS.Z()); + qLCMSvskStar[multBin][kTbin]->Fill(qLCMS.X(), qLCMS.Y(), qLCMS.Z(), Pair->GetKstar()); } } } @@ -313,11 +325,11 @@ struct FemtoCorrelations { LOGF(fatal, "One of passed PDG is 0!!!"); for (auto track : tracks) { - if (abs(track.singleCollSel().posZ()) > _vertexZ) + if (abs(track.template singleCollSel_as>().posZ()) > _vertexZ) continue; if (track.tpcNClsShared() > _tpcNClsShared || track.itsNCls() < _itsNCls) continue; - if (track.singleCollSel().multPerc() < *_centBins.value.begin() || track.singleCollSel().multPerc() > *(_centBins.value.end() - 1)) + if (track.template singleCollSel_as>().multPerc() < *_centBins.value.begin() || track.template singleCollSel_as>().multPerc() >= *(_centBins.value.end() - 1)) continue; if (track.sign() == _sign_1 && (track.p() < _PIDtrshld_1 ? o2::aod::singletrackselector::TPCselection(track, TPCcuts_1) : o2::aod::singletrackselector::TOFselection(track, TOFcuts_1, _tpcNSigmaResidual_1))) { // filling the map: eventID <-> selected particles1 @@ -368,7 +380,7 @@ struct FemtoCorrelations { } for (auto collision : collisions) { - if (collision.multPerc() < *_centBins.value.begin() || collision.multPerc() > *(_centBins.value.end() - 1)) + if (collision.multPerc() < *_centBins.value.begin() || collision.multPerc() >= *(_centBins.value.end() - 1)) continue; if (selectedtracks_1.find(collision.globalIndex()) == selectedtracks_1.end()) { @@ -388,8 +400,9 @@ struct FemtoCorrelations { if (IsIdentical) { //====================================== mixing identical ====================================== for (auto i = mixbins.begin(); i != mixbins.end(); i++) { // iterating over all vertex&mult bins + int EvPerBin = (i->second).size(); - for (int indx1 = 0; indx1 < (i->second).size(); indx1++) { // loop over all the events in each vertex&mult bin + for (int indx1 = 0; indx1 < EvPerBin; indx1++) { // loop over all the events in each vertex&mult bin auto col1 = (i->second)[indx1]; @@ -399,9 +412,19 @@ struct FemtoCorrelations { int centBin = std::floor((i->first).second); MultHistos[centBin]->Fill(col1->mult()); + if (_fill3dCF) { // shuffling is important only for 3D because if there are any sudden order/correlation in the tables, it could couse unwanted asymmetries in the final 3d rel. momentum distributions; irrelevant in 1D case because the absolute value of the rel.momentum is taken + std::mt19937 gen(std::chrono::steady_clock::now().time_since_epoch().count()); + std::shuffle(selectedtracks_1[col1->index()].begin(), selectedtracks_1[col1->index()].end(), gen); + } + mixTracks(selectedtracks_1[col1->index()], centBin); // mixing SE identical - for (int indx2 = indx1 + 1; indx2 < (i->second).size(); indx2++) { // nested loop for all the combinations of collisions in a chosen mult/vertex bin + for (int indx2 = indx1 + 1; indx2 < EvPerBin; indx2++) { // nested loop for all the combinations of collisions in a chosen mult/vertex bin + if (_MEreductionFactor.value > 1) { + std::mt19937 mt(std::chrono::steady_clock::now().time_since_epoch().count()); + if ((mt() % (_MEreductionFactor.value + 1)) < _MEreductionFactor.value) + continue; + } auto col2 = (i->second)[indx2]; @@ -414,8 +437,9 @@ struct FemtoCorrelations { } else { //====================================== mixing non-identical ====================================== for (auto i = mixbins.begin(); i != mixbins.end(); i++) { // iterating over all vertex&mult bins + int EvPerBin = (i->second).size(); - for (int indx1 = 0; indx1 < (i->second).size(); indx1++) { // loop over all the events in each vertex&mult bin + for (int indx1 = 0; indx1 < EvPerBin; indx1++) { // loop over all the events in each vertex&mult bin auto col1 = (i->second)[indx1]; @@ -425,9 +449,19 @@ struct FemtoCorrelations { int centBin = std::floor((i->first).second); MultHistos[centBin]->Fill(col1->mult()); + if (_fill3dCF) { + std::mt19937 gen(std::chrono::steady_clock::now().time_since_epoch().count()); + std::shuffle(selectedtracks_1[col1->index()].begin(), selectedtracks_1[col1->index()].end(), gen); + } + mixTracks<0>(selectedtracks_1[col1->index()], selectedtracks_2[col1->index()], centBin); // mixing SE non-identical, in <> brackets: 0 -- SE; 1 -- ME - for (int indx2 = indx1 + 1; indx2 < (i->second).size(); indx2++) { // nested loop for all the combinations of collisions in a chosen mult/vertex bin + for (int indx2 = indx1 + 1; indx2 < EvPerBin; indx2++) { // nested loop for all the combinations of collisions in a chosen mult/vertex bin + if (_MEreductionFactor.value > 1) { + std::mt19937 mt(std::chrono::steady_clock::now().time_since_epoch().count()); + if (mt() % (_MEreductionFactor.value + 1) < _MEreductionFactor.value) + continue; + } auto col2 = (i->second)[indx2]; diff --git a/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx b/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx index 44fbe8adf53..b7d83d8d6a7 100755 --- a/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx +++ b/PWGCF/Femto3D/Tasks/femto3dPairTaskMC.cxx @@ -77,6 +77,9 @@ struct FemtoCorrelationsMC { ConfigurableAxis CFkStarBinning{"CFkStarBinning", {500, 0.005, 5.005}, "k* binning of the res. matrix (Nbins, lowlimit, uplimit)"}; + Configurable _vertexNbinsToMix{"vertexNbinsToMix", 10, "Number of vertexZ bins for the mixing"}; + Configurable _multNsubBins{"multSubBins", 10, "number of sub-bins to perform the mixing within"}; + bool IsIdentical; std::pair> TPCcuts_1; @@ -93,6 +96,7 @@ struct FemtoCorrelationsMC { std::map> selectedtracks_1; std::map> selectedtracks_2; + std::map, std::vector> mixbins; std::unique_ptr> Pair = std::make_unique>(); @@ -158,8 +162,6 @@ struct FemtoCorrelationsMC { for (int iii = ii + 1; iii < tracks.size(); iii++) { Pair->SetPair(tracks[ii], tracks[iii]); - Pair->SetMagField1((tracks[ii]->singleCollSel()).magField()); - Pair->SetMagField2((tracks[iii]->singleCollSel()).magField()); registry.fill(HIST("DoubleTrackEffects"), Pair->GetPhiStarDiff(_radiusTPC), Pair->GetEtaDiff()); Pair->ResetPair(); @@ -174,8 +176,6 @@ struct FemtoCorrelationsMC { for (auto iii : tracks2) { Pair->SetPair(ii, iii); - Pair->SetMagField1((ii->singleCollSel()).magField()); - Pair->SetMagField2((iii->singleCollSel()).magField()); registry.fill(HIST("DoubleTrackEffects"), Pair->GetPhiStarDiff(_radiusTPC), Pair->GetEtaDiff()); Pair->ResetPair(); @@ -209,7 +209,7 @@ struct FemtoCorrelationsMC { int trackPDG, trackOrigin; for (auto track : tracks) { - if (abs(track.singleCollSel().posZ()) > _vertexZ) + if (abs(track.template singleCollSel_as>().posZ()) > _vertexZ) continue; if (track.tpcNClsShared() > _tpcNClsShared || track.itsNCls() < _itsNCls) continue; @@ -305,29 +305,67 @@ struct FemtoCorrelationsMC { } } + for (auto collision : collisions) { + if (selectedtracks_1.find(collision.globalIndex()) == selectedtracks_1.end()) { + if (IsIdentical) + continue; + else if (selectedtracks_2.find(collision.globalIndex()) == selectedtracks_2.end()) + continue; + } + int vertexBinToMix = std::floor((collision.posZ() + _vertexZ) / (2 * _vertexZ / _vertexNbinsToMix)); + int centBinToMix = std::floor(collision.multPerc() / (100.0 / _multNsubBins)); + + mixbins[std::pair{vertexBinToMix, centBinToMix}].push_back(std::make_shared(collision)); + } + //====================================== filling deta(dphi*) & res. matrix starts here ====================================== if (IsIdentical) { //====================================== identical ====================================== - for (auto i = selectedtracks_1.begin(); i != selectedtracks_1.end(); i++) { // iterating over all selected collisions with selected tracks - fillEtaPhi(i->second); // filling deta(dphi*) -- SE identical - auto j = i; + for (auto i = mixbins.begin(); i != mixbins.end(); i++) { // iterating over all vertex&mult bins + + for (int indx1 = 0; indx1 < (i->second).size(); indx1++) { // iterating over all selected collisions with selected tracks + + auto col1 = (i->second)[indx1]; + + Pair->SetMagField1(col1->magField()); + Pair->SetMagField2(col1->magField()); + + fillEtaPhi(selectedtracks_1[col1->index()]); // filling deta(dphi*) -- SE identical + + for (int indx2 = indx1 + 1; indx2 < (i->second).size(); indx2++) { // nested loop for all the combinations of collisions in a chosen mult/vertex bin - for (++j; j != selectedtracks_1.end(); j++) { // nested loop to do all the ME identical combinations - fillResMatrix(i->second, j->second); // filling res. matrix -- ME identical + auto col2 = (i->second)[indx2]; + + Pair->SetMagField2(col2->magField()); + fillResMatrix(selectedtracks_1[col1->index()], selectedtracks_1[col2->index()]); // filling res. matrix -- ME identical + } } } + } else { //====================================== non-identical ====================================== - for (auto i = selectedtracks_1.begin(); i != selectedtracks_1.end(); i++) { // iterating over all selected collisions with selected tracks1 - auto ii = selectedtracks_2.find(i->first); - if (ii != selectedtracks_2.end()) - fillEtaPhi(i->second, ii->second); // checking if there are tracks2 for the choosen collision and filling deta(dphi*) -- SE non-identical + for (auto i = mixbins.begin(); i != mixbins.end(); i++) { // iterating over all vertex&mult bins + + for (int indx1 = 0; indx1 < (i->second).size(); indx1++) { // iterating over all selected collisions with selected tracks1 + + auto col1 = (i->second)[indx1]; + + Pair->SetMagField1(col1->magField()); + Pair->SetMagField2(col1->magField()); + + fillEtaPhi(selectedtracks_1[col1->index()], selectedtracks_2[col1->index()]); // filling deta(dphi*) -- SE non-identical - for (auto j = selectedtracks_2.begin(); j != selectedtracks_2.end(); j++) { // nested loop to do all the ME non-identical combinations - fillResMatrix(i->second, j->second); // filling res. matrix -- ME non-identical + for (int indx2 = indx1 + 1; indx2 < (i->second).size(); indx2++) { // nested loop for all the combinations of collisions in a chosen mult/vertex bin + + auto col2 = (i->second)[indx2]; + + Pair->SetMagField2(col2->magField()); + fillResMatrix(selectedtracks_1[col1->index()], selectedtracks_2[col2->index()]); // filling res. matrix -- ME non-identical + } } } + } //====================================== end of mixing non-identical ====================================== // clearing up @@ -340,6 +378,10 @@ struct FemtoCorrelationsMC { (i->second).clear(); selectedtracks_2.clear(); } + + for (auto i = mixbins.begin(); i != mixbins.end(); i++) + (i->second).clear(); + mixbins.clear(); } }; diff --git a/PWGCF/Femto3D/Tasks/femto3dQA.cxx b/PWGCF/Femto3D/Tasks/femto3dQA.cxx index 38ac8f26c5b..1a0483114d0 100755 --- a/PWGCF/Femto3D/Tasks/femto3dQA.cxx +++ b/PWGCF/Femto3D/Tasks/femto3dQA.cxx @@ -144,7 +144,7 @@ struct QAHistograms { } for (auto& track : tracks) { - if (abs(track.singleCollSel().posZ()) > _vertexZ) + if (abs(track.template singleCollSel_as().posZ()) > _vertexZ) continue; if ((track.tpcNClsShared()) > _tpcNClsShared || (track.itsNCls()) < _itsNCls) continue; diff --git a/PWGCF/FemtoDream/CMakeLists.txt b/PWGCF/FemtoDream/CMakeLists.txt index 6e4282fe53b..d9a4175dd3a 100644 --- a/PWGCF/FemtoDream/CMakeLists.txt +++ b/PWGCF/FemtoDream/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# Copyright 2019-2024 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. # @@ -9,52 +9,8 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. -o2physics_add_dpl_workflow(femtodream-producer - SOURCES femtoDreamProducerTask.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(femtodream-collision-masker - SOURCES femtoDreamCollisionMasker.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(femtodream-producer-reduced - SOURCES femtoDreamProducerReducedTask.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(femtodream-pair-track-track - SOURCES femtoDreamPairTaskTrackTrack.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(femtodream-pair-track-track-track - SOURCES femtoDreamPairTaskTrackTrackTrack.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(femtodream-debug-track - SOURCES femtoDreamDebugTrack.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 - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(femtodream-debug-v0 - SOURCES femtoDreamDebugV0.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_executable(femtodream-cutculator - SOURCES femtoDreamCutCulator.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore - COMPONENT_NAME Analysis) +add_subdirectory(Core) +add_subdirectory(DataModel) +add_subdirectory(TableProducer) +add_subdirectory(Tasks) +add_subdirectory(Utils) diff --git a/PWGCF/FemtoDream/Core/CMakeLists.txt b/PWGCF/FemtoDream/Core/CMakeLists.txt new file mode 100644 index 00000000000..4c182222bf2 --- /dev/null +++ b/PWGCF/FemtoDream/Core/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright 2019-2024 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. diff --git a/PWGCF/FemtoDream/FemtoDreamCollisionSelection.h b/PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h similarity index 95% rename from PWGCF/FemtoDream/FemtoDreamCollisionSelection.h rename to PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h index 4e27e96b4ce..8902551374e 100644 --- a/PWGCF/FemtoDream/FemtoDreamCollisionSelection.h +++ b/PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h @@ -13,8 +13,8 @@ /// \brief FemtoDreamCollisionSelection - event selection within the o2femtodream framework /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de -#ifndef PWGCF_FEMTODREAM_FEMTODREAMCOLLISIONSELECTION_H_ -#define PWGCF_FEMTODREAM_FEMTODREAMCOLLISIONSELECTION_H_ +#ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMCOLLISIONSELECTION_H_ +#define PWGCF_FEMTODREAM_CORE_FEMTODREAMCOLLISIONSELECTION_H_ #include #include @@ -131,15 +131,15 @@ class FemtoDreamCollisionSelection /// \tparam T type of the collision /// \param col Collision template - void fillQA(T const& col) + void fillQA(T const& col, float cent) { if (mHistogramRegistry) { mHistogramRegistry->fill(HIST("Event/Zvtx"), col.posZ()); mHistogramRegistry->fill(HIST("Event/MultNTracksPV"), col.multNTracksPV()); mHistogramRegistry->fill(HIST("Event/MultTPC"), col.multTPC()); if (mCheckIsRun3) { - mHistogramRegistry->fill(HIST("Event/MultPercentile"), col.centFT0M()); - mHistogramRegistry->fill(HIST("Event/MultPercentileVSMultNTracksPV"), col.centFT0M(), col.multNTracksPV()); + mHistogramRegistry->fill(HIST("Event/MultPercentile"), cent); + mHistogramRegistry->fill(HIST("Event/MultPercentileVSMultNTracksPV"), cent, col.multNTracksPV()); } else { mHistogramRegistry->fill(HIST("Event/MultNTracklets"), col.multTracklets()); } @@ -172,4 +172,4 @@ class FemtoDreamCollisionSelection }; } // namespace o2::analysis::femtoDream -#endif // PWGCF_FEMTODREAM_FEMTODREAMCOLLISIONSELECTION_H_ +#endif // PWGCF_FEMTODREAM_CORE_FEMTODREAMCOLLISIONSELECTION_H_ diff --git a/PWGCF/FemtoDream/FemtoDreamContainer.h b/PWGCF/FemtoDream/Core/femtoDreamContainer.h similarity index 80% rename from PWGCF/FemtoDream/FemtoDreamContainer.h rename to PWGCF/FemtoDream/Core/femtoDreamContainer.h index 7850ff5401f..1dd0138ce2b 100644 --- a/PWGCF/FemtoDream/FemtoDreamContainer.h +++ b/PWGCF/FemtoDream/Core/femtoDreamContainer.h @@ -16,15 +16,16 @@ /// \author Georgios Mantzaridis, TU München, georgios.mantzaridis@tum.de /// \author Anton Riedel, TU München, anton.riedel@tum.de -#ifndef PWGCF_FEMTODREAM_FEMTODREAMCONTAINER_H_ -#define PWGCF_FEMTODREAM_FEMTODREAMCONTAINER_H_ +#ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMCONTAINER_H_ +#define PWGCF_FEMTODREAM_CORE_FEMTODREAMCONTAINER_H_ #include #include #include #include "Framework/HistogramRegistry.h" -#include "FemtoDreamMath.h" +#include "PWGCF/FemtoDream/Core/femtoDreamMath.h" +#include "PWGCF/DataModel/FemtoDerived.h" #include "Math/Vector4D.h" #include "TMath.h" @@ -70,7 +71,10 @@ class FemtoDreamContainer /// \param kTAxis axis object for the kT axis /// \param mTAxis axis object for the mT axis template - void init_base(std::string folderName, std::string femtoObs, T femtoObsAxis, T multAxis, T kTAxis, T mTAxis, T multAxis3D, T mTAxis3D, bool use3dplots, bool extendedplots) + void init_base(std::string folderName, std::string femtoObs, + T& femtoObsAxis, T& pTAxis, T& kTAxis, T& mTAxis, T& multAxis, T& multPercentileAxis, + T& kstarAxis4D, T& mTAxis4D, T& multAxis4D, T& multPercentileAxis4D, + bool use4dplots, bool extendedplots) { mHistogramRegistry->add((folderName + "/relPairDist").c_str(), ("; " + femtoObs + "; Entries").c_str(), kTH1F, {femtoObsAxis}); @@ -78,16 +82,19 @@ class FemtoDreamContainer mHistogramRegistry->add((folderName + "/relPairkstarkT").c_str(), ("; " + femtoObs + "; #it{k}_{T} (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, kTAxis}); mHistogramRegistry->add((folderName + "/relPairkstarmT").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2})").c_str(), kTH2F, {femtoObsAxis, mTAxis}); mHistogramRegistry->add((folderName + "/relPairkstarMult").c_str(), ("; " + femtoObs + "; Multiplicity").c_str(), kTH2F, {femtoObsAxis, multAxis}); - mHistogramRegistry->add((folderName + "/kstarPtPart1").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 1 (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, {375, 0., 7.5}}); - mHistogramRegistry->add((folderName + "/kstarPtPart2").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 2 (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, {375, 0., 7.5}}); - mHistogramRegistry->add((folderName + "/MultPtPart1").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); Multiplicity", kTH2F, {{375, 0., 7.5}, multAxis}); - mHistogramRegistry->add((folderName + "/MultPtPart2").c_str(), "; #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity", kTH2F, {{375, 0., 7.5}, multAxis}); - mHistogramRegistry->add((folderName + "/PtPart1PtPart2").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 2 (GeV/#it{c})", kTH2F, {{375, 0., 7.5}, {375, 0., 7.5}}); - if (use3dplots) { - mHistogramRegistry->add((folderName + "/relPairkstarmTMult").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2}); Multiplicity").c_str(), kTH3F, {femtoObsAxis, mTAxis3D, multAxis3D}); + mHistogramRegistry->add((folderName + "/relPairkstarMultPercentile").c_str(), ("; " + femtoObs + "; Multiplicity Percentile").c_str(), kTH2F, {femtoObsAxis, multPercentileAxis4D}); + mHistogramRegistry->add((folderName + "/kstarPtPart1").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 1 (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, pTAxis}); + mHistogramRegistry->add((folderName + "/kstarPtPart2").c_str(), ("; " + femtoObs + "; #it{p} _{T} Particle 2 (GeV/#it{c})").c_str(), kTH2F, {femtoObsAxis, pTAxis}); + mHistogramRegistry->add((folderName + "/MultPtPart1").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); Multiplicity", kTH2F, {pTAxis, multAxis}); + mHistogramRegistry->add((folderName + "/MultPtPart2").c_str(), "; #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity", kTH2F, {pTAxis, multAxis}); + mHistogramRegistry->add((folderName + "/MultPercentilePtPart1").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); Multiplicity Percentile", kTH2F, {pTAxis, multPercentileAxis}); + mHistogramRegistry->add((folderName + "/MultPercentilePtPart2").c_str(), "; #it{p} _{T} Particle 2 (GeV/#it{c}); Multiplicity Percentile", kTH2F, {pTAxis, multPercentileAxis}); + mHistogramRegistry->add((folderName + "/PtPart1PtPart2").c_str(), "; #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 2 (GeV/#it{c})", kTH2F, {pTAxis, pTAxis}); + if (use4dplots) { + mHistogramRegistry->add((folderName + "/relPairkstarmTMultMultPercentile").c_str(), ("; " + femtoObs + "; #it{m}_{T} (GeV/#it{c}^{2}); Multiplicity").c_str(), kTHnSparseF, {femtoObsAxis, mTAxis4D, multAxis4D, multPercentileAxis4D}); } if (extendedplots) { - mHistogramRegistry->add((folderName + "/mTPtPart1PtPart2").c_str(), "; #it{m}_{T} (GeV/#it{c}^{2}); #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 1 (GeV/#it{c})", kTH3F, {mTAxis3D, {375, 0., 7.5}, {375, 0., 7.5}}); + mHistogramRegistry->add((folderName + "/mTPtPart1PtPart2").c_str(), "; #it{m}_{T} (GeV/#it{c}^{2}); #it{p} _{T} Particle 1 (GeV/#it{c}); #it{p} _{T} Particle 1 (GeV/#it{c})", kTH3F, {mTAxis4D, {375, 0., 7.5}, {375, 0., 7.5}}); } } @@ -118,7 +125,11 @@ class FemtoDreamContainer /// \param mTBins mT binning for the histograms /// \param isMC add Monte Carlo truth histograms to the output file template - void init(HistogramRegistry* registry, T& kstarBins, T& multBins, T& kTBins, T& mTBins, T& multBins3D, T& mTBins3D, bool isMC, bool use3dplots, bool extendedplots, float highkstarCut) + void init(HistogramRegistry* registry, + T& kstarBins, T& pTBins, T& kTBins, T& mTBins, T& multBins, T& multPercentileBins, + T& kstarBins4D, T& mTBins4D, T& multBins4D, T& multPercentileBins4D, + bool isMC, bool use4dplots, bool extendedplots, + float highkstarCut) { mHistogramRegistry = registry; std::string femtoObs; @@ -126,21 +137,30 @@ class FemtoDreamContainer femtoObs = "#it{k*} (GeV/#it{c})"; } mHighkstarCut = highkstarCut; - std::vector tmpVecMult = multBins; - framework::AxisSpec multAxis = {tmpVecMult, "Multiplicity"}; framework::AxisSpec femtoObsAxis = {kstarBins, femtoObs.c_str()}; + framework::AxisSpec pTAxis = {pTBins, "#it{p}_{T} (GeV/#it{c})"}; framework::AxisSpec kTAxis = {kTBins, "#it{k}_{T} (GeV/#it{c})"}; framework::AxisSpec mTAxis = {mTBins, "#it{m}_{T} (GeV/#it{c}^{2})"}; + framework::AxisSpec multAxis = {multBins, "Multiplicity"}; + framework::AxisSpec multPercentileAxis = {multBins, "Multiplicity percentile (%)"}; - framework::AxisSpec multAxis3D = {multBins3D, "Multiplicity"}; - framework::AxisSpec mTAxis3D = {mTBins3D, "#it{m}_{T} (GeV/#it{c})"}; + framework::AxisSpec kstarAxis4D = {kstarBins4D, "Multiplicity"}; + framework::AxisSpec mTAxis4D = {mTBins4D, "#it{m}_{T} (GeV/#it{c})"}; + framework::AxisSpec multAxis4D = {multBins4D, "Multiplicity"}; + framework::AxisSpec multPercentileAxis4D = {multPercentileBins4D, "Multiplicity Percentile (%)"}; std::string folderName = static_cast(mFolderSuffix[mEventType]) + static_cast(o2::aod::femtodreamMCparticle::MCTypeName[o2::aod::femtodreamMCparticle::MCType::kRecon]); - init_base(folderName, femtoObs, femtoObsAxis, multAxis, kTAxis, mTAxis, multAxis3D, mTAxis3D, use3dplots, extendedplots); + init_base(folderName, femtoObs, + femtoObsAxis, pTAxis, kTAxis, mTAxis, multAxis, multPercentileAxis, + kstarAxis4D, mTAxis4D, multAxis4D, multPercentileAxis4D, + use4dplots, extendedplots); if (isMC) { folderName = static_cast(mFolderSuffix[mEventType]) + static_cast(o2::aod::femtodreamMCparticle::MCTypeName[o2::aod::femtodreamMCparticle::MCType::kTruth]); - init_base(folderName, femtoObs, femtoObsAxis, multAxis, kTAxis, mTAxis, multAxis3D, mTAxis3D, use3dplots, extendedplots); + init_base(folderName, femtoObs, + femtoObsAxis, pTAxis, kTAxis, mTAxis, multAxis, multPercentileAxis, + kstarAxis4D, mTAxis4D, multAxis4D, multPercentileAxis4D, + use4dplots, extendedplots); init_MC(folderName, femtoObs, femtoObsAxis, multAxis, mTAxis); } } @@ -163,7 +183,7 @@ class FemtoDreamContainer /// \param part2 Particle two /// \param mult Multiplicity of the event template - void setPair_base(const float femtoObs, const float mT, T const& part1, T const& part2, const int mult, bool use3dplots, bool extendedplots) + void setPair_base(const float femtoObs, const float mT, T const& part1, T const& part2, const int mult, const float multPercentile, bool use4dplots, bool extendedplots) { const float kT = FemtoDreamMath::getkT(part1, mMassOne, part2, mMassTwo); mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/relPairDist"), femtoObs); @@ -171,13 +191,16 @@ class FemtoDreamContainer mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/relPairkstarkT"), femtoObs, kT); mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/relPairkstarmT"), femtoObs, mT); mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/relPairkstarMult"), femtoObs, mult); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/relPairkstarMultPercentile"), femtoObs, multPercentile); mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/kstarPtPart1"), femtoObs, part1.pt()); mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/kstarPtPart2"), femtoObs, part2.pt()); mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/MultPtPart1"), part1.pt(), mult); mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/MultPtPart2"), part2.pt(), mult); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/MultPercentilePtPart1"), part1.pt(), multPercentile); + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/MultPercentilePtPart2"), part2.pt(), multPercentile); mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/PtPart1PtPart2"), part1.pt(), part2.pt()); - if (use3dplots) { - mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/relPairkstarmTMult"), femtoObs, mT, mult); + if (use4dplots) { + mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/relPairkstarmTMultMultPercentile"), femtoObs, mT, mult, multPercentile); } if (extendedplots) { mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[mc]) + HIST("/mTPtPart1PtPart2"), mT, part1.pt(), part2.pt()); @@ -212,7 +235,7 @@ class FemtoDreamContainer /// \param part2 Particle two /// \param mult Multiplicity of the event template - void setPair(T const& part1, T const& part2, const int mult, bool use3dplots, bool extendedplots) + void setPair(T const& part1, T const& part2, const int mult, const float multPercentile, bool use4dplots, bool extendedplots) { float femtoObs, femtoObsMC; // Calculate femto observable and the mT with reconstructed information @@ -227,7 +250,7 @@ class FemtoDreamContainer const float mT = FemtoDreamMath::getmT(part1, mMassOne, part2, mMassTwo); if (mHistogramRegistry) { - setPair_base(femtoObs, mT, part1, part2, mult, use3dplots, extendedplots); + setPair_base(femtoObs, mT, part1, part2, mult, multPercentile, use4dplots, extendedplots); if constexpr (isMC) { if (part1.has_fdMCParticle() && part2.has_fdMCParticle()) { @@ -238,7 +261,7 @@ class FemtoDreamContainer const float mTMC = FemtoDreamMath::getmT(part1.fdMCParticle(), mMassOne, part2.fdMCParticle(), mMassTwo); if (abs(part1.fdMCParticle().pdgMCTruth()) == mPDGOne && abs(part2.fdMCParticle().pdgMCTruth()) == mPDGTwo) { // Note: all pair-histogramms are filled with MC truth information ONLY in case of non-fake candidates - setPair_base(femtoObsMC, mTMC, part1.fdMCParticle(), part2.fdMCParticle(), mult, use3dplots, extendedplots); + setPair_base(femtoObsMC, mTMC, part1.fdMCParticle(), part2.fdMCParticle(), mult, multPercentile, use4dplots, extendedplots); setPair_MC(femtoObsMC, femtoObs, mT, mult); } else { mHistogramRegistry->fill(HIST(mFolderSuffix[mEventType]) + HIST(o2::aod::femtodreamMCparticle::MCTypeName[o2::aod::femtodreamMCparticle::MCType::kTruth]) + HIST("/hFakePairsCounter"), 0); @@ -265,4 +288,4 @@ class FemtoDreamContainer } // namespace o2::analysis::femtoDream -#endif // PWGCF_FEMTODREAM_FEMTODREAMCONTAINER_H_ +#endif // PWGCF_FEMTODREAM_CORE_FEMTODREAMCONTAINER_H_ diff --git a/PWGCF/FemtoDream/FemtoDreamContainerThreeBody.h b/PWGCF/FemtoDream/Core/femtoDreamContainerThreeBody.h similarity index 98% rename from PWGCF/FemtoDream/FemtoDreamContainerThreeBody.h rename to PWGCF/FemtoDream/Core/femtoDreamContainerThreeBody.h index 128b8a26169..c75c897d0d2 100644 --- a/PWGCF/FemtoDream/FemtoDreamContainerThreeBody.h +++ b/PWGCF/FemtoDream/Core/femtoDreamContainerThreeBody.h @@ -17,15 +17,15 @@ /// \author Anton Riedel, TU München, anton.riedel@tum.de /// \author Laura Serksnyte, TU München, laura.serksnyte@tum.de -#ifndef PWGCF_FEMTODREAM_FEMTODREAMCONTAINERTHREEBODY_H_ -#define PWGCF_FEMTODREAM_FEMTODREAMCONTAINERTHREEBODY_H_ +#ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMCONTAINERTHREEBODY_H_ +#define PWGCF_FEMTODREAM_CORE_FEMTODREAMCONTAINERTHREEBODY_H_ #include #include #include #include "Framework/HistogramRegistry.h" -#include "FemtoDreamMath.h" +#include "PWGCF/FemtoDream/Core/femtoDreamMath.h" #include "Math/Vector4D.h" #include "TMath.h" @@ -224,4 +224,4 @@ class FemtoDreamContainerThreeBody } // namespace o2::analysis::femtoDream -#endif // PWGCF_FEMTODREAM_FEMTODREAMCONTAINERTHREEBODY_H_ +#endif // PWGCF_FEMTODREAM_CORE_FEMTODREAMCONTAINERTHREEBODY_H_ diff --git a/PWGCF/FemtoDream/FemtoDreamDetaDphiStar.h b/PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h similarity index 98% rename from PWGCF/FemtoDream/FemtoDreamDetaDphiStar.h rename to PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h index a3dad973b68..371487d70df 100644 --- a/PWGCF/FemtoDream/FemtoDreamDetaDphiStar.h +++ b/PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h @@ -13,8 +13,8 @@ /// \brief FemtoDreamDetaDphiStar - Checks particles for the close pair rejection. /// \author Laura Serksnyte, TU München, laura.serksnyte@tum.de -#ifndef PWGCF_FEMTODREAM_FEMTODREAMDETADPHISTAR_H_ -#define PWGCF_FEMTODREAM_FEMTODREAMDETADPHISTAR_H_ +#ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMDETADPHISTAR_H_ +#define PWGCF_FEMTODREAM_CORE_FEMTODREAMDETADPHISTAR_H_ #include #include @@ -204,4 +204,4 @@ class FemtoDreamDetaDphiStar } /* namespace femtoDream */ } /* namespace o2::analysis */ -#endif // PWGCF_FEMTODREAM_FEMTODREAMDETADPHISTAR_H_ +#endif // PWGCF_FEMTODREAM_CORE_FEMTODREAMDETADPHISTAR_H_ diff --git a/PWGCF/FemtoDream/FemtoDreamEventHisto.h b/PWGCF/FemtoDream/Core/femtoDreamEventHisto.h similarity index 62% rename from PWGCF/FemtoDream/FemtoDreamEventHisto.h rename to PWGCF/FemtoDream/Core/femtoDreamEventHisto.h index d44dba5ddc6..108c6c1db4e 100644 --- a/PWGCF/FemtoDream/FemtoDreamEventHisto.h +++ b/PWGCF/FemtoDream/Core/femtoDreamEventHisto.h @@ -13,8 +13,8 @@ /// \brief FemtoDreamEventHisto - Histogram class for tracks, V0s and cascades /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de -#ifndef PWGCF_FEMTODREAM_FEMTODREAMEVENTHISTO_H_ -#define PWGCF_FEMTODREAM_FEMTODREAMEVENTHISTO_H_ +#ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMEVENTHISTO_H_ +#define PWGCF_FEMTODREAM_CORE_FEMTODREAMEVENTHISTO_H_ #include "PWGCF/DataModel/FemtoDerived.h" #include "Framework/HistogramRegistry.h" @@ -35,10 +35,11 @@ class FemtoDreamEventHisto { mHistogramRegistry = registry; mHistogramRegistry->add("Event/hZvtx", "; vtx_{z} (cm); Entries", kTH1F, {{300, -12.5, 12.5}}); - mHistogramRegistry->add("Event/hMultV0M", "; vMultV0M; Entries", kTH1F, {{16384, 0, 32768}}); - mHistogramRegistry->add("Event/hMultNTr", "; vMultNTr; Entries", kTH1F, {{200, 0, 200}}); - mHistogramRegistry->add("Event/hMultNTrVsZvtx", "; vMultNTr; vtx_{z} (cm)", kTH2F, {{200, 0, 200}, {300, -12.5, 12.5}}); - mHistogramRegistry->add("Event/hMultNTrVsMultV0M", "; vMultNTr; vMultV0M", kTH2F, {{200, 0, 200}, {16384, 0, 32768}}); + mHistogramRegistry->add("Event/hMultPercentile", "; Multiplicity Percentile (FT0M); Entries", kTH1F, {{110, 0, 110}}); + mHistogramRegistry->add("Event/hMultNTr", "; Multiplicity (MultNtr); Entries", kTH1F, {{200, 0, 200}}); + mHistogramRegistry->add("Event/hMultNTrVsZvtx", "; Multiplicity (MultNtr); vtx_{z} (cm)", kTH2F, {{200, 0, 200}, {300, -12.5, 12.5}}); + mHistogramRegistry->add("Event/hMultNTrVsMultPercentile", "; Multiplicity (MultNtr); Multiplicity Percentile (FT0M)", kTH2F, {{200, 0, 200}, {110, 0, 110}}); + mHistogramRegistry->add("Event/hMultPercentileVsZvtx", "; Multiplicity Percentile (FT0M); vtx_{z} (cm)", kTH2F, {{110, 0, 110}, {300, -12.5, 12.5}}); } /// Some basic QA of the event @@ -49,10 +50,11 @@ class FemtoDreamEventHisto { if (mHistogramRegistry) { mHistogramRegistry->fill(HIST("Event/hZvtx"), col.posZ()); - mHistogramRegistry->fill(HIST("Event/hMultV0M"), col.multV0M()); + mHistogramRegistry->fill(HIST("Event/hMultPercentile"), col.multV0M()); mHistogramRegistry->fill(HIST("Event/hMultNTr"), col.multNtr()); mHistogramRegistry->fill(HIST("Event/hMultNTrVsZvtx"), col.multNtr(), col.posZ()); - mHistogramRegistry->fill(HIST("Event/hMultNTrVsMultV0M"), col.multNtr(), col.multV0M()); + mHistogramRegistry->fill(HIST("Event/hMultNTrVsMultPercentile"), col.multNtr(), col.multV0M()); + mHistogramRegistry->fill(HIST("Event/hMultPercentileVsZvtx"), col.multV0M(), col.posZ()); } } @@ -61,4 +63,4 @@ class FemtoDreamEventHisto }; } // namespace o2::analysis::femtoDream -#endif // PWGCF_FEMTODREAM_FEMTODREAMEVENTHISTO_H_ +#endif // PWGCF_FEMTODREAM_CORE_FEMTODREAMEVENTHISTO_H_ diff --git a/PWGCF/FemtoDream/FemtoDreamMath.h b/PWGCF/FemtoDream/Core/femtoDreamMath.h similarity index 97% rename from PWGCF/FemtoDream/FemtoDreamMath.h rename to PWGCF/FemtoDream/Core/femtoDreamMath.h index 259c59ceb87..d263d4c3ba3 100644 --- a/PWGCF/FemtoDream/FemtoDreamMath.h +++ b/PWGCF/FemtoDream/Core/femtoDreamMath.h @@ -13,8 +13,8 @@ /// \brief Definition of the FemtoDreamMath Container for math calculations of quantities related to pairs /// \author Valentina Mantovani Sarti, TU München, valentina.mantovani-sarti@tum.de, Laura Serksnyte, TU München, laura.serksnyte@cern.ch -#ifndef PWGCF_FEMTODREAM_FEMTODREAMMATH_H_ -#define PWGCF_FEMTODREAM_FEMTODREAMMATH_H_ +#ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMMATH_H_ +#define PWGCF_FEMTODREAM_CORE_FEMTODREAMMATH_H_ #include @@ -140,4 +140,4 @@ class FemtoDreamMath } // namespace o2::analysis::femtoDream -#endif // PWGCF_FEMTODREAM_FEMTODREAMMATH_H_ +#endif // PWGCF_FEMTODREAM_CORE_FEMTODREAMMATH_H_ diff --git a/PWGCF/FemtoDream/FemtoDreamObjectSelection.h b/PWGCF/FemtoDream/Core/femtoDreamObjectSelection.h similarity index 97% rename from PWGCF/FemtoDream/FemtoDreamObjectSelection.h rename to PWGCF/FemtoDream/Core/femtoDreamObjectSelection.h index e63b09ab5ed..713cbb14c73 100644 --- a/PWGCF/FemtoDream/FemtoDreamObjectSelection.h +++ b/PWGCF/FemtoDream/Core/femtoDreamObjectSelection.h @@ -13,14 +13,14 @@ /// \brief FemtoDreamObjectSelection - Parent class of all selections /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de -#ifndef PWGCF_FEMTODREAM_FEMTODREAMOBJECTSELECTION_H_ -#define PWGCF_FEMTODREAM_FEMTODREAMOBJECTSELECTION_H_ +#ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMOBJECTSELECTION_H_ +#define PWGCF_FEMTODREAM_CORE_FEMTODREAMOBJECTSELECTION_H_ #include #include #include -#include "FemtoDreamSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" #include "ReconstructionDataFormats/PID.h" #include "Framework/HistogramRegistry.h" #include "PWGCF/DataModel/FemtoDerived.h" @@ -195,4 +195,4 @@ class FemtoDreamObjectSelection } // namespace femtoDream } // namespace o2::analysis -#endif // PWGCF_FEMTODREAM_FEMTODREAMOBJECTSELECTION_H_ +#endif // PWGCF_FEMTODREAM_CORE_FEMTODREAMOBJECTSELECTION_H_ diff --git a/PWGCF/FemtoDream/FemtoDreamPairCleaner.h b/PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h similarity index 95% rename from PWGCF/FemtoDream/FemtoDreamPairCleaner.h rename to PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h index f140d1e626f..d6f334c5acb 100644 --- a/PWGCF/FemtoDream/FemtoDreamPairCleaner.h +++ b/PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h @@ -13,8 +13,8 @@ /// \brief FemtoDreamPairCleaner - Makes sure only proper candidates are paired /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de, Laura Serksnyte , TU München -#ifndef PWGCF_FEMTODREAM_FEMTODREAMPAIRCLEANER_H_ -#define PWGCF_FEMTODREAM_FEMTODREAMPAIRCLEANER_H_ +#ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMPAIRCLEANER_H_ +#define PWGCF_FEMTODREAM_CORE_FEMTODREAMPAIRCLEANER_H_ #include "PWGCF/DataModel/FemtoDerived.h" #include "Framework/HistogramRegistry.h" @@ -87,4 +87,4 @@ class FemtoDreamPairCleaner }; } // namespace o2::analysis::femtoDream -#endif // PWGCF_FEMTODREAM_FEMTODREAMPAIRCLEANER_H_ +#endif // PWGCF_FEMTODREAM_CORE_FEMTODREAMPAIRCLEANER_H_ diff --git a/PWGCF/FemtoDream/FemtoDreamParticleHisto.h b/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h similarity index 99% rename from PWGCF/FemtoDream/FemtoDreamParticleHisto.h rename to PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h index bdbc1410203..6c3c8646c41 100644 --- a/PWGCF/FemtoDream/FemtoDreamParticleHisto.h +++ b/PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h @@ -15,8 +15,8 @@ /// \author Georgios Mantzaridis, TU München, georgios.mantzaridis@tum.de /// \author Anton Riedel, TU München, anton.riedel@tum.de -#ifndef PWGCF_FEMTODREAM_FEMTODREAMPARTICLEHISTO_H_ -#define PWGCF_FEMTODREAM_FEMTODREAMPARTICLEHISTO_H_ +#ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMPARTICLEHISTO_H_ +#define PWGCF_FEMTODREAM_CORE_FEMTODREAMPARTICLEHISTO_H_ #include #include @@ -413,4 +413,4 @@ class FemtoDreamParticleHisto }; } // namespace o2::analysis::femtoDream -#endif // PWGCF_FEMTODREAM_FEMTODREAMPARTICLEHISTO_H_ +#endif // PWGCF_FEMTODREAM_CORE_FEMTODREAMPARTICLEHISTO_H_ diff --git a/PWGCF/FemtoDream/FemtoDreamSelection.h b/PWGCF/FemtoDream/Core/femtoDreamSelection.h similarity index 97% rename from PWGCF/FemtoDream/FemtoDreamSelection.h rename to PWGCF/FemtoDream/Core/femtoDreamSelection.h index cb3b76ac36e..b9490db549f 100644 --- a/PWGCF/FemtoDream/FemtoDreamSelection.h +++ b/PWGCF/FemtoDream/Core/femtoDreamSelection.h @@ -13,8 +13,8 @@ /// \brief FemtoDreamSelection - small generic class to do selections /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de -#ifndef PWGCF_FEMTODREAM_FEMTODREAMSELECTION_H_ -#define PWGCF_FEMTODREAM_FEMTODREAMSELECTION_H_ +#ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMSELECTION_H_ +#define PWGCF_FEMTODREAM_CORE_FEMTODREAMSELECTION_H_ #include #include "Framework/HistogramRegistry.h" @@ -141,4 +141,4 @@ class FemtoDreamSelection } // namespace o2::analysis::femtoDream -#endif // PWGCF_FEMTODREAM_FEMTODREAMSELECTION_H_ +#endif // PWGCF_FEMTODREAM_CORE_FEMTODREAMSELECTION_H_ diff --git a/PWGCF/FemtoDream/FemtoDreamTrackSelection.h b/PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h similarity index 99% rename from PWGCF/FemtoDream/FemtoDreamTrackSelection.h rename to PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h index 1dc749e3fbb..ccc2913a1e7 100644 --- a/PWGCF/FemtoDream/FemtoDreamTrackSelection.h +++ b/PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h @@ -14,8 +14,8 @@ /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de /// \author Luca Barioglio, TU München, luca.barioglio@cern.ch -#ifndef PWGCF_FEMTODREAM_FEMTODREAMTRACKSELECTION_H_ -#define PWGCF_FEMTODREAM_FEMTODREAMTRACKSELECTION_H_ +#ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMTRACKSELECTION_H_ +#define PWGCF_FEMTODREAM_CORE_FEMTODREAMTRACKSELECTION_H_ #include #include @@ -26,7 +26,7 @@ #include "Common/DataModel/TrackSelectionTables.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" -#include "FemtoDreamObjectSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamObjectSelection.h" #include "ReconstructionDataFormats/PID.h" #include "Framework/HistogramRegistry.h" @@ -607,4 +607,4 @@ void FemtoDreamTrackSelection::fillQA(T const& track) } // namespace o2::analysis::femtoDream -#endif // PWGCF_FEMTODREAM_FEMTODREAMTRACKSELECTION_H_ +#endif // PWGCF_FEMTODREAM_CORE_FEMTODREAMTRACKSELECTION_H_ diff --git a/PWGCF/FemtoDream/FemtoUtils.h b/PWGCF/FemtoDream/Core/femtoDreamUtils.h similarity index 97% rename from PWGCF/FemtoDream/FemtoUtils.h rename to PWGCF/FemtoDream/Core/femtoDreamUtils.h index 54e3d168a8b..0323eb77be5 100644 --- a/PWGCF/FemtoDream/FemtoUtils.h +++ b/PWGCF/FemtoDream/Core/femtoDreamUtils.h @@ -13,8 +13,8 @@ /// \brief Utilities for the FemtoDream framework /// \author Luca Barioglio, TU München, luca.barioglio@cern.ch -#ifndef PWGCF_FEMTODREAM_FEMTOUTILS_H_ -#define PWGCF_FEMTODREAM_FEMTOUTILS_H_ +#ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMUTILS_H_ +#define PWGCF_FEMTODREAM_CORE_FEMTODREAMUTILS_H_ #include #include @@ -150,4 +150,4 @@ bool containsNameValuePair(const std::vector& myVector, const std::string& na } } // namespace o2::analysis::femtoDream -#endif // PWGCF_FEMTODREAM_FEMTOUTILS_H_ +#endif // PWGCF_FEMTODREAM_CORE_FEMTODREAMUTILS_H_ diff --git a/PWGCF/FemtoDream/FemtoDreamV0Selection.h b/PWGCF/FemtoDream/Core/femtoDreamV0Selection.h similarity index 98% rename from PWGCF/FemtoDream/FemtoDreamV0Selection.h rename to PWGCF/FemtoDream/Core/femtoDreamV0Selection.h index 73ad22e2a26..fb6d1aa4d36 100644 --- a/PWGCF/FemtoDream/FemtoDreamV0Selection.h +++ b/PWGCF/FemtoDream/Core/femtoDreamV0Selection.h @@ -15,8 +15,8 @@ /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de /// \author Luca Barioglio, TU München, luca.barioglio@cern.ch -#ifndef PWGCF_FEMTODREAM_FEMTODREAMV0SELECTION_H_ -#define PWGCF_FEMTODREAM_FEMTODREAMV0SELECTION_H_ +#ifndef PWGCF_FEMTODREAM_CORE_FEMTODREAMV0SELECTION_H_ +#define PWGCF_FEMTODREAM_CORE_FEMTODREAMV0SELECTION_H_ #include #include @@ -24,9 +24,9 @@ #include // FIXME -#include "FemtoDreamObjectSelection.h" -#include "FemtoDreamSelection.h" -#include "FemtoDreamTrackSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamObjectSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" #include "Common/Core/RecoDecay.h" #include "Framework/HistogramRegistry.h" @@ -707,4 +707,4 @@ void FemtoDreamV0Selection::fillQA(C const& col, V const& v0, T const& posTrack, } // namespace o2::analysis::femtoDream -#endif // PWGCF_FEMTODREAM_FEMTODREAMV0SELECTION_H_ +#endif // PWGCF_FEMTODREAM_CORE_FEMTODREAMV0SELECTION_H_ diff --git a/PWGCF/FemtoDream/DataModel/CMakeLists.txt b/PWGCF/FemtoDream/DataModel/CMakeLists.txt new file mode 100644 index 00000000000..4c182222bf2 --- /dev/null +++ b/PWGCF/FemtoDream/DataModel/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright 2019-2024 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. diff --git a/PWGCF/FemtoDream/TableProducer/CMakeLists.txt b/PWGCF/FemtoDream/TableProducer/CMakeLists.txt new file mode 100644 index 00000000000..0f8d87d9570 --- /dev/null +++ b/PWGCF/FemtoDream/TableProducer/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright 2019-2024 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(femtodream-producer + SOURCES femtoDreamProducerTask.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(femtodream-producer-reduced + SOURCES femtoDreamProducerReducedTask.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/FemtoDream/femtoDreamProducerReducedTask.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx similarity index 93% rename from PWGCF/FemtoDream/femtoDreamProducerReducedTask.cxx rename to PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx index 25f08a71c2d..cb0cce833d2 100644 --- a/PWGCF/FemtoDream/femtoDreamProducerReducedTask.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerReducedTask.cxx @@ -17,8 +17,9 @@ #include "TMath.h" #include -#include "FemtoDreamCollisionSelection.h" -#include "FemtoDreamTrackSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" #include "PWGCF/DataModel/FemtoDerived.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" @@ -35,7 +36,6 @@ #include "DataFormatsParameters/GRPObject.h" #include "DataFormatsParameters/GRPMagField.h" #include "Math/Vector4D.h" -#include "FemtoUtils.h" using namespace o2; using namespace o2::analysis::femtoDream; @@ -47,6 +47,7 @@ namespace o2::aod using FemtoFullCollision = soa::Join::iterator; using FemtoFullCollisionMC = soa::Join::iterator; +using FemtoFullCollision_noCent_MC = soa::Join::iterator; using FemtoFullTracks = soa::Join + template void fillCollisionsAndTracks(CollisionType const& col, TrackType const& tracks) /// \todo with FilteredFullV0s { // get magnetic field for run @@ -224,7 +225,11 @@ struct femtoDreamProducerReducedTask { int mult = 0; int multNtr = 0; if (ConfIsRun3) { - mult = col.centFT0M(); + if constexpr (useCentrality) { + mult = col.centFT0M(); + } else { + mult = 0.; + } multNtr = col.multNTracksPV(); } else { mult = 1; // multiplicity percentile is known in Run 2 @@ -233,8 +238,7 @@ struct femtoDreamProducerReducedTask { if (ConfEvtUseTPCmult) { multNtr = col.multTPC(); } - - colCuts.fillQA(col); + colCuts.fillQA(col, mult); /// First thing to do is to check whether the basic event selection criteria are fulfilled /// That includes checking if there are any usable tracks in a collision @@ -307,7 +311,7 @@ struct femtoDreamProducerReducedTask { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); // fill the tables - fillCollisionsAndTracks(col, tracks); + fillCollisionsAndTracks(col, tracks); } PROCESS_SWITCH(femtoDreamProducerReducedTask, processData, "Provide experimental data", true); @@ -319,9 +323,21 @@ struct femtoDreamProducerReducedTask { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); // fill the tables - fillCollisionsAndTracks(col, tracks); + fillCollisionsAndTracks(col, tracks); } PROCESS_SWITCH(femtoDreamProducerReducedTask, processMC, "Provide MC data", false); + + void processMC_noCentrality(aod::FemtoFullCollision_noCent_MC const& col, + aod::BCsWithTimestamps const&, + soa::Join const& tracks, + aod::McCollisions const& mcCollisions, aod::McParticles const& mcParticles) + { + // get magnetic field for run + getMagneticFieldTesla(col.bc_as()); + // fill the tables + fillCollisionsAndTracks(col, tracks); + } + PROCESS_SWITCH(femtoDreamProducerReducedTask, processMC_noCentrality, "Provide MC data", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/FemtoDream/femtoDreamProducerTask.cxx b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx similarity index 94% rename from PWGCF/FemtoDream/femtoDreamProducerTask.cxx rename to PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx index a498340ee17..9f141fba39a 100644 --- a/PWGCF/FemtoDream/femtoDreamProducerTask.cxx +++ b/PWGCF/FemtoDream/TableProducer/femtoDreamProducerTask.cxx @@ -22,10 +22,10 @@ #include "Common/DataModel/TrackSelectionTables.h" #include "DataFormatsParameters/GRPMagField.h" #include "DataFormatsParameters/GRPObject.h" -#include "FemtoDreamCollisionSelection.h" -#include "FemtoDreamTrackSelection.h" -#include "FemtoDreamV0Selection.h" -#include "FemtoUtils.h" +#include "PWGCF/FemtoDream/Core/femtoDreamCollisionSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamV0Selection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisDataModel.h" #include "Framework/AnalysisTask.h" @@ -48,6 +48,7 @@ namespace o2::aod using FemtoFullCollision = soa::Join::iterator; using FemtoFullCollisionMC = soa::Join::iterator; +using FemtoFullCollision_noCent_MC = soa::Join::iterator; using FemtoFullTracks = soa::Join + template void fillCollisionsAndTracksAndV0(CollisionType const& col, TrackType const& tracks, V0Type const& fullV0s) { const auto vtxZ = col.posZ(); @@ -350,7 +351,11 @@ struct femtoDreamProducerTask { float mult = 0; int multNtr = 0; if (ConfIsRun3) { - mult = col.centFT0M(); + if constexpr (useCentrality) { + mult = col.centFT0M(); + } else { + mult = 0; + } multNtr = col.multNTracksPV(); } else { mult = 1; // multiplicity percentile is know in Run 2 @@ -360,7 +365,7 @@ struct femtoDreamProducerTask { multNtr = col.multTPC(); } - colCuts.fillQA(col); + colCuts.fillQA(col, mult); // check whether the basic event selection criteria are fulfilled // that included checking if there is at least on usable track or V0 @@ -508,7 +513,7 @@ struct femtoDreamProducerTask { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); // fill the tables - fillCollisionsAndTracksAndV0(col, tracks, fullV0s); + fillCollisionsAndTracksAndV0(col, tracks, fullV0s); } PROCESS_SWITCH(femtoDreamProducerTask, processData, "Provide experimental data", true); @@ -523,9 +528,23 @@ struct femtoDreamProducerTask { // get magnetic field for run getMagneticFieldTesla(col.bc_as()); // fill the tables - fillCollisionsAndTracksAndV0(col, tracks, fullV0s); + fillCollisionsAndTracksAndV0(col, tracks, fullV0s); } PROCESS_SWITCH(femtoDreamProducerTask, processMC, "Provide MC data", false); + + void processMC_noCentrality(aod::FemtoFullCollision_noCent_MC const& col, + aod::BCsWithTimestamps const&, + soa::Join const& tracks, + aod::McCollisions const& mcCollisions, + aod::McParticles const& mcParticles, + soa::Join const& fullV0s) /// \todo with FilteredFullV0s + { + // get magnetic field for run + getMagneticFieldTesla(col.bc_as()); + // fill the tables + fillCollisionsAndTracksAndV0(col, tracks, fullV0s); + } + PROCESS_SWITCH(femtoDreamProducerTask, processMC_noCentrality, "Provide MC data without requiring a centrality calibration", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGCF/FemtoDream/Tasks/CMakeLists.txt b/PWGCF/FemtoDream/Tasks/CMakeLists.txt new file mode 100644 index 00000000000..2faaafdc4f5 --- /dev/null +++ b/PWGCF/FemtoDream/Tasks/CMakeLists.txt @@ -0,0 +1,45 @@ +# Copyright 2019-2024 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(femtodream-pair-track-track + SOURCES femtoDreamPairTaskTrackTrack.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(femtodream-triplet-track-track-track + SOURCES femtoDreamTripletTaskTrackTrackTrack.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 + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(femtodream-debug-track + SOURCES femtoDreamDebugTrack.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(femtodream-debug-v0 + SOURCES femtoDreamDebugV0.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(femtodream-collision-masker + SOURCES femtoDreamCollisionMasker.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) diff --git a/PWGCF/FemtoDream/femtoDreamCollisionMasker.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamCollisionMasker.cxx similarity index 81% rename from PWGCF/FemtoDream/femtoDreamCollisionMasker.cxx rename to PWGCF/FemtoDream/Tasks/femtoDreamCollisionMasker.cxx index 614c9427b64..d9a0a4b6dc2 100644 --- a/PWGCF/FemtoDream/femtoDreamCollisionMasker.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamCollisionMasker.cxx @@ -16,6 +16,7 @@ #include #include #include +#include #include "fairlogger/Logger.h" #include "Framework/Configurable.h" @@ -42,12 +43,20 @@ enum Parts { enum Tasks { kTrackTrack, kTrackV0, + kTrackTrackTrack, kNTasks, }; } // namespace CollisionMasks struct femoDreamCollisionMasker { Produces Masks; + Produces DownSample; + + // configurable for downsampling + Configurable ConfDownsampling{"ConfDownsampling", -1., "Fraction of events to be used in mixed event sample. Factor should be between 0 and 1. Deactivate with negative value"}; + Configurable ConfSeed{"ConfSeed", 29012024, "Seed for downsampling"}; + + std::mt19937* rng = nullptr; // particle selection bits std::array, CollisionMasks::kNParts> TrackCutBits; @@ -83,6 +92,12 @@ struct femoDreamCollisionMasker { void init(InitContext& context) { + + // seed rng for downsampling + if (ConfSeed.value > 0) { + rng = new std::mt19937(ConfSeed.value); + } + std::vector MatchedWorkflows; LOG(info) << "*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*"; LOG(info) << " Collision masker self-configuration "; @@ -175,6 +190,22 @@ struct femoDreamCollisionMasker { NegChildPIDTPCBits.at(CollisionMasks::kPartTwo).push_back(option.defaultValue.get()); } } + } else if (device.name.find("femto-dream-triplet-task-track-track-track") != std::string::npos) { + LOG(info) << "Matched workflow: " << device.name; + TaskFinder = CollisionMasks::kTrackTrackTrack; + for (auto const& option : device.options) { + if (option.name.compare(std::string("ConfCutPart")) == 0) { + TrackCutBits.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTPCPIDBit")) == 0) { + TrackPIDTPCBits.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfTPCTOFPIDBit")) == 0) { + TrackPIDTPCTOFBits.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfPIDthrMom")) == 0) { + TrackPIDThreshold.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } else if (option.name.compare(std::string("ConfMaxpT")) == 0) { + FilterPtMax.at(CollisionMasks::kPartOne).push_back(option.defaultValue.get()); + } + } } } @@ -186,7 +217,7 @@ struct femoDreamCollisionMasker { } } - // make bitmask for a track + // make bitmask for a track for two body task template void MaskForTrack(T& BitSet, CollisionMasks::Parts P, R& track) { @@ -217,6 +248,36 @@ struct femoDreamCollisionMasker { } } + // make bitmask for a track for three body task + template + void MaskForTrack_ThreeBody(T& BitSet, CollisionMasks::Parts P, R& track) + { + if (track.partType() != static_cast(femtodreamparticle::kTrack)) { + return; + } + for (size_t index = 0; index < TrackCutBits.at(P).size(); index++) { + // check filter cuts + if (track.pt() > FilterPtMax.at(P).at(index)) { + // if they are not passed, skip the particle + continue; + } + // set the bit at the index of the selection equal to one if the track passes all selections + // check track cuts + if ((track.cut() & TrackCutBits.at(P).at(index)) == TrackCutBits.at(P).at(index)) { + // check pid cuts + if (track.p() <= TrackPIDThreshold.at(P).at(index)) { + if ((track.pidcut() & TrackPIDTPCBits.at(P).at(index)) == TrackPIDTPCBits.at(P).at(index)) { + BitSet.at(P).set(index); + } + } else { + if ((track.pidcut() & TrackPIDTPCTOFBits.at(P).at(index)) == TrackPIDTPCTOFBits.at(P).at(index)) { + BitSet.at(P).set(index); + } + } + } + } + } + // make bit mask for v0 template void MaskForV0(T& BitSet, CollisionMasks::Parts P, R& v0, S& parts) @@ -275,6 +336,15 @@ struct femoDreamCollisionMasker { } // TODO: add all supported pair/triplet tasks break; + case CollisionMasks::kTrackTrackTrack: + // triplet-track-track-track task + // create mask track + for (auto const& part : parts) { + // currently three-body task can be run only for three identical tracks, only one part needs to be checked + MaskForTrack_ThreeBody(Mask, CollisionMasks::kPartOne, part); + } + // TODO: add all supported pair/triplet tasks + break; default: LOG(fatal) << "No femtodream pair task found!"; } @@ -282,6 +352,15 @@ struct femoDreamCollisionMasker { Masks(static_cast(Mask.at(CollisionMasks::kPartOne).to_ulong()), static_cast(Mask.at(CollisionMasks::kPartTwo).to_ulong()), static_cast(Mask.at(CollisionMasks::kPartThree).to_ulong())); + + bool UseInMixedEvent = true; + std::uniform_real_distribution<> dist(0, 1); + + if (ConfSeed.value > 0 && (1 - dist(*rng)) > ConfDownsampling.value) { + UseInMixedEvent = false; + } + + DownSample(UseInMixedEvent); }; }; diff --git a/PWGCF/FemtoDream/femtoDreamDebugTrack.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamDebugTrack.cxx similarity index 83% rename from PWGCF/FemtoDream/femtoDreamDebugTrack.cxx rename to PWGCF/FemtoDream/Tasks/femtoDreamDebugTrack.cxx index 515ed97a83d..25a4ec71c5a 100644 --- a/PWGCF/FemtoDream/femtoDreamDebugTrack.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamDebugTrack.cxx @@ -22,9 +22,8 @@ #include "Framework/StepTHn.h" #include "Framework/runDataProcessing.h" -#include "FemtoDreamEventHisto.h" -#include "FemtoDreamParticleHisto.h" -#include "FemtoUtils.h" +#include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" #include "PWGCF/DataModel/FemtoDerived.h" using namespace o2; @@ -51,14 +50,17 @@ struct femtoDreamDebugTrack { ConfigurableAxis ConfDummy{"ConfDummy", {1, 0, 1}, "Dummy axis for inv mass"}; using FemtoFullParticles = soa::Join; - - Partition partsOne = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && ncheckbit(aod::femtodreamparticle::cut, ConfTrk1_CutBit) && - ifnode(aod::femtodreamparticle::pt * (nexp(aod::femtodreamparticle::eta) + nexp(-1.f * aod::femtodreamparticle::eta)) / 2.f <= ConfTrk1_PIDThres, ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk1_TPCBit), ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk1_TPCTOFBit)); - + Partition partsOne = + (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && + ncheckbit(aod::femtodreamparticle::cut, ConfTrk1_CutBit) && + ifnode(aod::femtodreamparticle::pt * (nexp(aod::femtodreamparticle::eta) + nexp(-1.f * aod::femtodreamparticle::eta)) / 2.f <= ConfTrk1_PIDThres, ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk1_TPCBit), ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk1_TPCTOFBit)); Preslice perColReco = aod::femtodreamparticle::fdCollisionId; using FemtoFullParticlesMC = soa::Join; - Partition partsOneMC = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && ncheckbit(aod::femtodreamparticle::cut, ConfTrk1_CutBit); + Partition partsOneMC = + (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && + ncheckbit(aod::femtodreamparticle::cut, ConfTrk1_CutBit) && + ifnode(aod::femtodreamparticle::pt * (nexp(aod::femtodreamparticle::eta) + nexp(-1.f * aod::femtodreamparticle::eta)) / 2.f <= ConfTrk1_PIDThres, ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk1_TPCBit), ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk1_TPCTOFBit)); Preslice perColGen = aod::femtodreamparticle::fdCollisionId; /// Histogramming for Event diff --git a/PWGCF/FemtoDream/femtoDreamDebugV0.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamDebugV0.cxx similarity index 98% rename from PWGCF/FemtoDream/femtoDreamDebugV0.cxx rename to PWGCF/FemtoDream/Tasks/femtoDreamDebugV0.cxx index 1992a17bde3..83296131cde 100644 --- a/PWGCF/FemtoDream/femtoDreamDebugV0.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamDebugV0.cxx @@ -26,9 +26,8 @@ #include "fairlogger/Logger.h" #include "PWGCF/DataModel/FemtoDerived.h" -#include "FemtoDreamParticleHisto.h" -#include "FemtoDreamEventHisto.h" -#include "FemtoUtils.h" +#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" using namespace o2; using namespace o2::analysis::femtoDream; diff --git a/PWGCF/FemtoDream/femtoDreamHashTask.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamHashTask.cxx similarity index 100% rename from PWGCF/FemtoDream/femtoDreamHashTask.cxx rename to PWGCF/FemtoDream/Tasks/femtoDreamHashTask.cxx diff --git a/PWGCF/FemtoDream/femtoDreamPairTaskTrackTrack.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackTrack.cxx similarity index 55% rename from PWGCF/FemtoDream/femtoDreamPairTaskTrackTrack.cxx rename to PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackTrack.cxx index 93f20708efc..ec5774ee379 100644 --- a/PWGCF/FemtoDream/femtoDreamPairTaskTrackTrack.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackTrack.cxx @@ -15,8 +15,6 @@ /// \author Georgios Mantzaridis, TU München, georgios.mantzaridis@tum.de /// \author Anton Riedel, TU München, anton.riedel@tum.de -#include -#include #include #include #include @@ -27,15 +25,17 @@ #include "Framework/RunningWorkflowInfo.h" #include "Framework/StepTHn.h" #include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/Configurable.h" +#include "Framework/Expressions.h" #include "TDatabasePDG.h" #include "PWGCF/DataModel/FemtoDerived.h" -#include "FemtoDreamParticleHisto.h" -#include "FemtoDreamEventHisto.h" -#include "FemtoDreamPairCleaner.h" -#include "FemtoDreamContainer.h" -#include "FemtoDreamDetaDphiStar.h" -#include "FemtoUtils.h" +#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" +#include "PWGCF/FemtoDream/Core/femtoDreamContainer.h" +#include "PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h" +#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" using namespace o2::aod; using namespace o2::soa; @@ -47,19 +47,34 @@ struct femtoDreamPairTaskTrackTrack { SliceCache cache; Preslice perCol = aod::femtodreamparticle::fdCollisionId; - using MaskedCollisions = soa::Join; - using MaskedCollision = MaskedCollisions::iterator; - femtodreamcollision::BitMaskType MaskBit = -1; - - /// Table for both particles - Configurable ConfIsMC{"ConfIsMC", false, "Enable additional Histogramms 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 ConfExtendedPlots{"ConfExtendedPlots", false, "Enable additional three dimensional histogramms. High memory consumption. Use for debugging"}; - Configurable ConfHighkstarCut{"ConfHighkstarCut", -1., "Set a cut for high k*, above which the pairs are rejected. Set it to -1 to deactivate it"}; - - /// Particle selection part - - /// Particle 1 + /// General options + Configurable ConfOptIsMC{"ConfOptIsMC", false, "Enable additional Histogramms in the case of a MonteCarlo Run"}; + Configurable ConfOptUse4D{"ConfOptUse4D", false, "Enable four dimensional histogramms (to be used only for analysis with high statistics): k* vs multiplicity vs multiplicity percentil vs mT"}; + Configurable ConfOptExtendedPlots{"ConfOptExtendedPlots", false, "Enable additional three dimensional histogramms. High memory consumption. Use for debugging"}; + Configurable ConfOptHighkstarCut{"ConfOptHighkstarCut", -1., "Set a cut for high k*, above which the pairs are rejected. Set it to -1 to deactivate it"}; + Configurable ConfOptSameSpecies{"ConfOptSameSpecies", false, "Set to true if particle 1 and particle 2 are the same species"}; + Configurable ConfOptUseCPR{"ConfOptCPR", true, "Close Pair Rejection"}; + Configurable ConfOptCPRPlotPerRadii{"ConfOptCPRPlotPerRadii", false, "Plot CPR per radii"}; + Configurable ConfOptCPRdeltaPhiMax{"ConfOptCPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; + Configurable ConfOptCPRdeltaEtaMax{"ConfOptCPRdeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; + ConfigurableAxis ConfOptDummy{"ConfOptDummy", {1, 0, 1}, "Dummy axis"}; + + /// Event selection + Configurable ConfEvent_minMult{"ConfEvent_minMult", 0, "Minimum Multiplicity (MultNtr)"}; + Configurable ConfEvent_maxMult{"ConfEvent_maxMult", 99999, "Maximum Multiplicity (MultNtr)"}; + Configurable ConfEvent_minMultPercentile{"ConfEvent_minMultPercentile", 0, "Minimum Multiplicity Percentile"}; + Configurable ConfEvent_maxMultPercentile{"ConfEvent_maxMultPercentile", 100, "Maximum Multiplicity Percentile"}; + + Filter EventMultiplicity = aod::femtodreamcollision::multNtr >= ConfEvent_minMult && aod::femtodreamcollision::multNtr <= ConfEvent_maxMult; + Filter EventMultiplicityPercentile = aod::femtodreamcollision::multV0M >= ConfEvent_minMultPercentile && aod::femtodreamcollision::multV0M <= ConfEvent_maxMultPercentile; + + using FilteredCollisions = soa::Filtered; + using FilteredCollision = FilteredCollisions::iterator; + using FilteredMaskedCollisions = soa::Filtered>; + using FilteredMaskedCollision = FilteredMaskedCollisions::iterator; + femtodreamcollision::BitMaskType BitMask = -1; + + /// Track 1 Configurable ConfTrk1_PDGCode{"ConfTrk1_PDGCode", 2212, "PDG code of particle 1 (Track)"}; Configurable ConfTrk1_CutBit{"ConfTrk1_CutBit", 3191978, "Selection bit from cutCulator for particle 1 (Track)"}; Configurable ConfTrk1_TPCBit{"ConfTrk1_TPCBit", 4, "PID TPC bit from cutCulator for particle 1 (Track)"}; @@ -90,8 +105,7 @@ struct femtoDreamPairTaskTrackTrack { /// Histogramming for particle 1 FemtoDreamParticleHisto trackHistoPartOne; - /// Particle 2 - Configurable ConfIsSame{"ConfIsSame", false, "Set to true if particle 1 and particle 2 are the same species"}; + /// Track 2 Configurable ConfTrk2_PDGCode{"ConfTrk2_PDGCode", 2212, "PDG code of particle 2 (Track)"}; Configurable ConfTrk2_CutBit{"ConfTrk2_CutBit", 3191978, "Selection bit from cutCulator for particle 2 (Track)"}; Configurable ConfTrk2_TPCBit{"ConfTrk2_TPCBit", 4, "PID TPC bit from cutCulator for particle 2 (Track)"}; @@ -102,7 +116,7 @@ struct femtoDreamPairTaskTrackTrack { Configurable ConfTrk2_minEta{"ConfTrk2_minEta", -10., "Minimum eta of partricle 2 (Track)"}; Configurable ConfTrk2_maxEta{"ConfTrk2_maxEta", 10., "Maximum eta of partricle 2 (Track)"}; - /// Partition for particle 2 + /// Partition for track 2 Partition PartitionTrk2 = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && (ncheckbit(aod::femtodreamparticle::cut, ConfTrk2_CutBit)) && ifnode(aod::femtodreamparticle::pt * (nexp(aod::femtodreamparticle::eta) + nexp(-1.f * aod::femtodreamparticle::eta)) / 2.f <= ConfTrk2_PIDThres, ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk2_TPCBit), ncheckbit(aod::femtodreamparticle::pidcut, ConfTrk2_TPCTOFBit)) && @@ -119,33 +133,35 @@ struct femtoDreamPairTaskTrackTrack { (aod::femtodreamparticle::eta > ConfTrk2_minEta) && (aod::femtodreamparticle::eta < ConfTrk2_maxEta); - /// Histogramming for particle 2 + /// Histogramming for track 2 FemtoDreamParticleHisto trackHistoPartTwo; /// Histogramming for Event FemtoDreamEventHisto eventHisto; - /// particle part - ConfigurableAxis ConfTempFitVarBins{"ConfTempFitVarBins", {300, -0.15, 0.15}, "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"}; - - /// 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 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)"}; - 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 ConfCPRdeltaPhiMax{"ConfCPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; - Configurable ConfCPRdeltaEtaMax{"ConfCPRdeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; - ConfigurableAxis ConfDummy{"ConfDummy", {1, 0, 1}, "Dummy axis"}; + /// Binning configurables + ConfigurableAxis ConfBinTempFitVar{"ConfBinTempFitVar", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot"}; + ConfigurableAxis ConfBinTrackpT{"ConfBinTrackpT", {20, 0.5, 4.05}, "pT binning for pT vs. TempFitVar plot"}; + ConfigurableAxis ConfBinpT{"ConfBinpT", {20, 0.5, 4.05}, "pT binning"}; + ConfigurableAxis ConfBinkstar{"ConfBinkstar", {1500, 0., 6.}, "binning kstar"}; + ConfigurableAxis ConfBinkT{"ConfBinkT", {150, 0., 9.}, "binning kT"}; + ConfigurableAxis ConfBinmT{"ConfBinmT", {225, 0., 7.5}, "binning mT"}; + + ConfigurableAxis ConfBin4Dkstar{"ConfBin4Dkstar", {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 ConfBin4DmT{"ConfBin4DmT", {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 ConfBin4Dmult{"ConfBin4Dmult", {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 ConfBin4DmultPercentile{"ConfBin4DmultPercentile", {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)"}; + + // Mixing configurables + ConfigurableAxis ConfMixingBinMult{"ConfMixingBinMult", {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 ConfMixingBinMultPercentile{"ConfMixingBinMultPercentile", {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 ConfMixingBinVztx{"ConfMixingBinVztx", {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 ConfMixingDepth{"ConfMixingDepth", 5, "Number of events for mixing"}; + Configurable ConfMixingPolicy{"ConfMixingBinPolicy", 0, "Binning policy for mixing - 0: multiplicity, 1: multipliciy percentile, 2: both"}; + + ColumnBinningPolicy colBinningMult{{ConfMixingBinVztx, ConfMixingBinMult}, true}; + ColumnBinningPolicy colBinningMultPercentile{{ConfMixingBinVztx, ConfMixingBinMultPercentile}, true}; + ColumnBinningPolicy colBinningMultMultPercentile{{ConfMixingBinVztx, ConfMixingBinMult, ConfMixingBinMultPercentile}, true}; FemtoDreamContainer sameEventCont; FemtoDreamContainer mixedEventCont; @@ -154,26 +170,31 @@ struct femtoDreamPairTaskTrackTrack { /// Histogram output HistogramRegistry qaRegistry{"TrackQA", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry resultRegistry{"Correlations", {}, OutputObjHandlingPolicy::AnalysisObject}; - HistogramRegistry MixQaRegistry{"MixQaRegistry", {}, OutputObjHandlingPolicy::AnalysisObject}; void init(InitContext& context) { eventHisto.init(&qaRegistry); - trackHistoPartOne.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfDummy, ConfIsMC, ConfTrk1_PDGCode); - if (!ConfIsSame) { - trackHistoPartTwo.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfDummy, ConfIsMC, ConfTrk2_PDGCode); + trackHistoPartOne.init(&qaRegistry, ConfBinTrackpT, ConfBinTempFitVar, ConfOptDummy, ConfOptDummy, ConfOptDummy, ConfOptDummy, ConfOptIsMC, ConfTrk1_PDGCode); + if (!ConfOptSameSpecies) { + trackHistoPartTwo.init(&qaRegistry, ConfBinTrackpT, ConfBinTempFitVar, ConfOptDummy, ConfOptDummy, ConfOptDummy, ConfOptDummy, ConfOptIsMC, ConfTrk2_PDGCode); } - 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, + ConfBinkstar, ConfBinpT, ConfBinkT, ConfBinmT, ConfMixingBinMult, ConfMixingBinMultPercentile, + ConfBin4Dkstar, ConfBin4DmT, ConfBin4Dmult, ConfBin4DmultPercentile, + ConfOptIsMC, ConfOptUse4D, ConfOptExtendedPlots, + ConfOptHighkstarCut); + mixedEventCont.init(&resultRegistry, + ConfBinkstar, ConfBinpT, ConfBinkT, ConfBinmT, ConfMixingBinMult, ConfMixingBinMultPercentile, + ConfBin4Dkstar, ConfBin4DmT, ConfBin4Dmult, ConfBin4DmultPercentile, + ConfOptIsMC, ConfOptUse4D, ConfOptExtendedPlots, + ConfOptHighkstarCut); - sameEventCont.init(&resultRegistry, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, ConfIsMC, ConfUse3D, ConfExtendedPlots, ConfHighkstarCut); - mixedEventCont.init(&resultRegistry, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, ConfIsMC, ConfUse3D, ConfExtendedPlots, ConfHighkstarCut); sameEventCont.setPDGCodes(ConfTrk1_PDGCode, ConfTrk2_PDGCode); mixedEventCont.setPDGCodes(ConfTrk1_PDGCode, ConfTrk2_PDGCode); pairCleaner.init(&qaRegistry); - if (ConfIsCPR.value) { - pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRPlotPerRadii.value); + if (ConfOptUseCPR.value) { + pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfOptCPRdeltaPhiMax.value, ConfOptCPRdeltaEtaMax.value, ConfOptCPRPlotPerRadii.value); } // get bit for the collision mask @@ -199,7 +220,7 @@ struct femtoDreamPairTaskTrackTrack { containsNameValuePair(device.options, "ConfTrk2_minEta", ConfTrk2_minEta.value) && containsNameValuePair(device.options, "ConfTrk2_maxEta", ConfTrk2_maxEta.value)) { mask.set(index); - MaskBit = static_cast(mask.to_ulong()); + BitMask = static_cast(mask.to_ulong()); LOG(info) << "Device name matched: " << device.name; LOG(info) << "Bitmask for collisions: " << mask.to_string(); break; @@ -219,7 +240,6 @@ struct femtoDreamPairTaskTrackTrack { template void fillCollision(CollisionType col) { - MixQaRegistry.fill(HIST("MixingQA/hSECollisionBins"), colBinning.getBin({col.posZ(), col.multNtr()})); eventHisto.fillQA(col); } @@ -233,25 +253,24 @@ struct femtoDreamPairTaskTrackTrack { /// @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 SliceTrk1, PartitionType SliceTrk2, PartType parts, float magFieldTesla, int multCol) + template + void doSameEvent(PartitionType SliceTrk1, PartitionType SliceTrk2, PartType parts, Collision col) { - /// Histogramming same event for (auto& part : SliceTrk1) { trackHistoPartOne.fillQA(part, aod::femtodreamparticle::kPt); } - if (!ConfIsSame.value) { + if (!ConfOptSameSpecies.value) { for (auto& part : SliceTrk2) { trackHistoPartTwo.fillQA(part, aod::femtodreamparticle::kPt); } } /// Now build the combinations - if (ConfIsSame.value) { + if (ConfOptSameSpecies.value) { for (auto& [p1, p2] : combinations(CombinationsStrictlyUpperIndexPolicy(SliceTrk1, SliceTrk2))) { - if (ConfIsCPR.value) { - if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { + if (ConfOptUseCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, col.magField())) { continue; } } @@ -259,12 +278,12 @@ struct femtoDreamPairTaskTrackTrack { if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; } - sameEventCont.setPair(p1, p2, multCol, ConfUse3D, ConfExtendedPlots); + sameEventCont.setPair(p1, p2, col.multNtr(), col.multV0M(), ConfOptUse4D, ConfOptExtendedPlots); } } else { for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(SliceTrk1, SliceTrk2))) { - if (ConfIsCPR.value) { - if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { + if (ConfOptUseCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, col.magField())) { continue; } } @@ -272,7 +291,7 @@ struct femtoDreamPairTaskTrackTrack { if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; } - sameEventCont.setPair(p1, p2, multCol, ConfUse3D, ConfExtendedPlots); + sameEventCont.setPair(p1, p2, col.multNtr(), col.multV0M(), ConfOptUse4D, ConfOptExtendedPlots); } } } @@ -280,7 +299,7 @@ struct femtoDreamPairTaskTrackTrack { /// process function for to call doSameEvent with Data /// \param col subscribe to the collision table (Data) /// \param parts subscribe to the femtoDreamParticleTable - void processSameEvent(o2::aod::FDCollision& col, o2::aod::FDParticles& parts) + void processSameEvent(FilteredCollision& col, o2::aod::FDParticles& parts) { fillCollision(col); auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); @@ -288,25 +307,25 @@ struct femtoDreamPairTaskTrackTrack { if (SliceTrk1.size() == 0 && SliceTrk2.size() == 0) { return; } - doSameEvent(SliceTrk1, SliceTrk2, parts, col.magField(), col.multNtr()); + doSameEvent(SliceTrk1, SliceTrk2, parts, col); } PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processSameEvent, "Enable processing same event", true); - void processSameEventMasked(MaskedCollision& col, o2::aod::FDParticles& parts) + void processSameEventMasked(FilteredMaskedCollision& col, o2::aod::FDParticles& parts) { - if (ConfIsSame.value) { - if ((col.bitmaskTrackOne() & MaskBit) != MaskBit) { + if (ConfOptSameSpecies.value) { + if ((col.bitmaskTrackOne() & BitMask) != BitMask) { return; } } else { - if ((col.bitmaskTrackOne() & MaskBit) != MaskBit && (col.bitmaskTrackTwo() & MaskBit) != MaskBit) { + if ((col.bitmaskTrackOne() & BitMask) != BitMask && (col.bitmaskTrackTwo() & BitMask) != BitMask) { return; } } fillCollision(col); auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); auto SliceTrk2 = PartitionTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - doSameEvent(SliceTrk1, SliceTrk2, parts, col.magField(), col.multNtr()); + doSameEvent(SliceTrk1, SliceTrk2, parts, col); } PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processSameEventMasked, "Enable processing same event with masks", false); @@ -314,7 +333,7 @@ struct femtoDreamPairTaskTrackTrack { /// \param col subscribe to the collision table (Monte Carlo Reconstructed reconstructed) /// \param parts subscribe to joined table FemtoDreamParticles and FemtoDreamMCLables to access Monte Carlo truth /// \param FemtoDreamMCParticles subscribe to the Monte Carlo truth table - void processSameEventMC(o2::aod::FDCollision& col, soa::Join& parts, + void processSameEventMC(FilteredCollision& col, soa::Join& parts, o2::aod::FDMCParticles&) { fillCollision(col); @@ -323,85 +342,105 @@ struct femtoDreamPairTaskTrackTrack { if (SliceMCTrk1.size() == 0 && SliceMCTrk2.size() == 0) { return; } - doSameEvent(SliceMCTrk1, SliceMCTrk2, parts, col.magField(), col.multNtr()); + doSameEvent(SliceMCTrk1, SliceMCTrk2, parts, col); } PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processSameEventMC, "Enable processing same event for Monte Carlo", false); - void processSameEventMCMasked(MaskedCollision& col, soa::Join& parts, + void processSameEventMCMasked(FilteredMaskedCollision& col, soa::Join& parts, o2::aod::FDMCParticles&) { - if (ConfIsSame.value) { - if ((col.bitmaskTrackOne() & MaskBit) != MaskBit) { + if (ConfOptSameSpecies.value) { + if ((col.bitmaskTrackOne() & BitMask) != BitMask) { return; } } else { - if ((col.bitmaskTrackOne() & MaskBit) != MaskBit && (col.bitmaskTrackTwo() & MaskBit) != MaskBit) { + if ((col.bitmaskTrackOne() & BitMask) != BitMask && (col.bitmaskTrackTwo() & BitMask) != BitMask) { return; } } fillCollision(col); auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); auto SliceMCTrk2 = PartitionMCTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - doSameEvent(SliceMCTrk1, SliceMCTrk2, parts, col.magField(), col.multNtr()); + doSameEvent(SliceMCTrk1, SliceMCTrk2, parts, col); } PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processSameEventMCMasked, "Enable processing same event for Monte Carlo with masked collisions", false); - /// This function processes the mixed event - /// \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 doMixedEvent(PartitionType SliceTrk1, PartitionType SliceTrk2, PartType parts, float magFieldTesla, int multCol) + template + void doMixedEvent_NotMasked(CollisionType& cols, PartType& parts, PartitionType& part1, PartitionType& part2, BinningType policy) { - for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(SliceTrk1, SliceTrk2))) { - if (ConfIsCPR.value) { - if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { - continue; + for (auto const& [collision1, collision2] : soa::selfCombinations(policy, ConfMixingDepth.value, -1, cols, cols)) { + auto SliceTrk1 = part1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto SliceTrk2 = part2->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + if (SliceTrk1.size() == 0 || SliceTrk2.size() == 0) { + continue; + } + for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(SliceTrk1, SliceTrk2))) { + if (ConfOptUseCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, collision1.magField())) { + continue; + } } + mixedEventCont.setPair(p1, p2, collision1.multNtr(), collision1.multV0M(), ConfOptUse4D, ConfOptExtendedPlots); + } + } + } + + template + void doMixedEvent_Masked(CollisionType& cols, PartType& parts, PartitionType& part1, PartitionType& part2, BinningType policy) + { + Partition PartitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & BitMask) == BitMask && aod::femtodreamcollision::downsample == true; + Partition PartitionMaskedCol2 = (aod::femtodreamcollision::bitmaskTrackTwo & BitMask) == BitMask && aod::femtodreamcollision::downsample == true; + PartitionMaskedCol1.bindTable(cols); + PartitionMaskedCol2.bindTable(cols); + for (auto const& [collision1, collision2] : combinations(soa::CombinationsBlockUpperIndexPolicy(policy, ConfMixingDepth.value, -1, PartitionMaskedCol1, PartitionMaskedCol2))) { + auto SliceTrk1 = part1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto SliceTrk2 = part2->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(SliceTrk1, SliceTrk2))) { + if (ConfOptUseCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, collision1.magField())) { + continue; + } + } + mixedEventCont.setPair(p1, p2, collision1.multNtr(), collision1.multV0M(), ConfOptUse4D, ConfOptExtendedPlots); } - mixedEventCont.setPair(p1, p2, multCol, ConfUse3D, ConfExtendedPlots); } } /// process function for to call doMixedEvent with Data /// @param cols subscribe to the collisions table (Data) /// @param parts subscribe to the femtoDreamParticleTable - void processMixedEvent(o2::aod::FDCollisions& cols, o2::aod::FDParticles& parts) + void processMixedEvent(FilteredCollisions& cols, o2::aod::FDParticles& parts) { - for (auto const& [collision1, collision2] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, cols, cols)) { - const int multiplicityCol = collision1.multNtr(); - MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); - auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); - auto SliceTrk2 = PartitionTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); - if (SliceTrk1.size() == 0 || SliceTrk2.size() == 0) { - continue; - } - const auto magFieldTesla1 = collision1.magField(); - doMixedEvent(SliceTrk1, SliceTrk2, parts, magFieldTesla1, multiplicityCol); + switch (ConfMixingPolicy.value) { + case femtodreamcollision::kMult: + doMixedEvent_NotMasked(cols, parts, PartitionTrk1, PartitionTrk2, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent_NotMasked(cols, parts, PartitionTrk1, PartitionTrk2, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent_NotMasked(cols, parts, PartitionTrk1, PartitionTrk2, colBinningMultMultPercentile); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; } } PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processMixedEvent, "Enable processing mixed events", true); - void processMixedEventMasked(MaskedCollisions& cols, o2::aod::FDParticles& parts) + void processMixedEventMasked(FilteredMaskedCollisions& cols, o2::aod::FDParticles& parts) { - Partition PartitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & MaskBit) == MaskBit; - Partition PartitionMaskedCol2 = (aod::femtodreamcollision::bitmaskTrackTwo & MaskBit) == MaskBit; - - PartitionMaskedCol1.bindTable(cols); - PartitionMaskedCol2.bindTable(cols); - - for (auto const& [collision1, collision2] : combinations(soa::CombinationsBlockUpperIndexPolicy(colBinning, ConfNEventsMix.value, -1, PartitionMaskedCol1, PartitionMaskedCol2))) { - const auto multiplicityCol = collision1.multNtr(); - const auto magFieldTesla1 = collision1.magField(); - MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); - auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); - auto SliceTrk2 = PartitionTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); - doMixedEvent(SliceTrk1, SliceTrk2, parts, magFieldTesla1, multiplicityCol); + switch (ConfMixingPolicy.value) { + case static_cast(femtodreamcollision::kMult): + doMixedEvent_Masked(cols, parts, PartitionTrk1, PartitionTrk2, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent_Masked(cols, parts, PartitionTrk1, PartitionTrk2, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent_Masked(cols, parts, PartitionTrk1, PartitionTrk2, colBinningMultMultPercentile); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; } } PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processMixedEventMasked, "Enable processing mixed events", false); @@ -410,37 +449,38 @@ struct femtoDreamPairTaskTrackTrack { /// @param cols subscribe to the collisions table (Monte Carlo Reconstructed reconstructed) /// @param parts subscribe to joined table FemtoDreamParticles and FemtoDreamMCLables to access Monte Carlo truth /// @param FemtoDreamMCParticles subscribe to the Monte Carlo truth table - void processMixedEventMC(o2::aod::FDCollisions& cols, soa::Join& parts, o2::aod::FDMCParticles&) + void processMixedEventMC(FilteredCollisions& cols, soa::Join& parts, o2::aod::FDMCParticles&) { - for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, cols, cols)) { - const int multiplicityCol = collision1.multNtr(); - MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); - auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); - auto SliceMCTrk2 = PartitionMCTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); - if (SliceMCTrk1.size() == 0 || SliceMCTrk2.size() == 0) { - continue; - } - const auto magFieldTesla1 = collision1.magField(); - doMixedEvent(SliceMCTrk1, SliceMCTrk2, parts, magFieldTesla1, multiplicityCol); + switch (ConfMixingPolicy.value) { + case femtodreamcollision::kMult: + doMixedEvent_NotMasked(cols, parts, PartitionMCTrk1, PartitionMCTrk2, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent_NotMasked(cols, parts, PartitionMCTrk1, PartitionMCTrk2, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent_NotMasked(cols, parts, PartitionMCTrk1, PartitionMCTrk2, colBinningMultMultPercentile); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; } } PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processMixedEventMC, "Enable processing mixed events MC", false); - void processMixedEventMCMasked(MaskedCollisions& cols, soa::Join& parts, o2::aod::FDMCParticles&) + void processMixedEventMCMasked(FilteredMaskedCollisions& cols, soa::Join& parts, o2::aod::FDMCParticles&) { - Partition PartitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & MaskBit) == MaskBit; - Partition PartitionMaskedCol2 = (aod::femtodreamcollision::bitmaskTrackTwo & MaskBit) == MaskBit; - - PartitionMaskedCol1.bindTable(cols); - PartitionMaskedCol2.bindTable(cols); - - for (auto const& [collision1, collision2] : combinations(soa::CombinationsBlockUpperIndexPolicy(colBinning, ConfNEventsMix.value, -1, PartitionMaskedCol1, PartitionMaskedCol2))) { - const auto multiplicityCol = collision1.multNtr(); - const auto& magFieldTesla1 = collision1.magField(); - MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); - auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); - auto SliceMCTrk2 = PartitionMCTrk2->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); - doMixedEvent(SliceMCTrk1, SliceMCTrk2, parts, magFieldTesla1, multiplicityCol); + switch (ConfMixingPolicy.value) { + case femtodreamcollision::kMult: + doMixedEvent_Masked(cols, parts, PartitionMCTrk1, PartitionMCTrk2, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent_Masked(cols, parts, PartitionMCTrk1, PartitionMCTrk2, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent_Masked(cols, parts, PartitionMCTrk1, PartitionMCTrk2, colBinningMultMultPercentile); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; } } PROCESS_SWITCH(femtoDreamPairTaskTrackTrack, processMixedEventMCMasked, "Enable processing mixed events MC with masked collisions", false); diff --git a/PWGCF/FemtoDream/femtoDreamPairTaskTrackV0.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackV0.cxx similarity index 53% rename from PWGCF/FemtoDream/femtoDreamPairTaskTrackV0.cxx rename to PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackV0.cxx index 025f2df1271..d746f217c5b 100644 --- a/PWGCF/FemtoDream/femtoDreamPairTaskTrackV0.cxx +++ b/PWGCF/FemtoDream/Tasks/femtoDreamPairTaskTrackV0.cxx @@ -25,12 +25,12 @@ #include "Framework/StepTHn.h" #include "PWGCF/DataModel/FemtoDerived.h" -#include "FemtoDreamParticleHisto.h" -#include "FemtoDreamEventHisto.h" -#include "FemtoDreamPairCleaner.h" -#include "FemtoDreamContainer.h" -#include "FemtoDreamDetaDphiStar.h" -#include "FemtoUtils.h" +#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" +#include "PWGCF/FemtoDream/Core/femtoDreamContainer.h" +#include "PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h" +#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" using namespace o2; using namespace o2::aod; @@ -43,9 +43,31 @@ struct femtoDreamPairTaskTrackV0 { SliceCache cache; Preslice perCol = aod::femtodreamparticle::fdCollisionId; - using MaskedCollisions = soa::Join; - using MaskedCollision = MaskedCollisions::iterator; - femtodreamcollision::BitMaskType MaskBit = -1; + /// General options + Configurable ConfOptIsMC{"ConfOptIsMC", false, "Enable additional Histogramms in the case of a MonteCarlo Run"}; + Configurable ConfOptUse4D{"ConfOptUse4D", false, "Enable four dimensional histogramms (to be used only for analysis with high statistics): k* vs multiplicity vs multiplicity percentil vs mT"}; + Configurable ConfOptExtendedPlots{"ConfOptExtendedPlots", false, "Enable additional three dimensional histogramms. High memory consumption. Use for debugging"}; + Configurable ConfOptHighkstarCut{"ConfOptHighkstarCut", -1., "Set a cut for high k*, above which the pairs are rejected. Set it to -1 to deactivate it"}; + Configurable ConfOptUseCPR{"ConfOptCPR", true, "Close Pair Rejection"}; + Configurable ConfOptCPRPlotPerRadii{"ConfOptCPRPlotPerRadii", false, "Plot CPR per radii"}; + Configurable ConfOptCPRdeltaPhiMax{"ConfOptCPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; + Configurable ConfOptCPRdeltaEtaMax{"ConfOptCPRdeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; + ConfigurableAxis ConfOptDummy{"ConfOptDummy", {1, 0, 1}, "Dummy axis"}; + + /// Event selection + Configurable ConfEvent_minMult{"ConfEvent_minMult", 0, "Minimum Multiplicity (MultNtr)"}; + Configurable ConfEvent_maxMult{"ConfEvent_maxMult", 99999, "Maximum Multiplicity (MultNtr)"}; + Configurable ConfEvent_minMultPercentile{"ConfEvent_minMultPercentile", 0, "Minimum Multiplicity Percentile"}; + Configurable ConfEvent_maxMultPercentile{"ConfEvent_maxMultPercentile", 100, "Maximum Multiplicity Percentile"}; + + Filter EventMultiplicity = aod::femtodreamcollision::multNtr >= ConfEvent_minMult && aod::femtodreamcollision::multNtr <= ConfEvent_maxMult; + Filter EventMultiplicityPercentile = aod::femtodreamcollision::multV0M >= ConfEvent_minMultPercentile && aod::femtodreamcollision::multV0M <= ConfEvent_maxMultPercentile; + + using FilteredCollisions = soa::Filtered; + using FilteredCollision = FilteredCollisions::iterator; + using FilteredMaskedCollisions = soa::Filtered>; + using FilteredMaskedCollision = FilteredMaskedCollisions::iterator; + femtodreamcollision::BitMaskType BitMask = -1; /// Particle 1 (track) Configurable ConfTrk1_PDGCode{"ConfTrk1_PDGCode", 2212, "PDG code of Particle 1 (Track)"}; @@ -58,9 +80,6 @@ struct femtoDreamPairTaskTrackV0 { Configurable ConfTrk1_minEta{"ConfTrk1_minEta", -10., "Minimum eta of partricle 1 (Track)"}; Configurable ConfTrk1_maxEta{"ConfTrk1_maxEta", 10., "Maximum eta of partricle 1 (Track)"}; - 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"}; - Filter trackPtFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt > ConfTrk1_minPt, true); Filter trackPtFilterLow = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::pt < ConfTrk1_maxPt, true); Filter trackEtaFilterUp = ifnode(aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack), aod::femtodreamparticle::eta > ConfTrk1_minEta, true); @@ -77,13 +96,6 @@ struct femtoDreamPairTaskTrackV0 { Configurable ConfV02_ChildNeg_CutBit{"ConfV02_ChildNeg_CutBit", 149, "Selection bit for negative child of V0"}; Configurable ConfV02_ChildNeg_TPCBit{"ConfV02_ChildNeg_TPCBit", 2, "PID TPC bit for negative child of V0"}; - 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"}; - ConfigurableAxis ConfV0TempFitVarInvMassBins{"ConfV0TempFitVarInvMassBins", {200, 1, 1.2}, "V0: InvMass binning"}; - - ConfigurableAxis ConfV0ChildTempFitVarBins{"ConfV0ChildTempFitVarBins", {300, -0.15, 0.15}, "V0 child: binning of the TempFitVar in the pT vs. TempFitVar plot"}; - ConfigurableAxis ConfV0ChildTempFitVarpTBins{"ConfV0ChildTempFitVarpTBins", {20, 0.5, 4.05}, "V0 child: pT binning of the pT vs. TempFitVar plot"}; - Configurable ConfV02_minInvMass{"ConfV02_minInvMass", 1.08, "Minimum invariant mass of Partricle 2 (particle) (V0)"}; Configurable ConfV02_maxInvMass{"ConfV02_maxInvMass", 1.15, "Maximum invariant mass of Partricle 2 (particle) (V0)"}; Configurable ConfV02_minInvMassAnti{"ConfV02_minInvMassAnti", 0., "Minimum invariant mass of Partricle 2 (antiparticle) (V0)"}; @@ -130,33 +142,40 @@ struct femtoDreamPairTaskTrackV0 { /// Histogramming for Event FemtoDreamEventHisto eventHisto; - /// Correlation part - Configurable ConfIsMC{"ConfIsMC", false, "Enable additional Histogramms 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 ConfExtendedPlots{"ConfExtendedPlots", false, "Enable additional three dimensional histogramms. High memory consumption. Use for debugging"}; - Configurable ConfHighkstarCut{"ConfHighkstarCut", -1., "Set a cut for high k*, above which the pairs are rejected. Set it to -1 to deactivate it"}; - - 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"}; - 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 ConfCPRdeltaPhiMax{"ConfCPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; - Configurable ConfCPRdeltaEtaMax{"ConfCPRdeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; - - 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 ConfDummy{"ConfDummy", {1, 0, 1}, "Dummy axis"}; - - ColumnBinningPolicy colBinning{{ConfVtxBins, ConfMultBins}, true}; + /// Binning configurables + ConfigurableAxis ConfBinTempFitVarTrack{"ConfBinTempFitVarTrack", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot (Track)"}; + ConfigurableAxis ConfBinTempFitVarV0{"ConfBinTempFitVarV0", {300, 0.9, 1}, "binning of the TempFitVar in the pT vs. TempFitVar plot (V0)"}; + ConfigurableAxis ConfBinTempFitVarV0Child{"ConfBinTempFitVarV0Child", {300, -0.15, 0.15}, "binning of the TempFitVar in the pT vs. TempFitVar plot (V0 child)"}; + ConfigurableAxis ConfBinInvMass{"ConfBinInvMass", {200, 1, 1.2}, "InvMass binning"}; + ConfigurableAxis ConfBinpTTrack{"ConfBinpTTrack", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot (Track)"}; + ConfigurableAxis ConfBinpTV0{"ConfBinpTV0", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot (V0)"}; + ConfigurableAxis ConfBinpTV0Child{"ConfBinpTV0Child", {20, 0.5, 4.05}, "pT binning of the pT vs. TempFitVar plot (V0)"}; + ConfigurableAxis ConfBinpT{"ConfBinpT", {20, 0.5, 4.05}, "pT binning"}; + ConfigurableAxis ConfBinkstar{"ConfBinkstar", {1500, 0., 6.}, "binning kstar"}; + ConfigurableAxis ConfBinkT{"ConfBinkT", {150, 0., 9.}, "binning kT"}; + ConfigurableAxis ConfBinmT{"ConfBinmT", {225, 0., 7.5}, "binning mT"}; + + ConfigurableAxis ConfBin4Dkstar{"ConfBin4Dkstar", {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 ConfBin4DmT{"ConfBin4DmT", {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 ConfBin4DMult{"ConfBin4Dmult", {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 ConfBin4DmultPercentile{"ConfBin4DmultPercentile", {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)"}; + + // Mixing configurables + ConfigurableAxis ConfMixingBinMult{"ConfMixingBinMult", {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 ConfMixingBinMultPercentile{"ConfMixingBinMultPercentile", {VARIABLE_WIDTH, 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.f}, "Mixing bins - multiplicity percentile"}; + ConfigurableAxis ConfMixingBinVztx{"ConfMixingBinVztx", {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 ConfMixingDepth{"ConfMixingDepth", 5, "Number of events for mixing"}; + Configurable ConfMixingPolicy{"ConfMixingBinPolicy", 0, "Binning policy for mixing - 0: multiplicity, 1: multipliciy percentile, 2: both"}; + + ColumnBinningPolicy colBinningMult{{ConfMixingBinVztx, ConfMixingBinMult}, true}; + ColumnBinningPolicy colBinningMultPercentile{{ConfMixingBinVztx, ConfMixingBinMultPercentile}, true}; + ColumnBinningPolicy colBinningMultMultPercentile{{ConfMixingBinVztx, ConfMixingBinMult, ConfMixingBinMultPercentile}, true}; FemtoDreamContainer sameEventCont; FemtoDreamContainer mixedEventCont; FemtoDreamPairCleaner pairCleaner; FemtoDreamDetaDphiStar pairCloseRejection; + /// Histogram output HistogramRegistry qaRegistry{"TrackQA", {}, OutputObjHandlingPolicy::AnalysisObject}; HistogramRegistry resultRegistry{"Correlations", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -164,18 +183,31 @@ struct femtoDreamPairTaskTrackV0 { void init(InitContext& context) { eventHisto.init(&qaRegistry); - trackHistoPartOne.init(&qaRegistry, ConfTrkTempFitVarpTBins, ConfTrkTempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfDummy, ConfIsMC, ConfTrk1_PDGCode); - trackHistoPartTwo.init(&qaRegistry, ConfV0TempFitVarpTBins, ConfV0TempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfV0TempFitVarInvMassBins, ConfIsMC, ConfV02_PDGCode); - posChildHistos.init(&qaRegistry, ConfV0ChildTempFitVarpTBins, ConfV0ChildTempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfDummy, false, false); - negChildHistos.init(&qaRegistry, ConfV0ChildTempFitVarpTBins, ConfV0ChildTempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfDummy, false, false); + // void init(HistogramRegistry* registry, + // T& MomentumBins, T& tempFitVarBins, T& NsigmaTPCBins, T& NsigmaTOFBins, T& NsigmaTPCTOFBins, T& InvMassBins, + // bool isMC, int pdgCode, bool isDebug = false) + trackHistoPartOne.init(&qaRegistry, ConfBinpTTrack, ConfBinTempFitVarTrack, ConfOptDummy, ConfOptDummy, ConfOptDummy, ConfOptDummy, ConfOptIsMC, ConfTrk1_PDGCode); + trackHistoPartTwo.init(&qaRegistry, ConfBinpTV0, ConfBinTempFitVarV0, ConfOptDummy, ConfOptDummy, ConfOptDummy, ConfBinInvMass, ConfOptIsMC, ConfV02_PDGCode); + posChildHistos.init(&qaRegistry, ConfBinpTV0Child, ConfBinTempFitVarV0Child, ConfOptDummy, ConfOptDummy, ConfOptDummy, ConfOptDummy, false, false); + negChildHistos.init(&qaRegistry, ConfBinpTV0Child, ConfBinTempFitVarV0Child, ConfOptDummy, ConfOptDummy, ConfOptDummy, ConfOptDummy, false, false); + + sameEventCont.init(&resultRegistry, + ConfBinkstar, ConfBinpT, ConfBinkT, ConfBinmT, ConfMixingBinMult, ConfMixingBinMultPercentile, + ConfBin4Dkstar, ConfBin4DmT, ConfBin4DMult, ConfBin4DmultPercentile, + ConfOptIsMC, ConfOptUse4D, ConfOptExtendedPlots, + ConfOptHighkstarCut); - sameEventCont.init(&resultRegistry, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, ConfIsMC, ConfUse3D, ConfExtendedPlots, ConfHighkstarCut); sameEventCont.setPDGCodes(ConfTrk1_PDGCode, ConfV02_PDGCode); - mixedEventCont.init(&resultRegistry, ConfkstarBins, ConfMultBins, ConfkTBins, ConfmTBins, ConfmultBins3D, ConfmTBins3D, ConfIsMC, ConfUse3D, ConfExtendedPlots, ConfHighkstarCut); + mixedEventCont.init(&resultRegistry, + ConfBinkstar, ConfBinpT, ConfBinkT, ConfBinmT, ConfMixingBinMult, ConfMixingBinMultPercentile, + ConfBin4Dkstar, ConfBin4DmT, ConfBin4DMult, ConfBin4DmultPercentile, + ConfOptIsMC, ConfOptUse4D, ConfOptExtendedPlots, + ConfOptHighkstarCut); + mixedEventCont.setPDGCodes(ConfTrk1_PDGCode, ConfV02_PDGCode); pairCleaner.init(&qaRegistry); - if (ConfIsCPR.value) { - pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRPlotPerRadii.value); + if (ConfOptUseCPR.value) { + pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfOptCPRdeltaPhiMax.value, ConfOptCPRdeltaEtaMax.value, ConfOptCPRPlotPerRadii.value); } // get bit for the collision mask @@ -206,7 +238,7 @@ struct femtoDreamPairTaskTrackV0 { containsNameValuePair(device.options, "ConfV02_minEta", ConfV02_minEta.value) && containsNameValuePair(device.options, "ConfV02_maxEta", ConfV02_maxEta.value)) { mask.set(index); - MaskBit = static_cast(mask.to_ulong()); + BitMask = static_cast(mask.to_ulong()); LOG(info) << "Device name matched: " << device.name; LOG(info) << "Bitmask for collisions: " << mask.to_string(); break; @@ -224,14 +256,13 @@ struct femtoDreamPairTaskTrackV0 { } /// This function processes the same event and takes care of all the histogramming - template - void doSameEvent(T& SliceTrk1, R& SliceV02, S& parts, float magFieldTesla, int multCol) + template + void doSameEvent(PartitionType& SliceTrk1, PartitionType& SliceV02, TableTracks& parts, Collision col) { /// Histogramming same event for (auto& part : SliceTrk1) { trackHistoPartOne.fillQA(part, aod::femtodreamparticle::kPt); } - for (auto& v0 : SliceV02) { const auto& posChild = parts.iteratorAt(v0.index() - 2); const auto& negChild = parts.iteratorAt(v0.index() - 1); @@ -251,31 +282,29 @@ struct femtoDreamPairTaskTrackV0 { negChildHistos.fillQA(negChild, aod::femtodreamparticle::kPt); } } - - /// Now build the combinations + /// Now build particle combinations for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(SliceTrk1, SliceV02))) { const auto& posChild = parts.iteratorAt(p2.index() - 2); const auto& negChild = parts.iteratorAt(p2.index() - 1); - // check cuts on V0 children + // cuts on V0 children still need to be applied if (((posChild.cut() & ConfV02_ChildPos_CutBit) == ConfV02_ChildPos_CutBit) && ((posChild.pidcut() & ConfV02_ChildPos_TPCBit) == ConfV02_ChildPos_TPCBit) && ((negChild.cut() & ConfV02_ChildNeg_CutBit) == ConfV02_ChildNeg_CutBit) && ((negChild.pidcut() & ConfV02_ChildNeg_TPCBit) == ConfV02_ChildNeg_TPCBit)) { - if (ConfIsCPR.value) { - if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { + if (ConfOptUseCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, col.magField())) { continue; } } - // track cleaning if (!pairCleaner.isCleanPair(p1, p2, parts)) { continue; } - sameEventCont.setPair(p1, p2, multCol, ConfUse3D, ConfExtendedPlots); + sameEventCont.setPair(p1, p2, col.multNtr(), col.multV0M(), ConfOptUse4D, ConfOptExtendedPlots); } } } - void processSameEvent(o2::aod::FDCollision const& col, FilteredFDParticles const& parts) + void processSameEvent(FilteredCollision const& col, FilteredFDParticles const& parts) { eventHisto.fillQA(col); auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); @@ -283,23 +312,23 @@ struct femtoDreamPairTaskTrackV0 { if (SliceTrk1.size() == 0 && SliceV02.size() == 0) { return; } - doSameEvent(SliceTrk1, SliceV02, parts, col.magField(), col.multNtr()); + doSameEvent(SliceTrk1, SliceV02, parts, col); } PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processSameEvent, "Enable processing same event", true); - void processSameEventMasked(MaskedCollision const& col, FilteredFDParticles const& parts) + void processSameEventMasked(FilteredMaskedCollision const& col, FilteredFDParticles const& parts) { - if ((col.bitmaskTrackOne() & MaskBit) != MaskBit && (col.bitmaskTrackTwo() & MaskBit) != MaskBit) { + if ((col.bitmaskTrackOne() & BitMask) != BitMask && (col.bitmaskTrackTwo() & BitMask) != BitMask) { return; } eventHisto.fillQA(col); auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); auto SliceV02 = PartitionV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - doSameEvent(SliceTrk1, SliceV02, parts, col.magField(), col.multNtr()); + doSameEvent(SliceTrk1, SliceV02, parts, col); } PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processSameEventMasked, "Enable processing same event with masks", false); - void processSameEventMC(o2::aod::FDCollision& col, FilteredFDMCParts& parts, o2::aod::FDMCParticles&) + void processSameEventMC(FilteredCollision& col, FilteredFDMCParts& parts, o2::aod::FDMCParticles&) { eventHisto.fillQA(col); auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); @@ -307,115 +336,155 @@ struct femtoDreamPairTaskTrackV0 { if (SliceMCTrk1.size() == 0 && SliceMCV02.size() == 0) { return; } - doSameEvent(SliceMCTrk1, SliceMCV02, parts, col.magField(), col.multNtr()); + doSameEvent(SliceMCTrk1, SliceMCV02, parts, col); } PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processSameEventMC, "Enable processing same event MC", false); - void processSameEventMCMasked(MaskedCollision& col, FilteredFDMCParts& parts, o2::aod::FDMCParticles&) + void processSameEventMCMasked(FilteredMaskedCollision& col, FilteredFDMCParts& parts, o2::aod::FDMCParticles&) { - if ((col.bitmaskTrackOne() & MaskBit) != MaskBit && (col.bitmaskTrackTwo() & MaskBit) != MaskBit) { + if ((col.bitmaskTrackOne() & BitMask) != BitMask && (col.bitmaskTrackTwo() & BitMask) != BitMask) { return; } eventHisto.fillQA(col); auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); auto SliceMCV02 = PartitionMCV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - doSameEvent(SliceMCTrk1, SliceMCV02, parts, col.magField(), col.multNtr()); + doSameEvent(SliceMCTrk1, SliceMCV02, parts, col); } PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processSameEventMCMasked, "Enable processing same event MC with masks", false); - /// 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, ... - template - void doMixedEvent(PartitionType SliceTrk1, PartitionType SliceV02, PartType parts, float magFieldTesla, int multCol) + template + void doMixedEvent_NotMasked(CollisionType& cols, PartType& parts, PartitionType& part1, PartitionType& part2, BinningType policy) { - for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(SliceTrk1, SliceV02))) { - const auto& posChild = parts.iteratorAt(p2.index() - 2); - const auto& negChild = parts.iteratorAt(p2.index() - 1); - // check cuts on V0 children - if (((posChild.cut() & ConfV02_ChildPos_CutBit) == ConfV02_ChildPos_CutBit) && - ((posChild.pidcut() & ConfV02_ChildPos_TPCBit) == ConfV02_ChildPos_TPCBit) && - ((negChild.cut() & ConfV02_ChildNeg_CutBit) == ConfV02_ChildNeg_CutBit) && - ((negChild.pidcut() & ConfV02_ChildNeg_TPCBit) == ConfV02_ChildNeg_TPCBit)) { + for (auto const& [collision1, collision2] : soa::selfCombinations(policy, ConfMixingDepth.value, -1, cols, cols)) { + auto SliceTrk1 = part1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto SliceV02 = part2->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + if (SliceTrk1.size() == 0 || SliceV02.size() == 0) { continue; } - if (ConfIsCPR.value) { - if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { + for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(SliceTrk1, SliceV02))) { + const auto& posChild = parts.iteratorAt(p2.index() - 2); + const auto& negChild = parts.iteratorAt(p2.index() - 1); + // check cuts on V0 children + if (((posChild.cut() & ConfV02_ChildPos_CutBit) == ConfV02_ChildPos_CutBit) && + ((posChild.pidcut() & ConfV02_ChildPos_TPCBit) == ConfV02_ChildPos_TPCBit) && + ((negChild.cut() & ConfV02_ChildNeg_CutBit) == ConfV02_ChildNeg_CutBit) && + ((negChild.pidcut() & ConfV02_ChildNeg_TPCBit) == ConfV02_ChildNeg_TPCBit)) { continue; } + if (ConfOptUseCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, collision1.magField())) { + continue; + } + } + if (!pairCleaner.isCleanPair(p1, p2, parts)) { + continue; + } + mixedEventCont.setPair(p1, p2, collision1.multNtr(), collision1.multV0M(), ConfOptUse4D, ConfOptExtendedPlots); } - // pair cleaning - if (!pairCleaner.isCleanPair(p1, p2, parts)) { - continue; - } - mixedEventCont.setPair(p1, p2, multCol, ConfUse3D, ConfExtendedPlots); } } - void processMixedEvent(o2::aod::FDCollisions& cols, FilteredFDParticles& parts) + template + void doMixedEvent_Masked(CollisionType& cols, PartType& parts, PartitionType& part1, PartitionType& part2, BinningType policy) { - for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, cols, cols)) { - auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); - auto SliceV02 = PartitionV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); - - const int multCol = collision1.multNtr(); - const auto magFieldTesla1 = collision1.magField(); - if (SliceTrk1.size() == 0 || SliceV02.size() == 0) { - return; + Partition PartitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & BitMask) == BitMask && aod::femtodreamcollision::downsample == true; + Partition PartitionMaskedCol2 = (aod::femtodreamcollision::bitmaskTrackTwo & BitMask) == BitMask && aod::femtodreamcollision::downsample == true; + PartitionMaskedCol1.bindTable(cols); + PartitionMaskedCol2.bindTable(cols); + for (auto const& [collision1, collision2] : combinations(soa::CombinationsBlockUpperIndexPolicy(policy, ConfMixingDepth.value, -1, PartitionMaskedCol1, PartitionMaskedCol2))) { + auto SliceTrk1 = part1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto SliceV02 = part2->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + for (auto& [p1, p2] : combinations(CombinationsFullIndexPolicy(SliceTrk1, SliceV02))) { + const auto& posChild = parts.iteratorAt(p2.index() - 2); + const auto& negChild = parts.iteratorAt(p2.index() - 1); + // check cuts on V0 children + if (((posChild.cut() & ConfV02_ChildPos_CutBit) == ConfV02_ChildPos_CutBit) && + ((posChild.pidcut() & ConfV02_ChildPos_TPCBit) == ConfV02_ChildPos_TPCBit) && + ((negChild.cut() & ConfV02_ChildNeg_CutBit) == ConfV02_ChildNeg_CutBit) && + ((negChild.pidcut() & ConfV02_ChildNeg_TPCBit) == ConfV02_ChildNeg_TPCBit)) { + continue; + } + if (ConfOptUseCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, collision1.magField())) { + continue; + } + } + if (!pairCleaner.isCleanPair(p1, p2, parts)) { + continue; + } + mixedEventCont.setPair(p1, p2, collision1.multNtr(), collision1.multV0M(), ConfOptUse4D, ConfOptExtendedPlots); } - doMixedEvent(SliceTrk1, SliceV02, parts, magFieldTesla1, multCol); } } - PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processMixedEvent, "Enable processing mixed events", true); - void processMixedEventMasked(MaskedCollisions const& cols, FilteredFDParticles const& parts) + void processMixedEvent(FilteredCollisions& cols, FilteredFDParticles& parts) { - Partition PartitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & MaskBit) == MaskBit; - Partition PartitionMaskedCol2 = (aod::femtodreamcollision::bitmaskTrackTwo & MaskBit) == MaskBit; - - PartitionMaskedCol1.bindTable(cols); - PartitionMaskedCol2.bindTable(cols); - - for (auto const& [collision1, collision2] : combinations(soa::CombinationsBlockUpperIndexPolicy(colBinning, ConfNEventsMix.value, -1, PartitionMaskedCol1, PartitionMaskedCol2))) { - auto SliceTrk1 = PartitionTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); - auto SliceV02 = PartitionV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + switch (ConfMixingPolicy.value) { + case femtodreamcollision::kMult: + doMixedEvent_NotMasked(cols, parts, PartitionTrk1, PartitionV02, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent_NotMasked(cols, parts, PartitionTrk1, PartitionV02, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent_NotMasked(cols, parts, PartitionTrk1, PartitionV02, colBinningMultMultPercentile); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; + } + } + PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processMixedEvent, "Enable processing mixed events", true); - const int multCol = collision1.multNtr(); - const auto magFieldTesla1 = collision1.magField(); - doMixedEvent(SliceTrk1, SliceV02, parts, magFieldTesla1, multCol); + void processMixedEventMasked(FilteredMaskedCollisions& cols, FilteredFDParticles& parts) + { + switch (ConfMixingPolicy.value) { + case femtodreamcollision::kMult: + doMixedEvent_Masked(cols, parts, PartitionTrk1, PartitionV02, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent_Masked(cols, parts, PartitionTrk1, PartitionV02, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent_Masked(cols, parts, PartitionTrk1, PartitionV02, colBinningMultMultPercentile); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; } } PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processMixedEventMasked, "Enable processing mixed events with masks", false); - void processMixedEventMC(o2::aod::FDCollisions& cols, FilteredFDMCParts& parts, o2::aod::FDMCParticles&) + void processMixedEventMC(FilteredCollisions& cols, FilteredFDMCParts& parts, o2::aod::FDMCParticles&) { - for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, cols, cols)) { - auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); - auto SliceMCV02 = PartitionMCV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); - - const int multCol = collision1.multNtr(); - const auto magFieldTesla1 = collision1.magField(); - if (SliceMCTrk1.size() == 0 || SliceMCV02.size() == 0) { - return; - } - doMixedEvent(SliceMCTrk1, SliceMCV02, parts, magFieldTesla1, multCol); + switch (ConfMixingPolicy.value) { + case femtodreamcollision::kMult: + doMixedEvent_NotMasked(cols, parts, PartitionMCTrk1, PartitionMCV02, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent_NotMasked(cols, parts, PartitionMCTrk1, PartitionMCV02, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent_NotMasked(cols, parts, PartitionMCTrk1, PartitionMCV02, colBinningMultMultPercentile); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; } } PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processMixedEventMC, "Enable processing mixed events MC", false); - void processMixedEventMCMasked(MaskedCollisions& cols, FilteredFDMCParts& parts, o2::aod::FDMCParticles&) + void processMixedEventMCMasked(FilteredMaskedCollisions& cols, FilteredFDMCParts& parts, o2::aod::FDMCParticles&) { - Partition PartitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & MaskBit) == MaskBit; - Partition PartitionMaskedCol2 = (aod::femtodreamcollision::bitmaskTrackTwo & MaskBit) == MaskBit; - - PartitionMaskedCol1.bindTable(cols); - PartitionMaskedCol2.bindTable(cols); - - for (auto const& [collision1, collision2] : combinations(soa::CombinationsBlockUpperIndexPolicy(colBinning, ConfNEventsMix.value, -1, PartitionMaskedCol1, PartitionMaskedCol2))) { - auto SliceMCTrk1 = PartitionMCTrk1->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); - auto SliceMCV02 = PartitionMCV02->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); - const int multCol = collision1.multNtr(); - const auto magFieldTesla1 = collision1.magField(); - doMixedEvent(SliceMCTrk1, SliceMCV02, parts, magFieldTesla1, multCol); + switch (ConfMixingPolicy.value) { + case femtodreamcollision::kMult: + doMixedEvent_Masked(cols, parts, PartitionMCTrk1, PartitionMCV02, colBinningMult); + break; + case femtodreamcollision::kMultPercentile: + doMixedEvent_Masked(cols, parts, PartitionMCTrk1, PartitionMCV02, colBinningMultPercentile); + break; + case femtodreamcollision::kMultMultPercentile: + doMixedEvent_Masked(cols, parts, PartitionMCTrk1, PartitionMCV02, colBinningMultMultPercentile); + break; + default: + LOG(fatal) << "Invalid binning policiy specifed. Breaking..."; } } PROCESS_SWITCH(femtoDreamPairTaskTrackV0, processMixedEventMCMasked, "Enable processing mixed events MC with masks", false); diff --git a/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackTrack.cxx b/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackTrack.cxx new file mode 100644 index 00000000000..d2334dafcbf --- /dev/null +++ b/PWGCF/FemtoDream/Tasks/femtoDreamTripletTaskTrackTrackTrack.cxx @@ -0,0 +1,423 @@ +// 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 femtoDreamTripletTaskTrackTrackTrack.cxx +/// \brief Tasks that reads the track tables and creates track triplets; only three identical particles can be used +/// \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 Laura Serksnyte, TU München, laura.serksnyte@tum.de + +#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 "TDatabasePDG.h" + +#include "PWGCF/DataModel/FemtoDerived.h" +#include "PWGCF/FemtoDream/Core/femtoDreamParticleHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamEventHisto.h" +#include "PWGCF/FemtoDream/Core/femtoDreamPairCleaner.h" +#include "PWGCF/FemtoDream/Core/femtoDreamContainerThreeBody.h" +#include "PWGCF/FemtoDream/Core/femtoDreamDetaDphiStar.h" +#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" + +using namespace o2; +using namespace o2::analysis::femtoDream; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::soa; + +struct femtoDreamTripletTaskTrackTrackTrack { + SliceCache cache; + Preslice perCol = aod::femtodreamparticle::fdCollisionId; + + using MaskedCollisions = soa::Join; + using MaskedCollision = MaskedCollisions::iterator; + aod::femtodreamcollision::BitMaskType MaskBit = -1; + + /// Particle selection part + + /// Table for both particles + Configurable ConfMaxpT{"ConfMaxpT", 4.05f, "Maximum transverse momentum of the particles"}; + Configurable ConfPIDthrMom{"ConfPIDthrMom", 1.f, "Momentum threshold from which TPC and TOF are required for PID"}; + Configurable ConfTPCPIDBit{"ConfTPCPIDBit", 16, "PID TPC bit from cutCulator "}; + Configurable ConfTPCTOFPIDBit{"ConfTPCTOFPIDBit", 8, "PID TPCTOF bit from cutCulator"}; + Configurable ConfIsMC{"ConfIsMC", false, "Enable additional Histogramms 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"}; + + // Which particles to analyse; currently support only for same species and cuts triplets + Configurable ConfPDGCodePart{"ConfPDGCodePart", 2212, "Particle PDG code"}; + Configurable ConfCutPart{"ConfCutPart", 5542474, "Particles - Selection bit from cutCulator"}; + + /// Partition for selected particles + Partition SelectedParts = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && + ifnode(aod::femtodreamparticle::pt * (nexp(aod::femtodreamparticle::eta) + nexp(-1.f * aod::femtodreamparticle::eta)) / 2.f <= ConfPIDthrMom, ncheckbit(aod::femtodreamparticle::pidcut, ConfTPCPIDBit), ncheckbit(aod::femtodreamparticle::pidcut, ConfTPCTOFPIDBit)) && + (ncheckbit(aod::femtodreamparticle::cut, ConfCutPart)) && + (aod::femtodreamparticle::pt < ConfMaxpT); + Partition> SelectedPartsMC = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && + ifnode(aod::femtodreamparticle::pt * (nexp(aod::femtodreamparticle::eta) + nexp(-1.f * aod::femtodreamparticle::eta)) / 2.f <= ConfPIDthrMom, ncheckbit(aod::femtodreamparticle::pidcut, ConfTPCPIDBit), ncheckbit(aod::femtodreamparticle::pidcut, ConfTPCTOFPIDBit)) && + (ncheckbit(aod::femtodreamparticle::cut, ConfCutPart)) && + (aod::femtodreamparticle::pt < ConfMaxpT); + + /// Histogramming of Selected Particles + FemtoDreamParticleHisto trackHistoSelectedParts; + + /// Histogramming for Event + FemtoDreamEventHisto eventHisto; + + /// particle part + ConfigurableAxis ConfTempFitVarBins{"ConfTempFitVarBins", {300, -0.15, 0.15}, "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"}; + + /// Correlation part + 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"}; + + ColumnBinningPolicy colBinning{{ConfVtxBins, ConfMultBins}, true}; + + ConfigurableAxis ConfQ3Bins{"ConfQ3Bins", {2000, 0., 8.}, "binning Q3"}; + 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 ConfCPRdeltaPhiMax{"ConfCPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; + Configurable ConfCPRdeltaEtaMax{"ConfCPRdeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; + ConfigurableAxis ConfDummy{"ConfDummy", {1, 0, 1}, "Dummy axis"}; + + FemtoDreamContainerThreeBody sameEventCont; + FemtoDreamContainerThreeBody mixedEventCont; + FemtoDreamPairCleaner pairCleaner; + FemtoDreamDetaDphiStar pairCloseRejection; + /// Histogram output + HistogramRegistry qaRegistry{"TrackQA", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry resultRegistry{"Correlations", {}, OutputObjHandlingPolicy::AnalysisObject}; + HistogramRegistry ThreeBodyQARegistry{"ThreeBodyQARegistry", {}, OutputObjHandlingPolicy::AnalysisObject}; + + void init(InitContext& context) + { + + eventHisto.init(&qaRegistry); + trackHistoSelectedParts.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfDummy, ConfIsMC, ConfPDGCodePart); + + ThreeBodyQARegistry.add("TripletTaskQA/hSECollisionBins", ";bin;Entries", kTH1F, {{120, -0.5, 119.5}}); + ThreeBodyQARegistry.add("TripletTaskQA/hMECollisionBins", ";bin;Entries", kTH1F, {{120, -0.5, 119.5}}); + std::vector tmpVecMult = ConfMultBins; + framework::AxisSpec multAxis = {tmpVecMult, "Multiplicity"}; + ThreeBodyQARegistry.add("TripletTaskQA/hSEMultVSGoodTracks", ";Mult;GoodT", kTH2F, {multAxis, {100, 0, 100}}); + + sameEventCont.init(&resultRegistry, ConfQ3Bins, ConfMultBins, ConfIsMC); + mixedEventCont.init(&resultRegistry, ConfQ3Bins, ConfMultBins, ConfIsMC); + sameEventCont.setPDGCodes(ConfPDGCodePart, ConfPDGCodePart, ConfPDGCodePart); + mixedEventCont.setPDGCodes(ConfPDGCodePart, ConfPDGCodePart, ConfPDGCodePart); + pairCleaner.init(&qaRegistry); // SERKSNYTE : later check if init should be updated to have 3 separate histos + if (ConfIsCPR.value) { + pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRPlotPerRadii.value); + } + + // get bit for the collision mask + std::bitset<8 * sizeof(aod::femtodreamcollision::BitMaskType)> mask; + int index = 0; + auto& workflows = context.services().get(); + for (DeviceSpec const& device : workflows.devices) { + if (device.name.find("femto-dream-triplet-task-track-track-track") != std::string::npos) { + if (containsNameValuePair(device.options, "ConfCutPart", ConfCutPart.value) && + containsNameValuePair(device.options, "ConfTPCPIDBit", ConfTPCPIDBit.value) && + containsNameValuePair(device.options, "ConfTPCTOFPIDBit", ConfTPCTOFPIDBit.value) && + containsNameValuePair(device.options, "ConfPIDthrMom", ConfPIDthrMom.value) && + containsNameValuePair(device.options, "ConfMaxpT", ConfMaxpT.value)) { + mask.set(index); + MaskBit = static_cast(mask.to_ulong()); + LOG(info) << "Device name matched: " << device.name; + LOG(info) << "Bitmask for collisions: " << mask.to_string(); + break; + } else { + index++; + } + } + } + + if ((doprocessSameEvent && doprocessSameEventMasked) || + (doprocessMixedEvent && doprocessMixedEventMasked) || + (doprocessSameEventMC && doprocessSameEventMCMasked) || + (doprocessMixedEventMC && doprocessMixedEventMCMasked)) { + LOG(fatal) << "Normal and masked processing cannot be activated simultaneously!"; + } + } + + template + void fillCollision(CollisionType col) + { + ThreeBodyQARegistry.fill(HIST("TripletTaskQA/hSECollisionBins"), colBinning.getBin({col.posZ(), col.multNtr()})); + eventHisto.fillQA(col); + } + + /// This function processes the same event and takes care of all the histogramming + /// @tparam PartitionType + /// @tparam PartType + /// @tparam isMC: enables Monte Carlo truth specific histograms + /// @param groupSelectedParts partition for the first 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 groupSelectedParts, PartType parts, float magFieldTesla, int multCol) + { + /// Histogramming same event + for (auto& part : groupSelectedParts) { + trackHistoSelectedParts.fillQA(part, aod::femtodreamparticle::kPt); + } + + /// Now build the combinations + for (auto& [p1, p2, p3] : combinations(CombinationsStrictlyUpperIndexPolicy(groupSelectedParts, groupSelectedParts, groupSelectedParts))) { + if (ConfIsCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { + continue; + } + if (pairCloseRejection.isClosePair(p2, p3, parts, magFieldTesla)) { + continue; + } + if (pairCloseRejection.isClosePair(p1, p3, parts, magFieldTesla)) { + continue; + } + } + + // track cleaning + if (!pairCleaner.isCleanPair(p1, p2, parts)) { + continue; + } + if (!pairCleaner.isCleanPair(p2, p3, parts)) { + continue; + } + if (!pairCleaner.isCleanPair(p1, p3, parts)) { + continue; + } + sameEventCont.setTriplet(p1, p2, p3, multCol); + } + } + + /// process function to call doSameEvent with Data + /// \param col subscribe to the collision table (Data) + /// \param parts subscribe to the femtoDreamParticleTable + void processSameEvent(o2::aod::FDCollision& col, + o2::aod::FDParticles& parts) + { + fillCollision(col); + auto thegroupSelectedParts = SelectedParts->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + doSameEvent(thegroupSelectedParts, parts, col.magField(), col.multNtr()); + } + PROCESS_SWITCH(femtoDreamTripletTaskTrackTrackTrack, processSameEvent, "Enable processing same event", true); + + /// process function to call doSameEvent with Data which has a mask for containing particles or not + /// \param col subscribe to the collision table (Data) + /// \param parts subscribe to the femtoDreamParticleTable + void processSameEventMasked(MaskedCollision& col, o2::aod::FDParticles& parts) + { + if ((col.bitmaskTrackOne() & MaskBit) != MaskBit) + return; + fillCollision(col); + auto thegroupSelectedParts = SelectedParts->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + doSameEvent(thegroupSelectedParts, parts, col.magField(), col.multNtr()); + } + PROCESS_SWITCH(femtoDreamTripletTaskTrackTrackTrack, processSameEventMasked, "Enable processing same event with masks", false); + + /// process function for to call doSameEvent with Monte Carlo + /// \param col subscribe to the collision table (Monte Carlo Reconstructed reconstructed) + /// \param parts subscribe to joined table FemtoDreamParticles and FemtoDreamMCLables to access Monte Carlo truth + /// \param FemtoDreamMCParticles subscribe to the Monte Carlo truth table + void processSameEventMC(o2::aod::FDCollision& col, + soa::Join& parts, + o2::aod::FDMCParticles&) + { + fillCollision(col); + auto thegroupSelectedParts = SelectedPartsMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + doSameEvent(thegroupSelectedParts, parts, col.magField(), col.multNtr()); + } + PROCESS_SWITCH(femtoDreamTripletTaskTrackTrackTrack, processSameEventMC, "Enable processing same event for Monte Carlo", false); + + /// process function for to call doSameEvent with Monte Carlo which has a mask for containing particles or not + /// \param col subscribe to the collision table (Monte Carlo Reconstructed reconstructed) + /// \param parts subscribe to joined table FemtoDreamParticles and FemtoDreamMCLables to access Monte Carlo truth + /// \param FemtoDreamMCParticles subscribe to the Monte Carlo truth table + void processSameEventMCMasked(MaskedCollision& col, + soa::Join& parts, + o2::aod::FDMCParticles&) + { + if ((col.bitmaskTrackOne() & MaskBit) != MaskBit) + return; + fillCollision(col); + auto thegroupSelectedParts = SelectedPartsMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); + doSameEvent(thegroupSelectedParts, parts, col.magField(), col.multNtr()); + } + PROCESS_SWITCH(femtoDreamTripletTaskTrackTrackTrack, processSameEventMCMasked, "Enable processing same event for Monte Carlo", false); + + /// This function processes the mixed event + /// \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 groupPartsThree partition for the third 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 doMixedEvent(PartitionType groupPartsOne, PartitionType groupPartsTwo, PartitionType groupPartsThree, PartType parts, float magFieldTesla, int multCol) + { + for (auto& [p1, p2, p3] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo, groupPartsThree))) { + if (ConfIsCPR.value) { + if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { + continue; + } + if (pairCloseRejection.isClosePair(p2, p3, parts, magFieldTesla)) { + continue; + } + + if (pairCloseRejection.isClosePair(p1, p3, parts, magFieldTesla)) { + continue; + } + } + mixedEventCont.setTriplet(p1, p2, p3, multCol); + } + } + + /// process function for to call doMixedEvent with Data + /// @param cols subscribe to the collisions table (Data) + /// @param parts subscribe to the femtoDreamParticleTable + void processMixedEvent(o2::aod::FDCollisions& cols, + o2::aod::FDParticles& parts) + { + for (auto& [collision1, collision2, collision3] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, cols, cols, cols)) { + const int multiplicityCol = collision1.multNtr(); + ThreeBodyQARegistry.fill(HIST("TripletTaskQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); + + auto groupPartsOne = SelectedParts->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsTwo = SelectedParts->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + auto groupPartsThree = SelectedParts->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision3.globalIndex(), cache); + + const auto& magFieldTesla1 = collision1.magField(); + const auto& magFieldTesla2 = collision2.magField(); + const auto& magFieldTesla3 = collision3.magField(); + + if ((magFieldTesla1 != magFieldTesla2) || (magFieldTesla2 != magFieldTesla3) || (magFieldTesla1 != magFieldTesla3)) { + continue; + } + // CONSIDER testing different strategies to which events to use + + doMixedEvent(groupPartsOne, groupPartsTwo, groupPartsThree, parts, magFieldTesla1, multiplicityCol); + } + } + PROCESS_SWITCH(femtoDreamTripletTaskTrackTrackTrack, processMixedEvent, "Enable processing mixed events", true); + + /// process function for to call doMixedEvent with Data which has a mask for containing particles or not + /// @param cols subscribe to the collisions table (Data) + /// @param parts subscribe to the femtoDreamParticleTable + void processMixedEventMasked(MaskedCollisions& cols, o2::aod::FDParticles& parts) + { + Partition PartitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & MaskBit) == MaskBit; + PartitionMaskedCol1.bindTable(cols); + + for (auto& [collision1, collision2, collision3] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, PartitionMaskedCol1, PartitionMaskedCol1, PartitionMaskedCol1)) { + const int multiplicityCol = collision1.multNtr(); + ThreeBodyQARegistry.fill(HIST("TripletTaskQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); + + auto groupPartsOne = SelectedParts->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsTwo = SelectedParts->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + auto groupPartsThree = SelectedParts->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision3.globalIndex(), cache); + + const auto& magFieldTesla1 = collision1.magField(); + const auto& magFieldTesla2 = collision2.magField(); + const auto& magFieldTesla3 = collision3.magField(); + + if ((magFieldTesla1 != magFieldTesla2) || (magFieldTesla2 != magFieldTesla3) || (magFieldTesla1 != magFieldTesla3)) { + continue; + } + doMixedEvent(groupPartsOne, groupPartsTwo, groupPartsThree, parts, magFieldTesla1, multiplicityCol); + } + } + PROCESS_SWITCH(femtoDreamTripletTaskTrackTrackTrack, processMixedEventMasked, "Enable processing mixed events", false); + + /// brief process function for to call doMixedEvent with Monte Carlo + /// @param cols subscribe to the collisions table (Monte Carlo Reconstructed reconstructed) + /// @param parts subscribe to joined table FemtoDreamParticles and FemtoDreamMCLables to access Monte Carlo truth + /// @param FemtoDreamMCParticles subscribe to the Monte Carlo truth table + void processMixedEventMC(o2::aod::FDCollisions& cols, + soa::Join& parts, + o2::aod::FDMCParticles&) + { + for (auto& [collision1, collision2, collision3] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, cols, cols, cols)) { + + const int multiplicityCol = collision1.multNtr(); + ThreeBodyQARegistry.fill(HIST("TripletTaskQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); + + auto groupPartsOne = SelectedPartsMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsTwo = SelectedPartsMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + auto groupPartsThree = SelectedPartsMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision3.globalIndex(), cache); + + const auto& magFieldTesla1 = collision1.magField(); + const auto& magFieldTesla2 = collision2.magField(); + const auto& magFieldTesla3 = collision3.magField(); + + if ((magFieldTesla1 != magFieldTesla2) || (magFieldTesla2 != magFieldTesla3) || (magFieldTesla1 != magFieldTesla3)) { + continue; + } + // CONSIDER testing different strategies to which events to use + + doMixedEvent(groupPartsOne, groupPartsTwo, groupPartsThree, parts, magFieldTesla1, multiplicityCol); + } + } + PROCESS_SWITCH(femtoDreamTripletTaskTrackTrackTrack, processMixedEventMC, "Enable processing mixed events MC", false); + + /// brief process function for to call doMixedEvent with Monte Carlo which has a mask for containing particles or not + /// @param cols subscribe to the collisions table (Monte Carlo Reconstructed reconstructed) + /// @param parts subscribe to joined table FemtoDreamParticles and FemtoDreamMCLables to access Monte Carlo truth + /// @param FemtoDreamMCParticles subscribe to the Monte Carlo truth table + void processMixedEventMCMasked(MaskedCollisions& cols, + soa::Join& parts, + o2::aod::FDMCParticles&) + { + Partition PartitionMaskedCol1 = (aod::femtodreamcollision::bitmaskTrackOne & MaskBit) == MaskBit; + PartitionMaskedCol1.bindTable(cols); + + for (auto& [collision1, collision2, collision3] : soa::selfCombinations(colBinning, ConfNEventsMix, -1, PartitionMaskedCol1, PartitionMaskedCol1, PartitionMaskedCol1)) { + + const int multiplicityCol = collision1.multNtr(); + ThreeBodyQARegistry.fill(HIST("TripletTaskQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); + + auto groupPartsOne = SelectedPartsMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsTwo = SelectedPartsMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); + auto groupPartsThree = SelectedPartsMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision3.globalIndex(), cache); + + const auto& magFieldTesla1 = collision1.magField(); + const auto& magFieldTesla2 = collision2.magField(); + const auto& magFieldTesla3 = collision3.magField(); + + if ((magFieldTesla1 != magFieldTesla2) || (magFieldTesla2 != magFieldTesla3) || (magFieldTesla1 != magFieldTesla3)) { + continue; + } + // CONSIDER testing different strategies to which events to use + + doMixedEvent(groupPartsOne, groupPartsTwo, groupPartsThree, parts, magFieldTesla1, multiplicityCol); + } + } + PROCESS_SWITCH(femtoDreamTripletTaskTrackTrackTrack, processMixedEventMCMasked, "Enable processing mixed events MC", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + WorkflowSpec workflow{ + adaptAnalysisTask(cfgc), + }; + return workflow; +} diff --git a/PWGCF/FemtoDream/Utils/CMakeLists.txt b/PWGCF/FemtoDream/Utils/CMakeLists.txt new file mode 100644 index 00000000000..11e95315fba --- /dev/null +++ b/PWGCF/FemtoDream/Utils/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright 2019-2024 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_executable(femtodream-cutculator + SOURCES femtoDreamCutCulator.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/FemtoDream/femtoDreamCutCulator.cxx b/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.cxx similarity index 94% rename from PWGCF/FemtoDream/femtoDreamCutCulator.cxx rename to PWGCF/FemtoDream/Utils/femtoDreamCutCulator.cxx index b5b5cc63ebc..afef9ef7245 100644 --- a/PWGCF/FemtoDream/femtoDreamCutCulator.cxx +++ b/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.cxx @@ -16,9 +16,9 @@ #include #include #include -#include "FemtoDreamCutculator.h" -#include "FemtoDreamSelection.h" -#include "FemtoDreamTrackSelection.h" +#include "PWGCF/FemtoDream/Utils/femtoDreamCutCulator.h" +#include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" #include "PWGCF/DataModel/FemtoDerived.h" using namespace o2::analysis::femtoDream; diff --git a/PWGCF/FemtoDream/FemtoDreamCutculator.h b/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.h similarity index 97% rename from PWGCF/FemtoDream/FemtoDreamCutculator.h rename to PWGCF/FemtoDream/Utils/femtoDreamCutCulator.h index 1f7ecab464d..7bb2035dba9 100644 --- a/PWGCF/FemtoDream/FemtoDreamCutculator.h +++ b/PWGCF/FemtoDream/Utils/femtoDreamCutCulator.h @@ -15,12 +15,9 @@ /// andreas.mathis@ph.tum.de \author Luca Barioglio, TU München, /// luca.barioglio@cern.ch -#ifndef PWGCF_FEMTODREAM_FEMTODREAMCUTCULATOR_H_ -#define PWGCF_FEMTODREAM_FEMTODREAMCUTCULATOR_H_ +#ifndef PWGCF_FEMTODREAM_UTILS_FEMTODREAMCUTCULATOR_H_ +#define PWGCF_FEMTODREAM_UTILS_FEMTODREAMCUTCULATOR_H_ -#include "FemtoDreamSelection.h" -#include "FemtoDreamTrackSelection.h" -#include "FemtoDreamV0Selection.h" #include #include #include @@ -32,6 +29,10 @@ #include #include +#include "PWGCF/FemtoDream/Core/femtoDreamSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamTrackSelection.h" +#include "PWGCF/FemtoDream/Core/femtoDreamV0Selection.h" + namespace o2::analysis::femtoDream { @@ -366,4 +367,4 @@ class FemtoDreamCutculator }; } // namespace o2::analysis::femtoDream -#endif // PWGCF_FEMTODREAM_FEMTODREAMCUTCULATOR_H_ */ +#endif // PWGCF_FEMTODREAM_UTILS_FEMTODREAMCUTCULATOR_H_ diff --git a/PWGCF/FemtoDream/femtoDreamPairTaskTrackTrackTrack.cxx b/PWGCF/FemtoDream/femtoDreamPairTaskTrackTrackTrack.cxx deleted file mode 100644 index 589cafc9e38..00000000000 --- a/PWGCF/FemtoDream/femtoDreamPairTaskTrackTrackTrack.cxx +++ /dev/null @@ -1,421 +0,0 @@ -// 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 femtoDreamPairTaskTrackTrackTrack.cxx -/// \brief Tasks that reads the track tables and creates track triplets; should be currently used only for identical 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 Laura Serksnyte, TU München, laura.serksnyte@tum.de - -#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 "TDatabasePDG.h" - -#include "PWGCF/DataModel/FemtoDerived.h" -#include "FemtoDreamParticleHisto.h" -#include "FemtoDreamEventHisto.h" -#include "FemtoDreamPairCleaner.h" -#include "FemtoDreamContainerThreeBody.h" -#include "FemtoDreamDetaDphiStar.h" -#include "FemtoUtils.h" - -using namespace o2; -using namespace o2::analysis::femtoDream; -using namespace o2::framework; -using namespace o2::framework::expressions; -using namespace o2::soa; - -namespace -{ -static constexpr int nPart = 3; -static constexpr int nCuts = 5; -static const std::vector partNames{"PartOne", "PartTwo", "PartThree"}; -static const std::vector cutNames{"MaxPt", "PIDthr", "nSigmaTPC", "nSigmaTPCTOF", "MaxP"}; -static const float cutsTable[nPart][nCuts]{ - {4.05f, 1.f, 3.f, 3.f, 100.f}, - {4.05f, 1.f, 3.f, 3.f, 100.f}, - {4.05f, 1.f, 3.f, 3.f, 100.f}}; -} // namespace - -struct femtoDreamPairTaskTrackTrackTrack { - SliceCache cache; - Preslice perCol = aod::femtodreamparticle::fdCollisionId; - - /// Particle selection part - - /// Table for both particles - Configurable> ConfCutTable{"ConfCutTable", {cutsTable[0], nPart, nCuts, partNames, cutNames}, "Particle selections"}; - Configurable ConfNspecies{"ConfNspecies", 2, "Number of particle spieces with PID info"}; - 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"}; - - // Which particles to analyse; currently support only for same species and cuts triplets - Configurable ConfPDGCodePart{"ConfPDGCodePart", 2212, "Particle PDG code"}; - Configurable ConfPIDPart{"ConfPIDPart", 2, "Particles - Read from cutCulator"}; - Configurable ConfCutPart{"ConfCutPart", 5542474, "Particles - Selection bit from cutCulator"}; - - // Keep this format as next code update will include also different particle species and cuts: - - /// Particle 1 - - /// Partition for particle 1 - Partition partsOne = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && ((aod::femtodreamparticle::cut & ConfCutPart) == ConfCutPart); - Partition> partsOneMC = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && ((aod::femtodreamparticle::cut & ConfCutPart) == ConfCutPart); - - /// Histogramming for particle 1 - FemtoDreamParticleHisto trackHistoPartOne; - - /// Particle 2 - - /// Partition for particle 2 - Partition partsTwo = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && - // (aod::femtodreamparticle::pt < cfgCutTable->get("PartTwo", "MaxPt")) && - ((aod::femtodreamparticle::cut & ConfCutPart) == ConfCutPart); - Partition> partsTwoMC = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && - ((aod::femtodreamparticle::cut & ConfCutPart) == ConfCutPart); - - /// Particle 3 - - /// Partition for particle 3 - Partition partsThree = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && - // (aod::femtodreamparticle::pt < cfgCutTable->get("PartTwo", "MaxPt")) && - ((aod::femtodreamparticle::cut & ConfCutPart) == ConfCutPart); - Partition> partsThreeMC = (aod::femtodreamparticle::partType == uint8_t(aod::femtodreamparticle::ParticleType::kTrack)) && - ((aod::femtodreamparticle::cut & ConfCutPart) == ConfCutPart); - - /// Histogramming for Event - FemtoDreamEventHisto eventHisto; - - /// The configurables need to be passed to an std::vector - int vPIDPart; - std::vector kNsigma; - - /// particle part - ConfigurableAxis ConfTempFitVarBins{"ConfDTempFitVarBins", {300, -0.15, 0.15}, "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"}; - - /// 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"}; - - ColumnBinningPolicy colBinning{{ConfVtxBins, ConfMultBins}, true}; - - ConfigurableAxis ConfQ3Bins{"ConfQ3Bins", {2000, 0., 8.}, "binning Q3"}; - 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 ConfCPRdeltaPhiMax{"ConfCPRdeltaPhiMax", 0.01, "Max. Delta Phi for Close Pair Rejection"}; - Configurable ConfCPRdeltaEtaMax{"ConfCPRdeltaEtaMax", 0.01, "Max. Delta Eta for Close Pair Rejection"}; - ConfigurableAxis ConfDummy{"ConfDummy", {1, 0, 1}, "Dummy axis"}; - - FemtoDreamContainerThreeBody sameEventCont; - FemtoDreamContainerThreeBody mixedEventCont; - FemtoDreamPairCleaner pairCleaner; - FemtoDreamDetaDphiStar pairCloseRejection; - /// Histogram output - HistogramRegistry qaRegistry{"TrackQA", {}, OutputObjHandlingPolicy::AnalysisObject}; - HistogramRegistry resultRegistry{"Correlations", {}, OutputObjHandlingPolicy::AnalysisObject}; - HistogramRegistry MixQaRegistry{"MixQaRegistry", {}, OutputObjHandlingPolicy::AnalysisObject}; - - void init(InitContext&) - { - - eventHisto.init(&qaRegistry); - trackHistoPartOne.init(&qaRegistry, ConfTempFitVarpTBins, ConfTempFitVarBins, ConfDummy, ConfDummy, ConfDummy, ConfDummy, ConfIsMC, ConfPDGCodePart); - - 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, ConfQ3Bins, ConfMultBins, ConfIsMC); - mixedEventCont.init(&resultRegistry, ConfQ3Bins, ConfMultBins, ConfIsMC); - sameEventCont.setPDGCodes(ConfPDGCodePart, ConfPDGCodePart, ConfPDGCodePart); - mixedEventCont.setPDGCodes(ConfPDGCodePart, ConfPDGCodePart, ConfPDGCodePart); - pairCleaner.init(&qaRegistry); // SERKSNYTE : later check if init should be updated to have 3 separate histos - if (ConfIsCPR.value) { - pairCloseRejection.init(&resultRegistry, &qaRegistry, ConfCPRdeltaPhiMax.value, ConfCPRdeltaEtaMax.value, ConfCPRPlotPerRadii.value); - } - - // CURRENTLY do only for one species - vPIDPart = ConfPIDPart.value; - kNsigma = ConfTrkPIDnSigmaMax.value; - } - - template - void fillCollision(CollisionType col) - { - MixQaRegistry.fill(HIST("MixingQA/hSECollisionBins"), colBinning.getBin({col.posZ(), col.multNtr()})); - 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 groupPartsOne, PartitionType groupPartsTwo, PartitionType groupPartsThree, PartType parts, float magFieldTesla, int multCol) - { - /// Histogramming same event - int NGoodTracks = 0; - for (auto& part : groupPartsOne) { - if (part.p() > ConfCutTable->get("PartOne", "MaxP") || part.pt() > ConfCutTable->get("PartOne", "MaxPt")) { - continue; - } - if (!isFullPIDSelected(part.pidcut(), - part.p(), - ConfCutTable->get("PartOne", "PIDthr"), - vPIDPart, - ConfNspecies, - kNsigma, - ConfCutTable->get("PartOne", "nSigmaTPC"), - ConfCutTable->get("PartOne", "nSigmaTPCTOF"))) { - continue; - } - NGoodTracks++; - - trackHistoPartOne.fillQA(part, aod::femtodreamparticle::kPt); - } - - /// Now build the combinations - for (auto& [p1, p2, p3] : combinations(CombinationsStrictlyUpperIndexPolicy(groupPartsOne, groupPartsTwo, groupPartsThree))) { - if (p1.p() > ConfCutTable->get("PartOne", "MaxP") || p1.pt() > ConfCutTable->get("PartOne", "MaxPt") || p2.p() > ConfCutTable->get("PartTwo", "MaxP") || p2.pt() > ConfCutTable->get("PartTwo", "MaxPt") || p3.p() > ConfCutTable->get("PartThree", "MaxP") || p3.pt() > ConfCutTable->get("PartThree", "MaxPt")) { - continue; - } - if (!isFullPIDSelected(p1.pidcut(), - p1.p(), - ConfCutTable->get("PartOne", "PIDthr"), - vPIDPart, - ConfNspecies, - kNsigma, - ConfCutTable->get("PartOne", "nSigmaTPC"), - ConfCutTable->get("PartOne", "nSigmaTPCTOF")) || - !isFullPIDSelected(p2.pidcut(), - p2.p(), - ConfCutTable->get("PartTwo", "PIDthr"), - vPIDPart, - ConfNspecies, - kNsigma, - ConfCutTable->get("PartTwo", "nSigmaTPC"), - ConfCutTable->get("PartTwo", "nSigmaTPCTOF")) || - !isFullPIDSelected(p3.pidcut(), - p3.p(), - ConfCutTable->get("PartThree", "PIDthr"), - vPIDPart, - ConfNspecies, - kNsigma, - ConfCutTable->get("PartThree", "nSigmaTPC"), - ConfCutTable->get("PartThree", "nSigmaTPCTOF"))) { - continue; - } - - if (ConfIsCPR.value) { - if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { - continue; - } - if (pairCloseRejection.isClosePair(p2, p3, parts, magFieldTesla)) { - continue; - } - if (pairCloseRejection.isClosePair(p1, p3, parts, magFieldTesla)) { - continue; - } - } - - // track cleaning - if (!pairCleaner.isCleanPair(p1, p2, parts)) { - continue; - } - if (!pairCleaner.isCleanPair(p2, p3, parts)) { - continue; - } - if (!pairCleaner.isCleanPair(p1, p3, parts)) { - continue; - } - sameEventCont.setTriplet(p1, p2, p3, multCol); - } - } - - /// process function to call doSameEvent with Data - /// \param col subscribe to the collision table (Data) - /// \param parts subscribe to the femtoDreamParticleTable - void processSameEvent(o2::aod::FDCollision& col, - o2::aod::FDParticles& parts) - { - fillCollision(col); - - auto thegroupPartsOne = partsOne->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - auto thegroupPartsTwo = partsTwo->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - auto thegroupPartsThree = partsThree->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - - doSameEvent(thegroupPartsOne, thegroupPartsTwo, thegroupPartsTwo, parts, col.magField(), col.multNtr()); - } - PROCESS_SWITCH(femtoDreamPairTaskTrackTrackTrack, processSameEvent, "Enable processing same event", true); - - /// process function for to call doSameEvent with Monte Carlo - /// \param col subscribe to the collision table (Monte Carlo Reconstructed reconstructed) - /// \param parts subscribe to joined table FemtoDreamParticles and FemtoDreamMCLables to access Monte Carlo truth - /// \param FemtoDreamMCParticles subscribe to the Monte Carlo truth table - void processSameEventMC(o2::aod::FDCollision& col, - soa::Join& parts, - o2::aod::FDMCParticles&) - { - fillCollision(col); - - auto thegroupPartsOne = partsOneMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - auto thegroupPartsTwo = partsTwoMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - auto thegroupPartsThree = partsThreeMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, col.globalIndex(), cache); - - doSameEvent(thegroupPartsOne, thegroupPartsTwo, thegroupPartsThree, parts, col.magField(), col.multNtr()); - } - PROCESS_SWITCH(femtoDreamPairTaskTrackTrackTrack, processSameEventMC, "Enable processing same event for Monte Carlo", false); - - /// 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, ... - /// \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 groupPartsThree partition for the third 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 doMixedEvent(PartitionType groupPartsOne, PartitionType groupPartsTwo, PartitionType groupPartsThree, PartType parts, float magFieldTesla, int multCol) - { - for (auto& [p1, p2, p3] : combinations(CombinationsFullIndexPolicy(groupPartsOne, groupPartsTwo, groupPartsThree))) { - if (p1.p() > ConfCutTable->get("PartOne", "MaxP") || p1.pt() > ConfCutTable->get("PartOne", "MaxPt") || p2.p() > ConfCutTable->get("PartTwo", "MaxP") || p2.pt() > ConfCutTable->get("PartTwo", "MaxPt") || p3.p() > ConfCutTable->get("PartThree", "MaxP") || p3.pt() > ConfCutTable->get("PartThree", "MaxPt")) { - continue; - } - - if (!isFullPIDSelected(p1.pidcut(), - p1.p(), - ConfCutTable->get("PartOne", "PIDthr"), - vPIDPart, - ConfNspecies, - kNsigma, - ConfCutTable->get("PartOne", "nSigmaTPC"), - ConfCutTable->get("PartOne", "nSigmaTPCTOF")) || - !isFullPIDSelected(p2.pidcut(), - p2.p(), - ConfCutTable->get("PartTwo", "PIDthr"), - vPIDPart, - ConfNspecies, - kNsigma, - ConfCutTable->get("PartTwo", "nSigmaTPC"), - ConfCutTable->get("PartTwo", "nSigmaTPCTOF")) || - !isFullPIDSelected(p3.pidcut(), - p3.p(), - ConfCutTable->get("PartThree", "PIDthr"), - vPIDPart, - ConfNspecies, - kNsigma, - ConfCutTable->get("PartThree", "nSigmaTPC"), - ConfCutTable->get("PartThree", "nSigmaTPCTOF"))) { - continue; - } - - if (ConfIsCPR.value) { - if (pairCloseRejection.isClosePair(p1, p2, parts, magFieldTesla)) { - continue; - } - if (pairCloseRejection.isClosePair(p2, p3, parts, magFieldTesla)) { - continue; - } - - if (pairCloseRejection.isClosePair(p1, p3, parts, magFieldTesla)) { - continue; - } - } - mixedEventCont.setTriplet(p1, p2, p3, multCol); - } - } - - /// process function for to call doMixedEvent with Data - /// @param cols subscribe to the collisions table (Data) - /// @param parts subscribe to the femtoDreamParticleTable - void processMixedEvent(o2::aod::FDCollisions& cols, - o2::aod::FDParticles& parts) - { - for (auto& [collision1, collision2, collision3] : soa::selfCombinations(colBinning, 5, -1, cols, cols, cols)) { - const int multiplicityCol = collision1.multNtr(); - MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); - - auto groupPartsOne = partsOne->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); - auto groupPartsTwo = partsTwo->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); - auto groupPartsThree = partsThree->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision3.globalIndex(), cache); - - const auto& magFieldTesla1 = collision1.magField(); - const auto& magFieldTesla2 = collision2.magField(); - const auto& magFieldTesla3 = collision3.magField(); - - if ((magFieldTesla1 != magFieldTesla2) || (magFieldTesla2 != magFieldTesla3) || (magFieldTesla1 != magFieldTesla3)) { - continue; - } - // CONSIDER testing different strategies to which events to use - - doMixedEvent(groupPartsOne, groupPartsTwo, groupPartsThree, parts, magFieldTesla1, multiplicityCol); - } - } - PROCESS_SWITCH(femtoDreamPairTaskTrackTrackTrack, processMixedEvent, "Enable processing mixed events", true); - - /// brief process function for to call doMixedEvent with Monte Carlo - /// @param cols subscribe to the collisions table (Monte Carlo Reconstructed reconstructed) - /// @param parts subscribe to joined table FemtoDreamParticles and FemtoDreamMCLables to access Monte Carlo truth - /// @param FemtoDreamMCParticles subscribe to the Monte Carlo truth table - void processMixedEventMC(o2::aod::FDCollisions& cols, - soa::Join& parts, - o2::aod::FDMCParticles&) - { - for (auto& [collision1, collision2, collision3] : soa::selfCombinations(colBinning, 5, -1, cols, cols, cols)) { - - const int multiplicityCol = collision1.multNtr(); - MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); - - auto groupPartsOne = partsOneMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision1.globalIndex(), cache); - auto groupPartsTwo = partsTwoMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision2.globalIndex(), cache); - auto groupPartsThree = partsThreeMC->sliceByCached(aod::femtodreamparticle::fdCollisionId, collision3.globalIndex(), cache); - - const auto& magFieldTesla1 = collision1.magField(); - const auto& magFieldTesla2 = collision2.magField(); - const auto& magFieldTesla3 = collision3.magField(); - - if ((magFieldTesla1 != magFieldTesla2) || (magFieldTesla2 != magFieldTesla3) || (magFieldTesla1 != magFieldTesla3)) { - continue; - } - // CONSIDER testing different strategies to which events to use - - doMixedEvent(groupPartsOne, groupPartsTwo, groupPartsThree, parts, magFieldTesla1, multiplicityCol); - } - } - PROCESS_SWITCH(femtoDreamPairTaskTrackTrackTrack, processMixedEventMC, "Enable processing mixed events MC", false); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - WorkflowSpec workflow{ - adaptAnalysisTask(cfgc), - }; - return workflow; -} diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniverseCollisionSelection.h b/PWGCF/FemtoUniverse/Core/FemtoUniverseCollisionSelection.h index 5aa132eb963..4b53e1034b5 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniverseCollisionSelection.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniverseCollisionSelection.h @@ -13,6 +13,7 @@ /// \brief FemtoUniverseCollisionSelection - event selection within the o2femtouniverse framework /// \author Andi Mathis, TU München, andreas.mathis@ph.tum.de /// \author Zuzanna Chochulska, WUT Warsaw, zuzanna.chochulska.stud@pw.edu.pl +/// \author Pritam Chakraborty, WUT Warsaw, pritam.chakraborty@pw.edu.pl #ifndef PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSECOLLISIONSELECTION_H_ #define PWGCF_FEMTOUNIVERSE_CORE_FEMTOUNIVERSECOLLISIONSELECTION_H_ @@ -38,10 +39,14 @@ class FemtoUniverseCollisionSelection /// Pass the selection criteria to the class /// \param zvtxMax Maximal value of the z-vertex - /// \param checkTrigger whether or not to check for the trigger alias + /// \param checkTrigger Whether or not to check for the trigger alias /// \param trig Requested trigger alias - /// \param checkOffline whether or not to check for offline selection criteria - void setCuts(float zvtxMax, bool checkTrigger, int trig, bool checkOffline, bool checkRun3) + /// \param checkOffline Whether or not to check for offline selection criteria + /// \param checkRun3 To check for the Run3 data + /// \param centmin Minimum value of centrality selection + /// \param centmax Maximum value of centrality selection + void setCuts(float zvtxMax, bool checkTrigger, int trig, bool checkOffline, bool checkRun3, float centmin, float centmax) + // void setCuts(float zvtxMax, bool checkTrigger, int trig, bool checkOffline, bool checkRun3) { mCutsSet = true; mZvtxMax = zvtxMax; @@ -49,6 +54,8 @@ class FemtoUniverseCollisionSelection mTrigger = static_cast(trig); mCheckOffline = checkOffline; mCheckIsRun3 = checkRun3; + mCentMin = centmin; + mCentMax = centmax; } /// Initializes histograms for the task @@ -75,6 +82,8 @@ class FemtoUniverseCollisionSelection LOG(info) << "Check trigger: " << mCheckTrigger; LOG(info) << "Trigger: " << mTrigger; LOG(info) << " Check offline: " << mCheckOffline; + LOG(info) << " Minimum Centrality: " << mCentMin; + LOG(info) << " Maximum Centrality: " << mCentMax; } /// Check whether the collisions fulfills the specified selections @@ -91,6 +100,9 @@ class FemtoUniverseCollisionSelection if (mCheckOffline && !col.sel8()) { return false; } + if ((col.centFT0C() < mCentMin) || (col.centFT0C() > mCentMax)) { + return false; + } } else { if (mCheckTrigger && !col.alias_bit(mTrigger)) { return false; @@ -145,6 +157,8 @@ class FemtoUniverseCollisionSelection bool mCheckIsRun3 = false; ///< Check if running on Pilot Beam triggerAliases mTrigger = kINT7; ///< Trigger to check for float mZvtxMax = 999.f; ///< Maximal deviation from nominal z-vertex (cm) + float mCentMin = 0.0; ///< Minimum centrality value + float mCentMax = 100.0; ///< Maximum centrality value }; } // namespace o2::analysis::femtoUniverse diff --git a/PWGCF/FemtoUniverse/Core/FemtoUniversePairWithCentMultKt.h b/PWGCF/FemtoUniverse/Core/FemtoUniversePairWithCentMultKt.h index d4c449041cc..c3ef4ca4fad 100644 --- a/PWGCF/FemtoUniverse/Core/FemtoUniversePairWithCentMultKt.h +++ b/PWGCF/FemtoUniverse/Core/FemtoUniversePairWithCentMultKt.h @@ -34,15 +34,19 @@ class PairWithCentMultKt /// @param kstarbins /// @param centmultbins template - void init(HistogramRegistry* registry, t1& kstarbins, t1& centmultbins, t1& ktbins, bool processKT) + void init(HistogramRegistry* registry, t1& kstarbins, t1& centmultbins, t1& ktbins, bool processKT, bool process3D) { PairWithCentMultKtRegistry = registry; AxisSpec kstarAxis = {kstarbins, "#it{k*} (GeV/#it{c})"}; + AxisSpec kOutAxis = {kstarbins, "#it{q}_{out} (GeV/#it{c})"}; + AxisSpec kSideAxis = {kstarbins, "#it{q}_{side} (GeV/#it{c})"}; + AxisSpec kLongAxis = {kstarbins, "#it{q}_{long} (GeV/#it{c})"}; CentMultBins = centmultbins; KtBins = ktbins; KtBins.erase(KtBins.begin()); CentMultBins.erase(CentMultBins.begin()); UseKt = processKT; + Use3D = process3D; for (int i = 0; i < static_cast(CentMultBins.size() - 1); i++) { int lowBin = static_cast((CentMultBins[i])); @@ -50,11 +54,16 @@ class PairWithCentMultKt std::string HistTitle = "mult_" + std::to_string(lowBin) + "-" + std::to_string(highBin); std::string HistSuffix1 = static_cast(HistSuffix[i]); std::string HistSuffix2 = static_cast(HistSuffix[i + 1]); + std::cout << "HistSuffix1 " << HistSuffix1 << " HistSuffix2 " << HistSuffix2 << std::endl; std::string HistFolderMult = "mult_" + HistSuffix1 + "_" + HistSuffix2; std::string HistName = HistFolderMult + "/kstar"; + std::string HistName3D = HistFolderMult + "/q3D"; PairWithCentMultKtRegistry->add(HistName.c_str(), HistTitle.c_str(), HistType::kTH1F, {kstarAxis}); + PairWithCentMultKtRegistry->add(HistName3D.c_str(), HistTitle.c_str(), HistType::kTH3F, {kOutAxis, kSideAxis, kLongAxis}); if (UseKt) { + std::cout << "Working 0" << std::endl; for (int i = 0; i < static_cast(KtBins.size() - 1); i++) { + std::cout << "Working 1" << std::endl; std::string kt_bin1_string = std::to_string(KtBins[i]); std::replace(kt_bin1_string.begin(), kt_bin1_string.end(), '.', '_'); std::string kt_bin2_string = std::to_string(KtBins[i + 1]); @@ -65,11 +74,30 @@ class PairWithCentMultKt std::string HistSuffix1Kt = static_cast(HistSuffix[i]); std::string HistSuffix2Kt = static_cast(HistSuffix[i + 1]); std::string HistNameKt = HistFolderMult + "/kstar_kt_" + HistSuffix1Kt + "_" + HistSuffix2Kt; + std::cout << "HistNameKt " << HistNameKt << std::endl; PairWithCentMultKtRegistry->add(HistNameKt.c_str(), HistTitleKt.c_str(), HistType::kTH1F, {kstarAxis}); } } + if (Use3D) { + for (int i = 0; i < static_cast(KtBins.size() - 1); i++) { + std::cout << "Working 2" << std::endl; + std::string kt_bin1_string = std::to_string(KtBins[i]); + std::replace(kt_bin1_string.begin(), kt_bin1_string.end(), '.', '_'); + std::string kt_bin2_string = std::to_string(KtBins[i + 1]); + std::replace(kt_bin2_string.begin(), kt_bin2_string.end(), '.', '_'); + kt_bin1_string.resize(4); + kt_bin2_string.resize(4); + std::string HistTitleKt = "kt_" + kt_bin1_string + "-" + kt_bin2_string; + std::string HistSuffix1Kt = static_cast(HistSuffix[i]); + std::string HistSuffix2Kt = static_cast(HistSuffix[i + 1]); + std::string HistNameKt = HistFolderMult + "/q3D_kt_" + HistSuffix1Kt + "_" + HistSuffix2Kt; + std::cout << "HistNameKt " << HistNameKt << std::endl; + PairWithCentMultKtRegistry->add(HistNameKt.c_str(), HistTitleKt.c_str(), HistType::kTH3F, {kOutAxis, kSideAxis, kLongAxis}); + } + } } PairWithCentMultKtRegistry->add("Beyond_Max", "Beyond_Max", HistType::kTH1F, {kstarAxis}); + PairWithCentMultKtRegistry->add("Beyond_Max_3D", "Beyond_Max_3D", HistType::kTH3F, {kOutAxis, kSideAxis, kLongAxis}); } /// @brief @@ -169,11 +197,100 @@ class PairWithCentMultKt } } + /// @brief + /// @tparam t1 + /// @param qout_value + /// @param qside_value + /// @param qlong_value + /// @param cent_mult_value + template + void fill_3D(t1 qout_value, t1 qside_value, t1 qlong_value, t1 cent_mult_value, t1 kt_value) + { + + if (cent_mult_value > CentMultBins[CentMultBins.size() - 1] || cent_mult_value < CentMultBins[0]) { + PairWithCentMultKtRegistry->fill(HIST("Beyond_Max_3D"), qout_value, qside_value, qlong_value); + } else if (cent_mult_value <= CentMultBins[1]) { + PairWithCentMultKtRegistry->fill(HIST("mult_0_1/q3D"), qout_value, qside_value, qlong_value); + if (Use3D) { + auto histMultFolder = HIST("mult_0_1/"); + fill_kT_3d(qout_value, qside_value, qlong_value, kt_value, histMultFolder); + } + } else if (cent_mult_value <= CentMultBins[2]) { + // PairWithCentMultKtRegistry->fill(HIST("mult_1_2/q3D"), qout_value, qside_value, qlong_value); + if (Use3D) { + auto histMultFolder = HIST("mult_1_2/"); + fill_kT_3d(qout_value, qside_value, qlong_value, kt_value, histMultFolder); + } + } else if (cent_mult_value <= CentMultBins[3]) { + // PairWithCentMultKtRegistry->fill(HIST("mult_2_3/q3D"), qout_value, qside_value, qlong_value); + if (Use3D) { + auto histMultFolder = HIST("mult_2_3/"); + fill_kT_3d(qout_value, qside_value, qlong_value, kt_value, histMultFolder); + } + } else if (cent_mult_value <= CentMultBins[4]) { + // PairWithCentMultKtRegistry->fill(HIST("mult_3_4/q3D"), qout_value, qside_value, qlong_value); + if (Use3D) { + auto histMultFolder = HIST("mult_3_4/"); + fill_kT_3d(qout_value, qside_value, qlong_value, kt_value, histMultFolder); + } + } else if (cent_mult_value <= CentMultBins[5]) { + // PairWithCentMultKtRegistry->fill(HIST("mult_4_5/q3D"), qout_value, qside_value, qlong_value); + if (Use3D) { + auto histMultFolder = HIST("mult_4_5/"); + fill_kT_3d(qout_value, qside_value, qlong_value, kt_value, histMultFolder); + } + } else if (cent_mult_value <= CentMultBins[6]) { + // PairWithCentMultKtRegistry->fill(HIST("mult_5_6/q3D"), qout_value, qside_value, qlong_value); + if (Use3D) { + auto histMultFolder = HIST("mult_5_6/"); + fill_kT_3d(qout_value, qside_value, qlong_value, kt_value, histMultFolder); + } + } else if (cent_mult_value <= CentMultBins[7]) { + // PairWithCentMultKtRegistry->fill(HIST("mult_6_7/q3D"), qout_value, qside_value, qlong_value); + if (Use3D) { + auto histMultFolder = HIST("mult_6_7/"); + fill_kT_3d(qout_value, qside_value, qlong_value, kt_value, histMultFolder); + } + } else if (cent_mult_value <= CentMultBins[8]) { + // PairWithCentMultKtRegistry->fill(HIST("mult_7_8/q3D"), qout_value, qside_value, qlong_value); + if (Use3D) { + auto histMultFolder = HIST("mult_7_8/"); + fill_kT_3d(qout_value, qside_value, qlong_value, kt_value, histMultFolder); + } + } else if (cent_mult_value <= CentMultBins[9]) { + // PairWithCentMultKtRegistry->fill(HIST("mult_8_9/q3D"), qout_value, qside_value, qlong_value); + if (Use3D) { + auto histMultFolder = HIST("mult_8_9/"); + fill_kT_3d(qout_value, qside_value, qlong_value, kt_value, histMultFolder); + } + } + } + + /// @brief + /// @tparam t1 + /// @tparam t2 + /// @param qout_value + /// @param qside_value + /// @param qlong_value + /// @param folder + template + void fill_kT_3d(t1 qout_value, t1 qside_value, t1 qlong_value, t1 kt_value, t2 folder) + { + if (kt_value <= KtBins[1]) { + PairWithCentMultKtRegistry->fill(folder + HIST("q3D_kt_0_1"), qout_value, qside_value, qlong_value); + } else if (kt_value <= KtBins[2]) { + PairWithCentMultKtRegistry->fill(folder + HIST("q3D_kt_1_2"), qout_value, qside_value, qlong_value); + } else if (kt_value <= KtBins[3]) { + PairWithCentMultKtRegistry->fill(folder + HIST("q3D_kt_2_3"), qout_value, qside_value, qlong_value); + } + } + protected: HistogramRegistry* PairWithCentMultKtRegistry = nullptr; std::vector CentMultBins; std::vector KtBins; bool UseKt = false; + bool Use3D = false; static constexpr std::string_view HistSuffix[10] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}; }; } // namespace o2::analysis::femtoUniverse diff --git a/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h b/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h index 723db5fc069..b7fd3e34524 100644 --- a/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h +++ b/PWGCF/FemtoUniverse/DataModel/FemtoDerived.h @@ -124,12 +124,6 @@ DECLARE_SOA_COLUMN(DecayVtxY, decayVtxY, float); //! Y position of the decay DECLARE_SOA_COLUMN(DecayVtxZ, decayVtxZ, float); //! Z position of the decay vertex DECLARE_SOA_COLUMN(MKaon, mKaon, float); //! The invariant mass of V0 candidate, assuming kaon -DECLARE_SOA_COLUMN(TOFNSigmaEl, tofNSigmaEl, float); -DECLARE_SOA_COLUMN(TOFNSigmaPi, tofNSigmaPi, float); -DECLARE_SOA_COLUMN(TOFNSigmaKa, tofNSigmaKa, float); -DECLARE_SOA_COLUMN(TOFNSigmaPr, tofNSigmaPr, float); -DECLARE_SOA_COLUMN(TOFNSigmaDe, tofNSigmaDe, float); - } // namespace femtouniverseparticle DECLARE_SOA_TABLE(FDParticles, "AOD", "FDPARTICLE", o2::soa::Index<>, @@ -168,11 +162,11 @@ DECLARE_SOA_TABLE(FDExtParticles, "AOD", "FDEXTPARTICLE", pidtpc_tiny::TPCNSigmaStoreKa, pidtpc_tiny::TPCNSigmaStorePr, pidtpc_tiny::TPCNSigmaStoreDe, - femtouniverseparticle::TOFNSigmaEl, - femtouniverseparticle::TOFNSigmaPi, - femtouniverseparticle::TOFNSigmaKa, - femtouniverseparticle::TOFNSigmaPr, - femtouniverseparticle::TOFNSigmaDe, + pidtof_tiny::TOFNSigmaStoreEl, + pidtof_tiny::TOFNSigmaStorePi, + pidtof_tiny::TOFNSigmaStoreKa, + pidtof_tiny::TOFNSigmaStorePr, + pidtof_tiny::TOFNSigmaStoreDe, femtouniverseparticle::DaughDCA, femtouniverseparticle::TransRadius, femtouniverseparticle::DecayVtxX, @@ -184,7 +178,12 @@ DECLARE_SOA_TABLE(FDExtParticles, "AOD", "FDEXTPARTICLE", pidtpc_tiny::TPCNSigmaPi, pidtpc_tiny::TPCNSigmaKa, pidtpc_tiny::TPCNSigmaPr, - pidtpc_tiny::TPCNSigmaDe); + pidtpc_tiny::TPCNSigmaDe, + pidtof_tiny::TOFNSigmaEl, + pidtof_tiny::TOFNSigmaPi, + pidtof_tiny::TOFNSigmaKa, + pidtof_tiny::TOFNSigmaPr, + pidtof_tiny::TOFNSigmaDe); using FDFullParticle = FDExtParticles::iterator; /// FemtoUniverseTrackMC diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx index 9f06c287ebd..6590ce32056 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerMCTruthTask.cxx @@ -47,7 +47,7 @@ using namespace o2::framework::expressions; namespace o2::aod { -using FemtoFullCollisionMC = soa::Join::iterator; +using FemtoFullCollisionMC = soa::Join::iterator; } // namespace o2::aod @@ -98,6 +98,8 @@ struct femtoUniverseProducerMCTruthTask { 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 ConfCentFT0Min{"ConfCentFT0Min", 0.f, "Min CentFT0 value for centrality selection"}; + Configurable ConfCentFT0Max{"ConfCentFT0Max", 200.f, "Max CentFT0 value for centrality selection"}; // Track cuts struct : o2::framework::ConfigurableGroup { @@ -116,7 +118,7 @@ struct femtoUniverseProducerMCTruthTask { LOGF(fatal, "Neither processFullData nor processFullMC enabled. Please choose one."); } - colCuts.setCuts(ConfEvtZvtx, ConfEvtTriggerCheck, ConfEvtTriggerSel, ConfEvtOfflineCheck, ConfIsRun3); + colCuts.setCuts(ConfEvtZvtx, ConfEvtTriggerCheck, ConfEvtTriggerSel, ConfEvtOfflineCheck, ConfIsRun3, ConfCentFT0Min, ConfCentFT0Max); colCuts.init(&qaRegistry); trackCuts.init(&qaRegistry); @@ -166,7 +168,9 @@ struct femtoUniverseProducerMCTruthTask { bool pass = false; std::vector tmpPDGCodes = ConfPDGCodes; // necessary due to some features of the Configurable for (uint32_t pdg : tmpPDGCodes) { - if (static_cast(pdg) == static_cast(pdgCode)) { + if (pdgCode == 333) { + pass = true; + } else if (static_cast(pdg) == static_cast(pdgCode)) { if (particle.isPhysicalPrimary()) pass = true; } diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerReducedTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerReducedTask.cxx index fe46d7509ba..658b70b2367 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerReducedTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerReducedTask.cxx @@ -48,10 +48,12 @@ namespace o2::aod using FemtoFullCollision = soa::Join::iterator; + aod::Mults, + aod::CentFT0Cs>::iterator; using FemtoFullCollisionMC = soa::Join::iterator; using FemtoFullTracks = soa::Join 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 ConfCentFT0Min{"ConfCentFT0Min", 0.f, "Min CentFT0 value for centrality selection"}; + Configurable ConfCentFT0Max{"ConfCentFT0Max", 200.f, "Max CentFT0 value for centrality selection"}; Configurable ConfRejectNotPropagatedTracks{"ConfRejectNotPropagatedTracks", false, "True: reject not propagated tracks"}; Configurable ConfRejectITSHitandTOFMissing{"ConfRejectITSHitandTOFMissing", false, "True: reject if neither ITS hit nor TOF timing satisfied"}; @@ -116,7 +120,7 @@ struct femtoUniverseProducerReducedTask { void init(InitContext&) { - colCuts.setCuts(ConfEvtZvtx, ConfEvtTriggerCheck, ConfEvtTriggerSel, ConfEvtOfflineCheck, ConfIsRun3); + colCuts.setCuts(ConfEvtZvtx, ConfEvtTriggerCheck, ConfEvtTriggerSel, ConfEvtOfflineCheck, ConfIsRun3, ConfCentFT0Min, ConfCentFT0Max); colCuts.init(&qaRegistry); trackCuts.setSelection(ConfTrkCharge, femtoUniverseTrackSelection::kSign, femtoUniverseSelection::kEqual); diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx index 0c14ee52a13..bb61a42151a 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTask.cxx @@ -55,18 +55,18 @@ namespace o2::aod { using FemtoFullCollision = - soa::Join::iterator; + soa::Join::iterator; using FemtoFullCollisionCentRun2 = - soa::Join::iterator; + soa::Join::iterator; using FemtoFullCollisionCentRun3 = soa::Join::iterator; -using FemtoFullCollisionMC = soa::Join::iterator; +using FemtoFullCollisionMC = soa::Join::iterator; using FemtoFullTracks = soa::Join; + aod::pidTPCDe, aod::pidTOFEl, aod::pidTOFMu, aod::pidTOFPi, + aod::pidTOFKa, aod::pidTOFPr, aod::pidTOFDe>; // using FilteredFullV0s = soa::Filtered; /// predefined Join // table for o2::aod::V0s = soa::Join @@ -160,7 +160,7 @@ struct femtoUniverseProducerTask { Configurable> ConfTrkPIDnSigmaMax{FemtoUniverseTrackSelection::getSelectionName(femtoUniverseTrackSelection::kPIDnSigmaMax, "ConfTrk"), std::vector{3.5f, 3.f, 2.5f}, FemtoUniverseTrackSelection::getSelectionHelper(femtoUniverseTrackSelection::kPIDnSigmaMax, "Track selection: ")}; Configurable ConfTrkPIDnSigmaOffsetTPC{"ConfTrkPIDnSigmaOffsetTPC", 0., "Offset for TPC nSigma because of bad calibration"}; Configurable ConfTrkPIDnSigmaOffsetTOF{"ConfTrkPIDnSigmaOffsetTOF", 0., "Offset for TOF nSigma because of bad calibration"}; - Configurable> ConfTrkPIDspecies{"ConfTrkPIDspecies", 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> ConfTrkPIDspecies{"ConfTrkPIDspecies", std::vector{o2::track::PID::Pion, o2::track::PID::Kaon, o2::track::PID::Proton, o2::track::PID::Deuteron}, "Trk sel: Particles species for PID (Pion=2, Kaon=3, Proton=4, Deuteron=5)"}; // Numbers from ~/alice/O2/DataFormats/Reconstruction/include/ReconstructionDataFormats/PID.h //static constexpr ID Pion = 2; static constexpr ID Kaon = 3; static constexpr ID Proton = 4; static constexpr ID Deuteron = 5; Configurable ConfTOFpTmin{"ConfTOFpTmin", 500, "TOF pT min"}; @@ -242,10 +242,7 @@ struct femtoUniverseProducerTask { // D0/D0bar mesons struct : o2::framework::ConfigurableGroup { - Configurable ConfD0SelectionFlag{"ConfD0SelectionFlag", 1, "Selection Flag for D0"}; - Configurable ConfD0barSelectionFlag{"ConfD0barSelectionFlag", 1, "Selection Flag for D0bar"}; - Configurable ConfD0D0barCandMaxY{"ConfD0D0barCandMaxY", 4.0, "max. cand. rapidity"}; - Configurable ConfD0D0barMinPt{"ConfD0D0barMinPt", 0., "min. cand. pT"}; + Configurable ConfD0D0barCandMaxY{"ConfD0D0barCandMaxY", -1., "max. cand. rapidity"}; } ConfD0Selection; HfHelper hfHelper; @@ -321,7 +318,7 @@ struct femtoUniverseProducerTask { "Please choose one."); } - colCuts.setCuts(ConfEvtZvtx, ConfEvtTriggerCheck, ConfEvtTriggerSel, ConfEvtOfflineCheck, ConfIsRun3); + colCuts.setCuts(ConfEvtZvtx, ConfEvtTriggerCheck, ConfEvtTriggerSel, ConfEvtOfflineCheck, ConfIsRun3, ConfCentFT0Min, ConfCentFT0Max); colCuts.init(&qaRegistry); trackCuts.setSelection(ConfTrkCharge, femtoUniverseTrackSelection::kSign, femtoUniverseSelection::kEqual); @@ -453,9 +450,9 @@ struct femtoUniverseProducerTask { particle.dcaXY(), particle.dcaZ(), particle.tpcSignal(), particle.tpcNSigmaStoreEl(), particle.tpcNSigmaStorePi(), particle.tpcNSigmaStoreKa(), particle.tpcNSigmaStorePr(), - particle.tpcNSigmaStoreDe(), particle.tofNSigmaEl(), - particle.tofNSigmaPi(), particle.tofNSigmaKa(), - particle.tofNSigmaPr(), particle.tofNSigmaDe(), + particle.tpcNSigmaStoreDe(), particle.tofNSigmaStoreEl(), + particle.tofNSigmaStorePi(), particle.tofNSigmaStoreKa(), + particle.tofNSigmaStorePr(), particle.tofNSigmaStoreDe(), -999., -999., -999., -999., -999., -999.); } else if constexpr (isPhiOrD0) { outputDebugParts(-999., -999., -999., -999., -999., -999., -999., -999., @@ -621,11 +618,9 @@ struct femtoUniverseProducerTask { continue; } - if (!(ConfIsActivateV0 || ConfIsActivatePhi)) { - if (track.pt() > ConfTOFpTmin) { - if (!track.hasTOF()) { - continue; - } + if (track.pt() > ConfTOFpTmin) { + if (!track.hasTOF()) { + continue; } } @@ -751,7 +746,6 @@ struct femtoUniverseProducerTask { 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; - // phiCuts.fillQA(col, p1, p1, p2, ConfPhiChildOne.ConfPDGCodePartOne, ConfPhiChildTwo.ConfPDGCodePartTwo); ///\todo fill QA also for daughters for (auto const& hfCand : hfCands) { @@ -763,10 +757,6 @@ struct femtoUniverseProducerTask { continue; } - if (hfCand.pt() > ConfD0Selection.ConfD0D0barMinPt) { - continue; - } - int postrackID = hfCand.globalIndex(); int rowInPrimaryTrackTablePos = -1; rowInPrimaryTrackTablePos = getRowDaughters(postrackID, tmpIDtrack); @@ -775,15 +765,15 @@ struct femtoUniverseProducerTask { auto postrack = hfCand.template prong0_as(); auto negtrack = hfCand.template prong1_as(); - if (hfCand.isSelD0() == ConfD0Selection.ConfD0SelectionFlag && hfCand.isSelD0bar() != ConfD0Selection.ConfD0barSelectionFlag) { + if (hfCand.isSelD0() == 1 && hfCand.isSelD0bar() == 0) { invMassD0 = hfHelper.invMassD0ToPiK(hfCand); - invMassD0bar = -hfHelper.invMassD0ToPiK(hfCand); - } else if (hfCand.isSelD0() != ConfD0Selection.ConfD0SelectionFlag && hfCand.isSelD0bar() == ConfD0Selection.ConfD0barSelectionFlag) { + invMassD0bar = -hfHelper.invMassD0barToKPi(hfCand); + } else if (hfCand.isSelD0() == 0 && hfCand.isSelD0bar() == 1) { invMassD0 = -hfHelper.invMassD0ToPiK(hfCand); - invMassD0bar = hfHelper.invMassD0ToPiK(hfCand); - } else if (hfCand.isSelD0() == ConfD0Selection.ConfD0SelectionFlag && hfCand.isSelD0bar() == ConfD0Selection.ConfD0barSelectionFlag) { + invMassD0bar = hfHelper.invMassD0barToKPi(hfCand); + } else if (hfCand.isSelD0() == 1 && hfCand.isSelD0bar() == 1) { invMassD0 = hfHelper.invMassD0ToPiK(hfCand); - invMassD0bar = hfHelper.invMassD0ToPiK(hfCand); + invMassD0bar = hfHelper.invMassD0barToKPi(hfCand); } else { invMassD0 = 0.0; invMassD0bar = 0.0; @@ -1168,7 +1158,7 @@ struct femtoUniverseProducerTask { PROCESS_SWITCH(femtoUniverseProducerTask, processTrackCentRun2Data, "Provide experimental data for Run 2 with centrality for track track", false); void - processTrackCentRun3Data(soa::Filtered>::iterator const& col, + processTrackCentRun3Data(aod::FemtoFullCollisionCentRun3 const& col, aod::BCsWithTimestamps const&, aod::FemtoFullTracks const& tracks) { diff --git a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTaskV0Only.cxx b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTaskV0Only.cxx index c4cc6a67835..f72e1324c0c 100644 --- a/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTaskV0Only.cxx +++ b/PWGCF/FemtoUniverse/TableProducer/femtoUniverseProducerTaskV0Only.cxx @@ -44,7 +44,7 @@ namespace o2::aod { using FemtoFullCollision = - soa::Join::iterator; + soa::Join::iterator; using FemtoFullTracks = soa::Join 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 ConfCentFT0Min{"ConfCentFT0Min", 0.f, "Min CentFT0 value for centrality selection"}; + Configurable ConfCentFT0Max{"ConfCentFT0Max", 200.f, "Max CentFT0 value for centrality selection"}; Configurable ConfStoreV0{"ConfStoreV0", true, "True: store V0 table"}; // just sanity check to make sure in case there are problems in conversion or @@ -215,7 +217,7 @@ struct femtoUniverseProducerTaskV0Only { void init(InitContext&) { colCuts.setCuts(ConfEvtZvtx, ConfEvtTriggerCheck, ConfEvtTriggerSel, - ConfEvtOfflineCheck, ConfIsRun3); + ConfEvtOfflineCheck, ConfIsRun3, ConfCentFT0Min, ConfCentFT0Max); colCuts.init(&qaRegistry); /// \todo fix how to pass array to setSelection, getRow() passing a diff --git a/PWGCF/FemtoUniverse/Tasks/Femto.md b/PWGCF/FemtoUniverse/Tasks/Femto.md index d2c6926a52d..e299f440dd5 100644 --- a/PWGCF/FemtoUniverse/Tasks/Femto.md +++ b/PWGCF/FemtoUniverse/Tasks/Femto.md @@ -2,12 +2,13 @@ Here you can find a summary of the tasks and information about who is developing it! -| Task name | What it does? | Who is developing it? | -|---------------------------------------------|-----------------------------------|-----------------------| -| femtoUniversePairTaskTrackTrack.cxx | | | -| femtoUniversePairTaskTrackTrackExtended.cxx | | | -| femtoUniversePairTaskTrackPhi.cxx | Angular correlations of h--$\Phi$ | Zuzanna Chochulska | -| femtoUniversePairTaskTrackV0Extended.cxx | Angular correlations of h--V0 | Shirajum Monira +| Task name | What it does? | Who is developing it? | +|---------------------------------------------|------------------------------------|-----------------------| +| femtoUniversePairTaskTrackTrack.cxx | | | +| femtoUniversePairTaskTrackTrackExtended.cxx | | | +| femtoUniversePairTaskTrackPhi.cxx | Angular correlations of h--$\Phi$ | Zuzanna Chochulska | +| femtoUniversePairTaskTrackV0Extended.cxx | Angular correlations of h--V0 | Shirajum Monira | +| femtoUniversePairTaskTrackD0.cxx | Angular correlations of h-D0/D0bar | Katarzyna Gwiździel | > **Note:** If you have any issues or questions feel free to contact us via mattermost ;) diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx index 2c0ffa487be..118c94b8bb9 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackD0.cxx @@ -100,7 +100,7 @@ struct femtoUniversePairTaskTrackD0 { Partition> partsTrackMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)); /// Partitions for particle 2 - Partition partsAllDmesons = aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0); + Partition partsAllDmesons = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)); Partition partsOnlyD0D0bar = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)) && (aod::femtouniverseparticle::mLambda < 0.0f || aod::femtouniverseparticle::mAntiLambda < 0.0f); Partition> partsD0D0barMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kD0)); @@ -352,8 +352,8 @@ struct femtoUniversePairTaskTrackD0 { } if (dmeson.mAntiLambda() > 0.0f) { - registry.fill(HIST("hMassVsPt"), dmeson.mLambda(), dmeson.pt()); - registry.fill(HIST("hMassVsPtFiner"), dmeson.mLambda(), dmeson.pt()); + registry.fill(HIST("hMassVsPt"), dmeson.mAntiLambda(), dmeson.pt()); + registry.fill(HIST("hMassVsPtFiner"), dmeson.mAntiLambda(), dmeson.pt()); } registry.fill(HIST("hPtDmesonCand"), dmeson.pt()); @@ -373,7 +373,7 @@ struct femtoUniversePairTaskTrackD0 { registry.fill(HIST("hEtaD0"), d0d0bar.eta()); } if (d0d0bar.mLambda() < 0.0f && d0d0bar.mAntiLambda() > 0.0f) { - registry.fill(HIST("hInvMassVsPtOnlyD0D0bar"), d0d0bar.mLambda(), d0d0bar.pt()); + registry.fill(HIST("hInvMassVsPtOnlyD0D0bar"), d0d0bar.mAntiLambda(), d0d0bar.pt()); if (d0d0bar.mAntiLambda() > ConfDmesons.ConfMinInvMassD0D0bar && d0d0bar.mAntiLambda() < ConfDmesons.ConfMaxInvMassD0D0bar) { registry.fill(HIST("hInvMassD0bar"), d0d0bar.mAntiLambda()); } @@ -451,7 +451,7 @@ struct femtoUniversePairTaskTrackD0 { fillCollision(col); auto thegroupPartsTrack = partsTrack->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); - auto thegroupPartsD0 = partsOnlyD0D0bar->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto thegroupPartsD0 = partsAllDmesons->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); doSameEvent(thegroupPartsTrack, thegroupPartsD0, parts, col.magField(), col.multNtr()); } @@ -517,7 +517,7 @@ struct femtoUniversePairTaskTrackD0 { MixQaRegistry.fill(HIST("MixingQA/hMECollisionBins"), colBinning.getBin({collision1.posZ(), multiplicityCol})); auto groupPartsTrack = partsTrack->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision2.globalIndex(), cache); - auto groupPartsD0 = partsOnlyD0D0bar->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); + auto groupPartsD0 = partsAllDmesons->sliceByCached(aod::femtouniverseparticle::fdCollisionId, collision1.globalIndex(), cache); const auto& magFieldTesla1 = collision1.magField(); const auto& magFieldTesla2 = collision2.magField(); diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx index 9575dbe019e..9ca1edf50dc 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackPhi.cxx @@ -83,7 +83,7 @@ struct femtoUniversePairTaskTrackPhi { Configurable ConfPDGCodeTrack{"ConfPDGCodeTrack", 2212, "Particle 2 - PDG code"}; // Configurable ConfCutTrack{"ConfCutTrack", 5542474, "Particle 2 - Selection bit"}; Configurable ConfPIDTrack{"ConfPIDTrack", 2, "Particle 2 - Read from cutCulator"}; // we also need the possibility to specify whether the bit is true/false ->std>>vector> - Configurable ConfTrackSign{"ConfTrackSign", 1, "Track sign"}; + Configurable ConfTrackSign{"ConfTrackSign", 1, "Track sign"}; Configurable ConfIsTrackIdentified{"ConfIsTrackIdentified", true, "Enable PID for the track"}; } ConfTrack; @@ -97,7 +97,7 @@ struct femtoUniversePairTaskTrackPhi { } ConfPhi; /// Partitions for particle 1 - Partition partsTrack = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::sign == int8_t(ConfTrack.ConfTrackSign)); + Partition partsTrack = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && (aod::femtouniverseparticle::sign == ConfTrack.ConfTrackSign); Partition> partsTrackMC = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)); /// Partitions for particle 2 diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx index f442a92735b..45598235207 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrack3DMultKtExtended.cxx @@ -15,6 +15,7 @@ /// \author Pritam Chakraborty, WUT Warsaw, pritam.chakraborty@pw.edu.pl #include +#include "TRandom2.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" #include "Framework/HistogramRegistry.h" @@ -142,8 +143,8 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended { /// 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 or centrality"}; // \todo to be obtained from the hash task - ConfigurableAxis ConfMultKstarBins{"ConfMultKstarBins", {VARIABLE_WIDTH, 0.0f, 13.0f, 20.0f, 30.0f, 40.0f, 50.0f, 100.0f, 99999.f}, "Bins for kstar analysis in multiplicity or centrality bins (10 is maximum)"}; - ConfigurableAxis ConfKtKstarBins{"ConfKtKstarBins", {VARIABLE_WIDTH, 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f, 2.0f, 99999.f}, "Bins for kstar analysis in kT bins (10 is maximum)"}; + ConfigurableAxis ConfMultKstarBins{"ConfMultKstarBins", {VARIABLE_WIDTH, 0.0f, 200.0f}, "Bins for kstar analysis in multiplicity or centrality bins (10 is maximum)"}; + ConfigurableAxis ConfKtKstarBins{"ConfKtKstarBins", {VARIABLE_WIDTH, 0.1f, 0.2f, 0.3f, 0.4f}, "Bins for kstar analysis in kT bins"}; 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)"}; @@ -168,6 +169,7 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended { Configurable cfgProcessMM{"cfgProcessMM", true, "Process particles of the same, positice charge"}; Configurable cfgProcessMultBins{"cfgProcessMultBins", true, "Process kstar histograms in multiplicity bins (in multiplicity bins)"}; Configurable cfgProcessKtBins{"cfgProcessKtBins", true, "Process kstar histograms in kT bins (if cfgProcessMultBins is set false, this will not be processed regardless this Configurable state)"}; + Configurable cfgProcessKtMt3DCF{"cfgProcessKtMt3DCF", false, "Process 3D histograms in kT and Mult bins"}; FemtoUniverse3DContainer sameEventCont; FemtoUniverse3DContainer mixedEventCont; @@ -358,8 +360,8 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended { mixedEventCont.setPDGCodes(trackonefilter.ConfPDGCodePartOne, tracktwofilter.ConfPDGCodePartTwo); if (cfgProcessMultBins) { - sameEventMultCont.init(&SameMultRegistryPM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins); - mixedEventMultCont.init(&MixedMultRegistryPM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins); + sameEventMultCont.init(&SameMultRegistryPM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins, cfgProcessKtMt3DCF); + mixedEventMultCont.init(&MixedMultRegistryPM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins, cfgProcessKtMt3DCF); } } @@ -370,8 +372,8 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended { mixedEventContPP.setPDGCodes(trackonefilter.ConfPDGCodePartOne, tracktwofilter.ConfPDGCodePartTwo); if (cfgProcessMultBins) { - sameEventMultContPP.init(&SameMultRegistryPP, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins); - mixedEventMultContPP.init(&MixedMultRegistryPP, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins); + sameEventMultContPP.init(&SameMultRegistryPP, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins, cfgProcessKtMt3DCF); + mixedEventMultContPP.init(&MixedMultRegistryPP, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins, cfgProcessKtMt3DCF); } } @@ -382,8 +384,8 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended { mixedEventContMM.setPDGCodes(trackonefilter.ConfPDGCodePartOne, tracktwofilter.ConfPDGCodePartTwo); if (cfgProcessMultBins) { - sameEventMultContMM.init(&SameMultRegistryMM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins); - mixedEventMultContMM.init(&MixedMultRegistryMM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins); + sameEventMultContMM.init(&SameMultRegistryMM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins, cfgProcessKtMt3DCF); + mixedEventMultContMM.init(&MixedMultRegistryMM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins, cfgProcessKtMt3DCF); } } @@ -461,15 +463,16 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended { continue; } - float kstar = FemtoUniverseMath::getkstar(p1, mass1, p2, mass2); float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass2); - sameEventCont.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + std::vector k3d = FemtoUniverseMath::getpairmom3d(p1, mass1, p2, mass2, ConfIsIden, ConfIsLCMS); if (cfgProcessMultBins) - sameEventMultCont.fill(kstar, multCol, kT); + sameEventMultCont.fill_3D(k3d[1], k3d[2], k3d[3], multCol, kT); } } else { /// Now build the combinations for identical particles pairs + TRandom2* randgen = new TRandom2(1); + double rand; for (auto& [p1, p2] : combinations(CombinationsStrictlyUpperIndexPolicy(groupPartsOne, groupPartsOne))) { if (!IsParticleNSigma((int8_t)2, p1.pt(), trackCuts.getNsigmaTPC(p1, o2::track::PID::Proton), trackCuts.getNsigmaTOF(p1, o2::track::PID::Proton), trackCuts.getNsigmaTPC(p1, o2::track::PID::Pion), trackCuts.getNsigmaTOF(p1, o2::track::PID::Pion), trackCuts.getNsigmaTPC(p1, o2::track::PID::Kaon), trackCuts.getNsigmaTOF(p1, o2::track::PID::Kaon))) { @@ -493,22 +496,34 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended { switch (ContType) { case 2: { - float kstar = FemtoUniverseMath::getkstar(p1, mass1, p2, mass1); - float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass1); - - sameEventContPP.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass2); + std::vector k3d; + rand = randgen->Rndm(); + if (rand > 0.5) { + sameEventContPP.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + k3d = FemtoUniverseMath::getpairmom3d(p1, mass1, p2, mass2, ConfIsIden, ConfIsLCMS); + } else { + sameEventContPP.setPair(p2, p1, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + k3d = FemtoUniverseMath::getpairmom3d(p2, mass2, p1, mass1, ConfIsIden, ConfIsLCMS); + } if (cfgProcessMultBins) - sameEventMultContPP.fill(kstar, multCol, kT); + sameEventMultContPP.fill_3D(k3d[1], k3d[2], k3d[3], multCol, kT); break; } case 3: { - float kstar = FemtoUniverseMath::getkstar(p1, mass2, p2, mass2); - float kT = FemtoUniverseMath::getkT(p1, mass2, p2, mass2); - - sameEventContMM.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass2); + std::vector k3d; + rand = randgen->Rndm(); + if (rand > 0.5) { + sameEventContMM.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + k3d = FemtoUniverseMath::getpairmom3d(p1, mass1, p2, mass2, ConfIsIden, ConfIsLCMS); + } else { + sameEventContMM.setPair(p2, p1, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + k3d = FemtoUniverseMath::getpairmom3d(p2, mass2, p1, mass1, ConfIsIden, ConfIsLCMS); + } if (cfgProcessMultBins) - sameEventMultContMM.fill(kstar, multCol, kT); + sameEventMultContMM.fill_3D(k3d[1], k3d[2], k3d[3], multCol, kT); break; } default: @@ -529,6 +544,11 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended { auto thegroupPartsOne = partsOne->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); auto thegroupPartsTwo = partsTwo->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + /*if(rand > 0.5) { + auto thegroupPartsTwo = partsOne->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + auto thegroupPartsOne = partsTwo->sliceByCached(aod::femtouniverseparticle::fdCollisionId, col.globalIndex(), cache); + }*/ + bool fillQA = true; if (cfgProcessPM) { @@ -599,28 +619,28 @@ struct femtoUniversePairTaskTrackTrack3DMultKtExtended { switch (ContType) { case 1: { - float kstar = FemtoUniverseMath::getkstar(p1, mass1, p2, mass2); float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass2); mixedEventCont.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + std::vector k3d = FemtoUniverseMath::getpairmom3d(p1, mass1, p2, mass2, ConfIsIden, ConfIsLCMS); if (cfgProcessMultBins) - mixedEventMultCont.fill(kstar, multCol, kT); + mixedEventMultCont.fill_3D(k3d[1], k3d[2], k3d[3], multCol, kT); break; } case 2: { - float kstar = FemtoUniverseMath::getkstar(p1, mass1, p2, mass1); float kT = FemtoUniverseMath::getkT(p1, mass1, p2, mass1); mixedEventContPP.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + std::vector k3d = FemtoUniverseMath::getpairmom3d(p1, mass1, p2, mass2, ConfIsIden, ConfIsLCMS); if (cfgProcessMultBins) - mixedEventMultContPP.fill(kstar, multCol, kT); + mixedEventMultContPP.fill_3D(k3d[1], k3d[2], k3d[3], multCol, kT); break; } case 3: { - float kstar = FemtoUniverseMath::getkstar(p1, mass2, p2, mass2); float kT = FemtoUniverseMath::getkT(p1, mass2, p2, mass2); mixedEventContMM.setPair(p1, p2, multCol, twotracksconfigs.ConfUse3D, ConfIsIden, ConfIsLCMS); + std::vector k3d = FemtoUniverseMath::getpairmom3d(p1, mass1, p2, mass2, ConfIsIden, ConfIsLCMS); if (cfgProcessMultBins) - mixedEventMultContMM.fill(kstar, multCol, kT); + mixedEventMultContMM.fill_3D(k3d[1], k3d[2], k3d[3], multCol, kT); break; } default: diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMcTruth.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMcTruth.cxx index ad5a60a11ef..a4447aa4aea 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMcTruth.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMcTruth.cxx @@ -50,13 +50,13 @@ struct femtoUniversePairTaskTrackTrackMcTruth { Configurable ConfEtaMax{"ConfEtaMax", 0.8f, "Higher limit for |Eta| (the same for both particles)"}; /// Particle 1 - Configurable ConfPDGCodePartOne{"ConfPDGCodePartOne", 211, "Particle 1 - PDG code"}; + Configurable ConfPDGCodePartOne{"ConfPDGCodePartOne", 211, "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)) && (ConfNoPDGPartOne || aod::femtouniverseparticle::pidcut == ConfPDGCodePartOne) && + Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && (ConfNoPDGPartOne || aod::femtouniverseparticle::pidcut == uint32_t(ConfPDGCodePartOne)) && aod::femtouniverseparticle::pt < ConfPtHighPart1 && aod::femtouniverseparticle::pt > ConfPtLowPart1&& nabs(aod::femtouniverseparticle::eta) < ConfEtaMax; /// Histogramming for particle 1 @@ -64,13 +64,13 @@ struct femtoUniversePairTaskTrackTrackMcTruth { /// Particle 2 Configurable ConfIsSame{"ConfIsSame", false, "Pairs of the same particle"}; - Configurable ConfPDGCodePartTwo{"ConfPDGCodePartTwo", 211, "Particle 2 - PDG code"}; + Configurable ConfPDGCodePartTwo{"ConfPDGCodePartTwo", 211, "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)) && (ConfNoPDGPartTwo || aod::femtouniverseparticle::pidcut == ConfPDGCodePartTwo) && + Partition partsTwo = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kMCTruthTrack)) && (ConfNoPDGPartTwo || aod::femtouniverseparticle::pidcut == uint32_t(ConfPDGCodePartTwo)) && aod::femtouniverseparticle::pt < ConfPtHighPart2 && aod::femtouniverseparticle::pt > ConfPtLowPart2&& nabs(aod::femtouniverseparticle::eta) < ConfEtaMax; /// Histogramming for particle 2 diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx index a264835b731..508ce7dbdf2 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackTrackMultKtExtended.cxx @@ -170,6 +170,7 @@ struct femtoUniversePairTaskTrackTrackMultKtExtended { Configurable cfgProcessMM{"cfgProcessMM", true, "Process particles of the same, positice charge"}; Configurable cfgProcessMultBins{"cfgProcessMultBins", true, "Process kstar histograms in multiplicity bins (in multiplicity bins)"}; Configurable cfgProcessKtBins{"cfgProcessKtBins", true, "Process kstar histograms in kT bins (if cfgProcessMultBins is set false, this will not be processed regardless this Configurable state)"}; + Configurable cfgProcessKtMt3DCF{"cfgProcessKtMt3DCF", false, "Process 3D histograms in kT and Mult bins"}; FemtoUniverseFemtoContainer sameEventCont; FemtoUniverseFemtoContainer mixedEventCont; @@ -360,8 +361,8 @@ struct femtoUniversePairTaskTrackTrackMultKtExtended { mixedEventCont.setPDGCodes(trackonefilter.ConfPDGCodePartOne, tracktwofilter.ConfPDGCodePartTwo); if (cfgProcessMultBins) { - sameEventMultCont.init(&SameMultRegistryPM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins); - mixedEventMultCont.init(&MixedMultRegistryPM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins); + sameEventMultCont.init(&SameMultRegistryPM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins, cfgProcessKtMt3DCF); + mixedEventMultCont.init(&MixedMultRegistryPM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins, cfgProcessKtMt3DCF); } } @@ -372,8 +373,8 @@ struct femtoUniversePairTaskTrackTrackMultKtExtended { mixedEventContPP.setPDGCodes(trackonefilter.ConfPDGCodePartOne, tracktwofilter.ConfPDGCodePartTwo); if (cfgProcessMultBins) { - sameEventMultContPP.init(&SameMultRegistryPP, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins); - mixedEventMultContPP.init(&MixedMultRegistryPP, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins); + sameEventMultContPP.init(&SameMultRegistryPP, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins, cfgProcessKtMt3DCF); + mixedEventMultContPP.init(&MixedMultRegistryPP, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins, cfgProcessKtMt3DCF); } } @@ -384,8 +385,8 @@ struct femtoUniversePairTaskTrackTrackMultKtExtended { mixedEventContMM.setPDGCodes(trackonefilter.ConfPDGCodePartOne, tracktwofilter.ConfPDGCodePartTwo); if (cfgProcessMultBins) { - sameEventMultContMM.init(&SameMultRegistryMM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins); - mixedEventMultContMM.init(&MixedMultRegistryMM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins); + sameEventMultContMM.init(&SameMultRegistryMM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins, cfgProcessKtMt3DCF); + mixedEventMultContMM.init(&MixedMultRegistryMM, ConfkstarBins, ConfMultKstarBins, ConfKtKstarBins, cfgProcessKtBins, cfgProcessKtMt3DCF); } } diff --git a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx index 5697376630e..b67bba8d782 100644 --- a/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx +++ b/PWGCF/FemtoUniverse/Tasks/femtoUniversePairTaskTrackV0Extended.cxx @@ -42,12 +42,12 @@ struct femtoUniversePairTaskTrackV0Extended { using FemtoFullParticles = soa::Join; Preslice perCol = aod::femtouniverseparticle::fdCollisionId; - /// Particle 1 (from 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{"ConfTrkDTempFitVarBins", {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", 1, "sign of particle 1"}; // not used + 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"}; @@ -55,17 +55,17 @@ struct femtoUniversePairTaskTrackV0Extended { Configurable ConfNsigmaCombinedParticle{"ConfNsigmaCombinedParticle", 3.0, "TPC and TOF Sigma (combined) for particle momentum > Confmom"}; /// Partition for particle 1 - // Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && aod::femtouniverseparticle::sign == ConfChargePart1 && aod::femtouniverseparticle::pt < ConfHPtPart1 && aod::femtouniverseparticle::pt > ConfLPtPart1; - Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && aod::femtouniverseparticle::pt < ConfHPtPart1 && aod::femtouniverseparticle::pt > ConfLPtPart1; + Partition partsOne = (aod::femtouniverseparticle::partType == uint8_t(aod::femtouniverseparticle::ParticleType::kTrack)) && aod::femtouniverseparticle::sign == ConfChargePart1 && aod::femtouniverseparticle::pt < ConfHPtPart1 && aod::femtouniverseparticle::pt > ConfLPtPart1; /// Histogramming for particle 1 - FemtoUniverseParticleHisto trackHistoPartOne; + FemtoUniverseParticleHisto trackHistoPartOnePos; + FemtoUniverseParticleHisto trackHistoPartOneNeg; - /// Particle 2 (from V0) + /// 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 ConfChildnSpecies{"ConfChildnSpecies", 2, "Number of particle spieces (for V0 children) with PID info"}; // not used + Configurable ConfV0PosChildType{"ConfV0PosChildType", -1, "identifier for positive v0 daughter"}; 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"}; @@ -128,12 +128,25 @@ struct femtoUniversePairTaskTrackV0Extended { } } + template + bool IsParticleType(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 IsParticleNSigma(part.p(), tpcNSigmas[id], tofNSigmas[id]); + } + void init(InitContext&) { eventHisto.init(&qaRegistry); - qaRegistry.add("Tracks_one/nSigmaTPC", "; #it{p} (GeV/#it{c}); n#sigma_{TPC}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - qaRegistry.add("Tracks_one/nSigmaTOF", "; #it{p} (GeV/#it{c}); n#sigma_{TOF}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); - trackHistoPartOne.init(&qaRegistry, ConfTrkTempFitVarpTBins, ConfTrkTempFitVarBins, ConfIsMC, ConfTrkPDGCodePartOne); + qaRegistry.add("Tracks_pos/nSigmaTPC", "; #it{p} (GeV/#it{c}); n#sigma_{TPC}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); + qaRegistry.add("Tracks_pos/nSigmaTOF", "; #it{p} (GeV/#it{c}); n#sigma_{TOF}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); + qaRegistry.add("Tracks_neg/nSigmaTPC", "; #it{p} (GeV/#it{c}); n#sigma_{TPC}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); + qaRegistry.add("Tracks_neg/nSigmaTOF", "; #it{p} (GeV/#it{c}); n#sigma_{TOF}", kTH2F, {{100, 0, 10}, {100, -5, 5}}); + trackHistoPartOnePos.init(&qaRegistry, ConfTrkTempFitVarpTBins, ConfTrkTempFitVarBins, ConfIsMC, ConfTrkPDGCodePartOne); + trackHistoPartOneNeg.init(&qaRegistry, ConfTrkTempFitVarpTBins, ConfTrkTempFitVarBins, ConfIsMC, ConfTrkPDGCodePartOne); trackHistoPartTwo.init(&qaRegistry, ConfV0TempFitVarpTBins, ConfV0TempFitVarBins, ConfIsMC, ConfV0PDGCodePartTwo); posChildHistos.init(&qaRegistry, ConfChildTempFitVarpTBins, ConfChildTempFitVarBins, false, false); negChildHistos.init(&qaRegistry, ConfChildTempFitVarpTBins, ConfChildTempFitVarBins, false, false); @@ -166,6 +179,8 @@ struct femtoUniversePairTaskTrackV0Extended { const auto& posChild = parts.iteratorAt(part.index() - 2); const auto& negChild = parts.iteratorAt(part.index() - 1); // printf("-- V0 d- %d d+ %d\n",negChild.globalIndex(),posChild.globalIndex()); + if (ConfV0PosChildType >= 0 && !IsParticleType(posChild, ConfV0PosChildType)) + continue; trackHistoPartTwo.fillQA(part); posChildHistos.fillQA(posChild); @@ -173,17 +188,22 @@ struct femtoUniversePairTaskTrackV0Extended { } for (auto& part : groupPartsOne) { - /// PID using stored binned nsigma + /// PID plot for particle 1 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] = {part.tofNSigmaPr(), part.tofNSigmaPi(), part.tofNSigmaKa()}; + const float tofNSigmas[3] = {unPackInTable(part.tofNSigmaStorePr()), unPackInTable(part.tofNSigmaStorePi()), unPackInTable(part.tofNSigmaStoreKa())}; - if (!IsParticleNSigma(part.p(), tpcNSigmas[ConfTrackChoicePartOne], tofNSigmas[ConfTrackChoicePartOne])) { + if (!IsParticleNSigma(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); } - qaRegistry.fill(HIST("Tracks_one/nSigmaTPC"), part.p(), tpcNSigmas[ConfTrackChoicePartOne]); - qaRegistry.fill(HIST("Tracks_one/nSigmaTOF"), part.p(), tofNSigmas[ConfTrackChoicePartOne]); - - trackHistoPartOne.fillQA(part); } /// Now build the combinations @@ -198,12 +218,11 @@ struct femtoUniversePairTaskTrackV0Extended { continue; } /// PID using stored binned nsigma - const float tpcNSigmas[3] = {unPackInTable(p1.tpcNSigmaStorePr()), unPackInTable(p1.tpcNSigmaStorePi()), unPackInTable(p1.tpcNSigmaStoreKa())}; - const float tofNSigmas[3] = {p1.tofNSigmaPr(), p1.tofNSigmaPi(), p1.tofNSigmaKa()}; - - if (!IsParticleNSigma(p1.p(), tpcNSigmas[ConfTrackChoicePartOne], tofNSigmas[ConfTrackChoicePartOne])) { + if (!IsParticleType(p1, ConfTrackChoicePartOne)) + continue; + const auto& posChild = parts.iteratorAt(p2.index() - 2); + if (ConfV0PosChildType >= 0 && !IsParticleType(posChild, ConfV0PosChildType)) continue; - } sameEventCont.setPair(p1, p2, multCol, ConfUse3D); } } @@ -240,12 +259,11 @@ struct femtoUniversePairTaskTrackV0Extended { continue; } /// PID using stored binned nsigma - const float tpcNSigmas[3] = {unPackInTable(p1.tpcNSigmaStorePr()), unPackInTable(p1.tpcNSigmaStorePi()), unPackInTable(p1.tpcNSigmaStoreKa())}; - const float tofNSigmas[3] = {p1.tofNSigmaPr(), p1.tofNSigmaPi(), p1.tofNSigmaKa()}; - - if (!IsParticleNSigma(p1.p(), tpcNSigmas[ConfTrackChoicePartOne], tofNSigmas[ConfTrackChoicePartOne])) { + if (!IsParticleType(p1, ConfTrackChoicePartOne)) + continue; + const auto& posChild = parts.iteratorAt(p2.index() - 2); + if (ConfV0PosChildType >= 0 && !IsParticleType(posChild, ConfV0PosChildType)) continue; - } mixedEventCont.setPair(p1, p2, multCol, ConfUse3D); } } diff --git a/PWGCF/MultiparticleCorrelations/Core/MuPa-DataMembers.h b/PWGCF/MultiparticleCorrelations/Core/MuPa-DataMembers.h index 4410296191b..3f97f56e7c5 100644 --- a/PWGCF/MultiparticleCorrelations/Core/MuPa-DataMembers.h +++ b/PWGCF/MultiparticleCorrelations/Core/MuPa-DataMembers.h @@ -56,6 +56,7 @@ struct TaskConfiguration { TString fWhatToProcess = "Rec"; // "Rec" = process only reconstructed, "Sim" = process only simulated, "RecSim" = process both reconstructed and simulated UInt_t fRandomSeed = 0; // argument to TRandom3 constructor. By default it is 0 (i.e. seed is guaranteed to be unique in time and space), use SetRandomSeed(...) to change it Bool_t fUseFisherYates = kFALSE; // algorithm used to randomize particle indices, set via configurable + TArrayI* fRandomIndices = NULL; // array to store random indices obtained from Fisher-Yates algorithm Int_t fFixedNumberOfRandomlySelectedTracks = -1; // use a fixed number of randomly selected particles in each event. It is set and applied, if > 0. Set to <=0 to ignore. // Bool_t fRescaleWithTheoreticalInput; // if kTRUE, all measured correlators are @@ -126,7 +127,7 @@ Bool_t fCalculateCorrelations = struct Correlations_Arrays { TProfile* fCorrelationsPro[4][gMaxHarmonic][eAsFunctionOf_N] = { {{NULL}}}; //! multiparticle correlations - //! [2p=0,4p=1,6p=2,8p=3][n=1,n=2,...,n=6][0=integrated,1=vs. + //! [2p=0,4p=1,6p=2,8p=3][n=1,n=2,...,n=gMaxHarmonic][0=integrated,1=vs. //! multiplicity,2=vs. centrality,3=pT,4=eta] } c_a; @@ -151,9 +152,9 @@ Bool_t fCalculateNestedLoops = kTRUE; // calculate and store correlations with Bool_t fCalculateCustomNestedLoop = kFALSE; // validate e-b-e all correlations with custom nested loop struct NestedLoops_Arrays { - TProfile* fNestedLoopsPro[4][6][eAsFunctionOf_N] = { + TProfile* fNestedLoopsPro[4][gMaxHarmonic][eAsFunctionOf_N] = { {{NULL}}}; //! multiparticle correlations from nested loops - //! [2p=0,4p=1,6p=2,8p=3][n=1,n=2,...,n=6][0=integrated,1=vs. + //! [2p=0,4p=1,6p=2,8p=3][n=1,n=2,...,n=gMaxHarmonic][0=integrated,1=vs. //! multiplicity,2=vs. centrality,3=pT,4=eta] TArrayD* ftaNestedLoops[2] = {NULL}; //! e-b-e container for nested loops //! [0=angles;1=product of all weights] @@ -185,12 +186,12 @@ TProfile* fResultsFlagsPro = NULL; //!GetXaxis()->SetBinLabel(eTaskName, - Form("fTaskName = %s", tc.fTaskName.Data())); // TBI 20240115 or use the full name tc.fTaskName ? + Form("fTaskName = %s", tc.fTaskName.Data())); + fBasePro->GetXaxis()->SetBinLabel(eRunNumber, - Form("tc.fRunNumber = %s", tc.fRunNumber.Data())); - fBasePro->GetXaxis()->SetBinLabel(eVerbose, "fVerbose"); // TBI 20240115 or use the full name tc.fVerbose ? + Form("fRunNumber = %s", tc.fRunNumber.Data())); + + fBasePro->GetXaxis()->SetBinLabel(eVerbose, "fVerbose"); fBasePro->Fill(eVerbose - 0.5, (Int_t)tc.fVerbose); - fBasePro->GetXaxis()->SetBinLabel(eVerboseForEachParticle, - "fVerboseForEachParticle"); // TBI 20240115 or use the full name tc.fVerboseForEachParticle ? + + fBasePro->GetXaxis()->SetBinLabel(eVerboseForEachParticle, "fVerboseForEachParticle"); fBasePro->Fill(eVerboseForEachParticle - 0.5, (Int_t)tc.fVerboseForEachParticle); - fBasePro->GetXaxis()->SetBinLabel(eUseCCDB, "fUseCCDB"); // TBI 20240115 or use the full name tc.fUseCCDB ? + + fBasePro->GetXaxis()->SetBinLabel(eDoAdditionalInsanityChecks, "fDoAdditionalInsanityChecks"); + fBasePro->Fill(eDoAdditionalInsanityChecks - 0.5, (Int_t)tc.fDoAdditionalInsanityChecks); + + fBasePro->GetXaxis()->SetBinLabel(eUseCCDB, "fUseCCDB"); fBasePro->Fill(eUseCCDB - 0.5, (Int_t)tc.fUseCCDB); + fBasePro->GetXaxis()->SetBinLabel(eProcessRemainingEvents, "fProcessRemainingEvents"); + fBasePro->Fill(eProcessRemainingEvents - 0.5, (Int_t)tc.fProcessRemainingEvents); + + fBasePro->GetXaxis()->SetBinLabel(eWhatToProcess, + Form("WhatToProcess = %s", tc.fWhatToProcess.Data())); + + fBasePro->GetXaxis()->SetBinLabel(eRandomSeed, "fRandomSeed"); + fBasePro->Fill(eRandomSeed - 0.5, (Int_t)tc.fRandomSeed); + + fBasePro->GetXaxis()->SetBinLabel(eUseFisherYates, "fUseFisherYates"); + fBasePro->Fill(eUseFisherYates - 0.5, (Int_t)tc.fUseFisherYates); + + fBasePro->GetXaxis()->SetBinLabel(eFixedNumberOfRandomlySelectedTracks, "fFixedNumberOfRandomlySelectedTracks"); + fBasePro->Fill(eFixedNumberOfRandomlySelectedTracks - 0.5, (Int_t)tc.fFixedNumberOfRandomlySelectedTracks); + fBaseList->Add(fBasePro); } // void BookBaseList() @@ -105,6 +126,10 @@ void DefaultConfiguration() // identical to the internal definitions in MuPa-Configurables.h, the // settings in json file are silently ignored. + // c) Scientific notation is NOT supported in json file. E.g. if you have + // "cSelectedTracks_max": "1e3", + // that setting and ALL other ones in json are silently ignored. + if (tc.fVerbose) { LOGF(info, "\033[1;32m%s\033[0m", __PRETTY_FUNCTION__); } @@ -199,6 +224,10 @@ void DefaultBooking() ceh_a.fBookEventHistograms[eNumberOfEvents] = kTRUE; ceh_a.fBookEventHistograms[eTotalMultiplicity] = kTRUE; ceh_a.fBookEventHistograms[eSelectedTracks] = kTRUE; + ceh_a.fBookEventHistograms[eMultFV0M] = kTRUE; + ceh_a.fBookEventHistograms[eMultFT0M] = kTRUE; + ceh_a.fBookEventHistograms[eMultTPC] = kTRUE; + ceh_a.fBookEventHistograms[eMultNTracksPV] = kTRUE; ceh_a.fBookEventHistograms[eCentrality] = kTRUE; ceh_a.fBookEventHistograms[eVertex_x] = kTRUE; ceh_a.fBookEventHistograms[eVertex_y] = kTRUE; @@ -252,10 +281,26 @@ void DefaultBinning() ceh_a.fEventHistogramsBins[eSelectedTracks][0] = 10000; ceh_a.fEventHistogramsBins[eSelectedTracks][1] = 0.; ceh_a.fEventHistogramsBins[eSelectedTracks][2] = 10000.; + // ... TBI 20240120 + ceh_a.fEventHistogramsBins[eMultFV0M][0] = 10000; + ceh_a.fEventHistogramsBins[eMultFV0M][1] = 0.; + ceh_a.fEventHistogramsBins[eMultFV0M][2] = 10000.; + // ... TBI 20240120 + ceh_a.fEventHistogramsBins[eMultFT0M][0] = 10000; + ceh_a.fEventHistogramsBins[eMultFT0M][1] = 0.; + ceh_a.fEventHistogramsBins[eMultFT0M][2] = 10000.; + // ... TBI 20240120 + ceh_a.fEventHistogramsBins[eMultTPC][0] = 10000; + ceh_a.fEventHistogramsBins[eMultTPC][1] = 0.; + ceh_a.fEventHistogramsBins[eMultTPC][2] = 10000.; + // ... TBI 20240120 + ceh_a.fEventHistogramsBins[eMultNTracksPV][0] = 10000; + ceh_a.fEventHistogramsBins[eMultNTracksPV][1] = 0.; + ceh_a.fEventHistogramsBins[eMultNTracksPV][2] = 10000.; // task->SetEventHistogramsBins("Centrality",100,0.,100.); - ceh_a.fEventHistogramsBins[eCentrality][0] = 100; + ceh_a.fEventHistogramsBins[eCentrality][0] = 110; // intentionally, because if centrality is not determined, it's set to 105.0 at the moment ceh_a.fEventHistogramsBins[eCentrality][1] = 0.; - ceh_a.fEventHistogramsBins[eCentrality][2] = 100.; + ceh_a.fEventHistogramsBins[eCentrality][2] = 110.; // task->SetEventHistogramsBins("Vertex_x",1000,-20.,20.); ceh_a.fEventHistogramsBins[eVertex_x][0] = 1000; ceh_a.fEventHistogramsBins[eVertex_x][1] = -20.; @@ -367,8 +412,6 @@ void CastStringIntoArray(Int_t AFO) TObjArray* oa = rh_a.fResultsHistogramsVariableLengthBinsString[AFO].Tokenize(","); if (!oa) { LOGF(fatal, "in function \033[1;31m%s at line %d \n fResultsHistogramsVariableLengthBinsString[AFO] = %s\033[0m", __PRETTY_FUNCTION__, __LINE__, rh_a.fResultsHistogramsVariableLengthBinsString[AFO].Data()); - cout << __LINE__ << endl; - exit(1); } Int_t nEntries = oa->GetEntries(); rh_a.fResultsHistogramsVariableLengthBins[AFO] = new TArrayD(nEntries); @@ -604,7 +647,7 @@ void BookEventHistograms() // b) Book specific control event histograms: TString stype[eEventHistograms_N] = { - "NumberOfEvents", "TotalMultiplicity", "SelectedTracks", + "NumberOfEvents", "TotalMultiplicity", "SelectedTracks", "MultFV0M", "MultFT0M", "MultTPC", "MultNTracksPV", "Centrality", "Vertex_x", "Vertex_y", "Vertex_z", "NContributors", "ImpactParameter"}; // keep in sync. with enum eEventHistograms TString srs[2] = {"rec", "sim"}; @@ -745,7 +788,8 @@ void BookCorrelationsHistograms() // a) Book the profile holding flags; // b) Common local labels; - // c) Histograms. + // c) Histograms; + // d) Few quick insanity checks on booking. if (tc.fVerbose) { LOGF(info, "\033[1;32m%s\033[0m", __PRETTY_FUNCTION__); @@ -778,7 +822,7 @@ void BookCorrelationsHistograms() // c) Histograms: for (Int_t k = 0; k < 4; k++) // order [2p=0,4p=1,6p=2,8p=3] { - for (Int_t n = 0; n < 6; n++) // harmonic [n=1,n=2,...,n=6] + for (Int_t n = 0; n < gMaxHarmonic; n++) // harmonic { for (Int_t v = 0; v < eAsFunctionOf_N; v++) // variable [0=integrated,1=vs. multiplicity,2=vs. centrality,3=pt,4=eta] @@ -798,8 +842,16 @@ void BookCorrelationsHistograms() c_a.fCorrelationsPro[k][n][v]->GetYaxis()->SetTitle(Form("#LT#LTcos[%s(%s)]#GT#GT", 1 == n + 1 ? "" : Form("%d", n + 1), oVariable[k].Data())); fCorrelationsList->Add(c_a.fCorrelationsPro[k][n][v]); } - } - } // for (Int_t k = 0; k < 4; k++) // order [2p=0,4p=1,6p=2,8p=3] + } // for (Int_t n = 0; n < gMaxHarmonic; n++) // harmonic + } // for (Int_t k = 0; k < 4; k++) // order [2p=0,4p=1,6p=2,8p=3] + + // d) Few quick insanity checks on booking: + if (c_a.fCorrelationsPro[0][0][AFO_INTEGRATED] && !TString(c_a.fCorrelationsPro[0][0][AFO_INTEGRATED]->GetXaxis()->GetTitle()).EqualTo("integrated")) { + LOGF(fatal, "in function \033[1;31m%s at line %d\033[0m", __PRETTY_FUNCTION__, __LINE__); // ordering in enum eAsFunctionOf is not the same as in TString fResultsHistogramsXaxisTitle[eAsFunctionOf_N] + } + if (c_a.fCorrelationsPro[0][0][AFO_PT] && !TString(c_a.fCorrelationsPro[0][0][AFO_PT]->GetXaxis()->GetTitle()).EqualTo("p_{T}")) { + LOGF(fatal, "in function \033[1;31m%s at line %d\033[0m", __PRETTY_FUNCTION__, __LINE__); // ordering in enum eAsFunctionOf is not the same as in TString fResultsHistogramsXaxisTitle[eAsFunctionOf_N] + } } // BookCorrelationsHistograms() @@ -872,7 +924,9 @@ void BookNestedLoopsHistograms() // Book all nested loops histograms. // a) Book the profile holding flags; - // *) ... + // b) Common local labels (keep 'em in sync with BookCorrelationsHistograms()); + // c) Book what needs to be booked; + // d) Few quick insanity checks on booking. if (tc.fVerbose) { LOGF(info, "\033[1;32m%s\033[0m", __PRETTY_FUNCTION__); @@ -913,9 +967,10 @@ void BookNestedLoopsHistograms() "#varphi_{1}+#varphi_{2}+#varphi_{3}+#varphi_{4}-#varphi_{5}-#varphi_{6}-" "#varphi_{7}-#varphi_{8}"}; + // c) Book what needs to be booked: for (Int_t k = 0; k < 4; k++) // order [2p=0,4p=1,6p=2,8p=3] { - for (Int_t n = 0; n < 6; n++) // harmonic [n=1,n=2,...,n=6] + for (Int_t n = 0; n < gMaxHarmonic; n++) // harmonic { for (Int_t v = 0; v < eAsFunctionOf_N; v++) // variable [0=integrated,1=vs. multiplicity,2=vs. centrality,3=pt,4=eta] @@ -958,8 +1013,16 @@ void BookNestedLoopsHistograms() fNestedLoopsList->Add(nl_a.fNestedLoopsPro[k][n][v]); } // for(Int_t v=0;v<5;v++) // variable [0=integrated,1=vs. // multiplicity,2=vs. centrality] - } // for(Int_t n=0;n<6;n++) // harmonic [n=1,n=2,...,n=6] - } // for(Int_t n=0;n<6;n++) // harmonics [n=1,n=2,...,n=6] + } // for (Int_t n = 0; n < gMaxHarmonic; n++) // harmonic + } // for (Int_t k = 0; k < 4; k++) // order [2p=0,4p=1,6p=2,8p=3] + + // d) Few quick insanity checks on booking: + if (nl_a.fNestedLoopsPro[0][0][AFO_INTEGRATED] && !TString(nl_a.fNestedLoopsPro[0][0][AFO_INTEGRATED]->GetXaxis()->GetTitle()).EqualTo("integrated")) { + LOGF(fatal, "in function \033[1;31m%s at line %d\033[0m", __PRETTY_FUNCTION__, __LINE__); // ordering in enum eAsFunctionOf is not the same as in TString fResultsHistogramsXaxisTitle[eAsFunctionOf_N] + } + if (nl_a.fNestedLoopsPro[0][0][AFO_PT] && !TString(nl_a.fNestedLoopsPro[0][0][AFO_PT]->GetXaxis()->GetTitle()).EqualTo("p_{T}")) { + LOGF(fatal, "in function \033[1;31m%s at line %d\033[0m", __PRETTY_FUNCTION__, __LINE__); // ordering in enum eAsFunctionOf is not the same as in TString fResultsHistogramsXaxisTitle[eAsFunctionOf_N] + } } // void BookNestedLoopsHistograms() @@ -971,8 +1034,9 @@ void BookTest0Histograms() // a) Book the profile holding flags; // b) Book placeholder and make sure all labels are stored in the placeholder; - // c) Retreive labels from placeholder; - // d) Book what needs to be booked. + // c) Retrieve labels from placeholder; + // d) Book what needs to be booked; + // e) Few quick insanity checks on booking. if (tc.fVerbose) { LOGF(info, "\033[1;32m%s\033[0m", __PRETTY_FUNCTION__); @@ -996,7 +1060,7 @@ void BookTest0Histograms() fTest0List->Add(fTest0LabelsPlaceholder); } - // c) Retreive labels from placeholder: + // c) Retrieve labels from placeholder: if (!(this->RetrieveCorrelationsLabels())) { LOGF(fatal, "in function \033[1;31m%s at line %d\033[0m", __PRETTY_FUNCTION__, __LINE__); @@ -1041,6 +1105,14 @@ void BookTest0Histograms() } // for(Int_t mi=0;miGetXaxis()->GetTitle()).EqualTo("integrated")) { + LOGF(fatal, "in function \033[1;31m%s at line %d\033[0m", __PRETTY_FUNCTION__, __LINE__); // ordering in enum eAsFunctionOf is not the same as in TString fResultsHistogramsXaxisTitle[eAsFunctionOf_N] + } + if (t0_a.fTest0Pro[0][0][AFO_PT] && !TString(t0_a.fTest0Pro[0][0][AFO_PT]->GetXaxis()->GetTitle()).EqualTo("p_{T}")) { + LOGF(fatal, "in function \033[1;31m%s at line %d\033[0m", __PRETTY_FUNCTION__, __LINE__); // ordering in enum eAsFunctionOf is not the same as in TString fResultsHistogramsXaxisTitle[eAsFunctionOf_N] + } + } // void BookTest0Histograms() //============================================================ @@ -1173,7 +1245,7 @@ void ResetEventByEventQuantities() fSelectedTracks = 0; fCentrality = 0; - // c) Q-vectors: + // b) Q-vectors: if (fCalculateQvector) { ResetQ(); // generic Q-vector for (Int_t h = 0; h < gMaxHarmonic * gMaxCorrelator + 1; h++) { @@ -1184,7 +1256,7 @@ void ResetEventByEventQuantities() } } // if(fCalculateQvector) - // d) Reset ebe containers for nested loops: + // c) Reset ebe containers for nested loops: if (fCalculateNestedLoops || fCalculateCustomNestedLoop) { if (nl_a.ftaNestedLoops[0]) { nl_a.ftaNestedLoops[0]->Reset(); @@ -1198,7 +1270,13 @@ void ResetEventByEventQuantities() } // if(fCalculateNestedLoops||fCalculateCustomNestedLoop) - // ... TBI 20220809 port the rest ... + // d) Fisher-Yates algorithm: + if (tc.fUseFisherYates) { + delete tc.fRandomIndices; + tc.fRandomIndices = NULL; + } + + // ... TBI 20240117 port the rest ... } // void ResetEventByEventQuantities() @@ -1322,6 +1400,11 @@ void FillEventHistograms(T1 const& collision, T2 const& tracks, eBeforeAfter ba) ceh_a.fEventHistograms[eNContributors][eRec][ba]->Fill(collision.numContrib()); ceh_a.fEventHistograms[eTotalMultiplicity][eRec][ba]->Fill(tracks.size()); // TBI 20231106 check and validate further ceh_a.fEventHistograms[eSelectedTracks][eRec][ba]->Fill(fSelectedTracks); // TBI 20240108 this one makes sense only for eAfter + ceh_a.fEventHistograms[eMultFT0M][eRec][ba]->Fill(collision.multFT0M()); + ceh_a.fEventHistograms[eMultFV0M][eRec][ba]->Fill(collision.multFV0M()); + ceh_a.fEventHistograms[eMultTPC][eRec][ba]->Fill(collision.multTPC()); + ceh_a.fEventHistograms[eMultNTracksPV][eRec][ba]->Fill(collision.multNTracksPV()); + ceh_a.fEventHistograms[eCentrality][eRec][ba]->Fill(fCentrality); // TBI 20240120 for the time being, I fill only default centrality // ... and corresponding MC truth simulated ( see https://github.com/AliceO2Group/O2Physics/blob/master/Tutorials/src/mcHistograms.cxx ): if constexpr (rs == eRecAndSim) { @@ -1335,6 +1418,8 @@ void FillEventHistograms(T1 const& collision, T2 const& tracks, eBeforeAfter ba) ceh_a.fEventHistograms[eVertex_z][eSim][ba]->Fill(collision.mcCollision().posZ()); // ceh_a.fEventHistograms[eTotalMultiplicity][eSim][ba]->Fill(tracks.size()); // TBI 20231106 check how to get corresponding MC truth info, and validate further // ceh_a.fEventHistograms[eSelectedTracks][eSim][ba]->Fill(fSelectedTracks); // TBI 20240108 this one makes sense only for eAfter + re-think if I really need it here + // TBI 20240120 eMultFT0M, ..., eMultNTracksPV are not needed here + // ceh_a.fEventHistograms[eCentrality][eSim][ba]->Fill(fCentrality); // TBI 20240120 this case is still not supported in DetermineCentrality() } // if constexpr (rs == eRecAndSim) { } // if constexpr (rs == eRec || rs == eRecAndSim) { @@ -1342,7 +1427,7 @@ void FillEventHistograms(T1 const& collision, T2 const& tracks, eBeforeAfter ba) if constexpr (rs == eSim) { ceh_a.fEventHistograms[eImpactParameter][eSim][ba]->Fill(collision.impactParameter()); // yes, because in this branch 'collision' is always aod::McCollision ceh_a.fEventHistograms[eSelectedTracks][eSim][ba]->Fill(fSelectedTracks); // TBI 20240108 this one makes sense only for eAfter - + // ceh_a.fEventHistograms[eCentrality][eSim][ba]->Fill(fCentrality); // TBI 20240120 this case is still not supported in DetermineCentrality() // ceh_a.fEventHistograms[eTotalMultiplicity][eSim][ba]->Fill(tracks.size()); // TBI 20231030 check further how to use the same thing for 'sim' } // if constexpr (rs == eSim) { @@ -1524,13 +1609,17 @@ void CalculateCorrelations() */ // integrated: - if (c_a.fCorrelationsPro[0][h - 1][0]) { - c_a.fCorrelationsPro[0][h - 1][0]->Fill(0.5, twoC, wTwo); + if (c_a.fCorrelationsPro[0][h - 1][AFO_INTEGRATED]) { + c_a.fCorrelationsPro[0][h - 1][AFO_INTEGRATED]->Fill(0.5, twoC, wTwo); } // vs. multiplicity: - // if(c_a.fCorrelationsPro[0][h-1][1]){c_a.fCorrelationsPro[0][h-1][1]->Fill(fSelectedTracks+0.5,twoC,wTwo);} + if (c_a.fCorrelationsPro[0][h - 1][AFO_MULTIPLICITY]) { + c_a.fCorrelationsPro[0][h - 1][AFO_MULTIPLICITY]->Fill(fSelectedTracks + 0.5, twoC, wTwo); + } // vs. centrality: - // if(c_a.fCorrelationsPro[0][h-1][2]){c_a.fCorrelationsPro[0][h-1][2]->Fill(fCentrality,twoC,wTwo);} + if (c_a.fCorrelationsPro[0][h - 1][AFO_CENTRALITY]) { + c_a.fCorrelationsPro[0][h - 1][AFO_CENTRALITY]->Fill(fCentrality, twoC, wTwo); + } // 4p: if (fSelectedTracks < 4) { @@ -1571,18 +1660,125 @@ void CalculateCorrelations() // TMath::Abs(fInternalValidationAmplitudes->GetAt(h-1))>0.){fourC/=pow(fInternalValidationAmplitudes->GetAt(h-1),4.);} // integrated: - if (c_a.fCorrelationsPro[1][h - 1][0]) { - c_a.fCorrelationsPro[1][h - 1][0]->Fill(0.5, fourC, wFour); + if (c_a.fCorrelationsPro[1][h - 1][AFO_INTEGRATED]) { + c_a.fCorrelationsPro[1][h - 1][AFO_INTEGRATED]->Fill(0.5, fourC, wFour); + } + // vs. multiplicity: + if (c_a.fCorrelationsPro[1][h - 1][AFO_MULTIPLICITY]) { + c_a.fCorrelationsPro[1][h - 1][AFO_MULTIPLICITY]->Fill(fSelectedTracks + 0.5, fourC, wFour); + } + // vs. centrality: + if (c_a.fCorrelationsPro[1][h - 1][AFO_CENTRALITY]) { + c_a.fCorrelationsPro[1][h - 1][AFO_CENTRALITY]->Fill(fCentrality, fourC, wFour); } - /* - if(fCorrelationsPro[1][h-1][AFO_MULTIPLICITY]){fCorrelationsPro[1][h-1][AFO_MULTIPLICITY]->Fill(fSelectedTracks+0.5,fourC,wFour);} - // vs. centrality: - if(fCorrelationsPro[1][h-1][AFO_CENTRALITY]){fCorrelationsPro[1][h-1][AFO_CENTRALITY]->Fill(fCentrality,fourC,wFour);} - */ + // 6p: + if (fSelectedTracks < 6) { + continue; + } // yes, continue, because I can still calculate 2-p and 4-p in other harmonics! + if (tc.fVerbose) { + LOGF(info, "\033[1;32m%s => calculating 6-particle correlations....\033[0m", __PRETTY_FUNCTION__); + } + TComplex six = Six(h, h, h, -h, -h, -h); + Double_t sixC = six.Re(); // cos + // Double_t sixS = six.Im(); // sin + Double_t wSix = Six(0, 0, 0, 0, 0, 0).Re(); // Weight is 'number of combinations' by default TBI_20210515 add support for other weights + if (wSix > 0.0) { + sixC /= wSix; + } else { + LOGF(fatal, "In function \033[1;31m%s at line %d, wSix = %f <=0. fSelectedTracks = %d\033[0m", __PRETTY_FUNCTION__, __LINE__, wSix, fSelectedTracks); + // TBI 20240110 shall I 'continue' here, instead of bailing out? + } + + if (fCalculateCustomNestedLoop) { + // e-b-e sanity check: + TArrayI* harmonics = new TArrayI(6); + harmonics->SetAt(h, 0); + harmonics->SetAt(h, 1); + harmonics->SetAt(h, 2); + harmonics->SetAt(-h, 3); + harmonics->SetAt(-h, 4); + harmonics->SetAt(-h, 5); + Double_t nestedLoopValue = this->CalculateCustomNestedLoop(harmonics); + if (TMath::Abs(nestedLoopValue) > 0. && TMath::Abs(sixC - nestedLoopValue) > 1.e-5) { + LOGF(fatal, "in function \033[1;31m%s at line %d, nestedLoopValue = %f is not the same as sixC = %f\033[0m", __PRETTY_FUNCTION__, __LINE__, nestedLoopValue, sixC); + } else { + LOGF(info, "=> e-b-e check with CustomNestedLoop is OK for isotropic 6-p, harmonic %d", h); + } + delete harmonics; + harmonics = NULL; + } // if(fCalculateCustomNestedLoop) + + // if(fUseInternalValidation && fInternalValidationAmplitudes && fRescaleWithTheoreticalInput && + // TMath::Abs(fInternalValidationAmplitudes->GetAt(h-1))>0.){sixC/=pow(fInternalValidationAmplitudes->GetAt(h-1),4.);} + + // integrated: + if (c_a.fCorrelationsPro[2][h - 1][AFO_INTEGRATED]) { + c_a.fCorrelationsPro[2][h - 1][AFO_INTEGRATED]->Fill(0.5, sixC, wSix); + } + // vs. multiplicity: + if (c_a.fCorrelationsPro[2][h - 1][AFO_MULTIPLICITY]) { + c_a.fCorrelationsPro[2][h - 1][AFO_MULTIPLICITY]->Fill(fSelectedTracks + 0.5, sixC, wSix); + } + // vs. centrality: + if (c_a.fCorrelationsPro[2][h - 1][AFO_CENTRALITY]) { + c_a.fCorrelationsPro[2][h - 1][AFO_CENTRALITY]->Fill(fCentrality, sixC, wSix); + } - // TBC 6-p and 8-p + // 8p: + if (fSelectedTracks < 8) { + continue; + } // yes, continue, because I can still calculate 2-p, 4-p and 6-p in other harmonics! + if (tc.fVerbose) { + LOGF(info, "\033[1;32m%s => calculating 8-particle correlations....\033[0m", __PRETTY_FUNCTION__); + } + TComplex eight = Eight(h, h, h, h, -h, -h, -h, -h); + Double_t eightC = eight.Re(); // cos + // Double_t eightS = eight.Im(); // sin + Double_t wEight = Eight(0, 0, 0, 0, 0, 0, 0, 0).Re(); // Weight is 'number of combinations' by default TBI_20210515 add support for other weights + if (wEight > 0.0) { + eightC /= wEight; + } else { + LOGF(fatal, "In function \033[1;31m%s at line %d, wEight = %f <=0. fSelectedTracks = %d\033[0m", __PRETTY_FUNCTION__, __LINE__, wEight, fSelectedTracks); + // TBI 20240110 shall I 'continue' here, instead of bailing out? + } + if (fCalculateCustomNestedLoop) { + // e-b-e sanity check: + TArrayI* harmonics = new TArrayI(8); + harmonics->SetAt(h, 0); + harmonics->SetAt(h, 1); + harmonics->SetAt(h, 2); + harmonics->SetAt(h, 3); + harmonics->SetAt(-h, 4); + harmonics->SetAt(-h, 5); + harmonics->SetAt(-h, 6); + harmonics->SetAt(-h, 7); + Double_t nestedLoopValue = this->CalculateCustomNestedLoop(harmonics); + if (TMath::Abs(nestedLoopValue) > 0. && TMath::Abs(eightC - nestedLoopValue) > 1.e-5) { + LOGF(fatal, "in function \033[1;31m%s at line %d, nestedLoopValue = %f is not the same as eightC = %f\033[0m", __PRETTY_FUNCTION__, __LINE__, nestedLoopValue, eightC); + } else { + LOGF(info, "=> e-b-e check with CustomNestedLoop is OK for isotropic 8-p, harmonic %d", h); + } + delete harmonics; + harmonics = NULL; + } // if(fCalculateCustomNestedLoop) + + // if(fUseInternalValidation && fInternalValidationAmplitudes && fRescaleWithTheoreticalInput && + // TMath::Abs(fInternalValidationAmplitudes->GetAt(h-1))>0.){eightC/=pow(fInternalValidationAmplitudes->GetAt(h-1),4.);} + + // integrated: + if (c_a.fCorrelationsPro[3][h - 1][AFO_INTEGRATED]) { + c_a.fCorrelationsPro[3][h - 1][AFO_INTEGRATED]->Fill(0.5, eightC, wEight); + } + // vs. multiplicity: + if (c_a.fCorrelationsPro[3][h - 1][AFO_MULTIPLICITY]) { + c_a.fCorrelationsPro[3][h - 1][AFO_MULTIPLICITY]->Fill(fSelectedTracks + 0.5, eightC, wEight); + } + // vs. centrality: + if (c_a.fCorrelationsPro[3][h - 1][AFO_CENTRALITY]) { + c_a.fCorrelationsPro[3][h - 1][AFO_CENTRALITY]->Fill(fCentrality, eightC, wEight); + } } // for(Int_t h=1;h<=gMaxHarmonic;h++) // harmonic // c) Flush the generic Q-vectors: @@ -1679,55 +1875,69 @@ void CalculateTest0() weight = Four(0, 0, 0, 0).Re(); break; - /* - case 5: - if(fSelectedTracks<5){return;} - correlation = Five(n[0],n[1],n[2],n[3],n[4]).Re(); - weight = Five(0,0,0,0,0).Re(); - break; - - case 6: - if(fSelectedTracks<6){return;} - correlation = Six(n[0],n[1],n[2],n[3],n[4],n[5]).Re(); - weight = Six(0,0,0,0,0,0).Re(); - break; - - case 7: - if(fSelectedTracks<7){return;} - correlation = Seven(n[0],n[1],n[2],n[3],n[4],n[5],n[6]).Re(); - weight = Seven(0,0,0,0,0,0,0).Re(); - break; - - case 8: - if(fSelectedTracks<8){return;} - correlation = Eight(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]).Re(); - weight = Eight(0,0,0,0,0,0,0,0).Re(); - break; - - case 9: - if(fSelectedTracks<9){return;} - correlation = Nine(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8]).Re(); - weight = Nine(0,0,0,0,0,0,0,0,0).Re(); - break; - - case 10: - if(fSelectedTracks<10){return;} - correlation = Ten(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],n[9]).Re(); - weight = Ten(0,0,0,0,0,0,0,0,0,0).Re(); - break; - - case 11: - if(fSelectedTracks<11){return;} - correlation = Eleven(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],n[9],n[10]).Re(); - weight = Eleven(0,0,0,0,0,0,0,0,0,0,0).Re(); - break; - - case 12: - if(fSelectedTracks<12){return;} - correlation = Twelve(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8],n[9],n[10],n[11]).Re(); - weight = Twelve(0,0,0,0,0,0,0,0,0,0,0,0).Re(); - break; - */ + case 5: + if (fSelectedTracks < 5) { + return; + } + correlation = Five(n[0], n[1], n[2], n[3], n[4]).Re(); + weight = Five(0, 0, 0, 0, 0).Re(); + break; + + case 6: + if (fSelectedTracks < 6) { + return; + } + correlation = Six(n[0], n[1], n[2], n[3], n[4], n[5]).Re(); + weight = Six(0, 0, 0, 0, 0, 0).Re(); + break; + + case 7: + if (fSelectedTracks < 7) { + return; + } + correlation = Seven(n[0], n[1], n[2], n[3], n[4], n[5], n[6]).Re(); + weight = Seven(0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 8: + if (fSelectedTracks < 8) { + return; + } + correlation = Eight(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7]).Re(); + weight = Eight(0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 9: + if (fSelectedTracks < 9) { + return; + } + correlation = Nine(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8]).Re(); + weight = Nine(0, 0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 10: + if (fSelectedTracks < 10) { + return; + } + correlation = Ten(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9]).Re(); + weight = Ten(0, 0, 0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 11: + if (fSelectedTracks < 11) { + return; + } + correlation = Eleven(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9], n[10]).Re(); + weight = Eleven(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; + + case 12: + if (fSelectedTracks < 12) { + return; + } + correlation = Twelve(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], n[8], n[9], n[10], n[11]).Re(); + weight = Twelve(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).Re(); + break; default: LOGF(fatal, "in function \033[1;31m%s at line %d\n Not supported yet: %s \n\n\033[0m", __PRETTY_FUNCTION__, __LINE__, t0_a.fTest0Labels[mo][mi]->Data()); @@ -1774,17 +1984,17 @@ void CalculateTest0() // Finally, fill: // integrated: - if (t0_a.fTest0Pro[mo][mi][0]) // TBI 20240110 replace 0 with new enum AFO_INTEGRATED, also in the lines below - { - t0_a.fTest0Pro[mo][mi][0]->Fill(0.5, correlation / weight, weight); + if (t0_a.fTest0Pro[mo][mi][AFO_INTEGRATED]) { + t0_a.fTest0Pro[mo][mi][AFO_INTEGRATED]->Fill(0.5, correlation / weight, weight); } - /* // vs. multiplicity: - if(fTest0Pro[mo][mi][AFO_MULTIPLICITY]){fTest0Pro[mo][mi][AFO_MULTIPLICITY]->Fill(fSelectedTracks+0.5,correlation/weight,weight);} + if (t0_a.fTest0Pro[mo][mi][AFO_MULTIPLICITY]) { + t0_a.fTest0Pro[mo][mi][AFO_MULTIPLICITY]->Fill(fSelectedTracks + 0.5, correlation / weight, weight); + } // vs. centrality: - if(fTest0Pro[mo][mi][AFO_CENTRALITY]){fTest0Pro[mo][mi][AFO_CENTRALITY]->Fill(fCentrality,correlation/weight,weight);} - */ - + if (t0_a.fTest0Pro[mo][mi][AFO_CENTRALITY]) { + t0_a.fTest0Pro[mo][mi][AFO_CENTRALITY]->Fill(fCentrality, correlation / weight, weight); + } } // if(fTest0Labels[mo][mi]) } // for(Int_t mi=0;miFill( + if (nl_a.fNestedLoopsPro[0][h][AFO_INTEGRATED]) { + nl_a.fNestedLoopsPro[0][h][AFO_INTEGRATED]->Fill( 0.5, TMath::Cos((h + 1.) * (dPhi1 - dPhi2)), dW1 * dW2); } - // fill cos, 2p, vs. M: - if (nl_a.fNestedLoopsPro[0][h][1]) { - nl_a.fNestedLoopsPro[0][h][1]->Fill( + // fill cos, 2p, vs. multiplicity: + if (nl_a.fNestedLoopsPro[0][h][AFO_MULTIPLICITY]) { + nl_a.fNestedLoopsPro[0][h][AFO_MULTIPLICITY]->Fill( fSelectedTracks + 0.5, TMath::Cos((h + 1.) * (dPhi1 - dPhi2)), dW1 * dW2); } // fill cos, 2p, vs. centrality: - if (nl_a.fNestedLoopsPro[0][h][2]) { - nl_a.fNestedLoopsPro[0][h][2]->Fill( + if (nl_a.fNestedLoopsPro[0][h][AFO_CENTRALITY]) { + nl_a.fNestedLoopsPro[0][h][AFO_CENTRALITY]->Fill( fCentrality, TMath::Cos((h + 1.) * (dPhi1 - dPhi2)), dW1 * dW2); } } // for(int h=1; h<=6; h++) } // for(int i2=0; i2GetAt(i1); + Double_t dW1 = nl_a.ftaNestedLoops[1]->GetAt(i1); + for (int i2 = 0; i2 < nParticles; i2++) { + if (i2 == i1) { + continue; + } + Double_t dPhi2 = nl_a.ftaNestedLoops[0]->GetAt(i2); + Double_t dW2 = nl_a.ftaNestedLoops[1]->GetAt(i2); + for (int i3 = 0; i3 < nParticles; i3++) { + if (i3 == i1 || i3 == i2) { + continue; + } + Double_t dPhi3 = nl_a.ftaNestedLoops[0]->GetAt(i3); + Double_t dW3 = nl_a.ftaNestedLoops[1]->GetAt(i3); + for (int i4 = 0; i4 < nParticles; i4++) { + if (i4 == i1 || i4 == i2 || i4 == i3) { + continue; + } + Double_t dPhi4 = nl_a.ftaNestedLoops[0]->GetAt(i4); + Double_t dW4 = nl_a.ftaNestedLoops[1]->GetAt(i4); + for (int h = 0; h < gMaxHarmonic; h++) { + // fill cos, 4p, integreated: + if (nl_a.fNestedLoopsPro[1][h][AFO_INTEGRATED]) { + nl_a.fNestedLoopsPro[1][h][AFO_INTEGRATED]->Fill(0.5, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 - dPhi3 - dPhi4)), dW1 * dW2 * dW3 * dW4); + } + // fill cos, 4p, all harmonics, vs. M: + if (nl_a.fNestedLoopsPro[1][h][AFO_MULTIPLICITY]) { + nl_a.fNestedLoopsPro[1][h][AFO_MULTIPLICITY]->Fill(fSelectedTracks + 0.5, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 - dPhi3 - dPhi4)), dW1 * dW2 * dW3 * dW4); + } + // fill cos, 4p, all harmonics, vs. centrality: + if (nl_a.fNestedLoopsPro[1][h][AFO_CENTRALITY]) { + nl_a.fNestedLoopsPro[1][h][AFO_CENTRALITY]->Fill(fCentrality, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 - dPhi3 - dPhi4)), dW1 * dW2 * dW3 * dW4); + } + } // for(int h=0; hGetAt(i1); + Double_t dW1 = nl_a.ftaNestedLoops[1]->GetAt(i1); + for (int i2 = 0; i2 < nParticles; i2++) { + if (i2 == i1) { + continue; + } + Double_t dPhi2 = nl_a.ftaNestedLoops[0]->GetAt(i2); + Double_t dW2 = nl_a.ftaNestedLoops[1]->GetAt(i2); + for (int i3 = 0; i3 < nParticles; i3++) { + if (i3 == i1 || i3 == i2) { + continue; + } + Double_t dPhi3 = nl_a.ftaNestedLoops[0]->GetAt(i3); + Double_t dW3 = nl_a.ftaNestedLoops[1]->GetAt(i3); + for (int i4 = 0; i4 < nParticles; i4++) { + if (i4 == i1 || i4 == i2 || i4 == i3) { + continue; + } + Double_t dPhi4 = nl_a.ftaNestedLoops[0]->GetAt(i4); + Double_t dW4 = nl_a.ftaNestedLoops[1]->GetAt(i4); + for (int i5 = 0; i5 < nParticles; i5++) { + if (i5 == i1 || i5 == i2 || i5 == i3 || i5 == i4) { + continue; + } + Double_t dPhi5 = nl_a.ftaNestedLoops[0]->GetAt(i5); + Double_t dW5 = nl_a.ftaNestedLoops[1]->GetAt(i5); + for (int i6 = 0; i6 < nParticles; i6++) { + if (i6 == i1 || i6 == i2 || i6 == i3 || i6 == i4 || i6 == i5) { + continue; + } + Double_t dPhi6 = nl_a.ftaNestedLoops[0]->GetAt(i6); + Double_t dW6 = nl_a.ftaNestedLoops[1]->GetAt(i6); + for (int h = 0; h < gMaxHarmonic; h++) { + // fill cos, 6p, integreated: + if (nl_a.fNestedLoopsPro[2][h][AFO_INTEGRATED]) { + nl_a.fNestedLoopsPro[2][h][AFO_INTEGRATED]->Fill(0.5, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 - dPhi4 - dPhi5 - dPhi6)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6); + } + // fill cos, 6p, all harmonics, vs. M: + if (nl_a.fNestedLoopsPro[2][h][AFO_MULTIPLICITY]) { + nl_a.fNestedLoopsPro[2][h][AFO_MULTIPLICITY]->Fill(fSelectedTracks + 0.5, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 - dPhi4 - dPhi5 - dPhi6)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6); + } + // fill cos, 6p, all harmonics, vs. M: + if (nl_a.fNestedLoopsPro[2][h][AFO_CENTRALITY]) { + nl_a.fNestedLoopsPro[2][h][AFO_CENTRALITY]->Fill(fCentrality, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 - dPhi4 - dPhi5 - dPhi6)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6); + } + } // for(int h=0; hGetAt(i1); + Double_t dW1 = nl_a.ftaNestedLoops[1]->GetAt(i1); + for (int i2 = 0; i2 < nParticles; i2++) { + if (i2 == i1) { + continue; + } + Double_t dPhi2 = nl_a.ftaNestedLoops[0]->GetAt(i2); + Double_t dW2 = nl_a.ftaNestedLoops[1]->GetAt(i2); + for (int i3 = 0; i3 < nParticles; i3++) { + if (i3 == i1 || i3 == i2) { + continue; + } + Double_t dPhi3 = nl_a.ftaNestedLoops[0]->GetAt(i3); + Double_t dW3 = nl_a.ftaNestedLoops[1]->GetAt(i3); + for (int i4 = 0; i4 < nParticles; i4++) { + if (i4 == i1 || i4 == i2 || i4 == i3) { + continue; + } + Double_t dPhi4 = nl_a.ftaNestedLoops[0]->GetAt(i4); + Double_t dW4 = nl_a.ftaNestedLoops[1]->GetAt(i4); + for (int i5 = 0; i5 < nParticles; i5++) { + if (i5 == i1 || i5 == i2 || i5 == i3 || i5 == i4) { + continue; + } + Double_t dPhi5 = nl_a.ftaNestedLoops[0]->GetAt(i5); + Double_t dW5 = nl_a.ftaNestedLoops[1]->GetAt(i5); + for (int i6 = 0; i6 < nParticles; i6++) { + if (i6 == i1 || i6 == i2 || i6 == i3 || i6 == i4 || i6 == i5) { + continue; + } + Double_t dPhi6 = nl_a.ftaNestedLoops[0]->GetAt(i6); + Double_t dW6 = nl_a.ftaNestedLoops[1]->GetAt(i6); + for (int i7 = 0; i7 < nParticles; i7++) { + if (i7 == i1 || i7 == i2 || i7 == i3 || i7 == i4 || i7 == i5 || i7 == i6) { + continue; + } + Double_t dPhi7 = nl_a.ftaNestedLoops[0]->GetAt(i7); + Double_t dW7 = nl_a.ftaNestedLoops[1]->GetAt(i7); + for (int i8 = 0; i8 < nParticles; i8++) { + if (i8 == i1 || i8 == i2 || i8 == i3 || i8 == i4 || i8 == i5 || i8 == i6 || i8 == i7) { + continue; + } + Double_t dPhi8 = nl_a.ftaNestedLoops[0]->GetAt(i8); + Double_t dW8 = nl_a.ftaNestedLoops[1]->GetAt(i8); + for (int h = 0; h < gMaxHarmonic; h++) { + // fill cos, 8p, integreated: + if (nl_a.fNestedLoopsPro[3][h][AFO_INTEGRATED]) { + nl_a.fNestedLoopsPro[3][h][AFO_INTEGRATED]->Fill(0.5, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 + dPhi4 - dPhi5 - dPhi6 - dPhi7 - dPhi8)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8); + } + // fill cos, 8p, all harmonics, vs. M: + if (nl_a.fNestedLoopsPro[3][h][AFO_MULTIPLICITY]) { + nl_a.fNestedLoopsPro[3][h][AFO_MULTIPLICITY]->Fill(fSelectedTracks + 0.5, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 + dPhi4 - dPhi5 - dPhi6 - dPhi7 - dPhi8)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8); + } + // fill cos, 8p, all harmonics, vs. M: + if (nl_a.fNestedLoopsPro[3][h][AFO_CENTRALITY]) { + nl_a.fNestedLoopsPro[3][h][AFO_CENTRALITY]->Fill(fCentrality, TMath::Cos((h + 1.) * (dPhi1 + dPhi2 + dPhi3 + dPhi4 - dPhi5 - dPhi6 - dPhi7 - dPhi8)), dW1 * dW2 * dW3 * dW4 * dW5 * dW6 * dW7 * dW8); + } + } // for(int h=0; hGetNbinsX(); - nBinsNL = nl_a.fNestedLoopsPro[0][0][0]->GetNbinsX(); - if (nBinsQV != nBinsNL) { - LOGF(fatal, "in function \033[1;31m%s at line %d\033[0m", - __PRETTY_FUNCTION__, __LINE__); - } - cout << endl; - cout << " [0] : integrated" << endl; - for (Int_t o = 0; o < 4; o++) { - cout << Form(" ==== <<%d>>-particle correlations ====", 2 * (o + 1)) - << endl; - for (Int_t h = 0; h < 6; h++) { - for (Int_t b = 1; b <= nBinsQV; b++) { - if (c_a.fCorrelationsPro[o][h][0]) { - valueQV = c_a.fCorrelationsPro[o][h][0]->GetBinContent(b); - } - if (nl_a.fNestedLoopsPro[o][h][0]) { - valueNL = nl_a.fNestedLoopsPro[o][h][0]->GetBinContent(b); - } - if (TMath::Abs(valueQV) > 0. && TMath::Abs(valueNL) > 0.) { - cout << Form(" h=%d, Q-vectors: ", h + 1) << valueQV << endl; - cout << Form(" h=%d, Nested loops: ", h + 1) << valueNL << endl; - if (TMath::Abs(valueQV - valueNL) > 1.e-5) { - LOGF(info, "\n\033[1;33m[%d][%d][%d] \033[0m\n", o, h, 0); - LOGF(fatal, "in function \033[1;31m%s at line %d\033[0m", - __PRETTY_FUNCTION__, __LINE__); + for (Int_t v = 0; v < 3; v++) { // TBI 20240116 this corresponds to the ordering of variables in enum eAsFunctionOf . Here (for the time being) I compare only int, mult. and cent. + // a) Integrated comparison: + nBinsQV = c_a.fCorrelationsPro[0][0][v]->GetNbinsX(); + nBinsNL = nl_a.fNestedLoopsPro[0][0][v]->GetNbinsX(); + if (nBinsQV != nBinsNL) { + LOGF(fatal, "in function \033[1;31m%s at line %d\033[0m", + __PRETTY_FUNCTION__, __LINE__); + } + LOGF(info, "\033[1;32m [%d] : %s\033[0m", v, rh_a.fResultsHistogramsXaxisTitle[v].Data()); + for (Int_t o = 0; o < 4; o++) { + LOGF(info, "\033[1;32m ==== <<%d>>-particle correlations ====\033[0m", 2 * (o + 1)); + for (Int_t h = 0; h < gMaxHarmonic; h++) { + for (Int_t b = 1; b <= nBinsQV; b++) { + if (c_a.fCorrelationsPro[o][h][v]) { + valueQV = c_a.fCorrelationsPro[o][h][v]->GetBinContent(b); } - } // if(TMath::Abs(valueQV)>0. && TMath::Abs(valueNL)>0.) - } // for(Int_t b=1;b<=nBinsQV;b++) - } // for(Int_t h=0;h<6;h++) - cout << endl; - } // for(Int_t o=0;o<4;o++) - - // TBI 20230530 port the rest, i.e. vs. multiplicity, centrality, etc. + if (nl_a.fNestedLoopsPro[o][h][v]) { + valueNL = nl_a.fNestedLoopsPro[o][h][v]->GetBinContent(b); + } + if (TMath::Abs(valueQV) > 0. && TMath::Abs(valueNL) > 0.) { + LOGF(info, " bin=%d, h=%d, Q-vectors: %f", b, h + 1, valueQV); + LOGF(info, " bin=%d, h=%d, Nested loops: %f", b, h + 1, valueNL); + if (TMath::Abs(valueQV - valueNL) > 1.e-5) { + LOGF(info, "\n\033[1;33m[%d][%d][%d] \033[0m\n", o, h, v); + LOGF(fatal, "in function \033[1;31m%s at line %d\033[0m", + __PRETTY_FUNCTION__, __LINE__); + } + } // if(TMath::Abs(valueQV)>0. && TMath::Abs(valueNL)>0.) + } // for(Int_t b=1;b<=nBinsQV;b++) + } // for(Int_t h=0;h<6;h++) + LOGF(info, ""); // new line + } // for(Int_t o=0;o<4;o++) + } // for (Int_t v = 0; v < 3; v++) } // void ComparisonNestedLoopsVsCorrelations() @@ -1993,6 +2377,156 @@ TComplex Four(Int_t n1, Int_t n2, Int_t n3, Int_t n4) //============================================================ +TComplex Five(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5) +{ + // Generic five-particle correlation . + + TComplex five = Q(n1, 1) * Q(n2, 1) * Q(n3, 1) * Q(n4, 1) * Q(n5, 1) - Q(n1 + n2, 2) * Q(n3, 1) * Q(n4, 1) * Q(n5, 1) - Q(n2, 1) * Q(n1 + n3, 2) * Q(n4, 1) * Q(n5, 1) - Q(n1, 1) * Q(n2 + n3, 2) * Q(n4, 1) * Q(n5, 1) + 2. * Q(n1 + n2 + n3, 3) * Q(n4, 1) * Q(n5, 1) - Q(n2, 1) * Q(n3, 1) * Q(n1 + n4, 2) * Q(n5, 1) + Q(n2 + n3, 2) * Q(n1 + n4, 2) * Q(n5, 1) - Q(n1, 1) * Q(n3, 1) * Q(n2 + n4, 2) * Q(n5, 1) + Q(n1 + n3, 2) * Q(n2 + n4, 2) * Q(n5, 1) + 2. * Q(n3, 1) * Q(n1 + n2 + n4, 3) * Q(n5, 1) - Q(n1, 1) * Q(n2, 1) * Q(n3 + n4, 2) * Q(n5, 1) + Q(n1 + n2, 2) * Q(n3 + n4, 2) * Q(n5, 1) + 2. * Q(n2, 1) * Q(n1 + n3 + n4, 3) * Q(n5, 1) + 2. * Q(n1, 1) * Q(n2 + n3 + n4, 3) * Q(n5, 1) - 6. * Q(n1 + n2 + n3 + n4, 4) * Q(n5, 1) - Q(n2, 1) * Q(n3, 1) * Q(n4, 1) * Q(n1 + n5, 2) + Q(n2 + n3, 2) * Q(n4, 1) * Q(n1 + n5, 2) + Q(n3, 1) * Q(n2 + n4, 2) * Q(n1 + n5, 2) + Q(n2, 1) * Q(n3 + n4, 2) * Q(n1 + n5, 2) - 2. * Q(n2 + n3 + n4, 3) * Q(n1 + n5, 2) - Q(n1, 1) * Q(n3, 1) * Q(n4, 1) * Q(n2 + n5, 2) + Q(n1 + n3, 2) * Q(n4, 1) * Q(n2 + n5, 2) + Q(n3, 1) * Q(n1 + n4, 2) * Q(n2 + n5, 2) + Q(n1, 1) * Q(n3 + n4, 2) * Q(n2 + n5, 2) - 2. * Q(n1 + n3 + n4, 3) * Q(n2 + n5, 2) + 2. * Q(n3, 1) * Q(n4, 1) * Q(n1 + n2 + n5, 3) - 2. * Q(n3 + n4, 2) * Q(n1 + n2 + n5, 3) - Q(n1, 1) * Q(n2, 1) * Q(n4, 1) * Q(n3 + n5, 2) + Q(n1 + n2, 2) * Q(n4, 1) * Q(n3 + n5, 2) + Q(n2, 1) * Q(n1 + n4, 2) * Q(n3 + n5, 2) + Q(n1, 1) * Q(n2 + n4, 2) * Q(n3 + n5, 2) - 2. * Q(n1 + n2 + n4, 3) * Q(n3 + n5, 2) + 2. * Q(n2, 1) * Q(n4, 1) * Q(n1 + n3 + n5, 3) - 2. * Q(n2 + n4, 2) * Q(n1 + n3 + n5, 3) + 2. * Q(n1, 1) * Q(n4, 1) * Q(n2 + n3 + n5, 3) - 2. * Q(n1 + n4, 2) * Q(n2 + n3 + n5, 3) - 6. * Q(n4, 1) * Q(n1 + n2 + n3 + n5, 4) - Q(n1, 1) * Q(n2, 1) * Q(n3, 1) * Q(n4 + n5, 2) + Q(n1 + n2, 2) * Q(n3, 1) * Q(n4 + n5, 2) + Q(n2, 1) * Q(n1 + n3, 2) * Q(n4 + n5, 2) + Q(n1, 1) * Q(n2 + n3, 2) * Q(n4 + n5, 2) - 2. * Q(n1 + n2 + n3, 3) * Q(n4 + n5, 2) + 2. * Q(n2, 1) * Q(n3, 1) * Q(n1 + n4 + n5, 3) - 2. * Q(n2 + n3, 2) * Q(n1 + n4 + n5, 3) + 2. * Q(n1, 1) * Q(n3, 1) * Q(n2 + n4 + n5, 3) - 2. * Q(n1 + n3, 2) * Q(n2 + n4 + n5, 3) - 6. * Q(n3, 1) * Q(n1 + n2 + n4 + n5, 4) + 2. * Q(n1, 1) * Q(n2, 1) * Q(n3 + n4 + n5, 3) - 2. * Q(n1 + n2, 2) * Q(n3 + n4 + n5, 3) - 6. * Q(n2, 1) * Q(n1 + n3 + n4 + n5, 4) - 6. * Q(n1, 1) * Q(n2 + n3 + n4 + n5, 4) + 24. * Q(n1 + n2 + n3 + n4 + n5, 5); + + return five; + +} // TComplex Five(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5) + +//============================================================ + +TComplex Six(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6) +{ + // Generic six-particle correlation . + + TComplex six = Q(n1, 1) * Q(n2, 1) * Q(n3, 1) * Q(n4, 1) * Q(n5, 1) * Q(n6, 1) - Q(n1 + n2, 2) * Q(n3, 1) * Q(n4, 1) * Q(n5, 1) * Q(n6, 1) - Q(n2, 1) * Q(n1 + n3, 2) * Q(n4, 1) * Q(n5, 1) * Q(n6, 1) - Q(n1, 1) * Q(n2 + n3, 2) * Q(n4, 1) * Q(n5, 1) * Q(n6, 1) + 2. * Q(n1 + n2 + n3, 3) * Q(n4, 1) * Q(n5, 1) * Q(n6, 1) - Q(n2, 1) * Q(n3, 1) * Q(n1 + n4, 2) * Q(n5, 1) * Q(n6, 1) + Q(n2 + n3, 2) * Q(n1 + n4, 2) * Q(n5, 1) * Q(n6, 1) - Q(n1, 1) * Q(n3, 1) * Q(n2 + n4, 2) * Q(n5, 1) * Q(n6, 1) + Q(n1 + n3, 2) * Q(n2 + n4, 2) * Q(n5, 1) * Q(n6, 1) + 2. * Q(n3, 1) * Q(n1 + n2 + n4, 3) * Q(n5, 1) * Q(n6, 1) - Q(n1, 1) * Q(n2, 1) * Q(n3 + n4, 2) * Q(n5, 1) * Q(n6, 1) + Q(n1 + n2, 2) * Q(n3 + n4, 2) * Q(n5, 1) * Q(n6, 1) + 2. * Q(n2, 1) * Q(n1 + n3 + n4, 3) * Q(n5, 1) * Q(n6, 1) + 2. * Q(n1, 1) * Q(n2 + n3 + n4, 3) * Q(n5, 1) * Q(n6, 1) - 6. * Q(n1 + n2 + n3 + n4, 4) * Q(n5, 1) * Q(n6, 1) - Q(n2, 1) * Q(n3, 1) * Q(n4, 1) * Q(n1 + n5, 2) * Q(n6, 1) + Q(n2 + n3, 2) * Q(n4, 1) * Q(n1 + n5, 2) * Q(n6, 1) + Q(n3, 1) * Q(n2 + n4, 2) * Q(n1 + n5, 2) * Q(n6, 1) + Q(n2, 1) * Q(n3 + n4, 2) * Q(n1 + n5, 2) * Q(n6, 1) - 2. * Q(n2 + n3 + n4, 3) * Q(n1 + n5, 2) * Q(n6, 1) - Q(n1, 1) * Q(n3, 1) * Q(n4, 1) * Q(n2 + n5, 2) * Q(n6, 1) + Q(n1 + n3, 2) * Q(n4, 1) * Q(n2 + n5, 2) * Q(n6, 1) + Q(n3, 1) * Q(n1 + n4, 2) * Q(n2 + n5, 2) * Q(n6, 1) + Q(n1, 1) * Q(n3 + n4, 2) * Q(n2 + n5, 2) * Q(n6, 1) - 2. * Q(n1 + n3 + n4, 3) * Q(n2 + n5, 2) * Q(n6, 1) + 2. * Q(n3, 1) * Q(n4, 1) * Q(n1 + n2 + n5, 3) * Q(n6, 1) - 2. * Q(n3 + n4, 2) * Q(n1 + n2 + n5, 3) * Q(n6, 1) - Q(n1, 1) * Q(n2, 1) * Q(n4, 1) * Q(n3 + n5, 2) * Q(n6, 1) + Q(n1 + n2, 2) * Q(n4, 1) * Q(n3 + n5, 2) * Q(n6, 1) + Q(n2, 1) * Q(n1 + n4, 2) * Q(n3 + n5, 2) * Q(n6, 1) + Q(n1, 1) * Q(n2 + n4, 2) * Q(n3 + n5, 2) * Q(n6, 1) - 2. * Q(n1 + n2 + n4, 3) * Q(n3 + n5, 2) * Q(n6, 1) + 2. * Q(n2, 1) * Q(n4, 1) * Q(n1 + n3 + n5, 3) * Q(n6, 1) - 2. * Q(n2 + n4, 2) * Q(n1 + n3 + n5, 3) * Q(n6, 1) + 2. * Q(n1, 1) * Q(n4, 1) * Q(n2 + n3 + n5, 3) * Q(n6, 1) - 2. * Q(n1 + n4, 2) * Q(n2 + n3 + n5, 3) * Q(n6, 1) - 6. * Q(n4, 1) * Q(n1 + n2 + n3 + n5, 4) * Q(n6, 1) - Q(n1, 1) * Q(n2, 1) * Q(n3, 1) * Q(n4 + n5, 2) * Q(n6, 1) + Q(n1 + n2, 2) * Q(n3, 1) * Q(n4 + n5, 2) * Q(n6, 1) + Q(n2, 1) * Q(n1 + n3, 2) * Q(n4 + n5, 2) * Q(n6, 1) + Q(n1, 1) * Q(n2 + n3, 2) * Q(n4 + n5, 2) * Q(n6, 1) - 2. * Q(n1 + n2 + n3, 3) * Q(n4 + n5, 2) * Q(n6, 1) + 2. * Q(n2, 1) * Q(n3, 1) * Q(n1 + n4 + n5, 3) * Q(n6, 1) - 2. * Q(n2 + n3, 2) * Q(n1 + n4 + n5, 3) * Q(n6, 1) + 2. * Q(n1, 1) * Q(n3, 1) * Q(n2 + n4 + n5, 3) * Q(n6, 1) - 2. * Q(n1 + n3, 2) * Q(n2 + n4 + n5, 3) * Q(n6, 1) - 6. * Q(n3, 1) * Q(n1 + n2 + n4 + n5, 4) * Q(n6, 1) + 2. * Q(n1, 1) * Q(n2, 1) * Q(n3 + n4 + n5, 3) * Q(n6, 1) - 2. * Q(n1 + n2, 2) * Q(n3 + n4 + n5, 3) * Q(n6, 1) - 6. * Q(n2, 1) * Q(n1 + n3 + n4 + n5, 4) * Q(n6, 1) - 6. * Q(n1, 1) * Q(n2 + n3 + n4 + n5, 4) * Q(n6, 1) + 24. * Q(n1 + n2 + n3 + n4 + n5, 5) * Q(n6, 1) - Q(n2, 1) * Q(n3, 1) * Q(n4, 1) * Q(n5, 1) * Q(n1 + n6, 2) + Q(n2 + n3, 2) * Q(n4, 1) * Q(n5, 1) * Q(n1 + n6, 2) + Q(n3, 1) * Q(n2 + n4, 2) * Q(n5, 1) * Q(n1 + n6, 2) + Q(n2, 1) * Q(n3 + n4, 2) * Q(n5, 1) * Q(n1 + n6, 2) - 2. * Q(n2 + n3 + n4, 3) * Q(n5, 1) * Q(n1 + n6, 2) + Q(n3, 1) * Q(n4, 1) * Q(n2 + n5, 2) * Q(n1 + n6, 2) - Q(n3 + n4, 2) * Q(n2 + n5, 2) * Q(n1 + n6, 2) + Q(n2, 1) * Q(n4, 1) * Q(n3 + n5, 2) * Q(n1 + n6, 2) - Q(n2 + n4, 2) * Q(n3 + n5, 2) * Q(n1 + n6, 2) - 2. * Q(n4, 1) * Q(n2 + n3 + n5, 3) * Q(n1 + n6, 2) + Q(n2, 1) * Q(n3, 1) * Q(n4 + n5, 2) * Q(n1 + n6, 2) - Q(n2 + n3, 2) * Q(n4 + n5, 2) * Q(n1 + n6, 2) - 2. * Q(n3, 1) * Q(n2 + n4 + n5, 3) * Q(n1 + n6, 2) - 2. * Q(n2, 1) * Q(n3 + n4 + n5, 3) * Q(n1 + n6, 2) + 6. * Q(n2 + n3 + n4 + n5, 4) * Q(n1 + n6, 2) - Q(n1, 1) * Q(n3, 1) * Q(n4, 1) * Q(n5, 1) * Q(n2 + n6, 2) + Q(n1 + n3, 2) * Q(n4, 1) * Q(n5, 1) * Q(n2 + n6, 2) + Q(n3, 1) * Q(n1 + n4, 2) * Q(n5, 1) * Q(n2 + n6, 2) + Q(n1, 1) * Q(n3 + n4, 2) * Q(n5, 1) * Q(n2 + n6, 2) - 2. * Q(n1 + n3 + n4, 3) * Q(n5, 1) * Q(n2 + n6, 2) + Q(n3, 1) * Q(n4, 1) * Q(n1 + n5, 2) * Q(n2 + n6, 2) - Q(n3 + n4, 2) * Q(n1 + n5, 2) * Q(n2 + n6, 2) + Q(n1, 1) * Q(n4, 1) * Q(n3 + n5, 2) * Q(n2 + n6, 2) - Q(n1 + n4, 2) * Q(n3 + n5, 2) * Q(n2 + n6, 2) - 2. * Q(n4, 1) * Q(n1 + n3 + n5, 3) * Q(n2 + n6, 2) + Q(n1, 1) * Q(n3, 1) * Q(n4 + n5, 2) * Q(n2 + n6, 2) - Q(n1 + n3, 2) * Q(n4 + n5, 2) * Q(n2 + n6, 2) - 2. * Q(n3, 1) * Q(n1 + n4 + n5, 3) * Q(n2 + n6, 2) - 2. * Q(n1, 1) * Q(n3 + n4 + n5, 3) * Q(n2 + n6, 2) + 6. * Q(n1 + n3 + n4 + n5, 4) * Q(n2 + n6, 2) + 2. * Q(n3, 1) * Q(n4, 1) * Q(n5, 1) * Q(n1 + n2 + n6, 3) - 2. * Q(n3 + n4, 2) * Q(n5, 1) * Q(n1 + n2 + n6, 3) - 2. * Q(n4, 1) * Q(n3 + n5, 2) * Q(n1 + n2 + n6, 3) - 2. * Q(n3, 1) * Q(n4 + n5, 2) * Q(n1 + n2 + n6, 3) + 4. * Q(n3 + n4 + n5, 3) * Q(n1 + n2 + n6, 3) - Q(n1, 1) * Q(n2, 1) * Q(n4, 1) * Q(n5, 1) * Q(n3 + n6, 2) + Q(n1 + n2, 2) * Q(n4, 1) * Q(n5, 1) * Q(n3 + n6, 2) + Q(n2, 1) * Q(n1 + n4, 2) * Q(n5, 1) * Q(n3 + n6, 2) + Q(n1, 1) * Q(n2 + n4, 2) * Q(n5, 1) * Q(n3 + n6, 2) - 2. * Q(n1 + n2 + n4, 3) * Q(n5, 1) * Q(n3 + n6, 2) + Q(n2, 1) * Q(n4, 1) * Q(n1 + n5, 2) * Q(n3 + n6, 2) - Q(n2 + n4, 2) * Q(n1 + n5, 2) * Q(n3 + n6, 2) + Q(n1, 1) * Q(n4, 1) * Q(n2 + n5, 2) * Q(n3 + n6, 2) - Q(n1 + n4, 2) * Q(n2 + n5, 2) * Q(n3 + n6, 2) - 2. * Q(n4, 1) * Q(n1 + n2 + n5, 3) * Q(n3 + n6, 2) + Q(n1, 1) * Q(n2, 1) * Q(n4 + n5, 2) * Q(n3 + n6, 2) - Q(n1 + n2, 2) * Q(n4 + n5, 2) * Q(n3 + n6, 2) - 2. * Q(n2, 1) * Q(n1 + n4 + n5, 3) * Q(n3 + n6, 2) - 2. * Q(n1, 1) * Q(n2 + n4 + n5, 3) * Q(n3 + n6, 2) + 6. * Q(n1 + n2 + n4 + n5, 4) * Q(n3 + n6, 2) + 2. * Q(n2, 1) * Q(n4, 1) * Q(n5, 1) * Q(n1 + n3 + n6, 3) - 2. * Q(n2 + n4, 2) * Q(n5, 1) * Q(n1 + n3 + n6, 3) - 2. * Q(n4, 1) * Q(n2 + n5, 2) * Q(n1 + n3 + n6, 3) - 2. * Q(n2, 1) * Q(n4 + n5, 2) * Q(n1 + n3 + n6, 3) + 4. * Q(n2 + n4 + n5, 3) * Q(n1 + n3 + n6, 3) + 2. * Q(n1, 1) * Q(n4, 1) * Q(n5, 1) * Q(n2 + n3 + n6, 3) - 2. * Q(n1 + n4, 2) * Q(n5, 1) * Q(n2 + n3 + n6, 3) - 2. * Q(n4, 1) * Q(n1 + n5, 2) * Q(n2 + n3 + n6, 3) - 2. * Q(n1, 1) * Q(n4 + n5, 2) * Q(n2 + n3 + n6, 3) + 4. * Q(n1 + n4 + n5, 3) * Q(n2 + n3 + n6, 3) - 6. * Q(n4, 1) * Q(n5, 1) * Q(n1 + n2 + n3 + n6, 4) + 6. * Q(n4 + n5, 2) * Q(n1 + n2 + n3 + n6, 4) - Q(n1, 1) * Q(n2, 1) * Q(n3, 1) * Q(n5, 1) * Q(n4 + n6, 2) + Q(n1 + n2, 2) * Q(n3, 1) * Q(n5, 1) * Q(n4 + n6, 2) + Q(n2, 1) * Q(n1 + n3, 2) * Q(n5, 1) * Q(n4 + n6, 2) + Q(n1, 1) * Q(n2 + n3, 2) * Q(n5, 1) * Q(n4 + n6, 2) - 2. * Q(n1 + n2 + n3, 3) * Q(n5, 1) * Q(n4 + n6, 2) + Q(n2, 1) * Q(n3, 1) * Q(n1 + n5, 2) * Q(n4 + n6, 2) - Q(n2 + n3, 2) * Q(n1 + n5, 2) * Q(n4 + n6, 2) + Q(n1, 1) * Q(n3, 1) * Q(n2 + n5, 2) * Q(n4 + n6, 2) - Q(n1 + n3, 2) * Q(n2 + n5, 2) * Q(n4 + n6, 2) - 2. * Q(n3, 1) * Q(n1 + n2 + n5, 3) * Q(n4 + n6, 2) + Q(n1, 1) * Q(n2, 1) * Q(n3 + n5, 2) * Q(n4 + n6, 2) - Q(n1 + n2, 2) * Q(n3 + n5, 2) * Q(n4 + n6, 2) - 2. * Q(n2, 1) * Q(n1 + n3 + n5, 3) * Q(n4 + n6, 2) - 2. * Q(n1, 1) * Q(n2 + n3 + n5, 3) * Q(n4 + n6, 2) + 6. * Q(n1 + n2 + n3 + n5, 4) * Q(n4 + n6, 2) + 2. * Q(n2, 1) * Q(n3, 1) * Q(n5, 1) * Q(n1 + n4 + n6, 3) - 2. * Q(n2 + n3, 2) * Q(n5, 1) * Q(n1 + n4 + n6, 3) - 2. * Q(n3, 1) * Q(n2 + n5, 2) * Q(n1 + n4 + n6, 3) - 2. * Q(n2, 1) * Q(n3 + n5, 2) * Q(n1 + n4 + n6, 3) + 4. * Q(n2 + n3 + n5, 3) * Q(n1 + n4 + n6, 3) + 2. * Q(n1, 1) * Q(n3, 1) * Q(n5, 1) * Q(n2 + n4 + n6, 3) - 2. * Q(n1 + n3, 2) * Q(n5, 1) * Q(n2 + n4 + n6, 3) - 2. * Q(n3, 1) * Q(n1 + n5, 2) * Q(n2 + n4 + n6, 3) - 2. * Q(n1, 1) * Q(n3 + n5, 2) * Q(n2 + n4 + n6, 3) + 4. * Q(n1 + n3 + n5, 3) * Q(n2 + n4 + n6, 3) - 6. * Q(n3, 1) * Q(n5, 1) * Q(n1 + n2 + n4 + n6, 4) + 6. * Q(n3 + n5, 2) * Q(n1 + n2 + n4 + n6, 4) + 2. * Q(n1, 1) * Q(n2, 1) * Q(n5, 1) * Q(n3 + n4 + n6, 3) - 2. * Q(n1 + n2, 2) * Q(n5, 1) * Q(n3 + n4 + n6, 3) - 2. * Q(n2, 1) * Q(n1 + n5, 2) * Q(n3 + n4 + n6, 3) - 2. * Q(n1, 1) * Q(n2 + n5, 2) * Q(n3 + n4 + n6, 3) + 4. * Q(n1 + n2 + n5, 3) * Q(n3 + n4 + n6, 3) - 6. * Q(n2, 1) * Q(n5, 1) * Q(n1 + n3 + n4 + n6, 4) + 6. * Q(n2 + n5, 2) * Q(n1 + n3 + n4 + n6, 4) - 6. * Q(n1, 1) * Q(n5, 1) * Q(n2 + n3 + n4 + n6, 4) + 6. * Q(n1 + n5, 2) * Q(n2 + n3 + n4 + n6, 4) + 24. * Q(n5, 1) * Q(n1 + n2 + n3 + n4 + n6, 5) - Q(n1, 1) * Q(n2, 1) * Q(n3, 1) * Q(n4, 1) * Q(n5 + n6, 2) + Q(n1 + n2, 2) * Q(n3, 1) * Q(n4, 1) * Q(n5 + n6, 2) + Q(n2, 1) * Q(n1 + n3, 2) * Q(n4, 1) * Q(n5 + n6, 2) + Q(n1, 1) * Q(n2 + n3, 2) * Q(n4, 1) * Q(n5 + n6, 2) - 2. * Q(n1 + n2 + n3, 3) * Q(n4, 1) * Q(n5 + n6, 2) + Q(n2, 1) * Q(n3, 1) * Q(n1 + n4, 2) * Q(n5 + n6, 2) - Q(n2 + n3, 2) * Q(n1 + n4, 2) * Q(n5 + n6, 2) + Q(n1, 1) * Q(n3, 1) * Q(n2 + n4, 2) * Q(n5 + n6, 2) - Q(n1 + n3, 2) * Q(n2 + n4, 2) * Q(n5 + n6, 2) - 2. * Q(n3, 1) * Q(n1 + n2 + n4, 3) * Q(n5 + n6, 2) + Q(n1, 1) * Q(n2, 1) * Q(n3 + n4, 2) * Q(n5 + n6, 2) - Q(n1 + n2, 2) * Q(n3 + n4, 2) * Q(n5 + n6, 2) - 2. * Q(n2, 1) * Q(n1 + n3 + n4, 3) * Q(n5 + n6, 2) - 2. * Q(n1, 1) * Q(n2 + n3 + n4, 3) * Q(n5 + n6, 2) + 6. * Q(n1 + n2 + n3 + n4, 4) * Q(n5 + n6, 2) + 2. * Q(n2, 1) * Q(n3, 1) * Q(n4, 1) * Q(n1 + n5 + n6, 3) - 2. * Q(n2 + n3, 2) * Q(n4, 1) * Q(n1 + n5 + n6, 3) - 2. * Q(n3, 1) * Q(n2 + n4, 2) * Q(n1 + n5 + n6, 3) - 2. * Q(n2, 1) * Q(n3 + n4, 2) * Q(n1 + n5 + n6, 3) + 4. * Q(n2 + n3 + n4, 3) * Q(n1 + n5 + n6, 3) + 2. * Q(n1, 1) * Q(n3, 1) * Q(n4, 1) * Q(n2 + n5 + n6, 3) - 2. * Q(n1 + n3, 2) * Q(n4, 1) * Q(n2 + n5 + n6, 3) - 2. * Q(n3, 1) * Q(n1 + n4, 2) * Q(n2 + n5 + n6, 3) - 2. * Q(n1, 1) * Q(n3 + n4, 2) * Q(n2 + n5 + n6, 3) + 4. * Q(n1 + n3 + n4, 3) * Q(n2 + n5 + n6, 3) - 6. * Q(n3, 1) * Q(n4, 1) * Q(n1 + n2 + n5 + n6, 4) + 6. * Q(n3 + n4, 2) * Q(n1 + n2 + n5 + n6, 4) + 2. * Q(n1, 1) * Q(n2, 1) * Q(n4, 1) * Q(n3 + n5 + n6, 3) - 2. * Q(n1 + n2, 2) * Q(n4, 1) * Q(n3 + n5 + n6, 3) - 2. * Q(n2, 1) * Q(n1 + n4, 2) * Q(n3 + n5 + n6, 3) - 2. * Q(n1, 1) * Q(n2 + n4, 2) * Q(n3 + n5 + n6, 3) + 4. * Q(n1 + n2 + n4, 3) * Q(n3 + n5 + n6, 3) - 6. * Q(n2, 1) * Q(n4, 1) * Q(n1 + n3 + n5 + n6, 4) + 6. * Q(n2 + n4, 2) * Q(n1 + n3 + n5 + n6, 4) - 6. * Q(n1, 1) * Q(n4, 1) * Q(n2 + n3 + n5 + n6, 4) + 6. * Q(n1 + n4, 2) * Q(n2 + n3 + n5 + n6, 4) + 24. * Q(n4, 1) * Q(n1 + n2 + n3 + n5 + n6, 5) + 2. * Q(n1, 1) * Q(n2, 1) * Q(n3, 1) * Q(n4 + n5 + n6, 3) - 2. * Q(n1 + n2, 2) * Q(n3, 1) * Q(n4 + n5 + n6, 3) - 2. * Q(n2, 1) * Q(n1 + n3, 2) * Q(n4 + n5 + n6, 3) - 2. * Q(n1, 1) * Q(n2 + n3, 2) * Q(n4 + n5 + n6, 3) + 4. * Q(n1 + n2 + n3, 3) * Q(n4 + n5 + n6, 3) - 6. * Q(n2, 1) * Q(n3, 1) * Q(n1 + n4 + n5 + n6, 4) + 6. * Q(n2 + n3, 2) * Q(n1 + n4 + n5 + n6, 4) - 6. * Q(n1, 1) * Q(n3, 1) * Q(n2 + n4 + n5 + n6, 4) + 6. * Q(n1 + n3, 2) * Q(n2 + n4 + n5 + n6, 4) + 24. * Q(n3, 1) * Q(n1 + n2 + n4 + n5 + n6, 5) - 6. * Q(n1, 1) * Q(n2, 1) * Q(n3 + n4 + n5 + n6, 4) + 6. * Q(n1 + n2, 2) * Q(n3 + n4 + n5 + n6, 4) + 24. * Q(n2, 1) * Q(n1 + n3 + n4 + n5 + n6, 5) + 24. * Q(n1, 1) * Q(n2 + n3 + n4 + n5 + n6, 5) - 120. * Q(n1 + n2 + n3 + n4 + n5 + n6, 6); + + return six; + +} // TComplex Six(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6) + +//============================================================ + +TComplex Seven(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6, Int_t n7) +{ + // Generic seven-particle correlation . + + Int_t harmonic[7] = {n1, n2, n3, n4, n5, n6, n7}; + + TComplex seven = Recursion(7, harmonic); + + return seven; + +} // end of TComplex Seven(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6, Int_t n7) + +//============================================================ + +TComplex Eight(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6, Int_t n7, Int_t n8) +{ + // Generic eight-particle correlation . + + Int_t harmonic[8] = {n1, n2, n3, n4, n5, n6, n7, n8}; + + TComplex eight = Recursion(8, harmonic); + + return eight; + +} // end of Eight(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6, Int_t n7, Int_t n8) + +//============================================================ + +TComplex Nine(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6, Int_t n7, Int_t n8, Int_t n9) +{ + // Generic nine-particle correlation . + + Int_t harmonic[9] = {n1, n2, n3, n4, n5, n6, n7, n8, n9}; + + TComplex nine = Recursion(9, harmonic); + + return nine; + +} // end of TComplex Nine(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6, Int_t n7, Int_t n8, Int_t n9) + +//============================================================ + +TComplex Ten(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6, Int_t n7, Int_t n8, Int_t n9, Int_t n10) +{ + // Generic ten-particle correlation . + + Int_t harmonic[10] = {n1, n2, n3, n4, n5, n6, n7, n8, n9, n10}; + + TComplex ten = Recursion(10, harmonic); + + return ten; + +} // end of TComplex Ten(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6, Int_t n7, Int_t n8, Int_t n9, Int_t n10) + +//============================================================ + +TComplex Eleven(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6, Int_t n7, Int_t n8, Int_t n9, Int_t n10, Int_t n11) +{ + // Generic eleven-particle correlation . + + Int_t harmonic[11] = {n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11}; + + TComplex eleven = Recursion(11, harmonic); + + return eleven; + +} // end of TComplex Eleven(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6, Int_t n7, Int_t n8, Int_t n9, Int_t n10, Int_t n11) + +//============================================================ + +TComplex Twelve(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6, Int_t n7, Int_t n8, Int_t n9, Int_t n10, Int_t n11, Int_t n12) +{ + // Generic twelve-particle correlation . + + Int_t harmonic[12] = {n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12}; + + TComplex twelve = Recursion(12, harmonic); + + return twelve; + +} // end of TComplex Twelve(Int_t n1, Int_t n2, Int_t n3, Int_t n4, Int_t n5, Int_t n6, Int_t n7, Int_t n8, Int_t n9, Int_t n10, Int_t n11, Int_t n12) + +//============================================================ + +TComplex Recursion(Int_t n, Int_t* harmonic, Int_t mult = 1, Int_t skip = 0) +{ + // Calculate multi-particle correlators by using recursion (an improved faster version) originally developed by + // Kristjan Gulbrandsen (gulbrand@nbi.dk). + + Int_t nm1 = n - 1; + TComplex c(Q(harmonic[nm1], mult)); + if (nm1 == 0) + return c; + c *= Recursion(nm1, harmonic); + if (nm1 == skip) + return c; + + Int_t multp1 = mult + 1; + Int_t nm2 = n - 2; + Int_t counter1 = 0; + Int_t hhold = harmonic[counter1]; + harmonic[counter1] = harmonic[nm2]; + harmonic[nm2] = hhold + harmonic[nm1]; + TComplex c2(Recursion(nm1, harmonic, multp1, nm2)); + Int_t counter2 = n - 3; + while (counter2 >= skip) { + harmonic[nm2] = harmonic[counter1]; + harmonic[counter1] = hhold; + ++counter1; + hhold = harmonic[counter1]; + harmonic[counter1] = harmonic[nm2]; + harmonic[nm2] = hhold + harmonic[nm1]; + c2 += Recursion(nm1, harmonic, multp1, counter2); + --counter2; + } + harmonic[nm2] = harmonic[counter1]; + harmonic[counter1] = hhold; + + if (mult == 1) + return c - c2; + return c - Double_t(mult) * c2; + +} // TComplex Recursion(Int_t n, Int_t* harmonic, Int_t mult = 1, Int_t skip = 0) + +//============================================================ + void ResetQ() { // Reset the components of generic Q-vectors. Use it whenever you call the @@ -2433,7 +2967,8 @@ void StoreLabelsInPlaceholder() // a) Initialize all counters; // b) Fetch TObjArray with labels from an external file; // c) Book the placeholder fTest0LabelsPlaceholder for all labels; - // d) Finally, store the labels from external source into placeholder. + // d) Finally, store the labels from external source into placeholder; + // e) Insantity check on labels. if (tc.fVerbose) { LOGF(info, "\033[1;32m%s\033[0m", __PRETTY_FUNCTION__); @@ -2488,6 +3023,19 @@ void StoreLabelsInPlaceholder() // cout<GetEntries()<GetXaxis()->GetNbins(); b++) { + TObjArray* temp = TString(fTest0LabelsPlaceholder->GetXaxis()->GetBinLabel(b)).Tokenize(" "); + for (Int_t h = 0; h < temp->GetEntries(); h++) { + if (TMath::Abs(TString(temp->At(h)->GetName()).Atoi()) > gMaxHarmonic) { + LOGF(info, "\033[1;31m bin = %d, label = %s, gMaxHarmonic = %d\033[0m", b, fTest0LabelsPlaceholder->GetXaxis()->GetBinLabel(b), (Int_t)gMaxHarmonic); + LOGF(fatal, "in function \033[1;31m%s at line %d\033[0m", __PRETTY_FUNCTION__, __LINE__); + } // if(TString(temp->At(h)->GetName()).Atoi() > gMaxHarmonic) { + } // for(Int_t h = 0; h < temp->GetEntries(); h++) { + delete temp; // yes, otherwise it's a memory leak + } // for(Int_t b = 1; b <= fTest0LabelsPlaceholder->GetXaxis()->GetNbins(); b++) { + } // void StoreLabelsInPlaceholder() //============================================================ @@ -2722,8 +3270,7 @@ Double_t CalculateCustomNestedLoop(TArrayI* harmonics) } if (!harmonics) { - cout << __LINE__ << endl; - exit(1); + LOGF(fatal, "in function \033[1;31m%s at line %d\033[0m", __PRETTY_FUNCTION__, __LINE__); } Int_t nParticles = fSelectedTracks; @@ -2916,6 +3463,68 @@ Double_t CalculateCustomNestedLoop(TArrayI* harmonics) //============================================================ +template +void DetermineCentrality(T const& collision) +{ + // Determine collision centrality. + + // a) For real data, determine centrality from default centrality estimator; + // b) For simulated data, determine centrality directly from impact parameter. + + if (tc.fVerbose) { + LOGF(info, "\033[1;32m%s\033[0m", __FUNCTION__); // just a bare function name + } + + // a) For real data, determine centrality from default centrality estimator: + if constexpr (rs == eRec || rs == eRecAndSim) { + // fCentrality = gRandom->Uniform(0.,100.); // collision.centFT0M(); // TBI 20240120 not ready yet, estimators are specific for Run 1,2,3 data processing ... + fCentrality = collision.centFT0M(); // TBI 20240120 not ready yet, estimators are specific for Run 1,2,3 data processing ... + // TBI 20240120 I could also here access also corresponding simulated centrality from impact parameter, if available through collision.has_mcCollision() + } + + // b) For simulated data, determine centrality directly from impact parameter: + if constexpr (rs == eSim) { + fCentrality = -44.; // TBI 20240120 add support eventualy + } // if constexpr (rs == eSim) { + + // TBI 20240120 remove this printout eventually: + if (tc.fVerbose) { + LOGF(info, "\033[1;32m fCentrality = %f\033[0m", fCentrality); + } + +} // template void DetermineCentrality(T const& collision) + +//============================================================ + +void RandomIndices(Int_t nTracks) +{ + // Randomize indices using Fisher-Yates algorithm. + + if (tc.fVerbose) { + LOGF(info, "\033[1;32m%s\033[0m", __PRETTY_FUNCTION__); + } + + if (nTracks < 1) { + return; + } + + // Fisher-Yates algorithm: + tc.fRandomIndices = new TArrayI(nTracks); + tc.fRandomIndices->Reset(); // just in case there is some random garbage in memory at init + for (Int_t i = 0; i < nTracks; i++) { + tc.fRandomIndices->AddAt(i, i); + } + for (Int_t i = nTracks - 1; i >= 1; i--) { + Int_t j = gRandom->Integer(i + 1); + Int_t temp = tc.fRandomIndices->GetAt(j); + tc.fRandomIndices->AddAt(tc.fRandomIndices->GetAt(i), j); + tc.fRandomIndices->AddAt(temp, i); + } // end of for(Int_t i=nTracks-1;i>=1;i--) + +} // void RandomIndices(Int_t nTracks) + +//============================================================ + void CalculateEverything() { // Calculate everything for selected events and particles. @@ -2941,9 +3550,7 @@ void CalculateEverything() // *) Calculate nested loops: if (fCalculateNestedLoops) { this->CalculateNestedLoops(); - - // TBI 20220823 this shall be called after all events are processed, only temporarily here called for each event: - this->ComparisonNestedLoopsVsCorrelations(); + this->ComparisonNestedLoopsVsCorrelations(); // I call it here, so comparison is performed cumulatively after each event. The final printout corresponds to all events. } } // void CalculateEverything() @@ -2965,6 +3572,9 @@ void Steer(T1 const& collision, T2 const& tracks) // *) Do all thingies before starting to process data from this collision (e.g. count number of events, fetch the run number, etc.): Preprocess(collision); + // *) Determine collision centrality: + DetermineCentrality(collision); + // *) Fill event histograms before event cuts: FillEventHistograms(collision, tracks, eBefore); @@ -3020,7 +3630,28 @@ void MainLoopOverParticles(T const& tracks) Double_t wToPowerP = 1.; // weight raised to power p fSelectedTracks = 0; // reset number of selected tracks - for (auto& track : tracks) { + // *) If random access of tracks from collection is requested, use Fisher-Yates algorithm to generate random indices: + if (tc.fUseFisherYates) { + if (tc.fRandomIndices) { + LOGF(fatal, "in function \033[1;31m%s at line %d\033[0m", __PRETTY_FUNCTION__, __LINE__); + } + this->RandomIndices(tracks.size()); + if (!tc.fRandomIndices) { + LOGF(fatal, "in function \033[1;31m%s at line %d\033[0m", __PRETTY_FUNCTION__, __LINE__); + } + } + + // *) Main loop over particles: + // for (auto& track : tracks) { // default standard way of looping of tracks + auto track = tracks.iteratorAt(0); // set the type and scope from one instance + for (int64_t i = 0; i < tracks.size(); i++) { + + // *) Access track sequentially from collection of tracks (default), or randomly using Fisher-Yates algorithm: + if (!tc.fUseFisherYates) { + track = tracks.iteratorAt(i); + } else { + track = tracks.iteratorAt((int64_t)tc.fRandomIndices->GetAt(i)); + } // *) Fill particle histograms before particle cuts: FillParticleHistograms(track, eBefore); @@ -3090,8 +3721,19 @@ void MainLoopOverParticles(T const& tracks) break; } + // *) Break the loop if fixed number of particles is taken randomly from each event (use always in combination with tc.fUseFisherYates = kTRUE): + if (tc.fFixedNumberOfRandomlySelectedTracks > 0 && tc.fFixedNumberOfRandomlySelectedTracks == fSelectedTracks) { + LOGF(info, "\033[1;32mBreaking the loop over particles, since requested fixed number of %d particles was reached\033[0m", tc.fFixedNumberOfRandomlySelectedTracks); + break; + } + } // for (auto& track : tracks) + // *) Insanity check on fixed number of randomly selected tracks: + if (tc.fFixedNumberOfRandomlySelectedTracks > 0 && tc.fFixedNumberOfRandomlySelectedTracks < fSelectedTracks) { + LOGF(fatal, "\033[1;31mIn this event there are too few particles (fSelectedTracks = %d), and requested number of fixed number randomly selected tracks %d couldn't be reached\033[0m", fSelectedTracks, tc.fFixedNumberOfRandomlySelectedTracks); + } + } // template void MainLoopOverParticles(T const& tracks) { #endif // PWGCF_MULTIPARTICLECORRELATIONS_CORE_MUPA_MEMBERFUNCTIONS_H_ diff --git a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx index b91c551ee83..6b4eaa2e0f5 100644 --- a/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx +++ b/PWGCF/MultiparticleCorrelations/Tasks/multiparticle-correlations-ab.cxx @@ -15,12 +15,17 @@ #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" #include "Common/DataModel/TrackSelectionTables.h" // needed for aod::TracksDCA table +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/Centrality.h" using namespace o2; using namespace o2::framework; -using CollisionRec = aod::Collision; -using CollisionRecSim = soa::Join::iterator; -using CollisionSim = aod::McCollision; +using EventSelection = soa::Join; // TBI 20240120 add support for other centrality estimators, why aod::Cents doesn't work? + +using CollisionRec = soa::Join::iterator; +using CollisionRecSim = soa::Join::iterator; +using CollisionSim = aod::McCollision; // TBI 20240120 add support for centrality also for this case using TracksRec = soa::Join; using TrackRec = soa::Join::iterator; diff --git a/PWGCF/TableProducer/CMakeLists.txt b/PWGCF/TableProducer/CMakeLists.txt index 4a90ccdea3d..1bfef915ff3 100644 --- a/PWGCF/TableProducer/CMakeLists.txt +++ b/PWGCF/TableProducer/CMakeLists.txt @@ -14,7 +14,12 @@ o2physics_add_dpl_workflow(filter-correlations PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(filter-correlations-2prong + SOURCES filter2Prong.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(dptdpt-filter SOURCES dptdptfilter.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::PWGCFCore - COMPONENT_NAME Analysis) \ No newline at end of file + COMPONENT_NAME Analysis) diff --git a/PWGCF/TableProducer/filter2Prong.cxx b/PWGCF/TableProducer/filter2Prong.cxx new file mode 100644 index 00000000000..74191f70ddc --- /dev/null +++ b/PWGCF/TableProducer/filter2Prong.cxx @@ -0,0 +1,72 @@ +// 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. +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" + +#include "MathUtils/detail/TypeTruncation.h" + +#include "PWGCF/DataModel/CorrelationsDerived.h" + +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::math_utils::detail; + +#define FLOAT_PRECISION 0xFFFFFFF0 +#define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable NAME{#NAME, DEFAULT, HELP}; + +struct Filter2Prong { + O2_DEFINE_CONFIGURABLE(cfgVerbosity, int, 0, "Verbosity level (0 = major, 1 = per collision)") + + Produces output2ProngTracks; + + using HFCandidates = soa::Join; + void processData(aod::Collisions::iterator const& collision, aod::BCsWithTimestamps const&, aod::CFCollRefs const& cfcollisions, aod::CFTrackRefs const& cftracks, HFCandidates const& candidates) + { + if (cfcollisions.size() <= 0 || cftracks.size() <= 0) + return; // rejected collision + if (cfgVerbosity > 0 && candidates.size() > 0) + LOGF(info, "Candidates for collision: %lu, cfcollisions: %lu, CFTracks: %lu", candidates.size(), cfcollisions.size(), cftracks.size()); + for (auto& c : candidates) { + int prongCFId[2] = {-1, -1}; + for (auto& cftrack : cftracks) { + if (c.prong0Id() == cftrack.trackId()) { + prongCFId[0] = cftrack.globalIndex(); + break; + } + } + for (auto& cftrack : cftracks) { + if (c.prong1Id() == cftrack.trackId()) { + prongCFId[1] = cftrack.globalIndex(); + break; + } + } + // look-up the collision id + if ((c.hfflag() & (1 << aod::hf_cand_2prong::DecayType::D0ToPiK)) == 0) + continue; + output2ProngTracks(cfcollisions.begin().globalIndex(), + prongCFId[0], prongCFId[1], c.pt(), c.eta(), c.phi(), aod::cf2prongtrack::D0ToPiK); + } + } + PROCESS_SWITCH(Filter2Prong, processData, "Process data D0 candidates", true); +}; // struct + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc, TaskName{"filter-2prong"})}; +} diff --git a/PWGCF/TableProducer/filterCorrelations.cxx b/PWGCF/TableProducer/filterCorrelations.cxx index 24c398289e4..3e1ffcd8488 100644 --- a/PWGCF/TableProducer/filterCorrelations.cxx +++ b/PWGCF/TableProducer/filterCorrelations.cxx @@ -55,6 +55,7 @@ struct FilterCF { 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)") O2_DEFINE_CONFIGURABLE(cfgCollisionFlags, uint16_t, aod::collision::CollisionFlagsRun2::Run2VertexerTracks, "Request collision flags if non-zero (0 = off, 1 = Run2VertexerTracks)") + O2_DEFINE_CONFIGURABLE(cfgTransientTables, bool, false, "Output transient tables for collision and track IDs") // Filters and input definitions Filter collisionZVtxFilter = nabs(aod::collision::posZ) < cfgCutVertex; @@ -78,6 +79,9 @@ struct FilterCF { Produces outputMcCollisions; Produces outputMcParticles; + Produces outputCollRefs; + Produces outputTrackRefs; + template bool keepCollision(TCollision& collision) { @@ -104,6 +108,9 @@ struct FilterCF { auto bc = collision.bc_as(); outputCollisions(bc.runNumber(), collision.posZ(), collision.multiplicity(), bc.timestamp()); + if (cfgTransientTables) + outputCollRefs(collision.globalIndex()); + for (auto& track : tracks) { uint8_t trackType = 0; if (track.isGlobalTrack()) { @@ -113,6 +120,8 @@ struct FilterCF { } outputTracks(outputCollisions.lastIndex(), track.pt(), track.eta(), track.phi(), track.sign(), trackType); + if (cfgTransientTables) + outputTrackRefs(collision.globalIndex(), track.globalIndex()); yields->Fill(collision.multiplicity(), track.pt(), track.eta()); etaphi->Fill(collision.multiplicity(), track.eta(), track.phi()); @@ -256,6 +265,15 @@ struct MultiplicitySelector { if (doprocessTracks) { enabledFunctions++; } + if (doprocessFT0M) { + enabledFunctions++; + } + if (doprocessFT0C) { + enabledFunctions++; + } + if (doprocessFT0A) { + enabledFunctions++; + } if (enabledFunctions != 1) { LOGP(fatal, "{} multiplicity selectors enabled but we need exactly 1.", enabledFunctions); @@ -268,6 +286,30 @@ struct MultiplicitySelector { } PROCESS_SWITCH(MultiplicitySelector, processTracks, "Select track count as multiplicity", false); + void processFT0M(aod::CentFT0Ms const& centralities) + { + for (auto& c : centralities) { + output(c.centFT0M()); + } + } + PROCESS_SWITCH(MultiplicitySelector, processFT0M, "Select FT0M centrality as multiplicity", false); + + void processFT0C(aod::CentFT0Cs const& centralities) + { + for (auto& c : centralities) { + output(c.centFT0C()); + } + } + PROCESS_SWITCH(MultiplicitySelector, processFT0C, "Select FT0C centrality as multiplicity", false); + + void processFT0A(aod::CentFT0As const& centralities) + { + for (auto& c : centralities) { + output(c.centFT0A()); + } + } + PROCESS_SWITCH(MultiplicitySelector, processFT0A, "Select FT0A centrality as multiplicity", false); + void processRun2V0M(aod::CentRun2V0Ms const& centralities) { for (auto& c : centralities) { diff --git a/PWGCF/Tasks/correlations.cxx b/PWGCF/Tasks/correlations.cxx index 6986c0bf4fc..85c2b3b331d 100644 --- a/PWGCF/Tasks/correlations.cxx +++ b/PWGCF/Tasks/correlations.cxx @@ -8,11 +8,18 @@ // 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. +#include + +#include +#include +#include +#include + #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" #include "Framework/AnalysisDataModel.h" #include "Framework/ASoAHelpers.h" -#include +#include "CCDB/BasicCCDBManager.h" #include "Framework/StepTHn.h" #include "Framework/HistogramRegistry.h" #include "Framework/RunningWorkflowInfo.h" @@ -27,11 +34,6 @@ #include "DataFormatsParameters/GRPObject.h" #include "DataFormatsParameters/GRPMagField.h" -#include -#include -#include -#include - using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; @@ -78,6 +80,8 @@ struct CorrelationTask { O2_DEFINE_CONFIGURABLE(cfgVerbosity, int, 1, "Verbosity level (0 = major, 1 = per collision)") + O2_DEFINE_CONFIGURABLE(cfgDecayParticleMask, int, 0, "Selection bitmask for the decay particles: 0 = no selection") + ConfigurableAxis axisVertex{"axisVertex", {7, -7, 7}, "vertex axis for histograms"}; ConfigurableAxis axisDeltaPhi{"axisDeltaPhi", {72, -PIHalf, PIHalf * 3}, "delta phi axis for histograms"}; ConfigurableAxis axisDeltaEta{"axisDeltaEta", {40, -2, 2}, "delta eta axis for histograms"}; @@ -102,10 +106,15 @@ struct CorrelationTask { Filter cfMCCollisionFilter = nabs(aod::mccollision::posZ) < cfgCutVertex; Filter cfMCParticleFilter = (nabs(aod::cfmcparticle::eta) < cfgCutEta) && (aod::cfmcparticle::pt > cfgCutPt) && (aod::cfmcparticle::sign != 0); + // HF filters + Filter track2pFilter = (nabs(aod::cf2prongtrack::eta) < cfgCutEta) && (aod::cf2prongtrack::pt > cfgCutPt); + // Output definitions OutputObj same{"sameEvent"}; OutputObj mixed{"mixedEvent"}; + std::vector efficiencyAssociatedCache; + struct Config { bool mPairCuts = false; THn* mEfficiencyTrigger = nullptr; @@ -128,6 +137,10 @@ struct CorrelationTask { { registry.add("yields", "multiplicity/centrality vs pT vs eta", {HistType::kTH3F, {{100, 0, 100, "/multiplicity/centrality"}, {40, 0, 20, "p_{T}"}, {100, -2, 2, "#eta"}}}); registry.add("etaphi", "multiplicity/centrality vs eta vs phi", {HistType::kTH3F, {{100, 0, 100, "multiplicity/centrality"}, {100, -2, 2, "#eta"}, {200, 0, 2 * M_PI, "#varphi"}}}); + if (doprocessSame2ProngDerived || doprocessMixed2ProngDerived) { + registry.add("yieldsTrigger", "multiplicity/centrality vs pT vs eta (triggers)", {HistType::kTH3F, {{100, 0, 100, "/multiplicity/centrality"}, {40, 0, 20, "p_{T}"}, {100, -2, 2, "#eta"}}}); + registry.add("etaphiTrigger", "multiplicity/centrality vs eta vs phi (triggers)", {HistType::kTH3F, {{100, 0, 100, "multiplicity/centrality"}, {100, -2, 2, "#eta"}, {200, 0, 2 * M_PI, "#varphi"}}}); + } const int maxMixBin = AxisSpec(axisMultiplicity).getNbins() * AxisSpec(axisVertex).getNbins(); registry.add("eventcount_same", "bin", {HistType::kTH1F, {{maxMixBin + 2, -2.5, -0.5 + maxMixBin, "bin"}}}); @@ -165,13 +178,15 @@ struct CorrelationTask { same->setTrackEtaCut(cfgCutEta); mixed->setTrackEtaCut(cfgCutEta); + efficiencyAssociatedCache.reserve(512); + // o2-ccdb-upload -p Users/jgrosseo/correlations/LHC15o -f /tmp/correction_2011_global.root -k correction ccdb->setURL("http://alice-ccdb.cern.ch"); ccdb->setCaching(true); ccdb->setLocalObjectValidityChecking(); - long now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + auto now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); ccdb->setCreatedNotAfter(now); // TODO must become global parameter from the train creation time } @@ -193,7 +208,7 @@ struct CorrelationTask { } template - void fillQA(TCollision collision, float multiplicity, TTracks tracks) + void fillQA(const TCollision& collision, float multiplicity, const TTracks& tracks) { for (auto& track1 : tracks) { registry.fill(HIST("yields"), multiplicity, track1.pt(), track1.eta()); @@ -201,6 +216,20 @@ struct CorrelationTask { } } + template + void fillQA(const TCollision& collision, float multiplicity, const TTracks1& tracks1, const TTracks2& tracks2) + { + for (auto& track1 : tracks1) { + if constexpr (std::is_same::value) { + if (cfgDecayParticleMask != 0 && (cfgDecayParticleMask & (1u << (uint32_t)track1.decay())) == 0u) + continue; + } + registry.fill(HIST("yieldsTrigger"), multiplicity, track1.pt(), track1.eta()); + registry.fill(HIST("etaphiTrigger"), multiplicity, track1.eta(), track1.phi()); + } + fillQA(collision, multiplicity, tracks2); + } + template bool fillCollisionAOD(TTarget target, TCollision collision, float multiplicity) { @@ -229,17 +258,19 @@ struct CorrelationTask { return true; } - template - void fillCorrelations(TTarget target, TTracks& tracks1, TTracks& tracks2, float multiplicity, float posZ, int magField, float eventWeight) + template + using hasSign = decltype(std::declval().sign()); + + template + void fillCorrelations(TTarget target, TTracks1& tracks1, TTracks2& tracks2, float multiplicity, float posZ, int magField, float eventWeight) { // Cache efficiency for particles (too many FindBin lookups) - float* efficiencyAssociated = nullptr; if constexpr (step == CorrelationContainer::kCFStepCorrected) { if (cfg.mEfficiencyAssociated) { - efficiencyAssociated = new float[tracks2.size()]; - int i = 0; + efficiencyAssociatedCache.clear(); + efficiencyAssociatedCache.reserve(tracks2.size()); for (auto& track : tracks2) { - efficiencyAssociated[i++] = getEfficiencyCorrection(cfg.mEfficiencyAssociated, track.eta(), track.pt(), multiplicity, posZ); + efficiencyAssociatedCache.push_back(getEfficiencyCorrection(cfg.mEfficiencyAssociated, track.eta(), track.pt(), multiplicity, posZ)); } } } @@ -253,8 +284,15 @@ struct CorrelationTask { } } - if (cfgTriggerCharge != 0 && cfgTriggerCharge * track1.sign() < 0) { - continue; + if constexpr (std::is_same::value) { + if (cfgDecayParticleMask != 0 && (cfgDecayParticleMask & (1u << (uint32_t)track1.decay())) == 0u) + continue; + } + + if constexpr (std::experimental::is_detected::value) { + if (cfgTriggerCharge != 0 && cfgTriggerCharge * track1.sign() < 0) { + continue; + } } float triggerWeight = eventWeight; @@ -267,9 +305,15 @@ struct CorrelationTask { target->getTriggerHist()->Fill(step, track1.pt(), multiplicity, posZ, triggerWeight); for (auto& track2 : tracks2) { - if (track1.globalIndex() == track2.globalIndex()) { - // LOGF(info, "Track identical: %f | %f | %f || %f | %f | %f", track1.eta(), track1.phi(), track1.pt(), track2.eta(), track2.phi(), track2.pt()); - continue; + if constexpr (std::is_same::value) { + if (track1.globalIndex() == track2.globalIndex()) { + // LOGF(info, "Track identical: %f | %f | %f || %f | %f | %f", track1.eta(), track1.phi(), track1.pt(), track2.eta(), track2.phi(), track2.pt()); + continue; + } + } + if constexpr (std::is_same::value) { + if (track2.globalIndex() == track1.cfTrackProng0Id() || track2.globalIndex() == track1.cfTrackProng1Id()) // do not correlate daughter tracks of the same event + continue; } if constexpr (step <= CorrelationContainer::kCFStepTracked) { @@ -285,24 +329,29 @@ struct CorrelationTask { if (cfgAssociatedCharge != 0 && cfgAssociatedCharge * track2.sign() < 0) { continue; } - if (cfgPairCharge != 0 && cfgPairCharge * track1.sign() * track2.sign() < 0) { - continue; - } - if constexpr (step >= CorrelationContainer::kCFStepReconstructed) { - if (cfg.mPairCuts && mPairCuts.conversionCuts(track1, track2)) { + if constexpr (std::experimental::is_detected::value) { + if (cfgPairCharge != 0 && cfgPairCharge * track1.sign() * track2.sign() < 0) { continue; } + } - if (cfgTwoTrackCut > 0 && mPairCuts.twoTrackCut(track1, track2, magField)) { - continue; + if constexpr (std::is_same::value) { + if constexpr (step >= CorrelationContainer::kCFStepReconstructed) { + if (cfg.mPairCuts && mPairCuts.conversionCuts(track1, track2)) { + continue; + } + + if (cfgTwoTrackCut > 0 && mPairCuts.twoTrackCut(track1, track2, magField)) { + continue; + } } } float associatedWeight = triggerWeight; if constexpr (step == CorrelationContainer::kCFStepCorrected) { if (cfg.mEfficiencyAssociated) { - associatedWeight *= efficiencyAssociated[track2.filteredIndex()]; + associatedWeight *= efficiencyAssociatedCache[track2.filteredIndex()]; } } @@ -318,8 +367,6 @@ struct CorrelationTask { track1.eta() - track2.eta(), track2.pt(), track1.pt(), multiplicity, deltaPhi, posZ, associatedWeight); } } - - delete[] efficiencyAssociated; } void loadEfficiency(uint64_t timestamp) @@ -405,6 +452,29 @@ struct CorrelationTask { } PROCESS_SWITCH(CorrelationTask, processSameDerived, "Process same event on derived data", false); + void processSame2ProngDerived(derivedCollisions::iterator const& collision, soa::Filtered const& tracks, soa::Filtered const& p2tracks) + { + if (cfgVerbosity > 0) { + LOGF(info, "processSame2ProngDerived: Tracks for collision: %d | 2-prong candidates: %d | Vertex: %.1f | Multiplicity/Centrality: %.1f", tracks.size(), p2tracks.size(), collision.posZ(), collision.multiplicity()); + } + loadEfficiency(collision.timestamp()); + + const auto multiplicity = collision.multiplicity(); + + int bin = configurableBinningDerived.getBin({collision.posZ(), collision.multiplicity()}); + registry.fill(HIST("eventcount_same"), bin); + fillQA(collision, multiplicity, p2tracks, tracks); + + same->fillEvent(multiplicity, CorrelationContainer::kCFStepReconstructed); + fillCorrelations(same, p2tracks, tracks, multiplicity, collision.posZ(), 0, 1.0f); + + if (cfg.mEfficiencyAssociated || cfg.mEfficiencyTrigger) { + same->fillEvent(multiplicity, CorrelationContainer::kCFStepCorrected); + fillCorrelations(same, p2tracks, tracks, multiplicity, collision.posZ(), 0, 1.0f); + } + } + PROCESS_SWITCH(CorrelationTask, processSame2ProngDerived, "Process same event on derived data", false); + using BinningTypeAOD = ColumnBinningPolicy; void processMixedAOD(aodCollisions& collisions, aodTracks const& tracks, aod::BCsWithTimestamps const&) { @@ -490,6 +560,44 @@ struct CorrelationTask { } PROCESS_SWITCH(CorrelationTask, processMixedDerived, "Process mixed events on derived data", false); + void processMixed2ProngDerived(derivedCollisions& collisions, derivedTracks const& tracks, soa::Filtered const& p2tracks) + { + // Strictly upper categorised collisions, for cfgNoMixedEvents combinations per bin, skipping those in entry -1 + auto tracksTuple = std::make_tuple(p2tracks, tracks); + Pair, derivedTracks, BinningTypeDerived> 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 eventWeight = 1.0f / it.currentWindowNeighbours(); + int field = 0; + if (cfgTwoTrackCut > 0) { + field = getMagneticField(collision1.timestamp()); + } + + if (cfgVerbosity > 0) { + LOGF(info, "processMixed2ProngDerived: Mixed collisions bin: %d pair: [%d, %d] %d (%.3f, %.3f), %d (%.3f, %.3f)", bin, it.isNewWindow(), it.currentWindowNeighbours(), collision1.globalIndex(), collision1.posZ(), collision1.multiplicity(), collision2.globalIndex(), collision2.posZ(), collision2.multiplicity()); + } + + if (it.isNewWindow()) { + loadEfficiency(collision1.timestamp()); + + mixed->fillEvent(collision1.multiplicity(), CorrelationContainer::kCFStepReconstructed); + } + + registry.fill(HIST("eventcount_mixed"), bin); + fillCorrelations(mixed, tracks1, tracks2, collision1.multiplicity(), collision1.posZ(), field, eventWeight); + + if (cfg.mEfficiencyAssociated || cfg.mEfficiencyTrigger) { + if (it.isNewWindow()) { + mixed->fillEvent(collision1.multiplicity(), CorrelationContainer::kCFStepCorrected); + } + fillCorrelations(mixed, tracks1, tracks2, collision1.multiplicity(), collision1.posZ(), field, eventWeight); + } + } + } + PROCESS_SWITCH(CorrelationTask, processMixed2ProngDerived, "Process mixed events on derived data", false); + // Version with combinations /*void processWithCombinations(soa::Join::iterator const& collision, aod::BCsWithTimestamps const&, soa::Filtered const& tracks) { diff --git a/PWGCF/TwoParticleCorrelations/Tasks/CMakeLists.txt b/PWGCF/TwoParticleCorrelations/Tasks/CMakeLists.txt index d00f92c540d..1d4a0295e64 100644 --- a/PWGCF/TwoParticleCorrelations/Tasks/CMakeLists.txt +++ b/PWGCF/TwoParticleCorrelations/Tasks/CMakeLists.txt @@ -13,3 +13,7 @@ o2physics_add_dpl_workflow(twopartcorr SOURCES twoParticleCorrelations.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::TwoPartCorrCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(r2p24id + SOURCES r2p2-4-id.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/TwoParticleCorrelations/Tasks/r2p2-4-id.cxx b/PWGCF/TwoParticleCorrelations/Tasks/r2p2-4-id.cxx new file mode 100644 index 00000000000..017fdaebe86 --- /dev/null +++ b/PWGCF/TwoParticleCorrelations/Tasks/r2p2-4-id.cxx @@ -0,0 +1,451 @@ +// 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. + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/PIDResponse.h" +#include "Framework/ASoAHelpers.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +//-----PID Functions----------------------------------------------------------- +template +bool NO_PID(T track) +{ + return true; +} +template +bool PID_PION(T track) +{ + float tpccut = 2.5, tofcut = 2.5; + if (fabs(track.tpcNSigmaPi()) >= tpccut) + return false; + if (track.pt() >= 0.6) { + if (track.hasTOF()) { + if (fabs(track.tofNSigmaPi()) >= tofcut) + return false; + } else { + return false; + } + } + return true; +} +template +bool PID_KAON(T track) +{ + float tpccut = 2, tofcut = 2; + if (track.pt() < 0.6) { + if (track.pt() < 0.45) + tpccut = 2; + else if (track.pt() < 0.55) + tpccut = 1; + else + tpccut = 0.6; + if (fabs(track.tpcNSigmaKa()) > tpccut) + return false; + } else if (track.hasTOF()) { + if ((fabs(track.tpcNSigmaKa()) > tpccut) || (fabs(track.tofNSigmaKa()) > tofcut)) + return false; + } else { + return false; + } + return true; +} +template +bool PID_PROTON(T track) +{ + float tpccut = 2.2, tofcut = 2; + if (track.pt() < 1.1) { + if (track.pt() < 0.85) + tpccut = 2.2; + else + tpccut = 1; + if (fabs(track.tpcNSigmaPr()) > tpccut) + return false; + } else if (track.hasTOF()) { + if ((fabs(track.tpcNSigmaPr()) > tpccut) || (fabs(track.tofNSigmaPr()) > tofcut)) + return false; + } else { + return false; + } + return true; +} +//----------------------------------------------------------------------------- +template +bool (*pidarray[4])(T) = {NO_PID, PID_PION, PID_KAON, PID_PROTON}; // Array of PID functions + +namespace o2::aod +{ +namespace idr2p2columns +{ +DECLARE_SOA_COLUMN(BinNPIDFlag, binNpid, int8_t); // Flag tracks without proper binning as -1, and indicate type of particle 0->un-Id, 1->pion, 2->kaon, 3->proton +} // namespace idr2p2columns +DECLARE_SOA_TABLE(Flags, "AOD", "Flags", idr2p2columns::BinNPIDFlag); +} // namespace o2::aod +struct FillFlagsTable { + Produces ftable; + + void process(soa::Join const& tracks) + { + int etabin, phibin; + int8_t binNpid; + float nsigma_array[3]; + for (auto track : tracks) { + etabin = (track.eta() + 0.8) * 15; // 15= 24/1.6 + phibin = 36 * track.phi() / (2 * constants::math::PI); + if ((etabin < 0) || (etabin >= 24) || (phibin < 0) || (phibin >= 36)) { + binNpid = -1; + } else { + binNpid = 0; + for (int i = 0; i < 4; i++) { + if (pidarray[i](track)) + binNpid = binNpid * 10 + i; + if (binNpid > 10) // If a track is identified as two different tracks. + { + nsigma_array[0] = track.tpcNSigmaPi(); + nsigma_array[1] = track.tpcNSigmaKa(); + nsigma_array[2] = track.tpcNSigmaPr(); + if (fabs(nsigma_array[(binNpid / 10) - 1]) < fabs(nsigma_array[(binNpid % 10) - 1])) // The track is identified as the particle whose |nsigma| is the least. + binNpid /= 10; + else + binNpid %= 10; + } + } + } + ftable(binNpid); + } + } +}; +struct r2p24id { + Configurable minpT{"minpT", 0.2, "Minimum pT"}; + Configurable maxpT{"maxpT", 2.0, "Maximum pT"}; + //-----Track&Event Selection------------------------------------------------- + Filter col = aod::evsel::sel8 == true; + Filter collisionFilter = (nabs(aod::collision::posZ) < 10.f); + Filter ptfilter = aod::track::pt > minpT&& aod::track::pt < maxpT; + Filter globalfilter = requireGlobalTrackInFilter(); + Filter properbinfilter = aod::idr2p2columns::binNpid != -1; + //--------------------------------------------------------------------------- + HistogramRegistry histos{"R2P2", {}, OutputObjHandlingPolicy::AnalysisObject}; + + struct histarray { + std::shared_ptr h2d_1p[4][2][2], h2d_2p[7][2][2][4]; + std::shared_ptr h1d_1p[4][2]; + } hist; + + void init(InitContext const&) + { + //-----Defining Histograms------------------------------------------------- + const AxisSpec phi{36, 0, 2.0 * constants::math::PI, "phi"}; + const AxisSpec eta{24, -0.8, 0.8, "eta"}; + const AxisSpec etaphi1{864, 0, 864, "etaphi1"}; + const AxisSpec etaphi2{864, 0, 864, "etaphi2"}; + char histname[50]; + char name[4][3] = {"ch", "pi", "ka", "pr"}; + + histos.add("h1d_n1_phi", "#phi distribution", kTH1D, {phi}); + histos.add("h1d_n1_eta", "#eta distribution", kTH1D, {eta}); + histos.add("h1d_n1_pt", "p_T", kTH1D, {{100, 0, 5, "p_T"}}); + histos.add("h1i_n1_multPM", "Multiplicity", kTH1I, {{200, 0, 200, "Multiplicity"}}); + + for (int i = 0; i < 7; i++) { + if (i < 4) { // Single particle distribution histograms + snprintf(histname, sizeof(histname), "h1d_n1_ptP_%s", name[i]); + histos.add(histname, "p_T for +ve particles", kTH1D, {{100, 0, 6, "p_T"}}); + snprintf(histname, sizeof(histname), "h1d_n1_ptM_%s", name[i]); + histos.add(histname, "p_T for -ve particles", kTH1D, {{100, 0, 6, "p_T"}}); + snprintf(histname, sizeof(histname), "h2d_n1_etaPhiP_%s", name[i]); + histos.add(histname, "#rho_1 for +ve particles", kTH2D, {eta, phi}); + snprintf(histname, sizeof(histname), "h2d_n1_etaPhiM_%s", name[i]); + histos.add(histname, "#rho_1 for -ve particles", kTH2D, {eta, phi}); + snprintf(histname, sizeof(histname), "h2d_pt_etaPhiP_%s", name[i]); + histos.add(histname, "p_T for +ve particles", kTH2D, {eta, phi}); + snprintf(histname, sizeof(histname), "h2d_pt_etaPhiM_%s", name[i]); + histos.add(histname, "p_T for -ve particles", kTH2D, {eta, phi}); + } + //---Two patricle distribution histograms-------------------------------- + int e = i, f = i; + if (i > 3) { + e = 1; + f = 3; + if (i == 4) + f = 2; + else if (i == 6) + e = 2; + // There are two kinds of "********PM_*" histograms here, one is for when track1 is +ve the other is for when track2 is +ve. + snprintf(histname, sizeof(histname), "h2d_n2_eta1Phi1Eta2Phi2PM_%s%s", name[e], name[f]); + histos.add(histname, "#rho_2 for +ve_1 -ve_2 particles", kTH2D, {etaphi1, etaphi2}); + snprintf(histname, sizeof(histname), "h2d_ptpt_eta1Phi1Eta2Phi2PM_%s%s", name[e], name[f]); + histos.add(histname, "p_Tp_T for +ve_1 -ve_2 particles", kTH2D, {etaphi1, etaphi2}); + snprintf(histname, sizeof(histname), "h2d_ptn_eta1Phi1Eta2Phi2PM_%s%s", name[e], name[f]); + histos.add(histname, "p_Tn for +ve_1 -ve_2 particles", kTH2D, {etaphi1, etaphi2}); + snprintf(histname, sizeof(histname), "h2d_npt_eta1Phi1Eta2Phi2PM_%s%s", name[e], name[f]); + histos.add(histname, "np_T for +ve_1 -ve_2 particles", kTH2D, {etaphi1, etaphi2}); + snprintf(histname, sizeof(histname), "h2d_n2_eta1Phi1Eta2Phi2PM_%s%s", name[f], name[e]); + histos.add(histname, "#rho_2 for -ve_1 +ve_2 particles", kTH2D, {etaphi1, etaphi2}); + snprintf(histname, sizeof(histname), "h2d_ptpt_eta1Phi1Eta2Phi2PM_%s%s", name[f], name[e]); + histos.add(histname, "p_Tp_T for -ve_1 +ve_2 particles", kTH2D, {etaphi1, etaphi2}); + snprintf(histname, sizeof(histname), "h2d_ptn_eta1Phi1Eta2Phi2PM_%s%s", name[f], name[e]); + histos.add(histname, "p_Tn for -ve_1 +ve_2 particles", kTH2D, {etaphi1, etaphi2}); + snprintf(histname, sizeof(histname), "h2d_npt_eta1Phi1Eta2Phi2PM_%s%s", name[f], name[e]); + histos.add(histname, "np_T for -ve_1 +ve_2 particles", kTH2D, {etaphi1, etaphi2}); + } else { + snprintf(histname, sizeof(histname), "h2d_n2_eta1Phi1Eta2Phi2PM_%s%s", name[e], name[f]); + histos.add(histname, "#rho_2 for +ve-ve particles", kTH2D, {etaphi1, etaphi2}); + snprintf(histname, sizeof(histname), "h2d_ptpt_eta1Phi1Eta2Phi2PM_%s%s", name[e], name[f]); + histos.add(histname, "p_Tp_T for +ve-ve particles", kTH2D, {etaphi1, etaphi2}); + snprintf(histname, sizeof(histname), "h2d_ptn_eta1Phi1Eta2Phi2PM_%s%s", name[e], name[f]); + histos.add(histname, "p_Tn for +ve-ve particles", kTH2D, {etaphi1, etaphi2}); + snprintf(histname, sizeof(histname), "h2d_npt_eta1Phi1Eta2Phi2PM_%s%s", name[e], name[f]); + histos.add(histname, "np_T for +ve-ve particles", kTH2D, {etaphi1, etaphi2}); + } + snprintf(histname, sizeof(histname), "h2d_n2_eta1Phi1Eta2Phi2PP_%s%s", name[e], name[f]); + histos.add(histname, "#rho_2 for +ve+ve particles", kTH2D, {etaphi1, etaphi2}); + snprintf(histname, sizeof(histname), "h2d_n2_eta1Phi1Eta2Phi2MM_%s%s", name[e], name[f]); + histos.add(histname, "#rho_2 for -ve-ve particles", kTH2D, {etaphi1, etaphi2}); + snprintf(histname, sizeof(histname), "h2d_ptpt_eta1Phi1Eta2Phi2PP_%s%s", name[e], name[f]); + histos.add(histname, "p_Tp_T for +ve+ve particles", kTH2D, {etaphi1, etaphi2}); + snprintf(histname, sizeof(histname), "h2d_ptpt_eta1Phi1Eta2Phi2MM_%s%s", name[e], name[f]); + histos.add(histname, "p_Tp_T for -ve-ve particles", kTH2D, {etaphi1, etaphi2}); + snprintf(histname, sizeof(histname), "h2d_ptn_eta1Phi1Eta2Phi2PP_%s%s", name[e], name[f]); + histos.add(histname, "p_Tn for +ve+ve particles", kTH2D, {etaphi1, etaphi2}); + snprintf(histname, sizeof(histname), "h2d_ptn_eta1Phi1Eta2Phi2MM_%s%s", name[e], name[f]); + histos.add(histname, "p_Tn for -ve-ve particles", kTH2D, {etaphi1, etaphi2}); + snprintf(histname, sizeof(histname), "h2d_npt_eta1Phi1Eta2Phi2PP_%s%s", name[e], name[f]); + histos.add(histname, "np_T for +ve+ve particles", kTH2D, {etaphi1, etaphi2}); + snprintf(histname, sizeof(histname), "h2d_npt_eta1Phi1Eta2Phi2MM_%s%s", name[e], name[f]); + histos.add(histname, "np_T for -ve-ve particles", kTH2D, {etaphi1, etaphi2}); + //----------------------------------------------------------------------- + } + //------------------------------------------------------------------------- + //-----Assigning histogram pointers to an Array---------------------------- + //------Single Particle..........------------------------------------------ + hist.h1d_1p[0][0] = histos.template get(HIST("h1d_n1_ptM_ch")); + hist.h1d_1p[0][1] = histos.template get(HIST("h1d_n1_ptP_ch")); + hist.h2d_1p[0][0][0] = histos.template get(HIST("h2d_n1_etaPhiM_ch")); + hist.h2d_1p[0][0][1] = histos.template get(HIST("h2d_pt_etaPhiM_ch")); + hist.h2d_1p[0][1][0] = histos.template get(HIST("h2d_n1_etaPhiP_ch")); + hist.h2d_1p[0][1][1] = histos.template get(HIST("h2d_pt_etaPhiP_ch")); + + hist.h1d_1p[1][0] = histos.template get(HIST("h1d_n1_ptM_pi")); + hist.h1d_1p[1][1] = histos.template get(HIST("h1d_n1_ptP_pi")); + hist.h2d_1p[1][0][0] = histos.template get(HIST("h2d_n1_etaPhiM_pi")); + hist.h2d_1p[1][0][1] = histos.template get(HIST("h2d_pt_etaPhiM_pi")); + hist.h2d_1p[1][1][0] = histos.template get(HIST("h2d_n1_etaPhiP_pi")); + hist.h2d_1p[1][1][1] = histos.template get(HIST("h2d_pt_etaPhiP_pi")); + + hist.h1d_1p[2][0] = histos.template get(HIST("h1d_n1_ptM_ka")); + hist.h1d_1p[2][1] = histos.template get(HIST("h1d_n1_ptP_ka")); + hist.h2d_1p[2][0][0] = histos.template get(HIST("h2d_n1_etaPhiM_ka")); + hist.h2d_1p[2][0][1] = histos.template get(HIST("h2d_pt_etaPhiM_ka")); + hist.h2d_1p[2][1][0] = histos.template get(HIST("h2d_n1_etaPhiP_ka")); + hist.h2d_1p[2][1][1] = histos.template get(HIST("h2d_pt_etaPhiP_ka")); + + hist.h1d_1p[3][0] = histos.template get(HIST("h1d_n1_ptM_pr")); + hist.h1d_1p[3][1] = histos.template get(HIST("h1d_n1_ptP_pr")); + hist.h2d_1p[3][0][0] = histos.template get(HIST("h2d_n1_etaPhiM_pr")); + hist.h2d_1p[3][0][1] = histos.template get(HIST("h2d_pt_etaPhiM_pr")); + hist.h2d_1p[3][1][0] = histos.template get(HIST("h2d_n1_etaPhiP_pr")); + hist.h2d_1p[3][1][1] = histos.template get(HIST("h2d_pt_etaPhiP_pr")); + //------------------------------------------------------------------------- + //------Two Particle............------------------------------------------- + hist.h2d_2p[0][0][0][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2MM_chch")); + hist.h2d_2p[0][0][0][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2MM_chch")); + hist.h2d_2p[0][0][0][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2MM_chch")); + hist.h2d_2p[0][0][0][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2MM_chch")); + hist.h2d_2p[0][0][1][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PM_chch")); + hist.h2d_2p[0][0][1][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PM_chch")); + hist.h2d_2p[0][0][1][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PM_chch")); + hist.h2d_2p[0][0][1][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PM_chch")); + hist.h2d_2p[0][1][0][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PM_chch")); + hist.h2d_2p[0][1][0][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PM_chch")); + hist.h2d_2p[0][1][0][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PM_chch")); + hist.h2d_2p[0][1][0][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PM_chch")); + hist.h2d_2p[0][1][1][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PP_chch")); + hist.h2d_2p[0][1][1][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PP_chch")); + hist.h2d_2p[0][1][1][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PP_chch")); + hist.h2d_2p[0][1][1][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PP_chch")); + + hist.h2d_2p[1][0][0][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2MM_pipi")); + hist.h2d_2p[1][0][0][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2MM_pipi")); + hist.h2d_2p[1][0][0][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2MM_pipi")); + hist.h2d_2p[1][0][0][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2MM_pipi")); + hist.h2d_2p[1][0][1][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PM_pipi")); + hist.h2d_2p[1][0][1][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PM_pipi")); + hist.h2d_2p[1][0][1][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PM_pipi")); + hist.h2d_2p[1][0][1][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PM_pipi")); + hist.h2d_2p[1][1][0][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PM_pipi")); + hist.h2d_2p[1][1][0][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PM_pipi")); + hist.h2d_2p[1][1][0][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PM_pipi")); + hist.h2d_2p[1][1][0][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PM_pipi")); + hist.h2d_2p[1][1][1][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PP_pipi")); + hist.h2d_2p[1][1][1][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PP_pipi")); + hist.h2d_2p[1][1][1][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PP_pipi")); + hist.h2d_2p[1][1][1][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PP_pipi")); + + hist.h2d_2p[2][0][0][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2MM_kaka")); + hist.h2d_2p[2][0][0][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2MM_kaka")); + hist.h2d_2p[2][0][0][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2MM_kaka")); + hist.h2d_2p[2][0][0][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2MM_kaka")); + hist.h2d_2p[2][0][1][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PM_kaka")); + hist.h2d_2p[2][0][1][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PM_kaka")); + hist.h2d_2p[2][0][1][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PM_kaka")); + hist.h2d_2p[2][0][1][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PM_kaka")); + hist.h2d_2p[2][1][0][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PM_kaka")); + hist.h2d_2p[2][1][0][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PM_kaka")); + hist.h2d_2p[2][1][0][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PM_kaka")); + hist.h2d_2p[2][1][0][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PM_kaka")); + hist.h2d_2p[2][1][1][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PP_kaka")); + hist.h2d_2p[2][1][1][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PP_kaka")); + hist.h2d_2p[2][1][1][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PP_kaka")); + hist.h2d_2p[2][1][1][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PP_kaka")); + + hist.h2d_2p[3][0][0][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2MM_prpr")); + hist.h2d_2p[3][0][0][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2MM_prpr")); + hist.h2d_2p[3][0][0][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2MM_prpr")); + hist.h2d_2p[3][0][0][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2MM_prpr")); + hist.h2d_2p[3][0][1][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PM_prpr")); + hist.h2d_2p[3][0][1][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PM_prpr")); + hist.h2d_2p[3][0][1][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PM_prpr")); + hist.h2d_2p[3][0][1][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PM_prpr")); + hist.h2d_2p[3][1][0][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PM_prpr")); + hist.h2d_2p[3][1][0][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PM_prpr")); + hist.h2d_2p[3][1][0][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PM_prpr")); + hist.h2d_2p[3][1][0][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PM_prpr")); + hist.h2d_2p[3][1][1][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PP_prpr")); + hist.h2d_2p[3][1][1][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PP_prpr")); + hist.h2d_2p[3][1][1][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PP_prpr")); + hist.h2d_2p[3][1][1][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PP_prpr")); + + hist.h2d_2p[4][0][0][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2MM_pika")); + hist.h2d_2p[4][0][0][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2MM_pika")); + hist.h2d_2p[4][0][0][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2MM_pika")); + hist.h2d_2p[4][0][0][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2MM_pika")); + hist.h2d_2p[4][0][1][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PM_kapi")); + hist.h2d_2p[4][0][1][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PM_kapi")); + hist.h2d_2p[4][0][1][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PM_kapi")); + hist.h2d_2p[4][0][1][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PM_kapi")); + hist.h2d_2p[4][1][0][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PM_pika")); + hist.h2d_2p[4][1][0][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PM_pika")); + hist.h2d_2p[4][1][0][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PM_pika")); + hist.h2d_2p[4][1][0][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PM_pika")); + hist.h2d_2p[4][1][1][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PP_pika")); + hist.h2d_2p[4][1][1][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PP_pika")); + hist.h2d_2p[4][1][1][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PP_pika")); + hist.h2d_2p[4][1][1][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PP_pika")); + + hist.h2d_2p[5][0][0][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2MM_pipr")); + hist.h2d_2p[5][0][0][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2MM_pipr")); + hist.h2d_2p[5][0][0][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2MM_pipr")); + hist.h2d_2p[5][0][0][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2MM_pipr")); + hist.h2d_2p[5][0][1][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PM_prpi")); + hist.h2d_2p[5][0][1][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PM_prpi")); + hist.h2d_2p[5][0][1][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PM_prpi")); + hist.h2d_2p[5][0][1][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PM_prpi")); + hist.h2d_2p[5][1][0][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PM_pipr")); + hist.h2d_2p[5][1][0][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PM_pipr")); + hist.h2d_2p[5][1][0][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PM_pipr")); + hist.h2d_2p[5][1][0][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PM_pipr")); + hist.h2d_2p[5][1][1][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PP_pipr")); + hist.h2d_2p[5][1][1][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PP_pipr")); + hist.h2d_2p[5][1][1][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PP_pipr")); + hist.h2d_2p[5][1][1][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PP_pipr")); + + hist.h2d_2p[6][0][0][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2MM_kapr")); + hist.h2d_2p[6][0][0][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2MM_kapr")); + hist.h2d_2p[6][0][0][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2MM_kapr")); + hist.h2d_2p[6][0][0][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2MM_kapr")); + hist.h2d_2p[6][0][1][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PM_prka")); + hist.h2d_2p[6][0][1][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PM_prka")); + hist.h2d_2p[6][0][1][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PM_prka")); + hist.h2d_2p[6][0][1][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PM_prka")); + hist.h2d_2p[6][1][0][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PM_kapr")); + hist.h2d_2p[6][1][0][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PM_kapr")); + hist.h2d_2p[6][1][0][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PM_kapr")); + hist.h2d_2p[6][1][0][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PM_kapr")); + hist.h2d_2p[6][1][1][0] = histos.template get(HIST("h2d_n2_eta1Phi1Eta2Phi2PP_kapr")); + hist.h2d_2p[6][1][1][1] = histos.template get(HIST("h2d_npt_eta1Phi1Eta2Phi2PP_kapr")); + hist.h2d_2p[6][1][1][2] = histos.template get(HIST("h2d_ptn_eta1Phi1Eta2Phi2PP_kapr")); + hist.h2d_2p[6][1][1][3] = histos.template get(HIST("h2d_ptpt_eta1Phi1Eta2Phi2PP_kapr")); + //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + } + void process(soa::Filtered>::iterator const& filteredCollision, soa::Filtered> const& tracks) + { + int mult = 0; + int8_t pid1, pid2; + int sign1, sign2; + int etabin1, phibin1, etabin2, phibin2; + + for (auto track1 : tracks) { + + mult++; + histos.fill(HIST("h1d_n1_phi"), track1.phi()); + histos.fill(HIST("h1d_n1_eta"), track1.eta()); + histos.fill(HIST("h1d_n1_pt"), track1.pt()); + //---Single Particle Distribution---------------------------------------- + sign1 = (track1.sign() + 1) / 2; + pid1 = track1.binNpid(); + if (pid1 > 0) // Filling histograms for different particle species; pid1 = 0 means ch, 1->pi, 2->ka, 3->pr. + { + hist.h1d_1p[pid1][sign1]->Fill(track1.pt(), 1.0 / (2.0 * constants::math::PI * track1.pt())); // h1d_n1_pt* + hist.h2d_1p[pid1][sign1][0]->Fill(track1.eta(), track1.phi()); // h2d_n1_etaphi* + hist.h2d_1p[pid1][sign1][1]->Fill(track1.eta(), track1.phi(), track1.pt()); // h2d_pt_etaPhi* + } + hist.h1d_1p[0][sign1]->Fill(track1.pt(), 1.0 / (2.0 * constants::math::PI * track1.pt())); // h1d_n1_pt*ch + hist.h2d_1p[0][sign1][0]->Fill(track1.eta(), track1.phi()); // h2d_n1_etaphi*ch + hist.h2d_1p[0][sign1][1]->Fill(track1.eta(), track1.phi(), track1.pt()); // h2d_pt_etaPhi*ch + //----------------------------------------------------------------------- + etabin1 = (track1.eta() + 0.8) * 15; // 15= 24/1.6 + phibin1 = 36 * track1.phi() / (2 * constants::math::PI); + + for (auto track2 : tracks) { + + if (track1.index() == track2.index()) + continue; + etabin2 = (track2.eta() + 0.8) * 15; // 15= 24/1.6 + phibin2 = 36 * track2.phi() / (2 * constants::math::PI); + sign2 = (track2.sign() + 1) / 2; + pid2 = track2.binNpid(); + + //-----Two Particle Distribution--------------------------------------- + int i; + if ((pid1 > 0) && (pid2 >= pid1)) { + i = ((pid2 - pid1) / 2 + (pid2 - pid1) % 2); + i = i + (pid1 + pid2) * (1 + i) / 2; // This formula gives 1 for pipi, 2 for kaka, 3->prpr, 4->pik, 5->pip, 6->kp + + hist.h2d_2p[i][sign1][sign2][0]->Fill(36 * etabin1 + phibin1 + 0.5, 36 * etabin2 + phibin2 + 0.5); // h2d_n2_eta1Phi1Eta2Phi2* + hist.h2d_2p[i][sign1][sign2][1]->Fill(36 * etabin1 + phibin1 + 0.5, 36 * etabin2 + phibin2 + 0.5, track2.pt()); // h2d_npt_eta1Phi1Eta2Phi2* + hist.h2d_2p[i][sign1][sign2][2]->Fill(36 * etabin1 + phibin1 + 0.5, 36 * etabin2 + phibin2 + 0.5, track1.pt()); // h2d_ptn_eta1Phi1Eta2Phi2* + hist.h2d_2p[i][sign1][sign2][3]->Fill(36 * etabin1 + phibin1 + 0.5, 36 * etabin2 + phibin2 + 0.5, track1.pt() * track2.pt()); // h2d_ptpt_eta1Phi1Eta2Phi2* + } + hist.h2d_2p[0][sign1][sign2][0]->Fill(36 * etabin1 + phibin1 + 0.5, 36 * etabin2 + phibin2 + 0.5); // h2d_n2_eta1Phi1Eta2Phi2*chch + hist.h2d_2p[0][sign1][sign2][1]->Fill(36 * etabin1 + phibin1 + 0.5, 36 * etabin2 + phibin2 + 0.5, track2.pt()); // h2d_npt_eta1Phi1Eta2Phi2*chch + hist.h2d_2p[0][sign1][sign2][2]->Fill(36 * etabin1 + phibin1 + 0.5, 36 * etabin2 + phibin2 + 0.5, track1.pt()); // h2d_ptn_eta1Phi1Eta2Phi2*chch + hist.h2d_2p[0][sign1][sign2][3]->Fill(36 * etabin1 + phibin1 + 0.5, 36 * etabin2 + phibin2 + 0.5, track1.pt() * track2.pt()); // h2d_ptpt_eta1Phi1Eta2Phi2*chch + //--------------------------------------------------------------------- + } + } + histos.fill(HIST("h1i_n1_multPM"), mult); + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + }; +} diff --git a/PWGDQ/Core/CutsLibrary.cxx b/PWGDQ/Core/CutsLibrary.cxx index 65c7cdba7ea..3622f2b052d 100644 --- a/PWGDQ/Core/CutsLibrary.cxx +++ b/PWGDQ/Core/CutsLibrary.cxx @@ -420,6 +420,11 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } + if (!nameStr.compare("hasTOF")) { + cut->AddCut(GetAnalysisCut("hasTOF")); + return cut; + } + if (!nameStr.compare("PIDCalib")) { cut->AddCut(GetAnalysisCut("PIDStandardKine")); // standard kine cuts usually are applied via Filter in the task cut->AddCut(GetAnalysisCut("electronStandardQuality")); @@ -874,70 +879,112 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } - // 4 cuts to separate pos & neg tracks in pos & neg eta range - if (!nameStr.compare("lmee_posTrack_posEta_selection")) { - cut->AddCut(GetAnalysisCut("posTrack")); - cut->AddCut(GetAnalysisCut("posEtaSel")); - cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3")); - cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - return cut; - } + std::vector vecTypetrack; + vecTypetrack.emplace_back(""); // default TightGlobalTrackRun3 + vecTypetrack.emplace_back("_7ITSncls"); // default TightGlobalTrackRun3 but with 7 ITS clusters + vecTypetrack.emplace_back("_ITS"); // Ask only for ITS requirements + vecTypetrack.emplace_back("_ITSalone"); // Ask only for ITS requirements + ITSalone (no TPC matching) + vecTypetrack.emplace_back("_TPC"); // Ask only for TPC requirements + vecTypetrack.emplace_back("_TPCalone"); // Ask only for TPC requirements + TPCalone (no ITS matching) + vecTypetrack.emplace_back("_TPCnoTRD"); // Ask only for TPC requirements no TRD matching - if (!nameStr.compare("lmee_negTrack_posEta_selection")) { - cut->AddCut(GetAnalysisCut("negTrack")); - cut->AddCut(GetAnalysisCut("posEtaSel")); - cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3")); - cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - return cut; - } + // loop to define PID cuts with and without post calibration + for (int icase = 0; icase < vecTypetrack.size(); icase++) { + // 4 cuts to separate pos & neg tracks in pos & neg eta range + if (!nameStr.compare(Form("lmee_posTrack_posEta_selection%s", vecTypetrack.at(icase).Data()))) { + cut->AddCut(GetAnalysisCut("posTrack")); + cut->AddCut(GetAnalysisCut("posEtaSel")); + cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); + cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); + return cut; + } - if (!nameStr.compare("lmee_posTrack_negEta_selection")) { - cut->AddCut(GetAnalysisCut("posTrack")); - cut->AddCut(GetAnalysisCut("negEtaSel")); - cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3")); - cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - return cut; - } + if (!nameStr.compare(Form("lmee_negTrack_posEta_selection%s", vecTypetrack.at(icase).Data()))) { + cut->AddCut(GetAnalysisCut("negTrack")); + cut->AddCut(GetAnalysisCut("posEtaSel")); + cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); + cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); + return cut; + } - if (!nameStr.compare("lmee_negTrack_negEta_selection")) { - cut->AddCut(GetAnalysisCut("negTrack")); - cut->AddCut(GetAnalysisCut("negEtaSel")); - cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3")); - cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); - return cut; - } + if (!nameStr.compare(Form("lmee_posTrack_negEta_selection%s", vecTypetrack.at(icase).Data()))) { + cut->AddCut(GetAnalysisCut("posTrack")); + cut->AddCut(GetAnalysisCut("negEtaSel")); + cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); + cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); + return cut; + } - // 4 cuts to separate pos & neg tracks in pos & neg eta range low B field - if (!nameStr.compare("lmee_lowB_posTrack_posEta_selection")) { - cut->AddCut(GetAnalysisCut("posTrack")); - cut->AddCut(GetAnalysisCut("posEtaSel")); - cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3")); - cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - return cut; - } + if (!nameStr.compare(Form("lmee_negTrack_negEta_selection%s", vecTypetrack.at(icase).Data()))) { + cut->AddCut(GetAnalysisCut("negTrack")); + cut->AddCut(GetAnalysisCut("negEtaSel")); + cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); + cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); + return cut; + } - if (!nameStr.compare("lmee_lowB_negTrack_posEta_selection")) { - cut->AddCut(GetAnalysisCut("negTrack")); - cut->AddCut(GetAnalysisCut("posEtaSel")); - cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3")); - cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - return cut; - } + // 2 cuts to separate pos & neg tracks + if (!nameStr.compare(Form("lmee_posTrack_selection%s", vecTypetrack.at(icase).Data()))) { + cut->AddCut(GetAnalysisCut("posTrack")); + cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); + cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); + return cut; + } - if (!nameStr.compare("lmee_lowB_posTrack_negEta_selection")) { - cut->AddCut(GetAnalysisCut("posTrack")); - cut->AddCut(GetAnalysisCut("negEtaSel")); - cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3")); - cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - return cut; - } + if (!nameStr.compare(Form("lmee_negTrack_selection%s", vecTypetrack.at(icase).Data()))) { + cut->AddCut(GetAnalysisCut("negTrack")); + cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); + cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); + return cut; + } - if (!nameStr.compare("lmee_lowB_negTrack_negEta_selection")) { - cut->AddCut(GetAnalysisCut("negTrack")); - cut->AddCut(GetAnalysisCut("negEtaSel")); - cut->AddCut(GetAnalysisCut("TightGlobalTrackRun3")); - cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); - return cut; + // 4 cuts to separate pos & neg tracks in pos & neg eta range low B field + if (!nameStr.compare(Form("lmee_lowB_posTrack_posEta_selection%s", vecTypetrack.at(icase).Data()))) { + cut->AddCut(GetAnalysisCut("posTrack")); + cut->AddCut(GetAnalysisCut("posEtaSel")); + cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); + cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); + return cut; + } + + if (!nameStr.compare(Form("lmee_lowB_negTrack_posEta_selection%s", vecTypetrack.at(icase).Data()))) { + cut->AddCut(GetAnalysisCut("negTrack")); + cut->AddCut(GetAnalysisCut("posEtaSel")); + cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); + cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); + return cut; + } + + if (!nameStr.compare(Form("lmee_lowB_posTrack_negEta_selection%s", vecTypetrack.at(icase).Data()))) { + cut->AddCut(GetAnalysisCut("posTrack")); + cut->AddCut(GetAnalysisCut("negEtaSel")); + cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); + cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); + return cut; + } + + if (!nameStr.compare(Form("lmee_lowB_negTrack_negEta_selection%s", vecTypetrack.at(icase).Data()))) { + cut->AddCut(GetAnalysisCut("negTrack")); + cut->AddCut(GetAnalysisCut("negEtaSel")); + cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); + cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); + return cut; + } + + // 2 cuts to separate pos & neg tracks in low B field + if (!nameStr.compare(Form("lmee_lowB_posTrack_selection%s", vecTypetrack.at(icase).Data()))) { + cut->AddCut(GetAnalysisCut("posTrack")); + cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); + cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); + return cut; + } + + if (!nameStr.compare(Form("lmee_lowB_negTrack_selection%s", vecTypetrack.at(icase).Data()))) { + cut->AddCut(GetAnalysisCut("negTrack")); + cut->AddCut(GetAnalysisCut(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))); + cut->AddCut(GetAnalysisCut("standardPrimaryTrackDCAz")); + return cut; + } } std::vector vecPIDcase; @@ -1609,6 +1656,14 @@ AnalysisCompositeCut* o2::aod::dqcuts::GetCompositeCut(const char* cutName) return cut; } + if (!nameStr.compare(Form("lmee_skimmingtesta_TOF_pionrej%s", vecPIDcase.at(icase).Data()))) { + cut->AddCut(GetAnalysisCut("lmeeStandardKine")); + cut->AddCut(GetAnalysisCut("LooseGlobalTrackRun3")); + cut->AddCut(GetAnalysisCut("PrimaryTrack_looseDCA")); + cut->AddCut(GetAnalysisCut(Form("lmee_pp_502TeV_TOFloose_pionrej%s", vecPIDcase.at(icase).Data()))); + return cut; + } + // some older cuts if (!nameStr.compare(Form("lmee_pp502TeV_PID%s", vecPIDcase.at(icase).Data()))) { cut->AddCut(GetAnalysisCut("lmeeStandardKine")); @@ -2707,7 +2762,7 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } - if (!nameStr.compare("TightGlobalTrackRun3")) { + if ((!nameStr.compare("TightGlobalTrackRun3")) || (!nameStr.compare("lmeeQCTrackCuts"))) { cut->AddCut(VarManager::kIsSPDfirst, 0.5, 1.5); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); @@ -2717,6 +2772,53 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } + std::vector vecTypetrack; + vecTypetrack.emplace_back(""); // default TightGlobalTrackRun3 as above + vecTypetrack.emplace_back("_7ITSncls"); // default TightGlobalTrackRun3 but with 7 ITS clusters + vecTypetrack.emplace_back("_ITS"); // Ask only for ITS requirements + vecTypetrack.emplace_back("_ITSalone"); // Ask only for ITS requirements + ITSalone (no TPC matching) + vecTypetrack.emplace_back("_TPC"); // Ask only for TPC requirements + vecTypetrack.emplace_back("_TPCalone"); // Ask only for TPC requirements + TPCalone (no ITS matching) + vecTypetrack.emplace_back("_TPCnoTRD"); // Ask only for TPC requirements no TRD matching + + // loop to define PID cuts with and without post calibration + for (int icase = 1; icase < vecTypetrack.size(); icase++) { + if (!nameStr.compare(Form("lmeeQCTrackCuts%s", vecTypetrack.at(icase).Data()))) { + if (icase == 1) { + cut->AddCut(VarManager::kIsSPDfirst, 0.5, 1.5); + cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); + cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); + cut->AddCut(VarManager::kITSncls, 6.5, 7.5); + cut->AddCut(VarManager::kTPCnclsCR, 80.0, 161.); + cut->AddCut(VarManager::kTPCncls, 90.0, 170.); + } else if (icase == 2) { + cut->AddCut(VarManager::kIsSPDfirst, 0.5, 1.5); + cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); + cut->AddCut(VarManager::kITSncls, 4.5, 7.5); + } else if (icase == 3) { + cut->AddCut(VarManager::kIsSPDfirst, 0.5, 1.5); + cut->AddCut(VarManager::kITSchi2, 0.0, 5.0); + cut->AddCut(VarManager::kITSncls, 4.5, 7.5); + cut->AddCut(VarManager::kHasTPC, -0.5, 0.5); + } else if (icase == 4) { + cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); + cut->AddCut(VarManager::kTPCnclsCR, 80.0, 161.); + cut->AddCut(VarManager::kTPCncls, 90.0, 170.); + } else if (icase == 5) { + cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); + cut->AddCut(VarManager::kTPCnclsCR, 80.0, 161.); + cut->AddCut(VarManager::kTPCncls, 90.0, 170.); + cut->AddCut(VarManager::kHasITS, -0.5, 0.5); + } else { + cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); + cut->AddCut(VarManager::kTPCnclsCR, 80.0, 161.); + cut->AddCut(VarManager::kTPCncls, 90.0, 170.); + cut->AddCut(VarManager::kHasTRD, -0.5, 0.5); + } + return cut; + } + } + if (!nameStr.compare("LooseGlobalTrackRun3")) { cut->AddCut(VarManager::kIsSPDfirst, 0.5, 1.5); cut->AddCut(VarManager::kTPCchi2, 0.0, 4.0); @@ -2866,6 +2968,11 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) return cut; } + if (!nameStr.compare("hasTOF")) { + cut->AddCut(VarManager::kHasTOF, 0.5, 1.5); + return cut; + } + // ----------------------------------------------------- // V0 and Dalitz legs selections @@ -3679,6 +3786,21 @@ AnalysisCut* o2::aod::dqcuts::GetAnalysisCut(const char* cutName) } return cut; } + + if (!nameStr.compare(Form("lmee_pp_502TeV_TOFloose_pionrej%s", vecPIDcase.at(icase).Data()))) { + if (icase == 0) { + cut->AddCut(VarManager::kTPCnSigmaEl, -4., 4., false, VarManager::kPin, 0.0, 1e+10, false); + cut->AddCut(VarManager::kTPCnSigmaPi, -99., 3.5, true, VarManager::kPin, 0.0, 2.0, false); + cut->AddCut(VarManager::kTPCnSigmaPi, -99., 2.5, true, VarManager::kPin, 2.0, 1e+10, false); + cut->AddCut(VarManager::kTOFnSigmaEl, -4., 4., false, VarManager::kPin, 0.3, 1e+10, false); + } else if (icase == 1 || icase == 2) { + cut->AddCut(VarManager::kTPCnSigmaEl_Corr, -4., 4., false, VarManager::kPin, 0.0, 1e+10, false); + cut->AddCut(VarManager::kTPCnSigmaPi_Corr, -99., 3.5, true, VarManager::kPin, 0.0, 2.0, false); + cut->AddCut(VarManager::kTPCnSigmaPi_Corr, -99., 2.5, true, VarManager::kPin, 2.0, 1e+10, false); + cut->AddCut(VarManager::kTOFnSigmaEl, -4., 4., false, VarManager::kPin, 0.3, 1e+10, false); + } + return cut; + } } // ------------------------------------------------------------------------------------------------- diff --git a/PWGDQ/Core/HistogramsLibrary.cxx b/PWGDQ/Core/HistogramsLibrary.cxx index 55fb9b2300d..5f3bc1b2522 100644 --- a/PWGDQ/Core/HistogramsLibrary.cxx +++ b/PWGDQ/Core/HistogramsLibrary.cxx @@ -159,7 +159,7 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "Psi2B_CentFT0C", "", false, 90, 0.0, 90.0, VarManager::kCentFT0C, 100, -2.0, 2.0, VarManager::kPsi2B); hm->AddHistogram(histClass, "Psi2C_CentFT0C", "", false, 90, 0.0, 90.0, VarManager::kCentFT0C, 100, -2.0, 2.0, VarManager::kPsi2C); } - + if (subGroupStr.Contains("res")) { hm->AddHistogram(histClass, "R2SP_CentV0M", "", true, 9, 0.0, 90.0, VarManager::kCentVZERO, 100, -1.0, 1.0, VarManager::kR2SP); hm->AddHistogram(histClass, "R3SP_CentV0M", "", true, 9, 0.0, 90.0, VarManager::kCentVZERO, 100, -1.0, 1.0, VarManager::kR3SP); @@ -225,6 +225,9 @@ void o2::aod::dqhistograms::DefineHistograms(HistogramManager* hm, const char* h hm->AddHistogram(histClass, "ITSchi2_CentFT0C", "ITS chi2", false, 100, 0.0, 50.0, VarManager::kITSchi2, 20, 0.0, 100.0, VarManager::kCentFT0C); hm->AddHistogram(histClass, "ITSClusterMap_CentFT0C", "", false, 128, -0.5, 127.5, VarManager::kITSClusterMap, 20, 0.0, 100.0, VarManager::kCentFT0C); } + if (subGroupStr.Contains("clssize")) { + hm->AddHistogram(histClass, "ITSclssize_p", "Mean ITS cluster size vs P", false, 200, 0.0, 10.0, VarManager::kP, 150, 0.0, 15., VarManager::kITSmeanClsSize); + } } if (subGroupStr.Contains("itsvspt")) { hm->AddHistogram(histClass, "ITSncls_Pt", "Number of cluster in ITS vs Pt", false, 200, 0.0, 10.0, VarManager::kPt, 8, -0.5, 7.5, VarManager::kITSncls); diff --git a/PWGDQ/Core/VarManager.cxx b/PWGDQ/Core/VarManager.cxx index 3f8bef6fb58..f3f0fbe9ce9 100644 --- a/PWGDQ/Core/VarManager.cxx +++ b/PWGDQ/Core/VarManager.cxx @@ -378,6 +378,8 @@ void VarManager::SetDefaultVarNames() fgVariableUnits[kITSchi2] = ""; fgVariableNames[kITSlayerHit] = "ITS layer"; fgVariableUnits[kITSlayerHit] = ""; + fgVariableNames[kITSmeanClsSize] = "ITS mean Cls Size"; + fgVariableUnits[kITSmeanClsSize] = ""; fgVariableNames[kTPCncls] = "TPC #cls"; fgVariableUnits[kTPCncls] = ""; fgVariableNames[kTPCnclsCR] = "TPC #cls crossed rows"; diff --git a/PWGDQ/Core/VarManager.h b/PWGDQ/Core/VarManager.h index fa0bb6c9248..2b3164388e3 100644 --- a/PWGDQ/Core/VarManager.h +++ b/PWGDQ/Core/VarManager.h @@ -258,6 +258,7 @@ class VarManager : public TObject kITSncls, kITSchi2, kITSlayerHit, + kITSmeanClsSize, kIsTPCrefit, kTPCncls, kITSClusterMap, @@ -648,8 +649,8 @@ class VarManager : public TObject static void FillDileptonCharmHadron(DQ const& dilepton, HF const& charmHadron, H hfHelper, T& bdtScoreCharmHad, float* values = nullptr); template static void FillQVectorFromGFW(C const& collision, A const& compA2, A const& compB2, A const& compC2, A const& compA3, A const& compB3, A const& compC3, float normA = 1.0, float normB = 1.0, float normC = 1.0, float* values = nullptr); - //static void FillEventPlaneABC(A const& EpA, A const& EpB, A const& EpC, float* values = nullptr); - + // static void FillEventPlaneABC(A const& EpA, A const& EpB, A const& EpC, float* values = nullptr); + template static void FillPairVn(T1 const& t1, T2 const& t2, float* values = nullptr); @@ -838,12 +839,12 @@ void VarManager::FillPropagateMuon(const T& muon, const C& collision, float* val propmuon.setCovariances(proptrack.getCovariances()); } else if (static_cast(muon.trackType()) < 2) { - double centerMFT[3] = {0, 0, -61.4}; - o2::field::MagneticField* field = static_cast(TGeoGlobalMagField::Instance()->GetField()); - auto Bz = field->getBz(centerMFT); // Get field at centre of MFT + double x[3] = {0., 0., 0.}; + double b[3] = {0., 0., 0.}; + TGeoGlobalMagField::Instance()->Field(x, b); auto geoMan = o2::base::GeometryManager::meanMaterialBudget(muon.x(), muon.y(), muon.z(), collision.posX(), collision.posY(), collision.posZ()); auto x2x0 = static_cast(geoMan.meanX2X0); - fwdtrack.propagateToVtxhelixWithMCS(collision.posZ(), {collision.posX(), collision.posY()}, {collision.covXX(), collision.covYY()}, Bz, x2x0); + fwdtrack.propagateToVtxhelixWithMCS(collision.posZ(), {collision.posX(), collision.posY()}, {collision.covXX(), collision.covYY()}, b[2], x2x0); propmuon.setParameters(fwdtrack.getParameters()); propmuon.setZ(fwdtrack.getZ()); propmuon.setCovariances(fwdtrack.getCovariances()); @@ -1059,7 +1060,6 @@ void VarManager::FillEvent(T const& event, float* values) values[kPsi2A] = getEventPlane(2, event.q2x0a(), event.q2y0a()); values[kPsi2B] = getEventPlane(2, event.q2x0b(), event.q2y0b()); values[kPsi2C] = getEventPlane(2, event.q2x0c(), event.q2y0c()); - } if constexpr ((fillMap & CollisionMC) > 0) { @@ -1229,6 +1229,17 @@ void VarManager::FillTrack(T const& track, float* values) if (fgUsedVars[kITSncls]) { values[kITSncls] = track.itsNCls(); // dynamic column } + if (fgUsedVars[kITSmeanClsSize]) { + values[kITSmeanClsSize] = 0.0; + uint32_t clsizeflag = track.itsClusterSizes(); + float mcls = 0.; + for (unsigned int layer = 0; layer < 7; layer++) { + mcls += (clsizeflag >> (layer * 4)) & 0xF; + } + if (track.itsNCls() > 0) { + values[kITSmeanClsSize] = mcls / track.itsNCls(); + } + } } if constexpr ((fillMap & ReducedTrackBarrel) > 0) { if (fgUsedVars[kITSncls]) { @@ -2002,7 +2013,7 @@ void VarManager::FillPairVertexing(C const& collision, T const& t1, T const& t2, values[kVertexingLxyz] = 1.e-8f; values[kVertexingLxyzErr] = values[kVertexingLxyzErr] < 0. ? 1.e8f : std::sqrt(values[kVertexingLxyzErr]) / values[kVertexingLxyz]; values[kVertexingTauxy] = KFGeoTwoProng.GetPseudoProperDecayTime(KFPV, KFGeoTwoProng.GetMass()) / (o2::constants::physics::LightSpeedCm2NS); - values[kVertexingTauz] = dzPair2PV * KFGeoTwoProng.GetMass() / (TMath::Abs(KFGeoTwoProng.GetPz()) * o2::constants::physics::LightSpeedCm2NS); + values[kVertexingTauz] = -1 * dzPair2PV * KFGeoTwoProng.GetMass() / (TMath::Abs(KFGeoTwoProng.GetPz()) * o2::constants::physics::LightSpeedCm2NS); values[kVertexingTauxyErr] = values[kVertexingLxyErr] * KFGeoTwoProng.GetMass() / (KFGeoTwoProng.GetPt() * o2::constants::physics::LightSpeedCm2NS); values[kVertexingTauzErr] = values[kVertexingLzErr] * KFGeoTwoProng.GetMass() / (TMath::Abs(KFGeoTwoProng.GetPz()) * o2::constants::physics::LightSpeedCm2NS); values[kCosPointingAngle] = (std::sqrt(dxPair2PV * dxPair2PV) * v12.Px() + @@ -2077,6 +2088,15 @@ void VarManager::FillPairVertexing(C const& collision, T const& t1, T const& t2, float B[3]; float xyz[3] = {0, 0, 0}; KFGeoTwoProng.GetFieldValue(xyz, B); + // TODO: find better soluton to handle cases where KF outputs negative variances + float covXX = 0.1; + float covYY = 0.1; + if (KFGeoTwoProng.GetCovariance(0, 0) > 0) { + covXX = KFGeoTwoProng.GetCovariance(0, 0); + } + if (KFGeoTwoProng.GetCovariance(1, 1) > 0) { + covYY = KFGeoTwoProng.GetCovariance(0, 0); + } pars1.propagateToVtxhelixWithMCS(KFGeoTwoProng.GetZ(), {KFGeoTwoProng.GetX(), KFGeoTwoProng.GetY()}, {KFGeoTwoProng.GetCovariance(0, 0), KFGeoTwoProng.GetCovariance(1, 1)}, B[2], x2x01); pars2.propagateToVtxhelixWithMCS(KFGeoTwoProng.GetZ(), {KFGeoTwoProng.GetX(), KFGeoTwoProng.GetY()}, {KFGeoTwoProng.GetCovariance(0, 0), KFGeoTwoProng.GetCovariance(1, 1)}, B[2], x2x02); v1 = {pars1.getPt(), pars1.getEta(), pars1.getPhi(), m1}; @@ -2088,7 +2108,7 @@ void VarManager::FillPairVertexing(C const& collision, T const& t1, T const& t2, values[kPhi] = v12.Phi(); values[kRap] = -v12.Rapidity(); values[kVertexingTauxy] = KFGeoTwoProng.GetPseudoProperDecayTime(KFPV, v12.M()) / (o2::constants::physics::LightSpeedCm2NS); - values[kVertexingTauz] = dzPair2PV * v12.M() / (TMath::Abs(v12.Pz()) * o2::constants::physics::LightSpeedCm2NS); + values[kVertexingTauz] = -1 * dzPair2PV * v12.M() / (TMath::Abs(v12.Pz()) * o2::constants::physics::LightSpeedCm2NS); values[kVertexingTauxyErr] = values[kVertexingLxyErr] * v12.M() / (v12.Pt() * o2::constants::physics::LightSpeedCm2NS); values[kVertexingTauzErr] = values[kVertexingLzErr] * v12.M() / (TMath::Abs(v12.Pz()) * o2::constants::physics::LightSpeedCm2NS); @@ -2403,7 +2423,7 @@ void VarManager::FillQVectorFromGFW(C const& collision, A const& compA2, A const // TODO: provide different computations for R // Compute the R factor using the 2 sub-events technique for second and third harmonic - //Compute event planes + // Compute event planes auto Psi2B = getEventPlane(2, values[kQ2X0B], values[kQ2Y0B]); auto Psi3B = getEventPlane(3, values[kQ3X0B], values[kQ3Y0B]); auto Psi2C = getEventPlane(2, values[kQ2X0C], values[kQ2Y0C]); @@ -2459,7 +2479,7 @@ void VarManager::FillPairVn(T1 const& t1, T2 const& t2, float* values) values[kU3Q3] = values[kQ3X0A] * std::cos(3 * v12.Phi()) + values[kQ3Y0A] * std::sin(3 * v12.Phi()); values[kCos2DeltaPhi] = std::cos(2 * (v12.Phi() - getEventPlane(2, values[kQ2X0A], values[kQ2Y0A]))); values[kCos3DeltaPhi] = std::cos(3 * (v12.Phi() - getEventPlane(3, values[kQ3X0A], values[kQ3Y0A]))); - + if (isnan(VarManager::fgValues[VarManager::kU2Q2]) == true) { values[kU2Q2] = -999.; values[kU3Q3] = -999.; diff --git a/PWGDQ/DataModel/MchTrkEffTables.h b/PWGDQ/DataModel/MchTrkEffTables.h index 4ae92520ba5..3fbecfb619c 100644 --- a/PWGDQ/DataModel/MchTrkEffTables.h +++ b/PWGDQ/DataModel/MchTrkEffTables.h @@ -32,11 +32,12 @@ DECLARE_SOA_COLUMN(MchBitMap, mchBitMap, uint16_t); //! mch bit map DECLARE_SOA_COLUMN(EtaGen, etaGen, float); //! simulated eta DECLARE_SOA_COLUMN(PtGen, ptGen, float); //! simulated pt DECLARE_SOA_COLUMN(PhiGen, phiGen, float); //! simulated phi +DECLARE_SOA_COLUMN(TrackType, trackType, int); //! track type } // namespace mch_trk_eff // Table DECLARE_SOA_TABLE(MchTrkEffBase, "AOD", "MCHTRKEFFBASE", //! table with muon track properties and mch bit map - mch_trk_eff::Eta, mch_trk_eff::Pt, mch_trk_eff::Phi, mch_trk_eff::MchBitMap); + mch_trk_eff::Eta, mch_trk_eff::Pt, mch_trk_eff::Phi, mch_trk_eff::MchBitMap, mch_trk_eff::TrackType); DECLARE_SOA_TABLE(MchTrkEffGen, "AOD", "MCHTRKEFFGEN", //! table with simulated muon track properties mch_trk_eff::EtaGen, mch_trk_eff::PtGen, mch_trk_eff::PhiGen); diff --git a/PWGDQ/DataModel/ReducedInfoTables.h b/PWGDQ/DataModel/ReducedInfoTables.h index 8f9b24c7990..863df359bbb 100644 --- a/PWGDQ/DataModel/ReducedInfoTables.h +++ b/PWGDQ/DataModel/ReducedInfoTables.h @@ -267,11 +267,14 @@ namespace reducedmft DECLARE_SOA_INDEX_COLUMN(ReducedEvent, reducedevent); //! DECLARE_SOA_COLUMN(FilteringFlags, filteringFlags, uint8_t); //! -DECLARE_SOA_COLUMN(Pt, pt, float); //! -DECLARE_SOA_COLUMN(Eta, eta, float); //! -DECLARE_SOA_COLUMN(Phi, phi, float); //! -DECLARE_SOA_COLUMN(Sign, sign, int); //! +DECLARE_SOA_COLUMN(Pt, pt, float); //! +DECLARE_SOA_COLUMN(Eta, eta, float); //! +DECLARE_SOA_COLUMN(Phi, phi, float); //! +DECLARE_SOA_COLUMN(Sign, sign, int); //! +DECLARE_SOA_COLUMN(FwdDcaX, fwdDcaX, float); //! +DECLARE_SOA_COLUMN(FwdDcaY, fwdDcaY, float); //! DECLARE_SOA_COLUMN(MftClusterSizesAndTrackFlags, mftClusterSizesAndTrackFlags, uint64_t); //! +DECLARE_SOA_COLUMN(MftNClusters, mftNClusters, int); //! } // namespace reducedmft // MFT track kinematics @@ -281,7 +284,8 @@ DECLARE_SOA_TABLE(ReducedMFTTracks, "AOD", "RMFTTR", //! // MFT tracks extra info (cluster size, sign) DECLARE_SOA_TABLE(ReducedMFTTracksExtra, "AOD", "RMFTTREXTRA", //! - reducedmft::MftClusterSizesAndTrackFlags, reducedmft::Sign); + reducedmft::MftClusterSizesAndTrackFlags, reducedmft::Sign, + reducedmft::FwdDcaX, reducedmft::FwdDcaY, reducedmft::MftNClusters); // iterator using ReducedMFTTrack = ReducedMFTTracks::iterator; @@ -318,7 +322,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(MIDBoardCh3, midBoardCh3, //! DECLARE_SOA_DYNAMIC_COLUMN(MIDBoardCh4, midBoardCh4, //! [](uint32_t midBoards) -> int { return static_cast((midBoards >> 24) & 0xFF); }); DECLARE_SOA_SELF_INDEX_COLUMN_FULL(MCHTrack, matchMCHTrack, int, "RTMuons_MatchMCHTrack"); -DECLARE_SOA_SELF_INDEX_COLUMN_FULL(ReducedMFTTrack, matchMFTTrack, int, "RTMuons_MatchMFTTrack"); //! matching index pointing to the ReducedMFTTrack table if filled +DECLARE_SOA_INDEX_COLUMN(ReducedMFTTrack, matchMFTTrack); //! matching index pointing to the ReducedMFTTrack table if filled } // namespace reducedmuon // Muon track kinematics @@ -438,30 +442,30 @@ DECLARE_SOA_COLUMN(FwdDcaY2, fwdDcaY2, float); //! Y component of forward DCA // pair information namespace reducedpair { -DECLARE_SOA_INDEX_COLUMN(ReducedEvent, reducedevent); //! -DECLARE_SOA_COLUMN(Mass, mass, float); //! -DECLARE_SOA_COLUMN(Pt, pt, float); //! -DECLARE_SOA_COLUMN(Eta, eta, float); //! -DECLARE_SOA_COLUMN(Phi, phi, float); //! -DECLARE_SOA_COLUMN(Sign, sign, int); //! -DECLARE_SOA_COLUMN(FilterMap, filterMap, uint32_t); //! -DECLARE_SOA_COLUMN(McDecision, mcDecision, uint32_t); //! -DECLARE_SOA_COLUMN(Tauz, tauz, float); //! Longitudinal pseudo-proper time of lepton pair (in ns) -DECLARE_SOA_COLUMN(TauzErr, tauzErr, float); //! Error on longitudinal pseudo-proper time of lepton pair (in ns) -DECLARE_SOA_COLUMN(Tauxy, tauxy, float); //! Transverse pseudo-proper time of lepton pair (in ns) -DECLARE_SOA_COLUMN(TauxyErr, tauxyErr, float); //! Error on transverse pseudo-proper time of lepton pair (in ns) -DECLARE_SOA_COLUMN(Lz, lz, float); //! Longitudinal projection of decay length -DECLARE_SOA_COLUMN(Lxy, lxy, float); //! Transverse projection of decay length -DECLARE_SOA_COLUMN(Chi2pca, chi2pca, float); //! Chi2 for PCA of the dilepton +DECLARE_SOA_INDEX_COLUMN(ReducedEvent, reducedevent); //! +DECLARE_SOA_COLUMN(Mass, mass, float); //! +DECLARE_SOA_COLUMN(Pt, pt, float); //! +DECLARE_SOA_COLUMN(Eta, eta, float); //! +DECLARE_SOA_COLUMN(Phi, phi, float); //! +DECLARE_SOA_COLUMN(Sign, sign, int); //! +DECLARE_SOA_COLUMN(FilterMap, filterMap, uint32_t); //! +DECLARE_SOA_COLUMN(McDecision, mcDecision, uint32_t); //! +DECLARE_SOA_COLUMN(Tauz, tauz, float); //! Longitudinal pseudo-proper time of lepton pair (in ns) +DECLARE_SOA_COLUMN(TauzErr, tauzErr, float); //! Error on longitudinal pseudo-proper time of lepton pair (in ns) +DECLARE_SOA_COLUMN(Tauxy, tauxy, float); //! Transverse pseudo-proper time of lepton pair (in ns) +DECLARE_SOA_COLUMN(TauxyErr, tauxyErr, float); //! Error on transverse pseudo-proper time of lepton pair (in ns) +DECLARE_SOA_COLUMN(Lz, lz, float); //! Longitudinal projection of decay length +DECLARE_SOA_COLUMN(Lxy, lxy, float); //! Transverse projection of decay length +DECLARE_SOA_COLUMN(Chi2pca, chi2pca, float); //! Chi2 for PCA of the dilepton DECLARE_SOA_COLUMN(CosPointingAngle, cosPointingAngle, float); //! Cosine of the pointing angle -DECLARE_SOA_COLUMN(U2Q2, u2q2, float); //! Scalar product between unitary vector with event flow vector (harmonic 2) -DECLARE_SOA_COLUMN(U3Q3, u3q3, float); //! Scalar product between unitary vector with event flow vector (harmonic 3) -DECLARE_SOA_COLUMN(Cos2DeltaPhi, cos2deltaphi, float); //! Cosinus term using event plane angle (harmonic 2) -DECLARE_SOA_COLUMN(Cos3DeltaPhi, cos3deltaphi, float); //! Cosinus term using event plane angle (harmonic 3) -DECLARE_SOA_COLUMN(Psi2A, psi2a, float); //! Event plane for sub-sample A -DECLARE_SOA_COLUMN(Psi2B, psi2b, float); //! Event plane for sub-sample B -DECLARE_SOA_COLUMN(Psi2C, psi2c, float); //! Event plane for sub-sample C -DECLARE_SOA_COLUMN(CollisionId, collisionId, int); //! +DECLARE_SOA_COLUMN(U2Q2, u2q2, float); //! Scalar product between unitary vector with event flow vector (harmonic 2) +DECLARE_SOA_COLUMN(U3Q3, u3q3, float); //! Scalar product between unitary vector with event flow vector (harmonic 3) +DECLARE_SOA_COLUMN(Cos2DeltaPhi, cos2deltaphi, float); //! Cosinus term using event plane angle (harmonic 2) +DECLARE_SOA_COLUMN(Cos3DeltaPhi, cos3deltaphi, float); //! Cosinus term using event plane angle (harmonic 3) +DECLARE_SOA_COLUMN(Psi2A, psi2a, float); //! Event plane for sub-sample A +DECLARE_SOA_COLUMN(Psi2B, psi2b, float); //! Event plane for sub-sample B +DECLARE_SOA_COLUMN(Psi2C, psi2c, float); //! Event plane for sub-sample C +DECLARE_SOA_COLUMN(CollisionId, collisionId, int); //! // DECLARE_SOA_INDEX_COLUMN(ReducedMuon, reducedmuon2); //! DECLARE_SOA_DYNAMIC_COLUMN(Px, px, //! [](float pt, float phi) -> float { return pt * std::cos(phi); }); @@ -500,8 +504,7 @@ DECLARE_SOA_TABLE(DileptonsFlow, "AOD", "RTDILEPTONFLOW", //! reducedpair::Cos3DeltaPhi, reducedpair::Psi2A, reducedpair::Psi2B, - reducedpair::Psi2C - ); + reducedpair::Psi2C); // Dilepton collision information (joined with DileptonsExtra) allowing to connect different tables (cross PWGs) DECLARE_SOA_TABLE(DileptonsInfo, "AOD", "RTDILEPTONINFO", @@ -534,8 +537,7 @@ DECLARE_SOA_TABLE(DimuonsAll, "AOD", "RTDIMUONALL", //! reducedpair::Cos3DeltaPhi, reducedpair::Psi2A, reducedpair::Psi2B, - reducedpair::Psi2C - ); + reducedpair::Psi2C); using Dilepton = Dileptons::iterator; using DileptonExtra = DileptonsExtra::iterator; @@ -543,6 +545,23 @@ using DileptonFlow = DileptonsFlow::iterator; using DileptonInfo = DileptonsInfo::iterator; using DimuonAll = DimuonsAll::iterator; +// mft PID reduced data model +namespace fwdpid +{ +DECLARE_SOA_COLUMN(Pt, pt, float); //! +DECLARE_SOA_COLUMN(Eta, eta, float); //! +DECLARE_SOA_COLUMN(Phi, phi, float); //! +DECLARE_SOA_COLUMN(Sign, sign, int); //! +} // namespace fwdpid + +DECLARE_SOA_TABLE(FwdPidsAll, "AOD", "RTFWDPIDALL", //! + fwdtrack::TrackType, collision::PosX, collision::PosY, collision::PosZ, collision::NumContrib, + fwdpid::Pt, fwdpid::Eta, fwdpid::Phi, fwdpid::Sign, + reducedmft::MftClusterSizesAndTrackFlags, + reducedmft::FwdDcaX, reducedmft::FwdDcaY, fwdtrack::Chi2MatchMCHMID, fwdtrack::Chi2MatchMCHMFT); + +using FwdPidAll = FwdPidsAll::iterator; + // candidate information namespace dileptonTrackCandidate { diff --git a/PWGDQ/TableProducer/tableMaker.cxx b/PWGDQ/TableProducer/tableMaker.cxx index 6baa6fdc067..7ee931a7d31 100644 --- a/PWGDQ/TableProducer/tableMaker.cxx +++ b/PWGDQ/TableProducer/tableMaker.cxx @@ -364,13 +364,13 @@ struct TableMaker { o2::base::Propagator::initFieldFromGRP(grpmagrun2); } } else { - if (fPropMuon) { - VarManager::SetupMuonMagField(); - } grpmag = fCCDB->getForTimeStamp(grpmagPath, bc.timestamp()); if (grpmag != nullptr) { o2::base::Propagator::initFieldFromGRP(grpmag); } + if (fPropMuon) { + VarManager::SetupMuonMagField(); + } } fCurrentRun = bc.runNumber(); @@ -587,11 +587,21 @@ struct TableMaker { mftOffsets[mft.globalIndex()] = mft.offsets(); + double chi2 = mft.chi2(); + SMatrix5 tpars(mft.x(), mft.y(), mft.phi(), mft.tgl(), mft.signed1Pt()); + std::vector v1; + SMatrix55 tcovs(v1.begin(), v1.end()); + o2::track::TrackParCovFwd pars1{mft.z(), tpars, tcovs, chi2}; + pars1.propagateToZlinear(collision.posZ()); + + double dcaX = (pars1.getX() - collision.posX()); + double dcaY = (pars1.getY() - collision.posY()); + VarManager::FillTrack(mft); fHistMan->FillHistClass("MftTracks", VarManager::fgValues); trackMFT(event.lastIndex(), trackFilteringTag, mft.pt(), mft.eta(), mft.phi()); - trackMFTExtra(mft.mftClusterSizesAndTrackFlags(), mft.sign()); + trackMFTExtra(mft.mftClusterSizesAndTrackFlags(), mft.sign(), dcaX, dcaY, mft.nClusters()); } // end of mft : mftTracks } // end if constexpr (TMFTFillMap) @@ -738,14 +748,34 @@ struct TableMaker { void fullSkimmingIndices(TEvent const& collision, aod::BCsWithTimestamps const&, TTracks const& tracksBarrel, TMuons const& tracksMuon, AssocTracks const& trackIndices, AssocMuons const& fwdtrackIndices) { auto bc = collision.template bc_as(); - if (fConfigComputeTPCpostCalib && fCurrentRun != bc.runNumber()) { - auto calibList = fCCDB->getForTimeStamp(fConfigCcdbPathTPC.value, bc.timestamp()); - VarManager::SetCalibrationObject(VarManager::kTPCElectronMean, calibList->FindObject("mean_map_electron")); - VarManager::SetCalibrationObject(VarManager::kTPCElectronSigma, calibList->FindObject("sigma_map_electron")); - VarManager::SetCalibrationObject(VarManager::kTPCPionMean, calibList->FindObject("mean_map_pion")); - VarManager::SetCalibrationObject(VarManager::kTPCPionSigma, calibList->FindObject("sigma_map_pion")); - VarManager::SetCalibrationObject(VarManager::kTPCProtonMean, calibList->FindObject("mean_map_proton")); - VarManager::SetCalibrationObject(VarManager::kTPCProtonSigma, calibList->FindObject("sigma_map_proton")); + if (fCurrentRun != bc.runNumber()) { + if (fConfigComputeTPCpostCalib) { + auto calibList = fCCDB->getForTimeStamp(fConfigCcdbPathTPC.value, bc.timestamp()); + VarManager::SetCalibrationObject(VarManager::kTPCElectronMean, calibList->FindObject("mean_map_electron")); + VarManager::SetCalibrationObject(VarManager::kTPCElectronSigma, calibList->FindObject("sigma_map_electron")); + VarManager::SetCalibrationObject(VarManager::kTPCPionMean, calibList->FindObject("mean_map_pion")); + VarManager::SetCalibrationObject(VarManager::kTPCPionSigma, calibList->FindObject("sigma_map_pion")); + VarManager::SetCalibrationObject(VarManager::kTPCProtonMean, calibList->FindObject("mean_map_proton")); + VarManager::SetCalibrationObject(VarManager::kTPCProtonSigma, calibList->FindObject("sigma_map_proton")); + if (fConfigComputeTPCpostCalibKaon) { + VarManager::SetCalibrationObject(VarManager::kTPCKaonMean, calibList->FindObject("mean_map_kaon")); + VarManager::SetCalibrationObject(VarManager::kTPCKaonSigma, calibList->FindObject("sigma_map_kaon")); + } + } + if (fIsRun2 == true) { + grpmagrun2 = fCCDB->getForTimeStamp(grpmagPathRun2, bc.timestamp()); + if (grpmagrun2 != nullptr) { + o2::base::Propagator::initFieldFromGRP(grpmagrun2); + } + } else { + grpmag = fCCDB->getForTimeStamp(grpmagPath, bc.timestamp()); + if (grpmag != nullptr) { + o2::base::Propagator::initFieldFromGRP(grpmag); + } + if (fPropMuon) { + VarManager::SetupMuonMagField(); + } + } fCurrentRun = bc.runNumber(); } @@ -1155,6 +1185,13 @@ struct TableMaker { fullSkimming(collision, bcs, tracksBarrel, tracksMuon, nullptr, nullptr); } + // Produce barrel + muon tables, with covariance, centrality and multiplicity --------------------------------------------------------------------------- + void processFullWithCovCentAndMults(MyEventsWithCentAndMults::iterator const& collision, aod::BCsWithTimestamps const& bcs, + soa::Filtered const& tracksBarrel, soa::Filtered const& tracksMuon) + { + fullSkimming(collision, bcs, tracksBarrel, tracksMuon, nullptr, nullptr); + } + // Produce barrel + muon tables, with track covariance matrix and event filtering ---------------------------------------------------------------------------------------- void processFullWithCovAndEventFilter(MyEventsWithFilter::iterator const& collision, aod::BCsWithTimestamps const& bcs, soa::Filtered const& tracksBarrel, soa::Filtered const& tracksMuon) @@ -1335,6 +1372,12 @@ struct TableMaker { fullSkimming(collision, bcs, nullptr, tracksMuon, nullptr, nullptr); } + // Produce muon tables only, with muon cov matrix and multiplicity----------------------------------------------------------------------------------- + void processMuonOnlyWithCovAndMults(MyEventsWithMults::iterator const& collision, aod::BCsWithTimestamps const& bcs, + soa::Filtered const& tracksMuon) + { + fullSkimming(collision, bcs, nullptr, tracksMuon, nullptr, nullptr); + } // Produce muon tables only, with muon cov matrix, with event filtering -------------------------------------------------------------------------------------------- void processMuonOnlyWithCovAndEventFilter(MyEventsWithFilter::iterator const& collision, aod::BCsWithTimestamps const& bcs, soa::Filtered const& tracksMuon) @@ -1514,6 +1557,7 @@ struct TableMaker { PROCESS_SWITCH(TableMaker, processFullWithCovMultsAndEventFilter, "Build full DQ skimmed data model, w/ track and fwdtrack covariance tables, w/ event filter and multiplicities", false); PROCESS_SWITCH(TableMaker, processFullWithCent, "Build full DQ skimmed data model, w/ centrality", false); PROCESS_SWITCH(TableMaker, processFullWithCentAndMults, "Build full DQ skimmed data model, w/ centrality and multiplicities", false); + PROCESS_SWITCH(TableMaker, processFullWithCovCentAndMults, "Build full DQ skimmed data model, w/ centrality, multiplicities and track covariances", false); PROCESS_SWITCH(TableMaker, processBarrelOnlyWithV0Bits, "Build full DQ skimmed data model, w/o centrality, w/ V0Bits", false); PROCESS_SWITCH(TableMaker, processBarrelOnlyWithV0BitsAndMaps, "Build full DQ skimmed data model, w/o multiplicity, w/ V0Bits", false); PROCESS_SWITCH(TableMaker, processBarrelOnlyWithDalitzBits, "Build barrel-only DQ skimmed data model, w/o centrality, w/ DalitzBits", false); @@ -1533,6 +1577,7 @@ struct TableMaker { PROCESS_SWITCH(TableMaker, processMuonOnlyWithCentAndMults, "Build muon-only DQ skimmed data model, w/ centrality and multiplicities", false); PROCESS_SWITCH(TableMaker, processMuonOnlyWithCovAndCent, "Build muon-only DQ skimmed data model, w/ centrality and muon cov matrix", false); PROCESS_SWITCH(TableMaker, processMuonOnlyWithCov, "Build muon-only DQ skimmed data model, w/ muon cov matrix", false); + PROCESS_SWITCH(TableMaker, processMuonOnlyWithCovAndMults, "Build muon-only DQ skimmed data model, w/ muon cov matrix and multiplicity", false); PROCESS_SWITCH(TableMaker, processMuonOnlyWithCovAndEventFilter, "Build muon-only DQ skimmed data model, w/ muon cov matrix, w/ event filter", false); PROCESS_SWITCH(TableMaker, processMuonOnly, "Build muon-only DQ skimmed data model", false); PROCESS_SWITCH(TableMaker, processMuonOnlyWithEventFilter, "Build muon-only DQ skimmed data model, w/ event filter", false); diff --git a/PWGDQ/TableProducer/tableMakerMC.cxx b/PWGDQ/TableProducer/tableMakerMC.cxx index 08dfe3d60c7..17519bc0769 100644 --- a/PWGDQ/TableProducer/tableMakerMC.cxx +++ b/PWGDQ/TableProducer/tableMakerMC.cxx @@ -371,13 +371,13 @@ struct TableMakerMC { o2::base::Propagator::initFieldFromGRP(grpmagrun2); } } else { - if (fPropMuon) { - VarManager::SetupMuonMagField(); - } grpmag = fCCDB->getForTimeStamp(grpmagPath, bc.timestamp()); if (grpmag != nullptr) { o2::base::Propagator::initFieldFromGRP(grpmag); } + if (fPropMuon) { + VarManager::SetupMuonMagField(); + } } fCurrentRun = bc.runNumber(); } diff --git a/PWGDQ/TableProducer/tableMakerMuonMchTrkEfficiency.cxx b/PWGDQ/TableProducer/tableMakerMuonMchTrkEfficiency.cxx index e6b8899b1da..123ad96fa16 100644 --- a/PWGDQ/TableProducer/tableMakerMuonMchTrkEfficiency.cxx +++ b/PWGDQ/TableProducer/tableMakerMuonMchTrkEfficiency.cxx @@ -107,9 +107,10 @@ struct tableMakerMuonMchTrkEfficiency { Configurable fConfigEventCuts{"cfgEventCuts", "eventStandard", "Event selection"}; /// Event selection list Configurable fConfigMuonCuts{"cfgMuonCuts", "muonQualityCuts", "Comma separated list of muon cuts"}; /// List of muon selections /// - Configurable ptMuonMin{"ptMin", 0., "Lower bound of pT"}; /// Muon minimum pt to be studied - Configurable etaMuonMin{"etaMin", 2.5, "Lower bound of |eta|"}; /// Muon minimum |eta| to be studied - Configurable etaMuonMax{"etaMax", 4.0, "Upper bound of |eta|"}; /// Muon maximum |eta| to be studied + Configurable muonSelType{"muonSelType", -1, "Selected muon track type"}; /// Muon track type to be selected if value >=0 (no selection by default) + Configurable ptMuonMin{"ptMin", 0., "Lower bound of pT"}; /// Muon minimum pt to be studied + Configurable etaMuonMin{"etaMin", 2.5, "Lower bound of |eta|"}; /// Muon minimum |eta| to be studied + Configurable etaMuonMax{"etaMax", 4.0, "Upper bound of |eta|"}; /// Muon maximum |eta| to be studied /// Configurable> binsMuonPt{"binsPt", std::vector{muon_trk_eff_bins::vecBinsPt}, "pT bin limits"}; /// Pt intervals for the histograms Configurable nEtaBins{"nEtaBins", 12, "Number of Eta bins"}; /// Number of eta bins for output histograms @@ -420,6 +421,7 @@ struct tableMakerMuonMchTrkEfficiency { VarManager::FillTrack(muon); LOGF(debug, " %i / %f / %f / %f", muon.trackType(), muon.eta(), muon.pt(), muon.p()); + int mType = muon.trackType(); double mPt = muon.pt(); double mEta = TMath::Abs(muon.eta()); double mPhi = muon.phi(); @@ -445,11 +447,14 @@ struct tableMakerMuonMchTrkEfficiency { bool isKineAcc = IsInKinematics(mEta, mPt); if (!isKineAcc) isMuonSelectedAny = false; - + if (muonSelType >= 0) { + if (mType != muonSelType) + isMuonSelectedAny = false; + } FillHistos(mEta, mPhi, mPt, mchBitmap, isMuonSelectedAny); if (isMuonSelectedAny) - rowCandidateBase(mEta, mPt, mPhi, mchBitmap); + rowCandidateBase(mEta, mPt, mPhi, mchBitmap, mType); } // end loop on muons LOGF(debug, "end muon loop"); @@ -528,6 +533,7 @@ struct tableMakerMuonMchTrkEfficiency { VarManager::FillTrack(muon); LOGF(debug, " %i / %f / %f / %f", muon.trackType(), muon.eta(), muon.pt(), muon.p()); + int mType = muon.trackType(); double mPt = muon.pt(); double mEta = TMath::Abs(muon.eta()); double mPhi = muon.phi(); @@ -551,13 +557,16 @@ struct tableMakerMuonMchTrkEfficiency { bool isKineAcc = IsInKinematics(mEta, mPt); if (!isKineAcc) isMuonSelectedAny = false; - + if (muonSelType >= 0) { + if (mType != muonSelType) + isMuonSelectedAny = false; + } /// fill histograms FillHistos(mEta, mPhi, mPt, mchBitmap, isMuonSelectedAny); FillHistosMC(mEta, mPhi, mPt, mchBitmap, isMuonSelectedAny, mGenEta, mGenPt, mGenPhi); if (isMuonSelectedAny) { - rowCandidateBase(mEta, mPt, mPhi, mchBitmap); + rowCandidateBase(mEta, mPt, mPhi, mchBitmap, mType); rowCandidateGen(mGenEta, mGenPt, mGenPhi); } diff --git a/PWGDQ/Tasks/dqEfficiency.cxx b/PWGDQ/Tasks/dqEfficiency.cxx index f030af86d15..2550416d553 100644 --- a/PWGDQ/Tasks/dqEfficiency.cxx +++ b/PWGDQ/Tasks/dqEfficiency.cxx @@ -797,7 +797,7 @@ struct AnalysisSameEventPairing { t2.reducedMCTrack().pt(), t2.reducedMCTrack().eta(), t2.reducedMCTrack().phi(), t2.reducedMCTrack().e(), t1.reducedMCTrack().vx(), t1.reducedMCTrack().vy(), t1.reducedMCTrack().vz(), t1.reducedMCTrack().vt(), t2.reducedMCTrack().vx(), t2.reducedMCTrack().vy(), t2.reducedMCTrack().vz(), t2.reducedMCTrack().vt(), - t1.isAmbiguous(), t2.isAmbiguous(), -999., -999., -999., -999.,-999., -999., -999.); + t1.isAmbiguous(), t2.isAmbiguous(), -999., -999., -999., -999., -999., -999., -999.); } } diff --git a/PWGDQ/Tasks/dqFlow.cxx b/PWGDQ/Tasks/dqFlow.cxx index e5708ddef3a..0cbf0c0d468 100644 --- a/PWGDQ/Tasks/dqFlow.cxx +++ b/PWGDQ/Tasks/dqFlow.cxx @@ -320,12 +320,10 @@ struct DQEventQvector { } } - // Fill the tree for the reduced event table with Q vector quantities if (fEventCut->IsSelected(VarManager::fgValues)) { eventQvector(VarManager::fgValues[VarManager::kQ2X0A], VarManager::fgValues[VarManager::kQ2Y0A], VarManager::fgValues[VarManager::kQ2X0B], VarManager::fgValues[VarManager::kQ2Y0B], VarManager::fgValues[VarManager::kQ2X0C], VarManager::fgValues[VarManager::kQ2Y0C], VarManager::fgValues[VarManager::kMultA], VarManager::fgValues[VarManager::kMultC], VarManager::fgValues[VarManager::kMultC], VarManager::fgValues[VarManager::kQ3X0A], VarManager::fgValues[VarManager::kQ3Y0A], VarManager::fgValues[VarManager::kQ3X0B], VarManager::fgValues[VarManager::kQ3Y0B], VarManager::fgValues[VarManager::kQ3X0C], VarManager::fgValues[VarManager::kQ3Y0C]); } - } // Process to fill Q vector using barrel tracks in a reduced event table for barrel/muon tracks flow related analyses Run 2 diff --git a/PWGDQ/Tasks/filterPPwithAssociation.cxx b/PWGDQ/Tasks/filterPPwithAssociation.cxx index 81ac67482b5..2b59c2f3928 100644 --- a/PWGDQ/Tasks/filterPPwithAssociation.cxx +++ b/PWGDQ/Tasks/filterPPwithAssociation.cxx @@ -40,6 +40,13 @@ #include "PWGDQ/Core/HistogramsLibrary.h" #include "PWGDQ/Core/CutsLibrary.h" #include "CommonConstants/LHCConstants.h" +#include "Common/DataModel/CollisionAssociationTables.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DataFormatsParameters/GRPObject.h" +#include "Field/MagneticField.h" +#include "TGeoGlobalMagField.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsBase/GeometryManager.h" using std::cout; using std::endl; @@ -556,6 +563,10 @@ struct DQMuonsSelection { Configurable fConfigQA{"cfgWithQA", false, "If true, fill QA histograms"}; Configurable fConfigMuonPtLow{"cfgMuonLowPt", 0.5f, "Low pt cut for muons"}; Configurable fConfigCollisionMuonAssoc{"cfgCollisionMuonAssoc", 0, "0 - standard association, 1 - time compatibility, 2 - ambiguous"}; + Configurable fPropMuon{"cfgPropMuon", false, "Propgate muon tracks through absorber"}; + 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 fConfigAssocTimeMargin{"cfgAssocTimeMargin", 0.0f, "Extra time margin to be considered when doing collision - muon matching (in ns)"}; Configurable fConfigSigmaForTimeCompat{"cfgSigmaForTimeCompat", 4.0, "nSigma window when doing collision - track matching "}; Configurable fSigmaTrack{"cfgSigmaTrack", 1.0, "Number of sigma for track time window"}; @@ -564,6 +575,11 @@ struct DQMuonsSelection { Configurable fTimeMarginVtx{"cfgTimeMarginVtx", 0.0, "Number of sigma for vertex time window"}; Configurable fTimeBias{"cfgTimeBias", 0.0, "Number of sigma for track time window"}; + Service fCCDB; + o2::parameters::GRPMagField* grpmag = nullptr; // for run 3, we access GRPMagField from GLO/Config/GRPMagField + + int fCurrentRun; // needed to detect if the run changed and trigger update of calibrations etc. + // TODO: configure the histogram classes to be filled by QA Filter muonFilter = o2::aod::fwdtrack::pt >= fConfigMuonPtLow; @@ -577,6 +593,15 @@ struct DQMuonsSelection { void init(o2::framework::InitContext&) { + fCCDB->setURL(fConfigCcdbUrl); + fCCDB->setCaching(true); + fCCDB->setLocalObjectValidityChecking(); + if (fPropMuon) { + if (!o2::base::GeometryManager::isGeometryLoaded()) { + fCCDB->get(geoPath); + } + } + TString cutNamesStr = fConfigCuts.value; if (!cutNamesStr.IsNull()) { std::unique_ptr objArray(cutNamesStr.Tokenize(",")); @@ -614,8 +639,20 @@ struct DQMuonsSelection { } template - void runMuonSelection(TMuons const& muons) + void runMuonSelection(Collisions const& collisions, aod::BCsWithTimestamps const& bcs, TMuons const& muons) { + auto bc = bcs.begin(); // check just the first bc to get the run number + if (fCurrentRun != bc.runNumber()) { + fCurrentRun = bc.runNumber(); + if (fPropMuon) { + VarManager::SetupMuonMagField(); + } + grpmag = fCCDB->getForTimeStamp(grpmagPath, bc.timestamp()); + if (grpmag != nullptr) { + o2::base::Propagator::initFieldFromGRP(grpmag); + } + } + fSelectedMuons.clear(); uint32_t filterMap = uint32_t(0); @@ -626,6 +663,9 @@ struct DQMuonsSelection { filterMap = uint32_t(0); // NOTE: here we do not exclude orphan muon tracks VarManager::FillTrack(muon); + if (fPropMuon) { + VarManager::FillPropagateMuon(muon, collisions); + } if (fConfigQA) { fHistMan->FillHistClass("Muon_BeforeCuts", VarManager::fgValues); } @@ -956,7 +996,7 @@ struct DQMuonsSelection { soa::Filtered const& filteredMuons, AmbiguousFwdTracks const& ambFwdTracks) { - runMuonSelection(filteredMuons); + runMuonSelection(collisions, bcstimestamp, filteredMuons); if (fConfigCollisionMuonAssoc.value == 0) { associateMuonsToCollisionsStandard(collisions, muons); } else if (fConfigCollisionMuonAssoc.value == 1) { diff --git a/PWGDQ/Tasks/tableReader.cxx b/PWGDQ/Tasks/tableReader.cxx index 39805bfc61a..c24f507494c 100644 --- a/PWGDQ/Tasks/tableReader.cxx +++ b/PWGDQ/Tasks/tableReader.cxx @@ -106,6 +106,7 @@ using MyMuonTracksSelected = soa::Join; using MyMuonTracksSelectedWithCov = soa::Join; using MyMuonTracksSelectedWithColl = soa::Join; +using MyMftTracks = soa::Join; // bit maps used for the Fill functions of the VarManager constexpr static uint32_t gkEventFillMap = VarManager::ObjTypes::ReducedEvent | VarManager::ObjTypes::ReducedEventExtended; @@ -1057,7 +1058,7 @@ struct AnalysisSameEventPairing { } if constexpr (eventHasQvector) { - dileptonFlowList(VarManager::fgValues[VarManager::kU2Q2], VarManager::fgValues[VarManager::kU3Q3], VarManager::fgValues[VarManager::kCos2DeltaPhi], VarManager::fgValues[VarManager::kCos3DeltaPhi],VarManager::fgValues[VarManager::kR2SP],VarManager::fgValues[VarManager::kR2EP],VarManager::fgValues[VarManager::kCentFT0C]); + dileptonFlowList(VarManager::fgValues[VarManager::kU2Q2], VarManager::fgValues[VarManager::kU3Q3], VarManager::fgValues[VarManager::kCos2DeltaPhi], VarManager::fgValues[VarManager::kCos3DeltaPhi], VarManager::fgValues[VarManager::kR2SP], VarManager::fgValues[VarManager::kR2EP], VarManager::fgValues[VarManager::kCentFT0C]); } int iCut = 0; @@ -1241,6 +1242,61 @@ struct AnalysisSameEventPairing { PROCESS_SWITCH(AnalysisSameEventPairing, processDummy, "Dummy function, enabled only if none of the others are enabled", false); }; +struct AnalysisFwdTrackPid { + Produces fwdPidAllList; + + Filter filterEventSelected = aod::dqanalysisflags::isEventSelected == 1; + + Configurable fConfigMaxDCA{"cfgMaxDCA", 0.5f, "Manually set maximum DCA of the track"}; + + void init(o2::framework::InitContext& context) + { + } + + // Template function to pair mft tracks and muon tracks + template + void runFwdTrackPid(TEvent const& event, Muons const& muons, MftTracks const& mftTracks) + { + fwdPidAllList.reserve(1); + for (const auto& muon : muons) { + if (muon.has_matchMFTTrack() && muon.trackType() == 0 && TMath::Abs(muon.fwdDcaX()) < fConfigMaxDCA && TMath::Abs(muon.fwdDcaY()) < fConfigMaxDCA) { + auto mftTrack = muon.template matchMFTTrack_as(); + fwdPidAllList(muon.trackType(), event.posX(), event.posY(), event.posZ(), event.numContrib(), muon.pt(), muon.eta(), muon.phi(), muon.sign(), mftTrack.mftClusterSizesAndTrackFlags(), muon.fwdDcaX(), muon.fwdDcaY(), muon.chi2MatchMCHMID(), muon.chi2MatchMCHMFT()); + } + } + if constexpr (TMatchedOnly == false) { + for (const auto& mftTrack : mftTracks) { + if (TMath::Abs(mftTrack.fwdDcaX()) < fConfigMaxDCA && TMath::Abs(mftTrack.fwdDcaY()) < fConfigMaxDCA) { + fwdPidAllList(4, event.posX(), event.posY(), event.posZ(), event.numContrib(), mftTrack.pt(), mftTrack.eta(), mftTrack.phi(), mftTrack.sign(), mftTrack.mftClusterSizesAndTrackFlags(), mftTrack.fwdDcaX(), mftTrack.fwdDcaY(), -999, -999); + } + } + } + } + + void processFwdPidMatchedSkimmed(soa::Filtered::iterator const& event, MyMuonTracks const& muons, MyMftTracks const& mftTracks) + { + if (muons.size() > 0 && mftTracks.size() > 0) { + runFwdTrackPid(event, muons, mftTracks); + } + } + + void processFwdPidMatchedOnlySkimmed(soa::Filtered::iterator const& event, MyMuonTracks const& muons, MyMftTracks const& mftTracks) + { + if (muons.size() > 0) { + runFwdTrackPid(event, muons, mftTracks); + } + } + + void processDummy(MyEvents&) + { + // do nothing + } + + PROCESS_SWITCH(AnalysisFwdTrackPid, processFwdPidMatchedSkimmed, "Run MFT - muon track pairing filling tree with MFT and global tracks", false); + PROCESS_SWITCH(AnalysisFwdTrackPid, processFwdPidMatchedOnlySkimmed, "Run MFT - muon track pairing filling tree with global tracks only", false); + PROCESS_SWITCH(AnalysisFwdTrackPid, processDummy, "Dummy function", false); +}; + struct AnalysisDileptonHadron { // // This task combines dilepton candidates with a track and could be used for example @@ -1474,6 +1530,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc)}; } diff --git a/PWGDQ/Tasks/taskMuonMchTrkEfficiency.cxx b/PWGDQ/Tasks/taskMuonMchTrkEfficiency.cxx index 093d791eec5..c1df70cbad1 100644 --- a/PWGDQ/Tasks/taskMuonMchTrkEfficiency.cxx +++ b/PWGDQ/Tasks/taskMuonMchTrkEfficiency.cxx @@ -74,6 +74,8 @@ static const std::vector labelsPtTrack{ struct taskMuonMchTrkEfficiency { + Configurable muonSelType{"muonSelType", 4, "Selected muon track type"}; /// Muon track type to be selected if value >=0 (no selection by default) + Configurable ptMuonMin{"ptMin", 0., "Lower bound of pT"}; /// Muon minimum pt to be studied Configurable etaMuonMin{"etaMin", 2.5, "Lower bound of |eta|"}; /// Muon minimum |eta| to be studied Configurable etaMuonMax{"etaMax", 4.0, "Upper bound of |eta|"}; /// Muon maximum |eta| to be studied @@ -219,7 +221,14 @@ struct taskMuonMchTrkEfficiency { void processReco(aod::MchTrkEffBase const& mchtrkeffbases) { for (auto& mchtrkeffbase : mchtrkeffbases) { - if (IsInKinematics(mchtrkeffbase.eta(), mchtrkeffbase.pt())) + bool isSel = true; + if (!IsInKinematics(mchtrkeffbase.eta(), mchtrkeffbase.pt())) + isSel = false; + if (muonSelType >= 0) { + if (mchtrkeffbase.trackType() != muonSelType) + isSel = false; + } + if (isSel) FillHistos(mchtrkeffbase.eta(), mchtrkeffbase.pt(), mchtrkeffbase.phi(), mchtrkeffbase.mchBitMap()); } } @@ -233,7 +242,7 @@ struct taskMuonMchTrkEfficiency { FillHistosMC(mchtrkeffbase.eta(), mchtrkeffbase.pt(), mchtrkeffbase.phi(), mchtrkeffbase.mchBitMap(), mchtrkeffbase.etaGen(), mchtrkeffbase.ptGen(), mchtrkeffbase.phiGen()); } } - PROCESS_SWITCH(taskMuonMchTrkEfficiency, processSim, "process reconstructed information", false); + PROCESS_SWITCH(taskMuonMchTrkEfficiency, processSim, "process simulated information", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGEM/Dilepton/Tasks/MCtemplates.cxx b/PWGEM/Dilepton/Tasks/MCtemplates.cxx index d06aeed8caf..4ddf086e3a7 100644 --- a/PWGEM/Dilepton/Tasks/MCtemplates.cxx +++ b/PWGEM/Dilepton/Tasks/MCtemplates.cxx @@ -60,27 +60,27 @@ DECLARE_SOA_TABLE(BarrelTrackCuts, "AOD", "BARRELTRACKCUTS", emanalysisflags::Is } // namespace o2::aod // No skimming: works for events and single tracks -using MyEventsNoSkimmed = soa::Join; -using MyEventsSelectedNoSkimmed = soa::Join; -using MyMCEventsSelectedNoSkimmed = soa::Join; -using MyBarrelTracksNoSkimmed = soa::Join; -using MyBarrelTracksSelectedNoSkimmed = soa::Join; -// using MyMCTrackNoSkimmed = soa::Join; - -constexpr static uint32_t gkEventFillMapNoSkimmed = VarManager::ObjTypes::Collision; -constexpr static uint32_t gkMCEventFillMapNoSkimmed = VarManager::ObjTypes::CollisionMC; -constexpr static uint32_t gkTrackFillMapNoSkimmed = VarManager::ObjTypes::Track | VarManager::ObjTypes::TrackExtra | VarManager::ObjTypes::TrackCov | VarManager::ObjTypes::TrackDCA | VarManager::ObjTypes::TrackSelection | VarManager::ObjTypes::TrackPID; -constexpr static uint32_t gkParticleMCFillMapNoSkimmed = VarManager::ObjTypes::ParticleMC; +using MyEventsAOD = soa::Join; +using MyEventsSelectedAOD = soa::Join; +// using MyMCEventsSelectedAOD = soa::Join; +using MyBarrelTracksAOD = soa::Join; +using MyBarrelTracksSelectedAOD = soa::Join; +// using MyMCTrackAOD = soa::Join; + +constexpr static uint32_t gkEventFillMapAOD = VarManager::ObjTypes::Collision; +constexpr static uint32_t gkMCEventFillMapAOD = VarManager::ObjTypes::CollisionMC; +constexpr static uint32_t gkTrackFillMapAOD = VarManager::ObjTypes::Track | VarManager::ObjTypes::TrackExtra | VarManager::ObjTypes::TrackCov | VarManager::ObjTypes::TrackDCA | VarManager::ObjTypes::TrackSelection | VarManager::ObjTypes::TrackPID; +constexpr static uint32_t gkParticleMCFillMapAOD = VarManager::ObjTypes::ParticleMC; // Skimmed data // using MyEvents = soa::Join; @@ -160,24 +160,24 @@ struct AnalysisEventSelection { runSelection(event, mcEvents); } - void processNoSkimmed(MyEventsNoSkimmed::iterator const& event, aod::McCollisions const& mcEvents) + void processAOD(MyEventsAOD::iterator const& event, aod::McCollisions const& mcEvents) { - runSelection(event, mcEvents); + runSelection(event, mcEvents); } void processDummy(MyEvents&) { // do nothing } - void processDummyNoSkimmed(MyEventsNoSkimmed&) + void processDummyAOD(MyEventsAOD&) { // do nothing } - PROCESS_SWITCH(AnalysisEventSelection, processNoSkimmed, "Run event selection without skimming", false); PROCESS_SWITCH(AnalysisEventSelection, processSkimmed, "Run event selection on DQ skimmed events", false); + PROCESS_SWITCH(AnalysisEventSelection, processAOD, "Run event selection without skimming", false); PROCESS_SWITCH(AnalysisEventSelection, processDummy, "Dummy process function", false); - PROCESS_SWITCH(AnalysisEventSelection, processDummyNoSkimmed, "Dummy process function", false); + PROCESS_SWITCH(AnalysisEventSelection, processDummyAOD, "Dummy process function", false); }; struct AnalysisTrackSelection { @@ -248,8 +248,8 @@ struct AnalysisTrackSelection { } } - template - void runSelection(TEvent const& event, TTracks const& tracks) + template + void runSelection(TEvent const& event, TTracks const& tracks, TEventsMC const& eventsMC, TTracksMC const& tracksMC) { VarManager::ResetValues(0, VarManager::kNMCParticleVariables); // fill event information which might be needed in histograms that combine track and event properties @@ -328,28 +328,28 @@ struct AnalysisTrackSelection { } // end loop over tracks } - void processSkimmed(MyEventsSelected::iterator const& event, MyBarrelTracks const& tracks) + void processSkimmed(MyEventsSelected::iterator const& event, MyBarrelTracks const& tracks, ReducedMCEvents const& eventsMC, ReducedMCTracks const& tracksMC) { - runSelection(event, tracks); + runSelection(event, tracks, eventsMC, tracksMC); } - void processNoSkimmed(soa::Filtered::iterator const& event, MyBarrelTracksNoSkimmed const& tracks) + void processAOD(MyEventsSelectedAOD::iterator const& event, MyBarrelTracksAOD const& tracks, aod::McCollisions const& eventsMC, aod::McParticles const& tracksMC) { - runSelection(event, tracks); + runSelection(event, tracks, eventsMC, tracksMC); } void processDummy(MyEvents&) { // do nothing } - void processDummyNoSkimmed(MyEventsNoSkimmed&) + void processDummyAOD(MyEventsAOD&) { // do nothing } PROCESS_SWITCH(AnalysisTrackSelection, processSkimmed, "Run barrel track selection on DQ skimmed tracks", false); - PROCESS_SWITCH(AnalysisTrackSelection, processNoSkimmed, "Run barrel track selection without skimming", false); + PROCESS_SWITCH(AnalysisTrackSelection, processAOD, "Run barrel track selection without skimming", false); PROCESS_SWITCH(AnalysisTrackSelection, processDummy, "Dummy process function", false); - PROCESS_SWITCH(AnalysisTrackSelection, processDummyNoSkimmed, "Dummy process function", false); + PROCESS_SWITCH(AnalysisTrackSelection, processDummyAOD, "Dummy process function", false); }; struct AnalysisSameEventPairing { @@ -617,16 +617,16 @@ struct AnalysisSameEventPairing { runMCGen(groupedMCTracks); } - void processDecayToEENoSkimmed(soa::Filtered::iterator const& event, - soa::Filtered const& tracks, - aod::McParticles const& tracksMC) + void processDecayToEEAOD(soa::Filtered::iterator const& event, + soa::Filtered const& tracks, + aod::McParticles const& tracksMC) { // Reset the fValues array VarManager::ResetValues(0, VarManager::kNVars); - VarManager::FillEvent(event); - // VarManager::FillEvent(event.reducedMCevent()); + VarManager::FillEvent(event); + VarManager::FillEvent(event.mcCollision()); - runPairing(event, tracks, tracks); + runPairing(event, tracks, tracks); auto groupedMCTracks = tracksMC.sliceBy(perMcCollision, event.mcCollision().globalIndex()); groupedMCTracks.bindInternalIndicesTo(&tracksMC); runMCGen(groupedMCTracks); @@ -636,16 +636,16 @@ struct AnalysisSameEventPairing { { // do nothing } - void processDummyNoSkimmed(MyEventsNoSkimmed&) + void processDummyAOD(MyEventsAOD&) { // do nothing } PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToEESkimmed, "Run barrel barrel pairing on DQ skimmed tracks", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToEEVertexingSkimmed, "Run barrel barrel pairing on DQ skimmed tracks including vertexing", false); - PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToEENoSkimmed, "Run barrel barrel pairing on non skimmed tracks", false); + PROCESS_SWITCH(AnalysisSameEventPairing, processDecayToEEAOD, "Run barrel barrel pairing on non skimmed tracks", false); PROCESS_SWITCH(AnalysisSameEventPairing, processDummy, "Dummy process function", false); - PROCESS_SWITCH(AnalysisSameEventPairing, processDummyNoSkimmed, "Dummy process function", false); + PROCESS_SWITCH(AnalysisSameEventPairing, processDummyAOD, "Dummy process function", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGEM/PhotonMeson/Core/CutsLibrary.cxx b/PWGEM/PhotonMeson/Core/CutsLibrary.cxx index 6946f3788dc..1d8691261c4 100644 --- a/PWGEM/PhotonMeson/Core/CutsLibrary.cxx +++ b/PWGEM/PhotonMeson/Core/CutsLibrary.cxx @@ -20,7 +20,7 @@ V0PhotonCut* o2::aod::pcmcuts::GetCut(const char* cutName) if (!nameStr.compare("analysis")) { // for track - cut->SetTrackPtRange(0.02f, 1e10f); + cut->SetTrackPtRange(0.04f, 1e10f); // cut->SetTrackEtaRange(-0.9, +0.9); cut->SetMinNCrossedRowsTPC(20); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); @@ -37,7 +37,7 @@ V0PhotonCut* o2::aod::pcmcuts::GetCut(const char* cutName) } if (!nameStr.compare("qc")) { // for track - cut->SetTrackPtRange(0.02f, 1e10f); + cut->SetTrackPtRange(0.04f, 1e10f); // cut->SetTrackEtaRange(-0.9, +0.9); cut->SetMinNCrossedRowsTPC(20); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); @@ -48,14 +48,14 @@ V0PhotonCut* o2::aod::pcmcuts::GetCut(const char* cutName) cut->SetV0PtRange(0.1f, 1e10f); cut->SetV0EtaRange(-0.9, +0.9); cut->SetMinCosPA(0.99); - cut->SetMaxPCA(1.5); + cut->SetMaxPCA(3.0); cut->SetRxyRange(1, 90); cut->SetAPRange(0.95, 0.01); return cut; } if (!nameStr.compare("qc_ITSTPC")) { // for track - cut->SetTrackPtRange(0.02f, 1e10f); + cut->SetTrackPtRange(0.04f, 1e10f); // cut->SetTrackEtaRange(-0.9, +0.9); cut->SetMinNCrossedRowsTPC(20); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); @@ -74,7 +74,7 @@ V0PhotonCut* o2::aod::pcmcuts::GetCut(const char* cutName) } if (!nameStr.compare("qc_ITSonly")) { // for track - cut->SetTrackPtRange(0.02f, 1e10f); + cut->SetTrackPtRange(0.04f, 1e10f); // cut->SetTrackEtaRange(-0.9, +0.9); cut->SetIsWithinBeamPipe(true); cut->SetRequireITSonly(true); @@ -89,7 +89,7 @@ V0PhotonCut* o2::aod::pcmcuts::GetCut(const char* cutName) } if (!nameStr.compare("qc_TPConly")) { // for track - cut->SetTrackPtRange(0.02f, 1e10f); + cut->SetTrackPtRange(0.04f, 1e10f); // cut->SetTrackEtaRange(-0.9, +0.9); cut->SetMinNCrossedRowsTPC(20); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); @@ -101,14 +101,14 @@ V0PhotonCut* o2::aod::pcmcuts::GetCut(const char* cutName) cut->SetV0PtRange(0.1f, 1e10f); cut->SetV0EtaRange(-0.9, +0.9); cut->SetMinCosPA(0.99); - cut->SetMaxPCA(1.5); - cut->SetRxyRange(1, 90); + cut->SetMaxPCA(3.0); + cut->SetRxyRange(36, 90); cut->SetAPRange(0.95, 0.01); return cut; } if (!nameStr.compare("wwire")) { // conversion only on tungstate wire // for track - cut->SetTrackPtRange(0.02f, 1e10f); + cut->SetTrackPtRange(0.04f, 1e10f); // cut->SetTrackEtaRange(-0.9, +0.9); cut->SetMinNCrossedRowsTPC(20); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); @@ -120,7 +120,7 @@ V0PhotonCut* o2::aod::pcmcuts::GetCut(const char* cutName) cut->SetV0PtRange(0.1f, 1e10f); cut->SetV0EtaRange(-0.9, +0.9); cut->SetMinCosPA(0.99); - cut->SetMaxPCA(0.5); + cut->SetMaxPCA(0.3); cut->SetOnWwireIB(true); cut->SetOnWwireOB(true); cut->SetAPRange(0.95, 0.01); @@ -128,7 +128,7 @@ V0PhotonCut* o2::aod::pcmcuts::GetCut(const char* cutName) } if (!nameStr.compare("wwire_ib")) { // conversion only on tungstate wire outside of ITSib // for track - cut->SetTrackPtRange(0.02f, 1e10f); + cut->SetTrackPtRange(0.04f, 1e10f); // cut->SetTrackEtaRange(-0.9, +0.9); cut->SetMinNCrossedRowsTPC(20); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); @@ -140,7 +140,7 @@ V0PhotonCut* o2::aod::pcmcuts::GetCut(const char* cutName) cut->SetV0PtRange(0.1f, 1e10f); cut->SetV0EtaRange(-0.9, +0.9); cut->SetMinCosPA(0.99); - cut->SetMaxPCA(0.5); + cut->SetMaxPCA(0.3); cut->SetOnWwireIB(true); cut->SetOnWwireOB(false); cut->SetAPRange(0.95, 0.01); @@ -148,7 +148,7 @@ V0PhotonCut* o2::aod::pcmcuts::GetCut(const char* cutName) } if (!nameStr.compare("wwire_ob")) { // conversion only on tungstate wire outside of ITSob (middle layer) // for track - cut->SetTrackPtRange(0.02f, 1e10f); + cut->SetTrackPtRange(0.04f, 1e10f); // cut->SetTrackEtaRange(-0.9, +0.9); cut->SetMinNCrossedRowsTPC(20); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); @@ -160,32 +160,106 @@ V0PhotonCut* o2::aod::pcmcuts::GetCut(const char* cutName) cut->SetV0PtRange(0.1f, 1e10f); cut->SetV0EtaRange(-0.9, +0.9); cut->SetMinCosPA(0.99); - cut->SetMaxPCA(0.5); + cut->SetMaxPCA(0.3); cut->SetOnWwireIB(false); cut->SetOnWwireOB(true); cut->SetAPRange(0.95, 0.01); return cut; } - if (!nameStr.compare("nopid")) { + + // for low B=0.2T + if (!nameStr.compare("qc_lowB")) { // for track cut->SetTrackPtRange(0.02f, 1e10f); // cut->SetTrackEtaRange(-0.9, +0.9); cut->SetMinNCrossedRowsTPC(20); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); + cut->SetTPCNsigmaElRange(-3, +3); + cut->SetIsWithinBeamPipe(true); + // for v0 + cut->SetV0PtRange(0.05f, 1e10f); + cut->SetV0EtaRange(-0.9, +0.9); + cut->SetMinCosPA(0.99); + cut->SetMaxPCA(3.0); + cut->SetRxyRange(1, 90); + cut->SetAPRange(0.95, 0.01); + return cut; + } + if (!nameStr.compare("qc_ITSTPC_lowB")) { + // for track + cut->SetTrackPtRange(0.02f, 1e10f); + // cut->SetTrackEtaRange(-0.9, +0.9); + cut->SetMinNCrossedRowsTPC(20); + cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); + cut->SetChi2PerClusterTPC(0.0, 4.0); + cut->SetTPCNsigmaElRange(-3, +3); + cut->SetIsWithinBeamPipe(true); + cut->SetRequireITSTPC(true); + // for v0 + cut->SetV0PtRange(0.05f, 1e10f); + cut->SetV0EtaRange(-0.9, +0.9); + cut->SetMinCosPA(0.99); + cut->SetMaxPCA(0.5); + cut->SetRxyRange(1, 90); + cut->SetAPRange(0.95, 0.01); + return cut; + } + if (!nameStr.compare("qc_ITSonly_lowB")) { + // for track + cut->SetTrackPtRange(0.02f, 1e10f); + // cut->SetTrackEtaRange(-0.9, +0.9); + cut->SetIsWithinBeamPipe(true); + cut->SetRequireITSonly(true); + // for v0 + cut->SetV0PtRange(0.05f, 1e10f); + cut->SetV0EtaRange(-0.9, +0.9); + cut->SetMinCosPA(0.99); + cut->SetMaxPCA(0.5); + cut->SetRxyRange(1, 90); + cut->SetAPRange(0.95, 0.01); + return cut; + } + if (!nameStr.compare("qc_TPConly_lowB")) { + // for track + cut->SetTrackPtRange(0.02f, 1e10f); + // cut->SetTrackEtaRange(-0.9, +0.9); + cut->SetMinNCrossedRowsTPC(20); + cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); + cut->SetChi2PerClusterTPC(0.0, 4.0); + cut->SetTPCNsigmaElRange(-3, +3); + cut->SetIsWithinBeamPipe(true); + cut->SetRequireTPConly(true); + // for v0 + cut->SetV0PtRange(0.05f, 1e10f); + cut->SetV0EtaRange(-0.9, +0.9); + cut->SetMinCosPA(0.99); + cut->SetMaxPCA(3.0); + cut->SetRxyRange(36, 90); + cut->SetAPRange(0.95, 0.01); + return cut; + } + + if (!nameStr.compare("nopid")) { + // for track + cut->SetTrackPtRange(0.04f, 1e10f); + // cut->SetTrackEtaRange(-0.9, +0.9); + cut->SetMinNCrossedRowsTPC(20); + cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); + cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetIsWithinBeamPipe(true); // for v0 cut->SetV0PtRange(0.1f, 1e10f); cut->SetV0EtaRange(-0.9, +0.9); cut->SetMinCosPA(0.99); - cut->SetMaxPCA(1.5); + cut->SetMaxPCA(3.0); cut->SetRxyRange(1, 90); cut->SetAPRange(0.95, 0.01); return cut; } if (!nameStr.compare("nocut")) { // for track - cut->SetTrackPtRange(0.02f, 1e10f); + cut->SetTrackPtRange(0.04f, 1e10f); // cut->SetTrackEtaRange(-0.9, +0.9); cut->SetMinNCrossedRowsTPC(20); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); @@ -195,15 +269,15 @@ V0PhotonCut* o2::aod::pcmcuts::GetCut(const char* cutName) // for v0 cut->SetV0PtRange(0.1f, 1e10f); cut->SetV0EtaRange(-0.9, +0.9); - cut->SetMinCosPA(0.99); - cut->SetMaxPCA(1.5); + cut->SetMinCosPA(0.95); + cut->SetMaxPCA(3.0); cut->SetRxyRange(1, 90); cut->SetAPRange(0.95, 0.01); return cut; } if (!nameStr.compare("tag_track")) { // for track - cut->SetTrackPtRange(0.02f, 1e10f); + cut->SetTrackPtRange(0.04f, 1e10f); // cut->SetTrackEtaRange(-0.9, +0.9); cut->SetMinNCrossedRowsTPC(20); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); @@ -214,7 +288,7 @@ V0PhotonCut* o2::aod::pcmcuts::GetCut(const char* cutName) // for v0 cut->SetV0PtRange(0.1f, 1e10f); cut->SetV0EtaRange(-0.9, +0.9); - cut->SetMinCosPA(0.995); + cut->SetMinCosPA(0.99); cut->SetMaxPCA(0.5); cut->SetRxyRange(1, 90); cut->SetAPRange(0.95, 0.01); @@ -231,6 +305,32 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) DalitzEECut* cut = new DalitzEECut(cutName, cutName); std::string nameStr = cutName; + if (!nameStr.compare("pc_itsib")) { + // for pair + cut->SelectPhotonConversion(true); + cut->SetMaxPhivPairMeeDep([](float mee) { + return (mee - -0.028) / 0.0185; + }); + + // for track + cut->SetTrackPtRange(0.05f, 1e10f); + cut->SetTrackEtaRange(-0.9, +0.9); + cut->SetMinNCrossedRowsTPC(80); + cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); + cut->SetChi2PerClusterTPC(0.0, 4.0); + cut->SetChi2PerClusterITS(0.0, 5.0); + cut->SetNClustersITS(2, 7); + cut->SetMaxDcaXY(1.0); + cut->SetMaxDcaZ(1.0); + + // for PID + cut->SetPIDScheme(DalitzEECut::PIDSchemes::kTPConly_lowB); + cut->SetTOFbetaRange(true, 0.0, 0.95); + cut->SetTPCNsigmaElRange(-3, +3); + cut->SetTPCNsigmaPiRange(0, 0); + return cut; + } + if (!nameStr.compare("mee_all_tpchadrejortofreq_wo_phiv_lowB")) { // for pair @@ -241,7 +341,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -268,7 +368,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -297,7 +397,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -326,7 +426,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetDca3DRange(0.0, 1.0); // for PID @@ -354,7 +454,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetDca3DRange(2.0, 1e+10); // for PID @@ -382,7 +482,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -412,7 +512,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -437,7 +537,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -455,11 +555,11 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) // for track cut->SetTrackPtRange(0.2f, 1e10f); cut->SetTrackEtaRange(-0.9, +0.9); - cut->SetMinNCrossedRowsTPC(80); + cut->SetMinNCrossedRowsTPC(100); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -480,11 +580,11 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) // for track cut->SetTrackPtRange(0.2f, 1e10f); cut->SetTrackEtaRange(-0.9, +0.9); - cut->SetMinNCrossedRowsTPC(80); + cut->SetMinNCrossedRowsTPC(100); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -505,11 +605,11 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) // for track cut->SetTrackPtRange(0.2f, 1e10f); cut->SetTrackEtaRange(-0.9, +0.9); - cut->SetMinNCrossedRowsTPC(80); + cut->SetMinNCrossedRowsTPC(100); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -531,7 +631,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -554,7 +654,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -579,7 +679,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -602,7 +702,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -627,7 +727,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -652,7 +752,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -675,7 +775,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -700,7 +800,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -730,7 +830,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -760,7 +860,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -789,7 +889,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -817,7 +917,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -845,7 +945,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -873,7 +973,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -897,7 +997,7 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -919,11 +1019,11 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) // for track cut->SetTrackPtRange(0.2f, 1e10f); cut->SetTrackEtaRange(-0.9, +0.9); - cut->SetMinNCrossedRowsTPC(80); + cut->SetMinNCrossedRowsTPC(100); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -946,12 +1046,12 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) // for track cut->SetTrackPtRange(0.2f, 1e10f); cut->SetTrackEtaRange(-0.9, +0.9); - cut->SetMinNCrossedRowsTPC(80); + cut->SetMinNCrossedRowsTPC(100); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); - cut->SetDca3DRange(0.0, 1.0); // in sigma + cut->SetNClustersITS(5, 7); + cut->SetDca3DRange(0.0, 0.6); // in sigma // for PID cut->SetPIDScheme(DalitzEECut::PIDSchemes::kTPChadrejORTOFreq); @@ -972,11 +1072,11 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) // for track cut->SetTrackPtRange(0.2f, 1e10f); cut->SetTrackEtaRange(-0.9, +0.9); - cut->SetMinNCrossedRowsTPC(80); + cut->SetMinNCrossedRowsTPC(100); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetDca3DRange(2.0, 1e+10); // in sigma // for PID @@ -999,11 +1099,11 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) // for track cut->SetTrackPtRange(0.2f, 1e10f); cut->SetTrackEtaRange(-0.9, +0.9); - cut->SetMinNCrossedRowsTPC(80); + cut->SetMinNCrossedRowsTPC(100); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -1024,11 +1124,11 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) // for track cut->SetTrackPtRange(0.2f, 1e10f); cut->SetTrackEtaRange(-0.9, +0.9); - cut->SetMinNCrossedRowsTPC(80); + cut->SetMinNCrossedRowsTPC(100); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -1052,11 +1152,11 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) // for track cut->SetTrackPtRange(0.2f, 1e10f); cut->SetTrackEtaRange(-0.9, +0.9); - cut->SetMinNCrossedRowsTPC(80); + cut->SetMinNCrossedRowsTPC(100); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -1080,11 +1180,11 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) // for track cut->SetTrackPtRange(0.2f, 1e10f); cut->SetTrackEtaRange(-0.9, +0.9); - cut->SetMinNCrossedRowsTPC(80); + cut->SetMinNCrossedRowsTPC(100); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); @@ -1103,11 +1203,11 @@ DalitzEECut* o2::aod::dalitzeecuts::GetCut(const char* cutName) // for track cut->SetTrackPtRange(0.01f, 1e10f); cut->SetTrackEtaRange(-0.9, +0.9); - cut->SetMinNCrossedRowsTPC(80); + cut->SetMinNCrossedRowsTPC(100); cut->SetMinNCrossedRowsOverFindableClustersTPC(0.8); cut->SetChi2PerClusterTPC(0.0, 4.0); cut->SetChi2PerClusterITS(0.0, 5.0); - cut->SetNClustersITS(4, 7); + cut->SetNClustersITS(5, 7); cut->SetMaxDcaXY(1.0); cut->SetMaxDcaZ(1.0); return cut; diff --git a/PWGEM/PhotonMeson/Core/DalitzEECut.cxx b/PWGEM/PhotonMeson/Core/DalitzEECut.cxx index d6ec8536f8f..df7369fb3a1 100644 --- a/PWGEM/PhotonMeson/Core/DalitzEECut.cxx +++ b/PWGEM/PhotonMeson/Core/DalitzEECut.cxx @@ -43,6 +43,11 @@ void DalitzEECut::SetMaxPhivPairMeeDep(std::function meeDepCut) mMaxPhivPairMeeDep = meeDepCut; LOG(info) << "DalitzEE Cut, set max phiv pair mee dep: " << mMaxPhivPairMeeDep(0.02); } +void DalitzEECut::SelectPhotonConversion(bool flag) +{ + mSelectPC = flag; + LOG(info) << "DalitzEE Cut, select photon conversion: " << mSelectPC; +} void DalitzEECut::SetTrackPtRange(float minPt, float maxPt) { mMinTrackPt = minPt; diff --git a/PWGEM/PhotonMeson/Core/DalitzEECut.h b/PWGEM/PhotonMeson/Core/DalitzEECut.h index c7a543287c6..9db1cb72747 100644 --- a/PWGEM/PhotonMeson/Core/DalitzEECut.h +++ b/PWGEM/PhotonMeson/Core/DalitzEECut.h @@ -320,7 +320,7 @@ class DalitzEECut : public TNamed return mMinMee <= pair.mass() && pair.mass() <= mMaxMee; case DalitzEECuts::kPhiV: - return mMinPhivPair <= pair.phiv() && pair.phiv() <= (mMaxPhivPairMeeDep ? mMaxPhivPairMeeDep(pair.mass()) : mMaxPhivPair); + return (mMinPhivPair <= pair.phiv() && pair.phiv() <= (mMaxPhivPairMeeDep ? mMaxPhivPairMeeDep(pair.mass()) : mMaxPhivPair)) ^ mSelectPC; default: return false; @@ -385,6 +385,7 @@ class DalitzEECut : public TNamed void SetPairEtaRange(float minEta = -1e10f, float maxEta = 1e10f); void SetMeeRange(float min = 0.f, float max = 0.5); void SetMaxPhivPairMeeDep(std::function meeDepCut); + void SelectPhotonConversion(bool flag); void SetTrackPtRange(float minPt = 0.f, float maxPt = 1e10f); void SetTrackEtaRange(float minEta = -1e10f, float maxEta = 1e10f); @@ -427,6 +428,7 @@ class DalitzEECut : public TNamed float mMinPairEta{-1e10f}, mMaxPairEta{1e10f}; // range in eta float mMinPhivPair{0.f}, mMaxPhivPair{+3.2}; std::function mMaxPhivPairMeeDep{}; // max phiv as a function of mee + bool mSelectPC{false}; // flag to select photon conversion used in mMaxPhivPairMeeDep // kinematic cuts float mMinTrackPt{0.f}, mMaxTrackPt{1e10f}; // range in pT diff --git a/PWGEM/PhotonMeson/Core/EMCPhotonCut.h b/PWGEM/PhotonMeson/Core/EMCPhotonCut.h index bf5bd13ae2d..31764e31f50 100644 --- a/PWGEM/PhotonMeson/Core/EMCPhotonCut.h +++ b/PWGEM/PhotonMeson/Core/EMCPhotonCut.h @@ -85,7 +85,7 @@ class EMCPhotonCut : public TNamed return cluster.nCells() >= mMinNCell; case EMCPhotonCuts::kM02: - return mMinM02 <= cluster.m02() && cluster.m02() <= mMaxM02; + return (cluster.nCells() == 1 || (mMinM02 <= cluster.m02() && cluster.m02() <= mMaxM02)); case EMCPhotonCuts::kTiming: return mMinTime <= cluster.time() && cluster.time() <= mMaxTime; diff --git a/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx b/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx index 0053fb66a20..db43abf59ed 100644 --- a/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx +++ b/PWGEM/PhotonMeson/Core/HistogramsLibrary.cxx @@ -38,14 +38,14 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* list->Add(new TH1F("hCollisionCounter", "hCollisionCounter", 5, 0.5f, 5.5f)); list->Add(new TH1F("hZvtx_before", "vertex z; Zvtx (cm)", 100, -50, +50)); list->Add(new TH1F("hZvtx_after", "vertex z; Zvtx (cm)", 100, -50, +50)); - list->Add(new TH1F("hMultNTracksPV", "hMultNTracksPV; N_{track} to PV", 5001, -0.5, 5000.5)); - list->Add(new TH1F("hMultNTracksPVeta1", "hMultNTracksPVeta1; N_{track} to PV", 5001, -0.5, 5000.5)); - list->Add(new TH2F("hMultFT0", "hMultFT0;mult. FT0A;mult. FT0C", 200, 0, 6000, 200, 0, 6000)); + list->Add(new TH1F("hMultNTracksPV", "hMultNTracksPV; N_{track} to PV", 6001, -0.5, 6000.5)); + list->Add(new TH1F("hMultNTracksPVeta1", "hMultNTracksPVeta1; N_{track} to PV", 6001, -0.5, 6000.5)); + list->Add(new TH2F("hMultFT0", "hMultFT0;mult. FT0A;mult. FT0C", 300, 0, 6000, 300, 0, 6000)); list->Add(new TH1F("hCentFT0A", "hCentFT0A;centrality FT0A (%)", 110, 0, 110)); list->Add(new TH1F("hCentFT0C", "hCentFT0C;centrality FT0C (%)", 110, 0, 110)); list->Add(new TH1F("hCentFT0M", "hCentFT0M;centrality FT0M (%)", 110, 0, 110)); - list->Add(new TH2F("hCentFT0MvsMultNTracksPV", "hCentFT0MvsMultNTracksPV;centrality FT0M (%);N_{track} to PV", 110, 0, 110, 500, 0, 5000)); - list->Add(new TH2F("hMultFT0MvsMultNTracksPV", "hMultFT0MvsMultNTracksPV;mult. FT0M;N_{track} to PV", 600, 0, 6000, 500, 0, 5000)); + list->Add(new TH2F("hCentFT0MvsMultNTracksPV", "hCentFT0MvsMultNTracksPV;centrality FT0M (%);N_{track} to PV", 110, 0, 110, 600, 0, 6000)); + list->Add(new TH2F("hMultFT0MvsMultNTracksPV", "hMultFT0MvsMultNTracksPV;mult. FT0M;N_{track} to PV", 600, 0, 6000, 600, 0, 6000)); } if (TString(histClass) == "V0Leg") { list->Add(new TH1F("hPt", "pT;p_{T} (GeV/c)", 1000, 0.0f, 10)); @@ -63,24 +63,27 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* list->Add(new TH1F("hNclsITS", "number of ITS clusters", 8, -0.5, 7.5)); list->Add(new TH1F("hChi2ITS", "chi2/number of ITS clusters", 100, 0, 10)); list->Add(new TH1F("hITSClusterMap", "ITS cluster map", 128, -0.5, 127.5)); + list->Add(new TH1F("hMeanClusterSizeITS", "mean cluster size ITS; on ITS #times cos(#lambda)", 160, 0, 16)); list->Add(new TH2F("hXY", "X vs. Y;X (cm);Y (cm)", 100, 0, 100, 100, -50, 50)); list->Add(new TH2F("hZX", "Z vs. X;Z (cm);X (cm)", 200, -100, 100, 100, 0, 100)); list->Add(new TH2F("hZY", "Z vs. Y;Z (cm);Y (cm)", 200, -100, 100, 100, -50, 50)); - list->Add(new TH2F("hDCAxyZ", "DCAxy vs. Z;Z (cm);DCA_{xy} (cm)", 200, -100, +100, 100, -50, 50)); - list->Add(new TH2F("hXZ_tgl", "correlation of tgl vs. z/x;tgl;z/x - tgl", 300, -1.5, 1.5, 300, -1.5, 1.5)); if (TString(subGroup) == "mc") { list->Add(new TH2F("hPtGen_DeltaPtOverPtGen", "electron p_{T} resolution;p_{T}^{gen} (GeV/c);(p_{T}^{rec} - p_{T}^{gen})/p_{T}^{gen}", 1000, 0, 10, 400, -1.0f, 1.0f)); list->Add(new TH2F("hPtGen_DeltaEta", "electron #eta resolution;p_{T}^{gen} (GeV/c);#eta^{rec} - #eta^{gen}", 1000, 0, 10, 400, -1.0f, 1.0f)); list->Add(new TH2F("hPtGen_DeltaPhi", "electron #varphi resolution;p_{T}^{gen} (GeV/c);#varphi^{rec} - #varphi^{gen} (rad.)", 1000, 0, 10, 400, -1.0f, 1.0f)); + list->Add(new TH2F("hEtaRec_DeltaPtOverPtGen", "electron p_{T} resolution;#eta^{rec} of conversion point;(p_{T}^{rec} - p_{T}^{gen})/p_{T}^{gen}", 400, -2, +2, 400, -1.0f, 1.0f)); + list->Add(new TH2F("hEtaRec_DeltaEta", "electron #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", "electron #varphi resolution;#eta^{rec} of conversion point;#varphi^{rec} - #varphi^{gen} (rad.)", 400, -2, +2, 400, -1.0f, 1.0f)); } } if (TString(histClass) == "V0") { list->Add(new TH1F("hPt", "pT;p_{T} (GeV/c)", 2000, 0.0f, 20)); list->Add(new TH2F("hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", 180, 0, TMath::TwoPi(), 40, -2.0f, 2.0f)); list->Add(new TH2F("hRadius", "V0Radius; radius in Z (cm);radius in XY (cm)", 200, -100, 100, 200, 0.0f, 100.0f)); - list->Add(new TH1F("hCosPA", "V0CosPA;cosine pointing angle", 100, 0.99f, 1.0f)); - list->Add(new TH1F("hPCA", "distance between 2 legs;PCA (cm)", 200, 0.0f, 2.0f)); - list->Add(new TH2F("hPCA_Rxy", "distance between 2 legs vs. R_{xy};R_{xy} (cm);PCA (cm)", 200, 0.f, 100.f, 200, 0.0f, 2.0f)); + list->Add(new TH1F("hCosPA", "V0CosPA;cosine pointing angle", 100, 0.9f, 1.0f)); + list->Add(new TH2F("hCosPA_Rxy", "cos PA vs. R_{xy};R_{xy} (cm);cosine pointing angle", 200, 0.f, 100.f, 100, 0.9f, 1.0f)); + list->Add(new TH1F("hPCA", "distance between 2 legs;PCA (cm)", 500, 0.0f, 5.0f)); + list->Add(new TH2F("hPCA_Rxy", "distance between 2 legs vs. R_{xy};R_{xy} (cm);PCA (cm)", 200, 0.f, 100.f, 500, 0.0f, 5.0f)); list->Add(new TH2F("hDCAxyz", "DCA to PV;DCA_{xy} (cm);DCA_{z} (cm)", 200, -5.f, +5.f, 200, -5.f, +5.f)); list->Add(new TH2F("hAPplot", "AP plot;#alpha;q_{T} (GeV/c)", 200, -1.0f, +1.0f, 250, 0.0f, 0.25f)); list->Add(new TH2F("hMassGamma", "hMassGamma;R_{xy} (cm);m_{ee} (GeV/c^{2})", 200, 0.0f, 100.0f, 100, 0.0f, 0.1f)); @@ -118,6 +121,9 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* list->Add(new TH2F("hPtGen_DeltaPtOverPtGen", "photon p_{T} resolution;p_{T}^{gen} (GeV/c);(p_{T}^{rec} - p_{T}^{gen})/p_{T}^{gen}", 1000, 0, 10, 400, -1.0f, 1.0f)); list->Add(new TH2F("hPtGen_DeltaEta", "photon #eta resolution;p_{T}^{gen} (GeV/c);#eta^{rec} - #eta^{gen}", 1000, 0, 10, 400, -1.0f, 1.0f)); list->Add(new TH2F("hPtGen_DeltaPhi", "photon #varphi resolution;p_{T}^{gen} (GeV/c);#varphi^{rec} - #varphi^{gen} (rad.)", 1000, 0, 10, 400, -1.0f, 1.0f)); + list->Add(new TH2F("hEtaRec_DeltaPtOverPtGen", "photon p_{T} resolution;#eta^{rec} of conversion point;(p_{T}^{rec} - p_{T}^{gen})/p_{T}^{gen}", 400, -2, +2, 400, -1.0f, 1.0f)); + 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 @@ -177,22 +183,53 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* hs_dilepton_lsmm_same->Sumw2(); list->Add(hs_dilepton_lsmm_same); - const int ndim_dca = 4; // mee, dca1, dca2 - const int nbins_dca[ndim_dca] = {nm - 1, 50, 50, 50}; - const double xmin_dca[ndim_dca] = {0.0, 0.0, 0.0, 0.0}; - const double xmax_dca[ndim_dca] = {3.5, 5.0, 5.0, 5.0}; - - hs_dilepton_uls_dca_same = new THnSparseF("hs_dilepton_uls_dca_same", "hs_dilepton_uls_dca;m_{ee} (GeV/c^{2});DCA_{e^{+}}^{3D} (#sigma);DCA_{e^{-}}^{3D} (#sigma);DCA_{ee}^{3D} (#sigma);", ndim_dca, nbins_dca, xmin_dca, xmax_dca); - hs_dilepton_uls_dca_same->SetBinEdges(0, mee); - hs_dilepton_uls_dca_same->Sumw2(); - list->Add(hs_dilepton_uls_dca_same); + if (TString(subGroup).Contains("mix")) { + THnSparseF* hs_dilepton_uls_mix = reinterpret_cast(hs_dilepton_uls_same->Clone("hs_dilepton_uls_mix")); + THnSparseF* hs_dilepton_lspp_mix = reinterpret_cast(hs_dilepton_lspp_same->Clone("hs_dilepton_lspp_mix")); + THnSparseF* hs_dilepton_lsmm_mix = reinterpret_cast(hs_dilepton_lsmm_same->Clone("hs_dilepton_lsmm_mix")); + list->Add(hs_dilepton_uls_mix); + list->Add(hs_dilepton_lspp_mix); + list->Add(hs_dilepton_lsmm_mix); + } - hs_dilepton_lspp_dca_same = reinterpret_cast(hs_dilepton_uls_dca_same->Clone("hs_dilepton_lspp_dca_same")); - hs_dilepton_lsmm_dca_same = reinterpret_cast(hs_dilepton_uls_dca_same->Clone("hs_dilepton_lsmm_dca_same")); - list->Add(hs_dilepton_lspp_dca_same); - list->Add(hs_dilepton_lsmm_dca_same); + if (TString(subGroup).Contains("dca")) { + const int ndim_dca = 4; // mee, dca1, dca2, dca12 + + const int ndca = 27; + double dca[ndca] = {0.f}; + for (int i = 0; i < 20; i++) { + dca[i] = 0.1 * i; + } + for (int i = 20; i < ndca; i++) { + dca[i] = 0.5 * (i - 20) + 2.0; + } + + const int nbins_dca[ndim_dca] = {nm - 1, ndca - 1, ndca - 1, ndca - 1}; + const double xmin_dca[ndim_dca] = {0.0, 0.0, 0.0, 0.0}; + const double xmax_dca[ndim_dca] = {3.5, 5.0, 5.0, 5.0}; + + hs_dilepton_uls_dca_same = new THnSparseF("hs_dilepton_uls_dca_same", "hs_dilepton_uls_dca;m_{ee} (GeV/c^{2});DCA_{e^{+}}^{3D} (#sigma);DCA_{e^{-}}^{3D} (#sigma);DCA_{ee}^{3D} (#sigma);", ndim_dca, nbins_dca, xmin_dca, xmax_dca); + hs_dilepton_uls_dca_same->SetBinEdges(0, mee); + hs_dilepton_uls_dca_same->SetBinEdges(1, dca); + hs_dilepton_uls_dca_same->SetBinEdges(2, dca); + hs_dilepton_uls_dca_same->SetBinEdges(3, dca); + hs_dilepton_uls_dca_same->Sumw2(); + list->Add(hs_dilepton_uls_dca_same); + + hs_dilepton_lspp_dca_same = reinterpret_cast(hs_dilepton_uls_dca_same->Clone("hs_dilepton_lspp_dca_same")); + hs_dilepton_lsmm_dca_same = reinterpret_cast(hs_dilepton_uls_dca_same->Clone("hs_dilepton_lsmm_dca_same")); + list->Add(hs_dilepton_lspp_dca_same); + list->Add(hs_dilepton_lsmm_dca_same); + + THnSparseF* hs_dilepton_uls_dca_mix = reinterpret_cast(hs_dilepton_uls_dca_same->Clone("hs_dilepton_uls_dca_mix")); + THnSparseF* hs_dilepton_lspp_dca_mix = reinterpret_cast(hs_dilepton_lspp_dca_same->Clone("hs_dilepton_lspp_dca_mix")); + THnSparseF* hs_dilepton_lsmm_dca_mix = reinterpret_cast(hs_dilepton_lsmm_dca_same->Clone("hs_dilepton_lsmm_dca_mix")); + list->Add(hs_dilepton_uls_dca_mix); + list->Add(hs_dilepton_lspp_dca_mix); + list->Add(hs_dilepton_lsmm_dca_mix); + } - if (TString(subGroup) == "mc") { + if (TString(subGroup).Contains("mc")) { // create phiv template list->Add(new TH2F("hMvsPhiV_Pi0", "m_{ee} vs. #varphi_{V};#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", 32, 0, 3.2, 100, 0.0f, 0.1f)); // ee from pi0 dalitz decay list->Add(new TH2F("hMvsPhiV_Eta", "m_{ee} vs. #varphi_{V};#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", 32, 0, 3.2, 100, 0.0f, 0.1f)); // ee from eta dalitz decay @@ -201,45 +238,37 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* list->Add(new TH2F("hMvsOPA_Pi0", "m_{ee} vs. opening angle;opening angle (rad.);m_{ee} (GeV/c^{2})", 100, 0, 0.1, 100, 0.0f, 0.1f)); // ee from pi0 dalitz decay list->Add(new TH2F("hMvsOPA_Eta", "m_{ee} vs. opening angle;opening angle (rad.);m_{ee} (GeV/c^{2})", 100, 0, 0.1, 100, 0.0f, 0.1f)); // ee from eta dalitz decay list->Add(new TH2F("hMvsOPA_Photon", "m_{ee} vs. opening angle;opening angle (rad.);m_{ee} (GeV/c^{2})", 100, 0, 0.1, 100, 0.0f, 0.1f)); // ee from photon conversion - - } // end of mc + } // end of mc } else if (TString(histClass).Contains("MuMu")) { const int ndim = 4; // m, pt, dca, phiv const int nbins[ndim] = {90, 20, 50, 1}; const double xmin[ndim] = {0.2, 0.0, 0.0, 0.0}; const double xmax[ndim] = {1.1, 2.0, 5.0, 3.2}; - hs_dilepton_uls_same = new THnSparseF("hs_dilepton_uls_same", "hs_dilepton_uls;m_{#mu#mu} (GeV/c^{2});p_{T,#mu#mu} (GeV/c);DCA_{xy,#mu#mu} (#sigma);#varphi_{V} (rad.);", ndim, nbins, xmin, xmax); + hs_dilepton_uls_same = new THnSparseF("hs_dilepton_uls_same", "hs_dilepton_uls;m_{#mu#mu} (GeV/c^{2});p_{T,#mu#mu} (GeV/c);DCA_{#mu#mu}^{3D} (#sigma);#varphi_{V} (rad.);", ndim, nbins, xmin, xmax); hs_dilepton_uls_same->Sumw2(); list->Add(hs_dilepton_uls_same); - hs_dilepton_lspp_same = new THnSparseF("hs_dilepton_lspp_same", "hs_dilepton_lspp;m_{#mu#mu} (GeV/c^{2});p_{T,#mu#mu} (GeV/c);DCA_{xy,#mu#mu} (#sigma);#varphi_{V} (rad.);", ndim, nbins, xmin, xmax); + hs_dilepton_lspp_same = new THnSparseF("hs_dilepton_lspp_same", "hs_dilepton_lspp;m_{#mu#mu} (GeV/c^{2});p_{T,#mu#mu} (GeV/c);DCA_{#mu#mu}^{3D} (#sigma);#varphi_{V} (rad.);", ndim, nbins, xmin, xmax); hs_dilepton_lspp_same->Sumw2(); list->Add(hs_dilepton_lspp_same); - hs_dilepton_lsmm_same = new THnSparseF("hs_dilepton_lsmm_same", "hs_dilepton_lsmm;m_{#mu#mu} (GeV/c^{2});p_{T,#mu#mu} (GeV/c);DCA_{xy,#mu#mu} (#sigma);#varphi_{V} (rad.);", ndim, nbins, xmin, xmax); + hs_dilepton_lsmm_same = new THnSparseF("hs_dilepton_lsmm_same", "hs_dilepton_lsmm;m_{#mu#mu} (GeV/c^{2});p_{T,#mu#mu} (GeV/c);DCA_{#mu#mu}^{3D} (#sigma);#varphi_{V} (rad.);", ndim, nbins, xmin, xmax); hs_dilepton_lsmm_same->Sumw2(); list->Add(hs_dilepton_lsmm_same); + + if (TString(subGroup).Contains("mix")) { + THnSparseF* hs_dilepton_uls_mix = reinterpret_cast(hs_dilepton_uls_same->Clone("hs_dilepton_uls_mix")); + THnSparseF* hs_dilepton_lspp_mix = reinterpret_cast(hs_dilepton_lspp_same->Clone("hs_dilepton_lspp_mix")); + THnSparseF* hs_dilepton_lsmm_mix = reinterpret_cast(hs_dilepton_lsmm_same->Clone("hs_dilepton_lsmm_mix")); + list->Add(hs_dilepton_uls_mix); + list->Add(hs_dilepton_lspp_mix); + list->Add(hs_dilepton_lsmm_mix); + } } else { LOGF(info, "EE or MuMu are supported."); } - if (TString(subGroup) == "mix") { - THnSparseF* hs_dilepton_uls_mix = reinterpret_cast(hs_dilepton_uls_same->Clone("hs_dilepton_uls_mix")); - THnSparseF* hs_dilepton_lspp_mix = reinterpret_cast(hs_dilepton_lspp_same->Clone("hs_dilepton_lspp_mix")); - THnSparseF* hs_dilepton_lsmm_mix = reinterpret_cast(hs_dilepton_lsmm_same->Clone("hs_dilepton_lsmm_mix")); - list->Add(hs_dilepton_uls_mix); - list->Add(hs_dilepton_lspp_mix); - list->Add(hs_dilepton_lsmm_mix); - - THnSparseF* hs_dilepton_uls_dca_mix = reinterpret_cast(hs_dilepton_uls_dca_same->Clone("hs_dilepton_uls_dca_mix")); - THnSparseF* hs_dilepton_lspp_dca_mix = reinterpret_cast(hs_dilepton_lspp_dca_same->Clone("hs_dilepton_lspp_dca_mix")); - THnSparseF* hs_dilepton_lsmm_dca_mix = reinterpret_cast(hs_dilepton_lsmm_dca_same->Clone("hs_dilepton_lsmm_dca_mix")); - list->Add(hs_dilepton_uls_dca_mix); - list->Add(hs_dilepton_lspp_dca_mix); - list->Add(hs_dilepton_lsmm_dca_mix); - } - list->Add(new TH1F("hNpair_uls", "Number of ULS pairs per collision", 101, -0.5f, 100.5f)); list->Add(new TH1F("hNpair_lspp", "Number of LS++ pairs per collision", 101, -0.5f, 100.5f)); list->Add(new TH1F("hNpair_lsmm", "Number of LS-- pairs per collision", 101, -0.5f, 100.5f)); @@ -278,6 +307,7 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* list->Add(new TH1F("hNclsITS", "number of ITS clusters", 8, -0.5, 7.5)); list->Add(new TH1F("hChi2ITS", "chi2/number of ITS clusters", 100, 0, 10)); list->Add(new TH1F("hITSClusterMap", "ITS cluster map", 128, -0.5, 127.5)); + list->Add(new TH1F("hMeanClusterSizeITS", "mean cluster size ITS; on ITS #times cos(#lambda)", 160, 0, 16)); if (TString(subGroup).Contains("mc")) { list->Add(new TH2F("hPtGen_DeltaPtOverPtGen", "electron p_{T} resolution;p_{T}^{gen} (GeV/c);(p_{T}^{rec} - p_{T}^{gen})/p_{T}^{gen}", 1000, 0, maxP, 400, -1.0f, 1.0f)); list->Add(new TH2F("hPtGen_DeltaEta", "electron #eta resolution;p_{T}^{gen} (GeV/c);#eta^{rec} - #eta^{gen}", 1000, 0, maxP, 400, -1.0f, 1.0f)); @@ -410,16 +440,16 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* list->Add(new TH1F("hZvtx_after", "vertex z; Zvtx (cm)", 100, -50, +50)); list->Add(new TH1F("hNrecPerMCCollision", "Nrec per mc collisions;N_{rec} collisions per MC collisions", 101, -0.5f, 100.5f)); - if (TString(subGroup) == "ConversionStudy") { - list->Add(new TH2F("hPhotonRxy", "conversion point in XY MC;V_{x} (cm);V_{y} (cm)", 2000, -100.0f, 100.0f, 2000, -100.0f, 100.0f)); - list->Add(new TH2F("hPhotonRZ", "conversion point in RZ MC;V_{z} (cm);R_{xy} (cm)", 5000, -250.0f, 250.0f, 1000, 0.f, 100.0f)); - list->Add(new TH2F("hPhotonPhivsRxy", "conversion point of #varphi vs. R_{xy} MC;#varphi (rad.);R_{xy} (cm);N_{e}", 360, 0.0f, TMath::TwoPi(), 200, 0, 200)); - } - if (TString(subGroup) == "Photon") { list->Add(new TH1F("hPt_Photon", "photon pT;p_{T} (GeV/c)", 2000, 0.0f, 20)); list->Add(new TH1F("hY_Photon", "photon y;rapidity y", 40, -2.0f, 2.0f)); list->Add(new TH1F("hPhi_Photon", "photon #varphi;#varphi (rad.)", 180, 0, TMath::TwoPi())); + list->Add(new TH1F("hPt_ConvertedPhoton", "converted photon pT;p_{T} (GeV/c)", 2000, 0.0f, 20)); + list->Add(new TH1F("hY_ConvertedPhoton", "converted photon y;rapidity y", 40, -2.0f, 2.0f)); + list->Add(new TH1F("hPhi_ConvertedPhoton", "converted photon #varphi;#varphi (rad.)", 180, 0, TMath::TwoPi())); + list->Add(new TH2F("hPhotonRxy", "conversion point in XY MC;V_{x} (cm);V_{y} (cm)", 2000, -100.0f, 100.0f, 2000, -100.0f, 100.0f)); + list->Add(new TH2F("hPhotonRZ", "conversion point in RZ MC;V_{z} (cm);R_{xy} (cm)", 2000, -100.0f, 100.0f, 1000, 0.f, 100.0f)); + list->Add(new TH2F("hPhotonPhivsRxy", "conversion point of #varphi vs. R_{xy} MC;#varphi (rad.);R_{xy} (cm);N_{e}", 360, 0.0f, TMath::TwoPi(), 100, 0, 100)); } if (TString(subGroup) == "Pi0Eta") { @@ -455,25 +485,25 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* pTgg10[i] = 0.5 * (i - 50) + 5.0; // from 5 to 10 GeV/c, evety 0.5 GeV/c } if (TString(histClass) == "tagging_pi0") { - list->Add(new TH2F("hMggPt_Same", "m_{ee#gamma} vs. p_{T,ee};m_{ee#gamma} (GeV/c^{2});p_{T,ee} (GeV/c)", nmgg04 - 1, mgg04, npTgg10 - 1, pTgg10)); - list->Add(new TH2F("hMggPt_Mixed", "m_{ee#gamma} vs. p_{T,ee};m_{ee#gamma} (GeV/c^{2});p_{T,ee} (GeV/c)", nmgg04 - 1, mgg04, npTgg10 - 1, pTgg10)); + list->Add(new TH2F("hMggPt_Same", "m_{ee#gamma} vs. p_{T,#gamma};m_{ee#gamma} (GeV/c^{2});p_{T,#gamma} (GeV/c)", nmgg04 - 1, mgg04, npTgg10 - 1, pTgg10)); + list->Add(new TH2F("hMggPt_Mixed", "m_{ee#gamma} vs. p_{T,#gamma};m_{ee#gamma} (GeV/c^{2});p_{T,#gamma} (GeV/c)", nmgg04 - 1, mgg04, npTgg10 - 1, pTgg10)); reinterpret_cast(list->FindObject("hMggPt_Same"))->Sumw2(); reinterpret_cast(list->FindObject("hMggPt_Mixed"))->Sumw2(); } if (TString(histClass) == "tagging_pi0_mc") { if (TString(subGroup) == "pcm") { - list->Add(new TH1F("hPt_v0photon_Pi0_Primary", "reconstcuted v0 photon from primary #pi^{0};p_{T,ee} (GeV/c);N_{ee}^{#pi^{0}}", npTgg10 - 1, pTgg10)); // denominator for conditional probability + list->Add(new TH1F("hPt_v0photon_Pi0_Primary", "reconstcuted v0 photon from primary #pi^{0};p_{T,#gamma} (GeV/c);N_{#gamma}^{#pi^{0}}", npTgg10 - 1, pTgg10)); // denominator for conditional probability reinterpret_cast(list->FindObject("hPt_v0photon_Pi0_Primary"))->Sumw2(); - list->Add(new TH1F("hPt_v0photon_Pi0_FromWD", "reconstcuted v0 photon from #pi^{0} from WD;p_{T,ee} (GeV/c);N_{ee}^{#pi^{0}}", npTgg10 - 1, pTgg10)); // denominator for conditional probability + list->Add(new TH1F("hPt_v0photon_Pi0_FromWD", "reconstcuted v0 photon from #pi^{0} from WD;p_{T,#gamma} (GeV/c);N_{#gamma}^{#pi^{0}}", npTgg10 - 1, pTgg10)); // denominator for conditional probability reinterpret_cast(list->FindObject("hPt_v0photon_Pi0_FromWD"))->Sumw2(); - list->Add(new TH1F("hPt_v0photon_Pi0_hs", "reconstcuted v0 photon from #pi^{0} from hadronic shower in materials;p_{T,ee} (GeV/c);N_{ee}^{#pi^{0}}", npTgg10 - 1, pTgg10)); // denominator for conditional probability + list->Add(new TH1F("hPt_v0photon_Pi0_hs", "reconstcuted v0 photon from #pi^{0} from hadronic shower in materials;p_{T,#gamma} (GeV/c);N_{#gamma}^{#pi^{0}}", npTgg10 - 1, pTgg10)); // denominator for conditional probability reinterpret_cast(list->FindObject("hPt_v0photon_Pi0_hs"))->Sumw2(); } else if (TString(subGroup) == "pair") { - list->Add(new TH2F("hMggPt_Pi0_Primary", "reconstructed m_{ee#gamma} vs. p_{T,ee} from primary #pi^{0};m_{ee#gamma} (GeV/c^{2});p_{T,ee} (GeV/c);N_{ee}^{tagged #pi^{0}}", nmgg04 - 1, mgg04, npTgg10 - 1, pTgg10)); // numerator for conditional probability + list->Add(new TH2F("hMggPt_Pi0_Primary", "reconstructed m_{ee#gamma} vs. p_{T,#gamma} from primary #pi^{0};m_{ee#gamma} (GeV/c^{2});p_{T,#gamma} (GeV/c);N_{#gamma}^{tagged #pi^{0}}", nmgg04 - 1, mgg04, npTgg10 - 1, pTgg10)); // numerator for conditional probability reinterpret_cast(list->FindObject("hMggPt_Pi0_Primary"))->Sumw2(); - list->Add(new TH2F("hMggPt_Pi0_FromWD", "reconstructed m_{ee#gamma} vs. p_{T,ee} from #pi^{0} from WD;m_{ee#gamma} (GeV/c^{2});p_{T,ee} (GeV/c);N_{ee}^{tagged #pi^{0}}", nmgg04 - 1, mgg04, npTgg10 - 1, pTgg10)); // numerator for conditional probability + list->Add(new TH2F("hMggPt_Pi0_FromWD", "reconstructed m_{ee#gamma} vs. p_{T,#gamma} from #pi^{0} from WD;m_{ee#gamma} (GeV/c^{2});p_{T,#gamma} (GeV/c);N_{#gamma}^{tagged #pi^{0}}", nmgg04 - 1, mgg04, npTgg10 - 1, pTgg10)); // numerator for conditional probability reinterpret_cast(list->FindObject("hMggPt_Pi0_FromWD"))->Sumw2(); - list->Add(new TH2F("hMggPt_Pi0_hs", "reconstructed m_{ee#gamma} vs. p_{T,ee} from #pi^{0} from hadronic shower in material;m_{ee#gamma} (GeV/c^{2});p_{T,ee} (GeV/c);N_{ee}^{tagged #pi^{0}}", nmgg04 - 1, mgg04, npTgg10 - 1, pTgg10)); // numerator for conditional probability + list->Add(new TH2F("hMggPt_Pi0_hs", "reconstructed m_{ee#gamma} vs. p_{T,#gamma} from #pi^{0} from hadronic shower in material;m_{ee#gamma} (GeV/c^{2});p_{T,#gamma} (GeV/c);N_{#gamma}^{tagged #pi^{0}}", nmgg04 - 1, mgg04, npTgg10 - 1, pTgg10)); // numerator for conditional probability reinterpret_cast(list->FindObject("hMggPt_Pi0_hs"))->Sumw2(); } } @@ -492,23 +522,36 @@ void o2::aod::emphotonhistograms::DefineHistograms(THashList* list, const char* if (TString(histClass) == "photon_hbt") { const int nm_hbt = 6; double m_hbt[nm_hbt] = {0.0, 0.14, 0.5, 1.1, 2.0, 2.7}; - - const int ndim = 9; // m1, m2, kt, qinv, qlong_cms, qout_cms, qside_cms, qt_cms, qlong_lcms - const int nbins[ndim] = {nm_hbt - 1, nm_hbt - 1, 10, 40, 80, 80, 80, 40, 80}; - const double xmin[ndim] = {0.0, 0.0, 0.0, 0.0, -0.4, -0.4, -0.4, 0.0, -0.4}; - const double xmax[ndim] = {2.7, 2.7, 1.0, 0.4, +0.4, +0.4, +0.4, +0.4, +0.4}; - - THnSparseF* hs_q_same = new THnSparseF("hs_q_same", "hs_q_same;m_{1} (GeV/c^{2});m_{2} (GeV/c^{2});k_{T} (GeV/c);q_{inv} (GeV/c);q_{long}^{CMS} (GeV/c);q_{out}^{CMS} (GeV/c);q_{side}^{CMS} (GeV/c);q_{T}^{CMS} (GeV/c);q_{long}^{LCMS} (GeV/c);", ndim, nbins, xmin, xmax); - THnSparseF* hs_q_mix = new THnSparseF("hs_q_mix", "hs_q_mix;m_{1} (GeV/c^{2});m_{2} (GeV/c^{2});k_{T} (GeV/c);q_{inv} (GeV/c);q_{long}^{CMS} (GeV/c);q_{out}^{CMS} (GeV/c);q_{side}^{CMS} (GeV/c);q_{T}^{CMS} (GeV/c);q_{long}^{LCMS} (GeV/c);", ndim, nbins, xmin, xmax); - hs_q_same->Sumw2(); - hs_q_mix->Sumw2(); - hs_q_same->SetBinEdges(0, m_hbt); - hs_q_same->SetBinEdges(1, m_hbt); - hs_q_mix->Sumw2(); - hs_q_mix->SetBinEdges(0, m_hbt); - hs_q_mix->SetBinEdges(1, m_hbt); - list->Add(hs_q_same); - list->Add(hs_q_mix); + THnSparseF* hs_q_same = nullptr; + THnSparseF* hs_q_mix = nullptr; + + if (TString(subGroup) == "1d") { + const int ndim_1d = 4; // m1, m2, kt, qinv + const int nbins_1d[ndim_1d] = {nm_hbt - 1, nm_hbt - 1, 10, 40}; + const double xmin_1d[ndim_1d] = {0.0, 0.0, 0.0, 0.0}; + const double xmax_1d[ndim_1d] = {2.7, 2.7, 1.0, 0.4}; + + hs_q_same = new THnSparseF("hs_q_same", "hs_q_same;m_{1} (GeV/c^{2});m_{2} (GeV/c^{2});k_{T} (GeV/c);q_{inv} (GeV/c);q_{long}^{CMS} (GeV/c);q_{out}^{CMS} (GeV/c);q_{side}^{CMS} (GeV/c);q_{long}^{LCMS} (GeV/c);", ndim_1d, nbins_1d, xmin_1d, xmax_1d); + hs_q_same->Sumw2(); + hs_q_same->SetBinEdges(0, m_hbt); + hs_q_same->SetBinEdges(1, m_hbt); + hs_q_mix = reinterpret_cast(hs_q_same->Clone("hs_q_mix")); + list->Add(hs_q_same); + list->Add(hs_q_mix); + } else if (TString(subGroup) == "3d") { + const int ndim_3d = 8; // m1, m2, kt, qinv, qlong_cms, qout_cms, qside_cms, qlong_lcms + const int nbins_3d[ndim_3d] = {nm_hbt - 1, nm_hbt - 1, 10, 40, 80, 80, 80, 80}; + const double xmin_3d[ndim_3d] = {0.0, 0.0, 0.0, 0.0, -0.4, -0.4, -0.4, -0.4}; + const double xmax_3d[ndim_3d] = {2.7, 2.7, 1.0, 0.4, +0.4, +0.4, +0.4, +0.4}; + + hs_q_same = new THnSparseF("hs_q_same", "hs_q_same;m_{1} (GeV/c^{2});m_{2} (GeV/c^{2});k_{T} (GeV/c);q_{inv} (GeV/c);q_{long}^{CMS} (GeV/c);q_{out}^{CMS} (GeV/c);q_{side}^{CMS} (GeV/c);q_{long}^{LCMS} (GeV/c);", ndim_3d, nbins_3d, xmin_3d, xmax_3d); + hs_q_same->Sumw2(); + hs_q_same->SetBinEdges(0, m_hbt); + hs_q_same->SetBinEdges(1, m_hbt); + hs_q_mix = reinterpret_cast(hs_q_same->Clone("hs_q_mix")); + list->Add(hs_q_same); + list->Add(hs_q_mix); + } } } THashList* o2::aod::emphotonhistograms::AddHistClass(THashList* list, const char* histClass) diff --git a/PWGEM/PhotonMeson/Core/HistogramsLibrary.h b/PWGEM/PhotonMeson/Core/HistogramsLibrary.h index a3e11a86a69..7621e103409 100644 --- a/PWGEM/PhotonMeson/Core/HistogramsLibrary.h +++ b/PWGEM/PhotonMeson/Core/HistogramsLibrary.h @@ -73,9 +73,10 @@ void FillHistClass(THashList* list, const char* subGroup, T const& obj) reinterpret_cast(list->FindObject("hEtaPhi"))->Fill(obj.phi(), obj.eta()); reinterpret_cast(list->FindObject("hRadius"))->Fill(obj.vz(), obj.v0radius()); reinterpret_cast(list->FindObject("hCosPA"))->Fill(obj.cospa()); + reinterpret_cast(list->FindObject("hCosPA_Rxy"))->Fill(obj.v0radius(), obj.cospa()); reinterpret_cast(list->FindObject("hPCA"))->Fill(obj.pca()); reinterpret_cast(list->FindObject("hPCA_Rxy"))->Fill(obj.v0radius(), obj.pca()); - reinterpret_cast(list->FindObject("hDCAxyz"))->Fill(obj.dcaXYv0topv(), obj.dcaZv0topv()); + reinterpret_cast(list->FindObject("hDCAxyz"))->Fill(obj.dcaXYtopv(), obj.dcaZtopv()); reinterpret_cast(list->FindObject("hAPplot"))->Fill(obj.alpha(), obj.qtarm()); reinterpret_cast(list->FindObject("hMassGamma"))->Fill(obj.v0radius(), obj.mGamma()); reinterpret_cast(list->FindObject("hGammaRxy"))->Fill(obj.vx(), obj.vy()); @@ -97,14 +98,13 @@ void FillHistClass(THashList* list, const char* subGroup, T const& obj) reinterpret_cast(list->FindObject("hChi2TPC"))->Fill(obj.tpcChi2NCl()); reinterpret_cast(list->FindObject("hChi2ITS"))->Fill(obj.itsChi2NCl()); reinterpret_cast(list->FindObject("hITSClusterMap"))->Fill(obj.itsClusterMap()); + reinterpret_cast(list->FindObject("hMeanClusterSizeITS"))->Fill(obj.meanClusterSizeITS() * std::cos(std::atan(obj.tgl()))); reinterpret_cast(list->FindObject("hTPCdEdx"))->Fill(obj.tpcInnerParam(), obj.tpcSignal()); reinterpret_cast(list->FindObject("hTPCNsigmaEl"))->Fill(obj.tpcInnerParam(), obj.tpcNSigmaEl()); reinterpret_cast(list->FindObject("hTPCNsigmaPi"))->Fill(obj.tpcInnerParam(), obj.tpcNSigmaPi()); reinterpret_cast(list->FindObject("hXY"))->Fill(obj.x(), obj.y()); reinterpret_cast(list->FindObject("hZX"))->Fill(obj.z(), obj.x()); reinterpret_cast(list->FindObject("hZY"))->Fill(obj.z(), obj.y()); - reinterpret_cast(list->FindObject("hDCAxyZ"))->Fill(obj.z(), obj.dcaXY()); - reinterpret_cast(list->FindObject("hXZ_tgl"))->Fill(obj.tgl(), obj.z() / obj.x() - obj.tgl()); } else if constexpr (htype == EMHistType::kTrack) { reinterpret_cast(list->FindObject("hPt"))->Fill(obj.pt()); reinterpret_cast(list->FindObject("hQoverPt"))->Fill(obj.sign() / obj.pt()); @@ -121,6 +121,7 @@ void FillHistClass(THashList* list, const char* subGroup, T const& obj) reinterpret_cast(list->FindObject("hChi2TPC"))->Fill(obj.tpcChi2NCl()); reinterpret_cast(list->FindObject("hChi2ITS"))->Fill(obj.itsChi2NCl()); reinterpret_cast(list->FindObject("hITSClusterMap"))->Fill(obj.itsClusterMap()); + reinterpret_cast(list->FindObject("hMeanClusterSizeITS"))->Fill(obj.meanClusterSizeITS() * std::cos(std::atan(obj.tgl()))); reinterpret_cast(list->FindObject("hTPCdEdx"))->Fill(obj.tpcInnerParam(), obj.tpcSignal()); reinterpret_cast(list->FindObject("hTPCNsigmaEl"))->Fill(obj.tpcInnerParam(), obj.tpcNSigmaEl()); reinterpret_cast(list->FindObject("hTPCNsigmaMu"))->Fill(obj.tpcInnerParam(), obj.tpcNSigmaMu()); diff --git a/PWGEM/PhotonMeson/Core/V0PhotonCut.h b/PWGEM/PhotonMeson/Core/V0PhotonCut.h index 1a2132cc640..15d68256064 100644 --- a/PWGEM/PhotonMeson/Core/V0PhotonCut.h +++ b/PWGEM/PhotonMeson/Core/V0PhotonCut.h @@ -301,17 +301,17 @@ class V0PhotonCut : public TNamed // const float z_max = +31.15; // cm float x = abs(v0.vx()); // cm, measured secondary vertex of gamma->ee float y = v0.vy(); // cm, measured secondary vertex of gamma->ee - // float z = v0.vz(); // cm, measured secondary vertex of gamma->ee + float z = v0.vz(); // cm, measured secondary vertex of gamma->ee float rxy = sqrt(x * x + y * y); - if (rxy < 7.0 || 16.0 < rxy) { + if (rxy < 7.0 || 15.0 < rxy) { return false; } - // float z_exp = z_min + (rxy - rxy_min) / TMath::Tan(10.86 * TMath::DegToRad()); // cm, expected position rxy of W wire as a function of z - // if (abs(z - z_exp) > margin_z) { - // return false; - // } + // r = 0.192 * z + 8.88 (cm) expected wire position in RZ plane.TMath::Tan(10.86 * TMath::DegToRad()) = 0.192 + if (rxy > 0.192 * z + 14.0) { // upper limit + return false; + } float dxy = abs(1.0 * y - x * TMath::Tan(-8.52 * TMath::DegToRad())) / sqrt(pow(1.0, 2) + pow(TMath::Tan(-8.52 * TMath::DegToRad()), 2)); return !(dxy > margin_xy); @@ -382,17 +382,26 @@ class V0PhotonCut : public TNamed return mMinChi2PerClusterITS < track.itsChi2NCl() && track.itsChi2NCl() < mMaxChi2PerClusterITS; 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 && abs(track.y()) > 15.f) { + return false; + } if (track.x() > 82.9 && abs(track.y()) > abs(track.x() * TMath::Tan(10.f * TMath::DegToRad())) + 5.f) { return false; } - - 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) < 7.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())); + if (track.x() > 82.9 && abs(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); diff --git a/PWGEM/PhotonMeson/DataModel/gammaTables.h b/PWGEM/PhotonMeson/DataModel/gammaTables.h index 7bf03140ace..dc0b62252bb 100644 --- a/PWGEM/PhotonMeson/DataModel/gammaTables.h +++ b/PWGEM/PhotonMeson/DataModel/gammaTables.h @@ -228,7 +228,51 @@ DECLARE_SOA_DYNAMIC_COLUMN(P, p, [](float px, float py, float pz) -> float { ret 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_COLUMN(IsAmbTrack, isAmbTrack, bool); //! +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++) { + int cluster_size_per_layer = (itsClusterSizes >> (layer * 4)) & 0xf; + if (cluster_size_per_layer > 0) { + nl++; + } + total_cluster_size += cluster_size_per_layer; + } + if (nl > 0) { + return static_cast(total_cluster_size) / static_cast(nl); + } else { + return 0; + } +}); +DECLARE_SOA_DYNAMIC_COLUMN(MeanClusterSizeITSib, meanClusterSizeITSib, [](uint32_t itsClusterSizes) -> float { + int total_cluster_size = 0, nl = 0; + for (unsigned int layer = 0; layer < 3; layer++) { + int cluster_size_per_layer = (itsClusterSizes >> (layer * 4)) & 0xf; + if (cluster_size_per_layer > 0) { + nl++; + } + total_cluster_size += cluster_size_per_layer; + } + if (nl > 0) { + return static_cast(total_cluster_size) / static_cast(nl); + } else { + return 0; + } +}); +DECLARE_SOA_DYNAMIC_COLUMN(MeanClusterSizeITSob, meanClusterSizeITSob, [](uint32_t itsClusterSizes) -> float { + int total_cluster_size = 0, nl = 0; + for (unsigned int layer = 4; 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; + } + if (nl > 0) { + return static_cast(total_cluster_size) / static_cast(nl); + } else { + return 0; + } +}); } // namespace v0leg DECLARE_SOA_TABLE(V0Legs, "AOD", "V0LEG", //! o2::soa::Index<>, v0leg::CollisionId, v0leg::TrackId, v0leg::Sign, @@ -237,7 +281,7 @@ DECLARE_SOA_TABLE(V0Legs, "AOD", "V0LEG", //! track::TPCNClsFindable, track::TPCNClsFindableMinusFound, track::TPCNClsFindableMinusCrossedRows, track::TPCChi2NCl, track::TPCInnerParam, track::TPCSignal, pidtpc::TPCNSigmaEl, pidtpc::TPCNSigmaPi, - track::ITSClusterMap, track::ITSChi2NCl, track::DetectorMap, + track::ITSClusterSizes, track::ITSChi2NCl, track::DetectorMap, track::X, track::Y, track::Z, track::Tgl, track::Signed1Pt, // dynamic column @@ -249,9 +293,12 @@ DECLARE_SOA_TABLE(V0Legs, "AOD", "V0LEG", //! track::TPCNClsCrossedRows, track::TPCCrossedRowsOverFindableCls, track::TPCFoundOverFindableCls, - track::ITSNCls, + track::v001::ITSClusterMap, track::v001::ITSNCls, track::v001::ITSNClsInnerBarrel, track::HasITS, track::HasTPC, - track::HasTRD, track::HasTOF); + track::HasTRD, track::HasTOF, + v0leg::MeanClusterSizeITS, + v0leg::MeanClusterSizeITSib, + v0leg::MeanClusterSizeITSob); // iterators using V0Leg = V0Legs::iterator; @@ -269,14 +316,13 @@ DECLARE_SOA_COLUMN(Px, px, float); //! px f 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(MGammaPV, mGammaPV, float); //! invariant mass of dielectron at PV -DECLARE_SOA_COLUMN(DCAxyV0ToPV, dcaXYv0topv, float); //! DCAxy of V0 to PV -DECLARE_SOA_COLUMN(DCAzV0ToPV, dcaZv0topv, float); //! DCAz of V0 to PV -DECLARE_SOA_COLUMN(CosPA, cospa, 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(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(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_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); }); @@ -290,8 +336,7 @@ DECLARE_SOA_TABLE(V0PhotonsKF, "AOD", "V0PHOTONKF", //! v0photonkf::Vx, v0photonkf::Vy, v0photonkf::Vz, v0photonkf::Px, v0photonkf::Py, v0photonkf::Pz, v0photonkf::MGamma, - // v0photonkf::MGammaPV, - v0photonkf::DCAxyV0ToPV, v0photonkf::DCAzV0ToPV, + v0photonkf::DCAxyToPV, v0photonkf::DCAzToPV, v0photonkf::CosPA, v0photonkf::PCA, v0photonkf::Alpha, v0photonkf::QtArm, v0photonkf::ChiSquareNDF, @@ -320,6 +365,51 @@ DECLARE_SOA_COLUMN(PrefilterBit, pfb, uint8_t); //! 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(MeanClusterSizeITS, meanClusterSizeITS, [](uint32_t itsClusterSizes) -> float { + 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; + } + if (nl > 0) { + return static_cast(total_cluster_size) / static_cast(nl); + } else { + return 0; + } +}); +DECLARE_SOA_DYNAMIC_COLUMN(MeanClusterSizeITSib, meanClusterSizeITSib, [](uint32_t itsClusterSizes) -> float { + int total_cluster_size = 0, nl = 0; + for (unsigned int layer = 0; layer < 3; layer++) { + int cluster_size_per_layer = (itsClusterSizes >> (layer * 4)) & 0xf; + if (cluster_size_per_layer > 0) { + nl++; + } + total_cluster_size += cluster_size_per_layer; + } + if (nl > 0) { + return static_cast(total_cluster_size) / static_cast(nl); + } else { + return 0; + } +}); +DECLARE_SOA_DYNAMIC_COLUMN(MeanClusterSizeITSob, meanClusterSizeITSob, [](uint32_t itsClusterSizes) -> float { + int total_cluster_size = 0, nl = 0; + for (unsigned int layer = 4; 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; + } + if (nl > 0) { + return static_cast(total_cluster_size) / static_cast(nl); + } else { + return 0; + } +}); } // namespace emprimaryelectron DECLARE_SOA_TABLE(EMPrimaryElectrons, "AOD", "EMPRIMARYEL", //! o2::soa::Index<>, emprimaryelectron::CollisionId, @@ -329,19 +419,22 @@ DECLARE_SOA_TABLE(EMPrimaryElectrons, "AOD", "EMPRIMARYEL", //! track::TPCChi2NCl, track::TPCInnerParam, track::TPCSignal, pidtpc::TPCNSigmaEl, pidtpc::TPCNSigmaMu, pidtpc::TPCNSigmaPi, pidtpc::TPCNSigmaKa, pidtpc::TPCNSigmaPr, pidtofbeta::Beta, pidtof::TOFNSigmaEl, pidtof::TOFNSigmaMu, pidtof::TOFNSigmaPi, pidtof::TOFNSigmaKa, pidtof::TOFNSigmaPr, - track::ITSClusterMap, track::ITSChi2NCl, track::DetectorMap, track::Signed1Pt, track::CYY, track::CZZ, track::CZY, + track::ITSClusterSizes, track::ITSChi2NCl, track::DetectorMap, track::Tgl, track::Signed1Pt, track::CYY, track::CZZ, track::CZY, // dynamic column track::TPCNClsFound, track::TPCNClsCrossedRows, track::TPCCrossedRowsOverFindableCls, track::TPCFoundOverFindableCls, - track::ITSNCls, + track::v001::ITSClusterMap, track::v001::ITSNCls, track::v001::ITSNClsInnerBarrel, track::HasITS, track::HasTPC, track::HasTRD, track::HasTOF, emprimaryelectron::Px, emprimaryelectron::Py, - emprimaryelectron::Pz); + emprimaryelectron::Pz, + emprimaryelectron::MeanClusterSizeITS, + emprimaryelectron::MeanClusterSizeITSib, + emprimaryelectron::MeanClusterSizeITSob); // iterators using EMPrimaryElectron = EMPrimaryElectrons::iterator; @@ -363,16 +456,16 @@ DECLARE_SOA_COLUMN(Pt, pt, float); DECLARE_SOA_COLUMN(Eta, eta, float); DECLARE_SOA_COLUMN(Phi, phi, float); DECLARE_SOA_COLUMN(Mass, mass, float); +DECLARE_SOA_COLUMN(Rapidity, rapidity, float); DECLARE_SOA_COLUMN(PhiV, phiv, float); DECLARE_SOA_COLUMN(OpeningAngle, opangle, float); -DECLARE_SOA_COLUMN(DCAXY, dcaXY, float); -DECLARE_SOA_COLUMN(DCAZ, dcaZ, float); DECLARE_SOA_COLUMN(Sign, sign, int); //! DECLARE_SOA_DYNAMIC_COLUMN(Energy, e, [](float pt, float eta, float m) { return RecoDecay::sqrtSumOfSquares(pt * std::cosh(eta), m); }); // e = sqrt(p*p + m*m) } // namespace dalitzee DECLARE_SOA_TABLE(DalitzEEs, "AOD", "DALITZEE", //! o2::soa::Index<>, dalitzee::CollisionId, dalitzee::PosTrackId, dalitzee::NegTrackId, - dalitzee::Pt, dalitzee::Eta, dalitzee::Phi, dalitzee::Mass, dalitzee::PhiV, dalitzee::OpeningAngle, dalitzee::DCAXY, dalitzee::DCAZ, dalitzee::Sign, + dalitzee::Pt, dalitzee::Eta, dalitzee::Phi, dalitzee::Mass, dalitzee::Rapidity, + dalitzee::PhiV, dalitzee::OpeningAngle, dalitzee::Sign, dalitzee::Energy); // iterators using DalitzEE = DalitzEEs::iterator; @@ -391,6 +484,51 @@ DECLARE_SOA_COLUMN(PrefilterBit, pfb, uint8_t); //! 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(MeanClusterSizeITS, meanClusterSizeITS, [](uint32_t itsClusterSizes) -> float { + 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; + } + if (nl > 0) { + return static_cast(total_cluster_size) / static_cast(nl); + } else { + return 0; + } +}); +DECLARE_SOA_DYNAMIC_COLUMN(MeanClusterSizeITSib, meanClusterSizeITSib, [](uint32_t itsClusterSizes) -> float { + int total_cluster_size = 0, nl = 0; + for (unsigned int layer = 0; layer < 3; layer++) { + int cluster_size_per_layer = (itsClusterSizes >> (layer * 4)) & 0xf; + if (cluster_size_per_layer > 0) { + nl++; + } + total_cluster_size += cluster_size_per_layer; + } + if (nl > 0) { + return static_cast(total_cluster_size) / static_cast(nl); + } else { + return 0; + } +}); +DECLARE_SOA_DYNAMIC_COLUMN(MeanClusterSizeITSob, meanClusterSizeITSob, [](uint32_t itsClusterSizes) -> float { + int total_cluster_size = 0, nl = 0; + for (unsigned int layer = 4; 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; + } + if (nl > 0) { + return static_cast(total_cluster_size) / static_cast(nl); + } else { + return 0; + } +}); } // namespace emprimarymuon DECLARE_SOA_TABLE(EMPrimaryMuons, "AOD", "EMPRIMARYMU", //! o2::soa::Index<>, emprimarymuon::CollisionId, @@ -400,19 +538,22 @@ DECLARE_SOA_TABLE(EMPrimaryMuons, "AOD", "EMPRIMARYMU", //! track::TPCChi2NCl, track::TPCInnerParam, track::TPCSignal, pidtpc::TPCNSigmaEl, pidtpc::TPCNSigmaMu, pidtpc::TPCNSigmaPi, pidtpc::TPCNSigmaKa, pidtpc::TPCNSigmaPr, pidtofbeta::Beta, pidtof::TOFNSigmaEl, pidtof::TOFNSigmaMu, pidtof::TOFNSigmaPi, pidtof::TOFNSigmaKa, pidtof::TOFNSigmaPr, - track::ITSClusterMap, track::ITSChi2NCl, track::DetectorMap, track::Signed1Pt, track::CYY, track::CZZ, track::CZY, + track::ITSClusterSizes, track::ITSChi2NCl, track::DetectorMap, track::Tgl, track::Signed1Pt, track::CYY, track::CZZ, track::CZY, // dynamic column track::TPCNClsFound, track::TPCNClsCrossedRows, track::TPCCrossedRowsOverFindableCls, track::TPCFoundOverFindableCls, - track::ITSNCls, + track::v001::ITSClusterMap, track::v001::ITSNCls, track::v001::ITSNClsInnerBarrel, track::HasITS, track::HasTPC, track::HasTRD, track::HasTOF, emprimarymuon::Px, emprimarymuon::Py, - emprimarymuon::Pz); + emprimarymuon::Pz, + emprimarymuon::MeanClusterSizeITS, + emprimarymuon::MeanClusterSizeITSib, + emprimarymuon::MeanClusterSizeITSob); // iterators using EMPrimaryMuon = EMPrimaryMuons::iterator; @@ -434,16 +575,16 @@ DECLARE_SOA_COLUMN(Pt, pt, float); DECLARE_SOA_COLUMN(Eta, eta, float); DECLARE_SOA_COLUMN(Phi, phi, float); DECLARE_SOA_COLUMN(Mass, mass, float); +DECLARE_SOA_COLUMN(Rapidity, rapidity, float); DECLARE_SOA_COLUMN(PhiV, phiv, float); DECLARE_SOA_COLUMN(OpeningAngle, opangle, float); -DECLARE_SOA_COLUMN(DCAXY, dcaXY, float); -DECLARE_SOA_COLUMN(DCAZ, dcaZ, float); DECLARE_SOA_COLUMN(Sign, sign, int); //! DECLARE_SOA_DYNAMIC_COLUMN(Energy, e, [](float pt, float eta, float m) { return RecoDecay::sqrtSumOfSquares(pt * std::cosh(eta), m); }); // e = sqrt(p*p + m*m) } // namespace dalitzmumu DECLARE_SOA_TABLE(DalitzMuMus, "AOD", "DALITZMUMU", //! o2::soa::Index<>, dalitzmumu::CollisionId, dalitzmumu::PosTrackId, dalitzmumu::NegTrackId, - dalitzmumu::Pt, dalitzmumu::Eta, dalitzmumu::Phi, dalitzmumu::Mass, dalitzmumu::PhiV, dalitzmumu::OpeningAngle, dalitzmumu::DCAXY, dalitzmumu::DCAZ, dalitzmumu::Sign, + dalitzmumu::Pt, dalitzmumu::Eta, dalitzmumu::Phi, dalitzmumu::Mass, dalitzmumu::Rapidity, + dalitzmumu::PhiV, dalitzmumu::OpeningAngle, dalitzmumu::Sign, dalitzmumu::Energy); // iterators using DalitzMuMu = DalitzMuMus::iterator; diff --git a/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx b/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx index 5eecb2d8a2a..c328d150da4 100644 --- a/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx +++ b/PWGEM/PhotonMeson/TableProducer/photonconversionbuilder.cxx @@ -78,31 +78,39 @@ struct PhotonConversionBuilder { Configurable useMatCorrType{"useMatCorrType", 0, "0: none, 1: TGeo, 2: LUT"}; // single track cuts + Configurable min_ncluster_tpc{"min_ncluster_tpc", 10, "min ncluster tpc"}; Configurable mincrossedrows{"mincrossedrows", 10, "min crossed rows"}; - Configurable maxchi2tpc{"maxchi2tpc", 4.0, "max chi2/NclsTPC"}; - Configurable maxchi2its{"maxchi2its", 5.0, "max chi2/NclsITS"}; + Configurable maxchi2tpc{"maxchi2tpc", 5.0, "max chi2/NclsTPC"}; // default 4.0 + 1.0 + Configurable maxchi2its{"maxchi2its", 6.0, "max chi2/NclsITS"}; // default 5.0 + 1.0 Configurable maxpt_itsonly{"maxpt_itsonly", 0.15, "max pT for ITSonly tracks at SV"}; Configurable maxTPCNsigmaEl{"maxTPCNsigmaEl", 4.0, "max. TPC n sigma for electron"}; Configurable dcanegtopv{"dcanegtopv", 0.1, "DCA Neg To PV"}; Configurable dcapostopv{"dcapostopv", 0.1, "DCA Pos To PV"}; - Configurable min_pt_leg{"min_pt_leg", 0.05, "min pT for v0 legs at SV"}; + Configurable min_pt_leg{"min_pt_leg", 0.04, "min pT for v0 legs at SV"}; Configurable maxX{"maxX", 83.1, "max X for track IU"}; // v0 cuts - Configurable min_v0cospa{"min_v0cospa", 0.99, "V0 CosPA"}; // double -> N.B. dcos(x)/dx = 0 at x=0) - Configurable max_dcav0dau{"max_dcav0dau", 2.0, "max distance btween 2 legs"}; + Configurable min_v0cospa_tpconly{"min_v0cospa_tpconly", 0.99, "min V0 CosPA to V0s with TPConly tracks"}; // double -> N.B. dcos(x)/dx = 0 at x=0) + Configurable min_v0cospa_its{"min_v0cospa_its", 0.99, "min V0 CosPA to V0s with ITs hits"}; // double -> N.B. dcos(x)/dx = 0 at x=0) + Configurable max_dcav0dau_tpconly{"max_dcav0dau_tpconly", 3.0, "max distance btween 2 legs to V0s with TPConly tracks"}; + Configurable max_dcav0dau_its{"max_dcav0dau_its", 0.5, "max distance btween 2 legs to V0s with ITS hits"}; + Configurable max_dcav0dau_itsibss{"max_dcav0dau_itsibss", 1.0, "max distance btween 2 legs to V0s with ITS hits on ITSib SS"}; + Configurable max_dcav0dau_tpc_inner_fc{"max_dcav0dau_tpc_inner_fc", 1.5, "max distance btween 2 legs to V0s with ITS hits on TPC inner FC"}; Configurable min_v0radius{"min_v0radius", 1.0, "min v0 radius"}; Configurable margin_r_its{"margin_r_its", 3.0, "margin for r cut in cm"}; Configurable margin_r_tpconly{"margin_r_tpconly", 7.0, "margin for r cut in cm"}; Configurable margin_z{"margin_z", 7.0, "margin for z cut in cm"}; Configurable max_alpha_ap{"max_alpha_ap", 0.95, "max alpha for AP cut"}; - Configurable max_qt_ap{"max_qt_ap", 0.02, "max qT for AP cut"}; + Configurable max_qt_ap{"max_qt_ap", 0.01, "max qT for AP cut"}; Configurable min_pt_v0{"min_pt_v0", 0.05, "min pT for v0 photons at SV"}; Configurable max_pt_v0_itsonly{"max_pt_v0_itsonly", 0.3, "max pT for v0 photons wth 2 ITSonly tracks at SV"}; Configurable max_eta_v0{"max_eta_v0", 0.9, "max eta for v0 photons at SV"}; Configurable kfMassConstrain{"kfMassConstrain", -1.f, "mass constrain for the KFParticle mother particle"}; Configurable max_r_req_its{"max_r_req_its", 16.0, "max Rxy for V0 with ITS hits"}; - Configurable min_r_tpconly{"min_r_tpconly", 32.0, "min Rxy for V0 with TPConly tracks"}; + Configurable min_r_tpconly{"min_r_tpconly", 36.0, "min Rxy for V0 with TPConly tracks"}; + Configurable max_r_itsmft_ss{"max_r_itsmft_ss", 66.0, "max Rxy for ITS/MFT SS"}; + Configurable max_dcatopv_xy_v0{"max_dcatopv_xy_v0", +1e+10, "max. DCAxy to PV for V0"}; + Configurable max_dcatopv_z_v0{"max_dcatopv_z_v0", +1e+10, "max. DCAz to PV for V0"}; int mRunNumber; float d_bz; @@ -119,14 +127,14 @@ struct PhotonConversionBuilder { {"V0/hAP", "Armenteros Podolanski;#alpha;q_{T} (GeV/c)", {HistType::kTH2F, {{200, -1.0f, 1.0f}, {250, 0, 0.25}}}}, {"V0/hConversionPointXY", "conversion point in XY;X (cm);Y (cm)", {HistType::kTH2F, {{400, -100.0f, 100.0f}, {400, -100.f, 100.f}}}}, {"V0/hConversionPointRZ", "conversion point in RZ;Z (cm);R_{xy} (cm)", {HistType::kTH2F, {{200, -100.0f, 100.0f}, {200, 0.f, 100.f}}}}, - {"V0/hPt", "pT of V0 at PV;p_{T,#gamma} (GeV/c)", {HistType::kTH1F, {{1000, 0.0f, 10.0f}}}}, - {"V0/hEtaPhi", "#eta vs. #varphi of V0 at PV;#varphi (rad.);#eta", {HistType::kTH2F, {{72, 0.0f, TMath::TwoPi()}, {400, -2, +2}}}}, + {"V0/hPt", "pT of V0 at SV;p_{T,#gamma} (GeV/c)", {HistType::kTH1F, {{1000, 0.0f, 10.0f}}}}, + {"V0/hEtaPhi", "#eta vs. #varphi of V0 at SV;#varphi (rad.);#eta", {HistType::kTH2F, {{72, 0.0f, TMath::TwoPi()}, {400, -2, +2}}}}, {"V0/hCosPA", "cosine of pointing angle;cosine of pointing angle", {HistType::kTH1F, {{100, 0.9f, 1.f}}}}, + {"V0/hCosPA_Rxy", "cosine of pointing angle;r_{xy} (cm);cosine of pointing angle", {HistType::kTH2F, {{100, 0, 100}, {100, 0.9f, 1.f}}}}, {"V0/hPCA", "distance between 2 legs at SV;PCA (cm)", {HistType::kTH1F, {{500, 0.0f, 5.f}}}}, + {"V0/hPCA_Rxy", "distance between 2 legs at SV;R_{xy} (cm);PCA (cm)", {HistType::kTH2F, {{100, 0, 100}, {500, 0.0f, 5.f}}}}, {"V0/hDCAxyz", "DCA to PV;DCA_{xy} (cm);DCA_{z} (cm)", {HistType::kTH2F, {{200, -5.f, +5.f}, {200, -5.f, +5.f}}}}, - // {"V0/hMee_SVPV", "mee at PV and SV;m_{ee} at PV (GeV/c^{2});m_{ee} at SV (GeV/c^{2})", {HistType::kTH2F, {{100, 0.0f, 0.1f}, {100, 0, 0.1f}}}}, {"V0/hMeeSV_Rxy", "mee at SV vs. R_{xy};R_{xy} (cm);m_{ee} at SV (GeV/c^{2})", {HistType::kTH2F, {{200, 0.0f, 100.f}, {100, 0, 0.1f}}}}, - // {"V0/hMeePV_Rxy", "mee at PV vs. R_{xy};R_{xy} (cm);m_{ee} at PV (GeV/c^{2})", {HistType::kTH2F, {{200, 0.0f, 100.f}, {100, 0, 0.1f}}}}, {"V0Leg/hPt", "pT of leg at SV;p_{T,e} (GeV/c)", {HistType::kTH1F, {{1000, 0.0f, 10.0f}}}}, {"V0Leg/hEtaPhi", "#eta vs. #varphi of leg at SV;#varphi (rad.);#eta", {HistType::kTH2F, {{72, 0.0f, TMath::TwoPi()}, {400, -2, +2}}}}, {"V0Leg/hDCAxyz", "DCA xy vs. z to PV;DCA_{xy} (cm);DCA_{z} (cm)", {HistType::kTH2F, {{200, -10.f, 10.f}, {200, -10.f, +10.f}}}}, @@ -230,7 +238,14 @@ struct PhotonConversionBuilder { return false; } + if (track.hasITS() && !track.hasTPC() && (track.hasTRD() || track.hasTOF())) { // remove unrealistic track. this should not happen. + return false; + } + if (track.hasTPC()) { + if (track.tpcNClsFound() < min_ncluster_tpc) { + return false; + } if (track.tpcNClsCrossedRows() < mincrossedrows || track.tpcChi2NCl() > maxchi2tpc) { return false; } @@ -244,9 +259,9 @@ struct PhotonConversionBuilder { return false; } - if (abs(track.z() / track.x() - track.tgl()) > 0.4) { - return false; - } + // if (abs(track.z() / track.x() - track.tgl()) > 0.4) { + // return false; + // } auto hits_ib = std::count_if(its_ib_Requirement.second.begin(), its_ib_Requirement.second.end(), [&](auto&& requiredLayer) { return track.itsClusterMap() & (1 << requiredLayer); }); bool its_ob_only = hits_ib <= its_ib_Requirement.first; @@ -255,41 +270,19 @@ struct PhotonConversionBuilder { } } - if (!track.hasITS() && track.x() < 0.1) { // TPConly tracks which cannot be propagated to X=83cm during asynch. reco.. - auto track_par_cov = getTrackParCov(track); - o2::base::Propagator::Instance()->propagateToX(track_par_cov, 83.f, d_bz, o2::base::PropagatorImpl::MAX_SIN_PHI, o2::base::PropagatorImpl::MAX_STEP, matCorr); - if (40.0 < track_par_cov.getX() && track_par_cov.getX() < 82.9) { // propagation failed. - return false; - } - } - return true; } template void fillTrackTable(TTrack const& track, TKFParticle const& kfp, float dcaXY, float dcaZ) { - float trackiu_x = 0.0, trackiu_y = 0.0, trackiu_z = 0.0; - if (!track.hasITS() && track.x() < 0.1) { // TPConly tracks which cannot be propagated to X=83cm during asynch. reco.. - auto track_par_cov = getTrackParCov(track); - o2::base::Propagator::Instance()->propagateToX(track_par_cov, 83.f, d_bz, o2::base::PropagatorImpl::MAX_SIN_PHI, o2::base::PropagatorImpl::MAX_STEP, matCorr); - trackiu_x = track_par_cov.getX(); - // trackiu_y = track_par_cov.getY(); - trackiu_y = track.y(); - trackiu_z = track_par_cov.getZ(); - } else { - trackiu_x = track.x(); - trackiu_y = track.y(); - trackiu_z = track.z(); - } - v0legs(track.collisionId(), track.globalIndex(), track.sign(), kfp.GetPx(), kfp.GetPy(), kfp.GetPz(), dcaXY, dcaZ, track.tpcNClsFindable(), track.tpcNClsFindableMinusFound(), track.tpcNClsFindableMinusCrossedRows(), track.tpcChi2NCl(), track.tpcInnerParam(), track.tpcSignal(), track.tpcNSigmaEl(), track.tpcNSigmaPi(), - track.itsClusterMap(), track.itsChi2NCl(), track.detectorMap(), - trackiu_x, trackiu_y, trackiu_z, track.tgl(), track.signed1Pt()); + track.itsClusterSizes(), track.itsChi2NCl(), track.detectorMap(), + track.x(), track.y(), track.z(), track.tgl(), track.signed1Pt()); } template @@ -308,10 +301,10 @@ struct PhotonConversionBuilder { return; } - if (isITSonlyTrack(pos) && isTPConlyTrack(ele)) { + if (isITSonlyTrack(pos) && !ele.hasITS()) { return; } - if (isITSonlyTrack(ele) && isTPConlyTrack(pos)) { + if (isITSonlyTrack(ele) && !pos.hasITS()) { return; } @@ -324,13 +317,11 @@ struct PhotonConversionBuilder { gpu::gpustd::array dcaInfo; auto pTrack = getTrackPar(pos); - // pTrack.setPID(o2::track::PID::Electron); o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, pTrack, 2.f, matCorr, &dcaInfo); auto posdcaXY = dcaInfo[0]; auto posdcaZ = dcaInfo[1]; auto nTrack = getTrackPar(ele); - // nTrack.setPID(o2::track::PID::Electron); o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, nTrack, 2.f, matCorr, &dcaInfo); auto eledcaXY = dcaInfo[0]; auto eledcaZ = dcaInfo[1]; @@ -342,10 +333,12 @@ struct PhotonConversionBuilder { float xyz[3] = {0.f, 0.f, 0.f}; Vtx_recalculation(o2::base::Propagator::Instance(), pos, ele, xyz, matCorr); float rxy_tmp = RecoDecay::sqrtSumOfSquares(xyz[0], xyz[1]); - if (rxy_tmp > maxX + margin_r_tpconly) { return; } + if (rxy_tmp < abs(xyz[2]) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-max_eta_v0))) - margin_z) { + return; // RZ line cut + } KFPTrack kfp_track_pos = createKFPTrackFromTrack(pos); KFPTrack kfp_track_ele = createKFPTrackFromTrack(ele); @@ -367,8 +360,14 @@ struct PhotonConversionBuilder { gammaKF_DecayVtx.TransportToPoint(xyz); float cospa_kf = cpaFromKF(gammaKF_DecayVtx, KFPV); - if (cospa_kf < min_v0cospa) { - return; + if (!ele.hasITS() && !pos.hasITS()) { + if (cospa_kf < min_v0cospa_tpconly) { + return; + } + } else { + if (cospa_kf < min_v0cospa_its) { + return; + } } float rxy = RecoDecay::sqrtSumOfSquares(gammaKF_DecayVtx.GetX(), gammaKF_DecayVtx.GetY()); @@ -394,6 +393,13 @@ struct PhotonConversionBuilder { } } + if (rxy > maxX + margin_r_tpconly) { + return; + } + if (rxy < abs(gammaKF_DecayVtx.GetZ()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-max_eta_v0))) - margin_z) { + return; // RZ line cut + } + if ((!pos.hasITS() || !ele.hasITS()) && rxy < max_r_req_its) { // conversion points smaller than max_r_req_its have to be detected with ITS hits. return; } @@ -402,13 +408,19 @@ struct PhotonConversionBuilder { return; } - if (rxy < abs(gammaKF_DecayVtx.GetZ()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-max_eta_v0))) - margin_z) { - return; // RZ line cut - } + // Apply a topological constraint of the gamma to the PV. Parameters will be given at the primary vertex. + KFParticle gammaKF_PV = gammaKF; + gammaKF_PV.SetProductionVertex(KFPV); + float v0pt = RecoDecay::sqrtSumOfSquares(gammaKF_PV.GetPx(), gammaKF_PV.GetPy()); + float v0eta = RecoDecay::eta(std::array{gammaKF_PV.GetPx(), gammaKF_PV.GetPy(), gammaKF_PV.GetPz()}); + float v0phi = RecoDecay::phi(gammaKF_PV.GetPx(), gammaKF_PV.GetPy()) > 0.f ? RecoDecay::phi(gammaKF_PV.GetPx(), gammaKF_PV.GetPy()) : RecoDecay::phi(gammaKF_PV.GetPx(), gammaKF_PV.GetPy()) + TMath::TwoPi(); - float v0pt = RecoDecay::sqrtSumOfSquares(gammaKF_DecayVtx.GetPx(), gammaKF_DecayVtx.GetPy()); - float v0eta = RecoDecay::eta(std::array{gammaKF_DecayVtx.GetPx(), gammaKF_DecayVtx.GetPy(), gammaKF_DecayVtx.GetPz()}); - float v0phi = RecoDecay::phi(gammaKF_DecayVtx.GetPx(), gammaKF_DecayVtx.GetPy()) > 0.f ? RecoDecay::phi(gammaKF_DecayVtx.GetPx(), gammaKF_DecayVtx.GetPy()) : RecoDecay::phi(gammaKF_DecayVtx.GetPx(), gammaKF_DecayVtx.GetPy()) + TMath::TwoPi(); + // KFParticle gammaKF_DecayVtx2 = gammaKF; + // gammaKF_DecayVtx2.SetProductionVertex(KFPV); + // gammaKF_DecayVtx2.TransportToPoint(xyz); + // LOGF(info, "gammaKF_PV.GetPx() = %f, gammaKF_DecayVtx.GetPx() = %f, gammaKF_DecayVtx2.GetPx() = %f", gammaKF_PV.GetPx(), gammaKF_DecayVtx.GetPx(), gammaKF_DecayVtx2.GetPx()); + // LOGF(info, "gammaKF_PV.GetPy() = %f, gammaKF_DecayVtx.GetPy() = %f, gammaKF_DecayVtx2.GetPy() = %f", gammaKF_PV.GetPy(), gammaKF_DecayVtx.GetPy(), gammaKF_DecayVtx2.GetPy()); + // LOGF(info, "gammaKF_PV.GetPz() = %f, gammaKF_DecayVtx.GetPz() = %f, gammaKF_DecayVtx2.GetPz() = %f", gammaKF_PV.GetPz(), gammaKF_DecayVtx.GetPz(), gammaKF_DecayVtx2.GetPz()); if (fabs(v0eta) > max_eta_v0 || v0pt < min_pt_v0) { return; @@ -423,14 +435,31 @@ struct PhotonConversionBuilder { kfp_pos_DecayVtx.TransportToPoint(xyz); // Don't set Primary Vertex kfp_ele_DecayVtx.TransportToPoint(xyz); // Don't set Primary Vertex - // KFParticle kfp_pos_PV = kfp_pos_DecayVtx; - // KFParticle kfp_ele_PV = kfp_ele_DecayVtx; - // kfp_pos_PV.SetProductionVertex(KFPV); - // kfp_ele_PV.SetProductionVertex(KFPV); - float pca_kf = kfp_pos_DecayVtx.GetDistanceFromParticle(kfp_ele_DecayVtx); - if (pca_kf > max_dcav0dau) { - return; + if (!ele.hasITS() && !pos.hasITS()) { + if (max_r_itsmft_ss < rxy && rxy < maxX + margin_r_tpconly) { + if (pca_kf > max_dcav0dau_tpc_inner_fc) { + return; + } + } else { + if (pca_kf > max_dcav0dau_tpconly) { + return; + } + } + } else { + if (rxy < max_r_req_its) { + if (pca_kf > max_dcav0dau_itsibss) { + return; + } + } else if (rxy < min_r_tpconly) { + if (pca_kf > max_dcav0dau_its) { + return; + } + } else { + if (pca_kf > max_dcav0dau_tpconly) { + return; + } + } } float pos_pt = RecoDecay::sqrtSumOfSquares(kfp_pos_DecayVtx.GetPx(), kfp_pos_DecayVtx.GetPy()); @@ -439,18 +468,24 @@ struct PhotonConversionBuilder { return; } - if (isITSonlyTrack(pos)) { - float legpt = RecoDecay::sqrtSumOfSquares(kfp_pos_DecayVtx.GetPx(), kfp_pos_DecayVtx.GetPy()); - if (legpt > maxpt_itsonly) { - return; - } + if (isITSonlyTrack(pos) && pos_pt > maxpt_itsonly) { + return; } - if (isITSonlyTrack(ele)) { - float legpt = RecoDecay::sqrtSumOfSquares(kfp_ele_DecayVtx.GetPx(), kfp_ele_DecayVtx.GetPy()); - if (legpt > maxpt_itsonly) { - return; - } + if (isITSonlyTrack(ele) && ele_pt > maxpt_itsonly) { + 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()); + float dca_x_v0_to_pv = (gammaKF_DecayVtx.GetX() - gammaKF_DecayVtx.GetPx() * cospa_kf * length / v0mom) - collision.posX(); + float dca_y_v0_to_pv = (gammaKF_DecayVtx.GetY() - gammaKF_DecayVtx.GetPy() * cospa_kf * length / v0mom) - collision.posY(); + float dca_z_v0_to_pv = (gammaKF_DecayVtx.GetZ() - gammaKF_DecayVtx.GetPz() * cospa_kf * length / v0mom) - collision.posZ(); + float sign_tmp = dca_x_v0_to_pv * dca_y_v0_to_pv > 0 ? +1.f : -1.f; + float dca_xy_v0_to_pv = RecoDecay::sqrtSumOfSquares(dca_x_v0_to_pv, dca_y_v0_to_pv) * sign_tmp; + if (abs(dca_xy_v0_to_pv) > max_dcatopv_xy_v0 || abs(dca_z_v0_to_pv) > max_dcatopv_z_v0) { + return; } float alpha = v0_alpha(kfp_pos_DecayVtx.GetPx(), kfp_pos_DecayVtx.GetPy(), kfp_pos_DecayVtx.GetPz(), kfp_ele_DecayVtx.GetPx(), kfp_ele_DecayVtx.GetPy(), kfp_ele_DecayVtx.GetPz()); @@ -468,16 +503,9 @@ struct PhotonConversionBuilder { registry.fill(HIST("V0/hPt"), v0pt); registry.fill(HIST("V0/hEtaPhi"), v0phi, v0eta); registry.fill(HIST("V0/hCosPA"), cospa_kf); + registry.fill(HIST("V0/hCosPA_Rxy"), rxy, cospa_kf); registry.fill(HIST("V0/hPCA"), pca_kf); - - // 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()); - float dca_x_v0_to_pv = (gammaKF_DecayVtx.GetX() - gammaKF_DecayVtx.GetPx() * cospa_kf * length / v0mom) - collision.posX(); - float dca_y_v0_to_pv = (gammaKF_DecayVtx.GetY() - gammaKF_DecayVtx.GetPy() * cospa_kf * length / v0mom) - collision.posY(); - float dca_z_v0_to_pv = (gammaKF_DecayVtx.GetZ() - gammaKF_DecayVtx.GetPz() * cospa_kf * length / v0mom) - collision.posZ(); - float sign_tmp = dca_x_v0_to_pv * dca_y_v0_to_pv > 0 ? +1.f : -1.f; - float dca_xy_v0_to_pv = RecoDecay::sqrtSumOfSquares(dca_x_v0_to_pv, dca_y_v0_to_pv) * sign_tmp; + registry.fill(HIST("V0/hPCA_Rxy"), rxy, pca_kf); registry.fill(HIST("V0/hDCAxyz"), dca_xy_v0_to_pv, dca_z_v0_to_pv); float chi2kf = gammaKF_DecayVtx.GetChi2() / gammaKF_DecayVtx.GetNDF(); @@ -496,20 +524,14 @@ struct PhotonConversionBuilder { registry.fill(HIST("V0Leg/hDCAxyz"), posdcaXY, posdcaZ); registry.fill(HIST("V0Leg/hDCAxyz"), eledcaXY, eledcaZ); - // ROOT::Math::PxPyPzMVector vpos_pv(kfp_pos_PV.GetPx(), kfp_pos_PV.GetPy(), kfp_pos_PV.GetPz(), o2::constants::physics::MassElectron); - // ROOT::Math::PxPyPzMVector vele_pv(kfp_ele_PV.GetPx(), kfp_ele_PV.GetPy(), kfp_ele_PV.GetPz(), o2::constants::physics::MassElectron); - // ROOT::Math::PxPyPzMVector v0_pv = vpos_pv + vele_pv; - ROOT::Math::PxPyPzMVector vpos_sv(kfp_pos_DecayVtx.GetPx(), kfp_pos_DecayVtx.GetPy(), kfp_pos_DecayVtx.GetPz(), o2::constants::physics::MassElectron); ROOT::Math::PxPyPzMVector vele_sv(kfp_ele_DecayVtx.GetPx(), kfp_ele_DecayVtx.GetPy(), kfp_ele_DecayVtx.GetPz(), o2::constants::physics::MassElectron); ROOT::Math::PxPyPzMVector v0_sv = vpos_sv + vele_sv; - // registry.fill(HIST("V0/hMee_SVPV"), v0_pv.M(), v0_sv.M()); registry.fill(HIST("V0/hMeeSV_Rxy"), rxy, v0_sv.M()); - // registry.fill(HIST("V0/hMeePV_Rxy"), rxy, v0_pv.M()); v0photonskf(collision.globalIndex(), v0legs.lastIndex() + 1, v0legs.lastIndex() + 2, gammaKF_DecayVtx.GetX(), gammaKF_DecayVtx.GetY(), gammaKF_DecayVtx.GetZ(), - gammaKF_DecayVtx.GetPx(), gammaKF_DecayVtx.GetPy(), gammaKF_DecayVtx.GetPz(), + gammaKF_PV.GetPx(), gammaKF_PV.GetPy(), gammaKF_PV.GetPz(), v0_sv.M(), dca_xy_v0_to_pv, dca_z_v0_to_pv, cospa_kf, pca_kf, alpha, qt, chi2kf); diff --git a/PWGEM/PhotonMeson/TableProducer/skimmerDalitzEE.cxx b/PWGEM/PhotonMeson/TableProducer/skimmerDalitzEE.cxx index 725fa86e9ac..2aaaa07e161 100644 --- a/PWGEM/PhotonMeson/TableProducer/skimmerDalitzEE.cxx +++ b/PWGEM/PhotonMeson/TableProducer/skimmerDalitzEE.cxx @@ -52,22 +52,84 @@ struct skimmerDalitzEE { // Configurables Configurable maxMee{"maxMee", 0.5, "max. mee to store ee pairs"}; Configurable storeLS{"storeLS", false, "flag to store LS pairs"}; + Configurable minpt{"minpt", 0.2, "min pt for track for loose track sample"}; + Configurable maxeta{"maxeta", 0.9, "eta acceptance for loose track sample"}; + Configurable minTPCNsigmaEl{"minTPCNsigmaEl", -2.0, "min. TPC n sigma for electron inclusion"}; + Configurable maxTPCNsigmaEl{"maxTPCNsigmaEl", 3.0, "max. TPC n sigma for electron inclusion"}; + Configurable min_ncluster_tpc{"min_ncluster_tpc", 10, "min ncluster tpc"}; + Configurable mincrossedrows{"mincrossedrows", 100, "min. crossed rows"}; + Configurable min_tpc_cr_findable_ratio{"min_tpc_cr_findable_ratio", 0.8, "min. TPC Ncr/Nf ratio"}; + Configurable minitsncls{"minitsncls", 5, "min. number of ITS clusters"}; + Configurable maxchi2tpc{"maxchi2tpc", 4.0, "max. chi2/NclsTPC"}; + Configurable maxchi2its{"maxchi2its", 5.0, "max. chi2/NclsITS"}; + 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", 1.f, "max DCA 3D in sigma"}; HistogramRegistry fRegistry{ "fRegistry", { {"hNpairs", "hNpairs;pair type;Number of Pairs", {HistType::kTH1F, {{3, -1.5f, +1.5f}}}}, + {"hNele", "hNele;centrality FT0C;Number of electrons", {HistType::kTH2F, {{110, 0, 110}, {101, -0.5f, +100.5f}}}}, + {"hNpos", "hNpos;centrality FT0C;Number of positrons", {HistType::kTH2F, {{110, 0, 110}, {101, -0.5f, +100.5f}}}}, }, }; + std::pair> itsRequirement = {1, {0, 1, 2}}; // any hits on 3 ITS ib layers. void init(InitContext const&) {} + template + bool checkTrack(TTrack const& track) + { + 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; + } + + float dca_3d = 999.f; + float det = track.cYY() * track.cZZ() - track.cZY() * track.cZY(); + if (det < 0) { + 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.); + } + if (dca_3d > dca_3d_sigma_max) { + return false; + } + + return true; + } + template int fillPairTable(TCollision const& collision, TTracks1 const& tracks1, TTracks2 const& tracks2) { int npair = 0; if constexpr (pairtype == EM_EEPairType::kULS) { // ULS for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { + if (!checkTrack(t1) || !checkTrack(t2)) { + continue; + } + 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); ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; @@ -76,18 +138,16 @@ struct skimmerDalitzEE { } float phiv = getPhivPair(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz(), t1.sign(), t2.sign(), collision.bz()); float opangle = getOpeningAngle(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz()); - float dcaxy1 = t1.dcaXY() / sqrt(t1.cYY()); - float dcaxy2 = t2.dcaXY() / sqrt(t2.cYY()); - float dcaeexy = sqrt((pow(dcaxy1, 2) + pow(dcaxy2, 2)) / 2.); - float dcaz1 = t1.dcaZ() / sqrt(t1.cZZ()); - float dcaz2 = t2.dcaZ() / sqrt(t2.cZZ()); - float dcaeez = sqrt((pow(dcaz1, 2) + pow(dcaz2, 2)) / 2.); + + if (!std::isfinite(phiv)) { + LOGF(info, "t1.px() = %f, t1.py() = %f, t1.pz() = %f, t2.px() = %f, t2.py() = %f, t2.pz() = %f", t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz()); + } if constexpr (isCEFP) { - dalitzees(collision.globalIndex(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, opangle, dcaeexy, dcaeez, static_cast(pairtype)); + dalitzees(collision.globalIndex(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), v12.Rapidity(), phiv, opangle, static_cast(pairtype)); dalitz_ee_eventid(collision.globalIndex()); } else { // for analysis - dalitzees(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, opangle, dcaeexy, dcaeez, static_cast(pairtype)); + dalitzees(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), v12.Rapidity(), phiv, opangle, static_cast(pairtype)); dalitz_ee_eventid(collision.globalIndex()); } @@ -96,6 +156,9 @@ struct skimmerDalitzEE { } // end of pairing loop } else { // LS for (auto& [t1, t2] : combinations(CombinationsStrictlyUpperIndexPolicy(tracks1, tracks2))) { + if (!checkTrack(t1) || !checkTrack(t2)) { + continue; + } 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); ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; @@ -104,18 +167,12 @@ struct skimmerDalitzEE { } float phiv = getPhivPair(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz(), t1.sign(), t2.sign(), collision.bz()); float opangle = getOpeningAngle(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz()); - float dcaxy1 = t1.dcaXY() / sqrt(t1.cYY()); - float dcaxy2 = t2.dcaXY() / sqrt(t2.cYY()); - float dcaeexy = sqrt((pow(dcaxy1, 2) + pow(dcaxy2, 2)) / 2.); - float dcaz1 = t1.dcaZ() / sqrt(t1.cZZ()); - float dcaz2 = t2.dcaZ() / sqrt(t2.cZZ()); - float dcaeez = sqrt((pow(dcaz1, 2) + pow(dcaz2, 2)) / 2.); if constexpr (isCEFP) { - dalitzees(collision.globalIndex(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, opangle, dcaeexy, dcaeez, static_cast(pairtype)); + dalitzees(collision.globalIndex(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), v12.M(), phiv, opangle, static_cast(pairtype)); dalitz_ee_eventid(collision.globalIndex()); } else { // for analysis - dalitzees(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, opangle, dcaeexy, dcaeez, static_cast(pairtype)); + dalitzees(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), v12.Rapidity(), phiv, opangle, static_cast(pairtype)); dalitz_ee_eventid(collision.globalIndex()); } @@ -126,13 +183,16 @@ struct skimmerDalitzEE { return npair; } - Partition posTracks = o2::aod::emprimaryelectron::sign > 0; - Partition negTracks = o2::aod::emprimaryelectron::sign < 0; + Partition posTracks = o2::aod::emprimaryelectron::sign > 0 && o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& minTPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl&& o2::aod::pidtpc::tpcNSigmaEl < maxTPCNsigmaEl; + Partition negTracks = o2::aod::emprimaryelectron::sign < 0 && o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& minTPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl&& o2::aod::pidtpc::tpcNSigmaEl < maxTPCNsigmaEl; void processAnalysis(MyCollisions const& collisions, MyTracks const& tracks) { for (auto& collision : collisions) { auto posTracks_per_coll = posTracks->sliceByCached(o2::aod::emprimaryelectron::emreducedeventId, collision.globalIndex(), cache); auto negTracks_per_coll = negTracks->sliceByCached(o2::aod::emprimaryelectron::emreducedeventId, collision.globalIndex(), cache); + fRegistry.fill(HIST("hNpos"), collision.centFT0C(), posTracks_per_coll.size()); + fRegistry.fill(HIST("hNele"), collision.centFT0C(), negTracks_per_coll.size()); + // LOGF(info, "collision.centFT0C() = %f, posTracks_per_coll.size() = %d, negTracks_per_coll.size() = %d", collision.centFT0C() , posTracks_per_coll.size(), negTracks_per_coll.size()); int npair_uls = 0, npair_lspp = 0, npair_lsmm = 0; npair_uls = fillPairTable(collision, posTracks_per_coll, negTracks_per_coll); // ULS @@ -145,8 +205,8 @@ struct skimmerDalitzEE { } PROCESS_SWITCH(skimmerDalitzEE, processAnalysis, "Process dalitz ee for analysis", true); - Partition posTracks_cefp = o2::aod::emprimaryelectron::sign > 0; - Partition negTracks_cefp = o2::aod::emprimaryelectron::sign < 0; + Partition posTracks_cefp = o2::aod::emprimaryelectron::sign > 0 && o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& minTPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl&& o2::aod::pidtpc::tpcNSigmaEl < maxTPCNsigmaEl; + Partition negTracks_cefp = o2::aod::emprimaryelectron::sign < 0 && o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& minTPCNsigmaEl < o2::aod::pidtpc::tpcNSigmaEl&& o2::aod::pidtpc::tpcNSigmaEl < maxTPCNsigmaEl; void processCEFP(soa::Join const& collisions, aod::EMPrimaryElectrons const& tracks) { for (auto& collision : collisions) { diff --git a/PWGEM/PhotonMeson/TableProducer/skimmerDalitzMuMu.cxx b/PWGEM/PhotonMeson/TableProducer/skimmerDalitzMuMu.cxx index 5f725831bf7..860ff89713f 100644 --- a/PWGEM/PhotonMeson/TableProducer/skimmerDalitzMuMu.cxx +++ b/PWGEM/PhotonMeson/TableProducer/skimmerDalitzMuMu.cxx @@ -48,6 +48,20 @@ struct skimmerDalitzMuMu { // Configurables Configurable maxMmumu{"maxMmumu", 1.1, "max. mmumu to store mumu pairs"}; Configurable storeLS{"storeLS", false, "flag to store LS pairs"}; + Configurable minpt{"minpt", 0.05, "min pt for track"}; + Configurable maxpt{"maxpt", 0.6, "max pt for track"}; + Configurable maxeta{"maxeta", 0.9, "eta acceptance"}; + 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", 5, "min. number of ITS clusters"}; + Configurable maxchi2tpc{"maxchi2tpc", 4.0, "max. chi2/NclsTPC"}; + Configurable maxchi2its{"maxchi2its", 5.0, "max. chi2/NclsITS"}; + 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", 1.0f, "max DCA 3D in sigma"}; + Configurable minTPCNsigmaMu{"minTPCNsigmaMu", -3.0, "min. TPC n sigma for muon inclusion"}; + Configurable maxTPCNsigmaMu{"maxTPCNsigmaMu", 3.0, "max. TPC n sigma for muon inclusion"}; HistogramRegistry fRegistry{ "fRegistry", @@ -58,50 +72,90 @@ struct skimmerDalitzMuMu { void init(InitContext const&) {} + std::pair> itsRequirement = {1, {0, 1, 2}}; // any hits on 3 ITS ib layers. + + template + bool checkTrack(TTrack const& track) + { + 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; + } + + // float rel_diff = (track.tpcInnerParam() - track.p())/track.p(); + // if (rel_diff < -0.0156432+-0.00154524/pow(track.p(),2.29244) - 0.02 || -0.0156432+-0.00154524/pow(track.p(),2.29244) + 0.02 < rel_diff) { + // return false; + // } + + float dca_3d = 999.f; + float det = track.cYY() * track.cZZ() - track.cZY() * track.cZY(); + if (det < 0) { + 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.); + } + if (dca_3d > dca_3d_sigma_max) { + return false; + } + + return true; + } + template int fillPairTable(TCollision const& collision, TTracks1 const& tracks1, TTracks2 const& tracks2) { int npair = 0; + const float phiv = 0.f; + const float opangle = 0.f; if constexpr (pairtype == EM_MuMuPairType::kULS) { // ULS for (auto& [t1, t2] : combinations(CombinationsFullIndexPolicy(tracks1, tracks2))) { + if (!checkTrack(t1) || !checkTrack(t2)) { + continue; + } ROOT::Math::PtEtaPhiMVector v1(t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassMuon); ROOT::Math::PtEtaPhiMVector v2(t2.pt(), t2.eta(), t2.phi(), o2::constants::physics::MassMuon); ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; if (v12.M() > maxMmumu) { // don't store continue; } - float phiv = 0.f; - float opangle = 0.f; - float dcaxy1 = t1.dcaXY() / sqrt(t1.cYY()); - float dcaxy2 = t2.dcaXY() / sqrt(t2.cYY()); - float dcamumuxy = sqrt((pow(dcaxy1, 2) + pow(dcaxy2, 2)) / 2.); - float dcaz1 = t1.dcaZ() / sqrt(t1.cZZ()); - float dcaz2 = t2.dcaZ() / sqrt(t2.cZZ()); - float dcamumuz = sqrt((pow(dcaz1, 2) + pow(dcaz2, 2)) / 2.); - - dalitzmumus(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, opangle, dcamumuxy, dcamumuz, static_cast(pairtype)); + dalitzmumus(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), v12.Rapidity(), phiv, opangle, static_cast(pairtype)); dalitz_mumu_eventid(collision.globalIndex()); fRegistry.fill(HIST("hNpairs"), static_cast(pairtype)); npair++; } // end of pairing loop } else { // LS for (auto& [t1, t2] : combinations(CombinationsStrictlyUpperIndexPolicy(tracks1, tracks2))) { + if (!checkTrack(t1) || !checkTrack(t2)) { + continue; + } ROOT::Math::PtEtaPhiMVector v1(t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassMuon); ROOT::Math::PtEtaPhiMVector v2(t2.pt(), t2.eta(), t2.phi(), o2::constants::physics::MassMuon); ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; if (v12.M() > maxMmumu) { // don't store continue; } - float phiv = 0.f; - float opangle = 0.f; - float dcaxy1 = t1.dcaXY() / sqrt(t1.cYY()); - float dcaxy2 = t2.dcaXY() / sqrt(t2.cYY()); - float dcamumuxy = sqrt((pow(dcaxy1, 2) + pow(dcaxy2, 2)) / 2.); - float dcaz1 = t1.dcaZ() / sqrt(t1.cZZ()); - float dcaz2 = t2.dcaZ() / sqrt(t2.cZZ()); - float dcamumuz = sqrt((pow(dcaz1, 2) + pow(dcaz2, 2)) / 2.); - - dalitzmumus(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), phiv, opangle, dcamumuxy, dcamumuz, static_cast(pairtype)); + dalitzmumus(collision.collisionId(), t1.globalIndex(), t2.globalIndex(), v12.Pt(), v12.Eta(), v12.Phi() > 0 ? v12.Phi() : v12.Phi() + TMath::TwoPi(), v12.M(), v12.Rapidity(), phiv, opangle, static_cast(pairtype)); dalitz_mumu_eventid(collision.globalIndex()); fRegistry.fill(HIST("hNpairs"), static_cast(pairtype)); npair++; @@ -110,9 +164,8 @@ struct skimmerDalitzMuMu { return npair; } - Partition posTracks = o2::aod::emprimarymuon::sign > 0; - Partition negTracks = o2::aod::emprimarymuon::sign < 0; - + Partition posTracks = minpt < o2::aod::track::pt && o2::aod::track::pt < maxpt && nabs(o2::aod::track::eta) < maxeta && o2::aod::emprimarymuon::sign > 0 && minTPCNsigmaMu < o2::aod::pidtpc::tpcNSigmaMu&& o2::aod::pidtpc::tpcNSigmaMu < maxTPCNsigmaMu; + Partition negTracks = minpt < o2::aod::track::pt && o2::aod::track::pt < maxpt && nabs(o2::aod::track::eta) < maxeta && o2::aod::emprimarymuon::sign < 0 && minTPCNsigmaMu < o2::aod::pidtpc::tpcNSigmaMu && o2::aod::pidtpc::tpcNSigmaMu < maxTPCNsigmaMu; void process(MyCollisions const& collisions, MyTracks const& tracks) { for (auto& collision : collisions) { diff --git a/PWGEM/PhotonMeson/TableProducer/skimmerGammaConversion.cxx b/PWGEM/PhotonMeson/TableProducer/skimmerGammaConversion.cxx index 1ad9a8be8bb..bce0662dc69 100644 --- a/PWGEM/PhotonMeson/TableProducer/skimmerGammaConversion.cxx +++ b/PWGEM/PhotonMeson/TableProducer/skimmerGammaConversion.cxx @@ -189,7 +189,7 @@ struct skimmerGammaConversion { theTrack.tpcNClsFindable(), theTrack.tpcNClsFindableMinusFound(), theTrack.tpcNClsFindableMinusCrossedRows(), theTrack.tpcChi2NCl(), theTrack.tpcInnerParam(), theTrack.tpcSignal(), theTrack.tpcNSigmaEl(), theTrack.tpcNSigmaPi(), - theTrack.itsClusterMap(), theTrack.itsChi2NCl(), theTrack.detectorMap(), + theTrack.itsClusterSizes(), theTrack.itsChi2NCl(), theTrack.detectorMap(), theTrack.x(), theTrack.y(), theTrack.z(), theTrack.tgl(), theTrack.signed1Pt()); } diff --git a/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryElectron.cxx b/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryElectron.cxx index 5d47c7c7476..7cdb41a2a80 100644 --- a/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryElectron.cxx +++ b/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryElectron.cxx @@ -26,12 +26,14 @@ #include "CommonConstants/PhysicsConstants.h" #include "PWGEM/PhotonMeson/DataModel/gammaTables.h" #include "PWGEM/PhotonMeson/Utils/PCMUtilities.h" +#include "PWGEM/PhotonMeson/Utils/TrackSelection.h" using namespace o2; using namespace o2::soa; using namespace o2::framework; using namespace o2::framework::expressions; using namespace o2::constants::physics; +using namespace o2::pwgem::photonmeson; using MyTracks = soa::Join 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"}; @@ -68,13 +71,18 @@ struct skimmerPrimaryElectron { 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", 1.0f, "max DCA 3D in sigma"}; - Configurable minTPCNsigmaEl{"minTPCNsigmaEl", -4.0, "min. TPC n sigma for electron inclusion"}; + Configurable dca_3d_sigma_max{"dca_3d_sigma_max", 100.f, "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 maxTOFNsigmaEl{"maxTOFNsigmaEl", 4.0, "max. TOF n sigma for electron inclusion"}; + Configurable minTPCNsigmaPi{"minTPCNsigmaPi", -2.0, "min. TPC n sigma for pion exclusion"}; // set to -2 for lowB, -999 for nominalB Configurable maxTPCNsigmaPi{"maxTPCNsigmaPi", 2.0, "max. TPC n sigma for pion exclusion"}; + Configurable maxTPCNsigmaKa{"maxTPCNsigmaKa", 2.0, "max. TPC n sigma for kaon exclusion"}; + Configurable maxTPCNsigmaPr{"maxTPCNsigmaPr", 2.0, "max. TPC n sigma for proton exclusion"}; Configurable maxMee{"maxMee", 0.5, "max. mee to store ee pairs"}; Configurable storeLS{"storeLS", false, "flag to store LS pairs"}; + Configurable applyKaRej_TPC{"applyKaRej_TPC", false, "flag to apply Kaon rejection in TPC at the skimming level"}; // used for CEFP only + Configurable applyPrRej_TPC{"applyPrRej_TPC", false, "flag to apply Kaon rejection in TPC at the skimming level"}; // used for CEFP only HistogramRegistry fRegistry{ "fRegistry", @@ -178,6 +186,10 @@ struct skimmerPrimaryElectron { return false; } + if (track.tpcNClsFound() < min_ncluster_tpc) { + return false; + } + if (track.tpcNClsCrossedRows() < mincrossedrows) { return false; } @@ -204,20 +216,42 @@ struct skimmerPrimaryElectron { template bool isElectron(TTrack const& track) { - return isElectron_TPChadrej(track) || isElectron_TOFrecovery(track); + return isElectron_TPChadrej(track) || isElectron_TOFrecovery(track) || isElectron_TOFrecovery_lowB(track); } template bool isElectron_TPChadrej(TTrack const& track) { - return abs(track.tpcNSigmaEl()) < maxTPCNsigmaEl && abs(track.tpcNSigmaPi()) > maxTPCNsigmaPi; + if (track.tpcNSigmaEl() < minTPCNsigmaEl || maxTPCNsigmaEl < track.tpcNSigmaEl()) { + return false; + } + if (minTPCNsigmaPi < track.tpcNSigmaPi() && track.tpcNSigmaPi() < maxTPCNsigmaPi) { + return false; + } + if (applyKaRej_TPC && abs(track.tpcNSigmaKa()) < maxTPCNsigmaKa) { + return false; + } + if (applyPrRej_TPC && abs(track.tpcNSigmaPr()) < maxTPCNsigmaPr) { + return false; + } + + return true; } template bool isElectron_TOFrecovery(TTrack const& track) { - // TOF info is available for pin > 0.12 GeV/c at B=0.2T and pin > 0.34 GeV/c at B=0.5T - return abs(track.tpcNSigmaEl()) < maxTPCNsigmaEl && abs(track.tofNSigmaEl()) < maxTOFNsigmaEl && track.tpcInnerParam() < 0.4; // TOF recovery only at low pin. + if (minTPCNsigmaPi < track.tpcNSigmaPi() && track.tpcNSigmaPi() < maxTPCNsigmaPi) { + return false; + } + return minTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < maxTPCNsigmaEl && abs(track.tofNSigmaEl()) < maxTOFNsigmaEl; + } + + template + bool isElectron_TOFrecovery_lowB(TTrack const& track) + { + // TOF info is available for pin > 0.12 GeV/c at B=0.2T and pin > 0.34 GeV/c at B=0.5T. This is for electron recovery in pion rejection band. + return minTPCNsigmaEl < track.tpcNSigmaEl() && track.tpcNSigmaEl() < maxTPCNsigmaEl && abs(track.tofNSigmaEl()) < maxTOFNsigmaEl && track.tpcInnerParam() < 0.4; // TOF recovery only at low pin. } template @@ -249,7 +283,7 @@ struct skimmerPrimaryElectron { 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.itsClusterMap(), track.itsChi2NCl(), track.detectorMap(), track.signed1Pt(), track.cYY(), track.cZZ(), track.cZY()); + track.itsClusterSizes(), track.itsChi2NCl(), track.detectorMap(), track.tgl(), track.signed1Pt(), track.cYY(), track.cZZ(), track.cZY()); fRegistry.fill(HIST("Track/hTPCdEdx_Pin_after"), track.tpcInnerParam(), track.tpcSignal()); fRegistry.fill(HIST("Track/hTOFbeta_Pin_after"), track.tpcInnerParam(), track.beta()); fRegistry.fill(HIST("Track/hTPCNsigmaEl_after"), track.tpcInnerParam(), track.tpcNSigmaEl()); @@ -395,13 +429,15 @@ struct prefilterPrimaryElectron { // Operation and minimisation criteria Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; + Configurable max_pt_itsonly{"max_pt_itsonly", 0.15, "max pT for ITSonly tracks at PV"}; Configurable min_dcatopv{"min_dcatopv", -1.f, "DCAxyTo PV"}; Configurable minpt{"minpt", 0.05, "min pt for track for loose track sample"}; Configurable maxeta{"maxeta", 1.2, "eta acceptance for loose track sample"}; Configurable mincrossedrows{"mincrossedrows", 40, "min crossed rows"}; Configurable maxchi2tpc{"maxchi2tpc", 5.0, "max chi2/NclsTPC"}; Configurable maxchi2its{"maxchi2its", 6.0, "max chi2/NclsITS"}; - Configurable maxTPCNsigmaEl{"maxTPCNsigmaEl", 4.0, "max. TPC n sigma for electron"}; + Configurable minTPCNsigmaEl{"minTPCNsigmaEl", -4.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"}; @@ -478,8 +514,12 @@ struct prefilterPrimaryElectron { return false; } + if (isITSonlyTrack(track) && track.pt() > max_pt_itsonly) { + return false; + } + if (track.hasTPC()) { - if (abs(track.tpcNSigmaEl()) > maxTPCNsigmaEl) { + if (track.tpcNSigmaEl() < minTPCNsigmaEl || maxTPCNsigmaEl < track.tpcNSigmaEl()) { return false; } if (track.tpcNClsCrossedRows() < mincrossedrows) { diff --git a/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx b/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx index 06f55d6d422..6c200db8953 100644 --- a/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx +++ b/PWGEM/PhotonMeson/TableProducer/skimmerPrimaryMuon.cxx @@ -44,6 +44,7 @@ struct skimmerPrimaryMuon { Produces muon_pfb; // Configurables + 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"}; @@ -54,7 +55,7 @@ struct skimmerPrimaryMuon { 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", 1.0f, "max DCA 3D in sigma"}; + Configurable dca_3d_sigma_max{"dca_3d_sigma_max", 2.0f, "max DCA 3D in sigma"}; Configurable minTPCNsigmaMu{"minTPCNsigmaMu", -4.0, "min. TPC n sigma for muon inclusion"}; Configurable maxTPCNsigmaMu{"maxTPCNsigmaMu", 4.0, "max. TPC n sigma for muon inclusion"}; Configurable maxPin{"maxPin", 1.0, "max pin for PID"}; @@ -92,6 +93,8 @@ struct skimmerPrimaryMuon { // for MC primary muon {"MC/Primary/hPt_Gen", "generated pT;p_{T,#mu}^{gen} (GeV/c)", {HistType::kTH1F, {{100, 0.f, 1.f}}}}, {"MC/Primary/hPt_Rec", "reconstructed pT;p_{T,#mu}^{rec} (GeV/c)", {HistType::kTH1F, {{100, 0.f, 1.f}}}}, + {"MC/Primary/hP_Correlation", "p vs. pin correlation;p_{pv} (GeV/c);(p_{in} - p_{pv})/p_{pv}", {HistType::kTH2F, {{100, 0.f, 1.f}, {200, -1, +1}}}}, + {"MC/Primary/hP_Correlation_Profile", "p vs. pin correlation;p_{pv} (GeV/c);(p_{in} - p_{pv})/p_{pv}", {HistType::kTProfile, {{100, 0.f, 1.f}}}}, {"MC/Primary/hTPCdEdx_Pin", "TPC dE/dx vs. p_{in};p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{1000, 0.f, 1.f}, {200, 0.f, 200.f}}}}, {"MC/Primary/hTOFbeta_Pin", "TOF beta vs. p_{in};p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{1000, 0.f, 1.f}, {250, 0.6f, 1.1f}}}}, {"MC/Primary/hNclsITS", "Ncls ITS;N_{cls}^{ITS}", {HistType::kTH1F, {{8, -0.5f, +7.5f}}}}, @@ -112,6 +115,8 @@ struct skimmerPrimaryMuon { // for MC seconday muon {"MC/Secondary/hPt_Gen", "generated pT;p_{T,#mu}^{gen} (GeV/c)", {HistType::kTH1F, {{100, 0.f, 1.f}}}}, {"MC/Secondary/hPt_Rec", "reconstructed pT;p_{T,#mu}^{rec} (GeV/c)", {HistType::kTH1F, {{100, 0.f, 1.f}}}}, + {"MC/Secondary/hP_Correlation", "p vs. pin correlation;p_{pv} (GeV/c);(p_{in} - p_{pv})/p_{pv}", {HistType::kTH2F, {{100, 0.f, 1.f}, {200, -1, +1}}}}, + {"MC/Secondary/hP_Correlation_Profile", "p vs. pin correlation;p_{pv} (GeV/c);(p_{in} - p_{pv})/p_{pv}", {HistType::kTProfile, {{100, 0.f, 1.f}}}}, {"MC/Secondary/hTPCdEdx_Pin", "TPC dE/dx vs. p_{in};p_{in} (GeV/c);TPC dE/dx", {HistType::kTH2F, {{1000, 0.f, 1.f}, {200, 0.f, 200.f}}}}, {"MC/Secondary/hTOFbeta_Pin", "TOF beta vs. p_{in};p_{in} (GeV/c);TOF #beta", {HistType::kTH2F, {{1000, 0.f, 1.f}, {250, 0.6f, 1.1f}}}}, {"MC/Secondary/hNclsITS", "Ncls ITS;N_{cls}^{ITS}", {HistType::kTH1F, {{8, -0.5f, +7.5f}}}}, @@ -158,6 +163,10 @@ struct skimmerPrimaryMuon { return false; } + if (track.tpcNClsFound() < min_ncluster_tpc) { + return false; + } + if (track.tpcNClsCrossedRows() < mincrossedrows) { return false; } @@ -166,6 +175,11 @@ struct skimmerPrimaryMuon { return false; } + // float rel_diff = (track.tpcInnerParam() - track.p())/track.p(); + // if (rel_diff < -0.0156432+-0.00154524/pow(track.p(),2.29244) - 0.02 || -0.0156432+-0.00154524/pow(track.p(),2.29244) + 0.02 < rel_diff) { + // return false; + // } + float dca_3d = 999.f; float det = track.cYY() * track.cZZ() - track.cZY() * track.cZY(); if (det < 0) { @@ -220,6 +234,15 @@ struct skimmerPrimaryMuon { fRegistry.fill(HIST("Track/hTPCNsigmaEl_before"), track.tpcInnerParam(), track.tpcNSigmaEl()); fRegistry.fill(HIST("Track/hTOFNsigmaEl_before"), track.tpcInnerParam(), track.tofNSigmaEl()); + float dca_3d = 999.f; + float det = track.cYY() * track.cZZ() - track.cZY() * track.cZY(); + if (det < 0) { + 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.); + } + if constexpr (isMC) { auto mctrack = track.template mcParticle_as(); if (abs(mctrack.pdgCode()) == 13 /* && mctrack.has_mothers()*/) { @@ -228,6 +251,8 @@ struct skimmerPrimaryMuon { if (isMuon(track)) { fRegistry.fill(HIST("MC/Primary/hPt_Rec"), track.pt()); } + fRegistry.fill(HIST("MC/Primary/hP_Correlation"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + fRegistry.fill(HIST("MC/Primary/hP_Correlation_Profile"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); fRegistry.fill(HIST("MC/Primary/hTPCdEdx_Pin"), track.tpcInnerParam(), track.tpcSignal()); fRegistry.fill(HIST("MC/Primary/hTOFbeta_Pin"), track.tpcInnerParam(), track.beta()); fRegistry.fill(HIST("MC/Primary/hNclsITS"), track.itsNCls()); @@ -243,12 +268,14 @@ struct skimmerPrimaryMuon { fRegistry.fill(HIST("MC/Primary/hDCAxy_resolution"), sqrt(track.cYY())); fRegistry.fill(HIST("MC/Primary/hDCAz_resolution"), sqrt(track.cZZ())); fRegistry.fill(HIST("MC/Primary/hDCAxyz_sigma"), track.dcaXY() / sqrt(track.cYY()), track.dcaZ() / sqrt(track.cZZ())); - fRegistry.fill(HIST("MC/Primary/hDCA3D_sigma"), sqrt(pow(track.dcaXY() / sqrt(track.cYY()), 2) + pow(track.dcaZ() / sqrt(track.cZZ()), 2))); + fRegistry.fill(HIST("MC/Primary/hDCA3D_sigma"), dca_3d); fRegistry.fill(HIST("MC/Primary/hProdVtx"), mctrack.vx(), mctrack.vy()); } else { if (isMuon(track)) { fRegistry.fill(HIST("MC/Secondary/hPt_Rec"), track.pt()); } + fRegistry.fill(HIST("MC/Secondary/hP_Correlation"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); + fRegistry.fill(HIST("MC/Secondary/hP_Correlation_Profile"), track.p(), (track.tpcInnerParam() - track.p()) / track.p()); fRegistry.fill(HIST("MC/Secondary/hTPCdEdx_Pin"), track.tpcInnerParam(), track.tpcSignal()); fRegistry.fill(HIST("MC/Secondary/hTOFbeta_Pin"), track.tpcInnerParam(), track.beta()); fRegistry.fill(HIST("MC/Secondary/hNclsITS"), track.itsNCls()); @@ -264,7 +291,7 @@ struct skimmerPrimaryMuon { fRegistry.fill(HIST("MC/Secondary/hDCAxy_resolution"), sqrt(track.cYY())); fRegistry.fill(HIST("MC/Secondary/hDCAz_resolution"), sqrt(track.cZZ())); fRegistry.fill(HIST("MC/Secondary/hDCAxyz_sigma"), track.dcaXY() / sqrt(track.cYY()), track.dcaZ() / sqrt(track.cZZ())); - fRegistry.fill(HIST("MC/Secondary/hDCA3D_sigma"), sqrt(pow(track.dcaXY() / sqrt(track.cYY()), 2) + pow(track.dcaZ() / sqrt(track.cZZ()), 2))); + fRegistry.fill(HIST("MC/Secondary/hDCA3D_sigma"), dca_3d); fRegistry.fill(HIST("MC/Secondary/hProdVtx"), mctrack.vx(), mctrack.vy()); } } @@ -283,7 +310,7 @@ struct skimmerPrimaryMuon { 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.itsClusterMap(), track.itsChi2NCl(), track.detectorMap(), track.signed1Pt(), track.cYY(), track.cZZ(), track.cZY()); + track.itsClusterSizes(), track.itsChi2NCl(), track.detectorMap(), track.tgl(), track.signed1Pt(), track.cYY(), track.cZZ(), track.cZY()); fRegistry.fill(HIST("Track/hTPCdEdx_Pin_after"), track.tpcInnerParam(), track.tpcSignal()); fRegistry.fill(HIST("Track/hTOFbeta_Pin_after"), track.tpcInnerParam(), track.beta()); fRegistry.fill(HIST("Track/hTPCNsigmaMu_after"), track.tpcInnerParam(), track.tpcNSigmaMu()); diff --git a/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx b/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx index 8fe9c101211..01e49b0b362 100644 --- a/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx +++ b/PWGEM/PhotonMeson/Tasks/MaterialBudget.cxx @@ -109,7 +109,7 @@ struct MaterialBudget { } // end of cut1 loop } - static constexpr std::string_view pairnames[8] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitzEE", "PCMDalitzMuMu", "PHOSEMC"}; + static constexpr std::string_view pairnames[9] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitzEE", "PCMDalitzMuMu", "PHOSEMC", "DalitzEEDalitzEE"}; void addhistograms() { fMainList->SetOwner(true); diff --git a/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx b/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx index 2551a4de068..cf8424bf93f 100644 --- a/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/MaterialBudgetMC.cxx @@ -60,6 +60,8 @@ struct MaterialBudgetMC { Configurable CentEstimator{"CentEstimator", "FT0M", "centrality estimator"}; Configurable maxY{"maxY", 0.9, "maximum rapidity for generated particles"}; + 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 fConfigTagCuts{"cfgTagCuts", "qc", "Comma separated list of V0 photon cuts for tag"}; Configurable fConfigProbeCuts{"cfgProbeCuts", "qc,wwire_ib", "Comma separated list of V0 photon cuts for probe"}; Configurable fConfigPairCuts{"cfgPairCuts", "nocut", "Comma separated list of pair cuts"}; @@ -119,7 +121,7 @@ struct MaterialBudgetMC { } // end of tagcut loop } - static constexpr std::string_view pairnames[8] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitzEE", "PCMDalitzMuMu", "PHOSEMC"}; + static constexpr std::string_view pairnames[9] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitzEE", "PCMDalitzMuMu", "PHOSEMC", "DalitzEEDalitzEE"}; void addhistograms() { fMainList->SetOwner(true); @@ -159,8 +161,7 @@ struct MaterialBudgetMC { o2::aod::emphotonhistograms::AddHistClass(fMainList, "Generated"); THashList* list_gen = reinterpret_cast(fMainList->FindObject("Generated")); - o2::aod::emphotonhistograms::DefineHistograms(list_gen, "Generated", "Photon"); - o2::aod::emphotonhistograms::DefineHistograms(list_gen, "Generated", "ConversionStudy"); + o2::aod::emphotonhistograms::DefineHistograms(list_gen, "Generated", ""); } void DefineTagCuts() @@ -394,31 +395,7 @@ struct MaterialBudgetMC { } reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hCollisionCounter"))->Fill(4.0); reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hZvtx_after"))->Fill(mccollision.posZ()); - - auto mctracks_coll = mcparticles.sliceBy(perMcCollision, mccollision.globalIndex()); - for (auto& mctrack : mctracks_coll) { - if (abs(mctrack.y()) > maxY) { - continue; - } - if (abs(mctrack.pdgCode()) == 22 && IsPhysicalPrimary(mctrack.emreducedmcevent(), mctrack, mcparticles)) { - reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hPt_Photon"))->Fill(mctrack.pt()); - reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hY_Photon"))->Fill(mctrack.y()); - reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hPhi_Photon"))->Fill(mctrack.phi()); - } - - int photonid = IsEleFromPC(mctrack, mcparticles); - if (photonid > 0) { - auto mcphoton = mcparticles.iteratorAt(photonid); - if (!IsPhysicalPrimary(mcphoton.emreducedmcevent(), mcphoton, mcparticles)) { - continue; - } - float rxy = sqrt(pow(mctrack.vx(), 2) + pow(mctrack.vy(), 2)); - reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hPhotonRZ"))->Fill(mctrack.vz(), rxy); - reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hPhotonRxy"))->Fill(mctrack.vx(), mctrack.vy()); - reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hPhotonPhivsRxy"))->Fill(mctrack.phi(), rxy); - } - } - } + } // end of collision loop } void processDummy(MyCollisions::iterator const& collision) {} diff --git a/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx b/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx index 59a776ad5b1..0b9d9454415 100644 --- a/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx +++ b/PWGEM/PhotonMeson/Tasks/PhotonHBT.cxx @@ -51,7 +51,7 @@ using namespace o2::framework::expressions; using namespace o2::soa; using namespace o2::aod::photonpair; -using MyCollisions = soa::Join; +using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; using MyV0Photons = soa::Join; @@ -69,6 +69,8 @@ struct PhotonHBT { Configurable fConfigDalitzEECuts{"cfgDalitzEECuts", "mee_all_tpchadrejortofreq_prompt", "Comma separated list of DalitzEE cuts"}; Configurable fConfigPHOSCuts{"cfgPHOSCuts", "test02,test03", "Comma separated list of PHOS photon cuts"}; Configurable fConfigPairCuts{"cfgPairCuts", "nocut", "Comma separated list of pair cuts"}; + Configurable fConfigDo3D{"cfgDo3D", false, "Flag to analyze 3D BE correlation"}; // it is very heavy. + Configurable maxY_dielectron{"maxY_dielectron", 0.9, "maximum rapidity for dielectron"}; OutputObj fOutputEvent{"Event"}; OutputObj fOutputPair{"Pair"}; // 2-photon pair @@ -88,6 +90,9 @@ struct PhotonHBT { if (context.mOptions.get("processPCMDalitzEE")) { fPairNames.push_back("PCMDalitzEE"); } + if (context.mOptions.get("processDalitzEEDalitzEE")) { + fPairNames.push_back("DalitzEEDalitzEE"); + } if (context.mOptions.get("processPHOSPHOS")) { fPairNames.push_back("PHOSPHOS"); } @@ -113,8 +118,9 @@ struct PhotonHBT { std::string cutname1 = cut1.GetName(); std::string cutname2 = cut2.GetName(); - if ((pairname == "PCMPCM" || pairname == "PHOSPHOS" || pairname == "EMCEMC") && (cutname1 != cutname2)) + if ((pairname == "PCMPCM" || pairname == "PHOSPHOS" || pairname == "EMCEMC" || pairname == "DalitzEEDalitzEE") && (cutname1 != cutname2)) { continue; + } THashList* list_pair_subsys = reinterpret_cast(list_pair->FindObject(pairname.data())); std::string photon_cut_name = cutname1 + "_" + cutname2; @@ -125,13 +131,17 @@ struct PhotonHBT { std::string pair_cut_name = cut3.GetName(); o2::aod::emphotonhistograms::AddHistClass(list_pair_subsys_photoncut, pair_cut_name.data()); THashList* list_pair_subsys_paircut = reinterpret_cast(list_pair_subsys_photoncut->FindObject(pair_cut_name.data())); - o2::aod::emphotonhistograms::DefineHistograms(list_pair_subsys_paircut, "photon_hbt"); + if (fConfigDo3D) { + o2::aod::emphotonhistograms::DefineHistograms(list_pair_subsys_paircut, "photon_hbt", "3d"); + } else { + o2::aod::emphotonhistograms::DefineHistograms(list_pair_subsys_paircut, "photon_hbt", "1d"); + } } // end of pair cut3 loop } // end of cut2 loop } // end of cut1 loop } - static constexpr std::string_view pairnames[8] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitzEE", "PCMDalitzMuMu", "PHOSEMC"}; + static constexpr std::string_view pairnames[9] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitzEE", "PCMDalitzMuMu", "PHOSEMC", "DalitzEEDalitzEE"}; void addhistograms() { fMainList->SetOwner(true); @@ -159,6 +169,9 @@ struct PhotonHBT { if (pairname == "PCMDalitzEE") { add_pair_histograms(list_pair, pairname, fPCMCuts, fDalitzEECuts, fPairCuts); } + if (pairname == "DalitzEEDalitzEE") { + add_pair_histograms(list_pair, pairname, fDalitzEECuts, fDalitzEECuts, fPairCuts); + } if (pairname == "PHOSPHOS") { add_pair_histograms(list_pair, pairname, fPHOSCuts, fPHOSCuts, fPairCuts); } @@ -233,6 +246,8 @@ struct PhotonHBT { is_selected_pair = o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); } else if constexpr (pairtype == PairType::kPCMDalitzEE) { is_selected_pair = o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); + } else if constexpr (pairtype == PairType::kDalitzEEDalitzEE) { + is_selected_pair = o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); } else if constexpr (pairtype == PairType::kPHOSPHOS) { is_selected_pair = o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); // dummy, because track matching is not ready. } else if constexpr (pairtype == PairType::kPCMPHOS) { @@ -276,9 +291,11 @@ struct PhotonHBT { auto photons1_coll = photons1.sliceBy(perCollision1, collision.globalIndex()); auto photons2_coll = photons2.sliceBy(perCollision2, collision.globalIndex()); + // LOGF(info, "photons1_coll.size() = %d, photons2_coll.size() = %d", photons1_coll.size(), photons2_coll.size()); - double values[9] = {0.f}; - if constexpr (pairtype == PairType::kPCMPCM || pairtype == PairType::kPHOSPHOS || pairtype == PairType::kEMCEMC) { + double values_1d[4] = {0.f}; + double values_3d[8] = {0.f}; + if constexpr (pairtype == PairType::kPCMPCM || pairtype == PairType::kPHOSPHOS || pairtype == PairType::kEMCEMC || pairtype == PairType::kDalitzEEDalitzEE) { for (auto& cut : cuts1) { for (auto& paircut : paircuts) { for (auto& [g1, g2] : combinations(CombinationsStrictlyUpperIndexPolicy(photons1_coll, photons2_coll))) { @@ -286,54 +303,72 @@ struct PhotonHBT { continue; } - values[0] = 0.0; - values[1] = 0.0; + values_1d[0] = 0.0, values_1d[1] = 0.0; + values_3d[0] = 0.0, values_3d[1] = 0.0; // center-of-mass system (CMS) ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); - if constexpr (pairtype == PairType::kPCMDalitzEE) { + if constexpr (pairtype == PairType::kDalitzEEDalitzEE) { + auto pos1 = g1.template posTrack_as(); + auto ele1 = g1.template negTrack_as(); + auto pos2 = g2.template posTrack_as(); + auto ele2 = g2.template negTrack_as(); + if (pos1.trackId() == pos2.trackId() || ele1.trackId() == ele2.trackId()) { + continue; + } + v1.SetM(g1.mass()); v2.SetM(g2.mass()); - values[1] = g2.mass(); + values_1d[0] = g1.mass(); + values_1d[1] = g2.mass(); + values_3d[0] = g1.mass(); + values_3d[1] = g2.mass(); } + ROOT::Math::PtEtaPhiMVector q12 = v1 - v2; ROOT::Math::PtEtaPhiMVector k12 = 0.5 * (v1 + v2); float qinv = -q12.M(); float kt = k12.Pt(); - float qt = q12.Pt(); - float qlong_cms = q12.Pz(); - - ROOT::Math::XYZVector q_3d = q12.Vect(); // 3D q vector - ROOT::Math::XYZVector uv_out(k12.Px() / k12.Pt(), k12.Py() / k12.Pt(), 0); // unit vector for out. i.e. parallel to kt - ROOT::Math::XYZVector uv_long(0, 0, 1); // unit vector for long, beam axis - ROOT::Math::XYZVector uv_side = uv_out.Cross(uv_long); // unit vector for side - float qout_cms = q_3d.Dot(uv_out); - float qside_cms = q_3d.Dot(uv_side); - - // longitudinally co-moving system (LCMS) - ROOT::Math::PxPyPzEVector v1_cartesian(v1.Px(), v1.Py(), v1.Pz(), v1.E()); - ROOT::Math::PxPyPzEVector v2_cartesian(v2.Px(), v2.Py(), v2.Pz(), v2.E()); - ROOT::Math::PxPyPzEVector q12_cartesian = v1_cartesian - v2_cartesian; - float beta_z = (v1 + v2).Pz() / (v1 + v2).E(); - ROOT::Math::Boost bst_z(0, 0, -beta_z); // Boost supports only PxPyPzEVector - ROOT::Math::PxPyPzEVector q12_lcms = bst_z(q12_cartesian); - float qlong_lcms = q12_lcms.Pz(); - - // ROOT::Math::PxPyPzEVector v1_lcms_cartesian = bst_z(v1_cartesian); - // ROOT::Math::PxPyPzEVector v2_lcms_cartesian = bst_z(v2_cartesian); - // ROOT::Math::PxPyPzEVector q12_lcms_cartesian = bst_z(q12_cartesian); - // LOGF(info, "q12.Pz() = %f, q12_cartesian.Pz() = %f",q12.Pz(), q12_cartesian.Pz()); - // LOGF(info, "v1.Pz() = %f, v2.Pz() = %f",v1.Pz(), v2.Pz()); - // LOGF(info, "v1_lcms_cartesian.Pz() = %f, v2_lcms_cartesian.Pz() = %f",v1_lcms_cartesian.Pz(), v2_lcms_cartesian.Pz()); - // LOGF(info, "q12_lcms_cartesian.Pz() = %f", q12_lcms_cartesian.Pz()); - - values[2] = kt; - values[3] = qinv; - values[4] = qlong_cms; - values[5] = qout_cms; - values[6] = qside_cms; - values[7] = qt; - values[8] = qlong_lcms; - reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut.GetName(), cut.GetName()))->FindObject(paircut.GetName())->FindObject("hs_q_same"))->Fill(values); + + values_1d[2] = kt; + values_1d[3] = qinv; + + if (fConfigDo3D) { + // float qt = q12.Pt(); + float qlong_cms = q12.Pz(); + + ROOT::Math::XYZVector q_3d = q12.Vect(); // 3D q vector + ROOT::Math::XYZVector uv_out(k12.Px() / k12.Pt(), k12.Py() / k12.Pt(), 0); // unit vector for out. i.e. parallel to kt + ROOT::Math::XYZVector uv_long(0, 0, 1); // unit vector for long, beam axis + ROOT::Math::XYZVector uv_side = uv_out.Cross(uv_long); // unit vector for side + float qout_cms = q_3d.Dot(uv_out); + float qside_cms = q_3d.Dot(uv_side); + + // longitudinally co-moving system (LCMS) + ROOT::Math::PxPyPzEVector v1_cartesian(v1.Px(), v1.Py(), v1.Pz(), v1.E()); + ROOT::Math::PxPyPzEVector v2_cartesian(v2.Px(), v2.Py(), v2.Pz(), v2.E()); + ROOT::Math::PxPyPzEVector q12_cartesian = v1_cartesian - v2_cartesian; + float beta_z = (v1 + v2).Pz() / (v1 + v2).E(); + ROOT::Math::Boost bst_z(0, 0, -beta_z); // Boost supports only PxPyPzEVector + ROOT::Math::PxPyPzEVector q12_lcms = bst_z(q12_cartesian); + float qlong_lcms = q12_lcms.Pz(); + + // ROOT::Math::PxPyPzEVector v1_lcms_cartesian = bst_z(v1_cartesian); + // ROOT::Math::PxPyPzEVector v2_lcms_cartesian = bst_z(v2_cartesian); + // ROOT::Math::PxPyPzEVector q12_lcms_cartesian = bst_z(q12_cartesian); + // LOGF(info, "q12.Pz() = %f, q12_cartesian.Pz() = %f",q12.Pz(), q12_cartesian.Pz()); + // LOGF(info, "v1.Pz() = %f, v2.Pz() = %f",v1.Pz(), v2.Pz()); + // LOGF(info, "v1_lcms_cartesian.Pz() = %f, v2_lcms_cartesian.Pz() = %f",v1_lcms_cartesian.Pz(), v2_lcms_cartesian.Pz()); + // LOGF(info, "q12_lcms_cartesian.Pz() = %f", q12_lcms_cartesian.Pz()); + values_3d[2] = kt; + values_3d[3] = qinv; + values_3d[4] = qlong_cms; + values_3d[5] = qout_cms; + values_3d[6] = qside_cms; + values_3d[7] = qlong_lcms; + reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut.GetName(), cut.GetName()))->FindObject(paircut.GetName())->FindObject("hs_q_same"))->Fill(values_3d); + } else { + reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut.GetName(), cut.GetName()))->FindObject(paircut.GetName())->FindObject("hs_q_same"))->Fill(values_1d); + } } // end of combination } // end of pair cut loop } // end of cut loop @@ -356,46 +391,53 @@ struct PhotonHBT { } } - values[0] = 0.0; - values[1] = 0.0; + values_1d[0] = 0.0, values_1d[1] = 0.0; + values_3d[0] = 0.0, values_3d[1] = 0.0; // center-of-mass system (CMS) ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); if constexpr (pairtype == PairType::kPCMDalitzEE) { v2.SetM(g2.mass()); - values[1] = g2.mass(); + values_1d[1] = g2.mass(); + values_3d[1] = g2.mass(); } ROOT::Math::PtEtaPhiMVector q12 = v1 - v2; ROOT::Math::PtEtaPhiMVector k12 = 0.5 * (v1 + v2); float qinv = -q12.M(); float kt = k12.Pt(); - float qt = q12.Pt(); - float qlong_cms = q12.Pz(); - ROOT::Math::XYZVector q_3d = q12.Vect(); // 3D q vector - ROOT::Math::XYZVector uv_out(k12.Px() / k12.Pt(), k12.Py() / k12.Pt(), 0); // unit vector for out. i.e. parallel to kt - ROOT::Math::XYZVector uv_long(0, 0, 1); // unit vector for long, beam axis - ROOT::Math::XYZVector uv_side = uv_out.Cross(uv_long); // unit vector for side - float qout_cms = q_3d.Dot(uv_out); - float qside_cms = q_3d.Dot(uv_side); - - // longitudinally co-moving system (LCMS) - ROOT::Math::PxPyPzEVector v1_cartesian(v1.Px(), v1.Py(), v1.Pz(), v1.E()); - ROOT::Math::PxPyPzEVector v2_cartesian(v2.Px(), v2.Py(), v2.Pz(), v2.E()); - ROOT::Math::PxPyPzEVector q12_cartesian = v1_cartesian - v2_cartesian; - float beta_z = (v1 + v2).Pz() / (v1 + v2).E(); - ROOT::Math::Boost bst_z(0, 0, -beta_z); // Boost supports only PxPyPzEVector - ROOT::Math::PxPyPzEVector q12_lcms = bst_z(q12_cartesian); - float qlong_lcms = q12_lcms.Pz(); - - values[2] = kt; - values[3] = qinv; - values[4] = qlong_cms; - values[5] = qout_cms; - values[6] = qside_cms; - values[7] = qt; - values[8] = qlong_lcms; - reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut1.GetName(), cut2.GetName()))->FindObject(paircut.GetName())->FindObject("hs_q_same"))->Fill(values); + values_1d[2] = kt; + values_1d[3] = qinv; + + if (fConfigDo3D) { + // float qt = q12.Pt(); + float qlong_cms = q12.Pz(); + + ROOT::Math::XYZVector q_3d = q12.Vect(); // 3D q vector + ROOT::Math::XYZVector uv_out(k12.Px() / k12.Pt(), k12.Py() / k12.Pt(), 0); // unit vector for out. i.e. parallel to kt + ROOT::Math::XYZVector uv_long(0, 0, 1); // unit vector for long, beam axis + ROOT::Math::XYZVector uv_side = uv_out.Cross(uv_long); // unit vector for side + float qout_cms = q_3d.Dot(uv_out); + float qside_cms = q_3d.Dot(uv_side); + + // longitudinally co-moving system (LCMS) + ROOT::Math::PxPyPzEVector v1_cartesian(v1.Px(), v1.Py(), v1.Pz(), v1.E()); + ROOT::Math::PxPyPzEVector v2_cartesian(v2.Px(), v2.Py(), v2.Pz(), v2.E()); + ROOT::Math::PxPyPzEVector q12_cartesian = v1_cartesian - v2_cartesian; + float beta_z = (v1 + v2).Pz() / (v1 + v2).E(); + ROOT::Math::Boost bst_z(0, 0, -beta_z); // Boost supports only PxPyPzEVector + ROOT::Math::PxPyPzEVector q12_lcms = bst_z(q12_cartesian); + float qlong_lcms = q12_lcms.Pz(); + values_3d[2] = kt; + values_3d[3] = qinv; + values_3d[4] = qlong_cms; + values_3d[5] = qout_cms; + values_3d[6] = qside_cms; + values_3d[7] = qlong_lcms; + reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut1.GetName(), cut2.GetName()))->FindObject(paircut.GetName())->FindObject("hs_q_same"))->Fill(values_3d); + } else { + reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut1.GetName(), cut2.GetName()))->FindObject(paircut.GetName())->FindObject("hs_q_same"))->Fill(values_1d); + } } // end of combination } // end of pair cut loop } // end of cut2 loop @@ -424,14 +466,15 @@ struct PhotonHBT { // LOGF(info, "collision1: posZ = %f, numContrib = %d , sel8 = %d | collision2: posZ = %f, numContrib = %d , sel8 = %d", // collision1.posZ(), collision1.numContrib(), collision1.sel8(), collision2.posZ(), collision2.numContrib(), collision2.sel8()); - double values[9] = {0.f}; + double values_1d[4] = {0.f}; + double values_3d[8] = {0.f}; for (auto& cut1 : cuts1) { for (auto& cut2 : cuts2) { for (auto& paircut : paircuts) { for (auto& [g1, g2] : combinations(soa::CombinationsFullIndexPolicy(photons_coll1, photons_coll2))) { // LOGF(info, "Mixed event photon pair: (%d, %d) from events (%d, %d), photon event: (%d, %d)", g1.index(), g2.index(), collision1.index(), collision2.index(), g1.globalIndex(), g2.globalIndex()); - if ((pairtype == PairType::kPCMPCM || pairtype == PairType::kPHOSPHOS || pairtype == PairType::kEMCEMC) && (TString(cut1.GetName()) != TString(cut2.GetName()))) { + if ((pairtype == PairType::kPCMPCM || pairtype == PairType::kPHOSPHOS || pairtype == PairType::kEMCEMC || pairtype == PairType::kDalitzEEDalitzEE) && (TString(cut1.GetName()) != TString(cut2.GetName()))) { continue; } if (!IsSelectedPair(g1, g2, cut1, cut2)) { @@ -442,45 +485,60 @@ struct PhotonHBT { } // center-of-mass system (CMS) - values[0] = 0.0; - values[1] = 0.0; + values_1d[0] = 0.0, values_1d[1] = 0.0; + values_3d[0] = 0.0, values_3d[1] = 0.0; ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), 0.); if constexpr (pairtype == PairType::kPCMDalitzEE) { v2.SetM(g2.mass()); - values[1] = g2.mass(); + values_1d[1] = g2.mass(); + values_3d[1] = g2.mass(); + } else if constexpr (pairtype == PairType::kDalitzEEDalitzEE) { + v1.SetM(g1.mass()); + v2.SetM(g2.mass()); + values_1d[0] = g1.mass(); + values_1d[1] = g2.mass(); + values_3d[0] = g1.mass(); + values_3d[1] = g2.mass(); } ROOT::Math::PtEtaPhiMVector q12 = v1 - v2; ROOT::Math::PtEtaPhiMVector k12 = 0.5 * (v1 + v2); float qinv = -q12.M(); float kt = k12.Pt(); - float qt = q12.Pt(); - float qlong_cms = q12.Pz(); - - ROOT::Math::XYZVector q_3d = q12.Vect(); // 3D q vector - ROOT::Math::XYZVector uv_out(k12.Px() / k12.Pt(), k12.Py() / k12.Pt(), 0); // unit vector for out. i.e. parallel to kt - ROOT::Math::XYZVector uv_long(0, 0, 1); // unit vector for long, beam axis - ROOT::Math::XYZVector uv_side = uv_out.Cross(uv_long); // unit vector for side - float qout_cms = q_3d.Dot(uv_out); - float qside_cms = q_3d.Dot(uv_side); - - // longitudinally co-moving system (LCMS) - ROOT::Math::PxPyPzEVector v1_cartesian(v1.Px(), v1.Py(), v1.Pz(), v1.E()); - ROOT::Math::PxPyPzEVector v2_cartesian(v2.Px(), v2.Py(), v2.Pz(), v2.E()); - ROOT::Math::PxPyPzEVector q12_cartesian = v1_cartesian - v2_cartesian; - float beta_z = (v1 + v2).Pz() / (v1 + v2).E(); - ROOT::Math::Boost bst_z(0, 0, -beta_z); // Boost supports only PxPyPzEVector - ROOT::Math::PxPyPzEVector q12_lcms = bst_z(q12_cartesian); - float qlong_lcms = q12_lcms.Pz(); - - values[2] = kt; - values[3] = qinv; - values[4] = qlong_cms; - values[5] = qout_cms; - values[6] = qside_cms; - values[7] = qt; - values[8] = qlong_lcms; - reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut1.GetName(), cut2.GetName()))->FindObject(paircut.GetName())->FindObject("hs_q_mix"))->Fill(values); + values_1d[2] = kt; + values_1d[3] = qinv; + + if (fConfigDo3D) { + // float qt = q12.Pt(); + float qlong_cms = q12.Pz(); + + ROOT::Math::XYZVector q_3d = q12.Vect(); // 3D q vector + ROOT::Math::XYZVector uv_out(k12.Px() / k12.Pt(), k12.Py() / k12.Pt(), 0); // unit vector for out. i.e. parallel to kt + ROOT::Math::XYZVector uv_long(0, 0, 1); // unit vector for long, beam axis + ROOT::Math::XYZVector uv_side = uv_out.Cross(uv_long); // unit vector for side + float qout_cms = q_3d.Dot(uv_out); + float qside_cms = q_3d.Dot(uv_side); + + // longitudinally co-moving system (LCMS) + ROOT::Math::PxPyPzEVector v1_cartesian(v1.Px(), v1.Py(), v1.Pz(), v1.E()); + ROOT::Math::PxPyPzEVector v2_cartesian(v2.Px(), v2.Py(), v2.Pz(), v2.E()); + ROOT::Math::PxPyPzEVector q12_cartesian = v1_cartesian - v2_cartesian; + float beta_z = (v1 + v2).Pz() / (v1 + v2).E(); + ROOT::Math::Boost bst_z(0, 0, -beta_z); // Boost supports only PxPyPzEVector + ROOT::Math::PxPyPzEVector q12_lcms = bst_z(q12_cartesian); + float qlong_lcms = q12_lcms.Pz(); + + values_3d[2] = kt; + values_3d[3] = qinv; + values_3d[4] = qlong_cms; + values_3d[5] = qout_cms; + values_3d[6] = qside_cms; + values_3d[7] = qlong_lcms; + reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut1.GetName(), cut2.GetName()))->FindObject(paircut.GetName())->FindObject("hs_q_mix"))->Fill(values_3d); + } else { + reinterpret_cast(list_pair_ss->FindObject(Form("%s_%s", cut1.GetName(), cut2.GetName()))->FindObject(paircut.GetName())->FindObject("hs_q_mix"))->Fill(values_1d); + } + } // end of different photon combinations } // end of pair cut loop } // end of cut2 loop @@ -492,8 +550,11 @@ struct PhotonHBT { Preslice perCollision_dalitzee = aod::dalitzee::emreducedeventId; Preslice perCollision_phos = aod::skimmedcluster::collisionId; + Filter eeFilter = o2::aod::dalitzee::sign == 0 && nabs(o2::aod::dalitzee::rapidity) < maxY_dielectron; // analyze only uls + using filteredMyDalitzEEs = soa::Filtered; + Filter collisionFilter_common = nabs(o2::aod::collision::posZ) < 10.f && o2::aod::collision::numContrib > (uint16_t)0 && o2::aod::evsel::sel8 == true; - Filter collisionFilter_subsys = (o2::aod::emreducedevent::ngpcm >= 1) || (o2::aod::emreducedevent::neeuls >= 1); + Filter collisionFilter_subsys = (o2::aod::emreducedevent::ngpcm >= 1); using MyFilteredCollisions = soa::Filtered; void processPCMPCM(MyCollisions const& collisions, MyFilteredCollisions const& filtered_collisions, MyV0Photons const& v0photons, aod::V0Legs const& legs) @@ -502,12 +563,18 @@ struct PhotonHBT { MixedEventPairing(filtered_collisions, v0photons, v0photons, perCollision_pcm, perCollision_pcm, fPCMCuts, fPCMCuts, fPairCuts, legs, nullptr); } - void processPCMDalitzEE(MyCollisions const& collisions, MyFilteredCollisions const& filtered_collisions, MyV0Photons const& v0photons, aod::V0Legs const& legs, MyDalitzEEs const& dielectrons, MyPrimaryElectrons const& emprimaryelectrons) + void processPCMDalitzEE(MyCollisions const& collisions, MyFilteredCollisions const& filtered_collisions, MyV0Photons const& v0photons, aod::V0Legs const& legs, filteredMyDalitzEEs const& dielectrons, MyPrimaryElectrons const& emprimaryelectrons) { SameEventPairing(collisions, v0photons, dielectrons, perCollision_pcm, perCollision_dalitzee, fPCMCuts, fDalitzEECuts, fPairCuts, legs, emprimaryelectrons); MixedEventPairing(filtered_collisions, v0photons, dielectrons, perCollision_pcm, perCollision_dalitzee, fPCMCuts, fDalitzEECuts, fPairCuts, legs, emprimaryelectrons); } + void processDalitzEEDalitzEE(MyCollisions const& collisions, MyFilteredCollisions const& filtered_collisions, filteredMyDalitzEEs const& dielectrons, MyPrimaryElectrons const& emprimaryelectrons) + { + SameEventPairing(collisions, dielectrons, dielectrons, perCollision_dalitzee, perCollision_dalitzee, fDalitzEECuts, fDalitzEECuts, fPairCuts, nullptr, emprimaryelectrons); + MixedEventPairing(filtered_collisions, dielectrons, dielectrons, perCollision_dalitzee, perCollision_dalitzee, fDalitzEECuts, fDalitzEECuts, fPairCuts, nullptr, emprimaryelectrons); + } + void processPHOSPHOS(MyCollisions const& collisions, MyFilteredCollisions const& filtered_collisions, aod::PHOSClusters const& phosclusters) { SameEventPairing(collisions, phosclusters, phosclusters, perCollision_phos, perCollision_phos, fPHOSCuts, fPHOSCuts, fPairCuts, nullptr, nullptr); @@ -524,6 +591,7 @@ struct PhotonHBT { PROCESS_SWITCH(PhotonHBT, processPCMPCM, "pairing PCM-PCM", false); PROCESS_SWITCH(PhotonHBT, processPCMDalitzEE, "pairing PCM-DalitzEE", false); + PROCESS_SWITCH(PhotonHBT, processDalitzEEDalitzEE, "pairing DalitzEE-DalitzEE", false); PROCESS_SWITCH(PhotonHBT, processPHOSPHOS, "pairing PHOS-PHOS", false); PROCESS_SWITCH(PhotonHBT, processPCMPHOS, "pairing PCM-PHOS", false); PROCESS_SWITCH(PhotonHBT, processDummy, "Dummy function", true); diff --git a/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGamma.cxx b/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGamma.cxx index bf6a17708bf..969e6f49bee 100644 --- a/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGamma.cxx +++ b/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGamma.cxx @@ -49,7 +49,7 @@ using namespace o2::aod::photonpair; using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; -using MyV0Photons = soa::Join; +using MyV0Photons = soa::Join; using MyV0Photon = MyV0Photons::iterator; using MyDalitzEEs = soa::Join; @@ -71,9 +71,9 @@ struct Pi0EtaToGammaGamma { Configurable CentEstimator{"CentEstimator", "FT0M", "centrality estimator"}; Configurable maxY{"maxY", 0.9, "maximum rapidity for reconstructed particles"}; - Configurable fConfigPCMCuts{"cfgPCMCuts", "analysis,qc,nocut", "Comma separated list of V0 photon cuts"}; + Configurable fConfigPCMCuts{"cfgPCMCuts", "qc,nocut", "Comma separated list of V0 photon cuts"}; Configurable fConfigDalitzEECuts{"cfgDalitzEECuts", "mee_0_120_tpchadrejortofreq_lowB,mee_120_500_tpchadrejortofreq_lowB,mee_0_500_tpchadrejortofreq_lowB", "Comma separated list of Dalitz ee cuts"}; - Configurable fConfigDalitzMuMuCuts{"cfgDalitzMuMuCuts", "mee_0_500_lowB", "Comma separated list of Dalitz mumu cuts"}; + Configurable fConfigDalitzMuMuCuts{"cfgDalitzMuMuCuts", "mmumu_0_500_lowB", "Comma separated list of Dalitz mumu cuts"}; Configurable fConfigPHOSCuts{"cfgPHOSCuts", "test02,test03", "Comma separated list of PHOS photon cuts"}; Configurable fConfigPairCuts{"cfgPairCuts", "nocut,asym08", "Comma separated list of pair cuts"}; @@ -169,7 +169,7 @@ struct Pi0EtaToGammaGamma { } // end of cut1 loop } - static constexpr std::string_view pairnames[8] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitzEE", "PCMDalitzMuMu", "PHOSEMC"}; + static constexpr std::string_view pairnames[9] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitzEE", "PCMDalitzMuMu", "PHOSEMC", "DalitzEEDalitzEE"}; void addhistograms() { fMainList->SetOwner(true); diff --git a/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGammaMC.cxx b/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGammaMC.cxx index d55de46cef7..bd51b070739 100644 --- a/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGammaMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/Pi0EtaToGammaGammaMC.cxx @@ -43,7 +43,7 @@ using namespace o2::aod::photonpair; using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; -using MyV0Photons = soa::Join; +using MyV0Photons = soa::Join; using MyV0Photon = MyV0Photons::iterator; using MyDalitzEEs = soa::Join; @@ -58,7 +58,7 @@ struct Pi0EtaToGammaGammaMC { using MyMCMuons = soa::Join; Configurable maxY{"maxY", 0.9, "maximum rapidity for generated particles"}; - Configurable fConfigPCMCuts{"cfgPCMCuts", "analysis,qc,nocut", "Comma separated list of V0 photon cuts"}; + Configurable fConfigPCMCuts{"cfgPCMCuts", "qc,nocut", "Comma separated list of V0 photon cuts"}; Configurable fConfigDalitzEECuts{"cfgDalitzEECuts", "mee_0_120_tpchadrejortofreq_lowB,mee_120_500_tpchadrejortofreq_lowB,mee_0_500_tpchadrejortofreq_lowB", "Comma separated list of Dalitz ee cuts"}; Configurable fConfigDalitzMuMuCuts{"cfgDalitzMuMuCuts", "mmumu_0_500_lowB", "Comma separated list of Dalitz mumu cuts"}; Configurable fConfigPairCuts{"cfgPairCuts", "nocut,asym08", "Comma separated list of pair cuts"}; @@ -140,7 +140,7 @@ struct Pi0EtaToGammaGammaMC { } // end of cut1 loop } - static constexpr std::string_view pairnames[8] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitzEE", "PCMDalitzMuMu", "PHOSEMC"}; + static constexpr std::string_view pairnames[9] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitzEE", "PCMDalitzMuMu", "PHOSEMC", "DalitzEEDalitzEE"}; static constexpr std::string_view parnames[3] = {"Gamma", "Pi0", "Eta"}; void addhistograms() { @@ -507,9 +507,12 @@ struct Pi0EtaToGammaGammaMC { void processPHOSEMC(MyCollisions const& collisions) {} + Filter collisionFilter = nabs(o2::aod::collision::posZ) < 10.f && o2::aod::collision::numContrib > (uint16_t)0 && o2::aod::evsel::sel8 == true; + using filteredMyCollisions = soa::Filtered; + PresliceUnsorted perMcCollision = aod::emmcparticle::emreducedmceventId; PresliceUnsorted rec_perMcCollision = aod::emmceventlabel::emreducedmceventId; - void processGen(MyCollisions const& collisions, aod::EMReducedMCEvents const& mccollisions, aod::EMMCParticles const& mcparticles) + void processGen(filteredMyCollisions const& collisions, aod::EMReducedMCEvents const& mccollisions, aod::EMMCParticles const& mcparticles) { // loop over mc stack and fill histograms for pure MC truth signals // all MC tracks which belong to the MC event corresponding to the current reconstructed event @@ -520,7 +523,6 @@ struct Pi0EtaToGammaGammaMC { } for (auto& collision : collisions) { - auto mccollision = collision.emreducedmcevent(); reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hZvtx_before"))->Fill(mccollision.posZ()); reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hCollisionCounter"))->Fill(1.0); // all @@ -551,8 +553,7 @@ struct Pi0EtaToGammaGammaMC { reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hPt_Pi0"))->Fill(mctrack.pt()); reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hY_Pi0"))->Fill(mctrack.y()); reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hPhi_Pi0"))->Fill(mctrack.phi()); - } - if (abs(pdg) == 221 && IsPhysicalPrimary(mctrack.emreducedmcevent(), mctrack, mcparticles)) { + } else if (abs(pdg) == 221 && IsPhysicalPrimary(mctrack.emreducedmcevent(), mctrack, mcparticles)) { reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hPt_Eta"))->Fill(mctrack.pt()); reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hY_Eta"))->Fill(mctrack.y()); reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hPhi_Eta"))->Fill(mctrack.phi()); diff --git a/PWGEM/PhotonMeson/Tasks/TaggingPi0.cxx b/PWGEM/PhotonMeson/Tasks/TaggingPi0.cxx index ad7ed63220d..7b099c0b6d7 100644 --- a/PWGEM/PhotonMeson/Tasks/TaggingPi0.cxx +++ b/PWGEM/PhotonMeson/Tasks/TaggingPi0.cxx @@ -41,10 +41,10 @@ using namespace o2::framework::expressions; using namespace o2::soa; using namespace o2::aod::photonpair; -using MyCollisions = soa::Join; +using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; -using MyV0Photons = soa::Join; +using MyV0Photons = soa::Join; using MyV0Photon = MyV0Photons::iterator; using MyDalitzEEs = soa::Join; @@ -58,7 +58,6 @@ struct TaggingPi0 { // Configurable maxY{"maxY", 0.9, "maximum rapidity for reconstructed particles"}; Configurable fConfigPCMCuts{"cfgPCMCuts", "analysis", "Comma separated list of V0 photon cuts"}; Configurable fConfigDalitzEECuts{"cfgDalitzEECuts", "mee_0_120_tpchadrejortofreq,mee_0_120_tpchadrejortofreq_lowB", "Comma separated list of Dalitz ee cuts"}; - Configurable fConfigPCMibwCuts{"cfgPCMibwCuts", "wwire_ib", "Comma separated list of V0 photon cuts"}; Configurable fConfigPHOSCuts{"cfgPHOSCuts", "test02,test03", "Comma separated list of PHOS photon cuts"}; Configurable fConfigEMCCuts{"cfgEMCCuts", "standard", "Comma separated list of EMCal photon cuts"}; Configurable fConfigPairCuts{"cfgPairCuts", "nocut", "Comma separated list of pair cuts"}; @@ -81,7 +80,6 @@ struct TaggingPi0 { std::vector fPCMCuts; std::vector fDalitzEECuts; - std::vector fPCMibwCuts; std::vector fPHOSCuts; std::vector fEMCCuts; std::vector fPairCuts; @@ -89,11 +87,8 @@ struct TaggingPi0 { std::vector fPairNames; void init(InitContext& context) { - if (context.mOptions.get("processPCMPCMibw")) { - fPairNames.push_back("PCMPCMibw"); - } - if (context.mOptions.get("processPCMDalitz")) { - fPairNames.push_back("PCMDalitz"); + if (context.mOptions.get("processPCMDalitzEE")) { + fPairNames.push_back("PCMDalitzEE"); } if (context.mOptions.get("processPCMPHOS")) { fPairNames.push_back("PCMPHOS"); @@ -104,7 +99,6 @@ struct TaggingPi0 { DefinePCMCuts(); DefineDalitzEECuts(); - DefinePCMibwCuts(); DefinePHOSCuts(); DefineEMCCuts(); DefinePairCuts(); @@ -140,7 +134,7 @@ struct TaggingPi0 { } // end of cut1 loop } - static constexpr std::string_view pairnames[8] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitz", "PHOSEMC", "PCMPCMibw"}; + static constexpr std::string_view pairnames[9] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitzEE", "PCMDalitzMuMu", "PHOSEMC", "DalitzEEDalitzEE"}; void addhistograms() { fMainList->SetOwner(true); @@ -162,16 +156,13 @@ struct TaggingPi0 { o2::aod::emphotonhistograms::AddHistClass(list_pair, pairname.data()); - if (pairname == "PCMPCMibw") { - add_pair_histograms(list_pair, pairname, fPCMCuts, fPCMibwCuts, fPairCuts); - } if (pairname == "PCMPHOS") { add_pair_histograms(list_pair, pairname, fPCMCuts, fPHOSCuts, fPairCuts); } if (pairname == "PCMEMC") { add_pair_histograms(list_pair, pairname, fPCMCuts, fEMCCuts, fPairCuts); } - if (pairname == "PCMDalitz") { + if (pairname == "PCMDalitzEE") { add_pair_histograms(list_pair, pairname, fPCMCuts, fDalitzEECuts, fPairCuts); } @@ -206,20 +197,6 @@ struct TaggingPi0 { LOGF(info, "Number of DalitzEE cuts = %d", fDalitzEECuts.size()); } - void DefinePCMibwCuts() - { - TString cutNamesStr = fConfigPCMibwCuts.value; - if (!cutNamesStr.IsNull()) { - std::unique_ptr objArray(cutNamesStr.Tokenize(",")); - for (int icut = 0; icut < objArray->GetEntries(); ++icut) { - const char* cutname = objArray->At(icut)->GetName(); - LOGF(info, "add cut : %s", cutname); - fPCMibwCuts.push_back(*pcmcuts::GetCut(cutname)); - } - } - LOGF(info, "Number of PCM cuts = %d", fPCMibwCuts.size()); - } - void DefinePHOSCuts() { TString cutNamesStr = fConfigPHOSCuts.value; @@ -294,9 +271,7 @@ struct TaggingPi0 { bool IsSelectedPair(TG1 const& g1, TG2 const& g2, TCut1 const& cut1, TCut2 const& cut2) { bool is_selected_pair = false; - if constexpr (pairtype == PairType::kPCMPCMibw) { - is_selected_pair = o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); - } else if constexpr (pairtype == PairType::kPCMPHOS) { + if constexpr (pairtype == PairType::kPCMPHOS) { is_selected_pair = o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); } else if constexpr (pairtype == PairType::kPCMEMC) { is_selected_pair = o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); @@ -462,12 +437,7 @@ struct TaggingPi0 { Preslice perCollision_phos = aod::skimmedcluster::collisionId; Preslice perCollision_emc = aod::skimmedcluster::collisionId; - void processPCMPCMibw(MyCollisions const& collisions, MyFilteredCollisions const& filtered_collisions, MyV0Photons const& v0photons, aod::V0Legs const& legs) - { - SameEventPairing(collisions, v0photons, v0photons, perCollision_pcm, perCollision_pcm, fPCMCuts, fPCMibwCuts, fPairCuts, legs, nullptr); - MixedEventPairing(filtered_collisions, v0photons, v0photons, perCollision_pcm, perCollision_pcm, fPCMCuts, fPCMibwCuts, fPairCuts, legs, nullptr); - } - void processPCMDalitz(MyCollisions const& collisions, MyFilteredCollisions const& filtered_collisions, MyV0Photons const& v0photons, aod::V0Legs const& legs, MyFilteredDalitzEEs const& dielectrons, MyPrimaryElectrons const& emprimaryelectrons) + void processPCMDalitzEE(MyCollisions const& collisions, MyFilteredCollisions const& filtered_collisions, MyV0Photons const& v0photons, aod::V0Legs const& legs, MyFilteredDalitzEEs const& dielectrons, MyPrimaryElectrons const& emprimaryelectrons) { SameEventPairing(collisions, v0photons, dielectrons, perCollision_pcm, perCollision_dalitz, fPCMCuts, fDalitzEECuts, fPairCuts, legs, emprimaryelectrons); MixedEventPairing(filtered_collisions, v0photons, dielectrons, perCollision_pcm, perCollision_dalitz, fPCMCuts, fDalitzEECuts, fPairCuts, legs, emprimaryelectrons); @@ -490,8 +460,7 @@ struct TaggingPi0 { // do nothing } - PROCESS_SWITCH(TaggingPi0, processPCMPCMibw, "pairing PCM-PCMibw", false); - PROCESS_SWITCH(TaggingPi0, processPCMDalitz, "pairing PCM-Dalitz", false); + PROCESS_SWITCH(TaggingPi0, processPCMDalitzEE, "pairing PCM-Dalitz", false); PROCESS_SWITCH(TaggingPi0, processPCMPHOS, "pairing PCM-PHOS", false); PROCESS_SWITCH(TaggingPi0, processPCMEMC, "pairing PCM-EMCal", false); PROCESS_SWITCH(TaggingPi0, processDummy, "Dummy function", true); diff --git a/PWGEM/PhotonMeson/Tasks/TaggingPi0MC.cxx b/PWGEM/PhotonMeson/Tasks/TaggingPi0MC.cxx index 9765bef03cd..1f30ea0edf2 100644 --- a/PWGEM/PhotonMeson/Tasks/TaggingPi0MC.cxx +++ b/PWGEM/PhotonMeson/Tasks/TaggingPi0MC.cxx @@ -47,7 +47,7 @@ using namespace o2::aod::photonpair; using MyCollisions = soa::Join; using MyCollision = MyCollisions::iterator; -using MyV0Photons = soa::Join; +using MyV0Photons = soa::Join; using MyV0Photon = MyV0Photons::iterator; using MyDalitzEEs = soa::Join; @@ -60,7 +60,6 @@ struct TaggingPi0MC { Configurable maxY{"maxY", 0.9, "maximum rapidity for reconstructed particles"}; Configurable fConfigPCMCuts{"cfgPCMCuts", "analysis", "Comma separated list of V0 photon cuts"}; Configurable fConfigDalitzEECuts{"cfgDalitzEECuts", "mee_0_120_tpchadrejortofreq,mee_0_120_tpchadrejortofreq_lowB", "Comma separated list of Dalitz ee cuts"}; - Configurable fConfigPCMibwCuts{"cfgPCMibwCuts", "wwire_ib", "Comma separated list of V0 photon cuts"}; Configurable fConfigPHOSCuts{"cfgPHOSCuts", "test02,test03", "Comma separated list of PHOS photon cuts"}; Configurable fConfigEMCCuts{"fConfigEMCCuts", "standard", "Comma separated list of EMCal photon cuts"}; Configurable fConfigPairCuts{"cfgPairCuts", "nocut", "Comma separated list of pair cuts"}; @@ -84,7 +83,6 @@ struct TaggingPi0MC { std::vector fPCMCuts; std::vector fDalitzEECuts; - std::vector fPCMibwCuts; std::vector fPHOSCuts; std::vector fEMCCuts; std::vector fPairCuts; @@ -92,11 +90,8 @@ struct TaggingPi0MC { std::vector fPairNames; void init(InitContext& context) { - if (context.mOptions.get("processPCMPCMibw")) { - fPairNames.push_back("PCMPCMibw"); - } - if (context.mOptions.get("processPCMDalitz")) { - fPairNames.push_back("PCMDalitz"); + if (context.mOptions.get("processPCMDalitzEE")) { + fPairNames.push_back("PCMDalitzEE"); } if (context.mOptions.get("processPCMPHOS")) { fPairNames.push_back("PCMPHOS"); @@ -107,7 +102,6 @@ struct TaggingPi0MC { DefinePCMCuts(); DefineDalitzEECuts(); - DefinePCMibwCuts(); DefinePHOSCuts(); DefineEMCCuts(); DefinePairCuts(); @@ -144,7 +138,7 @@ struct TaggingPi0MC { } // end of cut1 loop } - static constexpr std::string_view pairnames[8] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitz", "PHOSEMC", "PCMPCMibw"}; + static constexpr std::string_view pairnames[9] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitzEE", "PCMDalitzMuMu", "PHOSEMC", "DalitzEEDalitzEE"}; void addhistograms() { fMainList->SetOwner(true); @@ -173,10 +167,7 @@ struct TaggingPi0MC { o2::aod::emphotonhistograms::AddHistClass(list_pair, pairname.data()); - if (pairname == "PCMPCMibw") { - add_pair_histograms(list_pair, pairname, fPCMCuts, fPCMibwCuts, fPairCuts); - } - if (pairname == "PCMDalitz") { + if (pairname == "PCMDalitzEE") { add_pair_histograms(list_pair, pairname, fPCMCuts, fDalitzEECuts, fPairCuts); } if (pairname == "PCMPHOS") { @@ -217,20 +208,6 @@ struct TaggingPi0MC { LOGF(info, "Number of DalitzEE cuts = %d", fDalitzEECuts.size()); } - void DefinePCMibwCuts() - { - TString cutNamesStr = fConfigPCMibwCuts.value; - if (!cutNamesStr.IsNull()) { - std::unique_ptr objArray(cutNamesStr.Tokenize(",")); - for (int icut = 0; icut < objArray->GetEntries(); ++icut) { - const char* cutname = objArray->At(icut)->GetName(); - LOGF(info, "add cut : %s", cutname); - fPCMibwCuts.push_back(*pcmcuts::GetCut(cutname)); - } - } - LOGF(info, "Number of PCMibw cuts = %d", fPCMibwCuts.size()); - } - void DefinePHOSCuts() { TString cutNamesStr = fConfigPHOSCuts.value; @@ -305,9 +282,7 @@ struct TaggingPi0MC { bool IsSelectedPair(TG1 const& g1, TG2 const& g2, TCut1 const& cut1, TCut2 const& cut2) { bool is_selected_pair = false; - if constexpr (pairtype == PairType::kPCMPCMibw) { - is_selected_pair = o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); - } else if constexpr (pairtype == PairType::kPCMPHOS) { + if constexpr (pairtype == PairType::kPCMPHOS) { is_selected_pair = o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); } else if constexpr (pairtype == PairType::kPCMEMC) { is_selected_pair = o2::aod::photonpair::IsSelectedPair(g1, g2, cut1, cut2); @@ -428,25 +403,7 @@ struct TaggingPi0MC { } int pi0id = -1; - if constexpr (pairtype == PairType::kPCMPCMibw) { - auto pos2 = g2.template posTrack_as(); - auto ele2 = g2.template negTrack_as(); - auto pos2mc = pos2.template emmcparticle_as(); - auto ele2mc = ele2.template emmcparticle_as(); - - int photonid2 = FindCommonMotherFrom2Prongs(pos2mc, ele2mc, -11, 11, 22, mcparticles); - if (photonid2 < 0) { // check swap, true electron is reconstructed as positron and vice versa. - photonid2 = FindCommonMotherFrom2Prongs(pos2mc, ele2mc, 11, -11, 22, mcparticles); - } - - if (photonid1 < 0 || photonid2 < 0) { - continue; - } - - auto g1mc = mcparticles.iteratorAt(photonid1); - auto g2mc = mcparticles.iteratorAt(photonid2); - pi0id = FindCommonMotherFrom2Prongs(g1mc, g2mc, 22, 22, 111, mcparticles); - } else if constexpr (pairtype == PairType::kPCMDalitzEE) { + if constexpr (pairtype == PairType::kPCMDalitzEE) { auto g1mc = mcparticles.iteratorAt(photonid1); auto pos2 = g2.template posTrack_as(); auto ele2 = g2.template negTrack_as(); @@ -496,11 +453,7 @@ struct TaggingPi0MC { Preslice perCollision_phos = aod::skimmedcluster::collisionId; Preslice perCollision_emc = aod::skimmedcluster::collisionId; - void processPCMPCMibw(MyCollisions const& collisions, MyV0Photons const& v0photons, MyMCV0Legs const& legs, aod::EMMCParticles const& mcparticles, aod::EMReducedMCEvents const& mccollisions) - { - TruePairing(collisions, v0photons, v0photons, perCollision_pcm, perCollision_pcm, fPCMCuts, fPCMibwCuts, fPairCuts, legs, nullptr, mcparticles, mccollisions); - } - void processPCMDalitz(MyCollisions const& collisions, MyV0Photons const& v0photons, MyMCV0Legs const& legs, MyFilteredDalitzEEs const& dielectrons, MyMCTracks const& emprimaryelectrons, aod::EMMCParticles const& mcparticles, aod::EMReducedMCEvents const& mccollisions) + void processPCMDalitzEE(MyCollisions const& collisions, MyV0Photons const& v0photons, MyMCV0Legs const& legs, MyFilteredDalitzEEs const& dielectrons, MyMCTracks const& emprimaryelectrons, aod::EMMCParticles const& mcparticles, aod::EMReducedMCEvents const& mccollisions) { TruePairing(collisions, v0photons, dielectrons, perCollision_pcm, perCollision_dalitz, fPCMCuts, fDalitzEECuts, fPairCuts, legs, emprimaryelectrons, mcparticles, mccollisions); } @@ -517,8 +470,7 @@ struct TaggingPi0MC { void processDummy(MyCollisions const& collision) {} - PROCESS_SWITCH(TaggingPi0MC, processPCMPCMibw, "pairing PCM-PCMibw", false); - PROCESS_SWITCH(TaggingPi0MC, processPCMDalitz, "pairing PCM-Dalitz", false); + PROCESS_SWITCH(TaggingPi0MC, processPCMDalitzEE, "pairing PCM-Dalitz", false); PROCESS_SWITCH(TaggingPi0MC, processPCMPHOS, "pairing PCM-PHOS", false); PROCESS_SWITCH(TaggingPi0MC, processPCMEMC, "pairing PCM-EMCal", false); PROCESS_SWITCH(TaggingPi0MC, processDummy, "Dummy function", true); diff --git a/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx b/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx index dc7417f80f0..6effd822cbc 100644 --- a/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx +++ b/PWGEM/PhotonMeson/Tasks/dalitzEEQC.cxx @@ -50,6 +50,14 @@ struct DalitzEEQC { Configurable fConfigDalitzEECuts{"cfgDalitzEECuts", "mee_all_tpchadrejortofreq_lowB,nocut", "Comma separated list of dalitz ee cuts"}; std::vector fDalitzEECuts; + Configurable cfgDoDCAstudy{"cfgDoDCAstudy", false, "flag to fill histograms for DCA"}; + Configurable cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; + Configurable> cfgArrCentMin{"cfgArrCentMin", {0.0f, 10.0f, 20.0f, 40.0f, 60.0f, 80.0f}, "cent min array"}; + Configurable> cfgArrCentMax{"cfgArrCentMax", {10.0f, 20.0f, 40.0f, 60.0f, 80.0f, 999.f}, "cent max array"}; + std::vector vec_cent_min; + std::vector vec_cent_max; + + static constexpr std::string_view cent_det_names[3] = {"FT0M", "FT0A", "FT0C"}; OutputObj fOutputEvent{"Event"}; OutputObj fOutputTrack{"Track"}; OutputObj fOutputDalitzEE{"DalitzEE"}; @@ -62,39 +70,35 @@ struct DalitzEEQC { fMainList->SetName("fMainList"); // create sub lists first. - o2::aod::emphotonhistograms::AddHistClass(fMainList, "Event"); - THashList* list_ev = reinterpret_cast(fMainList->FindObject("Event")); - o2::aod::emphotonhistograms::DefineHistograms(list_ev, "Event"); - - o2::aod::emphotonhistograms::AddHistClass(fMainList, "Track"); - THashList* list_track = reinterpret_cast(fMainList->FindObject("Track")); - - o2::aod::emphotonhistograms::AddHistClass(fMainList, "DalitzEE"); - THashList* list_dalitzee = reinterpret_cast(fMainList->FindObject("DalitzEE")); - - for (const auto& cut : fDalitzEECuts) { - const char* cutname = cut.GetName(); - o2::aod::emphotonhistograms::AddHistClass(list_track, cutname); - o2::aod::emphotonhistograms::AddHistClass(list_dalitzee, cutname); - } - - // for single tracks - for (auto& cut : fDalitzEECuts) { - std::string_view cutname = cut.GetName(); - THashList* list = reinterpret_cast(fMainList->FindObject("Track")->FindObject(cutname.data())); - o2::aod::emphotonhistograms::DefineHistograms(list, "Track"); - } - - // for DalitzEEs - for (auto& cut : fDalitzEECuts) { - std::string_view cutname = cut.GetName(); - THashList* list = reinterpret_cast(fMainList->FindObject("DalitzEE")->FindObject(cutname.data())); - if (doMix) { - o2::aod::emphotonhistograms::DefineHistograms(list, "DalitzEE", "mix"); - } else { - o2::aod::emphotonhistograms::DefineHistograms(list, "DalitzEE", ""); - } - } + THashList* list_ev = reinterpret_cast(o2::aod::emphotonhistograms::AddHistClass(fMainList, "Event")); + THashList* list_track = reinterpret_cast(o2::aod::emphotonhistograms::AddHistClass(fMainList, "Track")); + THashList* list_dalitzee = reinterpret_cast(o2::aod::emphotonhistograms::AddHistClass(fMainList, "DalitzEE")); + + for (size_t icen = 0; icen < vec_cent_min.size(); icen++) { + float cen_min = vec_cent_min[icen]; + float cen_max = vec_cent_max[icen]; + const char* cent_name = Form("Cent_%s_%3.2f_%3.2f", cent_det_names[cfgCentEstimator].data(), cen_min, cen_max); + THashList* list_ev_cent = reinterpret_cast(o2::aod::emphotonhistograms::AddHistClass(list_ev, cent_name)); + o2::aod::emphotonhistograms::DefineHistograms(list_ev_cent, "Event"); + + THashList* list_track_cent = reinterpret_cast(o2::aod::emphotonhistograms::AddHistClass(list_track, cent_name)); + THashList* list_dalitzee_cent = reinterpret_cast(o2::aod::emphotonhistograms::AddHistClass(list_dalitzee, cent_name)); + for (const auto& cut : fDalitzEECuts) { + const char* cutname = cut.GetName(); + THashList* list_track_cent_cut = reinterpret_cast(o2::aod::emphotonhistograms::AddHistClass(list_track_cent, cutname)); + o2::aod::emphotonhistograms::DefineHistograms(list_track_cent_cut, "Track"); + + THashList* list_dalitzee_cent_cut = reinterpret_cast(o2::aod::emphotonhistograms::AddHistClass(list_dalitzee_cent, cutname)); + std::string histo_sub_group = ""; + if (doMix) { + histo_sub_group += "mix"; + } + if (cfgDoDCAstudy) { + histo_sub_group += "dca"; + } + o2::aod::emphotonhistograms::DefineHistograms(list_dalitzee_cent_cut, "DalitzEE", histo_sub_group.data()); + } // end of cut loop + } // end of centrality loop } void DefineCuts() @@ -117,6 +121,13 @@ struct DalitzEEQC { doMix = true; } + vec_cent_min = (std::vector)cfgArrCentMin; + vec_cent_max = (std::vector)cfgArrCentMax; + LOGF(info, "vec_cent_min.size() = %d", vec_cent_min.size()); + for (size_t i = 0; i < vec_cent_min.size(); i++) { + LOGF(info, "id = %d : centrality range %f - %f", i, vec_cent_min[i], vec_cent_max[i]); + } + DefineCuts(); addhistograms(); // please call this after DefinCuts(); @@ -131,6 +142,7 @@ struct DalitzEEQC { SliceCache cache; Preslice perCollision = aod::dalitzee::emreducedeventId; + Preslice perCollision_track = aod::emprimaryelectron::emreducedeventId; std::vector used_trackIds; @@ -145,156 +157,182 @@ struct DalitzEEQC { float det_pos = 999.f, det_ele = 999.f; for (auto& collision : collisions) { - reinterpret_cast(fMainList->FindObject("Event")->FindObject("hZvtx_before"))->Fill(collision.posZ()); - reinterpret_cast(fMainList->FindObject("Event")->FindObject("hCollisionCounter"))->Fill(1.0); - if (!collision.sel8()) { - continue; - } - reinterpret_cast(fMainList->FindObject("Event")->FindObject("hCollisionCounter"))->Fill(2.0); - - if (collision.numContrib() < 0.5) { - continue; - } - reinterpret_cast(fMainList->FindObject("Event")->FindObject("hCollisionCounter"))->Fill(3.0); - - if (abs(collision.posZ()) > 10.0) { - continue; - } - reinterpret_cast(fMainList->FindObject("Event")->FindObject("hCollisionCounter"))->Fill(4.0); - reinterpret_cast(fMainList->FindObject("Event")->FindObject("hZvtx_after"))->Fill(collision.posZ()); - o2::aod::emphotonhistograms::FillHistClass(list_ev, "", collision); + float centralities[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}; + float centrality = centralities[cfgCentEstimator]; auto uls_pairs_per_coll = uls_pairs->sliceByCached(o2::aod::dalitzee::emreducedeventId, collision.globalIndex(), cache); auto lspp_pairs_per_coll = lspp_pairs->sliceByCached(o2::aod::dalitzee::emreducedeventId, collision.globalIndex(), cache); auto lsmm_pairs_per_coll = lsmm_pairs->sliceByCached(o2::aod::dalitzee::emreducedeventId, collision.globalIndex(), cache); - for (const auto& cut : fDalitzEECuts) { - THashList* list_dalitzee_cut = static_cast(list_dalitzee->FindObject(cut.GetName())); - THashList* list_track_cut = static_cast(list_track->FindObject(cut.GetName())); - used_trackIds.reserve(uls_pairs_per_coll.size() * 2); - - int nuls = 0, nlspp = 0, nlsmm = 0; - for (auto& uls_pair : uls_pairs_per_coll) { - auto pos = uls_pair.template posTrack_as(); - auto ele = uls_pair.template negTrack_as(); - if (cut.IsSelected(uls_pair)) { - det_pos = pos.cYY() * pos.cZZ() - pos.cZY() * pos.cZY(); - det_ele = ele.cYY() * ele.cZZ() - ele.cZY() * ele.cZY(); - if (det_pos < 0 || det_ele < 0) { - dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; - LOGF(info, "determinant is negative."); - } else { - float chi2pos = (pos.dcaXY() * pos.dcaXY() * pos.cZZ() + pos.dcaZ() * pos.dcaZ() * pos.cYY() - 2. * pos.dcaXY() * pos.dcaZ() * pos.cZY()) / det_pos; - float chi2ele = (ele.dcaXY() * ele.dcaXY() * ele.cZZ() + ele.dcaZ() * ele.dcaZ() * ele.cYY() - 2. * ele.dcaXY() * ele.dcaZ() * ele.cZY()) / det_ele; - dca_pos_3d = std::sqrt(std::abs(chi2pos) / 2.); - dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); - dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); - } - values_single[0] = uls_pair.mass(); - values_single[1] = dca_pos_3d; - values_single[2] = dca_ele_3d; - values_single[3] = dca_ee_3d; - reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_uls_dca_same"))->Fill(values_single); + // auto tracks_coll = tracks.sliceBy(perCollision_track, collision.globalIndex()); + // LOGF(info, "tracks_coll.size() = %d", tracks_coll.size()); + + for (size_t icen = 0; icen < vec_cent_min.size(); icen++) { + if (centrality < vec_cent_min[icen] || vec_cent_max[icen] < centrality) { + continue; + } + const char* cent_name = Form("Cent_%s_%3.2f_%3.2f", cent_det_names[cfgCentEstimator].data(), vec_cent_min[icen], vec_cent_max[icen]); + THashList* list_ev_cent = static_cast(list_ev->FindObject(cent_name)); + THashList* list_dalitzee_cent = static_cast(list_dalitzee->FindObject(cent_name)); + THashList* list_track_cent = static_cast(list_track->FindObject(cent_name)); + + reinterpret_cast(list_ev_cent->FindObject("hZvtx_before"))->Fill(collision.posZ()); + reinterpret_cast(list_ev_cent->FindObject("hCollisionCounter"))->Fill(1.0); + if (!collision.sel8()) { + continue; + } + reinterpret_cast(list_ev_cent->FindObject("hCollisionCounter"))->Fill(2.0); + + if (collision.numContrib() < 0.5) { + continue; + } + reinterpret_cast(list_ev_cent->FindObject("hCollisionCounter"))->Fill(3.0); + + if (abs(collision.posZ()) > 10.0) { + continue; + } + reinterpret_cast(list_ev_cent->FindObject("hCollisionCounter"))->Fill(4.0); + reinterpret_cast(list_ev_cent->FindObject("hZvtx_after"))->Fill(collision.posZ()); + + o2::aod::emphotonhistograms::FillHistClass(list_ev_cent, "", collision); + + for (const auto& cut : fDalitzEECuts) { + THashList* list_dalitzee_cent_cut = static_cast(list_dalitzee_cent->FindObject(cut.GetName())); + THashList* list_track_cent_cut = static_cast(list_track_cent->FindObject(cut.GetName())); + used_trackIds.reserve(uls_pairs_per_coll.size() * 2); + + int nuls = 0, nlspp = 0, nlsmm = 0; + for (auto& uls_pair : uls_pairs_per_coll) { + auto pos = uls_pair.template posTrack_as(); + auto ele = uls_pair.template negTrack_as(); + if (cut.IsSelected(uls_pair)) { + det_pos = pos.cYY() * pos.cZZ() - pos.cZY() * pos.cZY(); + det_ele = ele.cYY() * ele.cZZ() - ele.cZY() * ele.cZY(); + if (det_pos < 0 || det_ele < 0) { + dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + } else { + float chi2pos = (pos.dcaXY() * pos.dcaXY() * pos.cZZ() + pos.dcaZ() * pos.dcaZ() * pos.cYY() - 2. * pos.dcaXY() * pos.dcaZ() * pos.cZY()) / det_pos; + float chi2ele = (ele.dcaXY() * ele.dcaXY() * ele.cZZ() + ele.dcaZ() * ele.dcaZ() * ele.cYY() - 2. * ele.dcaXY() * ele.dcaZ() * ele.cZY()) / det_ele; + dca_pos_3d = std::sqrt(std::abs(chi2pos) / 2.); + dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); + dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); + } - values[0] = uls_pair.mass(); - values[1] = uls_pair.pt(); - values[2] = dca_ee_3d; - values[3] = uls_pair.phiv(); - reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_uls_same"))->Fill(values); - - nuls++; - for (auto& track : {pos, ele}) { - if (std::find(used_trackIds.begin(), used_trackIds.end(), track.globalIndex()) == used_trackIds.end()) { - o2::aod::emphotonhistograms::FillHistClass(list_track_cut, "", track); - used_trackIds.emplace_back(track.globalIndex()); + if (cfgDoDCAstudy) { + values_single[0] = uls_pair.mass(); + values_single[1] = dca_pos_3d; + values_single[2] = dca_ele_3d; + values_single[3] = dca_ee_3d; + reinterpret_cast(list_dalitzee_cent_cut->FindObject("hs_dilepton_uls_dca_same"))->Fill(values_single); + } + + values[0] = uls_pair.mass(); + values[1] = uls_pair.pt(); + values[2] = dca_ee_3d; + values[3] = uls_pair.phiv(); + reinterpret_cast(list_dalitzee_cent_cut->FindObject("hs_dilepton_uls_same"))->Fill(values); + nuls++; + for (auto& track : {pos, ele}) { + if (std::find(used_trackIds.begin(), used_trackIds.end(), track.globalIndex()) == used_trackIds.end()) { + o2::aod::emphotonhistograms::FillHistClass(list_track_cent_cut, "", track); + used_trackIds.emplace_back(track.globalIndex()); + } } } - } - } // end of uls pair loop - reinterpret_cast(list_dalitzee_cut->FindObject("hNpair_uls"))->Fill(nuls); - - for (auto& lspp_pair : lspp_pairs_per_coll) { - auto pos = lspp_pair.template posTrack_as(); - auto ele = lspp_pair.template negTrack_as(); - if (cut.IsSelected(lspp_pair)) { - det_pos = pos.cYY() * pos.cZZ() - pos.cZY() * pos.cZY(); - det_ele = ele.cYY() * ele.cZZ() - ele.cZY() * ele.cZY(); - if (det_pos < 0 || det_ele < 0) { - dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; - LOGF(info, "determinant is negative."); - } else { - float chi2pos = (pos.dcaXY() * pos.dcaXY() * pos.cZZ() + pos.dcaZ() * pos.dcaZ() * pos.cYY() - 2. * pos.dcaXY() * pos.dcaZ() * pos.cZY()) / det_pos; - float chi2ele = (ele.dcaXY() * ele.dcaXY() * ele.cZZ() + ele.dcaZ() * ele.dcaZ() * ele.cYY() - 2. * ele.dcaXY() * ele.dcaZ() * ele.cZY()) / det_ele; - dca_pos_3d = std::sqrt(std::abs(chi2pos) / 2.); - dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); - dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); + } // end of uls pair loop + reinterpret_cast(list_dalitzee_cent_cut->FindObject("hNpair_uls"))->Fill(nuls); + + for (auto& lspp_pair : lspp_pairs_per_coll) { + auto pos = lspp_pair.template posTrack_as(); + auto ele = lspp_pair.template negTrack_as(); + if (cut.IsSelected(lspp_pair)) { + det_pos = pos.cYY() * pos.cZZ() - pos.cZY() * pos.cZY(); + det_ele = ele.cYY() * ele.cZZ() - ele.cZY() * ele.cZY(); + if (det_pos < 0 || det_ele < 0) { + dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + } else { + float chi2pos = (pos.dcaXY() * pos.dcaXY() * pos.cZZ() + pos.dcaZ() * pos.dcaZ() * pos.cYY() - 2. * pos.dcaXY() * pos.dcaZ() * pos.cZY()) / det_pos; + float chi2ele = (ele.dcaXY() * ele.dcaXY() * ele.cZZ() + ele.dcaZ() * ele.dcaZ() * ele.cYY() - 2. * ele.dcaXY() * ele.dcaZ() * ele.cZY()) / det_ele; + dca_pos_3d = std::sqrt(std::abs(chi2pos) / 2.); + dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); + dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); + } + if (cfgDoDCAstudy) { + values_single[0] = lspp_pair.mass(); + values_single[1] = dca_pos_3d; + values_single[2] = dca_ele_3d; + values_single[3] = dca_ee_3d; + reinterpret_cast(list_dalitzee_cent_cut->FindObject("hs_dilepton_lspp_dca_same"))->Fill(values_single); + } + values[0] = lspp_pair.mass(); + values[1] = lspp_pair.pt(); + values[2] = dca_ee_3d; + values[3] = lspp_pair.phiv(); + reinterpret_cast(list_dalitzee_cent_cut->FindObject("hs_dilepton_lspp_same"))->Fill(values); + nlspp++; } - values_single[0] = lspp_pair.mass(); - values_single[1] = dca_pos_3d; - values_single[2] = dca_ele_3d; - values_single[3] = dca_ee_3d; - reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lspp_dca_same"))->Fill(values_single); + } // end of lspp pair loop + reinterpret_cast(list_dalitzee_cent_cut->FindObject("hNpair_lspp"))->Fill(nlspp); + + for (auto& lsmm_pair : lsmm_pairs_per_coll) { + auto pos = lsmm_pair.template posTrack_as(); + auto ele = lsmm_pair.template negTrack_as(); + if (cut.IsSelected(lsmm_pair)) { + det_pos = pos.cYY() * pos.cZZ() - pos.cZY() * pos.cZY(); + det_ele = ele.cYY() * ele.cZZ() - ele.cZY() * ele.cZY(); + if (det_pos < 0 || det_ele < 0) { + dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + } else { + float chi2pos = (pos.dcaXY() * pos.dcaXY() * pos.cZZ() + pos.dcaZ() * pos.dcaZ() * pos.cYY() - 2. * pos.dcaXY() * pos.dcaZ() * pos.cZY()) / det_pos; + float chi2ele = (ele.dcaXY() * ele.dcaXY() * ele.cZZ() + ele.dcaZ() * ele.dcaZ() * ele.cYY() - 2. * ele.dcaXY() * ele.dcaZ() * ele.cZY()) / det_ele; + dca_pos_3d = std::sqrt(std::abs(chi2pos) / 2.); + dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); + dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); + } - values[0] = lspp_pair.mass(); - values[1] = lspp_pair.pt(); - values[2] = dca_ee_3d; - values[3] = lspp_pair.phiv(); - reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lspp_same"))->Fill(values); - nlspp++; - } - } // end of lspp pair loop - reinterpret_cast(list_dalitzee_cut->FindObject("hNpair_lspp"))->Fill(nlspp); - - for (auto& lsmm_pair : lsmm_pairs_per_coll) { - auto pos = lsmm_pair.template posTrack_as(); - auto ele = lsmm_pair.template negTrack_as(); - if (cut.IsSelected(lsmm_pair)) { - det_pos = pos.cYY() * pos.cZZ() - pos.cZY() * pos.cZY(); - det_ele = ele.cYY() * ele.cZZ() - ele.cZY() * ele.cZY(); - if (det_pos < 0 || det_ele < 0) { - dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; - LOGF(info, "determinant is negative."); - } else { - float chi2pos = (pos.dcaXY() * pos.dcaXY() * pos.cZZ() + pos.dcaZ() * pos.dcaZ() * pos.cYY() - 2. * pos.dcaXY() * pos.dcaZ() * pos.cZY()) / det_pos; - float chi2ele = (ele.dcaXY() * ele.dcaXY() * ele.cZZ() + ele.dcaZ() * ele.dcaZ() * ele.cYY() - 2. * ele.dcaXY() * ele.dcaZ() * ele.cZY()) / det_ele; - dca_pos_3d = std::sqrt(std::abs(chi2pos) / 2.); - dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); - dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); - } - values_single[0] = lsmm_pair.mass(); - values_single[1] = dca_pos_3d; - values_single[2] = dca_ele_3d; - values_single[3] = dca_ee_3d; - reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lsmm_dca_same"))->Fill(values_single); + if (cfgDoDCAstudy) { + values_single[0] = lsmm_pair.mass(); + values_single[1] = dca_pos_3d; + values_single[2] = dca_ele_3d; + values_single[3] = dca_ee_3d; + reinterpret_cast(list_dalitzee_cent_cut->FindObject("hs_dilepton_lsmm_dca_same"))->Fill(values_single); + } - values[0] = lsmm_pair.mass(); - values[1] = lsmm_pair.pt(); - values[2] = dca_ee_3d; - values[3] = lsmm_pair.phiv(); - reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lsmm_same"))->Fill(values); - nlsmm++; - } - } // end of lsmm pair loop - reinterpret_cast(list_dalitzee_cut->FindObject("hNpair_lsmm"))->Fill(nlsmm); - - used_trackIds.clear(); - used_trackIds.shrink_to_fit(); - } // end of cut loop - } // end of collision loop - } // end of process + values[0] = lsmm_pair.mass(); + values[1] = lsmm_pair.pt(); + values[2] = dca_ee_3d; + values[3] = lsmm_pair.phiv(); + reinterpret_cast(list_dalitzee_cent_cut->FindObject("hs_dilepton_lsmm_same"))->Fill(values); + nlsmm++; + } + } // end of lsmm pair loop + reinterpret_cast(list_dalitzee_cent_cut->FindObject("hNpair_lsmm"))->Fill(nlsmm); + + used_trackIds.clear(); + used_trackIds.shrink_to_fit(); + } // end of cut loop + } // end of centrality list loop + } // end of collision loop + } // end of process PROCESS_SWITCH(DalitzEEQC, processQC, "run Dalitz QC", true); Configurable ndepth{"ndepth", 10, "depth for event mixing"}; 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, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 999.f}, "Mixing bins - centrality"}; - using BinningType = ColumnBinningPolicy; - BinningType colBinning{{ConfVtxBins, ConfCentBins}, true}; + using BinningType_M = ColumnBinningPolicy; + using BinningType_A = ColumnBinningPolicy; + using BinningType_C = ColumnBinningPolicy; + BinningType_M colBinning_M{{ConfVtxBins, ConfCentBins}, true}; + BinningType_A colBinning_A{{ConfVtxBins, ConfCentBins}, true}; + BinningType_C colBinning_C{{ConfVtxBins, ConfCentBins}, true}; + Filter collisionFilter_common = nabs(o2::aod::collision::posZ) < 10.f && o2::aod::collision::numContrib > (uint16_t)0 && o2::aod::evsel::sel8 == true; Filter collisionFilter_subsys = (o2::aod::emreducedevent::neeuls >= 1) || (o2::aod::emreducedevent::neelspp >= 1) || (o2::aod::emreducedevent::neelsmm >= 1); using MyFilteredCollisions = soa::Filtered; // this goes to mixed event. // e+, e- enter to event mixing, only if any pair exists. If you want to do mixed event, please store LS for ee - void processEventMixing(MyFilteredCollisions const& collisions, MyDalitzEEs const& dileptons, MyTracks const& tracks) + template + void MixedEventPairing(TEvents const& collisions, TTracks const& tracks, TMixedBinning const& colBinning) { THashList* list_dalitzee = static_cast(fMainList->FindObject("DalitzEE")); double values[4] = {0, 0, 0, 0}; @@ -305,71 +343,87 @@ struct DalitzEEQC { float det_pos = 999.f, det_ele = 999.f; for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ndepth, -1, collisions, collisions)) { // internally, CombinationsStrictlyUpperIndexPolicy(collisions, collisions) is called. - auto dileptons_coll1 = dileptons.sliceBy(perCollision, collision1.globalIndex()); - auto dileptons_coll2 = dileptons.sliceBy(perCollision, collision2.globalIndex()); - // LOGF(info, "collision1.globalIndex() = %d, collision1: posZ = %f, sel8 = %d | collision2.globalIndex() = %d, collision2: posZ = %f, sel8 = %d",collision1.globalIndex(), collision1.posZ(), collision1.sel8(), collision2.globalIndex(), collision2.posZ(), collision2.sel8()); - - for (auto& cut : fDalitzEECuts) { - THashList* list_dalitzee_cut = static_cast(list_dalitzee->FindObject(cut.GetName())); - for (auto& [dl1, dl2] : combinations(soa::CombinationsFullIndexPolicy(dileptons_coll1, dileptons_coll2))) { - if (!cut.IsSelected(dl1) || !cut.IsSelected(dl2)) { - continue; - } - - auto pos1 = dl1.template posTrack_as(); - auto ele1 = dl1.template negTrack_as(); - auto pos2 = dl2.template posTrack_as(); - auto ele2 = dl2.template negTrack_as(); - - for (auto& t1 : {pos1, ele1}) { - for (auto& t2 : {pos2, ele2}) { - v1 = ROOT::Math::PtEtaPhiMVector(t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassElectron); - v2 = ROOT::Math::PtEtaPhiMVector(t2.pt(), t2.eta(), t2.phi(), o2::constants::physics::MassElectron); - v12 = v1 + v2; - phiv = getPhivPair(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz(), t1.sign(), t2.sign(), collision1.bz()); - - det_pos = t1.cYY() * t1.cZZ() - t1.cZY() * t1.cZY(); - det_ele = t2.cYY() * t2.cZZ() - t2.cZY() * t2.cZY(); - if (det_pos < 0 || det_ele < 0) { - dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; - LOGF(info, "determinant is negative."); + float centralities[3] = {collision1.centFT0M(), collision1.centFT0A(), collision1.centFT0C()}; + float centrality = centralities[cfgCentEstimator]; + + auto tracks_coll1 = tracks.sliceBy(perCollision_track, collision1.globalIndex()); + auto tracks_coll2 = tracks.sliceBy(perCollision_track, collision2.globalIndex()); + // LOGF(info, "collision1.globalIndex() = %d, collision1: posZ = %f, sel8 = %d, centFT0C = %f, ndl1 = %d | collision2.globalIndex() = %d, collision2: posZ = %f, sel8 = %d, centFT0C = %f, ndl2 = %d",collision1.globalIndex(), collision1.posZ(), collision1.sel8(), collision1.centFT0C(), tracks_coll1.size(), collision2.globalIndex(), collision2.posZ(), collision2.sel8(), collision2.centFT0C(), tracks_coll2.size()); + + for (size_t icen = 0; icen < vec_cent_min.size(); icen++) { + if (centrality < vec_cent_min[icen] || vec_cent_max[icen] < centrality) { + continue; + } + const char* cent_name = Form("Cent_%s_%3.2f_%3.2f", cent_det_names[cfgCentEstimator].data(), vec_cent_min[icen], vec_cent_max[icen]); + THashList* list_dalitzee_cent = static_cast(list_dalitzee->FindObject(cent_name)); + + for (auto& cut : fDalitzEECuts) { + THashList* list_dalitzee_cent_cut = static_cast(list_dalitzee_cent->FindObject(cut.GetName())); + for (auto& [t1, t2] : combinations(soa::CombinationsFullIndexPolicy(tracks_coll1, tracks_coll2))) { + v1 = ROOT::Math::PtEtaPhiMVector(t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassElectron); + v2 = ROOT::Math::PtEtaPhiMVector(t2.pt(), t2.eta(), t2.phi(), o2::constants::physics::MassElectron); + v12 = v1 + v2; + phiv = getPhivPair(t1.px(), t1.py(), t1.pz(), t2.px(), t2.py(), t2.pz(), t1.sign(), t2.sign(), collision1.bz()); + + det_pos = t1.cYY() * t1.cZZ() - t1.cZY() * t1.cZY(); + det_ele = t2.cYY() * t2.cZZ() - t2.cZY() * t2.cZY(); + if (det_pos < 0 || det_ele < 0) { + dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + } else { + float chi2pos = (t1.dcaXY() * t1.dcaXY() * t1.cZZ() + t1.dcaZ() * t1.dcaZ() * t1.cYY() - 2. * t1.dcaXY() * t1.dcaZ() * t1.cZY()) / det_pos; + float chi2ele = (t2.dcaXY() * t2.dcaXY() * t2.cZZ() + t2.dcaZ() * t2.dcaZ() * t2.cYY() - 2. * t2.dcaXY() * t2.dcaZ() * t2.cZY()) / det_ele; + dca_pos_3d = std::sqrt(std::abs(chi2pos) / 2.); + dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); + dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); + } + values_single[0] = v12.M(); + values_single[1] = dca_pos_3d; + values_single[2] = dca_ele_3d; + values_single[3] = dca_ee_3d; + + values[0] = v12.M(); + values[1] = v12.Pt(); + values[2] = dca_ee_3d; + values[3] = phiv; + + if (cut.IsSelectedTrack(t1) && cut.IsSelectedTrack(t2) && cut.IsSelectedPair(v12.M(), phiv)) { + if (t1.sign() * t2.sign() < 0) { + reinterpret_cast(list_dalitzee_cent_cut->FindObject("hs_dilepton_uls_mix"))->Fill(values); + } else if (t1.sign() > 0 && t2.sign() > 0) { + reinterpret_cast(list_dalitzee_cent_cut->FindObject("hs_dilepton_lspp_mix"))->Fill(values); + } else if (t1.sign() < 0 && t2.sign() < 0) { + reinterpret_cast(list_dalitzee_cent_cut->FindObject("hs_dilepton_lsmm_mix"))->Fill(values); } else { - float chi2pos = (t1.dcaXY() * t1.dcaXY() * t1.cZZ() + t1.dcaZ() * t1.dcaZ() * t1.cYY() - 2. * t1.dcaXY() * t1.dcaZ() * t1.cZY()) / det_pos; - float chi2ele = (t2.dcaXY() * t2.dcaXY() * t2.cZZ() + t2.dcaZ() * t2.dcaZ() * t2.cYY() - 2. * t2.dcaXY() * t2.dcaZ() * t2.cZY()) / det_ele; - dca_pos_3d = std::sqrt(std::abs(chi2pos) / 2.); - dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); - dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); + LOGF(info, "This should not happen."); } - values_single[0] = v12.M(); - values_single[1] = dca_pos_3d; - values_single[2] = dca_ele_3d; - values_single[3] = dca_ee_3d; - - values[0] = v12.M(); - values[1] = v12.Pt(); - values[2] = dca_ee_3d; - values[3] = phiv; - if (cut.IsSelectedTrack(t1) && cut.IsSelectedTrack(t2) && cut.IsSelectedPair(v12.M(), phiv)) { + if (cfgDoDCAstudy) { if (t1.sign() * t2.sign() < 0) { - reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_uls_mix"))->Fill(values); - reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_uls_dca_mix"))->Fill(values_single); + reinterpret_cast(list_dalitzee_cent_cut->FindObject("hs_dilepton_uls_dca_mix"))->Fill(values_single); } else if (t1.sign() > 0 && t2.sign() > 0) { - reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lspp_mix"))->Fill(values); - reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lspp_dca_mix"))->Fill(values_single); + reinterpret_cast(list_dalitzee_cent_cut->FindObject("hs_dilepton_lspp_dca_mix"))->Fill(values_single); } else if (t1.sign() < 0 && t2.sign() < 0) { - reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lsmm_mix"))->Fill(values); - reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_lsmm_dca_mix"))->Fill(values_single); + reinterpret_cast(list_dalitzee_cent_cut->FindObject("hs_dilepton_lsmm_dca_mix"))->Fill(values_single); } else { LOGF(info, "This should not happen."); } } } - } + } // end of different dileptn combinations + } // end of centrality list loop + } // end of cut loop + } // end of different collision combinations + } - } // end of different dileptn combinations - } // end of cut loop - } // end of different collision combinations + void processEventMixing(MyFilteredCollisions const& collisions, MyTracks const& tracks) + { + if (cfgCentEstimator == 0) { + MixedEventPairing(collisions, tracks, colBinning_M); + } else if (cfgCentEstimator == 1) { + MixedEventPairing(collisions, tracks, colBinning_A); + } else if (cfgCentEstimator == 2) { + MixedEventPairing(collisions, tracks, colBinning_C); + } } PROCESS_SWITCH(DalitzEEQC, processEventMixing, "run Dalitz EE QC event mixing", true); diff --git a/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx b/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx index 8f711631939..a52f64f9879 100644 --- a/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/dalitzEEQCMC.cxx @@ -50,6 +50,8 @@ struct DalitzEEQCMC { Configurable fConfigDalitzEECuts{"cfgDalitzEECuts", "mee_all_tpchadrejortofreq_lowB,nocut", "Comma separated list of dalitz ee cuts"}; std::vector fDalitzEECuts; + Configurable cfgDoDCAstudy{"cfgDoDCAstudy", false, "flag to fill histograms for DCA"}; + OutputObj fOutputEvent{"Event"}; OutputObj fOutputTrack{"Track"}; OutputObj fOutputDalitzEE{"DalitzEE"}; @@ -93,7 +95,12 @@ struct DalitzEEQCMC { for (auto& cut : fDalitzEECuts) { std::string_view cutname = cut.GetName(); THashList* list = reinterpret_cast(fMainList->FindObject("DalitzEE")->FindObject(cutname.data())); - o2::aod::emphotonhistograms::DefineHistograms(list, "DalitzEE", "mc"); + // o2::aod::emphotonhistograms::DefineHistograms(list, "DalitzEE", "mc"); + std::string histo_sub_group = "mc,"; + if (cfgDoDCAstudy) { + histo_sub_group += "dca"; + } + o2::aod::emphotonhistograms::DefineHistograms(list, "DalitzEE", histo_sub_group.data()); } } @@ -199,7 +206,6 @@ struct DalitzEEQCMC { det_ele = ele.cYY() * ele.cZZ() - ele.cZY() * ele.cZY(); if (det_pos < 0 || det_ele < 0) { dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; - LOGF(info, "determinant is negative."); } else { float chi2pos = (pos.dcaXY() * pos.dcaXY() * pos.cZZ() + pos.dcaZ() * pos.dcaZ() * pos.cYY() - 2. * pos.dcaXY() * pos.dcaZ() * pos.cZY()) / det_pos; float chi2ele = (ele.dcaXY() * ele.dcaXY() * ele.cZZ() + ele.dcaZ() * ele.dcaZ() * ele.cYY() - 2. * ele.dcaXY() * ele.dcaZ() * ele.cZY()) / det_ele; @@ -207,11 +213,14 @@ struct DalitzEEQCMC { dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); } - values_single[0] = uls_pair.mass(); - values_single[1] = dca_pos_3d; - values_single[2] = dca_ele_3d; - values_single[3] = dca_ee_3d; - reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_uls_dca_same"))->Fill(values_single); + + if (cfgDoDCAstudy) { + values_single[0] = uls_pair.mass(); + values_single[1] = dca_pos_3d; + values_single[2] = dca_ele_3d; + values_single[3] = dca_ee_3d; + reinterpret_cast(list_dalitzee_cut->FindObject("hs_dilepton_uls_dca_same"))->Fill(values_single); + } values[0] = uls_pair.mass(); values[1] = uls_pair.pt(); diff --git a/PWGEM/PhotonMeson/Tasks/dalitzMuMuQC.cxx b/PWGEM/PhotonMeson/Tasks/dalitzMuMuQC.cxx index 0a09f0ccff1..f2fffd1935d 100644 --- a/PWGEM/PhotonMeson/Tasks/dalitzMuMuQC.cxx +++ b/PWGEM/PhotonMeson/Tasks/dalitzMuMuQC.cxx @@ -131,6 +131,7 @@ struct DalitzMuMuQC { SliceCache cache; Preslice perCollision = aod::dalitzmumu::emreducedeventId; + Preslice perCollision_track = aod::emprimarymuon::emreducedeventId; std::vector used_trackIds; @@ -182,7 +183,6 @@ struct DalitzMuMuQC { det_ele = ele.cYY() * ele.cZZ() - ele.cZY() * ele.cZY(); if (det_pos < 0 || det_ele < 0) { dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; - LOGF(info, "determinant is negative."); } else { float chi2pos = (pos.dcaXY() * pos.dcaXY() * pos.cZZ() + pos.dcaZ() * pos.dcaZ() * pos.cYY() - 2. * pos.dcaXY() * pos.dcaZ() * pos.cZY()) / det_pos; float chi2ele = (ele.dcaXY() * ele.dcaXY() * ele.cZZ() + ele.dcaZ() * ele.dcaZ() * ele.cYY() - 2. * ele.dcaXY() * ele.dcaZ() * ele.cZY()) / det_ele; @@ -215,7 +215,6 @@ struct DalitzMuMuQC { det_ele = ele.cYY() * ele.cZZ() - ele.cZY() * ele.cZY(); if (det_pos < 0 || det_ele < 0) { dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; - LOGF(info, "determinant is negative."); } else { float chi2pos = (pos.dcaXY() * pos.dcaXY() * pos.cZZ() + pos.dcaZ() * pos.dcaZ() * pos.cYY() - 2. * pos.dcaXY() * pos.dcaZ() * pos.cZY()) / det_pos; float chi2ele = (ele.dcaXY() * ele.dcaXY() * ele.cZZ() + ele.dcaZ() * ele.dcaZ() * ele.cYY() - 2. * ele.dcaXY() * ele.dcaZ() * ele.cZY()) / det_ele; @@ -241,7 +240,6 @@ struct DalitzMuMuQC { det_ele = ele.cYY() * ele.cZZ() - ele.cZY() * ele.cZY(); if (det_pos < 0 || det_ele < 0) { dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; - LOGF(info, "determinant is negative."); } else { float chi2pos = (pos.dcaXY() * pos.dcaXY() * pos.cZZ() + pos.dcaZ() * pos.dcaZ() * pos.cYY() - 2. * pos.dcaXY() * pos.dcaZ() * pos.cZY()) / det_pos; float chi2ele = (ele.dcaXY() * ele.dcaXY() * ele.cZZ() + ele.dcaZ() * ele.dcaZ() * ele.cYY() - 2. * ele.dcaXY() * ele.dcaZ() * ele.cZY()) / det_ele; @@ -269,59 +267,61 @@ struct DalitzMuMuQC { Configurable ndepth{"ndepth", 10, "depth for event mixing"}; 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, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 999.f}, "Mixing bins - centrality"}; - using BinningType = ColumnBinningPolicy; + using BinningType = ColumnBinningPolicy; BinningType colBinning{{ConfVtxBins, ConfCentBins}, true}; Filter collisionFilter_common = nabs(o2::aod::collision::posZ) < 10.f && o2::aod::collision::numContrib > (uint16_t)0 && o2::aod::evsel::sel8 == true; Filter collisionFilter_subsys = (o2::aod::emreducedevent::nmumuuls >= 1) || (o2::aod::emreducedevent::nmumulspp >= 1) || (o2::aod::emreducedevent::nmumulsmm >= 1); using MyFilteredCollisions = soa::Filtered; // this goes to mixed event. // mu+, mu- enter to event mixing, only if any pair exists. If you want to do mixed event, please store LS for mumu - void processEventMixing(MyFilteredCollisions const& collisions, MyDalitzMuMus const& dileptons, MyTracks const& tracks) + void processEventMixing(MyFilteredCollisions const& collisions, MyTracks const& tracks) { THashList* list_dalitzmumu = static_cast(fMainList->FindObject("DalitzMuMu")); double values[4] = {0, 0, 0, 0}; ROOT::Math::PtEtaPhiMVector v1, v2, v12; + float phiv = 0; + float dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + float det_pos = 999.f, det_ele = 999.f; for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ndepth, -1, collisions, collisions)) { // internally, CombinationsStrictlyUpperIndexPolicy(collisions, collisions) is called. - auto dileptons_coll1 = dileptons.sliceBy(perCollision, collision1.globalIndex()); - auto dileptons_coll2 = dileptons.sliceBy(perCollision, collision2.globalIndex()); - // LOGF(info, "collision1.globalIndex() = %d, collision1: posZ = %f, sel8 = %d | collision2.globalIndex() = %d, collision2: posZ = %f, sel8 = %d",collision1.globalIndex(), collision1.posZ(), collision1.sel8(), collision2.globalIndex(), collision2.posZ(), collision2.sel8()); + auto tracks_coll1 = tracks.sliceBy(perCollision_track, collision1.globalIndex()); + auto tracks_coll2 = tracks.sliceBy(perCollision_track, collision2.globalIndex()); + // LOGF(info, "collision1.globalIndex() = %d, collision1: posZ = %f, sel8 = %d, centFT0C = %f, ndl1 = %d | collision2.globalIndex() = %d, collision2: posZ = %f, sel8 = %d, centFT0C = %f, ndl2 = %d",collision1.globalIndex(), collision1.posZ(), collision1.sel8(), collision1.centFT0C(), tracks_coll1.size(), collision2.globalIndex(), collision2.posZ(), collision2.sel8(), collision2.centFT0C(), tracks_coll2.size()); for (auto& cut : fDalitzMuMuCuts) { THashList* list_dalitzmumu_cut = static_cast(list_dalitzmumu->FindObject(cut.GetName())); - for (auto& [dl1, dl2] : combinations(soa::CombinationsFullIndexPolicy(dileptons_coll1, dileptons_coll2))) { - if (!cut.IsSelected(dl1) || !cut.IsSelected(dl2)) { - continue; + for (auto& [t1, t2] : combinations(soa::CombinationsFullIndexPolicy(tracks_coll1, tracks_coll2))) { + v1 = ROOT::Math::PtEtaPhiMVector(t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassMuon); + v2 = ROOT::Math::PtEtaPhiMVector(t2.pt(), t2.eta(), t2.phi(), o2::constants::physics::MassMuon); + v12 = v1 + v2; + + det_pos = t1.cYY() * t1.cZZ() - t1.cZY() * t1.cZY(); + det_ele = t2.cYY() * t2.cZZ() - t2.cZY() * t2.cZY(); + if (det_pos < 0 || det_ele < 0) { + dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + } else { + float chi2pos = (t1.dcaXY() * t1.dcaXY() * t1.cZZ() + t1.dcaZ() * t1.dcaZ() * t1.cYY() - 2. * t1.dcaXY() * t1.dcaZ() * t1.cZY()) / det_pos; + float chi2ele = (t2.dcaXY() * t2.dcaXY() * t2.cZZ() + t2.dcaZ() * t2.dcaZ() * t2.cYY() - 2. * t2.dcaXY() * t2.dcaZ() * t2.cZY()) / det_ele; + dca_pos_3d = std::sqrt(std::abs(chi2pos) / 2.); + dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); + dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); } - - auto pos1 = dl1.template posTrack_as(); - auto ele1 = dl1.template negTrack_as(); - auto pos2 = dl2.template posTrack_as(); - auto ele2 = dl2.template negTrack_as(); - - for (auto& t1 : {pos1, ele1}) { - for (auto& t2 : {pos2, ele2}) { - v1 = ROOT::Math::PtEtaPhiMVector(t1.pt(), t1.eta(), t1.phi(), o2::constants::physics::MassMuon); - v2 = ROOT::Math::PtEtaPhiMVector(t2.pt(), t2.eta(), t2.phi(), o2::constants::physics::MassMuon); - v12 = v1 + v2; - values[0] = v12.M(); - values[1] = v12.Pt(); - values[2] = sqrt((pow(t1.dcaXY() / sqrt(t1.cYY()), 2) + pow(t2.dcaXY() / sqrt(t2.cYY()), 2)) / 2.); // pair DCAxy - values[3] = 0.f; - if (cut.IsSelectedTrack(t1) && cut.IsSelectedTrack(t2) && cut.IsSelectedPair(v12.M(), 0.f)) { - if (t1.sign() * t2.sign() < 0) { - reinterpret_cast(list_dalitzmumu_cut->FindObject("hs_dilepton_uls_mix"))->Fill(values); - } else if (t1.sign() > 0 && t2.sign() > 0) { - reinterpret_cast(list_dalitzmumu_cut->FindObject("hs_dilepton_lspp_mix"))->Fill(values); - } else if (t1.sign() < 0 && t2.sign() < 0) { - reinterpret_cast(list_dalitzmumu_cut->FindObject("hs_dilepton_lsmm_mix"))->Fill(values); - } else { - LOGF(info, "This should not happen."); - } - } + values[0] = v12.M(); + values[1] = v12.Pt(); + values[2] = dca_ee_3d; + values[3] = phiv; + + if (cut.IsSelectedTrack(t1) && cut.IsSelectedTrack(t2) && cut.IsSelectedPair(v12.M(), phiv)) { + if (t1.sign() * t2.sign() < 0) { + reinterpret_cast(list_dalitzmumu_cut->FindObject("hs_dilepton_uls_mix"))->Fill(values); + } else if (t1.sign() > 0 && t2.sign() > 0) { + reinterpret_cast(list_dalitzmumu_cut->FindObject("hs_dilepton_lspp_mix"))->Fill(values); + } else if (t1.sign() < 0 && t2.sign() < 0) { + reinterpret_cast(list_dalitzmumu_cut->FindObject("hs_dilepton_lsmm_mix"))->Fill(values); + } else { + LOGF(info, "This should not happen."); } } - } // end of different dileptn combinations } // end of cut loop } // end of different collision combinations diff --git a/PWGEM/PhotonMeson/Tasks/dalitzMuMuQCMC.cxx b/PWGEM/PhotonMeson/Tasks/dalitzMuMuQCMC.cxx index f936c95a462..3cc645ca879 100644 --- a/PWGEM/PhotonMeson/Tasks/dalitzMuMuQCMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/dalitzMuMuQCMC.cxx @@ -145,6 +145,8 @@ struct DalitzMuMuQCMC { THashList* list_dalitzmumu = static_cast(fMainList->FindObject("DalitzMuMu")); THashList* list_track = static_cast(fMainList->FindObject("Track")); double values[4] = {0, 0, 0, 0}; + float dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + float det_pos = 999.f, det_ele = 999.f; for (auto& collision : collisions) { reinterpret_cast(fMainList->FindObject("Event")->FindObject("hZvtx_before"))->Fill(collision.posZ()); @@ -192,9 +194,22 @@ struct DalitzMuMuQCMC { if (mother_id > 0) { auto mcmother = mcparticles.iteratorAt(mother_id); if (IsPhysicalPrimary(mcmother.emreducedmcevent(), mcmother, mcparticles)) { + + det_pos = pos.cYY() * pos.cZZ() - pos.cZY() * pos.cZY(); + det_ele = ele.cYY() * ele.cZZ() - ele.cZY() * ele.cZY(); + if (det_pos < 0 || det_ele < 0) { + dca_pos_3d = 999.f, dca_ele_3d = 999.f, dca_ee_3d = 999.f; + } else { + float chi2pos = (pos.dcaXY() * pos.dcaXY() * pos.cZZ() + pos.dcaZ() * pos.dcaZ() * pos.cYY() - 2. * pos.dcaXY() * pos.dcaZ() * pos.cZY()) / det_pos; + float chi2ele = (ele.dcaXY() * ele.dcaXY() * ele.cZZ() + ele.dcaZ() * ele.dcaZ() * ele.cYY() - 2. * ele.dcaXY() * ele.dcaZ() * ele.cZY()) / det_ele; + dca_pos_3d = std::sqrt(std::abs(chi2pos) / 2.); + dca_ele_3d = std::sqrt(std::abs(chi2ele) / 2.); + dca_ee_3d = std::sqrt((dca_pos_3d * dca_pos_3d + dca_ele_3d * dca_ele_3d) / 2.); + } + values[0] = uls_pair.mass(); values[1] = uls_pair.pt(); - values[2] = uls_pair.dcaXY(); + values[2] = dca_ee_3d; values[3] = uls_pair.phiv(); reinterpret_cast(list_dalitzmumu_cut->FindObject("hs_dilepton_uls_same"))->Fill(values); diff --git a/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx b/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx index 9c7d6209913..97b4aa0d32c 100644 --- a/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx +++ b/PWGEM/PhotonMeson/Tasks/emcalPi0QC.cxx @@ -159,8 +159,6 @@ struct Pi0QCTask { // define container for photons std::vector mPhotons; - // define container for photons for each collision - std::map> mapPhotons; // event mixing class EventMixVec evtMix; @@ -304,7 +302,6 @@ struct Pi0QCTask { LOG(debug) << "ProcessClusters"; // clear photon vector mPhotons.clear(); - mapPhotons.clear(); int globalCollID = -1000; @@ -395,9 +392,12 @@ struct Pi0QCTask { LOG(debug) << "Cluster rejected because of nCells cut"; return true; } - if (cluster.m02() < mClusterMinM02Cut || cluster.m02() > mClusterMaxM02Cut) { - LOG(debug) << "Cluster rejected because of m02 cut"; - return true; + // Only apply M02 cut when cluster contains more than one cell + if (cluster.nCells() > 1) { + if (cluster.m02() < mClusterMinM02Cut || cluster.m02() > mClusterMaxM02Cut) { + LOG(debug) << "Cluster rejected because of m02 cut"; + return true; + } } if (cluster.time() < mTimeMin || cluster.time() > mTimeMax) { LOG(debug) << "Cluster rejected because of time cut"; diff --git a/PWGEM/PhotonMeson/Tasks/pcmQC.cxx b/PWGEM/PhotonMeson/Tasks/pcmQC.cxx index 86a40466102..941ebdb4bc9 100644 --- a/PWGEM/PhotonMeson/Tasks/pcmQC.cxx +++ b/PWGEM/PhotonMeson/Tasks/pcmQC.cxx @@ -56,7 +56,7 @@ using MyV0Photon = MyV0Photons::iterator; struct PCMQC { - Configurable fConfigPCMCuts{"cfgPCMCuts", "analysis,wwire_ib,qc,qc_ITSTPC,qc_ITSonly,qc_TPConly,nocut", "Comma separated list of v0 photon cuts"}; + Configurable fConfigPCMCuts{"cfgPCMCuts", "qc,qc_ITSTPC,qc_ITSonly,qc_TPConly,wwire_ib,nocut", "Comma separated list of v0 photon cuts"}; std::vector fPCMCuts; diff --git a/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx b/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx index 99858984092..2dbb484ea57 100644 --- a/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx +++ b/PWGEM/PhotonMeson/Tasks/pcmQCMC.cxx @@ -57,8 +57,10 @@ using MyV0Photon = MyV0Photons::iterator; struct PCMQCMC { using MyMCV0Legs = soa::Join; - Configurable fConfigPCMCuts{"cfgPCMCuts", "analysis,qc,nocut", "Comma separated list of v0 photon cuts"}; - Configurable maxY{"maxY", 0.9, "maximum rapidity for generated particles"}; + Configurable fConfigPCMCuts{"cfgPCMCuts", "qc,qc_ITSTPC,qc_ITSonly,qc_TPConly,wwire_ib,nocut", "Comma separated list of v0 photon cuts"}; + Configurable maxY{"maxY", 0.9f, "maximum rapidity for generated particles"}; + Configurable maxRgen{"maxRgen", 100.f, "maximum radius for generated particles"}; + Configurable margin_z_mc{"margin_z_mc", 7.0, "margin for z cut in cm for MC"}; std::vector fPCMCuts; @@ -183,6 +185,7 @@ struct PCMQCMC { auto mcphoton = mcparticles.iteratorAt(photonid); float rxy_rec = sqrt(v0.vx() * v0.vx() + v0.vy() * v0.vy()); float rxy_mc = sqrt(posmc.vx() * posmc.vx() + posmc.vy() * posmc.vy()); + float eta_cp = std::atanh(v0.vz() / sqrt(pow(v0.vx(), 2) + pow(v0.vy(), 2) + pow(v0.vz(), 2))); o2::aod::emphotonhistograms::FillHistClass(list_v0_cut, "", v0); if (IsPhysicalPrimary(mcphoton.emreducedmcevent(), mcphoton, mcparticles)) { @@ -197,6 +200,10 @@ struct PCMQCMC { reinterpret_cast(fMainList->FindObject("V0")->FindObject(cut.GetName())->FindObject("hPtGen_DeltaEta"))->Fill(mcphoton.pt(), v0.eta() - mcphoton.eta()); reinterpret_cast(fMainList->FindObject("V0")->FindObject(cut.GetName())->FindObject("hPtGen_DeltaPhi"))->Fill(mcphoton.pt(), v0.phi() - mcphoton.phi()); + reinterpret_cast(fMainList->FindObject("V0")->FindObject(cut.GetName())->FindObject("hEtaRec_DeltaPtOverPtGen"))->Fill(eta_cp, (v0.pt() - mcphoton.pt()) / mcphoton.pt()); + reinterpret_cast(fMainList->FindObject("V0")->FindObject(cut.GetName())->FindObject("hEtaRec_DeltaEta"))->Fill(eta_cp, v0.eta() - mcphoton.eta()); + reinterpret_cast(fMainList->FindObject("V0")->FindObject(cut.GetName())->FindObject("hEtaRec_DeltaPhi"))->Fill(eta_cp, v0.phi() - mcphoton.phi()); + } else if (IsFromWD(mcphoton.emreducedmcevent(), mcphoton, mcparticles)) { reinterpret_cast(fMainList->FindObject("V0")->FindObject(cut.GetName())->FindObject("hPt_Photon_FromWD"))->Fill(v0.pt()); reinterpret_cast(fMainList->FindObject("V0")->FindObject(cut.GetName())->FindObject("hEtaPhi_Photon_FromWD"))->Fill(v0.phi(), v0.eta()); @@ -225,6 +232,9 @@ struct PCMQCMC { reinterpret_cast(fMainList->FindObject("V0Leg")->FindObject(cut.GetName())->FindObject("hPtGen_DeltaPtOverPtGen"))->Fill(mcleg.pt(), (leg.pt() - mcleg.pt()) / mcleg.pt()); reinterpret_cast(fMainList->FindObject("V0Leg")->FindObject(cut.GetName())->FindObject("hPtGen_DeltaEta"))->Fill(mcleg.pt(), leg.eta() - mcleg.eta()); reinterpret_cast(fMainList->FindObject("V0Leg")->FindObject(cut.GetName())->FindObject("hPtGen_DeltaPhi"))->Fill(mcleg.pt(), leg.phi() - mcleg.phi()); + reinterpret_cast(fMainList->FindObject("V0Leg")->FindObject(cut.GetName())->FindObject("hEtaRec_DeltaPtOverPtGen"))->Fill(eta_cp, (leg.pt() - mcleg.pt()) / mcleg.pt()); + reinterpret_cast(fMainList->FindObject("V0Leg")->FindObject(cut.GetName())->FindObject("hEtaRec_DeltaEta"))->Fill(eta_cp, leg.eta() - mcleg.eta()); + reinterpret_cast(fMainList->FindObject("V0Leg")->FindObject(cut.GetName())->FindObject("hEtaRec_DeltaPhi"))->Fill(eta_cp, leg.phi() - mcleg.phi()); } } } // end of v0 loop @@ -271,9 +281,40 @@ struct PCMQCMC { reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hPt_Photon"))->Fill(mctrack.pt()); reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hY_Photon"))->Fill(mctrack.y()); reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hPhi_Photon"))->Fill(mctrack.phi()); + + bool is_ele_fromPC = false; + bool is_pos_fromPC = false; + auto daughtersIds = mctrack.daughtersIds(); // always size = 2. first and last index. one should run loop from the first index to the last index. + for (auto& daughterId : daughtersIds) { + if (daughterId < 0) { + continue; + } + auto daughter = mcparticles.iteratorAt(daughterId); // always electron and positron + float rxy_gen_e = sqrt(pow(daughter.vx(), 2) + pow(daughter.vy(), 2)); + if (rxy_gen_e > maxRgen || rxy_gen_e < abs(daughter.vz()) * TMath::Tan(2 * TMath::ATan(TMath::Exp(-maxY))) - margin_z_mc) { + continue; + } + + if (daughter.pdgCode() == 11) { // electron from photon conversion + is_ele_fromPC = true; + } else if (daughter.pdgCode() == -11) { // positron from photon conversion + is_pos_fromPC = true; + } + } // end of daughter loop + if (is_ele_fromPC && is_pos_fromPC) { // ele and pos from photon conversion + reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hPt_ConvertedPhoton"))->Fill(mctrack.pt()); + reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hY_ConvertedPhoton"))->Fill(mctrack.y()); + reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hPhi_ConvertedPhoton"))->Fill(mctrack.phi()); + + auto daughter = mcparticles.iteratorAt(daughtersIds[0]); // choose ele or pos. + float rxy_gen_e = sqrt(pow(daughter.vx(), 2) + pow(daughter.vy(), 2)); + reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hPhotonRZ"))->Fill(daughter.vz(), rxy_gen_e); + reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hPhotonRxy"))->Fill(daughter.vx(), daughter.vy()); + reinterpret_cast(fMainList->FindObject("Generated")->FindObject("hPhotonPhivsRxy"))->Fill(daughter.phi(), rxy_gen_e); + } } - } - } + } // end of mctrack loop per collision + } // end of collision loop } void processDummy(MyCollisions const& collisions) diff --git a/PWGEM/PhotonMeson/Utils/MCUtilities.h b/PWGEM/PhotonMeson/Utils/MCUtilities.h index 26e5bdb80f5..9eab29bda5c 100644 --- a/PWGEM/PhotonMeson/Utils/MCUtilities.h +++ b/PWGEM/PhotonMeson/Utils/MCUtilities.h @@ -50,6 +50,11 @@ bool IsPhysicalPrimary(TCollision const& mccollision, TTrack const& mctrack, TMC } if (mp.has_mothers()) { motherid = mp.mothersIds()[0]; // first mother index + auto mp_tmp = mcTracks.iteratorAt(motherid); + int pdg_mother_tmp = mp_tmp.pdgCode(); + if (pdg_mother_tmp == pdg_mother) { // strange protection. mother of 111 is 111. observed in LHC23k6d on 25.January.2024 + return false; + } } else { motherid = -999; } diff --git a/PWGEM/PhotonMeson/Utils/PCMUtilities.h b/PWGEM/PhotonMeson/Utils/PCMUtilities.h index 3493abb6434..389eb79ed0f 100644 --- a/PWGEM/PhotonMeson/Utils/PCMUtilities.h +++ b/PWGEM/PhotonMeson/Utils/PCMUtilities.h @@ -76,13 +76,13 @@ void Vtx_recalculation(o2::base::Propagator* prop, T1 lTrackPos, T2 lTrackNeg, f // I think this calculation gets the closest point on the track to the conversion point // This alpha is a different alpha than the usual alpha and I think it is the angle between X axis and conversion point - Double_t alphaPos = TMath::Pi() + TMath::ATan2(-(xyz[1] - helixPos.yC), -(xyz[0] - helixPos.xC)); - Double_t alphaNeg = TMath::Pi() + TMath::ATan2(-(xyz[1] - helixNeg.yC), -(xyz[0] - helixNeg.xC)); + float alphaPos = TMath::Pi() + TMath::ATan2(-(xyz[1] - helixPos.yC), -(xyz[0] - helixPos.xC)); + float alphaNeg = TMath::Pi() + TMath::ATan2(-(xyz[1] - helixNeg.yC), -(xyz[0] - helixNeg.xC)); - Double_t vertexXPos = helixPos.xC + helixPos.rC * TMath::Cos(alphaPos); - Double_t vertexYPos = helixPos.yC + helixPos.rC * TMath::Sin(alphaPos); - Double_t vertexXNeg = helixNeg.xC + helixNeg.rC * TMath::Cos(alphaNeg); - Double_t vertexYNeg = helixNeg.yC + helixNeg.rC * TMath::Sin(alphaNeg); + float vertexXPos = helixPos.xC + helixPos.rC * TMath::Cos(alphaPos); + float vertexYPos = helixPos.yC + helixPos.rC * TMath::Sin(alphaPos); + float vertexXNeg = helixNeg.xC + helixNeg.rC * TMath::Cos(alphaNeg); + float vertexYNeg = helixNeg.yC + helixNeg.rC * TMath::Sin(alphaNeg); TVector2 vertexPos(vertexXPos, vertexYPos); TVector2 vertexNeg(vertexXNeg, vertexYNeg); @@ -173,7 +173,18 @@ float getPhivPair(float pxpos, float pypos, float pzpos, float pxneg, float pyne float wy = uz * vx - ux * vz; // by construction, (wx,wy,wz) must be a unit vector. Measure angle between (wx,wy,wz) and (ax,ay,0). // The angle between them should be small if the pair is conversion. This function then returns values close to pi! - return TMath::ACos(wx * ax + wy * ay); // phiv in [0,pi] //cosPhiV = wx * ax + wy * ay; + auto clipToPM1 = [](float x) { return x < -1.f ? -1.f : (x > 1.f ? 1.f : x); }; + + // if(!std::isfinite(std::acos(wx * ax + wy * ay))){ + // LOGF(info, "pos_x_ele[0] = %f, pos_x_ele[1] = %f, pos_x_ele[2] = %f", pos_x_ele[0], pos_x_ele[1], pos_x_ele[2]); + // LOGF(info, "ux = %f, uy = %f, uz = %f", ux, uy, uz); + // LOGF(info, "ax = %f, ay = %f", ax, ay); + // LOGF(info, "wx = %f, wy = %f", wx, wy); + // LOGF(info, "wx * ax + wy * ay = %f", wx * ax + wy * ay); + // LOGF(info, "std::acos(wx * ax + wy * ay) = %f", std::acos(clipToPM1(wx * ax + wy * ay))); + // } + + return std::acos(clipToPM1(wx * ax + wy * ay)); // phiv in [0,pi] //cosPhiV = wx * ax + wy * ay; } //_______________________________________________________________________ float getPsiPair(float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) @@ -196,9 +207,10 @@ float getPsiPair(float pxpos, float pypos, float pzpos, float pxneg, float pyneg //_______________________________________________________________________ float getOpeningAngle(float pxpos, float pypos, float pzpos, float pxneg, float pyneg, float pzneg) { + auto clipToPM1 = [](float x) { return x < -1.f ? -1.f : (x > 1.f ? 1.f : x); }; float ptot2 = RecoDecay::p2(pxpos, pypos, pzpos) * RecoDecay::p2(pxneg, pyneg, pzneg); float argcos = RecoDecay::dotProd(std::array{pxpos, pypos, pzpos}, std::array{pxneg, pyneg, pzneg}) / std::sqrt(ptot2); - return std::acos(argcos); + return std::acos(clipToPM1(argcos)); } //_______________________________________________________________________ #endif // PWGEM_PHOTONMESON_UTILS_PCMUTILITIES_H_ diff --git a/PWGEM/PhotonMeson/Utils/PairUtilities.h b/PWGEM/PhotonMeson/Utils/PairUtilities.h index c4c62546e17..39b41bfd655 100644 --- a/PWGEM/PhotonMeson/Utils/PairUtilities.h +++ b/PWGEM/PhotonMeson/Utils/PairUtilities.h @@ -29,7 +29,8 @@ enum PairType { kPCMDalitzEE = 5, kPCMDalitzMuMu = 6, kPHOSEMC = 7, - kPCMPCMibw = 8, + kDalitzEEDalitzEE = 8, + kNpair, }; template diff --git a/PWGEM/Tasks/phosCalibration.cxx b/PWGEM/Tasks/phosCalibration.cxx index 8e21dd79561..9c63becbf3e 100644 --- a/PWGEM/Tasks/phosCalibration.cxx +++ b/PWGEM/Tasks/phosCalibration.cxx @@ -73,8 +73,9 @@ struct phosCalibration { Configurable mMaxCellTimeMain{"maxCellTimeMain", 100.e-9, "Max. cell time of main bunch selection"}; Configurable mMixedEvents{"mixedEvents", 10, "number of events to mix"}; Configurable mSkipL1phase{"skipL1phase", false, "do not correct L1 phase from CCDB"}; - Configurable mBadMapPath{"badmapPath", "alien:///alice/cern.ch/user/p/prsnko/Calib/BadMap/snapshot.root", "path to BadMap snapshot"}; - Configurable mCalibPath{"calibPath", "alien:///alice/cern.ch/user/p/prsnko/Calib/CalibParams/snapshot.root", "path to Calibration snapshot"}; + Configurable mBadMapPath{"badmapPath", "PHS/Calib/BadMap", "path to BadMap snapshot"}; + Configurable mCalibPath{"calibPath", "PHS/Calib/CalibParams", "path to Calibration snapshot"}; + Configurable mL1PhasePath{"L1phasePath", "PHS/Calib/L1phase", "path to L1phase snapshot"}; Service ccdb; @@ -90,10 +91,6 @@ struct phosCalibration { std::vector event; int mL1 = 0; - // calibration will be set on first processing - std::unique_ptr badMap; // = ccdb->get("PHS/Calib/BadMap"); - std::unique_ptr calibParams; // = ccdb->get("PHS/Calib/CalibParams"); - /// \brief Create output histograms void init(o2::framework::InitContext const&) { @@ -151,7 +148,10 @@ struct phosCalibration { // clusterize // Fill clusters histograms - if (bcs.begin() == bcs.end()) { + int64_t timestamp = 0; + if (bcs.begin() != bcs.end()) { + timestamp = bcs.begin().timestamp(); // timestamp for CCDB object retrieval + } else { return; } @@ -160,30 +160,22 @@ struct phosCalibration { clusterizer->initialize(); } - if (!badMap) { - LOG(info) << "Reading BadMap from: " << mBadMapPath.value; - TFile* fBadMap = TFile::Open(mBadMapPath.value.data()); - if (fBadMap == nullptr) { // probably, TGrid not connected yet? - TGrid::Connect("alien"); - fBadMap = TFile::Open(mBadMapPath.value.data()); - } - o2::phos::BadChannelsMap* bm1 = (o2::phos::BadChannelsMap*)fBadMap->Get("ccdb_object"); - badMap.reset(bm1); - fBadMap->Close(); - clusterizer->setBadMap(badMap.get()); - LOG(info) << "Read bad map"; + const o2::phos::BadChannelsMap* badMap = ccdb->getForTimeStamp(mBadMapPath, timestamp); + const o2::phos::CalibParams* calibParams = ccdb->getForTimeStamp(mCalibPath, timestamp); + + if (badMap) { + clusterizer->setBadMap(badMap); + } else { + LOG(fatal) << "Can not get PHOS Bad Map"; } - if (!calibParams) { - LOG(info) << "Reading Calibration from: " << mCalibPath.value; - TFile* fCalib = TFile::Open(mCalibPath.value.data()); - o2::phos::CalibParams* calib1 = (o2::phos::CalibParams*)fCalib->Get("ccdb_object"); - calibParams.reset(calib1); - fCalib->Close(); - clusterizer->setCalibration(calibParams.get()); - LOG(info) << "Read calibration"; + if (calibParams) { + clusterizer->setCalibration(calibParams); + } else { + LOG(fatal) << "Can not get PHOS calibration"; } + if (!mSkipL1phase && mL1 == 0) { // should be read, but not read yet - const std::vector* vec = ccdb->getForTimeStamp>("PHS/Calib/L1phase", bcs.begin().timestamp()); + const std::vector* vec = ccdb->getForTimeStamp>(mL1PhasePath, timestamp); if (vec) { clusterizer->setL1phase((*vec)[0]); mL1 = (*vec)[0]; diff --git a/PWGHF/Core/HfMlResponseLcToPKPi.h b/PWGHF/Core/HfMlResponseLcToPKPi.h new file mode 100644 index 00000000000..31686ed3479 --- /dev/null +++ b/PWGHF/Core/HfMlResponseLcToPKPi.h @@ -0,0 +1,226 @@ +// 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 HfMlResponseLcToPKPi.h +/// \brief Class to compute the ML response for Lc+ → p K- π+ analysis selections +/// \author Grazia Luparello + +#ifndef PWGHF_CORE_HFMLRESPONSELCTOPKPI_H_ +#define PWGHF_CORE_HFMLRESPONSELCTOPKPI_H_ + +#include + +#include "PWGHF/Core/HfMlResponse.h" + +// Fill the map of available input features +// the key is the feature's name (std::string) +// the value is the corresponding value in EnumInputFeatures +#define FILL_MAP_LCTOPKPI(FEATURE) \ + { \ +#FEATURE, static_cast < uint8_t>(InputFeaturesLcToPKPi::FEATURE) \ + } + +// Check if the index of mCachedIndices (index associated to a FEATURE) +// matches the entry in EnumInputFeatures associated to this FEATURE +// if so, the inputFeatures vector is filled with the FEATURE's value +// by calling the corresponding GETTER from OBJECT +#define CHECK_AND_FILL_VEC_LCTOPKPI_FULL(OBJECT, FEATURE, GETTER) \ + case static_cast(InputFeaturesLcToPKPi::FEATURE): { \ + inputFeatures.emplace_back(OBJECT.GETTER()); \ + break; \ + } + +// Specific case of CHECK_AND_FILL_VEC_LCTOPKPI_FULL(OBJECT, FEATURE, GETTER) +// where OBJECT is named candidate and FEATURE = GETTER +#define CHECK_AND_FILL_VEC_LCTOPKPI(GETTER) \ + case static_cast(InputFeaturesLcToPKPi::GETTER): { \ + inputFeatures.emplace_back(candidate.GETTER()); \ + break; \ + } + +// Variation of CHECK_AND_FILL_VEC_LCTOPKPI_FULL(OBJECT, FEATURE, GETTER) +// where GETTER is a method of hfHelper +#define CHECK_AND_FILL_VEC_LCTOPKPI_HFHELPER(OBJECT, FEATURE, GETTER) \ + case static_cast(InputFeaturesLcToPKPi::FEATURE): { \ + inputFeatures.emplace_back(hfHelper.GETTER(OBJECT)); \ + break; \ + } + +namespace o2::analysis +{ +enum class InputFeaturesLcToPKPi : uint8_t { + ptProng0 = 0, + ptProng1, + ptProng2, + impactParameterXY0, + impactParameterXY1, + impactParameterXY2, + decayLength, + decayLengthXY, + decayLengthXYNormalised, + cpa, + cpaXY, + tpcNSigmaP0, // 0 + tpcNSigmaKa0, // 0 + tpcNSigmaPi0, // 0 + tpcNSigmaP1, // 1 + tpcNSigmaKa1, // 1 + tpcNSigmaPi1, // 1 + tpcNSigmaP2, // 2 + tpcNSigmaKa2, // 2 + tpcNSigmaPi2, // 2 + tofNSigmaP0, // + tofNSigmaKa0, // + tofNSigmaPi0, // + tofNSigmaP1, + tofNSigmaKa1, + tofNSigmaPi1, + tofNSigmaP2, + tofNSigmaKa2, + tofNSigmaPi2, + tpcTofNSigmaPi0, + tpcTofNSigmaPi1, + tpcTofNSigmaPi2, + tpcTofNSigmaKa0, + tpcTofNSigmaKa1, + tpcTofNSigmaKa2, + tpcTofNSigmaPr0, + tpcTofNSigmaPr1, + tpcTofNSigmaPr2 +}; + +template +class HfMlResponseLcToPKPi : public HfMlResponse +{ + public: + /// Default constructor + HfMlResponseLcToPKPi() = default; + /// Default destructor + virtual ~HfMlResponseLcToPKPi() = default; + + /// Method to get the input features vector needed for ML inference + /// \param candidate is the Lc candidate + /// \param prong0 is the candidate's prong0 + /// \param prong1 is the candidate's prong1 + /// \param prong2 is the candidate's prong2 + /// \return inputFeatures vector + template + std::vector getInputFeatures(T1 const& candidate, + T2 const& prong0, T2 const& prong1, T2 const& prong2) + { + std::vector inputFeatures; + + for (const auto& idx : MlResponse::mCachedIndices) { + switch (idx) { + CHECK_AND_FILL_VEC_LCTOPKPI(ptProng0); + CHECK_AND_FILL_VEC_LCTOPKPI(ptProng1); + CHECK_AND_FILL_VEC_LCTOPKPI(ptProng2); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, impactParameterXY0, impactParameter0); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, impactParameterXY1, impactParameter1); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(candidate, impactParameterXY2, impactParameter2); + CHECK_AND_FILL_VEC_LCTOPKPI(decayLength); + CHECK_AND_FILL_VEC_LCTOPKPI(decayLengthXY); + CHECK_AND_FILL_VEC_LCTOPKPI(decayLengthXYNormalised); + CHECK_AND_FILL_VEC_LCTOPKPI(cpa); + CHECK_AND_FILL_VEC_LCTOPKPI(cpaXY); + // TPC PID variables + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong0, tpcNSigmaP0, tpcNSigmaPr); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong0, tpcNSigmaKa0, tpcNSigmaKa); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong0, tpcNSigmaPi0, tpcNSigmaPi); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong1, tpcNSigmaP1, tpcNSigmaPr); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong1, tpcNSigmaKa1, tpcNSigmaKa); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong1, tpcNSigmaPi1, tpcNSigmaPi); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong2, tpcNSigmaP2, tpcNSigmaPr); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong2, tpcNSigmaKa2, tpcNSigmaKa); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong2, tpcNSigmaPi2, tpcNSigmaPi); + // TOF PID variables + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong0, tofNSigmaP0, tofNSigmaPr); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong0, tofNSigmaKa0, tofNSigmaKa); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong0, tofNSigmaPi0, tofNSigmaPi); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong1, tofNSigmaP1, tofNSigmaPr); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong1, tofNSigmaKa1, tofNSigmaKa); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong1, tofNSigmaPi1, tofNSigmaPi); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong2, tofNSigmaP2, tofNSigmaPr); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong2, tofNSigmaKa2, tofNSigmaKa); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong2, tofNSigmaPi2, tofNSigmaPi); + // Combined PID variables + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong0, tpcTofNSigmaPi0, tpcTofNSigmaPi); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong1, tpcTofNSigmaPi1, tpcTofNSigmaPi); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong2, tpcTofNSigmaPi2, tpcTofNSigmaPi); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong0, tpcTofNSigmaKa0, tpcTofNSigmaKa); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong1, tpcTofNSigmaKa1, tpcTofNSigmaKa); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong2, tpcTofNSigmaKa2, tpcTofNSigmaKa); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong0, tpcTofNSigmaPr0, tpcTofNSigmaPr); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong1, tpcTofNSigmaPr1, tpcTofNSigmaPr); + CHECK_AND_FILL_VEC_LCTOPKPI_FULL(prong2, tpcTofNSigmaPr2, tpcTofNSigmaPr); + } + } + + return inputFeatures; + } + + protected: + /// Method to fill the map of available input features + void setAvailableInputFeatures() + { + MlResponse::mAvailableInputFeatures = { + FILL_MAP_LCTOPKPI(ptProng0), + FILL_MAP_LCTOPKPI(ptProng1), + FILL_MAP_LCTOPKPI(ptProng2), + FILL_MAP_LCTOPKPI(impactParameterXY0), + FILL_MAP_LCTOPKPI(impactParameterXY1), + FILL_MAP_LCTOPKPI(impactParameterXY2), + FILL_MAP_LCTOPKPI(decayLength), + FILL_MAP_LCTOPKPI(decayLengthXY), + FILL_MAP_LCTOPKPI(decayLengthXYNormalised), + FILL_MAP_LCTOPKPI(cpa), + FILL_MAP_LCTOPKPI(cpaXY), + // TPC PID variables + FILL_MAP_LCTOPKPI(tpcNSigmaP0), + FILL_MAP_LCTOPKPI(tpcNSigmaKa0), + FILL_MAP_LCTOPKPI(tpcNSigmaPi0), + FILL_MAP_LCTOPKPI(tpcNSigmaP1), + FILL_MAP_LCTOPKPI(tpcNSigmaKa1), + FILL_MAP_LCTOPKPI(tpcNSigmaPi1), + FILL_MAP_LCTOPKPI(tpcNSigmaP2), + FILL_MAP_LCTOPKPI(tpcNSigmaKa2), + FILL_MAP_LCTOPKPI(tpcNSigmaPi2), + // TOF PID variables + FILL_MAP_LCTOPKPI(tofNSigmaP0), + FILL_MAP_LCTOPKPI(tofNSigmaKa0), + FILL_MAP_LCTOPKPI(tofNSigmaPi0), + FILL_MAP_LCTOPKPI(tofNSigmaP1), + FILL_MAP_LCTOPKPI(tofNSigmaKa1), + FILL_MAP_LCTOPKPI(tofNSigmaPi1), + FILL_MAP_LCTOPKPI(tofNSigmaP2), + FILL_MAP_LCTOPKPI(tofNSigmaKa2), + FILL_MAP_LCTOPKPI(tofNSigmaPi2), + // Combined PID variables + FILL_MAP_LCTOPKPI(tpcTofNSigmaPi0), + FILL_MAP_LCTOPKPI(tpcTofNSigmaPi1), + FILL_MAP_LCTOPKPI(tpcTofNSigmaPi2), + FILL_MAP_LCTOPKPI(tpcTofNSigmaKa0), + FILL_MAP_LCTOPKPI(tpcTofNSigmaKa1), + FILL_MAP_LCTOPKPI(tpcTofNSigmaKa2), + FILL_MAP_LCTOPKPI(tpcTofNSigmaPr0), + FILL_MAP_LCTOPKPI(tpcTofNSigmaPr1), + FILL_MAP_LCTOPKPI(tpcTofNSigmaPr2)}; + } +}; + +} // namespace o2::analysis + +#undef FILL_MAP_LCTOPKPI +#undef CHECK_AND_FILL_VEC_LCTOPKPI_FULL +#undef CHECK_AND_FILL_VEC_LCTOPKPI +#undef CHECK_AND_FILL_VEC_LCTOPKPI_HFHELPER + +#endif // PWGHF_CORE_HFMLRESPONSELCTOPKPI_H_ diff --git a/PWGHF/Core/SelectorCuts.h b/PWGHF/Core/SelectorCuts.h index cfeeeb8dcbb..27aab472530 100644 --- a/PWGHF/Core/SelectorCuts.h +++ b/PWGHF/Core/SelectorCuts.h @@ -356,11 +356,13 @@ static const std::vector labelsCutVar = {"m", "DCA", "cos theta*", namespace hf_cuts_dstar_to_d0_pi { -static constexpr int nBinsPt = 10; +static constexpr int nBinsPt = 25; static constexpr int nCutVars = 8; // default values for the pT bin edges (can be used to configure histogram axis) // offset by 1 from the bin numbers in cuts array constexpr double binsPt[nBinsPt + 1] = { + 0., + 0.5, 1.0, 1.5, 2.0, @@ -371,7 +373,20 @@ constexpr double binsPt[nBinsPt + 1] = { 4.5, 5.0, 5.5, - 6.0}; + 6.0, + 6.5, + 7.0, + 7.5, + 8.0, + 9.0, + 10.0, + 12.0, + 16.0, + 20.0, + 24.0, + 36.0, + 50.0, + 100.0}; auto vecBinsPt = std::vector{binsPt, binsPt + nBinsPt + 1}; // row labels @@ -385,22 +400,52 @@ static const std::vector labelsPt = { "pT bin 6", "pT bin 7", "pT bin 8", - "pT bin 9"}; + "pT bin 9", + "pT bin 10", + "pT bin 11", + "pT bin 12", + "pT bin 13", + "pT bin 14", + "pT bin 15", + "pT bin 16", + "pT bin 17", + "pT bin 18", + "pT bin 19", + "pT bin 20", + "pT bin 21", + "pT bin 22", + "pT bin 23", + "pT bin 24"}; // column label static const std::vector labelsCutVar = {"ptSoftPiMin", "ptSoftPiMax", "d0SoftPi", "d0SoftPiNormalised", "deltaMInvDstar", "chi2PCA", "d0Prong0Normalised", "d0Prong1Normalised"}; // default values for the cuts -constexpr double cuts[nBinsPt][nCutVars] = {{0.05, 0.3, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}, - {0.05, 0.3, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}, - {0.05, 0.4, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}, - {0.05, 0.4, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}, - {0.05, 0.6, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}, - {0.05, 0.6, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}, - {0.05, 0.6, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}, - {0.05, 100, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}, - {0.05, 100, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}, - {0.05, 100, 0.1, 0.5, 0.2, 300.0, 0.5, 0.5}}; +constexpr double cuts[nBinsPt][nCutVars] = {{0.05, 0.2, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 0.2, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 0.3, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 0.3, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 0.4, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 0.4, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 0.6, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 0.6, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 0.6, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 100, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 100, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 100, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 100, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 100, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 100, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 100, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 100, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 100, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 100, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 100, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 100, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 100, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 100, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 100, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}, + {0.05, 100, 0.1, 1000.0, 0.2, 300.0, 0.0, 0.0}}; } // namespace hf_cuts_dstar_to_d0_pi namespace hf_cuts_lc_to_p_k_pi diff --git a/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx b/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx index 0f312fa0c44..f6055279c35 100644 --- a/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx +++ b/PWGHF/D2H/TableProducer/candidateSelectorB0ToDPiReduced.cxx @@ -37,7 +37,7 @@ struct HfCandidateSelectorB0ToDPiReduced { Configurable ptCandMin{"ptCandMin", 0., "Lower bound of candidate pT"}; Configurable ptCandMax{"ptCandMax", 50., "Upper bound of candidate pT"}; // Enable PID - Configurable usePid{"usePid", true, "Switch for PID selection at track level"}; + Configurable usePionPid{"usePionPid", 1, "Switch for PID selection for the bachelor pion (0: none, 1: TPC or TOF, 2: TPC and TOF)"}; Configurable acceptPIDNotApplicable{"acceptPIDNotApplicable", true, "Switch to accept Status::NotApplicable [(NotApplicable for one detector) and (NotApplicable or Conditional for the other)] in PID selection"}; // TPC PID Configurable ptPidTpcMin{"ptPidTpcMin", 0.15, "Lower bound of track pT for TPC PID"}; @@ -58,8 +58,6 @@ struct HfCandidateSelectorB0ToDPiReduced { // QA switch Configurable activateQA{"activateQA", false, "Flag to enable QA histogram"}; - // check if selectionFlagD (defined in dataCreatorDplusPiReduced.cxx) and usePid configurables are in sync - bool selectionFlagDAndUsePidInSync = true; // variable that will store the value of selectionFlagD (defined in dataCreatorDplusPiReduced.cxx) int mySelectionFlagD = -1; @@ -77,7 +75,11 @@ struct HfCandidateSelectorB0ToDPiReduced { LOGP(fatal, "Only one process function for data should be enabled at a time."); } - if (usePid) { + if (usePionPid < 0 || usePionPid > 2) { + LOGP(fatal, "Invalid PID option in configurable, please set 0 (no PID), 1 (TPC or TOF), or 2 (TPC and TOF)"); + } + + if (usePionPid) { selectorPion.setRangePtTpc(ptPidTpcMin, ptPidTpcMax); selectorPion.setRangeNSigmaTpc(-nSigmaTpcMax, nSigmaTpcMax); selectorPion.setRangeNSigmaTpcCondTof(-nSigmaTpcCombinedMax, nSigmaTpcCombinedMax); @@ -114,15 +116,6 @@ struct HfCandidateSelectorB0ToDPiReduced { // get DplusPi creator configurable for (const auto& config : configs) { mySelectionFlagD = config.mySelectionFlagD(); - - if (usePid && !TESTBIT(mySelectionFlagD, SelectionStep::RecoPID)) { - selectionFlagDAndUsePidInSync = false; - LOG(warning) << "PID selections required on B0 daughters (usePid=true) but no PID selections on D candidates were required a priori (selectionFlagD<7). Set selectionFlagD=7 in hf-candidate-creator-b0"; - } - if (!usePid && TESTBIT(mySelectionFlagD, SelectionStep::RecoPID)) { - selectionFlagDAndUsePidInSync = false; - LOG(warning) << "No PID selections required on B0 daughters (usePid=false) but PID selections on D candidates were required a priori (selectionFlagD=7). Set selectionFlagD<7 in hf-candidate-creator-b0"; - } } for (const auto& hfCandB0 : hfCandsB0) { @@ -163,15 +156,15 @@ struct HfCandidateSelectorB0ToDPiReduced { registry.fill(HIST("hSelections"), 2 + SelectionStep::RecoTopol, ptCandB0); } - // checking if selectionFlagD and usePid are in sync - if (!selectionFlagDAndUsePidInSync) { - hfSelB0ToDPiCandidate(statusB0ToDPi); - continue; - } // track-level PID selection - if (usePid) { + if (usePionPid) { auto trackPi = hfCandB0.template prong1_as(); - int pidTrackPi = selectorPion.statusTpcAndTof(trackPi); + int pidTrackPi{TrackSelectorPID::Status::NotApplicable}; + if (usePionPid == 1) { + pidTrackPi = selectorPion.statusTpcOrTof(trackPi); + } else { + pidTrackPi = selectorPion.statusTpcAndTof(trackPi); + } if (!hfHelper.selectionB0ToDPiPid(pidTrackPi, acceptPIDNotApplicable.value)) { // LOGF(info, "B0 candidate selection failed at PID selection"); hfSelB0ToDPiCandidate(statusB0ToDPi); diff --git a/PWGHF/D2H/Tasks/CMakeLists.txt b/PWGHF/D2H/Tasks/CMakeLists.txt index 6a5c13a2cf3..08a62450afa 100644 --- a/PWGHF/D2H/Tasks/CMakeLists.txt +++ b/PWGHF/D2H/Tasks/CMakeLists.txt @@ -87,4 +87,9 @@ o2physics_add_dpl_workflow(task-xicc o2physics_add_dpl_workflow(task-flow-charm-hadrons SOURCES taskFlowCharmHadrons.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(task-charm-polarisation + SOURCES taskCharmPolarisation.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGHF/D2H/Tasks/taskB0Reduced.cxx b/PWGHF/D2H/Tasks/taskB0Reduced.cxx index afc37574248..d9b5f31be32 100644 --- a/PWGHF/D2H/Tasks/taskB0Reduced.cxx +++ b/PWGHF/D2H/Tasks/taskB0Reduced.cxx @@ -97,8 +97,8 @@ struct HfTaskB0Reduced { Configurable selectionFlagB0{"selectionFlagB0", 1, "Selection Flag for B0"}; Configurable yCandGenMax{"yCandGenMax", 0.5, "max. gen particle rapidity"}; Configurable yCandRecoMax{"yCandRecoMax", 0.8, "max. cand. rapidity"}; - Configurable etaTrackMax{"etaTrackMax", 0.8, "max. track pseudo-rapidity"}; - Configurable ptTrackMin{"ptTrackMin", 0.1, "min. track transverse momentum"}; + Configurable etaTrackMax{"etaTrackMax", 0.8, "max. track pseudo-rapidity for acceptance calculation"}; + Configurable ptTrackMin{"ptTrackMin", 0.1, "min. track transverse momentum for acceptance calculation"}; Configurable fillHistograms{"fillHistograms", true, "Flag to enable histogram filling"}; Configurable fillSparses{"fillSparses", false, "Flag to enable sparse filling"}; Configurable fillTree{"fillTree", false, "Flag to enable tree filling"}; diff --git a/PWGHF/D2H/Tasks/taskCharmPolarisation.cxx b/PWGHF/D2H/Tasks/taskCharmPolarisation.cxx new file mode 100644 index 00000000000..5ab14980cee --- /dev/null +++ b/PWGHF/D2H/Tasks/taskCharmPolarisation.cxx @@ -0,0 +1,269 @@ +// 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 taskCharmPolarisation.cxx +/// \brief Analysis task for non-scalar charm hadron polarisation +/// +/// \author F. Grosa (CERN) fabrizio.grosa@cern.ch +/// \author S. Kundu (CERN) sourav.kundu@cern.ch +/// \author M. Faggin (CERN) mattia.faggin@cern.ch + +#include "TRandom3.h" +#include "Math/Vector3D.h" +#include "Math/Vector4D.h" +#include "Math/GenVector/Boost.h" + +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +// #include "Common/Core/EventPlaneHelper.h" +// #include "Common/DataModel/Qvectors.h" + +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" + +using namespace o2; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; + +namespace o2::aod +{ +namespace charm_polarisation +{ +enum DecayChannel : uint8_t { + DstarToDzeroPi = 0, + LcToPKPi, + LcToPK0S +}; +enum MassHyposLcToPKPi : uint8_t { + PKPi = 0, + PiKP, + NMassHypoLcToPKPi +}; +} // namespace charm_polarisation +} // namespace o2::aod + +struct TaskPolarisationCharmHadrons { + using CandDstarWSelFlag = soa::Join; + using CandLcToPKPiWSelFlag = soa::Join; + + float massPi{0.f}; + float massProton{0.f}; + float massDstar{0.f}; + float massLc{0.f}; + + uint8_t nMassHypos{0u}; + + Configurable selectionFlagDstarToD0Pi{"selectionFlagDstarToD0Pi", true, "Selection Flag for D* decay to D0 Pi"}; + Configurable selectionFlagLcToPKPi{"selectionFlagLcToPKPi", 1, "Selection Flag for Lc decay to P K Pi"}; + + ConfigurableAxis thnAxisInvMass{"thnAxisInvMass", {200, 0.139, 0.179}, "#it{M} (GeV/#it{c}^{2})"}; + ConfigurableAxis thnAxisPt{"thnAxisPt", {100, 0., 100.}, "#it{p}_{T} (GeV/#it{c})"}; + ConfigurableAxis thnAxisPz{"thnAxisPz", {100, -50., 50.}, "#it{p}_{z} (GeV/#it{c})"}; + ConfigurableAxis thnAxisY{"thnAxisY", {20, -1., 1.}, "#it{y}"}; + ConfigurableAxis thnAxisCosThetaStarHelicity{"thnAxisCosThetaStarHelicity", {20, -1., 1.}, "cos(#vartheta_{helicity})"}; + ConfigurableAxis thnAxisCosThetaStarProduction{"thnAxisCosThetaStarProduction", {20, -1., 1.}, "cos(#vartheta_{production})"}; + ConfigurableAxis thnAxisCosThetaStarRandom{"thnAxisCosThetaStarRandom", {20, -1., 1.}, "cos(#vartheta_{random})"}; + ConfigurableAxis thnAxisCosThetaStarBeam{"thnAxisCosThetaStarBeam", {20, -1., 1.}, "cos(#vartheta_{beam})"}; + ConfigurableAxis thnConfigAxisMlBkg{"thnConfigAxisMlBkg", {100, 0., 1.}, "ML bkg"}; + ConfigurableAxis thnConfigAxisMlPrompt{"thnConfigAxisMlPrompt", {100, 0., 1.}, "ML prompt"}; + ConfigurableAxis thnConfigAxisMlNonPrompt{"thnConfigAxisMlNonPrompt", {100, 0., 1.}, "ML non-prompt"}; + // ConfigurableAxis thnAxisCent{"thnAxisCent", {102, -1., 101.}, "centrality (%)"}; + + Filter filterSelectDstarCandidates = aod::hf_sel_candidate_dstar::isSelDstarToD0Pi == selectionFlagDstarToD0Pi; + Filter filterSelectLcToPKPiCandidates = (aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlagLcToPKPi) || (aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlagLcToPKPi); + + HfHelper hfHelper; + HistogramRegistry registry{"registry", {}}; + + void init(InitContext&) + { + std::array processes = {doprocessDstar, doprocessDstarWithMl, doprocessLcToPKPi, doprocessLcToPKPiWithMl}; + const int nProcesses = std::accumulate(processes.begin(), processes.end(), 0); + if (nProcesses > 1) { + LOGP(fatal, "Only one process function should be enabled at a time, please check your configuration"); + } else if (nProcesses == 0) { + LOGP(fatal, "No process function enabled"); + } + + massPi = o2::constants::physics::MassPiPlus; + massProton = o2::constants::physics::MassProton; + massDstar = o2::constants::physics::MassDStar; + massLc = o2::constants::physics::MassLambdaCPlus; + + if (doprocessDstarWithMl || doprocessLcToPKPiWithMl) { + registry.add("hSparseCharmPolarisation", "THn for polarisation studies", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisPz, thnAxisY, thnAxisCosThetaStarHelicity, thnAxisCosThetaStarProduction, thnAxisCosThetaStarBeam, thnAxisCosThetaStarRandom, thnConfigAxisMlBkg, thnConfigAxisMlPrompt, thnConfigAxisMlNonPrompt}); + } else { + registry.add("hSparseCharmPolarisation", "THn for polarisation studies", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisPz, thnAxisY, thnAxisCosThetaStarHelicity, thnAxisCosThetaStarProduction, thnAxisCosThetaStarBeam, thnAxisCosThetaStarRandom}); + } + + // inv. mass hypothesis to loop over + // e.g.: Lc->pKpi has the ambiguity pKpi vs. piKp + if (doprocessLcToPKPi || doprocessLcToPKPiWithMl) { + nMassHypos = charm_polarisation::MassHyposLcToPKPi::NMassHypoLcToPKPi; + } else { + // D*, Lc->pK0s + nMassHypos = 1; + } + + }; // end init + + /// \param candidates are the selected candidates + template + void runPolarisationAnalysis(Cand const& candidate) + { + + // loop over mass hypotheses + for (uint8_t iMass = 0u; iMass < nMassHypos; iMass++) { + + // variable definition + float pxDau{-1000.}, pyDau{-1000.}, pzDau{-1000.}; + float pxCharmHad{-1000.}, pyCharmHad{-1000.}, pzCharmHad{-1000.}; + float massDau{0.}, invMassCharmHad{0.}, invMassCharmHadForSparse{0.}; + float rapidity{-999.}; + std::array outputMl{-1., -1., -1.}; + + if constexpr (channel == charm_polarisation::DecayChannel::DstarToDzeroPi) { + // Dstar analysis + // polarization measured from the soft-pion daughter (*) + + pxDau = candidate.pxSoftPi(); + pyDau = candidate.pySoftPi(); + pzDau = candidate.pzSoftPi(); + pxCharmHad = candidate.pxDstar(); + pyCharmHad = candidate.pyDstar(); + pzCharmHad = candidate.pzDstar(); + massDau = massPi; // (*) + invMassCharmHad = (candidate.signSoftPi() > 0) ? candidate.invMassDstar() : candidate.invMassAntiDstar(); + invMassCharmHadForSparse = (candidate.signSoftPi() > 0) ? (invMassCharmHad - candidate.invMassD0()) : (invMassCharmHad - candidate.invMassD0Bar()); // different for D* + rapidity = candidate.y(massDstar); + if constexpr (withMl) { + outputMl[0] = -1.; // not yet implemented in the selector + outputMl[1] = -1.; // not yet implemented in the selector + outputMl[2] = -1.; // not yet implemented in the selector + } + } else if constexpr (channel == charm_polarisation::DecayChannel::LcToPKPi) { + // Lc->pKpi analysis + // polarization measured from the proton daughter (*) + + if (iMass == charm_polarisation::MassHyposLcToPKPi::PKPi && candidate.isSelLcToPKPi() >= selectionFlagLcToPKPi) { + // reconstructed as pKpi + pxDau = candidate.pxProng0(); + pyDau = candidate.pyProng0(); + pzDau = candidate.pzProng0(); + invMassCharmHadForSparse = hfHelper.invMassLcToPKPi(candidate); + if constexpr (withMl) { + if (candidate.mlProbLcToPKPi().size() == 3) { + // protect from empty vectors + // the BDT output score might be empty if no preselections were enabled (selectionFlag null) + outputMl[0] = candidate.mlProbLcToPKPi()[0]; + outputMl[1] = candidate.mlProbLcToPKPi()[1]; + outputMl[2] = candidate.mlProbLcToPKPi()[2]; + } + } + } else if (iMass == charm_polarisation::MassHyposLcToPKPi::PiKP && candidate.isSelLcToPiKP() >= selectionFlagLcToPKPi) { + // reconstructed as piKp + pxDau = candidate.pxProng2(); + pyDau = candidate.pyProng2(); + pzDau = candidate.pzProng2(); + invMassCharmHadForSparse = hfHelper.invMassLcToPiKP(candidate); + if constexpr (withMl) { + if (candidate.mlProbLcToPiKP().size() == 3) { + // protect from empty vectors + // the BDT output score might be empty if no preselections were enabled (selectionFlag null) + outputMl[0] = candidate.mlProbLcToPiKP()[0]; + outputMl[1] = candidate.mlProbLcToPiKP()[1]; + outputMl[2] = candidate.mlProbLcToPiKP()[2]; + } + } + } + + // NB: no need to check cases in which candidate.isSelLcToPKPi() and candidate.isSelLcToPiKP() are both false, because they are rejected already by the Filter + + // hypothesis-independent variables + pxCharmHad = candidate.px(); + pyCharmHad = candidate.py(); + pzCharmHad = candidate.pz(); + massDau = massProton; // (*) + rapidity = candidate.y(massLc); + + } // Lc->pKpi + + float phiRandom = gRandom->Uniform(0., constants::math::TwoPI); + float thetaRandom = gRandom->Uniform(0., constants::math::PI); + ROOT::Math::PxPyPzMVector fourVecDau = ROOT::Math::PxPyPzMVector(pxDau, pyDau, pzDau, massDau); + ROOT::Math::PxPyPzMVector fourVecMother = ROOT::Math::PxPyPzMVector(pxCharmHad, pyCharmHad, pzCharmHad, invMassCharmHad); + ROOT::Math::Boost boost{fourVecMother.BoostToCM()}; + ROOT::Math::PxPyPzMVector fourVecDauCM = boost(fourVecDau); + ROOT::Math::XYZVector threeVecDauCM = fourVecDauCM.Vect(); + + ROOT::Math::XYZVector randomVec = ROOT::Math::XYZVector(std::sin(thetaRandom) * std::cos(phiRandom), std::sin(thetaRandom) * std::sin(phiRandom), std::cos(thetaRandom)); + ROOT::Math::XYZVector beamVec = ROOT::Math::XYZVector(0., 0., 1.); + ROOT::Math::XYZVector helicityVec = fourVecMother.Vect(); + ROOT::Math::XYZVector normalVec = ROOT::Math::XYZVector(pyCharmHad, -pxCharmHad, 0.); + + float cosThetaStarHelicity = helicityVec.Dot(threeVecDauCM) / std::sqrt(threeVecDauCM.Mag2()) / std::sqrt(helicityVec.Mag2()); + float cosThetaStarProduction = normalVec.Dot(threeVecDauCM) / std::sqrt(threeVecDauCM.Mag2()) / std::sqrt(normalVec.Mag2()); + float cosThetaStarBeam = beamVec.Dot(threeVecDauCM) / std::sqrt(threeVecDauCM.Mag2()); + float cosThetaStarRandom = randomVec.Dot(threeVecDauCM) / std::sqrt(threeVecDauCM.Mag2()); + + if constexpr (withMl) { + registry.fill(HIST("hSparseCharmPolarisation"), invMassCharmHadForSparse, candidate.pt(), pzCharmHad, rapidity, cosThetaStarHelicity, cosThetaStarProduction, cosThetaStarBeam, cosThetaStarRandom, outputMl[0], outputMl[1], outputMl[2]); + } else { + registry.fill(HIST("hSparseCharmPolarisation"), invMassCharmHadForSparse, candidate.pt(), pzCharmHad, rapidity, cosThetaStarHelicity, cosThetaStarProduction, cosThetaStarBeam, cosThetaStarRandom); + } + } /// end loop over mass hypotheses + } + + ///////////////////////// + // Dstar analysis /// + ///////////////////////// + + // Dstar with rectangular cuts + void processDstar(soa::Filtered::iterator const& dstarCandidate) + { + runPolarisationAnalysis(dstarCandidate); + } + PROCESS_SWITCH(TaskPolarisationCharmHadrons, processDstar, "Process Dstar candidates without ML", true); + + // Dstar with ML cuts + void processDstarWithMl(soa::Filtered::iterator const&) + { + // DUMMY + } + PROCESS_SWITCH(TaskPolarisationCharmHadrons, processDstarWithMl, "Process Dstar candidates with ML (DUMMY)", false); + + //////////////////////////// + // Lc->pKpi analysis /// + //////////////////////////// + + // Lc->pKpi with rectangular cuts + void processLcToPKPi(soa::Filtered::iterator const& lcCandidate) + { + runPolarisationAnalysis(lcCandidate); + } + PROCESS_SWITCH(TaskPolarisationCharmHadrons, processLcToPKPi, "Process Lc candidates without ML", false); + + // Lc->pKpi with ML cuts + void processLcToPKPiWithMl(soa::Filtered>::iterator const& lcCandidate) + { + runPolarisationAnalysis(lcCandidate); + } + PROCESS_SWITCH(TaskPolarisationCharmHadrons, processLcToPKPiWithMl, "Process Lc candidates with ML", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/D2H/Tasks/taskD0.cxx b/PWGHF/D2H/Tasks/taskD0.cxx index 3b50057b720..f4488a83d28 100644 --- a/PWGHF/D2H/Tasks/taskD0.cxx +++ b/PWGHF/D2H/Tasks/taskD0.cxx @@ -30,6 +30,15 @@ using namespace o2::framework; using namespace o2::framework::expressions; /// D0 analysis task +namespace +{ +enum CandTypeSel { + SigD0 = 0, // Signal D0 + SigD0bar, // Signal D0bar + ReflectedD0, // Reflected D0 + ReflectedD0bar // Reflected D0bar +}; +} // namespace struct HfTaskD0 { Configurable selectionFlagD0{"selectionFlagD0", 1, "Selection Flag for D0"}; Configurable selectionFlagD0bar{"selectionFlagD0bar", 1, "Selection Flag for D0bar"}; @@ -40,6 +49,8 @@ struct HfTaskD0 { Configurable selectionCand{"selectionCand", 1, "Selection Flag for conj. topol. selected candidates"}; Configurable selectionPid{"selectionPid", 1, "Selection Flag for reco PID candidates"}; Configurable> binsPt{"binsPt", std::vector{hf_cuts_d0_to_pi_k::vecBinsPt}, "pT bin limits"}; + // ML inference + Configurable applyMl{"applyMl", false, "Flag to apply ML selections"}; HfHelper hfHelper; @@ -48,11 +59,23 @@ struct HfTaskD0 { using D0CandidatesKF = soa::Join; using D0CandidatesMcKF = soa::Join; + using D0CandidatesMl = soa::Join; + using D0CandidatesMlMc = soa::Join; + using D0CandidatesMlKF = soa::Join; + using D0CandidatesMlMcKF = soa::Join; + Partition selectedD0Candidates = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlagD0 || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlagD0bar; Partition selectedD0CandidatesKF = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlagD0 || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlagD0bar; Partition selectedD0CandidatesMc = aod::hf_sel_candidate_d0::isRecoHfFlag >= selectionFlagHf; Partition selectedD0CandidatesMcKF = aod::hf_sel_candidate_d0::isRecoHfFlag >= selectionFlagHf; + Partition selectedD0CandidatesMl = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlagD0 || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlagD0bar; + Partition selectedD0CandidatesMlKF = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlagD0 || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlagD0bar; + Partition selectedD0CandidatesMlMc = aod::hf_sel_candidate_d0::isRecoHfFlag >= selectionFlagHf; + Partition selectedD0CandidatesMlMcKF = aod::hf_sel_candidate_d0::isRecoHfFlag >= selectionFlagHf; + + HistogramConfigSpec hTHnBdtScoreVsMassVsPtVsYVsOriginVsD0Type{HistType::kTHnSparseD, {{100, 0.f, 1.f}, {100, 0.f, 1.f}, {120, 1.5848, 2.1848}, {360, 0., 36.}, {100, -5., 5.}, {3, -0.5, 2.5}, {4, -0.5, 3.5}}}; + HistogramRegistry registry{ "registry", {{"hPtCand", "2-prong candidates;candidate #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{360, 0., 36.}}}}, @@ -131,11 +154,11 @@ struct HfTaskD0 { void init(InitContext&) { - std::array doprocess{doprocessDataWithDCAFitterN, doprocessDataWithKFParticle, doprocessMcWithDCAFitterN, doprocessMcWithKFParticle}; + std::array doprocess{doprocessDataWithDCAFitterN, doprocessDataWithKFParticle, doprocessMcWithDCAFitterN, doprocessMcWithKFParticle, doprocessDataWithDCAFitterNMl, doprocessDataWithKFParticleMl, doprocessMcWithDCAFitterNMl, doprocessMcWithKFParticleMl}; if ((std::accumulate(doprocess.begin(), doprocess.end(), 0)) == 0) { LOGP(fatal, "At least one process function should be enabled at a time."); } - if ((doprocessDataWithDCAFitterN || doprocessMcWithDCAFitterN) && (doprocessDataWithKFParticle || doprocessMcWithKFParticle)) { + if ((doprocessDataWithDCAFitterN || doprocessMcWithDCAFitterN || doprocessDataWithDCAFitterNMl || doprocessMcWithDCAFitterNMl) && (doprocessDataWithKFParticle || doprocessMcWithKFParticle || doprocessDataWithKFParticleMl || doprocessMcWithKFParticleMl)) { LOGP(fatal, "DCAFitterN and KFParticle can not be enabled at a time."); } @@ -177,9 +200,14 @@ struct HfTaskD0 { registry.add("hNormalisedDecLengthxyVsPtSig", "2-prong candidates;decay length xy (cm) vs #it{p}_{T} for signal;entries", {HistType::kTH2F, {{800, 0., 40.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); registry.add("hDecLengthVsPtSig", "2-prong candidates;decay length (cm) vs #it{p}_{T} for signal;entries", {HistType::kTH2F, {{800, 0., 4.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); registry.add("hDecLengthxyVsPtSig", "2-prong candidates;decay length xy (cm) vs #it{p}_{T} for signal;entries", {HistType::kTH2F, {{800, 0., 4.}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + + if (applyMl) { + registry.add("hBdtScoreVsMassVsPtVsYVsOriginVsD0Type", "2-prong candidates;BDT score bkg.;BDT score non-prompt;inv. mass (#pi K) (GeV/#it{c}^{2});#it{p}_{T};y;Origin;D0 Type;", hTHnBdtScoreVsMassVsPtVsYVsOriginVsD0Type); + registry.get(HIST("hBdtScoreVsMassVsPtVsYVsOriginVsD0Type"))->Sumw2(); + } } - template + template void processData(CandType const& candidates) { for (const auto& candidate : candidates) { @@ -238,21 +266,42 @@ struct HfTaskD0 { registry.fill(HIST("hCtFinerBinning"), hfHelper.ctD0(candidate), ptCandidate); registry.fill(HIST("hCPAFinerBinning"), candidate.cpa(), ptCandidate); registry.fill(HIST("hCPAXYFinerBinning"), candidate.cpaXY(), ptCandidate); + + if constexpr (applyMl) { + if (candidate.isSelD0() >= selectionFlagD0) { + registry.fill(HIST("hBdtScoreVsMassVsPtVsYVsOriginVsD0Type"), candidate.mlProbD0()[0], candidate.mlProbD0()[1], massD0, ptCandidate, hfHelper.yD0(candidate), 0, SigD0); + } + if (candidate.isSelD0bar() >= selectionFlagD0bar) { + registry.fill(HIST("hBdtScoreVsMassVsPtVsYVsOriginVsD0Type"), candidate.mlProbD0bar()[0], candidate.mlProbD0bar()[1], massD0bar, ptCandidate, hfHelper.yD0(candidate), 0, SigD0bar); + } + } } } void processDataWithDCAFitterN(D0Candidates const&) { - processData(selectedD0Candidates); + processData(selectedD0Candidates); } PROCESS_SWITCH(HfTaskD0, processDataWithDCAFitterN, "process taskD0 with DCAFitterN", true); void processDataWithKFParticle(D0CandidatesKF const&) { - processData(selectedD0CandidatesKF); + processData(selectedD0CandidatesKF); } PROCESS_SWITCH(HfTaskD0, processDataWithKFParticle, "process taskD0 with KFParticle", false); - template + void processDataWithDCAFitterNMl(D0CandidatesMl const&) + { + processData(selectedD0CandidatesMl); + } + PROCESS_SWITCH(HfTaskD0, processDataWithDCAFitterNMl, "process taskD0 with DCAFitterN and ML selections", false); + + void processDataWithKFParticleMl(D0CandidatesMlKF const&) + { + processData(selectedD0CandidatesMlKF); + } + PROCESS_SWITCH(HfTaskD0, processDataWithKFParticleMl, "process taskD0 with KFParticle and ML selections", false); + + template void processMc(CandType const& candidates, soa::Join const& mcParticles, aod::TracksWMc const& tracks) @@ -277,9 +326,9 @@ struct HfTaskD0 { // Get the corresponding MC particle. auto indexMother = RecoDecay::getMother(mcParticles, candidate.template prong0_as().template mcParticle_as>(), o2::constants::physics::Pdg::kD0, true); auto particleMother = mcParticles.rawIteratorAt(indexMother); - auto ptGen = particleMother.pt(); // gen. level pT - auto yGen = RecoDecay::y(std::array{particleMother.px(), particleMother.py(), particleMother.pz()}, o2::constants::physics::MassD0); // gen. level y - registry.fill(HIST("hPtGenSig"), ptGen); // gen. level pT + auto ptGen = particleMother.pt(); // gen. level pT + auto yGen = RecoDecay::y(std::array{particleMother.px(), particleMother.py(), particleMother.pz()}, o2::constants::physics::MassD0); // gen. level y + registry.fill(HIST("hPtGenSig"), ptGen); // gen. level pT auto ptRec = candidate.pt(); auto yRec = hfHelper.yD0(candidate); if (candidate.isRecoHfFlag() >= selectionFlagHf) { @@ -389,6 +438,9 @@ struct HfTaskD0 { registry.fill(HIST("hDecLengthVsPtSig"), declengthCandidate, ptCandidate); registry.fill(HIST("hDecLengthxyVsPtSig"), declengthxyCandidate, ptCandidate); registry.fill(HIST("hMassSigD0"), massD0, ptCandidate, rapidityCandidate); + if constexpr (applyMl) { + registry.fill(HIST("hBdtScoreVsMassVsPtVsYVsOriginVsD0Type"), candidate.mlProbD0()[0], candidate.mlProbD0()[1], massD0, ptCandidate, rapidityCandidate, candidate.originMcRec(), SigD0); + } } else { registry.fill(HIST("hPtProng0Bkg"), ptProng0, rapidityCandidate); registry.fill(HIST("hPtProng1Bkg"), ptProng1, rapidityCandidate); @@ -406,6 +458,9 @@ struct HfTaskD0 { registry.fill(HIST("hMassBkgD0"), massD0, ptCandidate, rapidityCandidate); if (candidate.flagMcMatchRec() == -(1 << aod::hf_cand_2prong::DecayType::D0ToPiK)) { registry.fill(HIST("hMassReflBkgD0"), massD0, ptCandidate, rapidityCandidate); + if constexpr (applyMl) { + registry.fill(HIST("hBdtScoreVsMassVsPtVsYVsOriginVsD0Type"), candidate.mlProbD0()[0], candidate.mlProbD0()[1], massD0, ptCandidate, rapidityCandidate, candidate.originMcRec(), ReflectedD0); + } } } } @@ -413,10 +468,16 @@ struct HfTaskD0 { registry.fill(HIST("hMassSigBkgD0bar"), massD0bar, ptCandidate, rapidityCandidate); if (candidate.flagMcMatchRec() == -(1 << aod::hf_cand_2prong::DecayType::D0ToPiK)) { registry.fill(HIST("hMassSigD0bar"), massD0bar, ptCandidate, rapidityCandidate); + if constexpr (applyMl) { + registry.fill(HIST("hBdtScoreVsMassVsPtVsYVsOriginVsD0Type"), candidate.mlProbD0bar()[0], candidate.mlProbD0bar()[1], massD0bar, ptCandidate, rapidityCandidate, candidate.originMcRec(), SigD0bar); + } } else { registry.fill(HIST("hMassBkgD0bar"), massD0bar, ptCandidate, rapidityCandidate); if (candidate.flagMcMatchRec() == (1 << aod::hf_cand_2prong::DecayType::D0ToPiK)) { registry.fill(HIST("hMassReflBkgD0bar"), massD0bar, ptCandidate, rapidityCandidate); + if constexpr (applyMl) { + registry.fill(HIST("hBdtScoreVsMassVsPtVsYVsOriginVsD0Type"), candidate.mlProbD0bar()[0], candidate.mlProbD0bar()[1], massD0bar, ptCandidate, rapidityCandidate, candidate.originMcRec(), ReflectedD0bar); + } } } } @@ -449,7 +510,7 @@ struct HfTaskD0 { soa::Join const& mcParticles, aod::TracksWMc const& tracks) { - processMc(selectedD0CandidatesMc, mcParticles, tracks); + processMc(selectedD0CandidatesMc, mcParticles, tracks); } PROCESS_SWITCH(HfTaskD0, processMcWithDCAFitterN, "Process MC with DCAFitterN", false); @@ -457,9 +518,25 @@ struct HfTaskD0 { soa::Join const& mcParticles, aod::TracksWMc const& tracks) { - processMc(selectedD0CandidatesMcKF, mcParticles, tracks); + processMc(selectedD0CandidatesMcKF, mcParticles, tracks); } PROCESS_SWITCH(HfTaskD0, processMcWithKFParticle, "Process MC with KFParticle", false); + + void processMcWithDCAFitterNMl(D0CandidatesMlMc const&, + soa::Join const& mcParticles, + aod::TracksWMc const& tracks) + { + processMc(selectedD0CandidatesMlMc, mcParticles, tracks); + } + PROCESS_SWITCH(HfTaskD0, processMcWithDCAFitterNMl, "Process MC with DCAFitterN and ML selection", false); + + void processMcWithKFParticleMl(D0CandidatesMlMcKF const&, + soa::Join const& mcParticles, + aod::TracksWMc const& tracks) + { + processMc(selectedD0CandidatesMlMcKF, mcParticles, tracks); + } + PROCESS_SWITCH(HfTaskD0, processMcWithKFParticleMl, "Process MC with KFParticle and ML selections", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/D2H/Tasks/taskDstarToD0Pi.cxx b/PWGHF/D2H/Tasks/taskDstarToD0Pi.cxx index a2dfd30ae67..96882fe6b99 100644 --- a/PWGHF/D2H/Tasks/taskDstarToD0Pi.cxx +++ b/PWGHF/D2H/Tasks/taskDstarToD0Pi.cxx @@ -45,6 +45,10 @@ struct HfTaskDstarToD0Pi { Partition rowsSelectedCandDstar = aod::hf_sel_candidate_dstar::isSelDstarToD0Pi == selectionFlagDstarToD0Pi; Partition rowsSelectedCandDstarMcRec = aod::hf_sel_candidate_dstar::isRecoD0Flag == selectionFlagHfD0ToPiK; + ConfigurableAxis binningImpactParam{"binningImpactParam", {1000, 0.1, -0.1}, " Bins of Impact Parameter"}; + ConfigurableAxis binningDecayLength{"binningDecayLength", {1000, 0.0, 0.7}, "Bins of Decay Length"}; + ConfigurableAxis binningNormDecayLength{"binningNormDecayLength", {1000, 0.0, 40.0}, "Bins of Normalised Decay Length"}; + HistogramRegistry registry{ "registry", {{"QA/hPtDstar", "Dstar Candidates; Dstar candidate #it{p}_{T} (GeV/#it{c}); entries", {HistType::kTH1F, {{360, 0., 36.}}}}, @@ -59,28 +63,32 @@ struct HfTaskDstarToD0Pi { { auto vecPtBins = (std::vector)ptBins; - registry.add("Yield/hDeltaInvMassDstar2D", "#Delta #it{M}_{inv} D* Candidate; inv. mass (#pi #pi k) (GeV/#it{c}^{2});#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {{100, 0.13, 0.16}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}, true); - registry.add("Yield/hDeltaInvMassDstar1D", "#Delta #it{M}_{inv} D* Candidate; inv. mass (#pi #pi k) (GeV/#it{c}^{2}); entries", {HistType::kTH1F, {{100, 0.13, 0.16}}}, true); + AxisSpec axisImpactParam = {binningImpactParam, "impact parameter (cm)"}; + AxisSpec axisDecayLength = {binningDecayLength, " decay length (cm)"}; + AxisSpec axisNormDecayLength = {binningNormDecayLength, "normalised decay length (cm)"}; + + 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, {{100, 0.13, 0.16}, {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, {{100, 0.13, 0.16}}}, 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, {{120, -20., 100.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hDecayLengthD0", "D0 Candidate; D0 Candidate's decay length (cm); entries", {HistType::kTH2F, {{800, 0., 4.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hDecayLengthXYD0", "D0 Candidate; D0 Candidate's decay length xy (cm); entries", {HistType::kTH2F, {{800, 0., 4.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hDecayLengthNormalisedD0", "D0 Candidates;Do Candidate's normalised decay length (cm); entries", {HistType::kTH2F, {{800, 0., 40.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hDecayLengthXYNormalisedD0", "D0 candidate; D0 Candidate's normalised decay length xy (cm); entries", {HistType::kTH2F, {{800, 0., 40.}, {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, {{200, -1., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hDeltaIPMaxNormalisedD0", "D0 Candidate; D0 Candidate's Norm. Delta IP; entries", {HistType::kTH2F, {{200, -20., 20.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hSqSumProngesImpactParameterD0", "D0 Candidates; Sqr Sum of Impact params of D0 Pronges; enteries ", {HistType::kTH2F, {{100, 0., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hDecayLengthErrorD0", "D0 Candidates; D0 Candidate's Decay Lenth Error (cm); entries", {HistType::kTH2F, {{100, 0., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hDecayLengthXYErrorD0", "D0 Candidates; D0 Candidate's Decay Length Error XY (cm); entries", {HistType::kTH2F, {{100, 0., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hImpactParameterError", "D0 Pronges; Impactparam error of different D0 Pronges (cm); entries", {HistType::kTH2F, {{100, 0., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hd0Prong0", "Prong0; DCAxy of Prong0 (cm); entries", {HistType::kTH2F, {{100, -1., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hd0Prong1", "Prong1; DCAxy of Prong1 (cm); entries", {HistType::kTH2F, {{100, -1., 1.}, {vecPtBins, "#it{p}_{T} (GeV/#it{c})"}}}); - registry.add("QA/hd0ProngSoftPi", "ProngSoftPi; DCAxy of Prong Soft Pi (cm); entries", {HistType::kTH2F, {{100, -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.}}}); @@ -119,8 +127,7 @@ struct HfTaskDstarToD0Pi { 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.}}}); } - void process(aod::Tracks const&, - CandDstarWSelFlag const&) + void process(CandDstarWSelFlag const&) { for (const auto& candDstar : rowsSelectedCandDstar) { auto yDstar = candDstar.y(constants::physics::MassDStar); @@ -140,7 +147,7 @@ struct HfTaskDstarToD0Pi { 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/hSqSumProngesImpactParameterD0"), candDstar.impactParameterProngSqSumD0(), 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()); @@ -155,8 +162,8 @@ struct HfTaskDstarToD0Pi { auto invD0 = candDstar.invMassD0(); auto invD0Bar = candDstar.invMassD0Bar(); - auto prongSoftPi = candDstar.prongPi_as(); - if (prongSoftPi.sign() > 0) { + auto signDstar = candDstar.signSoftPi(); + if (signDstar) { registry.fill(HIST("Yield/hDeltaInvMassDstar2D"), (invDstar - invD0), candDstar.pt()); registry.fill(HIST("Yield/hInvMassD0"), invD0, candDstar.ptD0()); registry.fill(HIST("Yield/hDeltaInvMassDstar1D"), (invDstar - invD0)); @@ -164,7 +171,7 @@ struct HfTaskDstarToD0Pi { // filling pt of two pronges of D0 registry.fill(HIST("QA/hPtProng0D0"), candDstar.ptProng0()); registry.fill(HIST("QA/hPtProng1D0"), candDstar.ptProng1()); - } else if (prongSoftPi.sign() < 0) { + } else if (signDstar) { registry.fill(HIST("Yield/hDeltaInvMassDstar2D"), (invAntiDstar - invD0Bar), candDstar.pt()); registry.fill(HIST("Yield/hInvMassD0"), invD0Bar, candDstar.ptD0()); registry.fill(HIST("Yield/hDeltaInvMassDstar1D"), (invAntiDstar - invD0Bar)); diff --git a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx index 11c3cc2a9b9..577792467d4 100644 --- a/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx +++ b/PWGHF/D2H/Tasks/taskFlowCharmHadrons.cxx @@ -59,12 +59,15 @@ struct HfTaskFlowCharmHadrons { ConfigurableAxis thnConfigAxisPt{"thnConfigAxisPt", {10, 0., 10.}, ""}; ConfigurableAxis thnConfigAxisCent{"thnConfigAxisCent", {10000, 0., 100.}, ""}; ConfigurableAxis thnConfigAxisCosNPhi{"thnConfigAxisCosNPhi", {100, -1., 1.}, ""}; + ConfigurableAxis thnConfigAxisCosDeltaPhi{"thnConfigAxisCosDeltaPhi", {100, -1., 1.}, ""}; ConfigurableAxis thnConfigAxisScalarProd{"thnConfigAxisScalarProd", {100, 0., 1.}, ""}; ConfigurableAxis thnConfigAxisMlOne{"thnConfigAxisMlOne", {1000, 0., 1.}, ""}; ConfigurableAxis thnConfigAxisMlTwo{"thnConfigAxisMlTwo", {1000, 0., 1.}, ""}; - using CandDsData = soa::Filtered>; - using CandDplusData = soa::Filtered>; + using CandDsDatawMl = soa::Filtered>; + using CandDsData = soa::Filtered>; + using CandDplusDatawMl = soa::Filtered>; + using CandDplusData = soa::Filtered>; using CollsWithQvecs = soa::Join; Filter filterSelectDsCandidates = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag || aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; @@ -72,6 +75,8 @@ struct HfTaskFlowCharmHadrons { Partition selectedDsToKKPi = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag; Partition selectedDsToPiKK = aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; + Partition selectedDsToKKPiwMl = aod::hf_sel_candidate_ds::isSelDsToKKPi >= selectionFlag; + Partition selectedDsToPiKKwMl = aod::hf_sel_candidate_ds::isSelDsToPiKK >= selectionFlag; HfHelper hfHelper; EventPlaneHelper epHelper; @@ -84,11 +89,16 @@ struct HfTaskFlowCharmHadrons { const AxisSpec thnAxisPt{thnConfigAxisPt, "#it{p}_{T} (GeV/#it{c})"}; const AxisSpec thnAxisCent{thnConfigAxisCent, "Centrality"}; const AxisSpec thnAxisCosNPhi{thnConfigAxisCosNPhi, Form("cos(%d#varphi)", harmonic.value)}; + const AxisSpec thnAxisCosDeltaPhi{thnConfigAxisCosDeltaPhi, Form("cos(%d(#varphi - #Psi_{sub}))", harmonic.value)}; const AxisSpec thnAxisScalarProd{thnConfigAxisScalarProd, "SP"}; const AxisSpec thnAxisMlOne{thnConfigAxisMlOne, "Bkg score"}; const AxisSpec thnAxisMlTwo{thnConfigAxisMlTwo, "FD score"}; - registry.add("hSparseFlowCharm", "THn for SP", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisCent, thnAxisCosNPhi, thnAxisScalarProd, thnAxisMlOne, thnAxisMlTwo}); + if (storeMl) { + registry.add("hSparseFlowCharm", "THn for SP", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisCent, thnAxisCosNPhi, thnAxisCosDeltaPhi, thnAxisScalarProd, thnAxisMlOne, thnAxisMlTwo}); + } else { + registry.add("hSparseFlowCharm", "THn for SP", HistType::kTHnSparseF, {thnAxisInvMass, thnAxisPt, thnAxisCent, thnAxisCosNPhi, thnAxisCosDeltaPhi, thnAxisScalarProd}); + } registry.add("spReso/hSpResoFT0cFT0a", "hSpResoFT0cFT0a; centrality; Q_{FT0c} #bullet Q_{FT0a}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); registry.add("spReso/hSpResoFT0cFT0m", "hSpResoFT0cFT0m; centrality; Q_{FT0c} #bullet Q_{FT0m}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); registry.add("spReso/hSpResoFT0cFV0m", "hSpResoFT0cFV0m; centrality; Q_{FT0c} #bullet Q_{FV0m}", {HistType::kTH2F, {thnAxisCent, thnAxisScalarProd}}); @@ -136,15 +146,15 @@ struct HfTaskFlowCharmHadrons { float pXtrack0 = cand.pxProng0(); float pYtrack0 = cand.pyProng0(); float pTtrack0 = cand.ptProng0(); - float phiTrack0 = TMath::ATan2(pYtrack0, pXtrack0); + float phiTrack0 = std::atan2(pYtrack0, pXtrack0); float pXtrack1 = cand.pxProng1(); float pYtrack1 = cand.pyProng1(); float pTtrack1 = cand.ptProng1(); - float phiTrack1 = TMath::ATan2(pYtrack1, pXtrack1); + float phiTrack1 = std::atan2(pYtrack1, pXtrack1); float pXtrack2 = cand.pxProng2(); float pYtrack2 = cand.pyProng2(); float pTtrack2 = cand.ptProng2(); - float phiTrack2 = TMath::ATan2(pYtrack2, pXtrack2); + float phiTrack2 = std::atan2(pYtrack2, pXtrack2); tracksQx.push_back(cos(harmonic * phiTrack0) * pTtrack0 / ampl); tracksQy.push_back(sin(harmonic * phiTrack0) * pTtrack0 / ampl); @@ -179,15 +189,19 @@ struct HfTaskFlowCharmHadrons { /// \param sp is the scalar product /// \param evtPlReso is the event plane resolution /// \param outputMl are the ML scores - void fillThn(float mass, - float pt, - float cent, - float cosNPhi, - float cosDeltaPhi, - float sp, - std::vector outputMl) + void fillThn(float& mass, + float& pt, + float& cent, + float& cosNPhi, + float& cosDeltaPhi, + float& sp, + std::vector& outputMl) { - registry.fill(HIST("hSparseFlowCharm"), mass, pt, cent, cosNPhi, cosDeltaPhi, sp, outputMl[0], outputMl[1]); + if (storeMl) { + registry.fill(HIST("hSparseFlowCharm"), mass, pt, cent, cosNPhi, cosDeltaPhi, sp, outputMl[0], outputMl[1]); + } else { + registry.fill(HIST("hSparseFlowCharm"), mass, pt, cent, cosNPhi, cosDeltaPhi, sp); + } } /// Get the centrality @@ -276,18 +290,18 @@ struct HfTaskFlowCharmHadrons { float massCand = 0.; std::vector outputMl = {-999., -999.}; - if constexpr (std::is_same::value) { + if constexpr (std::is_same::value || std::is_same::value) { switch (DecayChannel) { case DecayChannel::DsToKKPi: massCand = hfHelper.invMassDsToKKPi(candidate); - if (storeMl) { + if constexpr (std::is_same::value) { for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) outputMl[iclass] = candidate.mlProbDsToKKPi()[classMl->at(iclass)]; } break; case DecayChannel::DsToPiKK: massCand = hfHelper.invMassDsToPiKK(candidate); - if (storeMl) { + if constexpr (std::is_same::value) { for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) outputMl[iclass] = candidate.mlProbDsToPiKK()[classMl->at(iclass)]; } @@ -295,9 +309,9 @@ struct HfTaskFlowCharmHadrons { default: break; } - } else if constexpr (std::is_same::value) { + } else if constexpr (std::is_same::value || std::is_same::value) { massCand = hfHelper.invMassDplusToPiKPi(candidate); - if (storeMl) { + if constexpr (std::is_same::value) { for (unsigned int iclass = 0; iclass < classMl->size(); iclass++) outputMl[iclass] = candidate.mlProbDplusToPiKPi()[classMl->at(iclass)]; } @@ -306,7 +320,7 @@ struct HfTaskFlowCharmHadrons { float phiCand = candidate.phi(); // 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 == 4 || qvecDetector == 5) { + if (qvecDetector == qvecEstimator::TPCNeg || qvecDetector == qvecEstimator::TPCPos) { float ampl = amplQVec - 3.; std::vector tracksQx = {}; std::vector tracksQy = {}; @@ -317,16 +331,25 @@ struct HfTaskFlowCharmHadrons { } } - float cosNPhi = TMath::Cos(harmonic * phiCand); - float sinNPhi = TMath::Sin(harmonic * phiCand); + float cosNPhi = std::cos(harmonic * phiCand); + float sinNPhi = std::sin(harmonic * phiCand); float scalprodCand = cosNPhi * xQVec + sinNPhi * yQVec; - float cosDeltaPhi = TMath::Cos(harmonic * (phiCand - evtPl)); + float cosDeltaPhi = std::cos(harmonic * (phiCand - evtPl)); fillThn(massCand, ptCand, cent, cosNPhi, cosDeltaPhi, scalprodCand, outputMl); } } - // Ds + // Ds with ML + void processDsMl(CollsWithQvecs::iterator const& collision, + CandDsDatawMl const& candidatesDs) + { + runFlowAnalysis>(collision, selectedDsToKKPiwMl); + runFlowAnalysis>(collision, selectedDsToPiKKwMl); + } + PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDsMl, "Process Ds candidates with ML", false); + + // Ds with rectangular cuts void processDs(CollsWithQvecs::iterator const& collision, CandDsData const& candidatesDs) { @@ -335,7 +358,15 @@ struct HfTaskFlowCharmHadrons { } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDs, "Process Ds candidates", false); - // Dplus + // Dplus with ML + void processDplusMl(CollsWithQvecs::iterator const& collision, + CandDplusDatawMl const& candidatesDplus) + { + runFlowAnalysis(collision, candidatesDplus); + } + PROCESS_SWITCH(HfTaskFlowCharmHadrons, processDplusMl, "Process Dplus candidates with ML", false); + + // Dplus with rectangular cuts void processDplus(CollsWithQvecs::iterator const& collision, CandDplusData const& candidatesDplus) { @@ -383,20 +414,20 @@ struct HfTaskFlowCharmHadrons { float epBPoss = epHelper.GetEventPlane(xQVecBPos, yQVecBPos, harmonic); float epBNegs = epHelper.GetEventPlane(xQVecBNeg, yQVecBNeg, harmonic); - registry.fill(HIST("epReso/hEpResoFT0cFT0a"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0c, epFT0a))); - registry.fill(HIST("epReso/hEpResoFT0cFT0m"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0c, epFT0m))); - registry.fill(HIST("epReso/hEpResoFT0cFV0m"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0c, epFV0a))); - registry.fill(HIST("epReso/hEpResoFT0cTPCpos"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0c, epBPoss))); - registry.fill(HIST("epReso/hEpResoFT0cTPCneg"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0c, epBNegs))); - registry.fill(HIST("epReso/hEpResoFT0aFT0m"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0a, epFT0m))); - registry.fill(HIST("epReso/hEpResoFT0aFV0m"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0a, epFV0a))); - registry.fill(HIST("epReso/hEpResoFT0aTPCpos"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0a, epBPoss))); - registry.fill(HIST("epReso/hEpResoFT0aTPCneg"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0a, epBNegs))); - registry.fill(HIST("epReso/hEpResoFT0mFV0m"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0m, epFV0a))); - registry.fill(HIST("epReso/hEpResoFT0mTPCpos"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0m, epBPoss))); - registry.fill(HIST("epReso/hEpResoFT0mTPCneg"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFT0m, epBNegs))); - registry.fill(HIST("epReso/hEpResoFV0mTPCpos"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFV0a, epBPoss))); - registry.fill(HIST("epReso/hEpResoFV0mTPCneg"), centrality, TMath::Cos(harmonic * getDeltaPsiInRange(epFV0a, epBNegs))); + registry.fill(HIST("epReso/hEpResoFT0cFT0a"), centrality, std::cos(harmonic * getDeltaPsiInRange(epFT0c, epFT0a))); + registry.fill(HIST("epReso/hEpResoFT0cFT0m"), centrality, std::cos(harmonic * getDeltaPsiInRange(epFT0c, epFT0m))); + registry.fill(HIST("epReso/hEpResoFT0cFV0m"), centrality, std::cos(harmonic * getDeltaPsiInRange(epFT0c, epFV0a))); + registry.fill(HIST("epReso/hEpResoFT0cTPCpos"), centrality, std::cos(harmonic * getDeltaPsiInRange(epFT0c, epBPoss))); + registry.fill(HIST("epReso/hEpResoFT0cTPCneg"), centrality, std::cos(harmonic * getDeltaPsiInRange(epFT0c, epBNegs))); + registry.fill(HIST("epReso/hEpResoFT0aFT0m"), centrality, std::cos(harmonic * getDeltaPsiInRange(epFT0a, epFT0m))); + registry.fill(HIST("epReso/hEpResoFT0aFV0m"), centrality, std::cos(harmonic * getDeltaPsiInRange(epFT0a, epFV0a))); + registry.fill(HIST("epReso/hEpResoFT0aTPCpos"), centrality, std::cos(harmonic * getDeltaPsiInRange(epFT0a, epBPoss))); + registry.fill(HIST("epReso/hEpResoFT0aTPCneg"), centrality, std::cos(harmonic * getDeltaPsiInRange(epFT0a, epBNegs))); + registry.fill(HIST("epReso/hEpResoFT0mFV0m"), centrality, std::cos(harmonic * getDeltaPsiInRange(epFT0m, epFV0a))); + registry.fill(HIST("epReso/hEpResoFT0mTPCpos"), centrality, std::cos(harmonic * getDeltaPsiInRange(epFT0m, epBPoss))); + registry.fill(HIST("epReso/hEpResoFT0mTPCneg"), centrality, std::cos(harmonic * getDeltaPsiInRange(epFT0m, epBNegs))); + registry.fill(HIST("epReso/hEpResoFV0mTPCpos"), centrality, std::cos(harmonic * getDeltaPsiInRange(epFV0a, epBPoss))); + registry.fill(HIST("epReso/hEpResoFV0mTPCneg"), centrality, std::cos(harmonic * getDeltaPsiInRange(epFV0a, epBNegs))); } } PROCESS_SWITCH(HfTaskFlowCharmHadrons, processResolution, "Process resolution", false); diff --git a/PWGHF/D2H/Tasks/taskSigmac.cxx b/PWGHF/D2H/Tasks/taskSigmac.cxx index 5ff2edd58f3..6701c87880c 100644 --- a/PWGHF/D2H/Tasks/taskSigmac.cxx +++ b/PWGHF/D2H/Tasks/taskSigmac.cxx @@ -48,6 +48,8 @@ struct HfTaskSigmac { ConfigurableAxis thnConfigAxisCPAXY{"thnConfigAxisCPAXY", {20, 0.8, 1}, ""}; ConfigurableAxis configAxisMassLambdaC{"configAxisMassLambdaC", {600, 1.98, 2.58}, ""}; ConfigurableAxis configAxisDeltaMassSigmaC{"configAxisDeltaMassSigmaC", {200, 0.13, 0.23}, ""}; + ConfigurableAxis thnConfigAxisBdtScoreLcBkg{"thnConfigAxisBdtScoreLcBkg", {100, 0., 1.}, ""}; + ConfigurableAxis thnConfigAxisBdtScoreLcNonPrompt{"thnConfigAxisBdtScoreLcNonPrompt", {100, 0., 1.}, ""}; HfHelper hfHelper; @@ -96,11 +98,39 @@ struct HfTaskSigmac { using RecoLc = soa::Join; + bool isMc; + /// @brief init function, to define the additional analysis histograms /// @param void init(InitContext&) { + /// To be considered in the future, let's keep the possibility to run in MC also with "data-like" mode (just for TH1 objects) + // std::array processes {doprocessDataWoMl, doprocessDataWithMl, doprocessMcWoMl, doprocessMcWithMl}; + // if( std::accumulate(processes.begin(), processes.end(), 0) != 1 ) { + // LOG(fatal) << "One and only one process function must be enabled. Fix it!"; + // } + + // avoid 2 enabled process functions on data + if (doprocessDataWoMl && doprocessDataWithMl) { + LOG(fatal) << "processDataWoMl and processDataWithMl both enabled. Fix it!"; + } + // avoid 2 enabled process functions on MC + if (doprocessMcWoMl && doprocessMcWithMl) { + LOG(fatal) << "processMcWoMl and processMcWithMl both enabled. Fix it!"; + } + // avoid that in data no ML is used while in MC yes, and viceversa + if ((doprocessDataWithMl && doprocessMcWoMl) || (doprocessDataWoMl && doprocessMcWithMl)) { + LOG(fatal) << "process functions with and w/o ML enabled not consistently between data and MC. Fix it! processDataWoMl: " << doprocessDataWoMl << "processDataWithMl: " << doprocessDataWithMl << "processMcWoMl: " << doprocessMcWoMl << "processMcWithMl: " << doprocessMcWithMl; + } + + /// establish if the analysis is done on Data or MC + if (doprocessMcWoMl || doprocessMcWithMl) { + isMc = true; + } else { + isMc = false; + } + const AxisSpec axisDeltaMassSigmaC{configAxisDeltaMassSigmaC, "#it{M}(pK#pi#pi) - #it{M}(pK#pi) (GeV/#it{c}^{2})"}; registry.add("Data/hDeltaMassSc0", "#Sigma_{c}^{0} candidates; #it{M}(pK#pi#pi) - #it{M}(pK#pi) (GeV/#it{c}^{2}); #it{p}_{T}(#Sigma_{c}^{0}) (GeV/#it{c});", {HistType::kTH2D, {axisDeltaMassSigmaC, {36, 0., 36.}}}); registry.add("Data/hDeltaMassScPlusPlus", "#Sigma_{c}^{++} candidates; #it{M}(pK#pi#pi) - #it{M}(pK#pi) (GeV/#it{c}^{2}); #it{p}_{T}(#Sigma_{c}^{++}) (GeV/#it{c});", {HistType::kTH2D, {axisDeltaMassSigmaC, {36, 0., 36.}}}); @@ -108,7 +138,7 @@ struct HfTaskSigmac { registry.add("Data/hDeltaMassLcFromSc0", "#Lambda_{c}^{+} #leftarrow #Sigma_{c}^{0} candidates; #it{M}(pK#pi#pi) - #it{M}(pK#pi) (GeV/#it{c}^{2}); #it{p}_{T}(#Lambda_{c}^{+} #leftarrow #Sigma_{c}^{0}) (GeV/#it{c});", {HistType::kTH2D, {axisDeltaMassSigmaC, {36, 0., 36.}}}); registry.add("Data/hDeltaMassLcFromScPlusPlus", "#Lambda_{c}^{+} #leftarrow #Sigma_{c}^{++} candidates; #it{M}(pK#pi#pi) - #it{M}(pK#pi) (GeV/#it{c}^{2}); #it{p}_{T}(#Lambda_{c}^{+} #leftarrow #Sigma_{c}^{++}) (GeV/#it{c});", {HistType::kTH2D, {axisDeltaMassSigmaC, {36, 0., 36.}}}); registry.add("Data/hDeltaMassLcFromSc0PlusPlus", "#Lambda_{c}^{+} #leftarrow #Sigma_{c}^{0,++} candidates; #it{M}(pK#pi#pi) - #it{M}(pK#pi) (GeV/#it{c}^{2}); #it{p}_{T}(#Lambda_{c}^{+} #leftarrow #Sigma_{c}^{0,++}) (GeV/#it{c});", {HistType::kTH2D, {axisDeltaMassSigmaC, {36, 0., 36.}}}); - if (doprocessMc) { + if (isMc) { ///////////////////// /// Generated /// ///////////////////// @@ -223,8 +253,15 @@ struct HfTaskSigmac { const AxisSpec thnAxisOriginMc{3, -0.5, 2.5, "0: none, 1: prompt, 2: non-prompt"}; const AxisSpec thnAxisChargeSigmaC{3, -0.5, 2.5, "#Sigma_{c}-baryon charge"}; const AxisSpec thnAxisChannel{4, -0.5, 3.5, "0: direct 1,2,3: resonant"}; - registry.add("hnLambdaC", "THn for Lambdac", HistType::kTHnSparseF, {thnAxisPtLambdaC, thnAxisMassLambdaC, thnAxisDecLength, thnAxisDecLengthXY, thnAxisCPA, thnAxisCPAXY, thnAxisOriginMc, thnAxisChannel}); - registry.add("hnSigmaC", "THn for Sigmac", HistType::kTHnSparseF, {thnAxisPtLambdaC, axisDeltaMassSigmaC, thnAxisDecLength, thnAxisDecLengthXY, thnAxisCPA, thnAxisCPAXY, thnAxisOriginMc, thnAxisChannel, thnAxisPtSigmaC, thnAxisChargeSigmaC}); + const AxisSpec thnAxisBdtScoreLcBkg{thnConfigAxisBdtScoreLcBkg, "BDT bkg score (Lc)"}; + const AxisSpec thnAxisBdtScoreLcNonPrompt{thnConfigAxisBdtScoreLcNonPrompt, "BDT non-prompt score (Lc)"}; + if (doprocessDataWithMl || doprocessMcWithMl) { + registry.add("hnLambdaC", "THn for Lambdac", HistType::kTHnSparseF, {thnAxisPtLambdaC, thnAxisMassLambdaC, thnAxisBdtScoreLcBkg, thnAxisBdtScoreLcNonPrompt, thnAxisOriginMc, thnAxisChannel}); + registry.add("hnSigmaC", "THn for Sigmac", HistType::kTHnSparseF, {thnAxisPtLambdaC, axisDeltaMassSigmaC, thnAxisBdtScoreLcBkg, thnAxisBdtScoreLcNonPrompt, thnAxisOriginMc, thnAxisChannel, thnAxisPtSigmaC, thnAxisChargeSigmaC}); + } else { + registry.add("hnLambdaC", "THn for Lambdac", HistType::kTHnSparseF, {thnAxisPtLambdaC, thnAxisMassLambdaC, thnAxisDecLength, thnAxisDecLengthXY, thnAxisCPA, thnAxisCPAXY, thnAxisOriginMc, thnAxisChannel}); + registry.add("hnSigmaC", "THn for Sigmac", HistType::kTHnSparseF, {thnAxisPtLambdaC, axisDeltaMassSigmaC, thnAxisDecLength, thnAxisDecLengthXY, thnAxisCPA, thnAxisCPAXY, thnAxisOriginMc, thnAxisChannel, thnAxisPtSigmaC, thnAxisChargeSigmaC}); + } } }; /// end init @@ -250,12 +287,13 @@ struct HfTaskSigmac { return channel; /// 0: none; 1: pK-π+ only; 2: π+K-p only; 3: both possible } - /// @brief process function to fill the histograms needed in analysis (data) + /// @brief function to fill the histograms needed in analysis (data) /// @param candidatesSc are the reconstructed candidate Σc0,++ /// @param - void process(aod::HfCandSc const& candidatesSc, - RecoLc const& candidatesLc, - aod::Tracks const&) + template + void fillHistosData(aod::HfCandSc const& candidatesSc, + CandsLc const& candidatesLc, + aod::Tracks const&) { /// loop over the candidate Σc0,++ @@ -265,7 +303,7 @@ struct HfTaskSigmac { /// get the candidate Λc+ used to build the candidate Σc0,++ /// and understand which mass hypotheses are possible - const auto& candidateLc = candSc.prongLc_as(); + const auto& candidateLc = candSc.prongLc_as(); // const int iscandidateLcpKpi = (candidateLc.isSelLcToPKPi() >= 1) && candSc.statusSpreadLcMinvPKPiFromPDG(); // Λc+ → pK-π+ and within the requested mass to build the Σc0,++ // const int iscandidateLcpiKp = (candidateLc.isSelLcToPiKP() >= 1) && candSc.statusSpreadLcMinvPiKPFromPDG(); // Λc+ → π+K-p and within the requested mass to build the Σc0,++ const int isCandPKPiPiKP = isDecayToPKPiToPiKP(candidateLc, candSc); @@ -331,9 +369,21 @@ struct HfTaskSigmac { } /// THn for candidate Σc0,++ cut variation if (enableTHn) { - if (!doprocessMc) { + if (!isMc) { /// fill it only if no MC operations are enabled, otherwise fill it in the processMC with the right origin and channel! - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, 0, 0, ptSc, std::abs(chargeSc)); + if constexpr (useMl) { + /// fill with ML information + /// BDT index 0: bkg score; BDT index 2: non-prompt score + std::array outputMl{-1., -1.}; + if (candidateLc.mlProbLcToPKPi().size() > 0) { + outputMl.at(0) = candidateLc.mlProbLcToPKPi()[0]; /// bkg score + outputMl.at(1) = candidateLc.mlProbLcToPKPi()[2]; /// non-prompt score + } + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), 0, 0, ptSc, std::abs(chargeSc)); + } else { + /// fill w/o BDT information + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, 0, 0, ptSc, std::abs(chargeSc)); + } } } } /// end candidate Λc+ → pK-π+ (and charge conjugate) @@ -392,9 +442,21 @@ struct HfTaskSigmac { } /// THn for candidate Σc0,++ cut variation if (enableTHn) { - /// fill it only if no MC operations are enabled, otherwise fill it in the processMC with the right origin and channel! - if (!doprocessMc) { - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, 0, 0, ptSc, std::abs(chargeSc)); + if (!isMc) { + /// fill it only if no MC operations are enabled, otherwise fill it in the processMC with the right origin and channel! + if constexpr (useMl) { + /// fill with ML information + /// BDT index 0: bkg score; BDT index 2: non-prompt score + std::array outputMl{-1., -1.}; + if (candidateLc.mlProbLcToPiKP().size() > 0) { + outputMl.at(0) = candidateLc.mlProbLcToPiKP()[0]; /// bkg score + outputMl.at(1) = candidateLc.mlProbLcToPiKP()[2]; /// non-prompt score + } + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), 0, 0, ptSc, std::abs(chargeSc)); + } else { + /// fill w/o BDT information + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, 0, 0, ptSc, std::abs(chargeSc)); + } } } } /// end candidate Λc+ → π+K-p (and charge conjugate) @@ -403,7 +465,7 @@ struct HfTaskSigmac { /// THn for candidate Λc+ cut variation w/o Σc0,++ mass-window cut if (enableTHn) { /// fill it only if no MC operations are enabled, otherwise fill it in the processMC with the right origin and channel! - if (!doprocessMc) { + if (!isMc) { /// loop over Λc+ candidates w/o Σc0,++ mass-window cut for (const auto& candidateLc : candidatesLc) { double massLc(-1.); @@ -412,27 +474,52 @@ struct HfTaskSigmac { double cpaLc(candidateLc.cpa()), cpaXYLc(candidateLc.cpaXY()); if (candidateLc.isSelLcToPKPi() >= 1) { massLc = hfHelper.invMassLcToPKPi(candidateLc); - registry.get(HIST("hnLambdaC"))->Fill(ptLc, massLc, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, 0, 0); + if constexpr (useMl) { + /// fill with ML information + /// BDT index 0: bkg score; BDT index 2: non-prompt score + std::array outputMl{-1., -1.}; + if (candidateLc.mlProbLcToPKPi().size() > 0) { + outputMl.at(0) = candidateLc.mlProbLcToPKPi()[0]; /// bkg score + outputMl.at(1) = candidateLc.mlProbLcToPKPi()[2]; /// non-prompt score + } + registry.get(HIST("hnLambdaC"))->Fill(ptLc, massLc, outputMl.at(0), outputMl.at(1), 0, 0); + } else { + /// fill w/o BDT information + registry.get(HIST("hnLambdaC"))->Fill(ptLc, massLc, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, 0, 0); + } } if (candidateLc.isSelLcToPiKP() >= 1) { massLc = hfHelper.invMassLcToPiKP(candidateLc); - registry.get(HIST("hnLambdaC"))->Fill(ptLc, massLc, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, 0, 0); + if constexpr (useMl) { + /// fill with ML information + /// BDT index 0: bkg score; BDT index 2: non-prompt score + std::array outputMl{-1., -1.}; + if (candidateLc.mlProbLcToPiKP().size() > 0) { + outputMl.at(0) = candidateLc.mlProbLcToPiKP()[0]; /// bkg score + outputMl.at(1) = candidateLc.mlProbLcToPiKP()[2]; /// non-prompt score + } + registry.get(HIST("hnLambdaC"))->Fill(ptLc, massLc, outputMl.at(0), outputMl.at(1), 0, 0); + } else { + /// fill w/o BDT information + registry.get(HIST("hnLambdaC"))->Fill(ptLc, massLc, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, 0, 0); + } } } } } /// end THn for candidate Λc+ cut variation w/o Σc0,++ mass-window cut - }; /// end process + }; /// end fillHistosData - /// @brief process function to fill the histograms needed in analysis (MC) + /// @brief function to fill the histograms needed in analysis (MC) /// @param candidatesSc are the reconstructed candidate Σc0,++ with MC info /// @param mcParticles are the generated particles with flags wheter they are Σc0,++ or not /// @param - void processMc(soa::Join const& candidatesSc, - soa::Join const& mcParticlesSc, - soa::Join const& mcParticlesLc, - aod::McParticles const& mcParticles, // this establishes the type of particle obtained with the .mcParticle() getter - soa::Join const& candidatesLc, - aod::TracksWMc const&) + template + void fillHistosMc(soa::Join const& candidatesSc, + soa::Join const& mcParticlesSc, + soa::Join const& mcParticlesLc, + aod::McParticles const& mcParticles, // this establishes the type of particle obtained with the .mcParticle() getter + CandsLc const& candidatesLc, + aod::TracksWMc const&) { /// MC generated particles @@ -564,7 +651,7 @@ struct HfTaskSigmac { /// get the candidate Λc+ used to build the Σc0 /// and understand which mass hypotheses are possible - const auto& candidateLc = candSc.prongLc_as>(); + const auto& candidateLc = candSc.prongLc_as(); const int isCandPKPiPiKP = isDecayToPKPiToPiKP(candidateLc, candSc); // candidateLc.flagMcDecayChanRec(); @@ -575,7 +662,7 @@ struct HfTaskSigmac { auto indexMcScRec = RecoDecay::getMother(mcParticles, candSc.prong1_as().mcParticle(), o2::constants::physics::Pdg::kSigmaC0, true); auto particleSc = mcParticles.rawIteratorAt(indexMcScRec); // Get the corresponding MC particle for Lc - auto arrayDaughtersLc = std::array{candidateLc.prong0_as(), candidateLc.prong1_as(), candidateLc.prong2_as()}; + auto arrayDaughtersLc = std::array{candidateLc.template prong0_as(), candidateLc.template prong1_as(), candidateLc.template prong2_as()}; int8_t sign = 0; int indexMcLcRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersLc, o2::constants::physics::Pdg::kLambdaCPlus, std::array{+kProton, -kKPlus, +kPiPlus}, true, &sign, 2); auto particleLc = mcParticles.rawIteratorAt(indexMcLcRec); @@ -596,7 +683,7 @@ struct HfTaskSigmac { auto channel = candidateLc.flagMcDecayChanRec(); /// 0: direct; 1: Λc± → p± K*; 2: Λc± → Δ(1232)±± K∓; 3: Λc± → Λ(1520) π± /// candidate Λc+ → pK-π+ (and charge conjugate) within the range of M(pK-π+) chosen in the Σc0,++ builder - if ((isCandPKPiPiKP == 1 || isCandPKPiPiKP == 3) && std::abs(candidateLc.prong0_as().mcParticle().pdgCode()) == kProton) { + if ((isCandPKPiPiKP == 1 || isCandPKPiPiKP == 3) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kProton) { massSc = hfHelper.invMassScRecoLcToPKPi(candSc, candidateLc); massLc = hfHelper.invMassLcToPKPi(candidateLc); deltaMass = massSc - massLc; @@ -653,12 +740,24 @@ struct HfTaskSigmac { /// THn for candidate Σc0,++ cut variation if (enableTHn) { - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc)); + if constexpr (useMl) { + /// fill with ML information + /// BDT index 0: bkg score; BDT index 2: non-prompt score + std::array outputMl{-1., -1.}; + if (candidateLc.mlProbLcToPKPi().size() > 0) { + outputMl.at(0) = candidateLc.mlProbLcToPKPi()[0]; /// bkg score + outputMl.at(1) = candidateLc.mlProbLcToPKPi()[2]; /// non-prompt score + } + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc)); + } else { + /// fill w/o BDT information + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc)); + } } } /// end candidate Λc+ → pK-π+ (and charge conjugate) /// candidate Λc+ → π+K-p (and charge conjugate) within the range of M(π+K-p) chosen in the Σc0,++ builder - if ((isCandPKPiPiKP == 2 || isCandPKPiPiKP == 3) && std::abs(candidateLc.prong0_as().mcParticle().pdgCode()) == kPiPlus) { + if ((isCandPKPiPiKP == 2 || isCandPKPiPiKP == 3) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kPiPlus) { massSc = hfHelper.invMassScRecoLcToPiKP(candSc, candidateLc); massLc = hfHelper.invMassLcToPiKP(candidateLc); deltaMass = massSc - massLc; @@ -715,7 +814,19 @@ struct HfTaskSigmac { /// THn for candidate Σc0,++ cut variation if (enableTHn) { - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc)); + if constexpr (useMl) { + /// fill with ML information + /// BDT index 0: bkg score; BDT index 2: non-prompt score + std::array outputMl{-1., -1.}; + if (candidateLc.mlProbLcToPiKP().size() > 0) { + outputMl.at(0) = candidateLc.mlProbLcToPiKP()[0]; /// bkg score + outputMl.at(1) = candidateLc.mlProbLcToPiKP()[2]; /// non-prompt score + } + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc)); + } else { + /// fill w/o BDT information + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc)); + } } } /// end candidate Λc+ → π+K-p (and charge conjugate) @@ -726,7 +837,7 @@ struct HfTaskSigmac { auto indexMcScRec = RecoDecay::getMother(mcParticles, candSc.prong1_as().mcParticle(), o2::constants::physics::Pdg::kSigmaCPlusPlus, true); auto particleSc = mcParticles.rawIteratorAt(indexMcScRec); // Get the corresponding MC particle for Lc - auto arrayDaughtersLc = std::array{candidateLc.prong0_as(), candidateLc.prong1_as(), candidateLc.prong2_as()}; + auto arrayDaughtersLc = std::array{candidateLc.template prong0_as(), candidateLc.template prong1_as(), candidateLc.template prong2_as()}; int8_t sign = 0; int indexMcLcRec = RecoDecay::getMatchedMCRec(mcParticles, arrayDaughtersLc, o2::constants::physics::Pdg::kLambdaCPlus, std::array{+kProton, -kKPlus, +kPiPlus}, true, &sign, 2); auto particleLc = mcParticles.rawIteratorAt(indexMcLcRec); @@ -747,7 +858,7 @@ struct HfTaskSigmac { auto channel = candidateLc.flagMcDecayChanRec(); /// 0: direct; 1: Λc± → p± K*; 2: Λc± → Δ(1232)±± K∓; 3: Λc± → Λ(1520) π± /// candidate Λc+ → pK-π+ (and charge conjugate) within the range of M(pK-π+) chosen in the Σc0,++ builder - if ((isCandPKPiPiKP == 1 || isCandPKPiPiKP == 3) && std::abs(candidateLc.prong0_as().mcParticle().pdgCode()) == kProton) { + if ((isCandPKPiPiKP == 1 || isCandPKPiPiKP == 3) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kProton) { massSc = hfHelper.invMassScRecoLcToPKPi(candSc, candidateLc); massLc = hfHelper.invMassLcToPKPi(candidateLc); deltaMass = massSc - massLc; @@ -804,12 +915,24 @@ struct HfTaskSigmac { /// THn for candidate Σc0,++ cut variation if (enableTHn) { - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc)); + if constexpr (useMl) { + /// fill with ML information + /// BDT index 0: bkg score; BDT index 2: non-prompt score + std::array outputMl{-1., -1.}; + if (candidateLc.mlProbLcToPKPi().size() > 0) { + outputMl.at(0) = candidateLc.mlProbLcToPKPi()[0]; /// bkg score + outputMl.at(1) = candidateLc.mlProbLcToPKPi()[2]; /// non-prompt score + } + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc)); + } else { + /// fill w/o BDT information + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc)); + } } } /// end candidate Λc+ → pK-π+ (and charge conjugate) /// candidate Λc+ → π+K-p (and charge conjugate) within the range of M(π+K-p) chosen in the Σc0,++ builder - if ((isCandPKPiPiKP == 2 || isCandPKPiPiKP == 3) && std::abs(candidateLc.prong0_as().mcParticle().pdgCode()) == kPiPlus) { + if ((isCandPKPiPiKP == 2 || isCandPKPiPiKP == 3) && std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()) == kPiPlus) { massSc = hfHelper.invMassScRecoLcToPiKP(candSc, candidateLc); massLc = hfHelper.invMassLcToPiKP(candidateLc); deltaMass = massSc - massLc; @@ -864,7 +987,19 @@ struct HfTaskSigmac { /// THn for candidate Σc0,++ cut variation if (enableTHn) { - registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc)); + if constexpr (useMl) { + /// fill with ML information + /// BDT index 0: bkg score; BDT index 2: non-prompt score + std::array outputMl{-1., -1.}; + if (candidateLc.mlProbLcToPiKP().size() > 0) { + outputMl.at(0) = candidateLc.mlProbLcToPiKP()[0]; /// bkg score + outputMl.at(1) = candidateLc.mlProbLcToPiKP()[2]; /// non-prompt score + } + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, outputMl.at(0), outputMl.at(1), origin, channel, ptSc, std::abs(chargeSc)); + } else { + /// fill w/o BDT information + registry.get(HIST("hnSigmaC"))->Fill(ptLc, deltaMass, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel, ptSc, std::abs(chargeSc)); + } } } /// end candidate Λc+ → π+K-p (and charge conjugate) @@ -886,23 +1021,88 @@ struct HfTaskSigmac { int origin = candidateLc.originMcRec(); auto channel = candidateLc.flagMcDecayChanRec(); /// 0: direct; 1: Λc± → p± K*; 2: Λc± → Δ(1232)±± K∓; 3: Λc± → Λ(1520) π± int pdgAbs = -1; - if (candidateLc.prong0_as().has_mcParticle()) { - pdgAbs = std::abs(candidateLc.prong0_as().mcParticle().pdgCode()); + if (candidateLc.template prong0_as().has_mcParticle()) { + pdgAbs = std::abs(candidateLc.template prong0_as().mcParticle().pdgCode()); } if (candidateLc.isSelLcToPKPi() >= 1 && pdgAbs == kProton) { massLc = hfHelper.invMassLcToPKPi(candidateLc); - registry.get(HIST("hnLambdaC"))->Fill(ptLc, massLc, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel); + if constexpr (useMl) { + /// fill with ML information + /// BDT index 0: bkg score; BDT index 2: non-prompt score + std::array outputMl{-1., -1.}; + if (candidateLc.mlProbLcToPKPi().size() > 0) { + outputMl.at(0) = candidateLc.mlProbLcToPKPi()[0]; /// bkg score + outputMl.at(1) = candidateLc.mlProbLcToPKPi()[2]; /// non-prompt score + } + registry.get(HIST("hnLambdaC"))->Fill(ptLc, massLc, outputMl.at(0), outputMl.at(1), origin, channel); + } else { + /// fill w/o BDT information + registry.get(HIST("hnLambdaC"))->Fill(ptLc, massLc, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel); + } } if (candidateLc.isSelLcToPiKP() >= 1 && pdgAbs == kPiPlus) { massLc = hfHelper.invMassLcToPiKP(candidateLc); - registry.get(HIST("hnLambdaC"))->Fill(ptLc, massLc, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel); + if constexpr (useMl) { + /// fill with ML information + /// BDT index 0: bkg score; BDT index 2: non-prompt score + std::array outputMl{-1., -1.}; + if (candidateLc.mlProbLcToPiKP().size() > 0) { + outputMl.at(0) = candidateLc.mlProbLcToPiKP()[0]; /// bkg score + outputMl.at(1) = candidateLc.mlProbLcToPiKP()[2]; /// non-prompt score + } + registry.get(HIST("hnLambdaC"))->Fill(ptLc, massLc, outputMl.at(0), outputMl.at(1), origin, channel); + } else { + /// fill w/o BDT information + registry.get(HIST("hnLambdaC"))->Fill(ptLc, massLc, decLengthLc, decLengthXYLc, cpaLc, cpaXYLc, origin, channel); + } } } } /// end THn for candidate Λc+ cut variation w/o Σc0,++ mass-window cut - }; /// end processMc - PROCESS_SWITCH(HfTaskSigmac, processMc, "Process MC", false); + }; /// end fillHistosMc + + /// @brief process function to fill the histograms needed in analysis w/o ML information (data) + void processDataWoMl(aod::HfCandSc const& candidatesSc, + RecoLc const& candidatesLc, + aod::Tracks const& tracks) + { + fillHistosData(candidatesSc, candidatesLc, tracks); + } + PROCESS_SWITCH(HfTaskSigmac, processDataWoMl, "Process data w/o ML information on Lc", true); + + /// @brief process function to fill the histograms needed in analysis with ML information (data) + void processDataWithMl(aod::HfCandSc const& candidatesSc, + soa::Join const& candidatesLc, + aod::Tracks const& tracks) + { + fillHistosData(candidatesSc, candidatesLc, tracks); + } + PROCESS_SWITCH(HfTaskSigmac, processDataWithMl, "Process data with ML information on Lc", false); + + /// @brief process function to fill the histograms needed in analysis w/o ML information (MC) + void processMcWoMl(soa::Join const& candidatesSc, + soa::Join const& mcParticlesSc, + soa::Join const& mcParticlesLc, + aod::McParticles const& mcParticles, // this establishes the type of particle obtained with the .mcParticle() getter + soa::Join const& candidatesLc, + aod::TracksWMc const& tracksWithMc) + { + fillHistosMc(candidatesSc, mcParticlesSc, mcParticlesLc, mcParticles, candidatesLc, tracksWithMc); + } + PROCESS_SWITCH(HfTaskSigmac, processMcWoMl, "Process MC w/o ML information on Lc", false); + + /// @brief process function to fill the histograms needed in analysis with ML information (MC) + void processMcWithMl(soa::Join const& candidatesSc, + soa::Join const& mcParticlesSc, + soa::Join const& mcParticlesLc, + aod::McParticles const& mcParticles, // this establishes the type of particle obtained with the .mcParticle() getter + soa::Join const& candidatesLc, + aod::TracksWMc const& tracksWithMc) + { + fillHistosMc(candidatesSc, mcParticlesSc, mcParticlesLc, mcParticles, candidatesLc, tracksWithMc); + } + PROCESS_SWITCH(HfTaskSigmac, processMcWithMl, "Process MC with ML information on Lc", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGHF/DataModel/CandidateReconstructionTables.h b/PWGHF/DataModel/CandidateReconstructionTables.h index 84c1b68171e..873347ac0ec 100644 --- a/PWGHF/DataModel/CandidateReconstructionTables.h +++ b/PWGHF/DataModel/CandidateReconstructionTables.h @@ -152,13 +152,15 @@ DECLARE_SOA_TABLE(HfSelCollision, "AOD", "HFSELCOLLISION", //! namespace hf_sel_track { -DECLARE_SOA_COLUMN(IsSelProng, isSelProng, int); //! -DECLARE_SOA_COLUMN(IsProton, isProton, int8_t); //! +DECLARE_SOA_COLUMN(IsSelProng, isSelProng, uint32_t); //! +DECLARE_SOA_COLUMN(IsProton, isProton, int8_t); //! +DECLARE_SOA_COLUMN(IsPositive, isPositive, bool); //! } // namespace hf_sel_track DECLARE_SOA_TABLE(HfSelTrack, "AOD", "HFSELTRACK", //! hf_sel_track::IsSelProng, - hf_sel_track::IsProton); + hf_sel_track::IsProton, + hf_sel_track::IsPositive); namespace hf_pv_refit_track { @@ -994,7 +996,6 @@ DECLARE_SOA_COLUMN(XDecayVtxV0, xDecayVtxV0, float); DECLARE_SOA_COLUMN(YDecayVtxV0, yDecayVtxV0, float); DECLARE_SOA_COLUMN(ZDecayVtxV0, zDecayVtxV0, float); DECLARE_SOA_COLUMN(SignDecay, signDecay, int8_t); // sign of pi <- xi -DECLARE_SOA_COLUMN(Chi2PCACharmBaryon, chi2PCACharmBaryon, float); DECLARE_SOA_COLUMN(CovVtxCharmBaryon0, covVtxCharmBaryon0, float); DECLARE_SOA_COLUMN(CovVtxCharmBaryon1, covVtxCharmBaryon1, float); DECLARE_SOA_COLUMN(CovVtxCharmBaryon2, covVtxCharmBaryon2, float); @@ -1092,7 +1093,6 @@ DECLARE_SOA_TABLE(HfCandToXiPi, "AOD", "HFCANDTOXIPI", hf_cand_toxipi::XDecayVtxCascade, hf_cand_toxipi::YDecayVtxCascade, hf_cand_toxipi::ZDecayVtxCascade, hf_cand_toxipi::XDecayVtxV0, hf_cand_toxipi::YDecayVtxV0, hf_cand_toxipi::ZDecayVtxV0, hf_cand_toxipi::SignDecay, // charge pi<-cascade (neg -> omegac, pos -> antiomegac) - hf_cand_toxipi::Chi2PCACharmBaryon, hf_cand_toxipi::CovVtxCharmBaryon0, hf_cand_toxipi::CovVtxCharmBaryon1, hf_cand_toxipi::CovVtxCharmBaryon2, hf_cand_toxipi::CovVtxCharmBaryon3, hf_cand_toxipi::CovVtxCharmBaryon4, hf_cand_toxipi::CovVtxCharmBaryon5, hf_cand_toxipi::PxCharmBaryon, hf_cand_toxipi::PyCharmBaryon, hf_cand_toxipi::PzCharmBaryon, hf_cand_toxipi::PxCasc, hf_cand_toxipi::PyCasc, hf_cand_toxipi::PzCasc, @@ -1558,6 +1558,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(NormalisedImpParamSoftPi, normalisedImpParamSoftPi, DECLARE_SOA_COLUMN(PxSoftPi, pxSoftPi, float); DECLARE_SOA_COLUMN(PySoftPi, pySoftPi, float); DECLARE_SOA_COLUMN(PzSoftPi, pzSoftPi, float); +DECLARE_SOA_COLUMN(SignSoftPi, signSoftPi, int8_t); // 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); @@ -1660,6 +1661,7 @@ DECLARE_SOA_TABLE(HfCandDstarBase, "AOD", "HFCANDDSTRBASE", hf_track_index::ProngD0Id, // Index column points to Hf2Prongs table filled by indexSkimcreator // Softpi hf_cand_dstar::PxSoftPi, hf_cand_dstar::PySoftPi, hf_cand_dstar::PzSoftPi, + hf_cand_dstar::SignSoftPi, hf_cand_dstar::ImpParamSoftPi, hf_cand_dstar::ErrorImpParamSoftPi, // Two pronges of D0 hf_cand::PxProng0, hf_cand::PyProng0, hf_cand::PzProng0, @@ -1676,7 +1678,9 @@ DECLARE_SOA_TABLE(HfCandDstarBase, "AOD", "HFCANDDSTRBASE", hf_cand::Y, hf_cand::E, hf_cand_dstar::InvMassDstar, - hf_cand_dstar::InvMassAntiDstar); + hf_cand_dstar::InvMassAntiDstar, + hf_cand_dstar::InvMassD0, + hf_cand_dstar::InvMassD0Bar); // extended table with expression columns that can be used as arguments of dynamic columns DECLARE_SOA_EXTENDED_TABLE_USER(HfCandDstarExt, HfCandDstarBase, "HFCANDDSTREXT", diff --git a/PWGHF/DataModel/CandidateSelectionTables.h b/PWGHF/DataModel/CandidateSelectionTables.h index 2406ab13ec8..29d5e9b72db 100644 --- a/PWGHF/DataModel/CandidateSelectionTables.h +++ b/PWGHF/DataModel/CandidateSelectionTables.h @@ -153,11 +153,15 @@ DECLARE_SOA_TABLE(HfSelDstarToD0Pi, "AOD", "HFSELDSTAR", //! Table stores inform namespace hf_sel_candidate_lc { -DECLARE_SOA_COLUMN(IsSelLcToPKPi, isSelLcToPKPi, int); //! -DECLARE_SOA_COLUMN(IsSelLcToPiKP, isSelLcToPiKP, int); //! +DECLARE_SOA_COLUMN(IsSelLcToPKPi, isSelLcToPKPi, int); //! +DECLARE_SOA_COLUMN(IsSelLcToPiKP, isSelLcToPiKP, int); //! +DECLARE_SOA_COLUMN(MlProbLcToPKPi, mlProbLcToPKPi, std::vector); //! +DECLARE_SOA_COLUMN(MlProbLcToPiKP, mlProbLcToPiKP, std::vector); //! } // namespace hf_sel_candidate_lc DECLARE_SOA_TABLE(HfSelLc, "AOD", "HFSELLC", //! hf_sel_candidate_lc::IsSelLcToPKPi, hf_sel_candidate_lc::IsSelLcToPiKP); +DECLARE_SOA_TABLE(HfMlLcToPKPi, "AOD", "HFMLLc", //! + hf_sel_candidate_lc::MlProbLcToPKPi, hf_sel_candidate_lc::MlProbLcToPiKP); namespace hf_sel_candidate_lc_alice3 { diff --git a/PWGHF/DataModel/DerivedTables.h b/PWGHF/DataModel/DerivedTables.h index eb12c71a257..1f822a79b02 100644 --- a/PWGHF/DataModel/DerivedTables.h +++ b/PWGHF/DataModel/DerivedTables.h @@ -32,7 +32,7 @@ DECLARE_SOA_COLUMN(IsEventReject, isEventReject, int8_t); //! collision rejectio DECLARE_SOA_COLUMN(MultFT0M, multFT0M, float); //! FT0M multiplicity } // namespace hf_coll_base -DECLARE_SOA_TABLE(HfD0CollBases, "AOD1", "HFD0COLLBASE", //! Table with basic collision info +DECLARE_SOA_TABLE(HfD0CollBases, "AOD", "HFD0COLLBASE", //! Table with basic collision info o2::soa::Index<>, collision::NumContrib, hf_coll_base::IsEventReject, @@ -40,7 +40,7 @@ DECLARE_SOA_TABLE(HfD0CollBases, "AOD1", "HFD0COLLBASE", //! Table with basic co using HfD0CollBase = HfD0CollBases::iterator; -DECLARE_SOA_TABLE(StoredHfD0CollBases, "AOD", "HFD0COLLBASE", //! Table with basic collision info (stored version) +DECLARE_SOA_TABLE(StoredHfD0CollBases, "AOD1", "HFD0COLLBASE", //! Table with basic collision info (stored version) o2::soa::Index<>, collision::NumContrib, hf_coll_base::IsEventReject, @@ -49,10 +49,10 @@ DECLARE_SOA_TABLE(StoredHfD0CollBases, "AOD", "HFD0COLLBASE", //! Table with bas using StoredHfD0CollBase = StoredHfD0CollBases::iterator; -DECLARE_SOA_TABLE(HfD0CollIds, "AOD1", "HFD0COLLID", //! Table with global indices for collisions +DECLARE_SOA_TABLE(HfD0CollIds, "AOD", "HFD0COLLID", //! Table with global indices for collisions hf_cand::CollisionId); -DECLARE_SOA_TABLE(StoredHfD0CollIds, "AOD", "HFD0COLLID", //! Table with global indices for collisions (stored version) +DECLARE_SOA_TABLE(StoredHfD0CollIds, "AOD1", "HFD0COLLID", //! Table with global indices for collisions (stored version) hf_cand::CollisionId, soa::Marker<1>); @@ -77,9 +77,36 @@ auto y(TPt pt, TEta eta, TM m) { return std::log((RecoDecay::sqrtSumOfSquares(m, pt * std::cosh(eta)) + pt * std::sinh(eta)) / RecoDecay::sqrtSumOfSquares(m, pt)); } + +template +auto px(TPt pt, TPhi phi) +{ + return pt * std::cos(phi); +} + +template +auto py(TPt pt, TPhi phi) +{ + return pt * std::sin(phi); +} + +template +auto pz(TPt pt, TPhi eta) +{ + return pt * std::sinh(eta); +} + } // namespace functions DECLARE_SOA_DYNAMIC_COLUMN(Y, y, //! D0 rapidity [](float pt, float eta) -> float { return functions::y(pt, eta, o2::constants::physics::MassD0); }); +DECLARE_SOA_DYNAMIC_COLUMN(Px, px, //! D0 px + [](float pt, float phi) -> float { return functions::px(pt, phi); }); +DECLARE_SOA_DYNAMIC_COLUMN(Py, py, //! D0 py + [](float pt, float phi) -> float { return functions::py(pt, phi); }); +DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, //! D0 px + [](float pt, float eta) -> float { return functions::pz(pt, eta); }); +DECLARE_SOA_DYNAMIC_COLUMN(P, p, //! D0 momentum + [](float pt, float eta) -> float { return pt * std::cosh(eta); }); } // namespace hf_cand_base // Candidate properties used for selection @@ -158,30 +185,38 @@ DECLARE_SOA_COLUMN(MlScorePrompt, mlScorePrompt, float); //! ML score DECLARE_SOA_COLUMN(MlScoreNonPrompt, mlScoreNonPrompt, float); //! ML score for non-prompt class } // namespace hf_cand_mc -DECLARE_SOA_TABLE(HfD0Bases, "AOD1", "HFD0BASE", //! Table with basic candidate properties used in the analyses +DECLARE_SOA_TABLE(HfD0Bases, "AOD", "HFD0BASE", //! Table with basic candidate properties used in the analyses o2::soa::Index<>, hf_cand_base::HfD0CollBaseId, hf_cand_base::Pt, hf_cand_base::Eta, hf_cand_base::Phi, hf_cand_base::M, - hf_cand_base::Y); + hf_cand_base::Y, + hf_cand_base::Px, + hf_cand_base::Py, + hf_cand_base::Pz, + hf_cand_base::P); -DECLARE_SOA_TABLE(StoredHfD0Bases, "AOD", "HFD0BASE", //! Table with basic candidate properties used in the analyses (stored version) +DECLARE_SOA_TABLE(StoredHfD0Bases, "AOD1", "HFD0BASE", //! Table with basic candidate properties used in the analyses (stored version) o2::soa::Index<>, - hf_cand_base::StoredHfD0CollBaseId, + hf_cand_base::HfD0CollBaseId, hf_cand_base::Pt, hf_cand_base::Eta, hf_cand_base::Phi, hf_cand_base::M, hf_cand_base::Y, + hf_cand_base::Px, + hf_cand_base::Py, + hf_cand_base::Pz, + hf_cand_base::P, soa::Marker<1>); // candidates for removal: // PxProng0, PyProng0, PzProng0,... (same for 1, 2), we can keep Pt, Eta, Phi instead // XY: CpaXY, DecayLengthXY, ErrorDecayLengthXY // normalised: DecayLengthNormalised, DecayLengthXYNormalised, ImpactParameterNormalised0 -DECLARE_SOA_TABLE(HfD0Pars, "AOD1", "HFD0PAR", //! Table with candidate properties used for selection +DECLARE_SOA_TABLE(HfD0Pars, "AOD", "HFD0PAR", //! Table with candidate properties used for selection hf_cand::Chi2PCA, hf_cand_par::DecayLength, hf_cand_par::DecayLengthXY, @@ -210,7 +245,7 @@ DECLARE_SOA_TABLE(HfD0Pars, "AOD1", "HFD0PAR", //! Table with candidate properti hf_cand_par::MaxNormalisedDeltaIP, hf_cand_par::ImpactParameterProduct); -DECLARE_SOA_TABLE(StoredHfD0Pars, "AOD", "HFD0PAR", //! Table with candidate properties used for selection (stored version) +DECLARE_SOA_TABLE(StoredHfD0Pars, "AOD1", "HFD0PAR", //! Table with candidate properties used for selection (stored version) hf_cand::Chi2PCA, hf_cand_par::DecayLength, hf_cand_par::DecayLengthXY, @@ -240,7 +275,7 @@ DECLARE_SOA_TABLE(StoredHfD0Pars, "AOD", "HFD0PAR", //! Table with candidate pro hf_cand_par::ImpactParameterProduct, soa::Marker<1>); -DECLARE_SOA_TABLE(HfD0ParEs, "AOD1", "HFD0PARE", //! Table with additional candidate properties used for selection +DECLARE_SOA_TABLE(HfD0ParEs, "AOD", "HFD0PARE", //! Table with additional candidate properties used for selection collision::PosX, collision::PosY, collision::PosZ, @@ -264,7 +299,7 @@ DECLARE_SOA_TABLE(HfD0ParEs, "AOD1", "HFD0PARE", //! Table with additional candi hf_cand_par::CosThetaStar, hf_cand_par::Ct); -DECLARE_SOA_TABLE(StoredHfD0ParEs, "AOD", "HFD0PARE", //! Table with additional candidate properties used for selection (stored version) +DECLARE_SOA_TABLE(StoredHfD0ParEs, "AOD1", "HFD0PARE", //! Table with additional candidate properties used for selection (stored version) collision::PosX, collision::PosY, collision::PosZ, @@ -289,43 +324,47 @@ DECLARE_SOA_TABLE(StoredHfD0ParEs, "AOD", "HFD0PARE", //! Table with additional hf_cand_par::Ct, soa::Marker<1>); -DECLARE_SOA_TABLE(HfD0Sels, "AOD1", "HFD0SEL", //! Table with candidate selection flags +DECLARE_SOA_TABLE(HfD0Sels, "AOD", "HFD0SEL", //! Table with candidate selection flags hf_cand_sel::CandidateSelFlag); -DECLARE_SOA_TABLE(StoredHfD0Sels, "AOD", "HFD0SEL", //! Table with candidate selection flags (stored version) +DECLARE_SOA_TABLE(StoredHfD0Sels, "AOD1", "HFD0SEL", //! Table with candidate selection flags (stored version) hf_cand_sel::CandidateSelFlag, soa::Marker<1>); -DECLARE_SOA_TABLE(HfD0Ids, "AOD1", "HFD0ID", //! Table with global indices for candidates +DECLARE_SOA_TABLE(HfD0Ids, "AOD", "HFD0ID", //! Table with global indices for candidates hf_cand::CollisionId, hf_track_index::Prong0Id, hf_track_index::Prong1Id); -DECLARE_SOA_TABLE(StoredHfD0Ids, "AOD", "HFD0ID", //! Table with global indices for candidates (stored version) +DECLARE_SOA_TABLE(StoredHfD0Ids, "AOD1", "HFD0ID", //! Table with global indices for candidates (stored version) hf_cand::CollisionId, hf_track_index::Prong0Id, hf_track_index::Prong1Id, soa::Marker<1>); -DECLARE_SOA_TABLE(HfD0Mcs, "AOD1", "HFD0MC", //! Table with MC candidate info +DECLARE_SOA_TABLE(HfD0Mcs, "AOD", "HFD0MC", //! Table with MC candidate info hf_cand_mc::FlagMcMatchRec, hf_cand_mc::OriginMcRec); -DECLARE_SOA_TABLE(StoredHfD0Mcs, "AOD", "HFD0MC", //! Table with MC candidate info (stored version) +DECLARE_SOA_TABLE(StoredHfD0Mcs, "AOD1", "HFD0MC", //! Table with MC candidate info (stored version) hf_cand_mc::FlagMcMatchRec, hf_cand_mc::OriginMcRec, soa::Marker<1>); -DECLARE_SOA_TABLE(HfD0PBases, "AOD1", "HFD0PBASE", //! Table with MC particle info +DECLARE_SOA_TABLE(HfD0PBases, "AOD", "HFD0PBASE", //! Table with MC particle info o2::soa::Index<>, hf_cand_base::Pt, hf_cand_base::Eta, hf_cand_base::Phi, hf_cand_mc::FlagMcMatchGen, hf_cand_mc::OriginMcGen, - hf_cand_base::Y); + hf_cand_base::Y, + hf_cand_base::Px, + hf_cand_base::Py, + hf_cand_base::Pz, + hf_cand_base::P); -DECLARE_SOA_TABLE(StoredHfD0PBases, "AOD", "HFD0PBASE", //! Table with MC particle info (stored version) +DECLARE_SOA_TABLE(StoredHfD0PBases, "AOD1", "HFD0PBASE", //! Table with MC particle info (stored version) o2::soa::Index<>, hf_cand_base::Pt, hf_cand_base::Eta, @@ -333,13 +372,17 @@ DECLARE_SOA_TABLE(StoredHfD0PBases, "AOD", "HFD0PBASE", //! Table with MC partic hf_cand_mc::FlagMcMatchGen, hf_cand_mc::OriginMcGen, hf_cand_base::Y, + hf_cand_base::Px, + hf_cand_base::Py, + hf_cand_base::Pz, + hf_cand_base::P, soa::Marker<1>); -DECLARE_SOA_TABLE(HfD0PIds, "AOD1", "HFD0PID", //! Table with global indices for MC particles +DECLARE_SOA_TABLE(HfD0PIds, "AOD", "HFD0PID", //! Table with global indices for MC particles hf_cand_base::McCollisionId, hf_cand_base::McParticleId); -DECLARE_SOA_TABLE(StoredHfD0PIds, "AOD", "HFD0PID", //! Table with global indices for MC particles (stored version) +DECLARE_SOA_TABLE(StoredHfD0PIds, "AOD1", "HFD0PID", //! Table with global indices for MC particles (stored version) hf_cand_base::McCollisionId, hf_cand_base::McParticleId, soa::Marker<1>); diff --git a/PWGHF/HFC/DataModel/DMesonPairsTablesTesting.h b/PWGHF/HFC/DataModel/DMesonPairsTablesTesting.h new file mode 100644 index 00000000000..8ed32e50086 --- /dev/null +++ b/PWGHF/HFC/DataModel/DMesonPairsTablesTesting.h @@ -0,0 +1,75 @@ +// 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 DMesonPairsTablesTesting.h +/// \brief D meson pair table definition. +/// \note Temporary code for tests of D0-D0 correlations +/// +/// \author Andrea Tavira García , IJCLab Orsay + +#ifndef PWGHF_HFC_DATAMODEL_DMESONPAIRSTABLESTESTING_H_ +#define PWGHF_HFC_DATAMODEL_DMESONPAIRSTABLESTESTING_H_ + +#include "Framework/AnalysisDataModel.h" + +namespace o2::aod +{ +// definition of columns and tables for D(bar) Meson correlation pair studies +namespace hf_correlation_d_meson_pair_testing +{ +// Kinematic info +DECLARE_SOA_COLUMN(PtCand1, ptCand1, float); //! Transverse momentum of first candidate +DECLARE_SOA_COLUMN(PtCand2, ptCand2, float); //! Transverse momentum of second candidate +DECLARE_SOA_COLUMN(YCand1, yCand1, float); //! Rapidity of first candidate +DECLARE_SOA_COLUMN(YCand2, yCand2, float); //! Rapidity of second candidate +// Invariant mass +DECLARE_SOA_COLUMN(MDCand1, mDCand1, float); //! Invariant mass of first candidate as D +DECLARE_SOA_COLUMN(MDbarCand1, mDbarCand1, float); //! Invariant mass of first candidate as Dbar +DECLARE_SOA_COLUMN(MDCand2, mDCand2, float); //! Invariant mass of second candidate as D +DECLARE_SOA_COLUMN(MDbarCand2, mDbarCand2, float); //! Invariant mass of second candidate as Dbar +DECLARE_SOA_COLUMN(PairType, pairType, uint8_t); //! Bitmap with all pair types (DD, DDbar, etc.) a pair of candidates has passed +// MC info +DECLARE_SOA_COLUMN(Origin1, origin1, uint8_t); //! candidate 1 origin +DECLARE_SOA_COLUMN(Origin2, origin2, uint8_t); //! candidate 2 origin +DECLARE_SOA_COLUMN(MatchedMc1, matchedMc1, uint8_t); //! MC matching of candidate 1 +DECLARE_SOA_COLUMN(MatchedMc2, matchedMc2, uint8_t); //! MC matching of candidate 2 +} // namespace hf_correlation_d_meson_pair_testing + +// Definition of the D meson pair table. Contains the info needed at Data level. +#define DECLARE_DMESON_PAIR_TABLE_TESTING(_pair_type_, _marker_value_, _description_) \ + DECLARE_SOA_TABLE(_pair_type_, "AOD", _description_, o2::soa::Marker<_marker_value_>, \ + hf_correlation_d_meson_pair_testing::PtCand1, \ + hf_correlation_d_meson_pair_testing::PtCand2, \ + hf_correlation_d_meson_pair_testing::YCand1, \ + hf_correlation_d_meson_pair_testing::YCand2, \ + hf_correlation_d_meson_pair_testing::MDCand1, \ + hf_correlation_d_meson_pair_testing::MDbarCand1, \ + hf_correlation_d_meson_pair_testing::MDCand2, \ + hf_correlation_d_meson_pair_testing::MDbarCand2, \ + hf_correlation_d_meson_pair_testing::PairType); +// Definition of the D meson pair table with info at MC level. +#define DECLARE_DMESON_PAIR_MCINFO_TABLE_TESTING(_pair_type_, _marker_value_, _description_) \ + DECLARE_SOA_TABLE(_pair_type_, "AOD", _description_ "MCINFO", o2::soa::Marker<_marker_value_>, \ + hf_correlation_d_meson_pair_testing::Origin1, \ + hf_correlation_d_meson_pair_testing::Origin2, \ + hf_correlation_d_meson_pair_testing::MatchedMc1, \ + hf_correlation_d_meson_pair_testing::MatchedMc2); + +// Creation of tables with D Meson Pairs info +DECLARE_DMESON_PAIR_TABLE_TESTING(D0PairTesting, 1, "D0PAIR"); //! D0 pairs Info +DECLARE_DMESON_PAIR_MCINFO_TABLE_TESTING(D0PairMcInfoTesting, 1, "D0PAIR"); //! D0 pairs MC Rec Info + +DECLARE_DMESON_PAIR_TABLE_TESTING(D0PairMcGenTesting, 2, "D0PAIRGEN"); //! D0 pairs MC Gen Kinematic Info +DECLARE_DMESON_PAIR_MCINFO_TABLE_TESTING(D0PairMcGenInfoTesting, 2, "D0PAIRGEN"); //! D0 pairs MC Gen Info + +} // namespace o2::aod + +#endif // PWGHF_HFC_DATAMODEL_DMESONPAIRSTABLESTESTING_H_ diff --git a/PWGHF/HFC/TableProducer/CMakeLists.txt b/PWGHF/HFC/TableProducer/CMakeLists.txt index 16c61cdcdec..55c39530cd6 100644 --- a/PWGHF/HFC/TableProducer/CMakeLists.txt +++ b/PWGHF/HFC/TableProducer/CMakeLists.txt @@ -29,6 +29,11 @@ o2physics_add_dpl_workflow(correlator-d-meson-pairs PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(correlator-d-meson-pairs-testing + SOURCES correlatorDMesonPairsTesting.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(correlator-dplus-dminus SOURCES correlatorDplusDminus.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGHF/HFC/TableProducer/correlatorD0Hadrons.cxx b/PWGHF/HFC/TableProducer/correlatorD0Hadrons.cxx index 7a2aa274756..da890154128 100644 --- a/PWGHF/HFC/TableProducer/correlatorD0Hadrons.cxx +++ b/PWGHF/HFC/TableProducer/correlatorD0Hadrons.cxx @@ -49,9 +49,9 @@ const double efficiencyDmesonDefault[nPtBinsMassAndEfficiency] = {}; auto vecEfficiencyDmeson = std::vector{efficiencyDmesonDefault, efficiencyDmesonDefault + nPtBinsMassAndEfficiency}; // histogram binning definition -const int massAxisNBins = 120; -const double massAxisMin = 1.5848; -const double massAxisMax = 2.1848; +const int massAxisNBins = 200; +const double massAxisMin = 1.3848; +const double massAxisMax = 2.3848; const int phiAxisNBins = 32; const double phiAxisMin = 0.; const double phiAxisMax = o2::constants::math::TwoPI; @@ -458,7 +458,7 @@ struct HfCorrelatorD0Hadrons { registry.fill(HIST("hSelectionStatusRec"), candidate1.isSelD0bar() + (candidate1.isSelD0() * 2)); } // fill invariant mass plots from D0/D0bar signal and background candidates - if (candidate1.isSelD0() >= selectionFlagD0) { // only reco as D0 + if (candidate1.isSelD0() >= selectionFlagD0) { // only reco as D0 if (candidate1.flagMcMatchRec() == 1 << aod::hf_cand_2prong::DecayType::D0ToPiK) { // also matched as D0 registry.fill(HIST("hMassD0RecSig"), hfHelper.invMassD0ToPiK(candidate1), candidate1.pt(), efficiencyWeight); } else if (candidate1.flagMcMatchRec() == -(1 << aod::hf_cand_2prong::DecayType::D0ToPiK)) { @@ -467,7 +467,7 @@ struct HfCorrelatorD0Hadrons { registry.fill(HIST("hMassD0RecBg"), hfHelper.invMassD0ToPiK(candidate1), candidate1.pt(), efficiencyWeight); } } - if (candidate1.isSelD0bar() >= selectionFlagD0bar) { // only reco as D0bar + if (candidate1.isSelD0bar() >= selectionFlagD0bar) { // only reco as D0bar if (candidate1.flagMcMatchRec() == -(1 << aod::hf_cand_2prong::DecayType::D0ToPiK)) { // also matched as D0bar registry.fill(HIST("hMassD0barRecSig"), hfHelper.invMassD0barToKPi(candidate1), candidate1.pt(), efficiencyWeight); } else if (candidate1.flagMcMatchRec() == 1 << aod::hf_cand_2prong::DecayType::D0ToPiK) { diff --git a/PWGHF/HFC/TableProducer/correlatorDMesonPairsTesting.cxx b/PWGHF/HFC/TableProducer/correlatorDMesonPairsTesting.cxx new file mode 100644 index 00000000000..ca7251433d0 --- /dev/null +++ b/PWGHF/HFC/TableProducer/correlatorDMesonPairsTesting.cxx @@ -0,0 +1,763 @@ +// 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 correlatorDMesonPairs.cxx +/// \brief D0(bar) correlator task - data-like, MC-reco and MC-kine analyses. +/// \note Temporary code for tests of D0-D0 correlations +/// +/// \author Andrea Tavira García , IJCLab Orsay + +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "PWGHF/Core/HfHelper.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/HFC/DataModel/DMesonPairsTablesTesting.h" + +using namespace o2; +using namespace o2::analysis; +using namespace o2::constants::physics; +using namespace o2::framework; +using namespace o2::framework::expressions; + +namespace +{ +enum CandidateType { + SelectedD = 0, // This particle is selected as a D + SelectedDbar, // This particle is selected as a Dbar + TrueD, // This particle is a true D + TrueDbar // This particle is a true Dbar +}; + +enum PairTypeOfSelMassSel { + DD = 0, // This is a D0-D0 pair + DbarDbar, // This is a D0bar-D0bar pair + DDbar, // This is a D0-D0bar pair + DbarD // This is a D0bar-D0 pair +}; +} // namespace + +using McParticlesPlus2Prong = soa::Join; + +struct HfCorrelatorDMesonPairsTesting { + SliceCache cache; + Preslice perCol2Prong = aod::hf_cand::collisionId; + + Produces entryD0Pair; + Produces entryD0PairMcInfo; + Produces entryD0PairMcGen; + Produces entryD0PairMcGenInfo; + + Configurable selectionFlagD0{"selectionFlagD0", 1, "Selection Flag for D0"}; + Configurable selectionFlagD0bar{"selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable yCandMax{"yCandMax", 0.8, "maxmum |y| of D0 candidates"}; + Configurable ptCandMin{"ptCandMin", -1., "minimum pT of D0 candidates"}; + Configurable> binsPt{"binsPt", std::vector{o2::analysis::hf_cuts_d0_to_pi_k::vecBinsPt}, "pT bin limits for candidate mass plots"}; + + HfHelper hfHelper; + + using TracksWPid = soa::Join; + + Partition> selectedD0Candidates = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlagD0 || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlagD0bar; + Partition> selectedD0CandidatesMc = aod::hf_sel_candidate_d0::isSelD0 >= selectionFlagD0 || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlagD0bar; + + HistogramConfigSpec hTH1Pt{HistType::kTH1F, {{180, 0., 36.}}}; + HistogramConfigSpec hTH1Y{HistType::kTH1F, {{100, -5., 5.}}}; + HistogramConfigSpec hTH1Phi{HistType::kTH1F, {{32, 0., o2::constants::math::TwoPI}}}; + HistogramConfigSpec hTH2Pid{HistType::kTH2F, {{500, 0., 10.}, {400, -20., 20.}}}; + + HistogramRegistry registry{ + "registry", + {{"hPtCand", "D meson candidates;candidate #it{p}_{T} (GeV/#it{c});entries", hTH1Pt}, + {"hPtCandAfterCut", "D meson candidates after pT cut;candidate #it{p}_{T} (GeV/#it{c});entries", hTH1Pt}, + {"hPtProng0", "D meson candidates;prong 0 #it{p}_{T} (GeV/#it{c});entries", hTH1Pt}, + {"hPtProng1", "D meson candidates;prong 1 #it{p}_{T} (GeV/#it{c});entries", hTH1Pt}, + {"hEta", "D meson candidates;candidate #it{#eta};entries", hTH1Y}, + {"hPhi", "D meson candidates;candidate #it{#varphi};entries", hTH1Phi}, + {"hY", "D meson candidates;candidate #it{y};entries", hTH1Y}, + // MC Gen plots + {"hPtCandMcGen", "D meson candidates MC Gen;candidate #it{p}_{T} (GeV/#it{c});entries", hTH1Pt}, + {"hPtCandAfterCutMcGen", "D meson candidates after pT cut;candidate #it{p}_{T} (GeV/#it{c});entries", hTH1Pt}, + {"hEtaMcGen", "D meson candidates MC Gen;candidate #it{#eta};entries", hTH1Y}, + {"hPhiMcGen", "D meson candidates MC Gen;candidate #it{#varphi};entries", hTH1Phi}, + // PID plots ----- Not definitively here + {"PID/hTofNSigmaPi", "(TOFsignal-time#pi)/tofSigPid;p[GeV/c];(TOFsignal-time#pi)/tofSigPid", hTH2Pid}, + {"PID/hTofNSigmaKa", "(TOFsignal-timeK)/tofSigPid;p[GeV/c];(TOFsignal-timeK)/tofSigPid", hTH2Pid}, + {"PID/hTpcNSigmaPi", "(TPCsignal-time#pi)/tpcSigPid;p[GeV/c];(TPCsignal-time#pi)/tpcSigPid", hTH2Pid}, + {"PID/hTpcNSigmaKa", "(TPCsignal-timeK)/tpcSigPid;p[GeV/c];(TPCsignal-timeK)/tpcSigPid", hTH2Pid}, + {"PID/hTpcTofNSigmaPi", "(TPC+TOFsignal-time#pi)/tpcTofSigPid;p[GeV/#it{c}];(TPC+TOFsignal-time#pi)/tpcTofSigPid", hTH2Pid}, + {"PID/hTpcTofNSigmaKa", "(TPC+TOFsignal-timeK)/tpcTofSigPid;p[GeV/c];(TPC+TOFsignal-timeK)/tpcTofSigPid", hTH2Pid}}}; + + void init(InitContext&) + { + auto vbins = (std::vector)binsPt; + constexpr int kNBinsSelStatus = 25; + std::string labels[kNBinsSelStatus]; + + labels[0] = "total # of Selected pairs"; + // Cand1 analysis + labels[1] = "total # of Selected Cands 1"; + labels[2] = "# of Selected D Cand 1 ONLY"; + labels[3] = "# of Selected Dbar Cand 1 ONLY"; + labels[4] = "# of Selected Simultaneous D + Dbar Cand 1"; + labels[5] = "# of True D Cand 1"; + labels[6] = "# of True Dbar Cand 1"; + // Cand2 analysis + labels[7] = "total # of Selected Cands 2"; + labels[8] = "# of Selected D Cand 2 ONLY"; + labels[9] = "# of Selected Dbar Cand 2 ONLY"; + labels[10] = "# of Selected Simultaneous D + Dbar Cand 2"; + labels[11] = "# of True D Cand 2"; + labels[12] = "# of True Dbar Cand 2"; + // Pair analysis + labels[13] = "# of D+D Pairs"; + labels[14] = "# of Dbar+Dbar Pairs"; + labels[15] = "# of D+Dbar Pairs"; + labels[16] = "# of Dbar+D Pairs"; + labels[17] = "# of D+D ONLY Pairs"; + labels[18] = "# of Dbar+Dbar ONLY Pairs"; + labels[19] = "# of D+Dbar ONLY Pairs"; + labels[20] = "# of Dbar+D ONLY Pairs"; + // True pair analysis + labels[21] = "# of True D+D Pairs"; + labels[22] = "# of True Dbar+Dbar Pairs"; + labels[23] = "# of True D+Dbar Pairs"; + labels[24] = "# of True Dbar+D Pairs"; + + AxisSpec axisSelStatus = {kNBinsSelStatus, 0.5, kNBinsSelStatus + 0.5, ""}; + registry.add("hSelectionStatus", "D Meson candidates;selection status;entries", HistType::kTH1F, {axisSelStatus}); + registry.add("hSelectionStatusMcGen", "D Meson candidates MC Gen;selection status;entries", HistType::kTH1F, {axisSelStatus}); + + for (int iBin = 0; iBin < kNBinsSelStatus; iBin++) { + registry.get(HIST("hSelectionStatus"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); + registry.get(HIST("hSelectionStatusMcGen"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); + } + + constexpr int kNBinsMatching = 8; + std::string labelsMatching[kNBinsMatching]; + // Cand1 analysis + labelsMatching[0] = "total # of Cand 1"; + labelsMatching[1] = "# of matched D Cand 1"; + labelsMatching[2] = "# of matched Dbar Cand 1"; + labelsMatching[3] = "# of unmatched Cand 1"; + // Cand2 analysis + labelsMatching[4] = "total # of Cand 2"; + labelsMatching[5] = "# of matched D Cand 2"; + labelsMatching[6] = "# of matched Dbar Cand 2"; + labelsMatching[7] = "# of unmatched Cand 2"; + + AxisSpec axisMatching = {kNBinsMatching, 0.5, kNBinsMatching + 0.5, ""}; + registry.add("hMatchingMcRec", "D Meson candidates; MC matching status;entries", HistType::kTH1F, {axisMatching}); + registry.add("hMatchingMcGen", "D Meson candidates; MC matching status;entries", HistType::kTH1F, {axisMatching}); + + for (int iBin = 0; iBin < kNBinsMatching; iBin++) { + registry.get(HIST("hMatchingMcRec"))->GetXaxis()->SetBinLabel(iBin + 1, labelsMatching[iBin].data()); + registry.get(HIST("hMatchingMcGen"))->GetXaxis()->SetBinLabel(iBin + 1, labelsMatching[iBin].data()); + } + + constexpr int kNBinsSinglePart = 6; + std::string labelsSinglePart[kNBinsSinglePart]; + // Candidate analysis + labelsSinglePart[0] = "total # of Candidates"; + labelsSinglePart[1] = "# of selected D"; + labelsSinglePart[2] = "# of selected Dbar"; + labelsSinglePart[3] = "# of selected D and Dbar"; + labelsSinglePart[4] = "# of true D"; + labelsSinglePart[5] = "# of true Dbar"; + + AxisSpec axisSinglePart = {kNBinsSinglePart, 0.5, kNBinsSinglePart + 0.5, ""}; + registry.add("hStatusSinglePart", "D Meson candidates; MC matching status;entries", HistType::kTH1F, {axisSinglePart}); + registry.add("hStatusSinglePartMcGen", "D Meson candidates; MC matching status;entries", HistType::kTH1F, {axisSinglePart}); + + for (int iBin = 0; iBin < kNBinsSinglePart; iBin++) { + registry.get(HIST("hStatusSinglePart"))->GetXaxis()->SetBinLabel(iBin + 1, labelsSinglePart[iBin].data()); + registry.get(HIST("hStatusSinglePartMcGen"))->GetXaxis()->SetBinLabel(iBin + 1, labelsSinglePart[iBin].data()); + } + + AxisSpec axisInputD0 = {200, -0.5, 199.5}; + registry.add("hInputCheckD0", "Check on input D0 meson candidates/event", {HistType::kTH1F, {axisInputD0}}); + registry.add("hInputCheckD0bar", "Check on input D0bar meson candidates/event", {HistType::kTH1F, {axisInputD0}}); + registry.add("hInputCheckD0AndD0bar", "Check on input D0 & D0bar meson candidates/event", {HistType::kTH1F, {axisInputD0}}); + registry.add("hInputCheckD0OrD0bar", "Check on input D0 | D0bar meson candidates/event", {HistType::kTH1F, {axisInputD0}}); + // MC Gen + registry.add("hInputCheckD0McGen", "Check on input D0 meson candidates/event MC Gen", {HistType::kTH1F, {axisInputD0}}); + registry.add("hInputCheckD0barMcGen", "Check on input D0bar meson candidates/event MC Gen", {HistType::kTH1F, {axisInputD0}}); + registry.add("hInputCheckD0AndD0barMcGen", "Check on input D0 & D0bar meson candidates/event MC Gen", {HistType::kTH1F, {axisInputD0}}); + registry.add("hInputCheckD0OrD0barMcGen", "Check on input D0 | D0bar meson candidates/event MC Gen", {HistType::kTH1F, {axisInputD0}}); + + registry.add("hMass", "D Meson pair candidates;inv. mass (#pi K) (GeV/#it{c}^{2});entries", {HistType::kTH2F, {{120, 1.5848, 2.1848}, {vbins, "#it{p}_{T} (GeV/#it{c})"}}}); + } + + /// Sets bits to select candidate type for D0 + /// SelectedD and SelectedDbar bits look at whether the candidate passed the selection flags. + /// \param candidate is candidate + /// \return bitmap with type of candidate + template + uint8_t assignCandidateTypeD0(const T& candidate) + { + uint8_t candidateType(0); + if (candidate.isSelD0() >= selectionFlagD0) { + SETBIT(candidateType, SelectedD); + } + if (candidate.isSelD0bar() >= selectionFlagD0bar) { + SETBIT(candidateType, SelectedDbar); + } + return candidateType; + } + + /// Sets bits to select true candidate type for D0 + /// SelectedD and SelectedDbar bits look at whether the candidate passed the selection flags. + /// \param candidate is candidate + /// \return bitmap with true type of candidate + template + uint8_t assignCandidateTypeD0True(const T& candidate) + { + uint8_t candidateType(0); + if (candidate.flagMcMatchRec() == 1 << o2::aod::hf_cand_2prong::DecayType::D0ToPiK) { // matched as D0 + SETBIT(candidateType, TrueD); + } + if (candidate.flagMcMatchRec() == -(1 << o2::aod::hf_cand_2prong::DecayType::D0ToPiK)) { // matched as D0bar + SETBIT(candidateType, TrueDbar); + } + return candidateType; + } + + /// Sets bits to select candidate type at generator level + /// \param particle is particle + /// \return bitmap with type of gen particle - they are selected as True + template + uint8_t assignParticleTypeD0Gen(const T& particle) + { + uint8_t particleType(0); + if (particle.pdgCode() == Pdg::kD0) { // just checking the particle PDG, not the decay channel + SETBIT(particleType, TrueD); + } + if (particle.pdgCode() == (-Pdg::kD0)) { // just checking the particle PDG, not the decay channel + SETBIT(particleType, TrueDbar); + } + return particleType; + } + + /// Check if the candidate is a D + /// \param candidate is candidate + /// \return true if is a D + bool isD(const uint8_t candidateType) + { + return (TESTBIT(candidateType, SelectedD)); + } + + /// Check if the candidate is a Dbar + /// \param candidate is candidate + /// \return true if is a Dbar + bool isDbar(const uint8_t candidateType) + { + return (TESTBIT(candidateType, SelectedDbar)); + } + + /// Check if the candidate is a true D + /// \param candidate is candidate + /// \return true if is a true D + bool isTrueD(const uint8_t candidateType) + { + return (TESTBIT(candidateType, TrueD)); + } + + /// Check if the candidate is a true Dbar + /// \param candidate is candidate + /// \return true if is a true Dbar + bool isTrueDbar(const uint8_t candidateType) + { + return (TESTBIT(candidateType, TrueDbar)); + } + + /// Fill PID related plots for D0 and D0bar + /// \param candidate is candidate + template + void AnalysePid(const T& candidate) + { + auto prong0 = candidate.template prong0_as(); + auto prong1 = candidate.template prong1_as(); + if (candidate.isSelD0() >= selectionFlagD0) { + registry.fill(HIST("PID/hTofNSigmaPi"), candidate.ptProng0(), prong0.tofNSigmaPi()); + registry.fill(HIST("PID/hTofNSigmaKa"), candidate.ptProng1(), prong1.tofNSigmaKa()); + registry.fill(HIST("PID/hTpcNSigmaPi"), candidate.ptProng0(), prong0.tpcNSigmaPi()); + registry.fill(HIST("PID/hTpcNSigmaKa"), candidate.ptProng1(), prong1.tpcNSigmaKa()); + registry.fill(HIST("PID/hTpcTofNSigmaPi"), candidate.ptProng0(), prong0.tpcTofNSigmaPi()); + registry.fill(HIST("PID/hTpcTofNSigmaKa"), candidate.ptProng1(), prong1.tpcTofNSigmaKa()); + } + if (candidate.isSelD0bar() >= selectionFlagD0bar) { + registry.fill(HIST("PID/hTofNSigmaPi"), candidate.ptProng1(), prong1.tofNSigmaPi()); + registry.fill(HIST("PID/hTofNSigmaKa"), candidate.ptProng0(), prong0.tofNSigmaKa()); + registry.fill(HIST("PID/hTpcNSigmaPi"), candidate.ptProng1(), prong1.tpcNSigmaPi()); + registry.fill(HIST("PID/hTpcNSigmaKa"), candidate.ptProng0(), prong0.tpcNSigmaKa()); + registry.fill(HIST("PID/hTpcTofNSigmaPi"), candidate.ptProng1(), prong1.tpcTofNSigmaPi()); + registry.fill(HIST("PID/hTpcTofNSigmaKa"), candidate.ptProng0(), prong0.tpcTofNSigmaKa()); + } + } + + /// Fill counters for D0 and D0bar + /// \param selectedD0Candidates contains all D0 candidates + template + void GetCountersPerEvent(const T& selectedD0Candidates) + { + int nDevent = 0, nDbarevent = 0, nDDbarevent = 0, nDorDbarevent = 0; + for (const auto& candidate : selectedD0Candidates) { + // Get counters per event + auto candidateType1 = assignCandidateTypeD0(candidate); // Candidate type attribution + registry.fill(HIST("hPtCand"), candidate.pt()); + if (abs(hfHelper.yD0(candidate)) > yCandMax) { + continue; + } + if (ptCandMin >= 0. && candidate.pt() < ptCandMin) { + continue; + } + registry.fill(HIST("hPtProng0"), candidate.ptProng0()); + registry.fill(HIST("hPtProng1"), candidate.ptProng1()); + registry.fill(HIST("hEta"), candidate.eta()); + registry.fill(HIST("hPhi"), candidate.phi()); + registry.fill(HIST("hY"), candidate.y(MassD0)); + registry.fill(HIST("hPtCandAfterCut"), candidate.pt()); + registry.fill(HIST("hMass"), hfHelper.invMassD0ToPiK(candidate), candidate.pt()); + + bool isDCand1 = isD(candidateType1); + bool isDbarCand1 = isDbar(candidateType1); + if (isDCand1) { + nDevent++; + } + if (isDbarCand1) { + nDbarevent++; + } + if (isDCand1 && isDbarCand1) { + nDDbarevent++; + } + if (isDCand1 || isDbarCand1) { + nDorDbarevent++; + } + + // Fill selection status single particle + registry.fill(HIST("hStatusSinglePart"), 1); + if (isDCand1 && !isDbarCand1) { + registry.fill(HIST("hStatusSinglePart"), 2); + } else if (isDbarCand1 && !isDCand1) { + registry.fill(HIST("hStatusSinglePart"), 3); + } else if (isDCand1 && isDbarCand1) { + registry.fill(HIST("hStatusSinglePart"), 4); + } + } + if (nDevent > 0) { + registry.fill(HIST("hInputCheckD0"), nDevent); + } + if (nDbarevent > 0) { + registry.fill(HIST("hInputCheckD0bar"), nDbarevent); + } + if (nDDbarevent > 0) { + registry.fill(HIST("hInputCheckD0AndD0bar"), nDDbarevent); + } + if (nDorDbarevent > 0) { + registry.fill(HIST("hInputCheckD0OrD0bar"), nDorDbarevent); + } + } + + /// Fill selection status histogram + /// \param candidate1 is the first candidate of the pair + /// \param candidate2 is the second candidate of the pair + template + void fillEntry(const T& candidate1, const T& candidate2, const bool& isDCand1, const bool& isDbarCand1, + const bool& isDCand2, const bool& isDbarCand2) + { + + /// Fill information on the D candidates + registry.fill(HIST("hSelectionStatus"), 2); + if (isDCand1 && !isDbarCand1) { + registry.fill(HIST("hSelectionStatus"), 3); + } else if (isDbarCand1 && !isDCand1) { + registry.fill(HIST("hSelectionStatus"), 4); + } else if (isDCand1 && isDbarCand1) { + registry.fill(HIST("hSelectionStatus"), 5); + } + + registry.fill(HIST("hSelectionStatus"), 8); + if (isDCand2 && !isDbarCand2) { + registry.fill(HIST("hSelectionStatus"), 9); + } else if (isDbarCand2 && !isDCand2) { + registry.fill(HIST("hSelectionStatus"), 10); + } else if (isDCand2 && isDbarCand2) { + registry.fill(HIST("hSelectionStatus"), 11); + } + + /// Collect information on the D pairs + uint8_t pairType(0); + registry.fill(HIST("hSelectionStatus"), 1); + float yCand1 = hfHelper.yD0(candidate1); + float yCand2 = hfHelper.yD0(candidate2); + float massDCand1 = hfHelper.invMassD0ToPiK(candidate1); + float massDbarCand1 = hfHelper.invMassD0barToKPi(candidate1); + float massDCand2 = hfHelper.invMassD0ToPiK(candidate2); + float massDbarCand2 = hfHelper.invMassD0barToKPi(candidate1); + if (isDCand1 && isDCand2) { + SETBIT(pairType, DD); + registry.fill(HIST("hSelectionStatus"), 14); + if ((!isDbarCand1) && (!isDbarCand2)) { + registry.fill(HIST("hSelectionStatus"), 18); + } + } + if (isDbarCand1 && isDbarCand2) { + SETBIT(pairType, DbarDbar); + registry.fill(HIST("hSelectionStatus"), 15); + if ((!isDCand1) && (!isDCand2)) { + registry.fill(HIST("hSelectionStatus"), 19); + } + } + if (isDCand1 && isDbarCand2) { + SETBIT(pairType, DDbar); + registry.fill(HIST("hSelectionStatus"), 16); + if ((!isDbarCand1) && (!isDCand2)) { + registry.fill(HIST("hSelectionStatus"), 20); + } + } + if (isDbarCand1 && isDCand2) { + SETBIT(pairType, DbarD); + registry.fill(HIST("hSelectionStatus"), 17); + if ((!isDCand1) && (!isDbarCand2)) { + registry.fill(HIST("hSelectionStatus"), 21); + } + } + + entryD0Pair(candidate1.pt(), candidate2.pt(), yCand1, yCand2, massDCand1, massDbarCand1, massDCand2, massDbarCand2, pairType); + } + + /// D0(bar)-D0(bar) correlation pair builder - for real data and data-like analysis (i.e. reco-level w/o matching request via MC truth) + void processData(aod::Collision const& collision, + soa::Join const& candidates, TracksWPid const&) + { + for (const auto& candidate : candidates) { + AnalysePid(candidate); + } + auto selectedD0CandidatesGrouped = selectedD0Candidates->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + GetCountersPerEvent(selectedD0CandidatesGrouped); + // protection against empty tables to be sliced + if (selectedD0Candidates.size() <= 1) { + return; + } + for (const auto& candidate1 : selectedD0CandidatesGrouped) { + if (abs(hfHelper.yD0(candidate1)) > yCandMax) { + continue; + } + if (ptCandMin >= 0. && candidate1.pt() < ptCandMin) { + continue; + } + + auto candidateType1 = assignCandidateTypeD0(candidate1); // Candidate type attribution + bool isDCand1 = isD(candidateType1); + bool isDbarCand1 = isDbar(candidateType1); + + for (auto candidate2 = candidate1 + 1; candidate2 != selectedD0CandidatesGrouped.end(); ++candidate2) { + if (abs(hfHelper.yD0(candidate2)) > yCandMax) { + continue; + } + if (ptCandMin >= 0. && candidate2.pt() < ptCandMin) { + continue; + } + auto candidateType2 = assignCandidateTypeD0(candidate2); // Candidate type attribution + + bool isDCand2 = isD(candidateType2); + bool isDbarCand2 = isDbar(candidateType2); + + fillEntry(candidate1, candidate2, isDCand1, isDbarCand1, isDCand2, isDbarCand2); + } // end inner loop (Cand2) + } // end outer loop (Cand1) + } + + PROCESS_SWITCH(HfCorrelatorDMesonPairsTesting, processData, "Process data mode", true); + + void processMcRec(aod::Collision const& collision, soa::Join const& candidates, TracksWPid const&) + { + for (const auto& candidate : candidates) { + AnalysePid(candidate); + } + auto selectedD0CandidatesGroupedMc = selectedD0CandidatesMc->sliceByCached(aod::hf_cand::collisionId, collision.globalIndex(), cache); + GetCountersPerEvent(selectedD0CandidatesGroupedMc); + // protection against empty tables to be sliced + if (selectedD0CandidatesMc.size() <= 1) { + return; + } + for (const auto& candidate1 : selectedD0CandidatesGroupedMc) { + if (abs(hfHelper.yD0(candidate1)) > yCandMax) { + continue; + } + if (ptCandMin >= 0. && candidate1.pt() < ptCandMin) { + continue; + } + + auto candidateType1 = assignCandidateTypeD0(candidate1); // Candidate type attribution + + bool isDCand1 = isD(candidateType1); + bool isDbarCand1 = isDbar(candidateType1); + + // assign true type + auto candidateTypeTrue1 = assignCandidateTypeD0True(candidate1); + bool isTrueDCand1 = isTrueD(candidateTypeTrue1); + bool isTrueDbarCand1 = isTrueDbar(candidateTypeTrue1); + + int8_t matchedRec1 = candidate1.flagMcMatchRec(); + int8_t originRec1 = candidate1.originMcRec(); + + if (isTrueDCand1) { + registry.fill(HIST("hStatusSinglePart"), 5); + } else if (isTrueDbarCand1) { + registry.fill(HIST("hStatusSinglePart"), 6); + } + + for (auto candidate2 = candidate1 + 1; candidate2 != selectedD0CandidatesGroupedMc.end(); ++candidate2) { + if (abs(hfHelper.yD0(candidate2)) > yCandMax) { + continue; + } + if (ptCandMin >= 0. && candidate2.pt() < ptCandMin) { + continue; + } + auto candidateType2 = assignCandidateTypeD0(candidate2); // Candidate type attribution + + bool isDCand2 = isD(candidateType2); + bool isDbarCand2 = isDbar(candidateType2); + // assign true type + auto candidateTypeTrue2 = assignCandidateTypeD0True(candidate2); + bool isTrueDCand2 = isTrueD(candidateTypeTrue2); + bool isTrueDbarCand2 = isTrueDbar(candidateTypeTrue2); + + int8_t matchedRec2 = candidate2.flagMcMatchRec(); + int8_t originRec2 = candidate2.originMcRec(); + + // Fill hMatchingMcRec - Cand 1 + registry.fill(HIST("hMatchingMcRec"), 1); + if (matchedRec1 == 1) { + registry.fill(HIST("hMatchingMcRec"), 2); + } else if (matchedRec1 == -1) { + registry.fill(HIST("hMatchingMcRec"), 3); + } else if (matchedRec1 == 0) { + registry.fill(HIST("hMatchingMcRec"), 4); + } + // Fill hMatchingMcRec - Cand 2 + registry.fill(HIST("hMatchingMcRec"), 5); + if (matchedRec2 == 1) { + registry.fill(HIST("hMatchingMcRec"), 6); + } else if (matchedRec2 == -1) { + registry.fill(HIST("hMatchingMcRec"), 7); + } else if (matchedRec2 == 0) { + registry.fill(HIST("hMatchingMcRec"), 8); + } + fillEntry(candidate1, candidate2, isDCand1, isDbarCand1, isDCand2, isDbarCand2); + entryD0PairMcInfo(originRec1, originRec2, matchedRec1, matchedRec2); + + if (isTrueDCand1) { + registry.fill(HIST("hSelectionStatus"), 6); + } else if (isTrueDbarCand1) { + registry.fill(HIST("hSelectionStatus"), 7); + } + if (isTrueDCand2) { + registry.fill(HIST("hSelectionStatus"), 12); + } else if (isTrueDbarCand2) { + registry.fill(HIST("hSelectionStatus"), 13); + } + if (isTrueDCand1 && isTrueDCand2) { + registry.fill(HIST("hSelectionStatus"), 22); + } else if (isTrueDbarCand1 && isTrueDbarCand2) { + registry.fill(HIST("hSelectionStatus"), 23); + } else if (isTrueDCand1 && isTrueDbarCand2) { + registry.fill(HIST("hSelectionStatus"), 24); + } else if (isTrueDbarCand1 && isTrueDCand2) { + registry.fill(HIST("hSelectionStatus"), 25); + } + } // end inner loop (Cand2) + } // end outer loop (Cand1) + } + + PROCESS_SWITCH(HfCorrelatorDMesonPairsTesting, processMcRec, "Process Mc reco mode", false); + + void processMcGen(aod::McCollision const&, McParticlesPlus2Prong const& mcParticles) + { + // Get counters per event + int nDevent = 0, nDbarevent = 0, nDDbarevent = 0, nDorDbarevent = 0; + for (const auto& particle : mcParticles) { + // check if the particle is D0 or D0bar + if (std::abs(particle.pdgCode()) != Pdg::kD0) { + continue; + } + if (abs(particle.y()) > yCandMax) { + continue; + } + if (ptCandMin >= 0. && particle.pt() < ptCandMin) { + continue; + } + auto particleType = assignParticleTypeD0Gen(particle); // Candidate type attribution + bool isDParticle = isTrueD(particleType); + bool isDbarParticle = isTrueDbar(particleType); + if (isDParticle) { + nDevent++; + } + if (isDbarParticle) { + nDbarevent++; + } + if (isDParticle && isDbarParticle) { + nDDbarevent++; + } + if (isDParticle || isDbarParticle) { + nDorDbarevent++; + } + } + if (nDevent > 0) { + registry.fill(HIST("hInputCheckD0McGen"), nDevent); + } + if (nDbarevent > 0) { + registry.fill(HIST("hInputCheckD0barMcGen"), nDbarevent); + } + if (nDDbarevent > 0) { + registry.fill(HIST("hInputCheckD0AndD0barMcGen"), nDDbarevent); + } + if (nDorDbarevent > 0) { + registry.fill(HIST("hInputCheckD0OrD0barMcGen"), nDorDbarevent); + } + + auto massD = MassD0; + auto massDbar = MassD0Bar; + + for (const auto& particle1 : mcParticles) { + // check if the particle is D0 or D0bar + if (std::abs(particle1.pdgCode()) != Pdg::kD0) { + continue; + } + registry.fill(HIST("hPtCandMcGen"), particle1.pt()); + + if (abs(particle1.y()) > yCandMax) { + continue; + } + if (ptCandMin >= 0. && particle1.pt() < ptCandMin) { + continue; + } + registry.fill(HIST("hEtaMcGen"), particle1.eta()); + registry.fill(HIST("hPhiMcGen"), particle1.phi()); + registry.fill(HIST("hPtCandAfterCutMcGen"), particle1.pt()); + + auto particleType1 = assignParticleTypeD0Gen(particle1); // Candidate sign attribution + bool isDParticle1 = isTrueD(particleType1); + bool isDbarParticle1 = isTrueDbar(particleType1); + + // check if it's MC matched + int8_t matchedGen1 = particle1.flagMcMatchGen(); + // check origin + int8_t originGen1 = particle1.originMcGen(); + + // Fill selection status single particle + registry.fill(HIST("hStatusSinglePartMcGen"), 1); + if (isDParticle1 && !isDbarParticle1) { + registry.fill(HIST("hStatusSinglePartMcGen"), 2); + } else if (isDbarParticle1 && !isDParticle1) { + registry.fill(HIST("hStatusSinglePartMcGen"), 3); + } else if (isDParticle1 && isDbarParticle1) { + registry.fill(HIST("hStatusSinglePartMcGen"), 4); + } + + for (auto particle2 = particle1 + 1; particle2 != mcParticles.end(); ++particle2) { + // check if the particle is D0 or D0bar + if (std::abs(particle2.pdgCode()) != Pdg::kD0) { + continue; + } + if (abs(particle2.y()) > yCandMax) { + continue; + } + if (ptCandMin >= 0. && particle2.pt() < ptCandMin) { + continue; + } + // Candidate sign attribution. + auto particleType2 = assignParticleTypeD0Gen(particle2); + bool isDParticle2 = isTrueD(particleType2); + bool isDbarParticle2 = isTrueDbar(particleType2); + + // check if it's MC matched + int8_t matchedGen2 = particle2.flagMcMatchGen(); + // check origin + int8_t originGen2 = particle2.originMcGen(); + + // Fill hMatchingMcGen - Cand 1 + registry.fill(HIST("hMatchingMcGen"), 1); + if (matchedGen1 == 1) { + registry.fill(HIST("hMatchingMcGen"), 2); + } else if (matchedGen1 == -1) { + registry.fill(HIST("hMatchingMcGen"), 3); + } else if (matchedGen1 == 0) { + registry.fill(HIST("hMatchingMcGen"), 4); + } + // Fill hMatchingMcRec - Cand 2 + registry.fill(HIST("hMatchingMcGen"), 5); + if (matchedGen2 == 1) { + registry.fill(HIST("hMatchingMcGen"), 6); + } else if (matchedGen2 == -1) { + registry.fill(HIST("hMatchingMcGen"), 7); + } else if (matchedGen2 == 0) { + registry.fill(HIST("hMatchingMcGen"), 8); + } + + // Fill particle1's Selection Status + registry.fill(HIST("hSelectionStatusMcGen"), 2); + if (isDParticle1 && !isDbarParticle1) { + registry.fill(HIST("hSelectionStatusMcGen"), 6); + } else if (isDbarParticle1 && !isDParticle1) { + registry.fill(HIST("hSelectionStatusMcGen"), 7); + } + + // Fill particle2's Selection Status + registry.fill(HIST("hSelectionStatusMcGen"), 8); + if (isDParticle2 && !isDbarParticle2) { + registry.fill(HIST("hSelectionStatusMcGen"), 12); + } else if (isDbarParticle2 && !isDParticle2) { + registry.fill(HIST("hSelectionStatusMcGen"), 13); + } + + // Fill pair Selection Status + uint8_t pairType(0); + registry.fill(HIST("hSelectionStatusMcGen"), 1); + + if (isDParticle1 && isDParticle2) { + SETBIT(pairType, DD); + registry.fill(HIST("hSelectionStatusMcGen"), 22); + } + if (isDbarParticle1 && isDbarParticle2) { + SETBIT(pairType, DbarDbar); + registry.fill(HIST("hSelectionStatusMcGen"), 23); + } + if (isDParticle1 && isDbarParticle2) { + SETBIT(pairType, DDbar); + registry.fill(HIST("hSelectionStatusMcGen"), 24); + } + if (isDbarParticle1 && isDParticle2) { + SETBIT(pairType, DbarD); + registry.fill(HIST("hSelectionStatusMcGen"), 25); + } + + // Fill pair Selection Status + entryD0PairMcGen(particle1.pt(), particle2.pt(), particle1.y(), particle2.y(), massD, massDbar, massD, massDbar, pairType); + entryD0PairMcGenInfo(originGen1, originGen2, matchedGen1, matchedGen2); + + } // end inner loop + } // end outer loop + } + + PROCESS_SWITCH(HfCorrelatorDMesonPairsTesting, processMcGen, "Process D0 Mc Gen mode", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/HFC/Tasks/CMakeLists.txt b/PWGHF/HFC/Tasks/CMakeLists.txt index 567a21d2129..9bc18f22359 100644 --- a/PWGHF/HFC/Tasks/CMakeLists.txt +++ b/PWGHF/HFC/Tasks/CMakeLists.txt @@ -24,6 +24,11 @@ o2physics_add_dpl_workflow(task-correlation-d-meson-pairs PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(task-correlation-d-meson-pairs-testing + SOURCES taskCorrelationDMesonPairsTesting.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(task-correlation-dplus-hadrons SOURCES taskCorrelationDplusHadrons.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore diff --git a/PWGHF/HFC/Tasks/taskCorrelationD0Hadrons.cxx b/PWGHF/HFC/Tasks/taskCorrelationD0Hadrons.cxx index 8b23113b392..1a47f61d8fc 100644 --- a/PWGHF/HFC/Tasks/taskCorrelationD0Hadrons.cxx +++ b/PWGHF/HFC/Tasks/taskCorrelationD0Hadrons.cxx @@ -54,15 +54,15 @@ AxisSpec axisPtHadron = {11, 0., 11., ""}; AxisSpec axisPoolBin = {9, 0., 9., ""}; // definition of vectors for standard ptbin and invariant mass configurables -const int nPtBinsCorrelations = 8; -const double pTBinsCorrelations[nPtBinsCorrelations + 1] = {0., 2., 4., 6., 8., 12., 16., 24., 99.}; +const int nPtBinsCorrelations = 12; +const double pTBinsCorrelations[nPtBinsCorrelations + 1] = {0., 1., 2., 3., 4., 5., 6., 7., 8., 12., 16., 24., 99.}; auto vecPtBinsCorrelations = std::vector{pTBinsCorrelations, pTBinsCorrelations + nPtBinsCorrelations + 1}; -const double signalRegionLeftDefault[nPtBinsCorrelations] = {1.810, 1.810, 1.810, 1.810, 1.810, 1.810, 1.810, 1.810}; -const double signalRegionRightDefault[nPtBinsCorrelations] = {1.922, 1.922, 1.922, 1.922, 1.922, 1.922, 1.922, 1.922}; -const double sidebandLeftInnerDefault[nPtBinsCorrelations] = {1.754, 1.754, 1.754, 1.754, 1.754, 1.754, 1.754, 1.754}; -const double sidebandLeftOuterDefault[nPtBinsCorrelations] = {1.642, 1.642, 1.642, 1.642, 1.642, 1.642, 1.642, 1.642}; -const double sidebandRightInnerDefault[nPtBinsCorrelations] = {1.978, 1.978, 1.978, 1.978, 1.978, 1.978, 1.978, 1.978}; -const double sidebandRightOuterDefault[nPtBinsCorrelations] = {2.090, 2.090, 2.090, 2.090, 2.090, 2.090, 2.090, 2.090}; +const double signalRegionLeftDefault[nPtBinsCorrelations] = {1.7948, 1.8198, 1.8198, 1.8148, 1.8148, 1.8048, 1.8048, 1.7948, 1.7948, 1.7898, 1.7848, 1.7598}; +const double signalRegionRightDefault[nPtBinsCorrelations] = {1.9098, 1.8998, 1.9048, 1.9048, 1.9148, 1.9248, 1.9298, 1.9348, 1.9398, 1.9298, 1.9398, 1.9198}; +const double sidebandLeftInnerDefault[nPtBinsCorrelations] = {1.7398, 1.7748, 1.7798, 1.7698, 1.7648, 1.7448, 1.7448, 1.7198, 1.7198, 1.7198, 1.7048, 1.6798}; +const double sidebandLeftOuterDefault[nPtBinsCorrelations] = {1.6298, 1.6898, 1.6948, 1.6748, 1.6648, 1.6248, 1.6198, 1.5748, 1.5748, 1.5798, 1.5448, 1.5198}; +const double sidebandRightInnerDefault[nPtBinsCorrelations] = {1.9648, 1.9448, 1.9448, 1.9548, 1.9648, 1.9848, 1.9948, 2.0098, 2.0148, 1.9998, 2.0248, 1.9998}; +const double sidebandRightOuterDefault[nPtBinsCorrelations] = {2.0748, 2.0248, 2.0298, 2.0448, 2.0648, 2.1048, 2.1148, 2.1548, 2.1648, 2.1398, 2.1848, 2.1598}; auto vecsignalRegionLeft = std::vector{signalRegionLeftDefault, signalRegionLeftDefault + nPtBinsCorrelations}; auto vecsignalRegionRight = std::vector{signalRegionRightDefault, signalRegionRightDefault + nPtBinsCorrelations}; auto vecSidebandLeftInner = std::vector{sidebandLeftInnerDefault, sidebandLeftInnerDefault + nPtBinsCorrelations}; diff --git a/PWGHF/HFC/Tasks/taskCorrelationDMesonPairsTesting.cxx b/PWGHF/HFC/Tasks/taskCorrelationDMesonPairsTesting.cxx new file mode 100644 index 00000000000..4d9f5880078 --- /dev/null +++ b/PWGHF/HFC/Tasks/taskCorrelationDMesonPairsTesting.cxx @@ -0,0 +1,186 @@ +// 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 taskCorrelationDMesonPairs.cxx +/// \brief D-Dbar analysis task - data-like, MC-reco and MC-kine analyses for D0 and DPlus pairs. +/// \note Temporary code for tests of D0-D0 correlations +/// +/// \author Andrea Tavira García , IJCLab Orsay + +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/runDataProcessing.h" + +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/Utils/utilsAnalysis.h" +#include "PWGHF/HFC/DataModel/DMesonPairsTablesTesting.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +namespace +{ +enum PairTypeSel { + DD = 0, // D0-D0 + DbarDbar, // D0bar-D0bar + DDbar, + DbarD +}; +} // namespace + +// string definitions, used for histogram axis labels +const char stringCorrelationPairs[180] = "D meson pair candidates 2D;inv. mass D_{1} (GeV/#it{c}^{2});inv. mass D_{2} (GeV/#it{c}^{2});#it{p}_{T}^{D_{1}} (GeV/#it{c});#it{p}_{T}^{D_{2}} (GeV/#it{c});#eta D_{1};#eta D_{2};"; +const char stringCorrelationPairsFinerBinning[194] = "D meson pair candidates 2D Finer Binning;inv. mass D_{1} (GeV/#it{c}^{2});inv. mass D_{2} (GeV/#it{c}^{2});#it{p}_{T}^{D_{1}} (GeV/#it{c});#it{p}_{T}^{D_{2}} (GeV/#it{c});#eta D_{1};#eta D_{2};"; + +// definition of vectors for standard ptbin and invariant mass configurables +const int nPtBinsCorrelations = 8; +const double ptBinsCorrelations[nPtBinsCorrelations + 1] = {0., 2., 4., 6., 8., 12., 16., 24., 99.}; +auto vecPtBinsCorrelations = std::vector{ptBinsCorrelations, ptBinsCorrelations + nPtBinsCorrelations + 1}; + +struct HfTaskCorrelationDMesonPairsTesting { + // Enable histograms with finer pT and y binning + Configurable enableFinerBinning{"enableFinerBinning", false, "Enable histograms with finer pT and y binning"}; + Configurable> binsPtCorrelations{"binsPtCorrelations", std::vector{vecPtBinsCorrelations}, "pT bin limits for correlation plots"}; + + // HistoTypes + HistogramConfigSpec hTHnMass2DCorrPairs{HistType::kTHnSparseD, {{200, 1.6, 2.1}, {200, 1.6, 2.1}, {10, 0., 10.}, {10, 0., 10.}, {10, -1, 1}, {10, -1, 1}}}; // note: axes 3 and 4 (the pT) are updated in the init(); + HistogramConfigSpec hTHnMass2DCorrPairsFinerBinning{HistType::kTHnSparseD, {{200, 1.6, 2.1}, {200, 1.6, 2.1}, {60, 1., 6.}, {60, 1., 6.}, {160, -0.8, 0.8}, {160, -0.8, 0.8}}}; + + HistogramRegistry registry{ + "registry", + {{"hMass2DCorrelationPairsLS", stringCorrelationPairs, hTHnMass2DCorrPairs}, + {"hMass2DCorrelationPairsOS", stringCorrelationPairs, hTHnMass2DCorrPairs}, + {"hMass2DCorrelationPairsLSMcGen", stringCorrelationPairs, hTHnMass2DCorrPairs}, + {"hMass2DCorrelationPairsOSMcGen", stringCorrelationPairs, hTHnMass2DCorrPairs}}}; + + void init(InitContext&) + { + // redefinition of pT axes for THnSparse holding correlation entries + int nBinspTaxis = binsPtCorrelations->size() - 1; + const double* valuespTaxis = binsPtCorrelations->data(); + + if (enableFinerBinning) { + registry.add("hMass2DCorrelationPairsLSFinerBinning", stringCorrelationPairsFinerBinning, hTHnMass2DCorrPairsFinerBinning); + registry.get(HIST("hMass2DCorrelationPairsLSFinerBinning"))->Sumw2(); + registry.add("hMass2DCorrelationPairsOSFinerBinning", stringCorrelationPairsFinerBinning, hTHnMass2DCorrPairsFinerBinning); + registry.get(HIST("hMass2DCorrelationPairsOSFinerBinning"))->Sumw2(); + + registry.add("hMass2DCorrelationPairsLSMcGenFinerBinning", stringCorrelationPairsFinerBinning, hTHnMass2DCorrPairsFinerBinning); + registry.get(HIST("hMass2DCorrelationPairsLSMcGenFinerBinning"))->Sumw2(); + registry.add("hMass2DCorrelationPairsOSMcGenFinerBinning", stringCorrelationPairsFinerBinning, hTHnMass2DCorrPairsFinerBinning); + registry.get(HIST("hMass2DCorrelationPairsOSMcGenFinerBinning"))->Sumw2(); + } + + for (int i = 2; i <= 3; i++) { + registry.get(HIST("hMass2DCorrelationPairsLS"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hMass2DCorrelationPairsLS"))->Sumw2(); + registry.get(HIST("hMass2DCorrelationPairsOS"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hMass2DCorrelationPairsOS"))->Sumw2(); + + registry.get(HIST("hMass2DCorrelationPairsLSMcGen"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hMass2DCorrelationPairsLSMcGen"))->Sumw2(); + registry.get(HIST("hMass2DCorrelationPairsOSMcGen"))->GetAxis(i)->Set(nBinspTaxis, valuespTaxis); + registry.get(HIST("hMass2DCorrelationPairsOSMcGen"))->Sumw2(); + } + } + + void processData(aod::D0PairTesting const& pairEntries) + { + for (const auto& pairEntry : pairEntries) { + // define variables for widely used quantities + float ptCand1 = pairEntry.ptCand1(); + float ptCand2 = pairEntry.ptCand2(); + float massDCand1 = pairEntry.mDCand1(); + float massDbarCand1 = pairEntry.mDbarCand1(); + float massDCand2 = pairEntry.mDCand2(); + float massDbarCand2 = pairEntry.mDbarCand2(); + float yCand1 = pairEntry.yCand1(); + float yCand2 = pairEntry.yCand2(); + auto pairType = pairEntry.pairType(); + + if (TESTBIT(pairType, DD)) { + registry.fill(HIST("hMass2DCorrelationPairsLS"), massDCand1, massDCand2, ptCand1, ptCand2, yCand1, yCand2); + if (enableFinerBinning) { + registry.fill(HIST("hMass2DCorrelationPairsLSFinerBinning"), massDCand1, massDCand2, ptCand1, ptCand2, yCand1, yCand2); + } + } + if (TESTBIT(pairType, DbarDbar)) { + registry.fill(HIST("hMass2DCorrelationPairsLS"), massDbarCand1, massDbarCand2, ptCand1, ptCand2, yCand1, yCand2); + if (enableFinerBinning) { + registry.fill(HIST("hMass2DCorrelationPairsLSFinerBinning"), massDbarCand1, massDbarCand2, ptCand1, ptCand2, yCand1, yCand2); + } + } + + if (TESTBIT(pairType, DDbar)) { + registry.fill(HIST("hMass2DCorrelationPairsOS"), massDCand1, massDbarCand2, ptCand1, ptCand2, yCand1, yCand2); + if (enableFinerBinning) { + registry.fill(HIST("hMass2DCorrelationPairsOSFinerBinning"), massDCand1, massDbarCand2, ptCand1, ptCand2, yCand1, yCand2); + } + } + if (TESTBIT(pairType, DbarD)) { + registry.fill(HIST("hMass2DCorrelationPairsOS"), massDbarCand1, massDCand2, ptCand1, ptCand2, yCand1, yCand2); + if (enableFinerBinning) { + registry.fill(HIST("hMass2DCorrelationPairsOSFinerBinning"), massDbarCand1, massDCand2, ptCand1, ptCand2, yCand1, yCand2); + } + } + } + } + PROCESS_SWITCH(HfTaskCorrelationDMesonPairsTesting, processData, "Process data mode", true); + + void processMcGen(aod::D0PairMcGenTesting const& pairEntries) + { + for (const auto& pairEntry : pairEntries) { + // define variables for widely used quantities + double ptParticle1 = pairEntry.ptCand1(); + double ptParticle2 = pairEntry.ptCand2(); + float massDParticle1 = pairEntry.mDCand1(); + float massDbarParticle1 = pairEntry.mDbarCand1(); + float massDParticle2 = pairEntry.mDCand2(); + float massDbarParticle2 = pairEntry.mDbarCand2(); + float yParticle1 = pairEntry.yCand1(); + float yParticle2 = pairEntry.yCand2(); + auto pairType = pairEntry.pairType(); + + if (TESTBIT(pairType, DD)) { + registry.fill(HIST("hMass2DCorrelationPairsLSMcGen"), massDParticle1, massDParticle2, ptParticle1, ptParticle2, yParticle1, yParticle2); + if (enableFinerBinning) { + registry.fill(HIST("hMass2DCorrelationPairsLSMcGenFinerBinning"), massDParticle1, massDParticle2, ptParticle1, ptParticle2, yParticle1, yParticle2); + } + } + if (TESTBIT(pairType, DbarDbar)) { + registry.fill(HIST("hMass2DCorrelationPairsLSMcGen"), massDbarParticle1, massDbarParticle2, ptParticle1, ptParticle2, yParticle1, yParticle2); + if (enableFinerBinning) { + registry.fill(HIST("hMass2DCorrelationPairsLSMcGenFinerBinning"), massDbarParticle1, massDbarParticle2, ptParticle1, ptParticle2, yParticle1, yParticle2); + } + } + if (TESTBIT(pairType, DDbar)) { + registry.fill(HIST("hMass2DCorrelationPairsOSMcGen"), massDParticle1, massDbarParticle2, ptParticle1, ptParticle2, yParticle1, yParticle2); + if (enableFinerBinning) { + registry.fill(HIST("hMass2DCorrelationPairsOSMcGenFinerBinning"), massDParticle1, massDbarParticle2, ptParticle1, ptParticle2, yParticle1, yParticle2); + } + } + if (TESTBIT(pairType, DbarD)) { + registry.fill(HIST("hMass2DCorrelationPairsOSMcGen"), massDbarParticle1, massDParticle2, ptParticle1, ptParticle2, yParticle1, yParticle2); + if (enableFinerBinning) { + registry.fill(HIST("hMass2DCorrelationPairsOSMcGenFinerBinning"), massDbarParticle1, massDParticle2, ptParticle1, ptParticle2, yParticle1, yParticle2); + } + } + } + } + PROCESS_SWITCH(HfTaskCorrelationDMesonPairsTesting, processMcGen, "Process MC Gen mode", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGHF/TableProducer/CMakeLists.txt b/PWGHF/TableProducer/CMakeLists.txt index fe7ee5c6222..a687a12b7e7 100644 --- a/PWGHF/TableProducer/CMakeLists.txt +++ b/PWGHF/TableProducer/CMakeLists.txt @@ -122,7 +122,7 @@ o2physics_add_dpl_workflow(candidate-selector-lb-to-lc-pi o2physics_add_dpl_workflow(candidate-selector-lc SOURCES candidateSelectorLc.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2Physics::MLCore COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(candidate-selector-lc-pid-ml diff --git a/PWGHF/TableProducer/candidateCreatorDstar.cxx b/PWGHF/TableProducer/candidateCreatorDstar.cxx index da2acba4396..b7c88135221 100644 --- a/PWGHF/TableProducer/candidateCreatorDstar.cxx +++ b/PWGHF/TableProducer/candidateCreatorDstar.cxx @@ -255,9 +255,10 @@ struct HfCandidateCreatorDstar { // D0 pt magnitude auto ptD0 = RecoDecay::pt(pVecD0); - // Soft pi momentum vector + // Soft pi momentum vector and sign std::array pVecSoftPi; trackPiParVar.getPxPyPzGlo(pVecSoftPi); + int8_t signSoftPi = static_cast(trackPi.sign()); // D* pt magnitude auto ptDstar = RecoDecay::pt(pVecD0, pVecSoftPi); @@ -267,6 +268,7 @@ struct HfCandidateCreatorDstar { primaryVertex.getX(), primaryVertex.getY(), primaryVertex.getZ(), rowTrackIndexDstar.prong0Id(), rowTrackIndexDstar.prongD0Id(), pVecSoftPi[0], pVecSoftPi[1], pVecSoftPi[2], + signSoftPi, impactParameterPi.getY(), std::sqrt(impactParameterPi.getSigmaY2()), pVecD0Prong0[0], pVecD0Prong0[1], pVecD0Prong0[2], pVecD0Prong1[0], pVecD0Prong1[1], pVecD0Prong1[2]); diff --git a/PWGHF/TableProducer/candidateCreatorToXiPi.cxx b/PWGHF/TableProducer/candidateCreatorToXiPi.cxx index 89c3ef83fe3..3f8915c2406 100644 --- a/PWGHF/TableProducer/candidateCreatorToXiPi.cxx +++ b/PWGHF/TableProducer/candidateCreatorToXiPi.cxx @@ -209,7 +209,6 @@ struct HfCandidateCreatorToXiPi { hFitterStatus->Fill(0); hCandidateCounter->Fill(2); auto vertexCharmBaryonFromFitter = df.getPCACandidate(); - auto chi2PCACharmBaryon = df.getChi2AtPCACandidate(); std::array pVecCascAsD; std::array pVecPionFromCharmBaryon; df.propagateTracksToVertex(); @@ -301,7 +300,7 @@ struct HfCandidateCreatorToXiPi { vertexCasc[0], vertexCasc[1], vertexCasc[2], vertexV0[0], vertexV0[1], vertexV0[2], trackXiDauCharged.sign(), - chi2PCACharmBaryon, covVtxCharmBaryon[0], covVtxCharmBaryon[1], covVtxCharmBaryon[2], covVtxCharmBaryon[3], covVtxCharmBaryon[4], covVtxCharmBaryon[5], + covVtxCharmBaryon[0], covVtxCharmBaryon[1], covVtxCharmBaryon[2], covVtxCharmBaryon[3], covVtxCharmBaryon[4], covVtxCharmBaryon[5], pVecCharmBaryon[0], pVecCharmBaryon[1], pVecCharmBaryon[2], pVecCasc[0], pVecCasc[1], pVecCasc[2], pVecPionFromCharmBaryon[0], pVecPionFromCharmBaryon[1], pVecPionFromCharmBaryon[2], diff --git a/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx b/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx index a919affba3c..c11f1d73034 100644 --- a/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx +++ b/PWGHF/TableProducer/candidateSelectorDstarToD0Pi.cxx @@ -137,7 +137,7 @@ struct HfCandidateSelectorDstarToD0Pi { if (candidate.chi2PCAD0() > cutsDstar->get(binPt, "chi2PCA")) { return false; } - if (candidate.impactParameterXYD0() > cutsD0->get(binPt, "DCA")) { + if (std::abs(candidate.impactParameterXYD0()) > cutsD0->get(binPt, "DCA")) { return false; } // d0Prong0Normalised,1 @@ -287,19 +287,19 @@ struct HfCandidateSelectorDstarToD0Pi { { // LOG(info) << "selector called"; for (const auto& candDstar : rowsDstarCand) { - // final selection flag: 0 - rejected, 1 - accepted - int statusDstar = 0, statusD0Flag = 0, statusTopol = 0, statusCand = 0, statusPID = 0; + // final selection flag: false - rejected, true - accepted + bool statusDstar = false, statusD0Flag = false, statusTopol = false, statusCand = false, statusPID = false; - if (!(candDstar.hfflag() & 1 << aod::hf_cand_2prong::DecayType::D0ToPiK)) { + if (!TESTBIT(candDstar.hfflag(), aod::hf_cand_2prong::DecayType::D0ToPiK)) { hfSelDstarCandidate(statusDstar, statusD0Flag, statusTopol, statusCand, statusPID); continue; } - statusD0Flag = 1; + statusD0Flag = true; if (!selectionDstar(candDstar)) { hfSelDstarCandidate(statusDstar, statusD0Flag, statusTopol, statusCand, statusPID); continue; } - statusTopol = 1; + statusTopol = true; // implement filter bit 4 cut - should be done before this task at the track selection level // need to add special cuts (additional cuts on decay length and d0 norm) @@ -309,7 +309,7 @@ struct HfCandidateSelectorDstarToD0Pi { hfSelDstarCandidate(statusDstar, statusD0Flag, statusTopol, statusCand, statusPID); continue; } - statusCand = 1; + statusCand = true; // track-level PID selection int pidTrackPosKaon = -1; @@ -350,10 +350,10 @@ struct HfCandidateSelectorDstarToD0Pi { } if ((pidDstar == -1 || pidDstar == 1) && topoDstar) { - statusDstar = 1; // identified as dstar + statusDstar = true; // identified as dstar } - statusPID = 1; + statusPID = true; hfSelDstarCandidate(statusDstar, statusD0Flag, statusTopol, statusCand, statusPID); } } diff --git a/PWGHF/TableProducer/candidateSelectorLc.cxx b/PWGHF/TableProducer/candidateSelectorLc.cxx index 1de65bed0a7..ecb7156e6cf 100644 --- a/PWGHF/TableProducer/candidateSelectorLc.cxx +++ b/PWGHF/TableProducer/candidateSelectorLc.cxx @@ -15,6 +15,7 @@ /// \author Luigi Dello Stritto , University and INFN SALERNO /// \author Nima Zardoshti , CERN /// \author Vít Kučera , CERN +/// \author Grazia Luparello , INFN Trieste #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" @@ -23,6 +24,7 @@ #include "Common/Core/TrackSelectorPID.h" #include "PWGHF/Core/HfHelper.h" +#include "PWGHF/Core/HfMlResponseLcToPKPi.h" #include "PWGHF/Core/SelectorCuts.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" #include "PWGHF/DataModel/CandidateSelectionTables.h" @@ -31,9 +33,17 @@ using namespace o2; using namespace o2::analysis; using namespace o2::framework; +/// Struct to extend TracksPid tables +struct HfCandidateSelectorLcExpressions { + Spawns rowTracksPidFullPr; + Spawns rowTracksPidFullKa; + Spawns rowTracksPidFullPi; +}; + /// Struct for applying Lc selection cuts struct HfCandidateSelectorLc { Produces hfSelLcCandidate; + Produces hfMlLcToPKPiCandidate; Configurable ptCandMin{"ptCandMin", 0., "Lower bound of candidate pT"}; Configurable ptCandMax{"ptCandMax", 36., "Upper bound of candidate pT"}; @@ -57,16 +67,37 @@ struct HfCandidateSelectorLc { // topological cuts Configurable> binsPt{"binsPt", std::vector{hf_cuts_lc_to_p_k_pi::vecBinsPt}, "pT bin limits"}; Configurable> cuts{"cuts", {hf_cuts_lc_to_p_k_pi::cuts[0], hf_cuts_lc_to_p_k_pi::nBinsPt, hf_cuts_lc_to_p_k_pi::nCutVars, hf_cuts_lc_to_p_k_pi::labelsPt, hf_cuts_lc_to_p_k_pi::labelsCutVar}, "Lc candidate selection per pT bin"}; + // QA switch + Configurable activateQA{"activateQA", false, "Flag to enable QA histogram"}; + // ML inference + Configurable applyMl{"applyMl", false, "Flag to apply ML selections"}; + 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"}; + Configurable nClassesMl{"nClassesMl", (int8_t)hf_cuts_ml::nCutScores, "Number of classes in ML model"}; + Configurable> namesInputFeatures{"namesInputFeatures", std::vector{"feature1", "feature2"}, "Names of ML model input features"}; + // CCDB configuration + Configurable ccdbUrl{"ccdbUrl", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; + Configurable> modelPathsCCDB{"modelPathsCCDB", std::vector{"EventFiltering/PWGHF/BDTLc"}, "Paths of models on CCDB"}; + Configurable> onnxFileNames{"onnxFileNames", std::vector{"ModelHandler_onnx_LcToPKPi.onnx"}, "ONNX file names for each pT bin (if not from CCDB full path)"}; + 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"}; HfHelper hfHelper; + o2::analysis::HfMlResponseLcToPKPi hfMlResponse; + std::vector outputMlLcToPKPi = {}; + std::vector outputMlLcToPiKP = {}; + o2::ccdb::CcdbApi ccdbApi; TrackSelectorPi selectorPion; TrackSelectorKa selectorKaon; TrackSelectorPr selectorProton; using TracksSel = soa::Join; + HistogramRegistry registry{"registry"}; + void init(InitContext const&) { selectorPion.setRangePtTpc(ptPidTpcMin, ptPidTpcMax); @@ -78,6 +109,33 @@ struct HfCandidateSelectorLc { selectorPion.setRangePtBayes(ptPidBayesMin, ptPidBayesMax); selectorKaon = selectorPion; selectorProton = selectorPion; + + if (activateQA) { + constexpr int kNBinsSelections = 1 + aod::SelectionStep::NSelectionSteps; + std::string labels[kNBinsSelections]; + labels[0] = "No selection"; + labels[1 + aod::SelectionStep::RecoSkims] = "Skims selection"; + labels[1 + aod::SelectionStep::RecoTopol] = "Skims & Topological selections"; + labels[1 + aod::SelectionStep::RecoPID] = "Skims & Topological & PID selections"; + labels[1 + aod::SelectionStep::RecoMl] = "ML selection"; + static const AxisSpec axisSelections = {kNBinsSelections, 0.5, kNBinsSelections + 0.5, ""}; + registry.add("hSelections", "Selections;;#it{p}_{T} (GeV/#it{c})", {HistType::kTH2F, {axisSelections, {(std::vector)binsPt, "#it{p}_{T} (GeV/#it{c})"}}}); + for (int iBin = 0; iBin < kNBinsSelections; ++iBin) { + registry.get(HIST("hSelections"))->GetXaxis()->SetBinLabel(iBin + 1, labels[iBin].data()); + } + } + + if (applyMl) { + hfMlResponse.configure(binsPtMl, cutsMl, cutDirMl, nClassesMl); + if (loadModelsFromCCDB) { + ccdbApi.init(ccdbUrl); + hfMlResponse.setModelPathsCCDB(onnxFileNames, ccdbApi, modelPathsCCDB, timestampCCDB); + } else { + hfMlResponse.setModelPathsLocal(onnxFileNames); + } + hfMlResponse.cacheInputFeaturesIndices(namesInputFeatures); + hfMlResponse.init(); + } } /// Conjugate-independent topological cuts @@ -154,15 +212,30 @@ struct HfCandidateSelectorLc { // looping over 3-prong candidates for (const auto& candidate : candidates) { - // final selection flag: 0 - rejected, 1 - accepted + // final selection flag auto statusLcToPKPi = 0; auto statusLcToPiKP = 0; + outputMlLcToPKPi.clear(); + outputMlLcToPiKP.clear(); + + auto ptCand = candidate.pt(); + if (!(candidate.hfflag() & 1 << aod::hf_cand_3prong::DecayType::LcToPKPi)) { hfSelLcCandidate(statusLcToPKPi, statusLcToPiKP); + if (applyMl) { + hfMlLcToPKPiCandidate(outputMlLcToPKPi, outputMlLcToPiKP); + } + if (activateQA) { + registry.fill(HIST("hSelections"), 1, ptCand); + } continue; } + if (activateQA) { + registry.fill(HIST("hSelections"), 2 + aod::SelectionStep::RecoSkims, ptCand); + } + auto trackPos1 = candidate.prong0_as(); // positive daughter (negative for the antiparticles) auto trackNeg = candidate.prong1_as(); // negative daughter (positive for the antiparticles) auto trackPos2 = candidate.prong2_as(); // positive daughter (negative for the antiparticles) @@ -172,6 +245,9 @@ struct HfCandidateSelectorLc { // conjugate-independent topological selection if (!selectionTopol(candidate)) { hfSelLcCandidate(statusLcToPKPi, statusLcToPiKP); + if (applyMl) { + hfMlLcToPKPiCandidate(outputMlLcToPKPi, outputMlLcToPiKP); + } continue; } @@ -182,9 +258,16 @@ struct HfCandidateSelectorLc { if (!topolLcToPKPi && !topolLcToPiKP) { hfSelLcCandidate(statusLcToPKPi, statusLcToPiKP); + if (applyMl) { + hfMlLcToPKPiCandidate(outputMlLcToPKPi, outputMlLcToPiKP); + } continue; } + if (activateQA) { + registry.fill(HIST("hSelections"), 2 + aod::SelectionStep::RecoTopol, candidate.pt()); + } + auto pidLcToPKPi = -1; auto pidLcToPiKP = -1; auto pidBayesLcToPKPi = -1; @@ -268,8 +351,14 @@ struct HfCandidateSelectorLc { if (pidLcToPKPi == 0 && pidLcToPiKP == 0) { hfSelLcCandidate(statusLcToPKPi, statusLcToPiKP); + if (applyMl) { + hfMlLcToPKPiCandidate(outputMlLcToPKPi, outputMlLcToPiKP); + } continue; } + if (activateQA) { + registry.fill(HIST("hSelections"), 2 + aod::SelectionStep::RecoPID, candidate.pt()); + } if (pidBayesLcToPKPi == 0 && pidBayesLcToPiKP == 0) { hfSelLcCandidate(statusLcToPKPi, statusLcToPiKP); @@ -283,6 +372,32 @@ struct HfCandidateSelectorLc { statusLcToPiKP = 1; // identified as LcToPiKP } + if (applyMl) { + // ML selections + bool isSelectedMlLcToPKPi = false; + bool isSelectedMlLcToPiKP = false; + + if ((pidLcToPKPi == -1 || pidLcToPKPi == 1) && (pidBayesLcToPKPi == -1 || pidBayesLcToPKPi == 1) && topolLcToPKPi) { + std::vector inputFeaturesLcToPKPi = hfMlResponse.getInputFeatures(candidate, trackPos1, trackNeg, trackPos2); + isSelectedMlLcToPKPi = hfMlResponse.isSelectedMl(inputFeaturesLcToPKPi, candidate.pt(), outputMlLcToPKPi); + } + if ((pidLcToPiKP == -1 || pidLcToPiKP == 1) && (pidBayesLcToPiKP == -1 || pidBayesLcToPiKP == 1) && topolLcToPiKP) { + std::vector inputFeaturesLcToPiKP = hfMlResponse.getInputFeatures(candidate, trackPos1, trackNeg, trackPos2); + isSelectedMlLcToPiKP = hfMlResponse.isSelectedMl(inputFeaturesLcToPiKP, candidate.pt(), outputMlLcToPiKP); + } + + hfMlLcToPKPiCandidate(outputMlLcToPKPi, outputMlLcToPiKP); + + if (!isSelectedMlLcToPKPi && !isSelectedMlLcToPiKP) { + hfSelLcCandidate(statusLcToPKPi, statusLcToPiKP); + continue; + } + + if (activateQA) { + registry.fill(HIST("hSelections"), 2 + aod::SelectionStep::RecoMl, candidate.pt()); + } + } + hfSelLcCandidate(statusLcToPKPi, statusLcToPiKP); } } @@ -291,5 +406,6 @@ struct HfCandidateSelectorLc { WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{ + adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc)}; } diff --git a/PWGHF/TableProducer/trackIndexSkimCreator.cxx b/PWGHF/TableProducer/trackIndexSkimCreator.cxx index 19b3717a926..7c9c425e724 100644 --- a/PWGHF/TableProducer/trackIndexSkimCreator.cxx +++ b/PWGHF/TableProducer/trackIndexSkimCreator.cxx @@ -380,7 +380,6 @@ struct HfTrackIndexSkimCreatorTagSelTracks { Configurable useIsQualityTrackITSForBachLfCasc{"useIsQualityTrackITSForBachLfCasc", true, "check isQualityTrackITS status for bachelor in cascade + bachelor decays"}; // soft pion cuts for D* Configurable ptMinSoftPionForDstar{"ptMinSoftPionForDstar", 0.05, "min. track pT for soft pion in D* candidate"}; - Configurable ptMaxSoftPionForDstar{"ptMaxSoftPionForDstar", 2., "max. track pT for soft pion in D* candidate"}; Configurable etaMinSoftPionForDstar{"etaMinSoftPionForDstar", -99999., "min. pseudorapidity for soft pion in D* candidate"}; Configurable etaMaxSoftPionForDstar{"etaMaxSoftPionForDstar", 0.8, "max. pseudorapidity for soft pion in D* candidate"}; Configurable> cutsTrackDstar{"cutsTrackDstar", {hf_cuts_single_track::cutsTrackPrimary[0], hf_cuts_single_track::nBinsPtTrack, hf_cuts_single_track::nCutVarsTrack, hf_cuts_single_track::labelsPtTrack, hf_cuts_single_track::labelsCutVarTrack}, "Single-track selections per pT bin for the soft pion of D* candidates"}; @@ -619,7 +618,7 @@ struct HfTrackIndexSkimCreatorTagSelTracks { registry.fill(HIST("hRejTracks"), (nCuts + 1) * CandidateType::CandV0bachelor + iCut); } } - if (trackPt < ptMinSoftPionForDstar || trackPt > ptMaxSoftPionForDstar) { + if (trackPt < ptMinSoftPionForDstar) { CLRBIT(statusProng, CandidateType::CandDstar); if (fillHistograms) { registry.fill(HIST("hRejTracks"), (nCuts + 1) * CandidateType::CandDstar + iCut); @@ -1073,7 +1072,8 @@ struct HfTrackIndexSkimCreatorTagSelTracks { isSelectedTrack(track, trackPt, trackEta, pvRefitDcaXYDcaZ, statusProng); int8_t isProton = isSelectedProton(track); - rowSelectedTrack(statusProng, isProton); + bool isPositive = track.sign() > 0; + rowSelectedTrack(statusProng, isProton, isPositive); } } @@ -1264,6 +1264,8 @@ struct HfTrackIndexSkimCreatorTagSelTracks { /// Pre-selection of 2-prong and 3-prong secondary vertices struct HfTrackIndexSkimCreator { + SliceCache cache; + Produces rowTrackIndexProng2; Produces rowProng2CutStatus; Produces rowProng2PVrefit; @@ -1369,12 +1371,14 @@ struct HfTrackIndexSkimCreator { Preslice tracksPerCollision = aod::track::collisionId; // needed for PV refit // filter track indices - Filter filterSelectTrackIds = (aod::hf_sel_track::isSelProng > 0); + 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); Preslice trackIndicesPerCollision = aod::track_association::collisionId; - // FIXME - // Partition tracksPos = aod::track::signed1Pt > 0.f; - // Partition tracksNeg = aod::track::signed1Pt < 0.f; + // define partitions + Partition positiveFor2And3Prongs = aod::hf_sel_track::isPositive == true && (((aod::hf_sel_track::isSelProng & static_cast(BIT(CandidateType::Cand2Prong))) != 0u) || ((aod::hf_sel_track::isSelProng & static_cast(BIT(CandidateType::Cand3Prong))) != 0u)); + Partition negativeFor2And3Prongs = aod::hf_sel_track::isPositive == false && (((aod::hf_sel_track::isSelProng & static_cast(BIT(CandidateType::Cand2Prong))) != 0u) || ((aod::hf_sel_track::isSelProng & static_cast(BIT(CandidateType::Cand3Prong))) != 0u)); + Partition positiveSoftPions = aod::hf_sel_track::isPositive == true && ((aod::hf_sel_track::isSelProng & static_cast(BIT(CandidateType::CandDstar))) != 0u); + Partition negativeSoftPions = aod::hf_sel_track::isPositive == false && ((aod::hf_sel_track::isSelProng & static_cast(BIT(CandidateType::CandDstar))) != 0u); // QA of PV refit ConfigurableAxis axisPvRefitDeltaX{"axisPvRefitDeltaX", {1000, -0.5f, 0.5f}, "DeltaX binning PV refit"}; @@ -1493,9 +1497,10 @@ struct HfTrackIndexSkimCreator { /// \param dcaTrack1 is the dcaXY of the second daughter track /// \param cutStatus is a 2D array with outcome of each selection (filled only in debug mode) /// \param whichHypo information of the mass hypoteses that were selected - /// \param isSelected ia s bitmap with selection outcome + /// \param isSelected is a bitmap with selection outcome + /// \param pt2Prong is the pt of the 2-prong candidate template - void is2ProngPreselected(T1 const& pVecTrack0, T1 const& pVecTrack1, T2 const& dcaTrack0, T2 const& dcaTrack1, T3& cutStatus, T4& whichHypo, int& isSelected) + void is2ProngPreselected(T1 const& pVecTrack0, T1 const& pVecTrack1, T2 const& dcaTrack0, T2 const& dcaTrack1, T3& cutStatus, T4& whichHypo, int& isSelected, float& pt2Prong) { /// FIXME: this would be better fixed by having a convention on the position of min and max in the 2D Array static std::vector massMinIndex; @@ -1514,8 +1519,17 @@ struct HfTrackIndexSkimCreator { }; cacheIndices(cut2Prong, massMinIndex, massMaxIndex, d0d0Index); + int deltaMassD0Index; + static auto cacheIndicesForDstar = [](LabeledArray& cutDstar, int& deltaMassD0Idx) { + deltaMassD0Idx = cutDstar.colmap.find("deltaMassD0")->second; + return true; + }; + cacheIndicesForDstar(cutsDstarToD0Pi.value, deltaMassD0Index); + whichHypo[kN2ProngDecays] = 0; // D0 for D* + auto arrMom = std::array{pVecTrack0, pVecTrack1}; - auto pT = RecoDecay::pt(pVecTrack0, pVecTrack1) + ptTolerance; // add tolerance because of no reco decay vertex + pt2Prong = RecoDecay::pt(pVecTrack0, pVecTrack1); + auto pT = pt2Prong + ptTolerance; // add tolerance because of no reco decay vertex for (int iDecay2P = 0; iDecay2P < kN2ProngDecays; iDecay2P++) { @@ -1531,7 +1545,7 @@ struct HfTrackIndexSkimCreator { } // invariant mass - double massHypos[2]; + double massHypos[2] = {0.f, 0.f}; whichHypo[iDecay2P] = 3; double min2 = pow(cut2Prong[iDecay2P].get(pTBin, massMinIndex[iDecay2P]), 2); double max2 = pow(cut2Prong[iDecay2P].get(pTBin, massMaxIndex[iDecay2P]), 2); @@ -1563,6 +1577,22 @@ struct HfTrackIndexSkimCreator { } } } + + // additional check for D0 to be used in D* finding + if (iDecay2P == hf_cand_2prong::DecayType::D0ToPiK && doDstar && TESTBIT(isSelected, iDecay2P)) { + auto pTBinDstar = findBin(binsPtDstarToD0Pi, pT * 1.2); // assuming the D* pT about 20% higher than the one of the D0 to be safe + if (pTBinDstar >= 0) { + whichHypo[kN2ProngDecays] = whichHypo[hf_cand_2prong::DecayType::D0ToPiK]; + double deltaMass = cutsDstarToD0Pi->get(pTBinDstar, deltaMassD0Index); + + if (TESTBIT(whichHypo[iDecay2P], 0) && (massHypos[0] > (massDzero + deltaMass) * (massDzero + deltaMass) || massHypos[0] < (massDzero - deltaMass) * (massDzero - deltaMass))) { + CLRBIT(whichHypo[kN2ProngDecays], 0); + } + if (TESTBIT(whichHypo[iDecay2P], 1) && (massHypos[1] > (massDzero + deltaMass) * (massDzero + deltaMass) || massHypos[1] < (massDzero - deltaMass) * (massDzero - deltaMass))) { + CLRBIT(whichHypo[kN2ProngDecays], 1); + } + } + } } } @@ -2072,7 +2102,7 @@ struct HfTrackIndexSkimCreator { cutStatus3Prong[iDecay3P] = std::vector(kNCuts3Prong[iDecay3P], true); } - int whichHypo2Prong[kN2ProngDecays]; + int whichHypo2Prong[kN2ProngDecays + 1]; // we also put D0 for D* in the last slot int whichHypo3Prong[kN3ProngDecays]; // set the magnetic field from CCDB @@ -2110,28 +2140,18 @@ struct HfTrackIndexSkimCreator { // return; //} - // first loop over positive tracks - // for (auto trackPos1 = tracksPos.begin(); trackPos1 != tracksPos.end(); ++trackPos1) { - auto thisCollId = collision.globalIndex(); - auto groupedTrackIndices = trackIndices.sliceBy(trackIndicesPerCollision, thisCollId); + + // first loop over positive tracks + auto groupedTrackIndicesPos1 = positiveFor2And3Prongs->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); int lastFilledD0 = -1; // index to be filled in table for D* mesons - int counterTrackPos1{0}; - for (auto trackIndexPos1 = groupedTrackIndices.begin(); trackIndexPos1 != groupedTrackIndices.end(); ++trackIndexPos1) { - counterTrackPos1++; + for (auto trackIndexPos1 = groupedTrackIndicesPos1.begin(); trackIndexPos1 != groupedTrackIndicesPos1.end(); ++trackIndexPos1) { auto trackPos1 = trackIndexPos1.template track_as(); - if (trackPos1.signed1Pt() < 0) { - continue; - } - // retrieve the selection flag that corresponds to this collision auto isSelProngPos1 = trackIndexPos1.isSelProng(); bool sel2ProngStatusPos = TESTBIT(isSelProngPos1, CandidateType::Cand2Prong); bool sel3ProngStatusPos1 = TESTBIT(isSelProngPos1, CandidateType::Cand3Prong); - if (!sel2ProngStatusPos && !sel3ProngStatusPos1) { - continue; - } auto trackParVarPos1 = getTrackParCov(trackPos1); std::array pVecTrackPos1{trackPos1.px(), trackPos1.py(), trackPos1.pz()}; @@ -2142,22 +2162,14 @@ struct HfTrackIndexSkimCreator { } // first loop over negative tracks - // for (auto trackNeg1 = tracksNeg.begin(); trackNeg1 != tracksNeg.end(); ++trackNeg1) { - int counterTrackNeg1{0}; - for (auto trackIndexNeg1 = groupedTrackIndices.begin(); trackIndexNeg1 != groupedTrackIndices.end(); ++trackIndexNeg1) { - counterTrackNeg1++; + auto groupedTrackIndicesNeg1 = negativeFor2And3Prongs->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + for (auto trackIndexNeg1 = groupedTrackIndicesNeg1.begin(); trackIndexNeg1 != groupedTrackIndicesNeg1.end(); ++trackIndexNeg1) { auto trackNeg1 = trackIndexNeg1.template track_as(); - if (trackNeg1.signed1Pt() > 0) { - continue; - } // retrieve the selection flag that corresponds to this collision auto isSelProngNeg1 = trackIndexNeg1.isSelProng(); bool sel2ProngStatusNeg = TESTBIT(isSelProngNeg1, CandidateType::Cand2Prong); bool sel3ProngStatusNeg1 = TESTBIT(isSelProngNeg1, CandidateType::Cand3Prong); - if (!sel2ProngStatusNeg && !sel3ProngStatusNeg1) { - continue; - } auto trackParVarNeg1 = getTrackParCov(trackNeg1); std::array pVecTrackNeg1{trackNeg1.px(), trackNeg1.py(), trackNeg1.pz()}; @@ -2182,14 +2194,22 @@ struct HfTrackIndexSkimCreator { std::array pvRefitCovMatrix2Prong = getPrimaryVertex(collision).getCov(); /// initialize to the original PV // 2-prong vertex reconstruction + float pt2Prong{-1.}; if (sel2ProngStatusPos && sel2ProngStatusNeg) { // 2-prong preselections // TODO: in case of PV refit, the single-track DCA is calculated wrt two different PV vertices (only 1 track excluded) - is2ProngPreselected(pVecTrackPos1, pVecTrackNeg1, dcaInfoPos1[0], dcaInfoNeg1[0], cutStatus2Prong, whichHypo2Prong, isSelected2ProngCand); + is2ProngPreselected(pVecTrackPos1, pVecTrackNeg1, dcaInfoPos1[0], dcaInfoNeg1[0], cutStatus2Prong, whichHypo2Prong, isSelected2ProngCand, pt2Prong); // secondary vertex reconstruction and further 2-prong selections - if (isSelected2ProngCand > 0 && df2.process(trackParVarPos1, trackParVarNeg1) > 0) { // should it be this or > 0 or are they equivalent + int nVtxFrom2ProngFitter = 0; + try { + nVtxFrom2ProngFitter = df2.process(trackParVarPos1, trackParVarNeg1); + } catch (...) { + continue; + } + + if (isSelected2ProngCand > 0 && nVtxFrom2ProngFitter > 0) { // should it be this or > 0 or are they equivalent // get secondary vertex const auto& secondaryVertex2 = df2.getPCACandidate(); // get track momenta @@ -2333,64 +2353,20 @@ struct HfTrackIndexSkimCreator { isSelected2ProngCand = 0; // reset to 0 not to use the D0 to build a D* meson } - // 3-prong vertex and D* reconstruction - if (do3Prong == 1 || doDstar) { - if (!doDstar && (!sel3ProngStatusPos1 || !sel3ProngStatusNeg1)) { - continue; - } - + if (do3Prong == 1 && sel3ProngStatusPos1 && sel3ProngStatusNeg1) { // if 3 prongs are enabled and the first 2 tracks are selected for the 3-prong channels // second loop over positive tracks - // for (auto trackPos2 = trackPos1 + 1; trackPos2 != tracksPos.end(); ++trackPos2) { - int counterTrackPos2{0}; - auto startTrackIndexPos2 = (doDstar) ? groupedTrackIndices.begin() : trackIndexPos1 + 1; - for (auto trackIndexPos2 = startTrackIndexPos2; trackIndexPos2 != groupedTrackIndices.end(); ++trackIndexPos2) { - counterTrackPos2++; + for (auto trackIndexPos2 = trackIndexPos1 + 1; trackIndexPos2 != groupedTrackIndicesPos1.end(); ++trackIndexPos2) { + auto trackPos2 = trackIndexPos2.template track_as(); - if (trackPos2.signed1Pt() < 0) { - continue; - } auto trackParVarPos2 = getTrackParCov(trackPos2); std::array pVecTrackPos2{trackPos2.px(), trackPos2.py(), trackPos2.pz()}; o2::gpu::gpustd::array dcaInfoPos2{trackPos2.dcaXY(), trackPos2.dcaZ()}; - bool propagatedPos2{false}; - - // first we build D*+ candidates if enabled - auto isSelProngPos2 = trackIndexPos2.isSelProng(); - uint8_t isSelectedDstar{0}; - if (doDstar && TESTBIT(isSelected2ProngCand, hf_cand_2prong::DecayType::D0ToPiK) && TESTBIT(whichHypo2Prong[0], 0)) { // the 2-prong decay is compatible with a D0 - if (TESTBIT(isSelProngPos2, CandidateType::CandDstar) && trackPos2.globalIndex() != trackPos1.globalIndex()) { // compatible with a soft pion - if (thisCollId != trackPos2.collisionId()) { // this is not the "default" collision for this track, we have to re-propagate it - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParVarPos2, 2.f, noMatCorr, &dcaInfoPos2); - getPxPyPz(trackParVarPos2, pVecTrackPos2); - propagatedPos2 = true; - } - uint8_t cutStatus{BIT(kNCutsDstar) - 1}; - float deltaMass{-1.}; - isSelectedDstar = isDstarSelected(pVecTrackPos1, pVecTrackNeg1, pVecTrackPos2, cutStatus, deltaMass); // we do not compute the D* decay vertex at this stage because we are not interested in applying topological selections - if (isSelectedDstar) { - rowTrackIndexDstar(thisCollId, trackPos2.globalIndex(), lastFilledD0); - if (fillHistograms) { - registry.fill(HIST("hMassDstarToD0Pi"), deltaMass); - } - if constexpr (doPvRefit) { - // fill table row with coordinates of PV refit (same as 2-prong because we do not remove the soft pion) - rowDstarPVrefit(pvRefitCoord2Prong[0], pvRefitCoord2Prong[1], pvRefitCoord2Prong[2], - pvRefitCovMatrix2Prong[0], pvRefitCovMatrix2Prong[1], pvRefitCovMatrix2Prong[2], pvRefitCovMatrix2Prong[3], pvRefitCovMatrix2Prong[4], pvRefitCovMatrix2Prong[5]); - } - } - if (debug) { - rowDstarCutStatus(cutStatus); - } - } - } // end of D* // preselection of 3-prong candidates - if (doDstar && counterTrackPos2 < counterTrackPos1 + 1) { // we avoid duplication for 3-prongs - continue; - } int isSelected3ProngCand = n3ProngBit; - if (do3Prong && TESTBIT(isSelProngPos2, CandidateType::Cand3Prong) && (sel3ProngStatusPos1 && sel3ProngStatusNeg1)) { - if (thisCollId != trackPos2.collisionId() && !propagatedPos2) { // this is not the "default" collision for this track and we still did not re-propagate it, we have to re-propagate it + auto isSelProngPos2 = trackIndexPos2.isSelProng(); + if (TESTBIT(isSelProngPos2, CandidateType::Cand3Prong)) { + if (thisCollId != trackPos2.collisionId()) { // this is not the "default" collision for this track and we still did not re-propagate it, we have to re-propagate it o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParVarPos2, 2.f, noMatCorr, &dcaInfoPos2); getPxPyPz(trackParVarPos2, pVecTrackPos2); } @@ -2509,7 +2485,14 @@ struct HfTrackIndexSkimCreator { } // reconstruct the 3-prong secondary vertex - if (df3.process(trackParVarPos1, trackParVarNeg1, trackParVarPos2) == 0) { + int nVtxFrom3ProngFitter = 0; + try { + nVtxFrom3ProngFitter = df3.process(trackParVarPos1, trackParVarNeg1, trackParVarPos2); + } catch (...) { + continue; + } + + if (nVtxFrom3ProngFitter == 0) { continue; } // get secondary vertex @@ -2595,58 +2578,17 @@ struct HfTrackIndexSkimCreator { } // second loop over negative tracks - // for (auto trackNeg2 = trackNeg1 + 1; trackNeg2 != tracksNeg.end(); ++trackNeg2) { - int counterTrackNeg2{0}; - auto startTrackIndexNeg2 = (doDstar) ? groupedTrackIndices.begin() : trackIndexNeg1 + 1; - for (auto trackIndexNeg2 = startTrackIndexNeg2; trackIndexNeg2 != groupedTrackIndices.end(); ++trackIndexNeg2) { - counterTrackNeg2++; + for (auto trackIndexNeg2 = trackIndexNeg1 + 1; trackIndexNeg2 != groupedTrackIndicesNeg1.end(); ++trackIndexNeg2) { auto trackNeg2 = trackIndexNeg2.template track_as(); - if (trackNeg2.signed1Pt() > 0) { - continue; - } - auto trackParVarNeg2 = getTrackParCov(trackNeg2); std::array pVecTrackNeg2{trackNeg2.px(), trackNeg2.py(), trackNeg2.pz()}; o2::gpu::gpustd::array dcaInfoNeg2{trackNeg2.dcaXY(), trackNeg2.dcaZ()}; - bool propagatedNeg2{false}; - - // first we build D*+ candidates if enabled - auto isSelProngNeg2 = trackIndexNeg2.isSelProng(); - uint8_t isSelectedDstar{0}; - if (doDstar && TESTBIT(isSelected2ProngCand, hf_cand_2prong::DecayType::D0ToPiK) && TESTBIT(whichHypo2Prong[0], 1)) { // the 2-prong decay is compatible with a D0bar - if (TESTBIT(isSelProngNeg2, CandidateType::CandDstar) && trackNeg2.globalIndex() != trackNeg1.globalIndex()) { // compatible with a soft pion - if (thisCollId != trackNeg2.collisionId()) { // this is not the "default" collision for this track, we have to re-propagate it - o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParVarNeg2, 2.f, noMatCorr, &dcaInfoNeg2); - getPxPyPz(trackParVarNeg2, pVecTrackNeg2); - propagatedNeg2 = true; - } - uint8_t cutStatus{BIT(kNCutsDstar) - 1}; - float deltaMass{-1.}; - isSelectedDstar = isDstarSelected(pVecTrackNeg1, pVecTrackPos1, pVecTrackNeg2, cutStatus, deltaMass); // we do not compute the D* decay vertex at this stage because we are not interested in applying topological selections - if (isSelectedDstar) { - rowTrackIndexDstar(thisCollId, trackNeg2.globalIndex(), lastFilledD0); - if (fillHistograms) { - registry.fill(HIST("hMassDstarToD0Pi"), deltaMass); - } - if constexpr (doPvRefit) { - // fill table row with coordinates of PV refit (same as 2-prong because we do not remove the soft pion) - rowDstarPVrefit(pvRefitCoord2Prong[0], pvRefitCoord2Prong[1], pvRefitCoord2Prong[2], - pvRefitCovMatrix2Prong[0], pvRefitCovMatrix2Prong[1], pvRefitCovMatrix2Prong[2], pvRefitCovMatrix2Prong[3], pvRefitCovMatrix2Prong[4], pvRefitCovMatrix2Prong[5]); - } - } - if (debug) { - rowDstarCutStatus(cutStatus); - } - } - } // end of D* // preselection of 3-prong candidates - if (doDstar && counterTrackNeg2 < counterTrackNeg1 + 1) { // we avoid duplication for 3-prongs - continue; - } int isSelected3ProngCand = n3ProngBit; - if (do3Prong && TESTBIT(isSelProngNeg2, CandidateType::Cand3Prong) && (sel3ProngStatusPos1 && sel3ProngStatusNeg1)) { - if (thisCollId != trackNeg2.collisionId() && !propagatedNeg2) { // this is not the "default" collision for this track and we still did not re-propagate it, we have to re-propagate it + auto isSelProngNeg2 = trackIndexNeg2.isSelProng(); + if (TESTBIT(isSelProngNeg2, CandidateType::Cand3Prong)) { + if (thisCollId != trackNeg2.collisionId()) { // this is not the "default" collision for this track and we still did not re-propagate it, we have to re-propagate it o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParVarNeg2, 2.f, noMatCorr, &dcaInfoNeg2); getPxPyPz(trackParVarNeg2, pVecTrackNeg2); } @@ -2670,7 +2612,7 @@ struct HfTrackIndexSkimCreator { isSelected3ProngCand = 0; } - // if we did not preselected any D* or 3-prong candidate, continue + // if we did not preselected any 3-prong candidate, continue if (!debug && isSelected3ProngCand == 0) { continue; } @@ -2765,7 +2707,14 @@ struct HfTrackIndexSkimCreator { } // reconstruct the 3-prong secondary vertex - if (df3.process(trackParVarNeg1, trackParVarPos1, trackParVarNeg2) == 0) { + int nVtxFrom3ProngFitterSecondLoop = 0; + try { + nVtxFrom3ProngFitterSecondLoop = df3.process(trackParVarNeg1, trackParVarPos1, trackParVarNeg2); + } catch (...) { + continue; + } + + if (nVtxFrom3ProngFitterSecondLoop == 0) { continue; } // get secondary vertex @@ -2850,6 +2799,82 @@ struct HfTrackIndexSkimCreator { } } } + + if (doDstar && TESTBIT(isSelected2ProngCand, hf_cand_2prong::DecayType::D0ToPiK) && (pt2Prong + ptTolerance) * 1.2 > binsPtDstarToD0Pi->at(0) && whichHypo2Prong[kN2ProngDecays] != 0) { // if D* enabled and pt of the D0 is larger than the minimum of the D* one within 20% (D* and D0 momenta are very similar, always within 20% according to PYTHIA8) + // second loop over positive tracks + if (TESTBIT(whichHypo2Prong[kN2ProngDecays], 0)) { // only for D0 candidates + auto groupedTrackIndicesSoftPionsPos = positiveSoftPions->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + for (auto trackIndexPos2 = groupedTrackIndicesSoftPionsPos.begin(); trackIndexPos2 != groupedTrackIndicesSoftPionsPos.end(); ++trackIndexPos2) { + if (trackIndexPos2 == trackIndexPos1) { + continue; + } + auto trackPos2 = trackIndexPos2.template track_as(); + auto trackParVarPos2 = getTrackParCov(trackPos2); + std::array pVecTrackPos2{trackPos2.px(), trackPos2.py(), trackPos2.pz()}; + o2::gpu::gpustd::array dcaInfoPos2{trackPos2.dcaXY(), trackPos2.dcaZ()}; + if (thisCollId != trackPos2.collisionId()) { // this is not the "default" collision for this track, we have to re-propagate it + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParVarPos2, 2.f, noMatCorr, &dcaInfoPos2); + getPxPyPz(trackParVarPos2, pVecTrackPos2); + } + + uint8_t isSelectedDstar{0}; + uint8_t cutStatus{BIT(kNCutsDstar) - 1}; + float deltaMass{-1.}; + isSelectedDstar = isDstarSelected(pVecTrackPos1, pVecTrackNeg1, pVecTrackPos2, cutStatus, deltaMass); // we do not compute the D* decay vertex at this stage because we are not interested in applying topological selections + if (isSelectedDstar) { + rowTrackIndexDstar(thisCollId, trackPos2.globalIndex(), lastFilledD0); + if (fillHistograms) { + registry.fill(HIST("hMassDstarToD0Pi"), deltaMass); + } + if constexpr (doPvRefit) { + // fill table row with coordinates of PV refit (same as 2-prong because we do not remove the soft pion) + rowDstarPVrefit(pvRefitCoord2Prong[0], pvRefitCoord2Prong[1], pvRefitCoord2Prong[2], + pvRefitCovMatrix2Prong[0], pvRefitCovMatrix2Prong[1], pvRefitCovMatrix2Prong[2], pvRefitCovMatrix2Prong[3], pvRefitCovMatrix2Prong[4], pvRefitCovMatrix2Prong[5]); + } + } + if (debug) { + rowDstarCutStatus(cutStatus); + } + } + } + + // second loop over negative tracks + if (TESTBIT(whichHypo2Prong[kN2ProngDecays], 1)) { // only for D0bar candidates + auto groupedTrackIndicesSoftPionsNeg = negativeSoftPions->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + for (auto trackIndexNeg2 = groupedTrackIndicesSoftPionsNeg.begin(); trackIndexNeg2 != groupedTrackIndicesSoftPionsNeg.end(); ++trackIndexNeg2) { + if (trackIndexNeg1 == trackIndexNeg2) { + continue; + } + auto trackNeg2 = trackIndexNeg2.template track_as(); + auto trackParVarNeg2 = getTrackParCov(trackNeg2); + std::array pVecTrackNeg2{trackNeg2.px(), trackNeg2.py(), trackNeg2.pz()}; + o2::gpu::gpustd::array dcaInfoNeg2{trackNeg2.dcaXY(), trackNeg2.dcaZ()}; + if (thisCollId != trackNeg2.collisionId()) { // this is not the "default" collision for this track, we have to re-propagate it + o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, trackParVarNeg2, 2.f, noMatCorr, &dcaInfoNeg2); + getPxPyPz(trackParVarNeg2, pVecTrackNeg2); + } + + uint8_t isSelectedDstar{0}; + uint8_t cutStatus{BIT(kNCutsDstar) - 1}; + float deltaMass{-1.}; + isSelectedDstar = isDstarSelected(pVecTrackNeg1, pVecTrackPos1, pVecTrackNeg2, cutStatus, deltaMass); // we do not compute the D* decay vertex at this stage because we are not interested in applying topological selections + if (isSelectedDstar) { + rowTrackIndexDstar(thisCollId, trackNeg2.globalIndex(), lastFilledD0); + if (fillHistograms) { + registry.fill(HIST("hMassDstarToD0Pi"), deltaMass); + } + if constexpr (doPvRefit) { + // fill table row with coordinates of PV refit (same as 2-prong because we do not remove the soft pion) + rowDstarPVrefit(pvRefitCoord2Prong[0], pvRefitCoord2Prong[1], pvRefitCoord2Prong[2], + pvRefitCovMatrix2Prong[0], pvRefitCovMatrix2Prong[1], pvRefitCovMatrix2Prong[2], pvRefitCovMatrix2Prong[3], pvRefitCovMatrix2Prong[4], pvRefitCovMatrix2Prong[5]); + } + } + if (debug) { + rowDstarCutStatus(cutStatus); + } + } + } + } // end of D* } } @@ -2967,8 +2992,7 @@ struct HfTrackIndexSkimCreatorCascades { double mass2K0sP{0.}; // WHY HERE? Filter filterSelectCollisions = (aod::hf_sel_collision::whyRejectColl == 0); - Filter filterSelectTrackIds = (aod::hf_sel_track::isSelProng > 0); - // Partition TracksWithPVRefitAndDCA = aod::hf_sel_track::isSelProng >= 4; + Filter filterSelectTrackIds = (aod::hf_sel_track::isSelProng & static_cast(BIT(CandidateType::CandV0bachelor))) != 0u; using SelectedCollisions = soa::Filtered>; using FilteredTrackAssocSel = soa::Filtered>; @@ -3049,13 +3073,8 @@ struct HfTrackIndexSkimCreatorCascades { // selections on the bachelor - // // retrieve the selection flag that corresponds to this collision - auto isSelProngBach = bachIdx.isSelProng(); - // pT cut - if (!TESTBIT(isSelProngBach, CandidateType::CandV0bachelor)) { - continue; - } + // FIXME: this should go in the tag-sel-tracks if (tpcRefitBach) { if (!(bach.trackType() & o2::aod::track::TPCrefit)) { continue; @@ -3140,7 +3159,13 @@ struct HfTrackIndexSkimCreatorCascades { auto trackV0 = o2::dataformats::V0(vertexV0, momentumV0, {0, 0, 0, 0, 0, 0}, trackParCovV0DaughPos, trackParCovV0DaughNeg); // build the V0 track // now we find the DCA between the V0 and the bachelor, for the cascade - int nCand2 = fitter.process(trackV0, trackBach); + int nCand2 = 0; + try { + nCand2 = fitter.process(trackV0, trackBach); + } catch (...) { + continue; + } + if (nCand2 == 0) { continue; } @@ -3309,6 +3334,11 @@ struct HfTrackIndexSkimCreatorLfCascades { registry.add("hMassXicZeroOmegacZeroToXiPi", "2-prong candidates;inv. mass (#Xi #pi) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 2., 3.}}}); registry.add("hMassOmegacZeroToOmegaPi", "2-prong candidates;inv. mass (#Omega #pi) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 2., 3.}}}); registry.add("hMassXicPlusToXiPiPi", "3-prong candidates;inv. mass (#Xi #pi #pi) (GeV/#it{c}^{2});entries", {HistType::kTH1F, {{500, 2., 3.}}}); + + // dcaFitter exception counter + registry.add("hFitterStatusXi2Prong", "Charm DCAFitter status (xi hyp. - 2prong);status;entries", {HistType::kTH1D, {{2, -0.5, 1.5}}}); // 0 --> successful call of DCAFitter 1 --> exception found by DCAFitter + registry.add("hFitterStatusOmega2Prong", "Charm DCAFitter status (omega hyp. - 2prong);status;entries", {HistType::kTH1D, {{2, -0.5, 1.5}}}); // 0 --> successful call of DCAFitter 1 --> exception found by DCAFitter + registry.add("hFitterStatusXi3Prong", "Charm DCAFitter status (xi hyp. - 3prong);status;entries", {HistType::kTH1D, {{2, -0.5, 1.5}}}); // 0 --> successful call of DCAFitter 1 --> exception found by DCAFitter } } @@ -3318,7 +3348,7 @@ struct HfTrackIndexSkimCreatorLfCascades { using V0Full = soa::Join; Filter filterSelectCollisions = (aod::hf_sel_collision::whyRejectColl == 0); - Filter filterSelectTrackIds = (aod::hf_sel_track::isSelProng > 0); + Filter filterSelectTrackIds = (aod::hf_sel_track::isSelProng & static_cast(BIT(CandidateType::CandCascadeBachelor))) != 0u; Preslice tracksPerCollision = aod::track::collisionId; // needed for PV refit Preslice trackIndicesPerCollision = aod::track_association::collisionId; // aod::hf_track_association::collisionId @@ -3485,10 +3515,6 @@ struct HfTrackIndexSkimCreatorLfCascades { hfFlag = 0; - if (!TESTBIT(trackIdPion1.isSelProng(), CandidateType::CandCascadeBachelor)) { - continue; - } - auto trackPion1 = trackIdPion1.track_as(); if ((rejDiffCollTrack) && (trackXiDauCharged.collisionId() != trackPion1.collisionId())) { @@ -3509,7 +3535,19 @@ struct HfTrackIndexSkimCreatorLfCascades { auto trackParVarPion1 = getTrackParCov(trackPion1); // find charm baryon decay using xi PID hypothesis - int nVtxFrom2ProngFitterXiHyp = df2.process(trackCascXi2Prong, trackParVarPion1); + int nVtxFrom2ProngFitterXiHyp = 0; + try { + nVtxFrom2ProngFitterXiHyp = df2.process(trackCascXi2Prong, trackParVarPion1); + } catch (...) { + if (fillHistograms) { + registry.fill(HIST("hFitterStatusXi2Prong"), 1); + } + continue; + } + if (fillHistograms) { + registry.fill(HIST("hFitterStatusXi2Prong"), 0); + } + if (nVtxFrom2ProngFitterXiHyp > 0) { df2.propagateTracksToVertex(); @@ -3537,7 +3575,19 @@ struct HfTrackIndexSkimCreatorLfCascades { } // find charm baryon decay using omega PID hypothesis - int nVtxFrom2ProngFitterOmegaHyp = df2.process(trackCascOmega, trackParVarPion1); + int nVtxFrom2ProngFitterOmegaHyp = 0; + try { + nVtxFrom2ProngFitterOmegaHyp = df2.process(trackCascOmega, trackParVarPion1); + } catch (...) { + if (fillHistograms) { + registry.fill(HIST("hFitterStatusOmega2Prong"), 1); + } + continue; + } + if (fillHistograms) { + registry.fill(HIST("hFitterStatusOmega2Prong"), 0); + } + if (nVtxFrom2ProngFitterOmegaHyp > 0) { df2.propagateTracksToVertex(); @@ -3605,7 +3655,19 @@ struct HfTrackIndexSkimCreatorLfCascades { auto trackParVarPion2 = getTrackParCov(trackPion2); // reconstruct Xic with DCAFitter - int nVtxFrom3ProngFitterXiHyp = df3.process(trackCascXi3Prong, trackParVarPion1, trackParVarPion2); + int nVtxFrom3ProngFitterXiHyp = 0; + try { + nVtxFrom3ProngFitterXiHyp = df3.process(trackCascXi3Prong, trackParVarPion1, trackParVarPion2); + } catch (...) { + if (fillHistograms) { + registry.fill(HIST("hFitterStatusXi3Prong"), 1); + } + continue; + } + if (fillHistograms) { + registry.fill(HIST("hFitterStatusXi3Prong"), 0); + } + if (nVtxFrom3ProngFitterXiHyp > 0) { df3.propagateTracksToVertex(); diff --git a/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx b/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx index 34a0a30537e..53b3f8b7380 100644 --- a/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorLcToPKPi.cxx @@ -15,6 +15,7 @@ /// In this file are defined and filled the output tables /// /// \author Nicolo' Jacazio , CERN +/// \author Luigi Dello Stritto , CERN #include "CommonConstants/PhysicsConstants.h" #include "Framework/AnalysisTask.h" @@ -52,23 +53,20 @@ DECLARE_SOA_COLUMN(Phi, phi, float); DECLARE_SOA_COLUMN(Y, y, float); DECLARE_SOA_COLUMN(E, e, float); DECLARE_SOA_COLUMN(NSigTpcPi0, nSigTpcPi0, float); -DECLARE_SOA_COLUMN(NSigTpcKa0, nSigTpcKa0, float); DECLARE_SOA_COLUMN(NSigTpcPr0, nSigTpcPr0, float); DECLARE_SOA_COLUMN(NSigTofPi0, nSigTofPi0, float); -DECLARE_SOA_COLUMN(NSigTofKa0, nSigTofKa0, float); DECLARE_SOA_COLUMN(NSigTofPr0, nSigTofPr0, float); -DECLARE_SOA_COLUMN(NSigTpcPi1, nSigTpcPi1, float); DECLARE_SOA_COLUMN(NSigTpcKa1, nSigTpcKa1, float); -DECLARE_SOA_COLUMN(NSigTpcPr1, nSigTpcPr1, float); -DECLARE_SOA_COLUMN(NSigTofPi1, nSigTofPi1, float); DECLARE_SOA_COLUMN(NSigTofKa1, nSigTofKa1, float); -DECLARE_SOA_COLUMN(NSigTofPr1, nSigTofPr1, float); DECLARE_SOA_COLUMN(NSigTpcPi2, nSigTpcPi2, float); -DECLARE_SOA_COLUMN(NSigTpcKa2, nSigTpcKa2, float); DECLARE_SOA_COLUMN(NSigTpcPr2, nSigTpcPr2, float); DECLARE_SOA_COLUMN(NSigTofPi2, nSigTofPi2, float); -DECLARE_SOA_COLUMN(NSigTofKa2, nSigTofKa2, float); DECLARE_SOA_COLUMN(NSigTofPr2, nSigTofPr2, float); +DECLARE_SOA_COLUMN(NSigTpcTofPr0, nSigTpcTofPi0, float); +DECLARE_SOA_COLUMN(NSigTpcTofPi0, nSigTpcTofPr0, float); +DECLARE_SOA_COLUMN(NSigTpcTofKa1, nSigTpcTofKa1, float); +DECLARE_SOA_COLUMN(NSigTpcTofPr2, nSigTpcTofPi2, float); +DECLARE_SOA_COLUMN(NSigTpcTofPi2, nSigTpcTofPr2, float); DECLARE_SOA_COLUMN(DecayLength, decayLength, float); DECLARE_SOA_COLUMN(DecayLengthXY, decayLengthXY, float); DECLARE_SOA_COLUMN(DecayLengthNormalised, decayLengthNormalised, float); @@ -93,6 +91,61 @@ DECLARE_SOA_COLUMN(MultZeqFV0A, multZeqFV0A, float); DECLARE_SOA_COLUMN(MultZeqNTracksPV, multZeqNTracksPV, float); } // namespace full +DECLARE_SOA_TABLE(HfCandLcLites, "AOD", "HFCANDLCLITE", + collision::PosX, + collision::PosY, + collision::PosZ, + hf_cand::NProngsContributorsPV, + // hf_cand::ErrorDecayLength, + // hf_cand::ErrorDecayLengthXY, + hf_cand::Chi2PCA, + full::DecayLength, + full::DecayLengthXY, + // full::DecayLengthNormalised, + // full::DecayLengthXYNormalised, + // full::ImpactParameterNormalised0, + full::PtProng0, + // full::ImpactParameterNormalised1, + full::PtProng1, + // full::ImpactParameterNormalised2, + full::PtProng2, + hf_cand::ImpactParameter0, + hf_cand::ImpactParameter1, + hf_cand::ImpactParameter2, + // hf_cand::ErrorImpactParameter0, + // hf_cand::ErrorImpactParameter1, + // hf_cand::ErrorImpactParameter2, + full::NSigTpcPi0, + full::NSigTpcPr0, + full::NSigTofPi0, + full::NSigTofPr0, + full::NSigTpcKa1, + full::NSigTofKa1, + full::NSigTpcPi2, + full::NSigTpcPr2, + full::NSigTofPi2, + full::NSigTofPr2, + full::NSigTpcTofPi0, + full::NSigTpcTofPr0, + full::NSigTpcTofKa1, + full::NSigTpcTofPi2, + full::NSigTpcTofPr2, + full::CandidateSelFlag, + full::M, + full::Pt, + full::Cpa, + full::CpaXY, + full::Ct, + full::Eta, + full::Phi, + full::Y, + full::FlagMc, + full::OriginMcRec, + full::IsCandidateSwapped); + +DECLARE_SOA_TABLE(HfCollIdLCLite, "AOD", "HFCOLLIDLCLITE", + full::CollisionId); + DECLARE_SOA_TABLE(HfCandLcFulls, "AOD", "HFCANDLCFULL", full::CollisionId, collision::PosX, @@ -135,23 +188,20 @@ DECLARE_SOA_TABLE(HfCandLcFulls, "AOD", "HFCANDLCFULL", hf_cand::ErrorImpactParameter1, hf_cand::ErrorImpactParameter2, full::NSigTpcPi0, - full::NSigTpcKa0, full::NSigTpcPr0, full::NSigTofPi0, - full::NSigTofKa0, full::NSigTofPr0, - full::NSigTpcPi1, full::NSigTpcKa1, - full::NSigTpcPr1, - full::NSigTofPi1, full::NSigTofKa1, - full::NSigTofPr1, full::NSigTpcPi2, - full::NSigTpcKa2, full::NSigTpcPr2, full::NSigTofPi2, - full::NSigTofKa2, full::NSigTofPr2, + full::NSigTpcTofPi0, + full::NSigTpcTofPr0, + full::NSigTpcTofKa1, + full::NSigTpcTofPi2, + full::NSigTpcTofPr2, full::CandidateSelFlag, full::M, full::Pt, @@ -198,14 +248,21 @@ DECLARE_SOA_TABLE(HfCandLcFullPs, "AOD", "HFCANDLCFULLP", /// Writes the full information in an output TTree struct HfTreeCreatorLcToPKPi { Produces rowCandidateFull; + Produces rowCandidateLite; + Produces rowCollisionId; Produces rowCandidateFullEvents; Produces rowCandidateFullParticles; + Configurable fillCandidateLiteTable{"fillCandidateLiteTable", false, "Switch to fill lite table with candidate properties"}; + Configurable fillCollIdTable{"fillCollIdTable", false, "Fill a single-column table with collision index"}; + Configurable keepOnlySignalMc{"keepOnlySignalMc", false, "Fill MC tree only with signal candidates"}; + Configurable keepOnlyBkg{"keepOnlyBkg", false, "Fill MC tree only with background candidates"}; Configurable downSampleBkgFactor{"downSampleBkgFactor", 1., "Fraction of candidates to store in the tree"}; + Configurable downSampleBkgPtMax{"downSampleBkgPtMax", 100.f, "Max. pt for background downsampling"}; HfHelper hfHelper; - using TracksWPid = soa::Join; + using TracksWPid = soa::Join; void init(InitContext const&) { @@ -238,11 +295,20 @@ struct HfTreeCreatorLcToPKPi { } // Filling candidate properties - rowCandidateFull.reserve(candidates.size()); + if (fillCandidateLiteTable) { + rowCandidateLite.reserve(candidates.size()); + } else { + rowCandidateFull.reserve(candidates.size()); + } + if (fillCollIdTable) { + /// save also candidate collision indices + rowCollisionId.reserve(candidates.size()); + } for (const auto& candidate : candidates) { auto trackPos1 = candidate.prong0_as(); // positive daughter (negative for the antiparticles) auto trackNeg = candidate.prong1_as(); // negative daughter (positive for the antiparticles) auto trackPos2 = candidate.prong2_as(); // positive daughter (negative for the antiparticles) + bool isMcCandidateSignal = std::abs(candidate.flagMcMatchRec()) == (1 << o2::aod::hf_cand_3prong::DecayType::LcToPKPi); auto fillTable = [&](int CandFlag, int FunctionSelection, float FunctionInvMass, @@ -250,81 +316,139 @@ struct HfTreeCreatorLcToPKPi { float FunctionY, float FunctionE) { double pseudoRndm = trackPos1.pt() * 1000. - (int64_t)(trackPos1.pt() * 1000); - if (FunctionSelection >= 1 && pseudoRndm < downSampleBkgFactor) { - rowCandidateFull( - candidate.collisionId(), - candidate.posX(), - candidate.posY(), - candidate.posZ(), - candidate.nProngsContributorsPV(), - candidate.xSecondaryVertex(), - candidate.ySecondaryVertex(), - candidate.zSecondaryVertex(), - candidate.errorDecayLength(), - candidate.errorDecayLengthXY(), - candidate.chi2PCA(), - candidate.rSecondaryVertex(), - candidate.decayLength(), - candidate.decayLengthXY(), - candidate.decayLengthNormalised(), - candidate.decayLengthXYNormalised(), - candidate.impactParameterNormalised0(), - candidate.ptProng0(), - RecoDecay::p(candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()), - candidate.impactParameterNormalised1(), - candidate.ptProng1(), - RecoDecay::p(candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()), - candidate.impactParameterNormalised2(), - candidate.ptProng2(), - RecoDecay::p(candidate.pxProng2(), candidate.pyProng2(), candidate.pzProng2()), - candidate.pxProng0(), - candidate.pyProng0(), - candidate.pzProng0(), - candidate.pxProng1(), - candidate.pyProng1(), - candidate.pzProng1(), - candidate.pxProng2(), - candidate.pyProng2(), - candidate.pzProng2(), - candidate.impactParameter0(), - candidate.impactParameter1(), - candidate.impactParameter2(), - candidate.errorImpactParameter0(), - candidate.errorImpactParameter1(), - candidate.errorImpactParameter2(), - trackPos1.tpcNSigmaPi(), - trackPos1.tpcNSigmaKa(), - trackPos1.tpcNSigmaPr(), - trackPos1.tofNSigmaPi(), - trackPos1.tofNSigmaKa(), - trackPos1.tofNSigmaPr(), - trackNeg.tpcNSigmaPi(), - trackNeg.tpcNSigmaKa(), - trackNeg.tpcNSigmaPr(), - trackNeg.tofNSigmaPi(), - trackNeg.tofNSigmaKa(), - trackNeg.tofNSigmaPr(), - trackPos2.tpcNSigmaPi(), - trackPos2.tpcNSigmaKa(), - trackPos2.tpcNSigmaPr(), - trackPos2.tofNSigmaPi(), - trackPos2.tofNSigmaKa(), - trackPos2.tofNSigmaPr(), - 1 << CandFlag, - FunctionInvMass, - candidate.pt(), - candidate.p(), - candidate.cpa(), - candidate.cpaXY(), - FunctionCt, - candidate.eta(), - candidate.phi(), - FunctionY, - FunctionE, - candidate.flagMcMatchRec(), - candidate.originMcRec(), - candidate.isCandidateSwapped(), - candidate.globalIndex()); + if (FunctionSelection >= 1 && (/*keep all*/ (!keepOnlySignalMc && !keepOnlyBkg) || /*keep only signal*/ (keepOnlySignalMc && isMcCandidateSignal) || /*keep only background and downsample it*/ (keepOnlyBkg && !isMcCandidateSignal && (candidate.pt() > downSampleBkgPtMax || (pseudoRndm < downSampleBkgFactor && candidate.pt() < downSampleBkgPtMax))))) { + if (fillCandidateLiteTable) { + rowCandidateLite( + candidate.posX(), + candidate.posY(), + candidate.posZ(), + candidate.nProngsContributorsPV(), + // candidate.errorDecayLength(), + // candidate.errorDecayLengthXY(), + candidate.chi2PCA(), + candidate.decayLength(), + candidate.decayLengthXY(), + // candidate.decayLengthNormalised(), + // candidate.decayLengthXYNormalised(), + // candidate.impactParameterNormalised0(), + candidate.ptProng0(), + // candidate.impactParameterNormalised1(), + candidate.ptProng1(), + // candidate.impactParameterNormalised2(), + candidate.ptProng2(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.impactParameter2(), + // candidate.errorImpactParameter0(), + // candidate.errorImpactParameter1(), + // candidate.errorImpactParameter2(), + trackPos1.tpcNSigmaPi(), + trackPos1.tpcNSigmaPr(), + trackPos1.tofNSigmaPi(), + trackPos1.tofNSigmaPr(), + trackNeg.tpcNSigmaKa(), + trackNeg.tofNSigmaKa(), + trackPos2.tpcNSigmaPi(), + trackPos2.tpcNSigmaPr(), + trackPos2.tofNSigmaPi(), + trackPos2.tofNSigmaPr(), + trackPos1.tpcTofNSigmaPi(), + trackPos1.tpcTofNSigmaPr(), + trackNeg.tpcTofNSigmaKa(), + trackPos2.tpcTofNSigmaPi(), + trackPos2.tpcTofNSigmaPr(), + 1 << CandFlag, + FunctionInvMass, + candidate.pt(), + candidate.cpa(), + candidate.cpaXY(), + FunctionCt, + candidate.eta(), + candidate.phi(), + FunctionY, + candidate.flagMcMatchRec(), + candidate.originMcRec(), + candidate.isCandidateSwapped()); + // candidate.globalIndex()); + + if (fillCollIdTable) { + /// save also candidate collision indices + rowCollisionId(candidate.collisionId()); + } + + } else { + rowCandidateFull( + candidate.collisionId(), + candidate.posX(), + candidate.posY(), + candidate.posZ(), + candidate.nProngsContributorsPV(), + candidate.xSecondaryVertex(), + candidate.ySecondaryVertex(), + candidate.zSecondaryVertex(), + candidate.errorDecayLength(), + candidate.errorDecayLengthXY(), + candidate.chi2PCA(), + candidate.rSecondaryVertex(), + candidate.decayLength(), + candidate.decayLengthXY(), + candidate.decayLengthNormalised(), + candidate.decayLengthXYNormalised(), + candidate.impactParameterNormalised0(), + candidate.ptProng0(), + RecoDecay::p(candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()), + candidate.impactParameterNormalised1(), + candidate.ptProng1(), + RecoDecay::p(candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()), + candidate.impactParameterNormalised2(), + candidate.ptProng2(), + RecoDecay::p(candidate.pxProng2(), candidate.pyProng2(), candidate.pzProng2()), + candidate.pxProng0(), + candidate.pyProng0(), + candidate.pzProng0(), + candidate.pxProng1(), + candidate.pyProng1(), + candidate.pzProng1(), + candidate.pxProng2(), + candidate.pyProng2(), + candidate.pzProng2(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.impactParameter2(), + candidate.errorImpactParameter0(), + candidate.errorImpactParameter1(), + candidate.errorImpactParameter2(), + trackPos1.tpcNSigmaPi(), + trackPos1.tpcNSigmaPr(), + trackPos1.tofNSigmaPi(), + trackPos1.tofNSigmaPr(), + trackNeg.tpcNSigmaKa(), + trackNeg.tofNSigmaKa(), + trackPos2.tpcNSigmaPi(), + trackPos2.tpcNSigmaPr(), + trackPos2.tofNSigmaPi(), + trackPos2.tofNSigmaPr(), + trackPos1.tpcTofNSigmaPi(), + trackPos1.tpcTofNSigmaPr(), + trackNeg.tpcTofNSigmaKa(), + trackPos2.tpcTofNSigmaPi(), + trackPos2.tpcTofNSigmaPr(), + 1 << CandFlag, + FunctionInvMass, + candidate.pt(), + candidate.p(), + candidate.cpa(), + candidate.cpaXY(), + FunctionCt, + candidate.eta(), + candidate.phi(), + FunctionY, + FunctionE, + candidate.flagMcMatchRec(), + candidate.originMcRec(), + candidate.isCandidateSwapped(), + candidate.globalIndex()); + } } }; @@ -375,7 +499,15 @@ struct HfTreeCreatorLcToPKPi { } // Filling candidate properties - rowCandidateFull.reserve(candidates.size()); + if (fillCandidateLiteTable) { + rowCandidateLite.reserve(candidates.size()); + } else { + rowCandidateFull.reserve(candidates.size()); + } + if (fillCollIdTable) { + /// save also candidate collision indices + rowCollisionId.reserve(candidates.size()); + } for (const auto& candidate : candidates) { auto trackPos1 = candidate.prong0_as(); // positive daughter (negative for the antiparticles) auto trackNeg = candidate.prong1_as(); // negative daughter (positive for the antiparticles) @@ -387,81 +519,139 @@ struct HfTreeCreatorLcToPKPi { float FunctionY, float FunctionE) { double pseudoRndm = trackPos1.pt() * 1000. - (int64_t)(trackPos1.pt() * 1000); - if (FunctionSelection >= 1 && pseudoRndm < downSampleBkgFactor) { - rowCandidateFull( - candidate.collisionId(), - candidate.posX(), - candidate.posY(), - candidate.posZ(), - candidate.nProngsContributorsPV(), - candidate.xSecondaryVertex(), - candidate.ySecondaryVertex(), - candidate.zSecondaryVertex(), - candidate.errorDecayLength(), - candidate.errorDecayLengthXY(), - candidate.chi2PCA(), - candidate.rSecondaryVertex(), - candidate.decayLength(), - candidate.decayLengthXY(), - candidate.decayLengthNormalised(), - candidate.decayLengthXYNormalised(), - candidate.impactParameterNormalised0(), - candidate.ptProng0(), - RecoDecay::p(candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()), - candidate.impactParameterNormalised1(), - candidate.ptProng1(), - RecoDecay::p(candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()), - candidate.impactParameterNormalised2(), - candidate.ptProng2(), - RecoDecay::p(candidate.pxProng2(), candidate.pyProng2(), candidate.pzProng2()), - candidate.pxProng0(), - candidate.pyProng0(), - candidate.pzProng0(), - candidate.pxProng1(), - candidate.pyProng1(), - candidate.pzProng1(), - candidate.pxProng2(), - candidate.pyProng2(), - candidate.pzProng2(), - candidate.impactParameter0(), - candidate.impactParameter1(), - candidate.impactParameter2(), - candidate.errorImpactParameter0(), - candidate.errorImpactParameter1(), - candidate.errorImpactParameter2(), - trackPos1.tpcNSigmaPi(), - trackPos1.tpcNSigmaKa(), - trackPos1.tpcNSigmaPr(), - trackPos1.tofNSigmaPi(), - trackPos1.tofNSigmaKa(), - trackPos1.tofNSigmaPr(), - trackNeg.tpcNSigmaPi(), - trackNeg.tpcNSigmaKa(), - trackNeg.tpcNSigmaPr(), - trackNeg.tofNSigmaPi(), - trackNeg.tofNSigmaKa(), - trackNeg.tofNSigmaPr(), - trackPos2.tpcNSigmaPi(), - trackPos2.tpcNSigmaKa(), - trackPos2.tpcNSigmaPr(), - trackPos2.tofNSigmaPi(), - trackPos2.tofNSigmaKa(), - trackPos2.tofNSigmaPr(), - 1 << CandFlag, - FunctionInvMass, - candidate.pt(), - candidate.p(), - candidate.cpa(), - candidate.cpaXY(), - FunctionCt, - candidate.eta(), - candidate.phi(), - FunctionY, - FunctionE, - 0., - 0., - 0., - candidate.globalIndex()); + if (FunctionSelection >= 1 && (candidate.pt() > downSampleBkgPtMax || (pseudoRndm < downSampleBkgFactor && candidate.pt() < downSampleBkgPtMax))) { + if (fillCandidateLiteTable) { + rowCandidateLite( + candidate.posX(), + candidate.posY(), + candidate.posZ(), + candidate.nProngsContributorsPV(), + // candidate.errorDecayLength(), + // candidate.errorDecayLengthXY(), + candidate.chi2PCA(), + candidate.decayLength(), + candidate.decayLengthXY(), + // candidate.decayLengthNormalised(), + // candidate.decayLengthXYNormalised(), + // candidate.impactParameterNormalised0(), + candidate.ptProng0(), + // candidate.impactParameterNormalised1(), + candidate.ptProng1(), + // candidate.impactParameterNormalised2(), + candidate.ptProng2(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.impactParameter2(), + // candidate.errorImpactParameter0(), + // candidate.errorImpactParameter1(), + // candidate.errorImpactParameter2(), + trackPos1.tpcNSigmaPi(), + trackPos1.tpcNSigmaPr(), + trackPos1.tofNSigmaPi(), + trackPos1.tofNSigmaPr(), + trackNeg.tpcNSigmaKa(), + trackNeg.tofNSigmaKa(), + trackPos2.tpcNSigmaPi(), + trackPos2.tpcNSigmaPr(), + trackPos2.tofNSigmaPi(), + trackPos2.tofNSigmaPr(), + trackPos1.tpcTofNSigmaPi(), + trackPos1.tpcTofNSigmaPr(), + trackNeg.tpcTofNSigmaKa(), + trackPos2.tpcTofNSigmaPi(), + trackPos2.tpcTofNSigmaPr(), + 1 << CandFlag, + FunctionInvMass, + candidate.pt(), + candidate.cpa(), + candidate.cpaXY(), + FunctionCt, + candidate.eta(), + candidate.phi(), + FunctionY, + 0., + 0., + 0.); + // candidate.globalIndex()); + + if (fillCollIdTable) { + /// save also candidate collision indices + rowCollisionId(candidate.collisionId()); + } + + } else { + rowCandidateFull( + candidate.collisionId(), + candidate.posX(), + candidate.posY(), + candidate.posZ(), + candidate.nProngsContributorsPV(), + candidate.xSecondaryVertex(), + candidate.ySecondaryVertex(), + candidate.zSecondaryVertex(), + candidate.errorDecayLength(), + candidate.errorDecayLengthXY(), + candidate.chi2PCA(), + candidate.rSecondaryVertex(), + candidate.decayLength(), + candidate.decayLengthXY(), + candidate.decayLengthNormalised(), + candidate.decayLengthXYNormalised(), + candidate.impactParameterNormalised0(), + candidate.ptProng0(), + RecoDecay::p(candidate.pxProng0(), candidate.pyProng0(), candidate.pzProng0()), + candidate.impactParameterNormalised1(), + candidate.ptProng1(), + RecoDecay::p(candidate.pxProng1(), candidate.pyProng1(), candidate.pzProng1()), + candidate.impactParameterNormalised2(), + candidate.ptProng2(), + RecoDecay::p(candidate.pxProng2(), candidate.pyProng2(), candidate.pzProng2()), + candidate.pxProng0(), + candidate.pyProng0(), + candidate.pzProng0(), + candidate.pxProng1(), + candidate.pyProng1(), + candidate.pzProng1(), + candidate.pxProng2(), + candidate.pyProng2(), + candidate.pzProng2(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.impactParameter2(), + candidate.errorImpactParameter0(), + candidate.errorImpactParameter1(), + candidate.errorImpactParameter2(), + trackPos1.tpcNSigmaPi(), + trackPos1.tpcNSigmaPr(), + trackPos1.tofNSigmaPi(), + trackPos1.tofNSigmaPr(), + trackNeg.tpcNSigmaKa(), + trackNeg.tofNSigmaKa(), + trackPos2.tpcNSigmaPi(), + trackPos2.tpcNSigmaPr(), + trackPos2.tofNSigmaPi(), + trackPos2.tofNSigmaPr(), + trackPos1.tpcTofNSigmaPi(), + trackPos1.tpcTofNSigmaPr(), + trackNeg.tpcTofNSigmaKa(), + trackPos2.tpcTofNSigmaPi(), + trackPos2.tpcTofNSigmaPr(), + 1 << CandFlag, + FunctionInvMass, + candidate.pt(), + candidate.p(), + candidate.cpa(), + candidate.cpaXY(), + FunctionCt, + candidate.eta(), + candidate.phi(), + FunctionY, + FunctionE, + 0., + 0., + 0., + candidate.globalIndex()); + } } }; diff --git a/PWGHF/TableProducer/treeCreatorToXiPi.cxx b/PWGHF/TableProducer/treeCreatorToXiPi.cxx index ade6b9d69fe..709ab76196f 100644 --- a/PWGHF/TableProducer/treeCreatorToXiPi.cxx +++ b/PWGHF/TableProducer/treeCreatorToXiPi.cxx @@ -44,7 +44,6 @@ DECLARE_SOA_COLUMN(XDecayVtxV0, xDecayVtxV0, float); DECLARE_SOA_COLUMN(YDecayVtxV0, yDecayVtxV0, float); DECLARE_SOA_COLUMN(ZDecayVtxV0, zDecayVtxV0, float); DECLARE_SOA_COLUMN(SignDecay, signDecay, int8_t); // sign of pi <- xi -DECLARE_SOA_COLUMN(Chi2PCACharmBaryon, chi2PCACharmBaryon, float); DECLARE_SOA_COLUMN(CovVtxCharmBaryonXX, covVtxCharmBaryonXX, float); DECLARE_SOA_COLUMN(CovVtxCharmBaryonYY, covVtxCharmBaryonYY, float); DECLARE_SOA_COLUMN(CovVtxCharmBaryonZZ, covVtxCharmBaryonZZ, float); @@ -109,6 +108,9 @@ DECLARE_SOA_COLUMN(DecLenCascade, decLenCascade, double); DECLARE_SOA_COLUMN(DecLenV0, decLenV0, double); DECLARE_SOA_COLUMN(ErrorDecayLengthCharmBaryon, errorDecayLengthCharmBaryon, float); DECLARE_SOA_COLUMN(ErrorDecayLengthXYCharmBaryon, errorDecayLengthXYCharmBaryon, float); +DECLARE_SOA_COLUMN(NormImpParCascade, normImpParCascade, double); +DECLARE_SOA_COLUMN(NormImpParPiFromCharmBar, normImpParPiFromCharmBar, double); +DECLARE_SOA_COLUMN(NormDecayLenCharmBar, normDecayLenCharmBar, double); // from creator - MC DECLARE_SOA_COLUMN(FlagMcMatchRec, flagMcMatchRec, int8_t); // reconstruction level DECLARE_SOA_COLUMN(DebugMcRec, debugMcRec, int8_t); // debug flag for mis-association reconstruction level @@ -135,11 +137,11 @@ DECLARE_SOA_COLUMN(TofNSigmaPrFromLambda, tofNSigmaPrFromLambda, float); } // namespace full DECLARE_SOA_TABLE(HfToXiPiFulls, "AOD", "HFTOXIPIFULL", - full::XPv, full::YPv, full::ZPv, collision::NumContrib, + full::XPv, full::YPv, full::ZPv, collision::NumContrib, collision::Chi2, full::XDecayVtxCharmBaryon, full::YDecayVtxCharmBaryon, full::ZDecayVtxCharmBaryon, full::XDecayVtxCascade, full::YDecayVtxCascade, full::ZDecayVtxCascade, full::XDecayVtxV0, full::YDecayVtxV0, full::ZDecayVtxV0, - full::SignDecay, full::Chi2PCACharmBaryon, + full::SignDecay, full::CovVtxCharmBaryonXX, full::CovVtxCharmBaryonYY, full::CovVtxCharmBaryonZZ, full::PxCharmBaryon, full::PyCharmBaryon, full::PzCharmBaryon, full::PxCasc, full::PyCasc, full::PzCasc, @@ -160,6 +162,7 @@ DECLARE_SOA_TABLE(HfToXiPiFulls, "AOD", "HFTOXIPIFULL", full::DcaZToPvV0Dau0, full::DcaZToPvV0Dau1, full::DcaZToPvCascDau, full::DcaCascDau, full::DcaV0Dau, full::DcaCharmBaryonDau, full::DecLenCharmBaryon, full::DecLenCascade, full::DecLenV0, full::ErrorDecayLengthCharmBaryon, full::ErrorDecayLengthXYCharmBaryon, + full::NormImpParCascade, full::NormImpParPiFromCharmBar, full::NormDecayLenCharmBar, full::StatusPidLambda, full::StatusPidCascade, full::StatusPidCharmBaryon, full::StatusInvMassLambda, full::StatusInvMassCascade, full::StatusInvMassCharmBaryon, full::ResultSelections, full::PidTpcInfoStored, full::PidTofInfoStored, full::TpcNSigmaPiFromCharmBaryon, full::TpcNSigmaPiFromCasc, full::TpcNSigmaPiFromLambda, full::TpcNSigmaPrFromLambda, @@ -185,6 +188,7 @@ struct HfTreeCreatorToXiPi { candidate.yPv(), candidate.zPv(), candidate.collision().numContrib(), + candidate.collision().chi2(), candidate.xDecayVtxCharmBaryon(), candidate.yDecayVtxCharmBaryon(), candidate.zDecayVtxCharmBaryon(), @@ -195,7 +199,6 @@ struct HfTreeCreatorToXiPi { candidate.yDecayVtxV0(), candidate.zDecayVtxV0(), candidate.signDecay(), - candidate.chi2PCACharmBaryon(), candidate.covVtxCharmBaryon0(), candidate.covVtxCharmBaryon3(), candidate.covVtxCharmBaryon5(), @@ -260,6 +263,9 @@ struct HfTreeCreatorToXiPi { candidate.decLenV0(), candidate.errorDecayLengthCharmBaryon(), candidate.errorDecayLengthXYCharmBaryon(), + candidate.impactParCascXY() / candidate.errImpactParCascXY(), + candidate.impactParPiFromCharmBaryonXY() / candidate.errImpactParPiFromCharmBaryonXY(), + candidate.decLenCharmBaryon() / candidate.errorDecayLengthCharmBaryon(), candidate.statusPidLambda(), candidate.statusPidCascade(), candidate.statusPidCharmBaryon(), diff --git a/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx b/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx index 43d8a30fbd9..cbb70ce60c8 100644 --- a/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx +++ b/PWGHF/TableProducer/treeCreatorXicToPKPi.cxx @@ -44,7 +44,6 @@ DECLARE_SOA_COLUMN(ImpactParameterNormalised1, impactParameterNormalised1, float DECLARE_SOA_COLUMN(PtProng2, ptProng2, float); DECLARE_SOA_COLUMN(PProng2, pProng2, float); DECLARE_SOA_COLUMN(ImpactParameterNormalised2, impactParameterNormalised2, float); -DECLARE_SOA_COLUMN(CandidateSelFlag, candidateSelFlag, int8_t); DECLARE_SOA_COLUMN(M, m, float); DECLARE_SOA_COLUMN(Pt, pt, float); DECLARE_SOA_COLUMN(P, p, float); @@ -80,7 +79,6 @@ DECLARE_SOA_COLUMN(Ct, ct, float); DECLARE_SOA_COLUMN(FlagMc, flagMc, int8_t); DECLARE_SOA_COLUMN(OriginMcRec, originMcRec, int8_t); DECLARE_SOA_COLUMN(OriginMcGen, originMcGen, int8_t); -DECLARE_SOA_COLUMN(IsCandidateSwapped, isCandidateSwapped, int8_t); DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, HfCand3Prong, "_0"); // Events DECLARE_SOA_COLUMN(IsEventReject, isEventReject, int); @@ -117,7 +115,8 @@ DECLARE_SOA_TABLE(HfCandXicLites, "AOD", "HFCANDXICLITE", full::NSigTofPi2, full::NSigTofKa2, full::NSigTofPr2, - full::CandidateSelFlag, + hf_sel_candidate_xic::IsSelXicToPKPi, + hf_sel_candidate_xic::IsSelXicToPiKP, full::M, full::Pt, full::Cpa, @@ -125,8 +124,7 @@ DECLARE_SOA_TABLE(HfCandXicLites, "AOD", "HFCANDXICLITE", full::Eta, full::Phi, full::FlagMc, - full::OriginMcRec, - full::IsCandidateSwapped) + full::OriginMcRec) DECLARE_SOA_TABLE(HfCandXicFulls, "AOD", "HFCANDXICFULL", full::CollisionId, @@ -186,7 +184,8 @@ DECLARE_SOA_TABLE(HfCandXicFulls, "AOD", "HFCANDXICFULL", full::NSigTofPi2, full::NSigTofKa2, full::NSigTofPr2, - full::CandidateSelFlag, + hf_sel_candidate_xic::IsSelXicToPKPi, + hf_sel_candidate_xic::IsSelXicToPiKP, full::M, full::Pt, full::P, @@ -199,7 +198,6 @@ DECLARE_SOA_TABLE(HfCandXicFulls, "AOD", "HFCANDXICFULL", full::E, full::FlagMc, full::OriginMcRec, - full::IsCandidateSwapped, full::CandidateId); DECLARE_SOA_TABLE(HfCandXicFullEvs, "AOD", "HFCANDXICFULLEV", @@ -340,6 +338,7 @@ struct HfTreeCreatorXicToPKPi { candidate.phi(), flagMc, originMc); + } else { rowCandidateFull( candidate.collisionId(), diff --git a/PWGJE/Core/FastJetUtilities.cxx b/PWGJE/Core/FastJetUtilities.cxx index 73bfd282d16..8e678a75130 100644 --- a/PWGJE/Core/FastJetUtilities.cxx +++ b/PWGJE/Core/FastJetUtilities.cxx @@ -11,7 +11,7 @@ #include "FastJetUtilities.h" -void FastJetUtilities::setFastJetUserInfo(std::vector& constituents, int index, int status) +void fastjetutilities::setFastJetUserInfo(std::vector& constituents, int index, int status) { fastjet_user_info* user_info = new fastjet_user_info(status, index); // FIXME: can setting this as a pointer be avoided? constituents.back().set_user_info(user_info); @@ -29,10 +29,3 @@ void FastJetUtilities::setFastJetUserInfo(std::vector& const constituents.back().set_user_index(i); // FIXME: needed for constituent subtraction, but need to be quite careful to make sure indices dont overlap between tracks, clusters and HF candidates. Current solution might not be optimal } } - -// Selector of HF candidates -fastjet::Selector FastJetUtilities::SelectorIsHFCand() -{ - // This method is applied on particles or jet constituents only !!! - return fastjet::Selector(new SW_IsHFCand()); -} diff --git a/PWGJE/Core/FastJetUtilities.h b/PWGJE/Core/FastJetUtilities.h index be853563abc..cfc0aa0671b 100644 --- a/PWGJE/Core/FastJetUtilities.h +++ b/PWGJE/Core/FastJetUtilities.h @@ -33,7 +33,7 @@ enum class JetConstituentStatus { candidateHF = 2 }; -namespace FastJetUtilities +namespace fastjetutilities { static constexpr float mPion = 0.139; // TDatabasePDG::Instance()->GetParticle(211)->Mass(); //can be removed when pion mass becomes default for unidentified tracks @@ -72,29 +72,6 @@ class fastjet_user_info : public fastjet::PseudoJet::UserInfoBase void setFastJetUserInfo(std::vector& constituents, int index = -99999999, int status = static_cast(JetConstituentStatus::track)); -// Class defined to select the HF candidate particle -// This method is applied on particles or jet constituents only !!! -class SW_IsHFCand : public fastjet::SelectorWorker -{ - public: - // default ctor - SW_IsHFCand() {} - - // the selector's description - std::string description() const - { - return "HF candidate selector"; - } - - bool pass(const fastjet::PseudoJet& p) const - { - return (p.user_info().getStatus() == static_cast(JetConstituentStatus::candidateHF)); - } -}; - -// Selector of HF candidates -fastjet::Selector SelectorIsHFCand(); - /** * Add track as a pseudojet object to the fastjet vector * @@ -135,6 +112,6 @@ void fillClusters(const T& constituent, std::vector& constit setFastJetUserInfo(constituents, index, status); } -}; // namespace FastJetUtilities +}; // namespace fastjetutilities #endif // PWGJE_CORE_FASTJETUTILITIES_H_ diff --git a/PWGJE/Core/JetBkgSubUtils.cxx b/PWGJE/Core/JetBkgSubUtils.cxx index 27445f923af..336ebf9f67c 100644 --- a/PWGJE/Core/JetBkgSubUtils.cxx +++ b/PWGJE/Core/JetBkgSubUtils.cxx @@ -20,15 +20,20 @@ #include "PWGJE/Core/JetBkgSubUtils.h" #include "PWGJE/Core/FastJetUtilities.h" -JetBkgSubUtils::JetBkgSubUtils(float jetBkgR_out, float bkgEtaMin_out, float bkgEtaMax_out, float bkgPhiMin_out, float bkgPhiMax_out, float constSubAlpha_out, float constSubRMax_out, fastjet::GhostedAreaSpec ghostAreaSpec_out, int nHardReject) : jetBkgR(jetBkgR_out), - bkgEtaMin(bkgEtaMin_out), - bkgEtaMax(bkgEtaMax_out), - bkgPhiMin(bkgPhiMin_out), - bkgPhiMax(bkgPhiMax_out), - constSubAlpha(constSubAlpha_out), - constSubRMax(constSubRMax_out), - ghostAreaSpec(ghostAreaSpec_out) +JetBkgSubUtils::JetBkgSubUtils(float jetBkgR_out, float bkgEtaMin_out, float bkgEtaMax_out, float bkgPhiMin_out, float bkgPhiMax_out, float constSubAlpha_out, float constSubRMax_out, int nHardReject_out, fastjet::GhostedAreaSpec ghostAreaSpec_out) : jetBkgR(jetBkgR_out), + bkgEtaMin(bkgEtaMin_out), + bkgEtaMax(bkgEtaMax_out), + bkgPhiMin(bkgPhiMin_out), + bkgPhiMax(bkgPhiMax_out), + constSubAlpha(constSubAlpha_out), + constSubRMax(constSubRMax_out), + nHardReject(nHardReject_out), + ghostAreaSpec(ghostAreaSpec_out) +{ +} + +void JetBkgSubUtils::initialise() { // Note: if you are using the PerpCone method you should jetBkgR to be the same as the anit_kt jets R, otherwise use R=0.2 jetDefBkg = fastjet::JetDefinition(algorithmBkg, jetBkgR, recombSchemeBkg, fastjet::Best); @@ -38,13 +43,14 @@ JetBkgSubUtils::JetBkgSubUtils(float jetBkgR_out, float bkgEtaMin_out, float bkg std::tuple JetBkgSubUtils::estimateRhoAreaMedian(const std::vector& inputParticles, bool doSparseSub) { + JetBkgSubUtils::initialise(); if (inputParticles.size() == 0) { return std::make_tuple(0.0, 0.0); } // cluster the kT jets - fastjet::ClusterSequenceArea clusterSeq(removeHFCand ? selRemoveHFCand(inputParticles) : inputParticles, jetDefBkg, areaDefBkg); + fastjet::ClusterSequenceArea clusterSeq(inputParticles, jetDefBkg, areaDefBkg); // select jets in detector acceptance std::vector alljets = selRho(clusterSeq.inclusive_jets()); @@ -67,8 +73,13 @@ std::tuple JetBkgSubUtils::estimateRhoAreaMedian(const std::vect totalAreaCovered += ijet.area(); } // calculate Rho as the median of the jet pT / jet area - double rho = TMath::Median(rhovector.size(), rhovector.data()); - double rhoM = TMath::Median(rhoMdvector.size(), rhoMdvector.data()); + + double rho = 0.0; + double rhoM = 0.0; + if (rhovector.size() != 0) { + rho = TMath::Median(rhovector.size(), rhovector.data()); + rhoM = TMath::Median(rhoMdvector.size(), rhoMdvector.data()); + } if (doSparseSub) { // calculate The ocupancy factor, which the ratio of covered area / total area @@ -83,13 +94,11 @@ std::tuple JetBkgSubUtils::estimateRhoAreaMedian(const std::vect std::tuple JetBkgSubUtils::estimateRhoPerpCone(const std::vector& inputParticles, const std::vector& jets) { + JetBkgSubUtils::initialise(); if (inputParticles.size() == 0 || jets.size() == 0) { return std::make_tuple(0.0, 0.0); } - // Select a list of particles without the HF candidate - std::vector inputPartnoHF = removeHFCand ? selRemoveHFCand(inputParticles) : inputParticles; - double perpPtDensity1 = 0; double perpPtDensity2 = 0; double perpMdDensity1 = 0; @@ -113,7 +122,7 @@ std::tuple JetBkgSubUtils::estimateRhoPerpCone(const std::vector PerpendicularConeAxisPhi1 = RecoDecay::constrainAngle(leadingJet.phi() + (M_PI / 2.)); // This will contrain the angel between 0-2Pi PerpendicularConeAxisPhi2 = RecoDecay::constrainAngle(leadingJet.phi() - (M_PI / 2.)); // This will contrain the angel between 0-2Pi - for (auto& particle : inputPartnoHF) { + for (auto& particle : inputParticles) { // sum the momentum of all paricles that fill the two cones dPhi1 = particle.phi() - PerpendicularConeAxisPhi1; dPhi1 = RecoDecay::constrainAngle(dPhi1, -M_PI); // This will contrain the angel between -pi & Pi @@ -138,7 +147,7 @@ std::tuple JetBkgSubUtils::estimateRhoPerpCone(const std::vector return std::make_tuple(perpPtDensity, perpMdDensity); } -fastjet::PseudoJet JetBkgSubUtils::doRhoAreaSub(fastjet::PseudoJet& jet, double& rhoParam, double& rhoMParam) +fastjet::PseudoJet JetBkgSubUtils::doRhoAreaSub(fastjet::PseudoJet& jet, double rhoParam, double rhoMParam) { fastjet::Subtractor sub = fastjet::Subtractor(rhoParam, rhoMParam); @@ -148,18 +157,16 @@ fastjet::PseudoJet JetBkgSubUtils::doRhoAreaSub(fastjet::PseudoJet& jet, double& return sub(jet); } -std::vector JetBkgSubUtils::doEventConstSub(std::vector& inputParticles, double& rhoParam, double& rhoMParam) +std::vector JetBkgSubUtils::doEventConstSub(std::vector& inputParticles, double rhoParam, double rhoMParam) { + JetBkgSubUtils::initialise(); fastjet::contrib::ConstituentSubtractor constituentSub(rhoParam, rhoMParam); constituentSub.set_distance_type(fastjet::contrib::ConstituentSubtractor::deltaR); /// deltaR=sqrt((y_i-y_j)^2+(phi_i-phi_j)^2)), longitudinal Lorentz invariant constituentSub.set_max_distance(constSubRMax); constituentSub.set_alpha(constSubAlpha); constituentSub.set_ghost_area(ghostAreaSpec.ghost_area()); constituentSub.set_max_eta(maxEtaEvent); - if (removeHFCand) { - constituentSub.set_particle_selector(&selRemoveHFCand); - } // by default, the masses of all particles are set to zero. With this flag the jet mass will also be subtracted if (doRhoMassSub) { @@ -169,9 +176,9 @@ std::vector JetBkgSubUtils::doEventConstSub(std::vector JetBkgSubUtils::doJetConstSub(std::vector& jets, double& rhoParam, double& rhoMParam) +std::vector JetBkgSubUtils::doJetConstSub(std::vector& jets, double rhoParam, double rhoMParam) { - + JetBkgSubUtils::initialise(); if (jets.size() == 0) { return std::vector(); } @@ -184,9 +191,6 @@ std::vector JetBkgSubUtils::doJetConstSub(std::vector doEventConstSub(std::vector& inputParticles, double& rhoParam, double& rhoMParam); + std::vector doEventConstSub(std::vector& inputParticles, double rhoParam, double rhoMParam); /// @brief method that subtracts the background from jets using the jet-wise constituent subtractor /// @param jets (all jets in the event) /// @param rhoParam the underlying evvent density vs pT (to be set) /// @param rhoParam the underlying evvent density vs jet mass (to be set) /// @return jets, a vector of background subtracted jets - std::vector doJetConstSub(std::vector& jets, double& rhoParam, double& rhoMParam); + std::vector doJetConstSub(std::vector& jets, double rhoParam, double rhoMParam); // Setters void setJetBkgR(float jetbkgR_out) { jetBkgR = jetbkgR_out; } @@ -119,7 +121,6 @@ class JetBkgSubUtils } void setMaxEtaEvent(float etaMaxEvent) { maxEtaEvent = etaMaxEvent; } void setDoRhoMassSub(bool doMSub_out = true) { doRhoMassSub = doMSub_out; } - void setRemoveHFCandidate(bool removecandidate = true) { removeHFCand = removecandidate; } void setGhostAreaSpec(fastjet::GhostedAreaSpec ghostAreaSpec_out) { ghostAreaSpec = ghostAreaSpec_out; } void setJetDefinition(fastjet::JetDefinition jetdefbkg_out) { jetDefBkg = jetdefbkg_out; } void setAreaDefinition(fastjet::AreaDefinition areaDefBkg_out) { areaDefBkg = areaDefBkg_out; } @@ -135,7 +136,6 @@ class JetBkgSubUtils float getConstSubAlpha() const { return constSubAlpha; } float getConstSubRMax() const { return constSubRMax; } float getDoRhoMassSub() const { return doRhoMassSub; } - float getRemoveHFCandidate() const { return removeHFCand; } fastjet::GhostedAreaSpec getGhostAreaSpec() const { return ghostAreaSpec; } fastjet::JetDefinition getJetDefinition() const { return jetDefBkg; } fastjet::AreaDefinition getAreaDefinition() const { return areaDefBkg; } @@ -148,13 +148,13 @@ class JetBkgSubUtils float jetBkgR = 0.2; float bkgEtaMin = -0.9; float bkgEtaMax = 0.9; - float bkgPhiMin = -99.0; - float bkgPhiMax = 99.0; + float bkgPhiMin = 0.0; + float bkgPhiMax = 2.0 * M_PI; float constSubAlpha = 1.0; - float constSubRMax = 0.6; + float constSubRMax = 0.24; float maxEtaEvent = 0.9; + int nHardReject = 2; bool doRhoMassSub = false; /// flag whether to do jet mass subtraction with the const sub - bool removeHFCand = false; /// flag whether to remove the HF candidate from the list of particles fastjet::GhostedAreaSpec ghostAreaSpec = fastjet::GhostedAreaSpec(); fastjet::JetAlgorithm algorithmBkg = fastjet::kt_algorithm; @@ -162,7 +162,6 @@ class JetBkgSubUtils fastjet::JetDefinition jetDefBkg = fastjet::JetDefinition(algorithmBkg, jetBkgR, recombSchemeBkg, fastjet::Best); fastjet::AreaDefinition areaDefBkg = fastjet::AreaDefinition(fastjet::active_area_explicit_ghosts, ghostAreaSpec); fastjet::Selector selRho = fastjet::Selector(); - fastjet::Selector selRemoveHFCand = !FastJetUtilities::SelectorIsHFCand(); }; // class JetBkgSubUtils diff --git a/PWGJE/Core/JetDerivedDataUtilities.h b/PWGJE/Core/JetDerivedDataUtilities.h index 8ba572cde6f..d197a185afa 100644 --- a/PWGJE/Core/JetDerivedDataUtilities.h +++ b/PWGJE/Core/JetDerivedDataUtilities.h @@ -22,7 +22,7 @@ #include "Common/DataModel/EventSelection.h" #include "PWGJE/Core/JetFinder.h" -namespace JetDerivedDataUtilities +namespace jetderiveddatautilities { enum JCollisionSel { @@ -273,14 +273,21 @@ uint8_t setTrackSelectionBit(T const& track) return bit; } +uint8_t setSingleTrackSelectionBit(int trackSelection) +{ + uint8_t bit = 0; + if (trackSelection != -1) { + SETBIT(bit, trackSelection); + } + return bit; +} + template float trackEnergy(T const& track, float mass = JetFinder::mPion) { return std::sqrt((track.p() * track.p()) + (mass * mass)); } -} // namespace JetDerivedDataUtilities - -// namespace JetDerivedDataUtilities +} // namespace jetderiveddatautilities #endif // PWGJE_CORE_JETDERIVEDDATAUTILITIES_H_ diff --git a/PWGJE/Core/JetFinder.cxx b/PWGJE/Core/JetFinder.cxx index 71680d70a30..940a201bb92 100644 --- a/PWGJE/Core/JetFinder.cxx +++ b/PWGJE/Core/JetFinder.cxx @@ -51,10 +51,8 @@ fastjet::ClusterSequenceArea JetFinder::findJets(std::vector { setParams(); jets.clear(); - fastjet::ClusterSequenceArea clusterSeq(inputParticles, jetDef, areaDef); jets = clusterSeq.inclusive_jets(); - jets = selJets(jets); jets = fastjet::sorted_by_pt(jets); if (isReclustering) { diff --git a/PWGJE/Core/JetFinder.h b/PWGJE/Core/JetFinder.h index b400d1fdba5..b72082440f0 100644 --- a/PWGJE/Core/JetFinder.h +++ b/PWGJE/Core/JetFinder.h @@ -86,31 +86,31 @@ class JetFinder fastjet::Selector selGhosts; /// Default constructor - explicit JetFinder(float eta_Min = -0.9, float eta_Max = 0.9, float phi_Min = 0.0, float phi_Max = 2 * M_PI) : phiMin(phi_Min), - phiMax(phi_Max), - etaMin(eta_Min), - etaMax(eta_Max), - jetR(0.4), - jetPtMin(0.0), - jetPtMax(1000.0), - jetPhiMin(phi_Min), - jetPhiMax(phi_Max), - jetEtaMin(-99.0), - jetEtaMax(99.0), - jetEtaDefault(false), - ghostEtaMin(eta_Min), - ghostEtaMax(eta_Max), - ghostArea(0.005), - ghostRepeatN(1), - ghostktMean(1e-100), // is float precise enough? - gridScatter(1.0), - ktScatter(0.1), - isReclustering(false), - isTriggering(false), - algorithm(fastjet::antikt_algorithm), - recombScheme(fastjet::E_scheme), - strategy(fastjet::Best), - areaType(fastjet::active_area) + explicit JetFinder(float eta_Min = -0.9, float eta_Max = 0.9, float phi_Min = 0.0, float phi_Max = 2.0 * M_PI) : phiMin(phi_Min), + phiMax(phi_Max), + etaMin(eta_Min), + etaMax(eta_Max), + jetR(0.4), + jetPtMin(0.0), + jetPtMax(1000.0), + jetPhiMin(phi_Min), + jetPhiMax(phi_Max), + jetEtaMin(-99.0), + jetEtaMax(99.0), + jetEtaDefault(false), + ghostEtaMin(eta_Min), + ghostEtaMax(eta_Max), + ghostArea(0.005), + ghostRepeatN(1), + ghostktMean(1e-100), // is float precise enough? + gridScatter(1.0), + ktScatter(0.1), + isReclustering(false), + isTriggering(false), + algorithm(fastjet::antikt_algorithm), + recombScheme(fastjet::E_scheme), + strategy(fastjet::Best), + areaType(fastjet::active_area) { // default constructor diff --git a/PWGJE/Core/JetFindingUtilities.h b/PWGJE/Core/JetFindingUtilities.h new file mode 100644 index 00000000000..80f5a02fc44 --- /dev/null +++ b/PWGJE/Core/JetFindingUtilities.h @@ -0,0 +1,252 @@ +// 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 JetFindingUtilities.h +/// \brief Jet Finding related utilities +/// +/// \author Nima Zardoshti + +#ifndef PWGJE_CORE_JETFINDINGUTILITIES_H_ +#define PWGJE_CORE_JETFINDINGUTILITIES_H_ + +#include +#include +#include +#include +#include + +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoA.h" +#include "Framework/O2DatabasePDGPlugin.h" + +#include "Framework/Logger.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "PWGJE/DataModel/EMCALClusters.h" + +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" + +// #include "PWGJE/Core/JetBkgSubUtils.h" +#include "PWGJE/Core/FastJetUtilities.h" +#include "PWGJE/Core/JetDerivedDataUtilities.h" +#include "PWGJE/Core/JetFinder.h" +#include "PWGJE/Core/JetHFUtilities.h" +#include "PWGJE/DataModel/Jet.h" + +namespace jetfindingutilities +{ + +/** + * Adds tracks to a fastjet inputParticles list + * + * @param inputParticles fastjet container + * @param tracks track table to be added + * @param trackSelection track selection to be applied to tracks + * @param candidate optional HF candidiate + */ + +template +void analyseTracks(std::vector& inputParticles, T const& tracks, int trackSelection, std::optional const& candidate = std::nullopt) +{ + for (auto& track : tracks) { + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { + continue; + } + if (candidate != std::nullopt) { + auto cand = candidate.value(); + if (jethfutilities::isDaughterTrack(track, cand, tracks)) { + continue; + } + } + fastjetutilities::fillTracks(track, inputParticles, track.globalIndex()); + } +} + +/** + * Adds clusters to a fastjet inputParticles list + * + * @param inputParticles fastjet container + * @param clusters track table to be added + */ +template +void analyseClusters(std::vector& inputParticles, T const& clusters) +{ + for (auto& cluster : *clusters) { + // add cluster selections + fastjetutilities::fillClusters(cluster, inputParticles, cluster.globalIndex()); + } +} + +/** + * Adds hf candidates to a fastjet inputParticles list (for data) + * + * @param inputParticles fastjet container + * @param candMass pdg mass of hf candidate + * @param candPtMin minimum pT of hf candidate + * @param candPtMax maximum pT of hf candidate + * @param candYMin minimum Y of hf candidate + * @param candYMax maximum Y of hf candidate + * @param candidate hf candidate + */ +template +bool analyseCandidate(std::vector& inputParticles, T const& candidate, float candPtMin, float candPtMax, float candYMin, float candYMax, float candMass) +{ + if (isnan(candidate.y())) { + return false; + } + if (candidate.y() < candYMin || candidate.y() > candYMax) { + return false; + } + if (candidate.pt() < candPtMin || candidate.pt() >= candPtMax) { + return false; + } + fastjetutilities::fillTracks(candidate, inputParticles, candidate.globalIndex(), static_cast(JetConstituentStatus::candidateHF), candMass); + return true; +} + +/** + * Adds hf candidates to a fastjet inputParticles list (for MC det) + * + * @param inputParticles fastjet container + * @param candMass pdg mass of hf candidate + * @param candPtMin minimum pT of hf candidate + * @param candPtMax maximum pT of hf candidate + * @param candYMin minimum Y of hf candidate + * @param candYMax maximum Y of hf candidate + * @param candidate hf candidate + * @param rejectBackgroundMCCandidates choose whether to accept background hf candidates as defined by the selection flag + */ +template +bool analyseCandidateMC(std::vector& inputParticles, T const& candidate, float candPtMin, float candPtMax, float candYMin, float candYMax, float candMass, bool rejectBackgroundMCCandidates) +{ + if (rejectBackgroundMCCandidates && !jethfutilities::isMatchedHFCandidate(candidate)) { + return false; + } + return analyseCandidate(inputParticles, candidate, candPtMin, candPtMax, candYMin, candYMax, candMass); +} + +/** + * Performs jet finding and fills jet tables + * + * @param jetFinder JetFinder object which carries jet finding parameters + * @param inputParticles fastjet container + * @param jetRadius jet finding radii + * @param collision the collision within which jets are being found + * @param jetsTable output table of jets + * @param constituentsTable output table of jet constituents + * @param doHFJetFinding set whether only jets containing a HF candidate are saved + */ +template +void findJets(JetFinder& jetFinder, std::vector& inputParticles, std::vector jetRadius, T const& collision, U& jetsTable, V& constituentsTable, bool doHFJetFinding = false) +{ + auto jetRValues = static_cast>(jetRadius); + for (auto R : jetRValues) { + jetFinder.jetR = R; + std::vector jets; + fastjet::ClusterSequenceArea clusterSeq(jetFinder.findJets(inputParticles, jets)); + for (const auto& jet : jets) { + bool isHFJet = false; + if (doHFJetFinding) { + for (const auto& constituent : jet.constituents()) { + if (constituent.template user_info().getStatus() == static_cast(JetConstituentStatus::candidateHF)) { + isHFJet = true; + break; + } + } + if (!isHFJet) { + continue; + } + } + std::vector trackconst; + std::vector candconst; + std::vector clusterconst; + jetsTable(collision.globalIndex(), jet.pt(), jet.eta(), jet.phi(), + jet.E(), jet.m(), jet.has_area() ? jet.area() : 0., std::round(R * 100)); + for (const auto& constituent : sorted_by_pt(jet.constituents())) { + if (constituent.template user_info().getStatus() == static_cast(JetConstituentStatus::track)) { + trackconst.push_back(constituent.template user_info().getIndex()); + } + if (constituent.template user_info().getStatus() == static_cast(JetConstituentStatus::cluster)) { + clusterconst.push_back(constituent.template user_info().getIndex()); + } + if (constituent.template user_info().getStatus() == static_cast(JetConstituentStatus::candidateHF)) { + candconst.push_back(constituent.template user_info().getIndex()); + } + } + constituentsTable(jetsTable.lastIndex(), trackconst, clusterconst, candconst); + } + } +} + +/** + * Adds particles to a fastjet inputParticles list + * + * @param inputParticles fastjet container + * @param particleSelection particle selection to be applied to particles + * @param jetTypeParticleLevel set whether charged particles, neutral particles or both are accepted + * @param particles particle table to be added + * @param pdgDatabase database of pdg codes + * @param candidate optional hf candidiate + */ +template +void analyseParticles(std::vector& inputParticles, std::string particleSelection, int jetTypeParticleLevel, T const& particles, o2::framework::Service pdgDatabase, std::optional const& candidate = std::nullopt) +{ + for (auto& particle : particles) { + if (particleSelection == "PhysicalPrimary" && !particle.isPhysicalPrimary()) { // CHECK : Does this exclude the HF hadron? + continue; + } else if (particleSelection == "HepMCStatus" && particle.getHepMCStatusCode() != 1) { // do we need isPhysicalPrimary as well? Note: Might give unforseen results if the generator isnt PYTHIA + continue; + } else if (particleSelection == "GenStatus" && particle.getGenStatusCode() != 1) { + continue; + } else if (particleSelection == "PhysicalPrimaryAndHepMCStatus" && (!particle.isPhysicalPrimary() || particle.getHepMCStatusCode() != 1)) { + continue; + } + if (isinf(particle.eta())) { + continue; + } + auto pdgParticle = pdgDatabase->GetParticle(particle.pdgCode()); + auto pdgCharge = pdgParticle ? std::abs(pdgParticle->Charge()) : -1.0; + if (jetTypeParticleLevel == static_cast(JetType::charged) && pdgCharge < 3.0) { + continue; + } + if (jetTypeParticleLevel == static_cast(JetType::neutral) && pdgCharge != 0.0) { + continue; + } + if constexpr (jethfutilities::isHFMcCandidate()) { + if (candidate != std::nullopt) { + auto cand = candidate.value(); + auto hfParticle = cand.template mcParticle_as(); + if (jethfutilities::isDaughterParticle(hfParticle, particles, particle.globalIndex()) || (hfParticle.globalIndex() == particle.globalIndex())) { + continue; + } + } + } + fastjetutilities::fillTracks(particle, inputParticles, particle.globalIndex(), static_cast(JetConstituentStatus::track), pdgParticle->Mass()); + } +} + +template +bool isInEtaAcceptance(T const& jet, float jetEtaMin, float jetEtaMax, float etaMin = -0.9, float etaMax = 0.9) +{ + if (jetEtaMin < -98.0) { + return (jet.eta() >= etaMin + (jet.r() / 100.0) && jet.eta() <= etaMax - (jet.r() / 100.0)); + } else { + return (jet.eta() >= jetEtaMin && jet.eta() <= jetEtaMax); + } +} + +}; // namespace jetfindingutilities + +#endif // PWGJE_CORE_JETFINDINGUTILITIES_H_ diff --git a/PWGJE/Core/JetHFUtilities.h b/PWGJE/Core/JetHFUtilities.h new file mode 100644 index 00000000000..b9b3e3c071b --- /dev/null +++ b/PWGJE/Core/JetHFUtilities.h @@ -0,0 +1,542 @@ +// 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 JetHFUtilities.h +/// \brief Jet HF related utilities +/// +/// \author Nima Zardoshti + +#ifndef PWGJE_CORE_JETHFUTILITIES_H_ +#define PWGJE_CORE_JETHFUTILITIES_H_ + +#include +#include +#include +#include + +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoA.h" +#include "Framework/O2DatabasePDGPlugin.h" + +#include "Framework/Logger.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "PWGJE/DataModel/EMCALClusters.h" + +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" +#include "PWGHF/DataModel/DerivedTables.h" + +#include "PWGJE/Core/FastJetUtilities.h" +#include "PWGJE/Core/JetDerivedDataUtilities.h" +#include "PWGJE/Core/JetFinder.h" +#include "PWGJE/DataModel/Jet.h" + +namespace jethfutilities +{ + +/** + * returns true if the candidate is from a D0 table + */ +template +constexpr bool isD0Candidate() +{ + return std::is_same_v, CandidatesD0Data::iterator> || std::is_same_v, CandidatesD0Data::filtered_iterator> || std::is_same_v, CandidatesD0MCD::iterator> || std::is_same_v, CandidatesD0MCD::filtered_iterator>; +} + +/** + * returns true if the particle is from a D0 MC table + */ +template +constexpr bool isD0McCandidate() +{ + return std::is_same_v, CandidatesD0MCP::iterator> || std::is_same_v, CandidatesD0MCP::filtered_iterator>; +} + +/** + * returns true if the table is a D0 table + */ +template +constexpr bool isD0Table() +{ + + return isD0Candidate() || isD0Candidate(); +} + +/** + * returns true if the table is a D0 MC table + */ +template +constexpr bool isD0McTable() +{ + + return isD0McCandidate() || isD0McCandidate(); +} + +/** + * returns true if the candidate is from a Lc table + */ +template +constexpr bool isLcCandidate() +{ + return std::is_same_v, CandidatesLcData::iterator> || std::is_same_v, CandidatesLcData::filtered_iterator> || std::is_same_v, CandidatesLcMCD::iterator> || std::is_same_v, CandidatesLcMCD::filtered_iterator>; +} + +/** + * returns true if the particle is from a Lc MC table + */ +template +constexpr bool isLcMcCandidate() +{ + return std::is_same_v, CandidatesLcMCP::iterator> || std::is_same_v, CandidatesLcMCP::filtered_iterator>; +} + +/** + * returns true if the table is a Lc table + */ +template +constexpr bool isLcTable() +{ + return isLcCandidate() || isLcCandidate(); +} + +/** + * returns true if the table is a Lc MC table + */ +template +constexpr bool isLcMcTable() +{ + return isLcMcCandidate() || isLcMcCandidate(); +} + +/** + * returns true if the candidate is from a Bplus table + */ +template +constexpr bool isBplusCandidate() +{ + return std::is_same_v, CandidatesBplusData::iterator> || std::is_same_v, CandidatesBplusData::filtered_iterator> || std::is_same_v, CandidatesBplusMCD::iterator> || std::is_same_v, CandidatesBplusMCD::filtered_iterator>; +} + +/** + * returns true if the particle is from a Bplus MC table + */ +template +constexpr bool isBplusMcCandidate() +{ + return std::is_same_v, CandidatesBplusMCP::iterator> || std::is_same_v, CandidatesBplusMCP::filtered_iterator>; +} + +/** + * returns true if the table is a Bplus table + */ +template +constexpr bool isBplusTable() +{ + return isBplusCandidate() || isBplusCandidate(); +} + +/** + * returns true if the table is a Bplus MC table + */ +template +constexpr bool isBplusMcTable() +{ + return isBplusMcCandidate() || isBplusMcCandidate(); +} + +/** + * returns true if the candidate is from a HF table + * * @param candidate candidate that is being checked + */ +template +constexpr bool isHFCandidate() +{ + if constexpr (isD0Candidate()) { + return true; + } else if constexpr (isLcCandidate()) { + return true; + } else if constexpr (isBplusCandidate()) { + return true; + } else { + return false; + } +} + +/** + * returns true if the candidate is from a MC HF table + * * @param candidate candidate that is being checked + */ +template +constexpr bool isHFMcCandidate() +{ + + if constexpr (isD0McCandidate()) { + return true; + } else if constexpr (isLcMcCandidate()) { + return true; + } else if constexpr (isBplusMcCandidate()) { + return true; + } else { + return false; + } +} + +/** + * returns true if the table type is a HF table + */ +template +constexpr bool isHFTable() +{ + + if constexpr (isD0Candidate() || isD0Candidate()) { + return true; + } else if constexpr (isLcCandidate() || isLcCandidate()) { + return true; + } else if constexpr (isBplusCandidate() || isBplusCandidate()) { + return true; + } else { + return false; + } +} + +/** + * returns true if the table type is a HF table + */ +template +constexpr bool isHFMcTable() +{ + + if constexpr (isD0McCandidate() || isD0McCandidate()) { + return true; + } else if constexpr (isLcMcCandidate() || isLcMcCandidate()) { + return true; + } else if constexpr (isBplusMcCandidate() || isBplusMcCandidate()) { + return true; + } else { + return false; + } +} + +/** + * returns true if the candidate is matched to a reconstructed level candidate with the correct decay + * * @param candidate candidate that is being checked + */ +template +constexpr bool isMatchedHFCandidate(T const& candidate) +{ + + if constexpr (isD0Candidate()) { + if (std::abs(candidate.flagMcMatchRec()) == 1 << o2::aod::hf_cand_2prong::DecayType::D0ToPiK) { + return true; + } else { + return false; + } + } else if constexpr (isLcCandidate()) { + if (std::abs(candidate.flagMcMatchRec()) == 1 << o2::aod::hf_cand_3prong::DecayType::LcToPKPi) { + return true; + } else { + return false; + } + } else if constexpr (isBplusCandidate()) { + if (std::abs(candidate.flagMcMatchRec()) == 1 << o2::aod::hf_cand_bplus::DecayType::BplusToD0Pi) { + return true; + } else { + return false; + } + } else if constexpr (isD0McCandidate()) { + if (std::abs(candidate.flagMcMatchGen()) == 1 << o2::aod::hf_cand_2prong::DecayType::D0ToPiK) { + return true; + } else { + return false; + } + } else if constexpr (isLcMcCandidate()) { + if (std::abs(candidate.flagMcMatchGen()) == 1 << o2::aod::hf_cand_3prong::DecayType::LcToPKPi) { + return true; + } else { + return false; + } + } else if constexpr (isBplusMcCandidate()) { + if (std::abs(candidate.flagMcMatchGen()) == 1 << o2::aod::hf_cand_bplus::DecayType::BplusToD0Pi) { + return true; + } else { + return false; + } + } else { + return false; + } +} + +/** + * returns true if the track is a daughter of the HF candidate + * + * @param track track that is being checked + * @param candidate HF candidate that is being checked + * @param tracks the track table + */ +template +bool isDaughterTrack(T& track, U& candidate, V& tracks) +{ + + if constexpr (isD0Candidate()) { + if (candidate.template prong0_as().globalIndex() == track.globalIndex() || candidate.template prong1_as().globalIndex() == track.globalIndex()) { + return true; + } else { + return false; + } + } else if constexpr (isLcCandidate()) { + if (candidate.template prong0_as().globalIndex() == track.globalIndex() || candidate.template prong1_as().globalIndex() == track.globalIndex() || candidate.template prong2_as().globalIndex() == track.globalIndex()) { + return true; + } else { + return false; + } + } else if constexpr (isBplusCandidate()) { + if (candidate.template prong0_as().template prong0_as().globalIndex() == track.globalIndex() || candidate.template prong0_as().template prong1_as().globalIndex() == track.globalIndex() || candidate.template prong1_as().globalIndex() == track.globalIndex()) { + return true; + } else { + return false; + } + } else { + return false; + } +} + +/** + * returns true if the particle has any daughters with the given global index + * + * @param candidate mother hf particle that is being checked + * @param globalIndex global index of potnetial daughter particle + */ +template +bool isDaughterParticle(T const& particle, U const& particles, int globalIndex) +{ + for (auto daughter : particle.template daughters_as()) { + if (daughter.globalIndex() == globalIndex) { + return true; + } + if (isDaughterParticle(daughter, particles, globalIndex)) { + return true; + } + } + return false; +} + +/** + * returns a slice of the table depending on the index of the candidate + * + * @param candidate HF 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& perLcCandidate, N const& perBplusCandidate) +{ + + if constexpr (isD0Candidate()) { + return table.sliceBy(perD0Candidate, candidate.globalIndex()); + } else if constexpr (isLcCandidate()) { + return table.sliceBy(perLcCandidate, candidate.globalIndex()); + } else if constexpr (isBplusCandidate()) { + return table.sliceBy(perBplusCandidate, candidate.globalIndex()); + } else { + return table; + } +} + +template +int getCandidatePDG(T const& candidate) +{ + + if constexpr (isD0Candidate() || isD0McCandidate()) { + return static_cast(o2::constants::physics::Pdg::kD0); + } + if constexpr (isLcCandidate() || isLcMcCandidate()) { + return static_cast(o2::constants::physics::Pdg::kLambdaCPlus); + } + if constexpr (isBplusCandidate() || isBplusMcCandidate()) { + return static_cast(o2::constants::physics::Pdg::kBPlus); + } else { + return 0; + } +} + +template +int getTablePDG() +{ + + if constexpr (isD0Table() || isD0McTable()) { + return static_cast(o2::constants::physics::Pdg::kD0); + } + if constexpr (isLcTable() || isLcMcTable()) { + return static_cast(o2::constants::physics::Pdg::kLambdaCPlus); + } + if constexpr (isBplusTable() || isBplusMcTable()) { + return static_cast(o2::constants::physics::Pdg::kBPlus); + } else { + return 0; + } +} + +template +float getCandidatePDGMass(T const& candidate) +{ + + if constexpr (isD0Candidate() || isD0McCandidate()) { + return static_cast(o2::constants::physics::MassD0); + } + if constexpr (isLcCandidate() || isLcMcCandidate()) { + return static_cast(o2::constants::physics::MassLambdaCPlus); + } + if constexpr (isBplusCandidate() || isBplusMcCandidate()) { + return static_cast(o2::constants::physics::MassBPlus); + } else { + return 0.; + } +} + +template +float getTablePDGMass() +{ + + if constexpr (isD0Table() || isD0McTable()) { + return static_cast(o2::constants::physics::MassD0); + } + if constexpr (isLcTable() || isLcMcTable()) { + return static_cast(o2::constants::physics::MassLambdaCPlus); + } + if constexpr (isBplusTable() || isBplusMcTable()) { + return static_cast(o2::constants::physics::MassBPlus); + } else { + return 0.; + } +} + +template +void fillD0CollisionTable(T const& collision, U& D0CollisionTable, int32_t& D0CollisionTableIndex) +{ + + D0CollisionTable(collision.numContrib(), collision.isEventReject(), collision.runNumber()); + D0CollisionTableIndex = D0CollisionTable.lastIndex(); +} + +template +void fillHFCollisionTable(T const& collision, U const& candidates, V& HFCollisionTable, int32_t& HFCollisionTableIndex) +{ + if constexpr (isD0Table()) { + fillD0CollisionTable(collision, HFCollisionTable, HFCollisionTableIndex); + } +} + +template +void fillD0CandidateTable(T const& candidate, int32_t collisionIndex, U& D0BaseTable, V& D0ParTable, M& D0ParETable, N& D0SelectionFlagTable, O& D0MCDTable, int32_t& D0CandidateTableIndex) +{ + + D0BaseTable(collisionIndex, candidate.pt(), candidate.eta(), candidate.phi(), candidate.m()); + + D0ParTable( + candidate.chi2PCA(), + candidate.decayLength(), + candidate.decayLengthXY(), + candidate.decayLengthNormalised(), + candidate.decayLengthXYNormalised(), + candidate.ptProng0(), + candidate.ptProng1(), + candidate.impactParameter0(), + candidate.impactParameter1(), + candidate.impactParameterNormalised0(), + candidate.impactParameterNormalised1(), + candidate.nSigTpcPi0(), + candidate.nSigTpcKa0(), + candidate.nSigTofPi0(), + candidate.nSigTofKa0(), + candidate.nSigTpcTofPi0(), + candidate.nSigTpcTofKa0(), + candidate.nSigTpcPi1(), + candidate.nSigTpcKa1(), + candidate.nSigTofPi1(), + candidate.nSigTofKa1(), + candidate.nSigTpcTofPi1(), + candidate.nSigTpcTofKa1(), + candidate.cpa(), + candidate.cpaXY(), + candidate.maxNormalisedDeltaIP(), + candidate.impactParameterProduct()); + + D0ParETable( + candidate.posX(), + candidate.posY(), + candidate.posZ(), + candidate.xSecondaryVertex(), + candidate.ySecondaryVertex(), + candidate.zSecondaryVertex(), + candidate.errorDecayLength(), + candidate.errorDecayLengthXY(), + candidate.kfTopolChi2OverNdf(), + candidate.rSecondaryVertex(), + candidate.pProng0(), + candidate.pProng1(), + candidate.pxProng0(), + candidate.pyProng0(), + candidate.pzProng0(), + candidate.pxProng1(), + candidate.pyProng1(), + candidate.pzProng1(), + candidate.errorImpactParameter0(), + candidate.errorImpactParameter1(), + candidate.cosThetaStar(), + candidate.ct()); + + D0SelectionFlagTable(candidate.candidateSelFlag()); + if constexpr (isMc) { + D0MCDTable(candidate.flagMcMatchRec(), candidate.originMcRec()); + } + + D0CandidateTableIndex = D0BaseTable.lastIndex(); +} + +template +void fillCandidateTable(T const& candidate, int32_t collisionIndex, U& HFBaseTable, V& HFParTable, M& HFParETable, N& HFSelectionFlagTable, O& HFMCDTable, int32_t& HFCandidateTableIndex) +{ + if constexpr (isD0Candidate()) { + fillD0CandidateTable(candidate, collisionIndex, HFBaseTable, HFParTable, HFParETable, HFSelectionFlagTable, HFMCDTable, HFCandidateTableIndex); + } +} + +template +void fillD0CandidateMcTable(T const& candidate, U& D0PBaseTable, int32_t& D0CandidateTableIndex) +{ + D0PBaseTable(candidate.pt(), candidate.eta(), candidate.phi(), candidate.flagMcMatchGen(), candidate.originMcGen()); + D0CandidateTableIndex = D0PBaseTable.lastIndex(); +} + +template +void fillCandidateMcTable(T const& candidate, U& BaseMcTable, int32_t& candidateTableIndex) +{ + if constexpr (isD0McCandidate()) { + fillD0CandidateMcTable(candidate, BaseMcTable, candidateTableIndex); + } +} + +template +auto getCandidateCollision(T const& candidate, U const& candidateCollisions) +{ + if constexpr (isD0Candidate()) { // make sure this actually is working + return candidate.template hfD0CollBase_as(); + } else { + return candidate.template hfD0CollBase_as(); + } +} + +}; // namespace jethfutilities + +#endif // PWGJE_CORE_JETHFUTILITIES_H_ diff --git a/PWGJE/Core/JetMatchingUtilities.h b/PWGJE/Core/JetMatchingUtilities.h new file mode 100644 index 00000000000..19cf12f85cf --- /dev/null +++ b/PWGJE/Core/JetMatchingUtilities.h @@ -0,0 +1,438 @@ +// 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 JetMatchingUtilities.h +/// \brief Jet Matching related utilities +/// +/// \author Raymond Ehlers , ORNL +/// \author Jochen Klein +/// \author Aimeric Lanodu +/// \author Nima Zardoshti + +#ifndef PWGJE_CORE_JETMATCHINGUTILITIES_H_ +#define PWGJE_CORE_JETMATCHINGUTILITIES_H_ + +#include +#include +#include +#include +#include + +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoA.h" +#include "Framework/O2DatabasePDGPlugin.h" + +#include "Framework/Logger.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "PWGJE/DataModel/EMCALClusters.h" + +#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" + +#include "PWGJE/DataModel/Jet.h" + +namespace jetmatchingutilities +{ + +/** + * Duplicates jets around the phi boundary which are within the matching distance. + * + * NOTE: Assumes, but does not validate, that 0 <= phi < 2pi. + * + * @param jetsPhi Jets phi + * @param jetsEta Jets eta + * @param maxMatchingDistance Maximum matching distance. Only duplicate jets within this distance of the boundary. + */ +template +std::tuple, std::vector, std::vector> DuplicateJetsAroundPhiBoundary( + std::vector& jetsPhi, + std::vector& jetsEta, + double maxMatchingDistance, + // TODO: Remove additional margin after additional testing. + double additionalMargin = 0.05) +{ + const std::size_t nJets = jetsPhi.size(); + std::vector jetsMapToJetIndex(nJets); + // We need to keep track of the map from the duplicated vector to the existing jets. + // To start, we fill this map (practically, it maps from vector index to an index, so we + // just use a standard vector) with the existing jet indices, which range from 0..nJets. + std::iota(jetsMapToJetIndex.begin(), jetsMapToJetIndex.end(), 0); + + // The full duplicated jets will be stored in a new vector to avoid disturbing the input data. + std::vector jetsPhiComparison(jetsPhi); + std::vector jetsEtaComparison(jetsEta); + + // Duplicate the jets + // When a jet is outside of the desired phi range, we make a copy of the jet, shifting it by 2pi + // as necessary. The eta value is copied directly, as is the index of the original jet, so we can + // map from index in duplicated data -> index in original collection. + // NOTE: Assumes, but does not validate, that 0 <= phi < 2pi. + for (std::size_t i = 0; i < nJets; i++) { + // Handle lower edge + if (jetsPhi[i] <= (maxMatchingDistance + additionalMargin)) { + jetsPhiComparison.emplace_back(jetsPhi[i] + 2 * M_PI); + jetsEtaComparison.emplace_back(jetsEta[i]); + jetsMapToJetIndex.emplace_back(jetsMapToJetIndex[i]); + } + // Handle upper edge + if (jetsPhi[i] >= (2 * M_PI - (maxMatchingDistance + additionalMargin))) { + jetsPhiComparison.emplace_back(jetsPhi[i] - 2 * M_PI); + jetsEtaComparison.emplace_back(jetsEta[i]); + jetsMapToJetIndex.emplace_back(jetsMapToJetIndex[i]); + } + } + + return {jetsMapToJetIndex, jetsPhiComparison, jetsEtaComparison}; +} + +/** + * Implementation of geometrical jet matching. + * + * Jets are required to match uniquely - namely: base <-> tag. Only one direction of matching isn't enough. + * Unless special conditions are required, it's better to use `MatchJetsGeometrically`, which has an + * easier to use interface. + * + * NOTE: The vectors for matching could all be const, except that SetData() doesn't take a const. + * + * @param jetsBasePhi Base jet collection phi. + * @param jetsBaseEta Base jet collection eta. + * @param jetsBasePhiForMatching Base jet collection phi to use for matching. + * @param jetsBaseEtaForMatching Base jet collection eta to use for matching. + * @param jetMapBaseToJetIndex Base jet collection index map from duplicated jets to original jets. + * @param jetsTagPhi Tag jet collection phi. + * @param jetsTagEta Tag jet collection eta. + * @param jetsTagPhiForMatching Tag jet collection phi to use for matching. + * @param jetsTagEtaForMatching Tag jet collection eta to use for matching. + * @param jetMapTagToJetIndex Tag jet collection index map from duplicated jets to original jets. + * @param maxMatchingDistance Maximum matching distance. + * + * @returns (Base to tag index map, tag to base index map) for uniquely matched jets. + */ +template +std::tuple, std::vector> MatchJetsGeometricallyImpl( + const std::vector& jetsBasePhi, + const std::vector& jetsBaseEta, + std::vector jetsBasePhiForMatching, + std::vector jetsBaseEtaForMatching, + const std::vector jetMapBaseToJetIndex, + const std::vector& jetsTagPhi, + const std::vector& jetsTagEta, + std::vector jetsTagPhiForMatching, + std::vector jetsTagEtaForMatching, + const std::vector jetMapTagToJetIndex, + double maxMatchingDistance) +{ + // Validation + // If no jets in either collection, then return immediately. + const std::size_t nJetsBase = jetsBaseEta.size(); + const std::size_t nJetsTag = jetsTagEta.size(); + if (!(nJetsBase && nJetsTag)) { + return std::make_tuple(std::vector(nJetsBase, -1), std::vector(nJetsTag, -1)); + } + // Require that the comparison vectors are greater than or equal to the standard collections. + if (jetsBasePhiForMatching.size() < jetsBasePhi.size()) { + throw std::invalid_argument("Base collection phi for matching is smaller than the input base collection."); + } + if (jetsBaseEtaForMatching.size() < jetsBaseEta.size()) { + throw std::invalid_argument("Base collection eta for matching is smaller than the input base collection."); + } + if (jetsTagPhiForMatching.size() < jetsTagPhi.size()) { + throw std::invalid_argument("Tag collection phi for matching is smaller than the input tag collection."); + } + if (jetsTagEtaForMatching.size() < jetsTagEta.size()) { + throw std::invalid_argument("Tag collection eta for matching is smaller than the input tag collection."); + } + + // Build the KD-trees using vectors + // We build two trees: + // treeBase, which contains the base collection. + // treeTag, which contains the tag collection. + // The trees are built to match in two dimensions (eta, phi) + TKDTree treeBase(jetsBaseEtaForMatching.size(), 2, 1), treeTag(jetsTagEtaForMatching.size(), 2, 1); + // By utilizing SetData, we can avoid having to copy the data again. + treeBase.SetData(0, jetsBaseEtaForMatching.data()); + treeBase.SetData(1, jetsBasePhiForMatching.data()); + treeBase.Build(); + treeTag.SetData(0, jetsTagEtaForMatching.data()); + treeTag.SetData(1, jetsTagPhiForMatching.data()); + treeTag.Build(); + + // Storage for the jet matching indices. + // matchIndexTag maps from the base index to the tag index. + // matchBaseTag maps from the tag index to the base index. + std::vector matchIndexTag(nJetsBase, -1), matchIndexBase(nJetsTag, -1); + + // Find the tag jet closest to each base jet. + for (std::size_t iBase = 0; iBase < nJetsBase; iBase++) { + Double_t point[2] = {jetsBaseEta[iBase], jetsBasePhi[iBase]}; + Int_t index(-1); + Double_t distance(-1); + treeTag.FindNearestNeighbors(point, 1, &index, &distance); + // test whether indices are matching: + if (index >= 0 && distance < maxMatchingDistance) { + LOG(debug) << "Found closest tag jet for " << iBase << " with match index " << index << " and distance " << distance << "\n"; + matchIndexTag[iBase] = index; + } else { + LOG(debug) << "Closest tag jet not found for " << iBase << ", distance to closest " << distance << "\n"; + } + } + + // Find the base jet closest to each tag jet + for (std::size_t iTag = 0; iTag < nJetsTag; iTag++) { + Double_t point[2] = {jetsTagEta[iTag], jetsTagPhi[iTag]}; + Int_t index(-1); + Double_t distance(-1); + treeBase.FindNearestNeighbors(point, 1, &index, &distance); + if (index >= 0 && distance < maxMatchingDistance) { + LOG(debug) << "Found closest base jet for " << iTag << " with match index " << index << " and distance " << distance << std::endl; + matchIndexBase[iTag] = index; + } else { + LOG(debug) << "Closest tag jet not found for " << iTag << ", distance to closest " << distance << "\n"; + } + } + + // Convert indices in the duplicated jet vectors into the original jet indices. + // First for the base -> tag map. + for (auto& v : matchIndexTag) { + // If it's -1, it means that it didn't find a matching jet. + // We have to explicitly check for it here because it would be an invalid index. + if (v != -1) { + v = jetMapTagToJetIndex[v]; + } + } + // Then for the index -> base map. + for (auto& v : matchIndexBase) { + if (v != -1) { + v = jetMapBaseToJetIndex[v]; + } + } + + // Finally, we'll check for true matches, which are pairs where the base jet is the + // closest to the tag jet and vice versa + // As the lists are linear a loop over the outer base jet is sufficient. + std::vector baseToTagMap(nJetsBase, -1); + std::vector tagToBaseMap(nJetsTag, -1); + LOG(debug) << "Starting true jet loop: nbase(" << nJetsBase << "), ntag(" << nJetsTag << ")\n"; + for (std::size_t iBase = 0; iBase < nJetsBase; iBase++) { + LOG(debug) << "base jet " << iBase << ": match index in tag jet container " << matchIndexTag[iBase] << "\n"; + if (matchIndexTag[iBase] > -1) { + LOG(debug) << "tag jet " << matchIndexTag[iBase] << ": matched base jet " << matchIndexBase[matchIndexTag[iBase]] << "\n"; + } + if (matchIndexTag[iBase] > -1 && matchIndexBase[matchIndexTag[iBase]] == static_cast(iBase)) { + LOG(debug) << "True match! base index: " << iBase << ", tag index: " << matchIndexTag[iBase] << "\n"; + baseToTagMap[iBase] = matchIndexTag[iBase]; + tagToBaseMap[matchIndexTag[iBase]] = iBase; + } + } + + return std::make_tuple(baseToTagMap, tagToBaseMap); +} + +/** + * Geometrical jet matching. + * + * Match jets in the "base" collection with those in the "tag" collection. Jets are matched within + * the provided matching distance. Jets are required to match uniquely - namely: base <-> tag. + * Only one direction of matching isn't enough. + * + * If no unique match was found for a jet, an index of -1 is stored. + * + * @param jetsBasePhi Base jet collection phi. + * @param jetsBaseEta Base jet collection eta. + * @param jetsTagPhi Tag jet collection phi. + * @param jetsTagEta Tag jet collection eta. + * @param maxMatchingDistance Maximum matching distance. + * + * @returns (Base to tag index map, tag to base index map) for uniquely matched jets. + */ +template +std::tuple, std::vector> MatchJetsGeometrically( + std::vector jetsBasePhi, + std::vector jetsBaseEta, + std::vector jetsTagPhi, + std::vector jetsTagEta, + double maxMatchingDistance) +{ + // Validation + const std::size_t nJetsBase = jetsBaseEta.size(); + const std::size_t nJetsTag = jetsTagEta.size(); + if (!(nJetsBase && nJetsTag)) { + // There are no jets, so nothing to be done. + return std::make_tuple(std::vector(nJetsBase, -1), std::vector(nJetsTag, -1)); + } + // Input sizes must match + if (jetsBasePhi.size() != jetsBaseEta.size()) { + throw std::invalid_argument("Base collection eta and phi sizes don't match. Check the inputs."); + } + if (jetsTagPhi.size() != jetsTagEta.size()) { + throw std::invalid_argument("Tag collection eta and phi sizes don't match. Check the inputs."); + } + + // To perform matching with periodic boundary conditions (ie. phi) with a KDTree, we need + // to duplicate data up to maxMatchingDistance in phi because phi is periodic. + // NOTE: vectors are modified in place to avoid copies. + auto&& [jetMapBaseToJetIndex, jetsBasePhiComparison, jetsBaseEtaComparison] = DuplicateJetsAroundPhiBoundary(jetsBasePhi, jetsBaseEta, maxMatchingDistance); + auto&& [jetMapTagToJetIndex, jetsTagPhiComparison, jetsTagEtaComparison] = DuplicateJetsAroundPhiBoundary(jetsTagPhi, jetsTagEta, maxMatchingDistance); + + // Finally, perform the actual matching. + auto&& [baseToTagMap, tagToBaseMap] = MatchJetsGeometricallyImpl( + jetsBasePhi, jetsBaseEta, jetsBasePhiComparison, jetsBaseEtaComparison, jetMapBaseToJetIndex, + jetsTagPhi, jetsTagEta, jetsTagPhiComparison, jetsTagEtaComparison, jetMapTagToJetIndex, + maxMatchingDistance); + + return std::make_tuple(baseToTagMap, tagToBaseMap); +} + +template +void MatchGeo(T const& jetsBasePerCollision, U const& jetsTagPerCollision, std::vector>& baseToTagMatchingGeo, std::vector>& tagToBaseMatchingGeo, float maxMatchingDistance) +{ + std::vector baseToTagMatchingGeoIndex; + std::vector tagToBaseMatchingGeoIndex; + std::vector jetsBasePhi; + std::vector jetsBaseEta; + for (const auto& jetBase : jetsBasePerCollision) { + jetsBasePhi.emplace_back(jetBase.phi()); + jetsBaseEta.emplace_back(jetBase.eta()); + } + std::vector jetsTagPhi; + std::vector jetsTagEta; + for (const auto& jetTag : jetsTagPerCollision) { + jetsTagPhi.emplace_back(jetTag.phi()); + jetsTagEta.emplace_back(jetTag.eta()); + } + std::tie(baseToTagMatchingGeoIndex, tagToBaseMatchingGeoIndex) = MatchJetsGeometrically(jetsBasePhi, jetsBaseEta, jetsTagPhi, jetsTagEta, maxMatchingDistance); // change max distnace to a function call + for (const auto& jetBase : jetsBasePerCollision) { + int jetTagIndex = baseToTagMatchingGeoIndex[jetBase.index()]; + int jetTagGlobalIndex; + if (jetTagIndex > -1 && jetTagIndex < jetsTagPerCollision.size()) { + jetTagGlobalIndex = jetsTagPerCollision.iteratorAt(jetTagIndex).globalIndex(); + baseToTagMatchingGeo[jetBase.globalIndex()].push_back(jetTagGlobalIndex); + } + } + for (const auto& jetTag : jetsTagPerCollision) { + int jetBaseIndex = tagToBaseMatchingGeoIndex[jetTag.index()]; + int jetBaseGlobalIndex; + if (jetBaseIndex > -1 && jetBaseIndex < jetsBasePerCollision.size()) { + jetBaseGlobalIndex = jetsBasePerCollision.iteratorAt(jetBaseIndex).globalIndex(); + tagToBaseMatchingGeo[jetTag.globalIndex()].push_back(jetBaseGlobalIndex); + } + } +} + +// function that does the HF matching of jets from jetsBasePerColl and jets from jetsTagPerColl; assumes both jetsBasePerColl and jetsTagPerColl have access to Mc information +template +void MatchHF(T const& jetsBasePerCollision, U const& jetsTagPerCollision, std::vector>& baseToTagMatchingHF, std::vector>& tagToBaseMatchingHF, V const& candidatesBase, M const& candidatesTag, N const& tracksBase, O const& tracksTag) +{ + for (const auto& jetBase : jetsBasePerCollision) { + const auto candidateBase = jetBase.template hfcandidates_first_as(); + for (const auto& jetTag : jetsTagPerCollision) { + if constexpr (jetsBaseIsMc || jetsTagIsMc) { + if (jethfutilities::isMatchedHFCandidate(candidateBase)) { + const auto candidateBaseDaughterParticle = candidateBase.template prong1_as().template mcParticle_as(); + const auto candidateBaseMcId = candidateBaseDaughterParticle.template mothers_first_as().globalIndex(); + const auto candidateTag = jetTag.template hfcandidates_first_as(); + const auto candidateTagId = candidateTag.mcParticleId(); + if (candidateBaseMcId == candidateTagId) { + baseToTagMatchingHF[jetBase.globalIndex()].push_back(jetTag.globalIndex()); + tagToBaseMatchingHF[jetTag.globalIndex()].push_back(jetBase.globalIndex()); + } + } + } else { + const auto candidateTag = jetTag.template hfcandidates_first_as(); + if (candidateBase.globalIndex() == candidateTag.globalIndex()) { + baseToTagMatchingHF[jetBase.globalIndex()].push_back(jetTag.globalIndex()); + tagToBaseMatchingHF[jetTag.globalIndex()].push_back(jetBase.globalIndex()); + } + } + } + } +} + +template +auto constexpr getTrackId(T const& track) +{ + if constexpr (isMc) { + + if (track.has_mcParticle()) { + return track.mcParticleId(); + } else { + return -1; + } + + } else { + return track.globalIndex(); + } +} + +template +float getPtSum(T const& tracksBase, U const& tracksTag) +{ + float ptSum = 0.; + for (const auto& trackBase : tracksBase) { + auto trackBaseId = getTrackId(trackBase); + for (const auto& trackTag : tracksTag) { + auto trackTagId = getTrackId(trackTag); + if (trackBaseId != -1 && trackBaseId == trackTagId) { + ptSum += trackBase.pt(); + break; + } + } + } + return ptSum; +} + +template +void MatchPt(T const& jetsBasePerCollision, U const& jetsTagPerCollision, std::vector>& baseToTagMatchingPt, std::vector>& tagToBaseMatchingPt, V const& tracksBase, M const& tracksTag, float minPtFraction) +{ + float ptSumBase; + float ptSumTag; + for (const auto& jetBase : jetsBasePerCollision) { + auto jetBaseTracks = jetBase.template tracks_as(); + for (const auto& jetTag : jetsTagPerCollision) { + auto jetTagTracks = jetTag.template tracks_as(); + + ptSumBase = getPtSum(jetBaseTracks, jetTagTracks); + ptSumTag = getPtSum(jetTagTracks, jetBaseTracks); + if (ptSumBase > jetBase.pt() * minPtFraction) { + baseToTagMatchingPt[jetBase.globalIndex()].push_back(jetTag.globalIndex()); + } + if (ptSumTag > jetTag.pt() * minPtFraction) { + tagToBaseMatchingPt[jetTag.globalIndex()].push_back(jetBase.globalIndex()); + } + } + } +} + +// function that calls all the Match functions +template +void doAllMatching(T const& jetsBasePerCollision, U const& jetsTagPerCollision, std::vector>& baseToTagMatchingGeo, std::vector>& baseToTagMatchingPt, std::vector>& baseToTagMatchingHF, std::vector>& tagToBaseMatchingGeo, std::vector>& tagToBaseMatchingPt, std::vector>& tagToBaseMatchingHF, V const& candidatesBase, M const& candidatesTag, N const& tracksBase, O const& tracksTag, bool doMatchingGeo, bool doMatchingHf, bool doMatchingPt, float maxMatchingDistance, float minPtFraction) +{ + // geometric matching + if (doMatchingGeo) { + MatchGeo(jetsBasePerCollision, jetsTagPerCollision, baseToTagMatchingGeo, tagToBaseMatchingGeo, maxMatchingDistance); + } + // pt matching + if (doMatchingPt) { + MatchPt(jetsBasePerCollision, jetsTagPerCollision, baseToTagMatchingPt, tagToBaseMatchingPt, tracksBase, tracksTag, minPtFraction); + } + // HF matching + if constexpr (jethfutilities::isHFTable()) { + if (doMatchingHf) { + MatchHF(jetsBasePerCollision, jetsTagPerCollision, baseToTagMatchingHF, tagToBaseMatchingHF, candidatesBase, candidatesTag, tracksBase, tracksTag); + } + } +} +}; // namespace jetmatchingutilities +#endif // PWGJE_CORE_JETMATCHINGUTILITIES_H_ diff --git a/PWGJE/Core/JetTaggingUtilities.h b/PWGJE/Core/JetTaggingUtilities.h index f5fa56272c7..e0edfe7e611 100644 --- a/PWGJE/Core/JetTaggingUtilities.h +++ b/PWGJE/Core/JetTaggingUtilities.h @@ -36,7 +36,7 @@ enum JetTaggingSpecies { gluon = 5 }; -namespace JetTaggingUtilities +namespace jettaggingutilities { /** * returns the globalIndex of the earliest mother of a particle in the shower. returns -1 if a suitable mother is not found @@ -180,7 +180,7 @@ int mcdJetFromHFShower(T const& jet, U const& tracks, V const& particles, float int originalHFMotherIndex = getOriginalHFMotherIndex(hfparticle); if (originalHFMotherIndex > -1.0) { - if (JetUtilities::deltaR(jet, particles.iteratorAt(originalHFMotherIndex)) < dRMax) { + if (jetutilities::deltaR(jet, particles.iteratorAt(originalHFMotherIndex)) < dRMax) { return origin; @@ -217,7 +217,7 @@ int mcpJetFromHFShower(T const& jet, U const& particles, float dRMax = 0.25) int originalHFMotherIndex = getOriginalHFMotherIndex(hfparticle); if (originalHFMotherIndex > -1.0) { - if (JetUtilities::deltaR(jet, particles.iteratorAt(originalHFMotherIndex)) < dRMax) { + if (jetutilities::deltaR(jet, particles.iteratorAt(originalHFMotherIndex)) < dRMax) { return origin; @@ -260,8 +260,8 @@ int jetOrigin(T const& jet, U const& particles, float dRMax = 0.25) } } - float dR1 = JetUtilities::deltaR(jet, parton1); - float dR2 = JetUtilities::deltaR(jet, parton2); + float dR1 = jetutilities::deltaR(jet, parton1); + float dR2 = jetutilities::deltaR(jet, parton2); if (dR1 <= dR2 && dR1 < dRMax) { @@ -275,6 +275,6 @@ int jetOrigin(T const& jet, U const& particles, float dRMax = 0.25) return 0; } -}; // namespace JetTaggingUtilities +}; // namespace jettaggingutilities #endif // PWGJE_CORE_JETTAGGINGUTILITIES_H_ diff --git a/PWGJE/Core/JetUtilities.h b/PWGJE/Core/JetUtilities.h index 83dda3030e8..a681d76bf89 100644 --- a/PWGJE/Core/JetUtilities.h +++ b/PWGJE/Core/JetUtilities.h @@ -29,256 +29,8 @@ #include "Framework/Logger.h" #include "Common/Core/RecoDecay.h" -namespace JetUtilities +namespace jetutilities { -/** - * Duplicates jets around the phi boundary which are within the matching distance. - * - * NOTE: Assumes, but does not validate, that 0 <= phi < 2pi. - * - * @param jetsPhi Jets phi - * @param jetsEta Jets eta - * @param maxMatchingDistance Maximum matching distance. Only duplicate jets within this distance of the boundary. - */ -template -std::tuple, std::vector, std::vector> DuplicateJetsAroundPhiBoundary( - std::vector& jetsPhi, - std::vector& jetsEta, - double maxMatchingDistance, - // TODO: Remove additional margin after additional testing. - double additionalMargin = 0.05) -{ - const std::size_t nJets = jetsPhi.size(); - std::vector jetsMapToJetIndex(nJets); - // We need to keep track of the map from the duplicated vector to the existing jets. - // To start, we fill this map (practically, it maps from vector index to an index, so we - // just use a standard vector) with the existing jet indices, which range from 0..nJets. - std::iota(jetsMapToJetIndex.begin(), jetsMapToJetIndex.end(), 0); - - // The full duplicated jets will be stored in a new vector to avoid disturbing the input data. - std::vector jetsPhiComparison(jetsPhi); - std::vector jetsEtaComparison(jetsEta); - - // Duplicate the jets - // When a jet is outside of the desired phi range, we make a copy of the jet, shifting it by 2pi - // as necessary. The eta value is copied directly, as is the index of the original jet, so we can - // map from index in duplicated data -> index in original collection. - // NOTE: Assumes, but does not validate, that 0 <= phi < 2pi. - for (std::size_t i = 0; i < nJets; i++) { - // Handle lower edge - if (jetsPhi[i] <= (maxMatchingDistance + additionalMargin)) { - jetsPhiComparison.emplace_back(jetsPhi[i] + 2 * M_PI); - jetsEtaComparison.emplace_back(jetsEta[i]); - jetsMapToJetIndex.emplace_back(jetsMapToJetIndex[i]); - } - // Handle upper edge - if (jetsPhi[i] >= (2 * M_PI - (maxMatchingDistance + additionalMargin))) { - jetsPhiComparison.emplace_back(jetsPhi[i] - 2 * M_PI); - jetsEtaComparison.emplace_back(jetsEta[i]); - jetsMapToJetIndex.emplace_back(jetsMapToJetIndex[i]); - } - } - - return {jetsMapToJetIndex, jetsPhiComparison, jetsEtaComparison}; -} - -/** - * Implementation of geometrical jet matching. - * - * Jets are required to match uniquely - namely: base <-> tag. Only one direction of matching isn't enough. - * Unless special conditions are required, it's better to use `MatchJetsGeometrically`, which has an - * easier to use interface. - * - * NOTE: The vectors for matching could all be const, except that SetData() doesn't take a const. - * - * @param jetsBasePhi Base jet collection phi. - * @param jetsBaseEta Base jet collection eta. - * @param jetsBasePhiForMatching Base jet collection phi to use for matching. - * @param jetsBaseEtaForMatching Base jet collection eta to use for matching. - * @param jetMapBaseToJetIndex Base jet collection index map from duplicated jets to original jets. - * @param jetsTagPhi Tag jet collection phi. - * @param jetsTagEta Tag jet collection eta. - * @param jetsTagPhiForMatching Tag jet collection phi to use for matching. - * @param jetsTagEtaForMatching Tag jet collection eta to use for matching. - * @param jetMapTagToJetIndex Tag jet collection index map from duplicated jets to original jets. - * @param maxMatchingDistance Maximum matching distance. - * - * @returns (Base to tag index map, tag to base index map) for uniquely matched jets. - */ -template -std::tuple, std::vector> MatchJetsGeometricallyImpl( - const std::vector& jetsBasePhi, - const std::vector& jetsBaseEta, - std::vector jetsBasePhiForMatching, - std::vector jetsBaseEtaForMatching, - const std::vector jetMapBaseToJetIndex, - const std::vector& jetsTagPhi, - const std::vector& jetsTagEta, - std::vector jetsTagPhiForMatching, - std::vector jetsTagEtaForMatching, - const std::vector jetMapTagToJetIndex, - double maxMatchingDistance) -{ - // Validation - // If no jets in either collection, then return immediately. - const std::size_t nJetsBase = jetsBaseEta.size(); - const std::size_t nJetsTag = jetsTagEta.size(); - if (!(nJetsBase && nJetsTag)) { - return std::make_tuple(std::vector(nJetsBase, -1), std::vector(nJetsTag, -1)); - } - // Require that the comparison vectors are greater than or equal to the standard collections. - if (jetsBasePhiForMatching.size() < jetsBasePhi.size()) { - throw std::invalid_argument("Base collection phi for matching is smaller than the input base collection."); - } - if (jetsBaseEtaForMatching.size() < jetsBaseEta.size()) { - throw std::invalid_argument("Base collection eta for matching is smaller than the input base collection."); - } - if (jetsTagPhiForMatching.size() < jetsTagPhi.size()) { - throw std::invalid_argument("Tag collection phi for matching is smaller than the input tag collection."); - } - if (jetsTagEtaForMatching.size() < jetsTagEta.size()) { - throw std::invalid_argument("Tag collection eta for matching is smaller than the input tag collection."); - } - - // Build the KD-trees using vectors - // We build two trees: - // treeBase, which contains the base collection. - // treeTag, which contains the tag collection. - // The trees are built to match in two dimensions (eta, phi) - TKDTree treeBase(jetsBaseEtaForMatching.size(), 2, 1), treeTag(jetsTagEtaForMatching.size(), 2, 1); - // By utilizing SetData, we can avoid having to copy the data again. - treeBase.SetData(0, jetsBaseEtaForMatching.data()); - treeBase.SetData(1, jetsBasePhiForMatching.data()); - treeBase.Build(); - treeTag.SetData(0, jetsTagEtaForMatching.data()); - treeTag.SetData(1, jetsTagPhiForMatching.data()); - treeTag.Build(); - - // Storage for the jet matching indices. - // matchIndexTag maps from the base index to the tag index. - // matchBaseTag maps from the tag index to the base index. - std::vector matchIndexTag(nJetsBase, -1), matchIndexBase(nJetsTag, -1); - - // Find the tag jet closest to each base jet. - for (std::size_t iBase = 0; iBase < nJetsBase; iBase++) { - Double_t point[2] = {jetsBaseEta[iBase], jetsBasePhi[iBase]}; - Int_t index(-1); - Double_t distance(-1); - treeTag.FindNearestNeighbors(point, 1, &index, &distance); - // test whether indices are matching: - if (index >= 0 && distance < maxMatchingDistance) { - LOG(debug) << "Found closest tag jet for " << iBase << " with match index " << index << " and distance " << distance << "\n"; - matchIndexTag[iBase] = index; - } else { - LOG(debug) << "Closest tag jet not found for " << iBase << ", distance to closest " << distance << "\n"; - } - } - - // Find the base jet closest to each tag jet - for (std::size_t iTag = 0; iTag < nJetsTag; iTag++) { - Double_t point[2] = {jetsTagEta[iTag], jetsTagPhi[iTag]}; - Int_t index(-1); - Double_t distance(-1); - treeBase.FindNearestNeighbors(point, 1, &index, &distance); - if (index >= 0 && distance < maxMatchingDistance) { - LOG(debug) << "Found closest base jet for " << iTag << " with match index " << index << " and distance " << distance << std::endl; - matchIndexBase[iTag] = index; - } else { - LOG(debug) << "Closest tag jet not found for " << iTag << ", distance to closest " << distance << "\n"; - } - } - - // Convert indices in the duplicated jet vectors into the original jet indices. - // First for the base -> tag map. - for (auto& v : matchIndexTag) { - // If it's -1, it means that it didn't find a matching jet. - // We have to explicitly check for it here because it would be an invalid index. - if (v != -1) { - v = jetMapTagToJetIndex[v]; - } - } - // Then for the index -> base map. - for (auto& v : matchIndexBase) { - if (v != -1) { - v = jetMapBaseToJetIndex[v]; - } - } - - // Finally, we'll check for true matches, which are pairs where the base jet is the - // closest to the tag jet and vice versa - // As the lists are linear a loop over the outer base jet is sufficient. - std::vector baseToTagMap(nJetsBase, -1); - std::vector tagToBaseMap(nJetsTag, -1); - LOG(debug) << "Starting true jet loop: nbase(" << nJetsBase << "), ntag(" << nJetsTag << ")\n"; - for (std::size_t iBase = 0; iBase < nJetsBase; iBase++) { - LOG(debug) << "base jet " << iBase << ": match index in tag jet container " << matchIndexTag[iBase] << "\n"; - if (matchIndexTag[iBase] > -1) { - LOG(debug) << "tag jet " << matchIndexTag[iBase] << ": matched base jet " << matchIndexBase[matchIndexTag[iBase]] << "\n"; - } - if (matchIndexTag[iBase] > -1 && matchIndexBase[matchIndexTag[iBase]] == static_cast(iBase)) { - LOG(debug) << "True match! base index: " << iBase << ", tag index: " << matchIndexTag[iBase] << "\n"; - baseToTagMap[iBase] = matchIndexTag[iBase]; - tagToBaseMap[matchIndexTag[iBase]] = iBase; - } - } - - return std::make_tuple(baseToTagMap, tagToBaseMap); -} - -/** - * Geometrical jet matching. - * - * Match jets in the "base" collection with those in the "tag" collection. Jets are matched within - * the provided matching distance. Jets are required to match uniquely - namely: base <-> tag. - * Only one direction of matching isn't enough. - * - * If no unique match was found for a jet, an index of -1 is stored. - * - * @param jetsBasePhi Base jet collection phi. - * @param jetsBaseEta Base jet collection eta. - * @param jetsTagPhi Tag jet collection phi. - * @param jetsTagEta Tag jet collection eta. - * @param maxMatchingDistance Maximum matching distance. - * - * @returns (Base to tag index map, tag to base index map) for uniquely matched jets. - */ -template -std::tuple, std::vector> MatchJetsGeometrically( - std::vector jetsBasePhi, - std::vector jetsBaseEta, - std::vector jetsTagPhi, - std::vector jetsTagEta, - double maxMatchingDistance) -{ - // Validation - const std::size_t nJetsBase = jetsBaseEta.size(); - const std::size_t nJetsTag = jetsTagEta.size(); - if (!(nJetsBase && nJetsTag)) { - // There are no jets, so nothing to be done. - return std::make_tuple(std::vector(nJetsBase, -1), std::vector(nJetsTag, -1)); - } - // Input sizes must match - if (jetsBasePhi.size() != jetsBaseEta.size()) { - throw std::invalid_argument("Base collection eta and phi sizes don't match. Check the inputs."); - } - if (jetsTagPhi.size() != jetsTagEta.size()) { - throw std::invalid_argument("Tag collection eta and phi sizes don't match. Check the inputs."); - } - - // To perform matching with periodic boundary conditions (ie. phi) with a KDTree, we need - // to duplicate data up to maxMatchingDistance in phi because phi is periodic. - // NOTE: vectors are modified in place to avoid copies. - auto&& [jetMapBaseToJetIndex, jetsBasePhiComparison, jetsBaseEtaComparison] = DuplicateJetsAroundPhiBoundary(jetsBasePhi, jetsBaseEta, maxMatchingDistance); - auto&& [jetMapTagToJetIndex, jetsTagPhiComparison, jetsTagEtaComparison] = DuplicateJetsAroundPhiBoundary(jetsTagPhi, jetsTagEta, maxMatchingDistance); - - // Finally, perform the actual matching. - auto&& [baseToTagMap, tagToBaseMap] = MatchJetsGeometricallyImpl( - jetsBasePhi, jetsBaseEta, jetsBasePhiComparison, jetsBaseEtaComparison, jetMapBaseToJetIndex, - jetsTagPhi, jetsTagEta, jetsTagPhiComparison, jetsTagEtaComparison, jetMapTagToJetIndex, - maxMatchingDistance); - - return std::make_tuple(baseToTagMap, tagToBaseMap); -} /** * Match clusters and tracks. @@ -395,6 +147,6 @@ float deltaR(T const& A, U const& B) return TMath::Sqrt(dEta * dEta + dPhi * dPhi); } -}; // namespace JetUtilities +}; // namespace jetutilities #endif // PWGJE_CORE_JETUTILITIES_H_ diff --git a/PWGJE/Core/PWGJECoreLinkDef.h b/PWGJE/Core/PWGJECoreLinkDef.h index a67145d1d2a..869be064e38 100644 --- a/PWGJE/Core/PWGJECoreLinkDef.h +++ b/PWGJE/Core/PWGJECoreLinkDef.h @@ -18,8 +18,8 @@ #pragma link C++ class JetFinder + ; #pragma link C++ class JetBkgSubUtils + ; -#pragma link C++ namespace JetUtilities + ; -#pragma link C++ namespace FastJetUtilities + ; -#pragma link C++ namespace JetTaggingUtilities + ; +#pragma link C++ namespace jetutilities + ; +#pragma link C++ namespace fastjetutilities + ; +#pragma link C++ namespace jettaggingutilities + ; #endif // PWGJE_CORE_PWGJECORELINKDEF_H_ diff --git a/PWGJE/DataModel/Jet.h b/PWGJE/DataModel/Jet.h index 91bc9d64012..007c885777d 100644 --- a/PWGJE/DataModel/Jet.h +++ b/PWGJE/DataModel/Jet.h @@ -27,20 +27,14 @@ #include "Framework/AnalysisDataModel.h" #include "PWGJE/DataModel/EMCALClusters.h" #include "PWGJE/DataModel/JetReducedData.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" +#include "PWGJE/DataModel/JetReducedDataHF.h" +#include "PWGJE/DataModel/JetSubtraction.h" -namespace o2::aod -{ +#include "PWGHF/DataModel/DerivedTables.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" -namespace rho +namespace o2::aod { -DECLARE_SOA_COLUMN(Rho, rho, float); //! -DECLARE_SOA_COLUMN(RhoM, rhoM, float); //! -} // namespace rho -DECLARE_SOA_TABLE(JCollisionRhos, "AOD", "JCollisionRhos", - o2::soa::Index<>, - rho::Rho, - rho::RhoM); namespace jet { @@ -62,26 +56,6 @@ DECLARE_SOA_DYNAMIC_COLUMN(Pz, pz, //! DECLARE_SOA_DYNAMIC_COLUMN(P, p, //! absolute p [](float pt, float eta) -> float { return pt * std::cosh(eta); }); } // namespace jet - -// Constituent sub -namespace constituentssub -{ -// Jet index column will be added in the macro -DECLARE_SOA_COLUMN(Pt, pt, float); -DECLARE_SOA_COLUMN(Eta, eta, float); -DECLARE_SOA_COLUMN(Phi, phi, float); -DECLARE_SOA_COLUMN(Energy, energy, float); -DECLARE_SOA_COLUMN(Mass, mass, float); -DECLARE_SOA_COLUMN(Source, source, int); -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(P, p, - [](float pt, float eta) -> float { return pt * std::cosh(eta); }); -} // namespace constituentssub } // namespace o2::aod // Defines the jet table definition @@ -118,9 +92,6 @@ DECLARE_SOA_DYNAMIC_COLUMN(P, p, { \ DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_jet_type_, matchedJetCand, int32_t, _jet_type_##s, "_hf"); \ } - // DECLARE_SOA_INDEX_COLUMN_FULL(_jet_type_, matchedJetGeo, int32_t, _jet_type_##s, "_geo"); - // DECLARE_SOA_INDEX_COLUMN_FULL(_jet_type_, matchedJetPt, int32_t, _jet_type_##s, "_pt"); - // DECLARE_SOA_INDEX_COLUMN_FULL(_jet_type_, matchedJetCand, int32_t, _jet_type_##s, "_hf"); #define DECLARE_CONSTITUENTS_TABLE(_jet_type_, _name_, _Description_, _track_type_, _cand_type_) \ namespace _name_##constituents \ @@ -130,43 +101,30 @@ DECLARE_SOA_DYNAMIC_COLUMN(P, p, DECLARE_SOA_ARRAY_INDEX_COLUMN(JCluster, clusters); \ DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(HfCandidates, hfcandidates, int32_t, _cand_type_, "_hfcand"); \ } \ - DECLARE_SOA_TABLE(_jet_type_##Constituents, "AOD", _Description_ "CONSTS", \ + DECLARE_SOA_TABLE(_jet_type_##Constituents, "AOD", _Description_ "C", \ _name_##constituents::_jet_type_##Id, \ _name_##constituents::_track_type_##Ids, \ _name_##constituents::JClusterIds, \ _name_##constituents::HfCandidatesIds); -// Defines the jet constituent sub table -// NOTE: This relies on the jet index column being defined in the constituents namespace. -// Since these are always paired together, there's no point in redefining them. -#define DECLARE_CONSTITUENTS_SUB_TABLE(_jet_type_, _name_, _Description_) \ - DECLARE_SOA_TABLE(_jet_type_##ConstituentsSub, "AOD", _Description_ "CONSTSUB", \ - _name_##constituents::_jet_type_##Id, \ - constituentssub::Pt, \ - constituentssub::Eta, \ - constituentssub::Phi, \ - constituentssub::Energy, \ - constituentssub::Mass, \ - constituentssub::Source, \ - constituentssub::Px, \ - constituentssub::Py, \ - constituentssub::Pz, \ - constituentssub::P); - -// combine definition of tables for jets, constituents, and substructure -#define DECLARE_JET_TABLES(_collision_name_, _jet_type_, _const_type_, _hfcand_type_, _description_) \ +// combine definition of tables for jets, constituents +#define DECLARE_JET_TABLES(_collision_name_, _jet_type_, _track_type_, _hfcand_type_, _description_) \ DECLARE_JET_TABLE(_collision_name_, _jet_type_##Jet, _jet_type_##jet, _description_); \ using _jet_type_##Jet = _jet_type_##Jet##s::iterator; \ - DECLARE_CONSTITUENTS_TABLE(_jet_type_##Jet, _jet_type_##jet, _description_, _const_type_, _hfcand_type_); \ - using _jet_type_##Jet##Constituent = _jet_type_##Jet##Constituents::iterator; \ - DECLARE_CONSTITUENTS_SUB_TABLE(_jet_type_##Jet, _jet_type_##jet, _description_); \ - using _jet_type_##Jet##ConstituentSub = _jet_type_##Jet##ConstituentsSub::iterator; - -#define DECLARE_JETMATCHING_TABLE(_jet_type_base_, _jet_type_tag_, _description_) \ - DECLARE_SOA_TABLE(_jet_type_base_##JetsMatchedTo##_jet_type_tag_##Jets, "AOD", _description_, \ - _jet_type_tag_##jetmatchingGeo::_jet_type_tag_##JetIds, \ - _jet_type_tag_##jetmatchingPt::_jet_type_tag_##JetIds, \ - _jet_type_tag_##jetmatchingCand::_jet_type_tag_##JetIds); \ + DECLARE_CONSTITUENTS_TABLE(_jet_type_##Jet, _jet_type_##jet, _description_, _track_type_, _hfcand_type_); \ + using _jet_type_##Jet##Constituent = _jet_type_##Jet##Constituents::iterator; + +#define DECLARE_JETMATCHING_TABLE(_jet_type_base_, _jet_type_tag_, _description_) \ + namespace _jet_type_base_##jetsmatchedto##_jet_type_tag_ \ + { \ + DECLARE_SOA_DYNAMIC_COLUMN(Dummy##_jet_type_base_##s, dummy##_jet_type_base_##s, \ + []() -> int { return 0; }); \ + } \ + DECLARE_SOA_TABLE(_jet_type_base_##JetsMatchedTo##_jet_type_tag_##Jets, "AOD", _description_, \ + _jet_type_tag_##jetmatchingGeo::_jet_type_tag_##JetIds, \ + _jet_type_tag_##jetmatchingPt::_jet_type_tag_##JetIds, \ + _jet_type_tag_##jetmatchingCand::_jet_type_tag_##JetIds, \ + _jet_type_base_##jetsmatchedto##_jet_type_tag_::Dummy##_jet_type_base_##s<>); \ using _jet_type_base_##JetsMatchedTo##_jet_type_tag_##Jet = _jet_type_base_##JetsMatchedTo##_jet_type_tag_##Jets::iterator; #define DECLARE_MCEVENTWEIGHT_TABLE(_jet_type_, _name_, _description_) \ @@ -181,26 +139,59 @@ DECLARE_SOA_DYNAMIC_COLUMN(P, p, using _jet_type_##JetEventWeight = _jet_type_##JetEventWeights::iterator; // generate tables for data-, detector- and particle-level jets -#define DECLARE_JET_TABLES_LEVELS(_jet_type_, _hfcand_type_, _shortname_) \ - DECLARE_JET_TABLES(JCollision, _jet_type_, JTrack, _hfcand_type_, _shortname_ "JET") \ - DECLARE_JET_TABLES(JCollision, _jet_type_##MCDetectorLevel, JTrack, _hfcand_type_, _shortname_ "DJET") \ - DECLARE_JET_TABLES(JMcCollision, _jet_type_##MCParticleLevel, JMcParticle, JMcParticles, _shortname_ "PJET") \ - DECLARE_JETMATCHING_TABLE(_jet_type_##MCDetectorLevel, _jet_type_##MCParticleLevel, _shortname_ "JETMD2P") \ - DECLARE_JETMATCHING_TABLE(_jet_type_##MCParticleLevel, _jet_type_##MCDetectorLevel, _shortname_ "JETMP2D") \ - DECLARE_MCEVENTWEIGHT_TABLE(_jet_type_##MCDetectorLevel, _jet_type_##MCDetectorLevel, _shortname_ "JETMDEW") \ - DECLARE_MCEVENTWEIGHT_TABLE(_jet_type_##MCParticleLevel, _jet_type_##MCParticleLevel, _shortname_ "JETMPEW") - +#define DECLARE_JET_TABLES_LEVELS(_jet_type_, _subtracted_track_type_, _hfcand_type_, _hfparticle_type_, _shortname_) \ + DECLARE_JET_TABLES(JCollision, _jet_type_, JTrack, _hfcand_type_, _shortname_ "JET") \ + DECLARE_JET_TABLES(JCollision, _jet_type_##MCDetectorLevel, JTrack, _hfcand_type_, _shortname_ "DJET") \ + DECLARE_JET_TABLES(JMcCollision, _jet_type_##MCParticleLevel, JMcParticle, _hfparticle_type_, _shortname_ "PJET") \ + DECLARE_JETMATCHING_TABLE(_jet_type_##MCDetectorLevel, _jet_type_##MCParticleLevel, _shortname_ "JETD2P") \ + DECLARE_JETMATCHING_TABLE(_jet_type_##MCParticleLevel, _jet_type_##MCDetectorLevel, _shortname_ "JETP2D") \ + DECLARE_MCEVENTWEIGHT_TABLE(_jet_type_##MCDetectorLevel, _jet_type_##MCDetectorLevel, _shortname_ "DJETMW") \ + DECLARE_MCEVENTWEIGHT_TABLE(_jet_type_##MCParticleLevel, _jet_type_##MCParticleLevel, _shortname_ "PETMPW") \ + DECLARE_JET_TABLES(JCollision, _jet_type_##EventWiseSubtracted, _subtracted_track_type_, _hfcand_type_, _shortname_ "JETEWS") \ + DECLARE_JETMATCHING_TABLE(_jet_type_, _jet_type_##EventWiseSubtracted, _shortname_ "JET2EWS") \ + DECLARE_JETMATCHING_TABLE(_jet_type_##EventWiseSubtracted, _jet_type_, _shortname_ "JETEWS2") \ + DECLARE_JET_TABLES(JCollision, _jet_type_##MCDetectorLevelEventWiseSubtracted, _subtracted_track_type_, _hfcand_type_, _shortname_ "DJETEWS") \ + DECLARE_MCEVENTWEIGHT_TABLE(_jet_type_##MCDetectorLevelEventWiseSubtracted, _jet_type_##MCDetectorLevelEventWiseSubtracted, _shortname_ "DJETEWSW") \ + DECLARE_JETMATCHING_TABLE(_jet_type_##MCDetectorLevel, _jet_type_##MCDetectorLevelEventWiseSubtracted, _shortname_ "DJET2DEWS") \ + DECLARE_JETMATCHING_TABLE(_jet_type_##MCDetectorLevelEventWiseSubtracted, _jet_type_##MCDetectorLevel, _shortname_ "JETDEWS2D") \ + DECLARE_JET_TABLES(JMcCollision, _jet_type_##MCParticleLevelEventWiseSubtracted, _subtracted_track_type_, _hfparticle_type_, _shortname_ "PJETEWS") namespace o2::aod { -DECLARE_JET_TABLES_LEVELS(Charged, HfCand2Prong, "C"); -DECLARE_JET_TABLES_LEVELS(Full, HfCand2Prong, "F"); -DECLARE_JET_TABLES_LEVELS(Neutral, HfCand2Prong, "N"); -DECLARE_JET_TABLES_LEVELS(D0Charged, HfCand2Prong, "D0"); -DECLARE_JET_TABLES_LEVELS(LcCharged, HfCand3Prong, "Lc"); -DECLARE_JET_TABLES_LEVELS(BplusCharged, HfCandBplus, "BPl"); - -// Hybrid intermediate -DECLARE_JET_TABLES(JCollision, HybridIntermediate, JTrack, HfCand2Prong, "JEHYIN"); +DECLARE_JET_TABLES_LEVELS(Charged, JTrackSub, HfD0Bases, HfD0PBases, "C"); +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(LcCharged, JTrackLcSub, HfCand3Prong, HfD0PBases, "Lc"); +DECLARE_JET_TABLES_LEVELS(BplusCharged, JTrackBplusSub, HfCandBplus, HfD0PBases, "BPl"); + } // namespace o2::aod +using JetCollisions = o2::aod::JCollisions; +using JetCollision = JetCollisions::iterator; +using JetCollisionsMCD = o2::soa::Join; +using JetTracks = o2::aod::JTracks; +using JetTracksMCD = o2::soa::Join; +using JetTracksSub = o2::aod::JTrackSubs; +using JetClusters = o2::aod::JClusters; + +using JetMcCollisions = o2::aod::JMcCollisions; +using JetMcCollision = JetMcCollisions::iterator; +using JetParticles = o2::aod::JMcParticles; + +using CandidatesD0MCP = o2::soa::Join; +using CandidatesLcMCP = o2::soa::Join; +using CandidatesBplusMCP = o2::soa::Join; + +using CandidatesD0Data = o2::soa::Join; +using CandidatesD0MCD = o2::soa::Join; +using JetTracksSubD0 = o2::aod::JTrackD0Subs; + +using CandidatesBplusData = o2::soa::Join; +using CandidatesBplusMCD = o2::soa::Join; +using JetTracksSubBplus = o2::aod::JTrackBplusSubs; + +using CandidatesLcData = o2::soa::Join; +using CandidatesLcMCD = o2::soa::Join; +using JetTracksSubLc = o2::aod::JTrackLcSubs; + #endif // PWGJE_DATAMODEL_JET_H_ diff --git a/PWGJE/DataModel/JetReducedData.h b/PWGJE/DataModel/JetReducedData.h index eb20c80a1f0..5a15023e954 100644 --- a/PWGJE/DataModel/JetReducedData.h +++ b/PWGJE/DataModel/JetReducedData.h @@ -40,7 +40,7 @@ DECLARE_SOA_TABLE(JBCs, "AOD", "JBCs", using JBC = JBCs::iterator; -DECLARE_SOA_TABLE(StoredJBCs, "DYN", "JBCs", +DECLARE_SOA_TABLE(StoredJBCs, "AOD1", "JBCs", o2::soa::Index<>, jbc::RunNumber, jbc::GlobalBC, @@ -52,7 +52,7 @@ using StoredJBC = StoredJBCs::iterator; DECLARE_SOA_TABLE(JBCPIs, "AOD", "JBCPIs", jbc::BCId); -DECLARE_SOA_TABLE(StoredJBCPIs, "DYN", "JBCPIs", +DECLARE_SOA_TABLE(StoredJBCPIs, "AOD1", "JBCPIs", jbc::BCId, o2::soa::Marker<1>); @@ -61,6 +61,7 @@ namespace jcollision DECLARE_SOA_INDEX_COLUMN(Collision, collision); DECLARE_SOA_INDEX_COLUMN(JBC, bc); DECLARE_SOA_COLUMN(PosZ, posZ, float); +DECLARE_SOA_COLUMN(Centrality, centrality, float); DECLARE_SOA_COLUMN(EventSel, eventSel, uint8_t); DECLARE_SOA_BITMAP_COLUMN(Alias, alias, 32); DECLARE_SOA_COLUMN(ChargedTriggerSel, chargedTriggerSel, uint16_t); @@ -70,14 +71,16 @@ DECLARE_SOA_COLUMN(FullTriggerSel, fullTriggerSel, uint16_t); DECLARE_SOA_TABLE(JCollisions, "AOD", "JCollisions", o2::soa::Index<>, jcollision::PosZ, + jcollision::Centrality, jcollision::EventSel, jcollision::Alias); using JCollision = JCollisions::iterator; -DECLARE_SOA_TABLE(StoredJCollisions, "DYN", "JCollisions", +DECLARE_SOA_TABLE(StoredJCollisions, "AOD1", "JCollisions", o2::soa::Index<>, jcollision::PosZ, + jcollision::Centrality, jcollision::EventSel, jcollision::Alias, o2::soa::Marker<1>); @@ -87,28 +90,28 @@ using StoredJCollision = StoredJCollisions::iterator; DECLARE_SOA_TABLE(JCollisionPIs, "AOD", "JCollisionPIs", jcollision::CollisionId); -DECLARE_SOA_TABLE(StoredJCollisionPIs, "DYN", "JCollisionPIs", +DECLARE_SOA_TABLE(StoredJCollisionPIs, "AOD1", "JCollisionPIs", jcollision::CollisionId, o2::soa::Marker<1>); DECLARE_SOA_TABLE(JChTrigSels, "AOD", "JChrgTrigSels", jcollision::ChargedTriggerSel); -DECLARE_SOA_TABLE(StoredJChTrigSels, "DYN", "JChargTrigSels", +DECLARE_SOA_TABLE(StoredJChTrigSels, "AOD1", "JChargTrigSels", jcollision::ChargedTriggerSel, o2::soa::Marker<1>); DECLARE_SOA_TABLE(JFullTrigSels, "AOD", "JFullTrigSels", jcollision::FullTriggerSel); -DECLARE_SOA_TABLE(StoredJFullTrigSels, "DYN", "JFullTrigSels", +DECLARE_SOA_TABLE(StoredJFullTrigSels, "AOD1", "JFullTrigSels", jcollision::FullTriggerSel, o2::soa::Marker<1>); DECLARE_SOA_TABLE(JCollisionBCs, "AOD", "JCollisionBcs", jcollision::JBCId); -DECLARE_SOA_TABLE(StoredJCollisionBCs, "DYN", "JCollisionBcs", +DECLARE_SOA_TABLE(StoredJCollisionBCs, "AOD1", "JCollisionBcs", jcollision::JBCId, o2::soa::Marker<1>); @@ -125,7 +128,7 @@ DECLARE_SOA_TABLE(JMcCollisions, "AOD", "JMcCollisions", using JMcCollision = JMcCollisions::iterator; -DECLARE_SOA_TABLE(StoredJMcCollisions, "DYN", "JMcCollisions", +DECLARE_SOA_TABLE(StoredJMcCollisions, "AOD1", "JMcCollisions", o2::soa::Index<>, jmccollision::PosZ, jmccollision::Weight, @@ -136,7 +139,7 @@ using StoredJMcCollision = StoredJMcCollisions::iterator; DECLARE_SOA_TABLE(JMcCollisionPIs, "AOD", "JMcCollisionPIs", jmccollision::McCollisionId); -DECLARE_SOA_TABLE(StoredJMcCollisionPIs, "DYN", "JMcCollisionPIs", +DECLARE_SOA_TABLE(StoredJMcCollisionPIs, "AOD1", "JMcCollisionPIs", jmccollision::McCollisionId, o2::soa::Marker<1>); @@ -148,7 +151,7 @@ DECLARE_SOA_INDEX_COLUMN(JMcCollision, mcCollision); DECLARE_SOA_TABLE(JMcCollisionLbs, "AOD", "JMcCollisionLbs", jmccollisionlb::JMcCollisionId); -DECLARE_SOA_TABLE(StoredJMcCollisionLbs, "DYN", "JMcCollisionLbs", +DECLARE_SOA_TABLE(StoredJMcCollisionLbs, "AOD1", "JMcCollisionLbs", jmccollisionlb::JMcCollisionId, o2::soa::Marker<1>); @@ -188,7 +191,7 @@ DECLARE_SOA_TABLE(JTracks, "AOD", "JTracks", using JTrack = JTracks::iterator; -DECLARE_SOA_TABLE(StoredJTracks, "DYN", "JTracks", +DECLARE_SOA_TABLE(StoredJTracks, "AOD1", "JTracks", o2::soa::Index<>, jtrack::JCollisionId, jtrack::Pt, @@ -208,7 +211,7 @@ using StoredJTrack = StoredJTracks::iterator; DECLARE_SOA_TABLE(JTrackPIs, "AOD", "JTrackPIs", jtrack::TrackId); -DECLARE_SOA_TABLE(StoredJTrackPIs, "DYN", "JTrackPIs", +DECLARE_SOA_TABLE(StoredJTrackPIs, "AOD1", "JTrackPIs", jtrack::TrackId, o2::soa::Marker<1>); @@ -258,7 +261,7 @@ DECLARE_SOA_TABLE(JMcParticles, "AOD", "JMcParticles", using JMcParticle = JMcParticles::iterator; -DECLARE_SOA_TABLE(StoredJMcParticles, "DYN", "JMcParticles", +DECLARE_SOA_TABLE(StoredJMcParticles, "AOD1", "JMcParticles", o2::soa::Index<>, jmcparticle::JMcCollisionId, jmcparticle::Pt, @@ -283,7 +286,7 @@ using StoredJMcParticle = StoredJMcParticles::iterator; DECLARE_SOA_TABLE(JMcParticlePIs, "AOD", "JMcParticlePIs", jmcparticle::McParticleId); -DECLARE_SOA_TABLE(StoredJMcParticlePIs, "DYN", "JMcParticlePIs", +DECLARE_SOA_TABLE(StoredJMcParticlePIs, "AOD1", "JMcParticlePIs", jmcparticle::McParticleId, o2::soa::Marker<1>); @@ -295,7 +298,7 @@ DECLARE_SOA_INDEX_COLUMN(JMcParticle, mcParticle); DECLARE_SOA_TABLE(JMcTrackLbs, "AOD", "JMcTrackLbs", //! Table joined to the track table containing the MC index jmctracklb::JMcParticleId); -DECLARE_SOA_TABLE(StoredJMcTrackLbs, "DYN", "JMcTrackLbs", //! Table joined to the track table containing the MC index +DECLARE_SOA_TABLE(StoredJMcTrackLbs, "AOD1", "JMcTrackLbs", //! Table joined to the track table containing the MC index jmctracklb::JMcParticleId, o2::soa::Marker<1>); @@ -334,7 +337,7 @@ DECLARE_SOA_TABLE(JClusters, "AOD", "JClusters", //! using JCluster = JClusters::iterator; -DECLARE_SOA_TABLE(StoredJClusters, "DYN", "JClusters", +DECLARE_SOA_TABLE(StoredJClusters, "AOD1", "JClusters", o2::soa::Index<>, jcluster::JCollisionId, jcluster::ID, jcluster::Energy, jcluster::CoreEnergy, jcluster::RawEnergy, jcluster::Eta, jcluster::Phi, jcluster::M02, jcluster::M20, jcluster::NCells, jcluster::Time, @@ -347,14 +350,14 @@ using StoredJCluster = StoredJClusters::iterator; DECLARE_SOA_TABLE(JClusterPIs, "AOD", "JClusterPIs", jcluster::EMCALClusterId); -DECLARE_SOA_TABLE(StoredJClusterPIs, "DYN", "JClusterPIs", +DECLARE_SOA_TABLE(StoredJClusterPIs, "AOD1", "JClusterPIs", jcluster::EMCALClusterId, o2::soa::Marker<1>); DECLARE_SOA_TABLE(JClusterTracks, "AOD", "JClusterTracks", //! jcluster::JTrackIds); -DECLARE_SOA_TABLE(StoredJClusterTracks, "DYN", "JClusterTracks", //! +DECLARE_SOA_TABLE(StoredJClusterTracks, "AOD1", "JClusterTracks", //! jcluster::JTrackIds, o2::soa::Marker<1>); @@ -368,7 +371,7 @@ DECLARE_SOA_TABLE(JDummys, "AOD", "JDummys", o2::soa::Index<>, jdummy::Dummy); -DECLARE_SOA_TABLE(StoredJDummys, "DYN", "JDummys", +DECLARE_SOA_TABLE(StoredJDummys, "AOD1", "JDummys", o2::soa::Index<>, jdummy::Dummy, o2::soa::Marker<1>); diff --git a/PWGJE/DataModel/JetReducedDataHF.h b/PWGJE/DataModel/JetReducedDataHF.h new file mode 100644 index 00000000000..91d71bfc760 --- /dev/null +++ b/PWGJE/DataModel/JetReducedDataHF.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. + +/// +/// \brief Table definitions for reduced data model for hf jets +/// +/// \author Nima Zardoshti + +#ifndef PWGJE_DATAMODEL_JETREDUCEDDATAHF_H_ +#define PWGJE_DATAMODEL_JETREDUCEDDATAHF_H_ + +#include +#include "Framework/AnalysisDataModel.h" +#include "PWGJE/DataModel/EMCALClusters.h" +#include "PWGJE/DataModel/JetReducedData.h" + +namespace o2::aod +{ + +namespace jd0indices +{ +DECLARE_SOA_INDEX_COLUMN(JCollision, collision); +DECLARE_SOA_INDEX_COLUMN_FULL(Prong0, prong0, int, JTracks, "_0"); //! Index to first prong +DECLARE_SOA_INDEX_COLUMN_FULL(Prong1, prong1, int, JTracks, "_1"); //! Index to second prong +DECLARE_SOA_INDEX_COLUMN(JMcCollision, mcCollision); +DECLARE_SOA_INDEX_COLUMN(JMcParticle, mcParticle); +} // namespace jd0indices + +DECLARE_SOA_TABLE(JD0Ids, "AOD1", "JD0Ids", + jd0indices::JCollisionId, + jd0indices::Prong0Id, + jd0indices::Prong1Id); + +DECLARE_SOA_TABLE(StoredJD0Ids, "AOD", "JD0Ids", + jd0indices::JCollisionId, + jd0indices::Prong0Id, + jd0indices::Prong1Id, + o2::soa::Marker<1>); + +DECLARE_SOA_TABLE(JD0PIds, "AOD1", "JD0PIds", + jd0indices::JMcCollisionId, + jd0indices::JMcParticleId); + +DECLARE_SOA_TABLE(StoredJD0PIds, "AOD", "JD0PIds", + jd0indices::JMcCollisionId, + jd0indices::JMcParticleId, + o2::soa::Marker<1>); + +} // namespace o2::aod + +#endif // PWGJE_DATAMODEL_JETREDUCEDDATAHF_H_ diff --git a/PWGJE/DataModel/JetSubstructure.h b/PWGJE/DataModel/JetSubstructure.h index 2dfc5d9687a..21df5bb1cbd 100644 --- a/PWGJE/DataModel/JetSubstructure.h +++ b/PWGJE/DataModel/JetSubstructure.h @@ -18,6 +18,7 @@ #define PWGJE_DATAMODEL_JETSUBSTRUCTURE_H_ #include +#include #include "Framework/AnalysisDataModel.h" #include "PWGJE/DataModel/EMCALClusters.h" #include "PWGHF/DataModel/CandidateReconstructionTables.h" @@ -28,62 +29,85 @@ using namespace o2::analysis; namespace o2::aod { +namespace jetcollision +{ //! +DECLARE_SOA_COLUMN(PosZ, posZ, float); //! +DECLARE_SOA_COLUMN(Centrality, centrality, float); //! +DECLARE_SOA_COLUMN(EventSel, eventSel, uint8_t); //! +} // namespace jetcollision + namespace jetsubstructure -{ //! -DECLARE_SOA_COLUMN(Zg, zg, float); //! -DECLARE_SOA_COLUMN(Rg, rg, float); //! -DECLARE_SOA_COLUMN(Nsd, nsd, float); //! +{ //! +DECLARE_SOA_COLUMN(EnergyMother, energyMother, std::vector); //! +DECLARE_SOA_COLUMN(PtLeading, ptLeading, std::vector); //! +DECLARE_SOA_COLUMN(PtSubLeading, ptSubLeading, std::vector); //! +DECLARE_SOA_COLUMN(Theta, theta, std::vector); //! } // namespace jetsubstructure namespace jetoutput { -DECLARE_SOA_INDEX_COLUMN(Collision, collision); //! -DECLARE_SOA_INDEX_COLUMN(McCollision, mcCollision); //! -DECLARE_SOA_COLUMN(JetPt, jetPt, float); //! -DECLARE_SOA_COLUMN(JetPhi, jetPhi, float); //! -DECLARE_SOA_COLUMN(JetEta, jetEta, float); //! -DECLARE_SOA_COLUMN(JetR, jetR, float); //! -DECLARE_SOA_COLUMN(JetNConstituents, jetNConstituents, int); //! +DECLARE_SOA_COLUMN(JetPt, jetPt, float); //! +DECLARE_SOA_COLUMN(JetPhi, jetPhi, float); //! +DECLARE_SOA_COLUMN(JetEta, jetEta, float); //! +DECLARE_SOA_COLUMN(JetR, jetR, float); //! +DECLARE_SOA_COLUMN(JetNConstituents, jetNConstituents, int); //! } // namespace jetoutput // Defines the jet substrcuture table definition -#define JETSUBSTRUCTURE_TABLE_DEF(_collision_type_, _jet_type_, _matched_jet_type_, _cand_type_, _name_, _description_) \ - namespace _name_##substructure \ - { \ - DECLARE_SOA_INDEX_COLUMN(_jet_type_, jet); \ - DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, _cand_type_, "_0"); \ - DECLARE_SOA_DYNAMIC_COLUMN(Dummy##_jet_type_, dummy##_jet_type_, []() -> int { return 0; }); \ - } \ - \ - namespace _name_##geomatched \ - { \ - DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_matched_jet_type_, matchedJetGeo, int32_t, _matched_jet_type_##s, "_geo"); \ - } \ - \ - namespace _name_##ptmatched \ - { \ - DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_matched_jet_type_, matchedJetPt, int32_t, _matched_jet_type_##s, "_pt"); \ - } \ - \ - namespace _name_##candmatched \ - { \ - DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_matched_jet_type_, matchedJetCand, int32_t, _matched_jet_type_##s, "_hf"); \ - } \ - \ - DECLARE_SOA_TABLE(_jet_type_##Substructures, "AOD", _description_ "SS", jetsubstructure::Zg, jetsubstructure::Rg, jetsubstructure::Nsd, _name_##substructure::Dummy##_jet_type_<>); \ - DECLARE_SOA_TABLE(_jet_type_##Output, "AOD", _description_ "O", jetoutput::_collision_type_##Id, _name_##substructure::_jet_type_##Id, _name_##substructure::Candidate##Id, _name_##geomatched::_matched_jet_type_##Ids, _name_##ptmatched::_matched_jet_type_##Ids, _name_##candmatched::_matched_jet_type_##Ids, jetoutput::JetPt, jetoutput::JetPhi, jetoutput::JetEta, jetoutput::JetR, jetoutput::JetNConstituents); \ - DECLARE_SOA_TABLE(_jet_type_##SubstructureOutput, "AOD", _description_ "SSO", _name_##substructure::_jet_type_##Id, jetsubstructure::Zg, jetsubstructure::Rg, jetsubstructure::Nsd); +#define JETSUBSTRUCTURE_TABLE_DEF(_collision_type_, _jet_type_, _matched_jet_type_, _cand_type_, _name_, _description_) \ + \ + namespace _name_##collisionoutput \ + { \ + DECLARE_SOA_DYNAMIC_COLUMN(Dummy##_collision_type_, dummy##_collision_type_, []() -> int { return 0; }); \ + } \ + \ + DECLARE_SOA_TABLE(_jet_type_##CollisionOutputs, "AOD", _description_ "CO", jetcollision::PosZ, jetcollision::Centrality, jetcollision::EventSel, _name_##collisionoutput::Dummy##_collision_type_<>); \ + using _jet_type_##CollisionOutput = _jet_type_##CollisionOutputs::iterator; \ + \ + namespace _name_##geomatched \ + { \ + DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_matched_jet_type_, matchedJetGeo, int32_t, _matched_jet_type_##s, "_geo"); \ + } \ + \ + namespace _name_##ptmatched \ + { \ + DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_matched_jet_type_, matchedJetPt, int32_t, _matched_jet_type_##s, "_pt"); \ + } \ + \ + namespace _name_##candmatched \ + { \ + DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_matched_jet_type_, matchedJetCand, int32_t, _matched_jet_type_##s, "_hf"); \ + } \ + namespace _name_##jetoutput \ + { \ + DECLARE_SOA_INDEX_COLUMN(_jet_type_##CollisionOutput, collision); \ + DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, _cand_type_, "_0"); \ + } \ + DECLARE_SOA_TABLE(_jet_type_##Outputs, "AOD", _description_ "O", _name_##jetoutput::_jet_type_##CollisionOutputId, _name_##jetoutput::CandidateId, _name_##geomatched::_matched_jet_type_##Ids, _name_##ptmatched::_matched_jet_type_##Ids, _name_##candmatched::_matched_jet_type_##Ids, jetoutput::JetPt, jetoutput::JetPhi, jetoutput::JetEta, jetoutput::JetR, jetoutput::JetNConstituents); \ + using _jet_type_##Output = _jet_type_##Outputs::iterator; \ + namespace _name_##substructure \ + { \ + DECLARE_SOA_INDEX_COLUMN(_jet_type_##Output, outputTable); \ + DECLARE_SOA_DYNAMIC_COLUMN(Dummy##_jet_type_, dummy##_jet_type_, []() -> int { return 0; }); \ + } \ + \ + DECLARE_SOA_TABLE(_jet_type_##Substructures, "AOD", _description_ "SS", jetsubstructure::EnergyMother, jetsubstructure::PtLeading, jetsubstructure::PtSubLeading, jetsubstructure::Theta, _name_##substructure::Dummy##_jet_type_<>); \ + DECLARE_SOA_TABLE(_jet_type_##SubstructureOutputs, "AOD", _description_ "SSO", _name_##substructure::_jet_type_##OutputId, jetsubstructure::EnergyMother, jetsubstructure::PtLeading, jetsubstructure::PtSubLeading, jetsubstructure::Theta); \ + \ + using _jet_type_##Output = _jet_type_##Outputs::iterator; \ + using _jet_type_##SubstructureOutput = _jet_type_##SubstructureOutputs::iterator; -#define JETSUBSTRUCTURE_TABLES_DEF(_jet_type_, _cand_type_, _description_) \ - JETSUBSTRUCTURE_TABLE_DEF(Collision, _jet_type_##Jet, _jet_type_##Jet, _cand_type_, _jet_type_##jet, _description_) \ - JETSUBSTRUCTURE_TABLE_DEF(Collision, _jet_type_##MCDetectorLevelJet, _jet_type_##MCParticleLevelJet, _cand_type_, _jet_type_##mcdetectorleveljet, _description_ "MCD") \ - JETSUBSTRUCTURE_TABLE_DEF(McCollision, _jet_type_##MCParticleLevelJet, _jet_type_##MCDetectorLevelJet, McParticles, _jet_type_##mcparticleleveljet, _description_ "MCP") +#define JETSUBSTRUCTURE_TABLES_DEF(_jet_type_, _cand_type_, _hfparticle_type_, _description_) \ + JETSUBSTRUCTURE_TABLE_DEF(JCollision, _jet_type_##Jet, _jet_type_##Jet, _cand_type_, _jet_type_##jet, _description_) \ + JETSUBSTRUCTURE_TABLE_DEF(JCollision, _jet_type_##MCDetectorLevelJet, _jet_type_##MCParticleLevelJet, _cand_type_, _jet_type_##mcdetectorleveljet, _description_ "MCD") \ + JETSUBSTRUCTURE_TABLE_DEF(JMcCollision, _jet_type_##MCParticleLevelJet, _jet_type_##MCDetectorLevelJet, _hfparticle_type_, _jet_type_##mcparticleleveljet, _description_ "MCP") \ + JETSUBSTRUCTURE_TABLE_DEF(JCollision, _jet_type_##EventWiseSubtractedJet, _jet_type_##Jet, _cand_type_, _jet_type_##eventwisesubtractedjet, _description_ "EWS") -JETSUBSTRUCTURE_TABLES_DEF(Charged, HfCand2Prong, "C"); -JETSUBSTRUCTURE_TABLES_DEF(D0Charged, HfCand2Prong, "D0"); -JETSUBSTRUCTURE_TABLES_DEF(LcCharged, HfCand3Prong, "Lc"); -JETSUBSTRUCTURE_TABLES_DEF(BplusCharged, HfCandBplus, "BPL"); +JETSUBSTRUCTURE_TABLES_DEF(Charged, HfD0Bases, HfD0PBases, "C"); +JETSUBSTRUCTURE_TABLES_DEF(D0Charged, HfD0Bases, HfD0PBases, "D0"); +JETSUBSTRUCTURE_TABLES_DEF(LcCharged, HfD0Bases, HfD0PBases, "Lc"); +JETSUBSTRUCTURE_TABLES_DEF(BplusCharged, HfD0Bases, HfD0PBases, "BPL"); } // namespace o2::aod diff --git a/PWGJE/DataModel/JetSubtraction.h b/PWGJE/DataModel/JetSubtraction.h new file mode 100644 index 00000000000..3d1ee7f20de --- /dev/null +++ b/PWGJE/DataModel/JetSubtraction.h @@ -0,0 +1,161 @@ +// 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 Table definitions for background subtraction +/// +/// +/// \author Nima Zardoshti + +#ifndef PWGJE_DATAMODEL_JETSUBTRACTION_H_ +#define PWGJE_DATAMODEL_JETSUBTRACTION_H_ + +#include +#include "Framework/AnalysisDataModel.h" +#include "PWGJE/DataModel/EMCALClusters.h" +#include "PWGJE/DataModel/JetReducedData.h" +#include "PWGHF/DataModel/DerivedTables.h" +#include "PWGHF/DataModel/CandidateReconstructionTables.h" + +namespace o2::aod +{ + +namespace bkgrho +{ +DECLARE_SOA_COLUMN(Rho, rho, float); //! +DECLARE_SOA_COLUMN(RhoM, rhoM, float); //! +} // namespace bkgrho + +namespace bkgcharged +{ +DECLARE_SOA_INDEX_COLUMN(JCollision, collision); +} // namespace bkgcharged + +namespace bkgd0 +{ +DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, HfD0Bases, "_0"); +} // namespace bkgd0 + +namespace bkglc +{ +DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, HfCand3Prong, "_0"); +} // namespace bkglc + +namespace bkgbplus +{ +DECLARE_SOA_INDEX_COLUMN_FULL(Candidate, candidate, int, HfCandBplus, "_0"); +} // namespace bkgbplus + +DECLARE_SOA_TABLE(BkgChargedRhos, "AOD", "BkgCRho", + o2::soa::Index<>, + bkgcharged::JCollisionId, + bkgrho::Rho, + bkgrho::RhoM); + +DECLARE_SOA_TABLE(BkgD0Rhos, "AOD", "BkgD0Rho", + o2::soa::Index<>, + bkgd0::CandidateId, + bkgrho::Rho, + bkgrho::RhoM); + +DECLARE_SOA_TABLE(BkgLcRhos, "AOD", "BkgLcRho", + o2::soa::Index<>, + bkglc::CandidateId, + bkgrho::Rho, + bkgrho::RhoM); + +DECLARE_SOA_TABLE(BkgBplusRhos, "AOD", "BkgBPlRho", + o2::soa::Index<>, + bkgbplus::CandidateId, + bkgrho::Rho, + bkgrho::RhoM); + +namespace jtracksub +{ + +DECLARE_SOA_COLUMN(Pt, pt, float); +DECLARE_SOA_COLUMN(Eta, eta, float); +DECLARE_SOA_COLUMN(Phi, phi, float); +DECLARE_SOA_COLUMN(Energy, energy, float); +DECLARE_SOA_COLUMN(TrackSel, trackSel, uint8_t); +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(P, p, + [](float pt, float eta) -> float { return pt * std::cosh(eta); }); +} // namespace jtracksub + +DECLARE_SOA_TABLE(JTrackSubs, "AOD", "JTrackSubs", + o2::soa::Index<>, + bkgcharged::JCollisionId, + jtracksub::Pt, + jtracksub::Eta, + jtracksub::Phi, + jtracksub::Energy, + jtracksub::TrackSel, + jtracksub::Px, + jtracksub::Py, + jtracksub::Pz, + jtracksub::P); + +using JTrackSub = JTrackSubs::iterator; + +DECLARE_SOA_TABLE(JTrackD0Subs, "AOD", "JTrackD0Subs", + o2::soa::Index<>, + bkgd0::CandidateId, + jtracksub::Pt, + jtracksub::Eta, + jtracksub::Phi, + jtracksub::Energy, + jtracksub::TrackSel, + jtracksub::Px, + jtracksub::Py, + jtracksub::Pz, + jtracksub::P); + +using JTrackD0Sub = JTrackD0Subs::iterator; + +DECLARE_SOA_TABLE(JTrackLcSubs, "AOD", "JTrackLcSubs", + o2::soa::Index<>, + bkglc::CandidateId, + jtracksub::Pt, + jtracksub::Eta, + jtracksub::Phi, + jtracksub::Energy, + jtracksub::TrackSel, + jtracksub::Px, + jtracksub::Py, + jtracksub::Pz, + jtracksub::P); + +using JTrackLcSub = JTrackLcSubs::iterator; + +DECLARE_SOA_TABLE(JTrackBplusSubs, "AOD", "JTrackBPlSubs", + o2::soa::Index<>, + bkgbplus::CandidateId, + jtracksub::Pt, + jtracksub::Eta, + jtracksub::Phi, + jtracksub::Energy, + jtracksub::TrackSel, + jtracksub::Px, + jtracksub::Py, + jtracksub::Pz, + jtracksub::P); + +using JTrackBplusSub = JTrackBplusSubs::iterator; + +} // namespace o2::aod + +#endif // PWGJE_DATAMODEL_JETSUBTRACTION_H_ diff --git a/PWGJE/DataModel/TrackJetQa.h b/PWGJE/DataModel/TrackJetQa.h index 297704d7911..858aa53b0db 100644 --- a/PWGJE/DataModel/TrackJetQa.h +++ b/PWGJE/DataModel/TrackJetQa.h @@ -43,27 +43,28 @@ namespace o2::aod namespace jetcollisions { // Collision info -DECLARE_SOA_COLUMN(GlobalIdx, globalIdx, int64_t); +DECLARE_SOA_COLUMN(GlobalIdx, globalIdx, int); DECLARE_SOA_COLUMN(RunNumber, runNumber, int); DECLARE_SOA_COLUMN(Sel8, sel8, bool); +DECLARE_SOA_COLUMN(MultTracks, multTracks, int); DECLARE_SOA_COLUMN(MultNTracksPV, multNTracksPV, int); -DECLARE_SOA_COLUMN(MultFT0C, multFT0C, float); -DECLARE_SOA_COLUMN(CentFT0C, centFT0C, float); DECLARE_SOA_COLUMN(MultFT0A, multFT0A, float); +DECLARE_SOA_COLUMN(MultFT0C, multFT0C, float); DECLARE_SOA_COLUMN(CentFT0A, centFT0A, float); +DECLARE_SOA_COLUMN(CentFT0C, centFT0C, float); } // namespace jetcollisions namespace jettrack { // Track info -DECLARE_SOA_COLUMN(CollisionId, collisionId, int); //! Id of collision -DECLARE_SOA_COLUMN(IsPVContributor, isPVContributor, bool); //! IsPVContributor -DECLARE_SOA_COLUMN(HasTRD, hasTRD, bool); //! Has or not the TRD match -DECLARE_SOA_COLUMN(HasITS, hasITS, bool); //! Has or not the ITS match -DECLARE_SOA_COLUMN(HasTPC, hasTPC, bool); //! Has or not the TPC match // Addtional selections for trackJetqa // -DECLARE_SOA_COLUMN(IsGlobalTrack, isGlobalTrack, bool); // if a track passed the isGlobalTrack requirement -DECLARE_SOA_COLUMN(IsGlobalTrackWoDCA, isGlobalTrackWoDCA, bool); // if a track passed the isGlobalTrackWoDCA requirement -DECLARE_SOA_COLUMN(IsGlobalTrackWoPtEta, isGlobalTrackWoPtEta, bool); // if a track passed the isGlobalTrackWoPtEta requirement +DECLARE_SOA_COLUMN(CollisionId, collisionId, int); //! Id of collision +DECLARE_SOA_COLUMN(IsPVContributor, isPVContributor, bool); //! IsPVContributor +DECLARE_SOA_COLUMN(HasTRD, hasTRD, bool); //! Has or not the TRD match +DECLARE_SOA_COLUMN(HasITS, hasITS, bool); //! Has or not the ITS match +DECLARE_SOA_COLUMN(HasTPC, hasTPC, bool); //! Has or not the TPC match // Addtional selections for trackJetqa // +DECLARE_SOA_COLUMN(IsGlobalTrack, isGlobalTrack, bool); // if a track passed the isGlobalTrack requirement +DECLARE_SOA_COLUMN(IsGlobalTrackWoDCA, isGlobalTrackWoDCA, bool); // if a track passed the isGlobalTrackWoDCA requirement +DECLARE_SOA_COLUMN(IsGlobalTrackWoPtEta, isGlobalTrackWoPtEta, bool); // if a track passed the isGlobalTrackWoPtEta requirement DECLARE_SOA_COLUMN(ITSNCls, itsNCls, uint8_t); DECLARE_SOA_COLUMN(TPCFractionSharedCls, tpcFractionSharedCls, float); DECLARE_SOA_COLUMN(ITSClusterMap, itsClusterMap, float); @@ -71,16 +72,17 @@ DECLARE_SOA_COLUMN(TPCNClsFound, tpcNClsFound, int16_t); DECLARE_SOA_COLUMN(TPCNClsCrossedRows, tpcNClsCrossedRows, int16_t); DECLARE_SOA_COLUMN(TPCCrossedRowsOverFindableCls, tpcCrossedRowsOverFindableCls, float); DECLARE_SOA_COLUMN(TPCFoundOverFindableCls, tpcFoundOverFindableCls, float); - } // namespace jettrack DECLARE_SOA_TABLE(JeColls, "AOD", "JECOLLS", o2::soa::Index<>, + jetcollisions::GlobalIdx, collision::CollisionTime, collision::NumContrib, collision::PosX, collision::PosY, collision::PosZ, + jetcollisions::MultTracks, jetcollisions::Sel8, jetcollisions::MultNTracksPV, jetcollisions::MultFT0A, @@ -89,8 +91,6 @@ DECLARE_SOA_TABLE(JeColls, "AOD", "JECOLLS", jetcollisions::CentFT0C, jetcollisions::RunNumber); -// using JeColl = JeColls::iterator; - DECLARE_SOA_TABLE(JeTracks, "AOD", "JETRACKS", o2::soa::Index<>, jettrack::CollisionId, diff --git a/PWGJE/TableProducer/CMakeLists.txt b/PWGJE/TableProducer/CMakeLists.txt index a8ece358094..e368f584fe3 100644 --- a/PWGJE/TableProducer/CMakeLists.txt +++ b/PWGJE/TableProducer/CMakeLists.txt @@ -22,6 +22,11 @@ o2physics_add_dpl_workflow(jet-deriveddata-trigger-producer PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-deriveddata-producer-dummy + SOURCES jetderiveddataproducerdummy.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + o2physics_add_dpl_workflow(jet-deriveddata-writer SOURCES jetderiveddatawriter.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore @@ -47,13 +52,18 @@ o2physics_add_dpl_workflow(jet-finder-d0-mcp-charged PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(jet-finder-lc-data-charged - SOURCES jetfinderLcDataCharged.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore O2::FrameworkPhysicsSupport +o2physics_add_dpl_workflow(jet-matching-mc + SOURCES jetmatchingmc.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(jet-matching - SOURCES jetmatching.cxx +o2physics_add_dpl_workflow(jet-matching-sub + SOURCES jetmatchingsub.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(jet-matching-mc-sub + SOURCES jetmatchingmcsub.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) @@ -77,10 +87,15 @@ o2physics_add_dpl_workflow(jet-taggerhf PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) -o2physics_add_dpl_workflow(rho-estimator +o2physics_add_dpl_workflow(estimator-rho SOURCES rhoEstimator.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(subtractor-eventwiseconstituent + SOURCES eventwiseConstituentSubtractor.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::PWGJECore O2Physics::AnalysisCore + COMPONENT_NAME Analysis) endif() diff --git a/PWGJE/TableProducer/emcalCorrectionTask.cxx b/PWGJE/TableProducer/emcalCorrectionTask.cxx index 6dfa6020870..ae0353c7b2c 100644 --- a/PWGJE/TableProducer/emcalCorrectionTask.cxx +++ b/PWGJE/TableProducer/emcalCorrectionTask.cxx @@ -77,6 +77,8 @@ struct EmcalCorrectionTask { Configurable nonlinearityFunction{"nonlinearityFunction", "DATA_TestbeamFinal", "Nonlinearity correction at cluster level"}; Configurable disableNonLin{"disableNonLin", false, "Disable NonLin correction if set to true"}; Configurable hasShaperCorrection{"hasShaperCorrection", true, "Apply correction for shaper saturation"}; + Configurable applyCellAbsScale{"applyCellAbsScale", 0, "Enable absolute cell energy scale to correct for energy loss in material in front of EMCal"}; + Configurable> vCellAbsScaleFactor{"cellAbsScaleFactor", {1.f}, "values for absolute cell energy calibration. Different values correspond to different regions or SM types of EMCal"}; Configurable logWeight{"logWeight", 4.5, "logarithmic weight for the cluster center of gravity calculation"}; Configurable exoticCellFraction{"exoticCellFraction", 0.97, "Good cell if fraction < 1-ecross/ecell"}; Configurable exoticCellDiffTime{"exoticCellDiffTime", 1.e6, "If time of candidate to exotic and close cell is larger than exoticCellDiffTime (in ns), it must be noisy, set amp to 0"}; @@ -246,6 +248,9 @@ struct EmcalCorrectionTask { if (static_cast(hasShaperCorrection)) { amplitude = o2::emcal::NonlinearityHandler::evaluateShaperCorrectionCellEnergy(amplitude); } + if (applyCellAbsScale) { + amplitude *= GetAbsCellScale(cell.cellNumber()); + } cellsBC.emplace_back(cell.cellNumber(), amplitude, cell.time(), @@ -663,7 +668,7 @@ struct EmcalCorrectionTask { clusterEta.emplace_back(pos.Eta()); } IndexMapPair = - JetUtilities::MatchClustersAndTracks(clusterPhi, clusterEta, + jetutilities::MatchClustersAndTracks(clusterPhi, clusterEta, trackPhi, trackEta, maxMatchingDistance, 20); } @@ -731,6 +736,23 @@ struct EmcalCorrectionTask { mHistManager.fill(HIST("hCellRowCol"), std::get<1>(res), std::get<0>(res)); } } + + float GetAbsCellScale(const int cellID) + { + // Apply cell scale based on SM types (Full, Half (not used), EMC 1/3, DCal, DCal 1/3) + // Same as in Run2 data + if (applyCellAbsScale == 1) { + int iSM = mClusterizers.at(0)->getGeometry()->GetSuperModuleNumber(cellID); + return vCellAbsScaleFactor.value[mClusterizers.at(0)->getGeometry()->GetSMType(iSM)]; + + // Apply cell scale based on columns to accoutn for material of TRD structures + } else if (applyCellAbsScale == 2) { + auto res = mClusterizers.at(0)->getGeometry()->GlobalRowColFromIndex(cellID); + return vCellAbsScaleFactor.value[std::get<1>(res)]; + } else { + return 1.f; + } + } }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGJE/TableProducer/eventwiseConstituentSubtractor.cxx b/PWGJE/TableProducer/eventwiseConstituentSubtractor.cxx new file mode 100644 index 00000000000..4c50a10d998 --- /dev/null +++ b/PWGJE/TableProducer/eventwiseConstituentSubtractor.cxx @@ -0,0 +1,133 @@ +// 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. + +// Task to produce a table groupable with the jcollisions table which contains the event-wise constituent subtracted track list +// +/// \author Nima Zardoshti + +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoA.h" +#include "Framework/O2DatabasePDGPlugin.h" + +#include "PWGJE/Core/FastJetUtilities.h" +#include "PWGJE/Core/JetFindingUtilities.h" +#include "PWGJE/Core/JetDerivedDataUtilities.h" +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/Core/JetBkgSubUtils.h" +#include "Framework/runDataProcessing.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct eventWiseConstituentSubtractorTask { + Produces trackSubtractedTable; + Produces trackSubtractedD0Table; + Produces trackSubtractedLcTable; + Produces trackSubtractedBplusTable; + + Configurable trackPtMin{"trackPtMin", 0.15, "minimum track pT"}; + Configurable trackPtMax{"trackPtMax", 1000.0, "maximum track pT"}; + Configurable trackEtaMin{"trackEtaMin", -0.9, "minimum track eta"}; + Configurable trackEtaMax{"trackEtaMax", 0.9, "maximum track eta"}; + Configurable trackPhiMin{"trackPhiMin", -999, "minimum track phi"}; + Configurable trackPhiMax{"trackPhiMax", 999, "maximum track phi"}; + Configurable trackSelections{"trackSelections", "globalTracks", "set track selections"}; + + Configurable selectionFlagD0{"selectionFlagD0", 1, "Selection Flag for D0"}; + Configurable selectionFlagD0bar{"selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable selectionFlagLcToPKPi{"selectionFlagLcToPKPi", 1, "Selection Flag for Lc->PKPi"}; + Configurable selectionFlagLcToPiPK{"selectionFlagLcToPiPK", 1, "Selection Flag for Lc->PiPK"}; + Configurable selectionFlagBplus{"selectionFlagBplus", 1, "Selection Flag for B+"}; + + Configurable alpha{"alpha", 1.0, "exponent of transverse momentum in calculating the distance measure between pairs"}; + Configurable rMax{"rMax", 0.24, "maximum distance of subtraction"}; + Configurable eventEtaMax{"eventEtaMax", 0.9, "maximum pseudorapidity of event"}; + Configurable doRhoMassSub{"doRhoMassSub", true, "perfom mass subtraction as well"}; + + JetBkgSubUtils eventWiseConstituentSubtractor; + float bkgPhiMax_; + std::vector inputParticles; + std::vector tracksSubtracted; + int trackSelection = -1; + + void init(o2::framework::InitContext&) + { + trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); + + eventWiseConstituentSubtractor.setDoRhoMassSub(doRhoMassSub); + eventWiseConstituentSubtractor.setConstSubAlphaRMax(alpha, rMax); + eventWiseConstituentSubtractor.setMaxEtaEvent(eventEtaMax); + } + + 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); + + Preslice perD0Candidate = aod::bkgd0::candidateId; + Preslice perLcCandidate = aod::bkglc::candidateId; + Preslice perBplusCandidate = aod::bkgbplus::candidateId; + + template + void analyseHF(T const& tracks, U const& candidates, V const& bkgRhos, M& trackSubtractedTable) + { + + for (auto& candidate : candidates) { + + auto const bkgRhosSliced = jethfutilities::slicedPerCandidate(bkgRhos, candidate, perD0Candidate, perLcCandidate, perBplusCandidate); + auto const bkgRho = bkgRhosSliced.iteratorAt(0); + + inputParticles.clear(); + tracksSubtracted.clear(); + jetfindingutilities::analyseTracks(inputParticles, tracks, trackSelection, std::optional{candidate}); + + tracksSubtracted = eventWiseConstituentSubtractor.JetBkgSubUtils::doEventConstSub(inputParticles, bkgRho.rho(), bkgRho.rhoM()); + for (auto const& trackSubtracted : tracksSubtracted) { + + trackSubtractedTable(candidate.globalIndex(), trackSubtracted.pt(), trackSubtracted.eta(), trackSubtracted.phi(), trackSubtracted.E(), jetderiveddatautilities::setSingleTrackSelectionBit(trackSelection)); + } + } + } + + void processCollisions(soa::Join::iterator const& collision, soa::Filtered const& tracks) + { + + inputParticles.clear(); + tracksSubtracted.clear(); + jetfindingutilities::analyseTracks, soa::Filtered::iterator>(inputParticles, tracks, trackSelection); + + tracksSubtracted = eventWiseConstituentSubtractor.JetBkgSubUtils::doEventConstSub(inputParticles, collision.rho(), collision.rhoM()); + + for (auto const& trackSubtracted : tracksSubtracted) { + trackSubtractedTable(collision.globalIndex(), trackSubtracted.pt(), trackSubtracted.eta(), trackSubtracted.phi(), trackSubtracted.E(), jetderiveddatautilities::setSingleTrackSelectionBit(trackSelection)); + } + } + PROCESS_SWITCH(eventWiseConstituentSubtractorTask, processCollisions, "Fill table of subtracted tracks for collisions", true); + + void processD0Collisions(JetCollision const& collision, aod::BkgD0Rhos const& bkgRhos, soa::Filtered const& tracks, CandidatesD0Data const& candidates) + { + analyseHF(tracks, candidates, bkgRhos, trackSubtractedD0Table); + } + PROCESS_SWITCH(eventWiseConstituentSubtractorTask, processD0Collisions, "Fill table of subtracted tracks for collisions with D0 candidates", false); + + void processLcCollisions(JetCollision const& collision, aod::BkgLcRhos const& bkgRhos, soa::Filtered const& tracks, CandidatesLcData const& candidates) + { + analyseHF(tracks, candidates, bkgRhos, trackSubtractedLcTable); + } + PROCESS_SWITCH(eventWiseConstituentSubtractorTask, processLcCollisions, "Fill table of subtracted tracks for collisions with Lc candidates", false); + + void processBplusCollisions(JetCollision const& collision, aod::BkgBplusRhos const& bkgRhos, soa::Filtered const& tracks, CandidatesBplusData const& candidates) + { + analyseHF(tracks, candidates, bkgRhos, trackSubtractedBplusTable); + } + PROCESS_SWITCH(eventWiseConstituentSubtractorTask, processBplusCollisions, "Fill table of subtracted tracks for collisions with Bplus candidates", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"subtractor-eventwiseconstituent"})}; } diff --git a/PWGJE/TableProducer/jetderiveddataproducer.cxx b/PWGJE/TableProducer/jetderiveddataproducer.cxx index 3adac7913ce..b99c6b371bc 100644 --- a/PWGJE/TableProducer/jetderiveddataproducer.cxx +++ b/PWGJE/TableProducer/jetderiveddataproducer.cxx @@ -27,6 +27,7 @@ #include "Common/Core/TrackSelectionDefaults.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/Centrality.h" #include "Common/Core/RecoDecay.h" #include "PWGJE/DataModel/EMCALClusters.h" @@ -58,6 +59,8 @@ struct JetDerivedDataProducerTask { Produces jClustersTable; Produces jClustersParentIndexTable; Produces jClustersMatchedTracksTable; + Produces jD0IdsTable; + Produces jD0ParticleIdsTable; Preslice perClusterCells = aod::emcalclustercell::emcalclusterId; Preslice perClusterTracks = aod::emcalclustercell::emcalclusterId; @@ -66,21 +69,29 @@ struct JetDerivedDataProducerTask { { } - void processBunchCossings(soa::Join::iterator const& bc) + void processBunchCrossings(soa::Join::iterator const& bc) { jBCsTable(bc.runNumber(), bc.globalBC(), bc.timestamp()); jBCParentIndexTable(bc.globalIndex()); } - PROCESS_SWITCH(JetDerivedDataProducerTask, processBunchCossings, "produces derived bunch crossing table", false); + PROCESS_SWITCH(JetDerivedDataProducerTask, processBunchCrossings, "produces derived bunch crossing table", false); void processCollisions(soa::Join::iterator const& collision) { - jCollisionsTable(collision.posZ(), JetDerivedDataUtilities::setEventSelectionBit(collision), collision.alias_raw()); + jCollisionsTable(collision.posZ(), -1.0, jetderiveddatautilities::setEventSelectionBit(collision), collision.alias_raw()); jCollisionsParentIndexTable(collision.globalIndex()); jCollisionsBunchCrossingIndexTable(collision.bcId()); } PROCESS_SWITCH(JetDerivedDataProducerTask, processCollisions, "produces derived collision tables", true); + void processCollisionsWithCentrality(soa::Join::iterator const& collision) + { + jCollisionsTable(collision.posZ(), collision.centFT0C(), jetderiveddatautilities::setEventSelectionBit(collision), collision.alias_raw()); + jCollisionsParentIndexTable(collision.globalIndex()); + jCollisionsBunchCrossingIndexTable(collision.bcId()); + } + PROCESS_SWITCH(JetDerivedDataProducerTask, processCollisionsWithCentrality, "produces derived collision tables with centrality", false); + void processMcCollisionLabels(soa::Join::iterator const& collision) { @@ -101,7 +112,7 @@ struct JetDerivedDataProducerTask { void processTracks(soa::Join::iterator const& track) { - jTracksTable(track.collisionId(), track.pt(), track.eta(), track.phi(), JetDerivedDataUtilities::trackEnergy(track), track.sign(), JetDerivedDataUtilities::setTrackSelectionBit(track)); + jTracksTable(track.collisionId(), track.pt(), track.eta(), track.phi(), jetderiveddatautilities::trackEnergy(track), track.sign(), jetderiveddatautilities::setTrackSelectionBit(track)); jTracksParentIndexTable(track.globalIndex()); } PROCESS_SWITCH(JetDerivedDataProducerTask, processTracks, "produces derived track table", true); @@ -179,6 +190,18 @@ struct JetDerivedDataProducerTask { } } PROCESS_SWITCH(JetDerivedDataProducerTask, processClusters, "produces derived cluster tables", false); + + void processD0(aod::HfD0Ids::iterator const& D0, soa::Join const& collisions, aod::Tracks const& tracks) + { + jD0IdsTable(D0.collisionId(), D0.prong0Id(), D0.prong1Id()); + } + PROCESS_SWITCH(JetDerivedDataProducerTask, processD0, "produces derived bunch crossing table for D0 candidates", false); + + void processD0MC(aod::HfD0PIds::iterator const& D0, aod::McCollisions const& mcCollisions, aod::McParticles const& particles) + { + jD0ParticleIdsTable(D0.mcCollisionId(), D0.mcParticleId()); + } + PROCESS_SWITCH(JetDerivedDataProducerTask, processD0MC, "produces derived bunch crossing table for D0 particles", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGJE/TableProducer/jetderiveddataproducerdummy.cxx b/PWGJE/TableProducer/jetderiveddataproducerdummy.cxx new file mode 100644 index 00000000000..9ea3c38e064 --- /dev/null +++ b/PWGJE/TableProducer/jetderiveddataproducerdummy.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. + +// temporary task to produce HF tables needed when making inclusive derived data - should become obsolete when tables are able to be prouduced based on a configurable +// +/// \author Nima Zardoshti + +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoA.h" +#include "Framework/runDataProcessing.h" +#include "PWGJE/DataModel/JetReducedData.h" +#include "PWGHF/DataModel/DerivedTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct JetDerivedDataProducerDummyTask { + + Produces d0CollisionsTable; + Produces d0sTable; + Produces d0ParsTable; + Produces d0ParExtrasTable; + Produces d0SelsTable; + Produces d0McsTable; + Produces d0ParticlesTable; + + void init(InitContext const&) + { + } + + void processDummy(aod::JDummys const& dummys) + { + } + PROCESS_SWITCH(JetDerivedDataProducerDummyTask, processDummy, "leaves all tables empty", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc, TaskName{"jet-deriveddata-producer-dummy"})}; +} diff --git a/PWGJE/TableProducer/jetderiveddatatriggerproducer.cxx b/PWGJE/TableProducer/jetderiveddatatriggerproducer.cxx index 66a1c9e6ba3..3471a8950b2 100644 --- a/PWGJE/TableProducer/jetderiveddatatriggerproducer.cxx +++ b/PWGJE/TableProducer/jetderiveddatatriggerproducer.cxx @@ -42,25 +42,25 @@ struct JetDerivedDataTriggerProducerTask { void processChargedJetTriggers(soa::Join::iterator const& collision) { - jChargedTriggerSelsTable(JetDerivedDataUtilities::setChargedTriggerSelectionBit(collision)); + jChargedTriggerSelsTable(jetderiveddatautilities::setChargedTriggerSelectionBit(collision)); } PROCESS_SWITCH(JetDerivedDataTriggerProducerTask, processChargedJetTriggers, "produces derived charged trigger table", false); void processNoChargedJetTriggers(aod::Collision const& collision) { - jChargedTriggerSelsTable(JetDerivedDataUtilities::JTrigSelCh::noChargedTigger); + jChargedTriggerSelsTable(jetderiveddatautilities::JTrigSelCh::noChargedTigger); } PROCESS_SWITCH(JetDerivedDataTriggerProducerTask, processNoChargedJetTriggers, "produces derived charged trigger table when sample is not triggered", true); void processFullJetTriggers(soa::Join::iterator const& collision) { - jFullTriggerSelsTable(JetDerivedDataUtilities::setFullTriggerSelectionBit(collision)); + jFullTriggerSelsTable(jetderiveddatautilities::setFullTriggerSelectionBit(collision)); } PROCESS_SWITCH(JetDerivedDataTriggerProducerTask, processFullJetTriggers, "produces derived full trigger table", false); void processNoFullJetTriggers(aod::Collision const& collision) { - jFullTriggerSelsTable(JetDerivedDataUtilities::JTrigSelFull::noFullTrigger); + jFullTriggerSelsTable(jetderiveddatautilities::JTrigSelFull::noFullTrigger); } PROCESS_SWITCH(JetDerivedDataTriggerProducerTask, processNoFullJetTriggers, "produces derived full trigger table table when sample is not triggered", true); }; diff --git a/PWGJE/TableProducer/jetderiveddatawriter.cxx b/PWGJE/TableProducer/jetderiveddatawriter.cxx index bcb80aba159..a7c8da815a5 100644 --- a/PWGJE/TableProducer/jetderiveddatawriter.cxx +++ b/PWGJE/TableProducer/jetderiveddatawriter.cxx @@ -23,6 +23,7 @@ #include "Framework/ASoA.h" #include "Framework/runDataProcessing.h" +#include "PWGJE/Core/JetHFUtilities.h" #include "PWGJE/DataModel/Jet.h" #include "PWGJE/DataModel/JetReducedData.h" @@ -39,6 +40,10 @@ struct JetDerivedDataWriter { Configurable chargedD0JetPtMin{"chargedD0JetPtMin", 0.0, "Minimum charged D0 jet pt to accept event"}; Configurable chargedLcJetPtMin{"chargedLcJetPtMin", 0.0, "Minimum charged Lc jet pt to accept event"}; + Configurable saveBCsTable{"saveBCsTable", true, "save the bunch crossing table to the output"}; + Configurable saveClustersTable{"saveClustersTable", true, "save the clusters table to the output"}; + Configurable saveD0Table{"saveD0Table", false, "save the D0 table to the output"}; + Produces storedJDummysTable; Produces storedJBCsTable; Produces storedJBCParentIndexTable; @@ -59,10 +64,22 @@ struct JetDerivedDataWriter { Produces storedJClustersParentIndexTable; Produces storedJClustersMatchedTracksTable; - PresliceUnsorted> CollisionsPerMcCollision = aod::jmccollisionlb::mcCollisionId; + Produces storedD0CollisionsTable; + Produces storedD0sTable; + Produces storedD0ParsTable; + Produces storedD0ParExtrasTable; + Produces storedD0SelsTable; + Produces storedD0McsTable; + Produces storedD0IdsTable; + Produces storedD0ParticlesTable; + Produces storedD0ParticleIdsTable; + + PresliceUnsorted> + CollisionsPerMcCollision = aod::jmccollisionlb::mcCollisionId; PresliceUnsorted> ParticlesPerMcCollision = aod::jmcparticle::mcCollisionId; Preslice> TracksPerCollision = aod::jtrack::collisionId; Preslice> ClustersPerCollision = aod::jcluster::collisionId; + Preslice> D0sPerCollision = aod::jd0indices::collisionId; std::vector collisionFlag; std::vector McCollisionFlag; @@ -121,13 +138,13 @@ struct JetDerivedDataWriter { decltype(ProcessConfigurable{&_Class_ ::_Method_, #_Name_, _Default_, _Help_}) do##_Name_ = ProcessConfigurable{&_Class_ ::_Method_, #_Name_, _Default_, _Help_}; PROCESS_SWITCH(JetDerivedDataWriter, processCollisions, "setup the writing for data and MCD", true); PROCESS_SWITCH(JetDerivedDataWriter, processMcCollisions, "setup the writing for MCP", false); - PROCESS_SWITCH_JKL(JetDerivedDataWriter, processJets, processChargedJets, "process charged jets", true); - PROCESS_SWITCH_JKL(JetDerivedDataWriter, processJets, processChargedMCDJets, "process charged mcd jets", false); - PROCESS_SWITCH_JKL(JetDerivedDataWriter, processJets, processChargedMCPJets, "process charged mcp jets", false); - PROCESS_SWITCH_JKL(JetDerivedDataWriter, processJets, processNeutralJets, "process neutral jets", false); - PROCESS_SWITCH_JKL(JetDerivedDataWriter, processJets, processFullJets, "process full jets", false); - PROCESS_SWITCH_JKL(JetDerivedDataWriter, processJets, processD0ChargedJets, "process D0 charged jets", false); - PROCESS_SWITCH_JKL(JetDerivedDataWriter, processJets, processLcChargedJets, "process Lc charged jets", false); + PROCESS_SWITCH_FULL(JetDerivedDataWriter, processJets, processChargedJets, "process charged jets", true); + PROCESS_SWITCH_FULL(JetDerivedDataWriter, processJets, processChargedMCDJets, "process charged mcd jets", false); + PROCESS_SWITCH_FULL(JetDerivedDataWriter, processJets, processChargedMCPJets, "process charged mcp jets", false); + PROCESS_SWITCH_FULL(JetDerivedDataWriter, processJets, processNeutralJets, "process neutral jets", false); + PROCESS_SWITCH_FULL(JetDerivedDataWriter, processJets, processFullJets, "process full jets", false); + PROCESS_SWITCH_FULL(JetDerivedDataWriter, processJets, processD0ChargedJets, "process D0 charged jets", false); + PROCESS_SWITCH_FULL(JetDerivedDataWriter, processJets, processLcChargedJets, "process Lc charged jets", false); void processDummy(aod::JDummys const& Dummys) { @@ -135,28 +152,31 @@ struct JetDerivedDataWriter { } PROCESS_SWITCH(JetDerivedDataWriter, processDummy, "write out dummy output table", true); - void processData(soa::Join::iterator const& collision, soa::Join const& bcs, soa::Join const& tracks, soa::Join const& clusters) + void processData(soa::Join::iterator const& collision, soa::Join const& bcs, soa::Join const& tracks, soa::Join const& clusters, aod::HfD0CollBases const& D0Collisions, CandidatesD0Data const& D0s) { std::map trackMapping; if (collisionFlag[collision.globalIndex()]) { - - auto bc = collision.bc_as>(); - if (std::find(bcIndicies.begin(), bcIndicies.end(), bc.globalIndex()) == bcIndicies.end()) { - storedJBCsTable(bc.runNumber(), bc.globalBC(), bc.timestamp()); - storedJBCParentIndexTable(bc.bcId()); - bcIndicies.push_back(bc.globalIndex()); - bcMapping.insert(std::make_pair(bc.globalIndex(), storedJBCsTable.lastIndex())); + if (saveBCsTable) { + auto bc = collision.bc_as>(); + if (std::find(bcIndicies.begin(), bcIndicies.end(), bc.globalIndex()) == bcIndicies.end()) { + storedJBCsTable(bc.runNumber(), bc.globalBC(), bc.timestamp()); + storedJBCParentIndexTable(bc.bcId()); + bcIndicies.push_back(bc.globalIndex()); + bcMapping.insert(std::make_pair(bc.globalIndex(), storedJBCsTable.lastIndex())); + } } - storedJCollisionsTable(collision.posZ(), collision.eventSel(), collision.alias_raw()); + storedJCollisionsTable(collision.posZ(), collision.centrality(), collision.eventSel(), collision.alias_raw()); storedJCollisionsParentIndexTable(collision.collisionId()); - int32_t storedBCID = -1; - auto JBCIndex = bcMapping.find(collision.bcId()); - if (JBCIndex != bcMapping.end()) { - storedBCID = JBCIndex->second; + if (saveBCsTable) { + int32_t storedBCID = -1; + auto JBCIndex = bcMapping.find(collision.bcId()); + if (JBCIndex != bcMapping.end()) { + storedBCID = JBCIndex->second; + } + storedJCollisionsBunchCrossingIndexTable(storedBCID); } - storedJCollisionsBunchCrossingIndexTable(storedBCID); storedJChargedTriggerSelsTable(collision.chargedTriggerSel()); storedJFullTriggerSelsTable(collision.fullTriggerSel()); @@ -165,21 +185,48 @@ struct JetDerivedDataWriter { storedJTracksParentIndexTable(track.trackId()); trackMapping.insert(std::make_pair(track.globalIndex(), storedJTracksTable.lastIndex())); } + if (saveClustersTable) { + for (const auto& cluster : clusters) { + storedJClustersTable(storedJCollisionsTable.lastIndex(), cluster.id(), cluster.energy(), cluster.coreEnergy(), cluster.rawEnergy(), + cluster.eta(), cluster.phi(), cluster.m02(), cluster.m20(), cluster.nCells(), cluster.time(), cluster.isExotic(), cluster.distanceToBadChannel(), + cluster.nlm(), cluster.definition(), cluster.leadingCellEnergy(), cluster.subleadingCellEnergy(), cluster.leadingCellNumber(), cluster.subleadingCellNumber()); + storedJClustersParentIndexTable(cluster.clusterId()); + + std::vector clusterStoredJTrackIDs; + for (const auto& clusterTrack : cluster.matchedTracks_as>()) { + auto JtrackIndex = trackMapping.find(clusterTrack.globalIndex()); + if (JtrackIndex != trackMapping.end()) { + clusterStoredJTrackIDs.push_back(JtrackIndex->second); + } + } + storedJClustersMatchedTracksTable(clusterStoredJTrackIDs); + } + } - for (const auto& cluster : clusters) { - storedJClustersTable(storedJCollisionsTable.lastIndex(), cluster.id(), cluster.energy(), cluster.coreEnergy(), cluster.rawEnergy(), - cluster.eta(), cluster.phi(), cluster.m02(), cluster.m20(), cluster.nCells(), cluster.time(), cluster.isExotic(), cluster.distanceToBadChannel(), - cluster.nlm(), cluster.definition(), cluster.leadingCellEnergy(), cluster.subleadingCellEnergy(), cluster.leadingCellNumber(), cluster.subleadingCellNumber()); - storedJClustersParentIndexTable(cluster.clusterId()); + if (saveD0Table) { + int nD0InCollision = 0; + int32_t collisionD0Index = -1; + for (const auto& D0 : D0s) { + if (nD0InCollision == 0) { + jethfutilities::fillD0CollisionTable(D0.hfD0CollBase_as(), storedD0CollisionsTable, collisionD0Index); + } + nD0InCollision++; + + int32_t D0Index = -1; + jethfutilities::fillD0CandidateTable(D0, collisionD0Index, storedD0sTable, storedD0ParsTable, storedD0ParExtrasTable, storedD0SelsTable, storedD0McsTable, D0Index); - std::vector clusterStoredJTrackIDs; - for (const auto& clusterTrack : cluster.matchedTracks_as>()) { - auto JtrackIndex = trackMapping.find(clusterTrack.globalIndex()); + int32_t prong0Id = -1; + int32_t prong1Id = -1; + auto JtrackIndex = trackMapping.find(D0.prong0Id()); + if (JtrackIndex != trackMapping.end()) { + prong0Id = JtrackIndex->second; + } + JtrackIndex = trackMapping.find(D0.prong1Id()); if (JtrackIndex != trackMapping.end()) { - clusterStoredJTrackIDs.push_back(JtrackIndex->second); + prong1Id = JtrackIndex->second; } + storedD0IdsTable(storedJCollisionsTable.lastIndex(), prong0Id, prong1Id); } - storedJClustersMatchedTracksTable(clusterStoredJTrackIDs); } } } @@ -187,7 +234,7 @@ struct JetDerivedDataWriter { // to run after all jet selections PROCESS_SWITCH(JetDerivedDataWriter, processData, "write out data output tables", true); - void processMC(soa::Join const& mcCollisions, soa::Join const& collisions, soa::Join const& bcs, soa::Join const& tracks, soa::Join const& clusters, soa::Join const& particles) + void processMC(soa::Join const& mcCollisions, soa::Join const& collisions, soa::Join const& bcs, soa::Join const& tracks, soa::Join const& clusters, soa::Join const& particles, aod::HfD0CollBases const& D0Collisions, CandidatesD0MCD const& D0s, soa::Join const& D0Particles) { std::map paticleMapping; @@ -244,6 +291,19 @@ struct JetDerivedDataWriter { storedJMcParticlesTable(storedJMcCollisionsTable.lastIndex(), particle.pt(), particle.eta(), particle.phi(), particle.y(), particle.e(), particle.pdgCode(), particle.getGenStatusCode(), particle.getHepMCStatusCode(), particle.isPhysicalPrimary(), mothersId, daughtersId); storedJParticlesParentIndexTable(particle.mcParticleId()); } + + if (saveD0Table) { + for (const auto& D0Particle : D0Particles) { + int32_t D0ParticleIndex = -1; + jethfutilities::fillD0CandidateMcTable(D0Particle, storedD0ParticlesTable, D0ParticleIndex); + int32_t d0ParticleId = -1; + auto JParticleIndex = paticleMapping.find(D0Particle.mcParticleId()); + if (JParticleIndex != paticleMapping.end()) { + d0ParticleId = JParticleIndex->second; + } + storedD0ParticleIdsTable(storedJMcCollisionsTable.lastIndex(), d0ParticleId); + } + } } } @@ -260,28 +320,31 @@ struct JetDerivedDataWriter { for (auto collision : collisionsPerMcCollision) { std::map trackMapping; - - auto bc = collision.bc_as>(); - if (std::find(bcIndicies.begin(), bcIndicies.end(), bc.globalIndex()) == bcIndicies.end()) { - storedJBCsTable(bc.runNumber(), bc.globalBC(), bc.timestamp()); - storedJBCParentIndexTable(bc.bcId()); - bcIndicies.push_back(bc.globalIndex()); - bcMapping.insert(std::make_pair(bc.globalIndex(), storedJBCsTable.lastIndex())); + if (saveBCsTable) { + auto bc = collision.bc_as>(); + if (std::find(bcIndicies.begin(), bcIndicies.end(), bc.globalIndex()) == bcIndicies.end()) { + storedJBCsTable(bc.runNumber(), bc.globalBC(), bc.timestamp()); + storedJBCParentIndexTable(bc.bcId()); + bcIndicies.push_back(bc.globalIndex()); + bcMapping.insert(std::make_pair(bc.globalIndex(), storedJBCsTable.lastIndex())); + } } - storedJCollisionsTable(collision.posZ(), collision.eventSel(), collision.alias_raw()); + storedJCollisionsTable(collision.posZ(), collision.centrality(), collision.eventSel(), collision.alias_raw()); storedJCollisionsParentIndexTable(collision.collisionId()); auto JMcCollisionIndex = mcCollisionMapping.find(mcCollision.globalIndex()); if (JMcCollisionIndex != mcCollisionMapping.end()) { storedJMcCollisionsLabelTable(JMcCollisionIndex->second); } - int32_t storedBCID = -1; - auto JBCIndex = bcMapping.find(collision.bcId()); - if (JBCIndex != bcMapping.end()) { - storedBCID = JBCIndex->second; + if (saveBCsTable) { + int32_t storedBCID = -1; + auto JBCIndex = bcMapping.find(collision.bcId()); + if (JBCIndex != bcMapping.end()) { + storedBCID = JBCIndex->second; + } + storedJCollisionsBunchCrossingIndexTable(storedBCID); } - storedJCollisionsBunchCrossingIndexTable(storedBCID); storedJChargedTriggerSelsTable(collision.chargedTriggerSel()); storedJFullTriggerSelsTable(collision.fullTriggerSel()); @@ -302,22 +365,50 @@ struct JetDerivedDataWriter { } trackMapping.insert(std::make_pair(track.globalIndex(), storedJTracksTable.lastIndex())); } + if (saveClustersTable) { + const auto clustersPerCollision = clusters.sliceBy(ClustersPerCollision, collision.globalIndex()); + for (const auto& cluster : clustersPerCollision) { + storedJClustersTable(storedJCollisionsTable.lastIndex(), cluster.id(), cluster.energy(), cluster.coreEnergy(), cluster.rawEnergy(), + cluster.eta(), cluster.phi(), cluster.m02(), cluster.m20(), cluster.nCells(), cluster.time(), cluster.isExotic(), cluster.distanceToBadChannel(), + cluster.nlm(), cluster.definition(), cluster.leadingCellEnergy(), cluster.subleadingCellEnergy(), cluster.leadingCellNumber(), cluster.subleadingCellNumber()); + storedJClustersParentIndexTable(cluster.clusterId()); + + std::vector clusterStoredJTrackIDs; + for (const auto& clusterTrack : cluster.matchedTracks_as>()) { + auto JtrackIndex = trackMapping.find(clusterTrack.globalIndex()); + if (JtrackIndex != trackMapping.end()) { + clusterStoredJTrackIDs.push_back(JtrackIndex->second); + } + } + storedJClustersMatchedTracksTable(clusterStoredJTrackIDs); + } + } - const auto clustersPerCollision = clusters.sliceBy(ClustersPerCollision, collision.globalIndex()); - for (const auto& cluster : clustersPerCollision) { - storedJClustersTable(storedJCollisionsTable.lastIndex(), cluster.id(), cluster.energy(), cluster.coreEnergy(), cluster.rawEnergy(), - cluster.eta(), cluster.phi(), cluster.m02(), cluster.m20(), cluster.nCells(), cluster.time(), cluster.isExotic(), cluster.distanceToBadChannel(), - cluster.nlm(), cluster.definition(), cluster.leadingCellEnergy(), cluster.subleadingCellEnergy(), cluster.leadingCellNumber(), cluster.subleadingCellNumber()); - storedJClustersParentIndexTable(cluster.clusterId()); + if (saveD0Table) { + const auto d0sPerCollision = D0s.sliceBy(D0sPerCollision, collision.globalIndex()); + int nD0InCollision = 0; + int32_t collisionD0Index = -1; + for (const auto& D0 : d0sPerCollision) { + if (nD0InCollision == 0) { + jethfutilities::fillD0CollisionTable(D0.hfD0CollBase_as(), storedD0CollisionsTable, collisionD0Index); + } + nD0InCollision++; - std::vector clusterStoredJTrackIDs; - for (const auto& clusterTrack : cluster.matchedTracks_as>()) { - auto JtrackIndex = trackMapping.find(clusterTrack.globalIndex()); + int32_t D0Index = -1; + jethfutilities::fillD0CandidateTable(D0, collisionD0Index, storedD0sTable, storedD0ParsTable, storedD0ParExtrasTable, storedD0SelsTable, storedD0McsTable, D0Index); + + int32_t prong0Id = -1; + int32_t prong1Id = -1; + auto JtrackIndex = trackMapping.find(D0.prong0Id()); + if (JtrackIndex != trackMapping.end()) { + prong0Id = JtrackIndex->second; + } + JtrackIndex = trackMapping.find(D0.prong1Id()); if (JtrackIndex != trackMapping.end()) { - clusterStoredJTrackIDs.push_back(JtrackIndex->second); + prong1Id = JtrackIndex->second; } + storedD0IdsTable(storedJCollisionsTable.lastIndex(), prong0Id, prong1Id); } - storedJClustersMatchedTracksTable(clusterStoredJTrackIDs); } } } @@ -327,7 +418,7 @@ struct JetDerivedDataWriter { // to run after all jet selections PROCESS_SWITCH(JetDerivedDataWriter, processMC, "write out data output tables for mc", false); - void processMCP(soa::Join const& mcCollisions, soa::Join const& particles) + void processMCP(soa::Join const& mcCollisions, soa::Join const& particles, soa::Join const& D0Particles) { int particleTableIndex = 0; @@ -373,6 +464,19 @@ struct JetDerivedDataWriter { storedJMcParticlesTable(storedJMcCollisionsTable.lastIndex(), particle.pt(), particle.eta(), particle.phi(), particle.y(), particle.e(), particle.pdgCode(), particle.getGenStatusCode(), particle.getHepMCStatusCode(), particle.isPhysicalPrimary(), mothersId, daughtersId); storedJParticlesParentIndexTable(particle.mcParticleId()); } + + if (saveD0Table) { + for (const auto& D0Particle : D0Particles) { + int32_t D0ParticleIndex = -1; + jethfutilities::fillD0CandidateMcTable(D0Particle, storedD0ParticlesTable, D0ParticleIndex); + int32_t d0ParticleId = -1; + auto JParticleIndex = paticleMapping.find(D0Particle.mcParticleId()); + if (JParticleIndex != paticleMapping.end()) { + d0ParticleId = JParticleIndex->second; + } + storedD0ParticleIdsTable(storedJMcCollisionsTable.lastIndex(), d0ParticleId); + } + } } } } diff --git a/PWGJE/TableProducer/jeteventweightmcd.cxx b/PWGJE/TableProducer/jeteventweightmcd.cxx index 6be40adf686..b86a339ca85 100644 --- a/PWGJE/TableProducer/jeteventweightmcd.cxx +++ b/PWGJE/TableProducer/jeteventweightmcd.cxx @@ -26,30 +26,38 @@ using namespace o2::framework::expressions; #include "Framework/runDataProcessing.h" -template +template struct JetEventWeightMCDTask { Produces mcDetectorLevelWeightsTable; + Produces mcDetectorLevelEventWiseSubtractedWeightsTable; - void processDummy(aod::JCollisions const& collisions) + void processDummy(JetCollisions const& collisions) { } PROCESS_SWITCH(JetEventWeightMCDTask, processDummy, "Dummy process", true); - void processMCDetectorLevelEventWeight(MCDetectorLevelJetTable const& jet, soa::Join const& collisions, aod::JMcCollisions const& mcCollisions) + void processMCDetectorLevelEventWeight(MCDetectorLevelJetTable const& jet, soa::Join const& collisions, JetMcCollisions const& mcCollisions) { - auto collision = jet.template collision_as>(); + auto collision = jet.template collision_as>(); mcDetectorLevelWeightsTable(jet.globalIndex(), collision.mcCollision().weight()); } PROCESS_SWITCH(JetEventWeightMCDTask, processMCDetectorLevelEventWeight, "Fill event weight tables for detector level MC jets", false); + + void processMCDetectorLevelEventWiseSubtractedEventWeight(MCDetectorLevelEventWiseSubtractedJetTable const& jet, soa::Join const& collisions, JetMcCollisions const& mcCollisions) + { + auto collision = jet.template collision_as>(); + mcDetectorLevelEventWiseSubtractedWeightsTable(jet.globalIndex(), collision.mcCollision().weight()); + } + PROCESS_SWITCH(JetEventWeightMCDTask, processMCDetectorLevelEventWiseSubtractedEventWeight, "Fill event weight tables for detector level MC jets", false); }; -using ChargedMCJetsEventWeight = JetEventWeightMCDTask; -using NeutralMCJetsEventWeight = JetEventWeightMCDTask; -using FullMCJetsEventWeight = JetEventWeightMCDTask; -using D0ChargedMCJetsEventWeight = JetEventWeightMCDTask; -using LcChargedMCJetsEventWeight = JetEventWeightMCDTask; -using BplusChargedMCJetsEventWeight = JetEventWeightMCDTask; +using ChargedMCJetsEventWeight = JetEventWeightMCDTask; +using NeutralMCJetsEventWeight = JetEventWeightMCDTask; +using FullMCJetsEventWeight = JetEventWeightMCDTask; +using D0ChargedMCJetsEventWeight = JetEventWeightMCDTask; +using LcChargedMCJetsEventWeight = JetEventWeightMCDTask; +using BplusChargedMCJetsEventWeight = JetEventWeightMCDTask; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { diff --git a/PWGJE/TableProducer/jeteventweightmcp.cxx b/PWGJE/TableProducer/jeteventweightmcp.cxx index 44be5b8b708..63344091000 100644 --- a/PWGJE/TableProducer/jeteventweightmcp.cxx +++ b/PWGJE/TableProducer/jeteventweightmcp.cxx @@ -31,12 +31,12 @@ template mcParticleLevelWeightsTable; - void processDummy(aod::JMcCollisions const& collisions) + void processDummy(JetMcCollisions const& collisions) { } PROCESS_SWITCH(JetEventWeightMCPTask, processDummy, "Dummy process", true); - void processMCParticleLevelEventWeight(MCParticleLevelJetTable const& jet, aod::JMcCollisions const& collisions) + void processMCParticleLevelEventWeight(MCParticleLevelJetTable const& jet, JetMcCollisions const& collisions) { mcParticleLevelWeightsTable(jet.globalIndex(), jet.mcCollision().weight()); } diff --git a/PWGJE/TableProducer/jetfinder.cxx b/PWGJE/TableProducer/jetfinder.cxx index 766929ec8ba..15ab2af9e1e 100644 --- a/PWGJE/TableProducer/jetfinder.cxx +++ b/PWGJE/TableProducer/jetfinder.cxx @@ -15,7 +15,7 @@ /// \author Jochen Klein /// \author Raymond Ehlers , ORNL -#include "PWGJE/TableProducer/jetfinder.h" +#include "PWGJE/Core/JetFindingUtilities.h" #include "Framework/runDataProcessing.h" using namespace o2; @@ -23,14 +23,17 @@ using namespace o2::analysis; using namespace o2::framework; using namespace o2::framework::expressions; -template +template struct JetFinderTask { Produces jetsTable; Produces constituentsTable; - Produces constituentsSubTable; + Produces jetsEvtWiseSubTable; + Produces constituentsEvtWiseSubTable; // event level configurables Configurable vertexZCut{"vertexZCut", 10.0f, "Accepted z-vertex range"}; + Configurable centralityMin{"centralityMin", -999.0, "minimum centrality"}; + Configurable centralityMax{"centralityMax", 999.0, "maximum centrality"}; // track level configurables Configurable trackPtMin{"trackPtMin", 0.15, "minimum track pT"}; @@ -74,12 +77,10 @@ struct JetFinderTask { JetFinder jetFinder; std::vector inputParticles; - bool doConstSub = false; - void init(InitContext const&) { - trackSelection = JetDerivedDataUtilities::initialiseTrackSelection(static_cast(trackSelections)); - eventSelection = JetDerivedDataUtilities::initialiseEventSelection(static_cast(eventSelections)); + trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); + eventSelection = jetderiveddatautilities::initialiseEventSelection(static_cast(eventSelections)); particleSelection = static_cast(particleSelections); jetFinder.etaMin = trackEtaMin; @@ -101,92 +102,109 @@ struct JetFinderTask { } aod::EMCALClusterDefinition clusterDefinition = aod::emcalcluster::getClusterDefinitionFromString(clusterDefinitionS.value); - Filter collisionFilter = nabs(aod::jcollision::posZ) < vertexZCut; + Filter collisionFilter = (nabs(aod::jcollision::posZ) < vertexZCut && aod::jcollision::centrality >= centralityMin && aod::jcollision::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); // do we need eta cut both here and in globalselection? + Filter trackSubCuts = (aod::jtracksub::pt >= trackPtMin && aod::jtracksub::pt < trackPtMax && aod::jtracksub::eta > trackEtaMin && aod::jtracksub::eta < trackEtaMax && aod::jtracksub::phi >= trackPhiMin && aod::jtracksub::phi <= trackPhiMax); + Filter partCuts = (aod::jmcparticle::pt >= trackPtMin && aod::jmcparticle::pt < trackPtMax && aod::jmcparticle::eta > trackEtaMin && aod::jmcparticle::eta < trackEtaMax); 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)); - void processDummy(aod::JCollision const& collision) + void processDummy(JetCollisions const& collisions) { } PROCESS_SWITCH(JetFinderTask, processDummy, "Dummy process function turned on by default", true); - void processChargedJets(soa::Filtered::iterator const& collision, - JetTracks const& tracks) + void processChargedJets(soa::Filtered::iterator const& collision, + soa::Filtered const& tracks) { - if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } inputParticles.clear(); - analyseTracks(inputParticles, tracks, trackSelection); - findJets(jetFinder, inputParticles, jetRadius, collision, jetsTable, constituentsTable, constituentsSubTable, doConstSub); + jetfindingutilities::analyseTracks, soa::Filtered::iterator>(inputParticles, tracks, trackSelection); + jetfindingutilities::findJets(jetFinder, inputParticles, jetRadius, collision, jetsTable, constituentsTable); } - PROCESS_SWITCH(JetFinderTask, processChargedJets, "Data jet finding for charged jets", false); + PROCESS_SWITCH(JetFinderTask, processChargedJets, "Data and reco level jet finding for charged jets", false); - void processNeutralJets(soa::Filtered::iterator const& collision, - JetClusters const& clusters) + void processChargedEvtWiseSubJets(soa::Filtered::iterator const& collision, + soa::Filtered const& tracks) { - if (!JetDerivedDataUtilities::eventEMCAL(collision)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } inputParticles.clear(); - analyseClusters(inputParticles, &clusters); - findJets(jetFinder, inputParticles, jetRadius, collision, jetsTable, constituentsTable, constituentsSubTable, doConstSub); + jetfindingutilities::analyseTracks, soa::Filtered::iterator>(inputParticles, tracks, trackSelection); + jetfindingutilities::findJets(jetFinder, inputParticles, jetRadius, collision, jetsEvtWiseSubTable, constituentsEvtWiseSubTable); } - PROCESS_SWITCH(JetFinderTask, processNeutralJets, "Data jet finding for neutral jets", false); - void processFullJets(soa::Filtered::iterator const& collision, - JetTracks const& tracks, - JetClusters const& clusters) + PROCESS_SWITCH(JetFinderTask, processChargedEvtWiseSubJets, "Data and reco level jet finding for charged jets with event-wise constituent subtraction", false); + + void processNeutralJets(soa::Filtered::iterator const& collision, + soa::Filtered const& clusters) { - if (!JetDerivedDataUtilities::eventEMCAL(collision)) { + if (!jetderiveddatautilities::eventEMCAL(collision)) { return; } inputParticles.clear(); - analyseTracks(inputParticles, tracks, trackSelection); - analyseClusters(inputParticles, &clusters); - findJets(jetFinder, inputParticles, jetRadius, collision, jetsTable, constituentsTable, constituentsSubTable, doConstSub); + jetfindingutilities::analyseClusters(inputParticles, &clusters); + jetfindingutilities::findJets(jetFinder, inputParticles, jetRadius, collision, jetsTable, constituentsTable); } - PROCESS_SWITCH(JetFinderTask, processFullJets, "Data jet finding for full and neutral jets", false); + PROCESS_SWITCH(JetFinderTask, processNeutralJets, "Data and reco level jet finding for neutral jets", false); - void processParticleLevelChargedJets(aod::JMcCollision const& collision, soa::Filtered const& particles) + void processFullJets(soa::Filtered::iterator const& collision, + soa::Filtered const& tracks, + soa::Filtered const& clusters) + { + if (!jetderiveddatautilities::eventEMCAL(collision)) { + return; + } + inputParticles.clear(); + jetfindingutilities::analyseTracks, soa::Filtered::iterator>(inputParticles, tracks, trackSelection); + jetfindingutilities::analyseClusters(inputParticles, &clusters); + jetfindingutilities::findJets(jetFinder, inputParticles, jetRadius, collision, jetsTable, constituentsTable); + } + PROCESS_SWITCH(JetFinderTask, processFullJets, "Data and reco level jet finding for full and neutral jets", false); + + void processParticleLevelChargedJets(JetMcCollision const& collision, soa::Filtered const& particles) { // TODO: MC event selection? - analyseParticles, soa::Filtered::iterator>(inputParticles, particleSelection, 1, particles, pdgDatabase); - findJets(jetFinder, inputParticles, jetRadius, collision, jetsTable, constituentsTable, constituentsSubTable, doConstSub); + inputParticles.clear(); + jetfindingutilities::analyseParticles, soa::Filtered::iterator>(inputParticles, particleSelection, 1, particles, pdgDatabase); + jetfindingutilities::findJets(jetFinder, inputParticles, jetRadius, collision, jetsTable, constituentsTable); } PROCESS_SWITCH(JetFinderTask, processParticleLevelChargedJets, "Particle level charged jet finding", false); - void processParticleLevelNeutralJets(aod::JMcCollision const& collision, soa::Filtered const& particles) + void processParticleLevelNeutralJets(JetMcCollision const& collision, soa::Filtered const& particles) { // TODO: MC event selection? - analyseParticles, soa::Filtered::iterator>(inputParticles, particleSelection, 2, particles, pdgDatabase); - findJets(jetFinder, inputParticles, jetRadius, collision, jetsTable, constituentsTable, constituentsSubTable, doConstSub); + inputParticles.clear(); + jetfindingutilities::analyseParticles, soa::Filtered::iterator>(inputParticles, particleSelection, 2, particles, pdgDatabase); + jetfindingutilities::findJets(jetFinder, inputParticles, jetRadius, collision, jetsTable, constituentsTable); } PROCESS_SWITCH(JetFinderTask, processParticleLevelNeutralJets, "Particle level neutral jet finding", false); - void processParticleLevelFullJets(aod::JMcCollision const& collision, soa::Filtered const& particles) + void processParticleLevelFullJets(JetMcCollision const& collision, soa::Filtered const& particles) { // TODO: MC event selection? - analyseParticles, soa::Filtered::iterator>(inputParticles, particleSelection, 0, particles, pdgDatabase); - findJets(jetFinder, inputParticles, jetRadius, collision, jetsTable, constituentsTable, constituentsSubTable, doConstSub); + inputParticles.clear(); + jetfindingutilities::analyseParticles, soa::Filtered::iterator>(inputParticles, particleSelection, 0, particles, pdgDatabase); + jetfindingutilities::findJets(jetFinder, inputParticles, jetRadius, collision, jetsTable, constituentsTable); } PROCESS_SWITCH(JetFinderTask, processParticleLevelFullJets, "Particle level full jet finding", false); }; -using JetFinderDataCharged = JetFinderTask; -using JetFinderDataFull = JetFinderTask; -using JetFinderDataNeutral = JetFinderTask; -using JetFinderMCDetectorLevelCharged = JetFinderTask; -using JetFinderMCDetectorLevelFull = JetFinderTask; -using JetFinderMCDetectorLevelNeutral = JetFinderTask; -using JetFinderMCParticleLevelCharged = JetFinderTask; -using JetFinderMCParticleLevelFull = JetFinderTask; -using JetFinderMCParticleLevelNeutral = JetFinderTask; -// using JetFinderHybridIntermediate = JetFinderTask; +using JetFinderDataCharged = JetFinderTask; +using JetFinderDataFull = JetFinderTask; +using JetFinderDataNeutral = JetFinderTask; +using JetFinderMCDetectorLevelCharged = JetFinderTask; +using JetFinderMCDetectorLevelFull = JetFinderTask; +using JetFinderMCDetectorLevelNeutral = JetFinderTask; +using JetFinderMCParticleLevelCharged = JetFinderTask; +using JetFinderMCParticleLevelFull = JetFinderTask; +using JetFinderMCParticleLevelNeutral = JetFinderTask; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { @@ -217,10 +235,6 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) adaptAnalysisTask(cfgc, SetDefaultProcesses{}, TaskName{"jet-finder-mcd-neutral"})); - // tasks.emplace_back( - // adaptAnalysisTask(cfgc, - // SetDefaultProcesses{}, TaskName{"jet-finder-hybrid-intermedaite-full"})); - tasks.emplace_back( adaptAnalysisTask(cfgc, SetDefaultProcesses{}, TaskName{"jet-finder-mcp-charged"})); diff --git a/PWGJE/TableProducer/jetfinder.h b/PWGJE/TableProducer/jetfinder.h deleted file mode 100644 index a7da5143e17..00000000000 --- a/PWGJE/TableProducer/jetfinder.h +++ /dev/null @@ -1,234 +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. - -// jet finder task header file -// -/// \author Nima Zardoshti -/// \author Jochen Klein - -#ifndef PWGJE_TABLEPRODUCER_JETFINDER_H_ -#define PWGJE_TABLEPRODUCER_JETFINDER_H_ - -#include -#include -#include -#include - -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoA.h" -#include "Framework/O2DatabasePDGPlugin.h" - -#include "Common/Core/TrackSelection.h" -#include "Common/Core/TrackSelectionDefaults.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" -#include "PWGJE/DataModel/EMCALClusters.h" - -#include "PWGHF/Core/SelectorCuts.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" - -// #include "PWGJE/Core/JetBkgSubUtils.h" -#include "PWGJE/Core/FastJetUtilities.h" -#include "PWGJE/Core/JetDerivedDataUtilities.h" -#include "PWGJE/Core/JetFinder.h" -#include "PWGJE/DataModel/Jet.h" - -using JetTracks = o2::soa::Filtered; -using JetClusters = o2::soa::Filtered; - -using ParticlesD0 = o2::soa::Filtered>; -using ParticlesLc = o2::soa::Filtered>; -using ParticlesBplus = o2::soa::Filtered>; - -using CandidatesD0Data = o2::soa::Filtered>; -using CandidatesD0MCD = o2::soa::Filtered>; - -using CandidatesBplusData = o2::soa::Filtered>; -using CandidatesBplusMCD = o2::soa::Filtered>; - -using CandidatesLcData = o2::soa::Filtered>; -using CandidatesLcMCD = o2::soa::Filtered>; - -// functions for track, cluster and candidate selection - -// function that adds tracks to the fastjet list, removing daughters of 2Prong candidates -template -void analyseTracks(std::vector& inputParticles, T const& tracks, int trackSelection, std::optional const& candidate = std::nullopt) -{ - for (auto& track : tracks) { - if (!JetDerivedDataUtilities::selectTrack(track, trackSelection)) { - continue; - } - if (candidate != std::nullopt) { - auto cand = candidate.value(); - if constexpr (std::is_same_v, CandidatesD0Data::iterator> || std::is_same_v, CandidatesD0Data::filtered_iterator> || std::is_same_v, CandidatesD0MCD::iterator> || std::is_same_v, CandidatesD0MCD::filtered_iterator>) { - if (cand.template prong0_as().globalIndex() == track.globalIndex() || cand.template prong1_as().globalIndex() == track.globalIndex()) { - continue; - } - } - - if constexpr (std::is_same_v, CandidatesLcData::iterator> || std::is_same_v, CandidatesLcData::filtered_iterator> || std::is_same_v, CandidatesLcMCD::iterator> || std::is_same_v, CandidatesLcMCD::filtered_iterator>) { - if (cand.template prong0_as().globalIndex() == track.globalIndex() || cand.template prong1_as().globalIndex() == track.globalIndex() || cand.template prong2_as().globalIndex() == track.globalIndex()) { - continue; - } - } - - if constexpr (std::is_same_v, CandidatesBplusData::iterator> || std::is_same_v, CandidatesBplusData::filtered_iterator> || std::is_same_v, CandidatesBplusMCD::iterator> || std::is_same_v, CandidatesBplusMCD::filtered_iterator>) { - if (cand.template prong0_as().template prong0_as().globalIndex() == track.globalIndex() || cand.template prong0_as().template prong1_as().globalIndex() == track.globalIndex() || cand.template prong1_as().globalIndex() == track.globalIndex()) { - continue; - } - } - } - FastJetUtilities::fillTracks(track, inputParticles, track.globalIndex()); - } -} - -// function that adds clusters to the fastjet list -template -void analyseClusters(std::vector& inputParticles, T const& clusters) -{ - for (auto& cluster : *clusters) { - // add cluster selections - FastJetUtilities::fillClusters(cluster, inputParticles, cluster.globalIndex()); - } -} - -// function that takes any generic candidate, performs selections and adds the candidate to the fastjet list -template -bool analyseCandidate(std::vector& inputParticles, int candMass, float candPtMin, float candPtMax, float candYMin, float candYMax, T const& candidate) -{ - if (candidate.y(candMass) < candYMin || candidate.y(candMass) > candYMax) { - return false; - } - if (candidate.pt() < candPtMin || candidate.pt() >= candPtMax) { - return false; - } - FastJetUtilities::fillTracks(candidate, inputParticles, candidate.globalIndex(), static_cast(JetConstituentStatus::candidateHF), candMass); - return true; -} - -// function that checks the MC status of a candidate and then calls the function to analyseCandidates -template -bool analyseCandidateMC(std::vector& inputParticles, int candMass, int candDecay, float candPtMin, float candPtMax, float candYMin, float candYMax, T const& candidate, bool rejectBackgroundMCCandidates) -{ - if (rejectBackgroundMCCandidates && !(std::abs(candidate.flagMcMatchRec()) == 1 << candDecay)) { - return false; - } - return analyseCandidate(inputParticles, candMass, candPtMin, candPtMax, candYMin, candYMax, candidate); -} - -// function that calls the jet finding and fills the relevant tables -template -void findJets(JetFinder& jetFinder, std::vector& inputParticles, std::vector jetRadius, T const& collision, U& jetsTable, V& constituentsTable, W& constituentsSubTable, bool DoConstSub, bool doHFJetFinding = false) -{ - // auto candidatepT = 0.0; - auto jetRValues = static_cast>(jetRadius); - for (auto R : jetRValues) { - jetFinder.jetR = R; - std::vector jets; - fastjet::ClusterSequenceArea clusterSeq(jetFinder.findJets(inputParticles, jets)); - - // JetBkgSubUtils bkgSub(jetFinder.jetR, 1., 0.6, jetFinder.jetEtaMin, jetFinder.jetEtaMax, jetFinder.jetPhiMin, jetFinder.jetPhiMax, jetFinder.ghostAreaSpec); - // bkgSub.setMaxEtaEvent(jetFinder.etaMax); - // auto[rho, rhoM] = bkgSub.estimateRhoAreaMedian(inputParticles, false); - // jets = jetFinder.selJets(bkgSub.doRhoAreaSub(jets, rho, rhoM)); - - for (const auto& jet : jets) { - bool isHFJet = false; - if (doHFJetFinding) { - for (const auto& constituent : jet.constituents()) { - if (constituent.template user_info().getStatus() == static_cast(JetConstituentStatus::candidateHF)) { - isHFJet = true; - // candidatepT = constituent.pt(); - break; - } - } - if (!isHFJet) { - continue; - } - } - std::vector trackconst; - std::vector candconst; - std::vector clusterconst; - jetsTable(collision.globalIndex(), jet.pt(), jet.eta(), jet.phi(), - jet.E(), jet.m(), jet.has_area() ? jet.area() : -1., std::round(R * 100)); - for (const auto& constituent : sorted_by_pt(jet.constituents())) { - // need to add seperate thing for constituent subtraction - if (DoConstSub) { - constituentsSubTable(jetsTable.lastIndex(), constituent.pt(), constituent.eta(), constituent.phi(), - constituent.E(), constituent.m(), constituent.user_index()); - } - - if (constituent.template user_info().getStatus() == static_cast(JetConstituentStatus::track)) { - trackconst.push_back(constituent.template user_info().getIndex()); - } - if (constituent.template user_info().getStatus() == static_cast(JetConstituentStatus::cluster)) { - clusterconst.push_back(constituent.template user_info().getIndex()); - } - if (constituent.template user_info().getStatus() == static_cast(JetConstituentStatus::candidateHF)) { - candconst.push_back(constituent.template user_info().getIndex()); - } - } - constituentsTable(jetsTable.lastIndex(), trackconst, clusterconst, candconst); - } - } -} - -// function that checks if a candidate has any daughters that need to be removed from the event at gen level -template -bool checkDaughters(T const& particle, int globalIndex) -{ - for (auto daughter : particle.template daughters_as()) { - if (daughter.globalIndex() == globalIndex) { - return true; - } - if (checkDaughters(daughter, globalIndex)) { - return true; - } - } - return false; -} - -template -void analyseParticles(std::vector& inputParticles, std::string particleSelection, int jetTypeParticleLevel, T const& particles, o2::framework::Service pdgDatabase, std::optional const& candidate = std::nullopt) -{ - inputParticles.clear(); - for (auto& particle : particles) { - if (particleSelection == "PhysicalPrimary" && !particle.isPhysicalPrimary()) { // CHECK : Does this exclude the HF hadron? - continue; - } else if (particleSelection == "HepMCStatus" && particle.getHepMCStatusCode() != 1) { // do we need isPhysicalPrimary as well? Note: Might give unforseen results if the generator isnt PYTHIA - continue; - } else if (particleSelection == "GenStatus" && particle.getGenStatusCode() != 1) { - continue; - } else if (particleSelection == "PhysicalPrimaryAndHepMCStatus" && (!particle.isPhysicalPrimary() || particle.getHepMCStatusCode() != 1)) { - continue; - } - auto pdgParticle = pdgDatabase->GetParticle(particle.pdgCode()); - auto pdgCharge = pdgParticle ? std::abs(pdgParticle->Charge()) : -1.0; - if (jetTypeParticleLevel == static_cast(JetType::charged) && pdgCharge < 3.0) { - continue; - } - if (jetTypeParticleLevel == static_cast(JetType::neutral) && pdgCharge != 0.0) { - continue; - } - if (candidate != std::nullopt) { - auto cand = candidate.value(); - if (checkDaughters(cand, particle.globalIndex())) { - continue; - } - } - FastJetUtilities::fillTracks(particle, inputParticles, particle.globalIndex(), static_cast(JetConstituentStatus::track), pdgParticle->Mass()); - } -} - -#endif // PWGJE_TABLEPRODUCER_JETFINDER_H_ diff --git a/PWGJE/TableProducer/jetfinderD0DataCharged.cxx b/PWGJE/TableProducer/jetfinderD0DataCharged.cxx index 9250c8ad582..126cecd682b 100644 --- a/PWGJE/TableProducer/jetfinderD0DataCharged.cxx +++ b/PWGJE/TableProducer/jetfinderD0DataCharged.cxx @@ -15,7 +15,7 @@ #include "PWGJE/TableProducer/jetfinderhf.cxx" -using JetFinderD0DataCharged = JetFinderHFTask; +using JetFinderD0DataCharged = JetFinderHFTask; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { diff --git a/PWGJE/TableProducer/jetfinderD0MCDCharged.cxx b/PWGJE/TableProducer/jetfinderD0MCDCharged.cxx index 74813626c7c..52e2365084b 100644 --- a/PWGJE/TableProducer/jetfinderD0MCDCharged.cxx +++ b/PWGJE/TableProducer/jetfinderD0MCDCharged.cxx @@ -15,7 +15,7 @@ #include "PWGJE/TableProducer/jetfinderhf.cxx" -using JetFinderD0MCDetectorLevelCharged = JetFinderHFTask; +using JetFinderD0MCDetectorLevelCharged = JetFinderHFTask; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { diff --git a/PWGJE/TableProducer/jetfinderD0MCPCharged.cxx b/PWGJE/TableProducer/jetfinderD0MCPCharged.cxx index 38b839c03cc..31532715035 100644 --- a/PWGJE/TableProducer/jetfinderD0MCPCharged.cxx +++ b/PWGJE/TableProducer/jetfinderD0MCPCharged.cxx @@ -15,7 +15,7 @@ #include "PWGJE/TableProducer/jetfinderhf.cxx" -using JetFinderD0MCParticleLevelCharged = JetFinderHFTask; +using JetFinderD0MCParticleLevelCharged = JetFinderHFTask; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { diff --git a/PWGJE/TableProducer/jetfinderLcDataCharged.cxx b/PWGJE/TableProducer/jetfinderLcDataCharged.cxx deleted file mode 100644 index 0e2de5a83cb..00000000000 --- a/PWGJE/TableProducer/jetfinderLcDataCharged.cxx +++ /dev/null @@ -1,29 +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. - -// jet finder lc data charged task -// -/// \author Nima Zardoshti - -#include "PWGJE/TableProducer/jetfinderhf.cxx" - -using JetFinderLcDataCharged = JetFinderHFTask; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - std::vector tasks; - - tasks.emplace_back(adaptAnalysisTask(cfgc, - SetDefaultProcesses{}, - TaskName{"jet-finder-lc-data-charged"})); - - return WorkflowSpec{tasks}; -} diff --git a/PWGJE/TableProducer/jetfinderhf.cxx b/PWGJE/TableProducer/jetfinderhf.cxx index dc3d96a307a..1f17369f40d 100644 --- a/PWGJE/TableProducer/jetfinderhf.cxx +++ b/PWGJE/TableProducer/jetfinderhf.cxx @@ -16,10 +16,9 @@ #include "CommonConstants/PhysicsConstants.h" +#include "PWGJE/Core/JetFindingUtilities.h" #include "Common/Core/RecoDecay.h" -#include "PWGJE/TableProducer/jetfinder.h" - using namespace o2; using namespace o2::analysis; using namespace o2::framework; @@ -44,14 +43,17 @@ void customize(std::vector& workflowOptions) // NB: runDataProcessing.h must be included after customize! #include "Framework/runDataProcessing.h" -template +template struct JetFinderHFTask { Produces jetsTable; Produces constituentsTable; - Produces constituentsSubTable; + Produces jetsEvtWiseSubTable; + Produces constituentsEvtWiseSubTable; // event level configurables Configurable vertexZCut{"vertexZCut", 10.0f, "Accepted z-vertex range"}; + Configurable centralityMin{"centralityMin", -999.0, "minimum centrality"}; + Configurable centralityMax{"centralityMax", 999.0, "maximum centrality"}; // track level configurables Configurable trackPtMin{"trackPtMin", 0.15, "minimum track pT"}; @@ -81,12 +83,8 @@ struct JetFinderHFTask { Configurable candYMin{"candYMin", -0.8, "minimum candidate eta"}; Configurable candYMax{"candYMax", 0.8, "maximum candidate eta"}; // HF candidiate selection configurables - Configurable rejectBackgroundMCCandidates{"rejectBackgroundMCCandidates", true, "reject background HF candidates at MC detector level"}; - Configurable selectionFlagD0{"selectionFlagD0", 1, "Selection Flag for D0"}; - Configurable selectionFlagD0bar{"selectionFlagD0bar", 1, "Selection Flag for D0bar"}; - Configurable selectionFlagLcToPKPi{"selectionFlagLcToPKPi", 1, "Selection Flag for Lc->PKPi"}; - Configurable selectionFlagLcToPiPK{"selectionFlagLcToPiPK", 1, "Selection Flag for Lc->PiPK"}; - Configurable selectionFlagBplus{"selectionFlagBplus", 1, "Selection Flag for B+"}; + Configurable rejectBackgroundMCDCandidates{"rejectBackgroundMCDCandidates", false, "reject background HF candidates at MC detector level"}; + Configurable rejectIncorrectDecaysMCP{"rejectIncorrectDecaysMCP", true, "reject HF paticles decaying to the non-analysed decay channels at MC generator level"}; // jet level configurables Configurable> jetRadius{"jetRadius", {0.4}, "jet resolution parameters"}; @@ -108,14 +106,12 @@ struct JetFinderHFTask { JetFinder jetFinder; std::vector inputParticles; - bool doConstSub = false; - int candDecay; double candMass; void init(InitContext const&) { - trackSelection = JetDerivedDataUtilities::initialiseTrackSelection(static_cast(trackSelections)); - eventSelection = JetDerivedDataUtilities::initialiseEventSelection(static_cast(eventSelections)); + trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); + eventSelection = jetderiveddatautilities::initialiseEventSelection(static_cast(eventSelections)); particleSelection = static_cast(particleSelections); jetFinder.etaMin = trackEtaMin; @@ -132,124 +128,121 @@ struct JetFinderHFTask { jetFinder.ghostArea = jetGhostArea; jetFinder.ghostRepeatN = ghostRepeat; - if constexpr (std::is_same_v, CandidatesD0Data>) { // Note : need to be careful if configurable workflow options are added later - candMass = o2::constants::physics::MassD0; - candDecay = static_cast(aod::hf_cand_2prong::DecayType::D0ToPiK); - } - if constexpr (std::is_same_v, CandidatesBplusData>) { - candMass = o2::constants::physics::MassBPlus; - candDecay = static_cast(aod::hf_cand_bplus::DecayType::BplusToD0Pi); - } - if constexpr (std::is_same_v, CandidatesLcData>) { - candMass = o2::constants::physics::MassLambdaCPlus; - candDecay = static_cast(aod::hf_cand_3prong::DecayType::LcToPKPi); - } + candMass = jethfutilities::getTablePDGMass(); } aod::EMCALClusterDefinition clusterDefinition = aod::emcalcluster::getClusterDefinitionFromString(clusterDefinitionS.value); - Filter collisionFilter = (nabs(aod::jcollision::posZ) < vertexZCut); + Filter collisionFilter = (nabs(aod::jcollision::posZ) < vertexZCut && aod::jcollision::centrality >= centralityMin && aod::jcollision::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); + Filter trackSubCuts = (aod::jtracksub::pt >= trackPtMin && aod::jtracksub::pt < trackPtMax && aod::jtracksub::eta > trackEtaMin && aod::jtracksub::eta < trackEtaMax && aod::jtracksub::phi >= trackPhiMin && aod::jtracksub::phi <= trackPhiMax); Filter partCuts = (aod::jmcparticle::pt >= trackPtMin && aod::jmcparticle::pt < trackPtMax); 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)); // Filter candidateCuts = (aod::hfcand::pt >= candPtMin && aod::hfcand::pt < candPtMax && aod::hfcand::y >= candYMin && aod::hfcand::y < candYMax); - Filter candidateCutsD0 = (aod::hf_sel_candidate_d0::isSelD0 >= selectionFlagD0 || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlagD0bar); - Filter candidateCutsLc = (aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlagLcToPKPi || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlagLcToPiPK); - Filter candidateCutsBplus = (aod::hf_sel_candidate_bplus::isSelBplusToD0Pi >= selectionFlagBplus); - // function that processes data for all 2Prong candidates - template - void analyseData(T const& collision, U const& tracks, M const& candidates) + PresliceOptional> perD0Candidate = aod::bkgd0::candidateId; + PresliceOptional> perLcCandidate = aod::bkglc::candidateId; + PresliceOptional> perBplusCandidate = aod::bkgbplus::candidateId; + + // function that generalically processes Data and reco level events + template + void analyseCharged(T const& collision, U const& tracks, V const& candidate, M& jetsTableInput, N& constituentsTableInput, O& originalTracks) { - if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } + inputParticles.clear(); - for (auto& candidate : candidates) { - inputParticles.clear(); - if (!analyseCandidate(inputParticles, candMass, candPtMin, candPtMax, candYMin, candYMax, candidate)) { - continue; + if constexpr (jethfutilities::isHFCandidate()) { + if (!jetfindingutilities::analyseCandidate(inputParticles, candidate, candPtMin, candPtMax, candYMin, candYMax, candMass)) { + return; } - analyseTracks(inputParticles, tracks, trackSelection, std::optional{candidate}); - findJets(jetFinder, inputParticles, jetRadius, collision, jetsTable, constituentsTable, constituentsSubTable, doConstSub, true); - } - } - - // function that processes MC det for all 2Prong candidates - template - void analyseMCD(T const& collision, U const& tracks, M const& candidates) - { - if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) { - return; } - for (auto& candidate : candidates) { - inputParticles.clear(); - if (!analyseCandidateMC(inputParticles, candMass, candDecay, candPtMin, candPtMax, candYMin, candYMax, candidate, rejectBackgroundMCCandidates)) { - continue; + if constexpr (jethfutilities::isHFMcCandidate()) { + if (!jetfindingutilities::analyseCandidateMC(inputParticles, candidate, candPtMin, candPtMax, candYMin, candYMax, candMass, rejectBackgroundMCDCandidates)) { + return; } - analyseTracks(inputParticles, tracks, trackSelection, std::optional{candidate}); - findJets(jetFinder, inputParticles, jetRadius, collision, jetsTable, constituentsTable, constituentsSubTable, doConstSub, true); } + jetfindingutilities::analyseTracks(inputParticles, tracks, trackSelection, std::optional{candidate}); + jetfindingutilities::findJets(jetFinder, inputParticles, jetRadius, collision, jetsTableInput, constituentsTableInput, true); } // function that generalically processes gen level events - template - void analyseMCP(T const& collision, U const& particles, int jetTypeParticleLevel) + template + void analyseMCP(T const& collision, U const& particles, V const& candidate, int jetTypeParticleLevel) { - inputParticles.clear(); - std::vector candidates; - candidates.clear(); - - for (auto const& particle : particles) { - if (std::abs(particle.flagMcMatchGen()) & (1 << candDecay)) { - auto particleY = RecoDecay::y(std::array{particle.px(), particle.py(), particle.pz()}, pdgDatabase->Mass(particle.pdgCode())); - if (particleY < candYMin || particleY > candYMax) { - continue; - } - if (particle.pt() < candPtMin || particle.pt() >= candPtMax) { - continue; - } - candidates.push_back(particle); - } + if (rejectIncorrectDecaysMCP && !jethfutilities::isMatchedHFCandidate(candidate)) { // is this even needed in the new derived format? it means any simulations run have to force the decay channel + return; } - for (auto& candidate : candidates) { - analyseParticles(inputParticles, particleSelection, jetTypeParticleLevel, particles, pdgDatabase, std::optional{candidate}); - FastJetUtilities::fillTracks(candidate, inputParticles, candidate.globalIndex(), static_cast(JetConstituentStatus::candidateHF), pdgDatabase->Mass(candidate.pdgCode())); - findJets(jetFinder, inputParticles, jetRadius, collision, jetsTable, constituentsTable, constituentsSubTable, doConstSub, true); + + inputParticles.clear(); + if (!jetfindingutilities::analyseCandidate(inputParticles, candidate, candPtMin, candPtMax, candYMin, candYMax, candMass)) { + return; } + jetfindingutilities::analyseParticles(inputParticles, particleSelection, jetTypeParticleLevel, particles, pdgDatabase, std::optional{candidate}); + jetfindingutilities::findJets(jetFinder, inputParticles, jetRadius, collision, jetsTable, constituentsTable, true); } - void processDummy(aod::JCollision const& collision) + void processDummy(JetCollisions const& collisions) { } PROCESS_SWITCH(JetFinderHFTask, processDummy, "Dummy process function turned on by default", true); - void processChargedJetsData(soa::Filtered::iterator const& collision, JetTracks const& tracks, CandidateTableData const& candidates) { analyseData(collision, tracks, candidates); } + void processChargedJetsData(soa::Filtered::iterator const& collision, soa::Filtered const& tracks, CandidateTableData const& candidates) + { + for (typename CandidateTableData::iterator const& candidate : candidates) { // why can the type not be auto? try const auto + analyseCharged(collision, tracks, candidate, jetsTable, constituentsTable, tracks); + } + } PROCESS_SWITCH(JetFinderHFTask, processChargedJetsData, "charged hf jet finding on data", false); - void processChargedJetsMCD(soa::Filtered::iterator const& collision, JetTracks const& tracks, CandidateTableMCD const& candidates) { analyseMCD(collision, tracks, candidates); } + void processChargedEvtWiseSubJetsData(soa::Filtered::iterator const& collision, soa::Filtered const& tracks, CandidateTableData const& candidates) + { + for (typename CandidateTableData::iterator const& candidate : candidates) { + analyseCharged(collision, jethfutilities::slicedPerCandidate(tracks, candidate, perD0Candidate, perLcCandidate, perBplusCandidate), candidate, jetsEvtWiseSubTable, constituentsEvtWiseSubTable, tracks); + } + } + PROCESS_SWITCH(JetFinderHFTask, processChargedEvtWiseSubJetsData, "charged hf jet finding on data with event-wise constituent subtraction", false); + + void processChargedJetsMCD(soa::Filtered::iterator const& collision, soa::Filtered const& tracks, CandidateTableMCD const& candidates) + { + for (typename CandidateTableMCD::iterator const& candidate : candidates) { + analyseCharged(collision, tracks, candidate, jetsTable, constituentsTable, tracks); + } + } PROCESS_SWITCH(JetFinderHFTask, processChargedJetsMCD, "charged hf jet finding on MC detector level", false); - void processChargedJetsMCP(aod::JMcCollision const& collision, - ParticleTable const& particles) + void processChargedEvtWiseSubJetsMCD(soa::Filtered::iterator const& collision, soa::Filtered const& tracks, CandidateTableMCD const& candidates) + { + for (typename CandidateTableMCD::iterator const& candidate : candidates) { + analyseCharged(collision, jethfutilities::slicedPerCandidate(tracks, candidate, perD0Candidate, perLcCandidate, perBplusCandidate), candidate, jetsEvtWiseSubTable, constituentsEvtWiseSubTable, tracks); + } + } + PROCESS_SWITCH(JetFinderHFTask, processChargedEvtWiseSubJetsMCD, "charged hf jet finding on MC detector level with event-wise constituent subtraction", false); + + void processChargedJetsMCP(JetMcCollision const& collision, + soa::Filtered const& particles, + CandidateTableMCP const& candidates) { - analyseMCP(collision, particles, 1); + for (typename CandidateTableMCP::iterator const& candidate : candidates) { + analyseMCP(collision, particles, candidate, 1); + } } PROCESS_SWITCH(JetFinderHFTask, processChargedJetsMCP, "hf jet finding on MC particle level", false); }; /* -using JetFinderD0DataCharged = JetFinderHFTask; -using JetFinderD0MCDetectorLevelCharged = JetFinderHFTask; -using JetFinderD0MCParticleLevelCharged = JetFinderHFTask; +using JetFinderD0DataCharged = JetFinderHFTask; +using JetFinderD0MCDetectorLevelCharged = JetFinderHFTask; +using JetFinderD0MCParticleLevelCharged = JetFinderHFTask; -using JetFinderBplusDataCharged = JetFinderHFTask; -using JetFinderBplusMCDetectorLevelCharged = JetFinderHFTask; -using JetFinderBplusMCParticleLevelCharged = JetFinderHFTask; +using JetFinderBplusDataCharged = JetFinderHFTask; +using JetFinderBplusMCDetectorLevelCharged = JetFinderHFTask; +using JetFinderBplusMCParticleLevelCharged = JetFinderHFTask; -using JetFinderLcDataCharged = JetFinderHFTask; -using JetFinderLcMCDetectorLevelCharged = JetFinderHFTask; -using JetFinderLcMCParticleLevelCharged = JetFinderHFTask; +using JetFinderLcDataCharged = JetFinderHFTask; +using JetFinderLcMCDetectorLevelCharged = JetFinderHFTask; +using JetFinderLcMCParticleLevelCharged = JetFinderHFTask; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { diff --git a/PWGJE/TableProducer/jetmatching.cxx b/PWGJE/TableProducer/jetmatching.cxx deleted file mode 100644 index ab3cb816ebb..00000000000 --- a/PWGJE/TableProducer/jetmatching.cxx +++ /dev/null @@ -1,416 +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 jetmatching.cxx -/// \brief Unified implementation of jet matching based on different criteria -/// expanding on previously separate implementations of geometric matching -/// (by Raymond Ehlers) and heavy-flavour matching -/// -/// \author Raymond Ehlers , ORNL -/// \author Jochen Klein -/// \author Aimeric Lanodu - -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoA.h" -#include "Framework/runDataProcessing.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include "PWGJE/DataModel/Jet.h" -#include "PWGJE/Core/JetUtilities.h" -#include "PWGHF/DataModel/CandidateReconstructionTables.h" -#include "PWGHF/DataModel/CandidateSelectionTables.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; - -template -struct JetMatching { - - Configurable doMatchingGeo{"doMatchingGeo", true, "Enable geometric matching"}; - Configurable doMatchingPt{"doMatchingPt", true, "Enable pt matching"}; - Configurable doMatchingHf{"doMatchingHf", true, "Enable HF matching"}; - Configurable maxMatchingDistance{"maxMatchingDistance", 0.4f, "Max matching distance"}; - Configurable minPtFraction{"minPtFraction", 0.f, "Minimum pt fraction for pt matching"}; - - Produces jetsBaseToTag; - Produces jetsTagToBase; - - // preslicing jet collections, only for MC-based collection - static constexpr bool jetsBaseIsMC = o2::soa::relatedByIndex(); - static constexpr bool jetsTagIsMC = o2::soa::relatedByIndex(); - Preslice baseJetsPerCollision = jetsBaseIsMC ? aod::jet::mcCollisionId : aod::jet::collisionId; - Preslice tagJetsPerCollision = jetsTagIsMC ? aod::jet::mcCollisionId : aod::jet::collisionId; - - using JetCollisions = soa::Join; - PresliceUnsorted CollisionsCollectionPerMcCollision = aod::jmccollisionlb::mcCollisionId; - using JetTracks = soa::Join; - - // initialise objects used to store the matching index arrays (array in case a mcCollision is split) before filling the matching tables - std::vector> geojetidBaseToTag, ptjetidBaseToTag, hfjetidBaseToTag; - std::vector> geojetidTagToBase, ptjetidTagToBase, hfjetidTagToBase; - - static constexpr int8_t getHfFlag() - { - if (std::is_same::value && - std::is_same::value) - return 1 << aod::hf_cand_2prong::DecayType::D0ToPiK; - - if (std::is_same::value && - std::is_same::value) - return 1 << aod::hf_cand_3prong::DecayType::LcToPKPi; - - if (std::is_same::value && - std::is_same::value) - return 1 << aod::hf_cand_bplus::DecayType::BplusToD0Pi; - - return -1; - } - - void init(InitContext const&) - { - } - - // function that does the geometric matching of jets from jetsBasePerColl and jets from jetsTagPerColl - template - void MatchGeo(T const& jetsBasePerColl, U const& jetsTagPerColl, std::vector& baseToTagGeo, std::vector& tagToBaseGeo) - { - std::vector jetsBasePhi; - std::vector jetsBaseEta; - for (const auto& jet : jetsBasePerColl) { - jetsBasePhi.emplace_back(jet.phi()); - jetsBaseEta.emplace_back(jet.eta()); - } - std::vector jetsTagPhi; - std::vector jetsTagEta; - for (const auto& jet : jetsTagPerColl) { - jetsTagPhi.emplace_back(jet.phi()); - jetsTagEta.emplace_back(jet.eta()); - } - std::tie(baseToTagGeo, tagToBaseGeo) = JetUtilities::MatchJetsGeometrically(jetsBasePhi, jetsBaseEta, jetsTagPhi, jetsTagEta, maxMatchingDistance); - LOGF(debug, "geometric matching: %d - %d jets", baseToTagGeo.size(), tagToBaseGeo.size()); - for (std::size_t i = 0; i < baseToTagGeo.size(); ++i) { - LOGF(debug, "bjet %i -> %i", i, baseToTagGeo[i]); - } - for (std::size_t i = 0; i < tagToBaseGeo.size(); ++i) { - LOGF(debug, "tjet %i -> %i", i, tagToBaseGeo[i]); - } - } - - // function that does the HF matching of jets from jetsBasePerColl and jets from jetsTagPerColl; assumes both jetsBasePerColl and jetsTagPerColl have access to MC information - template - void MatchHF(T const& jetsBasePerColl, U const& jetsTagPerColl, std::vector& baseToTagHF, std::vector& tagToBaseHF) - { - int index_bjet = 0; - int index_tjet = 0; - for (const auto& bjet : jetsBasePerColl) { - LOGF(debug, "jet index: %d (coll %d, pt %g, phi %g) with %d tracks, %d HF candidates", - bjet.index(), bjet.collisionId(), bjet.pt(), bjet.phi(), bjet.tracks().size(), bjet.hfcandidates().size()); - const auto hfcand = bjet.template hfcandidates_first_as(); - if (hfcand.flagMcMatchRec() & getHfFlag()) { - const auto hfCandMC = hfcand.template prong1_as().template mcParticle_as(); - const auto hfCandMcId = hfCandMC.template mothers_first_as().globalIndex(); - for (const auto& tjet : jetsTagPerColl) { - const auto cand = tjet.template hfcandidates_first_as(); - if (cand.globalIndex() == hfCandMcId) { - LOGF(debug, "Found HF match: %d (pt %g) <-> %d (pt %g)", - bjet.globalIndex(), bjet.pt(), tjet.globalIndex(), tjet.pt()); - baseToTagHF[index_bjet] = index_tjet; - tagToBaseHF[index_tjet] = index_bjet; - } - index_tjet++; - } - } - index_bjet++; - } - } - - template - float getPtSum_FirstArgIsMC(T const& mcParts_IdCheck, U const& recoTracks_Summed) - { - float ptSum = 0; - for (const auto& mcPart_IdCheck : mcParts_IdCheck) { - for (const auto& recoTrack_Summed : recoTracks_Summed) { - if (recoTrack_Summed.has_mcParticle() && mcPart_IdCheck.globalIndex() == recoTrack_Summed.template mcParticle_as().globalIndex()) { - ptSum += recoTrack_Summed.pt(); - break; - } - } - } - return ptSum; - } - template - float getPtSum_SecondArgIsMC(T const& recoTracks_IdCheck, U const& mcParts_Summed) - { - float ptSum = 0; - for (const auto& recoTrack_IdCheck : recoTracks_IdCheck) { - for (const auto& mcPart_Summed : mcParts_Summed) { - if (recoTrack_IdCheck.has_mcParticle() && mcPart_Summed.globalIndex() == recoTrack_IdCheck.template mcParticle_as().globalIndex()) { - ptSum += mcPart_Summed.pt(); - break; - } - } - } - return ptSum; - } - - // function that does the pT matching of jets from jetsBasePerColl and jets from jetsTagPerColl ; assumes either one of jetsBasePerColl or jetsTagPerColl have access to MC information - template - void MatchPt(T const& jetsBasePerColl, U const& jetsTagPerColl, std::vector& baseToTagPt, std::vector& tagToBasePt) - { - float ptSum; - int index_bjet = 0; - int index_tjet = 0; - - for (const auto& bjet : jetsBasePerColl) { - for (const auto& tjet : jetsTagPerColl) { - auto btracksTracks = bjet.template tracks_as(); - auto btracksMcParts = bjet.template tracks_as(); - auto ttracksMcParts = tjet.template tracks_as(); - auto ttracksTracks = tjet.template tracks_as(); - - jetsBaseIsMC ? ptSum = getPtSum_FirstArgIsMC(btracksMcParts, ttracksTracks) : ptSum = getPtSum_SecondArgIsMC(btracksTracks, ttracksMcParts); - - if (ptSum > tjet.pt() * minPtFraction) { - LOGF(debug, "Found pt match: %d (pt %g) <-> %d (pt %g)", - bjet.globalIndex(), bjet.pt(), tjet.globalIndex(), tjet.pt()); - baseToTagPt[index_bjet] = index_tjet; - } else { - LOGF(debug, "DID NOT find pt match: %d (pt %g) <-> %d (pt %g)", - bjet.globalIndex(), bjet.pt(), tjet.globalIndex(), tjet.pt()); - } - index_tjet++; - } - index_bjet++; - } - - index_bjet = 0; - index_tjet = 0; - for (const auto& tjet : jetsTagPerColl) { - for (const auto& bjet : jetsBasePerColl) { - auto btracksMcParts = bjet.template tracks_as(); - auto btracksTracks = bjet.template tracks_as(); - auto ttracksMcParts = tjet.template tracks_as(); - auto ttracksTracks = tjet.template tracks_as(); - - jetsBaseIsMC ? ptSum = getPtSum_SecondArgIsMC(ttracksTracks, btracksMcParts) : ptSum = getPtSum_FirstArgIsMC(ttracksMcParts, btracksTracks); - - if (ptSum > bjet.pt() * minPtFraction) { - LOGF(debug, "Found pt match: %d (pt %g) <-> %d (pt %g)", - tjet.globalIndex(), tjet.pt(), bjet.globalIndex(), bjet.pt()); - tagToBasePt[index_tjet] = index_bjet; - } else { - LOGF(debug, "DID NOT find pt match: %d (pt %g) <-> %d (pt %g)", - bjet.globalIndex(), bjet.pt(), tjet.globalIndex(), tjet.pt()); - } - index_bjet++; - } - index_tjet++; - } - } - - // function that calls all the Match functions - template - void doAllMatching(T const& jetsBasePerColl, U const& jetsTagPerColl, std::vector& baseToTagGeo, std::vector& baseToTagHF, std::vector& baseToTagPt, std::vector& tagToBaseGeo, std::vector& tagToBaseHF, std::vector& tagToBasePt) - { - // geometric matching - if (doMatchingGeo) { - MatchGeo(jetsBasePerColl, jetsTagPerColl, baseToTagGeo, tagToBaseGeo); - } - // HF matching - if constexpr (getHfFlag() > 0) { - if (doMatchingHf) { - MatchHF(jetsBasePerColl, jetsTagPerColl, baseToTagHF, tagToBaseHF); - } - } - // pt matching - if (doMatchingPt) { - MatchPt(jetsBasePerColl, jetsTagPerColl, baseToTagPt, tagToBasePt); - } - } - - // function that fills the jetidTagToBase vectors, where the vector that is the i-th entry (corresponding to the tag jet with global index i) sees added to itself the global index of the matched base jet - template - void fillJetIdArraysTagToBase(T const& jetsBasePerColl, U const& jetsTagPerColl, std::vector const& tagToBaseGeo, std::vector const& tagToBasePt, std::vector const& tagToBaseHF) - { - int geojetidTemp; - int ptjetidTemp; - int hfjetidTemp; - std::vector geojetidTempVector; - std::vector ptjetidTempVector; - std::vector hfjetidTempVector; - for (const auto& jet : jetsTagPerColl) { - geojetidTemp = tagToBaseGeo[jet.index()]; - if (geojetidTemp > -1 && geojetidTemp < jetsBasePerColl.size()) { - geojetidTemp = jetsBasePerColl.iteratorAt(geojetidTemp).globalIndex(); - geojetidTagToBase[jet.globalIndex()].push_back(geojetidTemp); - } else { - geojetidTemp = -1; - } - // Pt matching - ptjetidTemp = tagToBasePt[jet.index()]; - if (ptjetidTemp > -1 && ptjetidTemp < jetsBasePerColl.size()) { - ptjetidTemp = jetsBasePerColl.iteratorAt(ptjetidTemp).globalIndex(); - ptjetidTagToBase[jet.globalIndex()].push_back(ptjetidTemp); - } else { - ptjetidTemp = -1; - } - // HF matching - hfjetidTemp = tagToBaseHF[jet.index()]; - if (hfjetidTemp > -1 && hfjetidTemp < jetsBasePerColl.size()) { - hfjetidTemp = jetsBasePerColl.iteratorAt(hfjetidTemp).globalIndex(); - hfjetidTagToBase[jet.globalIndex()].push_back(hfjetidTemp); - } - LOGF(debug, "registering matches for tag jet %d (%d): geo -> %d (%d), pT -> %d (%d), HF -> %d", - jet.index(), jet.globalIndex(), geojetidTemp, tagToBaseGeo[jet.index()], ptjetidTemp, tagToBasePt[jet.index()], tagToBaseHF[jet.index()]); - } - } - - // function that fills the jetidBaseToTag vectors, where the vector that is the i-th entry (corresponding to the base jet with global index i) sees added to itself the global index of the matched tag jet - template - void fillJetIdArraysBaseToTag(T const& jetsBasePerColl, U const& jetsTagPerColl, std::vector const& baseToTagGeo, std::vector const& baseToTagPt, std::vector const& baseToTagHF) - { - int geojetidTemp; - int ptjetidTemp; - int hfjetidTemp; - std::vector geojetidTempVector; - std::vector ptjetidTempVector; - std::vector hfjetidTempVector; - for (const auto& jet : jetsBasePerColl) { - geojetidTemp = baseToTagGeo[jet.index()]; - if (geojetidTemp > -1 && geojetidTemp < jetsTagPerColl.size()) { - geojetidTemp = jetsTagPerColl.iteratorAt(geojetidTemp).globalIndex(); - geojetidBaseToTag[jet.globalIndex()].push_back(geojetidTemp); - } else { - geojetidTemp = -1; - } - // Pt matching - ptjetidTemp = baseToTagPt[jet.index()]; - if (ptjetidTemp > -1 && ptjetidTemp < jetsTagPerColl.size()) { - ptjetidTemp = jetsTagPerColl.iteratorAt(ptjetidTemp).globalIndex(); - ptjetidBaseToTag[jet.globalIndex()].push_back(ptjetidTemp); - } - // HF matching - hfjetidTemp = baseToTagHF[jet.index()]; - if (hfjetidTemp > -1 && hfjetidTemp < jetsTagPerColl.size()) { - hfjetidTemp = jetsTagPerColl.iteratorAt(hfjetidTemp).globalIndex(); - hfjetidBaseToTag[jet.globalIndex()].push_back(hfjetidTemp); - } - LOGF(debug, "registering matches for base jet %d (%d): geo -> %d (%d), pT -> %d (%d), HF -> %d", - jet.index(), jet.globalIndex(), geojetidTemp, baseToTagGeo[jet.index()], ptjetidTemp, baseToTagPt[jet.index()], baseToTagHF[jet.index()]); - } - } - - void processDummy(aod::JMcCollisions const& mcCollisions) - { - } - PROCESS_SWITCH(JetMatching, processDummy, "Dummy process", true); - - // for now: - // the input file must have MC information to check collision<->mcCollision - // for HF tagging: both BaseJetCollection and TagJetCollection must have MC info - // for pT tagging: at least either one of BaseJetCollection or TagJetCollection must have MC info - // for geo tagging: no need to access MC info of either BaseJetCollection or TagJetCollection - void processJets(aod::JMcCollisions const& mcCollisions, JetCollisions const& collisions, - BaseJetCollection const& jetsBase, TagJetCollection const& jetsTag, McParticles const& particlesMC, - JetTracks const& tracks, HfCandidates const& hfcandidates) - { - - // waiting for framework fix to make sliced collection of same type as original collection: - geojetidBaseToTag.assign(jetsBase.size(), {}); - ptjetidBaseToTag.assign(jetsBase.size(), {}); - hfjetidBaseToTag.assign(jetsBase.size(), {}); - geojetidTagToBase.assign(jetsTag.size(), {}); - ptjetidTagToBase.assign(jetsTag.size(), {}); - hfjetidTagToBase.assign(jetsTag.size(), {}); - - for (const auto& mcCollision : mcCollisions) { - - const auto collisionsPerMcColl = collisions.sliceBy(CollisionsCollectionPerMcCollision, mcCollision.globalIndex()); - - int i_collision = 0; - for (const auto& collision : collisionsPerMcColl) { - ++i_collision; - - const auto jetsBasePerColl = jetsBase.sliceBy(baseJetsPerCollision, jetsBaseIsMC ? mcCollision.globalIndex() : collision.globalIndex()); - const auto jetsTagPerColl = jetsTag.sliceBy(tagJetsPerCollision, jetsTagIsMC ? mcCollision.globalIndex() : collision.globalIndex()); - - // mini jet matching tables for the collection of jets from the current mcCollision (if mcp jet) or collision (if mcd or data jet) - std::vector baseToTagGeo(jetsBasePerColl.size(), -1), baseToTagHF(jetsBasePerColl.size(), -1), baseToTagPt(jetsBasePerColl.size(), -1); - std::vector tagToBaseGeo(jetsTagPerColl.size(), -1), tagToBaseHF(jetsTagPerColl.size(), -1), tagToBasePt(jetsTagPerColl.size(), -1); - - LOGF(debug, "performing geometric matching for mcCollision %d and collision %d (%d / %d jets)", - mcCollision.globalIndex(), collision.globalIndex(), jetsBasePerColl.size(), jetsTagPerColl.size()); - - doAllMatching(jetsBasePerColl, jetsTagPerColl, baseToTagGeo, baseToTagHF, baseToTagPt, tagToBaseGeo, tagToBaseHF, tagToBasePt); - - // time to fill the tables - if (i_collision == 1) { // do this once regardless; if both tag and base are MC, or if one is MC and the other is not and there is no split vertex: it's the only iteration - fillJetIdArraysBaseToTag(jetsBasePerColl, jetsTagPerColl, baseToTagGeo, baseToTagPt, baseToTagHF); - fillJetIdArraysTagToBase(jetsBasePerColl, jetsTagPerColl, tagToBaseGeo, tagToBasePt, tagToBaseHF); - } - if (i_collision > 1) { // collision is split - if (!jetsBaseIsMC || !jetsTagIsMC) { // if both are MC, allowing those two lines below to happen would make duplicates in the matching table; this is why thie i_collision>1 case is not treated the same way as the i_collision==1 case - fillJetIdArraysBaseToTag(jetsBasePerColl, jetsTagPerColl, baseToTagGeo, baseToTagPt, baseToTagHF); - fillJetIdArraysTagToBase(jetsBasePerColl, jetsTagPerColl, tagToBaseGeo, tagToBasePt, tagToBaseHF); - } - } - } - } - for (std::size_t i = 0; i < jetsTag.size(); i++) { - jetsTagToBase(geojetidTagToBase[i], ptjetidTagToBase[i], hfjetidTagToBase[i]); // is (and needs to) be filled in order - } - for (std::size_t i = 0; i < jetsBase.size(); ++i) { - jetsBaseToTag(geojetidBaseToTag[i], ptjetidBaseToTag[i], hfjetidBaseToTag[i]); // is (and needs to) be filled in order - } - } - PROCESS_SWITCH(JetMatching, processJets, "Perform jet matching", false); -}; - -using ChargedJetMatching = JetMatching, - soa::Join, - aod::ChargedMCDetectorLevelJetsMatchedToChargedMCParticleLevelJets, - aod::ChargedMCParticleLevelJetsMatchedToChargedMCDetectorLevelJets, - aod::JMcParticles, - aod::JDummys>; -using D0ChargedJetMatching = JetMatching, - soa::Join, - aod::D0ChargedMCDetectorLevelJetsMatchedToD0ChargedMCParticleLevelJets, - aod::D0ChargedMCParticleLevelJetsMatchedToD0ChargedMCDetectorLevelJets, - soa::Join, - soa::Join>; -using LcChargedJetMatching = JetMatching, - soa::Join, - aod::LcChargedMCDetectorLevelJetsMatchedToLcChargedMCParticleLevelJets, - aod::LcChargedMCParticleLevelJetsMatchedToLcChargedMCDetectorLevelJets, - soa::Join, - soa::Join>; -using BplusChargedJetMatching = JetMatching, - soa::Join, - aod::BplusChargedMCDetectorLevelJetsMatchedToBplusChargedMCParticleLevelJets, - aod::BplusChargedMCParticleLevelJetsMatchedToBplusChargedMCDetectorLevelJets, - soa::Join, - soa::Join>; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - std::vector tasks; - - tasks.emplace_back(adaptAnalysisTask(cfgc, SetDefaultProcesses{}, TaskName{"jet-matching-ch"})); - tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-matching-d0-ch"})); - tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-matching-lc-ch"})); - tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-matching-bplus-ch"})); - - return WorkflowSpec{tasks}; -} diff --git a/PWGJE/TableProducer/jetmatchingmc.cxx b/PWGJE/TableProducer/jetmatchingmc.cxx new file mode 100644 index 00000000000..cb7cdc014d8 --- /dev/null +++ b/PWGJE/TableProducer/jetmatchingmc.cxx @@ -0,0 +1,143 @@ +// 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 jetmatchingmc.cxx +/// \brief matching detector level and generator level jets +/// +/// \author Raymond Ehlers , ORNL +/// \author Jochen Klein +/// \author Aimeric Lanodu +/// \author Nima Zardoshti + +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoA.h" +#include "Framework/runDataProcessing.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/Core/JetUtilities.h" +#include "PWGJE/Core/JetFindingUtilities.h" +#include "PWGJE/Core/JetMatchingUtilities.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +template +struct JetMatchingMc { + + Configurable doMatchingGeo{"doMatchingGeo", true, "Enable geometric matching"}; + Configurable doMatchingPt{"doMatchingPt", true, "Enable pt matching"}; + Configurable doMatchingHf{"doMatchingHf", false, "Enable HF matching"}; + Configurable maxMatchingDistance{"maxMatchingDistance", 0.24f, "Max matching distance"}; + Configurable minPtFraction{"minPtFraction", 0.5f, "Minimum pt fraction for pt matching"}; + + Produces jetsBasetoTagMatchingTable; + Produces jetsTagtoBaseMatchingTable; + + // preslicing jet collections, only for Mc-based collection + static constexpr bool jetsBaseIsMc = o2::soa::relatedByIndex(); + static constexpr bool jetsTagIsMc = o2::soa::relatedByIndex(); + + Preslice baseJetsPerCollision = jetsBaseIsMc ? aod::jet::mcCollisionId : aod::jet::collisionId; + Preslice tagJetsPerCollision = jetsTagIsMc ? aod::jet::mcCollisionId : aod::jet::collisionId; + + PresliceUnsorted CollisionsPerMcCollision = aod::jmccollisionlb::mcCollisionId; + + void init(InitContext const&) + { + } + + void processDummy(JetMcCollisions const& mcCollisions) + { + } + PROCESS_SWITCH(JetMatchingMc, processDummy, "Dummy process", true); + + void processJets(JetMcCollisions const& mcCollisions, JetCollisionsMCD const& collisions, + JetsBase const& jetsBase, JetsTag const& jetsTag, + JetTracksMCD const& tracks, + JetParticles const& particles, + CandidatesBase const& candidatesBase, + CandidatesTag const& candidatesTag) + { + + // initialise objects used to store the matching index arrays (array in case a mcCollision is split) before filling the matching tables + std::vector> jetsBasetoTagMatchingGeo, jetsBasetoTagMatchingPt, jetsBasetoTagMatchingHF; + std::vector> jetsTagtoBaseMatchingGeo, jetsTagtoBaseMatchingPt, jetsTagtoBaseMatchingHF; + // waiting for framework fix to make sliced collection of same type as original collection: + jetsBasetoTagMatchingGeo.assign(jetsBase.size(), {}); + jetsBasetoTagMatchingPt.assign(jetsBase.size(), {}); + jetsBasetoTagMatchingHF.assign(jetsBase.size(), {}); + jetsTagtoBaseMatchingGeo.assign(jetsTag.size(), {}); + jetsTagtoBaseMatchingPt.assign(jetsTag.size(), {}); + jetsTagtoBaseMatchingHF.assign(jetsTag.size(), {}); + + for (const auto& mcCollision : mcCollisions) { + + const auto collisionsPerMcColl = collisions.sliceBy(CollisionsPerMcCollision, mcCollision.globalIndex()); + + for (const auto& collision : collisionsPerMcColl) { + + const auto jetsBasePerColl = jetsBase.sliceBy(baseJetsPerCollision, jetsBaseIsMc ? mcCollision.globalIndex() : collision.globalIndex()); + const auto jetsTagPerColl = jetsTag.sliceBy(tagJetsPerCollision, jetsTagIsMc ? mcCollision.globalIndex() : collision.globalIndex()); + + jetmatchingutilities::doAllMatching(jetsBasePerColl, jetsTagPerColl, jetsBasetoTagMatchingGeo, jetsBasetoTagMatchingPt, jetsBasetoTagMatchingHF, jetsTagtoBaseMatchingGeo, jetsTagtoBaseMatchingPt, jetsTagtoBaseMatchingHF, candidatesBase, candidatesTag, tracks, particles, doMatchingGeo, doMatchingHf, doMatchingPt, maxMatchingDistance, minPtFraction); + } + } + for (auto i = 0; i < jetsBase.size(); ++i) { + jetsBasetoTagMatchingTable(jetsBasetoTagMatchingGeo[i], jetsBasetoTagMatchingPt[i], jetsBasetoTagMatchingHF[i]); // is (and needs to) be filled in order + } + for (auto i = 0; i < jetsTag.size(); i++) { + jetsTagtoBaseMatchingTable(jetsTagtoBaseMatchingGeo[i], jetsTagtoBaseMatchingPt[i], jetsTagtoBaseMatchingHF[i]); // is (and needs to) be filled in order + } + } + PROCESS_SWITCH(JetMatchingMc, processJets, "Perform jet matching", false); +}; + +using ChargedJetMatching = JetMatchingMc, + soa::Join, + aod::ChargedMCDetectorLevelJetsMatchedToChargedMCParticleLevelJets, + aod::ChargedMCParticleLevelJetsMatchedToChargedMCDetectorLevelJets, + aod::JCollisions, + aod::JMcCollisions>; +using D0ChargedJetMatching = JetMatchingMc, + soa::Join, + aod::D0ChargedMCDetectorLevelJetsMatchedToD0ChargedMCParticleLevelJets, + aod::D0ChargedMCParticleLevelJetsMatchedToD0ChargedMCDetectorLevelJets, + CandidatesD0MCD, + CandidatesD0MCP>; +/*using LcChargedJetMatching = JetMatchingMc, + soa::Join, + aod::LcChargedMCDetectorLevelJetsMatchedToLcChargedMCParticleLevelJets, + aod::LcChargedMCParticleLevelJetsMatchedToLcChargedMCDetectorLevelJets, + CandidatesLcMCD, + CandidatesLcMCP>; +using BplusChargedJetMatching = JetMatchingMc, + soa::Join, + aod::BplusChargedMCDetectorLevelJetsMatchedToBplusChargedMCParticleLevelJets, + aod::BplusChargedMCParticleLevelJetsMatchedToBplusChargedMCDetectorLevelJets, + CandidatesBplusMCD, + CandidatesBplusMCP>;*/ + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + + tasks.emplace_back(adaptAnalysisTask(cfgc, SetDefaultProcesses{}, TaskName{"jet-matching-mc-ch"})); + tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-matching-mc-d0-ch"})); + // tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-matching-mc-lc-ch"})); + // tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-matching-mc-bplus-ch"})); + + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/TableProducer/jetmatchingmcsub.cxx b/PWGJE/TableProducer/jetmatchingmcsub.cxx new file mode 100644 index 00000000000..734e971db94 --- /dev/null +++ b/PWGJE/TableProducer/jetmatchingmcsub.cxx @@ -0,0 +1,128 @@ +// 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 jetmatchingmcsub.cxx +/// \brief matching event-wise constituent subtracted detector level and unsubtracted generated level jets (this is usseful as a template for embedding matching) +/// \author Nima Zardoshti + +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoA.h" +#include "Framework/runDataProcessing.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/Core/JetUtilities.h" +#include "PWGJE/Core/JetFindingUtilities.h" +#include "PWGJE/Core/JetMatchingUtilities.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +template +struct JetMatchingMcSub { + + Configurable doMatchingGeo{"doMatchingGeo", true, "Enable geometric matching"}; + Configurable doMatchingPt{"doMatchingPt", true, "Enable pt matching"}; + Configurable doMatchingHf{"doMatchingHf", false, "Enable HF matching"}; + Configurable maxMatchingDistance{"maxMatchingDistance", 0.24f, "Max matching distance"}; + Configurable minPtFraction{"minPtFraction", 0.5f, "Minimum pt fraction for pt matching"}; + + Produces jetsBasetoTagMatchingTable; + Produces jetsTagtoBaseMatchingTable; + + // preslicing jet collections, only for Mc-based collection + static constexpr bool jetsBaseIsMc = false; + static constexpr bool jetsTagIsMc = false; + + Preslice baseJetsPerCollision = aod::jet::collisionId; + Preslice tagJetsPerCollision = aod::jet::collisionId; + + void init(InitContext const&) + { + } + + void processDummy(JetCollisions const& mcCollisions) + { + } + PROCESS_SWITCH(JetMatchingMcSub, processDummy, "Dummy process", true); + + void processJets(JetCollisions const& collisions, + JetsBase const& jetsBase, JetsTag const& jetsTag, + JetTracks const& tracks, + JetTracksSub const& tracksSub, + Candidates const& candidates) + { + + // initialise objects used to store the matching index arrays (array in case a mcCollision is split) before filling the matching tables + std::vector> jetsBasetoTagMatchingGeo, jetsBasetoTagMatchingPt, jetsBasetoTagMatchingHF; + std::vector> jetsTagtoBaseMatchingGeo, jetsTagtoBaseMatchingPt, jetsTagtoBaseMatchingHF; + // waiting for framework fix to make sliced collection of same type as original collection: + jetsBasetoTagMatchingGeo.assign(jetsBase.size(), {}); + jetsBasetoTagMatchingPt.assign(jetsBase.size(), {}); + jetsBasetoTagMatchingHF.assign(jetsBase.size(), {}); + jetsTagtoBaseMatchingGeo.assign(jetsTag.size(), {}); + jetsTagtoBaseMatchingPt.assign(jetsTag.size(), {}); + jetsTagtoBaseMatchingHF.assign(jetsTag.size(), {}); + + for (const auto& collision : collisions) { + + const auto jetsBasePerColl = jetsBase.sliceBy(baseJetsPerCollision, collision.globalIndex()); + const auto jetsTagPerColl = jetsTag.sliceBy(tagJetsPerCollision, collision.globalIndex()); + + jetmatchingutilities::doAllMatching(jetsBasePerColl, jetsTagPerColl, jetsBasetoTagMatchingGeo, jetsBasetoTagMatchingPt, jetsBasetoTagMatchingHF, jetsTagtoBaseMatchingGeo, jetsTagtoBaseMatchingPt, jetsTagtoBaseMatchingHF, candidates, candidates, tracks, tracksSub, doMatchingGeo, doMatchingHf, doMatchingPt, maxMatchingDistance, minPtFraction); + } + + for (auto i = 0; i < jetsBase.size(); ++i) { + jetsBasetoTagMatchingTable(jetsBasetoTagMatchingGeo[i], jetsBasetoTagMatchingPt[i], jetsBasetoTagMatchingHF[i]); // is (and needs to) be filled in order + } + for (auto i = 0; i < jetsTag.size(); i++) { + jetsTagtoBaseMatchingTable(jetsTagtoBaseMatchingGeo[i], jetsTagtoBaseMatchingPt[i], jetsTagtoBaseMatchingHF[i]); // is (and needs to) be filled in order + } + } + PROCESS_SWITCH(JetMatchingMcSub, processJets, "Perform jet matching", false); +}; + +using ChargedJetMatching = JetMatchingMcSub, + soa::Join, + aod::ChargedMCDetectorLevelJetsMatchedToChargedMCDetectorLevelEventWiseSubtractedJets, + aod::ChargedMCDetectorLevelEventWiseSubtractedJetsMatchedToChargedMCDetectorLevelJets, + aod::JDummys>; +using D0ChargedJetMatching = JetMatchingMcSub, + soa::Join, + aod::D0ChargedMCDetectorLevelJetsMatchedToD0ChargedMCDetectorLevelEventWiseSubtractedJets, + aod::D0ChargedMCDetectorLevelEventWiseSubtractedJetsMatchedToD0ChargedMCDetectorLevelJets, + CandidatesD0MCD>; +/*using LcChargedJetMatching = JetMatchingMcSub, + soa::Join, + aod::LcChargedMCDetectorLevelJetsMatchedToLcChargedMCDetectorLevelEventWiseSubtractedJets, + aod::LcChargedMCDetectorLevelEventWiseSubtractedJetsMatchedToLcChargedMCDetectorLevelJets, + CandidatesLcMCD>; +using BplusChargedJetMatching = JetMatchingMcSub, + soa::Join, + aod::BplusChargedMCDetectorLevelJetsMatchedToBplusChargedMCDetectorLevelEventWiseSubtractedJets, + aod::BplusChargedMCDetectorLevelEventWiseSubtractedJetsMatchedToBplusChargedMCDetectorLevelJets, + CandidatesBplusMCD>;*/ + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + + tasks.emplace_back(adaptAnalysisTask(cfgc, SetDefaultProcesses{}, TaskName{"jet-matching-mc-sub-ch"})); + tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-matching-mc-sub-d0-ch"})); + // tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-matching-mc-sub-lc-ch"})); + // tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-matching-mc-sub-bplus-ch"})); + + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/TableProducer/jetmatchingsub.cxx b/PWGJE/TableProducer/jetmatchingsub.cxx new file mode 100644 index 00000000000..85cc453a540 --- /dev/null +++ b/PWGJE/TableProducer/jetmatchingsub.cxx @@ -0,0 +1,130 @@ +// 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 jetmatching.cxx +/// \brief matching event-wise constituent subtracted data jets and unsubtracted data jets +/// \author Nima Zardoshti + +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoA.h" +#include "Framework/runDataProcessing.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "PWGJE/DataModel/Jet.h" +#include "PWGJE/Core/JetUtilities.h" +#include "PWGJE/Core/JetFindingUtilities.h" +#include "PWGJE/Core/JetMatchingUtilities.h" +#include "PWGHF/DataModel/CandidateSelectionTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +template +struct JetMatchingSub { + + Configurable doMatchingGeo{"doMatchingGeo", true, "Enable geometric matching"}; + Configurable doMatchingPt{"doMatchingPt", true, "Enable pt matching"}; + Configurable doMatchingHf{"doMatchingHf", false, "Enable HF matching"}; + Configurable maxMatchingDistance{"maxMatchingDistance", 0.24f, "Max matching distance"}; + Configurable minPtFraction{"minPtFraction", 0.5f, "Minimum pt fraction for pt matching"}; + + Produces jetsBasetoTagMatchingTable; + Produces jetsTagtoBaseMatchingTable; + + // preslicing jet collections, only for Mc-based collection + static constexpr bool jetsBaseIsMc = o2::soa::relatedByIndex(); + static constexpr bool jetsTagIsMc = o2::soa::relatedByIndex(); + + Preslice baseJetsPerCollision = jetsBaseIsMc ? aod::jet::mcCollisionId : aod::jet::collisionId; + Preslice tagJetsPerCollision = jetsTagIsMc ? aod::jet::mcCollisionId : aod::jet::collisionId; + + void init(InitContext const&) + { + } + + void processDummy(JetCollisions const& collisions) + { + } + PROCESS_SWITCH(JetMatchingSub, processDummy, "Dummy process", true); + + void processJets(JetCollisions const& collisions, + JetsBase const& jetsBase, JetsTag const& jetsTag, + JetTracks const& tracks, TracksTag const& tracksSub, Candidates const& candidates) + { + + // initialise objects used to store the matching index arrays (array in case a mcCollision is split) before filling the matching tables + std::vector> jetsBasetoTagMatchingGeo, jetsBasetoTagMatchingPt, jetsBasetoTagMatchingHF; + std::vector> jetsTagtoBaseMatchingGeo, jetsTagtoBaseMatchingPt, jetsTagtoBaseMatchingHF; + // waiting for framework fix to make sliced collection of same type as original collection: + jetsBasetoTagMatchingGeo.assign(jetsBase.size(), {}); + jetsBasetoTagMatchingPt.assign(jetsBase.size(), {}); + jetsBasetoTagMatchingHF.assign(jetsBase.size(), {}); + jetsTagtoBaseMatchingGeo.assign(jetsTag.size(), {}); + jetsTagtoBaseMatchingPt.assign(jetsTag.size(), {}); + jetsTagtoBaseMatchingHF.assign(jetsTag.size(), {}); + + for (const auto& collision : collisions) { + + const auto jetsBasePerColl = jetsBase.sliceBy(baseJetsPerCollision, collision.globalIndex()); + const auto jetsTagPerColl = jetsTag.sliceBy(tagJetsPerCollision, collision.globalIndex()); + + jetmatchingutilities::doAllMatching(jetsBasePerColl, jetsTagPerColl, jetsBasetoTagMatchingGeo, jetsBasetoTagMatchingPt, jetsBasetoTagMatchingHF, jetsTagtoBaseMatchingGeo, jetsTagtoBaseMatchingPt, jetsTagtoBaseMatchingHF, candidates, candidates, tracks, tracksSub, doMatchingGeo, doMatchingHf, doMatchingPt, maxMatchingDistance, minPtFraction); + } + + for (auto i = 0; i < jetsBase.size(); ++i) { + jetsBasetoTagMatchingTable(jetsBasetoTagMatchingGeo[i], jetsBasetoTagMatchingPt[i], jetsBasetoTagMatchingHF[i]); // is (and needs to) be filled in order + } + for (auto i = 0; i < jetsTag.size(); i++) { + jetsTagtoBaseMatchingTable(jetsTagtoBaseMatchingGeo[i], jetsTagtoBaseMatchingPt[i], jetsTagtoBaseMatchingHF[i]); // is (and needs to) be filled in order + } + } + PROCESS_SWITCH(JetMatchingSub, processJets, "Perform jet matching", false); +}; + +using ChargedJetMatching = JetMatchingSub, + soa::Join, + aod::ChargedJetsMatchedToChargedEventWiseSubtractedJets, + aod::ChargedEventWiseSubtractedJetsMatchedToChargedJets, + aod::JTrackSubs, + aod::JDummys>; +using D0ChargedJetMatching = JetMatchingSub, + soa::Join, + aod::D0ChargedJetsMatchedToD0ChargedEventWiseSubtractedJets, + aod::D0ChargedEventWiseSubtractedJetsMatchedToD0ChargedJets, + aod::JTrackD0Subs, + CandidatesD0Data>; +/*using LcChargedJetMatching = JetMatchingSub, + soa::Join, + aod::LcChargedJetsMatchedToLcChargedEventWiseSubtractedJets, + aod::LcChargedEventWiseSubtractedJetsMatchedToLcChargedJets, + aod::JTrackLcSubs, + CandidatesLcData>; +using BplusChargedJetMatching = JetMatchingSub, + soa::Join, + aod::BplusChargedJetsMatchedToBplusChargedEventWiseSubtractedJets, + aod::BplusChargedEventWiseSubtractedJetsMatchedToBplusChargedJets, + aod::JTrackBplusSubs, + CandidatesBplusData>;*/ + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + std::vector tasks; + + tasks.emplace_back(adaptAnalysisTask(cfgc, SetDefaultProcesses{}, TaskName{"jet-matching-sub-ch"})); + tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-matching-sub-d0-ch"})); + // tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-matching-sub-lc-ch"})); + // tasks.emplace_back(adaptAnalysisTask(cfgc, TaskName{"jet-matching-sub-bplus-ch"})); + + return WorkflowSpec{tasks}; +} diff --git a/PWGJE/TableProducer/jettaggerhf.cxx b/PWGJE/TableProducer/jettaggerhf.cxx index d929187ef3c..da941c4825b 100644 --- a/PWGJE/TableProducer/jettaggerhf.cxx +++ b/PWGJE/TableProducer/jettaggerhf.cxx @@ -39,37 +39,37 @@ struct JetTaggerHFTask { Configurable doAlgorithm3{"doAlgorithm3", false, "fill table for algoithm 3"}; Configurable maxDeltaR{"maxDeltaR", 0.25, "maximum distance of jet axis from flavour initiating parton"}; - void processDummy(aod::Collision const& collision) + void processDummy(JetCollisions const& collision) { } PROCESS_SWITCH(JetTaggerHFTask, processDummy, "Dummy process", true); - void processData(aod::JCollision const& collision, JetTableData const& jets, aod::JTracks const& tracks) + void processData(JetCollision const& collision, JetTableData const& jets, aod::JTracks const& tracks) { for (auto& jet : jets) { int algorithm1 = jet.globalIndex(); // This needs to be changed. It is only done because O2Physics compilation breaks if jet is unused int algorithm2 = 0; int algorithm3 = 0; - // if (doAlgorithm1) algorithm1 = JetTaggingUtilities::Algorithm1((mcdjet, tracks); - // if (doAlgorithm2) algorithm2 = JetTaggingUtilities::Algorithm2((mcdjet, tracks); - // if (doAlgorithm3) algorithm3 = JetTaggingUtilities::Algorithm3((mcdjet, tracks); + // if (doAlgorithm1) algorithm1 = jettaggingutilities::Algorithm1((mcdjet, tracks); + // if (doAlgorithm2) algorithm2 = jettaggingutilities::Algorithm2((mcdjet, tracks); + // if (doAlgorithm3) algorithm3 = jettaggingutilities::Algorithm3((mcdjet, tracks); taggingTableData(0, algorithm1, algorithm2, algorithm3); } } PROCESS_SWITCH(JetTaggerHFTask, processData, "Fill tagging decision for data jets", false); - void processMCD(aod::JCollision const& collision, JetTableMCD const& mcdjets, soa::Join const& tracks, aod::JMcParticles const& particles) + void processMCD(JetCollision const& collision, JetTableMCD const& mcdjets, JetTracksMCD const& tracks, JetParticles const& particles) { for (auto& mcdjet : mcdjets) { - int origin = JetTaggingUtilities::mcdJetFromHFShower(mcdjet, tracks, particles, maxDeltaR); + int origin = jettaggingutilities::mcdJetFromHFShower(mcdjet, tracks, particles, maxDeltaR); int algorithm1 = 0; int algorithm2 = 0; int algorithm3 = 0; - // if (doAlgorithm1) algorithm1 = JetTaggingUtilities::Algorithm1((mcdjet, tracks); - // if (doAlgorithm2) algorithm2 = JetTaggingUtilities::Algorithm2((mcdjet, tracks); - // if (doAlgorithm3) algorithm3 = JetTaggingUtilities::Algorithm3((mcdjet, tracks); + // if (doAlgorithm1) algorithm1 = jettaggingutilities::Algorithm1((mcdjet, tracks); + // if (doAlgorithm2) algorithm2 = jettaggingutilities::Algorithm2((mcdjet, tracks); + // if (doAlgorithm3) algorithm3 = jettaggingutilities::Algorithm3((mcdjet, tracks); taggingTableMCD(origin, algorithm1, algorithm2, algorithm3); } } diff --git a/PWGJE/TableProducer/jettrackderived.cxx b/PWGJE/TableProducer/jettrackderived.cxx index 923881c963b..827ec6c1c15 100644 --- a/PWGJE/TableProducer/jettrackderived.cxx +++ b/PWGJE/TableProducer/jettrackderived.cxx @@ -48,7 +48,7 @@ struct jetspectraDerivedMaker { // Custom track cuts for the cut variation study TrackSelection customTrackCuts; - Configurable itsPattern{"itsPattern", 1, "0 = Run3ITSibAny, 1 = Run3ITSallAny, 2 = Run3ITSall7Layers, 3 = Run3ITSibTwo"}; + Configurable itsPattern{"itsPattern", 2, "0 = Run3ITSibAny, 1 = Run3ITSibTwo, 2 = Run3ITSallAny, 3 = Run3ITSall7Layers"}; Configurable requireITS{"requireITS", true, "Additional cut on the ITS requirement"}; Configurable requireTPC{"requireTPC", true, "Additional cut on the TPC requirement"}; Configurable requireGoldenChi2{"requireGoldenChi2", true, "Additional cut on the GoldenChi2"}; @@ -56,8 +56,7 @@ struct jetspectraDerivedMaker { Configurable minNCrossedRowsOverFindableClustersTPC{"minNCrossedRowsOverFindableClustersTPC", 0.7f, "Additional cut on the minimum value of the ratio between crossed rows and findable clusters in the TPC"}; Configurable maxChi2PerClusterTPC{"maxChi2PerClusterTPC", 7.f, "Additional cut on the maximum value of the chi2 per cluster in the TPC"}; Configurable maxChi2PerClusterITS{"maxChi2PerClusterITS", 36.f, "Additional cut on the maximum value of the chi2 per cluster in the ITS"}; - Configurable maxDcaXYFactor{"maxDcaXYFactor", 1.f, "Additional cut on the maximum value of the DCA xy (multiplicative factor)"}; - Configurable maxDcaXY{"maxDcaXY", 3.f, "Additional cut on the maximum value of the DCA xy"}; + Configurable maxDcaXY{"maxDcaXY", 0.25f, "Cut on the maximum value of the DCA xy "}; Configurable maxDcaZ{"maxDcaZ", 3.f, "Additional cut on the maximum value of the DCA z"}; Configurable minTPCNClsFound{"minTPCNClsFound", 0.f, "Additional cut on the minimum value of the number of found clusters in the TPC"}; @@ -79,8 +78,8 @@ struct jetspectraDerivedMaker { LOG(info) << "\tminTPCNClsFound=" << minTPCNClsFound.value; LOG(info) << "\tmaxChi2PerClusterITS=" << maxChi2PerClusterITS.value; LOG(info) << "\tRequireHitsInITSLayers=" << maxChi2PerClusterITS.value; - LOG(info) << "\tmaxDcaZ=" << maxDcaZ.value; LOG(info) << "\tmaxDcaXY=" << maxDcaXY.value; + LOG(info) << "\tmaxDcaZ=" << maxDcaZ.value; LOG(info) << "\tminPt=" << minPt.value; LOG(info) << "\tmaxPt=" << maxPt.value; LOG(info) << "\tmaxEta=" << ValCutEta.value; @@ -96,17 +95,14 @@ struct jetspectraDerivedMaker { customTrackCuts.SetMaxChi2PerClusterITS(maxChi2PerClusterITS.value); customTrackCuts.SetMinNCrossedRowsTPC(minNCrossedRowsTPC.value); customTrackCuts.SetMinNClustersTPC(minTPCNClsFound.value); - // customTrackCuts.SetRequireHitsInITSLayers(nHits.value, {0, 1}); // one hit in any SPD layer (#hits, {layer0, layer1,...}) -> Defaults (1, {0, 1}) + // customTrackCuts.SetRequireHitsInITSLayers(nHits.value, {0, 1}); // one hit in any SPD layer (#hits, {layer0, layer1,...}) customTrackCuts.SetMinNCrossedRowsOverFindableClustersTPC(minNCrossedRowsOverFindableClustersTPC.value); - customTrackCuts.SetMaxDcaXYPtDep([](float pt) { return 1e+10; }); customTrackCuts.SetMaxDcaXY(maxDcaXY.value); customTrackCuts.SetMaxDcaZ(maxDcaZ.value); customTrackCuts.print(); // event property histograms histos.add("EventProp/collisionVtxZ", "Collsion Vertex Z;#it{Vtx}_{z} [cm];number of entries", HistType::kTH1F, {{nBins, -20, 20}}); - histos.add("EventProp/collisionVtxZnoSel", "Collsion Vertex Z without event selection;#it{Vtx}_{z} [cm];number of entries", HistType::kTH1F, {{nBins, -20, 20}}); - histos.add("EventProp/collisionVtxZSel8", "Collsion Vertex Z with event selection;#it{Vtx}_{z} [cm];number of entries", HistType::kTH1F, {{nBins, -20, 20}}); histos.add("EventProp/sampledvertexz", "Sampled collsion Vertex Z with event (sel8) selection;#it{Vtx}_{z} [cm];number of entries", HistType::kTH1F, {{nBins, -20, 20}}); histos.add("EventProp/NumContrib", "Number of contributors to vertex of collision; number of contributors to vtx; number of entries", HistType::kTH1F, {{nBins, 0, 600}}); histos.add("EventProp/rejectedCollId", "CollisionId of collisions that did not pass the event selection; collisionId; number of entries", HistType::kTH1F, {{10, 0, 5}}); @@ -155,55 +151,74 @@ struct jetspectraDerivedMaker { return true; } + Preslice trackPerColl = aod::track::collisionId; Produces tableTrack; + Produces tableColl; using CollisionCandidate = soa::Join; using TrackCandidates = soa::Join; unsigned int randomSeed = 0; void processData(CollisionCandidate const& collisions, - TrackCandidates const& tracks) + TrackCandidates const& tracks, aod::BCs const&) { for (const auto& collision : collisions) { if (!isEventSelected(collision)) { histos.fill(HIST("EventProp/rejectedCollId"), 1); - } - } - tableTrack.reserve(tracks.size()); - for (const auto& trk : tracks) { - if (!customTrackCuts.IsSelected(trk)) { // we fill all tracks that have a collision(rejected or not) and pass this check ! continue; } else { - tableTrack(trk.collisionId(), - trk.trackTime(), - trk.signed1Pt(), trk.eta(), trk.phi(), trk.pt(), - trk.sigma1Pt(), - trk.alpha(), - trk.x(), trk.y(), trk.z(), - trk.snp(), - trk.tgl(), - trk.isPVContributor(), - trk.hasTRD(), - trk.hasITS(), - trk.hasTPC(), - trk.isGlobalTrack(), - trk.isGlobalTrackWoDCA(), - trk.isGlobalTrackWoPtEta(), - trk.flags(), - trk.trackType(), - trk.length(), - trk.tpcChi2NCl(), trk.itsChi2NCl(), trk.tofChi2(), - trk.tpcNClsShared(), - trk.tpcNClsFindable(), - trk.tpcNClsFindableMinusFound(), - trk.tpcNClsFindableMinusCrossedRows(), - trk.itsClusterMap(), - trk.itsNCls(), - trk.tpcFractionSharedCls(), - trk.tpcNClsFound(), - trk.tpcNClsCrossedRows(), - trk.tpcCrossedRowsOverFindableCls(), - trk.tpcFoundOverFindableCls(), - trk.dcaXY(), - trk.dcaZ()); + auto tracksInCollision = tracks.sliceBy(trackPerColl, collision.globalIndex()); + tableColl(collision.globalIndex(), + collision.collisionTime(), + collision.numContrib(), + collision.posX(), + collision.posY(), + collision.posZ(), + collision.sel8(), + tracksInCollision.size(), + collision.multNTracksPV(), + collision.multFT0A(), + collision.multFT0C(), + collision.centFT0A(), + collision.centFT0C(), + collision.bc().runNumber()); + tableTrack.reserve(tracks.size()); + for (const auto& trk : tracksInCollision) { + if (!customTrackCuts.IsSelected(trk)) { + continue; + } else { + tableTrack(trk.collisionId(), + trk.trackTime(), + trk.signed1Pt(), trk.eta(), trk.phi(), trk.pt(), + trk.sigma1Pt(), + trk.alpha(), + trk.x(), trk.y(), trk.z(), + trk.snp(), + trk.tgl(), + trk.isPVContributor(), + trk.hasTRD(), + trk.hasITS(), + trk.hasTPC(), + trk.isGlobalTrack(), + trk.isGlobalTrackWoDCA(), + trk.isGlobalTrackWoPtEta(), + trk.flags(), + trk.trackType(), + trk.length(), + trk.tpcChi2NCl(), trk.itsChi2NCl(), trk.tofChi2(), + trk.tpcNClsShared(), + trk.tpcNClsFindable(), + trk.tpcNClsFindableMinusFound(), + trk.tpcNClsFindableMinusCrossedRows(), + trk.itsClusterMap(), + trk.itsNCls(), + trk.tpcFractionSharedCls(), + trk.tpcNClsFound(), + trk.tpcNClsCrossedRows(), + trk.tpcCrossedRowsOverFindableCls(), + trk.tpcFoundOverFindableCls(), + trk.dcaXY(), + trk.dcaZ()); + } + } } } } diff --git a/PWGJE/TableProducer/rhoEstimator.cxx b/PWGJE/TableProducer/rhoEstimator.cxx index aa9174e898b..dabbbcf08d4 100644 --- a/PWGJE/TableProducer/rhoEstimator.cxx +++ b/PWGJE/TableProducer/rhoEstimator.cxx @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -// Task to produce a table joinable to the collision table with the mean background pT density +// Task to produce a table joinable to the jcollision table with the mean background pT density // /// \author Nima Zardoshti @@ -19,6 +19,7 @@ #include "Framework/O2DatabasePDGPlugin.h" #include "PWGJE/Core/FastJetUtilities.h" +#include "PWGJE/Core/JetFindingUtilities.h" #include "PWGJE/Core/JetDerivedDataUtilities.h" #include "PWGJE/DataModel/Jet.h" #include "PWGJE/Core/JetBkgSubUtils.h" @@ -29,43 +30,98 @@ using namespace o2::framework; using namespace o2::framework::expressions; struct RhoEstimatorTask { - Produces rhoTable; + Produces rhoChargedTable; + Produces rhoD0Table; + Produces rhoLcTable; + Produces rhoBplusTable; + Configurable trackPtMin{"trackPtMin", 0.15, "minimum track pT"}; + Configurable trackPtMax{"trackPtMax", 1000.0, "maximum track pT"}; + Configurable trackEtaMin{"trackEtaMin", -0.9, "minimum track eta"}; + Configurable trackEtaMax{"trackEtaMax", 0.9, "maximum track eta"}; + Configurable trackPhiMin{"trackPhiMin", -999, "minimum track phi"}; + Configurable trackPhiMax{"trackPhiMax", 999, "maximum track phi"}; Configurable trackSelections{"trackSelections", "globalTracks", "set track selections"}; + + Configurable selectionFlagD0{"selectionFlagD0", 1, "Selection Flag for D0"}; + Configurable selectionFlagD0bar{"selectionFlagD0bar", 1, "Selection Flag for D0bar"}; + Configurable selectionFlagLcToPKPi{"selectionFlagLcToPKPi", 1, "Selection Flag for Lc->PKPi"}; + Configurable selectionFlagLcToPiPK{"selectionFlagLcToPiPK", 1, "Selection Flag for Lc->PiPK"}; + Configurable selectionFlagBplus{"selectionFlagBplus", 1, "Selection Flag for B+"}; + Configurable bkgjetR{"bkgjetR", 0.2, "jet resolution parameter for determining background density"}; Configurable bkgEtaMin{"bkgEtaMin", -0.9, "minimim pseudorapidity for determining background density"}; Configurable bkgEtaMax{"bkgEtaMax", 0.9, "maximum pseudorapidity for determining background density"}; - Configurable bkgPhiMin{"bkgPhiMin", -99., "minimim phi for determining background density"}; - Configurable bkgPhiMax{"bkgPhiMax", 99., "maximum phi for determining background density"}; + Configurable bkgPhiMin{"bkgPhiMin", 0., "minimim phi for determining background density"}; + Configurable bkgPhiMax{"bkgPhiMax", 99.0, "maximum phi for determining background density"}; Configurable doSparse{"doSparse", false, "perfom sparse estimation"}; JetBkgSubUtils bkgSub; + float bkgPhiMax_; std::vector inputParticles; int trackSelection = -1; void init(o2::framework::InitContext&) { - trackSelection = JetDerivedDataUtilities::initialiseTrackSelection(static_cast(trackSelections)); + trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); bkgSub.setJetBkgR(bkgjetR); bkgSub.setEtaMinMax(bkgEtaMin, bkgEtaMax); - bkgSub.setPhiMinMax(bkgPhiMin, bkgPhiMax); + if (bkgPhiMax > 98.0) { + bkgPhiMax_ = 2.0 * M_PI; + } + bkgSub.setPhiMinMax(bkgPhiMin, bkgPhiMax_); + } + + 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); + + void processChargedCollisions(JetCollision const& collision, soa::Filtered const& tracks) + { + inputParticles.clear(); + jetfindingutilities::analyseTracks, soa::Filtered::iterator>(inputParticles, tracks, trackSelection); + auto [rho, rhoM] = bkgSub.estimateRhoAreaMedian(inputParticles, doSparse); + rhoChargedTable(collision.globalIndex(), rho, rhoM); + } + PROCESS_SWITCH(RhoEstimatorTask, processChargedCollisions, "Fill rho tables for collisions using charged tracks", true); + + void processD0Collisions(JetCollision const& collision, soa::Filtered const& tracks, CandidatesD0Data const& candidates) + { + inputParticles.clear(); + for (auto& candidate : candidates) { + inputParticles.clear(); + jetfindingutilities::analyseTracks(inputParticles, tracks, trackSelection, std::optional{candidate}); + + auto [rho, rhoM] = bkgSub.estimateRhoAreaMedian(inputParticles, doSparse); + rhoD0Table(candidate.globalIndex(), rho, rhoM); + } } + PROCESS_SWITCH(RhoEstimatorTask, processD0Collisions, "Fill rho tables for collisions with D0 candidates", false); - void processCollisions(aod::JCollisions const& collision, aod::JTracks const& tracks) + void processLcCollisions(JetCollision const& collision, soa::Filtered const& tracks, CandidatesLcData const& candidates) { inputParticles.clear(); - for (auto& track : tracks) { - if (!JetDerivedDataUtilities::selectTrack(track, trackSelection)) { - continue; - } - FastJetUtilities::fillTracks(track, inputParticles, track.globalIndex()); + for (auto& candidate : candidates) { + inputParticles.clear(); + jetfindingutilities::analyseTracks(inputParticles, tracks, trackSelection, std::optional{candidate}); + + auto [rho, rhoM] = bkgSub.estimateRhoAreaMedian(inputParticles, doSparse); + rhoLcTable(candidate.globalIndex(), rho, rhoM); } + } + PROCESS_SWITCH(RhoEstimatorTask, processLcCollisions, "Fill rho tables for collisions with Lc candidates", false); - auto [rho, rhoM] = bkgSub.estimateRhoAreaMedian(inputParticles, doSparse); - rhoTable(rho, rhoM); + void processBplusCollisions(JetCollision const& collision, soa::Filtered const& tracks, CandidatesBplusData const& candidates) + { + inputParticles.clear(); + for (auto& candidate : candidates) { + inputParticles.clear(); + jetfindingutilities::analyseTracks(inputParticles, tracks, trackSelection, std::optional{candidate}); + + auto [rho, rhoM] = bkgSub.estimateRhoAreaMedian(inputParticles, doSparse); + rhoBplusTable(candidate.globalIndex(), rho, rhoM); + } } - PROCESS_SWITCH(RhoEstimatorTask, processCollisions, "Fill rho tables for collisions", true); + PROCESS_SWITCH(RhoEstimatorTask, processBplusCollisions, "Fill rho tables for collisions with Bplus candidates", false); }; -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"rho-estimator"})}; } +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"estimator-rho"})}; } diff --git a/PWGJE/Tasks/CMakeLists.txt b/PWGJE/Tasks/CMakeLists.txt index 6534cc97114..fd677e0557e 100644 --- a/PWGJE/Tasks/CMakeLists.txt +++ b/PWGJE/Tasks/CMakeLists.txt @@ -22,6 +22,14 @@ o2physics_add_dpl_workflow(emc-eventselection-qa SOURCES emceventselectionqa.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::EMCALBase O2::EMCALCalib O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(emc-vertexselection-qa + SOURCES emcvertexselectionqa.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::EMCALBase O2::EMCALCalib O2Physics::AnalysisCore + COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(emc-pi0-energyscale-calib + SOURCES emcalPi0EnergyScaleCalib.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::EMCALBase O2::EMCALCalib O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(emc-tmmonitor SOURCES emctmmonitor.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::EMCALBase O2::EMCALCalib O2Physics::AnalysisCore diff --git a/PWGJE/Tasks/ChJetTriggerQATask.cxx b/PWGJE/Tasks/ChJetTriggerQATask.cxx index 0c918c128b5..9cead597449 100644 --- a/PWGJE/Tasks/ChJetTriggerQATask.cxx +++ b/PWGJE/Tasks/ChJetTriggerQATask.cxx @@ -33,10 +33,10 @@ #include "PWGJE/Core/JetFinder.h" #include "PWGJE/Core/FastJetUtilities.h" +#include "PWGJE/Core/JetFindingUtilities.h" #include "PWGJE/Core/JetDerivedDataUtilities.h" #include "PWGJE/DataModel/EMCALClusters.h" #include "PWGJE/DataModel/Jet.h" -#include "PWGJE/TableProducer/jetfinder.h" #include "Framework/HistogramRegistry.h" @@ -103,8 +103,8 @@ struct ChJetTriggerQATask { void init(o2::framework::InitContext&) { fiducialVolume = static_cast(cfgTPCVolume) - static_cast(cfgJetR); - eventSelection = JetDerivedDataUtilities::initialiseEventSelection(static_cast(evSel)); - trackSelection = JetDerivedDataUtilities::initialiseTrackSelection(static_cast(trackSelections)); + eventSelection = jetderiveddatautilities::initialiseEventSelection(static_cast(evSel)); + trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); // Basic histos spectra.add("vertexZ", "z vertex", {HistType::kTH1F, {{400, -20., +20.}}}); @@ -151,19 +151,18 @@ struct ChJetTriggerQATask { Filter jetRadiusSelection = (o2::aod::jet::r == nround(cfgJetR.node() * 100.0f)); using filteredJets = o2::soa::Filtered; - using TrackCandidates = aod::JTracks; void - process(soa::Filtered>::iterator const& collision, - soa::Filtered const& tracks, o2::soa::Filtered> const& jets) + soa::Filtered const& tracks, o2::soa::Filtered> const& jets) { - if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } - if ((bLowPtTrigger && JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow)) || (bHighPtTrigger && JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) || ((!bLowPtTrigger) && (!bHighPtTrigger))) { + if ((bLowPtTrigger && jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow)) || (bHighPtTrigger && jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) || ((!bLowPtTrigger) && (!bHighPtTrigger))) { // bLowPtTrigger=1 and bHighPtTrigger=0 --> fill histos with low trigger only // bLowPtTrigger=0 and bHighPtTrigger=1 --> fill histos with high trigger only // bLowPtTrigger=1 and bHighPtTrigger=1 --> fill histos with mixture of low and high trigger @@ -186,7 +185,7 @@ struct ChJetTriggerQATask { for (auto& trk : tracks) { // loop over filtered tracks in full TPC volume having pT > 100 MeV - if (!JetDerivedDataUtilities::selectTrack(trk, trackSelection)) { + if (!jetderiveddatautilities::selectTrack(trk, trackSelection)) { continue; } @@ -243,7 +242,7 @@ struct ChJetTriggerQATask { // access jet constituents as tracks if (bAddBigHistosToOutput) { - for (auto& jct : jet.tracks_as()) { + for (auto& jct : jet.tracks_as()) { for (UInt_t itr = 0; itr < acceptedTracks.size(); itr++) { if (acceptedTracks[itr].globalIndex == jct.globalIndex()) { diff --git a/PWGJE/Tasks/FullJetTriggerQATask.cxx b/PWGJE/Tasks/FullJetTriggerQATask.cxx index 44247cc960b..630a0722065 100644 --- a/PWGJE/Tasks/FullJetTriggerQATask.cxx +++ b/PWGJE/Tasks/FullJetTriggerQATask.cxx @@ -38,7 +38,7 @@ using namespace o2::framework; using namespace o2::framework::expressions; struct JetTriggerQA { - using selectedClusters = o2::soa::Filtered; + using selectedClusters = o2::soa::Filtered; using fullJetInfos = soa::Join; using neutralJetInfos = soa::Join; using collisionWithTrigger = soa::Join::iterator; @@ -160,7 +160,7 @@ struct JetTriggerQA { histProcessed->GetXaxis()->SetBinLabel(15, "Selected Gamma very low DCAL"); std::array triggerlabels = {{"MB", "EMC Any", "EMC MB", "EMC jet full high", "EMC jet full low", "EMC jet neutral high", "EMC jet neutral low", "EMC gamma very high", "DCL gamma very high", "EMC gamma high", "DCL gamma high", "EMC gamma low", "DCL gamma low", "EMC gamma very low", "DCL gamma very low"}}; - registry.add("hTriggerCorrelation", "Correlation between EMCAL triggers", HistType::kTH2D, {{TriggerType_t::kNTriggers, -0.5, (double)TriggerType_t::kNTriggers - 0.5, "Main trigger"}, {TriggerType_t::kNTriggers, -0.5, (double)TriggerType_t::kNTriggers - 0.5, "Associated trigger"}}); + registry.add("hTriggerCorrelation", "Correlation between EMCAL triggers", HistType::kTH2D, {{TriggerType_t::kNTriggers, -0.5, static_cast(TriggerType_t::kNTriggers) - 0.5, "Main trigger"}, {TriggerType_t::kNTriggers, -0.5, static_cast(TriggerType_t::kNTriggers) - 0.5, "Associated trigger"}}); auto triggerCorrelation = registry.get(HIST("hTriggerCorrelation")); for (std::size_t triggertype = 0; triggertype < TriggerType_t::kNTriggers; triggertype++) { triggerCorrelation->GetXaxis()->SetBinLabel(triggertype + 1, triggerlabels[triggertype].data()); @@ -544,7 +544,7 @@ struct JetTriggerQA { } template - std::pair, std::vector> fillJetQA(const JetCollection& jets, aod::JTracks const& tracks, selectedClusters const& clusters, std::bitset hwtrg, const std::bitset& triggerstatus) + std::pair, std::vector> fillJetQA(const JetCollection& jets, JetTracks const& tracks, selectedClusters const& clusters, std::bitset hwtrg, const std::bitset& triggerstatus) { auto isTrigger = [&triggerstatus](TriggerType_t triggertype) -> bool { return triggerstatus.test(triggertype); @@ -568,7 +568,7 @@ struct JetTriggerQA { // This gives us access to all jet substructure information // auto tracksInJet = jetTrackConstituents.sliceBy(perJetTrackConstituents, jet.globalIndex()); // for (const auto& trackList : tracksInJet) { - for (auto& track : jet.template tracks_as()) { + for (auto& track : jet.template tracks_as()) { auto trackPt = track.pt(); auto chargeFrag = track.px() * jet.px() + track.py() * jet.py() + track.pz() * jet.pz(); chargeFrag /= (jet.p() * jet.p()); @@ -647,12 +647,12 @@ struct JetTriggerQA { return std::make_pair(vecMaxJet, vecMaxJetNoFiducial); } - using JetCollisionsTable = soa::Join; + using JetCollisionsTable = soa::Join; template void runQA(collisionWithTrigger const& collision, JetCollection const& jets, - aod::JTracks const& tracks, + JetTracks const& tracks, selectedClusters const& clusters) { std::bitset triggerstatus; @@ -688,55 +688,55 @@ struct JetTriggerQA { setTrigger(TriggerType_t::kEmcalMB); } - if (JetDerivedDataUtilities::selectFullTrigger(collision, JetDerivedDataUtilities::JTrigSelFull::fullHigh)) { + if (jetderiveddatautilities::selectFullTrigger(collision, jetderiveddatautilities::JTrigSelFull::fullHigh)) { fillEventSelectionCounter(3); setTrigger(TriggerType_t::kEmcalJetFull); } - if (JetDerivedDataUtilities::selectFullTrigger(collision, JetDerivedDataUtilities::JTrigSelFull::fullLow)) { + if (jetderiveddatautilities::selectFullTrigger(collision, jetderiveddatautilities::JTrigSelFull::fullLow)) { fillEventSelectionCounter(4); setTrigger(TriggerType_t::kEmcalJetFullLow); } - if (JetDerivedDataUtilities::selectFullTrigger(collision, JetDerivedDataUtilities::JTrigSelFull::neutralHigh)) { + if (jetderiveddatautilities::selectFullTrigger(collision, jetderiveddatautilities::JTrigSelFull::neutralHigh)) { fillEventSelectionCounter(5); setTrigger(TriggerType_t::kEmcalJetNeutral); } - if (JetDerivedDataUtilities::selectFullTrigger(collision, JetDerivedDataUtilities::JTrigSelFull::neutralLow)) { + if (jetderiveddatautilities::selectFullTrigger(collision, jetderiveddatautilities::JTrigSelFull::neutralLow)) { fillEventSelectionCounter(6); setTrigger(TriggerType_t::kEmcalJetNeutralLow); } - if (JetDerivedDataUtilities::selectFullTrigger(collision, JetDerivedDataUtilities::JTrigSelFull::neutralLow)) { + if (jetderiveddatautilities::selectFullTrigger(collision, jetderiveddatautilities::JTrigSelFull::neutralLow)) { fillEventSelectionCounter(6); setTrigger(TriggerType_t::kEmcalJetNeutralLow); } - if (JetDerivedDataUtilities::selectFullTrigger(collision, JetDerivedDataUtilities::JTrigSelFull::gammaVeryHighEMCAL)) { + if (jetderiveddatautilities::selectFullTrigger(collision, jetderiveddatautilities::JTrigSelFull::gammaVeryHighEMCAL)) { fillEventSelectionCounter(7); setTrigger(TriggerType_t::kEmcalGammaVeryHigh); } - if (JetDerivedDataUtilities::selectFullTrigger(collision, JetDerivedDataUtilities::JTrigSelFull::gammaVeryHighDCAL)) { + if (jetderiveddatautilities::selectFullTrigger(collision, jetderiveddatautilities::JTrigSelFull::gammaVeryHighDCAL)) { fillEventSelectionCounter(8); setTrigger(TriggerType_t::kDcalGammaVeryHigh); } - if (JetDerivedDataUtilities::selectFullTrigger(collision, JetDerivedDataUtilities::JTrigSelFull::gammaHighEMCAL)) { + if (jetderiveddatautilities::selectFullTrigger(collision, jetderiveddatautilities::JTrigSelFull::gammaHighEMCAL)) { fillEventSelectionCounter(9); setTrigger(TriggerType_t::kEmcalGammaHigh); } - if (JetDerivedDataUtilities::selectFullTrigger(collision, JetDerivedDataUtilities::JTrigSelFull::gammaHighDCAL)) { + if (jetderiveddatautilities::selectFullTrigger(collision, jetderiveddatautilities::JTrigSelFull::gammaHighDCAL)) { fillEventSelectionCounter(10); setTrigger(TriggerType_t::kDcalGammaHigh); } - if (JetDerivedDataUtilities::selectFullTrigger(collision, JetDerivedDataUtilities::JTrigSelFull::gammaLowEMCAL)) { + if (jetderiveddatautilities::selectFullTrigger(collision, jetderiveddatautilities::JTrigSelFull::gammaLowEMCAL)) { fillEventSelectionCounter(11); setTrigger(TriggerType_t::kEmcalGammaLow); } - if (JetDerivedDataUtilities::selectFullTrigger(collision, JetDerivedDataUtilities::JTrigSelFull::gammaLowDCAL)) { + if (jetderiveddatautilities::selectFullTrigger(collision, jetderiveddatautilities::JTrigSelFull::gammaLowDCAL)) { fillEventSelectionCounter(12); setTrigger(TriggerType_t::kDcalGammaLow); } - if (JetDerivedDataUtilities::selectFullTrigger(collision, JetDerivedDataUtilities::JTrigSelFull::gammaVeryLowEMCAL)) { + if (jetderiveddatautilities::selectFullTrigger(collision, jetderiveddatautilities::JTrigSelFull::gammaVeryLowEMCAL)) { fillEventSelectionCounter(13); setTrigger(TriggerType_t::kEmcalGammaVeryLow); } - if (JetDerivedDataUtilities::selectFullTrigger(collision, JetDerivedDataUtilities::JTrigSelFull::gammaVeryLowDCAL)) { + if (jetderiveddatautilities::selectFullTrigger(collision, jetderiveddatautilities::JTrigSelFull::gammaVeryLowDCAL)) { fillEventSelectionCounter(14); setTrigger(TriggerType_t::kDcalGammaVeryLow); } @@ -830,7 +830,7 @@ struct JetTriggerQA { void processFullJets(collisionWithTrigger const& collision, fullJetInfos const& jets, - aod::JTracks const& tracks, + JetTracks const& tracks, selectedClusters const& clusters) { runQA(collision, jets, tracks, clusters); @@ -839,7 +839,7 @@ struct JetTriggerQA { void processNeutralJets(collisionWithTrigger const& collision, neutralJetInfos const& jets, - aod::JTracks const& tracks, + JetTracks const& tracks, selectedClusters const& clusters) { runQA(collision, jets, tracks, clusters); diff --git a/PWGJE/Tasks/emcalPi0EnergyScaleCalib.cxx b/PWGJE/Tasks/emcalPi0EnergyScaleCalib.cxx new file mode 100644 index 00000000000..6d4affede79 --- /dev/null +++ b/PWGJE/Tasks/emcalPi0EnergyScaleCalib.cxx @@ -0,0 +1,552 @@ +// Copyright 2019-2024 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. + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoA.h" +#include "Framework/HistogramRegistry.h" + +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Centrality.h" + +#include "EMCALBase/Geometry.h" +#include "PWGJE/DataModel/EMCALClusters.h" +#include "PWGJE/DataModel/EMCALMatchedCollisions.h" +#include "DataFormatsEMCAL/Cell.h" +#include "DataFormatsEMCAL/Constants.h" +#include "DataFormatsEMCAL/AnalysisCluster.h" + +#include "CommonDataFormat/InteractionRecord.h" + +#include "TLorentzVector.h" +#include "TVector3.h" + +/// \brief Simple pi0 reconstruction task used to scale the cell energy based on the difference in mass position in data and MC +/// \author Nicolas Strangmann , Goethe University Frankfurt / Oak Ridge National Laoratory +/// \author Joshua Koenig , Goethe University Frankfurt +/// \since 12.01.2024 +/// +/// The task distiguishes the regions of EMCal, DCal and the 1/3rd modules and within these it differentiated between +/// the region on the edge, the region behind the TRD support structure and the rest (inner region) + +using namespace o2::framework; +using namespace o2::framework::expressions; +using collisionEvSelIt = o2::aod::Collision; +using selectedClusters = o2::soa::Filtered; +using selectedCluster = o2::soa::Filtered; + +// Returns a boolean on whether a given EMCal column is behind the TRD support structure +bool IsBehindTRD(int col) +{ + // Columns behind the TRD support structure to investigate the scaling factor seperately for this region + static constexpr std::array TRDColumns{7, 8, 9, 10, 34, 35, 36, 37, 58, 59, 60, 61, 85, 86, 87, 88}; // Observed in calibration ratios + return std::find(std::begin(TRDColumns), std::end(TRDColumns), col) != std::end(TRDColumns); +} + +// Returns a boolean on whether a given EMCal row is on the border of a given supermodule +bool IsAtBorder(int row, bool smallmodule) +{ + return (row == 0 || (smallmodule && row == 7) || (!smallmodule && row == 23)); +} + +// Return one of nine acceptance categories and set the second and third parameter to the global row and column +int GetAcceptanceCategory(int cellid, int& globalrow, int& globalcol, int& supermodulecategory) +{ + auto [supermodule, module, phiInModule, etaInModule] = o2::emcal::Geometry::GetInstance()->GetCellIndex(cellid); + auto [row, col] = o2::emcal::Geometry::GetInstance()->GetCellPhiEtaIndexInSModule(supermodule, module, phiInModule, etaInModule); + + // Calculate offset of global rows and columns + int xoffset = supermodule % 2 * 48; + int yoffset = supermodule / 2 * 24; + + if (supermodule > 11 && supermodule < 18) { + xoffset = supermodule % 2 * 64; + } + if (supermodule > 11) { + yoffset = (supermodule - 12) / 2 * 24 + (5 * 24 + 8); + } + + // Add the offset to the local column and row + globalcol = col + xoffset; + globalrow = row + yoffset; + + // Add 48 columns for all odd supermodules and 16 for uneven DCal supermodules + if (supermodule % 2) { + col += 48; + if (supermodule > 11 && supermodule < 18) { + col += 16; + } + } + + // LOGF(info, "cellid: %d\tsupermodule: %d\tmodule: %d\tphiInModule: %d\tetaInModule: %d\trow: %d\tcol: %d", cellid, supermodule, module, phiInModule, etaInModule, row, col); + + if (supermodule >= 0 && supermodule <= 9) { + supermodulecategory = 0; + if (IsBehindTRD(col)) { + return 1; // EMCalbehindTRD + } else if (IsAtBorder(row, false)) { + return 2; // EMCalBorder + } else { + return 3; // EMCalInside + } + } else if (supermodule >= 12 && supermodule <= 17) { + supermodulecategory = 1; + if (IsBehindTRD(col)) { + return 4; // DCalbehindTRD + } else if (IsAtBorder(row, false)) { + return 5; // DCalBorder + } else { + return 6; // DCalInside + } + } else if (supermodule == 10 || supermodule == 11 || supermodule == 18 || supermodule == 19) { + supermodulecategory = 2; + if (IsBehindTRD(col)) { + return 7; // OneThirdbehindTRD + } else if (IsAtBorder(row, true)) { + return 8; // OneThirdBorder + } else { + return 9; // OneThirdInside + } + } else { + LOGF(error, Form("Supermodule %d not found", supermodule)); + return -1; + } +} + +struct Photon { + Photon(float eta_tmp, float phi_tmp, float energy_tmp, int clusteridin = 0, int cellidin = 0) + { + eta = eta_tmp; + phi = phi_tmp; + energy = energy_tmp; + theta = 2 * std::atan2(std::exp(-eta), 1); + px = energy * std::sin(theta) * std::cos(phi); + py = energy * std::sin(theta) * std::sin(phi); + pz = energy * std::cos(theta); + pt = std::sqrt(px * px + py * py); + photon.SetPxPyPzE(px, py, pz, energy); + clusterid = clusteridin; + cellid = cellidin; + + acceptance_category = GetAcceptanceCategory(cellid, row, col, supermodulecategory); + } + + TLorentzVector photon; + float pt; + float px; + float py; + float pz; + float eta; + float phi; + float energy; + float theta; + int row; // Global row + int col; // Global column + int acceptance_category; // One of the nine acceptance categories (EMCal, DCal or one third and behindTRD, border and inside) + int cellid; + int clusterid; + int supermodulecategory; // 0: Full, 1: 2/3, 2: 1/3 +}; + +struct Meson { + Meson(Photon p1, Photon p2) : pgamma1(p1), + pgamma2(p2) + { + pMeson = p1.photon + p2.photon; + } + Photon pgamma1; + Photon pgamma2; + TLorentzVector pMeson; + + float getMass() const { return pMeson.M(); } + float getPt() const { return pMeson.Pt(); } + float getOpeningAngle() const { return pgamma1.photon.Angle(pgamma2.photon.Vect()); } +}; + +struct Pi0EnergyScaleCalibTask { + HistogramRegistry mHistManager{"NeutralMesonHistograms"}; + Preslice perCluster = o2::aod::emcalclustercell::emcalclusterId; + + // configurable parameters + Configurable mDoEventSel{"doEventSel", 0, "demand kINT7"}; + Configurable mVertexCut{"vertexCut", -1, "apply z-vertex cut with value in cm"}; + Configurable mTimeMin{"TimeMinCut", -600, "apply min timing cut (in ns)"}; + Configurable mTimeMax{"TimeMaxCut", 900, "apply min timing cut (in ns)"}; + Configurable mClusterMinM02Cut{"MinM02Cut", 0.1, "apply min M02 cut"}; + Configurable mClusterMaxM02Cut{"MaxM02Cut", 0.7, "apply max M02 cut"}; + Configurable mMinEnergyCut{"MinEnergyCut", 0.7, "apply min cluster energy cut"}; + Configurable mMinNCellsCut{"MinNCellsCut", 1, "apply min cluster number of cell cut"}; + Configurable mMinOpenAngleCut{"OpeningAngleCut", 0.0202, "apply min opening angle cut"}; + Configurable mClusterDefinition{"clusterDefinition", "kV3Default", "cluster definition to be selected, e.g. V3Default"}; + Configurable mRequireBothPhotonsFromAcceptance{"RequireBothPhotonsFromAcceptance", 0, "Require both photons to be from the same acceptance category"}; + Configurable mAcceptanceRestrictionType{"AcceptanceRestrictionType", 0, "0: No restriction, 1: Ignore behind TRD, 2: Only Behind TRD, 3: Only EMCal, 4: OnlyDCal"}; + + ConfigurableAxis pTBinning{"pTBinning", {200, 0.0f, 20.0f}, "Binning used along pT axis for inv mass histograms"}; + ConfigurableAxis invmassBinning{"invmassBinning", {200, 0.0f, 0.4f}, "Binning used for inv mass axis in inv mass - pT histograms"}; + ConfigurableAxis etaBinning{"etaBinning", {100, -1.0f, 1.0f}, "Binning used for eta axis in eta-phi maps"}; + ConfigurableAxis phiBinning{"phiBinning", {100, 0.0f, 6.2832f}, "Binning used for eta axis in eta-phi maps"}; + + // define cluster filter. It selects only those clusters which are of the type + // specified in the string mClusterDefinition,e.g. kV3Default, which is V3 clusterizer with default + // clusterization parameters + o2::aod::EMCALClusterDefinition clusDef = o2::aod::emcalcluster::getClusterDefinitionFromString(mClusterDefinition.value); + Filter clusterDefinitionSelection = o2::aod::emcalcluster::definition == static_cast(clusDef); + + // define container for photons + std::vector mPhotons; + + int NAcceptanceCategories; + + /// \brief Create output histograms and initialize geometry + void init(InitContext const&) + { + // create histograms + using o2HistType = HistType; + using o2Axis = AxisSpec; + + // load geometry used to match a cellid to a supermodule and the row+column + o2::emcal::Geometry::GetInstanceFromRunNumber(300000); + + NAcceptanceCategories = 10; + + // create common axes + const o2Axis bcAxis{3501, -0.5, 3500.5}; + const o2Axis AccCategoryAxis{10, -0.5, 9.5}; + const o2Axis RowAxis{208, -0.5, 207.5}; + const o2Axis ColAxis{96, -0.5, 95.5}; + + mHistManager.add("events", "events;;#it{count}", o2HistType::kTH1F, {{4, 0.5, 4.5}}); + auto heventType = mHistManager.get(HIST("events")); + heventType->GetXaxis()->SetBinLabel(1, "All events"); + heventType->GetXaxis()->SetBinLabel(2, "One collision in BC"); + heventType->GetXaxis()->SetBinLabel(3, "Triggered"); + heventType->GetXaxis()->SetBinLabel(4, "Selected"); + mHistManager.add("eventBCAll", "Bunch crossing ID of event (all events)", o2HistType::kTH1F, {bcAxis}); + mHistManager.add("eventBCSelected", "Bunch crossing ID of event (selected events)", o2HistType::kTH1F, {bcAxis}); + mHistManager.add("eventVertexZAll", "z-vertex of event (all events)", o2HistType::kTH1F, {{200, -20, 20}}); + mHistManager.add("eventVertexZSelected", "z-vertex of event (selected events)", o2HistType::kTH1F, {{200, -20, 20}}); + + // cluster properties + mHistManager.add("clusterE", "Energy of cluster", o2HistType::kTH1F, {{400, 0, 100, "#it{E} (GeV)"}}); + mHistManager.add("clusterTime", "Time of cluster", o2HistType::kTH1F, {{500, -250, 250, "#it{t}_{cls} (ns)"}}); + mHistManager.add("clusterEtaPhi", "Eta and phi of cluster", o2HistType::kTH3F, {etaBinning, phiBinning, AccCategoryAxis}); + mHistManager.add("clusterEtaPhiVsRow", "Eta and phi of cluster", o2HistType::kTH3F, {etaBinning, phiBinning, RowAxis}); + mHistManager.add("clusterEtaPhiVsCol", "Eta and phi of cluster", o2HistType::kTH3F, {etaBinning, phiBinning, ColAxis}); + mHistManager.add("clusterEtaPhiVsSMCat", "Eta and phi of cluster", o2HistType::kTH3F, {etaBinning, phiBinning, {3, -0.5, 2.5}}); + mHistManager.add("clusterM02", "M02 of cluster", o2HistType::kTH1F, {{400, 0, 5, "#it{M}_{02}"}}); + mHistManager.add("clusterM20", "M20 of cluster", o2HistType::kTH1F, {{400, 0, 2.5, "#it{M}_{20}"}}); + mHistManager.add("clusterNLM", "Number of local maxima of cluster", o2HistType::kTH1I, {{10, 0, 10, "#it{N}_{local maxima}"}}); + mHistManager.add("clusterNCells", "Number of cells in cluster", o2HistType::kTH1I, {{50, 0, 50, "#it{N}_{cells}"}}); + mHistManager.add("clusterDistanceToBadChannel", "Distance to bad channel", o2HistType::kTH1F, {{100, 0, 100, "#it{d}"}}); + + mHistManager.add("invMassVsPt", "invariant mass and pT of meson candidates", o2HistType::kTH2F, {invmassBinning, pTBinning}); + mHistManager.add("invMassVsPtBackground", "invariant mass and pT of meson candidates", o2HistType::kTH2F, {invmassBinning, pTBinning}); + mHistManager.add("invMassVsPtVsAcc", "invariant mass and pT of meson candidates", o2HistType::kTH3F, {invmassBinning, pTBinning, AccCategoryAxis}); + mHistManager.add("invMassVsPtVsAccBackground", "invariant mass and pT of background meson candidates", o2HistType::kTH3F, {invmassBinning, pTBinning, AccCategoryAxis}); + mHistManager.add("invMassVsPtVsRow", "invariant mass and pT of meson candidates", o2HistType::kTH3F, {invmassBinning, pTBinning, RowAxis}); + mHistManager.add("invMassVsPtVsRowBackground", "invariant mass and pT of background meson candidates", o2HistType::kTH3F, {invmassBinning, pTBinning, RowAxis}); + mHistManager.add("invMassVsPtVsCol", "invariant mass and pT of background meson candidates", o2HistType::kTH3F, {invmassBinning, pTBinning, ColAxis}); + mHistManager.add("invMassVsPtVsColBackground", "invariant mass and pT of background meson candidates", o2HistType::kTH3F, {invmassBinning, pTBinning, ColAxis}); + mHistManager.add("invMassVsPtVsSMCat", "invariant mass and pT of background meson candidates", o2HistType::kTH3F, {invmassBinning, pTBinning, {3, -0.5, 2.5}}); + mHistManager.add("invMassVsPtVsSMCatBackground", "invariant mass and pT of background meson candidates", o2HistType::kTH3F, {invmassBinning, pTBinning, {3, -0.5, 2.5}}); + initCategoryAxis(mHistManager.get(HIST("invMassVsPtVsAcc")).get()); + initCategoryAxis(mHistManager.get(HIST("invMassVsPtVsAccBackground")).get()); + initCategoryAxis(mHistManager.get(HIST("clusterEtaPhi")).get()); + } + + /// \brief Process EMCAL clusters that are matched to a collisions + void process(o2::soa::Join::iterator const& collision, o2::aod::Calos const& allcalos, selectedClusters const& clusters, o2::aod::EMCALClusterCells const& cells) + { + mHistManager.fill(HIST("events"), 1); // Fill "All events" bin of event histogram + LOG(debug) << "processCollisions"; + + if (collision.ambiguous()) { // Skip ambiguous collisions (those that are in BCs including multiple collisions) + LOG(debug) << "Event not selected becaus there are multiple collisions in this BC, skipping"; + return; + } + mHistManager.fill(HIST("events"), 2); // Fill "One collision in BC" bin of event histogram + + if (mDoEventSel && (!collision.alias_bit(kTVXinEMC))) { + LOG(debug) << "Event not selected becaus it is not kTVXinEMC, skipping"; + return; + } + mHistManager.fill(HIST("events"), 3); // Fill "Triggered" bin of event histogram + mHistManager.fill(HIST("eventVertexZAll"), collision.posZ()); + if (mVertexCut > 0 && std::abs(collision.posZ()) > mVertexCut) { + LOG(debug) << "Event not selected because of z-vertex cut z= " << collision.posZ() << " > " << mVertexCut << " cm, skipping"; + return; + } + mHistManager.fill(HIST("events"), 4); // Fill "Selected" bin of event histogram + mHistManager.fill(HIST("eventVertexZSelected"), collision.posZ()); + + ProcessClusters(clusters, cells); + ProcessMesons(); + } + + template + int GetLeadingCellID(Cluster const& cluster, o2::aod::EMCALClusterCells const& cells) + { + auto cellsofcluster = cells.sliceBy(perCluster, cluster.globalIndex()); + double maxamp = 0; + int cellid = -1; + for (const auto& cell : cellsofcluster) { + if (cell.calo().amplitude() > maxamp) { + maxamp = cell.calo().amplitude(); + cellid = cell.calo().cellNumber(); + } + } + return cellid; + } + + /// \brief Process EMCAL clusters that are matched to a collisions + template + void ProcessClusters(Clusters const& clusters, o2::aod::EMCALClusterCells const& cells) + { + // clear photon vector + mPhotons.clear(); + + int globalCollID = -1000; + + // loop over all clusters from accepted collision + // auto eventClusters = clusters.select(o2::aod::emcalcluster::bcId == theCollision.bc().globalBC()); + for (const auto& cluster : clusters) { + + auto collID = cluster.collisionId(); + if (globalCollID == -1000) + globalCollID = collID; + + int cellid = GetLeadingCellID(cluster, cells); + + if (ClusterRejectedByCut(cluster, cellid)) { + continue; + } + + FillClusterQAHistos(cluster, cellid); + + // put clusters in photon vector + mPhotons.push_back(Photon(cluster.eta(), cluster.phi(), cluster.energy(), cluster.id(), cellid)); + } + } + + /// \brief Fills the standard QA histograms for a given cluster + template + void FillClusterQAHistos(Cluster const& cluster, int cellid) + { + // In this implementation the cluster properties are directly loaded from the flat table, + // in the future one should consider using the AnalysisCluster object to work with after loading. + mHistManager.fill(HIST("clusterE"), cluster.energy()); + mHistManager.fill(HIST("clusterTime"), cluster.time()); + mHistManager.fill(HIST("clusterEtaPhi"), cluster.eta(), cluster.phi(), 0.); + int row, col, supermodulecategory = 0; // Initialize row and column, which are set in GetAcceptanceCategory and then used to fill the eta phi map + mHistManager.fill(HIST("clusterEtaPhi"), cluster.eta(), cluster.phi(), GetAcceptanceCategory(cellid, row, col, supermodulecategory)); + mHistManager.fill(HIST("clusterEtaPhiVsRow"), cluster.eta(), cluster.phi(), row); + mHistManager.fill(HIST("clusterEtaPhiVsCol"), cluster.eta(), cluster.phi(), col); + mHistManager.fill(HIST("clusterEtaPhiVsSMCat"), cluster.eta(), cluster.phi(), supermodulecategory); + mHistManager.fill(HIST("clusterM02"), cluster.m02()); + mHistManager.fill(HIST("clusterM20"), cluster.m20()); + mHistManager.fill(HIST("clusterNLM"), cluster.nlm()); + mHistManager.fill(HIST("clusterNCells"), cluster.nCells()); + mHistManager.fill(HIST("clusterDistanceToBadChannel"), cluster.distanceToBadChannel()); + } + + /// \brief Return a boolean that states, whether a cluster should be rejected by the applied cluster cuts + template + bool ClusterRejectedByCut(Cluster const& cluster, int cellid) + { + // apply basic cluster cuts + if (cluster.energy() < mMinEnergyCut) { + LOG(debug) << "Cluster rejected because of energy cut"; + return true; + } + if (cluster.nCells() < mMinNCellsCut) { + LOG(debug) << "Cluster rejected because of nCells cut"; + return true; + } + // Only apply M02 cut when cluster contains more than one cell + if (cluster.nCells() > 1) { + if (cluster.m02() < mClusterMinM02Cut || cluster.m02() > mClusterMaxM02Cut) { + LOG(debug) << "Cluster rejected because of m02 cut"; + return true; + } + } + if (cluster.time() < mTimeMin || cluster.time() > mTimeMax) { + LOG(debug) << "Cluster rejected because of time cut"; + return true; + } + + int row, col, supermodulecategory = 0; + GetAcceptanceCategory(cellid, row, col, supermodulecategory); + switch (mAcceptanceRestrictionType) { + case 0: + break; + case 1: // Not behind TRD + if (IsBehindTRD(col)) { + return true; + } + break; + case 2: // Only behind TRD + if (!IsBehindTRD(col)) { + return true; + } + break; + case 3: // Only EMCal + if (supermodulecategory != 0) { + return true; + } + break; + case 4: // Only DCal + if (supermodulecategory != 1) { + return true; + } + break; + default: + break; + } + + return false; + } + + /// \brief Process meson candidates, calculate invariant mass and pT and fill histograms + void ProcessMesons() + { + // if less then 2 clusters are found, skip event + if (mPhotons.size() < 2) + return; + + // loop over all photon combinations and build meson candidates + for (unsigned int ig1 = 0; ig1 < mPhotons.size(); ++ig1) { + for (unsigned int ig2 = ig1 + 1; ig2 < mPhotons.size(); ++ig2) { + Meson meson(mPhotons[ig1], mPhotons[ig2]); // build meson from photons + if (meson.getOpeningAngle() > mMinOpenAngleCut) { + mHistManager.fill(HIST("invMassVsPt"), meson.getMass(), meson.getPt()); + mHistManager.fill(HIST("invMassVsPtVsAcc"), meson.getMass(), meson.getPt(), 0.); + if (mPhotons[ig1].supermodulecategory == mPhotons[ig2].supermodulecategory) + mHistManager.fill(HIST("invMassVsPtVsSMCat"), meson.getMass(), meson.getPt(), mPhotons[ig1].supermodulecategory); + mHistManager.fill(HIST("invMassVsPtVsRow"), meson.getMass(), meson.getPt(), mPhotons[ig1].row); + mHistManager.fill(HIST("invMassVsPtVsRow"), meson.getMass(), meson.getPt(), mPhotons[ig2].row); + mHistManager.fill(HIST("invMassVsPtVsCol"), meson.getMass(), meson.getPt(), mPhotons[ig1].col); + mHistManager.fill(HIST("invMassVsPtVsCol"), meson.getMass(), meson.getPt(), mPhotons[ig2].col); + for (int iAcceptanceCategory = 1; iAcceptanceCategory < NAcceptanceCategories; iAcceptanceCategory++) { + if ((!mRequireBothPhotonsFromAcceptance && (mPhotons[ig1].acceptance_category == iAcceptanceCategory || mPhotons[ig2].acceptance_category == iAcceptanceCategory)) || + (mPhotons[ig1].acceptance_category == iAcceptanceCategory && mPhotons[ig2].acceptance_category == iAcceptanceCategory)) { + mHistManager.fill(HIST("invMassVsPtVsAcc"), meson.getMass(), meson.getPt(), iAcceptanceCategory); + } + } + CalculateBackground(meson, ig1, ig2); // calculate background candidates (rotation background) + } + } + } + } + + /// \brief Calculate background (using rotation background method) + void CalculateBackground(const Meson& meson, unsigned int ig1, unsigned int ig2) + { + // if less than 3 clusters are present, skip event + if (mPhotons.size() < 3) { + return; + } + const double rotationAngle = M_PI / 2.0; // 0.78539816339; // rotaion angle 90° + + TLorentzVector lvRotationPhoton1; // photon candidates which get rotated + TLorentzVector lvRotationPhoton2; // photon candidates which get rotated + TVector3 lvRotationPion; // rotation axis + for (unsigned int ig3 = 0; ig3 < mPhotons.size(); ++ig3) { + // continue if photons are identical + if (ig3 == ig1 || ig3 == ig2) { + continue; + } + // calculate rotation axis + lvRotationPion = (meson.pMeson).Vect(); + + // initialize photons for rotation + lvRotationPhoton1.SetPxPyPzE(mPhotons[ig1].px, mPhotons[ig1].py, mPhotons[ig1].pz, mPhotons[ig1].energy); + lvRotationPhoton2.SetPxPyPzE(mPhotons[ig2].px, mPhotons[ig2].py, mPhotons[ig2].pz, mPhotons[ig2].energy); + + // rotate photons around rotation axis + lvRotationPhoton1.Rotate(rotationAngle, lvRotationPion); + lvRotationPhoton2.Rotate(rotationAngle, lvRotationPion); + + // initialize Photon objects for rotated photons + Photon rotPhoton1(lvRotationPhoton1.Eta(), lvRotationPhoton1.Phi(), lvRotationPhoton1.E(), mPhotons[ig1].clusterid, mPhotons[ig1].cellid); + Photon rotPhoton2(lvRotationPhoton2.Eta(), lvRotationPhoton2.Phi(), lvRotationPhoton2.E(), mPhotons[ig2].clusterid, mPhotons[ig2].cellid); + + // build meson from rotated photons + Meson mesonRotated1(rotPhoton1, mPhotons[ig3]); + Meson mesonRotated2(rotPhoton2, mPhotons[ig3]); + + // Fill histograms + if (mesonRotated1.getOpeningAngle() > mMinOpenAngleCut) { + mHistManager.fill(HIST("invMassVsPtBackground"), mesonRotated1.getMass(), mesonRotated1.getPt()); + mHistManager.fill(HIST("invMassVsPtVsAccBackground"), mesonRotated1.getMass(), mesonRotated1.getPt(), 0); + if (mPhotons[ig3].supermodulecategory == rotPhoton1.supermodulecategory) + mHistManager.fill(HIST("invMassVsPtVsSMCatBackground"), mesonRotated1.getMass(), mesonRotated1.getPt(), mPhotons[ig3].supermodulecategory); + mHistManager.fill(HIST("invMassVsPtVsRowBackground"), mesonRotated1.getMass(), mesonRotated1.getPt(), mPhotons[ig3].row); + mHistManager.fill(HIST("invMassVsPtVsRowBackground"), mesonRotated1.getMass(), mesonRotated1.getPt(), rotPhoton1.row); + mHistManager.fill(HIST("invMassVsPtVsColBackground"), mesonRotated1.getMass(), mesonRotated1.getPt(), mPhotons[ig3].col); + mHistManager.fill(HIST("invMassVsPtVsColBackground"), mesonRotated1.getMass(), mesonRotated1.getPt(), rotPhoton1.col); + for (int iAcceptanceCategory = 1; iAcceptanceCategory < NAcceptanceCategories; iAcceptanceCategory++) { + if ((!mRequireBothPhotonsFromAcceptance && (rotPhoton1.acceptance_category == iAcceptanceCategory || mPhotons[ig3].acceptance_category == iAcceptanceCategory)) || + (rotPhoton1.acceptance_category == iAcceptanceCategory && mPhotons[ig3].acceptance_category == iAcceptanceCategory)) { + mHistManager.fill(HIST("invMassVsPtVsAccBackground"), mesonRotated1.getMass(), mesonRotated1.getPt(), iAcceptanceCategory); + } + } + } + if (mesonRotated2.getOpeningAngle() > mMinOpenAngleCut) { + mHistManager.fill(HIST("invMassVsPtBackground"), mesonRotated2.getMass(), mesonRotated2.getPt()); + mHistManager.fill(HIST("invMassVsPtVsAccBackground"), mesonRotated2.getMass(), mesonRotated2.getPt(), 0); + if (mPhotons[ig3].supermodulecategory == rotPhoton2.supermodulecategory) + mHistManager.fill(HIST("invMassVsPtVsSMCatBackground"), mesonRotated2.getMass(), mesonRotated2.getPt(), mPhotons[ig3].supermodulecategory); + mHistManager.fill(HIST("invMassVsPtVsRowBackground"), mesonRotated2.getMass(), mesonRotated2.getPt(), mPhotons[ig3].row); + mHistManager.fill(HIST("invMassVsPtVsRowBackground"), mesonRotated2.getMass(), mesonRotated2.getPt(), rotPhoton2.row); + mHistManager.fill(HIST("invMassVsPtVsColBackground"), mesonRotated2.getMass(), mesonRotated2.getPt(), mPhotons[ig3].col); + mHistManager.fill(HIST("invMassVsPtVsColBackground"), mesonRotated2.getMass(), mesonRotated2.getPt(), rotPhoton2.col); + for (int iAcceptanceCategory = 1; iAcceptanceCategory < NAcceptanceCategories; iAcceptanceCategory++) { + if ((!mRequireBothPhotonsFromAcceptance && (rotPhoton2.acceptance_category == iAcceptanceCategory || mPhotons[ig3].acceptance_category == iAcceptanceCategory)) || + (rotPhoton2.acceptance_category == iAcceptanceCategory && mPhotons[ig3].acceptance_category == iAcceptanceCategory)) { + mHistManager.fill(HIST("invMassVsPtVsAccBackground"), mesonRotated2.getMass(), mesonRotated2.getPt(), iAcceptanceCategory); + } + } + } + } + } + + // Beautify acceptance category bin labels + void initCategoryAxis(TH3* hist) + { + hist->GetZaxis()->SetTitle("Acceptance Category"); + hist->GetZaxis()->SetBinLabel(1, "FullAcceptance"); + hist->GetZaxis()->SetBinLabel(2, "EMCalbehindTRD"); + hist->GetZaxis()->SetBinLabel(3, "EMCalBorder"); + hist->GetZaxis()->SetBinLabel(4, "EMCalInside"); + hist->GetZaxis()->SetBinLabel(5, "DCalbehindTRD"); + hist->GetZaxis()->SetBinLabel(6, "DCalBorder"); + hist->GetZaxis()->SetBinLabel(7, "DCalInside"); + hist->GetZaxis()->SetBinLabel(8, "OneThirdbehindTRD"); + hist->GetZaxis()->SetBinLabel(9, "OneThirdBorder"); + hist->GetZaxis()->SetBinLabel(10, "OneThirdInside"); + } +}; + +WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGJE/Tasks/emcvertexselectionqa.cxx b/PWGJE/Tasks/emcvertexselectionqa.cxx new file mode 100644 index 00000000000..0d7369f7d9e --- /dev/null +++ b/PWGJE/Tasks/emcvertexselectionqa.cxx @@ -0,0 +1,238 @@ +// Copyright 2019-2024 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. + +// Monitoring task for EMCAL vertex selection (number and source of contributors to the vertices) +// +/// \author Nicolas Strangmann , Goethe University Frankfurt / Oak Ridge National Laoratory + +#include +#include +#include + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoA.h" +#include "Framework/HistogramRegistry.h" + +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/EventSelection.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +using bcEvSels = o2::soa::Join; +using collEventSels = o2::soa::Join; +using FullTracksIU = soa::Join; + +struct EmcVertexSelectionQA { + o2::framework::HistogramRegistry mHistManager{"EMCALVertexSelectionQAHistograms"}; + + void init(o2::framework::InitContext const&) + { + using o2HistType = o2::framework::HistType; + using o2Axis = o2::framework::AxisSpec; + + o2Axis matchingAxis{4, -0.5, 3.5, "matchingStatus", "Matching status"}; // 0, no vertex,1 vertex found , 2 vertices found, 3 or more vertices found + o2Axis qualityAxis{3, -0.5, 2.5, "VertexQuality", "Vertex quality"}; // 0: TPC/ITS contributor, 1: TRD contributor , 2: TOF contributor + o2Axis DCAStdDevAxis{500, 0., 0.05, "StdDevDCA", "#sigma DCA"}; + o2Axis TimeStdDevAxis{1000, 0., 10000., "TimeStdDev", "#sigma t"}; + + mHistManager.add("hCollisionMatching", "Collision Status", o2HistType::kTH1F, {matchingAxis}); + mHistManager.add("hCollisionMatchingReadout", "Collision Status EMCAL Readout", o2HistType::kTH1F, {matchingAxis}); + mHistManager.add("hnVerticeswithTOForTRDcontr", "Number of vertices vs number with TOF/TRD Contributors", o2HistType::kTH2F, {matchingAxis, matchingAxis}); + mHistManager.add("hnVertexContributors", "Number of Contributors to first and second vertex", o2HistType::kTH2F, {{50, 0, 50}, {50, 0, 50}}); + + // The standard deviations of the DCA and times of tracks contributing to the vertex are investigated as proxies for the quality of a vertex + + // First using the simple RMS from TMath + mHistManager.add("hVertexStdDevDCA", "StdDev DCA of Vertex vs its Quality", o2HistType::kTH2F, {DCAStdDevAxis, qualityAxis}); + mHistManager.add("hVertexTrackTimeStdDev", "Standard Deviation of Tracks Contributing to the Vertex vs its Quality", o2HistType::kTH2F, {TimeStdDevAxis, qualityAxis}); + + // And secondly using the TRobustEstimator to exclude outliers + mHistManager.add("hVertexRobustStdDevDCA", "Robust StdDev DCA of Vertex vs its Quality", o2HistType::kTH2F, {DCAStdDevAxis, qualityAxis}); + mHistManager.add("hVertexTrackTimeRobustStdDev", "Robust Standard Deviation of Tracks Contributing to the Vertex vs its Quality", o2HistType::kTH2F, {TimeStdDevAxis, qualityAxis}); + + // The ratio of normal/robust RMS to see how much the outlier rejection has impacted the RMS + mHistManager.add("hVertexRelDiffRobustStdDevDCA", "Relative Difference of Robust StdDev DCA to StdDev DCA of Vertex vs its Quality", o2HistType::kTH2F, {{200, 0, 2}, qualityAxis}); + mHistManager.add("hVertexRelDiffRobustStdDevTrackTime", "Relative Difference of Robust Standard Deviation to Standard Deviation of Tracks Contributing to the Vertex vs its Quality", o2HistType::kTH2F, {{200, 0, 2}, qualityAxis}); + + // Set axis labels and bin titles + initVertexHistogram(mHistManager.get(HIST("hCollisionMatching")).get()); + initVertexHistogram(mHistManager.get(HIST("hCollisionMatchingReadout")).get()); + initVertexHistogram(mHistManager.get(HIST("hnVerticeswithTOForTRDcontr")).get()); + + initVertexQualityAxis(mHistManager.get(HIST("hVertexStdDevDCA")).get()); + mHistManager.get(HIST("hVertexStdDevDCA")).get()->GetXaxis()->SetTitle(" of vtx contributers"); + initVertexQualityAxis(mHistManager.get(HIST("hVertexTrackTimeStdDev")).get()); + mHistManager.get(HIST("hVertexTrackTimeStdDev")).get()->GetXaxis()->SetTitle("#sigma t of vtx contributers"); + initVertexQualityAxis(mHistManager.get(HIST("hVertexRobustStdDevDCA")).get()); + mHistManager.get(HIST("hVertexRobustStdDevDCA")).get()->GetXaxis()->SetTitle("Robust of vtx contributers"); + initVertexQualityAxis(mHistManager.get(HIST("hVertexTrackTimeRobustStdDev")).get()); + mHistManager.get(HIST("hVertexTrackTimeRobustStdDev")).get()->GetXaxis()->SetTitle("Robust #sigma t of vtx contributers"); + initVertexQualityAxis(mHistManager.get(HIST("hVertexRelDiffRobustStdDevDCA")).get()); + initVertexQualityAxis(mHistManager.get(HIST("hVertexRelDiffRobustStdDevTrackTime")).get()); + + mHistManager.get(HIST("hnVertexContributors")).get()->GetXaxis()->SetTitle("N_{contr} to Vtx 1"); + mHistManager.get(HIST("hnVertexContributors")).get()->GetYaxis()->SetTitle("N_{contr} to Vtx 2"); + } + + Preslice perCollision = aod::track::collisionId; + PresliceUnsorted perFoundBC = aod::evsel::foundBCId; + void process(bcEvSels const& bcs, collEventSels const& collisions, FullTracksIU const& tracks) + { + for (const auto& bc : bcs) { + bool isEMCALreadout = false; + + if (bc.runNumber() > 300000) { + // in case of run3 not all BCs contain EMCAL data, require trigger selection also for min. bias + // in addition select also L0/L1 triggers as triggers with EMCAL in reaodut + if (bc.alias_bit(kTVXinEMC) || bc.alias_bit(kEMC7) || bc.alias_bit(kEG1) || bc.alias_bit(kEG2) || bc.alias_bit(kDG1) || bc.alias_bit(kDG2) || bc.alias_bit(kEJ1) || bc.alias_bit(kEJ2) || bc.alias_bit(kDJ1) || bc.alias_bit(kDJ2)) { + isEMCALreadout = true; + } + } else { + // run1/2: rely on trigger cluster, runlist must contain only runs with EMCAL in readout + // Select min. bias trigger and EMCAL L0/L1 triggers + if (bc.alias_bit(kINT7) || bc.alias_bit(kEMC7) || bc.alias_bit(kEG1) || bc.alias_bit(kEG2) || bc.alias_bit(kEJ1) || bc.alias_bit(kEJ2)) { + isEMCALreadout = true; + } + } + + auto colsinbc = collisions.sliceBy(perFoundBC, bc.globalIndex()); + int collisionStatus = -1; + if (!colsinbc.size()) { + collisionStatus = 0; + } else if (colsinbc.size() == 1) { + collisionStatus = 1; + } else if (colsinbc.size() == 2) { + collisionStatus = 2; + } else { + collisionStatus = 3; + } + if (collisionStatus >= 0) { + mHistManager.fill(HIST("hCollisionMatching"), collisionStatus); + if (isEMCALreadout) { + mHistManager.fill(HIST("hCollisionMatchingReadout"), collisionStatus); + } + } + if (collisionStatus > 0) { + int nVtx = 0; + int nVtxwithTOForTRDcontr = 0; + std::vector nVtxContributors; + for (auto& col : colsinbc) { // Loop over all collisions/vertices + int ivtxquality = 0; // 0: TPC/ITS contributor, 1: TRD contributor , 2: TOF contributor + int nITStracks = 0; + int nTPCtracks = 0; + int nTOFtracks = 0; + int nTRDtracks = 0; + int nPVContributorTracks = 0; + std::vector TrackDCA; + std::vector TrackTime; + auto tracksGrouped = tracks.sliceBy(perCollision, col.globalIndex()); + for (auto& track : tracksGrouped) { + if (!track.isPVContributor()) { + continue; + } + nITStracks += track.hasITS(); + nTPCtracks += track.hasTPC(); + nTOFtracks += track.hasTOF(); + nTRDtracks += track.hasTRD() && !track.hasTOF(); + TrackDCA.push_back(track.dcaXY()); + TrackTime.push_back(track.trackTime()); + // LOGF(info, "TOF: %d, TRD: %d - track.dcaXY[%d] = %f, track.trackTime[%d] = %f, pT = %f, nTPCrows = %d", track.hasTOF(), track.hasTRD(), nPVContributorTracks, track.dcaXY(), nPVContributorTracks, track.trackTime(), track.pt(), track.tpcNClsCrossedRows()); + + nPVContributorTracks++; + } + + if (nTRDtracks > 0) { + ivtxquality = 1; + } + if (nTOFtracks > 0) { + ivtxquality = 2; + } + + // Calculate the arithmetic RMS for all tracks contributing to the vertex + double StdDevTrackDCA = TMath::RMS(TrackDCA.begin(), TrackDCA.end()); + double StdDevTrackTime = TMath::RMS(TrackTime.begin(), TrackTime.end()); + + // Calculate the RMS using the robust estimator to reject outliers + TRobustEstimator robustEstimator; + double RobustMeanTrackDCA = 0, RobustStdDevTrackDCA = 0; + double RobustMeanTrackTime = 0, RobustStdDevTrackTime = 0; + robustEstimator.EvaluateUni(TrackDCA.size(), TrackDCA.data(), RobustMeanTrackDCA, RobustStdDevTrackDCA, 0.5 * TrackDCA.size()); + robustEstimator.EvaluateUni(TrackTime.size(), TrackTime.data(), RobustMeanTrackTime, RobustStdDevTrackTime, 0.5 * TrackTime.size()); + + mHistManager.fill(HIST("hVertexStdDevDCA"), StdDevTrackDCA, ivtxquality); + mHistManager.fill(HIST("hVertexTrackTimeStdDev"), StdDevTrackTime, ivtxquality); + mHistManager.fill(HIST("hVertexRobustStdDevDCA"), RobustStdDevTrackDCA, ivtxquality); + mHistManager.fill(HIST("hVertexTrackTimeRobustStdDev"), RobustStdDevTrackTime, ivtxquality); + mHistManager.fill(HIST("hVertexRelDiffRobustStdDevDCA"), RobustStdDevTrackDCA / StdDevTrackDCA, ivtxquality); + mHistManager.fill(HIST("hVertexRelDiffRobustStdDevTrackTime"), RobustStdDevTrackTime / StdDevTrackTime, ivtxquality); + // LOGF(info, "StdDevTrackDCA = %f, StdDevTrackTime = %f, RobustStdDevTrackDCA = %f, RobustStdDevTrackTime = %f", StdDevTrackDCA, StdDevTrackTime, RobustStdDevTrackDCA, RobustStdDevTrackTime); + + nVtx++; + if (nTOFtracks + nTRDtracks > 0) { + nVtxwithTOForTRDcontr++; + } + nVtxContributors.push_back(nPVContributorTracks); + } + mHistManager.fill(HIST("hnVerticeswithTOForTRDcontr"), nVtx, nVtxwithTOForTRDcontr); + if (collisionStatus == 2) { + mHistManager.fill(HIST("hnVertexContributors"), nVtxContributors.at(0), nVtxContributors.at(1)); + } + nVtxContributors.clear(); + } + } + } + + // Beautify bc type lables + void + initVertexHistogram(TH1* hist) + { + hist->GetXaxis()->SetTitle("N_{Vtx}"); + hist->GetXaxis()->SetBinLabel(1, "No vertex"); + hist->GetXaxis()->SetBinLabel(2, "1 vertex"); + hist->GetXaxis()->SetBinLabel(3, "2 vertices"); + hist->GetXaxis()->SetBinLabel(4, "3+ vertices"); + hist->GetYaxis()->SetTitle("Number of BCs"); + } + // Beautify bc type lables + void initVertexHistogram(TH2* hist) + { + hist->GetXaxis()->SetTitle("N_{Vtx}"); + hist->GetXaxis()->SetBinLabel(1, "No vertex"); + hist->GetXaxis()->SetBinLabel(2, "1 vertex"); + hist->GetXaxis()->SetBinLabel(3, "2 vertices"); + hist->GetXaxis()->SetBinLabel(4, "3+ vertices"); + hist->GetYaxis()->SetTitle("N_{Vtx} with TOF/TRD Contributors"); + hist->GetYaxis()->SetBinLabel(1, "No vertex"); + hist->GetYaxis()->SetBinLabel(2, "1 vertex"); + hist->GetYaxis()->SetBinLabel(3, "2 vertices"); + hist->GetYaxis()->SetBinLabel(4, "3+ vertices"); + hist->GetZaxis()->SetTitle("Number of BCs"); + } + // Beautify vertex quality lables + void initVertexQualityAxis(TH2* hist) + { + hist->GetYaxis()->SetTitle("Highest contributer quality"); + hist->GetYaxis()->SetBinLabel(1, "TPC/ITS"); + hist->GetYaxis()->SetBinLabel(2, "TRD"); + hist->GetYaxis()->SetBinLabel(3, "TOF"); + hist->GetZaxis()->SetTitle("Number of BCs"); + } +}; + +o2::framework::WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& cfgc) +{ + return o2::framework::WorkflowSpec{ + o2::framework::adaptAnalysisTask(cfgc)}; +} diff --git a/PWGJE/Tasks/jetHadronRecoil.cxx b/PWGJE/Tasks/jetHadronRecoil.cxx index a4c886aa700..03a2755707d 100644 --- a/PWGJE/Tasks/jetHadronRecoil.cxx +++ b/PWGJE/Tasks/jetHadronRecoil.cxx @@ -57,7 +57,7 @@ struct hJetAnalysis { {{"hNtrig", "number of triggers;trigger type;entries", {HistType::kTH1F, {{2, 0, 2}}}}, {"hPtTrack", "Track p_{T};p_{T};entries", {HistType::kTH1F, {{100, 0, 100}}}}, {"hEtaTrack", "Track #eta;#eta;entries", {HistType::kTH1F, {{20, -1, 1}}}}, - {"hPhiTrack", "Track #phi;#phi;entries", {HistType::kTH1F, {{200, -3.2, 6.4}}}}, + {"hPhiTrack", "Track #phi;#phi;entries", {HistType::kTH1F, {{200, -M_PI, 2 * M_PI}}}}, {"hReferencePtDPhi", "jet p_{T} vs DPhi;p_{T,jet};#Delta#phi", {HistType::kTH2F, {{150, 0, 150}, {100, M_PI - 0.6, M_PI}}}}, {"hSignalPtDPhi", "jet p_{T} vs DPhi;p_{T,jet};#Delta#phi", {HistType::kTH2F, {{150, 0, 150}, {100, M_PI - 0.6, M_PI}}}}, {"hReferencePt", "jet p_{T};p_{T,jet};entries", {HistType::kTH1F, {{150, 0, 150}}}}, @@ -69,7 +69,12 @@ struct hJetAnalysis { {"hJetSignalConstituentMultiplicity", "jet constituent multiplicity;p_{T,jet};#Delta#phi;N_{constituents}", {HistType::kTH3F, {{150, 0, 150}, {100, M_PI - 0.6, M_PI}, {50, 0, 50}}}}, {"hJetReferenceConstituentMultiplicity", "jet constituent multiplicity;p_{T,jet};#Delta#phi;N_{constituents}", {HistType::kTH3F, {{150, 0, 150}, {100, M_PI - 0.6, M_PI}, {50, 0, 50}}}}, {"hJetSignalConstituentPt", "jet constituent p_{T};p_{T,jet};#Delta#phi;p_{T,constituent}", {HistType::kTH3F, {{150, 0, 150}, {100, M_PI - 0.6, M_PI}, {150, 0, 150}}}}, - {"hJetReferenceConstituentPt", "jet constituent p_{T};p_{T,jet};#Delta#phi;p_{T,constituent}", {HistType::kTH3F, {{150, 0, 150}, {100, M_PI - 0.6, M_PI}, {150, 0, 150}}}}}}; + {"hJetReferenceConstituentPt", "jet constituent p_{T};p_{T,jet};#Delta#phi;p_{T,constituent}", {HistType::kTH3F, {{150, 0, 150}, {100, M_PI - 0.6, M_PI}, {150, 0, 150}}}}, + {"hSigEventTriggers", "N_{triggers};events", {HistType::kTH1F, {{10, 0, 10}}}}, + {"hRefEventTriggers", "N_{triggers};events", {HistType::kTH1F, {{10, 0, 10}}}}, + {"hJetPt", "jet p_{T};p_{T,jet};entries", {HistType::kTH1F, {{150, 0, 150}}}}, + {"hJetEta", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{20, -1, 1}}}}, + {"hJetPhi", "jet #phi;#phi_{jet};entries", {HistType::kTH1F, {{200, -M_PI, 2 * M_PI}}}}}}; void init(InitContext const&) {} @@ -119,14 +124,19 @@ struct hJetAnalysis { if (is_sig_col) { registry.fill(HIST("hNtrig"), 1.5); registry.fill(HIST("hJetSignalMultiplicity"), jets.size()); + registry.fill(HIST("hSigEventTriggers"), n_TT); } if (!is_sig_col) { registry.fill(HIST("hNtrig"), 0.5); registry.fill(HIST("hJetReferenceMultiplicity"), jets.size()); + registry.fill(HIST("hRefEventTriggers"), n_TT); } } for (auto& jet : jets) { + registry.fill(HIST("hJetPt"), jet.pt()); + registry.fill(HIST("hJetEta"), jet.eta()); + registry.fill(HIST("hJetPhi"), jet.phi()); if (n_TT > 0) { float dphi = dPhi(jet.phi(), phi_TT); if (is_sig_col && std::abs(dphi) > M_PI - 0.6) { diff --git a/PWGJE/Tasks/jetTutorial.cxx b/PWGJE/Tasks/jetTutorial.cxx index ba9b6b9b1ca..e42195d6691 100644 --- a/PWGJE/Tasks/jetTutorial.cxx +++ b/PWGJE/Tasks/jetTutorial.cxx @@ -77,22 +77,22 @@ struct JetTutorialTask { void init(o2::framework::InitContext&) { - eventSelection = JetDerivedDataUtilities::initialiseEventSelection(static_cast(eventSelections)); - trackSelection = JetDerivedDataUtilities::initialiseTrackSelection(static_cast(trackSelections)); + eventSelection = jetderiveddatautilities::initialiseEventSelection(static_cast(eventSelections)); + trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); } Filter jetCuts = aod::jet::pt > jetPtMin&& aod::jet::r == nround(jetR.node() * 100.0f); - void processCollisions(aod::JCollision const& collision, aod::JTracks const& tracks) + void processCollisions(JetCollision const& collision, JetTracks const& tracks) { registry.fill(HIST("h_collisions"), 0.5); - if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } registry.fill(HIST("h_collisions"), 1.5); for (auto const& track : tracks) { - if (!JetDerivedDataUtilities::selectTrack(track, trackSelection)) { + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { continue; } registry.fill(HIST("h_track_pt"), track.pt()); @@ -102,16 +102,16 @@ struct JetTutorialTask { } PROCESS_SWITCH(JetTutorialTask, processCollisions, "process self contained collisions", true); - void processCollisionsWithExternalTracks(aod::JCollision const& collision, soa::Join const& tracks, soa::Join const& originalTracks) + void processCollisionsWithExternalTracks(JetCollision const& collision, soa::Join const& tracks, soa::Join const& originalTracks) { registry.fill(HIST("h_collisions"), 0.5); - if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } registry.fill(HIST("h_collisions"), 1.5); for (auto const& track : tracks) { - if (!JetDerivedDataUtilities::selectTrack(track, trackSelection)) { + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { continue; } registry.fill(HIST("h_track_pt"), track.pt()); @@ -147,7 +147,7 @@ struct JetTutorialTask { } PROCESS_SWITCH(JetTutorialTask, processMCParticleLevel, "jets on particle level MC", false); - void processMCCharged(aod::JCollisions const& collision, soa::Filtered const& mcdjets, soa::Filtered const& mcpjets) + void processMCCharged(JetCollision const& collision, soa::Filtered const& mcdjets, soa::Filtered const& mcpjets) { for (auto& mcdjet : mcdjets) { registry.fill(HIST("h_jet_pt"), mcdjet.pt()); @@ -163,11 +163,11 @@ struct JetTutorialTask { PROCESS_SWITCH(JetTutorialTask, processMCCharged, "jets on detector and particle level MC", false); using JetMCPTable = soa::Filtered>; - void processMCChargedMatched(aod::JCollision const& collision, + void processMCChargedMatched(JetCollision const& collision, soa::Filtered> const& mcdjets, JetMCPTable const& mcpjets, - aod::JTracks const& tracks, - aod::JMcParticles const& particles) + JetTracks const& tracks, + JetParticles const& particles) { for (const auto& mcdjet : mcdjets) { @@ -182,7 +182,7 @@ struct JetTutorialTask { } PROCESS_SWITCH(JetTutorialTask, processMCChargedMatched, "jet finder QA matched mcp and mcd", false); - void processDataChargedSubstructure(soa::Filtered>::iterator const& jet, aod::JTracks const& tracks) + void processDataChargedSubstructure(soa::Filtered>::iterator const& jet, JetTracks const& tracks) { // add aditional selection on jet eta registry.fill(HIST("h_jet_pt"), jet.pt()); @@ -190,14 +190,14 @@ struct JetTutorialTask { registry.fill(HIST("h_jet_phi"), jet.phi()); registry.fill(HIST("h_jet_ntracks"), jet.tracks().size()); double angularity = 0.0; - for (auto& jetConstituent : jet.tracks_as()) { + for (auto& jetConstituent : jet.tracks_as()) { angularity += jetConstituent.pt() * TMath::Sqrt(TMath::Power(jet.phi() - jetConstituent.phi(), 2.0) + TMath::Power(jet.eta() - jetConstituent.eta(), 2.0)); } registry.fill(HIST("h_jet_angularity"), angularity / (jet.pt() * round(jet.r() / 100.0f))); } PROCESS_SWITCH(JetTutorialTask, processDataChargedSubstructure, "jet substructure charged jets", false); - void processMCParticleSubstructure(soa::Filtered>::iterator const& jet, aod::JMcParticles const& particles) + void processMCParticleSubstructure(soa::Filtered>::iterator const& jet, JetParticles const& particles) { double angularity = 0.0; for (auto& jetConstituents : jet.tracks_as()) { @@ -215,7 +215,7 @@ struct JetTutorialTask { } PROCESS_SWITCH(JetTutorialTask, processDataFull, "jets data", true); - void processDataFullSubstructure(soa::Filtered>::iterator const& jet, aod::JTracks const& tracks, aod::JClusters const& clusters) + void processDataFullSubstructure(soa::Filtered>::iterator const& jet, JetTracks const& tracks, JetClusters const& clusters) { // add aditional selection on jet eta registry.fill(HIST("h_full_jet_pt"), jet.pt()); @@ -224,11 +224,11 @@ struct JetTutorialTask { registry.fill(HIST("h_full_jet_ntracks"), jet.tracks().size()); registry.fill(HIST("h_full_jet_nclusters"), jet.clusters().size()); double angularity = 0.0; - for (auto& jetTrack : jet.tracks_as()) { + for (auto& jetTrack : jet.tracks_as()) { angularity += jetTrack.pt() * TMath::Sqrt(TMath::Power(jet.phi() - jetTrack.phi(), 2.0) + TMath::Power(jet.eta() - jetTrack.eta(), 2.0)); } - for (auto& jetCluster : jet.clusters_as()) { + for (auto& jetCluster : jet.clusters_as()) { angularity += jetCluster.energy() * TMath::Sqrt(TMath::Power(jet.phi() - jetCluster.phi(), 2.0) + TMath::Power(jet.eta() - jetCluster.eta(), 2.0)); } @@ -236,9 +236,9 @@ struct JetTutorialTask { } PROCESS_SWITCH(JetTutorialTask, processDataFullSubstructure, "jet substructure full jets", false); - void processDataRecoil(aod::JCollision const& collision, soa::Filtered const& jets, aod::JTracks const& tracks) + void processDataRecoil(JetCollision const& collision, soa::Filtered const& jets, JetTracks const& tracks) { - if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } double leadingTrackpT = 0.0; @@ -264,7 +264,7 @@ struct JetTutorialTask { } PROCESS_SWITCH(JetTutorialTask, processDataRecoil, "hadron-recoil jets", false); - void processDataBackgroundSubtracted(soa::Join::iterator const& collision, soa::Filtered const& jets) + /*void processDataBackgroundSubtracted(soa::Join::iterator const& collision, soa::Filtered const& jets) { for (auto jet : jets) { registry.fill(HIST("h_jet_pt"), jet.pt()); @@ -273,7 +273,7 @@ struct JetTutorialTask { registry.fill(HIST("h_jet_phi"), jet.phi()); } } - PROCESS_SWITCH(JetTutorialTask, processDataBackgroundSubtracted, "baackground subtracted jets", false); + PROCESS_SWITCH(JetTutorialTask, processDataBackgroundSubtracted, "baackground subtracted jets", false);*/ }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"jet-tutorial"})}; } diff --git a/PWGJE/Tasks/jetTutorialSkeleton.cxx b/PWGJE/Tasks/jetTutorialSkeleton.cxx index b27e86d6426..1c6139fb58d 100644 --- a/PWGJE/Tasks/jetTutorialSkeleton.cxx +++ b/PWGJE/Tasks/jetTutorialSkeleton.cxx @@ -77,8 +77,8 @@ struct JetTutorialSkeletonTask { void init(o2::framework::InitContext&) { - eventSelection = JetDerivedDataUtilities::initialiseEventSelection(static_cast(eventSelections)); - trackSelection = JetDerivedDataUtilities::initialiseTrackSelection(static_cast(trackSelections)); + eventSelection = jetderiveddatautilities::initialiseEventSelection(static_cast(eventSelections)); + trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); } Filter jetCuts = aod::jet::pt > jetPtMin&& aod::jet::r == nround(jetR.node() * 100.0f); @@ -148,10 +148,10 @@ struct JetTutorialSkeletonTask { } PROCESS_SWITCH(JetTutorialSkeletonTask, processDataRecoil, "hadron-recoil jets", false); - void processDataBackgroundSubtracted(soa::Join::iterator const& collision, soa::Filtered const& jets) + /*void processDataBackgroundSubtracted(soa::Join::iterator const& collision, soa::Filtered const& jets) { } - PROCESS_SWITCH(JetTutorialSkeletonTask, processDataBackgroundSubtracted, "baackground subtracted jets", false); + PROCESS_SWITCH(JetTutorialSkeletonTask, processDataBackgroundSubtracted, "baackground subtracted jets", false);*/ }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"jet-tutorial-skeleton"})}; } diff --git a/PWGJE/Tasks/jetfinderQA.cxx b/PWGJE/Tasks/jetfinderQA.cxx index b9792d1287a..598fd898fe8 100644 --- a/PWGJE/Tasks/jetfinderQA.cxx +++ b/PWGJE/Tasks/jetfinderQA.cxx @@ -14,6 +14,7 @@ /// \author Nima Zardoshti #include +#include #include "Framework/ASoA.h" #include "Framework/AnalysisDataModel.h" @@ -29,6 +30,7 @@ #include "PWGJE/Core/FastJetUtilities.h" #include "PWGJE/Core/JetFinder.h" +#include "PWGJE/Core/JetFindingUtilities.h" #include "PWGJE/DataModel/Jet.h" #include "PWGJE/Core/JetDerivedDataUtilities.h" @@ -46,6 +48,8 @@ struct JetFinderQATask { Configurable selectedJetsRadius{"selectedJetsRadius", 0.4, "resolution parameter for histograms without radius"}; Configurable eventSelections{"eventSelections", "sel8", "choose event selection"}; Configurable vertexZCut{"vertexZCut", 10.0f, "Accepted z-vertex range"}; + Configurable centralityMin{"centralityMin", -999.0, "minimum centrality"}; + Configurable centralityMax{"centralityMax", 999.0, "maximum centrality"}; Configurable> jetRadii{"jetRadii", std::vector{0.4}, "jet resolution parameters"}; Configurable trackEtaMin{"trackEtaMin", -0.9, "minimum eta acceptance for tracks"}; Configurable trackEtaMax{"trackEtaMax", 0.9, "maximum eta acceptance for tracks"}; @@ -55,8 +59,12 @@ struct JetFinderQATask { 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 pTHatExponent{"pTHatExponent", 6.0, "exponent of the event weight for the calculation of pTHat"}; - - std::vector filledJetR; + Configurable jetEtaMin{"jetEtaMin", -99.0, "minimum jet pseudorapidity"}; + Configurable jetEtaMax{"jetEtaMax", 99.0, "maximum jet pseudorapidity"}; + Configurable randomConeR{"randomConeR", 0.4, "size of random Cone for estimating background fluctuations"}; + std::vector filledJetR_Both; + std::vector filledJetR_Low; + std::vector filledJetR_High; std::vector jetRadiiValues; int eventSelection = -1; @@ -64,12 +72,14 @@ struct JetFinderQATask { void init(o2::framework::InitContext&) { - eventSelection = JetDerivedDataUtilities::initialiseEventSelection(static_cast(eventSelections)); - trackSelection = JetDerivedDataUtilities::initialiseTrackSelection(static_cast(trackSelections)); + eventSelection = jetderiveddatautilities::initialiseEventSelection(static_cast(eventSelections)); + trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); jetRadiiValues = (std::vector)jetRadii; for (std::size_t iJetRadius = 0; iJetRadius < jetRadiiValues.size(); iJetRadius++) { - filledJetR.push_back(0.0); + filledJetR_Both.push_back(0.0); + filledJetR_Low.push_back(0.0); + filledJetR_High.push_back(0.0); } auto jetRadiiBins = (std::vector)jetRadii; if (jetRadiiBins.size() > 1) { @@ -83,11 +93,16 @@ struct JetFinderQATask { registry.add("h_jet_eta", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}); registry.add("h_jet_phi", "jet #varphi;#varphi_{jet};entries", {HistType::kTH1F, {{160, -1.0, 7.}}}); registry.add("h_jet_ntracks", "jet N tracks;N_{jet tracks};entries", {HistType::kTH1F, {{200, -0.5, 199.5}}}); + registry.add("h2_centrality_jet_pt", "centrality vs #it{p}_{T,jet}; centrality; #it{p}_{T,jet} (GeV/#it{c})", {HistType::kTH2F, {{1200, -10.0, 110.0}, {200, 0., 200.}}}); + registry.add("h2_centrality_jet_eta", "centrality vs #eta_{jet}; centrality; #eta_{jet}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {100, -1.0, 1.0}}}); + registry.add("h2_centrality_jet_phi", "centrality vs #varphi_{jet}; centrality; #varphi_{jet}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {160, -1.0, 7.}}}); + registry.add("h2_centrality_jet_ntracks", "centrality vs N_{jet tracks}; centrality; N_{jet tracks}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_jet_pt_centrality", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});centrality", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {1200, -10.0, 110.0}}}); registry.add("h3_jet_r_jet_pt_jet_eta", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); registry.add("h3_jet_r_jet_pt_jet_phi", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); registry.add("h3_jet_r_jet_eta_jet_phi", "#it{R}_{jet};#eta_{jet};#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {160, -1.0, 7.}}}); - registry.add("h3_jet_r_jet_pt_jet_ntracks", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});N_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -0.5, 99.5}}}); - registry.add("h3_jet_r_jet_pt_jet_area", "#it{R}_{jet}; #it{p}_{T,jet} (GeV/#it{c}); #it{Area}_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {300, 0., 3.}}}); + registry.add("h3_jet_r_jet_pt_jet_ntracks", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});N_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_jet_pt_jet_area", "#it{R}_{jet}; #it{p}_{T,jet} (GeV/#it{c}); #it{area}_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {300, 0., 3.}}}); registry.add("h3_jet_r_jet_pt_track_pt", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#it{p}_{T,jet tracks} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); registry.add("h3_jet_r_jet_pt_track_eta", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); registry.add("h3_jet_r_jet_pt_track_phi", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); @@ -96,15 +111,63 @@ struct JetFinderQATask { registry.add("h_jet_ptcut", "p_{T} cut;p_{T,jet} (GeV/#it{c});N;entries", {HistType::kTH2F, {{200, 0, 200}, {20, 0, 5}}}); } + if (doprocessJetsRhoAreaSubData) { + + registry.add("h_jet_pt_rhoareasubtracted", "jet pT;#it{p}_{T,jet} (GeV/#it{c});entries", {HistType::kTH1F, {{200, 0., 200.}}}); + registry.add("h_jet_eta_rhoareasubtracted", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}); + registry.add("h_jet_phi_rhoareasubtracted", "jet #varphi;#varphi_{jet};entries", {HistType::kTH1F, {{160, -1.0, 7.}}}); + registry.add("h_jet_ntracks_rhoareasubtracted", "jet N tracks;N_{jet tracks};entries", {HistType::kTH1F, {{200, -0.5, 199.5}}}); + registry.add("h2_centrality_jet_pt_rhoareasubtracted", "centrality vs #it{p}_{T,jet}; centrality; #it{p}_{T,jet} (GeV/#it{c})", {HistType::kTH2F, {{1200, -10.0, 110.0}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_pt_centrality_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});centrality", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {1200, -10.0, 110.0}}}); + registry.add("h3_jet_r_jet_pt_jet_eta_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_pt_jet_phi_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_eta_jet_phi_rhoareasubtracted", "#it{R}_{jet};#eta_{jet};#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_pt_jet_ntracks_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});N_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_jet_pt_jet_area_rhoareasubtracted", "#it{R}_{jet}; #it{p}_{T,jet} (GeV/#it{c}); #it{area}_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {300, 0., 3.}}}); + registry.add("h3_jet_r_jet_pt_track_pt_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#it{p}_{T,jet tracks} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_pt_track_eta_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_pt_track_phi_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_pt_jet_pt_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#it{p}_{T,jet} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + } + + if (doprocessEvtWiseConstSubJetsData) { + registry.add("h_jet_pt_eventwiseconstituentsubtracted", "jet pT;#it{p}_{T,jet} (GeV/#it{c});entries", {HistType::kTH1F, {{200, 0., 200.}}}); + registry.add("h_jet_eta_eventwiseconstituentsubtracted", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}); + registry.add("h_jet_phi_eventwiseconstituentsubtracted", "jet #varphi;#varphi_{jet};entries", {HistType::kTH1F, {{160, -1.0, 7.}}}); + registry.add("h_jet_ntracks_eventwiseconstituentsubtracted", "jet N tracks;N_{jet tracks};entries", {HistType::kTH1F, {{200, -0.5, 199.5}}}); + registry.add("h2_centrality_jet_pt_eventwiseconstituentsubtracted", "centrality vs #it{p}_{T,jet}; centrality; #it{p}_{T,jet} (GeV/#it{c})", {HistType::kTH2F, {{1200, -10.0, 110.0}, {200, 0., 200.}}}); + registry.add("h2_centrality_jet_eta_eventwiseconstituentsubtracted", "centrality vs #eta_{jet}; centrality; #eta_{jet}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {100, -1.0, 1.0}}}); + registry.add("h2_centrality_jet_phi_eventwiseconstituentsubtracted", "centrality vs #varphi_{jet}; centrality; #varphi_{jet}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {160, -1.0, 7.}}}); + registry.add("h2_centrality_jet_ntracks_eventwiseconstituentsubtracted", "centrality vs N_{jet tracks}; centrality; N_{jet tracks}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_jet_pt_centrality_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});centrality", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {1200, -10.0, 110.0}}}); + registry.add("h3_jet_r_jet_pt_jet_eta_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_pt_jet_phi_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_eta_jet_phi_eventwiseconstituentsubtracted", "#it{R}_{jet};#eta_{jet};#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_pt_jet_ntracks_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});N_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_jet_pt_jet_area_eventwiseconstituentsubtracted", "#it{R}_{jet}; #it{p}_{T,jet} (GeV/#it{c}); #it{area}_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {300, 0., 3.}}}); + registry.add("h3_jet_r_jet_pt_track_pt_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#it{p}_{T,jet tracks} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_pt_track_eta_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_pt_track_phi_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + } + + if (doprocessRho) { + registry.add("h2_centrality_ntracks", "; centrality; N_{tracks};", {HistType::kTH2F, {{1100, 0., 110.0}, {10000, 0.0, 10000.0}}}); + registry.add("h2_ntracks_rho", "; N_{tracks}; #it{rho} (GeV/area);", {HistType::kTH2F, {{10000, 0.0, 10000.0}, {400, 0.0, 400.0}}}); + registry.add("h2_ntracks_rhom", "; N_{tracks}; #it{rho}_{m} (GeV/area);", {HistType::kTH2F, {{10000, 0.0, 10000.0}, {100, 0.0, 100.0}}}); + registry.add("h2_centrality_rho", "; centrality; #it{rho} (GeV/area);", {HistType::kTH2F, {{1100, 0., 110.}, {400, 0., 400.0}}}); + registry.add("h2_centrality_rhom", ";centrality; #it{rho}_{m} (GeV/area)", {HistType::kTH2F, {{1100, 0., 110.}, {100, 0., 100.0}}}); + registry.add("h2_centrality_rhoRandomCone", "; centrality; #it{p}_{T,random cone} - #it{area, random cone} * #it{rho} (GeV/c);", {HistType::kTH2F, {{1100, 0., 110.}, {400, -200.0, 200.0}}}); + } + if (doprocessJetsMCP || doprocessJetsMCPWeighted) { registry.add("h_jet_pt_part", "jet pT;#it{p}_{T,jet}^{part}(GeV/#it{c});entries", {HistType::kTH1F, {{200, 0., 200.}}}); registry.add("h_jet_eta_part", "jet #eta;#eta_{jet}^{part};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}); registry.add("h_jet_phi_part", "jet #varphi;#varphi_{jet}^{part};entries", {HistType::kTH1F, {{160, -1.0, 7.}}}); - registry.add("h_jet_ntracks_part", "jet N tracks;N_{jet tracks}^{part};entries", {HistType::kTH1F, {{100, -0.5, 99.5}}}); + registry.add("h_jet_ntracks_part", "jet N tracks;N_{jet tracks}^{part};entries", {HistType::kTH1F, {{200, -0.5, 199.5}}}); registry.add("h3_jet_r_part_jet_pt_part_jet_eta_part", ";#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});#eta_{jet}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); registry.add("h3_jet_r_part_jet_pt_part_jet_phi_part", ";#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});#varphi_{jet}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); registry.add("h3_jet_r_part_jet_eta_part_jet_phi_part", ";#it{R}_{jet}^{part};#eta_{jet}^{part};#varphi_{jet}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {160, -1.0, 7.}}}); - registry.add("h3_jet_r_part_jet_pt_part_jet_ntracks_part", "#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});N_{jet tracks}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -0.5, 99.5}}}); + registry.add("h3_jet_r_part_jet_pt_part_jet_ntracks_part", "#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});N_{jet tracks}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, -0.5, 199.5}}}); registry.add("h3_jet_r_part_jet_pt_part_track_pt_part", "#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});#it{p}_{T,jet tracks}^{part} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); registry.add("h3_jet_r_part_jet_pt_part_track_eta_part", "#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});#eta_{jet tracks}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); registry.add("h3_jet_r_part_jet_pt_part_track_phi_part", "#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});#varphi_{jet tracks}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); @@ -112,17 +175,39 @@ struct JetFinderQATask { registry.add("h_jet_ptcut_part", "p_{T} cut;p_{T,jet}^{part} (GeV/#it{c});N;entries", {HistType::kTH2F, {{200, 0, 200}, {20, 0, 5}}}); } - if (doprocessJetsMCPMCDMatched || doprocessJetsMCPMCDMatchedWeighted) { - registry.add("h3_jet_r_jet_pt_part_jet_pt", "#it{R}_{jet};#it{p}_{T,jet}^{part} (GeV/#it{c});#it{p}_{T,jet} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); - registry.add("h3_jet_r_jet_eta_part_jet_eta", "#it{R}_{jet};#eta_{jet}^{part};#eta_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); - registry.add("h3_jet_r_jet_phi_part_jet_phi", "#it{R}_{jet};#varphi_{jet}^{part};#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); - registry.add("h3_jet_r_jet_ntracks_part_jet_ntracks", "#it{R}_{jet};N_{jet tracks}^{part};N_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -0.5, 99.5}, {100, -0.5, 99.5}}}); - registry.add("h3_jet_r_jet_pt_part_jet_pt_diff", "#it{R}_{jet};#it{p}_{T,jet}^{part} (GeV/#it{c}); (#it{p}_{T,jet}^{part} (GeV/#it{c}) - #it{p}_{T,jet} (GeV/#it{c})) / #it{p}_{T,jet}^{part} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); - registry.add("h3_jet_r_jet_pt_part_jet_eta_diff", "#it{R}_{jet};#it{p}_{T,jet}^{part} (GeV/#it{c}); (#eta_{jet}^{part} - #eta_{jet}) / #eta_{jet}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); - registry.add("h3_jet_r_jet_pt_part_jet_phi_diff", "#it{R}_{jet};#it{p}_{T,jet}^{part} (GeV/#it{c}); (#varphi_{jet}^{part} - #varphi_{jet}) / #varphi_{jet}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); - registry.add("h3_jet_pt_part_jet_eta_part_jet_eta", ";#it{p}_{T,jet}^{part} (GeV/#it{c}); #eta_{jet}^{part}; #eta_{jet}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); - registry.add("h3_jet_pt_part_jet_phi_part_jet_phi", ";#it{p}_{T,jet}^{part} (GeV/#it{c}); #varphi_{jet}^{part}; #varphi_{jet}", {HistType::kTH3F, {{200, 0.0, 200}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); - registry.add("h3_jet_pt_part_jet_ntracks_part_jet_ntracks", ";#it{p}_{T,jet}^{part} (GeV/#it{c}); N_{jet tracks}^{part}; N_{jet tracks}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -0.5, 99.5}, {100, -0.5, 99.5}}}); + if (doprocessJetsMCPMCDMatched || doprocessJetsMCPMCDMatchedWeighted || doprocessJetsSubMatched) { + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_matchedgeo", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c});#it{p}_{T,jet}^{base} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_eta_tag_jet_eta_base_matchedgeo", "#it{R}_{jet};#eta_{jet}^{tag};#eta_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_phi_tag_jet_phi_base_matchedgeo", "#it{R}_{jet};#varphi_{jet}^{tag};#varphi_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedgeo", "#it{R}_{jet};N_{jet tracks}^{tag};N_{jet tracks}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedgeo", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#it{p}_{T,jet}^{tag} (GeV/#it{c}) - #it{p}_{T,jet}^{base} (GeV/#it{c})) / #it{p}_{T,jet}^{tag} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedgeo", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#eta_{jet}^{tag} - #eta_{jet}^{base}) / #eta_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedgeo", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#varphi_{jet}^{tag} - #varphi_{jet}^{base}) / #varphi_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedgeo", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #eta_{jet}^{tag}; #eta_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedgeo", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #varphi_{jet}^{tag}; #varphi_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedgeo", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); N_{jet tracks}^{tag}; N_{jet tracks}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_matchedpt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c});#it{p}_{T,jet}^{base} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_eta_tag_jet_eta_base_matchedpt", "#it{R}_{jet};#eta_{jet}^{tag};#eta_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_phi_tag_jet_phi_base_matchedpt", "#it{R}_{jet};#varphi_{jet}^{tag};#varphi_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedpt", "#it{R}_{jet};N_{jet tracks}^{tag};N_{jet tracks}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedpt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#it{p}_{T,jet}^{tag} (GeV/#it{c}) - #it{p}_{T,jet}^{base} (GeV/#it{c})) / #it{p}_{T,jet}^{tag} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedpt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#eta_{jet}^{tag} - #eta_{jet}^{base}) / #eta_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedpt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#varphi_{jet}^{tag} - #varphi_{jet}^{base}) / #varphi_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedpt", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #eta_{jet}^{tag}; #eta_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedpt", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #varphi_{jet}^{tag}; #varphi_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedpt", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); N_{jet tracks}^{tag}; N_{jet tracks}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_matchedgeopt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c});#it{p}_{T,jet}^{base} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_eta_tag_jet_eta_base_matchedgeopt", "#it{R}_{jet};#eta_{jet}^{tag};#eta_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_phi_tag_jet_phi_base_matchedgeopt", "#it{R}_{jet};#varphi_{jet}^{tag};#varphi_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedgeopt", "#it{R}_{jet};N_{jet tracks}^{tag};N_{jet tracks}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedgeopt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#it{p}_{T,jet}^{tag} (GeV/#it{c}) - #it{p}_{T,jet}^{base} (GeV/#it{c})) / #it{p}_{T,jet}^{tag} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedgeopt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#eta_{jet}^{tag} - #eta_{jet}^{base}) / #eta_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedgeopt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#varphi_{jet}^{tag} - #varphi_{jet}^{base}) / #varphi_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedgeopt", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #eta_{jet}^{tag}; #eta_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedgeopt", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #varphi_{jet}^{tag}; #varphi_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedgeopt", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); N_{jet tracks}^{tag}; N_{jet tracks}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); } if (doprocessTriggeredData) { @@ -168,6 +253,12 @@ struct JetFinderQATask { registry.add("h_collisions_weighted", "event status;event status;entries", {HistType::kTH1F, {{4, 0.0, 4.0}}}); } } + if (doprocessTracksSub) { + + registry.add("h_track_pt_eventwiseconstituentsubtracted", "track pT;#it{p}_{T,track} (GeV/#it{c});entries", {HistType::kTH1F, {{200, 0., 200.}}}); + registry.add("h_track_eta_eventwiseconstituentsubtracted", "track #eta;#eta_{track};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}); + registry.add("h_track_phi_eventwiseconstituentsubtracted", "track #varphi;#varphi_{track};entries", {HistType::kTH1F, {{160, -1.0, 7.}}}); + } if (doprocessMCCollisionsWeighted) { AxisSpec weightAxis = {{VARIABLE_WIDTH, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1.0, 10.0}, "weights"}; @@ -175,13 +266,12 @@ struct JetFinderQATask { } } - using JetTracks = aod::JTracks; - using JetParticles = aod::JMcParticles; - Filter trackCuts = (aod::jtrack::pt >= trackPtMin && aod::jtrack::pt < trackPtMax && aod::jtrack::eta > trackEtaMin && aod::jtrack::eta < trackEtaMax); + Filter trackSubCuts = (aod::jtracksub::pt >= trackPtMin && aod::jtracksub::pt < trackPtMax && aod::jtracksub::eta > trackEtaMin && aod::jtracksub::eta < trackEtaMax); + Filter eventCuts = (nabs(aod::jcollision::posZ) < vertexZCut && aod::jcollision::centrality >= centralityMin && aod::jcollision::centrality < centralityMax); template - void fillHistograms(T const& jet, float weight = 1.0) + void fillHistograms(T const& jet, float centrality, float weight = 1.0) { float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); @@ -194,8 +284,13 @@ struct JetFinderQATask { registry.fill(HIST("h_jet_eta"), jet.eta(), weight); registry.fill(HIST("h_jet_phi"), jet.phi(), weight); registry.fill(HIST("h_jet_ntracks"), jet.tracks().size(), weight); + registry.fill(HIST("h2_centrality_jet_pt"), centrality, jet.pt(), weight); + registry.fill(HIST("h2_centrality_jet_eta"), centrality, jet.eta(), weight); + registry.fill(HIST("h2_centrality_jet_phi"), centrality, jet.phi(), weight); + registry.fill(HIST("h2_centrality_jet_ntracks"), centrality, jet.tracks().size(), weight); } + registry.fill(HIST("h3_jet_r_jet_pt_centrality"), jet.r() / 100.0, jet.pt(), centrality, weight); registry.fill(HIST("h3_jet_r_jet_pt_jet_eta"), jet.r() / 100.0, jet.pt(), jet.eta(), weight); registry.fill(HIST("h3_jet_r_jet_pt_jet_phi"), jet.r() / 100.0, jet.pt(), jet.phi(), weight); registry.fill(HIST("h3_jet_r_jet_eta_jet_phi"), jet.r() / 100.0, jet.eta(), jet.phi(), weight); @@ -210,6 +305,62 @@ struct JetFinderQATask { } } + template + void fillRhoAreaSubtractedHistograms(T const& jet, float centrality, float rho, float weight = 1.0) + { + if (jet.r() == round(selectedJetsRadius * 100.0f)) { + registry.fill(HIST("h_jet_pt_rhoareasubtracted"), jet.pt() - (rho * jet.area()), weight); + registry.fill(HIST("h_jet_eta_rhoareasubtracted"), jet.eta(), weight); + registry.fill(HIST("h_jet_phi_rhoareasubtracted"), jet.phi(), weight); + registry.fill(HIST("h_jet_ntracks_rhoareasubtracted"), jet.tracks().size(), weight); + registry.fill(HIST("h2_centrality_jet_pt_rhoareasubtracted"), centrality, jet.pt() - (rho * jet.area()), weight); + } + + registry.fill(HIST("h3_jet_r_jet_pt_centrality_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), centrality, weight); + registry.fill(HIST("h3_jet_r_jet_pt_jet_eta_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), jet.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_jet_phi_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), jet.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_eta_jet_phi_rhoareasubtracted"), jet.r() / 100.0, jet.eta(), jet.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_jet_ntracks_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), jet.tracks().size(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_jet_area_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), jet.area(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_jet_pt_rhoareasubtracted"), jet.r() / 100.0, jet.pt(), jet.pt() - (rho * jet.area()), weight); + + for (auto& constituent : jet.template tracks_as()) { + + registry.fill(HIST("h3_jet_r_jet_pt_track_pt_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), constituent.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_track_eta_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), constituent.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_track_phi_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), constituent.phi(), weight); + } + } + + template + void fillEventWiseConstituentSubtractedHistograms(T const& jet, float centrality, float weight = 1.0) + { + if (jet.r() == round(selectedJetsRadius * 100.0f)) { + registry.fill(HIST("h_jet_pt_eventwiseconstituentsubtracted"), jet.pt(), weight); + registry.fill(HIST("h_jet_eta_eventwiseconstituentsubtracted"), jet.eta(), weight); + registry.fill(HIST("h_jet_phi_eventwiseconstituentsubtracted"), jet.phi(), weight); + registry.fill(HIST("h_jet_ntracks_eventwiseconstituentsubtracted"), jet.tracks().size(), weight); + registry.fill(HIST("h2_centrality_jet_pt_eventwiseconstituentsubtracted"), centrality, jet.pt(), weight); + registry.fill(HIST("h2_centrality_jet_eta_eventwiseconstituentsubtracted"), centrality, jet.eta(), weight); + registry.fill(HIST("h2_centrality_jet_phi_eventwiseconstituentsubtracted"), centrality, jet.phi(), weight); + registry.fill(HIST("h2_centrality_jet_ntracks_eventwiseconstituentsubtracted"), centrality, jet.tracks().size(), weight); + } + + registry.fill(HIST("h3_jet_r_jet_pt_centrality_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), centrality, weight); + registry.fill(HIST("h3_jet_r_jet_pt_jet_eta_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), jet.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_jet_phi_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), jet.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_eta_jet_phi_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.eta(), jet.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_jet_ntracks_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), jet.tracks().size(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_jet_area_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), jet.area(), weight); + + for (auto& constituent : jet.template tracks_as()) { + + registry.fill(HIST("h3_jet_r_jet_pt_track_pt_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), constituent.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_track_eta_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), constituent.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_track_phi_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), constituent.phi(), weight); + } + } + template void fillMCPHistograms(T const& jet, float weight = 1.0) { @@ -240,39 +391,85 @@ struct JetFinderQATask { } template - void fillMCMatchedHistograms(T const& mcdjet, float weight = 1.0) + void fillMatchedHistograms(T const& jetBase, float weight = 1.0) { float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); - if (mcdjet.pt() > pTHatMaxMCD * pTHat) { + if (jetBase.pt() > pTHatMaxMCD * pTHat) { return; } - for (auto& mcpjet : mcdjet.template matchedJetGeo_as>()) { - - if (mcpjet.pt() > pTHatMaxMCP * pTHat) { - continue; + if (jetBase.has_matchedJetGeo()) { + for (auto& jetTag : jetBase.template matchedJetGeo_as>()) { + if (jetTag.pt() > pTHatMaxMCP * pTHat) { + continue; + } + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_matchedgeo"), jetBase.r() / 100.0, jetTag.pt(), jetBase.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_eta_tag_jet_eta_base_matchedgeo"), jetBase.r() / 100.0, jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_phi_tag_jet_phi_base_matchedgeo"), jetBase.r() / 100.0, jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedgeo"), jetBase.r() / 100.0, jetTag.tracks().size(), jetBase.tracks().size(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedgeo"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.pt() - jetBase.pt()) / jetTag.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedgeo"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.eta() - jetBase.eta()) / jetTag.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedgeo"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.phi() - jetBase.phi()) / jetTag.phi(), weight); + + if (jetBase.r() == round(selectedJetsRadius * 100.0f)) { + registry.fill(HIST("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedgeo"), jetTag.pt(), jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedgeo"), jetTag.pt(), jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedgeo"), jetTag.pt(), jetTag.tracks().size(), jetBase.tracks().size(), weight); + } } + } + if (jetBase.has_matchedJetPt()) { + for (auto& jetTag : jetBase.template matchedJetPt_as>()) { + if (jetTag.pt() > pTHatMaxMCP * pTHat) { + continue; + } + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_matchedpt"), jetBase.r() / 100.0, jetTag.pt(), jetBase.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_eta_tag_jet_eta_base_matchedpt"), jetBase.r() / 100.0, jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_phi_tag_jet_phi_base_matchedpt"), jetBase.r() / 100.0, jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedpt"), jetBase.r() / 100.0, jetTag.tracks().size(), jetBase.tracks().size(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedpt"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.pt() - jetBase.pt()) / jetTag.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedpt"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.eta() - jetBase.eta()) / jetTag.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedpt"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.phi() - jetBase.phi()) / jetTag.phi(), weight); + + if (jetBase.r() == round(selectedJetsRadius * 100.0f)) { + registry.fill(HIST("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedpt"), jetTag.pt(), jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedpt"), jetTag.pt(), jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedpt"), jetTag.pt(), jetTag.tracks().size(), jetBase.tracks().size(), weight); + } + } + } + + if (jetBase.has_matchedJetGeo() && jetBase.has_matchedJetPt()) { - registry.fill(HIST("h3_jet_r_jet_pt_part_jet_pt"), mcdjet.r() / 100.0, mcpjet.pt(), mcdjet.pt(), weight); - registry.fill(HIST("h3_jet_r_jet_eta_part_jet_eta"), mcdjet.r() / 100.0, mcpjet.eta(), mcdjet.eta(), weight); - registry.fill(HIST("h3_jet_r_jet_phi_part_jet_phi"), mcdjet.r() / 100.0, mcpjet.phi(), mcdjet.phi(), weight); - registry.fill(HIST("h3_jet_r_jet_ntracks_part_jet_ntracks"), mcdjet.r() / 100.0, mcpjet.tracks().size(), mcdjet.tracks().size(), weight); - registry.fill(HIST("h3_jet_r_jet_pt_part_jet_pt_diff"), mcdjet.r() / 100.0, mcpjet.pt(), (mcpjet.pt() - mcdjet.pt()) / mcpjet.pt(), weight); - registry.fill(HIST("h3_jet_r_jet_pt_part_jet_eta_diff"), mcdjet.r() / 100.0, mcpjet.pt(), (mcpjet.eta() - mcdjet.eta()) / mcpjet.eta(), weight); - registry.fill(HIST("h3_jet_r_jet_pt_part_jet_phi_diff"), mcdjet.r() / 100.0, mcpjet.pt(), (mcpjet.phi() - mcdjet.phi()) / mcpjet.phi(), weight); - - if (mcdjet.r() == round(selectedJetsRadius * 100.0f)) { - registry.fill(HIST("h3_jet_pt_part_jet_eta_part_jet_eta"), mcpjet.pt(), mcpjet.eta(), mcdjet.eta(), weight); - registry.fill(HIST("h3_jet_pt_part_jet_phi_part_jet_phi"), mcpjet.pt(), mcpjet.phi(), mcdjet.phi(), weight); - registry.fill(HIST("h3_jet_pt_part_jet_ntracks_part_jet_ntracks"), mcpjet.pt(), mcpjet.tracks().size(), mcdjet.tracks().size(), weight); + for (auto& jetTag : jetBase.template matchedJetGeo_as>()) { + if (jetTag.pt() > pTHatMaxMCP * pTHat) { + continue; + } + + if (jetBase.template matchedJetGeo_first_as>().globalIndex() == jetBase.template matchedJetPt_first_as>().globalIndex()) { // not a good way to do this + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_matchedgeopt"), jetBase.r() / 100.0, jetTag.pt(), jetBase.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_eta_tag_jet_eta_base_matchedgeopt"), jetBase.r() / 100.0, jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_phi_tag_jet_phi_base_matchedgeopt"), jetBase.r() / 100.0, jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedgeopt"), jetBase.r() / 100.0, jetTag.tracks().size(), jetBase.tracks().size(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedgeopt"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.pt() - jetBase.pt()) / jetTag.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedgeopt"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.eta() - jetBase.eta()) / jetTag.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedgeopt"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.phi() - jetBase.phi()) / jetTag.phi(), weight); + + if (jetBase.r() == round(selectedJetsRadius * 100.0f)) { + registry.fill(HIST("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedgeopt"), jetTag.pt(), jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedgeopt"), jetTag.pt(), jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedgeopt"), jetTag.pt(), jetTag.tracks().size(), jetBase.tracks().size(), weight); + } + } } } } - void fillTrackHistograms(soa::Filtered const& tracks, float weight = 1.0) + template + void fillTrackHistograms(T const& tracks, float weight = 1.0) { for (auto const& track : tracks) { - if (!JetDerivedDataUtilities::selectTrack(track, trackSelection)) { + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { continue; } registry.fill(HIST("h_track_pt"), track.pt(), weight); @@ -281,39 +478,60 @@ struct JetFinderQATask { } } - void processJetsData(soa::Join::iterator const& jet, JetTracks const& tracks) + void processJetsData(soa::Filtered::iterator const& collision, soa::Join const& jets, JetTracks const& tracks) { - fillHistograms(jet); + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + fillHistograms(jet, collision.centrality()); + } } PROCESS_SWITCH(JetFinderQATask, processJetsData, "jet finder QA data", false); - void processJetsMCD(soa::Join::iterator const& jet, JetTracks const& tracks) + void processJetsMCD(soa::Filtered::iterator const& collision, soa::Join const& jets, JetTracks const& tracks) { - fillHistograms(jet); + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + fillHistograms(jet, collision.centrality()); + } } PROCESS_SWITCH(JetFinderQATask, processJetsMCD, "jet finder QA mcd", false); - void processJetsMCDWeighted(soa::Join::iterator const& jet, JetTracks const& tracks) + void processJetsMCDWeighted(soa::Filtered::iterator const& collision, soa::Join const& jets, JetTracks const& tracks) { - double pTHat = 10. / (std::pow(jet.eventWeight(), 1.0 / 6.0)); - for (int N = 1; N < 21; N++) { - if (jet.pt() < N * 0.25 * pTHat && jet.r() == round(selectedJetsRadius * 100.0f)) { - registry.fill(HIST("h_jet_ptcut"), jet.pt(), N * 0.25, jet.eventWeight()); + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; } + double pTHat = 10. / (std::pow(jet.eventWeight(), 1.0 / 6.0)); + for (int N = 1; N < 21; N++) { + if (jet.pt() < N * 0.25 * pTHat && jet.r() == round(selectedJetsRadius * 100.0f)) { + registry.fill(HIST("h_jet_ptcut"), jet.pt(), N * 0.25, jet.eventWeight()); + } + } + registry.fill(HIST("h_jet_phat"), pTHat); + fillHistograms(jet, collision.centrality(), jet.eventWeight()); } - registry.fill(HIST("h_jet_phat"), pTHat); - fillHistograms(jet, jet.eventWeight()); } PROCESS_SWITCH(JetFinderQATask, processJetsMCDWeighted, "jet finder QA mcd with weighted events", false); void processJetsMCP(soa::Join::iterator const& jet, JetParticles const& particles) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + return; + } fillMCPHistograms(jet); } PROCESS_SWITCH(JetFinderQATask, processJetsMCP, "jet finder QA mcp", false); void processJetsMCPWeighted(soa::Join::iterator const& jet, JetParticles const& particles) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + return; + } double pTHat = 10. / (std::pow(jet.eventWeight(), 1.0 / 6.0)); for (int N = 1; N < 21; N++) { if (jet.pt() < N * 0.25 * pTHat && jet.r() == round(selectedJetsRadius * 100.0f)) { @@ -325,69 +543,104 @@ struct JetFinderQATask { } PROCESS_SWITCH(JetFinderQATask, processJetsMCPWeighted, "jet finder QA mcp with weighted events", false); - void processJetsMCPMCDMatched(aod::JCollision const& collision, + void processJetsMCPMCDMatched(soa::Filtered::iterator const& collision, soa::Join const& mcdjets, soa::Join const& mcpjets, JetTracks const& tracks, JetParticles const& particles) { for (const auto& mcdjet : mcdjets) { - fillMCMatchedHistograms::iterator, soa::Join>(mcdjet); + if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + fillMatchedHistograms::iterator, soa::Join>(mcdjet); } } PROCESS_SWITCH(JetFinderQATask, processJetsMCPMCDMatched, "jet finder QA matched mcp and mcd", false); - void processJetsMCPMCDMatchedWeighted(aod::JCollision const& collision, + void processJetsMCPMCDMatchedWeighted(soa::Filtered::iterator const& collision, soa::Join const& mcdjets, soa::Join const& mcpjets, JetTracks const& tracks, JetParticles const& particles) { for (const auto& mcdjet : mcdjets) { - fillMCMatchedHistograms::iterator, soa::Join>(mcdjet, mcdjet.eventWeight()); + if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + fillMatchedHistograms::iterator, soa::Join>(mcdjet, mcdjet.eventWeight()); } } PROCESS_SWITCH(JetFinderQATask, processJetsMCPMCDMatchedWeighted, "jet finder QA matched mcp and mcd with weighted events", false); - void processMCCollisionsWeighted(aod::McCollision const& collision) + void processJetsSubMatched(soa::Filtered::iterator const& collision, + soa::Join const& jets, + soa::Join const& jetSubs, + JetTracks const& tracks, JetTracksSub const& tracksSub) + { + for (const auto& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + fillMatchedHistograms::iterator, soa::Join>(jet); + } + } + PROCESS_SWITCH(JetFinderQATask, processJetsSubMatched, "jet finder QA matched unsubtracted and constituent subtracted jets", false); + + void processMCCollisionsWeighted(JetMcCollision const& collision) { registry.fill(HIST("h_collision_eventweight_part"), collision.weight()); } PROCESS_SWITCH(JetFinderQATask, processMCCollisionsWeighted, "collision QA for weighted events", false); - void processTriggeredData(soa::Join::iterator const& collision, + void processTriggeredData(soa::Join::iterator const& collision, soa::Join const& jets, - JetTracks const& tracks) + soa::Filtered const& tracks) { registry.fill(HIST("h_collision_trigger_events"), 0.5); // all events if (collision.posZ() > vertexZCut) { return; } registry.fill(HIST("h_collision_trigger_events"), 1.5); // all events with z vertex cut - if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } registry.fill(HIST("h_collision_trigger_events"), 2.5); // events with sel8() - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow)) { registry.fill(HIST("h_collision_trigger_events"), 3.5); // events with high pT triggered jets } - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) { registry.fill(HIST("h_collision_trigger_events"), 4.5); // events with high pT triggered jets } - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow) && JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow) && jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) { registry.fill(HIST("h_collision_trigger_events"), 5.5); // events with high pT triggered jets } for (std::size_t iJetRadius = 0; iJetRadius < jetRadiiValues.size(); iJetRadius++) { - filledJetR[iJetRadius] = false; + filledJetR_Both[iJetRadius] = false; + filledJetR_Low[iJetRadius] = false; + filledJetR_High[iJetRadius] = false; } for (auto& jet : jets) { for (std::size_t iJetRadius = 0; iJetRadius < jetRadiiValues.size(); iJetRadius++) { - if (jet.r() == round(jetRadiiValues[iJetRadius] * 100.0f) && !filledJetR[iJetRadius]) { - filledJetR[iJetRadius] = true; - for (double pt = 0.0; pt <= jet.pt(); pt += 1.0) { - registry.fill(HIST("h2_jet_r_jet_pT_triggered"), jet.r() / 100.0, pt); + if (jet.r() == round(jetRadiiValues[iJetRadius] * 100.0f)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow) && !filledJetR_Low[iJetRadius]) { + filledJetR_Low[iJetRadius] = true; + for (double pt = 0.0; pt <= jet.pt(); pt += 1.0) { + registry.fill(HIST("h2_jet_r_jet_pT_triggered_Low"), jet.r() / 100.0, pt); + } + } + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh) && !filledJetR_High[iJetRadius]) { + filledJetR_High[iJetRadius] = true; + for (double pt = 0.0; pt <= jet.pt(); pt += 1.0) { + registry.fill(HIST("h2_jet_r_jet_pT_triggered_High"), jet.r() / 100.0, pt); + } + } + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow) && jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh) && !filledJetR_Both[iJetRadius]) { + filledJetR_Both[iJetRadius] = true; + for (double pt = 0.0; pt <= jet.pt(); pt += 1.0) { + registry.fill(HIST("h2_jet_r_jet_pT_triggered_Both"), jet.r() / 100.0, pt); + } } - break; } } @@ -399,17 +652,17 @@ struct JetFinderQATask { registry.fill(HIST("h3_jet_r_jet_eta_collision"), jet.r() / 100.0, jet.eta(), 0.0); registry.fill(HIST("h3_jet_r_jet_phi_collision"), jet.r() / 100.0, jet.phi(), 0.0); - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow)) { registry.fill(HIST("h3_jet_r_jet_pt_collision"), jet.r() / 100.0, jet.pt(), 1.0); registry.fill(HIST("h3_jet_r_jet_eta_collision"), jet.r() / 100.0, jet.eta(), 1.0); registry.fill(HIST("h3_jet_r_jet_phi_collision"), jet.r() / 100.0, jet.phi(), 1.0); } - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) { registry.fill(HIST("h3_jet_r_jet_pt_collision"), jet.r() / 100.0, jet.pt(), 2.0); registry.fill(HIST("h3_jet_r_jet_eta_collision"), jet.r() / 100.0, jet.eta(), 2.0); registry.fill(HIST("h3_jet_r_jet_phi_collision"), jet.r() / 100.0, jet.phi(), 2.0); } - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow) && JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow) && jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) { registry.fill(HIST("h3_jet_r_jet_pt_collision"), jet.r() / 100.0, jet.pt(), 3.0); registry.fill(HIST("h3_jet_r_jet_eta_collision"), jet.r() / 100.0, jet.eta(), 3.0); registry.fill(HIST("h3_jet_r_jet_phi_collision"), jet.r() / 100.0, jet.phi(), 3.0); @@ -420,17 +673,17 @@ struct JetFinderQATask { registry.fill(HIST("h3_jet_r_jet_pt_track_eta_MB"), jet.r() / 100.0, jet.pt(), constituent.eta()); registry.fill(HIST("h3_jet_r_jet_pt_track_phi_MB"), jet.r() / 100.0, jet.pt(), constituent.phi()); - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow)) { registry.fill(HIST("h3_jet_r_jet_pt_track_pt_Triggered_Low"), jet.r() / 100.0, jet.pt(), constituent.pt()); registry.fill(HIST("h3_jet_r_jet_pt_track_eta_Triggered_Low"), jet.r() / 100.0, jet.pt(), constituent.eta()); registry.fill(HIST("h3_jet_r_jet_pt_track_phi_Triggered_Low"), jet.r() / 100.0, jet.pt(), constituent.phi()); } - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) { registry.fill(HIST("h3_jet_r_jet_pt_track_pt_Triggered_High"), jet.r() / 100.0, jet.pt(), constituent.pt()); registry.fill(HIST("h3_jet_r_jet_pt_track_eta_Triggered_High"), jet.r() / 100.0, jet.pt(), constituent.eta()); registry.fill(HIST("h3_jet_r_jet_pt_track_phi_Triggered_High"), jet.r() / 100.0, jet.pt(), constituent.phi()); } - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow) && JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow) && jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) { registry.fill(HIST("h3_jet_r_jet_pt_track_pt_Triggered_Both"), jet.r() / 100.0, jet.pt(), constituent.pt()); registry.fill(HIST("h3_jet_r_jet_pt_track_eta_Triggered_Both"), jet.r() / 100.0, jet.pt(), constituent.eta()); registry.fill(HIST("h3_jet_r_jet_pt_track_phi_Triggered_Both"), jet.r() / 100.0, jet.pt(), constituent.phi()); @@ -439,24 +692,24 @@ struct JetFinderQATask { } for (auto& track : tracks) { - if (!JetDerivedDataUtilities::selectTrack(track, trackSelection) || !JetDerivedDataUtilities::applyTrackKinematics(track, trackPtMin, trackPtMax, trackEtaMin, trackEtaMax)) { + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { continue; } registry.fill(HIST("h_track_pt_MB"), track.pt()); registry.fill(HIST("h_track_eta_MB"), track.eta()); registry.fill(HIST("h_track_phi_MB"), track.phi()); - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow)) { registry.fill(HIST("h_track_pt_Triggered_Low"), track.pt()); registry.fill(HIST("h_track_eta_Triggered_Low"), track.eta()); registry.fill(HIST("h_track_phi_Triggered_Low"), track.phi()); } - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) { registry.fill(HIST("h_track_pt_Triggered_High"), track.pt()); registry.fill(HIST("h_track_eta_Triggered_High"), track.eta()); registry.fill(HIST("h_track_phi_Triggered_High"), track.phi()); } - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow) && JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow) && jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) { registry.fill(HIST("h_track_pt_Triggered_Both"), track.pt()); registry.fill(HIST("h_track_eta_Triggered_Both"), track.eta()); registry.fill(HIST("h_track_phi_Triggered_Both"), track.phi()); @@ -465,11 +718,11 @@ struct JetFinderQATask { } PROCESS_SWITCH(JetFinderQATask, processTriggeredData, "QA for charged jet trigger", false); - void processTracks(aod::JCollision const& collision, + void processTracks(soa::Filtered::iterator const& collision, soa::Filtered const& tracks) { registry.fill(HIST("h_collisions"), 0.5); - if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } registry.fill(HIST("h_collisions"), 1.5); @@ -477,14 +730,14 @@ struct JetFinderQATask { } PROCESS_SWITCH(JetFinderQATask, processTracks, "QA for charged tracks", false); - void processTracksWeighted(soa::Join::iterator const& collision, - aod::JMcCollisions const& mcCollisions, + void processTracksWeighted(soa::Join::iterator const& collision, + JetMcCollisions const& mcCollisions, soa::Filtered const& tracks) { float eventWeight = collision.mcCollision().weight(); registry.fill(HIST("h_collisions"), 0.5); registry.fill(HIST("h_collisions_weighted"), 0.5, eventWeight); - if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } registry.fill(HIST("h_collisions"), 1.5); @@ -492,6 +745,70 @@ struct JetFinderQATask { fillTrackHistograms(tracks, eventWeight); } PROCESS_SWITCH(JetFinderQATask, processTracksWeighted, "QA for charged tracks weighted", false); + + void processTracksSub(soa::Filtered::iterator const& collision, + soa::Filtered const& tracks) + { + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { + return; + } + for (auto const& track : tracks) { + registry.fill(HIST("h_track_pt_eventwiseconstituentsubtracted"), track.pt()); + registry.fill(HIST("h_track_eta_eventwiseconstituentsubtracted"), track.eta()); + registry.fill(HIST("h_track_phi_eventwiseconstituentsubtracted"), track.phi()); + } + } + PROCESS_SWITCH(JetFinderQATask, processTracksSub, "QA for charged event-wise embedded subtracted tracks", false); + + void processRho(soa::Join::iterator const& collision, soa::Filtered const& tracks) + { + int nTracks = 0; + TRandom3 rand(0); + float randomConeEta = rand.Uniform(trackEtaMin + randomConeR, trackEtaMax - randomConeR); + float randomConePhi = rand.Uniform(0.0, 2 * M_PI); + float randomConePt = 0; + for (auto const& track : tracks) { + if (jetderiveddatautilities::selectTrack(track, trackSelection)) { + nTracks++; + float dPhi = RecoDecay::constrainAngle(track.phi() - randomConePhi, -M_PI); + float dEta = track.eta() - randomConeEta; + if (TMath::Sqrt(dEta * dEta + dPhi * dPhi) < randomConeR) { + randomConePt += track.pt(); + } + } + } + registry.fill(HIST("h2_centrality_ntracks"), collision.centrality(), nTracks); + registry.fill(HIST("h2_ntracks_rho"), nTracks, collision.rho()); + registry.fill(HIST("h2_ntracks_rhom"), nTracks, collision.rhoM()); + registry.fill(HIST("h2_centrality_rho"), collision.centrality(), collision.rho()); + registry.fill(HIST("h2_centrality_rhom"), collision.centrality(), collision.rhoM()); + registry.fill(HIST("h2_centrality_rhoRandomCone"), collision.centrality(), randomConePt - M_PI * randomConeR * randomConeR * collision.rho()); + } + PROCESS_SWITCH(JetFinderQATask, processRho, "QA for rho-area subtracted jets", false); + + void processJetsRhoAreaSubData(soa::Filtered>::iterator const& collision, + soa::Join const& jets, + JetTracks const& tracks) + { + for (auto jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + fillRhoAreaSubtractedHistograms(jet, collision.centrality(), collision.rho()); + } + } + PROCESS_SWITCH(JetFinderQATask, processJetsRhoAreaSubData, "jet finder QA for rho-area subtracted jets", false); + + void processEvtWiseConstSubJetsData(soa::Filtered::iterator const& collision, soa::Join const& jets, JetTracksSub const& tracks) + { + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + fillEventWiseConstituentSubtractedHistograms(jet, collision.centrality()); + } + } + PROCESS_SWITCH(JetFinderQATask, processEvtWiseConstSubJetsData, "jet finder QA for eventwise constituent-subtracted jets data", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { return WorkflowSpec{adaptAnalysisTask(cfgc, TaskName{"jet-finder-charged-qa"})}; } diff --git a/PWGJE/Tasks/jetfinderfullQA.cxx b/PWGJE/Tasks/jetfinderfullQA.cxx index 78f854107ca..17ddd3e8717 100644 --- a/PWGJE/Tasks/jetfinderfullQA.cxx +++ b/PWGJE/Tasks/jetfinderfullQA.cxx @@ -29,6 +29,7 @@ #include "PWGJE/DataModel/Jet.h" #include "PWGJE/Core/JetDerivedDataUtilities.h" +#include "PWGJE/Core/JetFindingUtilities.h" #include "EventFiltering/filterTables.h" @@ -39,10 +40,13 @@ using namespace o2::framework::expressions; template struct JetFinderFullQATask { + HistogramRegistry registry; Configurable selectedJetsRadius{"selectedJetsRadius", 0.4, "resolution parameter for histograms without radius"}; Configurable vertexZCut{"vertexZCut", 10.0f, "Accepted z-vertex range"}; + Configurable centralityMin{"centralityMin", -999.0, "minimum centrality"}; + Configurable centralityMax{"centralityMax", 999.0, "maximum centrality"}; Configurable> jetRadii{"jetRadii", std::vector{0.4}, "jet resolution parameters"}; Configurable trackEtaMin{"trackEtaMin", -0.9, "minimum eta acceptance for tracks"}; Configurable trackEtaMax{"trackEtaMax", 0.9, "maximum eta acceptance for tracks"}; @@ -50,6 +54,9 @@ struct JetFinderFullQATask { Configurable trackPtMax{"trackPtMax", 100.0, "maximum pT acceptance for tracks"}; Configurable trackSelections{"trackSelections", "globalTracks", "set track selections"}; + Configurable jetEtaMin{"jetEtaMin", -99.0, "minimum jet pseudorapidity"}; + Configurable jetEtaMax{"jetEtaMax", 99.0, "maximum jet pseudorapidity"}; + // cluster level configurables Configurable clusterDefinitionS{"clusterDefinition", "kV3Default", "cluster definition to be selected, e.g. V3Default"}; Configurable clusterEtaMin{"clusterEtaMin", -0.7, "minimum cluster eta"}; // For ECMAL: |eta| < 0.7, phi = 1.40 - 3.26 @@ -70,10 +77,12 @@ struct JetFinderFullQATask { int trackSelection = -1; + Service pdgDatabase; + void init(o2::framework::InitContext&) { - trackSelection = JetDerivedDataUtilities::initialiseTrackSelection(static_cast(trackSelections)); + trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); jetRadiiValues = (std::vector)jetRadii; for (std::size_t iJetRadius = 0; iJetRadius < jetRadiiValues.size(); iJetRadius++) { @@ -92,12 +101,19 @@ struct JetFinderFullQATask { registry.add("h_jet_phi", "jet #varphi;#varphi_{jet};entries", {HistType::kTH1F, {{160, -1.0, 7.}}}); registry.add("h_jet_ntracks", "jet N tracks;N_{jet tracks};entries", {HistType::kTH1F, {{200, -0.5, 199.5}}}); registry.add("h_jet_nclusters", "jet N clusters;N_{jet clusters};entries", {HistType::kTH1F, {{200, -0.5, 199.5}}}); + registry.add("h2_centrality_jet_pt", "centrality vs #it{p}_{T,jet}; centrality; #it{p}_{T,jet} (GeV/#it{c})", {HistType::kTH2F, {{1200, -10.0, 110.0}, {200, 0., 200.}}}); + registry.add("h2_centrality_jet_eta", "centrality vs #eta_{jet}; centrality; #eta_{jet}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {100, -1.0, 1.0}}}); + registry.add("h2_centrality_jet_phi", "centrality vs #varphi_{jet}; centrality; #varphi_{jet}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {160, -1.0, 7.}}}); + registry.add("h2_centrality_jet_ntracks", "centrality vs N_{jet tracks}; centrality; N_{jet tracks}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {200, -0.5, 199.5}}}); + registry.add("h2_centrality_jet_nclusters", "centrality vs N_{jet clusters}; centrality; N_{jet clusters}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_jet_pt_centrality", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});centrality", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {1200, -10.0, 110.0}}}); registry.add("h3_jet_r_jet_pt_jet_eta", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); registry.add("h3_jet_r_jet_pt_jet_phi", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); registry.add("h3_jet_r_jet_eta_jet_phi", "#it{R}_{jet};#eta_{jet};#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {160, -1.0, 7.}}}); - registry.add("h3_jet_r_jet_pt_jet_ntracks", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});N_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -0.5, 99.5}}}); - registry.add("h3_jet_r_jet_pt_jet_nclusters", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});N_{jet clusters}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -0.5, 99.5}}}); - registry.add("h3_jet_r_jet_pt_jet_area", "#it{R}_{jet}; #it{p}_{T,jet} (GeV/#it{c}); #it{Area}_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {300, 0., 3.}}}); + registry.add("h3_jet_r_jet_pt_jet_ntracks", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});N_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_jet_pt_jet_nclusters", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});N_{jet clusters}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_jet_pt_jet_neutralenergyfraction", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});E_{neutral}/E_{total}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {120, 0.0, 1.2}}}); + registry.add("h3_jet_r_jet_pt_jet_area", "#it{R}_{jet}; #it{p}_{T,jet} (GeV/#it{c}); #it{area}_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {300, 0., 3.}}}); registry.add("h3_jet_r_jet_pt_track_pt", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#it{p}_{T,jet tracks} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); registry.add("h3_jet_r_jet_pt_track_eta", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); registry.add("h3_jet_r_jet_pt_track_phi", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); @@ -111,31 +127,62 @@ struct JetFinderFullQATask { registry.add("h_jet_pt_part", "jet pT;#it{p}_{T,jet}^{part}(GeV/#it{c});entries", {HistType::kTH1F, {{200, 0., 200.}}}); registry.add("h_jet_eta_part", "jet #eta;#eta_{jet}^{part};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}); registry.add("h_jet_phi_part", "jet #varphi;#varphi_{jet}^{part};entries", {HistType::kTH1F, {{160, -1.0, 7.}}}); - registry.add("h_jet_ntracks_part", "jet N tracks;N_{jet tracks}^{part};entries", {HistType::kTH1F, {{100, -0.5, 99.5}}}); + registry.add("h_jet_ntracks_part", "jet N tracks;N_{jet tracks}^{part};entries", {HistType::kTH1F, {{200, -0.5, 199.5}}}); registry.add("h3_jet_r_part_jet_pt_part_jet_eta_part", ";#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});#eta_{jet}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); registry.add("h3_jet_r_part_jet_pt_part_jet_phi_part", ";#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});#varphi_{jet}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); registry.add("h3_jet_r_part_jet_eta_part_jet_phi_part", ";#it{R}_{jet}^{part};#eta_{jet}^{part};#varphi_{jet}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {160, -1.0, 7.}}}); - registry.add("h3_jet_r_part_jet_pt_part_jet_ntracks_part", "#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});N_{jet tracks}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -0.5, 99.5}}}); + registry.add("h3_jet_r_part_jet_pt_part_jet_ntracks_part", "#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});N_{jet tracks}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_part_jet_pt_part_jet_neutralenergyfraction_part", "#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});E_{neutral}^{part}/E_{total}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {120, 0.0, 1.2}}}); registry.add("h3_jet_r_part_jet_pt_part_track_pt_part", "#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});#it{p}_{T,jet tracks}^{part} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); registry.add("h3_jet_r_part_jet_pt_part_track_eta_part", "#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});#eta_{jet tracks}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); registry.add("h3_jet_r_part_jet_pt_part_track_phi_part", "#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});#varphi_{jet tracks}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); } if (doprocessJetsMCPMCDMatched || doprocessJetsMCPMCDMatchedWeighted) { - registry.add("h3_jet_r_jet_pt_part_jet_pt", "#it{R}_{jet};#it{p}_{T,jet}^{part} (GeV/#it{c});#it{p}_{T,jet} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); - registry.add("h3_jet_r_jet_eta_part_jet_eta", "#it{R}_{jet};#eta_{jet}^{part};#eta_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); - registry.add("h3_jet_r_jet_phi_part_jet_phi", "#it{R}_{jet};#varphi_{jet}^{part};#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); - registry.add("h3_jet_r_jet_ntracks_part_jet_ntracks", "#it{R}_{jet};N_{jet tracks}^{part};N_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -0.5, 99.5}, {100, -0.5, 99.5}}}); - registry.add("h3_jet_r_cluster_pt_part_cluster_pt", "#it{R}_{jet};#it{p}_{T,cluster}^{part} (GeV/#it{c});#it{p}_{T,cluster} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); - registry.add("h3_jet_r_cluster_eta_part_cluster_eta", "#it{R}_{jet};#eta_{cluster}^{part};#eta_{cluster}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); - registry.add("h3_jet_r_cluster_phi_part_cluster_phi", "#it{R}_{jet};#varphi_{cluster}^{part};#varphi_{cluster}", {HistType::kTH3F, {{jetRadiiBins, ""}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); - registry.add("h3_jet_r_cluster_energy_part_cluster_energy", "#it{R}_{jet};#E_{cluster}^{part};#E_{cluster}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.0}}}); - registry.add("h3_jet_r_jet_pt_part_jet_pt_diff", "#it{R}_{jet};#it{p}_{T,jet}^{part} (GeV/#it{c}); (#it{p}_{T,jet}^{part} (GeV/#it{c}) - #it{p}_{T,jet} (GeV/#it{c})) / #it{p}_{T,jet}^{part} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); - registry.add("h3_jet_r_jet_pt_part_jet_eta_diff", "#it{R}_{jet};#it{p}_{T,jet}^{part} (GeV/#it{c}); (#eta_{jet}^{part} - #eta_{jet}) / #eta_{jet}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); - registry.add("h3_jet_r_jet_pt_part_jet_phi_diff", "#it{R}_{jet};#it{p}_{T,jet}^{part} (GeV/#it{c}); (#varphi_{jet}^{part} - #varphi_{jet}) / #varphi_{jet}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); - registry.add("h3_jet_pt_part_jet_eta_part_jet_eta", ";#it{p}_{T,jet}^{part} (GeV/#it{c}); #eta_{jet}^{part}; #eta_{jet}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); - registry.add("h3_jet_pt_part_jet_phi_part_jet_phi", ";#it{p}_{T,jet}^{part} (GeV/#it{c}); #varphi_{jet}^{part}; #varphi_{jet}", {HistType::kTH3F, {{200, 0.0, 200}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); - registry.add("h3_jet_pt_part_jet_ntracks_part_jet_ntracks", ";#it{p}_{T,jet}^{part} (GeV/#it{c}); N_{jet tracks}^{part}; N_{jet tracks}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -0.5, 99.5}, {100, -0.5, 99.5}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_matchedgeo", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c});#it{p}_{T,jet}^{base} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_eta_tag_jet_eta_base_matchedgeo", "#it{R}_{jet};#eta_{jet}^{tag};#eta_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_phi_tag_jet_phi_base_matchedgeo", "#it{R}_{jet};#varphi_{jet}^{tag};#varphi_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedgeo", "#it{R}_{jet};N_{jet tracks}^{tag};N_{jet tracks}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_cluster_pt_tag_cluster_pt_base_matchedgeo", "#it{R}_{jet};#it{p}_{T,cluster}^{tag} (GeV/#it{c});#it{p}_{T,cluster}^{base} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_cluster_eta_tag_cluster_eta_base_matchedgeo", "#it{R}_{jet};#eta_{cluster}^{tag};#eta_{cluster}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_cluster_phi_tag_cluster_phi_base_matchedgeo", "#it{R}_{jet};#varphi_{cluster}^{tag};#varphi_{cluster}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_cluster_energy_tag_cluster_energy_base_matchedgeo", "#it{R}_{jet};#E_{cluster}^{tag};#E_{cluster}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedgeo", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#it{p}_{T,jet}^{tag} (GeV/#it{c}) - #it{p}_{T,jet}^{base} (GeV/#it{c})) / #it{p}_{T,jet}^{tag} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedgeo", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#eta_{jet}^{tag} - #eta_{jet}^{base}) / #eta_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedgeo", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#varphi_{jet}^{tag} - #varphi_{jet}^{base}) / #varphi_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedgeo", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #eta_{jet}^{tag}; #eta_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedgeo", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #varphi_{jet}^{tag}; #varphi_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedgeo", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); N_{jet tracks}^{tag}; N_{jet tracks}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_matchedpt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c});#it{p}_{T,jet}^{base} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_eta_tag_jet_eta_base_matchedpt", "#it{R}_{jet};#eta_{jet}^{tag};#eta_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_phi_tag_jet_phi_base_matchedpt", "#it{R}_{jet};#varphi_{jet}^{tag};#varphi_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedpt", "#it{R}_{jet};N_{jet tracks}^{tag};N_{jet tracks}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_cluster_pt_tag_cluster_pt_base_matchedpt", "#it{R}_{jet};#it{p}_{T,cluster}^{tag} (GeV/#it{c});#it{p}_{T,cluster}^{base} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_cluster_eta_tag_cluster_eta_base_matchedpt", "#it{R}_{jet};#eta_{cluster}^{tag};#eta_{cluster}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_cluster_phi_tag_cluster_phi_base_matchedpt", "#it{R}_{jet};#varphi_{cluster}^{tag};#varphi_{cluster}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_cluster_energy_tag_cluster_energy_base_matchedpt", "#it{R}_{jet};#E_{cluster}^{tag};#E_{cluster}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedpt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#it{p}_{T,jet}^{tag} (GeV/#it{c}) - #it{p}_{T,jet}^{base} (GeV/#it{c})) / #it{p}_{T,jet}^{tag} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedpt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#eta_{jet}^{tag} - #eta_{jet}^{base}) / #eta_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedpt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#varphi_{jet}^{tag} - #varphi_{jet}^{base}) / #varphi_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedpt", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #eta_{jet}^{tag}; #eta_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedpt", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #varphi_{jet}^{tag}; #varphi_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedpt", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); N_{jet tracks}^{tag}; N_{jet tracks}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_matchedgeopt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c});#it{p}_{T,jet}^{base} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_eta_tag_jet_eta_base_matchedgeopt", "#it{R}_{jet};#eta_{jet}^{tag};#eta_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_phi_tag_jet_phi_base_matchedgeopt", "#it{R}_{jet};#varphi_{jet}^{tag};#varphi_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedgeopt", "#it{R}_{jet};N_{jet tracks}^{tag};N_{jet tracks}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_cluster_pt_tag_cluster_pt_base_matchedgeopt", "#it{R}_{jet};#it{p}_{T,cluster}^{tag} (GeV/#it{c});#it{p}_{T,cluster}^{base} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_cluster_eta_tag_cluster_eta_base_matchedgeopt", "#it{R}_{jet};#eta_{cluster}^{tag};#eta_{cluster}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_cluster_phi_tag_cluster_phi_base_matchedgeopt", "#it{R}_{jet};#varphi_{cluster}^{tag};#varphi_{cluster}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_cluster_energy_tag_cluster_energy_base_matchedgeopt", "#it{R}_{jet};#E_{cluster}^{tag};#E_{cluster}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedgeopt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#it{p}_{T,jet}^{tag} (GeV/#it{c}) - #it{p}_{T,jet}^{base} (GeV/#it{c})) / #it{p}_{T,jet}^{tag} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedgeopt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#eta_{jet}^{tag} - #eta_{jet}^{base}) / #eta_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedgeopt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#varphi_{jet}^{tag} - #varphi_{jet}^{base}) / #varphi_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedgeopt", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #eta_{jet}^{tag}; #eta_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedgeopt", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #varphi_{jet}^{tag}; #varphi_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedgeopt", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); N_{jet tracks}^{tag}; N_{jet tracks}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); } if (doprocessTracks || doprocessTracksWeighted) { @@ -158,9 +205,6 @@ struct JetFinderFullQATask { } } - using JetTracks = aod::JTracks; - using JetClusters = aod::JClusters; - using JetParticles = aod::JMcParticles; using JetTableDataJoined = soa::Join; using JetTableMCDJoined = soa::Join; using JetTableMCDWeightedJoined = soa::Join; @@ -172,11 +216,12 @@ struct JetFinderFullQATask { using JetTableMCPMatchedWeightedJoined = soa::Join; Filter trackCuts = (aod::jtrack::pt >= trackPtMin && aod::jtrack::pt < trackPtMax && aod::jtrack::eta > trackEtaMin && aod::jtrack::eta < trackEtaMax); + Filter eventCuts = (nabs(aod::jcollision::posZ) < vertexZCut && aod::jcollision::centrality >= centralityMin && aod::jcollision::centrality < centralityMax); 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)); template - void fillHistograms(T const& jet, float weight = 1.0) + void fillHistograms(T const& jet, float centrality, float weight = 1.0) { float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); @@ -184,14 +229,21 @@ struct JetFinderFullQATask { return; } + float neutralEnergy = 0.0; if (jet.r() == round(selectedJetsRadius * 100.0f)) { registry.fill(HIST("h_jet_pt"), jet.pt(), weight); registry.fill(HIST("h_jet_eta"), jet.eta(), weight); registry.fill(HIST("h_jet_phi"), jet.phi(), weight); registry.fill(HIST("h_jet_ntracks"), jet.tracks().size(), weight); registry.fill(HIST("h_jet_nclusters"), jet.clusters().size(), weight); + registry.fill(HIST("h2_centrality_jet_pt"), centrality, jet.pt(), weight); + registry.fill(HIST("h2_centrality_jet_eta"), centrality, jet.eta(), weight); + registry.fill(HIST("h2_centrality_jet_phi"), centrality, jet.phi(), weight); + registry.fill(HIST("h2_centrality_jet_ntracks"), centrality, jet.tracks().size(), weight); + registry.fill(HIST("h2_centrality_jet_nclusters"), centrality, jet.clusters().size(), weight); } + registry.fill(HIST("h3_jet_r_jet_pt_centrality"), jet.r() / 100.0, jet.pt(), centrality, weight); registry.fill(HIST("h3_jet_r_jet_pt_jet_eta"), jet.r() / 100.0, jet.pt(), jet.eta(), weight); registry.fill(HIST("h3_jet_r_jet_pt_jet_phi"), jet.r() / 100.0, jet.pt(), jet.phi(), weight); registry.fill(HIST("h3_jet_r_jet_eta_jet_phi"), jet.r() / 100.0, jet.eta(), jet.phi(), weight); @@ -208,11 +260,13 @@ struct JetFinderFullQATask { for (auto& cluster : jet.template clusters_as()) { double clusterpt = cluster.energy() / std::cosh(cluster.eta()); + neutralEnergy += cluster.energy(); registry.fill(HIST("h3_jet_r_jet_pt_cluster_pt"), jet.r() / 100.0, jet.pt(), clusterpt, weight); registry.fill(HIST("h3_jet_r_jet_pt_cluster_eta"), jet.r() / 100.0, jet.pt(), cluster.eta(), weight); registry.fill(HIST("h3_jet_r_jet_pt_cluster_phi"), jet.r() / 100.0, jet.pt(), cluster.phi(), weight); registry.fill(HIST("h3_jet_r_jet_pt_cluster_energy"), jet.r() / 100.0, jet.pt(), cluster.energy(), weight); } + registry.fill(HIST("h3_jet_r_jet_pt_jet_neutralenergyfraction"), jet.r() / 100.0, jet.pt(), neutralEnergy / jet.energy(), weight); } template @@ -224,6 +278,7 @@ struct JetFinderFullQATask { return; } + float neutralEnergy = 0.0; if (jet.r() == round(selectedJetsRadius * 100.0f)) { registry.fill(HIST("h_jet_pt_part"), jet.pt(), weight); registry.fill(HIST("h_jet_eta_part"), jet.eta(), weight); @@ -237,48 +292,97 @@ struct JetFinderFullQATask { registry.fill(HIST("h3_jet_r_part_jet_pt_part_jet_ntracks_part"), jet.r() / 100.0, jet.pt(), jet.tracks().size(), weight); for (auto& constituent : jet.template tracks_as()) { - + auto pdgParticle = pdgDatabase->GetParticle(constituent.pdgCode()); + if (pdgParticle->Charge() == 0) { + neutralEnergy += constituent.e(); + } registry.fill(HIST("h3_jet_r_part_jet_pt_part_track_pt_part"), jet.r() / 100.0, jet.pt(), constituent.pt(), weight); registry.fill(HIST("h3_jet_r_part_jet_pt_part_track_eta_part"), jet.r() / 100.0, jet.pt(), constituent.eta(), weight); registry.fill(HIST("h3_jet_r_part_jet_pt_part_track_phi_part"), jet.r() / 100.0, jet.pt(), constituent.phi(), weight); } + registry.fill(HIST("h3_jet_r_part_jet_pt_part_jet_neutralenergyfraction_part"), jet.r() / 100.0, jet.pt(), neutralEnergy / jet.energy(), weight); } template - void fillMCMatchedHistograms(T const& mcdjet, float weight = 1.0) + void fillMatchedHistograms(T const& jetBase, float weight = 1.0) { float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); - if (mcdjet.pt() > pTHatMaxMCD * pTHat) { + if (jetBase.pt() > pTHatMaxMCD * pTHat) { return; } - for (auto& mcpjet : mcdjet.template matchedJetGeo_as>()) { + if (jetBase.has_matchedJetGeo()) { + for (auto& jetTag : jetBase.template matchedJetGeo_as>()) { + if (jetTag.pt() > pTHatMaxMCP * pTHat) { + continue; + } + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_matchedgeo"), jetBase.r() / 100.0, jetTag.pt(), jetBase.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_eta_tag_jet_eta_base_matchedgeo"), jetBase.r() / 100.0, jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_phi_tag_jet_phi_base_matchedgeo"), jetBase.r() / 100.0, jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedgeo"), jetBase.r() / 100.0, jetTag.tracks().size(), jetBase.tracks().size(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedgeo"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.pt() - jetBase.pt()) / jetTag.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedgeo"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.eta() - jetBase.eta()) / jetTag.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedgeo"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.phi() - jetBase.phi()) / jetTag.phi(), weight); + + if (jetBase.r() == round(selectedJetsRadius * 100.0f)) { + registry.fill(HIST("h3_jet_pt_tag_jet_eta_tag_jet_eta_matchedgeo"), jetTag.pt(), jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_phi_tag_jet_phi_matchedgeo"), jetTag.pt(), jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_matchedgeo"), jetTag.pt(), jetTag.tracks().size(), jetBase.tracks().size(), weight); + } + } + } - if (mcpjet.pt() > pTHatMaxMCP * pTHat) { - continue; + if (jetBase.has_matchedJetPt()) { + for (auto& jetTag : jetBase.template matchedJetPt_as>()) { + if (jetTag.pt() > pTHatMaxMCP * pTHat) { + continue; + } + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_matchedpt"), jetBase.r() / 100.0, jetTag.pt(), jetBase.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_eta_tag_jet_eta_base_matchedpt"), jetBase.r() / 100.0, jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_phi_tag_jet_phi_base_matchedpt"), jetBase.r() / 100.0, jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedpt"), jetBase.r() / 100.0, jetTag.tracks().size(), jetBase.tracks().size(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedpt"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.pt() - jetBase.pt()) / jetTag.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedpt"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.eta() - jetBase.eta()) / jetTag.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedpt"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.phi() - jetBase.phi()) / jetTag.phi(), weight); + + if (jetBase.r() == round(selectedJetsRadius * 100.0f)) { + registry.fill(HIST("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedpt"), jetTag.pt(), jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedpt"), jetTag.pt(), jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedpt"), jetTag.pt(), jetTag.tracks().size(), jetBase.tracks().size(), weight); + } } + } - registry.fill(HIST("h3_jet_r_jet_pt_part_jet_pt"), mcdjet.r() / 100.0, mcpjet.pt(), mcdjet.pt(), weight); - registry.fill(HIST("h3_jet_r_jet_eta_part_jet_eta"), mcdjet.r() / 100.0, mcpjet.eta(), mcdjet.eta(), weight); - registry.fill(HIST("h3_jet_r_jet_phi_part_jet_phi"), mcdjet.r() / 100.0, mcpjet.phi(), mcdjet.phi(), weight); - registry.fill(HIST("h3_jet_r_jet_ntracks_part_jet_ntracks"), mcdjet.r() / 100.0, mcpjet.tracks().size(), mcdjet.tracks().size(), weight); // Note: At truth level tracks include both neutral and charged particles. Is it worth differentiating these in the jetFinder? - registry.fill(HIST("h3_jet_r_jet_pt_part_jet_pt_diff"), mcdjet.r() / 100.0, mcpjet.pt(), (mcpjet.pt() - mcdjet.pt()) / mcpjet.pt(), weight); - registry.fill(HIST("h3_jet_r_jet_pt_part_jet_eta_diff"), mcdjet.r() / 100.0, mcpjet.pt(), (mcpjet.eta() - mcdjet.eta()) / mcpjet.eta(), weight); - registry.fill(HIST("h3_jet_r_jet_pt_part_jet_phi_diff"), mcdjet.r() / 100.0, mcpjet.pt(), (mcpjet.phi() - mcdjet.phi()) / mcpjet.phi(), weight); - - if (mcdjet.r() == round(selectedJetsRadius * 100.0f)) { - registry.fill(HIST("h3_jet_pt_part_jet_eta_part_jet_eta"), mcpjet.pt(), mcpjet.eta(), mcdjet.eta(), weight); - registry.fill(HIST("h3_jet_pt_part_jet_phi_part_jet_phi"), mcpjet.pt(), mcpjet.phi(), mcdjet.phi(), weight); - registry.fill(HIST("h3_jet_pt_part_jet_ntracks_part_jet_ntracks"), mcpjet.pt(), mcpjet.tracks().size(), mcdjet.tracks().size(), weight); + if (jetBase.has_matchedJetGeo() && jetBase.has_matchedJetPt()) { + for (auto& jetTag : jetBase.template matchedJetGeo_as>()) { + if (jetTag.pt() > pTHatMaxMCP * pTHat) { + continue; + } + if (jetBase.template matchedJetGeo_first_as>().globalIndex() == jetBase.template matchedJetPt_first_as>().globalIndex()) { // not a good way to do this + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_matchedgeopt"), jetBase.r() / 100.0, jetTag.pt(), jetBase.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_eta_tag_jet_eta_base_matchedgeopt"), jetBase.r() / 100.0, jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_phi_tag_jet_phi_base_matchedgeopt"), jetBase.r() / 100.0, jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedgeopt"), jetBase.r() / 100.0, jetTag.tracks().size(), jetBase.tracks().size(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedgeopt"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.pt() - jetBase.pt()) / jetTag.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedgeopt"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.eta() - jetBase.eta()) / jetTag.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedgeopt"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.phi() - jetBase.phi()) / jetTag.phi(), weight); + + if (jetBase.r() == round(selectedJetsRadius * 100.0f)) { + registry.fill(HIST("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedpt"), jetTag.pt(), jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedpt"), jetTag.pt(), jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedpt"), jetTag.pt(), jetTag.tracks().size(), jetBase.tracks().size(), weight); + } + } } } } - void fillTrackHistograms(soa::Filtered const& tracks, soa::Filtered const& clusters, float weight = 1.0) + template + void fillTrackHistograms(T const& tracks, U const& clusters, float weight = 1.0) { for (auto const& track : tracks) { - if (!JetDerivedDataUtilities::selectTrack(track, trackSelection) || !JetDerivedDataUtilities::applyTrackKinematics(track, trackPtMin, trackPtMax, trackEtaMin, trackEtaMax)) { + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { continue; } registry.fill(HIST("h_track_pt"), track.pt(), weight); @@ -294,42 +398,63 @@ struct JetFinderFullQATask { } } - void processDummy(aod::JCollisions const& collision) + void processDummy(JetCollisions const& collisions) { } PROCESS_SWITCH(JetFinderFullQATask, processDummy, "dummy task", true); - void processJetsData(typename JetTableDataJoined::iterator const& jet, JetTracks const& tracks, JetClusters const& clusters) + void processJetsData(soa::Filtered::iterator const& collision, JetTableDataJoined const& jets, JetTracks const& tracks, JetClusters const& clusters) { - fillHistograms(jet); + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + fillHistograms(jet, collision.centrality()); + } } PROCESS_SWITCH(JetFinderFullQATask, processJetsData, "jet finder HF QA data", false); - void processJetsMCD(typename JetTableMCDJoined::iterator const& jet, JetTracks const& tracks, JetClusters const& clusters) + void processJetsMCD(soa::Filtered::iterator const& collision, JetTableMCDJoined const& jets, JetTracks const& tracks, JetClusters const& clusters) { - fillHistograms(jet); + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + fillHistograms(jet, collision.centrality()); + } } PROCESS_SWITCH(JetFinderFullQATask, processJetsMCD, "jet finder HF QA mcd", false); - void processJetsMCDWeighted(typename JetTableMCDWeightedJoined::iterator const& jet, JetTracks const& tracks, JetClusters const& clusters) + void processJetsMCDWeighted(soa::Filtered::iterator const& collision, JetTableMCDWeightedJoined const& jets, JetTracks const& tracks, JetClusters const& clusters) { - fillHistograms(jet, jet.eventWeight()); + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + fillHistograms(jet, collision.centrality(), jet.eventWeight()); + } } PROCESS_SWITCH(JetFinderFullQATask, processJetsMCDWeighted, "jet finder HF QA mcd on weighted events", false); void processJetsMCP(typename JetTableMCPJoined::iterator const& jet, JetParticles const& particles) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + return; + } fillMCPHistograms(jet); } PROCESS_SWITCH(JetFinderFullQATask, processJetsMCP, "jet finder HF QA mcp", false); - void processJetsMCPWeighted(typename JetTableMCDWeightedJoined::iterator const& jet, JetParticles const& particles) + void processJetsMCPWeighted(typename JetTableMCPWeightedJoined::iterator const& jet, JetParticles const& particles) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + return; + } fillMCPHistograms(jet, jet.eventWeight()); } PROCESS_SWITCH(JetFinderFullQATask, processJetsMCPWeighted, "jet finder HF QA mcp on weighted events", false); - void processJetsMCPMCDMatched(aod::JCollisions::iterator const& collision, + void processJetsMCPMCDMatched(JetCollision const& collision, JetTableMCDMatchedJoined const& mcdjets, JetTableMCPMatchedJoined const& mcpjets, JetTracks const& tracks, @@ -338,13 +463,15 @@ struct JetFinderFullQATask { { for (const auto& mcdjet : mcdjets) { - - fillMCMatchedHistograms(mcdjet); + if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + fillMatchedHistograms(mcdjet); } } PROCESS_SWITCH(JetFinderFullQATask, processJetsMCPMCDMatched, "jet finder HF QA matched mcp and mcd", false); - void processJetsMCPMCDMatchedWeighted(aod::JCollisions::iterator const& collision, + void processJetsMCPMCDMatchedWeighted(JetCollision const& collision, JetTableMCDMatchedWeightedJoined const& mcdjets, JetTableMCPMatchedWeightedJoined const& mcpjets, JetTracks const& tracks, @@ -353,25 +480,27 @@ struct JetFinderFullQATask { { for (const auto& mcdjet : mcdjets) { - - fillMCMatchedHistograms(mcdjet, mcdjet.eventWeight()); + if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + fillMatchedHistograms(mcdjet, mcdjet.eventWeight()); } } PROCESS_SWITCH(JetFinderFullQATask, processJetsMCPMCDMatchedWeighted, "jet finder HF QA matched mcp and mcd on weighted events", false); - void processMCCollisionsWeighted(aod::JMcCollision const& collision) + void processMCCollisionsWeighted(JetMcCollision const& collision) { registry.fill(HIST("h_collision_eventweight_part"), collision.weight()); } PROCESS_SWITCH(JetFinderFullQATask, processMCCollisionsWeighted, "collision QA for weighted events", false); - void processTracks(aod::JCollision const& collision, + void processTracks(JetCollision const& collision, soa::Filtered const& tracks, soa::Filtered const& clusters) { registry.fill(HIST("h_collisions"), 0.5); - if (!JetDerivedDataUtilities::eventEMCAL(collision)) { + if (!jetderiveddatautilities::eventEMCAL(collision)) { return; } registry.fill(HIST("h_collisions"), 1.5); @@ -387,7 +516,7 @@ struct JetFinderFullQATask { float eventWeight = collision.mcCollision().weight(); registry.fill(HIST("h_collisions"), 0.5); registry.fill(HIST("h_collisions_weighted"), 0.5, eventWeight); - if (!JetDerivedDataUtilities::eventEMCAL(collision)) { + if (!jetderiveddatautilities::eventEMCAL(collision)) { return; } registry.fill(HIST("h_collisions"), 1.5); diff --git a/PWGJE/Tasks/jetfinderhfQA.cxx b/PWGJE/Tasks/jetfinderhfQA.cxx index 1072e967b6d..9f9d606952f 100644 --- a/PWGJE/Tasks/jetfinderhfQA.cxx +++ b/PWGJE/Tasks/jetfinderhfQA.cxx @@ -13,6 +13,8 @@ // /// \author Nima Zardoshti +#include + #include "CommonConstants/PhysicsConstants.h" #include "Framework/ASoA.h" #include "Framework/AnalysisDataModel.h" @@ -32,6 +34,8 @@ #include "PWGJE/DataModel/Jet.h" #include "PWGJE/Core/JetDerivedDataUtilities.h" +#include "PWGJE/Core/JetHFUtilities.h" +#include "PWGJE/Core/JetFindingUtilities.h" #include "EventFiltering/filterTables.h" @@ -40,56 +44,49 @@ using namespace o2::analysis; using namespace o2::framework; using namespace o2::framework::expressions; -template +template struct JetFinderHFQATask { + HistogramRegistry registry; Configurable selectedJetsRadius{"selectedJetsRadius", 0.4, "resolution parameter for histograms without radius"}; Configurable eventSelections{"eventSelections", "sel8", "choose event selection"}; Configurable vertexZCut{"vertexZCut", 10.0f, "Accepted z-vertex range"}; + Configurable centralityMin{"centralityMin", -999.0, "minimum centrality"}; + Configurable centralityMax{"centralityMax", 999.0, "maximum centrality"}; Configurable> jetRadii{"jetRadii", std::vector{0.4}, "jet resolution parameters"}; Configurable trackEtaMin{"trackEtaMin", -0.9, "minimum eta acceptance for tracks"}; Configurable trackEtaMax{"trackEtaMax", 0.9, "maximum eta acceptance for tracks"}; Configurable trackPtMin{"trackPtMin", 0.15, "minimum pT acceptance for tracks"}; Configurable trackPtMax{"trackPtMax", 100.0, "maximum pT acceptance for tracks"}; Configurable trackSelections{"trackSelections", "globalTracks", "set track selections"}; - Configurable selectionFlagD0{"selectionFlagD0", 1, "Selection Flag for D0"}; - Configurable selectionFlagD0bar{"selectionFlagD0bar", 1, "Selection Flag for D0bar"}; - Configurable selectionFlagLcToPKPi{"selectionFlagLcToPKPi", 1, "Selection Flag for Lc->PKPi"}; - Configurable selectionFlagLcToPiPK{"selectionFlagLcToPiPK", 1, "Selection Flag for Lc->PiPK"}; - Configurable selectionFlagBplus{"selectionFlagBplus", 1, "Selection Flag for B+"}; + Configurable jetEtaMin{"jetEtaMin", -99.0, "minimum jet pseudorapidity"}; + Configurable jetEtaMax{"jetEtaMax", 99.0, "maximum jet pseudorapidity"}; 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 pTHatExponent{"pTHatExponent", 6.0, "exponent of the event weight for the calculation of pTHat"}; + Configurable randomConeR{"randomConeR", 0.4, "size of random Cone for estimating background fluctuations"}; HfHelper hfHelper; - std::vector filledJetR; + std::vector filledJetR_Both; + std::vector filledJetR_Low; + std::vector filledJetR_High; std::vector jetRadiiValues; int eventSelection = -1; int trackSelection = -1; - double candMass; - void init(o2::framework::InitContext&) { - eventSelection = JetDerivedDataUtilities::initialiseEventSelection(static_cast(eventSelections)); - trackSelection = JetDerivedDataUtilities::initialiseTrackSelection(static_cast(trackSelections)); - - if constexpr (std::is_same_v, soa::Join>) { // Note : need to be careful if configurable workflow options are added later - candMass = o2::constants::physics::MassD0; - } - if constexpr (std::is_same_v, soa::Join>) { - candMass = o2::constants::physics::MassLambdaCPlus; - } - if constexpr (std::is_same_v, soa::Join>) { - candMass = o2::constants::physics::MassBPlus; - } + eventSelection = jetderiveddatautilities::initialiseEventSelection(static_cast(eventSelections)); + trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); jetRadiiValues = (std::vector)jetRadii; for (std::size_t iJetRadius = 0; iJetRadius < jetRadiiValues.size(); iJetRadius++) { - filledJetR.push_back(0.0); + filledJetR_Both.push_back(0.0); + filledJetR_Low.push_back(0.0); + filledJetR_High.push_back(0.0); } auto jetRadiiBins = (std::vector)jetRadii; if (jetRadiiBins.size() > 1) { @@ -103,11 +100,16 @@ struct JetFinderHFQATask { registry.add("h_jet_eta", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}); registry.add("h_jet_phi", "jet #varphi;#varphi_{jet};entries", {HistType::kTH1F, {{160, -1.0, 7.}}}); registry.add("h_jet_ntracks", "jet N tracks;N_{jet tracks};entries", {HistType::kTH1F, {{200, -0.5, 199.5}}}); + registry.add("h2_centrality_jet_pt", "centrality vs #it{p}_{T,jet}; centrality; #it{p}_{T,jet} (GeV/#it{c})", {HistType::kTH2F, {{1200, -10.0, 110.0}, {200, 0., 200.}}}); + registry.add("h2_centrality_jet_eta", "centrality vs #eta_{jet}; centrality; #eta_{jet}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {100, -1.0, 1.0}}}); + registry.add("h2_centrality_jet_phi", "centrality vs #varphi_{jet}; centrality; #varphi_{jet}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {160, -1.0, 7.}}}); + registry.add("h2_centrality_jet_ntracks", "centrality vs N_{jet tracks}; centrality; N_{jet tracks}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_jet_pt_centrality", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});centrality", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {1200, -10.0, 110.0}}}); registry.add("h3_jet_r_jet_pt_jet_eta", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); registry.add("h3_jet_r_jet_pt_jet_phi", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); registry.add("h3_jet_r_jet_eta_jet_phi", "#it{R}_{jet};#eta_{jet};#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {160, -1.0, 7.}}}); - registry.add("h3_jet_r_jet_pt_jet_ntracks", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});N_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -0.5, 99.5}}}); - registry.add("h3_jet_r_jet_pt_jet_area", "#it{R}_{jet}; #it{p}_{T,jet} (GeV/#it{c}); #it{Area}_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {300, 0., 3.}}}); + registry.add("h3_jet_r_jet_pt_jet_ntracks", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});N_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_jet_pt_jet_area", "#it{R}_{jet}; #it{p}_{T,jet} (GeV/#it{c}); #it{area}_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {300, 0., 3.}}}); registry.add("h3_jet_r_jet_pt_track_pt", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#it{p}_{T,jet tracks} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); registry.add("h3_jet_r_jet_pt_track_eta", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); registry.add("h3_jet_r_jet_pt_track_phi", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); @@ -119,15 +121,71 @@ struct JetFinderHFQATask { registry.add("h3_candidatebar_invmass_jet_pt_candidate_pt", ";#it{m}_{inv, candidate bar} (GeV/#it{c}^{2}); #it{p}_{T,jet} (GeV/#it{c}) ;#it{p}_{T,candidate} (GeV/#it{c})", {HistType::kTH3F, {{500, 0.0, 5.0}, {200, 0.0, 200.0}, {200, 0.0, 200.0}}}); } + if (doprocessJetsRhoAreaSubData) { + + registry.add("h_jet_pt_rhoareasubtracted", "jet pT;#it{p}_{T,jet} (GeV/#it{c});entries", {HistType::kTH1F, {{200, 0., 200.}}}); + registry.add("h_jet_eta_rhoareasubtracted", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}); + registry.add("h_jet_phi_rhoareasubtracted", "jet #varphi;#varphi_{jet};entries", {HistType::kTH1F, {{160, -1.0, 7.}}}); + registry.add("h_jet_ntracks_rhoareasubtracted", "jet N tracks;N_{jet tracks};entries", {HistType::kTH1F, {{200, -0.5, 199.5}}}); + registry.add("h2_centrality_jet_pt_rhoareasubtracted", "centrality vs #it{p}_{T,jet}; centrality; #it{p}_{T,jet} (GeV/#it{c})", {HistType::kTH2F, {{1200, -10.0, 110.0}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_pt_centrality_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});centrality", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {1200, -10.0, 110.0}}}); + registry.add("h3_jet_r_jet_pt_jet_eta_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_pt_jet_phi_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_eta_jet_phi_rhoareasubtracted", "#it{R}_{jet};#eta_{jet};#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_pt_jet_ntracks_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});N_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_jet_pt_jet_area_rhoareasubtracted", "#it{R}_{jet}; #it{p}_{T,jet} (GeV/#it{c}); #it{area}_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {300, 0., 3.}}}); + registry.add("h3_jet_r_jet_pt_track_pt_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#it{p}_{T,jet tracks} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_pt_track_eta_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_pt_track_phi_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_pt_jet_pt_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#it{p}_{T,jet} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_pt_candidate_pt_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#it{p}_{T,candidate} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_pt_candidate_eta_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{candidate}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_pt_candidate_phi_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{candidate}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_pt_candidate_y_rhoareasubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});y_{candidate}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + } + + if (doprocessEvtWiseConstSubJetsData) { + registry.add("h_jet_pt_eventwiseconstituentsubtracted", "jet pT;#it{p}_{T,jet} (GeV/#it{c});entries", {HistType::kTH1F, {{200, 0., 200.}}}); + registry.add("h_jet_eta_eventwiseconstituentsubtracted", "jet #eta;#eta_{jet};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}); + registry.add("h_jet_phi_eventwiseconstituentsubtracted", "jet #varphi;#varphi_{jet};entries", {HistType::kTH1F, {{160, -1.0, 7.}}}); + registry.add("h_jet_ntracks_eventwiseconstituentsubtracted", "jet N tracks;N_{jet tracks};entries", {HistType::kTH1F, {{200, -0.5, 199.5}}}); + registry.add("h2_centrality_jet_pt_eventwiseconstituentsubtracted", "centrality vs #it{p}_{T,jet}; centrality; #it{p}_{T,jet} (GeV/#it{c})", {HistType::kTH2F, {{1200, -10.0, 110.0}, {200, 0., 200.}}}); + registry.add("h2_centrality_jet_eta_eventwiseconstituentsubtracted", "centrality vs #eta_{jet}; centrality; #eta_{jet}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {100, -1.0, 1.0}}}); + registry.add("h2_centrality_jet_phi_eventwiseconstituentsubtracted", "centrality vs #varphi_{jet}; centrality; #varphi_{jet}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {160, -1.0, 7.}}}); + registry.add("h2_centrality_jet_ntracks_eventwiseconstituentsubtracted", "centrality vs N_{jet tracks}; centrality; N_{jet tracks}", {HistType::kTH2F, {{1200, -10.0, 110.0}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_jet_pt_centrality_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});centrality", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {1200, -10.0, 110.0}}}); + registry.add("h3_jet_r_jet_pt_jet_eta_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_pt_jet_phi_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_eta_jet_phi_eventwiseconstituentsubtracted", "#it{R}_{jet};#eta_{jet};#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_pt_jet_ntracks_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});N_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_jet_pt_jet_area_eventwiseconstituentsubtracted", "#it{R}_{jet}; #it{p}_{T,jet} (GeV/#it{c}); #it{area}_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {300, 0., 3.}}}); + registry.add("h3_jet_r_jet_pt_track_pt_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#it{p}_{T,jet tracks} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_pt_track_eta_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_pt_track_phi_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_pt_candidate_pt_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#it{p}_{T,candidate} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_pt_candidate_eta_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#eta_{candidate}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_pt_candidate_phi_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});#varphi_{candidate}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_pt_candidate_y_eventwiseconstituentsubtracted", "#it{R}_{jet};#it{p}_{T,jet} (GeV/#it{c});y_{candidate}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + } + + if (doprocessRho) { + registry.add("h2_centrality_ntracks", "; centrality; N_{tracks};", {HistType::kTH2F, {{1100, 0., 110.0}, {10000, 0.0, 10000.0}}}); + registry.add("h2_ntracks_rho", "; N_{tracks}; #it{rho} (GeV/area);", {HistType::kTH2F, {{10000, 0.0, 10000.0}, {400, 0.0, 400.0}}}); + registry.add("h2_ntracks_rhom", "; N_{tracks}; #it{rho}_{m} (GeV/area);", {HistType::kTH2F, {{10000, 0.0, 10000.0}, {100, 0.0, 100.0}}}); + registry.add("h2_centrality_rho", "; centrality; #it{rho} (GeV/area);", {HistType::kTH2F, {{1100, 0., 110.}, {400, 0., 400.0}}}); + registry.add("h2_centrality_rhom", ";centrality; #it{rho}_{m} (GeV/area)", {HistType::kTH2F, {{1100, 0., 110.}, {100, 0., 100.0}}}); + registry.add("h2_centrality_rhoRandomCone", "; centrality; #it{p}_{T,random cone} - #it{area, random cone} * #it{rho} (GeV/c);", {HistType::kTH2F, {{1100, 0., 110.}, {400, -200.0, 200.0}}}); + } + if (doprocessJetsMCP || doprocessJetsMCPWeighted) { registry.add("h_jet_pt_part", "jet pT;#it{p}_{T,jet}^{part}(GeV/#it{c});entries", {HistType::kTH1F, {{200, 0., 200.}}}); registry.add("h_jet_eta_part", "jet #eta;#eta_{jet}^{part};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}); registry.add("h_jet_phi_part", "jet #varphi;#varphi_{jet}^{part};entries", {HistType::kTH1F, {{160, -1.0, 7.}}}); - registry.add("h_jet_ntracks_part", "jet N tracks;N_{jet tracks}^{part};entries", {HistType::kTH1F, {{100, -0.5, 99.5}}}); + registry.add("h_jet_ntracks_part", "jet N tracks;N_{jet tracks}^{part};entries", {HistType::kTH1F, {{200, -0.5, 199.5}}}); registry.add("h3_jet_r_part_jet_pt_part_jet_eta_part", ";#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});#eta_{jet}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); registry.add("h3_jet_r_part_jet_pt_part_jet_phi_part", ";#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});#varphi_{jet}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); registry.add("h3_jet_r_part_jet_eta_part_jet_phi_part", ";#it{R}_{jet}^{part};#eta_{jet}^{part};#varphi_{jet}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {160, -1.0, 7.}}}); - registry.add("h3_jet_r_part_jet_pt_part_jet_ntracks_part", "#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});N_{jet tracks}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -0.5, 99.5}}}); + registry.add("h3_jet_r_part_jet_pt_part_jet_ntracks_part", "#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});N_{jet tracks}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, -0.5, 199.5}}}); registry.add("h3_jet_r_part_jet_pt_part_track_pt_part", "#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});#it{p}_{T,jet tracks}^{part} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); registry.add("h3_jet_r_part_jet_pt_part_track_eta_part", "#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});#eta_{jet tracks}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); registry.add("h3_jet_r_part_jet_pt_part_track_phi_part", "#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});#varphi_{jet tracks}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); @@ -137,21 +195,104 @@ struct JetFinderHFQATask { registry.add("h3_jet_r_part_jet_pt_part_candidate_y_part", "#it{R}_{jet}^{part};#it{p}_{T,jet}^{part} (GeV/#it{c});y_{candidate}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); } - if (doprocessJetsMCPMCDMatched || doprocessJetsMCPMCDMatchedWeighted) { - registry.add("h3_jet_r_jet_pt_part_jet_pt", "#it{R}_{jet};#it{p}_{T,jet}^{part} (GeV/#it{c});#it{p}_{T,jet} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); - registry.add("h3_jet_r_jet_eta_part_jet_eta", "#it{R}_{jet};#eta_{jet}^{part};#eta_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); - registry.add("h3_jet_r_jet_phi_part_jet_phi", "#it{R}_{jet};#varphi_{jet}^{part};#varphi_{jet}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); - registry.add("h3_jet_r_jet_ntracks_part_jet_ntracks", "#it{R}_{jet};N_{jet tracks}^{part};N_{jet tracks}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -0.5, 99.5}, {100, -0.5, 99.5}}}); - registry.add("h3_jet_r_candidate_pt_part_candidate_pt", "#it{R}_{jet};#it{p}_{T,candidate}^{part} (GeV/#it{c});#it{p}_{T,candidate} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); - registry.add("h3_jet_r_candidate_eta_part_candidate_eta", "#it{R}_{jet};#eta_{candidate}^{part};#eta_{candidate}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); - registry.add("h3_jet_r_candidate_phi_part_candidate_phi", "#it{R}_{jet};#varphi_{candidate}^{part};#varphi_{candidate}", {HistType::kTH3F, {{jetRadiiBins, ""}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); - registry.add("h3_jet_r_candidate_y_part_candidate_y", "#it{R}_{jet};#y_{candidate}^{part};#y_{candidate}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); - registry.add("h3_jet_r_jet_pt_part_jet_pt_diff", "#it{R}_{jet};#it{p}_{T,jet}^{part} (GeV/#it{c}); (#it{p}_{T,jet}^{part} (GeV/#it{c}) - #it{p}_{T,jet} (GeV/#it{c})) / #it{p}_{T,jet}^{part} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); - registry.add("h3_jet_r_jet_pt_part_jet_eta_diff", "#it{R}_{jet};#it{p}_{T,jet}^{part} (GeV/#it{c}); (#eta_{jet}^{part} - #eta_{jet}) / #eta_{jet}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); - registry.add("h3_jet_r_jet_pt_part_jet_phi_diff", "#it{R}_{jet};#it{p}_{T,jet}^{part} (GeV/#it{c}); (#varphi_{jet}^{part} - #varphi_{jet}) / #varphi_{jet}^{part}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); - registry.add("h3_jet_pt_part_jet_eta_part_jet_eta", ";#it{p}_{T,jet}^{part} (GeV/#it{c}); #eta_{jet}^{part}; #eta_{jet}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); - registry.add("h3_jet_pt_part_jet_phi_part_jet_phi", ";#it{p}_{T,jet}^{part} (GeV/#it{c}); #varphi_{jet}^{part}; #varphi_{jet}", {HistType::kTH3F, {{200, 0.0, 200}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); - registry.add("h3_jet_pt_part_jet_ntracks_part_jet_ntracks", ";#it{p}_{T,jet}^{part} (GeV/#it{c}); N_{jet tracks}^{part}; N_{jet tracks}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -0.5, 99.5}, {100, -0.5, 99.5}}}); + if (doprocessJetsMCPMCDMatched || doprocessJetsMCPMCDMatchedWeighted || doprocessJetsSubMatched) { + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_matchedgeo", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c});#it{p}_{T,jet}^{base} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_eta_tag_jet_eta_base_matchedgeo", "#it{R}_{jet};#eta_{jet}^{tag};#eta_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_phi_tag_jet_phi_base_matchedgeo", "#it{R}_{jet};#varphi_{jet}^{tag};#varphi_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedgeo", "#it{R}_{jet};N_{jet tracks}^{tag};N_{jet tracks}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_candidate_pt_tag_candidate_pt_base_matchedgeo", "#it{R}_{jet};#it{p}_{T,candidate}^{tag} (GeV/#it{c});#it{p}_{T,candidate}^{base} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_candidate_eta_tag_candidate_eta_base_matchedgeo", "#it{R}_{jet};#eta_{candidate}^{tag};#eta_{candidate}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_candidate_phi_tag_candidate_phi_base_matchedgeo", "#it{R}_{jet};#varphi_{candidate}^{tag};#varphi_{candidate}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedgeo", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#it{p}_{T,jet}^{tag} (GeV/#it{c}) - #it{p}_{T,jet}^{base} (GeV/#it{c})) / #it{p}_{T,jet}^{tag} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedgeo", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#eta_{jet}^{tag} - #eta_{jet}^{base}) / #eta_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedgeo", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#varphi_{jet}^{tag} - #varphi_{jet}^{base}) / #varphi_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedgeo", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #eta_{jet}^{tag}; #eta_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedgeo", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #varphi_{jet}^{tag}; #varphi_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedgeo", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); N_{jet tracks}^{tag}; N_{jet tracks}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_matchedpt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c});#it{p}_{T,jet}^{base} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_eta_tag_jet_eta_base_matchedpt", "#it{R}_{jet};#eta_{jet}^{tag};#eta_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_phi_tag_jet_phi_base_matchedpt", "#it{R}_{jet};#varphi_{jet}^{tag};#varphi_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedpt", "#it{R}_{jet};N_{jet tracks}^{tag};N_{jet tracks}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_candidate_pt_tag_candidate_pt_base_matchedpt", "#it{R}_{jet};#it{p}_{T,candidate}^{tag} (GeV/#it{c});#it{p}_{T,candidate} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_candidate_eta_tag_candidate_eta_base_matchedpt", "#it{R}_{jet};#eta_{candidate}^{tag};#eta_{candidate}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_candidate_phi_tag_candidate_phi_base_matchedpt", "#it{R}_{jet};#varphi_{candidate}^{tag};#varphi_{candidate}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedpt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#it{p}_{T,jet}^{tag} (GeV/#it{c}) - #it{p}_{T,jet}^{base} (GeV/#it{c})) / #it{p}_{T,jet}^{tag} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedpt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#eta_{jet}^{tag} - #eta_{jet}^{base}) / #eta_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedpt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#varphi_{jet}^{tag} - #varphi_{jet}^{base}) / #varphi_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedpt", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #eta_{jet}^{tag}; #eta_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedpt", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #varphi_{jet}^{tag}; #varphi_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedpt", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); N_{jet tracks}^{tag}; N_{jet tracks}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_matchedgeopt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c});#it{p}_{T,jet}^{base} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_eta_tag_jet_eta_base_matchedgeopt", "#it{R}_{jet};#eta_{jet}^{tag};#eta_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_phi_tag_jet_phi_base_matchedgeopt", "#it{R}_{jet};#varphi_{jet}^{tag};#varphi_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedgeopt", "#it{R}_{jet};N_{jet tracks}^{tag};N_{jet tracks}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_candidate_pt_tag_candidate_pt_base_matchedgeopt", "#it{R}_{jet};#it{p}_{T,candidate}^{tag} (GeV/#it{c});#it{p}_{T,candidate} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_candidate_eta_tag_candidate_eta_base_matchedgeopt", "#it{R}_{jet};#eta_{candidate}^{tag};#eta_{candidate}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_candidate_phi_tag_candidate_phi_base_matchedgeopt", "#it{R}_{jet};#varphi_{candidate}^{tag};#varphi_{candidate}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedgeopt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#it{p}_{T,jet}^{tag} (GeV/#it{c}) - #it{p}_{T,jet}^{base} (GeV/#it{c})) / #it{p}_{T,jet}^{tag} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedgeopt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#eta_{jet}^{tag} - #eta_{jet}^{base}) / #eta_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedgeopt", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#varphi_{jet}^{tag} - #varphi_{jet}^{base}) / #varphi_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedgeopt", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #eta_{jet}^{tag}; #eta_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedgeopt", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #varphi_{jet}^{tag}; #varphi_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedgeopt", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); N_{jet tracks}^{tag}; N_{jet tracks}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_matchedhf", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c});#it{p}_{T,jet}^{base} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_eta_tag_jet_eta_base_matchedhf", "#it{R}_{jet};#eta_{jet}^{tag};#eta_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_phi_tag_jet_phi_base_matchedhf", "#it{R}_{jet};#varphi_{jet}^{tag};#varphi_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedhf", "#it{R}_{jet};N_{jet tracks}^{tag};N_{jet tracks}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_candidate_pt_tag_candidate_pt_base_matchedhf", "#it{R}_{jet};#it{p}_{T,candidate}^{tag} (GeV/#it{c});#it{p}_{T,candidate} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_candidate_eta_tag_candidate_eta_base_matchedhf", "#it{R}_{jet};#eta_{candidate}^{tag};#eta_{candidate}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_candidate_phi_tag_candidate_phi_base_matchedhf", "#it{R}_{jet};#varphi_{candidate}^{tag};#varphi_{candidate}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedhf", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#it{p}_{T,jet}^{tag} (GeV/#it{c}) - #it{p}_{T,jet}^{base} (GeV/#it{c})) / #it{p}_{T,jet}^{tag} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedhf", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#eta_{jet}^{tag} - #eta_{jet}^{base}) / #eta_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedhf", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#varphi_{jet}^{tag} - #varphi_{jet}^{base}) / #varphi_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedhf", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #eta_{jet}^{tag}; #eta_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedhf", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #varphi_{jet}^{tag}; #varphi_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedhf", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); N_{jet tracks}^{tag}; N_{jet tracks}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_matchedgeohf", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c});#it{p}_{T,jet}^{base} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_eta_tag_jet_eta_base_matchedgeohf", "#it{R}_{jet};#eta_{jet}^{tag};#eta_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_phi_tag_jet_phi_base_matchedgeohf", "#it{R}_{jet};#varphi_{jet}^{tag};#varphi_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedgeohf", "#it{R}_{jet};N_{jet tracks}^{tag};N_{jet tracks}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_candidate_pt_tag_candidate_pt_base_matchedgeohf", "#it{R}_{jet};#it{p}_{T,candidate}^{tag} (GeV/#it{c});#it{p}_{T,candidate} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_candidate_eta_tag_candidate_eta_base_matchedgeohf", "#it{R}_{jet};#eta_{candidate}^{tag};#eta_{candidate}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_candidate_phi_tag_candidate_phi_base_matchedgeohf", "#it{R}_{jet};#varphi_{candidate}^{tag};#varphi_{candidate}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedgeohf", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#it{p}_{T,jet}^{tag} (GeV/#it{c}) - #it{p}_{T,jet}^{base} (GeV/#it{c})) / #it{p}_{T,jet}^{tag} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedgeohf", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#eta_{jet}^{tag} - #eta_{jet}^{base}) / #eta_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedgeohf", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#varphi_{jet}^{tag} - #varphi_{jet}^{base}) / #varphi_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedgeohf", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #eta_{jet}^{tag}; #eta_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedgeohf", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #varphi_{jet}^{tag}; #varphi_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedgeohf", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); N_{jet tracks}^{tag}; N_{jet tracks}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_matchedpthf", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c});#it{p}_{T,jet}^{base} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_eta_tag_jet_eta_base_matchedpthf", "#it{R}_{jet};#eta_{jet}^{tag};#eta_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_phi_tag_jet_phi_base_matchedpthf", "#it{R}_{jet};#varphi_{jet}^{tag};#varphi_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedpthf", "#it{R}_{jet};N_{jet tracks}^{tag};N_{jet tracks}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_candidate_pt_tag_candidate_pt_base_matchedpthf", "#it{R}_{jet};#it{p}_{T,candidate}^{tag} (GeV/#it{c});#it{p}_{T,candidate} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_candidate_eta_tag_candidate_eta_base_matchedpthf", "#it{R}_{jet};#eta_{candidate}^{tag};#eta_{candidate}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_candidate_phi_tag_candidate_phi_base_matchedpthf", "#it{R}_{jet};#varphi_{candidate}^{tag};#varphi_{candidate}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedpthf", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#it{p}_{T,jet}^{tag} (GeV/#it{c}) - #it{p}_{T,jet}^{base} (GeV/#it{c})) / #it{p}_{T,jet}^{tag} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedpthf", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#eta_{jet}^{tag} - #eta_{jet}^{base}) / #eta_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedpthf", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#varphi_{jet}^{tag} - #varphi_{jet}^{base}) / #varphi_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedpthf", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #eta_{jet}^{tag}; #eta_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedpthf", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #varphi_{jet}^{tag}; #varphi_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedpthf", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); N_{jet tracks}^{tag}; N_{jet tracks}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_matchedgeopthf", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c});#it{p}_{T,jet}^{base} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_jet_eta_tag_jet_eta_base_matchedgeopthf", "#it{R}_{jet};#eta_{jet}^{tag};#eta_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_jet_phi_tag_jet_phi_base_matchedgeopthf", "#it{R}_{jet};#varphi_{jet}^{tag};#varphi_{jet}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedgeopthf", "#it{R}_{jet};N_{jet tracks}^{tag};N_{jet tracks}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); + registry.add("h3_jet_r_candidate_pt_tag_candidate_pt_base_matchedgeopthf", "#it{R}_{jet};#it{p}_{T,candidate}^{tag} (GeV/#it{c});#it{p}_{T,candidate} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0., 200.}, {200, 0., 200.}}}); + registry.add("h3_jet_r_candidate_eta_tag_candidate_eta_base_matchedgeopthf", "#it{R}_{jet};#eta_{candidate}^{tag};#eta_{candidate}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_r_candidate_phi_tag_candidate_phi_base_matchedgeopthf", "#it{R}_{jet};#varphi_{candidate}^{tag};#varphi_{candidate}^{base}", {HistType::kTH3F, {{jetRadiiBins, ""}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedgeopthf", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#it{p}_{T,jet}^{tag} (GeV/#it{c}) - #it{p}_{T,jet}^{base} (GeV/#it{c})) / #it{p}_{T,jet}^{tag} (GeV/#it{c})", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedgeopthf", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#eta_{jet}^{tag} - #eta_{jet}^{base}) / #eta_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedgeopthf", "#it{R}_{jet};#it{p}_{T,jet}^{tag} (GeV/#it{c}); (#varphi_{jet}^{tag} - #varphi_{jet}^{base}) / #varphi_{jet}^{tag}", {HistType::kTH3F, {{jetRadiiBins, ""}, {200, 0.0, 200}, {1000, -5.0, 5.0}}}); + registry.add("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedgeopthf", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #eta_{jet}^{tag}; #eta_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {100, -1.0, 1.0}, {100, -1.0, 1.0}}}); + registry.add("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedgeopthf", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); #varphi_{jet}^{tag}; #varphi_{jet}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {160, -1.0, 7.}, {160, -1.0, 7.}}}); + registry.add("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedgeopthf", ";#it{p}_{T,jet}^{tag} (GeV/#it{c}); N_{jet tracks}^{tag}; N_{jet tracks}^{base}", {HistType::kTH3F, {{200, 0.0, 200}, {200, -0.5, 199.5}, {200, -0.5, 199.5}}}); } if (doprocessTriggeredData) { @@ -214,27 +355,59 @@ struct JetFinderHFQATask { } } + if (doprocessTracksSub) { + + registry.add("h_track_pt_eventwiseconstituentsubtracted", "track pT;#it{p}_{T,track} (GeV/#it{c});entries", {HistType::kTH1F, {{200, 0., 200.}}}); + registry.add("h_track_eta_eventwiseconstituentsubtracted", "track #eta;#eta_{track};entries", {HistType::kTH1F, {{100, -1.0, 1.0}}}); + registry.add("h_track_phi_eventwiseconstituentsubtracted", "track #varphi;#varphi_{track};entries", {HistType::kTH1F, {{160, -1.0, 7.}}}); + } + if (doprocessMCCollisionsWeighted) { AxisSpec weightAxis = {{VARIABLE_WIDTH, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1.0, 10.0}, "weights"}; registry.add("h_collision_eventweight_part", "event weight;event weight;entries", {HistType::kTH1F, {weightAxis}}); } + + if (doprocessCandidates) { + registry.add("h_candidate_invmass", ";#it{m}_{inv, candidate} (GeV/#it{c}^{2});counts", {HistType::kTH1F, {{500, 0.0, 5.0}}}); + registry.add("h_candidate_pt", ";#it{p}_{T,candidate} (GeV/#it{c});counts", {HistType::kTH1F, {{200, 0.0, 200.0}}}); + registry.add("h_candidate_y", ";y_{candidate};counts", {HistType::kTH1F, {{100, -1.0, 1.0}}}); + registry.add("h2_centrality_ncandidates", "centrality vs N_{candidates};centrality;N_{candidates};", {HistType::kTH2F, {{1200, -10.0, 110.0}, {100, 0.0, 100.0}}}); + } } - using JetTracks = aod::JTracks; using JetTableDataJoined = soa::Join; + using JetTableDataMatchedJoined = soa::Join; + using JetTableDataSubJoined = soa::Join; + using JetTableDataSubMatchedJoined = soa::Join; + using JetTableMCDJoined = soa::Join; using JetTableMCDWeightedJoined = soa::Join; using JetTableMCDMatchedJoined = soa::Join; using JetTableMCDMatchedWeightedJoined = soa::Join; + using JetTableMCPJoined = soa::Join; using JetTableMCPWeightedJoined = soa::Join; using JetTableMCPMatchedJoined = soa::Join; using JetTableMCPMatchedWeightedJoined = soa::Join; Filter trackCuts = (aod::jtrack::pt >= trackPtMin && aod::jtrack::pt < trackPtMax && aod::jtrack::eta > trackEtaMin && aod::jtrack::eta < trackEtaMax); + Filter trackSubCuts = (aod::jtracksub::pt >= trackPtMin && aod::jtracksub::pt < trackPtMax && aod::jtracksub::eta > trackEtaMin && aod::jtracksub::eta < trackEtaMax); + Filter eventCuts = (nabs(aod::jcollision::posZ) < vertexZCut && aod::jcollision::centrality >= centralityMin && aod::jcollision::centrality < centralityMax); + + // Filter candidateCutsD0 = (aod::hf_sel_candidate_d0::isSelD0 >= selectionFlagD0 || aod::hf_sel_candidate_d0::isSelD0bar >= selectionFlagD0bar); + // Filter candidateCutsLc = (aod::hf_sel_candidate_lc::isSelLcToPKPi >= selectionFlagLcToPKPi || aod::hf_sel_candidate_lc::isSelLcToPiKP >= selectionFlagLcToPiPK); + // Filter candidateCutsBplus = (aod::hf_sel_candidate_bplus::isSelBplusToD0Pi >= selectionFlagBplus); + + PresliceOptional> perD0CandidateTracks = aod::bkgd0::candidateId; + PresliceOptional> perLcCandidateTracks = aod::bkglc::candidateId; + PresliceOptional> perBplusCandidateTracks = aod::bkgbplus::candidateId; + + PresliceOptional perD0CandidateRhos = aod::bkgd0::candidateId; + PresliceOptional perLcCandidateRhos = aod::bkglc::candidateId; + PresliceOptional perBplusCandidateRhos = aod::bkgbplus::candidateId; template - void fillHistograms(T const& jet, float weight = 1.0) + void fillHistograms(T const& jet, float centrality, float weight = 1.0) { float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); @@ -246,9 +419,14 @@ struct JetFinderHFQATask { registry.fill(HIST("h_jet_pt"), jet.pt(), weight); registry.fill(HIST("h_jet_eta"), jet.eta(), weight); registry.fill(HIST("h_jet_phi"), jet.phi(), weight); - registry.fill(HIST("h_jet_ntracks"), jet.tracks().size() + jet.hfcandidates().size(), weight); + registry.fill(HIST("h_jet_ntracks"), jet.tracks().size(), weight); + registry.fill(HIST("h2_centrality_jet_pt"), centrality, jet.pt(), weight); + registry.fill(HIST("h2_centrality_jet_eta"), centrality, jet.eta(), weight); + registry.fill(HIST("h2_centrality_jet_phi"), centrality, jet.phi(), weight); + registry.fill(HIST("h2_centrality_jet_ntracks"), centrality, jet.tracks().size(), weight); } + registry.fill(HIST("h3_jet_r_jet_pt_centrality"), jet.r() / 100.0, jet.pt(), centrality, weight); registry.fill(HIST("h3_jet_r_jet_pt_jet_eta"), jet.r() / 100.0, jet.pt(), jet.eta(), weight); registry.fill(HIST("h3_jet_r_jet_pt_jet_phi"), jet.r() / 100.0, jet.pt(), jet.phi(), weight); registry.fill(HIST("h3_jet_r_jet_eta_jet_phi"), jet.r() / 100.0, jet.eta(), jet.phi(), weight); @@ -271,38 +449,87 @@ struct JetFinderHFQATask { registry.fill(HIST("h3_jet_r_jet_pt_candidate_pt"), jet.r() / 100.0, jet.pt(), hfcandidate.pt(), weight); registry.fill(HIST("h3_jet_r_jet_pt_candidate_eta"), jet.r() / 100.0, jet.pt(), hfcandidate.eta(), weight); registry.fill(HIST("h3_jet_r_jet_pt_candidate_phi"), jet.r() / 100.0, jet.pt(), hfcandidate.phi(), weight); - registry.fill(HIST("h3_jet_r_jet_pt_candidate_y"), jet.r() / 100.0, jet.pt(), hfcandidate.y(candMass), weight); + registry.fill(HIST("h3_jet_r_jet_pt_candidate_y"), jet.r() / 100.0, jet.pt(), hfcandidate.y(), weight); if (jet.r() == round(selectedJetsRadius * 100.0f)) { - if constexpr (std::is_same_v, soa::Join> || std::is_same_v, soa::Join>) { - if (hfcandidate.isSelD0() >= selectionFlagD0) { - registry.fill(HIST("h3_candidate_invmass_jet_pt_candidate_pt"), hfHelper.invMassD0ToPiK(hfcandidate), jet.pt(), hfcandidate.pt(), weight); - } - if (hfcandidate.isSelD0bar() >= selectionFlagD0bar) { - registry.fill(HIST("h3_candidatebar_invmass_jet_pt_candidate_pt"), hfHelper.invMassD0barToKPi(hfcandidate), jet.pt(), hfcandidate.pt(), weight); - } - } - - if constexpr (std::is_same_v, soa::Join> || std::is_same_v, soa::Join>) { - if (hfcandidate.isSelLcToPKPi() >= selectionFlagLcToPKPi) { - registry.fill(HIST("h3_candidate_invmass_jet_pt_candidate_pt"), hfHelper.invMassLcToPKPi(hfcandidate), jet.pt(), hfcandidate.pt(), weight); - } - if (hfcandidate.isSelLcToPiKP() >= selectionFlagLcToPiPK) { - registry.fill(HIST("h3_candidatebar_invmass_jet_pt_candidate_pt"), hfHelper.invMassLcToPiKP(hfcandidate), jet.pt(), hfcandidate.pt(), weight); - } - } - - if constexpr (std::is_same_v, soa::Join> || std::is_same_v, soa::Join>) { - if (hfcandidate.isSelBplusToD0Pi() >= selectionFlagBplus) { - registry.fill(HIST("h3_candidate_invmass_jet_pt_candidate_pt"), hfHelper.invMassBplusToD0Pi(hfcandidate), jet.pt(), hfcandidate.pt(), weight); - registry.fill(HIST("h3_candidatebar_invmass_jet_pt_candidate_pt"), hfHelper.invMassBplusToD0Pi(hfcandidate), jet.pt(), hfcandidate.pt(), weight); - } - } + registry.fill(HIST("h3_candidate_invmass_jet_pt_candidate_pt"), hfcandidate.m(), jet.pt(), hfcandidate.pt(), weight); + registry.fill(HIST("h3_candidatebar_invmass_jet_pt_candidate_pt"), hfcandidate.m(), jet.pt(), hfcandidate.pt(), weight); } } } template + void fillRhoAreaSubtractedHistograms(T const& jet, float centrality, float rho, float weight = 1.0) + { + + if (jet.r() == round(selectedJetsRadius * 100.0f)) { + registry.fill(HIST("h_jet_pt_rhoareasubtracted"), jet.pt() - (rho * jet.area()), weight); + registry.fill(HIST("h_jet_eta_rhoareasubtracted"), jet.eta(), weight); + registry.fill(HIST("h_jet_phi_rhoareasubtracted"), jet.phi(), weight); + registry.fill(HIST("h_jet_ntracks_rhoareasubtracted"), jet.tracks().size(), weight); + registry.fill(HIST("h2_centrality_jet_pt_rhoareasubtracted"), centrality, jet.pt() - (rho * jet.area()), weight); + } + + registry.fill(HIST("h3_jet_r_jet_pt_centrality_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), centrality, weight); + registry.fill(HIST("h3_jet_r_jet_pt_jet_eta_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), jet.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_jet_phi_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), jet.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_eta_jet_phi_rhoareasubtracted"), jet.r() / 100.0, jet.eta(), jet.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_jet_ntracks_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), jet.tracks().size(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_jet_area_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), jet.area(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_jet_pt_rhoareasubtracted"), jet.r() / 100.0, jet.pt(), jet.pt() - (rho * jet.area()), weight); + + for (auto& constituent : jet.template tracks_as()) { + + registry.fill(HIST("h3_jet_r_jet_pt_track_pt_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), constituent.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_track_eta_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), constituent.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_track_phi_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), constituent.phi(), weight); + } + + for (auto& hfcandidate : jet.template hfcandidates_as>()) { + registry.fill(HIST("h3_jet_r_jet_pt_candidate_pt_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), hfcandidate.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_candidate_eta_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), hfcandidate.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_candidate_phi_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), hfcandidate.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_candidate_y_rhoareasubtracted"), jet.r() / 100.0, jet.pt() - (rho * jet.area()), hfcandidate.y(), weight); + } + } + + template + void fillEventWiseConstituentSubtractedHistograms(T const& jet, float centrality, float weight = 1.0) + { + if (jet.r() == round(selectedJetsRadius * 100.0f)) { + registry.fill(HIST("h_jet_pt_eventwiseconstituentsubtracted"), jet.pt(), weight); + registry.fill(HIST("h_jet_eta_eventwiseconstituentsubtracted"), jet.eta(), weight); + registry.fill(HIST("h_jet_phi_eventwiseconstituentsubtracted"), jet.phi(), weight); + registry.fill(HIST("h_jet_ntracks_eventwiseconstituentsubtracted"), jet.tracks().size(), weight); + registry.fill(HIST("h2_centrality_jet_pt_eventwiseconstituentsubtracted"), centrality, jet.pt(), weight); + registry.fill(HIST("h2_centrality_jet_eta_eventwiseconstituentsubtracted"), centrality, jet.eta(), weight); + registry.fill(HIST("h2_centrality_jet_phi_eventwiseconstituentsubtracted"), centrality, jet.phi(), weight); + registry.fill(HIST("h2_centrality_jet_ntracks_eventwiseconstituentsubtracted"), centrality, jet.tracks().size(), weight); + } + + registry.fill(HIST("h3_jet_r_jet_pt_centrality_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), centrality, weight); + registry.fill(HIST("h3_jet_r_jet_pt_jet_eta_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), jet.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_jet_phi_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), jet.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_eta_jet_phi_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.eta(), jet.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_jet_ntracks_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), jet.tracks().size(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_jet_area_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), jet.area(), weight); + + for (auto& constituent : jet.template tracks_as()) { + + registry.fill(HIST("h3_jet_r_jet_pt_track_pt_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), constituent.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_track_eta_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), constituent.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_track_phi_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), constituent.phi(), weight); + } + + for (auto& hfcandidate : jet.template hfcandidates_as>()) { + registry.fill(HIST("h3_jet_r_jet_pt_candidate_pt_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), hfcandidate.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_candidate_eta_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), hfcandidate.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_candidate_phi_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), hfcandidate.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_candidate_y_eventwiseconstituentsubtracted"), jet.r() / 100.0, jet.pt(), hfcandidate.y(), weight); + } + } + + template void fillMCPHistograms(T const& jet, float weight = 1.0) { @@ -330,7 +557,7 @@ struct JetFinderHFQATask { registry.fill(HIST("h3_jet_r_part_jet_pt_part_track_phi_part"), jet.r() / 100.0, jet.pt(), constituent.phi(), weight); } - for (auto& hfcandidate : jet.template hfcandidates_as>()) { + for (auto& hfcandidate : jet.template hfcandidates_as>()) { registry.fill(HIST("h3_jet_r_part_jet_pt_part_track_pt_part"), jet.r() / 100.0, jet.pt(), hfcandidate.pt(), weight); registry.fill(HIST("h3_jet_r_part_jet_pt_part_track_eta_part"), jet.r() / 100.0, jet.pt(), hfcandidate.eta(), weight); @@ -343,69 +570,245 @@ struct JetFinderHFQATask { } } - template - void fillMCMatchedHistograms(T const& mcdjet, float weight = 1.0) + template + void fillMatchedHistograms(T const& jetBase, float weight = 1.0) { float pTHat = 10. / (std::pow(weight, 1.0 / pTHatExponent)); - if (mcdjet.pt() > pTHatMaxMCD * pTHat) { + if (jetBase.pt() > pTHatMaxMCD * pTHat) { return; } - - for (auto& mcpjet : mcdjet.template matchedJetCand_as>()) { - - if (mcpjet.pt() > pTHatMaxMCP * pTHat) { - continue; + auto candidateBasePt = 0.0; + auto candidateBasePhi = 0.0; + auto candidateBaseEta = 0.0; + auto candidateTagPt = 0.0; + auto candidateTagPhi = 0.0; + auto candidateTagEta = 0.0; + + auto candidateBase = jetBase.template hfcandidates_first_as>(); + candidateBasePt = candidateBase.pt(); + candidateBasePhi = candidateBase.phi(); + candidateBaseEta = candidateBase.eta(); + + if (jetBase.has_matchedJetGeo()) { + for (auto& jetTag : jetBase.template matchedJetGeo_as>()) { + if (jetTag.pt() > pTHatMaxMCP * pTHat) { + continue; + } + auto candidateTag = jetTag.template hfcandidates_first_as>(); + candidateTagPt = candidateTag.pt(); + candidateTagPhi = candidateTag.phi(); + candidateTagEta = candidateTag.eta(); + + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_matchedgeo"), jetBase.r() / 100.0, jetTag.pt(), jetBase.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_eta_tag_jet_eta_base_matchedgeo"), jetBase.r() / 100.0, jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_phi_tag_jet_phi_base_matchedgeo"), jetBase.r() / 100.0, jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedgeo"), jetBase.r() / 100.0, jetTag.tracks().size(), jetBase.tracks().size(), weight); + registry.fill(HIST("h3_jet_r_candidate_pt_tag_candidate_pt_base_matchedgeo"), jetBase.r() / 100.0, candidateTagPt, candidateBasePt, weight); + registry.fill(HIST("h3_jet_r_candidate_eta_tag_candidate_eta_base_matchedgeo"), jetBase.r() / 100.0, candidateTagEta, candidateBaseEta, weight); + registry.fill(HIST("h3_jet_r_candidate_phi_tag_candidate_phi_base_matchedgeo"), jetBase.r() / 100.0, candidateTagPhi, candidateBasePhi, weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedgeo"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.pt() - jetBase.pt()) / jetTag.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedgeo"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.eta() - jetBase.eta()) / jetTag.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedgeo"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.phi() - jetBase.phi()) / jetTag.phi(), weight); + + if (jetBase.r() == round(selectedJetsRadius * 100.0f)) { + registry.fill(HIST("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedgeo"), jetTag.pt(), jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedgeo"), jetTag.pt(), jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedgeo"), jetTag.pt(), jetTag.tracks().size(), jetBase.tracks().size(), weight); + } } + } + if (jetBase.has_matchedJetPt()) { - auto mcdCandPt = 0.0; - auto mcdCandPhi = 0.0; - auto mcdCandEta = 0.0; - auto mcdCandY = 0.0; - auto mcpCandPt = 0.0; - auto mcpCandPhi = 0.0; - auto mcpCandEta = 0.0; - auto mcpCandY = 0.0; - for (auto& hfcandidate_mcd : mcdjet.template hfcandidates_as>()) { - - mcdCandPt = hfcandidate_mcd.pt(); - mcdCandPhi = hfcandidate_mcd.phi(); - mcdCandEta = hfcandidate_mcd.eta(); - mcdCandY = hfcandidate_mcd.y(candMass); + for (auto& jetTag : jetBase.template matchedJetPt_as>()) { + if (jetTag.pt() > pTHatMaxMCP * pTHat) { + continue; + } + auto candidateTag = jetTag.template hfcandidates_first_as>(); + candidateTagPt = candidateTag.pt(); + candidateTagPhi = candidateTag.phi(); + candidateTagEta = candidateTag.eta(); + + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_matchedpt"), jetBase.r() / 100.0, jetTag.pt(), jetBase.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_eta_tag_jet_eta_base_matchedpt"), jetBase.r() / 100.0, jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_phi_tag_jet_phi_base_matchedpt"), jetBase.r() / 100.0, jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedpt"), jetBase.r() / 100.0, jetTag.tracks().size(), jetBase.tracks().size(), weight); + registry.fill(HIST("h3_jet_r_candidate_pt_tag_candidate_pt_base_matchedpt"), jetBase.r() / 100.0, candidateTagPt, candidateBasePt, weight); + registry.fill(HIST("h3_jet_r_candidate_eta_tag_candidate_eta_base_matchedpt"), jetBase.r() / 100.0, candidateTagEta, candidateBaseEta, weight); + registry.fill(HIST("h3_jet_r_candidate_phi_tag_candidate_phi_base_matchedpt"), jetBase.r() / 100.0, candidateTagPhi, candidateBasePhi, weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_base_diff_matchedpt"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.pt() - jetBase.pt()) / jetTag.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_eta_base_base_diff_matchedpt"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.eta() - jetBase.eta()) / jetTag.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_phi_base_base_diff_matchedpt"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.phi() - jetBase.phi()) / jetTag.phi(), weight); + + if (jetBase.r() == round(selectedJetsRadius * 100.0f)) { + registry.fill(HIST("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedpt"), jetTag.pt(), jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedpt"), jetTag.pt(), jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedpt"), jetTag.pt(), jetTag.tracks().size(), jetBase.tracks().size(), weight); + } } - - for (auto& hfcandidate_mcp : mcpjet.template hfcandidates_as>()) { - - mcpCandPt = hfcandidate_mcp.pt(); - mcpCandPhi = hfcandidate_mcp.phi(); - mcpCandEta = hfcandidate_mcp.eta(); - mcpCandY = hfcandidate_mcp.y(); + } + if (jetBase.has_matchedJetCand()) { + for (auto& jetTag : jetBase.template matchedJetCand_as>()) { + if (jetTag.pt() > pTHatMaxMCP * pTHat) { + continue; + } + auto candidateTag = jetTag.template hfcandidates_first_as>(); + candidateTagPt = candidateTag.pt(); + candidateTagPhi = candidateTag.phi(); + candidateTagEta = candidateTag.eta(); + + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_matchedhf"), jetBase.r() / 100.0, jetTag.pt(), jetBase.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_eta_tag_jet_eta_base_matchedghf"), jetBase.r() / 100.0, jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_phi_tag_jet_phi_base_matchedghf"), jetBase.r() / 100.0, jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedghf"), jetBase.r() / 100.0, jetTag.tracks().size(), jetBase.tracks().size(), weight); + registry.fill(HIST("h3_jet_r_candidate_pt_tag_candidate_pt_base_matchedghf"), jetBase.r() / 100.0, candidateTagPt, candidateBasePt, weight); + registry.fill(HIST("h3_jet_r_candidate_eta_tag_candidate_eta_base_matchedghf"), jetBase.r() / 100.0, candidateTagEta, candidateBaseEta, weight); + registry.fill(HIST("h3_jet_r_candidate_phi_tag_candidate_phi_base_matchedghf"), jetBase.r() / 100.0, candidateTagPhi, candidateBasePhi, weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_diff_matchedghf"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.pt() - jetBase.pt()) / jetTag.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_eta_base_diff_matchedghf"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.eta() - jetBase.eta()) / jetTag.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_phi_base_diff_matchedghf"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.phi() - jetBase.phi()) / jetTag.phi(), weight); + + if (jetBase.r() == round(selectedJetsRadius * 100.0f)) { + registry.fill(HIST("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedghf"), jetTag.pt(), jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedghf"), jetTag.pt(), jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedhf"), jetTag.pt(), jetTag.tracks().size(), jetBase.tracks().size(), weight); + } } + } + if (jetBase.has_matchedJetGeo() && jetBase.has_matchedJetPt()) { + for (auto& jetTag : jetBase.template matchedJetGeo_as>()) { + if (jetTag.pt() > pTHatMaxMCP * pTHat) { + continue; + } + if (jetBase.template matchedJetGeo_first_as>().globalIndex() == jetBase.template matchedJetPt_first_as>().globalIndex()) { // not a good way to do this + + auto candidateTag = jetTag.template hfcandidates_first_as>(); + candidateTagPt = candidateTag.pt(); + candidateTagPhi = candidateTag.phi(); + candidateTagEta = candidateTag.eta(); + + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_matchedgeopt"), jetBase.r() / 100.0, jetTag.pt(), jetBase.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_eta_tag_jet_eta_base_matchedgeopt"), jetBase.r() / 100.0, jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_phi_tag_jet_phi_base_matchedgeopt"), jetBase.r() / 100.0, jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedgeopt"), jetBase.r() / 100.0, jetTag.tracks().size(), jetBase.tracks().size(), weight); + registry.fill(HIST("h3_jet_r_candidate_pt_tag_candidate_pt_base_matchedgeopt"), jetBase.r() / 100.0, candidateTagPt, candidateBasePt, weight); + registry.fill(HIST("h3_jet_r_candidate_eta_tag_candidate_eta_base_matchedgeopt"), jetBase.r() / 100.0, candidateTagEta, candidateBaseEta, weight); + registry.fill(HIST("h3_jet_r_candidate_phi_tag_candidate_phi_base_matchedgeopt"), jetBase.r() / 100.0, candidateTagPhi, candidateBasePhi, weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_base_diff_matchedgeopt"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.pt() - jetBase.pt()) / jetTag.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_eta_base_base_diff_matchedgeopt"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.eta() - jetBase.eta()) / jetTag.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_phi_base_base_diff_matchedgeopt"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.phi() - jetBase.phi()) / jetTag.phi(), weight); + + if (jetBase.r() == round(selectedJetsRadius * 100.0f)) { + registry.fill(HIST("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedgeopt"), jetTag.pt(), jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedgeopt"), jetTag.pt(), jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedgeopt"), jetTag.pt(), jetTag.tracks().size(), jetBase.tracks().size(), weight); + } + } + } + } + if (jetBase.has_matchedJetGeo() && jetBase.has_matchedJetCand()) { + for (auto& jetTag : jetBase.template matchedJetGeo_as>()) { + if (jetTag.pt() > pTHatMaxMCP * pTHat) { + continue; + } + if (jetBase.template matchedJetGeo_first_as>().globalIndex() == jetBase.template matchedJetCand_first_as>().globalIndex()) { // not a good way to do this + + auto candidateTag = jetTag.template hfcandidates_first_as>(); + candidateTagPt = candidateTag.pt(); + candidateTagPhi = candidateTag.phi(); + candidateTagEta = candidateTag.eta(); + + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_matchedgeohf"), jetBase.r() / 100.0, jetTag.pt(), jetBase.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_eta_tag_jet_eta_base_matchedgeohf"), jetBase.r() / 100.0, jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_phi_tag_jet_phi_base_matchedgeohf"), jetBase.r() / 100.0, jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedgeohf"), jetBase.r() / 100.0, jetTag.tracks().size(), jetBase.tracks().size(), weight); + registry.fill(HIST("h3_jet_r_candidate_pt_tag_candidate_pt_base_matchedgeohf"), jetBase.r() / 100.0, candidateTagPt, candidateBasePt, weight); + registry.fill(HIST("h3_jet_r_candidate_eta_tag_candidate_eta_base_matchedgeohf"), jetBase.r() / 100.0, candidateTagEta, candidateBaseEta, weight); + registry.fill(HIST("h3_jet_r_candidate_phi_tag_candidate_phi_base_matchedgeohf"), jetBase.r() / 100.0, candidateTagPhi, candidateBasePhi, weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_base_diff_matchedgeohf"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.pt() - jetBase.pt()) / jetTag.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_eta_base_base_diff_matchedgeohf"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.eta() - jetBase.eta()) / jetTag.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_phi_base_base_diff_matchedgeohf"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.phi() - jetBase.phi()) / jetTag.phi(), weight); + + if (jetBase.r() == round(selectedJetsRadius * 100.0f)) { + registry.fill(HIST("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedgeohf"), jetTag.pt(), jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedgeohf"), jetTag.pt(), jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedgeohf"), jetTag.pt(), jetTag.tracks().size(), jetBase.tracks().size(), weight); + } + } + } + } + if (jetBase.has_matchedJetPt() && jetBase.has_matchedJetCand()) { + for (auto& jetTag : jetBase.template matchedJetPt_as>()) { + if (jetTag.pt() > pTHatMaxMCP * pTHat) { + continue; + } + if (jetBase.template matchedJetPt_first_as>().globalIndex() == jetBase.template matchedJetCand_first_as>().globalIndex()) { // not a good way to do this + + auto candidateTag = jetTag.template hfcandidates_first_as>(); + candidateTagPt = candidateTag.pt(); + candidateTagPhi = candidateTag.phi(); + candidateTagEta = candidateTag.eta(); + + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_matchedpthf"), jetBase.r() / 100.0, jetTag.pt(), jetBase.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_eta_tag_jet_eta_base_matchedpthf"), jetBase.r() / 100.0, jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_phi_tag_jet_phi_base_matchedpthf"), jetBase.r() / 100.0, jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedpthf"), jetBase.r() / 100.0, jetTag.tracks().size(), jetBase.tracks().size(), weight); + registry.fill(HIST("h3_jet_r_candidate_pt_tag_candidate_pt_base_matchedpthf"), jetBase.r() / 100.0, candidateTagPt, candidateBasePt, weight); + registry.fill(HIST("h3_jet_r_candidate_eta_tag_candidate_eta_base_matchedpthf"), jetBase.r() / 100.0, candidateTagEta, candidateBaseEta, weight); + registry.fill(HIST("h3_jet_r_candidate_phi_tag_candidate_phi_base_matchedpthf"), jetBase.r() / 100.0, candidateTagPhi, candidateBasePhi, weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_base_diff_matchedpthf"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.pt() - jetBase.pt()) / jetTag.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_eta_base_base_diff_matchedpthf"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.eta() - jetBase.eta()) / jetTag.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_phi_base_base_diff_matchedpthf"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.phi() - jetBase.phi()) / jetTag.phi(), weight); + + if (jetBase.r() == round(selectedJetsRadius * 100.0f)) { + registry.fill(HIST("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedpthf"), jetTag.pt(), jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedpthf"), jetTag.pt(), jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedpthf"), jetTag.pt(), jetTag.tracks().size(), jetBase.tracks().size(), weight); + } + } + } + } - registry.fill(HIST("h3_jet_r_jet_pt_part_jet_pt"), mcdjet.r() / 100.0, mcpjet.pt(), mcdjet.pt(), weight); - registry.fill(HIST("h3_jet_r_jet_eta_part_jet_eta"), mcdjet.r() / 100.0, mcpjet.eta(), mcdjet.eta(), weight); - registry.fill(HIST("h3_jet_r_jet_phi_part_jet_phi"), mcdjet.r() / 100.0, mcpjet.phi(), mcdjet.phi(), weight); - registry.fill(HIST("h3_jet_r_jet_ntracks_part_jet_ntracks"), mcdjet.r() / 100.0, mcpjet.tracks().size() + mcpjet.hfcandidates().size(), mcdjet.tracks().size() + mcdjet.hfcandidates().size(), weight); - registry.fill(HIST("h3_jet_r_candidate_pt_part_candidate_pt"), mcdjet.r() / 100.0, mcpCandPt, mcdCandPt, weight); - registry.fill(HIST("h3_jet_r_candidate_eta_part_candidate_eta"), mcdjet.r() / 100.0, mcpCandEta, mcdCandEta, weight); - registry.fill(HIST("h3_jet_r_candidate_phi_part_candidate_phi"), mcdjet.r() / 100.0, mcpCandPhi, mcdCandPhi, weight); - registry.fill(HIST("h3_jet_r_candidate_y_part_candidate_y"), mcdjet.r() / 100.0, mcpCandY, mcdCandY, weight); - registry.fill(HIST("h3_jet_r_jet_pt_part_jet_pt_diff"), mcdjet.r() / 100.0, mcpjet.pt(), (mcpjet.pt() - mcdjet.pt()) / mcpjet.pt(), weight); - registry.fill(HIST("h3_jet_r_jet_pt_part_jet_eta_diff"), mcdjet.r() / 100.0, mcpjet.pt(), (mcpjet.eta() - mcdjet.eta()) / mcpjet.eta(), weight); - registry.fill(HIST("h3_jet_r_jet_pt_part_jet_phi_diff"), mcdjet.r() / 100.0, mcpjet.pt(), (mcpjet.phi() - mcdjet.phi()) / mcpjet.phi(), weight); - - if (mcdjet.r() == round(selectedJetsRadius * 100.0f)) { - registry.fill(HIST("h3_jet_pt_part_jet_eta_part_jet_eta"), mcpjet.pt(), mcpjet.eta(), mcdjet.eta(), weight); - registry.fill(HIST("h3_jet_pt_part_jet_phi_part_jet_phi"), mcpjet.pt(), mcpjet.phi(), mcdjet.phi(), weight); - registry.fill(HIST("h3_jet_pt_part_jet_ntracks_part_jet_ntracks"), mcpjet.pt(), mcpjet.tracks().size() + mcpjet.hfcandidates().size(), mcdjet.tracks().size() + mcdjet.hfcandidates().size(), weight); + if (jetBase.has_matchedJetGeo() && jetBase.has_matchedJetPt() && jetBase.has_matchedJetCand()) { + for (auto& jetTag : jetBase.template matchedJetGeo_as>()) { + if (jetTag.pt() > pTHatMaxMCP * pTHat) { + continue; + } + if (jetBase.template matchedJetGeo_first_as>().globalIndex() == jetBase.template matchedJetPt_first_as>().globalIndex()) { + if (jetBase.template matchedJetGeo_first_as>().globalIndex() == jetBase.template matchedJetCand_first_as>().globalIndex()) { // not a good way to do this + + auto candidateTag = jetTag.template hfcandidates_first_as>(); + candidateTagPt = candidateTag.pt(); + candidateTagPhi = candidateTag.phi(); + candidateTagEta = candidateTag.eta(); + + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_matchedgeopthf"), jetBase.r() / 100.0, jetTag.pt(), jetBase.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_eta_tag_jet_eta_base_matchedgeopthf"), jetBase.r() / 100.0, jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_phi_tag_jet_phi_base_matchedgeopthf"), jetBase.r() / 100.0, jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_r_jet_ntracks_tag_jet_ntracks_base_matchedgeopthf"), jetBase.r() / 100.0, jetTag.tracks().size(), jetBase.tracks().size(), weight); + registry.fill(HIST("h3_jet_r_candidate_pt_tag_candidate_pt_base_matchedgeopthf"), jetBase.r() / 100.0, candidateTagPt, candidateBasePt, weight); + registry.fill(HIST("h3_jet_r_candidate_eta_tag_candidate_eta_base_matchedgeopthf"), jetBase.r() / 100.0, candidateTagEta, candidateBaseEta, weight); + registry.fill(HIST("h3_jet_r_candidate_phi_tag_candidate_phi_base_matchedgeopthf"), jetBase.r() / 100.0, candidateTagPhi, candidateBasePhi, weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_pt_base_base_diff_matchedgeopthf"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.pt() - jetBase.pt()) / jetTag.pt(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_eta_base_base_diff_matchedgeopthf"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.eta() - jetBase.eta()) / jetTag.eta(), weight); + registry.fill(HIST("h3_jet_r_jet_pt_tag_jet_phi_base_base_diff_matchedgeopthf"), jetBase.r() / 100.0, jetTag.pt(), (jetTag.phi() - jetBase.phi()) / jetTag.phi(), weight); + + if (jetBase.r() == round(selectedJetsRadius * 100.0f)) { + registry.fill(HIST("h3_jet_pt_tag_jet_eta_tag_jet_eta_base_matchedgeopthf"), jetTag.pt(), jetTag.eta(), jetBase.eta(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_phi_tag_jet_phi_base_matchedgeopthf"), jetTag.pt(), jetTag.phi(), jetBase.phi(), weight); + registry.fill(HIST("h3_jet_pt_tag_jet_ntracks_tag_jet_ntracks_base_matchedgeopthf"), jetTag.pt(), jetTag.tracks().size(), jetBase.tracks().size(), weight); + } + } + } } } } - void fillTrackHistograms(soa::Filtered const& tracks, float weight = 1.0) + template + void fillTrackHistograms(T const& tracks, float weight = 1.0) { for (auto const& track : tracks) { - if (!JetDerivedDataUtilities::selectTrack(track, trackSelection)) { + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { continue; } registry.fill(HIST("h_track_pt"), track.pt(), weight); @@ -414,111 +817,168 @@ struct JetFinderHFQATask { } } - void processDummy(aod::Collisions const& collision) + void processDummy(JetCollisions const& collision) { } PROCESS_SWITCH(JetFinderHFQATask, processDummy, "dummy task", true); - void processJetsData(typename JetTableDataJoined::iterator const& jet, CandidateTableData const& candidates, JetTracks const& tracks) + void processJetsData(soa::Filtered::iterator const& collision, JetTableDataJoined const& jets, CandidateTableData const& candidates, JetTracks const& tracks) { - fillHistograms(jet); + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + fillHistograms(jet, collision.centrality()); + } } PROCESS_SWITCH(JetFinderHFQATask, processJetsData, "jet finder HF QA data", false); - void processJetsMCD(typename JetTableMCDJoined::iterator const& jet, CandidateTableMCD const& candidates, JetTracks const& tracks) + void processJetsMCD(soa::Filtered::iterator const& collision, JetTableMCDJoined const& jets, CandidateTableMCD const& candidates, JetTracks const& tracks) { - fillHistograms(jet); + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + fillHistograms(jet, collision.centrality()); + } } PROCESS_SWITCH(JetFinderHFQATask, processJetsMCD, "jet finder HF QA mcd", false); - void processJetsMCDWeighted(typename JetTableMCDWeightedJoined::iterator const& jet, CandidateTableMCD const& candidates, JetTracks const& tracks) + void processJetsMCDWeighted(soa::Filtered::iterator const& collision, JetTableMCDWeightedJoined const& jets, CandidateTableMCD const& candidates, JetTracks const& tracks) { - fillHistograms(jet, jet.eventWeight()); + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + fillHistograms(jet, collision.centrality(), jet.eventWeight()); + } } PROCESS_SWITCH(JetFinderHFQATask, processJetsMCDWeighted, "jet finder HF QA mcd on weighted events", false); - void processJetsMCP(typename JetTableMCPJoined::iterator const& jet, ParticleTableMCP const& particles) + void processJetsMCP(typename JetTableMCPJoined::iterator const& jet, JetParticles const& particles, CandidateTableMCP const& candidates) { - fillMCPHistograms(jet); + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + return; + } + fillMCPHistograms(jet); } PROCESS_SWITCH(JetFinderHFQATask, processJetsMCP, "jet finder HF QA mcp", false); - void processJetsMCPWeighted(typename JetTableMCDWeightedJoined::iterator const& jet, ParticleTableMCP const& particles) + void processJetsMCPWeighted(typename JetTableMCPWeightedJoined::iterator const& jet, JetParticles const& particles, CandidateTableMCP const& candidates) { - fillMCPHistograms(jet, jet.eventWeight()); + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + return; + } + fillMCPHistograms(jet, jet.eventWeight()); } PROCESS_SWITCH(JetFinderHFQATask, processJetsMCPWeighted, "jet finder HF QA mcp on weighted events", false); - void processJetsMCPMCDMatched(aod::JCollision const& collision, + void processJetsMCPMCDMatched(soa::Filtered::iterator const& collision, JetTableMCDMatchedJoined const& mcdjets, JetTableMCPMatchedJoined const& mcpjets, - CandidateTableMCD const& candidates, - JetTracks const& tracks, ParticleTableMCP const& particles) + CandidateTableMCD const& candidatesMCD, + JetTracks const& tracks, JetParticles const& particles, + CandidateTableMCP const& candidatesMCP) { for (const auto& mcdjet : mcdjets) { + if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } - fillMCMatchedHistograms(mcdjet); + fillMatchedHistograms(mcdjet); } } PROCESS_SWITCH(JetFinderHFQATask, processJetsMCPMCDMatched, "jet finder HF QA matched mcp and mcd", false); - void processJetsMCPMCDMatchedWeighted(aod::JCollision const& collision, + void processJetsMCPMCDMatchedWeighted(soa::Filtered::iterator const& collision, JetTableMCDMatchedWeightedJoined const& mcdjets, JetTableMCPMatchedWeightedJoined const& mcpjets, - CandidateTableMCD const& candidates, - JetTracks const& tracks, ParticleTableMCP const& particles) + CandidateTableMCD const& candidatesMCD, + JetTracks const& tracks, JetParticles const& particles, + CandidateTableMCP const& candidatesMCP) { for (const auto& mcdjet : mcdjets) { + if (!jetfindingutilities::isInEtaAcceptance(mcdjet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } - fillMCMatchedHistograms(mcdjet, mcdjet.eventWeight()); + fillMatchedHistograms(mcdjet, mcdjet.eventWeight()); } } PROCESS_SWITCH(JetFinderHFQATask, processJetsMCPMCDMatchedWeighted, "jet finder HF QA matched mcp and mcd on weighted events", false); - void processMCCollisionsWeighted(aod::McCollision const& collision) + void processJetsSubMatched(soa::Filtered::iterator const& collision, + JetTableDataMatchedJoined const& jets, + JetTableDataSubMatchedJoined const& jetSubs, + JetTracks const& tracks, JetTracksDataSub const& tracksSub, CandidateTableData const& candidates) { + for (const auto& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + fillMatchedHistograms(jet); + } + } + PROCESS_SWITCH(JetFinderHFQATask, processJetsSubMatched, "jet finder HF QA matched unsubtracted and constituent subtracted jets", false); + void processMCCollisionsWeighted(JetMcCollision const& collision) + { registry.fill(HIST("h_collision_eventweight_part"), collision.weight()); } PROCESS_SWITCH(JetFinderHFQATask, processMCCollisionsWeighted, "collision QA for weighted events", false); - void processTriggeredData(soa::Join::iterator const& collision, + void processTriggeredData(soa::Join::iterator const& collision, JetTableDataJoined const& jets, CandidateTableData const& candidates, - JetTracks const& tracks) + soa::Filtered const& tracks) { registry.fill(HIST("h_collision_trigger_events"), 0.5); // all events if (collision.posZ() > vertexZCut) { return; } registry.fill(HIST("h_collision_trigger_events"), 1.5); // all events with z vertex cut - if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } registry.fill(HIST("h_collision_trigger_events"), 2.5); // events with sel8() - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow)) { registry.fill(HIST("h_collision_trigger_events"), 3.5); // events with high pT triggered jets } - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) { registry.fill(HIST("h_collision_trigger_events"), 4.5); // events with high pT triggered jets } - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow) && JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow) && jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) { registry.fill(HIST("h_collision_trigger_events"), 5.5); // events with high pT triggered jets } for (std::size_t iJetRadius = 0; iJetRadius < jetRadiiValues.size(); iJetRadius++) { - filledJetR[iJetRadius] = false; + filledJetR_Both[iJetRadius] = false; + filledJetR_Low[iJetRadius] = false; + filledJetR_High[iJetRadius] = false; } for (auto& jet : jets) { for (std::size_t iJetRadius = 0; iJetRadius < jetRadiiValues.size(); iJetRadius++) { - if (jet.r() == round(jetRadiiValues[iJetRadius] * 100.0f) && !filledJetR[iJetRadius]) { - filledJetR[iJetRadius] = true; - for (double pt = 0.0; pt <= jet.pt(); pt += 1.0) { - registry.fill(HIST("h2_jet_r_jet_pT_triggered"), jet.r() / 100.0, pt); + if (jet.r() == round(jetRadiiValues[iJetRadius] * 100.0f)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow) && !filledJetR_Low[iJetRadius]) { + filledJetR_Low[iJetRadius] = true; + for (double pt = 0.0; pt <= jet.pt(); pt += 1.0) { + registry.fill(HIST("h2_jet_r_jet_pT_triggered_Low"), jet.r() / 100.0, pt); + } + } + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh) && !filledJetR_High[iJetRadius]) { + filledJetR_High[iJetRadius] = true; + for (double pt = 0.0; pt <= jet.pt(); pt += 1.0) { + registry.fill(HIST("h2_jet_r_jet_pT_triggered_High"), jet.r() / 100.0, pt); + } + } + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow) && jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh) && !filledJetR_Both[iJetRadius]) { + filledJetR_Both[iJetRadius] = true; + for (double pt = 0.0; pt <= jet.pt(); pt += 1.0) { + registry.fill(HIST("h2_jet_r_jet_pT_triggered_Both"), jet.r() / 100.0, pt); + } } - break; } } @@ -530,17 +990,17 @@ struct JetFinderHFQATask { registry.fill(HIST("h3_jet_r_jet_eta_collision"), jet.r() / 100.0, jet.eta(), 0.0); registry.fill(HIST("h3_jet_r_jet_phi_collision"), jet.r() / 100.0, jet.phi(), 0.0); - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow)) { registry.fill(HIST("h3_jet_r_jet_pt_collision"), jet.r() / 100.0, jet.pt(), 1.0); registry.fill(HIST("h3_jet_r_jet_eta_collision"), jet.r() / 100.0, jet.eta(), 1.0); registry.fill(HIST("h3_jet_r_jet_phi_collision"), jet.r() / 100.0, jet.phi(), 1.0); } - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) { registry.fill(HIST("h3_jet_r_jet_pt_collision"), jet.r() / 100.0, jet.pt(), 2.0); registry.fill(HIST("h3_jet_r_jet_eta_collision"), jet.r() / 100.0, jet.eta(), 2.0); registry.fill(HIST("h3_jet_r_jet_phi_collision"), jet.r() / 100.0, jet.phi(), 2.0); } - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow) && JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow) && jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) { registry.fill(HIST("h3_jet_r_jet_pt_collision"), jet.r() / 100.0, jet.pt(), 3.0); registry.fill(HIST("h3_jet_r_jet_eta_collision"), jet.r() / 100.0, jet.eta(), 3.0); registry.fill(HIST("h3_jet_r_jet_phi_collision"), jet.r() / 100.0, jet.phi(), 3.0); @@ -551,17 +1011,17 @@ struct JetFinderHFQATask { registry.fill(HIST("h3_jet_r_jet_pt_track_eta_MB"), jet.r() / 100.0, jet.pt(), constituent.eta()); registry.fill(HIST("h3_jet_r_jet_pt_track_phi_MB"), jet.r() / 100.0, jet.pt(), constituent.phi()); - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow)) { registry.fill(HIST("h3_jet_r_jet_pt_track_pt_Triggered_Low"), jet.r() / 100.0, jet.pt(), constituent.pt()); registry.fill(HIST("h3_jet_r_jet_pt_track_eta_Triggered_Low"), jet.r() / 100.0, jet.pt(), constituent.eta()); registry.fill(HIST("h3_jet_r_jet_pt_track_phi_Triggered_Low"), jet.r() / 100.0, jet.pt(), constituent.phi()); } - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) { registry.fill(HIST("h3_jet_r_jet_pt_track_pt_Triggered_High"), jet.r() / 100.0, jet.pt(), constituent.pt()); registry.fill(HIST("h3_jet_r_jet_pt_track_eta_Triggered_High"), jet.r() / 100.0, jet.pt(), constituent.eta()); registry.fill(HIST("h3_jet_r_jet_pt_track_phi_Triggered_High"), jet.r() / 100.0, jet.pt(), constituent.phi()); } - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow) && JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow) && jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) { registry.fill(HIST("h3_jet_r_jet_pt_track_pt_Triggered_Both"), jet.r() / 100.0, jet.pt(), constituent.pt()); registry.fill(HIST("h3_jet_r_jet_pt_track_eta_Triggered_Both"), jet.r() / 100.0, jet.pt(), constituent.eta()); registry.fill(HIST("h3_jet_r_jet_pt_track_phi_Triggered_Both"), jet.r() / 100.0, jet.pt(), constituent.phi()); @@ -572,48 +1032,48 @@ struct JetFinderHFQATask { registry.fill(HIST("h3_jet_r_jet_pt_candidate_pt_MB"), jet.r() / 100.0, jet.pt(), hfcandidate.pt()); registry.fill(HIST("h3_jet_r_jet_pt_candidate_eta_MB"), jet.r() / 100.0, jet.pt(), hfcandidate.eta()); registry.fill(HIST("h3_jet_r_jet_pt_candidate_phi_MB"), jet.r() / 100.0, jet.pt(), hfcandidate.phi()); - registry.fill(HIST("h3_jet_r_jet_pt_candidate_y_MB"), jet.r() / 100.0, jet.pt(), hfcandidate.y(candMass)); + registry.fill(HIST("h3_jet_r_jet_pt_candidate_y_MB"), jet.r() / 100.0, jet.pt(), hfcandidate.y()); - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow)) { registry.fill(HIST("h3_jet_r_jet_pt_candidate_pt_Triggered_Low"), jet.r() / 100.0, jet.pt(), hfcandidate.pt()); registry.fill(HIST("h3_jet_r_jet_pt_candidate_eta_Triggered_Low"), jet.r() / 100.0, jet.pt(), hfcandidate.eta()); registry.fill(HIST("h3_jet_r_jet_pt_candidate_phi_Triggered_Low"), jet.r() / 100.0, jet.pt(), hfcandidate.phi()); - registry.fill(HIST("h3_jet_r_jet_pt_candidate_y_Triggered_Low"), jet.r() / 100.0, jet.pt(), hfcandidate.y(candMass)); + registry.fill(HIST("h3_jet_r_jet_pt_candidate_y_Triggered_Low"), jet.r() / 100.0, jet.pt(), hfcandidate.y()); } - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) { registry.fill(HIST("h3_jet_r_jet_pt_candidate_pt_Triggered_High"), jet.r() / 100.0, jet.pt(), hfcandidate.pt()); registry.fill(HIST("h3_jet_r_jet_pt_candidate_eta_Triggered_High"), jet.r() / 100.0, jet.pt(), hfcandidate.eta()); registry.fill(HIST("h3_jet_r_jet_pt_candidate_phi_Triggered_High"), jet.r() / 100.0, jet.pt(), hfcandidate.phi()); - registry.fill(HIST("h3_jet_r_jet_pt_candidate_y_Triggered_High"), jet.r() / 100.0, jet.pt(), hfcandidate.y(candMass)); + registry.fill(HIST("h3_jet_r_jet_pt_candidate_y_Triggered_High"), jet.r() / 100.0, jet.pt(), hfcandidate.y()); } - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow) && JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow) && jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) { registry.fill(HIST("h3_jet_r_jet_pt_candidate_pt_Triggered_Both"), jet.r() / 100.0, jet.pt(), hfcandidate.pt()); registry.fill(HIST("h3_jet_r_jet_pt_candidate_eta_Triggered_Both"), jet.r() / 100.0, jet.pt(), hfcandidate.eta()); registry.fill(HIST("h3_jet_r_jet_pt_candidate_phi_Triggered_Both"), jet.r() / 100.0, jet.pt(), hfcandidate.phi()); - registry.fill(HIST("h3_jet_r_jet_pt_candidate_y_Triggered_Both"), jet.r() / 100.0, jet.pt(), hfcandidate.y(candMass)); + registry.fill(HIST("h3_jet_r_jet_pt_candidate_y_Triggered_Both"), jet.r() / 100.0, jet.pt(), hfcandidate.y()); } } } for (auto& track : tracks) { - if (!JetDerivedDataUtilities::selectTrack(track, trackSelection) || !JetDerivedDataUtilities::applyTrackKinematics(track, trackPtMin, trackPtMax, trackEtaMin, trackEtaMax)) { + if (!jetderiveddatautilities::selectTrack(track, trackSelection)) { continue; } registry.fill(HIST("h_track_pt_MB"), track.pt()); registry.fill(HIST("h_track_eta_MB"), track.eta()); registry.fill(HIST("h_track_phi_MB"), track.phi()); - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow)) { registry.fill(HIST("h_track_pt_Triggered_Low"), track.pt()); registry.fill(HIST("h_track_eta_Triggered_Low"), track.eta()); registry.fill(HIST("h_track_phi_Triggered_Low"), track.phi()); } - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) { registry.fill(HIST("h_track_pt_Triggered_High"), track.pt()); registry.fill(HIST("h_track_eta_Triggered_High"), track.eta()); registry.fill(HIST("h_track_phi_Triggered_High"), track.phi()); } - if (JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedLow) && JetDerivedDataUtilities::selectChargedTrigger(collision, JetDerivedDataUtilities::JTrigSelCh::chargedHigh)) { + if (jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedLow) && jetderiveddatautilities::selectChargedTrigger(collision, jetderiveddatautilities::JTrigSelCh::chargedHigh)) { registry.fill(HIST("h_track_pt_Triggered_Both"), track.pt()); registry.fill(HIST("h_track_eta_Triggered_Both"), track.eta()); registry.fill(HIST("h_track_phi_Triggered_Both"), track.phi()); @@ -623,11 +1083,11 @@ struct JetFinderHFQATask { PROCESS_SWITCH(JetFinderHFQATask, processTriggeredData, "QA for charged jet trigger", false); - void processTracks(aod::JCollision const& collision, + void processTracks(soa::Filtered::iterator const& collision, soa::Filtered const& tracks) { registry.fill(HIST("h_collisions"), 0.5); - if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } registry.fill(HIST("h_collisions"), 1.5); @@ -635,14 +1095,14 @@ struct JetFinderHFQATask { } PROCESS_SWITCH(JetFinderHFQATask, processTracks, "QA for charged tracks", false); - void processTracksWeighted(soa::Join::iterator const& collision, - aod::JMcCollisions const& mcCollisions, + void processTracksWeighted(soa::Join::iterator const& collision, + JetMcCollisions const& mcCollisions, soa::Filtered const& tracks) { float eventWeight = collision.mcCollision().weight(); registry.fill(HIST("h_collisions"), 0.5); registry.fill(HIST("h_collisions_weighted"), 0.5, eventWeight); - if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) { + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { return; } registry.fill(HIST("h_collisions"), 1.5); @@ -650,11 +1110,100 @@ struct JetFinderHFQATask { fillTrackHistograms(tracks, eventWeight); } PROCESS_SWITCH(JetFinderHFQATask, processTracksWeighted, "QA for charged tracks weighted", false); + + void processTracksSub(soa::Filtered::iterator const& collision, + CandidateTableData const& candidates, + soa::Filtered const& tracks) + { + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) { + return; + } + for (auto const& candidate : candidates) { + + for (auto const& track : jethfutilities::slicedPerCandidate(tracks, candidate, perD0CandidateTracks, perLcCandidateTracks, perBplusCandidateTracks)) { + registry.fill(HIST("h_track_pt_eventwiseconstituentsubtracted"), track.pt()); + registry.fill(HIST("h_track_eta_eventwiseconstituentsubtracted"), track.eta()); + registry.fill(HIST("h_track_phi_eventwiseconstituentsubtracted"), track.phi()); + } + break; // currently only fills it for the first candidate in the event (not pT ordered) + } + } + PROCESS_SWITCH(JetFinderHFQATask, processTracksSub, "QA for charged event-wise embedded subtracted tracks", false); + + void processRho(JetCollision const& collision, CandidateTableData const& candidates, BkgRhoTable const& bkgRhos, soa::Filtered const& tracks) + { + for (auto const& candidate : candidates) { + auto bkgRho = jethfutilities::slicedPerCandidate(bkgRhos, candidate, perD0CandidateRhos, perLcCandidateRhos, perBplusCandidateRhos).iteratorAt(0); + int nTracks = 0; + TRandom3 rand(0); + float randomConeEta = rand.Uniform(trackEtaMin + randomConeR, trackEtaMax - randomConeR); + float randomConePhi = rand.Uniform(0.0, 2 * M_PI); + float randomConePt = 0; + for (auto const& track : tracks) { + if (jetderiveddatautilities::selectTrack(track, trackSelection)) { + nTracks++; + float dPhi = RecoDecay::constrainAngle(track.phi() - randomConePhi, -M_PI); + float dEta = track.eta() - randomConeEta; + if (TMath::Sqrt(dEta * dEta + dPhi * dPhi) < randomConeR) { + randomConePt += track.pt(); + } + } + } + registry.fill(HIST("h2_centrality_ntracks"), collision.centrality(), nTracks); + registry.fill(HIST("h2_ntracks_rho"), nTracks, bkgRho.rho()); + registry.fill(HIST("h2_ntracks_rhom"), nTracks, bkgRho.rhoM()); + registry.fill(HIST("h2_centrality_rho"), collision.centrality(), bkgRho.rho()); + registry.fill(HIST("h2_centrality_rhom"), collision.centrality(), bkgRho.rhoM()); + registry.fill(HIST("h2_centrality_rhoRandomCone"), collision.centrality(), randomConePt - M_PI * randomConeR * randomConeR * bkgRho.rho()); + break; // currently only fills it for the first candidate in the event (not pT ordered) + } + } + PROCESS_SWITCH(JetFinderHFQATask, processRho, "QA for rho-area subtracted jets", false); + + void processJetsRhoAreaSubData(soa::Filtered::iterator const& collision, + BkgRhoTable const& bkgRhos, + JetTableDataJoined const& jets, + CandidateTableData const& candidates, + JetTracks const& tracks) + { + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + auto const jetCandidate = jet.template hfcandidates_first_as(); + auto bkgRho = jethfutilities::slicedPerCandidate(bkgRhos, jetCandidate, perD0CandidateRhos, perLcCandidateRhos, perBplusCandidateRhos).iteratorAt(0); + fillRhoAreaSubtractedHistograms(jet, collision.centrality(), bkgRho.rho()); + } + } + PROCESS_SWITCH(JetFinderHFQATask, processJetsRhoAreaSubData, "jet finder HF QA for rho-area subtracted jets", false); + + void processEvtWiseConstSubJetsData(soa::Filtered::iterator const& collision, JetTableDataSubJoined const& jets, CandidateTableData const& candidates, JetTracksDataSub const& tracks) + { + for (auto const& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } + fillEventWiseConstituentSubtractedHistograms(jet, collision.centrality()); + } + } + PROCESS_SWITCH(JetFinderHFQATask, processEvtWiseConstSubJetsData, "jet finder HF QA for eventwise constituent-subtracted jets data", false); + + void processCandidates(soa::Filtered::iterator const& collision, CandidateTableData const& candidates) + { + + for (auto const& candidate : candidates) { + registry.fill(HIST("h_candidate_invmass"), candidate.m()); + registry.fill(HIST("h_candidate_pt"), candidate.pt()); + registry.fill(HIST("h_candidate_y"), candidate.y()); + } + registry.fill(HIST("h2_centrality_ncandidates"), collision.centrality(), candidates.size()); + } + PROCESS_SWITCH(JetFinderHFQATask, processCandidates, "HF candidate QA", false); }; -using JetFinderD0QATask = JetFinderHFQATask, aod::D0ChargedMCDetectorLevelJets, aod::D0ChargedMCDetectorLevelJetConstituents, aod::D0ChargedMCDetectorLevelJetsMatchedToD0ChargedMCParticleLevelJets, aod::D0ChargedMCDetectorLevelJetEventWeights, soa::Join, aod::D0ChargedMCParticleLevelJets, aod::D0ChargedMCParticleLevelJetConstituents, aod::D0ChargedMCParticleLevelJetsMatchedToD0ChargedMCDetectorLevelJets, aod::D0ChargedMCParticleLevelJetEventWeights, soa::Join>; -using JetFinderLcQATask = JetFinderHFQATask, aod::LcChargedMCDetectorLevelJets, aod::LcChargedMCDetectorLevelJetConstituents, aod::LcChargedMCDetectorLevelJetsMatchedToLcChargedMCParticleLevelJets, aod::LcChargedMCDetectorLevelJetEventWeights, soa::Join, aod::LcChargedMCParticleLevelJets, aod::LcChargedMCParticleLevelJetConstituents, aod::LcChargedMCParticleLevelJetsMatchedToLcChargedMCDetectorLevelJets, aod::LcChargedMCParticleLevelJetEventWeights, soa::Join>; -using JetFinderBplusQATask = JetFinderHFQATask, aod::BplusChargedMCDetectorLevelJets, aod::BplusChargedMCDetectorLevelJetConstituents, aod::BplusChargedMCDetectorLevelJetsMatchedToBplusChargedMCParticleLevelJets, aod::BplusChargedMCDetectorLevelJetEventWeights, soa::Join, aod::BplusChargedMCParticleLevelJets, aod::BplusChargedMCParticleLevelJetConstituents, aod::BplusChargedMCParticleLevelJetsMatchedToBplusChargedMCDetectorLevelJets, aod::BplusChargedMCParticleLevelJetEventWeights, soa::Join>; +using JetFinderD0QATask = JetFinderHFQATask; +// using JetFinderLcQATask = JetFinderHFQATask; +// using JetFinderBplusQATask = JetFinderHFQATask; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { @@ -664,13 +1213,13 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) SetDefaultProcesses{}, TaskName{"jet-finder-charged-d0-qa"})); - tasks.emplace_back(adaptAnalysisTask(cfgc, - SetDefaultProcesses{}, - TaskName{"jet-finder-charged-bplus-qa"})); + // tasks.emplace_back(adaptAnalysisTask(cfgc, + // SetDefaultProcesses{}, + // TaskName{"jet-finder-charged-bplus-qa"})); - tasks.emplace_back(adaptAnalysisTask(cfgc, - SetDefaultProcesses{}, - TaskName{"jet-finder-charged-lc-qa"})); + // tasks.emplace_back(adaptAnalysisTask(cfgc, + // SetDefaultProcesses{}, + // TaskName{"jet-finder-charged-lc-qa"})); return WorkflowSpec{tasks}; } diff --git a/PWGJE/Tasks/jetfragmentation.cxx b/PWGJE/Tasks/jetfragmentation.cxx index 719b2b35a2c..a147c60f3df 100644 --- a/PWGJE/Tasks/jetfragmentation.cxx +++ b/PWGJE/Tasks/jetfragmentation.cxx @@ -35,11 +35,9 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -// using McTracks = soa::Filtered>; -using McTracks = soa::Join; using McDJets = soa::Join; -// using MatchedMcDJets = soa::Filtered>; using McPJets = soa::Join; +using MyTracks = soa::Join; struct JetFragmentation { HistogramRegistry registry{"registry"}; @@ -49,6 +47,18 @@ struct JetFragmentation { Configurable matchedDetJetEtaMin{"matchedDetJetEtaMin", -0.5, "minimum matchedDetJet eta"}; Configurable matchedDetJetEtaMax{"matchedDetJetEtaMax", 0.5, "maximum matchedDetJet eta"}; + Configurable dataJetEtaMin{"dataJetEtaMin", -0.5, "minimum data jet eta"}; + Configurable dataJetEtaMax{"dataJetEtaMax", 0.5, "maximum data jet eta"}; + + Configurable v0cospa{"v0cospa", 0.995, "V0 CosPA"}; // double -> N.B. dcos(x)/dx = 0 at x=0) + Configurable dcav0dau{"dcav0dau", 1.0, "DCA V0 Daughters"}; + Configurable dcanegtopv{"dcanegtopv", .1, "DCA Neg To PV"}; + Configurable dcapostopv{"dcapostopv", .1, "DCA Pos To PV"}; + Configurable v0radius{"v0radius", 5.0, "v0radius"}; + Configurable rapidity{"rapidity", 0.5, "rapidity"}; + Configurable lifetimecutK0S{"lifetimecutK0S", 20., "lifetimecutK0S"}; + Configurable lifetimecutLambda{"lifetimecutLambda", 25., "lifetimecutLambda"}; + Configurable TpcPidNsigmaCut{"TpcPidNsigmaCut", 5, "TpcPidNsigmaCut"}; // Binning ConfigurableAxis binJetPt{"binJetPt", {40, 0.f, 200.f}, ""}; @@ -69,14 +79,46 @@ struct JetFragmentation { ConfigurableAxis binZDiff{"binZDiff", {80, -1.05f, 0.95f}, ""}; ConfigurableAxis binXiDiff{"binXiDiff", {100, -9.5f, 10.5f}, ""}; ConfigurableAxis binThetaDiff{"binThetaDiff", {80, -0.35f, 0.45f}, ""}; - ConfigurableAxis binPtRatio{"binPtRatio", {100, -0.5f, 9.5f}, ""}; // Ratio of pt, eta, phi + ConfigurableAxis binPtRatio{"binPtRatio", {50, -0.5f, 9.5f}, ""}; // Ratio of pt, eta, phi ConfigurableAxis binMatchDist{"binMatchDist", {50, 0.f, 0.5f}, ""}; // Distance between matched jets + ConfigurableAxis binPtRelDiff{"binPtRelDiff", {100, -9.5f, 10.5f}, ""}; + ConfigurableAxis binZRelDiff{"binZRelDiff", {100, -9.5f, 10.5f}, ""}; + ConfigurableAxis binCount{"binCount", {1, .5f, 1.5f}, ""}; ConfigurableAxis jetCount{"jetCount", {20, -.5f, 19.5f}, ""}; ConfigurableAxis trackCount{"trackCount", {1000, -.5f, 999.5f}, ""}; + ConfigurableAxis binV0Pt{"binV0Pt", {200, 0.0f, 10.0f}, ""}; + ConfigurableAxis binV0Eta{"binV0Eta", {20, -1.f, 1.f}, ""}; + ConfigurableAxis binV0Phi{"binV0Phi", {18 * 8, 0.f, 2. * TMath::Pi()}, ""}; + ConfigurableAxis binV0Ctau{"binV0Ctau", {200, 0.0f, 40.0f}, ""}; + ConfigurableAxis binV0Radius{"binV0Radius", {100, 0.0f, 100.0f}, ""}; + ConfigurableAxis binV0CosPA{"binV0CosPA", {100, 0.95f, 1.0f}, ""}; + ConfigurableAxis binV0DCA{"binV0DCA", {200, 0.0f, 1.0f}, ""}; + ConfigurableAxis binV0DCAp{"binV0DCAp", {100, -10.0f, 10.0f}, ""}; + ConfigurableAxis binV0DCAn{"binV0DCAn", {100, -10.0f, 10.0f}, ""}; + ConfigurableAxis binV0DCAd{"binV0DCAd", {100, 0.0f, 10.0f}, ""}; + + ConfigurableAxis binK0SMass{"binK0SMass", {400, 0.400f, 0.600f}, "Inv. Mass (GeV/c^{2})"}; + // ConfigurableAxis binK0SCtau{"binK0SCtau", {200, 0.0f, 40.0f}, ""}; + // ConfigurableAxis binK0SRadius{"binK0SRadius", {1000, 0.0f, 100.0f}, ""}; + // ConfigurableAxis binK0SCosPA{"binK0SCosPA", {1000, 0.95f, 1.0f}, ""}; + // ConfigurableAxis binK0SDCAp{"binK0SDCAp", {1000, -10.0f, 10.0f}, ""}; + // ConfigurableAxis binK0SDCAn{"binK0SDCAn", {1000, -10.0f, 10.0f}, ""}; + // ConfigurableAxis binK0SDCAd{"binK0SDCAd", {1000, 0.0f, 10.0f}, ""}; + ConfigurableAxis binLambdaMass{"binLambdaMass", {200, 1.015f, 1.215f}, "Inv. Mass (GeV/c^{2})"}; + // ConfigurableAxis binLambdaCtau + // ConfigurableAxis binLambdaRadius + // ConfigurableAxis binLambdaCosPA + // ConfigurableAxis binLambdaDCAp + // ConfigurableAxis binLambdaDCAn + // ConfigurableAxis binLambdaDCAd + Preslice perMcPJet = aod::jet::mcCollisionId; + // Preslice> TracksPerCollision = aod::jtrack::collisionId; + Preslice TracksPerCollision = aod::track::collisionId; + Preslice V0sPerCollision = aod::v0data::collisionId; // Filter matchedDetJetFilter = (aod::chargedmcdetectorleveljets::eta >= matchedDetJetEtaMin && aod::chargedmcdetectorleveljets::eta <= matchedDetJetEtaMax); void init(InitContext& initContext) @@ -105,21 +147,41 @@ struct JetFragmentation { AxisSpec pdgAxis = {binPDG, ""}; AxisSpec trackPtAxis = {binTrackPt, "#it{p}_{T}^{tr}"}; - AxisSpec ptTrackDiffAxis = {binPtTrackDiff, "#it{p}_{T}^{particle} - #it{p}_{T}^{track}"}; - AxisSpec ptDiffAxis = {binPtDiff, "#it{p}_{T}^{jet, part} - #it{p}_{T}^{jet, det}"}; - AxisSpec etaDiffAxis = {binEtaDiff, "#eta^{jet, part} - #eta^{jet, det}"}; - AxisSpec phiDiffAxis = {binPhiDiff, "#varphi^{jet, part} - #varphi^{jet, det}"}; - AxisSpec zDiffAxis = {binZDiff, "#it{z}^{part} - #it{z}^{det}"}; - AxisSpec xiDiffAxis = {binXiDiff, "#xi^{part} - #xi^{det}"}; - AxisSpec thetaDiffAxis = {binThetaDiff, "#theta^{part} - #theta^{det}"}; + AxisSpec ptTrackDiffAxis = {binPtTrackDiff, "#it{p}_{T}^{track} - #it{p}_{T}^{particle}"}; + AxisSpec ptDiffAxis = {binPtDiff, "#it{p}_{T}^{jet, det} - #it{p}_{T}^{jet, part}"}; + AxisSpec etaDiffAxis = {binEtaDiff, "#eta^{jet, det} - #eta^{jet, part}"}; + AxisSpec phiDiffAxis = {binPhiDiff, "#varphi^{jet, det} - #varphi^{jet, part}"}; + AxisSpec zDiffAxis = {binZDiff, "#it{z}^{det} - #it{z}^{part}"}; + AxisSpec xiDiffAxis = {binXiDiff, "#xi^{det} - #xi^{part}"}; + AxisSpec thetaDiffAxis = {binThetaDiff, "#theta^{det} - #theta^{part}"}; AxisSpec ptRatioAxis = {binPtRatio, ""}; AxisSpec vtxZAxis = {binVtxZ, "Collision vertex z (cm)"}; AxisSpec matchDistAxis = {binMatchDist, "#Delta"}; - if (doprocessDataRun3) { + AxisSpec ptJetRelDiffAxis = {binPtRelDiff, "(#it{p}_{T}^{jet, det} - #it{p}_{T}^{jet, part})/#it{p}_{T, jet}^{part}"}; + AxisSpec ptTrackRelDiffAxis = {binPtRelDiff, "(#it{p}_{T}^{jet, det} - #it{p}_{T}^{jet, part})/#it{p}_{T, jet}^{part}"}; + AxisSpec zRelDiffAxis = {binZRelDiff, "(#it{p}_{T}^{jet, det} - #it{p}_{T}^{jet, part})/#it{p}_{T, jet}^{part}"}; + + AxisSpec V0PtAxis = {binV0Pt, "#it{p}_{T}^{V0}"}; + AxisSpec V0EtaAxis = {binV0Eta, "#eta^{V0}"}; + AxisSpec V0PhiAxis = {binV0Phi, "#varphi^{V0}"}; + AxisSpec V0detPtAxis = {binV0Pt, "#it{p}_{T}^{V0, det}"}; + AxisSpec V0partPtAxis = {binV0Pt, "#it{p}_{T}^{V0, part}"}; + AxisSpec V0CtauAxis = {binV0Ctau, "c#tau (cm)"}; + AxisSpec V0RadiusAxis = {binV0Radius, "R (cm)"}; + AxisSpec V0CosPAAxis = {binV0CosPA, "R (cm)"}; + AxisSpec V0DCApAxis = {binV0DCAp, "DCA pos (cm)"}; + AxisSpec V0DCAnAxis = {binV0DCAn, "DCA neg (cm)"}; + AxisSpec V0DCAdAxis = {binV0DCAd, "DCA daughters (cm^{2})"}; + + AxisSpec K0SMassAxis = {binK0SMass, "Inv. mass (GeV/#it{c}^{2})"}; + AxisSpec LambdaMassAxis = {binLambdaMass, "Inv. mass (GeV/#it{c}^{2})"}; + + if (doprocessDataRun3 || doprocessDataV0Frag) { registry.add("data/nJetsnTracks", "nJetsnTracks; nJets; nTracks", HistType::kTH2F, {jetCount, trackCount}); registry.add("data/collision/collisionVtxZ", "Collision vertex z (cm)", HistType::kTH1F, {binVtxZ}); registry.add("data/tracks/trackPtEtaPhi", "trackPtEtaPhi", HistType::kTH3F, {trackPtAxis, etaAxis, phiAxis}); + registry.add("data/jets/jetPtEtaPhi", "Jet #it{p}_{T}, #eta, #phi", HistType::kTH3F, {jetPtAxis, etaAxis, phiAxis}); registry.add("data/jets/jetPtTrackPt", "Jet #it{p}_{T}, track #it{p}_{T}", HistType::kTH2F, {jetPtAxis, trackPtAxis}); registry.add("data/jets/jetTrackPtEtaPhi", "Tracks in jets #it{p}_{T}, #eta, #phi", HistType::kTH3F, {trackPtAxis, etaAxis, phiAxis}); @@ -131,6 +193,73 @@ struct JetFragmentation { registry.add("data/jets/jetPtZTheta", "Jet #it{p}_{T}, z, #theta", HistType::kTH3F, {jetPtAxis, zAxis, thetaAxis}); } + if (doprocessDataV0 || doprocessDataV0Frag) { + registry.add("data/V0/nV0sEvent", "nV0sEvent", HistType::kTH1F, {trackCount}); + + // Unidentified + registry.add("data/V0/V0PtEtaPhi", "V0PtEtaPhi", HistType::kTH3F, {V0PtAxis, V0EtaAxis, V0PhiAxis}); + registry.add("data/V0/V0PtCtau", "V0PtCtau", HistType::kTHnSparseF, {V0PtAxis, V0CtauAxis, V0CtauAxis, V0CtauAxis}); + registry.add("data/V0/V0PtMass", "V0PtMass", HistType::kTHnSparseF, {V0PtAxis, K0SMassAxis, LambdaMassAxis, LambdaMassAxis}); + registry.add("data/V0/V0PtRadiusCosPA", "V0PtRadiusCosPA", HistType::kTH3F, {V0PtAxis, V0RadiusAxis, V0CosPAAxis}); + registry.add("data/V0/V0PtDCAposneg", "V0PtDCAposneg", HistType::kTH3F, {V0PtAxis, V0DCApAxis, V0DCAnAxis}); + registry.add("data/V0/V0PtDCAd", "V0PtDCAd", HistType::kTH2F, {V0PtAxis, V0DCAdAxis}); + + // Identified + registry.add("data/V0/K0SPtEtaPhi", "K0SPtEtaPhi", HistType::kTH3F, {V0PtAxis, V0EtaAxis, V0PhiAxis}); + registry.add("data/V0/K0SPtCtauMass", "K0SPtCtauMass", HistType::kTH3F, {V0partPtAxis, V0CtauAxis, K0SMassAxis}); + registry.add("data/V0/K0SPtRadiusCosPA", "K0SPtRadiusCosPA", HistType::kTH3F, {V0partPtAxis, V0RadiusAxis, V0CosPAAxis}); + registry.add("data/V0/K0SPtDCAposneg", "K0SPtDCAposneg", HistType::kTH3F, {V0partPtAxis, V0DCApAxis, V0DCAnAxis}); + registry.add("data/V0/K0SPtDCAd", "K0SPtDCAd", HistType::kTH2F, {V0partPtAxis, V0DCAdAxis}); + + registry.add("data/V0/LambdaPtEtaPhi", "LambdaPtEtaPhi", HistType::kTH3F, {V0PtAxis, V0EtaAxis, V0PhiAxis}); + registry.add("data/V0/LambdaPtCtauMass", "LambdaPtCtauMass", HistType::kTH3F, {V0partPtAxis, V0CtauAxis, LambdaMassAxis}); + registry.add("data/V0/LambdaPtRadiusCosPA", "LambdaPtRadiusCosPA", HistType::kTH3F, {V0partPtAxis, V0RadiusAxis, V0CosPAAxis}); + registry.add("data/V0/LambdaPtDCAposneg", "LambdaPtDCAposneg", HistType::kTH3F, {V0partPtAxis, V0DCApAxis, V0DCAnAxis}); + registry.add("data/V0/LambdaPtDCAd", "LambdaPtDCAd", HistType::kTH2F, {V0partPtAxis, V0DCAdAxis}); + + registry.add("data/V0/antiLambdaPtEtaPhi", "antiLambdaPtEtaPhi", HistType::kTH3F, {V0PtAxis, V0EtaAxis, V0PhiAxis}); + registry.add("data/V0/antiLambdaPtCtauMass", "antiLambdaPtCtauMass", HistType::kTH3F, {V0partPtAxis, V0CtauAxis, LambdaMassAxis}); + registry.add("data/V0/antiLambdaPtRadiusCosPA", "antiLambdaPtRadiusCosPA", HistType::kTH3F, {V0partPtAxis, V0RadiusAxis, V0CosPAAxis}); + registry.add("data/V0/antiLambdaPtDCAposneg", "antiLambdaPtDCAposneg", HistType::kTH3F, {V0partPtAxis, V0DCApAxis, V0DCAnAxis}); + registry.add("data/V0/antiLambdaPtDCAd", "antiLambdaPtDCAd", HistType::kTH2F, {V0partPtAxis, V0DCAdAxis}); + } + + if (doprocessDataV0Frag) { + registry.add("data/jets/V0/jetPtnV0", "jetPtnV0", HistType::kTH2F, {jetPtAxis, trackCount}); + registry.add("data/jets/V0/jetPtV0TrackProj", "jetPtV0TrackProj", HistType::kTH2F, {jetPtAxis, zAxis}); + + registry.add("data/jets/V0/jetPtV0PtEtaPhi", "jetPtV0PtEtaPhi", HistType::kTHnSparseF, {jetPtAxis, V0PtAxis, V0EtaAxis, V0PhiAxis}); + registry.add("data/jets/V0/jetPtV0PtCtau", "jetPtV0PtCtau", HistType::kTHnSparseF, {jetPtAxis, V0PtAxis, V0CtauAxis, V0CtauAxis, V0CtauAxis}); + registry.add("data/jets/V0/jetPtV0PtMass", "jetPtV0PtMass", HistType::kTHnSparseF, {jetPtAxis, V0PtAxis, K0SMassAxis, LambdaMassAxis, LambdaMassAxis}); + registry.add("data/jets/V0/jetPtV0PtRadiusCosPA", "jetPtV0PtRadiusCosPA", HistType::kTHnSparseF, {jetPtAxis, V0PtAxis, V0RadiusAxis, V0CosPAAxis}); + registry.add("data/jets/V0/jetPtV0PtDCAposneg", "jetPtV0PtDCAposneg", HistType::kTHnSparseF, {jetPtAxis, V0PtAxis, V0DCApAxis, V0DCAnAxis}); + registry.add("data/jets/V0/jetPtV0PtDCAd", "jetPtV0PtDCAd", HistType::kTH3F, {jetPtAxis, V0PtAxis, V0DCAdAxis}); + + registry.add("data/jets/V0/jetPtnLambda", "jetPtnLambda", HistType::kTH2F, {jetPtAxis, trackCount}); + registry.add("data/jets/V0/jetPtLambdaTrackProjCtau", "Jet #it{p}_{T}, #it{z}_{#Lambda^{0}}, c#tau", HistType::kTH3F, {jetPtAxis, zAxis, V0CtauAxis}); + registry.add("data/jets/V0/jetPtLambdaTrackProjMass", "Jet #it{p}_{T}, #it{z}_{#Lambda^{0}}, mass", HistType::kTH3F, {jetPtAxis, zAxis, LambdaMassAxis}); + registry.add("data/jets/V0/jetPtLambdaTrackProjRadius", "Jet #it{p}_{T}, #it{z}_{#Lambda^{0}}, radius", HistType::kTH3F, {jetPtAxis, zAxis, V0RadiusAxis}); + registry.add("data/jets/V0/jetPtLambdaTrackProjCosPA", "Jet #it{p}_{T}, #it{z}_{#Lambda^{0}}, cosPA", HistType::kTH3F, {jetPtAxis, zAxis, V0CosPAAxis}); + registry.add("data/jets/V0/jetPtLambdaTrackProjDCAd", "Jet #it{p}_{T}, #it{z}_{#Lambda^{0}}, DCA daughters", HistType::kTH3F, {jetPtAxis, zAxis, V0DCAdAxis}); + registry.add("data/jets/V0/jetPtLambdaTrackProjDCAposneg", "Jet #it{p}_{T}, #it{z}_{#Lambda^{0}}, DCA#pm", HistType::kTHnSparseF, {jetPtAxis, zAxis, V0DCApAxis, V0DCAnAxis}); + + registry.add("data/jets/V0/jetPtnAntiLambda", "jetPtnAntiLambda", HistType::kTH2F, {jetPtAxis, trackCount}); + registry.add("data/jets/V0/jetPtAntiLambdaTrackProjCtau", "Jet #it{p}_{T}, #it{z}_{#bar{#Lambda}^{0}}, c#tau", HistType::kTH3F, {jetPtAxis, zAxis, V0CtauAxis}); + registry.add("data/jets/V0/jetPtAntiLambdaTrackProjMass", "Jet #it{p}_{T}, #it{z}_{#bar{#Lambda}^{0}}, mass", HistType::kTH3F, {jetPtAxis, zAxis, LambdaMassAxis}); + registry.add("data/jets/V0/jetPtAntiLambdaTrackProjRadius", "Jet #it{p}_{T}, #it{z}_{#bar{#Lambda}^{0}}, radius", HistType::kTH3F, {jetPtAxis, zAxis, V0RadiusAxis}); + registry.add("data/jets/V0/jetPtAntiLambdaTrackProjCosPA", "Jet #it{p}_{T}, #it{z}_{#bar{#Lambda}^{0}}, cosPA", HistType::kTH3F, {jetPtAxis, zAxis, V0CosPAAxis}); + registry.add("data/jets/V0/jetPtAntiLambdaTrackProjDCAd", "Jet #it{p}_{T}, #it{z}_{#bar{#Lambda}^{0}}, DCA daughters", HistType::kTH3F, {jetPtAxis, zAxis, V0DCAdAxis}); + registry.add("data/jets/V0/jetPtAntiLambdaTrackProjDCAposneg", "Jet #it{p}_{T}, #it{z}_{#bar{#Lambda}^{0}}, DCA#pm", HistType::kTHnSparseF, {jetPtAxis, zAxis, V0DCApAxis, V0DCAnAxis}); + + registry.add("data/jets/V0/jetPtnK0S", "jetPtnK0S", HistType::kTH2F, {jetPtAxis, trackCount}); + registry.add("data/jets/V0/jetPtK0STrackProjCtau", "Jet #it{p}_{T}, #it{z}_{K^{0}_{S}}, c#tau", HistType::kTH3F, {jetPtAxis, zAxis, V0CtauAxis}); + registry.add("data/jets/V0/jetPtK0STrackProjMass", "Jet #it{p}_{T}, #it{z}_{K^{0}_{S}}, mass", HistType::kTH3F, {jetPtAxis, zAxis, K0SMassAxis}); + registry.add("data/jets/V0/jetPtK0STrackProjRadius", "Jet #it{p}_{T}, #it{z}_{K^{0}_{S}}, radius", HistType::kTH3F, {jetPtAxis, zAxis, V0RadiusAxis}); + registry.add("data/jets/V0/jetPtK0STrackProjCosPA", "Jet #it{p}_{T}, #it{z}_{K^{0}_{S}}, cosPA", HistType::kTH3F, {jetPtAxis, zAxis, V0CosPAAxis}); + registry.add("data/jets/V0/jetPtK0STrackProjDCAd", "Jet #it{p}_{T}, #it{z}_{K^{0}_{S}}, DCA daughters", HistType::kTH3F, {jetPtAxis, zAxis, V0DCAdAxis}); + registry.add("data/jets/V0/jetPtK0STrackProjDCAposneg", "Jet #it{p}_{T}, #it{z}_{K^{0}_{S}}, DCA#pm", HistType::kTHnSparseF, {jetPtAxis, zAxis, V0DCApAxis, V0DCAnAxis}); + } + if (doprocessMcP) { registry.add("particle-level/nJetsnTracks", "nJetsnTracks; nJets; nTracks", HistType::kTH2F, {jetCount, trackCount}); registry.add("particle-level/collision/partCollisionVtxZ", "Collision vertex z (cm)", HistType::kTH1F, {binVtxZ}); @@ -195,15 +324,17 @@ struct JetFragmentation { registry.add("matching/jets/matchDetJetPtPartJetPt", "matchDetJetPtPartJetPt", HistType::kTH2F, {detJetPtAxis, partJetPtAxis}); registry.add("matching/jets/matchPartJetPtDetJetEtaPartJetEta", "matchPartJetPtDetJetEtaPartJetEta", HistType::kTH3F, {partJetPtAxis, detEtaAxis, partEtaAxis}); registry.add("matching/jets/matchPartJetPtDetJetPhiPartJetPhi", "matchPartJetPtDetJetPhiPartJetPhi", HistType::kTH3F, {partJetPtAxis, detPhiAxis, partPhiAxis}); - registry.add("matching/jets/matchPartJetPtResolutionPt", "#it{p}_{T}^{jet, part} - #it{p}_{T}^{jet, det}", HistType::kTH2F, {partJetPtAxis, ptDiffAxis}); - registry.add("matching/jets/matchPartJetPtResolutionEta", "#eta^{jet, part} - #eta^{jet, det}", HistType::kTH3F, {partJetPtAxis, partEtaAxis, etaDiffAxis}); - registry.add("matching/jets/matchPartJetPtResolutionPhi", "#phi^{jet, part} - #phi^{jet, det}", HistType::kTH3F, {partJetPtAxis, partPhiAxis, phiDiffAxis}); + registry.add("matching/jets/matchPartJetPtResolutionPt", "#it{p}_{T}^{jet, det} - #it{p}_{T}^{jet, part}", HistType::kTH2F, {partJetPtAxis, ptDiffAxis}); + registry.add("matching/jets/matchPartJetPtRelDiffPt", "#it{p}_{T}^{jet, det} - #it{p}_{T}^{jet, part}", HistType::kTH2F, {partJetPtAxis, ptJetRelDiffAxis}); + registry.add("matching/jets/matchPartJetPtResolutionEta", "#eta^{jet, det} - #eta^{jet, part}", HistType::kTH3F, {partJetPtAxis, partEtaAxis, etaDiffAxis}); + registry.add("matching/jets/matchPartJetPtResolutionPhi", "#phi^{jet, det} - #phi^{jet, part}", HistType::kTH3F, {partJetPtAxis, partPhiAxis, phiDiffAxis}); registry.add("matching/jets/matchPartJetPtResolutionChargeFrag", "Resolution #it{p}_{T}^{tr} / #it{p}_{T}^{jet}", HistType::kTH3F, {partJetPtAxis, partZAxis, zDiffAxis}); registry.add("matching/jets/matchPartJetPtResolutionTrackPt", "Resolution #it{p}_{T}^{track}", HistType::kTH3F, {partJetPtAxis, trackPtAxis, ptTrackDiffAxis}); + registry.add("matching/jets/matching/jets/matchPartJetPtRelDiffTrackPt", "Rel. diff #it{p}_{T}^{track}", HistType::kTHnSparseF, {partJetPtAxis, ptRatioAxis, trackPtAxis, ptTrackRelDiffAxis}); registry.add("matching/jets/matchPartJetPtResolutionTrackProj", "Resolution #it{p}^{proj} / #it{p}^{jet}", HistType::kTH3F, {partJetPtAxis, partZAxis, zDiffAxis}); + registry.add("matching/jets/matchPartJetPtRelDiffTrackProj", "Rel. diff #it{p}^{proj} / #it{p}^{jet}", HistType::kTHnSparseF, {partJetPtAxis, ptRatioAxis, partZAxis, zRelDiffAxis}); registry.add("matching/jets/matchPartJetPtResolutionXi", "Resolution ln(1/#it{z})", HistType::kTH3F, {partJetPtAxis, partXiAxis, xiDiffAxis}); registry.add("matching/jets/matchPartJetPtResolutionTheta", "Resolution #theta", HistType::kTH3F, {partJetPtAxis, partThetaAxis, thetaDiffAxis}); - // TODO: does it make sense to add 2D resolution plots? registry.add("matching/jets/matchPartJetPtResolutionXiResolutionTheta", "Resolution #xi, #theta", HistType::kTHnSparseF, {partJetPtAxis, partXiAxis, xiDiffAxis, partThetaAxis, thetaDiffAxis}); registry.add("matching/jets/matchPartJetPtResolutionZResolutionTheta", "Resolution #it{z}, #theta", HistType::kTHnSparseF, {partJetPtAxis, partZAxis, zDiffAxis, partThetaAxis, thetaDiffAxis}); registry.add("matching/jets/matchPartJetPtEtaPhiMatchDist", "matchJetMatchDist", HistType::kTHnSparseF, {partJetPtAxis, partEtaAxis, partPhiAxis, matchDistAxis}); @@ -237,6 +368,28 @@ struct JetFragmentation { registry.add("matching/jets/fakeDetJetPtZTheta", "Fakes", HistType::kTH3F, {detJetPtAxis, detZAxis, detThetaAxis}); registry.add("matching/jets/missPartJetPtZTheta", "Misses", HistType::kTH3F, {partJetPtAxis, partZAxis, partThetaAxis}); } + + if (doprocessMcV0) { + registry.add("matching/V0/V0PartPtDetPt", "V0PartPtDetPt", HistType::kTH2F, {V0partPtAxis, V0detPtAxis}); + + registry.add("matching/V0/K0SPtEtaPhi", "K0SPtEtaPhi", HistType::kTH3F, {V0PtAxis, V0EtaAxis, V0PhiAxis}); + registry.add("matching/V0/K0SPtCtauMass", "K0SPtCtauMass", HistType::kTH3F, {V0partPtAxis, V0CtauAxis, K0SMassAxis}); + registry.add("matching/V0/K0SPtRadiusCosPA", "K0SPtRadiusCosPA", HistType::kTH3F, {V0partPtAxis, V0RadiusAxis, V0CosPAAxis}); + registry.add("matching/V0/K0SPtDCAposneg", "K0SPtDCAposneg", HistType::kTH3F, {V0partPtAxis, V0DCApAxis, V0DCAnAxis}); + registry.add("matching/V0/K0SPtDCAd", "K0SPtDCAd", HistType::kTH2F, {V0partPtAxis, V0DCAdAxis}); + + registry.add("matching/V0/LambdaPtEtaPhi", "LambdaPtEtaPhi", HistType::kTH3F, {V0PtAxis, V0EtaAxis, V0PhiAxis}); + registry.add("matching/V0/LambdaPtCtauMass", "LambdaPtCtauMass", HistType::kTH3F, {V0partPtAxis, V0CtauAxis, LambdaMassAxis}); + registry.add("matching/V0/LambdaPtRadiusCosPA", "LambdaPtRadiusCosPA", HistType::kTH3F, {V0partPtAxis, V0RadiusAxis, V0CosPAAxis}); + registry.add("matching/V0/LambdaPtDCAposneg", "LambdaPtDCAposneg", HistType::kTH3F, {V0partPtAxis, V0DCApAxis, V0DCAnAxis}); + registry.add("matching/V0/LambdaPtDCAd", "LambdaPtDCAd", HistType::kTH2F, {V0partPtAxis, V0DCAdAxis}); + + registry.add("matching/V0/antiLambdaPtEtaPhi", "antiLambdaPtEtaPhi", HistType::kTH3F, {V0PtAxis, V0EtaAxis, V0PhiAxis}); + registry.add("matching/V0/antiLambdaPtCtauMass", "antiLambdaPtCtauMass", HistType::kTH3F, {V0partPtAxis, V0CtauAxis, LambdaMassAxis}); + registry.add("matching/V0/antiLambdaPtRadiusCosPA", "antiLambdaPtRadiusCosPA", HistType::kTH3F, {V0partPtAxis, V0RadiusAxis, V0CosPAAxis}); + registry.add("matching/V0/antiLambdaPtDCAposneg", "antiLambdaPtDCAposneg", HistType::kTH3F, {V0partPtAxis, V0DCApAxis, V0DCAnAxis}); + registry.add("matching/V0/antiLambdaPtDCAd", "antiLambdaPtDCAd", HistType::kTH2F, {V0partPtAxis, V0DCAdAxis}); + } } // init double CheckDphi(double dphi) @@ -288,11 +441,59 @@ struct JetFragmentation { return xi; } + template + void fillMcV0Histograms(collisionType const& collision, v0Type const& v0, trackType const& tracks, particleType const& particles, double weight = 1.) + { + auto negTrack = v0.template negTrack_as(); + auto posTrack = v0.template posTrack_as(); + if (!negTrack.has_mcParticle() || !posTrack.has_mcParticle()) { + return; + } + auto mcNegTrack = negTrack.template mcParticle_as(); + auto mcPosTrack = posTrack.template mcParticle_as(); + if (!mcNegTrack.has_mothers() || !mcPosTrack.has_mothers()) { + return; + } + double ctauLambda = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0; + double ctauAntiLambda = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0Bar; + double ctauK0s = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short; + // Can tracks have multiple mothers? + for (auto& particleMotherOfNeg : mcNegTrack.template mothers_as()) { + for (auto& particleMotherOfPos : mcPosTrack.template mothers_as()) { + if (particleMotherOfNeg.isPhysicalPrimary() && particleMotherOfNeg == particleMotherOfPos) { + double ptPartV0 = particleMotherOfNeg.pt(); + int pdg = particleMotherOfNeg.pdgCode(); + registry.fill(HIST("matching/V0/V0PartPtDetPt"), ptPartV0, v0.pt()); + + if (pdg == 310) { // K0S + registry.fill(HIST("matching/V0/K0SPtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + registry.fill(HIST("matching/V0/K0SPtCtauMass"), ptPartV0, ctauK0s, v0.mK0Short(), weight); + registry.fill(HIST("matching/V0/K0SPtRadiusCosPA"), ptPartV0, v0.v0radius(), v0.v0cosPA(), weight); + registry.fill(HIST("matching/V0/K0SPtDCAposneg"), ptPartV0, v0.dcapostopv(), v0.dcanegtopv(), weight); + registry.fill(HIST("matching/V0/K0SPtDCAd"), ptPartV0, v0.dcaV0daughters(), weight); + } else if (pdg == 3122) { // Lambda + registry.fill(HIST("matching/V0/LambdaPtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + registry.fill(HIST("matching/V0/LambdaPtCtauMass"), ptPartV0, ctauLambda, v0.mLambda(), weight); + registry.fill(HIST("matching/V0/LambdaPtRadiusCosPA"), ptPartV0, v0.v0radius(), v0.v0cosPA(), weight); + registry.fill(HIST("matching/V0/LambdaPtDCAposneg"), ptPartV0, v0.dcapostopv(), v0.dcanegtopv(), weight); + registry.fill(HIST("matching/V0/LambdaPtDCAd"), ptPartV0, v0.dcaV0daughters(), weight); + } else if (pdg == -3122) { // AntiLambda + registry.fill(HIST("matching/V0/antiLambdaPtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + registry.fill(HIST("matching/V0/antiLambdaPtCtauMass"), ptPartV0, ctauAntiLambda, v0.mAntiLambda(), weight); + registry.fill(HIST("matching/V0/antiLambdaPtRadiusCosPA"), ptPartV0, v0.v0radius(), v0.v0cosPA(), weight); + registry.fill(HIST("matching/V0/antiLambdaPtDCAposneg"), ptPartV0, v0.dcapostopv(), v0.dcanegtopv(), weight); + registry.fill(HIST("matching/V0/antiLambdaPtDCAd"), ptPartV0, v0.dcaV0daughters(), weight); + } + } // if mothers match + } // for mothers of pos + } // for mothers of neg + } + template void fillDataRun3Histograms(T const& jet) { registry.fill(HIST("data/jets/jetPtEtaPhi"), jet.pt(), jet.eta(), jet.phi()); - for (const auto& track : jet.template tracks_as()) { + for (const auto& track : jet.template tracks_as()) { double chargeFrag = -1., trackProj = -1., xi = -1.; double theta = -1.; chargeFrag = ChargeFrag(jet, track); @@ -311,11 +512,86 @@ struct JetFragmentation { } } + template + void fillDataV0Histograms(CollisionType collision, V0Type V0s, TrackType tracks) + { + for (const auto& v0 : V0s) { + double ctauLambda = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0; + double ctauAntiLambda = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0Bar; + double ctauK0s = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short; + + registry.fill(HIST("data/V0/V0PtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + registry.fill(HIST("data/V0/V0PtCtau"), v0.pt(), ctauK0s, ctauLambda, ctauAntiLambda); + registry.fill(HIST("data/V0/V0PtMass"), v0.pt(), v0.mK0Short(), v0.mLambda(), v0.mAntiLambda()); + registry.fill(HIST("data/V0/V0PtRadiusCosPA"), v0.pt(), v0.v0radius(), v0.v0cosPA()); + registry.fill(HIST("data/V0/V0PtDCAposneg"), v0.pt(), v0.dcapostopv(), v0.dcanegtopv()); + registry.fill(HIST("data/V0/V0PtDCAd"), v0.pt(), v0.dcaV0daughters()); + + // auto negTrack = v0.template negTrack_as(); + // auto posTrack = v0.template posTrack_as(); + if (TMath::Abs(v0.dcanegtopv()) < dcanegtopv || TMath::Abs(v0.dcapostopv()) < dcapostopv || v0.dcaV0daughters() < dcav0dau) { + continue; + } // TODO: move to filter + + if (v0.v0radius() > v0radius && v0.v0cosPA() > v0cospa) { + // TODO: Add TPC info to tracks + if (ctauLambda < lifetimecutLambda) { + // if (TMath::Abs(posTrack.tpcNSigmaPr()) < TpcPidNsigmaCut) { + registry.fill(HIST("data/V0/LambdaPtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + registry.fill(HIST("data/V0/LambdaPtCtauMass"), v0.pt(), ctauLambda, v0.mLambda()); + registry.fill(HIST("data/V0/LambdaPtRadiusCosPA"), v0.pt(), v0.v0radius(), v0.v0cosPA()); + registry.fill(HIST("data/V0/LambdaPtDCAposneg"), v0.pt(), v0.dcapostopv(), v0.dcanegtopv()); + registry.fill(HIST("data/V0/LambdaPtDCAd"), v0.pt(), v0.dcaV0daughters()); + // } + // if (TMath::Abs(negTrack.tpcNSigmaPr()) < TpcPidNsigmaCut) { + registry.fill(HIST("data/V0/antiLambdaPtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + registry.fill(HIST("data/V0/antiLambdaPtCtauMass"), v0.pt(), ctauAntiLambda, v0.mAntiLambda()); + registry.fill(HIST("data/V0/antiLambdaPtRadiusCosPA"), v0.pt(), v0.v0radius(), v0.v0cosPA()); + registry.fill(HIST("data/V0/antiLambdaPtDCAposneg"), v0.pt(), v0.dcapostopv(), v0.dcanegtopv()); + registry.fill(HIST("data/V0/antiLambdaPtDCAd"), v0.pt(), v0.dcaV0daughters()); + // } + } // Lambda lifetime cut + if (ctauK0s < lifetimecutK0S) { + registry.fill(HIST("data/V0/K0SPtEtaPhi"), v0.pt(), v0.eta(), v0.phi()); + registry.fill(HIST("data/V0/K0SPtCtauMass"), v0.pt(), ctauK0s, v0.mK0Short()); + registry.fill(HIST("data/V0/K0SPtRadiusCosPA"), v0.pt(), v0.v0radius(), v0.v0cosPA()); + registry.fill(HIST("data/V0/K0SPtDCAposneg"), v0.pt(), v0.dcapostopv(), v0.dcanegtopv()); + registry.fill(HIST("data/V0/K0SPtDCAd"), v0.pt(), v0.dcaV0daughters()); + } // K0S lifetime cut + } // v0 radius, cosPA + } // for v0 + } + + template + void fillDataV0FragHistograms(CollisionType collision, JetType jet, V0Type v0, TrackType tracks) + { + // TODO: Add V0 PID + double trackProj = TrackProj(jet, v0); + double ctauLambda = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0; + double ctauAntiLambda = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0Bar; + double ctauK0s = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short; + + registry.fill(HIST("data/jets/V0/jetPtV0PtEtaPhi"), jet.pt(), v0.pt(), v0.eta(), v0.phi()); + registry.fill(HIST("data/jets/V0/jetPtV0PtCtau"), jet.pt(), v0.pt(), ctauK0s, ctauLambda, ctauAntiLambda); + registry.fill(HIST("data/jets/V0/jetPtV0PtMass"), jet.pt(), v0.pt(), v0.mK0Short(), v0.mLambda(), v0.mAntiLambda()); + registry.fill(HIST("data/jets/V0/jetPtV0PtRadiusCosPA"), jet.pt(), v0.pt(), v0.v0radius(), v0.v0cosPA()); + registry.fill(HIST("data/jets/V0/jetPtV0PtDCAposneg"), jet.pt(), v0.pt(), v0.dcapostopv(), v0.dcanegtopv()); + registry.fill(HIST("data/jets/V0/jetPtV0PtDCAd"), jet.pt(), v0.pt(), v0.dcaV0daughters()); + registry.fill(HIST("data/jets/V0/jetPtV0TrackProj"), jet.pt(), trackProj); + + registry.fill(HIST("data/jets/V0/jetPtAntiLambdaTrackProjCtau"), jet.pt(), trackProj, ctauLambda); + registry.fill(HIST("data/jets/V0/jetPtAntiLambdaTrackProjMass"), jet.pt(), trackProj, v0.mLambda()); + registry.fill(HIST("data/jets/V0/jetPtAntiLambdaTrackProjRadius"), jet.pt(), trackProj, v0.v0radius()); + registry.fill(HIST("data/jets/V0/jetPtAntiLambdaTrackProjCosPA"), jet.pt(), trackProj, v0.v0cosPA()); + registry.fill(HIST("data/jets/V0/jetPtAntiLambdaTrackProjDCAd"), jet.pt(), trackProj, v0.dcaV0daughters()); + registry.fill(HIST("data/jets/V0/jetPtAntiLambdaTrackProjDCAposneg"), jet.pt(), trackProj, v0.dcapostopv(), v0.dcanegtopv()); + } + template void fillMatchingHistogramsJet(DetJet const& detJet, PartJet const& partJet, double weight = 1.) { - double deltaEta = partJet.eta() - detJet.eta(); - double deltaPhi = partJet.phi() - detJet.phi(); + double deltaEta = detJet.eta() - partJet.eta(); + double deltaPhi = detJet.phi() - partJet.phi(); deltaPhi = CheckDphi(deltaPhi); double deltaR = TMath::Sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi); @@ -326,9 +602,10 @@ struct JetFragmentation { registry.fill(HIST("matching/jets/matchDetJetPtPartJetPt"), detJet.pt(), partJet.pt(), weight); registry.fill(HIST("matching/jets/matchPartJetPtDetJetEtaPartJetEta"), partJet.pt(), detJet.eta(), partJet.eta(), weight); registry.fill(HIST("matching/jets/matchPartJetPtDetJetPhiPartJetPhi"), partJet.pt(), detJet.phi(), partJet.phi(), weight); - registry.fill(HIST("matching/jets/matchPartJetPtResolutionPt"), partJet.pt(), (partJet.pt() - detJet.pt()), weight); + registry.fill(HIST("matching/jets/matchPartJetPtResolutionPt"), partJet.pt(), (detJet.pt() - partJet.pt()), weight); registry.fill(HIST("matching/jets/matchPartJetPtResolutionEta"), partJet.pt(), partJet.eta(), deltaEta, weight); registry.fill(HIST("matching/jets/matchPartJetPtResolutionPhi"), partJet.pt(), partJet.phi(), deltaPhi, weight); + registry.fill(HIST("matching/jets/matchPartJetPtRelDiffPt"), partJet.pt(), (detJet.pt() - partJet.pt()) / partJet.pt(), weight); } template @@ -369,12 +646,16 @@ struct JetFragmentation { // Resolution registry.fill(HIST("matching/jets/matchPartJetPtResolutionTrackPt"), partJet.pt(), particle.pt(), (particle.pt() - track.pt()), weight); - registry.fill(HIST("matching/jets/matchPartJetPtResolutionChargeFrag"), partJet.pt(), partChargeFrag, (partChargeFrag - detChargeFrag), weight); - registry.fill(HIST("matching/jets/matchPartJetPtResolutionTrackProj"), partJet.pt(), partTrackProj, (partTrackProj - detTrackProj), weight); - registry.fill(HIST("matching/jets/matchPartJetPtResolutionXi"), partJet.pt(), partXi, (partXi - detXi), weight); - registry.fill(HIST("matching/jets/matchPartJetPtResolutionTheta"), partJet.pt(), partTheta, (partTheta - detTheta), weight); - registry.fill(HIST("matching/jets/matchPartJetPtResolutionXiResolutionTheta"), partJet.pt(), partXi, (partXi - detXi), partTheta, (partTheta - detTheta), weight); - registry.fill(HIST("matching/jets/matchPartJetPtResolutionZResolutionTheta"), partJet.pt(), partTrackProj, (partTrackProj - detTrackProj), partTheta, (partTheta - detTheta), weight); + registry.fill(HIST("matching/jets/matchPartJetPtResolutionChargeFrag"), partJet.pt(), partChargeFrag, (detChargeFrag - partChargeFrag), weight); + registry.fill(HIST("matching/jets/matchPartJetPtResolutionTrackProj"), partJet.pt(), partTrackProj, (detTrackProj - partTrackProj), weight); + registry.fill(HIST("matching/jets/matchPartJetPtResolutionXi"), partJet.pt(), partXi, (detXi - partXi), weight); + registry.fill(HIST("matching/jets/matchPartJetPtResolutionTheta"), partJet.pt(), partTheta, (detTheta - partTheta), weight); + registry.fill(HIST("matching/jets/matchPartJetPtResolutionXiResolutionTheta"), partJet.pt(), partXi, (detXi - partXi), partTheta, (detTheta - partTheta), weight); + registry.fill(HIST("matching/jets/matchPartJetPtResolutionZResolutionTheta"), partJet.pt(), partTrackProj, (detTrackProj - partTrackProj), partTheta, (detTheta - partTheta), weight); + + // Relative difference + registry.fill(HIST("matching/jets/matching/jets/matchPartJetPtRelDiffTrackPt"), partJet.pt(), detJet.pt() / partJet.pt(), particle.pt(), (track.pt() - particle.pt()) / particle.pt(), weight); + registry.fill(HIST("matching/jets/matchPartJetPtRelDiffTrackProj"), partJet.pt(), detJet.pt() / partJet.pt(), partTrackProj, (detTrackProj - partTrackProj) / partTrackProj, weight); // Response registry.fill(HIST("matching/jets/matchDetJetPtFragPartJetPtFrag"), detJet.pt(), detChargeFrag, partJet.pt(), partChargeFrag, weight); @@ -415,7 +696,7 @@ struct JetFragmentation { void fillMCDHistograms(Jet const& jet, double weight = 1.) { registry.fill(HIST("detector-level/jets/detJetPtEtaPhi"), jet.pt(), jet.eta(), jet.phi(), weight); - for (const auto& track : jet.template tracks_as()) { + for (const auto& track : jet.template tracks_as()) { double chargeFrag = -1., trackProj = -1., theta = -1., xi = -1.; chargeFrag = ChargeFrag(jet, track); trackProj = TrackProj(jet, track); @@ -437,7 +718,7 @@ struct JetFragmentation { void fillMCPHistograms(Jet const& jet, double weight = 1.) { registry.fill(HIST("particle-level/jets/partJetPtEtaPhi"), jet.pt(), jet.eta(), jet.phi(), weight); - for (const auto& track : jet.template tracks_as()) { + for (const auto& track : jet.template tracks_as()) { double chargeFrag = -1., trackProj = -1., theta = -1., xi = -1.; chargeFrag = ChargeFrag(jet, track); trackProj = TrackProj(jet, track); @@ -455,13 +736,13 @@ struct JetFragmentation { } } - void processDummy(aod::JTracks const& track) {} + void processDummy(JetTracks const& tracks) {} PROCESS_SWITCH(JetFragmentation, processDummy, "Dummy process function turned on by default", true); - void processMcD(soa::Join::iterator const& collision, - aod::JMcCollisions const& mcCollisions, + void processMcD(JetCollisionsMCD::iterator const& collision, + JetMcCollisions const& mcCollisions, McDJets const& jets, - aod::JTracks const& tracks) + JetTracks const& tracks) { float nJets = 0, nTracks = 0; double weight = collision.mcCollision().weight(); @@ -479,9 +760,9 @@ struct JetFragmentation { } PROCESS_SWITCH(JetFragmentation, processMcD, "Monte Carlo detector level", false); - void processMcP(aod::JMcCollision const& mcCollision, // Add some form of event selection? + void processMcP(JetMcCollision const& mcCollision, // Add some form of event selection? McPJets const& jets, - aod::JMcParticles const& particles) + JetParticles const& particles) { float nJets = 0, nTracks = 0; double weight = mcCollision.weight(); @@ -500,9 +781,9 @@ struct JetFragmentation { PROCESS_SWITCH(JetFragmentation, processMcP, "Monte Carlo particle level", false); - void processDataRun3(aod::JCollision const& collision, + void processDataRun3(JetCollision const& collision, soa::Join const& jets, - aod::JTracks const& tracks) + JetTracks const& tracks) { float nJets = 0, nTracks = 0; for (const auto& track : tracks) { @@ -519,14 +800,16 @@ struct JetFragmentation { } PROCESS_SWITCH(JetFragmentation, processDataRun3, "Run 3 Data", false); - void processMcMatched(soa::Join::iterator const& collision, + void processMcMatched(JetCollisionsMCD::iterator const& collision, soa::Join const& mcDetJets, - McTracks const& tracks, - aod::JMcCollisions const& mcCollisions, + JetTracksMCD const& tracks, + JetMcCollisions const& mcCollisions, McPJets const& mcPartJets, - // soa::Join const& mcPartJets - aod::JMcParticles const& mcParticles) + JetParticles const& mcParticles) { + if (!collision.has_mcCollision()) { + return; + } double weight = collision.mcCollision().weight(); bool isFake = false; for (const auto& detJet : mcDetJets) { @@ -536,10 +819,10 @@ struct JetFragmentation { for (auto& partJet : detJet.template matchedJetGeo_as()) { fillMatchingHistogramsJet(detJet, partJet, weight); - for (const auto& track : detJet.tracks_as()) { + for (const auto& track : detJet.tracks_as()) { bool isTrackMatched = false; - for (const auto& particle : partJet.tracks_as()) { - if (track.has_mcParticle() && particle.globalIndex() == track.template mcParticle_as().globalIndex()) { + for (const auto& particle : partJet.tracks_as()) { + if (track.has_mcParticle() && particle.globalIndex() == track.template mcParticle_as().globalIndex()) { isTrackMatched = true; fillMatchingHistogramsConstituent(detJet, partJet, track, particle, weight); break; // No need to inspect other particles @@ -554,7 +837,7 @@ struct JetFragmentation { if (!detJet.has_matchedJetGeo()) { isFake = true; registry.fill(HIST("matching/jets/fakeDetJetPtEtaPhi"), detJet.pt(), detJet.eta(), detJet.phi(), weight); - for (const auto& track : detJet.tracks_as()) { + for (const auto& track : detJet.tracks_as()) { fillMatchingFakeOrMiss(detJet, track, isFake, weight); } } // if detJet does not have a match @@ -571,6 +854,84 @@ struct JetFragmentation { // } } PROCESS_SWITCH(JetFragmentation, processMcMatched, "Monte Carlo particle and detector level", false); + + void processMcV0(soa::Join::iterator const& collision, + aod::McCollisions const& mcCollisions, + aod::V0Datas const& V0s, + soa::Join const& tracks, + aod::McParticles const& mcParticles) + { + if (!collision.has_mcCollision()) { + return; + } + double weight = collision.mcCollision().weight(); + for (const auto& v0 : V0s) { + fillMcV0Histograms(collision, v0, tracks, mcParticles, weight); + } + } + PROCESS_SWITCH(JetFragmentation, processMcV0, "Monte Carlo V0", false); + + void processDataV0(aod::Collision const& collision, + aod::V0Datas const& V0s, + MyTracks const& tracks) + { + registry.fill(HIST("data/V0/nV0sEvent"), V0s.size()); + fillDataV0Histograms(collision, V0s, tracks); + } + PROCESS_SWITCH(JetFragmentation, processDataV0, "Data V0", false); + + void processDataV0Frag(soa::Join::iterator const& jcoll, + soa::Join const& jets, + JetTracks const& jtracks, + aod::Collisions const& collisions, + aod::V0Datas const& allV0s, + MyTracks const& allTracks) + { + // This is necessary, because jets are linked to JetCollisions, but V0s are linked to Collisions + const auto& collision = jcoll.collision_as(); + const auto& tracks = allTracks.sliceBy(TracksPerCollision, collision.globalIndex()); + const auto& v0s = allV0s.sliceBy(V0sPerCollision, collision.globalIndex()); + + int kNV0s = v0s.size(); + bool isV0Used[kNV0s]; + for (int i = 0; i < kNV0s; i++) { + isV0Used[i] = false; + } + registry.fill(HIST("data/V0/nV0sEvent"), kNV0s); + + fillDataV0Histograms(collision, v0s, tracks); + for (const auto& jet : jets) { + if (jet.eta() < dataJetEtaMin || jet.eta() > dataJetEtaMax) { + continue; // TODO: make filter + } + fillDataRun3Histograms(jet); + int iv0 = -1; + int nV0inJet = 0, nLambdainJet = 0, nAntiLambdainJet = 0, nK0SinJet = 0; + // Loop over V0s and fill histograms + // Jets are pt-sorted, so we prioritise matching V0s with high pt jets + for (const auto& v0 : v0s) { + iv0++; + if (isV0Used[iv0]) { + continue; + } + double deta = jet.eta() - v0.eta(); + double dphi = jet.phi() - v0.phi(); + CheckDphi(dphi); + double dR = TMath::Sqrt(dphi * dphi + deta * deta); + if (dR < jet.r() * 1e-2) { + isV0Used[iv0] = true; + nV0inJet++; + fillDataV0FragHistograms(collision, jet, v0, tracks); + } + } // v0 loop + registry.fill(HIST("data/jets/V0/jetPtnV0"), jet.pt(), nV0inJet); + // TODO: These histograms are now always filled with zeroes. Bring V0 PID back into process + registry.fill(HIST("data/jets/V0/jetPtnLambda"), jet.pt(), nLambdainJet); + registry.fill(HIST("data/jets/V0/jetPtnAntiLambda"), jet.pt(), nAntiLambdainJet); + registry.fill(HIST("data/jets/V0/jetPtnK0S"), jet.pt(), nK0SinJet); + } + } + PROCESS_SWITCH(JetFragmentation, processDataV0Frag, "Data V0 fragmentation", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGJE/Tasks/jetmatchingqa.cxx b/PWGJE/Tasks/jetmatchingqa.cxx index 65caa2a9c5f..9ea3049c619 100644 --- a/PWGJE/Tasks/jetmatchingqa.cxx +++ b/PWGJE/Tasks/jetmatchingqa.cxx @@ -76,7 +76,12 @@ struct JetMatchingQA { { } - void processMCD(aod::JCollision const& collision, aod::JMcParticles const& mcParticles, soa::Join const& tracks, + void processDummy(JetMcCollisions const& mcCollisions) + { + } + PROCESS_SWITCH(JetMatchingQA, processDummy, "Dummy process", true); + + void processMCD(JetCollision const& collision, JetParticles const& mcParticles, JetTracksMCD const& tracks, BaseJetCollection const& djets, TagJetCollection const& pjets) { for (const auto& djet : djets) { @@ -102,13 +107,13 @@ struct JetMatchingQA { registry.fill(HIST("h_jet_match_hf_Nconst"), pjet.tracksIds().size(), djet.tracksIds().size()); double pjet_pt_lead = 0.; - for (auto& mcparticle : pjet.template tracks_as()) { + for (auto& mcparticle : pjet.template tracks_as()) { if (mcparticle.pt() > pjet_pt_lead) { pjet_pt_lead = mcparticle.pt(); } } double djet_pt_lead = 0.; - for (auto& track : djet.template tracks_as>()) { + for (auto& track : djet.template tracks_as()) { if (track.pt() > djet_pt_lead) { djet_pt_lead = track.pt(); } @@ -131,13 +136,13 @@ struct JetMatchingQA { registry.fill(HIST("h_jet_match_geo_Nconst"), pjet.tracksIds().size(), djet.tracksIds().size()); double pjet_pt_lead = 0.; - for (auto& mcparticle : pjet.template tracks_as()) { + for (auto& mcparticle : pjet.template tracks_as()) { if (mcparticle.pt() > pjet_pt_lead) { pjet_pt_lead = mcparticle.pt(); } } double djet_pt_lead = 0.; - for (auto& track : djet.template tracks_as>()) { + for (auto& track : djet.template tracks_as()) { if (track.pt() > djet_pt_lead) { djet_pt_lead = track.pt(); } @@ -160,13 +165,13 @@ struct JetMatchingQA { registry.fill(HIST("h_jet_match_pt_Nconst"), pjet.tracksIds().size(), djet.tracksIds().size()); double pjet_pt_lead = 0.; - for (auto& mcparticle : pjet.template tracks_as()) { + for (auto& mcparticle : pjet.template tracks_as()) { if (mcparticle.pt() > pjet_pt_lead) { pjet_pt_lead = mcparticle.pt(); } } double djet_pt_lead = 0.; - for (auto& track : djet.template tracks_as>()) { + for (auto& track : djet.template tracks_as()) { if (track.pt() > djet_pt_lead) { djet_pt_lead = track.pt(); } @@ -177,7 +182,7 @@ struct JetMatchingQA { } PROCESS_SWITCH(JetMatchingQA, processMCD, "QA on detector-level jets", true); - void processMCP(aod::JMcCollision const& collision, + void processMCP(JetMcCollision const& collision, TagJetCollection const& pjets, BaseJetCollection const& djets) { for (const auto& pjet : pjets) { @@ -205,11 +210,6 @@ struct JetMatchingQA { } } PROCESS_SWITCH(JetMatchingQA, processMCP, "QA on generator-level jets", true); - - void processDummy(aod::JMcCollision const& mcCollision) - { - } - PROCESS_SWITCH(JetMatchingQA, processDummy, "Dummy process", true); }; using ChargedDetectorLevelJets = soa::Join; diff --git a/PWGJE/Tasks/jetsubstructure.cxx b/PWGJE/Tasks/jetsubstructure.cxx index 8ee01b215c4..e8626c764a5 100644 --- a/PWGJE/Tasks/jetsubstructure.cxx +++ b/PWGJE/Tasks/jetsubstructure.cxx @@ -21,6 +21,7 @@ #include "Framework/AnalysisDataModel.h" #include "Framework/ASoA.h" #include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/HistogramRegistry.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" @@ -38,9 +39,11 @@ using namespace o2::framework::expressions; #include "Framework/runDataProcessing.h" -template struct JetSubstructureTask { - Produces jetSubstructureTable; + Produces jetSubstructureDataTable; + Produces jetSubstructureMCDTable; + Produces jetSubstructureMCPTable; + Produces jetSubstructureDataSubTable; OutputObj hZg{"h_jet_zg_jet_pt"}; OutputObj hRg{"h_jet_rg_jet_pt"}; OutputObj hNsd{"h_jet_nsd_jet_pt"}; @@ -53,21 +56,28 @@ struct JetSubstructureTask { std::vector jetReclustered; JetFinder jetReclusterer; + HistogramRegistry registry; + void init(InitContext const&) { - hZg.setObject(new TH2F("h_jet_zg_jet_pt", ";z_{g}; #it{p}_{T,jet} (GeV/#it{c})", - 10, 0.0, 0.5, 200, 0.0, 200.0)); - hRg.setObject(new TH2F("h_jet_rg_jet_pt", ";R_{g}; #it{p}_{T,jet} (GeV/#it{c})", - 10, 0.0, 0.5, 200, 0.0, 200.0)); - hNsd.setObject(new TH2F("h_jet_nsd_jet_pt", ";n_{SD}; #it{p}_{T,jet} (GeV/#it{c})", - 7, -0.5, 6.5, 200, 0.0, 200.0)); + registry.add("h_jet_pt_jet_zg", ";#it{p}_{T,jet} (GeV/#it{c});#it{z}_{g}", {HistType::kTH2F, {{200, 0., 200.}, {22, 0.0, 1.1}}}); + registry.add("h_jet_pt_jet_rg", ";#it{p}_{T,jet} (GeV/#it{c});#it{R}_{g}", {HistType::kTH2F, {{200, 0., 200.}, {22, 0.0, 1.1}}}); + registry.add("h_jet_pt_jet_nsd", ";#it{p}_{T,jet} (GeV/#it{c});#it{n}_{SD}", {HistType::kTH2F, {{200, 0., 200.}, {10, -0.5, 9.5}}}); + + registry.add("h_jet_pt_part_jet_zg_part", ";#it{p}_{T,jet}^{part} (GeV/#it{c});#it{z}_{g}^{part}", {HistType::kTH2F, {{200, 0., 200.}, {22, 0.0, 1.1}}}); + registry.add("h_jet_pt_part_jet_rg_part", ";#it{p}_{T,jet}^{part} (GeV/#it{c});#it{R}_{g}^{part}", {HistType::kTH2F, {{200, 0., 200.}, {22, 0.0, 1.1}}}); + registry.add("h_jet_pt_part_jet_nsd_part", ";#it{p}_{T,jet}^{part} (GeV/#it{c});#it{n}_{SD}^{part}", {HistType::kTH2F, {{200, 0., 200.}, {10, -0.5, 9.5}}}); + + registry.add("h_jet_pt_jet_zg_eventwiseconstituentsubtracted", ";#it{p}_{T,jet} (GeV/#it{c});#it{z}_{g}", {HistType::kTH2F, {{200, 0., 200.}, {22, 0.0, 1.1}}}); + registry.add("h_jet_pt_jet_rg_eventwiseconstituentsubtracted", ";#it{p}_{T,jet} (GeV/#it{c});#it{R}_{g}", {HistType::kTH2F, {{200, 0., 200.}, {22, 0.0, 1.1}}}); + registry.add("h_jet_pt_jet_nsd_eventwiseconstituentsubtracted", ";#it{p}_{T,jet} (GeV/#it{c});#it{n}_{SD}", {HistType::kTH2F, {{200, 0., 200.}, {10, -0.5, 9.5}}}); jetReclusterer.isReclustering = true; jetReclusterer.algorithm = fastjet::JetAlgorithm::cambridge_algorithm; } - template - void jetReclustering(T const& jet) + template + void jetReclustering(T const& jet, U& outputTable) { jetReclustered.clear(); fastjet::ClusterSequenceArea clusterSeq(jetReclusterer.findJets(jetConstituents, jetReclustered)); @@ -79,74 +89,107 @@ struct JetSubstructureTask { auto nsd = 0.0; auto zg = -1.0; auto rg = -1.0; + std::vector energyMotherVec; + std::vector ptLeadingVec; + std::vector ptSubLeadingVec; + std::vector thetaVec; + while (daughterSubJet.has_parents(parentSubJet1, parentSubJet2)) { if (parentSubJet1.perp() < parentSubJet2.perp()) { std::swap(parentSubJet1, parentSubJet2); } auto z = parentSubJet2.perp() / (parentSubJet1.perp() + parentSubJet2.perp()); auto theta = parentSubJet1.delta_R(parentSubJet2); + energyMotherVec.push_back(daughterSubJet.e()); + ptLeadingVec.push_back(parentSubJet1.pt()); + ptSubLeadingVec.push_back(parentSubJet2.pt()); + thetaVec.push_back(theta); + if (z >= zCut * TMath::Power(theta / (jet.r() / 100.f), beta)) { if (!softDropped) { zg = z; rg = theta; - hZg->Fill(zg, jet.pt()); - hRg->Fill(rg, jet.pt()); + if constexpr (!isSubtracted && !isMCP) { + registry.fill(HIST("h_jet_pt_jet_zg"), jet.pt(), zg); + registry.fill(HIST("h_jet_pt_jet_rg"), jet.pt(), rg); + } + if constexpr (!isSubtracted && isMCP) { + registry.fill(HIST("h_jet_pt_part_jet_zg_part"), jet.pt(), zg); + registry.fill(HIST("h_jet_pt_part_jet_rg_part"), jet.pt(), rg); + } + if constexpr (isSubtracted && !isMCP) { + registry.fill(HIST("h_jet_pt_jet_zg_eventwiseconstituentsubtracted"), jet.pt(), zg); + registry.fill(HIST("h_jet_pt_jet_rg_eventwiseconstituentsubtracted"), jet.pt(), rg); + } softDropped = true; } nsd++; } daughterSubJet = parentSubJet1; } - hNsd->Fill(nsd, jet.pt()); - jetSubstructureTable(zg, rg, nsd); + if constexpr (!isSubtracted && !isMCP) { + registry.fill(HIST("h_jet_pt_jet_nsd"), jet.pt(), nsd); + } + if constexpr (!isSubtracted && isMCP) { + registry.fill(HIST("h_jet_pt_part_jet_nsd_part"), jet.pt(), nsd); + } + if constexpr (isSubtracted && !isMCP) { + registry.fill(HIST("h_jet_pt_jet_nsd_eventwiseconstituentsubtracted"), jet.pt(), nsd); + } + outputTable(energyMotherVec, ptLeadingVec, ptSubLeadingVec, thetaVec); + } + + template + void analyseCharged(T const& jet, U const& tracks, V& outputTable) + { + jetConstituents.clear(); + for (auto& jetConstituent : jet.template tracks_as()) { + fastjetutilities::fillTracks(jetConstituent, jetConstituents, jetConstituent.globalIndex()); + } + jetReclustering(jet, outputTable); } - void processDummy(aod::JTracks const& track) + void processDummy(JetTracks const& tracks) { } PROCESS_SWITCH(JetSubstructureTask, processDummy, "Dummy process function turned on by default", true); - void processChargedJets(typename JetTable::iterator const& jet, - aod::JTracks const& tracks) + void processChargedJetsData(soa::Join::iterator const& jet, + JetTracks const& tracks) { - jetConstituents.clear(); - for (auto& jetConstituent : jet.template tracks_as()) { - FastJetUtilities::fillTracks(jetConstituent, jetConstituents, jetConstituent.globalIndex()); - } - jetReclustering(jet); + analyseCharged(jet, tracks, jetSubstructureDataTable); + } + PROCESS_SWITCH(JetSubstructureTask, processChargedJetsData, "charged jet substructure", false); + + void processChargedJetsEventWiseSubData(soa::Join::iterator const& jet, + JetTracksSub const& tracks) + { + analyseCharged(jet, tracks, jetSubstructureDataSubTable); } - PROCESS_SWITCH(JetSubstructureTask, processChargedJets, "charged jet substructure", false); + PROCESS_SWITCH(JetSubstructureTask, processChargedJetsEventWiseSubData, "eventwise-constituent subtracted charged jet substructure", false); - void processChargedJetsMCP(typename JetTableMCP::iterator const& jet, - aod::JMcParticles const& particles) + void processChargedJetsMCD(typename soa::Join::iterator const& jet, + JetTracks const& tracks) + { + analyseCharged(jet, tracks, jetSubstructureMCDTable); + } + PROCESS_SWITCH(JetSubstructureTask, processChargedJetsMCD, "charged jet substructure", false); + + void processChargedJetsMCP(typename soa::Join::iterator const& jet, + JetParticles const& particles) { jetConstituents.clear(); - for (auto& jetConstituent : jet.template tracks_as()) { - FastJetUtilities::fillTracks(jetConstituent, jetConstituents, jetConstituent.globalIndex(), static_cast(JetConstituentStatus::track), pdg->Mass(jetConstituent.pdgCode())); + for (auto& jetConstituent : jet.template tracks_as()) { + fastjetutilities::fillTracks(jetConstituent, jetConstituents, jetConstituent.globalIndex(), static_cast(JetConstituentStatus::track), pdg->Mass(jetConstituent.pdgCode())); } - jetReclustering(jet); + jetReclustering(jet, jetSubstructureMCPTable); } PROCESS_SWITCH(JetSubstructureTask, processChargedJetsMCP, "charged jet substructure on MC particle level", false); }; -using JetSubstructureDataLevel = JetSubstructureTask, soa::Join, o2::aod::ChargedJetSubstructures>; -using JetSubstructureMCDetectorLevel = JetSubstructureTask, soa::Join, o2::aod::ChargedMCDetectorLevelJetSubstructures>; -using JetSubstructureMCParticleLevel = JetSubstructureTask, soa::Join, o2::aod::ChargedMCParticleLevelJetSubstructures>; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - std::vector tasks; - - tasks.emplace_back(adaptAnalysisTask(cfgc, - SetDefaultProcesses{}, - TaskName{"jet-substructure-data"})); - - tasks.emplace_back(adaptAnalysisTask(cfgc, - SetDefaultProcesses{}, - TaskName{"jet-substructure-mcd"})); - - tasks.emplace_back(adaptAnalysisTask(cfgc, - SetDefaultProcesses{}, - TaskName{"jet-substructure-mcp"})); - return WorkflowSpec{tasks}; + return WorkflowSpec{adaptAnalysisTask( + cfgc, TaskName{"jet-substructure"})}; } diff --git a/PWGJE/Tasks/jetsubstructurehf.cxx b/PWGJE/Tasks/jetsubstructurehf.cxx index c7fc671bda9..dacbb44cd8d 100644 --- a/PWGJE/Tasks/jetsubstructurehf.cxx +++ b/PWGJE/Tasks/jetsubstructurehf.cxx @@ -22,6 +22,7 @@ #include "Framework/AnalysisDataModel.h" #include "Framework/ASoA.h" #include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/HistogramRegistry.h" #include "Common/Core/TrackSelection.h" #include "Common/Core/TrackSelectionDefaults.h" @@ -35,6 +36,7 @@ #include "PWGJE/DataModel/JetSubstructure.h" #include "PWGJE/Core/JetFinder.h" #include "PWGJE/Core/FastJetUtilities.h" +#include "PWGJE/Core/JetHFUtilities.h" using namespace o2; using namespace o2::framework; @@ -43,9 +45,12 @@ using namespace o2::framework::expressions; // NB: runDataProcessing.h must be included after customize! #include "Framework/runDataProcessing.h" -template +template struct JetSubstructureHFTask { - Produces jetSubstructurehfTable; + Produces jetSubstructureDataTable; + Produces jetSubstructureMCDTable; + Produces jetSubstructureMCPTable; + Produces jetSubstructureDataSubTable; OutputObj hZg{"h_jet_zg_jet_pt"}; OutputObj hRg{"h_jet_rg_jet_pt"}; OutputObj hNsd{"h_jet_nsd_jet_pt"}; @@ -55,37 +60,35 @@ struct JetSubstructureHFTask { Configurable beta{"beta", 0.0, "soft drop beta"}; Service pdg; - int candPDG; + int candMass; std::vector jetConstituents; std::vector jetReclustered; JetFinder jetReclusterer; + HistogramRegistry registry; void init(InitContext const&) { - hZg.setObject(new TH2F("h_jet_zg_jet_pt", ";z_{g}; #it{p}_{T,jet} (GeV/#it{c})", - 10, 0.0, 0.5, 200, 0.0, 200.0)); - hRg.setObject(new TH2F("h_jet_rg_jet_pt", ";R_{g}; #it{p}_{T,jet} (GeV/#it{c})", - 10, 0.0, 0.5, 200, 0.0, 200.0)); - hNsd.setObject(new TH2F("h_jet_nsd_jet_pt", ";n_{SD}; #it{p}_{T,jet} (GeV/#it{c})", - 7, -0.5, 6.5, 200, 0.0, 200.0)); + registry.add("h_jet_pt_jet_zg", ";#it{p}_{T,jet} (GeV/#it{c});#it{z}_{g}", {HistType::kTH2F, {{200, 0., 200.}, {22, 0.0, 1.1}}}); + registry.add("h_jet_pt_jet_rg", ";#it{p}_{T,jet} (GeV/#it{c});#it{R}_{g}", {HistType::kTH2F, {{200, 0., 200.}, {22, 0.0, 1.1}}}); + registry.add("h_jet_pt_jet_nsd", ";#it{p}_{T,jet} (GeV/#it{c});#it{n}_{SD}", {HistType::kTH2F, {{200, 0., 200.}, {10, -0.5, 9.5}}}); + + registry.add("h_jet_pt_part_jet_zg_part", ";#it{p}_{T,jet}^{part} (GeV/#it{c});#it{z}_{g}^{part}", {HistType::kTH2F, {{200, 0., 200.}, {22, 0.0, 1.1}}}); + registry.add("h_jet_pt_part_jet_rg_part", ";#it{p}_{T,jet}^{part} (GeV/#it{c});#it{R}_{g}^{part}", {HistType::kTH2F, {{200, 0., 200.}, {22, 0.0, 1.1}}}); + registry.add("h_jet_pt_part_jet_nsd_part", ";#it{p}_{T,jet}^{part} (GeV/#it{c});#it{n}_{SD}^{part}", {HistType::kTH2F, {{200, 0., 200.}, {10, -0.5, 9.5}}}); + + registry.add("h_jet_pt_jet_zg_eventwiseconstituentsubtracted", ";#it{p}_{T,jet} (GeV/#it{c});#it{z}_{g}", {HistType::kTH2F, {{200, 0., 200.}, {22, 0.0, 1.1}}}); + registry.add("h_jet_pt_jet_rg_eventwiseconstituentsubtracted", ";#it{p}_{T,jet} (GeV/#it{c});#it{R}_{g}", {HistType::kTH2F, {{200, 0., 200.}, {22, 0.0, 1.1}}}); + registry.add("h_jet_pt_jet_nsd_eventwiseconstituentsubtracted", ";#it{p}_{T,jet} (GeV/#it{c});#it{n}_{SD}", {HistType::kTH2F, {{200, 0., 200.}, {10, -0.5, 9.5}}}); jetReclusterer.isReclustering = true; jetReclusterer.algorithm = fastjet::JetAlgorithm::cambridge_algorithm; - if constexpr (std::is_same_v, soa::Join>) { - candPDG = static_cast(o2::constants::physics::Pdg::kD0); - } - if constexpr (std::is_same_v, soa::Join>) { - candPDG = static_cast(o2::constants::physics::Pdg::kBPlus); - } - if constexpr (std::is_same_v, soa::Join>) { - candPDG = static_cast(o2::constants::physics::Pdg::kLambdaCPlus); - } + candMass = jethfutilities::getTablePDGMass(); } - template - void jetReclustering(T const& jet) + template + void jetReclustering(T const& jet, U& outputTable) { jetReclustered.clear(); fastjet::ClusterSequenceArea clusterSeq(jetReclusterer.findJets(jetConstituents, jetReclustered)); @@ -97,84 +100,123 @@ struct JetSubstructureHFTask { auto nsd = 0.0; auto zg = -1.0; auto rg = -1.0; + std::vector energyMotherVec; + std::vector ptLeadingVec; + std::vector ptSubLeadingVec; + std::vector thetaVec; while (daughterSubJet.has_parents(parentSubJet1, parentSubJet2)) { - if (parentSubJet1.perp() < parentSubJet2.perp()) { + + bool isHFInSubjet1 = false; + for (auto& subjet1Constituent : parentSubJet1.constituents()) { + if (subjet1Constituent.template user_info().getStatus() == static_cast(JetConstituentStatus::candidateHF)) { + isHFInSubjet1 = true; + break; + } + } + if (!isHFInSubjet1) { std::swap(parentSubJet1, parentSubJet2); } auto z = parentSubJet2.perp() / (parentSubJet1.perp() + parentSubJet2.perp()); auto theta = parentSubJet1.delta_R(parentSubJet2); + energyMotherVec.push_back(daughterSubJet.e()); + ptLeadingVec.push_back(parentSubJet1.pt()); + ptSubLeadingVec.push_back(parentSubJet2.pt()); + thetaVec.push_back(theta); if (z >= zCut * TMath::Power(theta / (jet.r() / 100.f), beta)) { if (!softDropped) { zg = z; rg = theta; - hZg->Fill(zg, jet.pt()); - hRg->Fill(rg, jet.pt()); + if constexpr (!isSubtracted && !isMCP) { + registry.fill(HIST("h_jet_pt_jet_zg"), jet.pt(), zg); + registry.fill(HIST("h_jet_pt_jet_rg"), jet.pt(), rg); + } + if constexpr (!isSubtracted && isMCP) { + registry.fill(HIST("h_jet_pt_part_jet_zg_part"), jet.pt(), zg); + registry.fill(HIST("h_jet_pt_part_jet_rg_part"), jet.pt(), rg); + } + if constexpr (isSubtracted && !isMCP) { + registry.fill(HIST("h_jet_pt_jet_zg_eventwiseconstituentsubtracted"), jet.pt(), zg); + registry.fill(HIST("h_jet_pt_jet_rg_eventwiseconstituentsubtracted"), jet.pt(), rg); + } softDropped = true; } nsd++; } - bool isHFInSubjet1 = false; - for (auto& subjet1Constituent : parentSubJet1.constituents()) { - if (subjet1Constituent.template user_info().getStatus() == static_cast(JetConstituentStatus::candidateHF)) { - isHFInSubjet1 = true; - break; - } - } - if (isHFInSubjet1) { - daughterSubJet = parentSubJet1; - } else { - daughterSubJet = parentSubJet2; - } + daughterSubJet = parentSubJet1; + } + if constexpr (!isSubtracted && !isMCP) { + registry.fill(HIST("h_jet_pt_jet_nsd"), jet.pt(), nsd); + } + if constexpr (!isSubtracted && isMCP) { + registry.fill(HIST("h_jet_pt_part_jet_nsd_part"), jet.pt(), nsd); } - hNsd->Fill(nsd, jet.pt()); - jetSubstructurehfTable(zg, rg, nsd); + if constexpr (isSubtracted && !isMCP) { + registry.fill(HIST("h_jet_pt_jet_nsd_eventwiseconstituentsubtracted"), jet.pt(), nsd); + } + outputTable(energyMotherVec, ptLeadingVec, ptSubLeadingVec, thetaVec); } - void processDummy(aod::JTracks const& track) + template + void analyseCharged(T const& jet, U const& tracks, V const& candidates, M& outputTable) { - } - PROCESS_SWITCH(JetSubstructureHFTask, processDummy, "Dummy process function turned on by default", true); - void processChargedJetsHF(typename JetTable::iterator const& jet, - CandidateTable const& candidates, - aod::JTracks const& tracks) - { jetConstituents.clear(); - for (auto& jetConstituent : jet.template tracks_as()) { - FastJetUtilities::fillTracks(jetConstituent, jetConstituents, jetConstituent.globalIndex()); + for (auto& jetConstituent : jet.template tracks_as()) { + fastjetutilities::fillTracks(jetConstituent, jetConstituents, jetConstituent.globalIndex()); } - for (auto& jetHFCandidate : jet.template hfcandidates_as()) { // should only be one at the moment - FastJetUtilities::fillTracks(jetHFCandidate, jetConstituents, jetHFCandidate.globalIndex(), static_cast(JetConstituentStatus::candidateHF), pdg->Mass(candPDG)); + for (auto& jetHFCandidate : jet.template hfcandidates_as()) { // should only be one at the moment + fastjetutilities::fillTracks(jetHFCandidate, jetConstituents, jetHFCandidate.globalIndex(), static_cast(JetConstituentStatus::candidateHF), candMass); } - jetReclustering(jet); + jetReclustering(jet, outputTable); + } + + void processDummy(JetTracks const& tracks) + { + } + PROCESS_SWITCH(JetSubstructureHFTask, processDummy, "Dummy process function turned on by default", true); + + void processChargedJetsData(typename JetTableData::iterator const& jet, + CandidateTable const& candidates, + JetTracks const& tracks) + { + analyseCharged(jet, tracks, candidates, jetSubstructureDataTable); } - PROCESS_SWITCH(JetSubstructureHFTask, processChargedJetsHF, "HF jet substructure", false); + PROCESS_SWITCH(JetSubstructureHFTask, processChargedJetsData, "HF jet substructure on data", false); - void processChargedJetsHFMCP(typename JetTableMCP::iterator const& jet, - aod::JMcParticles const& particles) + void processChargedJetsDataSub(typename JetTableDataSub::iterator const& jet, + CandidateTable const& candidates, + TracksSub const& tracks) + { + analyseCharged(jet, tracks, candidates, jetSubstructureDataSubTable); + } + PROCESS_SWITCH(JetSubstructureHFTask, processChargedJetsDataSub, "HF jet substructure on data", false); + + void processChargedJetsMCD(typename JetTableMCD::iterator const& jet, + CandidateTable const& candidates, + JetTracks const& tracks) + { + analyseCharged(jet, tracks, candidates, jetSubstructureMCDTable); + } + PROCESS_SWITCH(JetSubstructureHFTask, processChargedJetsMCD, "HF jet substructure on data", false); + + void processChargedJetsMCP(typename JetTableMCP::iterator const& jet, + JetParticles const& particles, + CandidateTableMCP const& candidates) { jetConstituents.clear(); - for (auto& jetConstituent : jet.template tracks_as()) { - FastJetUtilities::fillTracks(jetConstituent, jetConstituents, jetConstituent.globalIndex(), static_cast(JetConstituentStatus::track), pdg->Mass(jetConstituent.pdgCode())); + for (auto& jetConstituent : jet.template tracks_as()) { + fastjetutilities::fillTracks(jetConstituent, jetConstituents, jetConstituent.globalIndex(), static_cast(JetConstituentStatus::track), pdg->Mass(jetConstituent.pdgCode())); } - for (auto& jetHFCandidate : jet.template hfcandidates_as()) { // should only be one at the moment - FastJetUtilities::fillTracks(jetHFCandidate, jetConstituents, jetHFCandidate.globalIndex(), static_cast(JetConstituentStatus::candidateHF), pdg->Mass(jetHFCandidate.pdgCode())); + for (auto& jetHFCandidate : jet.template hfcandidates_as()) { + fastjetutilities::fillTracks(jetHFCandidate, jetConstituents, jetHFCandidate.globalIndex(), static_cast(JetConstituentStatus::candidateHF), candMass); } - jetReclustering(jet); + jetReclustering(jet, jetSubstructureMCPTable); } - PROCESS_SWITCH(JetSubstructureHFTask, processChargedJetsHFMCP, "HF jet substructure on MC particle level", false); + PROCESS_SWITCH(JetSubstructureHFTask, processChargedJetsMCP, "HF jet substructure on MC particle level", false); }; -using JetSubstructureD0 = JetSubstructureHFTask, soa::Join, soa::Join, o2::aod::D0ChargedJetSubstructures>; -using MCDetectorLevelJetSubstructureD0 = JetSubstructureHFTask, soa::Join, soa::Join, o2::aod::D0ChargedMCDetectorLevelJetSubstructures>; -using MCParticleLevelJetSubstructureD0 = JetSubstructureHFTask, soa::Join, soa::Join, o2::aod::D0ChargedMCParticleLevelJetSubstructures>; - -// using JetSubstructureBplus = JetSubstructureHFTask,soa::Join,soa::Join,o2::aod::BplusChargedJetSubstructures>; -// using MCDetectorLevelJetSubstructureBplus = JetSubstructureHFTask,soa::Join,soa::Join,o2::aod::BplusChargedMCDetectorLevelJetSubstructures>; -// using MCParticleLevelJetSubstructureBplus = JetSubstructureHFTask,soa::Join,soa::Join,o2::aod::BplusChargedMCParticleLevelJetSubstructures>; - -// using JetSubstructureLc = JetSubstructureHFTask, soa::Join, soa::Join, o2::aod::LcChargedJetSubstructures>; -// using MCDetectorLevelJetSubstructureLc = JetSubstructureHFTask,soa::Join,soa::Join,o2::aod::LcChargedMCDetectorLevelJetSubstructures>; -// using MCParticleLevelJetSubstructureLc = JetSubstructureHFTask,soa::Join,soa::Join,o2::aod::LcChargedMCParticleLevelJetSubstructures>; +using JetSubstructureD0 = JetSubstructureHFTask, soa::Join, soa::Join, soa::Join, CandidatesD0Data, CandidatesD0MCP, aod::D0ChargedJetSubstructures, aod::D0ChargedMCDetectorLevelJetSubstructures, aod::D0ChargedMCParticleLevelJetSubstructures, aod::D0ChargedEventWiseSubtractedJetSubstructures, aod::JTrackD0Subs>; +// using JetSubstructureLc = JetSubstructureHFTask,soa::Join,soa::Join,soa::Join, CandidatesLcData, CandidatesLcMCP, aod::LcChargedJetSubstructures,aod::LcChargedMCDetectorLevelJetSubstructures,aod::LcChargedMCParticleLevelJetSubstructures, aod::LcChargedEventWiseSubtractedJetSubstructures, aod::JTrackLcSubs>; +// using JetSubstructureBplus = JetSubstructureHFTask,soa::Join,soa::Join,soa::Join, CandidatesBplusData, CandidatesBplusMCP, aod::BplusChargedJetSubstructures,aod::BplusChargedMCDetectorLevelJetSubstructures,aod::BplusChargedMCParticleLevelJetSubstructures, aod::BplusChargedEventWiseSubtractedJetSubstructures, aod::JTrackBplusSubs>; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { @@ -182,39 +224,15 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) tasks.emplace_back(adaptAnalysisTask(cfgc, SetDefaultProcesses{}, - TaskName{"jet-substructure-D0-data"})); - - tasks.emplace_back(adaptAnalysisTask(cfgc, - SetDefaultProcesses{}, - TaskName{"jet-substructure-D0-mcd"})); - - tasks.emplace_back(adaptAnalysisTask(cfgc, - SetDefaultProcesses{}, - TaskName{"jet-substructure-D0-mcp"})); - /* - tasks.emplace_back(adaptAnalysisTask(cfgc, - SetDefaultProcesses{}, - TaskName{"jet-substructure-Lc-data"})); - - tasks.emplace_back(adaptAnalysisTask(cfgc, - SetDefaultProcesses{}, - TaskName{"jet-substructure-Lc-mcd"})); - - tasks.emplace_back(adaptAnalysisTask(cfgc, - SetDefaultProcesses{}, - TaskName{"jet-substructure-Lc-mcp"})); - - tasks.emplace_back(adaptAnalysisTask(cfgc, - SetDefaultProcesses{}, - TaskName{"jet-substructure-Bplus-data"})); - - tasks.emplace_back(adaptAnalysisTask(cfgc, - SetDefaultProcesses{}, - TaskName{"jet-substructure-Bplus-mcd"})); - - tasks.emplace_back(adaptAnalysisTask(cfgc, - SetDefaultProcesses{}, - TaskName{"jet-substructure-Bplus-mcp"})); - */ - return WorkflowSpec{tasks}; + TaskName{"jet-substructure-D0"})); + /* + tasks.emplace_back(adaptAnalysisTask(cfgc, + SetDefaultProcesses{}, + TaskName{"jet-substructure-Lc"})); + + tasks.emplace_back(adaptAnalysisTask(cfgc, + SetDefaultProcesses{}, + TaskName{"jet-substructure-Bplus"})); + */ + return WorkflowSpec{tasks}; } diff --git a/PWGJE/Tasks/jetsubstructurehfoutput.cxx b/PWGJE/Tasks/jetsubstructurehfoutput.cxx index 98accfaa77c..8a2b44c1b4f 100644 --- a/PWGJE/Tasks/jetsubstructurehfoutput.cxx +++ b/PWGJE/Tasks/jetsubstructurehfoutput.cxx @@ -31,6 +31,7 @@ #include "PWGJE/DataModel/Jet.h" #include "PWGJE/DataModel/JetSubstructure.h" #include "PWGJE/Core/JetFinder.h" +#include "PWGJE/Core/JetFindingUtilities.h" using namespace o2; using namespace o2::framework; @@ -39,17 +40,38 @@ using namespace o2::framework::expressions; // NB: runDataProcessing.h must be included after customize! #include "Framework/runDataProcessing.h" -template +template struct JetSubstructureHFOutputTask { + Produces collisionOutputTableData; Produces jetOutputTableData; Produces jetSubstructureOutputTableData; + Produces collisionOutputTableDataSub; + Produces jetOutputTableDataSub; + Produces jetSubstructureOutputTableDataSub; + Produces collisionOutputTableMCD; Produces jetOutputTableMCD; Produces jetSubstructureOutputTableMCD; + Produces collisionOutputTableMCP; Produces jetOutputTableMCP; Produces jetSubstructureOutputTableMCP; + Produces hfCollisionsTable; + Produces candidateTable; + Produces candidateParsTable; + Produces candidateParExtrasTable; + Produces candidateSelsTable; + Produces candidateMcsTable; + Produces hfParticlesTable; Configurable jetPtMin{"jetPtMin", 0.0, "minimum jet pT cut"}; Configurable> jetRadii{"jetRadii", std::vector{0.4}, "jet resolution parameters"}; + Configurable jetEtaMin{"jetEtaMin", -99.0, "minimum jet pseudorapidity"}; + Configurable jetEtaMax{"jetEtaMax", 99.0, "maximum jet pseudorapidity"}; + + Configurable trackEtaMin{"trackEtaMin", -0.9, "minimum track pseudorapidity"}; + Configurable trackEtaMax{"trackEtaMax", 0.9, "maximum track pseudorapidity"}; + + std::map candidateMapping; + std::map candidateCollisionMapping; std::vector jetRadiiValues; @@ -61,97 +83,223 @@ struct JetSubstructureHFOutputTask { Filter jetSelection = aod::jet::pt >= jetPtMin; template - void fillTables(T const& collision, U const& jet, V const& cand, M& jetOutputTable, N& jetSubstructureOutputTable, std::vector geoMatching, std::vector ptMatching, std::vector candMatching) + void fillTables(T const& jet, U const& cand, int32_t collisionIndex, int32_t candidateIndex, V& collisionOutputTable, M& jetOutputTable, N& jetSubstructureOutputTable, std::vector geoMatching, std::vector ptMatching, std::vector candMatching) { - jetOutputTable(collision.globalIndex(), jet.globalIndex(), cand.globalIndex(), geoMatching, ptMatching, candMatching, jet.pt(), jet.phi(), jet.eta(), jet.r(), jet.tracks().size() + jet.hfcandidates().size()); - jetSubstructureOutputTable(jet.globalIndex(), jet.zg(), jet.rg(), jet.nsd()); + std::vector energyMotherVec; + std::vector ptLeadingVec; + std::vector ptSubLeadingVec; + std::vector thetaVec; + auto energyMotherSpan = jet.energyMother(); + auto ptLeadingSpan = jet.ptLeading(); + auto ptSubLeadingSpan = jet.ptSubLeading(); + auto thetaSpan = jet.theta(); + std::copy(energyMotherSpan.begin(), energyMotherSpan.end(), std::back_inserter(energyMotherVec)); + std::copy(ptLeadingSpan.begin(), ptLeadingSpan.end(), std::back_inserter(ptLeadingVec)); + std::copy(ptSubLeadingSpan.begin(), ptSubLeadingSpan.end(), std::back_inserter(ptSubLeadingVec)); + std::copy(thetaSpan.begin(), thetaSpan.end(), std::back_inserter(thetaVec)); + jetOutputTable(collisionIndex, candidateIndex, geoMatching, ptMatching, candMatching, jet.pt(), jet.phi(), jet.eta(), jet.r(), jet.tracks().size() + jet.hfcandidates().size()); // here we take the decision to keep the collision index consistent with the JE framework in case it is later needed to join to other tables. The candidate Index however can be linked to the HF tables + jetSubstructureOutputTable(jetOutputTable.lastIndex(), energyMotherVec, ptLeadingVec, ptSubLeadingVec, thetaVec); } - void processDummy(aod::JCollision const& collision) {} - PROCESS_SWITCH(JetSubstructureHFOutputTask, processDummy, "Dummy process function turned on by default", true); - - void processOutputData(aod::JCollision const& collision, - JetTableData const& jets, - aod::JTracks const& tracks, - CandidateTableData const& candidates) + template + void analyseCharged(T const& collision, U const& jets, V const& jetsTag, M const& tracks, N const& candidates, O& collisionOutputTable, P& jetOutputTable, S& jetSubstructureOutputTable) { - std::vector geoMatching{-1}; - std::vector ptMatching{-1}; - std::vector candMatching{-1}; + + int nJetInCollision = 0; + int32_t collisionIndex = -1; for (const auto& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } for (const auto& jetRadiiValue : jetRadiiValues) { if (jet.r() == round(jetRadiiValue * 100.0f)) { - auto cands = jet.template hfcandidates_as(); - auto cand = cands[0]; - fillTables(collision, jet, cand, jetOutputTableData, jetSubstructureOutputTableData, geoMatching, ptMatching, candMatching); + auto candidate = jet.template hfcandidates_first_as(); + std::vector geoMatching; + std::vector ptMatching; + std::vector hfMatching; + if constexpr (isMatched) { + if (jet.has_matchedJetGeo()) { + for (auto& jetTag : jet.template matchedJetGeo_as()) { + geoMatching.push_back(jetTag.globalIndex()); + } + } + if (jet.has_matchedJetPt()) { + for (auto& jetTag : jet.template matchedJetPt_as()) { + ptMatching.push_back(jetTag.globalIndex()); + } + } + if (jet.has_matchedJetCand()) { + for (auto& jetTag : jet.template matchedJetCand_as()) { + hfMatching.push_back(jetTag.globalIndex()); + } + } + } + int32_t candidateIndex = -1; + auto candidateTableIndex = candidateMapping.find(candidate.globalIndex()); + if (candidateTableIndex != candidateMapping.end()) { + candidateIndex = candidateTableIndex->second; + } + + if (nJetInCollision == 0) { + collisionOutputTable(collision.posZ(), collision.centrality(), collision.eventSel()); + collisionIndex = collisionOutputTable.lastIndex(); + } + nJetInCollision++; + fillTables(jet, candidate, collisionIndex, candidateIndex, collisionOutputTable, jetOutputTable, jetSubstructureOutputTable, geoMatching, ptMatching, hfMatching); } } } } - PROCESS_SWITCH(JetSubstructureHFOutputTask, processOutputData, "hf jet substructure output Data", false); - void processOutputMCD(aod::JCollision const& collision, - JetTableMCD const& mcdjets, - JetTableMCP const& mcpjets, - aod::JTracks const& tracks, - CandidateTableMCD const& candidates) + template + void analyseCandidates(T const& jets, U const& candidateCollisions, V const& candidates) { - for (const auto& mcdjet : mcdjets) { + + int nJetInCollision = 0; + int32_t candidateCollisionIndex = -1; + for (const auto& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } for (const auto& jetRadiiValue : jetRadiiValues) { - if (mcdjet.r() == round(jetRadiiValue * 100.0f)) { - auto cands = mcdjet.template hfcandidates_as(); - auto cand = cands[0]; - std::vector geoMatching; - std::vector ptMatching; - std::vector candMatching; - for (auto& mcpjet : mcdjet.template matchedJetGeo_as()) { - geoMatching.push_back(mcpjet.globalIndex()); - } - for (auto& mcpjet : mcdjet.template matchedJetPt_as()) { - ptMatching.push_back(mcpjet.globalIndex()); + if (jet.r() == round(jetRadiiValue * 100.0f)) { + + auto candidate = jet.template hfcandidates_first_as(); + + auto candidateTableIndex = candidateMapping.find(candidate.globalIndex()); + if (candidateTableIndex != candidateMapping.end()) { + continue; } - for (auto& mcpjet : mcdjet.template matchedJetCand_as()) { - candMatching.push_back(mcpjet.globalIndex()); + + auto candidateCollision = jethfutilities::getCandidateCollision(candidate, candidateCollisions); + if (nJetInCollision == 0) { + auto candidateCollisionTableIndex = candidateCollisionMapping.find(candidateCollision.globalIndex()); + if (candidateCollisionTableIndex == candidateCollisionMapping.end()) { + jethfutilities::fillHFCollisionTable(candidateCollision, candidates, hfCollisionsTable, candidateCollisionIndex); + candidateCollisionMapping.insert(std::make_pair(candidateCollision.globalIndex(), candidateCollisionIndex)); + } else { + candidateCollisionIndex = candidateCollisionTableIndex->second; + } } - fillTables(collision, mcdjet, cand, jetOutputTableMCD, jetSubstructureOutputTableMCD, geoMatching, ptMatching, candMatching); + nJetInCollision++; + int32_t candidateIndex = -1; + jethfutilities::fillCandidateTable(candidate, candidateCollisionIndex, candidateTable, candidateParsTable, candidateParExtrasTable, candidateSelsTable, candidateMcsTable, candidateIndex); + candidateMapping.insert(std::make_pair(candidate.globalIndex(), candidateIndex)); } } } } + + void processDummy(JetCollisions const& collisions) {} + PROCESS_SWITCH(JetSubstructureHFOutputTask, processDummy, "Dummy process function turned on by default", true); + + void processOutputHFData(JetCollision const& collision, + JetTableData const& jets, + CandidateCollisionTable const& canidateCollisions, + CandidateTable const& candidates) + { + + analyseCandidates(jets, canidateCollisions, candidates); + } + PROCESS_SWITCH(JetSubstructureHFOutputTask, processOutputHFData, "hf output Data", false); + + void processOutputHFDataSub(JetCollision const& collision, + JetTableDataSub const& jets, + CandidateCollisionTable const& canidateCollisions, + CandidateTable const& candidates) + { + + analyseCandidates(jets, canidateCollisions, candidates); + } + PROCESS_SWITCH(JetSubstructureHFOutputTask, processOutputHFDataSub, "hf output Data eventwise constituent subtracted", false); + + void processOutputHFMCD(JetCollision const& collision, + JetTableMCD const& jets, + CandidateCollisionTable const& canidateCollisions, + CandidateTableMCD const& candidates) + { + + analyseCandidates(jets, canidateCollisions, candidates); + } + PROCESS_SWITCH(JetSubstructureHFOutputTask, processOutputHFMCD, "hf output MCD", false); + + void processOutputData(JetCollision const& collision, + JetTableData const& jets, + JetTracks const& tracks, + CandidateCollisionTable const& canidateCollisions, + CandidateTable const& candidates) + { + analyseCharged(collision, jets, jets, tracks, candidates, collisionOutputTableData, jetOutputTableData, jetSubstructureOutputTableData); + } + PROCESS_SWITCH(JetSubstructureHFOutputTask, processOutputData, "hf jet substructure output Data", false); + + void processOutputDataSub(JetCollision const& collision, + JetMatchedTableData const& jets, + JetTableDataSub const& jetsSub, + TracksSub const& tracks, + CandidateCollisionTable const& canidateCollisions, + CandidateTable const& candidates) + { + analyseCharged(collision, jets, jetsSub, tracks, candidates, collisionOutputTableData, jetOutputTableData, jetSubstructureOutputTableData); + analyseCharged(collision, jetsSub, jets, tracks, candidates, collisionOutputTableDataSub, jetOutputTableDataSub, jetSubstructureOutputTableDataSub); + } + PROCESS_SWITCH(JetSubstructureHFOutputTask, processOutputDataSub, "hf jet substructure output event-wise subtracted Data", false); + + void processOutputMCD(JetCollision const& collision, + JetTableMCD const& jets, + JetTableMCP const& jetsTag, + JetTracks const& tracks, + CandidateCollisionTable const& canidateCollisions, + CandidateTableMCD const& candidates) + { + analyseCharged(collision, jets, jetsTag, tracks, candidates, collisionOutputTableMCD, jetOutputTableMCD, jetSubstructureOutputTableMCD); + } PROCESS_SWITCH(JetSubstructureHFOutputTask, processOutputMCD, "hf jet substructure output MCD", false); - void processOutputMCP(aod::JMcCollision const& collision, - JetTableMCP const& mcpjets, - JetTableMCD const& mcdjets, - ParticleTable const& particles) + void processOutputMCP(JetMcCollision const& collision, + JetTableMCP const& jets, + JetTableMCD const& jetsTag, + JetParticles const& particles, + CandidateTableMCP const& candidates) { - for (const auto& mcpjet : mcpjets) { + for (const auto& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } for (const auto& jetRadiiValue : jetRadiiValues) { - if (mcpjet.r() == round(jetRadiiValue * 100.0f)) { - auto cands = mcpjet.template hfcandidates_as(); - auto cand = cands[0]; + if (jet.r() == round(jetRadiiValue * 100.0f)) { + auto candidate = jet.template hfcandidates_first_as(); std::vector geoMatching; std::vector ptMatching; - std::vector candMatching; - for (auto& mcdjet : mcpjet.template matchedJetGeo_as()) { - geoMatching.push_back(mcdjet.globalIndex()); + std::vector hfMatching; + if (jet.has_matchedJetGeo()) { + for (auto& jetTag : jet.template matchedJetGeo_as()) { + geoMatching.push_back(jetTag.globalIndex()); + } } - for (auto& mcdjet : mcpjet.template matchedJetPt_as()) { - ptMatching.push_back(mcdjet.globalIndex()); + if (jet.has_matchedJetPt()) { + for (auto& jetTag : jet.template matchedJetPt_as()) { + ptMatching.push_back(jetTag.globalIndex()); + } } - for (auto& mcdjet : mcpjet.template matchedJetCand_as()) { - candMatching.push_back(mcdjet.globalIndex()); + if (jet.has_matchedJetCand()) { + for (auto& jetTag : jet.template matchedJetCand_as()) { + hfMatching.push_back(jetTag.globalIndex()); + } } - fillTables(collision, mcpjet, cand, jetOutputTableMCP, jetSubstructureOutputTableMCP, geoMatching, ptMatching, candMatching); + int32_t candidateIndex = -1; + jethfutilities::fillCandidateMcTable(candidate, hfParticlesTable, candidateIndex); + + fillTables(jet, candidate, -1, candidateIndex, collisionOutputTableMCP, jetOutputTableMCP, jetSubstructureOutputTableMCP, geoMatching, ptMatching, hfMatching); } } } } PROCESS_SWITCH(JetSubstructureHFOutputTask, processOutputMCP, "hf jet substructure output MCP", false); }; -using JetSubstructureOutputD0 = JetSubstructureHFOutputTask, soa::Join, soa::Join, soa::Filtered>, aod::D0ChargedJetOutput, aod::D0ChargedJetSubstructureOutput, soa::Filtered>, aod::D0ChargedMCDetectorLevelJetOutput, aod::D0ChargedMCDetectorLevelJetSubstructureOutput, soa::Filtered>, aod::D0ChargedMCParticleLevelJetOutput, aod::D0ChargedMCParticleLevelJetSubstructureOutput>; -// using JetSubstructureOutputLc = JetSubstructureHFOutputTask, soa::Join, soa::Join, soa::Filtered>, aod::LcChargedJetOutput, aod::LcChargedJetSubstructureOutput,soa::Filtered>, aod::LcChargedMCDetectorLevelJetOutput, aod::LcChargedMCDetectorLevelJetSubstructureOutput, soa::Filtered>, aod::LcChargedMCParticleLevelJetOutput, aod::LcChargedMCParticleLevelJetSubstructureOutput>; -// using JetSubstructureOutputBplus = JetSubstructureHFOutputTask, soa::Join, soa::Join, soa::Filtered>, aod::BplusChargedJetOutput, aod::BplusChargedJetSubstructureOutput,soa::Filtered>, aod::BplusChargedMCDetectorLevelJetOutput, aod::BplusChargedMCDetectorLevelJetSubstructureOutput, soa::Filtered>, aod::BplusChargedMCParticleLevelJetOutput, aod::BplusChargedMCParticleLevelJetSubstructureOutput>; +using JetSubstructureOutputD0 = JetSubstructureHFOutputTask>, soa::Filtered>, aod::D0ChargedJetCollisionOutputs, aod::D0ChargedJetOutputs, aod::D0ChargedJetSubstructureOutputs, soa::Filtered>, aod::D0ChargedMCDetectorLevelJetCollisionOutputs, aod::D0ChargedMCDetectorLevelJetOutputs, aod::D0ChargedMCDetectorLevelJetSubstructureOutputs, soa::Filtered>, aod::D0ChargedMCParticleLevelJetCollisionOutputs, aod::D0ChargedMCParticleLevelJetOutputs, aod::D0ChargedMCParticleLevelJetSubstructureOutputs, soa::Filtered>, aod::D0ChargedEventWiseSubtractedJetCollisionOutputs, aod::D0ChargedEventWiseSubtractedJetOutputs, aod::D0ChargedEventWiseSubtractedJetSubstructureOutputs, aod::StoredHfD0CollBase, aod::StoredHfD0Bases, aod::StoredHfD0Pars, aod::StoredHfD0ParEs, aod::StoredHfD0Sels, aod::StoredHfD0Mcs, aod::StoredHfD0PBases>; +// using JetSubstructureOutputLc = JetSubstructureHFOutputTask>, soa::Filtered>, aod::LcChargedJetCollisionOutputs, aod::LcChargedJetOutputs, aod::LcChargedJetSubstructureOutputs, soa::Filtered>, aod::LcChargedMCDetectorLevelJetCollisionOutputs, aod::LcChargedMCDetectorLevelJetOutputs, aod::LcChargedMCDetectorLevelJetSubstructureOutputs, soa::Filtered>, aod::LcChargedMCParticleLevelJetCollisionOutputs, aod::LcChargedMCParticleLevelJetOutputs, aod::LcChargedMCParticleLevelJetSubstructureOutputs, soa::Filtered>, aod::LcChargedEventWiseSubtractedJetCollisionOutputs, aod::LcChargedEventWiseSubtractedJetOutputs, aod::LcChargedEventWiseSubtractedJetSubstructureOutputs, aod::StoredHfLcCollBase, aod::StoredHfLcBases, aod::StoredHfLcPars, aod::StoredHfLcParEs, aod::StoredHfLcSels, aod::StoredHfLcMcs, aod::StoredHfLcPBases>; +// using JetSubstructureOutputBplus = JetSubstructureHFOutputTask>, soa::Filtered>, aod::BplusChargedJetCollisionOutputs, aod::BplusChargedJetOutputs, aod::BplusChargedJetSubstructureOutputs, soa::Filtered>, aod::BplusChargedMCDetectorLevelJetCollisionOutputs, aod::BplusChargedMCDetectorLevelJetOutputs, aod::BplusChargedMCDetectorLevelJetSubstructureOutputs, soa::Filtered>, aod::BplusChargedMCParticleLevelJetCollisionOutputs, aod::BplusChargedMCParticleLevelJetOutputs, aod::BplusChargedMCParticleLevelJetSubstructureOutputs, soa::Filtered>, aod::BplusChargedEventWiseSubtractedJetCollisionOutputs, aod::BplusChargedEventWiseSubtractedJetOutputs, aod::BplusChargedEventWiseSubtractedJetSubstructureOutputs, aod::StoredHfBplusCollBase, aod::StoredHfBplusBases, aod::StoredHfBplusPars, aod::StoredHfBplusParEs, aod::StoredHfBplusSels, aod::StoredHfBplusMcs, aod::StoredHfBplusPBases>; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { diff --git a/PWGJE/Tasks/jetsubstructureoutput.cxx b/PWGJE/Tasks/jetsubstructureoutput.cxx index 397e66630c3..30313d70eee 100644 --- a/PWGJE/Tasks/jetsubstructureoutput.cxx +++ b/PWGJE/Tasks/jetsubstructureoutput.cxx @@ -26,6 +26,7 @@ #include "Common/DataModel/TrackSelectionTables.h" #include "PWGJE/Core/JetFinder.h" +#include "PWGJE/Core/JetFindingUtilities.h" #include "PWGJE/DataModel/Jet.h" #include "PWGJE/DataModel/JetSubstructure.h" @@ -36,17 +37,28 @@ using namespace o2::framework::expressions; // NB: runDataProcessing.h must be included after customize! #include "Framework/runDataProcessing.h" -template struct JetSubstructureOutputTask { - Produces jetOutputTableData; - Produces jetSubstructureOutputTableData; - Produces jetOutputTableMCD; - Produces jetSubstructureOutputTableMCD; - Produces jetOutputTableMCP; - Produces jetSubstructureOutputTableMCP; + + Produces collisionOutputTableData; + Produces jetOutputTableData; + Produces jetSubstructureOutputTableData; + Produces collisionOutputTableDataSub; + Produces jetOutputTableDataSub; + Produces jetSubstructureOutputTableDataSub; + Produces collisionOutputTableMCD; + Produces jetOutputTableMCD; + Produces jetSubstructureOutputTableMCD; + Produces collisionOutputTableMCP; + Produces jetOutputTableMCP; + Produces jetSubstructureOutputTableMCP; Configurable jetPtMin{"jetPtMin", 0.0, "minimum jet pT cut"}; Configurable> jetRadii{"jetRadii", std::vector{0.4}, "jet resolution parameters"}; + Configurable jetEtaMin{"jetEtaMin", -99.0, "minimum jet pseudorapidity"}; + Configurable jetEtaMax{"jetEtaMax", 99.0, "maximum jet pseudorapidity"}; + + Configurable trackEtaMin{"trackEtaMin", -0.9, "minimum track pseudorapidity"}; + Configurable trackEtaMax{"trackEtaMax", 0.9, "maximum track pseudorapidity"}; std::vector jetRadiiValues; @@ -58,87 +70,127 @@ struct JetSubstructureOutputTask { Filter jetSelection = aod::jet::pt >= jetPtMin; template - void fillTables(T const& collision, U const& jet, V& jetOutputTable, M& jetSubstructureOutputTable, std::vector geoMatching, std::vector ptMatching, std::vector candMatching) + void fillTables(T const& jet, int32_t collisionIndex, U& collisionOutputTable, V& jetOutputTable, M& jetSubstructureOutputTable, std::vector geoMatching, std::vector ptMatching, std::vector candMatching) { - jetOutputTable(collision.globalIndex(), jet.globalIndex(), -1, geoMatching, ptMatching, candMatching, jet.pt(), jet.phi(), jet.eta(), jet.r(), jet.tracks().size()); - jetSubstructureOutputTable(jet.globalIndex(), jet.zg(), jet.rg(), jet.nsd()); + std::vector energyMotherVec; + std::vector ptLeadingVec; + std::vector ptSubLeadingVec; + std::vector thetaVec; + auto energyMotherSpan = jet.energyMother(); + auto ptLeadingSpan = jet.ptLeading(); + auto ptSubLeadingSpan = jet.ptSubLeading(); + auto thetaSpan = jet.theta(); + std::copy(energyMotherSpan.begin(), energyMotherSpan.end(), std::back_inserter(energyMotherVec)); + std::copy(ptLeadingSpan.begin(), ptLeadingSpan.end(), std::back_inserter(ptLeadingVec)); + std::copy(ptSubLeadingSpan.begin(), ptSubLeadingSpan.end(), std::back_inserter(ptSubLeadingVec)); + std::copy(thetaSpan.begin(), thetaSpan.end(), std::back_inserter(thetaVec)); + jetOutputTable(collisionIndex, -1, geoMatching, ptMatching, candMatching, jet.pt(), jet.phi(), jet.eta(), jet.r(), jet.tracks().size()); + jetSubstructureOutputTable(jetOutputTable.lastIndex(), energyMotherVec, ptLeadingVec, ptSubLeadingVec, thetaVec); } - void processDummy(aod::JCollision const& collision) {} - PROCESS_SWITCH(JetSubstructureOutputTask, processDummy, "Dummy process function turned on by default", true); - - void processOutputData(aod::JCollision const& collision, - JetTableData const& jets, - aod::JTracks const& tracks) + template + void analyseCharged(T const& collision, U const& jets, V const& jetsTag, M& collisionOutputTable, N& jetOutputTable, O& jetSubstructureOutputTable) { - std::vector geoMatching{-1}; - std::vector ptMatching{-1}; + std::vector candMatching{-1}; + int nJetInCollision = 0; + int32_t collisionIndex = -1; for (const auto& jet : jets) { - for (const auto& jetRadiiValue : jetRadiiValues) { - if (jet.r() == round(jetRadiiValue * 100.0f)) { - fillTables(collision, jet, jetOutputTableData, jetSubstructureOutputTableData, geoMatching, ptMatching, candMatching); - } + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; } - } - } - PROCESS_SWITCH(JetSubstructureOutputTask, processOutputData, "jet substructure output Data", false); - - void processOutputMCD(aod::JCollision const& collision, - JetTableMCD const& mcdjets, - JetTableMCP const& mcpjets, - aod::JTracks const& tracks) - { - std::vector candMatching{-1}; - for (const auto& mcdjet : mcdjets) { for (const auto& jetRadiiValue : jetRadiiValues) { - if (mcdjet.r() == round(jetRadiiValue * 100.0f)) { + if (jet.r() == round(jetRadiiValue * 100.0f)) { std::vector geoMatching; std::vector ptMatching; - for (auto& mcpjet : mcdjet.template matchedJetGeo_as()) { - geoMatching.push_back(mcpjet.globalIndex()); + if constexpr (hasMatching) { + if (jet.has_matchedJetGeo()) { + for (auto& jetTag : jet.template matchedJetGeo_as()) { + geoMatching.push_back(jetTag.globalIndex()); + } + } + if (jet.has_matchedJetPt()) { + for (auto& jetTag : jet.template matchedJetPt_as()) { + ptMatching.push_back(jetTag.globalIndex()); + } + } } - for (auto& mcpjet : mcdjet.template matchedJetPt_as()) { - ptMatching.push_back(mcpjet.globalIndex()); + if (nJetInCollision == 0) { + collisionOutputTable(collision.posZ(), collision.centrality(), collision.eventSel()); + collisionIndex = collisionOutputTable.lastIndex(); } - fillTables(collision, mcdjet, jetOutputTableMCD, jetSubstructureOutputTableMCD, geoMatching, ptMatching, candMatching); + nJetInCollision++; + fillTables(jet, collisionIndex, collisionOutputTable, jetOutputTable, jetSubstructureOutputTable, geoMatching, ptMatching, candMatching); } } } } + + void processDummy(JetCollisions const& collisions) {} + PROCESS_SWITCH(JetSubstructureOutputTask, processDummy, "Dummy process function turned on by default", true); + + void processOutputData(JetCollision const& collision, + soa::Filtered> const& jets, + JetTracks const& tracks) + { + analyseCharged(collision, jets, jets, collisionOutputTableData, jetOutputTableData, jetSubstructureOutputTableData); + } + PROCESS_SWITCH(JetSubstructureOutputTask, processOutputData, "jet substructure output Data", false); + + void processOutputDataSub(JetCollision const& collision, + soa::Filtered> const& jets, + soa::Filtered> const& jetsSub, + JetTracks const& tracks) + { + analyseCharged(collision, jets, jetsSub, collisionOutputTableData, jetOutputTableData, jetSubstructureOutputTableData); + analyseCharged(collision, jetsSub, jets, collisionOutputTableDataSub, jetOutputTableDataSub, jetSubstructureOutputTableDataSub); + } + PROCESS_SWITCH(JetSubstructureOutputTask, processOutputDataSub, "jet substructure output event-wise subtracted Data", false); + + void processOutputMCD(JetCollision const& collision, + soa::Filtered> const& jets, + aod::ChargedMCParticleLevelJets const& jetsTag, + JetTracks const& tracks) + { + analyseCharged(collision, jets, jetsTag, collisionOutputTableMCD, jetOutputTableMCD, jetSubstructureOutputTableMCD); + } PROCESS_SWITCH(JetSubstructureOutputTask, processOutputMCD, "jet substructure output MCD", false); - void processOutputMCP(aod::JMcCollision const& collision, - JetTableMCP const& mcpjets, - JetTableMCD const& mcdjets, - aod::JMcParticles const& particles) + void processOutputMCP(JetMcCollision const& collision, + soa::Filtered> const& jets, + aod::ChargedMCDetectorLevelJets const& jetsTag, + JetParticles const& particles) { std::vector candMatching{-1}; - for (const auto& mcpjet : mcpjets) { + for (const auto& jet : jets) { + if (!jetfindingutilities::isInEtaAcceptance(jet, jetEtaMin, jetEtaMax, trackEtaMin, trackEtaMax)) { + continue; + } for (const auto& jetRadiiValue : jetRadiiValues) { - if (mcpjet.r() == round(jetRadiiValue * 100.0f)) { + if (jet.r() == round(jetRadiiValue * 100.0f)) { std::vector geoMatching; std::vector ptMatching; - for (auto& mcdjet : mcpjet.template matchedJetGeo_as()) { - geoMatching.push_back(mcdjet.globalIndex()); + if (jet.has_matchedJetGeo()) { + for (auto& jetTag : jet.template matchedJetGeo_as()) { + geoMatching.push_back(jetTag.globalIndex()); + } } - for (auto& mcdjet : mcpjet.template matchedJetPt_as()) { - ptMatching.push_back(mcdjet.globalIndex()); + if (jet.has_matchedJetPt()) { + for (auto& jetTag : jet.template matchedJetPt_as()) { + ptMatching.push_back(jetTag.globalIndex()); + } } - fillTables(collision, mcpjet, jetOutputTableMCP, jetSubstructureOutputTableMCP, geoMatching, ptMatching, candMatching); + fillTables(jet, -1, collisionOutputTableMCP, jetOutputTableMCP, jetSubstructureOutputTableMCP, geoMatching, ptMatching, candMatching); } } } } PROCESS_SWITCH(JetSubstructureOutputTask, processOutputMCP, "jet substructure output MCP", false); }; -using JetSubstructureOutput = JetSubstructureOutputTask>, aod::ChargedJetOutput, aod::ChargedJetSubstructureOutput, soa::Filtered>, aod::ChargedMCDetectorLevelJetOutput, aod::ChargedMCDetectorLevelJetSubstructureOutput, soa::Filtered>, aod::ChargedMCParticleLevelJetOutput, aod::ChargedMCParticleLevelJetSubstructureOutput>; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { - std::vector tasks; - - tasks.emplace_back(adaptAnalysisTask(cfgc, SetDefaultProcesses{}, TaskName{"jet-substructure-output"})); - return WorkflowSpec{tasks}; + return WorkflowSpec{adaptAnalysisTask( + cfgc, TaskName{"jet-substructure-output"})}; } diff --git a/PWGJE/Tasks/jetvalidationqa.cxx b/PWGJE/Tasks/jetvalidationqa.cxx index 0cc2e09824b..c9dcd9cb8a4 100644 --- a/PWGJE/Tasks/jetvalidationqa.cxx +++ b/PWGJE/Tasks/jetvalidationqa.cxx @@ -11,21 +11,6 @@ /// /// \author Johanna Lömker // \since Dec 2022 -////////////////=============================================//////////////// -// TODO's: -//============== 1)template in mcJetTrackCollisionQa to validate JetMatching ! -// loop over matched jets -// make additional TH2F's for matched jets in pt, phi, eta (just what i did for the ones for tracks and collisions) -// i) with mcrec vs mcpart -// ii)with (mcrec-mcpart)/mcpart as function of mcpart -// -//============== 2) Add processes for: -// i) processRun3AOD, process ESD: Full (doesn't work yet) and Neutral Jets -// ii)processMcRun3, processMcRun2: Full (doesn't work yet) and Neutral Jets -// -//============== 3) prepare plotting macros for Run3 and MCrun2, MCrun3 ! -// -////////////////=============================================//////////////// #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -34,7 +19,7 @@ #include "Framework/HistogramRegistry.h" #include "PWGJE/DataModel/Jet.h" -#include "PWGJE/TableProducer/jetfinder.h" +#include "PWGJE/Core/JetDerivedDataUtilities.h" #include "Common/DataModel/EventSelection.h" #include "Common/Core/TrackSelection.h" @@ -66,7 +51,7 @@ struct jetTrackCollisionQa { void init(InitContext const&) { - trackSelection = JetDerivedDataUtilities::initialiseTrackSelection(static_cast(trackSelections)); + trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); // histograms const AxisSpec vtxZAxis{nBins, -20, 20, "Vtx_{z} (cm)"}; @@ -75,7 +60,7 @@ struct jetTrackCollisionQa { const AxisSpec ptAxis{BinsPt, "#it{p}_{T} (GeV/#it{c})"}; // set trackselections - trackSelection = JetDerivedDataUtilities::initialiseTrackSelection(static_cast(trackSelections)); + trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); // histograms // 1)Jetvalidation on data mHistManager.add("collisionVtxZ", "selected collsion VtxZ ", HistType::kTH1D, {vtxZAxis}); @@ -184,13 +169,13 @@ struct jetTrackCollisionQa { Filter etafilter = (aod::jtrack::eta <= etaup) && (aod::jtrack::eta >= etalow); Filter ptfilter = (aod::jtrack::pt <= ptUp) && (aod::jtrack::pt >= ptLow); using Tracks = soa::Join; - using TracksJE = soa::Filtered>; + using TracksJE = soa::Filtered>; - void processESD(aod::JCollision const& collision, soa::Join const& jets, TracksJE const& tracks, Tracks const& originalTracks) + void processESD(JetCollision const& collision, soa::Join const& jets, TracksJE const& tracks, Tracks const& originalTracks) { mHistManager.fill(HIST("controlCollisionVtxZ"), collision.posZ()); if (evSel == true) { - if (!JetDerivedDataUtilities::selectCollision(collision, JetDerivedDataUtilities::JCollisionSel::sel7) || fabs(collision.posZ()) > 10) { + if (!jetderiveddatautilities::selectCollision(collision, jetderiveddatautilities::JCollisionSel::sel7) || fabs(collision.posZ()) > 10) { return; } } else { @@ -206,7 +191,7 @@ struct jetTrackCollisionQa { double leadingTrackEta = -1; // qa histograms for selected tracks in collision for (const auto& t : tracks) { - if (t.collisionId() == collision.globalIndex() && JetDerivedDataUtilities::selectTrack(t, trackSelection)) { + if (t.collisionId() == collision.globalIndex() && jetderiveddatautilities::selectTrack(t, trackSelection)) { auto track = t.track_as(); fillTrackQA(track); if (track.pt() > leadingTrackPt) { @@ -254,10 +239,10 @@ struct jetTrackCollisionQa { PROCESS_SWITCH(jetTrackCollisionQa, processESD, "validate jet-finder output on run2 ESD", true); // process for run3 AOD's - void processRun3AOD(aod::JCollision const& collision, soa::Join const& jets, TracksJE const& tracks, Tracks const& originalTracks) + void processRun3AOD(JetCollision const& collision, soa::Join const& jets, TracksJE const& tracks, Tracks const& originalTracks) { if (evSel == true) { - if (!JetDerivedDataUtilities::selectCollision(collision, JetDerivedDataUtilities::JCollisionSel::sel8) || fabs(collision.posZ()) > 10) { + if (!jetderiveddatautilities::selectCollision(collision, jetderiveddatautilities::JCollisionSel::sel8) || fabs(collision.posZ()) > 10) { return; } } else { @@ -271,7 +256,7 @@ struct jetTrackCollisionQa { double leadingTrackEta = -1; // qa histograms for selected tracks in collision for (const auto& t : tracks) { - if (t.collisionId() == collision.globalIndex() && JetDerivedDataUtilities::selectTrack(t, trackSelection)) { + if (t.collisionId() == collision.globalIndex() && jetderiveddatautilities::selectTrack(t, trackSelection)) { auto track = t.track_as(); fillTrackQA(track); if (track.pt() > leadingTrackPt) { @@ -319,7 +304,7 @@ struct jetTrackCollisionQa { PROCESS_SWITCH(jetTrackCollisionQa, processRun3AOD, "validate jet-finder output on run3 AOD", false); // dummy process to run jetfinder validation code on ESD, but MC validation for run3 on hyperloop - void processDummy(aod::JCollisions const& collision) + void processDummy(JetCollisions const& collisions) { } PROCESS_SWITCH(jetTrackCollisionQa, processDummy, "Dummy process function turned on by default", false); @@ -347,7 +332,7 @@ struct mcJetTrackCollisionQa { void init(InitContext const&) { // set trackselection - trackSelection = JetDerivedDataUtilities::initialiseTrackSelection(static_cast(trackSelections)); + trackSelection = jetderiveddatautilities::initialiseTrackSelection(static_cast(trackSelections)); // histograms const AxisSpec vtxZAxis{nBins, -20, 20, "Vtx_{z} (cm)"}; const AxisSpec ptAxis{BinsPt, "#it{p}_{T} (GeV/#it{c})"}; @@ -423,7 +408,7 @@ struct mcJetTrackCollisionQa { void fillMcTrackHistos(ValidationTracks const& mct, coll collision, bool mc) // could give collision as argument for additional association { for (const auto& track : mct) { - if (!JetDerivedDataUtilities::selectTrack(track, trackSelection) || !(track.collisionId() == collision.globalIndex())) { + if (!jetderiveddatautilities::selectTrack(track, trackSelection) || !(track.collisionId() == collision.globalIndex())) { continue; } if (mc == true) { @@ -488,12 +473,12 @@ struct mcJetTrackCollisionQa { Filter etafilter = (aod::jtrack::eta < etaup) && (aod::jtrack::eta > etalow); Filter ptfilter = (aod::jtrack::pt < ptUp) && (aod::jtrack::pt > ptLow); - using MCTracksJE = soa::Filtered>; + using MCTracksJE = soa::Filtered; - void processMcRun2(soa::Join::iterator const& collision, + void processMcRun2(JetCollisionsMCD::iterator const& collision, soa::Join const& mcPartJets, soa::Join const& mcDetJets, - aod::JMcParticles const& mcParticles, aod::JMcCollisions const& mcCollisions, + JetParticles const& mcParticles, JetMcCollisions const& mcCollisions, MCTracksJE const& tracks) { if (fabs(collision.posZ()) > 10) { @@ -506,12 +491,12 @@ struct mcJetTrackCollisionQa { for (const auto& genJet : mcPartJets) { if (genJet.mcCollisionId() == collision.globalIndex()) { fillMcPartJets(genJet); - for (auto& mcParticle : genJet.tracks_as()) { + for (auto& mcParticle : genJet.tracks_as()) { fillMcPartJetConstituents(mcParticle); } } } // end of loop particle level jets - } // end if has mc collision + } // end if has mc collision fillMcTrackHistos(tracks, collision, false); for (const auto& detJet : mcDetJets) { if (detJet.collisionId() == collision.globalIndex()) { @@ -524,10 +509,10 @@ struct mcJetTrackCollisionQa { } // end processMcRun2 PROCESS_SWITCH(mcJetTrackCollisionQa, processMcRun2, "validate jet-finder output on converted run2 mc AOD's", false); - void processMcRun3(soa::Join::iterator const& collision, + void processMcRun3(JetCollisionsMCD::iterator const& collision, soa::Join const& mcPartJets, soa::Join const& mcDetJets, - aod::JMcParticles const& mcParticles, aod::JMcCollisions const& mcCollisions, + JetParticles const& mcParticles, JetMcCollisions const& mcCollisions, MCTracksJE const& tracks) { if (fabs(collision.posZ()) > 10) { @@ -540,12 +525,12 @@ struct mcJetTrackCollisionQa { for (const auto& genJet : mcPartJets) { if (genJet.mcCollisionId() == collision.globalIndex()) { fillMcPartJets(genJet); - for (auto& mcParticle : genJet.tracks_as()) { + for (auto& mcParticle : genJet.tracks_as()) { fillMcPartJetConstituents(mcParticle); } } } // end of loop particle level jets - } // end of loop if mc collision + } // end of loop if mc collision fillMcTrackHistos(tracks, collision, false); for (const auto& detJet : mcDetJets) { if (detJet.collisionId() == collision.globalIndex()) { @@ -559,7 +544,7 @@ struct mcJetTrackCollisionQa { PROCESS_SWITCH(mcJetTrackCollisionQa, processMcRun3, "validate jet-finder output on run3 mc AOD's", false); // dummy process to run jetfinder validation code on AO2D's, but MC validation for run3 on hyperloop - void processDummy(aod::JCollisions const& collision) + void processDummy(JetMcCollisions const& collisions) { } PROCESS_SWITCH(mcJetTrackCollisionQa, processDummy, "Dummy process function turned off by default", true); diff --git a/PWGJE/Tasks/nSubjettiness.cxx b/PWGJE/Tasks/nSubjettiness.cxx index ae83127e540..8fa16550605 100644 --- a/PWGJE/Tasks/nSubjettiness.cxx +++ b/PWGJE/Tasks/nSubjettiness.cxx @@ -36,9 +36,6 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; -using Collisions = soa::Join; -using Tracks = soa::Join; - template struct nSubJettiness { @@ -104,7 +101,7 @@ struct nSubJettiness { void jetToPseudoJet(JetTableElement const& jet, fastjet::PseudoJet& pseudoJet, std::vector jetConstituents, fastjet::ClusterSequence& clusterSeqInput) { for (auto& jetConstituent : jet.template tracks_as()) { - FastJetUtilities::fillTracks(jetConstituent, jetConstituents, jetConstituent.globalIndex()); + fastjetutilities::fillTracks(jetConstituent, jetConstituents, jetConstituent.globalIndex()); } fastjet::JetDefinition jet_def(fastjet::JetAlgorithm::kt_algorithm, 2.5 * jet.r() / 100); @@ -197,20 +194,20 @@ struct nSubJettiness { } PROCESS_SWITCH(nSubJettiness, processJetsWeighted, "Process function with weighted events, turned off by default", false); - void processDummy(aod::JTracks const& track) + void processDummy(JetTracks const& tracks) { } PROCESS_SWITCH(nSubJettiness, processDummy, "Dummy process function, turned on by default", true); }; -using NSubjettinessChargedJetMCParticleLevel = nSubJettiness, aod::ChargedMCParticleLevelJetEventWeights, aod::JMcParticles>; -using NSubjettinessChargedJetMCDetectorLevel = nSubJettiness, aod::ChargedMCDetectorLevelJetEventWeights, aod::JTracks>; -// using NSubjettinessChargedJetMCParticleLevel = nSubJettiness, aod::JMcParticles>; -// using NSubjettinessChargedJetMCDetectorLevel = nSubJettiness, aod::JTracks>; -// using NSubjettinessChargedJetDataLevel = nSubJettiness, aod::JTracks>; - -// using NSubjettinessD0ChargedJetMCParticleLevel = nSubJettiness, aod::JMcParticles>; -// using NSubjettinessD0ChargedJetMCDetectorLevel = nSubJettiness, aod::JTracks>; -// // using NSubjettinessD0ChargedJetDataLevel = nSubJettiness, aod::JTracks>; +using NSubjettinessChargedJetMCParticleLevel = nSubJettiness, aod::ChargedMCParticleLevelJetEventWeights, JetParticles>; +using NSubjettinessChargedJetMCDetectorLevel = nSubJettiness, aod::ChargedMCDetectorLevelJetEventWeights, JetTracks>; +// using NSubjettinessChargedJetMCParticleLevel = nSubJettiness, JetParticles>; +// using NSubjettinessChargedJetMCDetectorLevel = nSubJettiness, JetTracks; +// using NSubjettinessChargedJetDataLevel = nSubJettiness, JetTracks>; + +// using NSubjettinessD0ChargedJetMCParticleLevel = nSubJettiness, JetParticles>; +// using NSubjettinessD0ChargedJetMCDetectorLevel = nSubJettiness, JetTracks>; +// // using NSubjettinessD0ChargedJetDataLevel = nSubJettiness, JetTracks>; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) { diff --git a/PWGJE/Tasks/phiInJets.cxx b/PWGJE/Tasks/phiInJets.cxx index 16e42aa8fe4..f2426d50f4c 100644 --- a/PWGJE/Tasks/phiInJets.cxx +++ b/PWGJE/Tasks/phiInJets.cxx @@ -159,7 +159,7 @@ struct phiInJets { LFhistos.add("hMultFT0M", "hMultFT0M", kTH1F, {MultAxis}); // EVENT SELECTION - eventSelection = JetDerivedDataUtilities::initialiseEventSelection(static_cast(cfgeventSelections)); + eventSelection = jetderiveddatautilities::initialiseEventSelection(static_cast(cfgeventSelections)); } // end of init @@ -309,7 +309,7 @@ struct phiInJets { } // MinvReconstruction int nEvents = 0; - void processJetTracks(aod::JCollision const& collision, soa::Filtered const& chargedjets, soa::Join const& tracks, TrackCandidates const&) + void processJetTracks(JetCollision const& collision, soa::Filtered const& chargedjets, soa::Join const& tracks, TrackCandidates const&) { if (cDebugLevel > 0) { nEvents++; @@ -318,7 +318,7 @@ struct phiInJets { } JEhistos.fill(HIST("nEvents"), 0.5); - if (!JetDerivedDataUtilities::selectCollision(collision, eventSelection)) + if (!jetderiveddatautilities::selectCollision(collision, eventSelection)) return; for (auto& [track1, track2] : combinations(o2::soa::CombinationsFullIndexPolicy(tracks, tracks))) { diff --git a/PWGJE/Tasks/trackJetqa.cxx b/PWGJE/Tasks/trackJetqa.cxx index f13a87dd4a9..9477f88d66e 100644 --- a/PWGJE/Tasks/trackJetqa.cxx +++ b/PWGJE/Tasks/trackJetqa.cxx @@ -10,11 +10,11 @@ // or submit itself to any jurisdiction. /// \author Alice Caluisi -// \since July 2023 - -// -// Task producing jet tracking qa histograms -// +/// \since July 2023 +/// \author Johanna Lömker +/// \since 2023-10-02 +/// \brief Task producing jet tracking qa histograms +/// #include #include "Framework/AnalysisDataModel.h" @@ -29,7 +29,7 @@ #include "PWGJE/DataModel/Jet.h" #include "PWGJE/DataModel/TrackJetQa.h" -#include "PWGJE/TableProducer/jetfinder.h" +#include "PWGJE/Core/JetDerivedDataUtilities.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/Multiplicity.h" @@ -53,7 +53,7 @@ struct TrackJetQa { // Custom track cuts for the cut variation study TrackSelection customTrackCuts; - Configurable itsPattern{"itsPattern", 1, "0 = Run3ITSibAny, 1 = Run3ITSallAny, 2 = Run3ITSall7Layers, 3 = Run3ITSibTwo"}; + Configurable itsPattern{"itsPattern", 2, "0 = Run3ITSibAny, 1 = Run3ITSibTwo, 2 = Run3ITSallAny, 3 = Run3ITSall7Layers"}; Configurable requireITS{"requireITS", true, "Additional cut on the ITS requirement"}; Configurable requireTPC{"requireTPC", true, "Additional cut on the TPC requirement"}; Configurable requireGoldenChi2{"requireGoldenChi2", true, "Additional cut on the GoldenChi2"}; @@ -61,160 +61,173 @@ struct TrackJetQa { Configurable minNCrossedRowsOverFindableClustersTPC{"minNCrossedRowsOverFindableClustersTPC", 0.7f, "Additional cut on the minimum value of the ratio between crossed rows and findable clusters in the TPC"}; Configurable maxChi2PerClusterTPC{"maxChi2PerClusterTPC", 7.f, "Additional cut on the maximum value of the chi2 per cluster in the TPC"}; Configurable maxChi2PerClusterITS{"maxChi2PerClusterITS", 36.f, "Additional cut on the maximum value of the chi2 per cluster in the ITS"}; - Configurable maxDcaXYFactor{"maxDcaXYFactor", 1.f, "Additional cut on the maximum value of the DCA xy (multiplicative factor)"}; + Configurable maxDcaXY{"maxDcaXY", 0.25f, "Cut on the maximum value of the DCA xy "}; Configurable maxDcaZ{"maxDcaZ", 3.f, "Additional cut on the maximum value of the DCA z"}; Configurable minTPCNClsFound{"minTPCNClsFound", 0.f, "Additional cut on the minimum value of the number of found clusters in the TPC"}; HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - Configurable nBins{"nBins", 200, "N bins in histos"}; - ConfigurableAxis binsMultiplicity{"binsMultiplicity", {100, 0, 100}, "Binning for multiplicity"}; + ConfigurableAxis binsMultiplicity{"binsMultiplicity", {2000, 0, 2000}, "Binning for multiplicity"}; + ConfigurableAxis binsMultPV{"binsMultNTracksPV", {10000, 0, 50000}, "Binning for the multNTracksPV axis"}; ConfigurableAxis binsPercentile{"binsPercentile", {100, 0, 100}, "Binning for percentiles"}; + ConfigurableAxis binsVtx{"binsVtx", {200, -20, 20}, "Binning for the vertex position z axis"}; ConfigurableAxis binsPt{"binsPt", {200, 0, 200}, "Binning for the pT axis"}; - ConfigurableAxis binsSigma1OverPt{"binsSigma1OverPt", {200, 0, 200}, "Binning for the sigma 1 over pT"}; + ConfigurableAxis binsSigma1OverPt{"binsSigma1OverPt", {100, 0, 1}, "Binning for the sigma 1 over pT * pT"}; + ConfigurableAxis binsPhi{"binsPhi", {180, 0, 2 * M_PI}, "Binning for the phi axis"}; + ConfigurableAxis binsEta{"binsEta", {100, -1, 1}, "Binning for the eta axis"}; + ConfigurableAxis binsTrackXY{"binsTrackXY", {100, -0.5, 0.5}, "Binning for the x and y track position at dca in local coordinate system axis"}; + ConfigurableAxis binsTrackZ{"binsTrackZ", {100, -11, 11}, "Binning for the z track position at dca in local coordinate system axis"}; + ConfigurableAxis binsRot{"binsRot", {36, -M_PI, M_PI}, "Binning for the rotation angle axis"}; + ConfigurableAxis binsSignedPt{"binsSignedPt", {200, -8, 8}, "Binning for the q over pt axis"}; + ConfigurableAxis binsDcaXY{"binsDcaXY", {100, -0.5, 0.5}, "Binning for the dcaXY axis"}; + ConfigurableAxis binsDcaZ{"binsDcaZ", {100, -5, 5}, "Binning for the dcaXY axis"}; + ConfigurableAxis binsLength{"binsLength", {200, 0, 1000}, "Binning for the track length axis"}; void init(o2::framework::InitContext&) { - // Custom track cuts - LOG(info) << "Using custom track cuts from values:"; - LOG(info) << "\trequireITS=" << requireITS.value; - LOG(info) << "\trequireTPC=" << requireTPC.value; - LOG(info) << "\trequireGoldenChi2=" << requireGoldenChi2.value; - LOG(info) << "\tmaxChi2PerClusterTPC=" << maxChi2PerClusterTPC.value; - LOG(info) << "\tminNCrossedRowsTPC=" << minNCrossedRowsTPC.value; - LOG(info) << "\tminTPCNClsFound=" << minTPCNClsFound.value; - LOG(info) << "\tmaxChi2PerClusterITS=" << maxChi2PerClusterITS.value; - LOG(info) << "\tRequireHitsInITSLayers=" << maxChi2PerClusterITS.value; - LOG(info) << "\tmaxDcaZ=" << maxDcaZ.value; - LOG(info) << "\tminPt=" << minPt.value; - LOG(info) << "\tmaxPt=" << maxPt.value; - LOG(info) << "\tmaxEta=" << ValCutEta.value; + if (customTrack) { + // Custom track cuts + LOG(info) << "Using custom track cuts from values:"; + LOG(info) << "\trequireITS=" << requireITS.value; + LOG(info) << "\trequireTPC=" << requireTPC.value; + LOG(info) << "\trequireGoldenChi2=" << requireGoldenChi2.value; + LOG(info) << "\tmaxChi2PerClusterTPC=" << maxChi2PerClusterTPC.value; + LOG(info) << "\tminNCrossedRowsTPC=" << minNCrossedRowsTPC.value; + LOG(info) << "\tminTPCNClsFound=" << minTPCNClsFound.value; + LOG(info) << "\tmaxChi2PerClusterITS=" << maxChi2PerClusterITS.value; + LOG(info) << "\tRequireHitsInITSLayers=" << maxChi2PerClusterITS.value; + LOG(info) << "\tmaxDcaXY=" << maxDcaXY.value; + LOG(info) << "\tmaxDcaZ=" << maxDcaZ.value; + LOG(info) << "\tminPt=" << minPt.value; + LOG(info) << "\tmaxPt=" << maxPt.value; + LOG(info) << "\tmaxEta=" << ValCutEta.value; - customTrackCuts = getGlobalTrackSelectionRun3ITSMatch(itsPattern.value); - LOG(info) << "Customizing track cuts:"; - customTrackCuts.SetEtaRange(-ValCutEta.value, ValCutEta.value); - customTrackCuts.SetPtRange(minPt.value, maxPt.value); - customTrackCuts.SetRequireITSRefit(requireITS.value); - customTrackCuts.SetRequireTPCRefit(requireTPC.value); - customTrackCuts.SetRequireGoldenChi2(requireGoldenChi2.value); - customTrackCuts.SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC.value); - customTrackCuts.SetMaxChi2PerClusterITS(maxChi2PerClusterITS.value); - customTrackCuts.SetMinNCrossedRowsTPC(minNCrossedRowsTPC.value); - customTrackCuts.SetMinNClustersTPC(minTPCNClsFound.value); - // customTrackCuts.SetRequireHitsInITSLayers(nHits.value, {0, 1}); // one hit in any SPD layer (#hits, {layer0, layer1,...}) - customTrackCuts.SetMinNCrossedRowsOverFindableClustersTPC(minNCrossedRowsOverFindableClustersTPC.value); - customTrackCuts.SetMaxDcaXYPtDep([](float pt) { return 10.f; }); // No DCAxy cut will be used, this is done via the member function of the task - customTrackCuts.SetMaxDcaZ(maxDcaZ.value); - customTrackCuts.print(); - - // kinetic histograms - histos.add("Kine/pt", "#it{p}_{T};#it{p}_{T} [GeV/c];number of entries", HistType::kTH1F, {{nBins, 0, 200}}); - histos.add("Kine/pt_TRD", "#it{p}_{T} if track has a TRD match;#it{p}_{T} [GeV/c];number of entries", HistType::kTH1F, {{nBins, 0, 200}}); - histos.add("Kine/eta", "#eta;#it{p}_{T} [GeV/c];#eta", {HistType::kTH2F, {{nBins, 0, 200}, {180, -0.9, 0.9}}}); - histos.add("Kine/phi", "#phi;#it{p}_{T} [GeV/c];#phi [rad]", {HistType::kTH2F, {{nBins, 0, 200}, {180, 0., 2 * M_PI}}}); - histos.add("Kine/etaVSphi", "#eta VS phi;#eta;#phi [rad]", {HistType::kTH2F, {{180, -0.9, 0.9}, {180, 0., 2 * M_PI}}}); - histos.add("Kine/EtaPhiPt", "Correlation of #eta, #phi and #it{p}_{T}; #it{p}_{T} [GeV/c]; #eta; #phi [rad]", {HistType::kTH3F, {{nBins, 0, 200}, {180, -0.9, 0.9}, {180, 0., 2 * M_PI}}}); - - // track parameter histograms - histos.add("TrackPar/x", "track #it{x} position at dca in local coordinate system;#it{p}_{T} [GeV/c];#it{x} [cm]", {HistType::kTH2F, {{nBins, 0, 200}, {200, -0.36, 0.36}}}); - histos.add("TrackPar/y", "track #it{y} position at dca in local coordinate system;#it{p}_{T} [GeV/c];#it{y} [cm]", {HistType::kTH2F, {{nBins, 0, 200}, {200, -0.5, 0.5}}}); - histos.add("TrackPar/z", "track #it{z} position at dca in local coordinate system;#it{p}_{T} [GeV/c];#it{z} [cm]", {HistType::kTH2F, {{nBins, 0, 200}, {200, -11., 11.}}}); - histos.add("TrackPar/alpha", "rotation angle of local wrt. global coordinate system;#it{p}_{T} [GeV/c];#alpha [rad]", {HistType::kTH2F, {{nBins, 0, 200}, {36, -M_PI, M_PI}}}); - histos.add("TrackPar/signed1Pt", "track signed 1/#it{p}_{T};#it{p}_{T} [GeV/c];#it{q}/#it{p}_{T}", {HistType::kTH2F, {{nBins, 0, 200}, {200, -8, 8}}}); - histos.add("TrackPar/snp", "sinus of track momentum azimuthal angle;#it{p}_{T} [GeV/c];snp", {HistType::kTH2F, {{nBins, 0, 200}, {11, -0.1, 0.1}}}); - histos.add("TrackPar/tgl", "tangent of the track momentum dip angle;#it{p}_{T} [GeV/c];tgl;", {HistType::kTH2F, {{nBins, 0, 200}, {200, -1., 1.}}}); - histos.add("TrackPar/flags", "track flag;#it{p}_{T} [GeV/c];flag bit", {HistType::kTH2F, {{nBins, 0, 200}, {64, -0.5, 63.5}}}); - histos.add("TrackPar/dcaXY", "distance of closest approach in #it{xy} plane;#it{p}_{T} [GeV/c];#it{dcaXY} [cm];", {HistType::kTH2F, {{nBins, 0, 200}, {200, -0.15, 0.15}}}); - histos.add("TrackPar/dcaZ", "distance of closest approach in #it{z};#it{p}_{T} [GeV/c];#it{dcaZ} [cm];", {HistType::kTH2F, {{nBins, 0, 200}, {200, -0.15, 0.15}}}); - histos.add("TrackPar/length", "track length in cm;#it{p}_{T} [GeV/c];#it{Length} [cm];", {HistType::kTH2F, {{nBins, 0, 200}, {200, 0, 1000}}}); - histos.add("TrackPar/Sigma1Pt", "uncertainty over #it{p}_{T};#it{p}_{T} [GeV/c];#it{p}_{T}*#it{sigma1}{p}_{T};", {HistType::kTH2F, {{nBins, 0, 200}, {100, 0, 1}}}); - histos.add("TrackPar/Sigma1Pt_hasTRD", "uncertainty over #it{p}_{T} for tracks with TRD;#it{p}_{T} [GeV/c];#it{p}_{T}*#it{sigma1}{p}_{T};", {HistType::kTH2F, {{nBins, 0, 200}, {100, 0, 1}}}); - histos.add("TrackPar/Sigma1Pt_hasNoTRD", "uncertainty over #it{p}_{T} for tracks without TRD;#it{p}_{T} [GeV/c];#it{p}_{T}*#it{sigma1}{p}_{T};", {HistType::kTH2F, {{nBins, 0, 200}, {100, 0, 1}}}); - histos.add("TrackPar/Sigma1Pt_Layer1", "uncertainty over #it{p}_{T} with only 1st ITS layer active;#it{p}_{T} [GeV/c];#it{p}_{T}*#it{sigma1}{p}_{T};", {HistType::kTH2F, {{nBins, 0, 200}, {100, 0, 1}}}); - histos.add("TrackPar/Sigma1Pt_Layer2", "uncertainty over #it{p}_{T} with only 2nd ITS layer active;#it{p}_{T} [GeV/c];#it{p}_{T}*#it{sigma1}{p}_{T};", {HistType::kTH2F, {{nBins, 0, 200}, {100, 0, 1}}}); - histos.add("TrackPar/Sigma1Pt_Layers12", "uncertainty over #it{p}_{T} with only 1st and 2nd ITS layers active;#it{p}_{T} [GeV/c];#it{p}_{T}*#it{sigma1}{p}_{T};", {HistType::kTH2F, {{nBins, 0, 200}, {100, 0, 1}}}); - histos.add("TrackPar/Sigma1Pt_Layer4", "uncertainty over #it{p}_{T} with only 4th ITS layer active;#it{p}_{T} [GeV/c];#it{p}_{T}*#it{sigma1}{p}_{T};", {HistType::kTH2F, {{nBins, 0, 200}, {100, 0, 1}}}); - histos.add("TrackPar/Sigma1Pt_Layer5", "uncertainty over #it{p}_{T} with only 5th ITS layer active;#it{p}_{T} [GeV/c];#it{p}_{T}*#it{sigma1}{p}_{T};", {HistType::kTH2F, {{nBins, 0, 200}, {100, 0, 1}}}); - histos.add("TrackPar/Sigma1Pt_Layer6", "uncertainty over #it{p}_{T} with only 6th ITS layer active;#it{p}_{T} [GeV/c];#it{p}_{T}*#it{sigma1}{p}_{T};", {HistType::kTH2F, {{nBins, 0, 200}, {100, 0, 1}}}); - histos.add("TrackPar/Sigma1Pt_Layers45", "uncertainty over #it{p}_{T} with only 4th and 5th ITS layers active;#it{p}_{T} [GeV/c];#it{p}_{T}*#it{sigma1}{p}_{T};", {HistType::kTH2F, {{nBins, 0, 200}, {100, 0, 1}}}); - histos.add("TrackPar/Sigma1Pt_Layers56", "uncertainty over #it{p}_{T} with only 5th and 6th ITS layers active;#it{p}_{T} [GeV/c];#it{p}_{T}*#it{sigma1}{p}_{T};", {HistType::kTH2F, {{nBins, 0, 200}, {100, 0, 1}}}); - histos.add("TrackPar/Sigma1Pt_Layers46", "uncertainty over #it{p}_{T} with only 4th and 6th ITS layers active;#it{p}_{T} [GeV/c];#it{p}_{T}*#it{sigma1}{p}_{T};", {HistType::kTH2F, {{nBins, 0, 200}, {100, 0, 1}}}); - histos.add("TrackPar/Sigma1Pt_Layers456", "uncertainty over #it{p}_{T} with only 4th, 5th and 6th ITS layers active;#it{p}_{T} [GeV/c];#it{p}_{T}*#it{sigma1}{p}_{T};", {HistType::kTH2F, {{nBins, 0, 200}, {100, 0, 1}}}); - - // event property histograms - histos.add("EventProp/collisionVtxZ", "Collsion Vertex Z;#it{Vtx}_{z} [cm];number of entries", HistType::kTH1F, {{nBins, -20, 20}}); - histos.add("EventProp/collisionVtxZnoSel", "Collsion Vertex Z without event selection;#it{Vtx}_{z} [cm];number of entries", HistType::kTH1F, {{nBins, -20, 20}}); - histos.add("EventProp/collisionVtxZSel8", "Collsion Vertex Z with event selection;#it{Vtx}_{z} [cm];number of entries", HistType::kTH1F, {{nBins, -20, 20}}); - histos.add("EventProp/rejectedCollId", "CollisionId of collisions that did not pass the event selection; collisionId; number of entries", HistType::kTH1F, {{10, 0, 5}}); + customTrackCuts = getGlobalTrackSelectionRun3ITSMatch(itsPattern.value); + LOG(info) << "Customizing track cuts:"; + customTrackCuts.SetEtaRange(-ValCutEta.value, ValCutEta.value); + customTrackCuts.SetPtRange(minPt.value, maxPt.value); + customTrackCuts.SetRequireITSRefit(requireITS.value); + customTrackCuts.SetRequireTPCRefit(requireTPC.value); + customTrackCuts.SetRequireGoldenChi2(requireGoldenChi2.value); + customTrackCuts.SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC.value); + customTrackCuts.SetMaxChi2PerClusterITS(maxChi2PerClusterITS.value); + customTrackCuts.SetMinNCrossedRowsTPC(minNCrossedRowsTPC.value); + customTrackCuts.SetMinNClustersTPC(minTPCNClsFound.value); + // customTrackCuts.SetRequireHitsInITSLayers(nHits.value, {0, 1}); // one hit in any SPD layer (#hits, {layer0, layer1,...}) + customTrackCuts.SetMinNCrossedRowsOverFindableClustersTPC(minNCrossedRowsOverFindableClustersTPC.value); + customTrackCuts.SetMaxDcaXY(maxDcaXY.value); + customTrackCuts.SetMaxDcaZ(maxDcaZ.value); + customTrackCuts.print(); + } + if (globalTrack) { + LOG(info) << "Using globalTracks"; + } + if (globalTrackWoPtEta) { + LOG(info) << "Using globalTracksWoPtEta"; + } + if (globalTrackWoDCA) { + LOG(info) << "Using globalTracksWoDCA"; + } else { + LOG(info) << "No trackselection enabled !"; + } // Common axes const AxisSpec axisPercentileFT0M{binsPercentile, "Centrality FT0M"}; const AxisSpec axisPercentileFT0A{binsPercentile, "Centrality FT0A"}; const AxisSpec axisPercentileFT0C{binsPercentile, "Centrality FT0C"}; - const AxisSpec axisMultiplicityPV{binsMultiplicity, "MultNTracksPV"}; + const AxisSpec axisMultiplicityPV{binsMultPV, "Multiplicity N TracksPV"}; + const AxisSpec axisMultiplicityTracks{binsMultiplicity, "Multiplicity tracks.size()"}; const AxisSpec axisMultiplicityFT0M{binsMultiplicity, "Multiplicity FT0M"}; const AxisSpec axisMultiplicityFT0A{binsMultiplicity, "Multiplicity FT0A"}; const AxisSpec axisMultiplicityFT0C{binsMultiplicity, "Multiplicity FT0C"}; + const AxisSpec axisVtx{binsVtx, "#it{Vtx}_{z} [cm]"}; const AxisSpec axisPt{binsPt, "#it{p}_{T} (GeV/#it{c})"}; - const AxisSpec axisSigma1OverPt{binsSigma1OverPt, "#sigma(1/#it{p}_{T}) (GeV/#it{c})^{-1}"}; + const AxisSpec axisPhi{binsPhi, "#phi [rad]"}; + const AxisSpec axisEta{binsEta, " #eta"}; + const AxisSpec axisSigma1OverPt{binsSigma1OverPt, "#sigma(1/#it{p}_{T})*#it{p}_{T}"}; + const AxisSpec axisTrackX{binsTrackXY, "track #it{x} [cm]"}; + const AxisSpec axisTrackY{binsTrackXY, "track #it{y} [cm]"}; + const AxisSpec axisTrackZ{binsTrackZ, "track #it{z} [cm]"}; + const AxisSpec axisRotation{binsRot, "#alpha [rad]"}; + const AxisSpec axisSignedPt{binsSignedPt, "#it{q}/#it{p}_{T}"}; + const AxisSpec axisDcaXY{binsDcaXY, "#it{dcaXY} [cm]"}; + const AxisSpec axisDcaZ{binsDcaZ, "#it{dcaZ} [cm]"}; + const AxisSpec axisTrackLength{binsLength, "#it{Length} [cm]"}; - histos.add("Centrality/FT0M", "CentFT0M", HistType::kTH1D, {axisPercentileFT0M}); - histos.add("Centrality/FT0A", "CentFT0A", HistType::kTH1D, {axisPercentileFT0A}); - histos.add("Centrality/FT0C", "CentFT0C", HistType::kTH1D, {axisPercentileFT0M}); - histos.add("Mult/NTracksPV", "MultNTracksPV", HistType::kTH1D, {axisMultiplicityPV}); - histos.add("Mult/FT0M", "MultFT0M", HistType::kTH1D, {axisMultiplicityFT0M}); - histos.add("Mult/FT0A", "MultFT0A", HistType::kTH1D, {axisMultiplicityFT0A}); - histos.add("Mult/FT0C", "MultFT0C", HistType::kTH1D, {axisMultiplicityFT0C}); - histos.add("Mult/MultCorrelations", "MultCorrelations", HistType::kTHnSparseD, {axisPercentileFT0A, axisPercentileFT0C, axisMultiplicityFT0A, axisMultiplicityFT0C, axisMultiplicityPV}); + // event property histograms + histos.add("EventProp/collisionVtxZ", "Collsion Vertex Z position", HistType::kTHnSparseD, {axisVtx, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("EventProp/collisionVtxZnoSel", "Collsion Vertex Z position without event selection", HistType::kTHnSparseD, {axisVtx, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("EventProp/collisionVtxZSel8", "Collsion Vertex Z position with event selection", HistType::kTHnSparseD, {axisVtx, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("EventProp/rejectedCollId", "CollisionId of collisions that did not pass the event selection; collisionId; number of entries", HistType::kTH1F, {{10, 0, 5}}); + histos.add("EventProp/MultCorrelations", "Multiplicity and Centrality Correlations", HistType::kTHnSparseD, {axisPercentileFT0A, axisPercentileFT0C, axisPercentileFT0M, axisMultiplicityFT0A, axisMultiplicityFT0C, axisMultiplicityFT0M, axisMultiplicityPV, axisMultiplicityTracks}); + + histos.add("TrackEventPar/MultCorrelations", "Sigma1Pt*pT vs Multiplicity and Centrality Correlations", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisPercentileFT0A, axisPercentileFT0C, axisPercentileFT0M, axisMultiplicityFT0A, axisMultiplicityFT0C, axisMultiplicityFT0M, axisMultiplicityPV, axisMultiplicityTracks}); + + // kinetic histograms + histos.add("Kine/pt", "#it{p}_{T}", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("Kine/pt_TRD", "#it{p}_{T} if track has a TRD match", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("Kine/EtaPhiPt", "Correlation of #eta #phi and #it{p}_{T}", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisEta, axisPhi, axisPercentileFT0A, axisPercentileFT0C}); - histos.add("TrackEventPar/Sigma1PtFT0Mcent", "Sigma1Pt vs pT vs FT0M centrality", HistType::kTHnSparseD, {axisPercentileFT0M, axisPt, axisSigma1OverPt}); - histos.add("TrackEventPar/Sigma1PtFT0Mmult", "Sigma1Pt vs pT vs FT0A,C multiplicity", HistType::kTHnSparseD, {axisMultiplicityFT0M, axisPt, axisSigma1OverPt}); - histos.add("TrackEventPar/Sigma1PtNTracksPV", "Sigma1Pt vs pT vs NTracksPV", HistType::kTHnSparseD, {axisMultiplicityPV, axisPt, axisSigma1OverPt}); - histos.add("TrackEventPar/MultCorrelations", "Sigma1Pt vs pT vs MultCorrelations", HistType::kTHnSparseD, {axisSigma1OverPt, axisPt, axisPercentileFT0A, axisPercentileFT0C, axisMultiplicityFT0A, axisMultiplicityFT0C, axisMultiplicityPV}); + // track parameter histograms - add sigma 1pt to all of them ! then cp this part to below + histos.add("TrackPar/xyz", "track #it{x}, #it{y}, #it{z} position at dca in local coordinate system", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisTrackX, axisTrackY, axisTrackZ, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/alpha", "rotation angle of local wrt. global coordinate system", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisRotation, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/signed1Pt", "track signed 1/#it{p}_{T}", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisSignedPt, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/snp", "sinus of track momentum azimuthal angle (snp)", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, {11, -0.05, 0.5, "snp"}, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/tgl", "tangent of the track momentum dip angle (tgl)", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, {200, -1., 1., "tgl"}, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/flags", "track flag;#it{p}_{T} [GeV/c];flag bit", {HistType::kTH2F, {{200, 0, 200}, {64, -0.5, 63.5}}}); + histos.add("TrackPar/dcaXY", "distance of closest approach in #it{xy} plane", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisDcaXY, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/dcaZ", "distance of closest approach in #it{z}", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisDcaZ, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/length", "track length in cm", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisTrackLength, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/Sigma1Pt", "uncertainty over #it{p}_{T}", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/Sigma1Pt_hasTRD", "uncertainty over #it{p}_{T} for tracks with TRD", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/Sigma1Pt_hasNoTRD", "uncertainty over #it{p}_{T} for tracks without TRD", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/Sigma1Pt_Layer1", "uncertainty over #it{p}_{T} with only 1st ITS layer active", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/Sigma1Pt_Layer2", "uncertainty over #it{p}_{T} with only 2nd ITS layer active", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/Sigma1Pt_Layers12", "uncertainty over #it{p}_{T} with only 1st and 2nd ITS layers active", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/Sigma1Pt_Layer4", "uncertainty over #it{p}_{T} with only 4th ITS layer active", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/Sigma1Pt_Layer5", "uncertainty over #it{p}_{T} with only 5th ITS layer active", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/Sigma1Pt_Layer6", "uncertainty over #it{p}_{T} with only 6th ITS layer active", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/Sigma1Pt_Layers45", "uncertainty over #it{p}_{T} with only 4th and 5th ITS layers active", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/Sigma1Pt_Layers56", "uncertainty over #it{p}_{T} with only 5th and 6th ITS layers active", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/Sigma1Pt_Layers46", "uncertainty over #it{p}_{T} with only 4th and 6th ITS layers active", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TrackPar/Sigma1Pt_Layers456", "uncertainty over #it{p}_{T} with only 4th, 5th and 6th ITS layers active", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, axisPercentileFT0A, axisPercentileFT0C}); // ITS histograms - histos.add("ITS/itsNCls", "number of found ITS clusters", {HistType::kTH2F, {axisPt, {8, -0.5, 7.5, "# clusters ITS"}}}); - histos.add("ITS/itsChi2NCl", "chi2 per ITS cluster", {HistType::kTH2F, {axisPt, {100, 0, 40, "chi2 / cluster ITS"}}}); - histos.add("ITS/itsHits", "hitmap ITS", {HistType::kTH2F, {axisPt, {7, -0.5, 6.5, "layer ITS"}}}); + histos.add("ITS/itsNCls", "number of found ITS clusters", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, {8, -0.5, 7.5, "# clusters ITS"}, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("ITS/itsChi2NCl", "chi2 per ITS cluster", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, {100, 0, 40, "chi2 / cluster ITS"}, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("ITS/itsHits", "hitmap ITS", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, {7, -0.5, 6.5, "layer ITS"}, axisPercentileFT0A, axisPercentileFT0C}); // TPC histograms - histos.add("TPC/tpcNClsFindable", "number of findable TPC clusters", {HistType::kTH2F, {axisPt, {165, -0.5, 164.5, "# findable clusters TPC"}}}); - histos.add("TPC/tpcNClsFound", "number of found TPC clusters", {HistType::kTH2F, {axisPt, {165, -0.5, 164.5, "# clusters TPC"}}}); - histos.add("TPC/tpcNClsShared", "number of shared TPC clusters", {HistType::kTH2F, {axisPt, {165, -0.5, 164.5, "# shared clusters TPC"}}}); - histos.add("TPC/tpcNClsCrossedRows", "number of crossed TPC rows", {HistType::kTH2F, {axisPt, {165, -0.5, 164.5, "# crossed rows TPC"}}}); - histos.add("TPC/tpcFractionSharedCls", "fraction of shared TPC clusters", {HistType::kTH2F, {axisPt, {100, 0., 1., "fraction shared clusters TPC"}}}); - histos.add("TPC/tpcCrossedRowsOverFindableCls", "crossed TPC rows over findable clusters", {HistType::kTH2F, {axisPt, {120, 0.0, 1.2, "crossed rows / findable clusters TPC"}}}); - histos.add("TPC/tpcChi2NCl", "chi2 per cluster in TPC", {HistType::kTH2F, {axisPt, {100, 0, 10, "chi2 / cluster TPC"}}}); + histos.add("TPC/tpcNClsFindable", "number of findable TPC clusters", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, {165, -0.5, 164.5, "# findable clusters TPC"}, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TPC/tpcNClsFound", "number of found TPC clusters", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, {165, -0.5, 164.5, "# clusters TPC"}, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TPC/tpcNClsShared", "number of shared TPC clusters", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, {165, -0.5, 164.5, "# shared clusters TPC"}, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TPC/tpcNClsCrossedRows", "number of crossed TPC rows", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, {165, -0.5, 164.5, "# crossed rows TPC"}, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TPC/tpcFractionSharedCls", "fraction of shared TPC clusters", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, {100, 0., 1., "fraction shared clusters TPC"}, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TPC/tpcCrossedRowsOverFindableCls", "crossed TPC rows over findable clusters", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, {120, 0.0, 1.2, "crossed rows / findable clusters TPC"}, axisPercentileFT0A, axisPercentileFT0C}); + histos.add("TPC/tpcChi2NCl", "chi2 per cluster in TPC", HistType::kTHnSparseD, {axisPt, axisSigma1OverPt, {100, 0, 10, "chi2 / cluster TPC"}, axisPercentileFT0A, axisPercentileFT0C}); histos.print(); } template - bool fillEventQa(eventInfo const& collision) + bool checkEventSelection(eventInfo const& collision) { // fill event property variables - histos.fill(HIST("EventProp/collisionVtxZnoSel"), collision.posZ()); + histos.fill(HIST("EventProp/collisionVtxZnoSel"), collision.posZ(), collision.centFT0A(), collision.centFT0C()); if (!collision.sel8()) { histos.fill(HIST("EventProp/rejectedCollId"), 2); return false; } - histos.fill(HIST("EventProp/collisionVtxZSel8"), collision.posZ()); + histos.fill(HIST("EventProp/collisionVtxZSel8"), collision.posZ(), collision.centFT0A(), collision.centFT0C()); if (fabs(collision.posZ()) > ValVtx) { histos.fill(HIST("EventProp/rejectedCollId"), 3); return false; } - histos.fill(HIST("EventProp/collisionVtxZ"), collision.posZ()); - if (fillMultiplicity) { - histos.fill(HIST("Centrality/FT0A"), collision.centFT0A()); - histos.fill(HIST("Centrality/FT0C"), collision.centFT0C()); - histos.fill(HIST("Mult/NTracksPV"), collision.multNTracksPV()); - histos.fill(HIST("Mult/FT0A"), collision.multFT0A()); - histos.fill(HIST("Mult/FT0C"), collision.multFT0C()); - } + histos.fill(HIST("EventProp/collisionVtxZ"), collision.posZ(), collision.centFT0A(), collision.centFT0C()); return true; } template - bool fillTrackQa(Tracks const& track) + bool checkTrackSelection(Tracks const& track) { // check track selection if ((globalTrack == true) && (!track.isGlobalTrack())) { @@ -229,36 +242,37 @@ struct TrackJetQa { if ((customTrack == true) && (!customTrackCuts.IsSelected(track))) { return false; } + return true; + } + + template + void fillTrackQa(Tracks const& track, eventInfo const& collision) + { // fill kinematic variables - histos.fill(HIST("Kine/pt"), track.pt()); + histos.fill(HIST("Kine/pt"), track.pt(), track.sigma1Pt() * track.pt(), collision.centFT0A(), collision.centFT0C()); if (track.hasTRD()) { - histos.fill(HIST("Kine/pt_TRD"), track.pt()); - histos.fill(HIST("TrackPar/Sigma1Pt_hasTRD"), track.pt(), track.sigma1Pt() * track.pt()); + histos.fill(HIST("Kine/pt_TRD"), track.pt(), track.sigma1Pt() * track.pt(), collision.centFT0A(), collision.centFT0C()); + histos.fill(HIST("TrackPar/Sigma1Pt_hasTRD"), track.pt(), track.sigma1Pt() * track.pt(), track.sigma1Pt() * track.pt(), collision.centFT0A(), collision.centFT0C()); } if (!track.hasTRD()) { - histos.fill(HIST("TrackPar/Sigma1Pt_hasNoTRD"), track.pt(), track.sigma1Pt() * track.pt()); + histos.fill(HIST("TrackPar/Sigma1Pt_hasNoTRD"), track.pt(), track.sigma1Pt() * track.pt(), track.sigma1Pt() * track.pt(), collision.centFT0A(), collision.centFT0C()); } - histos.fill(HIST("Kine/eta"), track.pt(), track.eta()); - histos.fill(HIST("Kine/phi"), track.pt(), track.phi()); - histos.fill(HIST("Kine/etaVSphi"), track.eta(), track.phi()); - histos.fill(HIST("Kine/EtaPhiPt"), track.pt(), track.eta(), track.phi()); + histos.fill(HIST("Kine/EtaPhiPt"), track.pt(), track.sigma1Pt() * track.pt(), track.eta(), track.phi(), collision.centFT0A(), collision.centFT0C()); // fill track parameter variables - histos.fill(HIST("TrackPar/alpha"), track.pt(), track.alpha()); - histos.fill(HIST("TrackPar/x"), track.pt(), track.x()); - histos.fill(HIST("TrackPar/y"), track.pt(), track.y()); - histos.fill(HIST("TrackPar/z"), track.pt(), track.z()); - histos.fill(HIST("TrackPar/signed1Pt"), track.pt(), track.signed1Pt()); - histos.fill(HIST("TrackPar/snp"), track.pt(), track.snp()); - histos.fill(HIST("TrackPar/tgl"), track.pt(), track.tgl()); + histos.fill(HIST("TrackPar/alpha"), track.pt(), track.sigma1Pt() * track.pt(), track.alpha(), collision.centFT0A(), collision.centFT0C()); + histos.fill(HIST("TrackPar/xyz"), track.pt(), track.sigma1Pt() * track.pt(), track.x(), track.y(), track.z(), collision.centFT0A(), collision.centFT0C()); + histos.fill(HIST("TrackPar/signed1Pt"), track.pt(), track.sigma1Pt() * track.pt(), track.signed1Pt(), collision.centFT0A(), collision.centFT0C()); + histos.fill(HIST("TrackPar/snp"), track.pt(), track.sigma1Pt() * track.pt(), track.snp(), collision.centFT0A(), collision.centFT0C()); + histos.fill(HIST("TrackPar/tgl"), track.pt(), track.sigma1Pt() * track.pt(), track.tgl(), collision.centFT0A(), collision.centFT0C()); for (unsigned int i = 0; i < 64; i++) { if (track.flags() & (1 << i)) { - histos.fill(HIST("TrackPar/flags"), track.pt(), i); + histos.fill(HIST("TrackPar/flags"), track.pt(), track.sigma1Pt() * track.pt(), i); } } - histos.fill(HIST("TrackPar/dcaXY"), track.pt(), track.dcaXY()); - histos.fill(HIST("TrackPar/dcaZ"), track.pt(), track.dcaZ()); - histos.fill(HIST("TrackPar/length"), track.pt(), track.length()); - histos.fill(HIST("TrackPar/Sigma1Pt"), track.pt(), track.sigma1Pt() * track.pt()); + histos.fill(HIST("TrackPar/dcaXY"), track.pt(), track.sigma1Pt() * track.pt(), track.dcaXY(), collision.centFT0A(), collision.centFT0C()); + histos.fill(HIST("TrackPar/dcaZ"), track.pt(), track.sigma1Pt() * track.pt(), track.dcaZ(), collision.centFT0A(), collision.centFT0C()); + histos.fill(HIST("TrackPar/length"), track.pt(), track.sigma1Pt() * track.pt(), track.length(), collision.centFT0A(), collision.centFT0C()); + histos.fill(HIST("TrackPar/Sigma1Pt"), track.pt(), track.sigma1Pt() * track.pt(), collision.centFT0A(), collision.centFT0C()); //// check the uncertainty over pT activating several ITS layers bool firstLayerActive = track.itsClusterMap() & (1 << 0); bool secondLayerActive = track.itsClusterMap() & (1 << 1); @@ -266,58 +280,54 @@ struct TrackJetQa { bool fifthLayerActive = track.itsClusterMap() & (1 << 4); bool sixthLayerActive = track.itsClusterMap() & (1 << 5); if (firstLayerActive) { - histos.fill(HIST("TrackPar/Sigma1Pt_Layer1"), track.pt(), track.sigma1Pt() * track.pt()); + histos.fill(HIST("TrackPar/Sigma1Pt_Layer1"), track.pt(), track.sigma1Pt() * track.pt(), collision.centFT0A(), collision.centFT0C()); } if (secondLayerActive) { - histos.fill(HIST("TrackPar/Sigma1Pt_Layer2"), track.pt(), track.sigma1Pt() * track.pt()); + histos.fill(HIST("TrackPar/Sigma1Pt_Layer2"), track.pt(), track.sigma1Pt() * track.pt(), collision.centFT0A(), collision.centFT0C()); } if (firstLayerActive && secondLayerActive) { - histos.fill(HIST("TrackPar/Sigma1Pt_Layers12"), track.pt(), track.sigma1Pt() * track.pt()); + histos.fill(HIST("TrackPar/Sigma1Pt_Layers12"), track.pt(), track.sigma1Pt() * track.pt(), collision.centFT0A(), collision.centFT0C()); } if (fourthLayerActive) { - histos.fill(HIST("TrackPar/Sigma1Pt_Layer4"), track.pt(), track.sigma1Pt() * track.pt()); + histos.fill(HIST("TrackPar/Sigma1Pt_Layer4"), track.pt(), track.sigma1Pt() * track.pt(), collision.centFT0A(), collision.centFT0C()); } if (fifthLayerActive) { - histos.fill(HIST("TrackPar/Sigma1Pt_Layer5"), track.pt(), track.sigma1Pt() * track.pt()); + histos.fill(HIST("TrackPar/Sigma1Pt_Layer5"), track.pt(), track.sigma1Pt() * track.pt(), collision.centFT0A(), collision.centFT0C()); } if (sixthLayerActive) { - histos.fill(HIST("TrackPar/Sigma1Pt_Layer6"), track.pt(), track.sigma1Pt() * track.pt()); + histos.fill(HIST("TrackPar/Sigma1Pt_Layer6"), track.pt(), track.sigma1Pt() * track.pt(), collision.centFT0A(), collision.centFT0C()); } if (fourthLayerActive && fifthLayerActive) { - histos.fill(HIST("TrackPar/Sigma1Pt_Layers45"), track.pt(), track.sigma1Pt() * track.pt()); + histos.fill(HIST("TrackPar/Sigma1Pt_Layers45"), track.pt(), track.sigma1Pt() * track.pt(), collision.centFT0A(), collision.centFT0C()); } if (fifthLayerActive && sixthLayerActive) { - histos.fill(HIST("TrackPar/Sigma1Pt_Layers56"), track.pt(), track.sigma1Pt() * track.pt()); + histos.fill(HIST("TrackPar/Sigma1Pt_Layers56"), track.pt(), track.sigma1Pt() * track.pt(), collision.centFT0A(), collision.centFT0C()); } if (fourthLayerActive && sixthLayerActive) { - histos.fill(HIST("TrackPar/Sigma1Pt_Layers46"), track.pt(), track.sigma1Pt() * track.pt()); + histos.fill(HIST("TrackPar/Sigma1Pt_Layers46"), track.pt(), track.sigma1Pt() * track.pt(), collision.centFT0A(), collision.centFT0C()); } if (fourthLayerActive && fifthLayerActive && sixthLayerActive) { - histos.fill(HIST("TrackPar/Sigma1Pt_Layers456"), track.pt(), track.sigma1Pt() * track.pt()); + histos.fill(HIST("TrackPar/Sigma1Pt_Layers456"), track.pt(), track.sigma1Pt() * track.pt(), collision.centFT0A(), collision.centFT0C()); } // fill ITS variables - histos.fill(HIST("ITS/itsNCls"), track.pt(), track.itsNCls()); - histos.fill(HIST("ITS/itsChi2NCl"), track.pt(), track.itsChi2NCl()); + histos.fill(HIST("ITS/itsNCls"), track.pt(), track.sigma1Pt() * track.pt(), track.itsNCls(), collision.centFT0A(), collision.centFT0C()); + histos.fill(HIST("ITS/itsChi2NCl"), track.pt(), track.sigma1Pt() * track.pt(), track.itsChi2NCl(), collision.centFT0A(), collision.centFT0C()); for (unsigned int i = 0; i < 7; i++) { if (track.itsClusterMap() & (1 << i)) { - histos.fill(HIST("ITS/itsHits"), track.pt(), i); + histos.fill(HIST("ITS/itsHits"), track.pt(), track.sigma1Pt() * track.pt(), i, collision.centFT0A(), collision.centFT0C()); } } // fill TPC variables - histos.fill(HIST("TPC/tpcNClsFindable"), track.pt(), track.tpcNClsFindable()); - histos.fill(HIST("TPC/tpcNClsFound"), track.pt(), track.tpcNClsFound()); - histos.fill(HIST("TPC/tpcNClsShared"), track.pt(), track.tpcNClsShared()); - histos.fill(HIST("TPC/tpcNClsCrossedRows"), track.pt(), track.tpcNClsCrossedRows()); - histos.fill(HIST("TPC/tpcCrossedRowsOverFindableCls"), track.pt(), track.tpcCrossedRowsOverFindableCls()); - histos.fill(HIST("TPC/tpcFractionSharedCls"), track.pt(), track.tpcFractionSharedCls()); - histos.fill(HIST("TPC/tpcChi2NCl"), track.pt(), track.tpcChi2NCl()); - - return true; + histos.fill(HIST("TPC/tpcNClsFindable"), track.pt(), track.sigma1Pt() * track.pt(), track.tpcNClsFindable(), collision.centFT0A(), collision.centFT0C()); + histos.fill(HIST("TPC/tpcNClsFound"), track.pt(), track.sigma1Pt() * track.pt(), track.tpcNClsFound(), collision.centFT0A(), collision.centFT0C()); + histos.fill(HIST("TPC/tpcNClsShared"), track.pt(), track.sigma1Pt() * track.pt(), track.tpcNClsShared(), collision.centFT0A(), collision.centFT0C()); + histos.fill(HIST("TPC/tpcNClsCrossedRows"), track.pt(), track.sigma1Pt() * track.pt(), track.tpcNClsCrossedRows(), collision.centFT0A(), collision.centFT0C()); + histos.fill(HIST("TPC/tpcCrossedRowsOverFindableCls"), track.pt(), track.sigma1Pt() * track.pt(), track.tpcCrossedRowsOverFindableCls(), collision.centFT0A(), collision.centFT0C()); + histos.fill(HIST("TPC/tpcFractionSharedCls"), track.pt(), track.sigma1Pt() * track.pt(), track.tpcFractionSharedCls(), collision.centFT0A(), collision.centFT0C()); + histos.fill(HIST("TPC/tpcChi2NCl"), track.pt(), track.sigma1Pt() * track.pt(), track.tpcChi2NCl(), collision.centFT0A(), collision.centFT0C()); } - // Preslice> trackPerColl = aod::track::collisionId; Preslice trackPerColl = aod::track::collisionId; - // SliceCache cacheTrk; using CollisionCandidate = soa::Join; using TrackCandidates = soa::Join; @@ -325,22 +335,14 @@ struct TrackJetQa { TrackCandidates const& tracks) { for (const auto& collision : collisions) { - if (fillEventQa(collision)) { - - if (fillMultiplicity) { - histos.fill(HIST("Centrality/FT0M"), collision.centFT0M()); - histos.fill(HIST("Mult/FT0M"), collision.multFT0M()); - histos.fill(HIST("Mult/MultCorrelations"), collision.centFT0A(), collision.centFT0C(), collision.multFT0A(), collision.multFT0C(), collision.multNTracksPV()); - } - auto tracksInCollision = tracks.sliceBy(trackPerColl, collision.globalIndex()); - + auto tracksInCollision = tracks.sliceBy(trackPerColl, collision.globalIndex()); + if (checkEventSelection(collision)) { + histos.fill(HIST("EventProp/MultCorrelations"), collision.centFT0A(), collision.centFT0C(), collision.centFT0M(), collision.multFT0A(), collision.multFT0C(), collision.multFT0M(), collision.multNTracksPV(), tracksInCollision.size()); for (const auto& track : tracksInCollision) { - if (track.has_collision() && (collision.globalIndex() == track.collisionId())) { // double check - if (fillTrackQa(track)) { - if (fillMultiplicity) { - histos.fill(HIST("TrackEventPar/Sigma1PtFT0Mcent"), collision.centFT0M(), track.pt(), track.sigma1Pt()); - histos.fill(HIST("TrackEventPar/MultCorrelations"), track.sigma1Pt(), track.pt(), collision.centFT0A(), collision.centFT0C(), collision.multFT0A(), collision.multFT0C(), collision.multNTracksPV()); - } + if (track.has_collision() && (collision.globalIndex() == track.collisionId())) { + if (checkTrackSelection(track)) { + histos.fill(HIST("TrackEventPar/MultCorrelations"), track.pt(), track.sigma1Pt() * track.pt(), collision.centFT0A(), collision.centFT0C(), collision.centFT0M(), collision.multFT0A(), collision.multFT0C(), collision.multFT0M(), collision.multNTracksPV(), tracksInCollision.size()); + fillTrackQa(track, collision); } } } @@ -351,9 +353,25 @@ struct TrackJetQa { } PROCESS_SWITCH(TrackJetQa, processFull, "Standard data processor", true); - void processDerived(aod::JeTracks::iterator const& track) + void processDerived(aod::JeColls const& collisions, aod::JeTracks const& tracks) { - fillTrackQa(track); + for (const auto& collision : collisions) { + if (checkEventSelection(collision)) { + histos.fill(HIST("EventProp/MultCorrelations"), collision.centFT0A(), collision.centFT0C(), collision.centFT0A() + collision.centFT0C(), collision.multFT0A(), collision.multFT0C(), collision.multFT0A() + collision.multFT0C(), collision.multNTracksPV(), collision.multTracks()); + for (const auto& track : tracks) { + if (!(track.collisionId() == collision.globalIdx())) { + continue; + } + // LOGF(info, "Compatible Id's: %d (tracks) and %d (collisions)", track.collisionId(), collision.globalIdx()); + if (checkTrackSelection(track)) { + histos.fill(HIST("TrackEventPar/MultCorrelations"), track.pt(), track.sigma1Pt() * track.pt(), collision.centFT0A(), collision.centFT0C(), collision.centFT0A() + collision.centFT0C(), collision.multFT0A(), collision.multFT0C(), collision.multFT0A() + collision.multFT0C(), collision.multNTracksPV(), collision.multTracks()); + fillTrackQa(track, collision); + } + } + } else { + histos.fill(HIST("EventProp/rejectedCollId"), 1); + } + } } PROCESS_SWITCH(TrackJetQa, processDerived, "Derived data processor", false); }; diff --git a/PWGJE/Tasks/triggerCorrelations.cxx b/PWGJE/Tasks/triggerCorrelations.cxx index e0d551b5968..f8490c9480f 100644 --- a/PWGJE/Tasks/triggerCorrelations.cxx +++ b/PWGJE/Tasks/triggerCorrelations.cxx @@ -65,18 +65,18 @@ struct TriggerCorrelationsTask { aod::EMCALClusterDefinition clusterDef = aod::emcalcluster::getClusterDefinitionFromString(clusterDefinition.value); Filter clusterDefinitionSelection = o2::aod::jcluster::definition == static_cast(clusterDef); - void processTriggeredCorrelations(aod::JCollision const& collision, + void processTriggeredCorrelations(JetCollision const& collision, soa::Join const& jetsCharged, soa::Join const& jetsFull, - soa::Filtered const& clusters, - aod::JTracks const& tracks) + soa::Filtered const& clusters, + JetTracks const& tracks) { registry.fill(HIST("h_collision_trigger_events"), 0.5); // all events if (collision.posZ() < vertexZCut) { registry.fill(HIST("h_collision_trigger_events"), 1.5); // all events with z vertex cut } - if (JetDerivedDataUtilities::selectCollision(collision, JetDerivedDataUtilities::JCollisionSel::sel8)) { + if (jetderiveddatautilities::selectCollision(collision, jetderiveddatautilities::JCollisionSel::sel8)) { registry.fill(HIST("h_collision_trigger_events"), 2.5); // events with sel8() } if (collision.alias_bit(triggerAliases::kTVXinEMC)) { @@ -86,7 +86,7 @@ struct TriggerCorrelationsTask { float jetsChargedLeadingPt = -1.0; float jetsFullLeadingPt = -1.0; float gammaLeadingPt = -1.0; - if (JetDerivedDataUtilities::selectCollision(collision, JetDerivedDataUtilities::JCollisionSel::sel8)) { + if (jetderiveddatautilities::selectCollision(collision, jetderiveddatautilities::JCollisionSel::sel8)) { if (doChargedJetTrigger) { for (auto& jetCharged : jetsCharged) { if (jetCharged.r() == round(jetsChargedR * 100.0f)) { diff --git a/PWGLF/DataModel/LFHypernucleiTables.h b/PWGLF/DataModel/LFHypernucleiTables.h index 026235d67bd..049b93ebb79 100644 --- a/PWGLF/DataModel/LFHypernucleiTables.h +++ b/PWGLF/DataModel/LFHypernucleiTables.h @@ -24,10 +24,23 @@ namespace o2::aod { namespace hyperrec { +DECLARE_SOA_COLUMN(CentralityFT0A, centralityFT0A, float); // centrality with FT0A estimator +DECLARE_SOA_COLUMN(CentralityFT0C, centralityFT0C, float); // centrality with FT0C estimator +DECLARE_SOA_COLUMN(CentralityFT0M, centralityFT0M, float); // centrality with FT0M estimator +DECLARE_SOA_COLUMN(QVecXFT0A, qVecXFT0A, float); // Q vector x component with FT0A estimator +DECLARE_SOA_COLUMN(QVecYFT0A, qVecYFT0A, float); // Q vector y component with FT0A estimator +DECLARE_SOA_COLUMN(QVecAmpFT0A, qVecAmpFT0A, float); // Q vector amplitude with FT0A estimator +DECLARE_SOA_COLUMN(QVecXFT0C, qVecXFT0C, float); // Q vector x component with FT0C estimator +DECLARE_SOA_COLUMN(QVecYFT0C, qVecYFT0C, float); // Q vector y component with FT0C estimator +DECLARE_SOA_COLUMN(QVecAmpFT0C, qVecAmpFT0C, float); // Q vector amplitude with FT0C estimator +DECLARE_SOA_COLUMN(QVecXFT0M, qVecXFT0M, float); // Q vector x component with FT0M estimator +DECLARE_SOA_COLUMN(QVecYFT0M, qVecYFT0M, float); // Q vector y component with FT0M estimator +DECLARE_SOA_COLUMN(QVecAmpFT0M, qVecAmpFT0M, float); // Q vector amplitude with FT0M estimator +DECLARE_SOA_COLUMN(QVecXFV0A, qVecXFV0A, float); // Q vector x component with FV0A estimator +DECLARE_SOA_COLUMN(QVecYFV0A, qVecYFV0A, float); // Q vector y component with FV0A estimator +DECLARE_SOA_COLUMN(QVecAmpFV0A, qVecAmpFV0A, float); // Q vector amplitude with FV0A estimator + DECLARE_SOA_COLUMN(IsMatter, isMatter, bool); // bool: true for matter -DECLARE_SOA_COLUMN(CentralityFT0A, centralityFT0A, float); // centrality with FT0A estimator -DECLARE_SOA_COLUMN(CentralityFT0C, centralityFT0C, float); // centrality with FT0C estimator -DECLARE_SOA_COLUMN(CentralityFT0M, centralityFT0M, float); // centrality with FT0M estimator DECLARE_SOA_COLUMN(PtHe3, ptHe3, float); // Pt of the He daughter DECLARE_SOA_COLUMN(PhiHe3, phiHe3, float); // Phi of the He daughter DECLARE_SOA_COLUMN(EtaHe3, etaHe3, float); // Eta of the He daughter @@ -67,68 +80,53 @@ DECLARE_SOA_COLUMN(IsReco, isReco, bool); // bool: tru DECLARE_SOA_COLUMN(IsSignal, isSignal, bool); // bool: true for signal } // namespace hyperrec -DECLARE_SOA_TABLE(DataHypCands, "AOD", "DATAHYPCANDS", +DECLARE_SOA_TABLE(DataHypCands, "AOD", "HYPCANDS", + o2::soa::Index<>, + hyperrec::CentralityFT0A, hyperrec::CentralityFT0C, hyperrec::CentralityFT0M, + hyperrec::XPrimVtx, hyperrec::YPrimVtx, hyperrec::ZPrimVtx, + + hyperrec::IsMatter, + hyperrec::PtHe3, hyperrec::PhiHe3, hyperrec::EtaHe3, + hyperrec::PtPi, hyperrec::PhiPi, hyperrec::EtaPi, + hyperrec::XDecVtx, hyperrec::YDecVtx, hyperrec::ZDecVtx, + hyperrec::DcaV0Daug, hyperrec::DcaHe, hyperrec::DcaPi, + hyperrec::NSigmaHe, hyperrec::NTPCclusHe, hyperrec::NTPCclusPi, + hyperrec::TPCmomHe, hyperrec::TPCmomPi, hyperrec::TPCsignalHe, hyperrec::TPCsignalPi, + hyperrec::ITSclusterSizesHe, hyperrec::ITSclusterSizesPi, + hyperrec::Flags); + +DECLARE_SOA_TABLE(DataHypCandsFlow, "AOD", "HYPCANDSFLOW", o2::soa::Index<>, + hyperrec::CentralityFT0A, hyperrec::CentralityFT0C, hyperrec::CentralityFT0M, + hyperrec::QVecXFT0A, hyperrec::QVecYFT0A, hyperrec::QVecAmpFT0A, + hyperrec::QVecXFT0C, hyperrec::QVecYFT0C, hyperrec::QVecAmpFT0C, + hyperrec::QVecXFT0M, hyperrec::QVecYFT0M, hyperrec::QVecAmpFT0M, + hyperrec::QVecXFV0A, hyperrec::QVecYFV0A, hyperrec::QVecAmpFV0A, + hyperrec::XPrimVtx, hyperrec::YPrimVtx, hyperrec::ZPrimVtx, + hyperrec::IsMatter, - hyperrec::CentralityFT0A, - hyperrec::CentralityFT0C, - hyperrec::CentralityFT0M, - hyperrec::PtHe3, - hyperrec::PhiHe3, - hyperrec::EtaHe3, - hyperrec::PtPi, - hyperrec::PhiPi, - hyperrec::EtaPi, - hyperrec::XPrimVtx, - hyperrec::YPrimVtx, - hyperrec::ZPrimVtx, - hyperrec::XDecVtx, - hyperrec::YDecVtx, - hyperrec::ZDecVtx, - hyperrec::DcaV0Daug, - hyperrec::DcaHe, - hyperrec::DcaPi, - hyperrec::NSigmaHe, - hyperrec::NTPCclusHe, - hyperrec::NTPCclusPi, - hyperrec::TPCmomHe, - hyperrec::TPCmomPi, - hyperrec::TPCsignalHe, - hyperrec::TPCsignalPi, - hyperrec::ITSclusterSizesHe, - hyperrec::ITSclusterSizesPi, + hyperrec::PtHe3, hyperrec::PhiHe3, hyperrec::EtaHe3, + hyperrec::PtPi, hyperrec::PhiPi, hyperrec::EtaPi, + hyperrec::XDecVtx, hyperrec::YDecVtx, hyperrec::ZDecVtx, + hyperrec::DcaV0Daug, hyperrec::DcaHe, hyperrec::DcaPi, + hyperrec::NSigmaHe, hyperrec::NTPCclusHe, hyperrec::NTPCclusPi, + hyperrec::TPCmomHe, hyperrec::TPCmomPi, hyperrec::TPCsignalHe, hyperrec::TPCsignalPi, + hyperrec::ITSclusterSizesHe, hyperrec::ITSclusterSizesPi, hyperrec::Flags); DECLARE_SOA_TABLE(MCHypCands, "AOD", "MCHYPCANDS", o2::soa::Index<>, + hyperrec::CentralityFT0A, hyperrec::CentralityFT0C, hyperrec::CentralityFT0M, + hyperrec::XPrimVtx, hyperrec::YPrimVtx, hyperrec::ZPrimVtx, + hyperrec::IsMatter, - hyperrec::CentralityFT0A, - hyperrec::CentralityFT0C, - hyperrec::CentralityFT0M, - hyperrec::PtHe3, - hyperrec::PhiHe3, - hyperrec::EtaHe3, - hyperrec::PtPi, - hyperrec::PhiPi, - hyperrec::EtaPi, - hyperrec::XPrimVtx, - hyperrec::YPrimVtx, - hyperrec::ZPrimVtx, - hyperrec::XDecVtx, - hyperrec::YDecVtx, - hyperrec::ZDecVtx, - hyperrec::DcaV0Daug, - hyperrec::DcaHe, - hyperrec::DcaPi, - hyperrec::NSigmaHe, - hyperrec::NTPCclusHe, - hyperrec::NTPCclusPi, - hyperrec::TPCmomHe, - hyperrec::TPCmomPi, - hyperrec::TPCsignalHe, - hyperrec::TPCsignalPi, - hyperrec::ITSclusterSizesHe, - hyperrec::ITSclusterSizesPi, + hyperrec::PtHe3, hyperrec::PhiHe3, hyperrec::EtaHe3, + hyperrec::PtPi, hyperrec::PhiPi, hyperrec::EtaPi, + hyperrec::XDecVtx, hyperrec::YDecVtx, hyperrec::ZDecVtx, + hyperrec::DcaV0Daug, hyperrec::DcaHe, hyperrec::DcaPi, + hyperrec::NSigmaHe, hyperrec::NTPCclusHe, hyperrec::NTPCclusPi, + hyperrec::TPCmomHe, hyperrec::TPCmomPi, hyperrec::TPCsignalHe, hyperrec::TPCsignalPi, + hyperrec::ITSclusterSizesHe, hyperrec::ITSclusterSizesPi, hyperrec::Flags, hyperrec::GenPt, hyperrec::GenPhi, @@ -141,6 +139,7 @@ DECLARE_SOA_TABLE(MCHypCands, "AOD", "MCHYPCANDS", hyperrec::IsSignal); using DataHypCand = DataHypCands::iterator; +using DataHypCandFlow = DataHypCandsFlow::iterator; using MCHypCand = MCHypCands::iterator; } // namespace o2::aod diff --git a/PWGLF/DataModel/LFNucleiTables.h b/PWGLF/DataModel/LFNucleiTables.h index 7ff192ed213..18faf3d37a9 100644 --- a/PWGLF/DataModel/LFNucleiTables.h +++ b/PWGLF/DataModel/LFNucleiTables.h @@ -99,6 +99,7 @@ DECLARE_SOA_COLUMN(ITSChi2NCl, itsChi2NCl, float); // For MC DECLARE_SOA_COLUMN(IsPhysicalPrimary, isPhysicalPrimary, bool); DECLARE_SOA_COLUMN(ProducedByGenerator, producedByGenerator, bool); +DECLARE_SOA_COLUMN(GetProcess, getProcess, int); } // namespace full namespace dummy @@ -230,6 +231,7 @@ DECLARE_SOA_TABLE(LfCandNucleusMC, "AOD", "LFNUCLMC", mcparticle::PdgCode, full::IsPhysicalPrimary, full::ProducedByGenerator, + full::GetProcess, mcparticle::Px, mcparticle::Py, mcparticle::Pz); diff --git a/PWGLF/DataModel/LFSlimNucleiTables.h b/PWGLF/DataModel/LFSlimNucleiTables.h index 02e8b90d303..68da4ee42b6 100644 --- a/PWGLF/DataModel/LFSlimNucleiTables.h +++ b/PWGLF/DataModel/LFSlimNucleiTables.h @@ -16,6 +16,7 @@ #include "Framework/AnalysisDataModel.h" #include "Framework/ASoAHelpers.h" +#include "Common/DataModel/Centrality.h" #ifndef PWGLF_DATAMODEL_LFSLIMNUCLEITABLES_H_ #define PWGLF_DATAMODEL_LFSLIMNUCLEITABLES_H_ @@ -40,12 +41,71 @@ DECLARE_SOA_COLUMN(TPCfindableCls, tpcFindableCls, uint8_t); DECLARE_SOA_COLUMN(TPCcrossedRows, tpcCrossedRows, uint8_t); DECLARE_SOA_COLUMN(ITSclsMap, itsClsMap, uint8_t); DECLARE_SOA_COLUMN(TPCnCls, tpcNCls, uint8_t); +DECLARE_SOA_COLUMN(ITSclusterSizes, itsClusterSizes, uint32_t); DECLARE_SOA_COLUMN(gPt, genPt, float); DECLARE_SOA_COLUMN(gEta, genEta, float); DECLARE_SOA_COLUMN(gPhi, genPhi, float); DECLARE_SOA_COLUMN(PDGcode, pdgCode, int); } // namespace NucleiTableNS +namespace NucleiFlowTableNS +{ +DECLARE_SOA_COLUMN(CentFV0A, centFV0A, float); +DECLARE_SOA_COLUMN(CentFT0M, centFT0M, float); +DECLARE_SOA_COLUMN(CentFT0A, centFT0A, float); +DECLARE_SOA_COLUMN(CentFT0C, centFT0C, float); +DECLARE_SOA_COLUMN(XQvecFV0A, xQvecFV0A, float); +DECLARE_SOA_COLUMN(YQvecFV0A, yQvecFV0A, float); +DECLARE_SOA_COLUMN(AmplQvecFV0A, amplQvecFV0A, float); +DECLARE_SOA_COLUMN(XQvecFT0M, xQvecFT0M, float); +DECLARE_SOA_COLUMN(YQvecFT0M, yQvecFT0M, float); +DECLARE_SOA_COLUMN(AmplQvecFT0M, amplQvecFT0M, float); +DECLARE_SOA_COLUMN(XQvecFT0A, xQvecFT0A, float); +DECLARE_SOA_COLUMN(YQvecFT0A, yQvecFT0A, float); +DECLARE_SOA_COLUMN(AmplQvecFT0A, amplQvecFT0A, float); +DECLARE_SOA_COLUMN(XQvecFT0C, xQvecFT0C, float); +DECLARE_SOA_COLUMN(YQvecFT0C, yQvecFT0C, float); +DECLARE_SOA_COLUMN(AmplQvecFT0C, amplQvecFT0C, float); +DECLARE_SOA_COLUMN(XQvecTPCpos, xQvecTPCpos, float); +DECLARE_SOA_COLUMN(YQvecTPCpos, yQvecTPCpos, float); +DECLARE_SOA_COLUMN(AmplQvecTPCpos, amplQvecTPCpos, float); +DECLARE_SOA_COLUMN(XQvecTPCneg, xQvecTPCneg, float); +DECLARE_SOA_COLUMN(YQvecTPCneg, yQvecTPCneg, float); +DECLARE_SOA_COLUMN(AmplQvecTPCneg, amplQvecTPCneg, float); +} // namespace NucleiFlowTableNS + +DECLARE_SOA_TABLE(NucleiFlowColls, "AOD", "NUCLEIFLOWCOLL", + o2::soa::Index<>, + NucleiFlowTableNS::CentFV0A, + NucleiFlowTableNS::CentFT0M, + NucleiFlowTableNS::CentFT0A, + NucleiFlowTableNS::CentFT0C, + NucleiFlowTableNS::XQvecFV0A, + NucleiFlowTableNS::YQvecFV0A, + NucleiFlowTableNS::AmplQvecFV0A, + NucleiFlowTableNS::XQvecFT0M, + NucleiFlowTableNS::YQvecFT0M, + NucleiFlowTableNS::AmplQvecFT0M, + NucleiFlowTableNS::XQvecFT0A, + NucleiFlowTableNS::YQvecFT0A, + NucleiFlowTableNS::AmplQvecFT0A, + NucleiFlowTableNS::XQvecFT0C, + NucleiFlowTableNS::YQvecFT0C, + NucleiFlowTableNS::AmplQvecFT0C, + NucleiFlowTableNS::XQvecTPCpos, + NucleiFlowTableNS::YQvecTPCpos, + NucleiFlowTableNS::AmplQvecTPCpos, + NucleiFlowTableNS::XQvecTPCneg, + NucleiFlowTableNS::YQvecTPCneg, + NucleiFlowTableNS::AmplQvecTPCneg) + +using NucleiFlowColl = NucleiFlowColls::iterator; + +namespace NucleiTableNS +{ +DECLARE_SOA_INDEX_COLUMN(NucleiFlowColl, nucleiFlowColl); +} + DECLARE_SOA_TABLE(NucleiTable, "AOD", "NUCLEITABLE", NucleiTableNS::Pt, NucleiTableNS::Eta, @@ -62,7 +122,9 @@ DECLARE_SOA_TABLE(NucleiTable, "AOD", "NUCLEITABLE", NucleiTableNS::TPCfindableCls, NucleiTableNS::TPCcrossedRows, NucleiTableNS::ITSclsMap, - NucleiTableNS::TPCnCls) + NucleiTableNS::TPCnCls, + NucleiTableNS::ITSclusterSizes, + NucleiTableNS::NucleiFlowCollId) DECLARE_SOA_TABLE(NucleiTableMC, "AOD", "NUCLEITABLEMC", NucleiTableNS::Pt, @@ -81,6 +143,7 @@ DECLARE_SOA_TABLE(NucleiTableMC, "AOD", "NUCLEITABLEMC", NucleiTableNS::TPCcrossedRows, NucleiTableNS::ITSclsMap, NucleiTableNS::TPCnCls, + NucleiTableNS::ITSclusterSizes, NucleiTableNS::gPt, NucleiTableNS::gEta, NucleiTableNS::gPhi, diff --git a/PWGLF/DataModel/LFSlimStrangeTables.h b/PWGLF/DataModel/LFSlimStrangeTables.h new file mode 100644 index 00000000000..8a68e17fda4 --- /dev/null +++ b/PWGLF/DataModel/LFSlimStrangeTables.h @@ -0,0 +1,83 @@ +// 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. + +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" + +#ifndef PWGLF_DATAMODEL_LFSLIMSTRANGETABLES_H_ +#define PWGLF_DATAMODEL_LFSLIMSTRANGETABLES_H_ + +namespace o2::aod +{ + +namespace SlimLambdaTables +{ +DECLARE_SOA_COLUMN(Pt, pt, float); +DECLARE_SOA_COLUMN(Eta, eta, float); +DECLARE_SOA_COLUMN(CentFT0C, centFT0C, float); +DECLARE_SOA_COLUMN(IsMatter, isMatter, bool); +DECLARE_SOA_COLUMN(Mass, mass, float); +DECLARE_SOA_COLUMN(Ct, ct, float); +DECLARE_SOA_COLUMN(Radius, radius, float); +DECLARE_SOA_COLUMN(DcaV0PV, dcaV0Pv, float); +DECLARE_SOA_COLUMN(DcaPiPV, dcaPiPv, float); +DECLARE_SOA_COLUMN(DcaPrPV, dcaPrPv, float); +DECLARE_SOA_COLUMN(DcaV0Tracks, dcaV0tracks, float); +DECLARE_SOA_COLUMN(CosPA, cosPa, double); +DECLARE_SOA_COLUMN(TpcNsigmaPi, tpcNsigmaPi, float); +DECLARE_SOA_COLUMN(TpcNsigmaPr, tpcNsigmaPr, float); +DECLARE_SOA_COLUMN(GenPt, gentPt, float); +DECLARE_SOA_COLUMN(GenEta, genEta, float); +DECLARE_SOA_COLUMN(GenCt, genCt, float); +DECLARE_SOA_COLUMN(PDGCode, pdgCode, int); +DECLARE_SOA_COLUMN(IsReco, isReco, bool); +} // namespace SlimLambdaTables + +DECLARE_SOA_TABLE(LambdaTableML, "AOD", "LAMBDATABLEML", + SlimLambdaTables::Pt, + SlimLambdaTables::Eta, + SlimLambdaTables::CentFT0C, + SlimLambdaTables::IsMatter, + SlimLambdaTables::Mass, + SlimLambdaTables::Ct, + SlimLambdaTables::Radius, + SlimLambdaTables::DcaV0PV, + SlimLambdaTables::DcaPiPV, + SlimLambdaTables::DcaPrPV, + SlimLambdaTables::DcaV0Tracks, + SlimLambdaTables::CosPA, + SlimLambdaTables::TpcNsigmaPi, + SlimLambdaTables::TpcNsigmaPr); + +DECLARE_SOA_TABLE(McLambdaTableML, "AOD", "MCLAMBDATABLEML", + SlimLambdaTables::Pt, + SlimLambdaTables::Eta, + SlimLambdaTables::CentFT0C, + SlimLambdaTables::IsMatter, + SlimLambdaTables::Mass, + SlimLambdaTables::Ct, + SlimLambdaTables::Radius, + SlimLambdaTables::DcaV0PV, + SlimLambdaTables::DcaPiPV, + SlimLambdaTables::DcaPrPV, + SlimLambdaTables::DcaV0Tracks, + SlimLambdaTables::CosPA, + SlimLambdaTables::TpcNsigmaPi, + SlimLambdaTables::TpcNsigmaPr, + SlimLambdaTables::GenPt, + SlimLambdaTables::GenEta, + SlimLambdaTables::GenCt, + SlimLambdaTables::PDGCode, + SlimLambdaTables::IsReco); + +} // namespace o2::aod + +#endif // PWGLF_DATAMODEL_LFSLIMSTRANGETABLES_H_ diff --git a/PWGLF/DataModel/LFStrangenessTables.h b/PWGLF/DataModel/LFStrangenessTables.h index 9d962372322..40ad9d5829a 100644 --- a/PWGLF/DataModel/LFStrangenessTables.h +++ b/PWGLF/DataModel/LFStrangenessTables.h @@ -16,6 +16,7 @@ #include "Common/Core/RecoDecay.h" #include "CommonConstants/PhysicsConstants.h" #include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/Qvectors.h" @@ -30,19 +31,23 @@ DECLARE_SOA_TABLE(StraCollisions, "AOD", "STRACOLLISION", //! basic collision pr DECLARE_SOA_TABLE(StraCents, "AOD", "STRACENTS", //! centrality percentiles cent::CentFT0M, cent::CentFT0A, cent::CentFT0C, cent::CentFV0A); +DECLARE_SOA_TABLE(StraRawCents, "AOD", "STRARAWCENTS", //! debug information + mult::MultFT0A, mult::MultFT0C, mult::MultFV0A, mult::MultNTracksPVeta1); DECLARE_SOA_TABLE(StraEvSels, "AOD", "STRAEVSELS", //! event selection: sel8 evsel::Sel8); -DECLARE_SOA_TABLE(StraEPs, "AOD", "STRAEPS", //! centrality percentiles - qvec::QvecFT0ARe, qvec::QvecFT0AIm, qvec::SumAmplFT0A, - qvec::QvecFT0CRe, qvec::QvecFT0CIm, qvec::SumAmplFT0C, - qvec::QvecFT0MRe, qvec::QvecFT0MIm, qvec::SumAmplFT0M, +DECLARE_SOA_TABLE(StraFT0AQVs, "AOD", "STRAFT0AQVS", //! t0a Qvec + qvec::QvecFT0ARe, qvec::QvecFT0AIm, qvec::SumAmplFT0A); +DECLARE_SOA_TABLE(StraFT0CQVs, "AOD", "STRAFT0CQVS", //! t0c Qvec + qvec::QvecFT0CRe, qvec::QvecFT0CIm, qvec::SumAmplFT0C); +DECLARE_SOA_TABLE(StraFT0MQVs, "AOD", "STRAFT0MQVS", //! t0m Qvec + qvec::QvecFT0MRe, qvec::QvecFT0MIm, qvec::SumAmplFT0M); +DECLARE_SOA_TABLE(StraFV0AQVs, "AOD", "STRAFV0AQVS", //! v0a Qvec qvec::QvecFV0ARe, qvec::QvecFV0AIm, qvec::SumAmplFV0A); DECLARE_SOA_TABLE(StraStamps, "AOD", "STRASTAMPS", //! information for ID-ing mag field if needed bc::RunNumber, timestamp::Timestamp); using StraCollision = StraCollisions::iterator; using StraCent = StraCents::iterator; -using StraEP = StraEPs::iterator; namespace dautrack { @@ -143,6 +148,14 @@ DECLARE_SOA_COLUMN(X, x, float); //! decay position X DECLARE_SOA_COLUMN(Y, y, float); //! decay position Y DECLARE_SOA_COLUMN(Z, z, float); //! decay position Z +// decay daughter positions for refit studies (specific purpose) +DECLARE_SOA_COLUMN(XPosAtDCA, xPosAtDCA, float); //! decay position X +DECLARE_SOA_COLUMN(YPosAtDCA, yPosAtDCA, float); //! decay position Y +DECLARE_SOA_COLUMN(ZPosAtDCA, zPosAtDCA, float); //! decay position Z +DECLARE_SOA_COLUMN(XNegAtDCA, xNegAtDCA, float); //! decay position X +DECLARE_SOA_COLUMN(YNegAtDCA, yNegAtDCA, float); //! decay position Y +DECLARE_SOA_COLUMN(ZNegAtDCA, zNegAtDCA, float); //! decay position Z + // Saved from finding: DCAs DECLARE_SOA_COLUMN(DCAV0Daughters, dcaV0daughters, float); //! DCA between V0 daughters DECLARE_SOA_COLUMN(DCAPosToPV, dcapostopv, float); //! DCA positive prong to PV @@ -399,6 +412,10 @@ DECLARE_SOA_TABLE_FULL(StoredV0Cores, "V0Cores", "AOD", "V0CORE", //! core infor DECLARE_SOA_EXTENDED_TABLE_USER(V0Cores, StoredV0Cores, "V0COREEXT", //! v0data::Px, v0data::Py, v0data::Pz, v0data::Pt, v0data::P, v0data::Phi, v0data::Eta); // the table name has here to be the one with EXT which is not nice and under study +DECLARE_SOA_TABLE(V0TraPosAtDCAs, "AOD", "V0TRAPOSATDCAs", //! positions of tracks at their DCA for debug + v0data::XPosAtDCA, v0data::YPosAtDCA, v0data::ZPosAtDCA, + v0data::XNegAtDCA, v0data::YNegAtDCA, v0data::ZNegAtDCA); + DECLARE_SOA_TABLE_FULL(V0Covs, "V0Covs", "AOD", "V0COVS", //! V0 covariance matrices v0data::PositionCovMat, v0data::MomentumCovMat, o2::soa::Marker<1>); @@ -481,10 +498,10 @@ using V0MCData = V0MCDatas::iterator; // definitions of indices for interlink tables namespace v0data { -DECLARE_SOA_INDEX_COLUMN(V0Data, v0Data); //! Index to V0Data entry +DECLARE_SOA_INDEX_COLUMN(V0Data, v0Data); //! Index to V0Data entry DECLARE_SOA_INDEX_COLUMN(V0fCData, v0fCData); //! Index to V0Data entry DECLARE_SOA_INDEX_COLUMN_FULL(V0MC, v0MC, int, V0MCCores, "_MC"); //! -} +} // namespace v0data DECLARE_SOA_TABLE(V0DataLink, "AOD", "V0DATALINK", //! Joinable table with V0s which links to V0Data which is not produced for all entries o2::soa::Index<>, v0data::V0DataId, v0data::V0fCDataId); @@ -982,10 +999,10 @@ using CascDataExt = CascDatas; namespace cascdata { -DECLARE_SOA_INDEX_COLUMN(CascData, cascData); //! Index to CascData entry -DECLARE_SOA_INDEX_COLUMN(KFCascData, kfCascData); //! Index to CascData entry +DECLARE_SOA_INDEX_COLUMN(CascData, cascData); //! Index to CascData entry +DECLARE_SOA_INDEX_COLUMN(KFCascData, kfCascData); //! Index to CascData entry DECLARE_SOA_INDEX_COLUMN(TraCascData, traCascData); //! Index to CascData entry -} +} // namespace cascdata DECLARE_SOA_TABLE(CascDataLink, "AOD", "CASCDATALINK", //! Joinable table with Cascades which links to CascData which is not produced for all entries cascdata::CascDataId); @@ -1029,7 +1046,7 @@ DECLARE_SOA_TABLE(CascTags, "AOD", "CASCTAGS", // Definition of labels for V0s namespace mcv0label { -DECLARE_SOA_INDEX_COLUMN(McParticle, mcParticle); //! MC particle for V0 +DECLARE_SOA_INDEX_COLUMN(McParticle, mcParticle); //! MC particle for V0 DECLARE_SOA_INDEX_COLUMN_FULL(McMotherParticle, mcMotherParticle, int, McParticles, "_Mother"); //! } // namespace mcv0label @@ -1050,9 +1067,9 @@ using McFullV0Label = McFullV0Labels::iterator; // Definition of labels for cascades namespace mccasclabel { -DECLARE_SOA_INDEX_COLUMN(McParticle, mcParticle); //! MC particle for Cascade +DECLARE_SOA_INDEX_COLUMN(McParticle, mcParticle); //! MC particle for Cascade DECLARE_SOA_INDEX_COLUMN_FULL(McMotherParticle, mcMotherParticle, int, McParticles, "_Mother"); //! -DECLARE_SOA_COLUMN(IsBachBaryonCandidate, isBachBaryonCandidate, bool); //! will this be built or not? +DECLARE_SOA_COLUMN(IsBachBaryonCandidate, isBachBaryonCandidate, bool); //! will this be built or not? } // namespace mccasclabel DECLARE_SOA_TABLE(McCascLabels, "AOD", "MCCASCLABEL", //! Table joinable with CascData containing the MC labels diff --git a/PWGLF/TableProducer/CMakeLists.txt b/PWGLF/TableProducer/CMakeLists.txt index e5c2e28f318..d3a58259240 100644 --- a/PWGLF/TableProducer/CMakeLists.txt +++ b/PWGLF/TableProducer/CMakeLists.txt @@ -18,7 +18,6 @@ o2physics_add_dpl_workflow(tpcpid COMPONENT_NAME Analysis) # Strangeness - o2physics_add_dpl_workflow(lambdakzerobuilder SOURCES lambdakzerobuilder.cxx PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore @@ -84,6 +83,22 @@ o2physics_add_dpl_workflow(st-coll-ids PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(strange-tree-creator + SOURCES LFStrangeTreeCreator.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +# strange derived - spawners +o2physics_add_dpl_workflow(lambdakzerospawner + SOURCES lambdakzerospawner.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(cascadespawner + SOURCES cascadespawner.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + # Nuclei o2physics_add_dpl_workflow(nucleustreecreator SOURCES LFTreeCreatorNuclei.cxx diff --git a/PWGLF/TableProducer/LFResonanceInitializer.cxx b/PWGLF/TableProducer/LFResonanceInitializer.cxx index 52c9dd91022..af0b961ea9c 100644 --- a/PWGLF/TableProducer/LFResonanceInitializer.cxx +++ b/PWGLF/TableProducer/LFResonanceInitializer.cxx @@ -325,14 +325,19 @@ struct reso2initializer { switch (multEstimator) { case 0: returnValue = ResoEvents.centFT0M(); + break; case 1: returnValue = ResoEvents.centFT0C(); + break; case 2: returnValue = ResoEvents.centFT0A(); + break; case 99: returnValue = ResoEvents.centFV0A(); + break; default: returnValue = ResoEvents.centFT0M(); + break; } return returnValue; } @@ -345,14 +350,19 @@ struct reso2initializer { switch (multEstimator) { case 0: returnValue = ResoEvents.multFT0M(); + break; case 1: returnValue = ResoEvents.multFT0C(); + break; case 2: returnValue = ResoEvents.multFT0A(); + break; case 99: returnValue = ResoEvents.multFV0A(); + break; default: returnValue = ResoEvents.multFT0M(); + break; } return returnValue; } diff --git a/PWGLF/TableProducer/LFStrangeTreeCreator.cxx b/PWGLF/TableProducer/LFStrangeTreeCreator.cxx new file mode 100644 index 00000000000..11815e69a42 --- /dev/null +++ b/PWGLF/TableProducer/LFStrangeTreeCreator.cxx @@ -0,0 +1,431 @@ +// 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. + +#include +#include +#include + +#include "Framework/runDataProcessing.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/DataModel/EventSelection.h" +#include "PWGLF/DataModel/LFStrangenessTables.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/Core/PID/TPCPIDResponse.h" +#include "Common/DataModel/PIDResponse.h" + +#include "PWGLF/DataModel/LFSlimStrangeTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +using TracksFull = soa::Join; +using TracksFullMC = soa::Join; + +struct CandidateV0 { + float pt; + float eta; + float centFT0C; + bool isMatter; + float mass; + float ct; + float radius; + float dcaV0PV; + float dcaPiPV; + float dcaPrPV; + float dcaV0Tracks; + float cosPA; + float tpcNsigmaPi; + float tpcNsigmaPr; + float genPt; + float genEta; + float genCt; + int pdgCode; + bool isReco; + int64_t globalIndexPos = -999; + int64_t globalIndexNeg = -999; +}; + +struct LFStrangeTreeCreator { + + std::mt19937 gen32; + + Produces lambdaTableML; + Produces mcLambdaTableML; + std::vector candidateV0s; + std::vector checkedV0s; + + Service ccdb; + + Configurable downscaleFactor{"downscaleFactor", 1.f, "downscaling factor"}; + Configurable fillOnlySignal{"fillOnlySignal", true, "toggle table filling of signal-only candidates (for mc)"}; + Configurable fillNonRecSignal{"fillNonRecSignal", true, "toggle table filling of non-reco signal candidates (for mc)"}; + Configurable cfgMaterialCorrection{"cfgMaterialCorrection", static_cast(o2::base::Propagator::MatCorrType::USEMatCorrNONE), "Type of material correction"}; + + ConfigurableAxis zVtxAxis{"zVtxBins", {100, -20.f, 20.f}, "Binning for the vertex z in cm"}; + ConfigurableAxis massLambdaAxis{"massLambdaAxis", {400, o2::constants::physics::MassLambda0 - 0.05f, o2::constants::physics::MassLambda0 + 0.05f}, "binning for the lambda invariant-mass"}; + ConfigurableAxis centAxis{"centAxis", {106, 0, 106}, "binning for the centrality"}; + + ConfigurableAxis cosPaAxis{"cosPaAxis", {1e3, 0.95f, 1.00f}, "binning for the cosPa axis"}; + ConfigurableAxis radiusAxis{"radiusAxis", {1e3, 0.f, 100.f}, "binning for the radius axis"}; + ConfigurableAxis dcaV0daughAxis{"dcaV0daughAxis", {2e2, 0.f, 2.f}, "binning for the dca of V0 daughters"}; + ConfigurableAxis dcaDaughPvAxis{"dcaDaughPvAxis", {1e3, 0.f, 10.f}, "binning for the dca of positive daughter to PV"}; + + // CCDB options + Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; + 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 pidPath{"pidPath", "", "Path to the PID response object"}; + + Configurable zVtxMax{"zVtxMax", 10.0f, "maximum z position of the primary vertex"}; + Configurable etaMax{"etaMax", 0.8f, "maximum eta"}; + + Configurable lambdaPtMin{"lambdaPtMin", 0.5f, "minimum (anti)lambda pT (GeV/c)"}; + Configurable lambdaPtMax{"lambdaPtMax", 3.0f, "maximum (anti)lambda pT (GeV/c)"}; + + Configurable v0setting_dcav0dau{"v0setting_dcav0dau", 1, "DCA V0 Daughters"}; + Configurable v0setting_dcapostopv{"v0setting_dcapostopv", 0.1f, "DCA Pos To PV"}; + Configurable v0setting_dcanegtopv{"v0setting_dcanegtopv", 0.1f, "DCA Neg To PV"}; + Configurable v0setting_cospa{"v0setting_cospa", 0.98, "V0 CosPA"}; + Configurable v0setting_radius{"v0setting_radius", 0.5f, "v0radius"}; + Configurable lambdaMassCut{"lambdaMassCut", 0.05f, "maximum deviation from PDG mass"}; + + int mRunNumber; + float d_bz; + + uint32_t randomSeed = 0.; + + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + Preslice> perCollision = aod::v0data::collisionId; + std::vector filledMothers; + + template + void fillRecoLambda(Collision const& collision, RecV0s const& v0s, T const& tracks) + { + candidateV0s.clear(); + + CandidateV0 candV0; + for (const auto& v0 : v0s) { + if (v0.pt() < lambdaPtMin || v0.pt() > lambdaPtMax) { + continue; + } + + if (std::abs(v0.dcapostopv()) < v0setting_dcapostopv && + std::abs(v0.dcanegtopv()) < v0setting_dcanegtopv && + std::abs(v0.dcaV0daughters()) > v0setting_dcav0dau) { + continue; + } + + if (std::abs(v0.eta()) > etaMax || + v0.v0cosPA() < v0setting_cospa || + v0.v0radius() < v0setting_radius) { + return; + } + auto mLambda = v0.alpha() > 0 ? v0.mLambda() : v0.mAntiLambda(); + if (std::abs(mLambda - o2::constants::physics::MassLambda0) > lambdaMassCut) { + return; + } + + auto pos = v0.template posTrack_as(); + auto neg = v0.template negTrack_as(); + if (std::abs(pos.eta()) > etaMax || std::abs(pos.eta()) > etaMax) { + return; + } + + bool matter = v0.alpha() > 0; + histos.fill(HIST("massLambda"), matter ? v0.mLambda() : v0.mAntiLambda()); + histos.fill(HIST("cosPa"), v0.v0cosPA()); + histos.fill(HIST("radius"), v0.v0radius()); + histos.fill(HIST("dcaV0daugh"), v0.dcaV0daughters()); + histos.fill(HIST("dcaPosPv"), v0.dcapostopv()); + histos.fill(HIST("dcaNegPv"), v0.dcanegtopv()); + + float ct = v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0; + float tpcNsigmaPi = matter ? neg.tpcNSigmaPi() : pos.tpcNSigmaPi(); + float tpcNsigmaPr = matter ? pos.tpcNSigmaPr() : neg.tpcNSigmaPr(); + + candV0.pt = v0.pt(); + candV0.eta = v0.eta(); + candV0.centFT0C = collision.centFT0C(); + candV0.isMatter = matter; + candV0.mass = matter ? v0.mLambda() : v0.mAntiLambda(); + candV0.ct = ct; + candV0.radius = v0.v0radius(); + candV0.dcaV0PV = v0.dcav0topv(); + candV0.dcaPiPV = matter ? v0.dcanegtopv() : v0.dcapostopv(); + candV0.dcaPrPV = matter ? v0.dcapostopv() : v0.dcanegtopv(); + candV0.dcaV0Tracks = v0.dcaV0daughters(); + candV0.cosPA = v0.v0cosPA(); + candV0.tpcNsigmaPi = tpcNsigmaPi; + candV0.tpcNsigmaPr = tpcNsigmaPr; + candV0.globalIndexPos = pos.globalIndex(); + candV0.globalIndexNeg = neg.globalIndex(); + + candidateV0s.emplace_back(candV0); + // LOGF(info, "v0.pt = %f", candV0.pt); + } + } + + template + void fillMcLambda(Collision const& collision, RecV0s const& v0s, T const& tracks, aod::McParticles const&, aod::McTrackLabels const& mcLabels) + { + fillRecoLambda(collision, v0s, tracks); + for (auto& candidateV0 : candidateV0s) { + candidateV0.isReco = true; + auto mcLabPos = mcLabels.rawIteratorAt(candidateV0.globalIndexPos); + auto mcLabNeg = mcLabels.rawIteratorAt(candidateV0.globalIndexNeg); + + if (mcLabPos.has_mcParticle() && mcLabNeg.has_mcParticle()) { + auto mcTrackPos = mcLabPos.template mcParticle_as(); + auto mcTrackNeg = mcLabNeg.template mcParticle_as(); + if (mcTrackPos.has_mothers() && mcTrackNeg.has_mothers()) { + for (auto& negMother : mcTrackNeg.template mothers_as()) { + for (auto& posMother : mcTrackPos.template mothers_as()) { + if (posMother.globalIndex() != negMother.globalIndex()) + continue; + if (!((mcTrackPos.pdgCode() == 2212 && mcTrackNeg.pdgCode() == -211) || (mcTrackPos.pdgCode() == 211 && mcTrackNeg.pdgCode() == -1 * 2212))) // TODO: check warning for constant comparison + continue; + if (std::abs(posMother.pdgCode()) != 3122) + continue; + + auto posPrimVtx = std::array{posMother.vx(), posMother.vy(), posMother.vz()}; + auto secVtx = std::array{mcTrackPos.vx(), mcTrackPos.vy(), mcTrackPos.vz()}; + candidateV0.genPt = std::hypot(posMother.px(), posMother.py()); + auto mom = std::sqrt(std::pow(posMother.px(), 2) + std::pow(posMother.py(), 2) + std::pow(posMother.pz(), 2)); + auto len = std::sqrt(std::pow(secVtx[0] - posPrimVtx[0], 2) + std::pow(secVtx[1] - posPrimVtx[1], 2) + std::pow(secVtx[2] - posPrimVtx[2], 2)); + candidateV0.pdgCode = posMother.pdgCode(); + candidateV0.genEta = posMother.eta(); + candidateV0.genCt = len / (mom + 1e-10) * o2::constants::physics::MassLambda0; + checkedV0s.push_back(posMother.globalIndex()); + } + } + } + } + } + } + + void init(o2::framework::InitContext&) + { + ccdb->setURL(ccdburl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(false); + + mRunNumber = 0; + d_bz = 0; + + randomSeed = static_cast(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); + + histos.add("zVtx", ";#it{z}_{vtx} (cm);Entries", HistType::kTH1F, {zVtxAxis}); + + // v0 QA + histos.add("massLambda", ";#it{M}(p + #pi^{-}) (GeV/#it{c}^{2});Entries", {HistType::kTH1F, {massLambdaAxis}}); + histos.add("cosPa", ";cosPa;Entries", {HistType::kTH1F}, {cosPaAxis}); + histos.add("radius", ";radius;Entries", {HistType::kTH1F}, {radiusAxis}); + histos.add("dcaV0daugh", ";dcaV0daugh;Entries", {HistType::kTH1F}, {dcaV0daughAxis}); + histos.add("dcaPosPv", ";dcaPosPv;Entries", {HistType::kTH1F}, {dcaDaughPvAxis}); + histos.add("dcaNegPv", ";dcaNegPv;Entries", {HistType::kTH1F}, {dcaDaughPvAxis}); + } + + void initCCDB(aod::BCsWithTimestamps::iterator const& bc) + { + if (mRunNumber == bc.runNumber()) { + return; + } + auto run3grp_timestamp = bc.timestamp(); + + o2::parameters::GRPObject* grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); + o2::parameters::GRPMagField* grpmag = 0x0; + if (grpo) { + o2::base::Propagator::initFieldFromGRP(grpo); + if (d_bz_input < -990) { + // 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 { + d_bz = d_bz_input; + } + } 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); + if (d_bz_input < -990) { + // 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"; + } else { + d_bz = d_bz_input; + } + } + mRunNumber = bc.runNumber(); + } + + void processData(soa::Join::iterator const& collision, TracksFull const& tracks, aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) + { + auto bc = collision.bc_as(); + initCCDB(bc); + + if (!collision.sel8()) + return; + + if (std::abs(collision.posZ()) > zVtxMax) + return; + + histos.fill(HIST("zVtx"), collision.posZ()); + + if (downscaleFactor < 1.f && (static_cast(rand_r(&randomSeed)) / static_cast(RAND_MAX)) > downscaleFactor) { + return; + } + + fillRecoLambda(collision, V0s, tracks); + for (auto& candidateV0 : candidateV0s) { + // LOG(info) << candidateV0.pt; + lambdaTableML( + candidateV0.pt, + candidateV0.eta, + candidateV0.centFT0C, + candidateV0.isMatter, + candidateV0.mass, + candidateV0.ct, + candidateV0.radius, + candidateV0.dcaV0PV, + candidateV0.dcaPiPV, + candidateV0.dcaPrPV, + candidateV0.dcaV0Tracks, + candidateV0.cosPA, + candidateV0.tpcNsigmaPi, + candidateV0.tpcNsigmaPr); + } + } + PROCESS_SWITCH(LFStrangeTreeCreator, processData, "process data", false); + + void processMC(soa::Join const& collisions, TracksFull const& tracks, aod::V0Datas const& V0s, aod::BCsWithTimestamps const&, aod::McParticles const& mcParticles, aod::McTrackLabels const& mcLabels) + { + for (auto& collision : collisions) { + auto bc = collision.bc_as(); + initCCDB(bc); + + if (!collision.sel8()) + return; + + if (std::abs(collision.posZ()) > zVtxMax) + return; + + const uint64_t collIdx = collision.globalIndex(); + auto V0Table_thisCollision = V0s.sliceBy(perCollision, collIdx); + V0Table_thisCollision.bindExternalIndices(&tracks); + + histos.fill(HIST("zVtx"), collision.posZ()); + + if (downscaleFactor < 1.f && (static_cast(rand_r(&randomSeed)) / static_cast(RAND_MAX)) > downscaleFactor) { + return; + } + + fillMcLambda(collision, V0Table_thisCollision, tracks, mcParticles, mcLabels); + + for (auto& candidateV0 : candidateV0s) { + if ((fillOnlySignal && std::abs(candidateV0.pdgCode) == 3122) || !fillOnlySignal) { + mcLambdaTableML( + candidateV0.pt, + candidateV0.eta, + candidateV0.centFT0C, + candidateV0.isMatter, + candidateV0.mass, + candidateV0.ct, + candidateV0.radius, + candidateV0.dcaV0PV, + candidateV0.dcaPiPV, + candidateV0.dcaPrPV, + candidateV0.dcaV0Tracks, + candidateV0.cosPA, + candidateV0.tpcNsigmaPi, + candidateV0.tpcNsigmaPr, + candidateV0.genPt, + candidateV0.genEta, + candidateV0.genCt, + candidateV0.pdgCode, + candidateV0.isReco); + } + } + } + + if (fillNonRecSignal) { + for (auto& mcPart : mcParticles) { + + if (std::abs(mcPart.pdgCode()) != 3122) + continue; + std::array secVtx; + std::array primVtx = {mcPart.vx(), mcPart.vy(), mcPart.vz()}; + std::array momMother = {mcPart.px(), mcPart.py(), mcPart.pz()}; + for (auto& mcDaught : mcPart.daughters_as()) { + if (std::abs(mcDaught.pdgCode()) == 2212) { + secVtx = {mcDaught.vx(), mcDaught.vy(), mcDaught.vz()}; + break; + } + } + if (std::find(checkedV0s.begin(), checkedV0s.end(), mcPart.globalIndex()) != std::end(checkedV0s)) { + continue; + } + CandidateV0 candidateV0; + auto momV0 = std::sqrt(std::pow(momMother[0], 2) + std::pow(momMother[1], 2) + std::pow(momMother[2], 2)); + candidateV0.genCt = std::sqrt(std::pow(secVtx[0] - primVtx[0], 2) + std::pow(secVtx[1] - primVtx[1], 2) + std::pow(secVtx[2] - primVtx[2], 2)) / (momV0 + 1e-10) * o2::constants::physics::MassLambda0; + candidateV0.isReco = false; + candidateV0.genPt = std::sqrt(std::pow(momMother[0], 2) + std::pow(momMother[1], 2)); + candidateV0.genEta = mcPart.eta(); + candidateV0.pdgCode = mcPart.pdgCode(); + mcLambdaTableML( + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + candidateV0.genPt, + candidateV0.genEta, + candidateV0.genCt, + candidateV0.pdgCode, + candidateV0.isReco); + } + } + } + PROCESS_SWITCH(LFStrangeTreeCreator, processMC, "process mc", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/TableProducer/LFTreeCreatorNuclei.cxx b/PWGLF/TableProducer/LFTreeCreatorNuclei.cxx index 2e6c176f446..81ddaac5df1 100644 --- a/PWGLF/TableProducer/LFTreeCreatorNuclei.cxx +++ b/PWGLF/TableProducer/LFTreeCreatorNuclei.cxx @@ -207,12 +207,14 @@ struct LfTreeCreatorNuclei { tableCandidateMC(particle.pdgCode(), particle.isPhysicalPrimary(), particle.producedByGenerator(), + particle.getProcess(), particle.px(), particle.py(), particle.pz()); + // if(particle.pdgCode() == 1000010020) LOG(info)<<"[TC]Deuteron PDGcode ===="<(collision, tracksInCollision)) @@ -253,6 +255,10 @@ struct LfTreeCreatorNuclei { if (useEvsel && !collision.sel8()) { continue; } + hEvents.fill(HIST("eventSelection"), 1); + if (collision.posZ() >= cfgHighCutVertex && collision.posZ() <= cfgLowCutVertex) + continue; + hEvents.fill(HIST("eventSelection"), 2); const auto& tracksInCollision = tracks.sliceBy(perCollision, collision.globalIndex()); fillForOneEvent(collision, tracksInCollision); } diff --git a/PWGLF/TableProducer/cascadebuilder.cxx b/PWGLF/TableProducer/cascadebuilder.cxx index 4521d9680ad..c5b3b032292 100644 --- a/PWGLF/TableProducer/cascadebuilder.cxx +++ b/PWGLF/TableProducer/cascadebuilder.cxx @@ -194,6 +194,8 @@ struct cascadeBuilder { Configurable roundDCAVariables{"roundDCAVariables", false, "round topological variables"}; Configurable precisionDCAs{"precisionDCAs", 0.01f, "precision to keep the DCAs with"}; + Configurable maxDaughterEta{"maxDaughterEta", 5.0, "Maximum daughter eta"}; + int mRunNumber; float d_bz; float maxSnp; // max sine phi for propagation @@ -218,6 +220,7 @@ struct cascadeBuilder { kCascDCADau, kCascCosPA, kCascRadius, + kCascDauEta, kCascTracked, kNCascSteps }; @@ -340,7 +343,8 @@ struct cascadeBuilder { h->GetXaxis()->SetBinLabel(6, "DCA dau"); h->GetXaxis()->SetBinLabel(7, "CosPA"); h->GetXaxis()->SetBinLabel(8, "Radius"); - h->GetXaxis()->SetBinLabel(9, "Tracked"); + h->GetXaxis()->SetBinLabel(9, "Pass dau eta"); + h->GetXaxis()->SetBinLabel(10, "Tracked"); // Optionally, add extra QA histograms to processing chain if (d_doQA) { @@ -513,10 +517,11 @@ struct cascadeBuilder { for (auto const& input : device.inputs) { if (device.name.compare("cascade-initializer") == 0) continue; // don't listen to the initializer, it's just to extend stuff - const std::string CascDataName = "StoredCascDatas"; - const std::string CascDataExtName = "CascDatasExtension"; - if (input.matcher.binding == CascDataName || input.matcher.binding == CascDataExtName) { - LOGF(info, "Device named %s has subscribed to CascData table! Will now scan for desired settings...", device.name); + const std::string CascCoresName = "StoredCascCores"; + const std::string KFCascCoresName = "StoredKFCascCores"; + const std::string TraCascCoresName = "StoredTraCascCores"; + if (input.matcher.binding == CascCoresName || input.matcher.binding == KFCascCoresName || input.matcher.binding == TraCascCoresName) { + LOGF(info, "Device named %s has subscribed to a CascCores table! Will now scan for desired settings...", device.name); for (auto const& option : device.options) { // 5 V0 topological selections + 1 mass if (option.name.compare("cascadesetting_cospa") == 0) { @@ -948,6 +953,12 @@ struct cascadeBuilder { return false; statisticsRegistry.cascstats[kCascRadius]++; + // Daughter eta check + if (TMath::Abs(RecoDecay::eta(std::array{cascadecandidate.bachP[0], cascadecandidate.bachP[1], cascadecandidate.bachP[2]})) > maxDaughterEta) { + return false; // reject - daughters have too large eta to be reliable for MC corrections + } + statisticsRegistry.cascstats[kCascDauEta]++; + // Calculate DCAxy of the cascade (with bending) lCascadeTrack = fitter.createParentTrackParCov(); lCascadeTrack.setAbsCharge(cascadecandidate.charge); // to be sure @@ -1278,6 +1289,11 @@ struct cascadeBuilder { if (cascadecandidate.cascradius < cascradius) return false; + // Daughter eta check + if (TMath::Abs(RecoDecay::eta(std::array{cascadecandidate.bachP[0], cascadecandidate.bachP[1], cascadecandidate.bachP[2]})) > maxDaughterEta) { + return false; // reject - daughters have too large eta to be reliable for MC corrections + } + // Calculate masses a priori cascadecandidate.kfMLambda = KFV0.GetMass(); cascadecandidate.mXi = KFXi.GetMass(); diff --git a/PWGLF/TableProducer/cascadespawner.cxx b/PWGLF/TableProducer/cascadespawner.cxx new file mode 100644 index 00000000000..4e2d0c68a44 --- /dev/null +++ b/PWGLF/TableProducer/cascadespawner.cxx @@ -0,0 +1,46 @@ +// 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 spawner +// *+-+*+-+*+-+*+-+*+-+*+-+* +// +// Creates Cascade extension tables for derived data. +// A minimal task that saves a lot of disk space. + +#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 "PWGLF/DataModel/LFStrangenessTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +/// Extends the cascdata table with expression columns +struct cascadespawner { + Spawns cascdataext; + void init(InitContext const&) {} +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/TableProducer/hyperRecoTask.cxx b/PWGLF/TableProducer/hyperRecoTask.cxx index c1500cc3fa2..85edcfb447d 100644 --- a/PWGLF/TableProducer/hyperRecoTask.cxx +++ b/PWGLF/TableProducer/hyperRecoTask.cxx @@ -32,6 +32,7 @@ #include "Common/Core/PID/TPCPIDResponse.h" #include "DataFormatsTPC/BetheBlochAleph.h" #include "DCAFitter/DCAFitterN.h" +#include "Common/DataModel/Qvectors.h" #include "PWGLF/DataModel/LFHypernucleiTables.h" @@ -40,6 +41,8 @@ using namespace o2::framework; using namespace o2::framework::expressions; using std::array; using TracksFull = soa::Join; +using CollisionsFull = soa::Join; +using CollisionsFullWithFlow = soa::Join; namespace { @@ -79,10 +82,6 @@ struct hyperCandidate { float momPiTPC = -10.f; std::array momHe3; std::array momPi; - std::array primVtx; - float centralityFT0A = -1; - float centralityFT0C = -1; - float centralityFT0M = -1; std::array decVtx; std::array gMom; std::array gMomHe3; @@ -103,6 +102,7 @@ struct hyperCandidate { struct hyperRecoTask { Produces outputDataTable; + Produces outputDataTableWithFlow; Produces outputMCTable; Service ccdb; @@ -110,9 +110,11 @@ struct hyperRecoTask { Configurable v0cospa{"hypcospa", 0.95, "V0 CosPA"}; Configurable masswidth{"hypmasswidth", 0.06, "Mass width (GeV/c^2)"}; Configurable dcav0dau{"hypdcaDau", 1.0, "DCA V0 Daughters"}; + Configurable ptMin{"ptMin", 0.5, "Minimum pT of the hypercandidate"}; + Configurable TPCRigidityMinHe{"TPCRigidityMinHe", 0.2, "Minimum rigidity of the helium candidate"}; Configurable etaMax{"eta", 1., "eta daughter"}; - Configurable heliumNsigmaMax{"heliumNsigmaMax", 5, "helium dEdx cut (n sigma)"}; - Configurable heliumNtpcClusMin{"heliumNtpcClusMin", 80, "helium NTPC clusters cut"}; + Configurable nSigmaMaxHe{"nSigmaMaxHe", 5, "helium dEdx cut (n sigma)"}; + Configurable nTPCClusMinHe{"nTPCClusMinHe", 80, "helium NTPC clusters cut"}; Configurable mcSignalOnly{"mcSignalOnly", true, "If true, save only signal in MC"}; // Define o2 fitter, 2-prong, active memory (no need to redefine per event) @@ -148,6 +150,8 @@ struct hyperRecoTask { // std vector of candidates std::vector hyperCandidates; + // vector to keep track of MC mothers already filled + std::vector filledMothers; Preslice perCollision = o2::aod::v0::collisionId; @@ -249,35 +253,39 @@ struct hyperRecoTask { mRunNumber = bc.runNumber(); } - template - void fillCandidateData(soa::Join::iterator const& collision, aod::V0s const& V0s) + template + void fillCandidateData(Tcoll const& collision, aod::V0s const& V0s) { if (mBBparamsHe[5] < 0) { LOG(fatal) << "Bethe-Bloch parameters for He3 not set, please check your CCDB and configuration"; } for (auto& v0 : V0s) { - auto posTrack = v0.posTrack_as(); - auto negTrack = v0.negTrack_as(); + auto posTrack = v0.posTrack_as(); + auto negTrack = v0.negTrack_as(); if (std::abs(posTrack.eta()) > etaMax || std::abs(negTrack.eta()) > etaMax) continue; - if (posTrack.tpcNClsFound() >= heliumNtpcClusMin) - hDeDxTot->Fill(posTrack.tpcInnerParam(), posTrack.tpcSignal()); - if (negTrack.tpcNClsFound() >= heliumNtpcClusMin) - hDeDxTot->Fill(-negTrack.tpcInnerParam(), negTrack.tpcSignal()); + // temporary fix: tpcInnerParam() returns the momentum in all the software tags before: https://github.com/AliceO2Group/AliceO2/pull/12521 + bool posHeliumPID = posTrack.pidForTracking() == o2::track::PID::Helium3 || posTrack.pidForTracking() == o2::track::PID::Alpha; + bool negHeliumPID = negTrack.pidForTracking() == o2::track::PID::Helium3 || negTrack.pidForTracking() == o2::track::PID::Alpha; + float posRigidity = posHeliumPID ? posTrack.tpcInnerParam() / 2 : posTrack.tpcInnerParam(); + float negRigidity = negHeliumPID ? negTrack.tpcInnerParam() / 2 : negTrack.tpcInnerParam(); - double expBethePos{tpc::BetheBlochAleph(static_cast(posTrack.tpcInnerParam() * 2 / constants::physics::MassHelium3), mBBparamsHe[0], mBBparamsHe[1], mBBparamsHe[2], mBBparamsHe[3], mBBparamsHe[4])}; - double expBetheNeg{tpc::BetheBlochAleph(static_cast(negTrack.tpcInnerParam() * 2 / constants::physics::MassHelium3), mBBparamsHe[0], mBBparamsHe[1], mBBparamsHe[2], mBBparamsHe[3], mBBparamsHe[4])}; + hDeDxTot->Fill(posRigidity, posTrack.tpcSignal()); + hDeDxTot->Fill(-negRigidity, negTrack.tpcSignal()); + + double expBethePos{tpc::BetheBlochAleph(static_cast(posRigidity * 2 / constants::physics::MassHelium3), mBBparamsHe[0], mBBparamsHe[1], mBBparamsHe[2], mBBparamsHe[3], mBBparamsHe[4])}; + double expBetheNeg{tpc::BetheBlochAleph(static_cast(negRigidity * 2 / constants::physics::MassHelium3), mBBparamsHe[0], mBBparamsHe[1], mBBparamsHe[2], mBBparamsHe[3], mBBparamsHe[4])}; double expSigmaPos{expBethePos * mBBparamsHe[5]}; double expSigmaNeg{expBetheNeg * mBBparamsHe[5]}; auto nSigmaTPCpos = static_cast((posTrack.tpcSignal() - expBethePos) / expSigmaPos); auto nSigmaTPCneg = static_cast((negTrack.tpcSignal() - expBetheNeg) / expSigmaNeg); // ITS only tracks do not have TPC information. TPCnSigma: only lower cut to allow for both hypertriton and hyperhydrogen4 reconstruction - bool isHe = posTrack.hasTPC() && nSigmaTPCpos > -1 * heliumNsigmaMax; - bool isAntiHe = negTrack.hasTPC() && nSigmaTPCneg > -1 * heliumNsigmaMax; + bool isHe = posTrack.hasTPC() && nSigmaTPCpos > -1 * nSigmaMaxHe; + bool isAntiHe = negTrack.hasTPC() && nSigmaTPCneg > -1 * nSigmaMaxHe; if (!isHe && !isAntiHe) continue; @@ -285,7 +293,8 @@ struct hyperRecoTask { hyperCandidate hypCand; hypCand.isMatter = isHe && isAntiHe ? std::abs(nSigmaTPCpos) < std::abs(nSigmaTPCneg) : isHe; auto& he3track = hypCand.isMatter ? posTrack : negTrack; - if (he3track.tpcNClsFound() < heliumNtpcClusMin) + auto& he3Rigidity = hypCand.isMatter ? posRigidity : negRigidity; + if (he3track.tpcNClsFound() < nTPCClusMinHe || he3Rigidity < TPCRigidityMinHe) continue; hypCand.nSigmaHe3 = hypCand.isMatter ? nSigmaTPCpos : nSigmaTPCneg; @@ -295,8 +304,8 @@ struct hyperRecoTask { hypCand.nTPCClustersPi = !hypCand.isMatter ? posTrack.tpcNClsFound() : negTrack.tpcNClsFound(); hypCand.tpcSignalPi = !hypCand.isMatter ? posTrack.tpcSignal() : negTrack.tpcSignal(); hypCand.clusterSizeITSPi = !hypCand.isMatter ? posTrack.itsClusterSizes() : negTrack.itsClusterSizes(); - hypCand.momHe3TPC = hypCand.isMatter ? posTrack.tpcInnerParam() : negTrack.tpcInnerParam(); - hypCand.momPiTPC = !hypCand.isMatter ? posTrack.tpcInnerParam() : negTrack.tpcInnerParam(); + hypCand.momHe3TPC = hypCand.isMatter ? posRigidity : negRigidity; + hypCand.momPiTPC = !hypCand.isMatter ? posRigidity : negRigidity; hypCand.flags |= hypCand.isMatter ? static_cast((posTrack.pidForTracking() & 0xF) << 4) : static_cast((negTrack.pidForTracking() & 0xF) << 4); hypCand.flags |= hypCand.isMatter ? static_cast(negTrack.pidForTracking() & 0xF) : static_cast(posTrack.pidForTracking() & 0xF); @@ -320,7 +329,7 @@ struct hyperRecoTask { hePropTrack.getPxPyPzGlo(hypCand.momHe3); piPropTrack.getPxPyPzGlo(hypCand.momPi); - // he momentum has to be multiplied by 2 (charge) + // the momentum has to be multiplied by 2 (charge) for (int i = 0; i < 3; i++) { hypCand.momHe3[i] *= 2; } @@ -333,10 +342,6 @@ struct hyperRecoTask { float h3lE = he3E + piE; float h4lE = he4E + piE; - hypCand.primVtx = array{collision.posX(), collision.posY(), collision.posZ()}; - hypCand.centralityFT0A = collision.centFT0A(); - hypCand.centralityFT0C = collision.centFT0C(); - hypCand.centralityFT0M = collision.centFT0M(); std::array hypMom; const auto& vtx = fitter.getPCACandidate(); for (int i = 0; i < 3; i++) { @@ -344,6 +349,10 @@ struct hyperRecoTask { hypMom[i] = hypCand.momHe3[i] + hypCand.momPi[i]; } + float hypPt = std::hypot(hypMom[0], hypMom[1]); + if (hypPt < ptMin) + continue; + float massH3L = std::sqrt(h3lE * h3lE - hypMom[0] * hypMom[0] - hypMom[1] * hypMom[1] - hypMom[2] * hypMom[2]); float massH4L = std::sqrt(h4lE * h4lE - hypMom[0] * hypMom[0] - hypMom[1] * hypMom[1] - hypMom[2] * hypMom[2]); bool isHypMass = false; @@ -359,13 +368,15 @@ struct hyperRecoTask { continue; } - double cosPA = RecoDecay::cpa(hypCand.primVtx, array{hypCand.decVtx[0], hypCand.decVtx[1], hypCand.decVtx[2]}, array{hypMom[0], hypMom[1], hypMom[2]}); + std::array primVtx = {collision.posX(), collision.posY(), collision.posZ()}; + + double cosPA = RecoDecay::cpa(primVtx, hypCand.decVtx, hypMom); if (cosPA < v0cospa) { continue; } for (int i = 0; i < 3; i++) { - hypCand.decVtx[i] = hypCand.decVtx[i] - hypCand.primVtx[i]; + hypCand.decVtx[i] = hypCand.decVtx[i] - primVtx[i]; } // if survived all selections, propagate decay daughters to PV @@ -383,9 +394,8 @@ struct hyperRecoTask { hypCand.negTrackID = negTrack.globalIndex(); int chargeFactor = -1 + 2 * hypCand.isMatter; - - hDeDx3HeSel->Fill(chargeFactor * he3track.tpcInnerParam(), he3track.tpcSignal()); - hNsigma3HeSel->Fill(chargeFactor * he3track.tpcInnerParam(), hypCand.nSigmaHe3); + hDeDx3HeSel->Fill(chargeFactor * hypCand.momHe3TPC, he3track.tpcSignal()); + hNsigma3HeSel->Fill(chargeFactor * hypCand.momHe3TPC, hypCand.nSigmaHe3); hyperCandidates.push_back(hypCand); } @@ -393,7 +403,6 @@ struct hyperRecoTask { void fillMCinfo(aod::McTrackLabels const& trackLabels, aod::McParticles const& particlesMC) { - std::vector filledMothers; for (auto& hypCand : hyperCandidates) { auto mcLabPos = trackLabels.rawIteratorAt(hypCand.posTrackID); auto mcLabNeg = trackLabels.rawIteratorAt(hypCand.negTrackID); @@ -426,61 +435,56 @@ struct hyperRecoTask { } } } + } - for (auto& mcPart : particlesMC) { + void processData(CollisionsFull const& collisions, aod::V0s const& V0s, TracksFull const& tracks, aod::BCsWithTimestamps const&) + { - if (std::abs(mcPart.pdgCode()) != hyperPdg) - continue; - std::array secVtx; - std::array primVtx = {mcPart.vx(), mcPart.vy(), mcPart.vz()}; - std::array momMother = {mcPart.px(), mcPart.py(), mcPart.pz()}; - std::array momHe3; - bool isHeFound = false; - for (auto& mcDaught : mcPart.daughters_as()) { - if (std::abs(mcDaught.pdgCode()) == heDauPdg) { - secVtx = {mcDaught.vx(), mcDaught.vy(), mcDaught.vz()}; - momHe3 = {mcDaught.px(), mcDaught.py(), mcDaught.pz()}; - isHeFound = true; - break; - } - } - if (mcPart.pdgCode() > 0) { - hIsMatterGen->Fill(0.); - } else { - hIsMatterGen->Fill(1.); - } - if (!isHeFound) { - hDecayChannel->Fill(1.); + for (const auto& collision : collisions) { + hyperCandidates.clear(); + + auto bc = collision.bc_as(); + initCCDB(bc); + + hEvents->Fill(0.); + if (!collision.sel8()) continue; - } - hDecayChannel->Fill(0.); - if (mcPart.pdgCode() > 0) { - hIsMatterGenTwoBody->Fill(0.); - } else { - hIsMatterGenTwoBody->Fill(1.); - } - if (std::find(filledMothers.begin(), filledMothers.end(), mcPart.globalIndex()) != std::end(filledMothers)) { + + hEvents->Fill(1.); + + if (std::abs(collision.posZ()) > 10.f) continue; + + hEvents->Fill(2.); + hZvtx->Fill(collision.posZ()); + + const uint64_t collIdx = collision.globalIndex(); + auto V0Table_thisCollision = V0s.sliceBy(perCollision, collIdx); + V0Table_thisCollision.bindExternalIndices(&tracks); + + fillCandidateData(collision, V0Table_thisCollision); + + for (auto& hypCand : hyperCandidates) { + outputDataTable(collision.centFT0A(), collision.centFT0C(), collision.centFT0M(), + collision.posX(), collision.posY(), collision.posZ(), + hypCand.isMatter, + hypCand.recoPtHe3(), hypCand.recoPhiHe3(), hypCand.recoEtaHe3(), + hypCand.recoPtPi(), hypCand.recoPhiPi(), hypCand.recoEtaPi(), + hypCand.decVtx[0], hypCand.decVtx[1], hypCand.decVtx[2], + hypCand.dcaV0dau, hypCand.he3DCAXY, hypCand.piDCAXY, + hypCand.nSigmaHe3, hypCand.nTPCClustersHe3, hypCand.nTPCClustersPi, + hypCand.momHe3TPC, hypCand.momPiTPC, hypCand.tpcSignalHe3, hypCand.tpcSignalPi, + hypCand.clusterSizeITSHe3, hypCand.clusterSizeITSPi, hypCand.flags); } - hyperCandidate hypCand; - for (int i = 0; i < 3; i++) { - hypCand.gDecVtx[i] = secVtx[i] - primVtx[i]; - hypCand.gMom[i] = momMother[i]; - hypCand.gMomHe3[i] = momHe3[i]; - } - hypCand.posTrackID = -1; - hypCand.negTrackID = -1; - hypCand.isSignal = true; - hypCand.pdgCode = mcPart.pdgCode(); - hyperCandidates.push_back(hypCand); } } + PROCESS_SWITCH(hyperRecoTask, processData, "Data analysis", true); - void processData(soa::Join const& collisions, aod::V0s const& V0s, TracksFull const& tracks, aod::BCsWithTimestamps const&) + void processDataWithFlow(CollisionsFullWithFlow const& collisions, aod::V0s const& V0s, TracksFull const& tracks, aod::BCsWithTimestamps const&) { - hyperCandidates.clear(); for (const auto& collision : collisions) { + hyperCandidates.clear(); auto bc = collision.bc_as(); initCCDB(bc); @@ -501,32 +505,34 @@ struct hyperRecoTask { auto V0Table_thisCollision = V0s.sliceBy(perCollision, collIdx); V0Table_thisCollision.bindExternalIndices(&tracks); - fillCandidateData(collision, V0Table_thisCollision); - } - - for (auto& hypCand : hyperCandidates) { - outputDataTable(hypCand.isMatter, - hypCand.centralityFT0A, - hypCand.centralityFT0C, - hypCand.centralityFT0M, - hypCand.recoPtHe3(), hypCand.recoPhiHe3(), hypCand.recoEtaHe3(), - hypCand.recoPtPi(), hypCand.recoPhiPi(), hypCand.recoEtaPi(), - hypCand.primVtx[0], hypCand.primVtx[1], hypCand.primVtx[2], - hypCand.decVtx[0], hypCand.decVtx[1], hypCand.decVtx[2], - hypCand.dcaV0dau, hypCand.he3DCAXY, hypCand.piDCAXY, - hypCand.nSigmaHe3, hypCand.nTPCClustersHe3, hypCand.nTPCClustersPi, - hypCand.momHe3TPC, hypCand.momPiTPC, hypCand.tpcSignalHe3, hypCand.tpcSignalPi, - hypCand.clusterSizeITSHe3, hypCand.clusterSizeITSPi, hypCand.flags); + fillCandidateData(collision, V0Table_thisCollision); + + for (auto& hypCand : hyperCandidates) { + outputDataTableWithFlow(collision.centFT0A(), collision.centFT0C(), collision.centFT0M(), + collision.qvecFT0ARe(), collision.qvecFT0AIm(), collision.sumAmplFT0A(), + collision.qvecFT0CRe(), collision.qvecFT0CIm(), collision.sumAmplFT0C(), + collision.qvecFT0MRe(), collision.qvecFT0MIm(), collision.sumAmplFT0M(), + collision.qvecFV0ARe(), collision.qvecFV0AIm(), collision.sumAmplFV0A(), + collision.posX(), collision.posY(), collision.posZ(), + hypCand.isMatter, + hypCand.recoPtHe3(), hypCand.recoPhiHe3(), hypCand.recoEtaHe3(), + hypCand.recoPtPi(), hypCand.recoPhiPi(), hypCand.recoEtaPi(), + hypCand.decVtx[0], hypCand.decVtx[1], hypCand.decVtx[2], + hypCand.dcaV0dau, hypCand.he3DCAXY, hypCand.piDCAXY, + hypCand.nSigmaHe3, hypCand.nTPCClustersHe3, hypCand.nTPCClustersPi, + hypCand.momHe3TPC, hypCand.momPiTPC, hypCand.tpcSignalHe3, hypCand.tpcSignalPi, + hypCand.clusterSizeITSHe3, hypCand.clusterSizeITSPi, hypCand.flags); + } } } - PROCESS_SWITCH(hyperRecoTask, processData, "Data analysis", true); + PROCESS_SWITCH(hyperRecoTask, processDataWithFlow, "Data analysis with flow", false); - void processMC(soa::Join const& collisions, aod::V0s const& V0s, TracksFull const& tracks, aod::BCsWithTimestamps const&, aod::McTrackLabels const& trackLabelsMC, aod::McParticles const& particlesMC) + void processMC(CollisionsFull const& collisions, aod::V0s const& V0s, TracksFull const& tracks, aod::BCsWithTimestamps const&, aod::McTrackLabels const& trackLabelsMC, aod::McParticles const& particlesMC) { - hyperCandidates.clear(); + filledMothers.clear(); for (const auto& collision : collisions) { - + hyperCandidates.clear(); auto bc = collision.bc_as(); initCCDB(bc); @@ -543,26 +549,85 @@ struct hyperRecoTask { auto V0Table_thisCollision = V0s.sliceBy(perCollision, collIdx); V0Table_thisCollision.bindExternalIndices(&tracks); - fillCandidateData(collision, V0Table_thisCollision); + fillCandidateData(collision, V0Table_thisCollision); + fillMCinfo(trackLabelsMC, particlesMC); + + for (auto& hypCand : hyperCandidates) { + if (!hypCand.isSignal && mcSignalOnly) + continue; + int chargeFactor = -1 + 2 * (hypCand.pdgCode > 0); + outputMCTable(collision.centFT0A(), collision.centFT0C(), collision.centFT0M(), + collision.posX(), collision.posY(), collision.posZ(), + hypCand.isMatter, + hypCand.recoPtHe3(), hypCand.recoPhiHe3(), hypCand.recoEtaHe3(), + hypCand.recoPtPi(), hypCand.recoPhiPi(), hypCand.recoEtaPi(), + hypCand.decVtx[0], hypCand.decVtx[1], hypCand.decVtx[2], + hypCand.dcaV0dau, hypCand.he3DCAXY, hypCand.piDCAXY, + hypCand.nSigmaHe3, hypCand.nTPCClustersHe3, hypCand.nTPCClustersPi, + hypCand.momHe3TPC, hypCand.momPiTPC, hypCand.tpcSignalHe3, hypCand.tpcSignalPi, + hypCand.clusterSizeITSHe3, hypCand.clusterSizeITSPi, hypCand.flags, + chargeFactor * hypCand.genPt(), hypCand.genPhi(), hypCand.genEta(), hypCand.genPtHe3(), + hypCand.gDecVtx[0], hypCand.gDecVtx[1], hypCand.gDecVtx[2], hypCand.isReco, hypCand.isSignal); + } } - fillMCinfo(trackLabelsMC, particlesMC); - for (auto& hypCand : hyperCandidates) { - if (!hypCand.isSignal && mcSignalOnly) + // now we fill only the signal candidates that were not reconstructed + for (auto& mcPart : particlesMC) { + + if (std::abs(mcPart.pdgCode()) != hyperPdg) continue; + std::array secVtx; + std::array primVtx = {mcPart.vx(), mcPart.vy(), mcPart.vz()}; + std::array momMother = {mcPart.px(), mcPart.py(), mcPart.pz()}; + std::array momHe3; + bool isHeFound = false; + for (auto& mcDaught : mcPart.daughters_as()) { + if (std::abs(mcDaught.pdgCode()) == heDauPdg) { + secVtx = {mcDaught.vx(), mcDaught.vy(), mcDaught.vz()}; + momHe3 = {mcDaught.px(), mcDaught.py(), mcDaught.pz()}; + isHeFound = true; + break; + } + } + if (mcPart.pdgCode() > 0) { + hIsMatterGen->Fill(0.); + } else { + hIsMatterGen->Fill(1.); + } + if (!isHeFound) { + hDecayChannel->Fill(1.); + continue; + } + hDecayChannel->Fill(0.); + if (mcPart.pdgCode() > 0) { + hIsMatterGenTwoBody->Fill(0.); + } else { + hIsMatterGenTwoBody->Fill(1.); + } + if (std::find(filledMothers.begin(), filledMothers.end(), mcPart.globalIndex()) != std::end(filledMothers)) { + continue; + } + hyperCandidate hypCand; int chargeFactor = -1 + 2 * (hypCand.pdgCode > 0); - outputMCTable(hypCand.isMatter, - hypCand.centralityFT0A, - hypCand.centralityFT0C, - hypCand.centralityFT0M, - hypCand.recoPtHe3(), hypCand.recoPhiHe3(), hypCand.recoEtaHe3(), - hypCand.recoPtPi(), hypCand.recoPhiPi(), hypCand.recoEtaPi(), - hypCand.primVtx[0], hypCand.primVtx[1], hypCand.primVtx[2], - hypCand.decVtx[0], hypCand.decVtx[1], hypCand.decVtx[2], - hypCand.dcaV0dau, hypCand.he3DCAXY, hypCand.piDCAXY, - hypCand.nSigmaHe3, hypCand.nTPCClustersHe3, hypCand.nTPCClustersPi, - hypCand.momHe3TPC, hypCand.momPiTPC, hypCand.tpcSignalHe3, hypCand.tpcSignalPi, - hypCand.clusterSizeITSHe3, hypCand.clusterSizeITSPi, hypCand.flags, + for (int i = 0; i < 3; i++) { + hypCand.gDecVtx[i] = secVtx[i] - primVtx[i]; + hypCand.gMom[i] = momMother[i]; + hypCand.gMomHe3[i] = momHe3[i]; + } + hypCand.posTrackID = -1; + hypCand.negTrackID = -1; + hypCand.isSignal = true; + hypCand.pdgCode = mcPart.pdgCode(); + outputMCTable(-1, -1, -1, + 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, chargeFactor * hypCand.genPt(), hypCand.genPhi(), hypCand.genEta(), hypCand.genPtHe3(), hypCand.gDecVtx[0], hypCand.gDecVtx[1], hypCand.gDecVtx[2], hypCand.isReco, hypCand.isSignal); } diff --git a/PWGLF/TableProducer/hypertriton3bodybuilder.cxx b/PWGLF/TableProducer/hypertriton3bodybuilder.cxx index 5d54cad115f..63e6e593089 100644 --- a/PWGLF/TableProducer/hypertriton3bodybuilder.cxx +++ b/PWGLF/TableProducer/hypertriton3bodybuilder.cxx @@ -248,9 +248,12 @@ struct hypertriton3bodyBuilder { } std::array p0 = {0.}, p1 = {0.}, p2{0.}; - Track0.getPxPyPzGlo(p0); - Track1.getPxPyPzGlo(p1); - Track2.getPxPyPzGlo(p2); + const auto& propagatedTrack0 = fitter3body.getTrack(0); + const auto& propagatedTrack1 = fitter3body.getTrack(1); + const auto& propagatedTrack2 = fitter3body.getTrack(2); + propagatedTrack0.getPxPyPzGlo(p0); + propagatedTrack1.getPxPyPzGlo(p1); + propagatedTrack2.getPxPyPzGlo(p2); std::array p3B = {p0[0] + p1[0] + p2[0], p0[1] + p1[1] + p2[1], p0[2] + p1[2] + p2[2]}; if (fitter3body.getChi2AtPCACandidate() > dcavtxdau) { diff --git a/PWGLF/TableProducer/hypertriton3bodyfinder.cxx b/PWGLF/TableProducer/hypertriton3bodyfinder.cxx index 2b29305dc5c..9341c3d7bff 100644 --- a/PWGLF/TableProducer/hypertriton3bodyfinder.cxx +++ b/PWGLF/TableProducer/hypertriton3bodyfinder.cxx @@ -46,9 +46,37 @@ using namespace o2::framework::expressions; using std::array; using FullTracksExtIU = soa::Join; -using FullTracksExtMCIU = soa::Join; +using MCLabeledFullTracksExtIU = soa::Join; -using LabeledTracks = soa::Join; +template +bool is3bodyDecayedH3L(TMCParticle const& particle) +{ + if (particle.pdgCode() != 1010010030 && particle.pdgCode() != -1010010030) { + return false; + } + bool haveProton = false, havePion = false, haveDeuteron = false; + bool haveAntiProton = false, haveAntiPion = false, haveAntiDeuteron = false; + for (auto& mcparticleDaughter : particle.template daughters_as()) { + if (mcparticleDaughter.pdgCode() == 2212) + haveProton = true; + if (mcparticleDaughter.pdgCode() == -2212) + haveAntiProton = true; + if (mcparticleDaughter.pdgCode() == 211) + havePion = true; + if (mcparticleDaughter.pdgCode() == -211) + haveAntiPion = true; + if (mcparticleDaughter.pdgCode() == 1000010020) + haveDeuteron = true; + if (mcparticleDaughter.pdgCode() == -1000010020) + haveAntiDeuteron = true; + } + if (haveProton && haveAntiPion && haveDeuteron && particle.pdgCode() == 1010010030) { + return true; + } else if (haveAntiProton && havePion && haveAntiDeuteron && particle.pdgCode() == -1010010030) { + return true; + } + return false; +} namespace o2::aod { @@ -56,23 +84,20 @@ namespace v0goodpostrack { DECLARE_SOA_INDEX_COLUMN_FULL(GoodTrack, goodTrack, int, Tracks, "_GoodTrack"); DECLARE_SOA_INDEX_COLUMN(Collision, collision); -DECLARE_SOA_COLUMN(DCAXY, dcaXY, float); } // namespace v0goodpostrack -DECLARE_SOA_TABLE(V0GoodPosTracks, "AOD", "V0GOODPOSTRACKS", o2::soa::Index<>, v0goodpostrack::GoodTrackId, v0goodpostrack::CollisionId, v0goodpostrack::DCAXY); +DECLARE_SOA_TABLE(V0GoodPosTracks, "AOD", "V0GOODPOSTRACKS", o2::soa::Index<>, v0goodpostrack::GoodTrackId, v0goodpostrack::CollisionId); namespace v0goodnegtrack { DECLARE_SOA_INDEX_COLUMN_FULL(GoodTrack, goodTrack, int, Tracks, "_GoodTrack"); DECLARE_SOA_INDEX_COLUMN(Collision, collision); -DECLARE_SOA_COLUMN(DCAXY, dcaXY, float); } // namespace v0goodnegtrack -DECLARE_SOA_TABLE(V0GoodNegTracks, "AOD", "V0GOODNEGTRACKS", o2::soa::Index<>, v0goodnegtrack::GoodTrackId, v0goodnegtrack::CollisionId, v0goodnegtrack::DCAXY); +DECLARE_SOA_TABLE(V0GoodNegTracks, "AOD", "V0GOODNEGTRACKS", o2::soa::Index<>, v0goodnegtrack::GoodTrackId, v0goodnegtrack::CollisionId); namespace v0goodtrack { DECLARE_SOA_INDEX_COLUMN_FULL(GoodTrack, goodTrack, int, Tracks, "_GoodTrack"); DECLARE_SOA_INDEX_COLUMN(Collision, collision); -DECLARE_SOA_COLUMN(DCAXY, dcaXY, float); } // namespace v0goodtrack -DECLARE_SOA_TABLE(V0GoodTracks, "AOD", "V0GOODTRACKS", o2::soa::Index<>, v0goodtrack::GoodTrackId, v0goodtrack::CollisionId, v0goodtrack::DCAXY); +DECLARE_SOA_TABLE(V0GoodTracks, "AOD", "V0GOODTRACKS", o2::soa::Index<>, v0goodtrack::GoodTrackId, v0goodtrack::CollisionId); } // namespace o2::aod struct trackprefilter { @@ -83,6 +108,7 @@ struct trackprefilter { {"hGoodTrackCount", "hGoodTrackCount", {HistType::kTH1F, {{4, 0.0f, 4.0f}}}}, {"hGoodPosTrackCount", "hGoodPosTrackCount", {HistType::kTH1F, {{1, 0.0f, 1.0f}}}}, {"hGoodNegTrackCount", "hGoodNegTrackCount", {HistType::kTH1F, {{1, 0.0f, 1.0f}}}}, + {"h3bodyCounter", "h3bodyCounter", {HistType::kTH1F, {{6, 0.0f, 6.0f}}}}, }, }; @@ -94,8 +120,9 @@ struct trackprefilter { Produces v0GoodNegTracks; Produces v0GoodTracks; - void process(aod::Collision const& collision, - FullTracksExtIU const& tracks) + // Fix: Add PID and pt cuts to tracks + void processDefault(aod::Collision const& collision, + FullTracksExtIU const& tracks) { for (auto& t0 : tracks) { registry.fill(HIST("hGoodTrackCount"), 0.5); @@ -111,49 +138,82 @@ struct trackprefilter { } registry.fill(HIST("hGoodTrackCount"), 2.5); if (t0.signed1Pt() > 0.0f) { - v0GoodPosTracks(t0.globalIndex(), collision.globalIndex(), t0.dcaXY()); + v0GoodPosTracks(t0.globalIndex(), t0.collisionId()); registry.fill(HIST("hGoodPosTrackCount"), 0.5); registry.fill(HIST("hGoodTrackCount"), 3.5); } if (t0.signed1Pt() < 0.0f) { - v0GoodNegTracks(t0.globalIndex(), collision.globalIndex(), t0.dcaXY()); + v0GoodNegTracks(t0.globalIndex(), t0.collisionId()); registry.fill(HIST("hGoodNegTrackCount"), 0.5); registry.fill(HIST("hGoodTrackCount"), 3.5); } - v0GoodTracks(t0.globalIndex(), collision.globalIndex(), t0.dcaXY()); + v0GoodTracks(t0.globalIndex(), t0.collisionId()); } } -}; + PROCESS_SWITCH(trackprefilter, processDefault, "Default process function", true); -template -bool is3bodyDecayedH3L(TMCParticle const& particle) -{ - if (particle.pdgCode() != 1010010030 && particle.pdgCode() != -1010010030) { - return false; - } - bool haveProton = false, havePion = false, haveDeuteron = false; - bool haveAntiProton = false, haveAntiPion = false, haveAntiDeuteron = false; - for (auto& mcparticleDaughter : particle.template daughters_as()) { - if (mcparticleDaughter.pdgCode() == 2212) - haveProton = true; - if (mcparticleDaughter.pdgCode() == -2212) - haveAntiProton = true; - if (mcparticleDaughter.pdgCode() == 211) - havePion = true; - if (mcparticleDaughter.pdgCode() == -211) - haveAntiPion = true; - if (mcparticleDaughter.pdgCode() == 1000010020) - haveDeuteron = true; - if (mcparticleDaughter.pdgCode() == -1000010020) - haveAntiDeuteron = true; - } - if (haveProton && haveAntiPion && haveDeuteron && particle.pdgCode() == 1010010030) { - return true; - } else if (haveAntiProton && havePion && haveAntiDeuteron && particle.pdgCode() == -1010010030) { - return true; + // process function for MC d3body check + // void processCheck(aod::Collision const& collision, aod::Decay3Bodys const& decay3bodys, + void processCheck(aod::Decay3Bodys const& decay3bodys, + MCLabeledFullTracksExtIU const& tracks, aod::McParticles const& particlesMC) + { + for (auto& d3body : decay3bodys) { + registry.fill(HIST("h3bodyCounter"), 0.5); + auto lTrack0 = d3body.track0_as(); + auto lTrack1 = d3body.track1_as(); + auto lTrack2 = d3body.track2_as(); + if (!lTrack0.has_mcParticle() || !lTrack1.has_mcParticle() || !lTrack2.has_mcParticle()) { + continue; + } + registry.fill(HIST("h3bodyCounter"), 1.5); + auto lMCTrack0 = lTrack0.mcParticle_as(); + auto lMCTrack1 = lTrack1.mcParticle_as(); + auto lMCTrack2 = lTrack2.mcParticle_as(); + if (!lMCTrack0.has_mothers() || !lMCTrack1.has_mothers() || !lMCTrack2.has_mothers()) { + continue; + } + registry.fill(HIST("h3bodyCounter"), 2.5); + + int lPDG = -1; + bool is3bodyDecay = false; + for (auto& lMother0 : lMCTrack0.mothers_as()) { + for (auto& lMother1 : lMCTrack1.mothers_as()) { + for (auto& lMother2 : lMCTrack2.mothers_as()) { + if (lMother0.globalIndex() == lMother1.globalIndex() && lMother0.globalIndex() == lMother2.globalIndex()) { + lPDG = lMother1.pdgCode(); + if (lPDG == 1010010030 && lMCTrack0.pdgCode() == 2212 && lMCTrack1.pdgCode() == -211 && lMCTrack2.pdgCode() == 1000010020) { + is3bodyDecay = true; // vtxs with the same mother + } + if (lPDG == -1010010030 && lMCTrack0.pdgCode() == 211 && lMCTrack1.pdgCode() == -2212 && lMCTrack2.pdgCode() == -1000010020) { + is3bodyDecay = true; // vtxs with the same mother + } + } + } + } + } // end association check + + if (!is3bodyDecay || std::abs(lPDG) != 1010010030) { + continue; + } + registry.fill(HIST("h3bodyCounter"), 3.5); + if (lTrack0.collisionId() != lTrack1.collisionId() || lTrack0.collisionId() != lTrack2.collisionId()) { + continue; + } + registry.fill(HIST("h3bodyCounter"), 4.5); + + if (lTrack0.collisionId() != d3body.collisionId()) { + continue; + } + registry.fill(HIST("h3bodyCounter"), 5.5); + + // LOG(info) << "; Track0ID: " << lTrack0.globalIndex() << "; Track1ID:" << lTrack1.globalIndex() << "; Track2ID:" << lTrack2.globalIndex(); + v0GoodPosTracks(lTrack0.globalIndex(), lTrack0.collisionId()); + v0GoodNegTracks(lTrack1.globalIndex(), lTrack1.collisionId()); + v0GoodTracks(lTrack2.globalIndex(), lTrack2.collisionId()); + } } - return false; -} + PROCESS_SWITCH(trackprefilter, processCheck, "Check specific paired tracks", false); +}; struct hypertriton3bodyFinder { @@ -163,7 +223,6 @@ struct hypertriton3bodyFinder { // Configurables Configurable UseCFFilter{"UseCFFilter", true, "Reject event without CF LD trigger"}; Configurable RejectBkgInMC{"RejectBkgInMC", false, "Reject fake 3-body pairs in MC check"}; - Configurable KeepSignalInMC{"KeepSignalInMC", false, "Reject fake 3-body pairs in MC check"}; Configurable d_UseAbsDCA{"d_UseAbsDCA", true, "Use Abs DCAs"}; Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; @@ -424,7 +483,7 @@ struct hypertriton3bodyFinder { //------------------------------------------------------------------ // Check the info of good tracks template - void CheckGoodTracks(TGoodTrackTable const& dGoodtracks, aod::McParticles const& mcparticles) + void CheckGoodTracks(TGoodTrackTable const& dGoodtracks, aod::McParticles const& particlesMC) { for (auto& goodtrackid : dGoodtracks) { auto goodtrack = goodtrackid.template goodTrack_as(); @@ -455,184 +514,223 @@ struct hypertriton3bodyFinder { o2::dataformats::VertexBase mMeanVertex{{0., 0., 0.}, {0.1 * 0.1, 0., 0.1 * 0.1, 0., 0., 6. * 6.}}; //------------------------------------------------------------------ - // 3body decay finder - template - void DecayFinder(TCollisionTable const& dCollision, TPosTrackTable const& dPtracks, TNegTrackTable const& dNtracks, TGoodTrackTable const& dGoodtracks) + // Virtual Lambda V0 finder + template + bool DecayV0Finder(TCollisionTable const& dCollision, TTrackTable const& dPtrack, TTrackTable const& dNtrack, float& rv0, bool isTrue3bodyV0 = false) { - for (auto& t0id : dPtracks) { // FIXME: turn into combination(...) - auto t0 = t0id.template goodTrack_as(); - auto Track0 = getTrackParCov(t0); + if (dPtrack.collisionId() != dNtrack.collisionId()) { + return false; + } + FillV0Counter(kV0All, isTrue3bodyV0); + if (!isTrue3bodyV0 && RejectBkgInMC) { + return false; + } - for (auto& t1id : dNtracks) { + auto Track0 = getTrackParCov(dPtrack); + auto Track1 = getTrackParCov(dNtrack); + int nCand = fitter.process(Track0, Track1); + if (nCand == 0) { + return false; + } + FillV0Counter(kV0hasSV, isTrue3bodyV0); + + // validate V0 radial position + // First check closeness to the beam-line as same as SVertexer + const auto& v0XYZ = fitter.getPCACandidate(); + float dxv0 = v0XYZ[0] - mMeanVertex.getX(), dyv0 = v0XYZ[1] - mMeanVertex.getY(), r2v0 = dxv0 * dxv0 + dyv0 * dyv0; + // float rv0 = std::sqrt(r2v0); + rv0 = std::sqrt(r2v0); + if (rv0 < minRToMeanVertex) { + return false; + } + FillV0Counter(kV0Radius, isTrue3bodyV0); - FillV0Counter(kV0All); - auto t1 = t1id.template goodTrack_as(); - auto Track1 = getTrackParCov(t1); - int nCand = fitter.process(Track0, Track1); - if (nCand == 0) { - continue; - } - FillV0Counter(kV0hasSV); - - // validate V0 radial position - // First check closeness to the beam-line as same as SVertexer - const auto& v0XYZ = fitter.getPCACandidate(); - float dxv0 = v0XYZ[0] - mMeanVertex.getX(), dyv0 = v0XYZ[1] - mMeanVertex.getY(), r2v0 = dxv0 * dxv0 + dyv0 * dyv0; - float rv0 = std::sqrt(r2v0); - if (rv0 < minRToMeanVertex) { - continue; - } - FillV0Counter(kV0Radius); + // Not involved: Get minR with same way in SVertexer + // float drv0P = rv0 - Track0minR, drv0N = rv0 - Track1minR; - // Not involved: Get minR with same way in SVertexer - // float drv0P = rv0 - Track0minR, drv0N = rv0 - Track1minR; + // check: if the process function finish the propagation + if (!fitter.isPropagateTracksToVertexDone() && !fitter.propagateTracksToVertex()) { + return false; + } - // check: if the process function finish the propagation - if (!fitter.isPropagateTracksToVertexDone() && !fitter.propagateTracksToVertex()) { - continue; - } + auto& trPProp = fitter.getTrack(0); + auto& trNProp = fitter.getTrack(1); + std::array pP, pN; + trPProp.getPxPyPzGlo(pP); + trNProp.getPxPyPzGlo(pN); + // estimate DCA of neutral V0 track to beamline: straight line with parametric equation + // x = X0 + pV0[0]*t, y = Y0 + pV0[1]*t reaches DCA to beamline (Xv, Yv) at + // t = -[ (x0-Xv)*pV0[0] + (y0-Yv)*pV0[1]) ] / ( pT(pV0)^2 ) + // Similar equation for 3D distance involving pV0[2] + std::array pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]}; + float pt2V0 = pV0[0] * pV0[0] + pV0[1] * pV0[1], prodXYv0 = dxv0 * pV0[0] + dyv0 * pV0[1], tDCAXY = prodXYv0 / pt2V0; + float p2V0 = pt2V0 + pV0[2] * pV0[2], ptV0 = std::sqrt(pt2V0); + if (ptV0 < minPtV0) { // pt cut + return false; + } + FillV0Counter(kV0Pt, isTrue3bodyV0); - int cand = 0; - auto& trPProp = fitter.getTrack(0, cand); - auto& trNProp = fitter.getTrack(1, cand); - std::array pP, pN; - trPProp.getPxPyPzGlo(pP); - trNProp.getPxPyPzGlo(pN); - // estimate DCA of neutral V0 track to beamline: straight line with parametric equation - // x = X0 + pV0[0]*t, y = Y0 + pV0[1]*t reaches DCA to beamline (Xv, Yv) at - // t = -[ (x0-Xv)*pV0[0] + (y0-Yv)*pV0[1]) ] / ( pT(pV0)^2 ) - // Similar equation for 3D distance involving pV0[2] - std::array pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]}; - float pt2V0 = pV0[0] * pV0[0] + pV0[1] * pV0[1], prodXYv0 = dxv0 * pV0[0] + dyv0 * pV0[1], tDCAXY = prodXYv0 / pt2V0; - float p2V0 = pt2V0 + pV0[2] * pV0[2], ptV0 = std::sqrt(pt2V0); - if (ptV0 < minPtV0) { // pt cut - continue; - } - FillV0Counter(kV0Pt); + if (pV0[2] / ptV0 > maxTglV0) { // tgLambda cut + return false; + } + FillV0Counter(kV0TgLamda, isTrue3bodyV0); + + // apply mass selections + float massV0LambdaHyp = RecoDecay::m(array{array{pP[0], pP[1], pP[2]}, array{pN[0], pN[1], pN[2]}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); + float massV0AntiLambdaHyp = RecoDecay::m(array{array{pP[0], pP[1], pP[2]}, array{pN[0], pN[1], pN[2]}}, array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); + float massMargin = 20 * (0.001 * (1. + 0.5 * ptV0)) + 0.07; + if (massV0LambdaHyp - o2::constants::physics::MassLambda > massMargin && massV0AntiLambdaHyp - o2::constants::physics::MassLambda > massMargin) { + return false; + } + FillV0Counter(kV0InvMass, isTrue3bodyV0); - if (pV0[2] / ptV0 > maxTglV0) { // tgLambda cut - continue; - } - FillV0Counter(kV0TgLamda); + float dcaX = dxv0 - pV0[0] * tDCAXY, dcaY = dyv0 - pV0[1] * tDCAXY, dca2 = dcaX * dcaX + dcaY * dcaY; + float cosPAXY = prodXYv0 / std::sqrt(r2v0 * pt2V0); + if (dca2 > maxDCAXY2ToMeanVertex3bodyV0) { + return false; + } + FillV0Counter(kV0DcaXY, isTrue3bodyV0); - // apply mass selections - float massV0LambdaHyp = RecoDecay::m(array{array{pP[0], pP[1], pP[2]}, array{pN[0], pN[1], pN[2]}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); - float massV0AntiLambdaHyp = RecoDecay::m(array{array{pP[0], pP[1], pP[2]}, array{pN[0], pN[1], pN[2]}}, array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); - float massMargin = 20 * (0.001 * (1. + 0.5 * ptV0)) + 0.07; - if (massV0LambdaHyp - o2::constants::physics::MassLambda > massMargin && massV0AntiLambdaHyp - o2::constants::physics::MassLambda > massMargin) { - continue; - } - FillV0Counter(kV0InvMass); + if (cosPAXY < minCosPAXYMeanVertex3bodyV0) { + return false; + } + float dx = v0XYZ[0] - dCollision.posX(), dy = v0XYZ[1] - dCollision.posY(), dz = v0XYZ[2] - dCollision.posZ(), prodXYZv0 = dx * pV0[0] + dy * pV0[1] + dz * pV0[2]; + float cosPA = prodXYZv0 / std::sqrt((dx * dx + dy * dy + dz * dz) * p2V0); + if (cosPA < minCosPA3bodyV0) { + return false; + } + FillV0Counter(kV0CosPA, isTrue3bodyV0); + return true; + } + //------------------------------------------------------------------ + // 3body decay vertex finder + template + void Decay3bodyFinder(TCollisionTable const& dCollision, TTrackTable const& dPtrack, TTrackTable const& dNtrack, TTrackTable const& dBachtrack, float const& rv0, bool isTrue3bodyVtx = false) + { + if (dPtrack.collisionId() != dBachtrack.collisionId()) { + return; + } + if (dPtrack.globalIndex() == dBachtrack.globalIndex()) { + return; // skip the track used by V0 + } + FillVtxCounter(kVtxAll, isTrue3bodyVtx); + if (!isTrue3bodyVtx && RejectBkgInMC) { + return; + } - float dcaX = dxv0 - pV0[0] * tDCAXY, dcaY = dyv0 - pV0[1] * tDCAXY, dca2 = dcaX * dcaX + dcaY * dcaY; - if (dca2 > maxDCAXY2ToMeanVertex3bodyV0) { - continue; - } - FillV0Counter(kV0DcaXY); + auto track0 = getTrackParCov(dPtrack); + auto track1 = getTrackParCov(dNtrack); + auto bach = getTrackParCov(dBachtrack); - float cosPAXY = prodXYv0 / std::sqrt(r2v0 * pt2V0); - if (cosPAXY < minCosPAXYMeanVertex3bodyV0) { - continue; - } - float dx = v0XYZ[0] - dCollision.posX(), dy = v0XYZ[1] - dCollision.posY(), dz = v0XYZ[2] - dCollision.posZ(), prodXYZv0 = dx * pV0[0] + dy * pV0[1] + dz * pV0[2]; - float cosPA = prodXYZv0 / std::sqrt((dx * dx + dy * dy + dz * dz) * p2V0); - if (cosPA < minCosPA3bodyV0) { - continue; - } - FillV0Counter(kV0CosPA); + if (bach.getPt() < minbachPt) { + return; + } + FillVtxCounter(kVtxbachPt, isTrue3bodyVtx); - for (auto& t2id : dGoodtracks) { - if (t2id.globalIndex() == t0id.globalIndex()) { - continue; // skip the track used by V0 - } - FillVtxCounter(kVtxAll); + int n3bodyVtx = fitter3body.process(track0, track1, bach); + if (n3bodyVtx == 0) { // discard this pair + return; + } + FillVtxCounter(kVtxhasSV, isTrue3bodyVtx); - auto t2 = t2id.template goodTrack_as(); - auto track0 = getTrackParCov(t0); - auto track1 = getTrackParCov(t1); - auto bach = getTrackParCov(t2); + const auto& vertexXYZ = fitter3body.getPCACandidatePos(); + // make sure the cascade radius is smaller than that of the vertex + float dxc = vertexXYZ[0] - dCollision.posX(), dyc = vertexXYZ[1] - dCollision.posY(), dzc = vertexXYZ[2] - dCollision.posZ(), r2vertex = dxc * dxc + dyc * dyc; + float rvertex = std::sqrt(r2vertex); + if (std::abs(rv0 - rvertex) > maxRDiff3bodyV0 || rvertex < minRToMeanVertex) { + return; + } + FillVtxCounter(kVtxRadius, isTrue3bodyVtx); - if (bach.getPt() < 0.6) { - continue; - } - FillVtxCounter(kVtxbachPt); + // Not involved: bach.minR - rveretx check - int n3bodyVtx = fitter3body.process(track0, track1, bach); - if (n3bodyVtx == 0) { // discard this pair - continue; - } - FillVtxCounter(kVtxhasSV); - - int cand3B = 0; - const auto& vertexXYZ = fitter3body.getPCACandidatePos(cand3B); - // make sure the cascade radius is smaller than that of the vertex - float dxc = vertexXYZ[0] - dCollision.posX(), dyc = vertexXYZ[1] - dCollision.posY(), dzc = vertexXYZ[2] - dCollision.posZ(), r2vertex = dxc * dxc + dyc * dyc; - float rvertex = std::sqrt(r2vertex); - if (std::abs(rv0 - rvertex) > maxRDiff3bodyV0 || rvertex < minRToMeanVertex) { - continue; - } - FillVtxCounter(kVtxRadius); + // check: if the process function finish the propagation + if (!fitter3body.isPropagateTracksToVertexDone() && !fitter3body.propagateTracksToVertex()) { + return; + } - // Not involved: bach.minR - rveretx check + auto& tr0 = fitter3body.getTrack(0); + auto& tr1 = fitter3body.getTrack(1); + auto& tr2 = fitter3body.getTrack(2); + std::array p0, p1, p2; + tr0.getPxPyPzGlo(p0); + tr1.getPxPyPzGlo(p1); + tr2.getPxPyPzGlo(p2); + std::array p3B = {p0[0] + p1[0] + p2[0], p0[1] + p1[1] + p2[1], p0[2] + p1[2] + p2[2]}; + + float pt2 = p3B[0] * p3B[0] + p3B[1] * p3B[1], p2candidate = pt2 + p3B[2] * p3B[2]; + float pt = std::sqrt(pt2); + if (pt < minPt3Body) { // pt cut + return; + } + FillVtxCounter(kVtxPt, isTrue3bodyVtx); - if (!fitter3body.isPropagateTracksToVertexDone() && !fitter3body.propagateTracksToVertex()) { - continue; - } + if (p3B[2] / pt > maxTgl3Body) { // tgLambda cut + return; + } + FillVtxCounter(kVtxTgLamda, isTrue3bodyVtx); - auto& tr0 = fitter3body.getTrack(0, cand3B); - auto& tr1 = fitter3body.getTrack(1, cand3B); - auto& tr2 = fitter3body.getTrack(2, cand3B); - std::array p0, p1, p2; - tr0.getPxPyPzGlo(p0); - tr1.getPxPyPzGlo(p1); - tr2.getPxPyPzGlo(p2); - std::array p3B = {p0[0] + p1[0] + p2[0], p0[1] + p1[1] + p2[1], p0[2] + p1[2] + p2[2]}; - - float pt2 = p3B[0] * p3B[0] + p3B[1] * p3B[1], p2candidate = pt2 + p3B[2] * p3B[2]; - float pt = std::sqrt(pt2); - if (pt < minPt3Body) { // pt cut - continue; - } - FillVtxCounter(kVtxPt); + float cosPA = (p3B[0] * dxc + p3B[1] * dyc + p3B[2] * dzc) / std::sqrt(p2candidate * (r2vertex + dzc * dzc)); + if (cosPA < minCosPA3body) { + return; + } + FillVtxCounter(kVtxCosPA, isTrue3bodyVtx); - if (p3B[2] / pt > maxTgl3Body) { // tgLambda cut - continue; - } - FillVtxCounter(kVtxTgLamda); + if (fitter3body.getChi2AtPCACandidate() > dcavtxdau) { + return; + } + FillVtxCounter(kVtxDcaDau, isTrue3bodyVtx); - float cosPA = (p3B[0] * dxc + p3B[1] * dyc + p3B[2] * dzc) / std::sqrt(p2candidate * (r2vertex + dzc * dzc)); - if (cosPA < minCosPA3body) { - continue; - } - FillVtxCounter(kVtxCosPA); + // Calculate DCA with respect to the collision associated to the V0, not individual tracks + gpu::gpustd::array dcaInfo; - if (fitter3body.getChi2AtPCACandidate() > dcavtxdau) { - continue; - } - FillVtxCounter(kVtxDcaDau); - - // Calculate DCA with respect to the collision associated to the V0, not individual tracks - gpu::gpustd::array dcaInfo; - - auto Track0Par = getTrackPar(t0); - o2::base::Propagator::Instance()->propagateToDCABxByBz({dCollision.posX(), dCollision.posY(), dCollision.posZ()}, Track0Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); - auto Track0dcaXY = dcaInfo[0]; - - auto Track1Par = getTrackPar(t1); - o2::base::Propagator::Instance()->propagateToDCABxByBz({dCollision.posX(), dCollision.posY(), dCollision.posZ()}, Track1Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); - auto Track1dcaXY = dcaInfo[0]; - - auto Track2Par = getTrackPar(t2); - o2::base::Propagator::Instance()->propagateToDCABxByBz({dCollision.posX(), dCollision.posY(), dCollision.posZ()}, Track2Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); - auto Track2dcaXY = dcaInfo[0]; - - // Not involved: H3L DCA Check - vtx3bodydata( - t0.globalIndex(), t1.globalIndex(), t2.globalIndex(), dCollision.globalIndex(), 0, - vertexXYZ[0], vertexXYZ[1], vertexXYZ[2], - p0[0], p0[1], p0[2], p1[0], p1[1], p1[2], p2[0], p2[1], p2[2], - fitter3body.getChi2AtPCACandidate(), - Track0dcaXY, Track1dcaXY, Track2dcaXY); + auto Track0Par = getTrackPar(dPtrack); + o2::base::Propagator::Instance()->propagateToDCABxByBz({dCollision.posX(), dCollision.posY(), dCollision.posZ()}, Track0Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); + auto Track0dcaXY = dcaInfo[0]; + + auto Track1Par = getTrackPar(dNtrack); + o2::base::Propagator::Instance()->propagateToDCABxByBz({dCollision.posX(), dCollision.posY(), dCollision.posZ()}, Track1Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); + auto Track1dcaXY = dcaInfo[0]; + + auto Track2Par = getTrackPar(dBachtrack); + o2::base::Propagator::Instance()->propagateToDCABxByBz({dCollision.posX(), dCollision.posY(), dCollision.posZ()}, Track2Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); + auto Track2dcaXY = dcaInfo[0]; + + // H3L DCA Check + // auto track3B = o2::track::TrackParCov(vertexXYZ, p3B, fitter3body.calcPCACovMatrixFlat(), t2.sign()); + auto track3B = o2::track::TrackParCov(vertexXYZ, p3B, dBachtrack.sign()); + o2::dataformats::DCA dca; + if (d_UseH3LDCACut && (!track3B.propagateToDCA({{dCollision.posX(), dCollision.posY(), dCollision.posZ()}, {dCollision.covXX(), dCollision.covXY(), dCollision.covYY(), dCollision.covXZ(), dCollision.covYZ(), dCollision.covZZ()}}, fitter3body.getBz(), &dca, 5.) || + std::abs(dca.getY()) > maxDCAXY3Body || std::abs(dca.getZ()) > maxDCAZ3Body)) { + return; + } + FillVtxCounter(kVtxDcaH3L, isTrue3bodyVtx); + + vtx3bodydata( + dPtrack.globalIndex(), dNtrack.globalIndex(), dBachtrack.globalIndex(), dCollision.globalIndex(), 0, + vertexXYZ[0], vertexXYZ[1], vertexXYZ[2], + p0[0], p0[1], p0[2], p1[0], p1[1], p1[2], p2[0], p2[1], p2[2], + fitter3body.getChi2AtPCACandidate(), + Track0dcaXY, Track1dcaXY, Track2dcaXY); + } + //------------------------------------------------------------------ + // 3body decay finder for a collsion + template + void DecayFinder(TCollisionTable const& dCollision, TPosTrackTable const& dPtracks, TNegTrackTable const& dNtracks, TGoodTrackTable const& dGoodtracks) + { + for (auto& t0id : dPtracks) { // FIXME: turn into combination(...) + auto t0 = t0id.template goodTrack_as(); + + for (auto& t1id : dNtracks) { + auto t1 = t1id.template goodTrack_as(); + float rv0; + if (!DecayV0Finder(dCollision, t0, t1, rv0)) { + continue; + } + + for (auto& t2id : dGoodtracks) { + auto t2 = t2id.template goodTrack_as(); + Decay3bodyFinder(dCollision, t0, t1, t2, rv0); } } } @@ -640,20 +738,17 @@ struct hypertriton3bodyFinder { resetHistos(); } //------------------------------------------------------------------ - // MC 3body decay finder + // MC 3body decay vertex finder template void DecayFinderMC(TCollisionTable const& dCollision, TPosTrackTable const& dPtracks, TNegTrackTable const& dNtracks, TGoodTrackTable const& dGoodtracks) { for (auto& t0id : dPtracks) { // FIXME: turn into combination(...) auto t0 = t0id.template goodTrack_as(); - auto Track0 = getTrackParCov(t0); for (auto& t1id : dNtracks) { - - if (t0id.collisionId() != t1id.collisionId()) { + auto t1 = t1id.template goodTrack_as(); + if (t0.collisionId() != t1.collisionId()) { continue; } - auto t1 = t1id.template goodTrack_as(); - auto Track1 = getTrackParCov(t1); bool isTrue3bodyV0 = false; if (t0.has_mcParticle() && t1.has_mcParticle()) { @@ -672,92 +767,13 @@ struct hypertriton3bodyFinder { } } - FillV0Counter(kV0All, isTrue3bodyV0); - if (!isTrue3bodyV0 && RejectBkgInMC) { + float rv0; + if (!DecayV0Finder(dCollision, t0, t1, rv0, isTrue3bodyV0)) { continue; } - int nCand = fitter.process(Track0, Track1); - if (nCand == 0) { - continue; - } - FillV0Counter(kV0hasSV, isTrue3bodyV0); - - // validate V0 radial position - // First check closeness to the beam-line as same as SVertexer - const auto& v0XYZ = fitter.getPCACandidate(); - float dxv0 = v0XYZ[0] - mMeanVertex.getX(), dyv0 = v0XYZ[1] - mMeanVertex.getY(), r2v0 = dxv0 * dxv0 + dyv0 * dyv0; - float rv0 = std::sqrt(r2v0); - if (rv0 < minRToMeanVertex) { - continue; - } - FillV0Counter(kV0Radius, isTrue3bodyV0); - - // Not involved: Get minR with same way in SVertexer - // float drv0P = rv0 - Track0minR, drv0N = rv0 - Track1minR; - - // check: if the process function finish the propagation - if (!fitter.isPropagateTracksToVertexDone() && !fitter.propagateTracksToVertex()) { - continue; - } - - int cand = 0; - auto& trPProp = fitter.getTrack(0, cand); - auto& trNProp = fitter.getTrack(1, cand); - std::array pP, pN; - trPProp.getPxPyPzGlo(pP); - trNProp.getPxPyPzGlo(pN); - // estimate DCA of neutral V0 track to beamline: straight line with parametric equation - // x = X0 + pV0[0]*t, y = Y0 + pV0[1]*t reaches DCA to beamline (Xv, Yv) at - // t = -[ (x0-Xv)*pV0[0] + (y0-Yv)*pV0[1]) ] / ( pT(pV0)^2 ) - // Similar equation for 3D distance involving pV0[2] - std::array pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]}; - float pt2V0 = pV0[0] * pV0[0] + pV0[1] * pV0[1], prodXYv0 = dxv0 * pV0[0] + dyv0 * pV0[1], tDCAXY = prodXYv0 / pt2V0; - float p2V0 = pt2V0 + pV0[2] * pV0[2], ptV0 = std::sqrt(pt2V0); - if (ptV0 < minPtV0) { // pt cut - continue; - } - FillV0Counter(kV0Pt, isTrue3bodyV0); - - if (pV0[2] / ptV0 > maxTglV0) { // tgLambda cut - continue; - } - FillV0Counter(kV0TgLamda, isTrue3bodyV0); - - // apply mass selections - float massV0LambdaHyp = RecoDecay::m(array{array{pP[0], pP[1], pP[2]}, array{pN[0], pN[1], pN[2]}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); - float massV0AntiLambdaHyp = RecoDecay::m(array{array{pP[0], pP[1], pP[2]}, array{pN[0], pN[1], pN[2]}}, array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); - float massMargin = 20 * (0.001 * (1. + 0.5 * ptV0)) + 0.07; - if (massV0LambdaHyp - o2::constants::physics::MassLambda > massMargin && massV0AntiLambdaHyp - o2::constants::physics::MassLambda > massMargin) { - continue; - } - FillV0Counter(kV0InvMass, isTrue3bodyV0); - - float dcaX = dxv0 - pV0[0] * tDCAXY, dcaY = dyv0 - pV0[1] * tDCAXY, dca2 = dcaX * dcaX + dcaY * dcaY; - float cosPAXY = prodXYv0 / std::sqrt(r2v0 * pt2V0); - if (dca2 > maxDCAXY2ToMeanVertex3bodyV0) { - continue; - } - FillV0Counter(kV0DcaXY, isTrue3bodyV0); - - if (cosPAXY < minCosPAXYMeanVertex3bodyV0) { - continue; - } - float dx = v0XYZ[0] - dCollision.posX(), dy = v0XYZ[1] - dCollision.posY(), dz = v0XYZ[2] - dCollision.posZ(), prodXYZv0 = dx * pV0[0] + dy * pV0[1] + dz * pV0[2]; - float cosPA = prodXYZv0 / std::sqrt((dx * dx + dy * dy + dz * dz) * p2V0); - if (cosPA < minCosPA3bodyV0) { - continue; - } - FillV0Counter(kV0CosPA, isTrue3bodyV0); - for (auto& t2id : dGoodtracks) { - if (t2id.globalIndex() == t0id.globalIndex()) { - continue; // skip the track used by V0 - } auto t2 = t2id.template goodTrack_as(); - auto track0 = getTrackParCov(t0); - auto track1 = getTrackParCov(t1); - auto bach = getTrackParCov(t2); bool isTrue3bodyVtx = false; if (t0.has_mcParticle() && t1.has_mcParticle() && t2.has_mcParticle()) { @@ -779,109 +795,13 @@ struct hypertriton3bodyFinder { } } - FillVtxCounter(kVtxAll, isTrue3bodyVtx); - if (!isTrue3bodyVtx && RejectBkgInMC) { - continue; - } - - if (bach.getPt() < minbachPt) { - continue; - } - FillVtxCounter(kVtxbachPt, isTrue3bodyVtx); - - int n3bodyVtx = fitter3body.process(track0, track1, bach); - if (n3bodyVtx == 0) { // discard this pair - continue; - } - FillVtxCounter(kVtxhasSV, isTrue3bodyVtx); - - int cand3B = 0; - const auto& vertexXYZ = fitter3body.getPCACandidatePos(cand3B); - // make sure the cascade radius is smaller than that of the vertex - float dxc = vertexXYZ[0] - dCollision.posX(), dyc = vertexXYZ[1] - dCollision.posY(), dzc = vertexXYZ[2] - dCollision.posZ(), r2vertex = dxc * dxc + dyc * dyc; - float rvertex = std::sqrt(r2vertex); - if (std::abs(rv0 - rvertex) > maxRDiff3bodyV0 || rvertex < minRToMeanVertex) { - continue; - } - FillVtxCounter(kVtxRadius, isTrue3bodyVtx); - - // Not involved: bach.minR - rveretx check - - // check: if the process function finish the propagation - if (!fitter3body.isPropagateTracksToVertexDone() && !fitter3body.propagateTracksToVertex()) { - continue; - } - - auto& tr0 = fitter3body.getTrack(0, cand3B); - auto& tr1 = fitter3body.getTrack(1, cand3B); - auto& tr2 = fitter3body.getTrack(2, cand3B); - std::array p0, p1, p2; - tr0.getPxPyPzGlo(p0); - tr1.getPxPyPzGlo(p1); - tr2.getPxPyPzGlo(p2); - std::array p3B = {p0[0] + p1[0] + p2[0], p0[1] + p1[1] + p2[1], p0[2] + p1[2] + p2[2]}; - - float pt2 = p3B[0] * p3B[0] + p3B[1] * p3B[1], p2candidate = pt2 + p3B[2] * p3B[2]; - float pt = std::sqrt(pt2); - if (pt < minPt3Body) { // pt cut - continue; - } - FillVtxCounter(kVtxPt, isTrue3bodyVtx); - - if (p3B[2] / pt > maxTgl3Body) { // tgLambda cut - continue; - } - FillVtxCounter(kVtxTgLamda, isTrue3bodyVtx); - - float cosPA = (p3B[0] * dxc + p3B[1] * dyc + p3B[2] * dzc) / std::sqrt(p2candidate * (r2vertex + dzc * dzc)); - if (cosPA < minCosPA3body) { - continue; - } - FillVtxCounter(kVtxCosPA, isTrue3bodyVtx); - - if (fitter3body.getChi2AtPCACandidate() > dcavtxdau) { - continue; - } - FillVtxCounter(kVtxDcaDau, isTrue3bodyVtx); - - // Calculate DCA with respect to the collision associated to the V0, not individual tracks - gpu::gpustd::array dcaInfo; - - auto Track0Par = getTrackPar(t0); - o2::base::Propagator::Instance()->propagateToDCABxByBz({dCollision.posX(), dCollision.posY(), dCollision.posZ()}, Track0Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); - auto Track0dcaXY = dcaInfo[0]; - - auto Track1Par = getTrackPar(t1); - o2::base::Propagator::Instance()->propagateToDCABxByBz({dCollision.posX(), dCollision.posY(), dCollision.posZ()}, Track1Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); - auto Track1dcaXY = dcaInfo[0]; - - auto Track2Par = getTrackPar(t2); - o2::base::Propagator::Instance()->propagateToDCABxByBz({dCollision.posX(), dCollision.posY(), dCollision.posZ()}, Track2Par, 2.f, fitter3body.getMatCorrType(), &dcaInfo); - auto Track2dcaXY = dcaInfo[0]; - - // Not involved: H3L DCA Check - // auto track3B = o2::track::TrackParCov(vertexXYZ, p3B, fitter3body.calcPCACovMatrixFlat(cand3B), t2.sign()); - auto track3B = o2::track::TrackParCov(vertexXYZ, p3B, t2.sign()); - o2::dataformats::DCA dca; - if (d_UseH3LDCACut && (!track3B.propagateToDCA({{dCollision.posX(), dCollision.posY(), dCollision.posZ()}, {dCollision.covXX(), dCollision.covXY(), dCollision.covYY(), dCollision.covXZ(), dCollision.covYZ(), dCollision.covZZ()}}, fitter3body.getBz(), &dca, 5.) || - std::abs(dca.getY()) > maxDCAXY3Body || std::abs(dca.getZ()) > maxDCAZ3Body)) { - continue; - } - FillVtxCounter(kVtxDcaH3L, isTrue3bodyVtx); - - vtx3bodydata( - t0.globalIndex(), t1.globalIndex(), t2.globalIndex(), dCollision.globalIndex(), 0, - vertexXYZ[0], vertexXYZ[1], vertexXYZ[2], - p0[0], p0[1], p0[2], p1[0], p1[1], p1[2], p2[0], p2[1], p2[2], - fitter3body.getChi2AtPCACandidate(), - Track0dcaXY, Track1dcaXY, Track2dcaXY); + Decay3bodyFinder(dCollision, t0, t1, t2, rv0, isTrue3bodyVtx); } } } fillHistos(); resetHistos(); } - //------------------------------------------------------------------ // MC virtual lambda check template @@ -925,7 +845,7 @@ struct hypertriton3bodyFinder { DecayFinder(collision, ptracks, ntracks, goodtracks); } - PROCESS_SWITCH(hypertriton3bodyFinder, processData, "Produce StoredVtx3BodyDatas with data", false); + PROCESS_SWITCH(hypertriton3bodyFinder, processData, "Produce StoredVtx3BodyDatas with data", true); void processCFFilteredData(aod::Collisions const& collisions, aod::CFFilters const& cffilters, aod::V0GoodPosTracks const& Ptracks, aod::V0GoodNegTracks const& Ntracks, aod::V0GoodTracks const& Goodtracks, FullTracksExtIU const&, aod::BCsWithTimestamps const&) { @@ -948,20 +868,20 @@ struct hypertriton3bodyFinder { DecayFinder(collision, ptracks, ntracks, goodtracks); } } - PROCESS_SWITCH(hypertriton3bodyFinder, processCFFilteredData, "Produce StoredVtx3BodyDatas with data using CFtriggers", true); + PROCESS_SWITCH(hypertriton3bodyFinder, processCFFilteredData, "Produce StoredVtx3BodyDatas with data using CFtriggers", false); - void processMC(aod::Collision const& collision, aod::V0GoodPosTracks const& ptracks, aod::V0GoodNegTracks const& ntracks, aod::V0GoodTracks const& goodtracks, aod::McParticles const& mcparticles, FullTracksExtMCIU const&, aod::BCsWithTimestamps const&) + void processMC(aod::Collision const& collision, aod::V0GoodPosTracks const& ptracks, aod::V0GoodNegTracks const& ntracks, aod::V0GoodTracks const& goodtracks, aod::McParticles const& particlesMC, MCLabeledFullTracksExtIU const&, aod::BCsWithTimestamps const&) { auto bc = collision.bc_as(); initCCDB(bc); registry.fill(HIST("hEventCounter"), 0.5); - CheckGoodTracks(goodtracks, mcparticles); - DecayFinderMC(collision, ptracks, ntracks, goodtracks); + CheckGoodTracks(goodtracks, particlesMC); + DecayFinderMC(collision, ptracks, ntracks, goodtracks); } PROCESS_SWITCH(hypertriton3bodyFinder, processMC, "Produce StoredVtx3BodyDatas with MC", false); - void processCFFilteredMC(aod::Collisions const& collisions, aod::CFFilters const& cffilters, aod::V0GoodPosTracks const& Ptracks, aod::V0GoodNegTracks const& Ntracks, aod::V0GoodTracks const& Goodtracks, aod::V0s const& V0s, aod::V0Datas const& fullV0s, aod::McParticles const& mcparticles, FullTracksExtMCIU const&, aod::BCsWithTimestamps const&) + void processCFFilteredMC(aod::Collisions const& collisions, aod::CFFilters const& cffilters, aod::V0GoodPosTracks const& Ptracks, aod::V0GoodNegTracks const& Ntracks, aod::V0GoodTracks const& Goodtracks, aod::V0s const& V0s, aod::V0Datas const& fullV0s, aod::McParticles const& particlesMC, MCLabeledFullTracksExtIU const&, aod::BCsWithTimestamps const&) { for (int i{0}; i < collisions.size(); i++) { auto collision = collisions.iteratorAt(i); @@ -971,11 +891,11 @@ struct hypertriton3bodyFinder { registry.fill(HIST("hEventCounter"), 0.5); auto goodtracks = Goodtracks.sliceBy(perCollisionGoodTracks, collision.globalIndex()); - CheckGoodTracks(goodtracks, mcparticles); + CheckGoodTracks(goodtracks, particlesMC); auto v0s = V0s.sliceBy(perCollisionV0s, collision.globalIndex()); auto fullv0s = fullV0s.sliceBy(perCollisionV0Datas, collision.globalIndex()); - VirtualLambdaCheck(collision, v0s, 0); - VirtualLambdaCheck(collision, fullv0s, 3); + VirtualLambdaCheck(collision, v0s, 0); + VirtualLambdaCheck(collision, fullv0s, 3); if (!cffilter.hasLD() && UseCFFilter) { continue; @@ -985,9 +905,9 @@ struct hypertriton3bodyFinder { auto ptracks = Ptracks.sliceBy(perCollisionGoodPosTracks, collision.globalIndex()); auto ntracks = Ntracks.sliceBy(perCollisionGoodNegTracks, collision.globalIndex()); - VirtualLambdaCheck(collision, v0s, 6); - VirtualLambdaCheck(collision, fullv0s, 9); - DecayFinderMC(collision, ptracks, ntracks, goodtracks); + VirtualLambdaCheck(collision, v0s, 6); + VirtualLambdaCheck(collision, fullv0s, 9); + DecayFinderMC(collision, ptracks, ntracks, goodtracks); } } PROCESS_SWITCH(hypertriton3bodyFinder, processCFFilteredMC, "Produce StoredVtx3BodyDatas with MC using CFtriggers", false); @@ -1037,7 +957,7 @@ struct hypertriton3bodyLabelBuilder { } PROCESS_SWITCH(hypertriton3bodyLabelBuilder, processDoNotBuildLabels, "Do not produce MC label tables", true); - void processBuildLabels(aod::Vtx3BodyDatas const& vtx3bodydatas, LabeledTracks const&, aod::McParticles const& particlesMC) + void processBuildLabels(aod::Vtx3BodyDatas const& vtx3bodydatas, MCLabeledFullTracksExtIU const&, aod::McParticles const& particlesMC) { std::vector lIndices; lIndices.reserve(vtx3bodydatas.size()); @@ -1054,9 +974,9 @@ struct hypertriton3bodyLabelBuilder { bool is3bodyDecay = false; int lGlobalIndex = -1; - auto lTrack0 = vtx3body.track0_as(); - auto lTrack1 = vtx3body.track1_as(); - auto lTrack2 = vtx3body.track2_as(); + auto lTrack0 = vtx3body.track0_as(); + auto lTrack1 = vtx3body.track1_as(); + auto lTrack2 = vtx3body.track2_as(); registry.fill(HIST("hLabelCounter"), 0.5); // Association check @@ -1146,6 +1066,152 @@ struct hypertriton3bodyLabelBuilder { PROCESS_SWITCH(hypertriton3bodyLabelBuilder, processBuildLabels, "Produce MC label tables", false); }; +struct hypertriton3bodyComparewithDecay3body { + + HistogramRegistry registry{ + "registry", + { + {"hMCInfoCounter", "hMCInfoCounter", {HistType::kTH1F, {{8, 0.0f, 8.0f}}}}, + {"hCheckCounter", "hCheckCounter", {HistType::kTH1F, {{5, 0.0f, 5.0f}}}}, + {"hHypertritonMCPtTotal", "hHypertritonMCPtTotal", {HistType::kTH1F, {{20, 0.0f, 10.0f}}}}, + {"hHypertritonMCPt", "hHypertritonMCPt", {HistType::kTH1F, {{100, 0.0f, 10.0f}}}}, + {"hAntiHypertritonMCPt", "hAntiHypertritonMCPt", {HistType::kTH1F, {{100, 0.0f, 10.0f}}}}, + {"hHypertritonMCMass", "hHypertritonMCMass", {HistType::kTH1F, {{40, 2.95f, 3.05f}}}}, + {"hAntiHypertritonMCMass", "hAntiHypertritonMCMass", {HistType::kTH1F, {{40, 2.95f, 3.05f}}}}, + {"hPairedHypertritonMCPt", "hPairedHypertritonMCPt", {HistType::kTH1F, {{100, 0.0f, 10.0f}}}}, + {"hPairedAntiHypertritonMCPt", "hPairedAntiHypertritonMCPt", {HistType::kTH1F, {{100, 0.0f, 10.0f}}}}, + {"hSameMcIndexCounter", "hSameMcIndexCounter", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, + }, + }; + + void init(InitContext const&) + { + registry.get(HIST("hCheckCounter"))->GetXaxis()->SetBinLabel(1, "Total"); + registry.get(HIST("hCheckCounter"))->GetXaxis()->SetBinLabel(2, "Sig in Decay3body"); + registry.get(HIST("hCheckCounter"))->GetXaxis()->SetBinLabel(3, "Sig SameCol"); + registry.get(HIST("hCheckCounter"))->GetXaxis()->SetBinLabel(4, "Sig contained by finder"); + registry.get(HIST("hCheckCounter"))->GetXaxis()->SetBinLabel(5, "Sig SameIndex"); + } + struct Indexdaughters { // check duplicated paired daughters + int64_t index0; + int64_t index1; + int64_t index2; + bool operator==(const Indexdaughters& t) const + { + return (this->index0 == t.index0 && this->index1 == t.index1 && this->index2 == t.index2); + } + }; + + void processDoNotCompare(aod::Collisions::iterator const& collision) + { + // dummy process function - should not be required in the future + } + PROCESS_SWITCH(hypertriton3bodyComparewithDecay3body, processDoNotCompare, "Do not do comparison", true); + + void processDoComparison(aod::Decay3Bodys const& decay3bodytable, soa::Join const& vtx3bodydatas, MCLabeledFullTracksExtIU const&, aod::McParticles const& particlesMC) + { + std::vector set_pair; + for (auto d3body : decay3bodytable) { + registry.fill(HIST("hCheckCounter"), 0.5); + registry.fill(HIST("hMCInfoCounter"), 0.5); + auto lTrack0 = d3body.track0_as(); + auto lTrack1 = d3body.track1_as(); + auto lTrack2 = d3body.track2_as(); + if (!lTrack0.has_mcParticle() || !lTrack1.has_mcParticle() || !lTrack2.has_mcParticle()) { + continue; + } + registry.fill(HIST("hMCInfoCounter"), 1.5); + auto lMCTrack0 = lTrack0.mcParticle_as(); + auto lMCTrack1 = lTrack1.mcParticle_as(); + auto lMCTrack2 = lTrack2.mcParticle_as(); + if (lMCTrack0.isPhysicalPrimary() || lMCTrack1.isPhysicalPrimary() || lMCTrack2.isPhysicalPrimary()) { + continue; + } + if (lMCTrack0.producedByGenerator() || lMCTrack1.producedByGenerator() || lMCTrack2.producedByGenerator()) { + continue; + } + registry.fill(HIST("hMCInfoCounter"), 2.5); + + if (!lMCTrack0.has_mothers() || !lMCTrack1.has_mothers() || !lMCTrack2.has_mothers()) { + continue; + } + registry.fill(HIST("hMCInfoCounter"), 3.5); + + int lPDG = -1; + float lPt = -1; + bool is3bodyDecayedH3L = false; + int lGlobalIndex = -1; + + for (auto& lMother0 : lMCTrack0.mothers_as()) { + for (auto& lMother1 : lMCTrack1.mothers_as()) { + for (auto& lMother2 : lMCTrack2.mothers_as()) { + registry.fill(HIST("hMCInfoCounter"), 4.5); + if (lMother0.globalIndex() == lMother1.globalIndex() && lMother0.globalIndex() == lMother2.globalIndex()) { // vtxs with the same mother + registry.fill(HIST("hMCInfoCounter"), 7.5); + lGlobalIndex = lMother1.globalIndex(); + lPDG = lMother1.pdgCode(); + lPt = lMother1.pt(); + if (lPDG == 1010010030 && lMCTrack0.pdgCode() == 2212 && lMCTrack1.pdgCode() == -211 && lMCTrack2.pdgCode() == 1000010020) { + is3bodyDecayedH3L = true; + double hypertritonMCMass = RecoDecay::m(array{array{lMCTrack0.px(), lMCTrack0.py(), lMCTrack0.pz()}, array{lMCTrack1.px(), lMCTrack1.py(), lMCTrack1.pz()}, array{lMCTrack2.px(), lMCTrack2.py(), lMCTrack2.pz()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged, o2::constants::physics::MassDeuteron}); + registry.fill(HIST("hHypertritonMCPt"), lPt); + registry.fill(HIST("hHypertritonMCMass"), hypertritonMCMass); + } + if (lPDG == -1010010030 && lMCTrack0.pdgCode() == 211 && lMCTrack1.pdgCode() == -2212 && lMCTrack2.pdgCode() == -1000010020) { + is3bodyDecayedH3L = true; + double antiHypertritonMCMass = RecoDecay::m(array{array{lMCTrack0.px(), lMCTrack0.py(), lMCTrack0.pz()}, array{lMCTrack1.px(), lMCTrack1.py(), lMCTrack1.pz()}, array{lMCTrack2.px(), lMCTrack2.py(), lMCTrack2.pz()}}, array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton, o2::constants::physics::MassDeuteron}); + registry.fill(HIST("hAntiHypertritonMCPt"), lPt); + registry.fill(HIST("hAntiHypertritonMCMass"), antiHypertritonMCMass); + } + } + } + } + } // end association check + + if (!is3bodyDecayedH3L) { + continue; + } + + registry.fill(HIST("hCheckCounter"), 1.5); + registry.fill(HIST("hMCInfoCounter"), 5.5); + // for check + registry.fill(HIST("hHypertritonMCPtTotal"), lPt); + + Indexdaughters temp = {lMCTrack0.globalIndex(), lMCTrack1.globalIndex(), lMCTrack2.globalIndex()}; + auto p = std::find(set_pair.begin(), set_pair.end(), temp); + if (p == set_pair.end()) { + set_pair.push_back(temp); + registry.fill(HIST("hMCInfoCounter"), 6.5); + } + + if (lTrack0.collisionId() != lTrack1.collisionId() || lTrack0.collisionId() != lTrack2.collisionId()) { + continue; + } + registry.fill(HIST("hCheckCounter"), 2.5); + + for (auto vtx : vtx3bodydatas) { + if (vtx.mcParticleId() == -1) { + continue; + } + auto mcparticle = vtx.mcParticle_as(); + if (mcparticle.globalIndex() == lGlobalIndex) { + registry.fill(HIST("hCheckCounter"), 4.5); // rare case check: if motherId matches but daughters not + if (lTrack0.globalIndex() == vtx.track0Id() && lTrack1.globalIndex() == vtx.track1Id() && lTrack2.globalIndex() == vtx.track2Id()) { + registry.fill(HIST("hCheckCounter"), 3.5); + if (lPDG > 0) { + registry.fill(HIST("hPairedHypertritonMCPt"), lPt); + } else { + registry.fill(HIST("hPairedAntiHypertritonMCPt"), lPt); + } + break; + } + } + } + } + } + PROCESS_SWITCH(hypertriton3bodyComparewithDecay3body, processDoComparison, "Compare decay3bodys and finder method with MC", true); +}; + struct hypertriton3bodyInitializer { Spawns vtx3bodydatas; void init(InitContext const&) {} @@ -1157,6 +1223,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), adaptAnalysisTask(cfgc), }; } diff --git a/PWGLF/TableProducer/lambdakzerobuilder.cxx b/PWGLF/TableProducer/lambdakzerobuilder.cxx index 0cee635b5bd..a79ea55d94d 100644 --- a/PWGLF/TableProducer/lambdakzerobuilder.cxx +++ b/PWGLF/TableProducer/lambdakzerobuilder.cxx @@ -93,7 +93,8 @@ struct lambdakzeroBuilder { Produces v0indices; Produces v0cores; Produces v0trackXs; - Produces v0covs; // covariances + Produces v0covs; // covariances + Produces v0dauPositions; // auxiliary debug information Produces v0fcindices; Produces v0fccores; @@ -104,6 +105,7 @@ struct lambdakzeroBuilder { // Configurables related to table creation Configurable createV0CovMats{"createV0CovMats", -1, {"Produces V0 cov matrices. -1: auto, 0: don't, 1: yes. Default: auto (-1)"}}; + Configurable createV0PosAtDCAs{"createV0PosAtDCAs", 0, {"Produces V0 track positions at minima. 0: don't, 1: yes. Default: no (0)"}}; Configurable storePhotonCandidates{"storePhotonCandidates", false, "store photon candidates (yes/no)"}; @@ -125,6 +127,7 @@ struct lambdakzeroBuilder { // select momentum slice if desired Configurable minimumPt{"minimumPt", 0.0f, "Minimum pT to store candidate"}; Configurable maximumPt{"maximumPt", 1000.0f, "Maximum pT to store candidate"}; + Configurable maxDaughterEta{"maxDaughterEta", 5.0, "Maximum daughter eta"}; // Operation and minimisation criteria Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; @@ -180,6 +183,24 @@ struct lambdakzeroBuilder { ConfigurableAxis axisDCACHI2{"axisDCACHI2", {500, 0, 50}, "#chi^{2}"}; ConfigurableAxis axisPositionGuess{"axisPositionGuess", {240, 0, 120}, "(cm)"}; + // default parameters from central Pb-Pb (worst case scenario), PbPb 2023 pass1 + // fuctional form: [0]+[1]*x+[2]*TMath::Exp(-x/[3]) + + static constexpr float defaultK0MassWindowParameters[1][4] = {{2.81882e-03, 1.14057e-03, 1.72138e-03, 5.00262e-01}}; + static constexpr float defaultLambdaWindowParameters[1][4] = {{1.17518e-03, 1.24099e-04, 5.47937e-03, 3.08009e-01}}; + Configurable> massCutK0{"massCutK0", {defaultK0MassWindowParameters[0], 4, {"constant", "linear", "expoConstant", "expoRelax"}}, "mass parameters for K0"}; + Configurable> massCutLambda{"massCutLambda", {defaultLambdaWindowParameters[0], 4, {"constant", "linear", "expoConstant", "expoRelax"}}, "mass parameters for Lambda"}; + Configurable massWindownumberOfSigmas{"massWindownumberOfSigmas", 5e+6, "number of sigmas around mass peaks to keep"}; + Configurable massWindowWithTPCPID{"massWindowWithTPCPID", true, "when checking mass windows, correlate with TPC dE/dx"}; + Configurable massWindowSafetyMargin{"massWindowSafetyMargin", 0.001, "Extra mass window safety margin"}; + + // apply lifetime cuts to K0Short and Lambda candidates + // unit of measurement: centimeters + // lifetime of Lambda ~7.9cm but keep in mind feeddown from cascades + // lifetime of K0Short ~2.5cm, no feeddown and plenty to cut + static constexpr float defaultLifetimeCuts[1][2] = {{1e+6, 1e+6}}; + Configurable> lifetimecut{"lifetimecut", {defaultLifetimeCuts[0], 2, {"lifetimecutLambda", "lifetimecutK0S"}}, "lifetimecut"}; + int mRunNumber; float d_bz; float maxSnp; // max sine phi for propagation @@ -190,6 +211,20 @@ struct lambdakzeroBuilder { // Define o2 fitter, 2-prong, active memory (no need to redefine per event) o2::vertexing::DCAFitterN<2> fitter; + // provision to repeat mass selections while doing AND with PID selections + // fixme : this could be done more uniformly svertexer with reconstruction + // but that requires decoupling the mass window selections in O2 + // - to be done at a later stage + + float getMassSigmaK0Short(float pt) + { + return massCutK0->get("constant") + pt * massCutK0->get("linear") + massCutK0->get("expoConstant") * TMath::Exp(-pt / massCutK0->get("expoRelax")); + } + float getMassSigmaLambda(float pt) + { + return massCutLambda->get("constant") + pt * massCutLambda->get("linear") + massCutLambda->get("expoConstant") * TMath::Exp(-pt / massCutLambda->get("expoRelax")); + } + Filter taggedFilter = aod::v0tag::isInteresting == true; // For manual sliceBy @@ -213,14 +248,17 @@ struct lambdakzeroBuilder { std::array pos; std::array posP; std::array negP; + std::array posPosition; + std::array negPosition; float dcaV0dau; float posDCAxy; float negDCAxy; float cosPA; float dcav0topv; float V0radius; + float k0ShortMass; float lambdaMass; - float antilambdaMass; + float antiLambdaMass; } v0candidate; // Helper struct to do bookkeeping of building parameters @@ -410,12 +448,17 @@ struct lambdakzeroBuilder { for (DeviceSpec const& device : workflows.devices) { // Step 1: check if this device subscribed to the V0data table for (auto const& input : device.inputs) { - if (device.name.compare("lambdakzero-initializer") == 0) - continue; // don't listen to the initializer, it's just to extend stuff - const std::string v0DataName = "V0Datas"; - const std::string v0DataExtName = "V0DatasExtension"; - if ((input.matcher.binding == v0DataName || input.matcher.binding == v0DataExtName) && device.name.compare("multistrange-builder") != 0) { - LOGF(info, "Device named %s has subscribed to V0datas table! Will now scan for desired settings...", device.name); + if (device.name.compare("lambdakzero-initializer") == 0 || device.name.compare("cascade-initializer") == 0) + continue; // don't listen to the initializers, it's just to extend stuff + const std::string v0CoresName = "V0Cores"; + const std::string v0fCCoressName = "V0fCCores"; + const std::string CascCoresName = "StoredCascCores"; + const std::string KFCascCoresName = "StoredKFCascCores"; + const std::string TraCascCoresName = "StoredTraCascCores"; + // Logic: device is subscribed to a V0 table (excluding the cascade builder) or it's subscribed a Casc table + if (((input.matcher.binding == v0CoresName || input.matcher.binding == v0fCCoressName) && device.name.compare("cascade-builder") != 0) || + input.matcher.binding == CascCoresName || input.matcher.binding == KFCascCoresName || input.matcher.binding == TraCascCoresName) { + LOGF(info, "Device named %s has subscribed to a V0/Casc Cores table! Will now scan for desired settings...", device.name); for (auto const& option : device.options) { // 5 V0 topological selections if (option.name.compare("v0setting_cospa") == 0) { @@ -634,6 +677,8 @@ struct lambdakzeroBuilder { lNegativeTrack = fitter.getTrack(1); lPositiveTrack.getPxPyPzGlo(v0candidate.posP); lNegativeTrack.getPxPyPzGlo(v0candidate.negP); + lPositiveTrack.getXYZGlo(v0candidate.posPosition); + lNegativeTrack.getXYZGlo(v0candidate.negPosition); // get decay vertex coordinates const auto& vtx = fitter.getPCACandidate(); @@ -679,14 +724,73 @@ struct lambdakzeroBuilder { auto py = v0candidate.posP[1] + v0candidate.negP[1]; auto pz = v0candidate.posP[2] + v0candidate.negP[2]; auto lPt = RecoDecay::sqrtSumOfSquares(v0candidate.posP[0] + v0candidate.negP[0], v0candidate.posP[1] + v0candidate.negP[1]); + auto lPtotal = RecoDecay::sqrtSumOfSquares(lPt, v0candidate.posP[2] + v0candidate.negP[2]); + auto lLengthTraveled = RecoDecay::sqrtSumOfSquares(v0candidate.pos[0] - primaryVertex.getX(), v0candidate.pos[1] - primaryVertex.getY(), v0candidate.pos[2] - primaryVertex.getZ()); + // Momentum range check if (lPt < minimumPt || lPt > maximumPt) { return false; // reject if not within desired window } + // Daughter eta check + if (TMath::Abs(RecoDecay::eta(std::array{v0candidate.posP[0], v0candidate.posP[1], v0candidate.posP[2]})) > maxDaughterEta || + TMath::Abs(RecoDecay::eta(std::array{v0candidate.negP[0], v0candidate.negP[1], v0candidate.negP[2]})) > maxDaughterEta) { + return false; // reject - daughters have too large eta to be reliable for MC corrections + } + + // calculate proper lifetime + // m*L/p for each hypothesis + float lML2P_K0Short = o2::constants::physics::MassKaonNeutral * lLengthTraveled / lPtotal; + float lML2P_Lambda = o2::constants::physics::MassLambda * lLengthTraveled / lPtotal; + // Passes momentum window check statisticsRegistry.v0stats[kWithinMomentumRange]++; + // Calculate masses + auto lGammaMass = RecoDecay::m(array{array{v0candidate.posP[0], v0candidate.posP[1], v0candidate.posP[2]}, array{v0candidate.negP[0], v0candidate.negP[1], v0candidate.negP[2]}}, array{o2::constants::physics::MassElectron, o2::constants::physics::MassElectron}); + v0candidate.k0ShortMass = RecoDecay::m(array{array{v0candidate.posP[0], v0candidate.posP[1], v0candidate.posP[2]}, array{v0candidate.negP[0], v0candidate.negP[1], v0candidate.negP[2]}}, array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); + v0candidate.lambdaMass = RecoDecay::m(array{array{v0candidate.posP[0], v0candidate.posP[1], v0candidate.posP[2]}, array{v0candidate.negP[0], v0candidate.negP[1], v0candidate.negP[2]}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); + v0candidate.antiLambdaMass = RecoDecay::m(array{array{v0candidate.posP[0], v0candidate.posP[1], v0candidate.posP[2]}, array{v0candidate.negP[0], v0candidate.negP[1], v0candidate.negP[2]}}, array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); + auto lHypertritonMass = RecoDecay::m(array{array{2.0f * v0candidate.posP[0], 2.0f * v0candidate.posP[1], 2.0f * v0candidate.posP[2]}, array{v0candidate.negP[0], v0candidate.negP[1], v0candidate.negP[2]}}, array{o2::constants::physics::MassHelium3, o2::constants::physics::MassPionCharged}); + auto lAntiHypertritonMass = RecoDecay::m(array{array{v0candidate.posP[0], v0candidate.posP[1], v0candidate.posP[2]}, array{2.0f * v0candidate.negP[0], 2.0f * v0candidate.negP[1], 2.0f * v0candidate.negP[2]}}, array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassHelium3}); + + // mass window check + bool keepCandidate = false; + + bool desiredMassK0Short = false; + bool desiredMassLambda = false; + bool desiredMassAntiLambda = false; + + if (massWindownumberOfSigmas > 1e+3) { + desiredMassK0Short = true; // safety fallback + desiredMassLambda = true; // safety fallback + desiredMassAntiLambda = true; // safety fallback + } else { + desiredMassK0Short = TMath::Abs(v0candidate.k0ShortMass - o2::constants::physics::MassKaonNeutral) < massWindownumberOfSigmas * getMassSigmaK0Short(lPt) + massWindowSafetyMargin; + desiredMassLambda = TMath::Abs(v0candidate.lambdaMass - o2::constants::physics::MassLambda) < massWindownumberOfSigmas * getMassSigmaLambda(lPt) + massWindowSafetyMargin; + desiredMassAntiLambda = TMath::Abs(v0candidate.antiLambdaMass - o2::constants::physics::MassLambda) < massWindownumberOfSigmas * getMassSigmaLambda(lPt) + massWindowSafetyMargin; + } + + // check if user requested to correlate mass requirement with TPC PID + // (useful for data volume reduction) + bool dEdxK0Short = V0.isdEdxK0Short() || !massWindowWithTPCPID; + bool dEdxLambda = V0.isdEdxLambda() || !massWindowWithTPCPID; + bool dEdxAntiLambda = V0.isdEdxAntiLambda() || !massWindowWithTPCPID; + + // check proper lifetime if asked for + bool passML2P_K0Short = lML2P_K0Short < lifetimecut->get("lifetimecutK0S") || lifetimecut->get("lifetimecutK0S") > 1000; + bool passML2P_Lambda = lML2P_Lambda < lifetimecut->get("lifetimecutLambda") || lifetimecut->get("lifetimecutLambda") > 1000; + + if (passML2P_K0Short && dEdxK0Short && desiredMassK0Short) + keepCandidate = true; + if (passML2P_Lambda && dEdxLambda && desiredMassLambda) + keepCandidate = true; + if (passML2P_Lambda && dEdxAntiLambda && desiredMassAntiLambda) + keepCandidate = true; + + if (!keepCandidate) + return false; + if (d_doTrackQA) { if (posTrack.itsNCls() < 10) statisticsRegistry.posITSclu[posTrack.itsNCls()]++; @@ -698,14 +802,6 @@ struct lambdakzeroBuilder { bool mcUnchecked = !d_QA_checkMC; bool dEdxUnchecked = !d_QA_checkdEdx; - // Calculate masses - auto lGammaMass = RecoDecay::m(array{array{v0candidate.posP[0], v0candidate.posP[1], v0candidate.posP[2]}, array{v0candidate.negP[0], v0candidate.negP[1], v0candidate.negP[2]}}, array{o2::constants::physics::MassElectron, o2::constants::physics::MassElectron}); - auto lK0ShortMass = RecoDecay::m(array{array{v0candidate.posP[0], v0candidate.posP[1], v0candidate.posP[2]}, array{v0candidate.negP[0], v0candidate.negP[1], v0candidate.negP[2]}}, array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassPionCharged}); - auto lLambdaMass = RecoDecay::m(array{array{v0candidate.posP[0], v0candidate.posP[1], v0candidate.posP[2]}, array{v0candidate.negP[0], v0candidate.negP[1], v0candidate.negP[2]}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged}); - auto lAntiLambdaMass = RecoDecay::m(array{array{v0candidate.posP[0], v0candidate.posP[1], v0candidate.posP[2]}, array{v0candidate.negP[0], v0candidate.negP[1], v0candidate.negP[2]}}, array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassProton}); - auto lHypertritonMass = RecoDecay::m(array{array{2.0f * v0candidate.posP[0], 2.0f * v0candidate.posP[1], 2.0f * v0candidate.posP[2]}, array{v0candidate.negP[0], v0candidate.negP[1], v0candidate.negP[2]}}, array{o2::constants::physics::MassHelium3, o2::constants::physics::MassPionCharged}); - auto lAntiHypertritonMass = RecoDecay::m(array{array{v0candidate.posP[0], v0candidate.posP[1], v0candidate.posP[2]}, array{2.0f * v0candidate.negP[0], 2.0f * v0candidate.negP[1], 2.0f * v0candidate.negP[2]}}, array{o2::constants::physics::MassPionCharged, o2::constants::physics::MassHelium3}); - auto lPtHy = RecoDecay::sqrtSumOfSquares(2.0f * v0candidate.posP[0] + v0candidate.negP[0], 2.0f * v0candidate.posP[1] + v0candidate.negP[1]); auto lPtAnHy = RecoDecay::sqrtSumOfSquares(v0candidate.posP[0] + 2.0f * v0candidate.negP[0], v0candidate.posP[1] + 2.0f * v0candidate.negP[1]); @@ -714,11 +810,11 @@ struct lambdakzeroBuilder { if ((V0.isdEdxGamma() || dEdxUnchecked) && (V0.isTrueGamma() || mcUnchecked)) registry.fill(HIST("h2dGammaMass"), lPt, lGammaMass); if ((V0.isdEdxK0Short() || dEdxUnchecked) && (V0.isTrueK0Short() || mcUnchecked)) - registry.fill(HIST("h2dK0ShortMass"), lPt, lK0ShortMass); + registry.fill(HIST("h2dK0ShortMass"), lPt, v0candidate.k0ShortMass); if ((V0.isdEdxLambda() || dEdxUnchecked) && (V0.isTrueLambda() || mcUnchecked)) - registry.fill(HIST("h2dLambdaMass"), lPt, lLambdaMass); + registry.fill(HIST("h2dLambdaMass"), lPt, v0candidate.lambdaMass); if ((V0.isdEdxAntiLambda() || dEdxUnchecked) && (V0.isTrueAntiLambda() || mcUnchecked)) - registry.fill(HIST("h2dAntiLambdaMass"), lPt, lAntiLambdaMass); + registry.fill(HIST("h2dAntiLambdaMass"), lPt, v0candidate.antiLambdaMass); if ((V0.isdEdxHypertriton() || dEdxUnchecked) && (V0.isTrueHypertriton() || mcUnchecked)) registry.fill(HIST("h2dHypertritonMass"), lPtHy, lHypertritonMass); if ((V0.isdEdxAntiHypertriton() || dEdxUnchecked) && (V0.isTrueAntiHypertriton() || mcUnchecked)) @@ -730,15 +826,15 @@ struct lambdakzeroBuilder { registry.fill(HIST("h2dITSCluMap_Gamma"), static_cast(posTrack.itsClusterMap()), static_cast(negTrack.itsClusterMap()), v0candidate.V0radius); registry.fill(HIST("h2dXIU_Gamma"), static_cast(posTrack.x()), static_cast(negTrack.x()), v0candidate.V0radius); } - if (TMath::Abs(lK0ShortMass - 0.497) < dQAK0ShortMassWindow && ((V0.isdEdxK0Short() || dEdxUnchecked) && (V0.isTrueK0Short() || mcUnchecked))) { + if (TMath::Abs(v0candidate.k0ShortMass - 0.497) < dQAK0ShortMassWindow && ((V0.isdEdxK0Short() || dEdxUnchecked) && (V0.isTrueK0Short() || mcUnchecked))) { registry.fill(HIST("h2dITSCluMap_K0Short"), static_cast(posTrack.itsClusterMap()), static_cast(negTrack.itsClusterMap()), v0candidate.V0radius); registry.fill(HIST("h2dXIU_K0Short"), static_cast(posTrack.x()), static_cast(negTrack.x()), v0candidate.V0radius); } - if (TMath::Abs(lLambdaMass - 1.116) < dQALambdaMassWindow && ((V0.isdEdxLambda() || dEdxUnchecked) && (V0.isTrueLambda() || mcUnchecked))) { + if (TMath::Abs(v0candidate.lambdaMass - 1.116) < dQALambdaMassWindow && ((V0.isdEdxLambda() || dEdxUnchecked) && (V0.isTrueLambda() || mcUnchecked))) { registry.fill(HIST("h2dITSCluMap_Lambda"), static_cast(posTrack.itsClusterMap()), static_cast(negTrack.itsClusterMap()), v0candidate.V0radius); registry.fill(HIST("h2dXIU_Lambda"), static_cast(posTrack.x()), static_cast(negTrack.x()), v0candidate.V0radius); } - if (TMath::Abs(lAntiLambdaMass - 1.116) < dQALambdaMassWindow && ((V0.isdEdxAntiLambda() || dEdxUnchecked) && (V0.isTrueAntiLambda() || mcUnchecked))) { + if (TMath::Abs(v0candidate.antiLambdaMass - 1.116) < dQALambdaMassWindow && ((V0.isdEdxAntiLambda() || dEdxUnchecked) && (V0.isTrueAntiLambda() || mcUnchecked))) { registry.fill(HIST("h2dITSCluMap_AntiLambda"), static_cast(posTrack.itsClusterMap()), static_cast(negTrack.itsClusterMap()), v0candidate.V0radius); registry.fill(HIST("h2dXIU_AntiLambda"), static_cast(posTrack.x()), static_cast(negTrack.x()), v0candidate.V0radius); } @@ -841,6 +937,9 @@ struct lambdakzeroBuilder { v0candidate.cosPA, v0candidate.dcav0topv, V0.v0Type()); + if (createV0PosAtDCAs) + v0dauPositions(v0candidate.posPosition[0], v0candidate.posPosition[1], v0candidate.posPosition[2], + v0candidate.negPosition[0], v0candidate.negPosition[1], v0candidate.negPosition[2]); } else { // place V0s built exclusively for the sake of cascades // in a fully independent table (though identical) to make @@ -955,7 +1054,11 @@ struct lambdakzeroPreselector { Configurable dTPCNCrossedRows{"dTPCNCrossedRows", 50, "Minimum TPC crossed rows"}; // context-aware selections - Configurable dPreselectOnlyBaryons{"dPreselectOnlyBaryons", false, "apply TPC dE/dx and quality only to baryon daughters"}; + Configurable dPreselectOnlyBaryons{"dPreselectOnlyBaryons", false, "apply TPC dE/dx only to baryon daughters"}; + + // for debugging and further tests + Configurable forceITSOnlyMesons{"forceITSOnlyMesons", false, "force meson-like daughters to be ITS-only to pass Lambda/AntiLambda selections (yes/no)"}; + Configurable minITSCluITSOnly{"minITSCluITSOnly", 0, "minimum number of ITS clusters to ask for if daughter track does not have TPC"}; // for bit-packed maps std::vector selectionMask; @@ -995,17 +1098,39 @@ struct lambdakzeroPreselector { auto lNegTrack = lV0Candidate.template negTrack_as(); auto lPosTrack = lV0Candidate.template posTrack_as(); + // crossed rows conditionals + bool posRowsOK = lPosTrack.tpcNClsCrossedRows() >= dTPCNCrossedRows; + bool negRowsOK = lNegTrack.tpcNClsCrossedRows() >= dTPCNCrossedRows; + + // check track explicitly for absence of TPC + bool posITSonly = !lPosTrack.hasTPC(); + bool negITSonly = !lNegTrack.hasTPC(); + bool longPosITSonly = posITSonly && lPosTrack.itsNCls() >= minITSCluITSOnly; + bool longNegITSonly = negITSonly && lNegTrack.itsNCls() >= minITSCluITSOnly; + // No baryons in decay - if (((bitcheck(maskElement, bitdEdxGamma) || bitcheck(maskElement, bitdEdxK0Short)) || passdEdx) && (lPosTrack.tpcNClsCrossedRows() >= dTPCNCrossedRows && lNegTrack.tpcNClsCrossedRows() >= dTPCNCrossedRows)) + if (((bitcheck(maskElement, bitdEdxGamma) || bitcheck(maskElement, bitdEdxK0Short)) || passdEdx) && (posRowsOK && negRowsOK) && (!forceITSOnlyMesons || (posITSonly && negITSonly))) bitset(maskElement, bitTrackQuality); // With baryons in decay - if ((bitcheck(maskElement, bitdEdxLambda) || passdEdx) && (lPosTrack.tpcNClsCrossedRows() >= dTPCNCrossedRows && (lNegTrack.tpcNClsCrossedRows() >= dTPCNCrossedRows || dPreselectOnlyBaryons))) + if ((bitcheck(maskElement, bitdEdxLambda) || passdEdx) && // logical AND with dEdx + (posRowsOK && (negRowsOK || dPreselectOnlyBaryons)) && // rows requirement + ((posRowsOK || longPosITSonly) && (negRowsOK || longNegITSonly)) && // if ITS-only, check for min length + (!forceITSOnlyMesons || negITSonly)) bitset(maskElement, bitTrackQuality); - if ((bitcheck(maskElement, bitdEdxAntiLambda) || passdEdx) && (lNegTrack.tpcNClsCrossedRows() >= dTPCNCrossedRows && (lPosTrack.tpcNClsCrossedRows() >= dTPCNCrossedRows || dPreselectOnlyBaryons))) + if ((bitcheck(maskElement, bitdEdxAntiLambda) || passdEdx) && // logical AND with dEdx + (negRowsOK && (posRowsOK || dPreselectOnlyBaryons)) && // rows requirement + ((posRowsOK || longPosITSonly) && (negRowsOK || longNegITSonly)) && // if ITS-only, check for min length + (!forceITSOnlyMesons || posITSonly)) bitset(maskElement, bitTrackQuality); - if ((bitcheck(maskElement, bitdEdxHypertriton) || passdEdx) && (lPosTrack.tpcNClsCrossedRows() >= dTPCNCrossedRows && (lNegTrack.tpcNClsCrossedRows() >= dTPCNCrossedRows || dPreselectOnlyBaryons))) + if ((bitcheck(maskElement, bitdEdxHypertriton) || passdEdx) && // logical AND with dEdx + (posRowsOK && (negRowsOK || dPreselectOnlyBaryons)) && // rows requirement + ((posRowsOK || longPosITSonly) && (negRowsOK || longNegITSonly)) && // if ITS-only, check for min length + (!forceITSOnlyMesons || negITSonly)) bitset(maskElement, bitTrackQuality); - if ((bitcheck(maskElement, bitdEdxAntiHypertriton) || passdEdx) && (lNegTrack.tpcNClsCrossedRows() >= dTPCNCrossedRows && (lPosTrack.tpcNClsCrossedRows() >= dTPCNCrossedRows || dPreselectOnlyBaryons))) + if ((bitcheck(maskElement, bitdEdxAntiHypertriton) || passdEdx) && // logical AND with dEdx + (negRowsOK && (posRowsOK || dPreselectOnlyBaryons)) && // rows requirement + ((posRowsOK || longPosITSonly) && (negRowsOK || longNegITSonly)) && // if ITS-only, check for min length + (!forceITSOnlyMesons || posITSonly)) bitset(maskElement, bitTrackQuality); } //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* diff --git a/PWGLF/TableProducer/lambdakzerospawner.cxx b/PWGLF/TableProducer/lambdakzerospawner.cxx new file mode 100644 index 00000000000..7ec0b4cc010 --- /dev/null +++ b/PWGLF/TableProducer/lambdakzerospawner.cxx @@ -0,0 +1,46 @@ +// 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 spawner +// *+-+*+-+*+-+*+-+*+-+*+-+* +// +// Creates V0 extension tables for derived data. +// A minimal task that saves a lot of disk space. + +#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 "PWGLF/DataModel/LFStrangenessTables.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +// Extends the v0data table with expression columns +struct lambdakzerospawner { + Spawns v0cores; + void init(InitContext const&) {} +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/TableProducer/nucleiSpectra.cxx b/PWGLF/TableProducer/nucleiSpectra.cxx index 99c8fc11a4d..ec107bed073 100644 --- a/PWGLF/TableProducer/nucleiSpectra.cxx +++ b/PWGLF/TableProducer/nucleiSpectra.cxx @@ -17,6 +17,7 @@ // Data (run3): // o2-analysis-lf-nuclei-spectra, o2-analysis-timestamp // o2-analysis-pid-tof-base, o2-analysis-multiplicity-table, o2-analysis-event-selection +// (to add flow: o2-analysis-qvector-table, o2-analysis-centrality-table) #include @@ -32,6 +33,8 @@ #include "Common/DataModel/TrackSelectionTables.h" #include "Common/Core/PID/PIDTOF.h" #include "Common/TableProducer/PID/pidTOFBase.h" +#include "Common/Core/EventPlaneHelper.h" +#include "Common/DataModel/Qvectors.h" #include "DataFormatsParameters/GRPMagField.h" #include "DataFormatsParameters/GRPObject.h" @@ -72,6 +75,8 @@ struct NucleusCandidate { uint8_t TPCcrossedRows; uint8_t ITSclsMap; uint8_t TPCnCls; + uint32_t clusterSizesITS; + int selCollIndex; }; namespace nuclei @@ -141,6 +146,15 @@ std::shared_ptr hDeltaP[2][5]; o2::base::MatLayerCylSet* lut = nullptr; std::vector candidates; + +enum centDetectors { + kFV0A = 0, + kFT0M = 1, + kFT0A = 2, + kFT0C = 3 +}; + +static const std::vector centDetectorNames{"FV0A", "FT0M", "FT0A", "FT0C"}; } // namespace nuclei struct nucleiSpectra { @@ -161,9 +175,10 @@ struct nucleiSpectra { Produces nucleiTable; Produces nucleiTableMC; + Produces nucleiFlowTable; Service ccdb; - Configurable cfgCentralityEstimator{"cfgCentralityEstimator", "V0A", "Centrality estimator name"}; + Configurable cfgCentralityEstimator{"cfgCentralityEstimator", 0, "Centrality estimator (FV0A: 0, FT0M: 1, FT0A: 2, FT0C: 3)"}; Configurable cfgCMrapidity{"cfgCMrapidity", 0.f, "Rapidity of the center of mass (only for p-Pb)"}; Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; @@ -197,6 +212,7 @@ struct nucleiSpectra { ConfigurableAxis cfgNsigmaTPCbins{"cfgNsigmaTPCbins", {100, -5., 5.}, "nsigma_TPC binning"}; ConfigurableAxis cfgNsigmaTOFbins{"cfgNsigmaTOFbins", {100, -5., 5.}, "nsigma_TOF binning"}; ConfigurableAxis cfgTOFmassBins{"cfgTOFmassBins", {200, -5., 5.}, "TOF mass binning"}; + ConfigurableAxis cfgSpBins{"cfgSpBins", {100, -1.f, 1.f}, "Binning for scalar product"}; // CCDB options Configurable cfgBz{"cfgBz", -999, "bz field, -999 is automatic"}; @@ -214,6 +230,12 @@ struct nucleiSpectra { using TrackCandidates = soa::Filtered>; + // Collisions with chentrality + using CollWithCent = soa::Filtered>::iterator; + + // Flow analysis + using CollWithQvec = soa::Filtered>::iterator; + HistogramRegistry spectra{"spectra", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; o2::pid::tof::Beta responseBeta; @@ -250,7 +272,7 @@ struct nucleiSpectra { ccdb->setLocalObjectValidityChecking(); ccdb->setFatalWhenNull(false); - const AxisSpec centAxis{cfgCentralityBins, fmt::format("{} percentile", (std::string)cfgCentralityEstimator)}; + const AxisSpec centAxis{cfgCentralityBins, fmt::format("{} percentile", (std::string)nuclei::centDetectorNames[cfgCentralityEstimator])}; const AxisSpec nSigmaAxes[2]{{cfgNsigmaTPCbins, "n#sigma_{TPC}"}, {cfgNsigmaTOFbins, "n#sigma_{TOF}"}}; const AxisSpec tofMassAxis{cfgTOFmassBins, "TOF mass - PDG mass"}; const AxisSpec ptResAxis{cfgMomResBins, "#Delta#it{p}_{T}/#it{p}_{T}"}; @@ -275,6 +297,10 @@ struct nucleiSpectra { {cfgDCAxyBinsAlpha, "DCA_{z} (cm)"}}; const AxisSpec etaAxis{40, -1., 1., "#eta"}; + const AxisSpec ft0Aft0CspAxis{cfgSpBins, "#vec{Q}_{2}^{FT0A} #upoint #vec{Q}_{2}^{FT0C}"}; + const AxisSpec fv0Aft0CspAxis{cfgSpBins, "#vec{Q}_{2}^{FV0A} #upoint #vec{Q}_{2}^{FT0C}"}; + const AxisSpec fv0Aft0AspAxis{cfgSpBins, "#vec{Q}_{2}^{FV0A} #upoint #vec{Q}_{2}^{FT0A}"}; + spectra.add("hRecVtxZData", "collision z position", HistType::kTH1F, {{200, -20., +20., "z position (cm)"}}); spectra.add("hTpcSignalData", "Specific energy loss", HistType::kTH2F, {{600, -6., 6., "#it{p} (GeV/#it{c})"}, {1400, 0, 1400, "d#it{E} / d#it{X} (a. u.)"}}); spectra.add("hTpcSignalDataSelected", "Specific energy loss for selected particles", HistType::kTH2F, {{600, -6., 6., "#it{p} (GeV/#it{c})"}, {1400, 0, 1400, "d#it{E} / d#it{X} (a. u.)"}}); @@ -294,7 +320,12 @@ struct nucleiSpectra { nuclei::hTOFmassEta[iS][iC] = spectra.add(fmt::format("h{}TOFmassEta{}", nuclei::matter[iC], nuclei::names[iS]).data(), fmt::format("TOF mass - {} PDG mass", nuclei::names[iS]).data(), HistType::kTH3D, {etaAxis, ptAxes[iS], tofMassAxis}); nuclei::hMomRes[iS][iC] = spectra.add(fmt::format("h{}MomRes{}", nuclei::matter[iC], nuclei::names[iS]).data(), fmt::format("Momentum resolution {}", nuclei::names[iS]).data(), HistType::kTH3D, {centAxis, ptAxes[iS], ptResAxis}); nuclei::hGenNuclei[iS][iC] = spectra.add(fmt::format("h{}Gen{}", nuclei::matter[iC], nuclei::names[iS]).data(), fmt::format("Generated {}", nuclei::names[iS]).data(), HistType::kTH2D, {centAxis, ptAxes[iS]}); - nuclei::hDeltaP[iC][iS] = spectra.add(fmt::format("hDeltaP{}_{}", nuclei::matter[iC], nuclei::names[iS]).data(), fmt::format("#Delta#it{{p}}/#it{{p}} {} {}", nuclei::matter[iC], nuclei::names[iS]).data(), HistType::kTH2D, {{232, 0.2, 6., "#it{{p}} (GeV/#it{{c}})"}, {200, -1.0, 1.0, "(#it{{p}}_{{IU}} - #it{{p}}_{{TPC}}) / #it{{p}}"}}); + nuclei::hDeltaP[iC][iS] = spectra.add(fmt::format("hDeltaP{}_{}", nuclei::matter[iC], nuclei::names[iS]).data(), fmt::format("#Delta#it{{p}}/#it{{p}} {} {}", nuclei::matter[iC], nuclei::names[iS]).data(), HistType::kTH2D, {{232, 0.2, 6., "#it{{p}} (GeV/#it{{c}})"}, {200, -1.0, 1.0, "(#it{p}_{IU} - #it{p}_{TPC}) / #it{p}"}}); + } + if (doprocessDataFlow) { + spectra.add("hScalarProductFT0AvsFT0C", "", HistType::kTH2F, {ft0Aft0CspAxis, centAxis}); + spectra.add("hScalarProductFV0AvsFT0C", "", HistType::kTH2F, {fv0Aft0CspAxis, centAxis}); + spectra.add("hScalarProductFV0AvsFT0A", "", HistType::kTH2F, {fv0Aft0AspAxis, centAxis}); } } @@ -308,10 +339,30 @@ struct nucleiSpectra { o2::base::Propagator::Instance(true)->setMatLUT(nuclei::lut); } - template - void fillDataInfo(soa::Filtered>::iterator const& collision, TC const& tracks) + template + float getCentrality(Tcoll const& collision) + { + float centrality = 1.; + if constexpr (std::is_same::value || std::is_same::value) { + if (cfgCentralityEstimator == nuclei::centDetectors::kFV0A) { + centrality = collision.centFV0A(); + } else if (cfgCentralityEstimator == nuclei::centDetectors::kFT0M) { + centrality = collision.centFT0M(); + } else if (cfgCentralityEstimator == nuclei::centDetectors::kFT0A) { + centrality = collision.centFT0A(); + } else if (cfgCentralityEstimator == nuclei::centDetectors::kFT0C) { + centrality = collision.centFT0C(); + } else { + LOG(warning) << "Centrality estimator not valid. Possible values: (FV0A: 0, FT0M: 1, FT0A: 2, FT0C: 3). Centrality set to 1."; + } + } + return centrality; + } + + template + void fillDataInfo(Tcoll const& collision, Ttrks const& tracks) { - auto bc = collision.bc_as(); + auto bc = collision.template bc_as(); initCCDB(bc); // collision process loop @@ -322,6 +373,16 @@ struct nucleiSpectra { const o2::math_utils::Point3D collVtx{collision.posX(), collision.posY(), collision.posZ()}; + float centrality = getCentrality(collision); + + if constexpr (std::is_same::value) { + if (doprocessDataFlow) { + spectra.fill(HIST("hScalarProductFT0AvsFT0C"), collision.qvecFT0ARe() * collision.qvecFT0CRe() + collision.qvecFT0AIm() * collision.qvecFT0CIm(), centrality); + spectra.fill(HIST("hScalarProductFV0AvsFT0C"), collision.qvecFV0ARe() * collision.qvecFT0CRe() + collision.qvecFV0AIm() * collision.qvecFT0CIm(), centrality); + spectra.fill(HIST("hScalarProductFV0AvsFT0C"), collision.qvecFT0ARe() * collision.qvecFV0ARe() + collision.qvecFT0AIm() * collision.qvecFV0AIm(), centrality); + } + } + const double bgScalings[5][2]{ {nuclei::charges[0] * cfgMomentumScalingBetheBloch->get(0u, 0u) / nuclei::masses[0], nuclei::charges[0] * cfgMomentumScalingBetheBloch->get(0u, 1u) / nuclei::masses[0]}, {nuclei::charges[1] * cfgMomentumScalingBetheBloch->get(1u, 0u) / nuclei::masses[1], nuclei::charges[1] * cfgMomentumScalingBetheBloch->get(1u, 1u) / nuclei::masses[1]}, @@ -397,16 +458,16 @@ struct nucleiSpectra { selectedTOF = true; } if (!cfgCutOnReconstructedRapidity || (y > cfgCutRapidityMin && y < cfgCutRapidityMax)) { - nuclei::hDCAxy[iPID][iS][iC]->Fill(1., fvector.pt(), dcaInfo[0]); - nuclei::hDCAz[iPID][iS][iC]->Fill(1., fvector.pt(), dcaInfo[1]); + nuclei::hDCAxy[iPID][iS][iC]->Fill(centrality, fvector.pt(), dcaInfo[0]); + nuclei::hDCAz[iPID][iS][iC]->Fill(centrality, fvector.pt(), dcaInfo[1]); if (std::abs(dcaInfo[0]) < cfgDCAcut->get(iS, 0u)) { if (!iPID) { /// temporary exclusion of the TOF nsigma PID for the He3 and Alpha - nuclei::hNsigma[iPID][iS][iC]->Fill(1., fvector.pt(), nSigma[iPID][iS]); + nuclei::hNsigma[iPID][iS][iC]->Fill(centrality, fvector.pt(), nSigma[iPID][iS]); nuclei::hNsigmaEta[iPID][iS][iC]->Fill(fvector.eta(), fvector.pt(), nSigma[iPID][iS]); } if (iPID) { float mass{track.tpcInnerParam() * nuclei::charges[iS] * std::sqrt(1.f / (beta * beta) - 1.f) - nuclei::masses[iS]}; - nuclei::hTOFmass[iS][iC]->Fill(1., fvector.pt(), mass); + nuclei::hTOFmass[iS][iC]->Fill(centrality, fvector.pt(), mass); nuclei::hTOFmassEta[iS][iC]->Fill(fvector.eta(), fvector.pt(), mass); } } @@ -422,8 +483,34 @@ struct nucleiSpectra { } } if (flag & (kProton | kDeuteron | kTriton | kHe3 | kHe4)) { + if constexpr (std::is_same::value) { + if (nuclei::candidates.empty()) { + nucleiFlowTable(collision.centFV0A(), + collision.centFT0M(), + collision.centFT0A(), + collision.centFT0C(), + collision.qvecFV0ARe(), + collision.qvecFV0AIm(), + collision.sumAmplFV0A(), + collision.qvecFT0MRe(), + collision.qvecFT0MIm(), + collision.sumAmplFT0M(), + collision.qvecFT0ARe(), + collision.qvecFT0AIm(), + collision.sumAmplFT0A(), + collision.qvecFT0CRe(), + collision.qvecFT0CIm(), + collision.sumAmplFT0C(), + collision.qvecBPosRe(), + collision.qvecBPosIm(), + collision.nTrkBPos(), + collision.qvecBNegRe(), + collision.qvecBNegIm(), + collision.nTrkBNeg()); + } + } nuclei::candidates.emplace_back(NucleusCandidate{static_cast(track.globalIndex()), (1 - 2 * iC) * trackParCov.getPt(), trackParCov.getEta(), trackParCov.getPhi(), track.tpcInnerParam(), beta, collision.posZ(), dcaInfo[0], dcaInfo[1], track.tpcSignal(), track.itsChi2NCl(), - track.tpcChi2NCl(), flag, track.tpcNClsFindable(), static_cast(track.tpcNClsCrossedRows()), track.itsClusterMap(), static_cast(track.tpcNClsFound())}); + track.tpcChi2NCl(), flag, track.tpcNClsFindable(), static_cast(track.tpcNClsCrossedRows()), track.itsClusterMap(), static_cast(track.tpcNClsFound()), static_cast(track.itsClusterSizes()), static_cast(nucleiFlowTable.lastIndex())}); } } // end loop over tracks @@ -436,11 +523,21 @@ struct nucleiSpectra { nuclei::candidates.clear(); fillDataInfo(collision, tracks); for (auto& c : nuclei::candidates) { - nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls); + nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.clusterSizesITS, c.selCollIndex); } } PROCESS_SWITCH(nucleiSpectra, processData, "Data analysis", true); + void processDataFlow(CollWithQvec const& collision, TrackCandidates const& tracks, aod::BCsWithTimestamps const&) + { + nuclei::candidates.clear(); + fillDataInfo(collision, tracks); + for (auto& c : nuclei::candidates) { + nucleiTable(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.clusterSizesITS, c.selCollIndex); + } + } + PROCESS_SWITCH(nucleiSpectra, processDataFlow, "Data analysis with flow", false); + Preslice tracksPerCollisions = aod::track::collisionId; void processMC(soa::Filtered> const& collisions, TrackCandidates const& tracks, aod::McTrackLabels const& trackLabelsMC, aod::McParticles const& particlesMC, aod::BCsWithTimestamps const&) { @@ -465,7 +562,7 @@ struct nucleiSpectra { c.flags |= kIsSecondaryFromMaterial; } - nucleiTableMC(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, particle.pt(), particle.eta(), particle.phi(), particle.pdgCode()); + nucleiTableMC(c.pt, c.eta, c.phi, c.tpcInnerParam, c.beta, c.zVertex, c.DCAxy, c.DCAz, c.TPCsignal, c.ITSchi2, c.TPCchi2, c.flags, c.TPCfindableCls, c.TPCcrossedRows, c.ITSclsMap, c.TPCnCls, c.clusterSizesITS, particle.pt(), particle.eta(), particle.phi(), particle.pdgCode()); for (int iS{0}; iS < nuclei::species; ++iS) { if (std::abs(particle.pdgCode()) == nuclei::codes[iS]) { nuclei::hMomRes[iS][particle.pdgCode() < 0]->Fill(1., std::abs(c.pt * nuclei::charges[iS]), 1. - std::abs(c.pt * nuclei::charges[iS]) / particle.pt()); @@ -494,7 +591,7 @@ struct nucleiSpectra { } if (!isReconstructed[index] && (cfgTreeConfig->get(iS, 0u) || cfgTreeConfig->get(iS, 1u))) { - nucleiTableMC(999., 999., 999., 0., 0., 999., 999., 999., -1, -1, -1, flags, 0, 0, 0, 0, particle.pt(), particle.eta(), particle.phi(), particle.pdgCode()); + nucleiTableMC(999., 999., 999., 0., 0., 999., 999., 999., -1, -1, -1, flags, 0, 0, 0, 0, 0, particle.pt(), particle.eta(), particle.phi(), particle.pdgCode()); } break; } diff --git a/PWGLF/TableProducer/strangederivedbuilder.cxx b/PWGLF/TableProducer/strangederivedbuilder.cxx index 6c4a6c3b9df..5cad9c8fc0a 100644 --- a/PWGLF/TableProducer/strangederivedbuilder.cxx +++ b/PWGLF/TableProducer/strangederivedbuilder.cxx @@ -44,6 +44,7 @@ #include "CommonConstants/PhysicsConstants.h" #include "Common/TableProducer/PID/pidTOFBase.h" #include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/Qvectors.h" #include "Framework/StaticFor.h" using namespace o2; @@ -64,6 +65,7 @@ struct strangederivedbuilder { // fundamental building blocks of derived data Produces strangeColl; // characterises collisions Produces strangeCents; // characterises collisions / centrality + Produces strangeRawCents; // characterises collisions / centrality Produces strangeEvSels; // characterises collisions / sel8 selection Produces strangeStamps; // provides timestamps, run numbers Produces v0collref; // references collisions from V0s @@ -97,6 +99,13 @@ struct strangederivedbuilder { Produces v0tofs; // V0 part Produces casctofs; // cascade part + //__________________________________________________ + // Q-vectors + Produces StraFT0AQVs; // FT0A Q-vector + Produces StraFT0CQVs; // FT0C Q-vector + Produces StraFT0MQVs; // FT0M Q-vector + Produces StraFV0AQVs; // FV0A Q-vector + // histogram registry for bookkeeping HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -130,6 +139,11 @@ struct strangederivedbuilder { Configurable roundNSigmaVariables{"roundNSigmaVariables", false, "round NSigma variables"}; Configurable precisionNSigmas{"precisionNSigmas", 0.1f, "precision to keep NSigmas"}; + Configurable fillRawFT0A{"fillRawFT0A", false, "Fill raw FT0A information for debug"}; + Configurable fillRawFT0C{"fillRawFT0C", true, "Fill raw FT0C information for debug"}; + Configurable fillRawFV0A{"fillRawFV0A", false, "Fill raw FV0A information for debug"}; + Configurable fillRawNTracksEta1{"fillRawNTracksEta1", true, "Fill raw NTracks |eta|<1 information for debug"}; + // For manual sliceBy Preslice V0perCollision = o2::aod::v0data::collisionId; Preslice CascperCollision = o2::aod::cascdata::collisionId; @@ -168,7 +182,7 @@ struct strangederivedbuilder { histos.add("h2dNVerticesVsCentrality", "h2dNVerticesVsCentrality", kTH2D, {axisCentrality, axisNVertices}); } - void processCollisionsV0sOnly(soa::Join const& collisions, aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) + void processCollisionsV0sOnly(soa::Join const& collisions, aod::V0Datas const& V0s, aod::BCsWithTimestamps const&) { for (const auto& collision : collisions) { const uint64_t collIdx = collision.globalIndex(); @@ -182,13 +196,20 @@ struct strangederivedbuilder { strangeEvSels(collision.sel8()); auto bc = collision.bc_as(); strangeStamps(bc.runNumber(), bc.timestamp()); + + if (fillRawFT0C || fillRawFT0C || fillRawFV0A || fillRawNTracksEta1) { + strangeRawCents(collision.multFT0A() * static_cast(fillRawFT0A), + collision.multFT0C() * static_cast(fillRawFT0C), + collision.multFT0A() * static_cast(fillRawFV0A), + collision.multNTracksPVeta1() * static_cast(fillRawNTracksEta1)); + } } for (int i = 0; i < V0Table_thisColl.size(); i++) v0collref(strangeColl.lastIndex()); } } - void processCollisions(soa::Join const& collisions, aod::V0Datas const& V0s, aod::CascDatas const& Cascades, aod::KFCascDatas const& KFCascades, aod::TraCascDatas const& TraCascades, aod::BCsWithTimestamps const&) + void processCollisions(soa::Join const& collisions, aod::V0Datas const& V0s, aod::CascDatas const& Cascades, aod::KFCascDatas const& KFCascades, aod::TraCascDatas const& TraCascades, aod::BCsWithTimestamps const&) { for (const auto& collision : collisions) { const uint64_t collIdx = collision.globalIndex(); @@ -208,6 +229,13 @@ struct strangederivedbuilder { strangeEvSels(collision.sel8()); auto bc = collision.bc_as(); strangeStamps(bc.runNumber(), bc.timestamp()); + + if (fillRawFT0C || fillRawFT0C || fillRawFV0A || fillRawNTracksEta1) { + strangeRawCents(collision.multFT0A() * static_cast(fillRawFT0A), + collision.multFT0C() * static_cast(fillRawFT0C), + collision.multFT0A() * static_cast(fillRawFV0A), + collision.multNTracksPVeta1() * static_cast(fillRawNTracksEta1)); + } } for (int i = 0; i < V0Table_thisColl.size(); i++) v0collref(strangeColl.lastIndex()); @@ -475,7 +503,7 @@ struct strangederivedbuilder { histos.fill(HIST("h2dNVerticesVsCentrality"), bestCentrality, collisions.size()); for (auto& mcp : mcParticles) { - if (TMath::Abs(mcp.y()) < 0.5) { + if (TMath::Abs(mcp.y()) < 0.5 && mcp.isPhysicalPrimary()) { static_for<0, nSpecies - 1>([&](auto i) { constexpr int index = i.value; if (mcp.pdgCode() == particlePDGCodes[index] && bitcheck(enabledBits, index)) { @@ -508,6 +536,23 @@ struct strangederivedbuilder { } } + void processFT0AQVectors(soa::Join::iterator const& collision) + { + StraFT0AQVs(collision.qvecFT0ARe(), collision.qvecFT0AIm(), collision.sumAmplFT0A()); + } + void processFT0CQVectors(soa::Join::iterator const& collision) + { + StraFT0CQVs(collision.qvecFT0CRe(), collision.qvecFT0CIm(), collision.sumAmplFT0C()); + } + void processFT0MQVectors(soa::Join::iterator const& collision) + { + StraFT0MQVs(collision.qvecFT0MRe(), collision.qvecFT0MIm(), collision.sumAmplFT0M()); + } + void processFV0AQVectors(soa::Join::iterator const& collision) + { + StraFV0AQVs(collision.qvecFV0ARe(), collision.qvecFV0AIm(), collision.sumAmplFV0A()); + } + PROCESS_SWITCH(strangederivedbuilder, processCollisionsV0sOnly, "Produce collisions (V0s only)", true); PROCESS_SWITCH(strangederivedbuilder, processCollisions, "Produce collisions (V0s + casc)", true); PROCESS_SWITCH(strangederivedbuilder, processTrackExtrasV0sOnly, "Produce track extra information (V0s only)", true); @@ -519,6 +564,10 @@ struct strangederivedbuilder { PROCESS_SWITCH(strangederivedbuilder, processReconstructedSimulation, "Produce reco-ed simulated information", true); PROCESS_SWITCH(strangederivedbuilder, processProduceV0TOFs, "Produce V0TOFs table", true); PROCESS_SWITCH(strangederivedbuilder, processProduceCascTOFs, "Produce CascTOFs table", true); + PROCESS_SWITCH(strangederivedbuilder, processFT0AQVectors, "Produce FT0A Q-vectors table", false); + PROCESS_SWITCH(strangederivedbuilder, processFT0CQVectors, "Produce FT0C Q-vectors table", false); + PROCESS_SWITCH(strangederivedbuilder, processFT0MQVectors, "Produce FT0M Q-vectors table", false); + PROCESS_SWITCH(strangederivedbuilder, processFV0AQVectors, "Produce FV0A Q-vectors table", false); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGLF/Tasks/CMakeLists.txt b/PWGLF/Tasks/CMakeLists.txt index 88931ba6097..972d36a7251 100644 --- a/PWGLF/Tasks/CMakeLists.txt +++ b/PWGLF/Tasks/CMakeLists.txt @@ -9,241 +9,10 @@ # granted to it by virtue of its status as an Intergovernmental Organization # or submit itself to any jurisdiction. +# Common add_subdirectory(QC) -# Nuclei -o2physics_add_dpl_workflow(hyperon-reco-test - SOURCES hyperon-reco-test.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(nuclei-batask - SOURCES LFNucleiBATask.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(hypertritonanalysis - SOURCES hypertritonAnalysis.cxx - PUBLIC_LINK_LIBRARIES O2::DetectorsBase O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(nuclei-hist - SOURCES NucleiHistTask.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(hypertriton3bodyanalysis - SOURCES hypertriton3bodyanalysis.cxx - PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(hypertriton3bodymcqa - SOURCES hypertriton3bodyMCQA.cxx - PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(nuclei-in-jets - SOURCES nuclei_in_jets.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(helium-flow - SOURCES helium_flow.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - - -o2physics_add_dpl_workflow(antimatter-abs-hmpid - SOURCES AntimatterAbsorptionHMPID.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2::ReconstructionDataFormats O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(hyhefour-analysis - SOURCES hyhe4analysis.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -# Spectra -o2physics_add_dpl_workflow(mc-spectra-efficiency - SOURCES mcspectraefficiency.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(spectra-tof - SOURCES spectraTOF.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(spectra-tof-run2 - SOURCES spectraTOFRun2.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(spectra-tpc - SOURCES spectraTPC.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(spectra-tpc-pikapr - SOURCES spectraTPCPiKaPr.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(spectra-tpc-tiny - SOURCES spectraTPCtiny.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(spectra-tpc-tiny-pikapr - SOURCES spectraTPCtinyPiKaPr.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(spectra-charged - SOURCES spectraCharged.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(id-raa - SOURCES identifiedraa.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -# Strangeness -o2physics_add_dpl_workflow(lambdakzeroanalysis - SOURCES lambdakzeroanalysis.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(lambdakzeroanalysis-mc - SOURCES lambdakzeroanalysisMC.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(cascadeanalysis - SOURCES cascadeanalysis.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(cascadeanalysismc - SOURCES cascadeanalysisMC.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(v0postprocessing - SOURCES v0postprocessing.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(stqa - SOURCES stqa.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2::ReconstructionDataFormats O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(cascadecorrelations - SOURCES cascadecorrelations.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(non-prompt-cascade - SOURCES nonPromptCascade.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2::ReconstructionDataFormats O2Physics::AnalysisCore O2::DetectorsBase - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(kinkanalysis - SOURCES kinkAnalysis.cxx - PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(vzero-cascade-absorption - SOURCES vzero_cascade_absorption.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -# Resonance -o2physics_add_dpl_workflow(rsnanalysis - SOURCES rsnanalysis.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(phianalysis - SOURCES phianalysis.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(k892analysis - SOURCES k892analysis.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(k892pmanalysis - SOURCES k892pmanalysis.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - - -o2physics_add_dpl_workflow(lambda1520analysis - SOURCES lambda1520analysis.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(qa-hist - SOURCES QAHistTask.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(cascpostprocessing - SOURCES cascpostprocessing.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(hstrangecorrelation - SOURCES hStrangeCorrelation.cxx - PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(k1analysis - SOURCES k1analysis.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(phianalysisrun3 - SOURCES phianalysisrun3.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(f0980analysis - SOURCES f0980analysis.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(lambda1520spherocityanalysis - SOURCES lambda1520SpherocityAnalysis.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(delta-analysis - SOURCES deltaanalysis.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - - o2physics_add_dpl_workflow(rhoanalysis - SOURCES rhoanalysis.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(phi-analysis-thnsparse - SOURCES phianalysisTHnSparse.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - -o2physics_add_dpl_workflow(f1protoncorrelation - SOURCES f1protoncorrelation.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) - - -o2physics_add_dpl_workflow(chargedkstaranalysis - SOURCES chargedkstaranalysis.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) +# PAGs +add_subdirectory(Nuspex) +add_subdirectory(Resonances) +add_subdirectory(Strangeness) diff --git a/PWGLF/Tasks/AntimatterAbsorptionHMPID.cxx b/PWGLF/Tasks/Nuspex/AntimatterAbsorptionHMPID.cxx similarity index 100% rename from PWGLF/Tasks/AntimatterAbsorptionHMPID.cxx rename to PWGLF/Tasks/Nuspex/AntimatterAbsorptionHMPID.cxx diff --git a/PWGLF/Tasks/Nuspex/CMakeLists.txt b/PWGLF/Tasks/Nuspex/CMakeLists.txt new file mode 100644 index 00000000000..04bb815f42f --- /dev/null +++ b/PWGLF/Tasks/Nuspex/CMakeLists.txt @@ -0,0 +1,115 @@ +# 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(nuclei-batask + SOURCES LFNucleiBATask.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(hypertritonanalysis + SOURCES hypertritonAnalysis.cxx + PUBLIC_LINK_LIBRARIES O2::DetectorsBase O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(nuclei-hist + SOURCES NucleiHistTask.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(hypertriton3bodyanalysis + SOURCES hypertriton3bodyanalysis.cxx + PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(hypertriton3bodymcqa + SOURCES hypertriton3bodyMCQA.cxx + PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(nuclei-in-jets + SOURCES nuclei_in_jets.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(helium-flow + SOURCES helium_flow.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(antimatter-abs-hmpid + SOURCES AntimatterAbsorptionHMPID.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2::ReconstructionDataFormats O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(hyhefour-analysis + SOURCES hyhe4analysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(antid-lambda-ebye + SOURCES antidLambdaEbye.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(mc-spectra-efficiency + SOURCES mcspectraefficiency.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(spectra-tof + SOURCES spectraTOF.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(spectra-tof-run2 + SOURCES spectraTOFRun2.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(spectra-tpc + SOURCES spectraTPC.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(spectra-tpc-pikapr + SOURCES spectraTPCPiKaPr.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(spectra-tpc-tiny + SOURCES spectraTPCtiny.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(spectra-tpc-tiny-pikapr + SOURCES spectraTPCtinyPiKaPr.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(spectra-charged + SOURCES spectraCharged.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(id-raa + SOURCES identifiedraa.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(qa-hist + SOURCES QAHistTask.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(nuclei-flow + SOURCES nucleiFlow.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGLF/Tasks/LFNucleiBATask.cxx b/PWGLF/Tasks/Nuspex/LFNucleiBATask.cxx similarity index 86% rename from PWGLF/Tasks/LFNucleiBATask.cxx rename to PWGLF/Tasks/Nuspex/LFNucleiBATask.cxx index db7ccec5da5..28d68db386e 100644 --- a/PWGLF/Tasks/LFNucleiBATask.cxx +++ b/PWGLF/Tasks/Nuspex/LFNucleiBATask.cxx @@ -12,7 +12,7 @@ /// /// \file LFNucleiBATask.cxx /// -/// \brief Analysis task for the measurement of the coalescence parameter B2/B3 in pp collisions for (anti)deutheron/(anti)helium-3 +/// \brief Analysis task for the measurement of the coalescence parameter B2/B3 in pp collisions for (anti)deuteron/(anti)helium-3 /// /// \author Giovanni Malfattore and Rutuparna Rath /// @@ -89,6 +89,9 @@ struct LFNucleiBATask { // Set the axis used in this task ConfigurableAxis binsPercentile{"binsPercentile", {100, 0, 100}, "Centrality FT0M"}; ConfigurableAxis binsPt{"binsPt", {VARIABLE_WIDTH, 0.0, 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, 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.5, 7.0, 7.5, 8.0}, ""}; + ConfigurableAxis binsPtHe{"binsPtHe", {VARIABLE_WIDTH, 1.0, 1.25, 1.50, 1.75, 2.0, 2.25, 2.50, 2.75, 3.0, 3.25, 3.50, 3.75, 4.0, 4.50, 5.0, 6.0, 7.0, 8.0}, ""}; + ConfigurableAxis binsPtZHe{"binsPtZHe", {VARIABLE_WIDTH, 0.5, 0.625, 0.75, 0.875, 1.0, 1.125, 1.25, 1.375, 1.5, 1.625, 1.75, 1.875, 2.0, 2.25, 2.5, 3.0, 3.5, 4.0}, ""}; + ConfigurableAxis binsdEdx{"binsdEdx", {1000, 0.f, 1000.f}, ""}; ConfigurableAxis binsBeta{"binsBeta", {120, 0.0, 1.2}, ""}; ConfigurableAxis binsDCA{"binsDCA", {400, -1.f, 1.f}, ""}; @@ -126,6 +129,7 @@ struct LFNucleiBATask { Configurable tritonSelConfig{"tritonSelConfig", 0, "Select tritons using (0) 3Sigma TPC triton (1) additional 3sigma TPC pi,K,p veto cut"}; Configurable helium3Pt{"helium3Pt", 0, "Select use default pT (0) or use instead 2*pT (1) for helium-3"}; Configurable antiDeuteronPt{"antiDeuteronPt", 0, "Select use default pT (0) or use instead pT shift (1) for antideuteron"}; + Configurable DeuteronPt{"DeuteronPt", 0, "Select use default pT (0) or use instead pT shift (1) for deuteron"}; // Additional function used for pT-shift calibration TF1* fShiftPtHe = 0; @@ -136,10 +140,12 @@ struct LFNucleiBATask { TF1* fShiftTPCmomantiHe = 0; TF1* fShiftAntiD = 0; + TF1* fShiftD = 0; Configurable enableTPCmomShift{"enableTPCmomShift", false, "Flag to enable TPC momentum shift (for He only)"}; Configurable enablePShift{"enablePShift", false, "Flag to enable P shift (for He only)"}; Configurable enablePtShift{"enablePtShift", false, "Flag to enable Pt shift (for He only)"}; Configurable enablePtShiftAntiD{"enablePtShiftAntiD", true, "Flag to enable Pt shift (for antiDeuteron only)"}; + Configurable enablePtShiftD{"enablePtShiftD", true, "Flag to enable Pt shift (for Deuteron only)"}; Configurable> parShiftPtHe{"parShiftPtHe", {0.0f, 0.1f, 0.1f, 0.1f, 0.1f}, "Parameters for helium3-Pt shift (if enabled)."}; Configurable> parShiftPtantiHe{"parShiftPtantiHe", {0.0f, 0.1f, 0.1f, 0.1f, 0.1f}, "Parameters for anti-helium3-Pt shift (if enabled)."}; @@ -147,6 +153,7 @@ struct LFNucleiBATask { Configurable> parShiftPantiHe{"parShiftPantiHe", {0.0f, 0.1f, 0.1f, 0.1f, 0.1f}, "Parameters for anti-helium3-P shift (if enabled)."}; Configurable> parShiftPtAntiD{"parShiftPtAntiD", {-0.0955412, 0.798164, -0.536111, 0.0887876, -1.11022e-13}, "Parameters for Pt shift (if enabled)."}; + Configurable> parShiftPtD{"parShiftPtD", {-0.0955412, 0.798164, -0.536111, 0.0887876, -1.11022e-13}, "Parameters for Pt shift (if enabled)."}; Configurable enableCentrality{"enableCentrality", true, "Flag to enable centrality 3D histos)"}; // PDG codes and masses used in this analysis @@ -167,6 +174,8 @@ struct LFNucleiBATask { { const AxisSpec pAxis{binsPt, "#it{p} (GeV/#it{c})"}; const AxisSpec ptAxis{binsPt, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec ptHeAxis{binsPtHe, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec ptZHeAxis{binsPtZHe, "#it{p}_{T} (GeV/#it{c})"}; const AxisSpec dedxAxis{binsdEdx, "d#it{E}/d#it{x} A.U."}; const AxisSpec betaAxis{binsBeta, "TOF #beta"}; const AxisSpec dcaxyAxis{binsDCA, "DCAxy (cm)"}; @@ -297,8 +306,8 @@ struct LFNucleiBATask { histos.add("tracks/dca/before/hDCAxy", "DCAxy", HistType::kTH1F, {dcaxyAxis}); histos.add("tracks/dca/before/hDCAz", "DCAz", HistType::kTH1F, {dcazAxis}); histos.add("tracks/dca/before/hDCAxyVsDCAz", "DCAxy vs DCAz", HistType::kTH2F, {{dcaxyAxis}, {dcazAxis}}); - histos.add("tracks/dca/before/hDCAxyVsPt", "DCAxy vs Pt", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); - histos.add("tracks/dca/before/hDCAzVsPt", "DCAz vs Pt", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); + histos.add("tracks/dca/before/hDCAxyVsPt", "DCAxy vs Pt", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/dca/before/hDCAzVsPt", "DCAz vs Pt", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); if (enablePr) { histos.add("tracks/proton/dca/before/hDCAxyVsPtProton", "DCAxy vs Pt (p)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); @@ -324,10 +333,17 @@ struct LFNucleiBATask { histos.add("tracks/triton/dca/before/hDCAzVsPtantiTriton", "DCAz vs Pt (#bar{t})", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); } if (enableHe) { - histos.add("tracks/helium/dca/before/hDCAxyVsPtHelium", "DCAxy vs Pt (He)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/before/hDCAxyVsPtantiHelium", "DCAxy vs Pt (#bar{He})", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/before/hDCAzVsPtHelium", "DCAz vs Pt (He)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - histos.add("tracks/helium/dca/before/hDCAzVsPtantiHelium", "DCAz vs Pt (#bar{He})", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); + histos.add("tracks/helium/dca/before/hDCAxyVsPtHelium", "DCAxy vs Pt (He)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/before/hDCAxyVsPtantiHelium", "DCAxy vs Pt (#bar{He})", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/before/hDCAzVsPtHelium", "DCAz vs Pt (He)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/before/hDCAzVsPtantiHelium", "DCAz vs Pt (#bar{He})", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + + if (doTOFplots) { + histos.add("tracks/helium/dca/before/TOF/hDCAxyVsPtHelium", "DCAxy vs Pt (He)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/before/TOF/hDCAxyVsPtantiHelium", "DCAxy vs Pt (#bar{He})", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/before/TOF/hDCAzVsPtHelium", "DCAz vs Pt (He)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/before/TOF/hDCAzVsPtantiHelium", "DCAz vs Pt (#bar{He})", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + } } if (enableAl) { histos.add("tracks/alpha/dca/before/hDCAxyVsPtAlpha", "DCAxy vs Pt (#alpha)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); @@ -341,8 +357,8 @@ struct LFNucleiBATask { histos.add("tracks/dca/after/hDCAxy", "DCAxy; DCAxy; counts", HistType::kTH1F, {{dcaxyAxis}}); histos.add("tracks/dca/after/hDCAz", "DCAz; DCAz; counts", HistType::kTH1F, {{dcazAxis}}); histos.add("tracks/dca/after/hDCAxyVsDCAz", "DCAxy vs DCAz; DCAxy (cm); DCAz (cm)", HistType::kTH2F, {{dcaxyAxis}, {dcazAxis}}); - histos.add("tracks/dca/after/hDCAxyVsPt", "DCAxy vs Pt", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); - histos.add("tracks/dca/after/hDCAzVsPt", "DCAz vs Pt", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); + histos.add("tracks/dca/after/hDCAxyVsPt", "DCAxy vs Pt", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/dca/after/hDCAzVsPt", "DCAz vs Pt", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); if (enablePr) { histos.add("tracks/proton/dca/after/hDCAxyVsPtProton", "DCAxy vs Pt (p)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); @@ -363,10 +379,17 @@ struct LFNucleiBATask { histos.add("tracks/triton/dca/after/hDCAzVsPtantiTriton", "DCAz vs Pt (#bar{t})", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); } if (enableHe) { - histos.add("tracks/helium/dca/after/hDCAxyVsPtHelium", "DCAxy vs Pt (He)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/after/hDCAxyVsPtantiHelium", "DCAxy vs Pt (#bar{He})", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/after/hDCAzVsPtHelium", "DCAz vs Pt (He)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - histos.add("tracks/helium/dca/after/hDCAzVsPtantiHelium", "DCAz vs Pt (#bar{He})", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); + histos.add("tracks/helium/dca/after/hDCAxyVsPtHelium", "DCAxy vs Pt (He)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/after/hDCAxyVsPtantiHelium", "DCAxy vs Pt (#bar{He})", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/after/hDCAzVsPtHelium", "DCAz vs Pt (He)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/after/hDCAzVsPtantiHelium", "DCAz vs Pt (#bar{He})", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + + if (doTOFplots) { + histos.add("tracks/helium/dca/after/TOF/hDCAxyVsPtHelium", "DCAxy vs Pt (He)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/after/TOF/hDCAxyVsPtantiHelium", "DCAxy vs Pt (#bar{He})", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/after/TOF/hDCAzVsPtHelium", "DCAz vs Pt (He)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/after/TOF/hDCAzVsPtantiHelium", "DCAz vs Pt (#bar{He})", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + } } if (enableAl) { histos.add("tracks/alpha/dca/after/hDCAxyVsPtAlpha", "DCAxy vs Pt (#alpha)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); @@ -400,21 +423,21 @@ struct LFNucleiBATask { histos.add("tracks/triton/h1antiTritonSpectra", "#it{p}_{T} (#bar{t})", HistType::kTH1F, {ptAxis}); } if (enableHe) { - histos.add("tracks/helium/h1HeliumSpectra", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - histos.add("tracks/helium/h1antiHeliumSpectra", "#it{p}_{T} (#bar{He})", HistType::kTH1F, {ptAxis}); + histos.add("tracks/helium/h1HeliumSpectra", "#it{p}_{T} (He)", HistType::kTH1F, {ptZHeAxis}); + histos.add("tracks/helium/h1antiHeliumSpectra", "#it{p}_{T} (#bar{He})", HistType::kTH1F, {ptZHeAxis}); - histos.add("tracks/helium/h2HeliumYvsPt", "#it{y} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); - histos.add("tracks/helium/h2HeliumYvsPt_Z2", "#it{y} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); - histos.add("tracks/helium/h2HeliumEtavsPt", "#it{#eta} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); - histos.add("tracks/helium/h2HeliumEtavsPt_Z2", "#it{#eta} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h2HeliumYvsPt", "#it{y} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptZHeAxis}}); + histos.add("tracks/helium/h2HeliumYvsPt_Z2", "#it{y} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptHeAxis}}); + histos.add("tracks/helium/h2HeliumEtavsPt", "#it{#eta} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptZHeAxis}}); + histos.add("tracks/helium/h2HeliumEtavsPt_Z2", "#it{#eta} vs #it{p}_{T} (He)", HistType::kTH2F, {{96, -1.2, 1.2}, {ptHeAxis}}); - histos.add("tracks/helium/h1HeliumSpectra_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - histos.add("tracks/helium/h1antiHeliumSpectra_Z2", "#it{p}_{T} (#bar{He})", HistType::kTH1F, {ptAxis}); + histos.add("tracks/helium/h1HeliumSpectra_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptHeAxis}); + histos.add("tracks/helium/h1antiHeliumSpectra_Z2", "#it{p}_{T} (#bar{He})", HistType::kTH1F, {ptHeAxis}); - histos.add("tracks/helium/h2antiHeliumYvsPt", "#it{y} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); - histos.add("tracks/helium/h2antiHeliumYvsPt_Z2", "#it{y} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); - histos.add("tracks/helium/h2antiHeliumEtavsPt", "#it{#eta} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); - histos.add("tracks/helium/h2antiHeliumEtavsPt_Z2", "#it{#eta} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptAxis}}); + histos.add("tracks/helium/h2antiHeliumYvsPt", "#it{y} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptZHeAxis}}); + histos.add("tracks/helium/h2antiHeliumYvsPt_Z2", "#it{y} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptHeAxis}}); + histos.add("tracks/helium/h2antiHeliumEtavsPt", "#it{#eta} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptZHeAxis}}); + histos.add("tracks/helium/h2antiHeliumEtavsPt_Z2", "#it{#eta} vs #it{p}_{T} (#bar{He})", HistType::kTH2F, {{96, -1.2, 1.2}, {ptHeAxis}}); } if (enableAl) { histos.add("tracks/alpha/h1AlphaSpectra", "#it{p}_{T} (#alpha)", HistType::kTH1F, {ptAxis}); @@ -438,12 +461,14 @@ struct LFNucleiBATask { if (enableDe) { histos.add("tracks/deuteron/h1DeuteronSpectraTrue", "#it{p}_{T} (d)", HistType::kTH1F, {ptAxis}); histos.add("tracks/deuteron/h1DeuteronSpectraTrueWPID", "#it{p}_{T} (d)", HistType::kTH1F, {ptAxis}); + histos.add("tracks/deuteron/hPtDeuteronTOFTrue", "#it{p}_{T} (d) with TOF", HistType::kTH1F, {ptAxis}); histos.add("tracks/deuteron/h1DeuteronSpectraTruePrim", "#it{p}_{T} (d)", HistType::kTH1F, {ptAxis}); histos.add("tracks/deuteron/h1DeuteronSpectraTrueSec", "#it{p}_{T} (d)", HistType::kTH1F, {ptAxis}); histos.add("tracks/deuteron/h1DeuteronSpectraTrueTransport", "#it{p}_{T} (d)", HistType::kTH1F, {ptAxis}); histos.add("tracks/deuteron/h1antiDeuteronSpectraTrue", "#it{p}_{T} (#bar{d})", HistType::kTH1F, {ptAxis}); histos.add("tracks/deuteron/h1antiDeuteronSpectraTrueWPID", "#it{p}_{T} (#bar{d})", HistType::kTH1F, {ptAxis}); + histos.add("tracks/deuteron/hPtantiDeuteronTOFTrue", "#it{p}_{T} (#bar{d}) with TOF", HistType::kTH1F, {ptAxis}); histos.add("tracks/deuteron/h1antiDeuteronSpectraTruePrim", "#it{p}_{T} (#bar{d})", HistType::kTH1F, {ptAxis}); histos.add("tracks/deuteron/h1antiDeuteronSpectraTrueSec", "#it{p}_{T} (#bar{d})", HistType::kTH1F, {ptAxis}); histos.add("tracks/deuteron/h1antiDeuteronSpectraTrueTransport", "#it{p}_{T} (#bar{d})", HistType::kTH1F, {ptAxis}); @@ -460,29 +485,29 @@ struct LFNucleiBATask { histos.add("tracks/triton/h1antiTritonSpectraTrueTransport", "#it{p}_{T} (#bar{t})", HistType::kTH1F, {ptAxis}); } if (enableHe) { - histos.add("tracks/helium/h1HeliumSpectraTrue", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - histos.add("tracks/helium/h1HeliumSpectraTrueWPID", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - histos.add("tracks/helium/h1HeliumSpectraTruePrim", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - histos.add("tracks/helium/h1HeliumSpectraTrueSec", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - histos.add("tracks/helium/h1HeliumSpectraTrueTransport", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - - histos.add("tracks/helium/h1HeliumSpectraTrue_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - histos.add("tracks/helium/h1HeliumSpectraTrueWPID_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - histos.add("tracks/helium/h1HeliumSpectraTruePrim_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - histos.add("tracks/helium/h1HeliumSpectraTrueSec_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - histos.add("tracks/helium/h1HeliumSpectraTrueTransport_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - - histos.add("tracks/helium/h1antiHeliumSpectraTrue", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - histos.add("tracks/helium/h1antiHeliumSpectraTrueWPID", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - histos.add("tracks/helium/h1antiHeliumSpectraTruePrim", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - histos.add("tracks/helium/h1antiHeliumSpectraTrueSec", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - histos.add("tracks/helium/h1antiHeliumSpectraTrueTransport", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - - histos.add("tracks/helium/h1antiHeliumSpectraTrue_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - histos.add("tracks/helium/h1antiHeliumSpectraTrueWPID_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - histos.add("tracks/helium/h1antiHeliumSpectraTruePrim_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - histos.add("tracks/helium/h1antiHeliumSpectraTrueSec_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); - histos.add("tracks/helium/h1antiHeliumSpectraTrueTransport_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptAxis}); + histos.add("tracks/helium/h1HeliumSpectraTrue", "#it{p}_{T} (He)", HistType::kTH1F, {ptZHeAxis}); + histos.add("tracks/helium/h1HeliumSpectraTrueWPID", "#it{p}_{T} (He)", HistType::kTH1F, {ptZHeAxis}); + histos.add("tracks/helium/h1HeliumSpectraTruePrim", "#it{p}_{T} (He)", HistType::kTH1F, {ptZHeAxis}); + histos.add("tracks/helium/h1HeliumSpectraTrueSec", "#it{p}_{T} (He)", HistType::kTH1F, {ptZHeAxis}); + histos.add("tracks/helium/h1HeliumSpectraTrueTransport", "#it{p}_{T} (He)", HistType::kTH1F, {ptZHeAxis}); + + histos.add("tracks/helium/h1HeliumSpectraTrue_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptHeAxis}); + histos.add("tracks/helium/h1HeliumSpectraTrueWPID_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptHeAxis}); + histos.add("tracks/helium/h1HeliumSpectraTruePrim_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptHeAxis}); + histos.add("tracks/helium/h1HeliumSpectraTrueSec_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptHeAxis}); + histos.add("tracks/helium/h1HeliumSpectraTrueTransport_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptHeAxis}); + + histos.add("tracks/helium/h1antiHeliumSpectraTrue", "#it{p}_{T} (He)", HistType::kTH1F, {ptZHeAxis}); + histos.add("tracks/helium/h1antiHeliumSpectraTrueWPID", "#it{p}_{T} (He)", HistType::kTH1F, {ptZHeAxis}); + histos.add("tracks/helium/h1antiHeliumSpectraTruePrim", "#it{p}_{T} (He)", HistType::kTH1F, {ptZHeAxis}); + histos.add("tracks/helium/h1antiHeliumSpectraTrueSec", "#it{p}_{T} (He)", HistType::kTH1F, {ptZHeAxis}); + histos.add("tracks/helium/h1antiHeliumSpectraTrueTransport", "#it{p}_{T} (He)", HistType::kTH1F, {ptZHeAxis}); + + histos.add("tracks/helium/h1antiHeliumSpectraTrue_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptHeAxis}); + histos.add("tracks/helium/h1antiHeliumSpectraTrueWPID_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptHeAxis}); + histos.add("tracks/helium/h1antiHeliumSpectraTruePrim_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptHeAxis}); + histos.add("tracks/helium/h1antiHeliumSpectraTrueSec_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptHeAxis}); + histos.add("tracks/helium/h1antiHeliumSpectraTrueTransport_Z2", "#it{p}_{T} (He)", HistType::kTH1F, {ptHeAxis}); if (enablePtSpectra) { histos.add("tracks/eff/helium/hPtHeTrue", "Track #it{p}_{T} (He); #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{400, 0., 8.}}); histos.add("tracks/eff/helium/hPtantiHeTrue", "Track #it{p}_{T} (#bar{He}); #it{p}_{T} (GeV/#it{c}); counts", HistType::kTH1F, {{400, 0., 8.}}); @@ -580,29 +605,57 @@ struct LFNucleiBATask { histos.add("tracks/triton/dca/after/hDCAxyVsPtantiTritonTrueTransport", "DCAxy vs Pt (#bar{t}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); } if (enableHe) { - histos.add("tracks/helium/dca/before/hDCAxyVsPtHeliumTrue", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); + // all tracks + histos.add("tracks/helium/dca/before/hDCAxyVsPtHeliumTrue", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/before/hDCAxyVsPtHeliumTruePrim", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/before/hDCAxyVsPtHeliumTrueSec", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/before/hDCAxyVsPtHeliumTrueTransport", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/before/hDCAxyVsPtHeliumTruePrim", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/before/hDCAxyVsPtHeliumTrueSec", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/before/hDCAxyVsPtHeliumTrueTransport", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/before/hDCAxyVsPtantiHeliumTrue", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/before/hDCAxyVsPtantiHeliumTrue", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + + histos.add("tracks/helium/dca/before/hDCAxyVsPtantiHeliumTruePrim", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/before/hDCAxyVsPtantiHeliumTrueSec", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/before/hDCAxyVsPtantiHeliumTrueTransport", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + + histos.add("tracks/helium/dca/after/hDCAxyVsPtHeliumTrue", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + + histos.add("tracks/helium/dca/after/hDCAxyVsPtHeliumTruePrim", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/after/hDCAxyVsPtHeliumTrueSec", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/after/hDCAxyVsPtHeliumTrueTransport", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + + histos.add("tracks/helium/dca/after/hDCAxyVsPtantiHeliumTrue", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + + histos.add("tracks/helium/dca/after/hDCAxyVsPtantiHeliumTruePrim", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/after/hDCAxyVsPtantiHeliumTrueSec", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/after/hDCAxyVsPtantiHeliumTrueTransport", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + + // wTOF + if (doTOFplots) { + histos.add("tracks/helium/dca/before/TOF/hDCAxyVsPtHeliumTrue", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/before/hDCAxyVsPtantiHeliumTruePrim", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/before/hDCAxyVsPtantiHeliumTrueSec", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/before/hDCAxyVsPtantiHeliumTrueTransport", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/before/TOF/hDCAxyVsPtHeliumTruePrim", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/before/TOF/hDCAxyVsPtHeliumTrueSec", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/before/TOF/hDCAxyVsPtHeliumTrueTransport", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/after/hDCAxyVsPtHeliumTrue", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/before/TOF/hDCAxyVsPtantiHeliumTrue", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/after/hDCAxyVsPtHeliumTruePrim", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/after/hDCAxyVsPtHeliumTrueSec", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/after/hDCAxyVsPtHeliumTrueTransport", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/before/TOF/hDCAxyVsPtantiHeliumTruePrim", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/before/TOF/hDCAxyVsPtantiHeliumTrueSec", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/before/TOF/hDCAxyVsPtantiHeliumTrueTransport", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/after/hDCAxyVsPtantiHeliumTrue", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/after/TOF/hDCAxyVsPtHeliumTrue", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/after/hDCAxyVsPtantiHeliumTruePrim", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/after/hDCAxyVsPtantiHeliumTrueSec", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); - histos.add("tracks/helium/dca/after/hDCAxyVsPtantiHeliumTrueTransport", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/after/TOF/hDCAxyVsPtHeliumTruePrim", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/after/TOF/hDCAxyVsPtHeliumTrueSec", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/after/TOF/hDCAxyVsPtHeliumTrueTransport", "DCAxy vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + + histos.add("tracks/helium/dca/after/TOF/hDCAxyVsPtantiHeliumTrue", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + + histos.add("tracks/helium/dca/after/TOF/hDCAxyVsPtantiHeliumTruePrim", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/after/TOF/hDCAxyVsPtantiHeliumTrueSec", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + histos.add("tracks/helium/dca/after/TOF/hDCAxyVsPtantiHeliumTrueTransport", "DCAxy vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcaxyAxis}}); + } } if (enableAl) { histos.add("tracks/alpha/dca/before/hDCAxyVsPtAlphaTrue", "DCAxy vs Pt (#alpha); #it{p}_{T} (GeV/#it{c}); DCAxy (cm)", HistType::kTH2F, {{ptAxis}, {dcaxyAxis}}); @@ -706,29 +759,57 @@ struct LFNucleiBATask { histos.add("tracks/triton/dca/after/hDCAzVsPtantiTritonTrueTransport", "DCAz vs Pt (#bar{t}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); } if (enableHe) { - histos.add("tracks/helium/dca/before/hDCAzVsPtHeliumTrue", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); + // all tracks + histos.add("tracks/helium/dca/before/hDCAzVsPtHeliumTrue", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + + histos.add("tracks/helium/dca/before/hDCAzVsPtHeliumTruePrim", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/before/hDCAzVsPtHeliumTrueSec", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/before/hDCAzVsPtHeliumTrueTransport", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); - histos.add("tracks/helium/dca/before/hDCAzVsPtHeliumTruePrim", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - histos.add("tracks/helium/dca/before/hDCAzVsPtHeliumTrueSec", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - histos.add("tracks/helium/dca/before/hDCAzVsPtHeliumTrueTransport", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); + histos.add("tracks/helium/dca/before/hDCAzVsPtantiHeliumTrue", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); - histos.add("tracks/helium/dca/before/hDCAzVsPtantiHeliumTrue", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); + histos.add("tracks/helium/dca/before/hDCAzVsPtantiHeliumTruePrim", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/before/hDCAzVsPtantiHeliumTrueSec", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/before/hDCAzVsPtantiHeliumTrueTransport", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); - histos.add("tracks/helium/dca/before/hDCAzVsPtantiHeliumTruePrim", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - histos.add("tracks/helium/dca/before/hDCAzVsPtantiHeliumTrueSec", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - histos.add("tracks/helium/dca/before/hDCAzVsPtantiHeliumTrueTransport", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); + histos.add("tracks/helium/dca/after/hDCAzVsPtHeliumTrue", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); - histos.add("tracks/helium/dca/after/hDCAzVsPtHeliumTrue", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); + histos.add("tracks/helium/dca/after/hDCAzVsPtHeliumTruePrim", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/after/hDCAzVsPtHeliumTrueSec", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/after/hDCAzVsPtHeliumTrueTransport", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); - histos.add("tracks/helium/dca/after/hDCAzVsPtHeliumTruePrim", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - histos.add("tracks/helium/dca/after/hDCAzVsPtHeliumTrueSec", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - histos.add("tracks/helium/dca/after/hDCAzVsPtHeliumTrueTransport", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); + histos.add("tracks/helium/dca/after/hDCAzVsPtantiHeliumTrue", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + + histos.add("tracks/helium/dca/after/hDCAzVsPtantiHeliumTruePrim", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/after/hDCAzVsPtantiHeliumTrueSec", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/after/hDCAzVsPtantiHeliumTrueTransport", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + + // w TOF + if (doTOFplots) { + histos.add("tracks/helium/dca/before/TOF/hDCAzVsPtHeliumTrue", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); - histos.add("tracks/helium/dca/after/hDCAzVsPtantiHeliumTrue", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); + histos.add("tracks/helium/dca/before/TOF/hDCAzVsPtHeliumTruePrim", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/before/TOF/hDCAzVsPtHeliumTrueSec", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/before/TOF/hDCAzVsPtHeliumTrueTransport", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); - histos.add("tracks/helium/dca/after/hDCAzVsPtantiHeliumTruePrim", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - histos.add("tracks/helium/dca/after/hDCAzVsPtantiHeliumTrueSec", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); - histos.add("tracks/helium/dca/after/hDCAzVsPtantiHeliumTrueTransport", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); + histos.add("tracks/helium/dca/before/TOF/hDCAzVsPtantiHeliumTrue", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + + histos.add("tracks/helium/dca/before/TOF/hDCAzVsPtantiHeliumTruePrim", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/before/TOF/hDCAzVsPtantiHeliumTrueSec", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/before/TOF/hDCAzVsPtantiHeliumTrueTransport", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + + histos.add("tracks/helium/dca/after/TOF/hDCAzVsPtHeliumTrue", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + + histos.add("tracks/helium/dca/after/TOF/hDCAzVsPtHeliumTruePrim", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/after/TOF/hDCAzVsPtHeliumTrueSec", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/after/TOF/hDCAzVsPtHeliumTrueTransport", "DCAz vs Pt (He); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + + histos.add("tracks/helium/dca/after/TOF/hDCAzVsPtantiHeliumTrue", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + + histos.add("tracks/helium/dca/after/TOF/hDCAzVsPtantiHeliumTruePrim", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/after/TOF/hDCAzVsPtantiHeliumTrueSec", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + histos.add("tracks/helium/dca/after/TOF/hDCAzVsPtantiHeliumTrueTransport", "DCAz vs Pt (#bar{He}); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{900, 0.5f, 5.f}, {dcazAxis}}); + } } if (enableAl) { histos.add("tracks/alpha/dca/before/hDCAzVsPtAlphaTrue", "DCAz vs Pt (#alpha); #it{p}_{T} (GeV/#it{c}); DCAz (cm)", HistType::kTH2F, {{ptAxis}, {dcazAxis}}); @@ -805,8 +886,8 @@ struct LFNucleiBATask { histos.add("tracks/deuteron/h2antiDeuteronTPCExpSignalDiffVsPt", "TPC <-dE/dX> - Exp <-dE/dX> (#bar{d}) vs #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); TPC <-dE/dX> ExpDiff (#bar{d})", HistType::kTH2F, {{ptAxis}, {16000, -800, 800.}}); } if (enableHe) { - histos.add("tracks/helium/h2HeliumTPCExpSignalDiffVsPt", "TPC <-dE/dX> - Exp <-dE/dX> (He) vs #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); TPC <-dE/dX> ExpDiff (He)", HistType::kTH2F, {{ptAxis}, {16000, -800, 800.}}); - histos.add("tracks/helium/h2antiHeliumTPCExpSignalDiffVsPt", "TPC <-dE/dX> - Exp <-dE/dX> (#bar{He}) vs #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); TPC <-dE/dX> ExpDiff (#bar{He})", HistType::kTH2F, {{ptAxis}, {16000, -800, 800.}}); + histos.add("tracks/helium/h2HeliumTPCExpSignalDiffVsPt", "TPC <-dE/dX> - Exp <-dE/dX> (He) vs #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); TPC <-dE/dX> ExpDiff (He)", HistType::kTH2F, {{ptZHeAxis}, {16000, -800, 800.}}); + histos.add("tracks/helium/h2antiHeliumTPCExpSignalDiffVsPt", "TPC <-dE/dX> - Exp <-dE/dX> (#bar{He}) vs #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); TPC <-dE/dX> ExpDiff (#bar{He})", HistType::kTH2F, {{ptZHeAxis}, {16000, -800, 800.}}); } } @@ -834,8 +915,8 @@ struct LFNucleiBATask { histos.add("tracks/triton/h2antiTritonVspTNSigmaTPC", "NSigmaTPC(#bar{t}) vs pT; #it{p}_{T} (GeV/#it{c}); NSigmaTPC", HistType::kTH2F, {{ptAxis}, {SigmaTPCAxis}}); } if (enableHe) { - histos.add("tracks/helium/h2HeliumVspTNSigmaTPC", "NSigmaTPC(He) vs pT; #it{p}_{T} (GeV/#it{c}); NSigmaTPC", HistType::kTH2F, {{ptAxis}, {SigmaTPCAxis}}); - histos.add("tracks/helium/h2antiHeliumVspTNSigmaTPC", "NSigmaTPC(#bar{He}) vs pT; #it{p}_{T} (GeV/#it{c}); NSigmaTPC", HistType::kTH2F, {{ptAxis}, {SigmaTPCAxis}}); + histos.add("tracks/helium/h2HeliumVspTNSigmaTPC", "NSigmaTPC(He) vs pT/Z; #it{p}_{T}/Z (GeV/#it{c}); NSigmaTPC", HistType::kTH2F, {{ptZHeAxis}, {SigmaTPCAxis}}); + histos.add("tracks/helium/h2antiHeliumVspTNSigmaTPC", "NSigmaTPC(#bar{He}) vs pT/Z; #it{p}_{T}/Z (GeV/#it{c}); NSigmaTPC", HistType::kTH2F, {{ptZHeAxis}, {SigmaTPCAxis}}); } if (enableAl) { histos.add("tracks/alpha/h2AlphaVspTNSigmaTPC", "NSigmaTPC(#alpha) vs pT; #it{p}_{T} (GeV/#it{c}); NSigmaTPC", HistType::kTH2F, {{ptAxis}, {SigmaTPCAxis}}); @@ -915,10 +996,10 @@ struct LFNucleiBATask { histos.add("tracks/deuteron/h2antiDeuteronTOFExpSignalDiffVsPtCut", "TOF t - t_{exp}(#bar{d}) vs #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); TOF t - t_{exp} (#bar{d})", HistType::kTH2F, {{ptAxis}, {2000, -25000, 25000}}); } if (enableHe) { - histos.add("tracks/helium/h2HeliumTOFExpSignalDiffVsPt", "TOF t - t_{exp}(He) vs #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); TOF t - t_{exp} (He)", HistType::kTH2F, {{ptAxis}, {2000, -25000, 25000}}); - histos.add("tracks/helium/h2antiHeliumTOFExpSignalDiffVsPt", "TOF t - t_{exp}(#bar{He}) vs #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); TOF t - t_{exp} (#bar{He})", HistType::kTH2F, {{ptAxis}, {2000, -25000, 25000}}); - histos.add("tracks/helium/h2HeliumTOFExpSignalDiffVsPtCut", "TOF t - t_{exp}(He) vs #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); TOF t - t_{exp} (He)", HistType::kTH2F, {{ptAxis}, {2000, -25000, 25000}}); - histos.add("tracks/helium/h2antiHeliumTOFExpSignalDiffVsPtCut", "TOF t - t_{exp}(#bar{He}}) vs #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); TOF t - t_{exp} (#bar{He})", HistType::kTH2F, {{ptAxis}, {2000, -25000, 25000}}); + histos.add("tracks/helium/h2HeliumTOFExpSignalDiffVsPt", "TOF t - t_{exp}(He) vs #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); TOF t - t_{exp} (He)", HistType::kTH2F, {{ptZHeAxis}, {2000, -25000, 25000}}); + histos.add("tracks/helium/h2antiHeliumTOFExpSignalDiffVsPt", "TOF t - t_{exp}(#bar{He}) vs #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); TOF t - t_{exp} (#bar{He})", HistType::kTH2F, {{ptZHeAxis}, {2000, -25000, 25000}}); + histos.add("tracks/helium/h2HeliumTOFExpSignalDiffVsPtCut", "TOF t - t_{exp}(He) vs #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); TOF t - t_{exp} (He)", HistType::kTH2F, {{ptZHeAxis}, {2000, -25000, 25000}}); + histos.add("tracks/helium/h2antiHeliumTOFExpSignalDiffVsPtCut", "TOF t - t_{exp}(#bar{He}}) vs #it{p}_{T}; #it{p}_{T} (GeV/#it{c}); TOF t - t_{exp} (#bar{He})", HistType::kTH2F, {{ptZHeAxis}, {2000, -25000, 25000}}); } } @@ -934,8 +1015,8 @@ struct LFNucleiBATask { histos.add("tracks/deuteron/h2antiDeuteronVspTNSigmaTOF", "NSigmaTOF(#bar{d}) vs pT; #it{p}_{T} (GeV/#it{c}); NSigmaTOF", HistType::kTH2F, {{ptAxis}, {SigmaTOFAxis}}); } if (enableHe) { - histos.add("tracks/helium/h2HeliumVspTNSigmaTOF", "NSigmaTOF(He) vs pT; #it{p}_{T} (GeV/#it{c}); NSigmaTOF", HistType::kTH2F, {{ptAxis}, {SigmaTOFAxis}}); - histos.add("tracks/helium/h2antiHeliumVspTNSigmaTOF", "NSigmaTOF(#bar{He}) vs pT; #it{p}_{T} (GeV/#it{c}); NSigmaTOF", HistType::kTH2F, {{ptAxis}, {SigmaTOFAxis}}); + histos.add("tracks/helium/h2HeliumVspTNSigmaTOF", "NSigmaTOF(He) vs pT; #it{p}_{T} (GeV/#it{c}); NSigmaTOF", HistType::kTH2F, {{ptZHeAxis}, {SigmaTOFAxis}}); + histos.add("tracks/helium/h2antiHeliumVspTNSigmaTOF", "NSigmaTOF(#bar{He}) vs pT; #it{p}_{T} (GeV/#it{c}); NSigmaTOF", HistType::kTH2F, {{ptZHeAxis}, {SigmaTOFAxis}}); } if (enableDebug) { // NSigmaTPC vs NSigmaTOF histograms @@ -975,11 +1056,11 @@ struct LFNucleiBATask { } } if (enableHe) { - histos.add("tracks/helium/h2TOFmassHeliumVsPt", "h2TOFmassHeliumVsPt; TOFmass; #it{p}_{T} (GeV)", HistType::kTH2F, {{320, 0.4, 4.}, {250, 0., 5.}}); - histos.add("tracks/helium/h2TOFmassantiHeliumVsPt", "h2TOFmassantiHeliumVsPt; TOFmass; #it{p}_{T} (GeV)", HistType::kTH2F, {{320, 0.4, 4.}, {250, 0., 5.}}); + histos.add("tracks/helium/h2TOFmassHeliumVsPt", "h2TOFmassHeliumVsPt; TOFmass; #it{p}_{T}/Z (GeV)", HistType::kTH2F, {{320, 0.4, 4.}, {ptZHeAxis}}); + histos.add("tracks/helium/h2TOFmassantiHeliumVsPt", "h2TOFmassantiHeliumVsPt; TOFmass; #it{p}_{T}/Z (GeV)", HistType::kTH2F, {{320, 0.4, 4.}, {ptZHeAxis}}); if (enableBetaCut) { - histos.add("tracks/helium/h2TOFmassHeliumVsPt_BetaCut", "h2TOFmassHeliumVsPt_BetaCut; TOFmass; #it{p}_{T} (GeV)", HistType::kTH2F, {{320, 0.4, 4.}, {250, 0., 5.}}); - histos.add("tracks/helium/h2TOFmassantiHeliumVsPt_BetaCut", "h2TOFmassantiHeliumVsPt_BetaCut; TOFmass; #it{p}_{T} (GeV)", HistType::kTH2F, {{320, 0.4, 4.}, {250, 0., 5.}}); + histos.add("tracks/helium/h2TOFmassHeliumVsPt_BetaCut", "h2TOFmassHeliumVsPt_BetaCut; TOFmass; #it{p}_{T}/Z (GeV)", HistType::kTH2F, {{320, 0.4, 4.}, {ptZHeAxis}}); + histos.add("tracks/helium/h2TOFmassantiHeliumVsPt_BetaCut", "h2TOFmassantiHeliumVsPt_BetaCut; TOFmass; #it{p}_{T}/Z (GeV)", HistType::kTH2F, {{320, 0.4, 4.}, {ptZHeAxis}}); } } // TOF mass squared histograms @@ -1013,13 +1094,13 @@ struct LFNucleiBATask { } } if (enableHe) { - histos.add("tracks/helium/h2TOFmass2antiHeliumVsPt", "#Delta M^{2} (#bar{He}) vs #it{p}_{T}; #Delta M^{2} (#bar{He}); #it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {{massHeAxis}, {250, 0., 5.}}); - histos.add("tracks/helium/h2TOFmass2HeliumVsPt", "#Delta M^{2} (He) vs #it{p}_{T}; #Delta M^{2} (He); #it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {{massHeAxis}, {250, 0., 5.}}); - histos.add("tracks/helium/h2TOFmassDeltaHeliumVsPt", "#Delta M (He) vs #it{p}_{T}; #Delta M (He); #it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {{massHeAxis}, {250, 0., 5.}}); - histos.add("tracks/helium/h2TOFmassDeltaantiHeliumVsPt", "#Delta M (#bar{He}) vs #it{p}_{T}; #Delta M (#bar{He}); #it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {{massHeAxis}, {250, 0., 5.}}); + histos.add("tracks/helium/h2TOFmass2antiHeliumVsPt", "#Delta M^{2} (#bar{He}) vs #it{p}_{T}; #Delta M^{2} (#bar{He}); #it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {{massHeAxis}, {ptZHeAxis}}); + histos.add("tracks/helium/h2TOFmass2HeliumVsPt", "#Delta M^{2} (He) vs #it{p}_{T}; #Delta M^{2} (He); #it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {{massHeAxis}, {ptZHeAxis}}); + histos.add("tracks/helium/h2TOFmassDeltaHeliumVsPt", "#Delta M (He) vs #it{p}_{T}; #Delta M (He); #it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {{massHeAxis}, {ptZHeAxis}}); + histos.add("tracks/helium/h2TOFmassDeltaantiHeliumVsPt", "#Delta M (#bar{He}) vs #it{p}_{T}; #Delta M (#bar{He}); #it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {{massHeAxis}, {ptZHeAxis}}); if (enableBetaCut) { - histos.add("tracks/helium/h2TOFmass2antiHeliumVsPt_BetaCut", "#Delta M^{2} (#bar{He}) vs #it{p}_{T}; #Delta M^{2} (#bar{He}); #it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {{massHeAxis}, {250, 0., 5.}}); - histos.add("tracks/helium/h2TOFmass2HeliumVsPt_BetaCut", "#Delta M^{2} (He) vs #it{p}_{T}; #Delta M^{2} (He); #it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {{massHeAxis}, {250, 0., 5.}}); + histos.add("tracks/helium/h2TOFmass2antiHeliumVsPt_BetaCut", "#Delta M^{2} (#bar{He}) vs #it{p}_{T}; #Delta M^{2} (#bar{He}); #it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {{massHeAxis}, {ptZHeAxis}}); + histos.add("tracks/helium/h2TOFmass2HeliumVsPt_BetaCut", "#Delta M^{2} (He) vs #it{p}_{T}; #Delta M^{2} (He); #it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {{massHeAxis}, {ptZHeAxis}}); } } // TOF EvTime Splitting plots @@ -1291,9 +1372,17 @@ struct LFNucleiBATask { histos.add("spectraGen/deuteron/histGenPtDPrim", "generated particles", HistType::kTH1F, {ptAxis}); histos.add("spectraGen/deuteron/histGenPtDSec", "generated particles", HistType::kTH1F, {ptAxis}); histos.add("spectraGen/deuteron/histSecTransportPtD", "generated particles", HistType::kTH1F, {ptAxis}); - histos.add("tracks/deuteron/histAntiDPtShiftRec", "histAntiDPtShiftRec", HistType::kTH1F, {ptAxis}); - histos.add("tracks/deuteron/histAntiDPtRec", "histAntiDPtRec", HistType::kTH1F, {ptAxis}); - histos.add("spectraGen/histPtShiftCorrection", "histPtShiftCorrection", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); + histos.add("tracks/deuteron/histAntiDeuteronPtShiftRec", "histAntiDeuteronPtShiftRec", HistType::kTH1F, {ptAxis}); + histos.add("tracks/deuteron/histAntiDeuteronPtRec", "histAntiDeuteronPtRec", HistType::kTH1F, {ptAxis}); + histos.add("spectraGen/deuteron/histAntiDeuteronPtShiftCorrection", "histAntiDeuteronPtShiftCorrection", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); + histos.add("spectraGen/deuteron/histAntiDeuteronPtShift", "PtReco-PtGen vs PtReco", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); + histos.add("spectraGen/deuteron/histAntiDeuteronPtShiftVsEta", "PtReco-PtGen vs #eta", HistType::kTH2F, {{200, -2.f, 2.f}, {400, -4.f, 4.f}}); + + histos.add("tracks/deuteron/histDeuteronPtShiftRec", "histDeuteronPtShiftRec", HistType::kTH1F, {ptAxis}); + histos.add("tracks/deuteron/histDeuteronPtRec", "histDeuteronPtRec", HistType::kTH1F, {ptAxis}); + histos.add("spectraGen/deuteron/histDeuteronPtShiftCorrection", "histDeuteronPtShiftCorrection", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); + histos.add("spectraGen/deuteron/histDeuteronPtShift", "PtReco-PtGen vs PtReco", HistType::kTH2F, {{800, 0.f, 8.f}, {400, -4.f, 4.f}}); + histos.add("spectraGen/deuteron/histDeuteronPtShiftVsEta", "PtReco-PtGen vs #eta", HistType::kTH2F, {{200, -2.f, 2.f}, {400, -4.f, 4.f}}); histos.add("spectraGen/deuteron/histGenPtantiD", "generated particles", HistType::kTH1F, {ptAxis}); histos.add("spectraGen/deuteron/histGenPtantiDPrim", "generated particles", HistType::kTH1F, {ptAxis}); @@ -1312,15 +1401,15 @@ struct LFNucleiBATask { histos.add("spectraGen/triton/histSecTransportPtantiT", "generated particles", HistType::kTH1F, {ptAxis}); } if (enableHe) { - histos.add("spectraGen/helium/histGenPtHe", "generated particles", HistType::kTH1F, {ptAxis}); - histos.add("spectraGen/helium/histGenPtHePrim", "generated particles", HistType::kTH1F, {ptAxis}); - histos.add("spectraGen/helium/histGenPtHeSec", "generated particles", HistType::kTH1F, {ptAxis}); - histos.add("spectraGen/helium/histSecTransportPtHe", "generated particles", HistType::kTH1F, {ptAxis}); - - histos.add("spectraGen/helium/histGenPtantiHe", "generated particles", HistType::kTH1F, {ptAxis}); - histos.add("spectraGen/helium/histGenPtantiHePrim", "generated particles", HistType::kTH1F, {ptAxis}); - histos.add("spectraGen/helium/histGenPtantiHeSec", "generated particles", HistType::kTH1F, {ptAxis}); - histos.add("spectraGen/helium/histSecTransportPtantiHe", "generated particles", HistType::kTH1F, {ptAxis}); + histos.add("spectraGen/helium/histGenPtHe", "generated particles", HistType::kTH1F, {ptHeAxis}); + histos.add("spectraGen/helium/histGenPtHePrim", "generated particles", HistType::kTH1F, {ptHeAxis}); + histos.add("spectraGen/helium/histGenPtHeSec", "generated particles", HistType::kTH1F, {ptHeAxis}); + histos.add("spectraGen/helium/histSecTransportPtHe", "generated particles", HistType::kTH1F, {ptHeAxis}); + + histos.add("spectraGen/helium/histGenPtantiHe", "generated particles", HistType::kTH1F, {ptHeAxis}); + histos.add("spectraGen/helium/histGenPtantiHePrim", "generated particles", HistType::kTH1F, {ptHeAxis}); + histos.add("spectraGen/helium/histGenPtantiHeSec", "generated particles", HistType::kTH1F, {ptHeAxis}); + histos.add("spectraGen/helium/histSecTransportPtantiHe", "generated particles", HistType::kTH1F, {ptHeAxis}); } if (enableAl) { histos.add("spectraGen/alpha/histGenPtAl", "generated particles", HistType::kTH1F, {ptAxis}); @@ -1365,7 +1454,7 @@ struct LFNucleiBATask { // if (event.posZ() < cfgLowCutVertex || event.posZ() > cfgHighCutVertex) // return; - float gamma = 0., massTOF = 0., massTOFhe = 0., massTOFantihe = 0., heTPCmomentum = 0.f, antiheTPCmomentum = 0.f, heP = 0.f, antiheP = 0.f, hePt = 0.f, antihePt = 0.f, antiDPt = 0.f; + float gamma = 0., massTOF = 0., massTOFhe = 0., massTOFantihe = 0., heTPCmomentum = 0.f, antiheTPCmomentum = 0.f, heP = 0.f, antiheP = 0.f, hePt = 0.f, antihePt = 0.f, antiDPt = 0.f, DPt = 0.f; bool isTriton = kFALSE; bool prRapCut = kFALSE; bool deRapCut = kFALSE; @@ -1470,6 +1559,24 @@ struct LFNucleiBATask { break; } + if (enablePtShiftD && !fShiftD) { + fShiftD = new TF1("fShiftD", "[0] * TMath::Exp([1] + [2] * x) + [3] + [4] * x", 0.f, 8.f); + auto par = (std::vector)parShiftPtD; + fShiftD->SetParameters(par[0], par[1], par[2], par[3], par[4]); + } + + switch (DeuteronPt) { + case 0: + if (enablePtShiftD && fShiftD) { + auto shiftD = fShiftD->Eval(track.pt()); + DPt = track.pt() - shiftD; + } + break; + case 1: + DPt = track.pt(); + break; + } + switch (helium3Pt) { case 0: hePt = track.pt(); @@ -1550,10 +1657,10 @@ struct LFNucleiBATask { continue; if (track.sign() > 0) { if (enableCentrality) - histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtDeuteronVsMult"), antiDPt, track.dcaXY(), event.centFT0M()); + histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtDeuteronVsMult"), DPt, track.dcaXY(), event.centFT0M()); else - histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtDeuteron"), antiDPt, track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtDeuteron"), antiDPt, track.dcaZ()); + histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtDeuteron"), DPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtDeuteron"), DPt, track.dcaZ()); } else { if (enableCentrality) histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtantiDeuteronVsMult"), antiDPt, track.dcaXY(), event.centFT0M()); @@ -1579,9 +1686,17 @@ struct LFNucleiBATask { if (track.sign() > 0) { histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtHelium"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtHelium"), hePt, track.dcaZ()); + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsPtHelium"), hePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAzVsPtHelium"), hePt, track.dcaZ()); + } } else { histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtantiHelium"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtantiHelium"), antihePt, track.dcaZ()); + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsPtantiHelium"), antihePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAzVsPtantiHelium"), antihePt, track.dcaZ()); + } } } } @@ -1600,19 +1715,26 @@ struct LFNucleiBATask { if constexpr (IsMC) { bool isPhysPrim = false; bool isProdByGen = false; + bool isWeakDecay = false; // PID int pdgCode = 0; + // gen Pt + float genPt = 0; if constexpr (IsFilteredData) { isPhysPrim = track.isPhysicalPrimary(); isProdByGen = track.producedByGenerator(); + isWeakDecay = track.getProcess() == 4; pdgCode = track.pdgCode(); + genPt = TMath::Sqrt(TMath::Power(track.px(), 2) + TMath::Power(track.py(), 2)); + } else { if (!track.has_mcParticle()) { continue; } isPhysPrim = track.mcParticle().isPhysicalPrimary(); isProdByGen = track.mcParticle().producedByGenerator(); + isWeakDecay = track.mcParticle().getProcess() == 4; pdgCode = track.mcParticle().pdgCode(); } switch (pdgCode) { @@ -1628,12 +1750,15 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/proton/dca/before/hDCAzVsPtProtonTruePrim"), track.pt(), track.dcaZ()); } if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/proton/dca/before/hDCAxyVsPtProtonTrueSec"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/proton/dca/before/hDCAzVsPtProtonTrueSec"), track.pt(), track.dcaZ()); + // } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/proton/dca/before/hDCAxyVsPtProtonTrueTransport"), track.pt(), track.dcaXY()); histos.fill(HIST("tracks/proton/dca/before/hDCAzVsPtProtonTrueTransport"), track.pt(), track.dcaZ()); + if (isWeakDecay) { + histos.fill(HIST("tracks/proton/dca/before/hDCAxyVsPtProtonTrueSec"), track.pt(), track.dcaXY()); + histos.fill(HIST("tracks/proton/dca/before/hDCAzVsPtProtonTrueSec"), track.pt(), track.dcaZ()); + } } } break; @@ -1647,56 +1772,67 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/proton/dca/before/hDCAzVsPtantiProtonTruePrim"), track.pt(), track.dcaZ()); } if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/proton/dca/before/hDCAxyVsPtantiProtonTrueSec"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/proton/dca/before/hDCAzVsPtantiProtonTrueSec"), track.pt(), track.dcaZ()); + // } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/proton/dca/before/hDCAxyVsPtantiProtonTrueTransport"), track.pt(), track.dcaXY()); histos.fill(HIST("tracks/proton/dca/before/hDCAzVsPtantiProtonTrueTransport"), track.pt(), track.dcaZ()); + if (isWeakDecay) { + histos.fill(HIST("tracks/proton/dca/before/hDCAxyVsPtantiProtonTrueSec"), track.pt(), track.dcaXY()); + histos.fill(HIST("tracks/proton/dca/before/hDCAzVsPtantiProtonTrueSec"), track.pt(), track.dcaZ()); + } } } break; case PDGDeuteron: if (enableDe) { - histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtDeuteronTrue"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtDeuteronTrue"), track.pt(), track.dcaZ()); + histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtDeuteronTrue"), DPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtDeuteronTrue"), DPt, track.dcaZ()); if (isPhysPrim) { - histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtDeuteronTruePrim"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtDeuteronTruePrim"), track.pt(), track.dcaZ()); - } - if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtDeuteronTrueSec"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtDeuteronTrueSec"), track.pt(), track.dcaZ()); + histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtDeuteronTruePrim"), DPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtDeuteronTruePrim"), DPt, track.dcaZ()); + if constexpr (IsFilteredData) { + histos.fill(HIST("spectraGen/deuteron/histDeuteronPtShift"), track.pt(), track.pt() - genPt); + histos.fill(HIST("spectraGen/deuteron/histDeuteronPtShiftVsEta"), track.eta(), track.pt() - genPt); + // histos.fill(HIST("spectraGen/histPShift"), track.p(), track.p() - track.mcParticle().p()); + histos.fill(HIST("tracks/deuteron/histDeuteronPtShiftRec"), DPt); + histos.fill(HIST("tracks/deuteron/histDeuteronPtRec"), track.pt()); + histos.fill(HIST("spectraGen/deuteron/histDeuteronPtShiftCorrection"), DPt, DPt - genPt); + } } if (!isPhysPrim && !isProdByGen) { - histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtDeuteronTrueTransport"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtDeuteronTrueTransport"), track.pt(), track.dcaZ()); + histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtDeuteronTrueTransport"), DPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtDeuteronTrueTransport"), DPt, track.dcaZ()); + if (isWeakDecay) { + histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtDeuteronTrueSec"), DPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtDeuteronTrueSec"), DPt, track.dcaZ()); + } } } break; case -PDGDeuteron: if (enableDe) { - histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtantiDeuteronTrue"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtantiDeuteronTrue"), track.pt(), track.dcaZ()); + histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtantiDeuteronTrue"), antiDPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtantiDeuteronTrue"), antiDPt, track.dcaZ()); if (isPhysPrim) { - histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtantiDeuteronTruePrim"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtantiDeuteronTruePrim"), track.pt(), track.dcaZ()); - if constexpr (!IsFilteredData) { - histos.fill(HIST("spectraGen/histPtShift"), track.pt(), track.pt() - track.mcParticle().pt()); - histos.fill(HIST("spectraGen/histPtShiftVsEta"), track.eta(), track.pt() - track.mcParticle().pt()); - histos.fill(HIST("spectraGen/histPShift"), track.p(), track.p() - track.mcParticle().p()); - histos.fill(HIST("tracks/deuteron/histAntiDPtShiftRec"), antiDPt); - histos.fill(HIST("tracks/deuteron/histAntiDPtRec"), track.pt()); - histos.fill(HIST("spectraGen/histPtShiftCorrection"), antiDPt, antiDPt - track.mcParticle().pt()); + histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtantiDeuteronTruePrim"), antiDPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtantiDeuteronTruePrim"), antiDPt, track.dcaZ()); + if constexpr (IsFilteredData) { + histos.fill(HIST("spectraGen/deuteron/histAntiDeuteronPtShift"), track.pt(), track.pt() - genPt); + histos.fill(HIST("spectraGen/deuteron/histAntiDeuteronPtShiftVsEta"), track.eta(), track.pt() - genPt); + // histos.fill(HIST("spectraGen/histPShift"), track.p(), track.p() - track.mcParticle().p()); + histos.fill(HIST("tracks/deuteron/histAntiDeuteronPtShiftRec"), antiDPt); + histos.fill(HIST("tracks/deuteron/histAntiDeuteronPtRec"), track.pt()); + histos.fill(HIST("spectraGen/deuteron/histAntiDeuteronPtShiftCorrection"), antiDPt, antiDPt - genPt); } } - if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtantiDeuteronTrueSec"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtantiDeuteronTrueSec"), track.pt(), track.dcaZ()); - } if (!isPhysPrim && !isProdByGen) { - histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtantiDeuteronTrueTransport"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtantiDeuteronTrueTransport"), track.pt(), track.dcaZ()); + histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtantiDeuteronTrueTransport"), antiDPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtantiDeuteronTrueTransport"), antiDPt, track.dcaZ()); + if (isWeakDecay) { + histos.fill(HIST("tracks/deuteron/dca/before/hDCAxyVsPtantiDeuteronTrueSec"), antiDPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/before/hDCAzVsPtantiDeuteronTrueSec"), antiDPt, track.dcaZ()); + } } } break; @@ -1709,12 +1845,15 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/triton/dca/before/hDCAzVsPtTritonTruePrim"), track.pt(), track.dcaZ()); } if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/triton/dca/before/hDCAxyVsPtTritonTrueSec"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/triton/dca/before/hDCAzVsPtTritonTrueSec"), track.pt(), track.dcaZ()); + // } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/triton/dca/before/hDCAxyVsPtTritonTrueTransport"), track.pt(), track.dcaXY()); histos.fill(HIST("tracks/triton/dca/before/hDCAzVsPtTritonTrueTransport"), track.pt(), track.dcaZ()); + if (isWeakDecay) { + histos.fill(HIST("tracks/triton/dca/before/hDCAxyVsPtTritonTrueSec"), track.pt(), track.dcaXY()); + histos.fill(HIST("tracks/triton/dca/before/hDCAzVsPtTritonTrueSec"), track.pt(), track.dcaZ()); + } } } break; @@ -1727,12 +1866,15 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/triton/dca/before/hDCAzVsPtantiTritonTruePrim"), track.pt(), track.dcaZ()); } if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/triton/dca/before/hDCAxyVsPtantiTritonTrueSec"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/triton/dca/before/hDCAzVsPtantiTritonTrueSec"), track.pt(), track.dcaZ()); + // } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/triton/dca/before/hDCAxyVsPtantiTritonTrueTransport"), track.pt(), track.dcaXY()); histos.fill(HIST("tracks/triton/dca/before/hDCAzVsPtantiTritonTrueTransport"), track.pt(), track.dcaZ()); + if (isWeakDecay) { + histos.fill(HIST("tracks/triton/dca/before/hDCAxyVsPtantiTritonTrueSec"), track.pt(), track.dcaXY()); + histos.fill(HIST("tracks/triton/dca/before/hDCAzVsPtantiTritonTrueSec"), track.pt(), track.dcaZ()); + } } } break; @@ -1740,6 +1882,11 @@ struct LFNucleiBATask { if (enableHe) { histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtHeliumTrue"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtHeliumTrue"), hePt, track.dcaZ()); + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsPtHeliumTrue"), hePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAzVsPtHeliumTrue"), hePt, track.dcaZ()); + } + if (isPhysPrim) { if constexpr (!IsFilteredData) { histos.fill(HIST("spectraGen/helium/histPtGenHe"), std::abs(track.mcParticle().pt())); @@ -1754,14 +1901,34 @@ struct LFNucleiBATask { } histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtHeliumTruePrim"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtHeliumTruePrim"), hePt, track.dcaZ()); + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsPtHeliumTruePrim"), hePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAzVsPtHeliumTruePrim"), hePt, track.dcaZ()); + } } if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtHeliumTrueSec"), hePt, track.dcaXY()); - histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtHeliumTrueSec"), hePt, track.dcaZ()); + // + if (track.hasTOF() && doTOFplots) { + // + } } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtHeliumTrueTransport"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtHeliumTrueTransport"), hePt, track.dcaZ()); + + if (isWeakDecay) { + histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtHeliumTrueSec"), hePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtHeliumTrueSec"), hePt, track.dcaZ()); + } + + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsPtHeliumTrueTransport"), hePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAzVsPtHeliumTrueTransport"), hePt, track.dcaZ()); + if (isWeakDecay) { + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsPtHeliumTrueSec"), hePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAzVsPtHeliumTrueSec"), hePt, track.dcaZ()); + } + } } } break; @@ -1769,6 +1936,10 @@ struct LFNucleiBATask { if (enableHe) { histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtantiHeliumTrue"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtantiHeliumTrue"), antihePt, track.dcaZ()); + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsPtantiHeliumTrue"), antihePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAzVsPtantiHeliumTrue"), antihePt, track.dcaZ()); + } if (isPhysPrim) { if constexpr (!IsFilteredData) { histos.fill(HIST("spectraGen/helium/histPtGenantiHe"), std::abs(track.mcParticle().pt())); @@ -1783,14 +1954,27 @@ struct LFNucleiBATask { } histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtantiHeliumTruePrim"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtantiHeliumTruePrim"), antihePt, track.dcaZ()); - } - if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtantiHeliumTrueSec"), antihePt, track.dcaXY()); - histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtantiHeliumTrueSec"), antihePt, track.dcaZ()); + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsPtantiHeliumTruePrim"), antihePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAzVsPtantiHeliumTruePrim"), antihePt, track.dcaZ()); + } } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtantiHeliumTrueTransport"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtantiHeliumTrueTransport"), antihePt, track.dcaZ()); + if (isWeakDecay) { + histos.fill(HIST("tracks/helium/dca/before/hDCAxyVsPtantiHeliumTrueSec"), antihePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/before/hDCAzVsPtantiHeliumTrueSec"), antihePt, track.dcaZ()); + } + + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsPtantiHeliumTrueTransport"), antihePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAzVsPtantiHeliumTrueTransport"), antihePt, track.dcaZ()); + if (isWeakDecay) { + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAxyVsPtantiHeliumTrueSec"), antihePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/before/TOF/hDCAzVsPtantiHeliumTrueSec"), antihePt, track.dcaZ()); + } + } } } break; @@ -1803,12 +1987,15 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/alpha/dca/before/hDCAzVsPtAlphaTruePrim"), track.pt(), track.dcaZ()); } if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/alpha/dca/before/hDCAxyVsPtAlphaTrueSec"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/alpha/dca/before/hDCAzVsPtAlphaTrueSec"), track.pt(), track.dcaZ()); + // } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/alpha/dca/before/hDCAxyVsPtAlphaTrueTransport"), track.pt(), track.dcaXY()); histos.fill(HIST("tracks/alpha/dca/before/hDCAzVsPtAlphaTrueTransport"), track.pt(), track.dcaZ()); + if (isWeakDecay) { + histos.fill(HIST("tracks/alpha/dca/before/hDCAxyVsPtAlphaTrueSec"), track.pt(), track.dcaXY()); + histos.fill(HIST("tracks/alpha/dca/before/hDCAzVsPtAlphaTrueSec"), track.pt(), track.dcaZ()); + } } } break; @@ -1821,12 +2008,15 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/alpha/dca/before/hDCAzVsPtantiAlphaTruePrim"), track.pt(), track.dcaZ()); } if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/alpha/dca/before/hDCAxyVsPtantiAlphaTrueSec"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/alpha/dca/before/hDCAzVsPtantiAlphaTrueSec"), track.pt(), track.dcaZ()); + // } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/alpha/dca/before/hDCAxyVsPtantiAlphaTrueTransport"), track.pt(), track.dcaXY()); histos.fill(HIST("tracks/alpha/dca/before/hDCAzVsPtantiAlphaTrueTransport"), track.pt(), track.dcaZ()); + if (isWeakDecay) { + histos.fill(HIST("tracks/alpha/dca/before/hDCAxyVsPtantiAlphaTrueSec"), track.pt(), track.dcaXY()); + histos.fill(HIST("tracks/alpha/dca/before/hDCAzVsPtantiAlphaTrueSec"), track.pt(), track.dcaZ()); + } } } break; @@ -1876,11 +2066,11 @@ struct LFNucleiBATask { if (usenITSLayer && !itsClusterMap.test(nITSLayer)) continue; if (track.sign() > 0) { - histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtDeuteron"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtDeuteron"), track.pt(), track.dcaZ()); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtDeuteron"), DPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtDeuteron"), DPt, track.dcaZ()); } else { - histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtantiDeuteron"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtantiDeuteron"), track.pt(), track.dcaZ()); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtantiDeuteron"), antiDPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtantiDeuteron"), antiDPt, track.dcaZ()); } } } @@ -1900,9 +2090,17 @@ struct LFNucleiBATask { if (track.sign() > 0) { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtHelium"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtHelium"), hePt, track.dcaZ()); + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtHelium"), hePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtHelium"), hePt, track.dcaZ()); + } } else { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtantiHelium"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtantiHelium"), antihePt, track.dcaZ()); + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtantiHelium"), antihePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtantiHelium"), antihePt, track.dcaZ()); + } } } } @@ -2005,23 +2203,23 @@ struct LFNucleiBATask { } if (enableDe && deRapCut) { if (enableExpSignalTPC) - histos.fill(HIST("tracks/deuteron/h2DeuteronTPCExpSignalDiffVsPt"), track.pt(), track.tpcExpSignalDiffDe()); + histos.fill(HIST("tracks/deuteron/h2DeuteronTPCExpSignalDiffVsPt"), DPt, track.tpcExpSignalDiffDe()); switch (useHasTRDConfig) { case 0: if (enableCentrality) - histos.fill(HIST("tracks/deuteron/h3DeuteronVspTNSigmaTPCVsMult"), antiDPt, track.tpcNSigmaDe(), event.centFT0M()); + histos.fill(HIST("tracks/deuteron/h3DeuteronVspTNSigmaTPCVsMult"), DPt, track.tpcNSigmaDe(), event.centFT0M()); else - histos.fill(HIST("tracks/deuteron/h2DeuteronVspTNSigmaTPC"), antiDPt, track.tpcNSigmaDe()); + histos.fill(HIST("tracks/deuteron/h2DeuteronVspTNSigmaTPC"), DPt, track.tpcNSigmaDe()); break; case 1: if (track.hasTRD()) { - histos.fill(HIST("tracks/deuteron/h2DeuteronVspTNSigmaTPC"), track.pt(), track.tpcNSigmaDe()); + histos.fill(HIST("tracks/deuteron/h2DeuteronVspTNSigmaTPC"), DPt, track.tpcNSigmaDe()); } break; case 2: if (!track.hasTRD()) { - histos.fill(HIST("tracks/deuteron/h2DeuteronVspTNSigmaTPC"), track.pt(), track.tpcNSigmaDe()); + histos.fill(HIST("tracks/deuteron/h2DeuteronVspTNSigmaTPC"), DPt, track.tpcNSigmaDe()); } break; } @@ -2062,7 +2260,7 @@ struct LFNucleiBATask { } if (enableDe && deRapCut) { if (enableExpSignalTPC) - histos.fill(HIST("tracks/deuteron/h2antiDeuteronTPCExpSignalDiffVsPt"), track.pt(), track.tpcExpSignalDiffDe()); + histos.fill(HIST("tracks/deuteron/h2antiDeuteronTPCExpSignalDiffVsPt"), antiDPt, track.tpcExpSignalDiffDe()); switch (useHasTRDConfig) { case 0: @@ -2073,12 +2271,12 @@ struct LFNucleiBATask { break; case 1: if (track.hasTRD()) { - histos.fill(HIST("tracks/deuteron/h2antiDeuteronVspTNSigmaTPC"), track.pt(), track.tpcNSigmaDe()); + histos.fill(HIST("tracks/deuteron/h2antiDeuteronVspTNSigmaTPC"), antiDPt, track.tpcNSigmaDe()); } break; case 2: if (!track.hasTRD()) { - histos.fill(HIST("tracks/deuteron/h2antiDeuteronVspTNSigmaTPC"), track.pt(), track.tpcNSigmaDe()); + histos.fill(HIST("tracks/deuteron/h2antiDeuteronVspTNSigmaTPC"), antiDPt, track.tpcNSigmaDe()); } break; } @@ -2125,21 +2323,21 @@ struct LFNucleiBATask { if (enableDe && deRapCut) { switch (useHasTRDConfig) { case 0: - histos.fill(HIST("tracks/deuteron/h2DeuteronVspTNSigmaTOF"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("tracks/deuteron/h2DeuteronVspTNSigmaTOF"), DPt, track.tofNSigmaDe()); break; case 1: if (track.hasTRD()) { - histos.fill(HIST("tracks/deuteron/h2DeuteronVspTNSigmaTOF"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("tracks/deuteron/h2DeuteronVspTNSigmaTOF"), DPt, track.tofNSigmaDe()); } break; case 2: if (!track.hasTRD()) { - histos.fill(HIST("tracks/deuteron/h2DeuteronVspTNSigmaTOF"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("tracks/deuteron/h2DeuteronVspTNSigmaTOF"), DPt, track.tofNSigmaDe()); } break; } if (enableExpSignalTOF) - histos.fill(HIST("tracks/deuteron/h2DeuteronTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("tracks/deuteron/h2DeuteronTOFExpSignalDiffVsPt"), DPt, track.tofExpSignalDiffDe()); } if (enableHe && heRapCut) { histos.fill(HIST("tracks/helium/h2HeliumVspTNSigmaTOF"), hePt, track.tofNSigmaHe()); @@ -2151,12 +2349,12 @@ struct LFNucleiBATask { if (enablePr) histos.fill(HIST("tracks/evtime/ft0tof/proton/h2ProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); if (enableDe) - histos.fill(HIST("tracks/evtime/ft0tof/deuteron/h2DeuteronVspTNSigmaTOF"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("tracks/evtime/ft0tof/deuteron/h2DeuteronVspTNSigmaTOF"), DPt, track.tofNSigmaDe()); if (enableExpSignalTOF) { if (enablePr) histos.fill(HIST("tracks/evtime/ft0tof/proton/h2ProtonTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffPr()); if (enableDe) - histos.fill(HIST("tracks/evtime/ft0tof/deuteron/h2DeuteronTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("tracks/evtime/ft0tof/deuteron/h2DeuteronTOFExpSignalDiffVsPt"), DPt, track.tofExpSignalDiffDe()); } if (enablePr) histos.fill(HIST("tracks/evtime/ft0tof/proton/h3ProtonNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaPr(), track.tofNSigmaPr(), track.pt()); @@ -2166,16 +2364,16 @@ struct LFNucleiBATask { if (enablePr) histos.fill(HIST("debug/evtime/ft0tof/proton/h2ProtonVspTNSigmaTPC_BetaCut"), track.pt(), track.tpcNSigmaPr()); if (enableDe) - histos.fill(HIST("debug/evtime/ft0tof/deuteron/h2DeuteronVspTNSigmaTPC_BetaCut"), track.pt(), track.tpcNSigmaDe()); + histos.fill(HIST("debug/evtime/ft0tof/deuteron/h2DeuteronVspTNSigmaTPC_BetaCut"), DPt, track.tpcNSigmaDe()); if (enablePr) histos.fill(HIST("debug/evtime/ft0tof/proton/h2ProtonVspTNSigmaTOF_BetaCut"), track.pt(), track.tofNSigmaPr()); if (enableDe) - histos.fill(HIST("debug/evtime/ft0tof/deuteron/h2DeuteronVspTNSigmaTOF_BetaCut"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("debug/evtime/ft0tof/deuteron/h2DeuteronVspTNSigmaTOF_BetaCut"), DPt, track.tofNSigmaDe()); if (enableExpSignalTOF) { histos.fill(HIST("debug/evtime/ft0tof/proton/h2ProtonTOFExpSignalDiffVsPt_BetaCut"), track.pt(), track.tofExpSignalDiffPr()); if (enableDe) - histos.fill(HIST("debug/evtime/ft0tof/deuteron/h2DeuteronTOFExpSignalDiffVsPt_BetaCut"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("debug/evtime/ft0tof/deuteron/h2DeuteronTOFExpSignalDiffVsPt_BetaCut"), DPt, track.tofExpSignalDiffDe()); } } @@ -2183,32 +2381,32 @@ struct LFNucleiBATask { if (enablePr) histos.fill(HIST("tracks/evtime/ft0/proton/h2ProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); if (enableDe) - histos.fill(HIST("tracks/evtime/ft0/deuteron/h2DeuteronVspTNSigmaTOF"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("tracks/evtime/ft0/deuteron/h2DeuteronVspTNSigmaTOF"), DPt, track.tofNSigmaDe()); if (enableExpSignalTOF) { if (enablePr) histos.fill(HIST("tracks/evtime/ft0/proton/h2ProtonTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffPr()); if (enableDe) - histos.fill(HIST("tracks/evtime/ft0/deuteron/h2DeuteronTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("tracks/evtime/ft0/deuteron/h2DeuteronTOFExpSignalDiffVsPt"), DPt, track.tofExpSignalDiffDe()); } if (enablePr) histos.fill(HIST("tracks/evtime/ft0/proton/h3ProtonNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaPr(), track.tofNSigmaPr(), track.pt()); if (enableDe) - histos.fill(HIST("tracks/evtime/ft0/deuteron/h3DeuteronNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaDe(), track.tofNSigmaDe(), track.pt()); + histos.fill(HIST("tracks/evtime/ft0/deuteron/h3DeuteronNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaDe(), track.tofNSigmaDe(), DPt); if (enableDebug && (track.beta() > betaCut)) { if (enablePr) histos.fill(HIST("debug/evtime/ft0/proton/h2ProtonVspTNSigmaTPC_BetaCut"), track.pt(), track.tpcNSigmaPr()); if (enableDe) - histos.fill(HIST("debug/evtime/ft0/deuteron/h2DeuteronVspTNSigmaTPC_BetaCut"), track.pt(), track.tpcNSigmaDe()); + histos.fill(HIST("debug/evtime/ft0/deuteron/h2DeuteronVspTNSigmaTPC_BetaCut"), DPt, track.tpcNSigmaDe()); if (enablePr) histos.fill(HIST("debug/evtime/ft0/proton/h2ProtonVspTNSigmaTOF_BetaCut"), track.pt(), track.tofNSigmaPr()); if (enableDe) - histos.fill(HIST("debug/evtime/ft0/deuteron/h2DeuteronVspTNSigmaTOF_BetaCut"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("debug/evtime/ft0/deuteron/h2DeuteronVspTNSigmaTOF_BetaCut"), DPt, track.tofNSigmaDe()); if (enableExpSignalTOF) { if (enablePr) histos.fill(HIST("debug/evtime/ft0/proton/h2ProtonTOFExpSignalDiffVsPt_BetaCut"), track.pt(), track.tofExpSignalDiffPr()); if (enableDe) - histos.fill(HIST("debug/evtime/ft0/deuteron/h2DeuteronTOFExpSignalDiffVsPt_BetaCut"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("debug/evtime/ft0/deuteron/h2DeuteronTOFExpSignalDiffVsPt_BetaCut"), DPt, track.tofExpSignalDiffDe()); } } @@ -2216,33 +2414,33 @@ struct LFNucleiBATask { if (enablePr) histos.fill(HIST("tracks/evtime/tof/proton/h2ProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); if (enableDe) - histos.fill(HIST("tracks/evtime/tof/deuteron/h2DeuteronVspTNSigmaTOF"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("tracks/evtime/tof/deuteron/h2DeuteronVspTNSigmaTOF"), DPt, track.tofNSigmaDe()); if (enableExpSignalTOF) { if (enablePr) histos.fill(HIST("tracks/evtime/tof/proton/h2ProtonTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffPr()); if (enableDe) - histos.fill(HIST("tracks/evtime/tof/deuteron/h2DeuteronTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("tracks/evtime/tof/deuteron/h2DeuteronTOFExpSignalDiffVsPt"), DPt, track.tofExpSignalDiffDe()); } if (enablePr) histos.fill(HIST("tracks/evtime/tof/proton/h3ProtonNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaPr(), track.tofNSigmaPr(), track.pt()); if (enableDe) - histos.fill(HIST("tracks/evtime/tof/deuteron/h3DeuteronNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaDe(), track.tofNSigmaDe(), track.pt()); + histos.fill(HIST("tracks/evtime/tof/deuteron/h3DeuteronNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaDe(), track.tofNSigmaDe(), DPt); if (enableDebug && (track.beta() > betaCut)) { if (enablePr) histos.fill(HIST("debug/evtime/tof/proton/h2ProtonVspTNSigmaTPC_BetaCut"), track.pt(), track.tpcNSigmaPr()); if (enableDe) - histos.fill(HIST("debug/evtime/tof/deuteron/h2DeuteronVspTNSigmaTPC_BetaCut"), track.pt(), track.tpcNSigmaDe()); + histos.fill(HIST("debug/evtime/tof/deuteron/h2DeuteronVspTNSigmaTPC_BetaCut"), DPt, track.tpcNSigmaDe()); if (enablePr) histos.fill(HIST("debug/evtime/tof/proton/h2ProtonVspTNSigmaTOF_BetaCut"), track.pt(), track.tofNSigmaPr()); if (enableDe) - histos.fill(HIST("debug/evtime/tof/deuteron/h2DeuteronVspTNSigmaTOF_BetaCut"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("debug/evtime/tof/deuteron/h2DeuteronVspTNSigmaTOF_BetaCut"), DPt, track.tofNSigmaDe()); if (enableExpSignalTOF) { if (enablePr) histos.fill(HIST("debug/evtime/tof/proton/h2ProtonTOFExpSignalDiffVsPt_BetaCut"), track.pt(), track.tofExpSignalDiffPr()); if (enableDe) - histos.fill(HIST("debug/evtime/tof/deuteron/h2DeuteronTOFExpSignalDiffVsPt_BetaCut"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("debug/evtime/tof/deuteron/h2DeuteronTOFExpSignalDiffVsPt_BetaCut"), DPt, track.tofExpSignalDiffDe()); } } @@ -2250,33 +2448,33 @@ struct LFNucleiBATask { if (enablePr) histos.fill(HIST("tracks/evtime/fill/proton/h2ProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); if (enableDe) - histos.fill(HIST("tracks/evtime/fill/deuteron/h2DeuteronVspTNSigmaTOF"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("tracks/evtime/fill/deuteron/h2DeuteronVspTNSigmaTOF"), DPt, track.tofNSigmaDe()); if (enableExpSignalTOF) { if (enablePr) histos.fill(HIST("tracks/evtime/fill/proton/h2ProtonTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffPr()); if (enableDe) - histos.fill(HIST("tracks/evtime/fill/deuteron/h2DeuteronTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("tracks/evtime/fill/deuteron/h2DeuteronTOFExpSignalDiffVsPt"), DPt, track.tofExpSignalDiffDe()); } if (enablePr) histos.fill(HIST("tracks/evtime/fill/proton/h3ProtonNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaPr(), track.tofNSigmaPr(), track.pt()); if (enableDe) - histos.fill(HIST("tracks/evtime/fill/deuteron/h3DeuteronNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaDe(), track.tofNSigmaDe(), track.pt()); + histos.fill(HIST("tracks/evtime/fill/deuteron/h3DeuteronNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaDe(), track.tofNSigmaDe(), DPt); if (enableDebug && (track.beta() > betaCut)) { if (enablePr) histos.fill(HIST("debug/evtime/fill/proton/h2ProtonVspTNSigmaTPC_BetaCut"), track.pt(), track.tpcNSigmaPr()); if (enableDe) - histos.fill(HIST("debug/evtime/fill/deuteron/h2DeuteronVspTNSigmaTPC_BetaCut"), track.pt(), track.tpcNSigmaDe()); + histos.fill(HIST("debug/evtime/fill/deuteron/h2DeuteronVspTNSigmaTPC_BetaCut"), DPt, track.tpcNSigmaDe()); if (enablePr) histos.fill(HIST("debug/evtime/fill/proton/h2ProtonVspTNSigmaTOF_BetaCut"), track.pt(), track.tofNSigmaPr()); if (enableDe) - histos.fill(HIST("debug/evtime/fill/deuteron/h2DeuteronVspTNSigmaTOF_BetaCut"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("debug/evtime/fill/deuteron/h2DeuteronVspTNSigmaTOF_BetaCut"), DPt, track.tofNSigmaDe()); if (enableExpSignalTOF) { if (enablePr) histos.fill(HIST("debug/evtime/fill/proton/h2ProtonTOFExpSignalDiffVsPt_BetaCut"), track.pt(), track.tofExpSignalDiffPr()); if (enableDe) - histos.fill(HIST("debug/evtime/fill/deuteron/h2DeuteronTOFExpSignalDiffVsPt_BetaCut"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("debug/evtime/fill/deuteron/h2DeuteronTOFExpSignalDiffVsPt_BetaCut"), DPt, track.tofExpSignalDiffDe()); } } } @@ -2305,21 +2503,21 @@ struct LFNucleiBATask { if (enableDe && deRapCut) { switch (useHasTRDConfig) { case 0: - histos.fill(HIST("tracks/deuteron/h2antiDeuteronVspTNSigmaTOF"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("tracks/deuteron/h2antiDeuteronVspTNSigmaTOF"), antiDPt, track.tofNSigmaDe()); break; case 1: if (track.hasTRD()) { - histos.fill(HIST("tracks/deuteron/h2antiDeuteronVspTNSigmaTOF"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("tracks/deuteron/h2antiDeuteronVspTNSigmaTOF"), antiDPt, track.tofNSigmaDe()); } break; case 2: if (!track.hasTRD()) { - histos.fill(HIST("tracks/deuteron/h2antiDeuteronVspTNSigmaTOF"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("tracks/deuteron/h2antiDeuteronVspTNSigmaTOF"), antiDPt, track.tofNSigmaDe()); } break; } if (enableExpSignalTOF) - histos.fill(HIST("tracks/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("tracks/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt"), antiDPt, track.tofExpSignalDiffDe()); } if (enableHe && heRapCut) { histos.fill(HIST("tracks/helium/h2antiHeliumVspTNSigmaTOF"), antihePt, track.tofNSigmaHe()); @@ -2331,32 +2529,32 @@ struct LFNucleiBATask { if (enablePr) histos.fill(HIST("tracks/evtime/ft0tof/proton/h2antiProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); if (enableDe) - histos.fill(HIST("tracks/evtime/ft0tof/deuteron/h2antiDeuteronVspTNSigmaTOF"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("tracks/evtime/ft0tof/deuteron/h2antiDeuteronVspTNSigmaTOF"), antiDPt, track.tofNSigmaDe()); if (enableExpSignalTOF) { if (enablePr) histos.fill(HIST("tracks/evtime/ft0tof/proton/h2antiProtonTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffPr()); if (enableDe) - histos.fill(HIST("tracks/evtime/ft0tof/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("tracks/evtime/ft0tof/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt"), antiDPt, track.tofExpSignalDiffDe()); } if (enablePr) histos.fill(HIST("tracks/evtime/ft0tof/proton/h3antiProtonNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaPr(), track.tofNSigmaPr(), track.pt()); if (enableDe) - histos.fill(HIST("tracks/evtime/ft0tof/deuteron/h3antiDeuteronNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaDe(), track.tofNSigmaDe(), track.pt()); + histos.fill(HIST("tracks/evtime/ft0tof/deuteron/h3antiDeuteronNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaDe(), track.tofNSigmaDe(), antiDPt); if (enableDebug && (track.beta() > betaCut)) { if (enablePr) histos.fill(HIST("debug/evtime/ft0tof/proton/h2antiProtonVspTNSigmaTPC_BetaCut"), track.pt(), track.tpcNSigmaPr()); if (enableDe) - histos.fill(HIST("debug/evtime/ft0tof/deuteron/h2antiDeuteronVspTNSigmaTPC_BetaCut"), track.pt(), track.tpcNSigmaDe()); + histos.fill(HIST("debug/evtime/ft0tof/deuteron/h2antiDeuteronVspTNSigmaTPC_BetaCut"), antiDPt, track.tpcNSigmaDe()); if (enablePr) histos.fill(HIST("debug/evtime/ft0tof/proton/h2antiProtonVspTNSigmaTOF_BetaCut"), track.pt(), track.tofNSigmaPr()); if (enableDe) - histos.fill(HIST("debug/evtime/ft0tof/deuteron/h2antiDeuteronVspTNSigmaTOF_BetaCut"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("debug/evtime/ft0tof/deuteron/h2antiDeuteronVspTNSigmaTOF_BetaCut"), antiDPt, track.tofNSigmaDe()); if (enableExpSignalTOF) { if (enablePr) histos.fill(HIST("debug/evtime/ft0tof/proton/h2antiProtonTOFExpSignalDiffVsPt_BetaCut"), track.pt(), track.tofExpSignalDiffPr()); if (enableDe) - histos.fill(HIST("debug/evtime/ft0tof/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt_BetaCut"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("debug/evtime/ft0tof/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt_BetaCut"), antiDPt, track.tofExpSignalDiffDe()); } } @@ -2364,28 +2562,28 @@ struct LFNucleiBATask { if (enablePr) histos.fill(HIST("tracks/evtime/ft0/proton/h2antiProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); if (enableDe) - histos.fill(HIST("tracks/evtime/ft0/deuteron/h2antiDeuteronVspTNSigmaTOF"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("tracks/evtime/ft0/deuteron/h2antiDeuteronVspTNSigmaTOF"), antiDPt, track.tofNSigmaDe()); if (enableExpSignalTOF) { if (enablePr) histos.fill(HIST("tracks/evtime/ft0/proton/h2antiProtonTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffPr()); if (enableDe) - histos.fill(HIST("tracks/evtime/ft0/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("tracks/evtime/ft0/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt"), antiDPt, track.tofExpSignalDiffDe()); if (enablePr) histos.fill(HIST("tracks/evtime/ft0/proton/h3antiProtonNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaPr(), track.tofNSigmaPr(), track.pt()); if (enablePr) histos.fill(HIST("debug/evtime/ft0/proton/h2antiProtonVspTNSigmaTPC_BetaCut"), track.pt(), track.tpcNSigmaPr()); if (enableDe) - histos.fill(HIST("debug/evtime/ft0/deuteron/h2antiDeuteronVspTNSigmaTPC_BetaCut"), track.pt(), track.tpcNSigmaDe()); + histos.fill(HIST("debug/evtime/ft0/deuteron/h2antiDeuteronVspTNSigmaTPC_BetaCut"), antiDPt, track.tpcNSigmaDe()); if (enablePr) histos.fill(HIST("debug/evtime/ft0/proton/h2antiProtonVspTNSigmaTOF_BetaCut"), track.pt(), track.tofNSigmaPr()); if (enableDe) - histos.fill(HIST("debug/evtime/ft0/deuteron/h2antiDeuteronVspTNSigmaTOF_BetaCut"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("debug/evtime/ft0/deuteron/h2antiDeuteronVspTNSigmaTOF_BetaCut"), antiDPt, track.tofNSigmaDe()); if (enableExpSignalTOF) { if (enablePr) histos.fill(HIST("debug/evtime/ft0/proton/h2antiProtonTOFExpSignalDiffVsPt_BetaCut"), track.pt(), track.tofExpSignalDiffPr()); if (enableDe) - histos.fill(HIST("debug/evtime/ft0/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt_BetaCut"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("debug/evtime/ft0/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt_BetaCut"), antiDPt, track.tofExpSignalDiffDe()); } } @@ -2393,29 +2591,29 @@ struct LFNucleiBATask { if (enablePr) histos.fill(HIST("tracks/evtime/tof/proton/h2antiProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); if (enableDe) - histos.fill(HIST("tracks/evtime/tof/deuteron/h2antiDeuteronVspTNSigmaTOF"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("tracks/evtime/tof/deuteron/h2antiDeuteronVspTNSigmaTOF"), antiDPt, track.tofNSigmaDe()); if (enableExpSignalTOF) { if (enablePr) histos.fill(HIST("tracks/evtime/tof/proton/h2antiProtonTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffPr()); if (enableDe) - histos.fill(HIST("tracks/evtime/tof/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("tracks/evtime/tof/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt"), antiDPt, track.tofExpSignalDiffDe()); if (enablePr) histos.fill(HIST("tracks/evtime/tof/proton/h3antiProtonNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaPr(), track.tofNSigmaPr(), track.pt()); if (enablePr) histos.fill(HIST("debug/evtime/tof/proton/h2antiProtonVspTNSigmaTPC_BetaCut"), track.pt(), track.tpcNSigmaPr()); if (enableDe) - histos.fill(HIST("debug/evtime/tof/deuteron/h2antiDeuteronVspTNSigmaTPC_BetaCut"), track.pt(), track.tpcNSigmaDe()); + histos.fill(HIST("debug/evtime/tof/deuteron/h2antiDeuteronVspTNSigmaTPC_BetaCut"), antiDPt, track.tpcNSigmaDe()); if (enablePr) histos.fill(HIST("debug/evtime/tof/proton/h2antiProtonVspTNSigmaTOF_BetaCut"), track.pt(), track.tofNSigmaPr()); if (enableDe) - histos.fill(HIST("debug/evtime/tof/deuteron/h2antiDeuteronVspTNSigmaTOF_BetaCut"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("debug/evtime/tof/deuteron/h2antiDeuteronVspTNSigmaTOF_BetaCut"), antiDPt, track.tofNSigmaDe()); if (enableExpSignalTOF) { if (enablePr) histos.fill(HIST("debug/evtime/tof/proton/h2antiProtonTOFExpSignalDiffVsPt_BetaCut"), track.pt(), track.tofExpSignalDiffPr()); if (enableDe) - histos.fill(HIST("debug/evtime/tof/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt_BetaCut"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("debug/evtime/tof/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt_BetaCut"), antiDPt, track.tofExpSignalDiffDe()); } } @@ -2423,29 +2621,29 @@ struct LFNucleiBATask { if (enablePr) histos.fill(HIST("tracks/evtime/fill/proton/h2antiProtonVspTNSigmaTOF"), track.pt(), track.tofNSigmaPr()); if (enableDe) - histos.fill(HIST("tracks/evtime/fill/deuteron/h2antiDeuteronVspTNSigmaTOF"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("tracks/evtime/fill/deuteron/h2antiDeuteronVspTNSigmaTOF"), antiDPt, track.tofNSigmaDe()); if (enableExpSignalTOF) { if (enablePr) histos.fill(HIST("tracks/evtime/fill/proton/h2antiProtonTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffPr()); if (enableDe) - histos.fill(HIST("tracks/evtime/fill/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("tracks/evtime/fill/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt"), antiDPt, track.tofExpSignalDiffDe()); if (enablePr) histos.fill(HIST("tracks/evtime/fill/proton/h3antiProtonNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaPr(), track.tofNSigmaPr(), track.pt()); if (enablePr) histos.fill(HIST("debug/evtime/fill/proton/h2antiProtonVspTNSigmaTPC_BetaCut"), track.pt(), track.tpcNSigmaPr()); if (enableDe) - histos.fill(HIST("debug/evtime/fill/deuteron/h2antiDeuteronVspTNSigmaTPC_BetaCut"), track.pt(), track.tpcNSigmaDe()); + histos.fill(HIST("debug/evtime/fill/deuteron/h2antiDeuteronVspTNSigmaTPC_BetaCut"), antiDPt, track.tpcNSigmaDe()); if (enablePr) histos.fill(HIST("debug/evtime/fill/proton/h2antiProtonVspTNSigmaTOF_BetaCut"), track.pt(), track.tofNSigmaPr()); if (enableDe) - histos.fill(HIST("debug/evtime/fill/deuteron/h2antiDeuteronVspTNSigmaTOF_BetaCut"), track.pt(), track.tofNSigmaDe()); + histos.fill(HIST("debug/evtime/fill/deuteron/h2antiDeuteronVspTNSigmaTOF_BetaCut"), antiDPt, track.tofNSigmaDe()); if (enableExpSignalTOF) { if (enablePr) histos.fill(HIST("debug/evtime/fill/proton/h2antiProtonTOFExpSignalDiffVsPt_BetaCut"), track.pt(), track.tofExpSignalDiffPr()); if (enableDe) - histos.fill(HIST("debug/evtime/fill/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt_BetaCut"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("debug/evtime/fill/deuteron/h2antiDeuteronTOFExpSignalDiffVsPt_BetaCut"), antiDPt, track.tofExpSignalDiffDe()); } } } @@ -2504,11 +2702,11 @@ struct LFNucleiBATask { if ((std::abs(track.tpcNSigmaDe()) < nsigmaTPCDe) && deRapCut) { if (track.sign() > 0) { if (enablePtSpectra) { - histos.fill(HIST("tracks/eff/deuteron/hPtDe"), track.pt()); + histos.fill(HIST("tracks/eff/deuteron/hPtDe"), DPt); histos.fill(HIST("tracks/eff/deuteron/h2pVsTPCmomentumDe"), track.tpcInnerParam(), track.p()); } - histos.fill(HIST("tracks/deuteron/h1DeuteronSpectra"), track.pt()); - histos.fill(HIST("tracks/deuteron/h2DeuteronYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Deuteron)), track.pt()); + histos.fill(HIST("tracks/deuteron/h1DeuteronSpectra"), DPt); + histos.fill(HIST("tracks/deuteron/h2DeuteronYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Deuteron)), DPt); if (enablePIDplot) histos.fill(HIST("tracks/deuteron/h2TPCsignVsTPCmomentumDeuteron"), track.tpcInnerParam(), track.tpcSignal()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaPi()) > 2) && (std::abs(track.tpcNSigmaKa()) > 2) && (std::abs(track.tpcNSigmaPr()) > 1) && (std::abs(track.tpcNSigmaTr()) > 1) && (std::abs(track.tpcNSigmaDe()) < nsigmaTPCStrongCut)) { @@ -2516,11 +2714,11 @@ struct LFNucleiBATask { } } else { if (enablePtSpectra) { - histos.fill(HIST("tracks/eff/deuteron/hPtantiDe"), track.pt()); + histos.fill(HIST("tracks/eff/deuteron/hPtantiDe"), antiDPt); histos.fill(HIST("tracks/eff/deuteron/h2pVsTPCmomentumantiDe"), track.tpcInnerParam(), track.p()); } - histos.fill(HIST("tracks/deuteron/h1antiDeuteronSpectra"), track.pt()); - histos.fill(HIST("tracks/deuteron/h2antiDeuteronYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Deuteron)), track.pt()); + histos.fill(HIST("tracks/deuteron/h1antiDeuteronSpectra"), antiDPt); + histos.fill(HIST("tracks/deuteron/h2antiDeuteronYvsPt"), track.rapidity(o2::track::PID::getMass2Z(o2::track::PID::Deuteron)), antiDPt); if (enablePIDplot) histos.fill(HIST("tracks/deuteron/h2TPCsignVsTPCmomentumantiDeuteron"), track.tpcInnerParam(), track.tpcSignal()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaPi()) > 2) && (std::abs(track.tpcNSigmaKa()) > 2) && (std::abs(track.tpcNSigmaPr()) > 1) && (std::abs(track.tpcNSigmaTr()) > 1) && (std::abs(track.tpcNSigmaDe()) < nsigmaTPCStrongCut)) { @@ -2715,15 +2913,15 @@ struct LFNucleiBATask { if (enableDebug) { if (enablePr) { if (track.sign() > 0) - histos.fill(HIST("tracks/deuteron/h3DeuteronNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaDe(), track.tofNSigmaDe(), track.pt()); + histos.fill(HIST("tracks/proton/h3ProtonNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaPr(), track.tofNSigmaPr(), track.pt()); else histos.fill(HIST("tracks/proton/h3antiProtonNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaPr(), track.tofNSigmaPr(), track.pt()); } if (enableDe) { if (track.sign() > 0) - histos.fill(HIST("tracks/deuteron/h3DeuteronNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaDe(), track.tofNSigmaDe(), track.pt()); + histos.fill(HIST("tracks/deuteron/h3DeuteronNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaDe(), track.tofNSigmaDe(), DPt); else - histos.fill(HIST("tracks/deuteron/h3antiDeuteronNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaDe(), track.tofNSigmaDe(), track.pt()); + histos.fill(HIST("tracks/deuteron/h3antiDeuteronNSigmaTPCvsNSigmaTOFvsPt"), track.tpcNSigmaDe(), track.tofNSigmaDe(), antiDPt); } if (enableEvTimeSplitting) { @@ -2853,66 +3051,66 @@ struct LFNucleiBATask { if ((std::abs(track.tpcNSigmaDe()) < nsigmaTPCDe) && deRapCut) { if (track.sign() > 0) { if (enablePtSpectra) - histos.fill(HIST("tracks/eff/deuteron/hPtDeTOF"), track.pt()); - histos.fill(HIST("tracks/deuteron/h2TOFmassDeuteronVsPt"), massTOF, track.pt()); + histos.fill(HIST("tracks/eff/deuteron/hPtDeTOF"), DPt); + histos.fill(HIST("tracks/deuteron/h2TOFmassDeuteronVsPt"), massTOF, DPt); if (enableCentrality) - histos.fill(HIST("tracks/deuteron/h3TOFmass2DeuteronVsPtVsMult"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, antiDPt, event.centFT0M()); + histos.fill(HIST("tracks/deuteron/h3TOFmass2DeuteronVsPtVsMult"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, DPt, event.centFT0M()); else - histos.fill(HIST("tracks/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, antiDPt); + histos.fill(HIST("tracks/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, DPt); if (enableBetaCut && (track.beta() > betaCut)) { - histos.fill(HIST("tracks/deuteron/h2TOFmassDeuteronVsPt_BetaCut"), massTOF, track.pt()); - histos.fill(HIST("tracks/deuteron/h2TOFmass2DeuteronVsPt_BetaCut"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, track.pt()); + histos.fill(HIST("tracks/deuteron/h2TOFmassDeuteronVsPt_BetaCut"), massTOF, DPt); + histos.fill(HIST("tracks/deuteron/h2TOFmass2DeuteronVsPt_BetaCut"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, DPt); } if (enableExpSignalTOF) - histos.fill(HIST("tracks/deuteron/h2DeuteronTOFExpSignalDiffVsPtCut"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("tracks/deuteron/h2DeuteronTOFExpSignalDiffVsPtCut"), DPt, track.tofExpSignalDiffDe()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaPr()) > 2) && (std::abs(track.tpcNSigmaTr()) > 2)) { - histos.fill(HIST("tracks/deuteron/hc/h2TOFmass2DeuteronVsPt_hard"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, track.pt()); + histos.fill(HIST("tracks/deuteron/hc/h2TOFmass2DeuteronVsPt_hard"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, DPt); } if (enableEvTimeSplitting) { if (track.isEvTimeTOF() && track.isEvTimeT0AC()) { - histos.fill(HIST("tracks/evtime/ft0tof/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, track.pt()); + histos.fill(HIST("tracks/evtime/ft0tof/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, DPt); // histos.fill(HIST("tracks/evtime/ft0tof/deuteron/h2DeuteronTOFExpSignalDiffVsPtCut"), track.pt(), track.tofExpSignalDiffDe()); } else if (track.isEvTimeT0AC()) { - histos.fill(HIST("tracks/evtime/ft0/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, track.pt()); + histos.fill(HIST("tracks/evtime/ft0/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, DPt); // histos.fill(HIST("tracks/evtime/ft0/deuteron/h2DeuteronTOFExpSignalDiffVsPtCut"), track.pt(), track.tofExpSignalDiffDe()); } else if (track.isEvTimeTOF()) { - histos.fill(HIST("tracks/evtime/tof/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, track.pt()); + histos.fill(HIST("tracks/evtime/tof/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, DPt); // histos.fill(HIST("tracks/evtime/tof/deuteron/h2DeuteronTOFExpSignalDiffVsPtCut"), track.pt(), track.tofExpSignalDiffDe()); } else { - histos.fill(HIST("tracks/evtime/fill/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, track.pt()); + histos.fill(HIST("tracks/evtime/fill/deuteron/h2TOFmass2DeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, DPt); // histos.fill(HIST("tracks/evtime/fill/deuteron/h2DeuteronTOFExpSignalDiffVsPtCut"), track.pt(), track.tofExpSignalDiffDe()); } } } else { if (enablePtSpectra) - histos.fill(HIST("tracks/eff/deuteron/hPtantiDeTOF"), track.pt()); - histos.fill(HIST("tracks/deuteron/h2TOFmassantiDeuteronVsPt"), massTOF, track.pt()); + histos.fill(HIST("tracks/eff/deuteron/hPtantiDeTOF"), antiDPt); + histos.fill(HIST("tracks/deuteron/h2TOFmassantiDeuteronVsPt"), massTOF, antiDPt); if (enableCentrality) histos.fill(HIST("tracks/deuteron/h3TOFmass2antiDeuteronVsPtVsMult"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, antiDPt, event.centFT0M()); else histos.fill(HIST("tracks/deuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, antiDPt); if (enableBetaCut && (track.beta() > betaCut)) { - histos.fill(HIST("tracks/deuteron/h2TOFmassantiDeuteronVsPt_BetaCut"), massTOF, track.pt()); - histos.fill(HIST("tracks/deuteron/h2TOFmass2antiDeuteronVsPt_BetaCut"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, track.pt()); + histos.fill(HIST("tracks/deuteron/h2TOFmassantiDeuteronVsPt_BetaCut"), massTOF, antiDPt); + histos.fill(HIST("tracks/deuteron/h2TOFmass2antiDeuteronVsPt_BetaCut"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, antiDPt); } if (enableExpSignalTOF) - histos.fill(HIST("tracks/deuteron/h2antiDeuteronTOFExpSignalDiffVsPtCut"), track.pt(), track.tofExpSignalDiffDe()); + histos.fill(HIST("tracks/deuteron/h2antiDeuteronTOFExpSignalDiffVsPtCut"), antiDPt, track.tofExpSignalDiffDe()); if (enableNucleiHardCut && (std::abs(track.tpcNSigmaPr()) > 2) && (std::abs(track.tpcNSigmaTr()) > 2)) { - histos.fill(HIST("tracks/deuteron/hc/h2TOFmass2antiDeuteronVsPt_hard"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, track.pt()); + histos.fill(HIST("tracks/deuteron/hc/h2TOFmass2antiDeuteronVsPt_hard"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, antiDPt); } if (enableEvTimeSplitting) { if (track.isEvTimeTOF() && track.isEvTimeT0AC()) { - histos.fill(HIST("tracks/evtime/ft0tof/deuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, track.pt()); + histos.fill(HIST("tracks/evtime/ft0tof/deuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, antiDPt); // histos.fill(HIST("tracks/evtime/ft0tof/deuteron/h2antiDeuteronTOFExpSignalDiffVsPtCut"), track.pt(), track.tofExpSignalDiffDe()); } else if (track.isEvTimeT0AC()) { - histos.fill(HIST("tracks/evtime/ft0/deuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, track.pt()); + histos.fill(HIST("tracks/evtime/ft0/deuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, antiDPt); // histos.fill(HIST("tracks/evtime/ft0/deuteron/h2antiDeuteronTOFExpSignalDiffVsPtCut"), track.pt(), track.tofExpSignalDiffDe()); } else if (track.isEvTimeTOF()) { - histos.fill(HIST("tracks/evtime/tof/deuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, track.pt()); + histos.fill(HIST("tracks/evtime/tof/deuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, antiDPt); // histos.fill(HIST("tracks/evtime/tof/deuteron/h2antiDeuteronTOFExpSignalDiffVsPtCut"), track.pt(), track.tofExpSignalDiffDe()); } else { - histos.fill(HIST("tracks/evtime/fill/deuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, track.pt()); + histos.fill(HIST("tracks/evtime/fill/deuteron/h2TOFmass2antiDeuteronVsPt"), massTOF * massTOF - fMassDeuteron * fMassDeuteron, antiDPt); // histos.fill(HIST("tracks/evtime/fill/deuteron/h2antiDeuteronTOFExpSignalDiffVsPtCut"), track.pt(), track.tofExpSignalDiffDe()); } } @@ -2990,12 +3188,14 @@ struct LFNucleiBATask { if constexpr (IsMC) { bool isPhysPrim = false; bool isProdByGen = false; + bool isWeakDecay = false; // PID int pdgCode = 0; if constexpr (IsFilteredData) { isPhysPrim = track.isPhysicalPrimary(); isProdByGen = track.producedByGenerator(); + isWeakDecay = track.getProcess() == 4; pdgCode = track.pdgCode(); } else { if (!track.has_mcParticle()) { @@ -3003,6 +3203,7 @@ struct LFNucleiBATask { } isPhysPrim = track.mcParticle().isPhysicalPrimary(); isProdByGen = track.mcParticle().producedByGenerator(); + isWeakDecay = track.mcParticle().getProcess() == 4; pdgCode = track.mcParticle().pdgCode(); } switch (pdgCode) { @@ -3020,14 +3221,16 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/proton/dca/after/hDCAzVsPtProtonTruePrim"), track.pt(), track.dcaZ()); } if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/proton/h1ProtonSpectraTrueSec"), track.pt()); - histos.fill(HIST("tracks/proton/dca/after/hDCAxyVsPtProtonTrueSec"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/proton/dca/after/hDCAzVsPtProtonTrueSec"), track.pt(), track.dcaZ()); } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/proton/h1ProtonSpectraTrueTransport"), track.pt()); histos.fill(HIST("tracks/proton/dca/after/hDCAxyVsPtProtonTrueTransport"), track.pt(), track.dcaXY()); histos.fill(HIST("tracks/proton/dca/after/hDCAzVsPtProtonTrueTransport"), track.pt(), track.dcaZ()); + if (isWeakDecay) { + histos.fill(HIST("tracks/proton/h1ProtonSpectraTrueSec"), track.pt()); + histos.fill(HIST("tracks/proton/dca/after/hDCAxyVsPtProtonTrueSec"), track.pt(), track.dcaXY()); + histos.fill(HIST("tracks/proton/dca/after/hDCAzVsPtProtonTrueSec"), track.pt(), track.dcaZ()); + } } } break; @@ -3045,64 +3248,79 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/proton/dca/after/hDCAzVsPtantiProtonTruePrim"), track.pt(), track.dcaZ()); } if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/proton/h1antiProtonSpectraTrueSec"), track.pt()); - histos.fill(HIST("tracks/proton/dca/after/hDCAxyVsPtantiProtonTrueSec"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/proton/dca/after/hDCAzVsPtantiProtonTrueSec"), track.pt(), track.dcaZ()); + // } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/proton/h1antiProtonSpectraTrueTransport"), track.pt()); histos.fill(HIST("tracks/proton/dca/after/hDCAxyVsPtantiProtonTrueTransport"), track.pt(), track.dcaXY()); histos.fill(HIST("tracks/proton/dca/after/hDCAzVsPtantiProtonTrueTransport"), track.pt(), track.dcaZ()); + if (isWeakDecay) { + histos.fill(HIST("tracks/proton/h1antiProtonSpectraTrueSec"), track.pt()); + histos.fill(HIST("tracks/proton/dca/after/hDCAxyVsPtantiProtonTrueSec"), track.pt(), track.dcaXY()); + histos.fill(HIST("tracks/proton/dca/after/hDCAzVsPtantiProtonTrueSec"), track.pt(), track.dcaZ()); + } } } break; case PDGDeuteron: if (enableDe) { - histos.fill(HIST("tracks/deuteron/h1DeuteronSpectraTrue"), track.pt()); - histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtDeuteronTrue"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtDeuteronTrue"), track.pt(), track.dcaZ()); + histos.fill(HIST("tracks/deuteron/h1DeuteronSpectraTrue"), DPt); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtDeuteronTrue"), DPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtDeuteronTrue"), DPt, track.dcaZ()); if (std::abs(track.tpcNSigmaDe()) < nsigmaTPCDe) { - histos.fill(HIST("tracks/deuteron/h1DeuteronSpectraTrueWPID"), track.pt()); + histos.fill(HIST("tracks/deuteron/h1DeuteronSpectraTrueWPID"), DPt); + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/deuteron/hPtDeuteronTOFTrue"), DPt); + } } if (isPhysPrim) { - histos.fill(HIST("tracks/deuteron/h1DeuteronSpectraTruePrim"), track.pt()); - histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtDeuteronTruePrim"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtDeuteronTruePrim"), track.pt(), track.dcaZ()); + histos.fill(HIST("tracks/deuteron/h1DeuteronSpectraTruePrim"), DPt); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtDeuteronTruePrim"), DPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtDeuteronTruePrim"), DPt, track.dcaZ()); } if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/deuteron/h1DeuteronSpectraTrueSec"), track.pt()); - histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtDeuteronTrueSec"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtDeuteronTrueSec"), track.pt(), track.dcaZ()); + // } if (!isPhysPrim && !isProdByGen) { - histos.fill(HIST("tracks/deuteron/h1DeuteronSpectraTrueTransport"), track.pt()); - histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtDeuteronTrueTransport"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtDeuteronTrueTransport"), track.pt(), track.dcaZ()); + histos.fill(HIST("tracks/deuteron/h1DeuteronSpectraTrueTransport"), DPt); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtDeuteronTrueTransport"), DPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtDeuteronTrueTransport"), DPt, track.dcaZ()); + if (isWeakDecay) { + histos.fill(HIST("tracks/deuteron/h1DeuteronSpectraTrueSec"), DPt); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtDeuteronTrueSec"), DPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtDeuteronTrueSec"), DPt, track.dcaZ()); + } } } break; case -PDGDeuteron: if (enableDe) { - histos.fill(HIST("tracks/deuteron/h1antiDeuteronSpectraTrue"), track.pt()); - histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtantiDeuteronTrue"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtantiDeuteronTrue"), track.pt(), track.dcaZ()); + histos.fill(HIST("tracks/deuteron/h1antiDeuteronSpectraTrue"), antiDPt); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtantiDeuteronTrue"), antiDPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtantiDeuteronTrue"), antiDPt, track.dcaZ()); if (std::abs(track.tpcNSigmaDe()) < nsigmaTPCDe) { - histos.fill(HIST("tracks/deuteron/h1antiDeuteronSpectraTrueWPID"), track.pt()); + histos.fill(HIST("tracks/deuteron/h1antiDeuteronSpectraTrueWPID"), antiDPt); + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/deuteron/hPtantiDeuteronTOFTrue"), antiDPt); + } } if (isPhysPrim) { - histos.fill(HIST("tracks/deuteron/h1antiDeuteronSpectraTruePrim"), track.pt()); - histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtantiDeuteronTruePrim"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtantiDeuteronTruePrim"), track.pt(), track.dcaZ()); + histos.fill(HIST("tracks/deuteron/h1antiDeuteronSpectraTruePrim"), antiDPt); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtantiDeuteronTruePrim"), antiDPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtantiDeuteronTruePrim"), antiDPt, track.dcaZ()); } if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/deuteron/h1antiDeuteronSpectraTrueSec"), track.pt()); - histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtantiDeuteronTrueSec"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtantiDeuteronTrueSec"), track.pt(), track.dcaZ()); + // } if (!isPhysPrim && !isProdByGen) { - histos.fill(HIST("tracks/deuteron/h1antiDeuteronSpectraTrueTransport"), track.pt()); - histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtantiDeuteronTrueTransport"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtantiDeuteronTrueTransport"), track.pt(), track.dcaZ()); + histos.fill(HIST("tracks/deuteron/h1antiDeuteronSpectraTrueTransport"), antiDPt); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtantiDeuteronTrueTransport"), antiDPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtantiDeuteronTrueTransport"), antiDPt, track.dcaZ()); + if (isWeakDecay) { + histos.fill(HIST("tracks/deuteron/h1antiDeuteronSpectraTrueSec"), antiDPt); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAxyVsPtantiDeuteronTrueSec"), antiDPt, track.dcaXY()); + histos.fill(HIST("tracks/deuteron/dca/after/hDCAzVsPtantiDeuteronTrueSec"), antiDPt, track.dcaZ()); + } } } break; @@ -3117,14 +3335,17 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/triton/dca/after/hDCAzVsPtTritonTruePrim"), track.pt(), track.dcaZ()); } if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/triton/h1TritonSpectraTrueSec"), track.pt()); - histos.fill(HIST("tracks/triton/dca/after/hDCAxyVsPtTritonTrueSec"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/triton/dca/after/hDCAzVsPtTritonTrueSec"), track.pt(), track.dcaZ()); + // } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/triton/h1TritonSpectraTrueTransport"), track.pt()); histos.fill(HIST("tracks/triton/dca/after/hDCAxyVsPtTritonTrueTransport"), track.pt(), track.dcaXY()); histos.fill(HIST("tracks/triton/dca/after/hDCAzVsPtTritonTrueTransport"), track.pt(), track.dcaZ()); + if (isWeakDecay) { + histos.fill(HIST("tracks/triton/h1TritonSpectraTrueSec"), track.pt()); + histos.fill(HIST("tracks/triton/dca/after/hDCAxyVsPtTritonTrueSec"), track.pt(), track.dcaXY()); + histos.fill(HIST("tracks/triton/dca/after/hDCAzVsPtTritonTrueSec"), track.pt(), track.dcaZ()); + } } } break; @@ -3139,14 +3360,17 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/triton/dca/after/hDCAzVsPtantiTritonTruePrim"), track.pt(), track.dcaZ()); } if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/triton/h1antiTritonSpectraTrueSec"), track.pt()); - histos.fill(HIST("tracks/triton/dca/after/hDCAxyVsPtantiTritonTrueSec"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/triton/dca/after/hDCAzVsPtantiTritonTrueSec"), track.pt(), track.dcaZ()); + // } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/triton/h1antiTritonSpectraTrueTransport"), track.pt()); histos.fill(HIST("tracks/triton/dca/after/hDCAxyVsPtantiTritonTrueTransport"), track.pt(), track.dcaXY()); histos.fill(HIST("tracks/triton/dca/after/hDCAzVsPtantiTritonTrueTransport"), track.pt(), track.dcaZ()); + if (isWeakDecay) { + histos.fill(HIST("tracks/triton/h1antiTritonSpectraTrueSec"), track.pt()); + histos.fill(HIST("tracks/triton/dca/after/hDCAxyVsPtantiTritonTrueSec"), track.pt(), track.dcaXY()); + histos.fill(HIST("tracks/triton/dca/after/hDCAzVsPtantiTritonTrueSec"), track.pt(), track.dcaZ()); + } } } break; @@ -3157,6 +3381,10 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtHeliumTrue"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtHeliumTrue"), hePt, track.dcaZ()); + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtHeliumTrue"), hePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtHeliumTrue"), hePt, track.dcaZ()); + } if (std::abs(track.tpcNSigmaHe()) < nsigmaTPCHe) { histos.fill(HIST("tracks/helium/h1HeliumSpectraTrueWPID"), hePt); histos.fill(HIST("tracks/helium/h1HeliumSpectraTrueWPID_Z2"), 2 * hePt); @@ -3173,13 +3401,13 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtHeliumTruePrim"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtHeliumTruePrim"), hePt, track.dcaZ()); + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtHeliumTruePrim"), hePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtHeliumTruePrim"), hePt, track.dcaZ()); + } } if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/helium/h1HeliumSpectraTrueSec"), hePt); - histos.fill(HIST("tracks/helium/h1HeliumSpectraTrueSec_Z2"), 2 * hePt); - - histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtHeliumTrueSec"), hePt, track.dcaXY()); - histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtHeliumTrueSec"), hePt, track.dcaZ()); + // } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/helium/h1HeliumSpectraTrueTransport"), hePt); @@ -3187,6 +3415,21 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtHeliumTrueTransport"), hePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtHeliumTrueTransport"), hePt, track.dcaZ()); + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtHeliumTrueTransport"), hePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtHeliumTrueTransport"), hePt, track.dcaZ()); + } + if (isWeakDecay) { + histos.fill(HIST("tracks/helium/h1HeliumSpectraTrueSec"), hePt); + histos.fill(HIST("tracks/helium/h1HeliumSpectraTrueSec_Z2"), 2 * hePt); + + histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtHeliumTrueSec"), hePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtHeliumTrueSec"), hePt, track.dcaZ()); + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtHeliumTrueSec"), hePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtHeliumTrueSec"), hePt, track.dcaZ()); + } + } } } break; @@ -3197,6 +3440,10 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtantiHeliumTrue"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtantiHeliumTrue"), antihePt, track.dcaZ()); + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtantiHeliumTrue"), antihePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtantiHeliumTrue"), antihePt, track.dcaZ()); + } if (std::abs(track.tpcNSigmaHe()) < nsigmaTPCHe) { histos.fill(HIST("tracks/helium/h1antiHeliumSpectraTrueWPID"), antihePt); histos.fill(HIST("tracks/helium/h1antiHeliumSpectraTrueWPID_Z2"), 2 * antihePt); @@ -3213,13 +3460,13 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtantiHeliumTruePrim"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtantiHeliumTruePrim"), antihePt, track.dcaZ()); + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtantiHeliumTruePrim"), antihePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtantiHeliumTruePrim"), antihePt, track.dcaZ()); + } } if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/helium/h1antiHeliumSpectraTrueSec"), antihePt); - histos.fill(HIST("tracks/helium/h1antiHeliumSpectraTrueSec_Z2"), 2 * antihePt); - - histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtantiHeliumTrueSec"), antihePt, track.dcaXY()); - histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtantiHeliumTrueSec"), antihePt, track.dcaZ()); + // } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/helium/h1antiHeliumSpectraTrueTransport"), antihePt); @@ -3227,6 +3474,22 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtantiHeliumTrueTransport"), antihePt, track.dcaXY()); histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtantiHeliumTrueTransport"), antihePt, track.dcaZ()); + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtantiHeliumTrueTransport"), antihePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtantiHeliumTrueTransport"), antihePt, track.dcaZ()); + } + + if (isWeakDecay) { + histos.fill(HIST("tracks/helium/h1antiHeliumSpectraTrueSec"), antihePt); + histos.fill(HIST("tracks/helium/h1antiHeliumSpectraTrueSec_Z2"), 2 * antihePt); + + histos.fill(HIST("tracks/helium/dca/after/hDCAxyVsPtantiHeliumTrueSec"), antihePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/after/hDCAzVsPtantiHeliumTrueSec"), antihePt, track.dcaZ()); + if (track.hasTOF() && doTOFplots) { + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAxyVsPtantiHeliumTrueSec"), antihePt, track.dcaXY()); + histos.fill(HIST("tracks/helium/dca/after/TOF/hDCAzVsPtantiHeliumTrueSec"), antihePt, track.dcaZ()); + } + } } } break; @@ -3241,14 +3504,18 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/alpha/dca/after/hDCAzVsPtAlphaTruePrim"), track.pt(), track.dcaZ()); } if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/alpha/h1AlphaSpectraTrueSec"), track.pt()); - histos.fill(HIST("tracks/alpha/dca/after/hDCAxyVsPtAlphaTrueSec"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/alpha/dca/after/hDCAzVsPtAlphaTrueSec"), track.pt(), track.dcaZ()); + // } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/alpha/h1AlphaSpectraTrueTransport"), track.pt()); histos.fill(HIST("tracks/alpha/dca/after/hDCAxyVsPtAlphaTrueTransport"), track.pt(), track.dcaXY()); histos.fill(HIST("tracks/alpha/dca/after/hDCAzVsPtAlphaTrueTransport"), track.pt(), track.dcaZ()); + + if (isWeakDecay) { + histos.fill(HIST("tracks/alpha/h1AlphaSpectraTrueSec"), track.pt()); + histos.fill(HIST("tracks/alpha/dca/after/hDCAxyVsPtAlphaTrueSec"), track.pt(), track.dcaXY()); + histos.fill(HIST("tracks/alpha/dca/after/hDCAzVsPtAlphaTrueSec"), track.pt(), track.dcaZ()); + } } } break; @@ -3263,14 +3530,17 @@ struct LFNucleiBATask { histos.fill(HIST("tracks/alpha/dca/after/hDCAzVsPtantiAlphaTruePrim"), track.pt(), track.dcaZ()); } if (!isPhysPrim && isProdByGen) { - histos.fill(HIST("tracks/alpha/h1antiAlphaSpectraTrueSec"), track.pt()); - histos.fill(HIST("tracks/alpha/dca/after/hDCAxyVsPtantiAlphaTrueSec"), track.pt(), track.dcaXY()); - histos.fill(HIST("tracks/alpha/dca/after/hDCAzVsPtantiAlphaTrueSec"), track.pt(), track.dcaZ()); + // } if (!isPhysPrim && !isProdByGen) { histos.fill(HIST("tracks/alpha/h1antiAlphaSpectraTrueTransport"), track.pt()); histos.fill(HIST("tracks/alpha/dca/after/hDCAxyVsPtantiAlphaTrueTransport"), track.pt(), track.dcaXY()); histos.fill(HIST("tracks/alpha/dca/after/hDCAzVsPtantiAlphaTrueTransport"), track.pt(), track.dcaZ()); + if (isWeakDecay) { + histos.fill(HIST("tracks/alpha/h1antiAlphaSpectraTrueSec"), track.pt()); + histos.fill(HIST("tracks/alpha/dca/after/hDCAxyVsPtantiAlphaTrueSec"), track.pt(), track.dcaXY()); + histos.fill(HIST("tracks/alpha/dca/after/hDCAzVsPtantiAlphaTrueSec"), track.pt(), track.dcaZ()); + } } } break; diff --git a/PWGLF/Tasks/NucleiHistTask.cxx b/PWGLF/Tasks/Nuspex/NucleiHistTask.cxx similarity index 69% rename from PWGLF/Tasks/NucleiHistTask.cxx rename to PWGLF/Tasks/Nuspex/NucleiHistTask.cxx index 8965bd0afab..751ecd413ca 100644 --- a/PWGLF/Tasks/NucleiHistTask.cxx +++ b/PWGLF/Tasks/Nuspex/NucleiHistTask.cxx @@ -54,24 +54,10 @@ struct NucleiHistTask { HistogramRegistry aHelium4_reg{"aHelium4", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; // MC - HistogramRegistry MC_spectra_reg{"mc_spectra", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry MC_spectra_reconstructed_reg{"mc_spectra_reconstructed", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry MC_proton_gen_reg{"mc_proton_gen", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry MC_aproton_gen_reg{"mc_aproton_gen", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry MC_deuteron_gen_reg{"mc_deuteron_gen", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry MC_adeuteron_gen_reg{"mc_adeuteron_gen", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry MC_proton_track_reg{"mc_proton_track", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry MC_aproton_track_reg{"mc_aproton_track", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry MC_deuteron_track_reg{"mc_deuteron_track", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry MC_adeuteron_track_reg{"mc_adeuteron_track", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry MC_proton_PID_reg{"mc_proton_PID", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry MC_aproton_PID_reg{"mc_aproton_PID", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry MC_deuteron_PID_reg{"mc_deuteron_PID", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry MC_adeuteron_PID_reg{"mc_adeuteron_PID", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry MC_proton_PR_reg{"mc_proton_PR", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry MC_aproton_PR_reg{"mc_aproton_PR", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry MC_deuteron_PR_reg{"mc_deuteron_PR", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; - HistogramRegistry MC_adeuteron_PR_reg{"mc_adeuteron_PR", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry MC_truth_reg{"MC_particles", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry MC_recon_reg{"MC_particles_reconstructed", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry MC_recon_diff_reg{"MC_reconstructed_diff", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + OutputObj histPDG{TH1F("PDG", "PDG;PDG code", 100, 0.0, 100.0)}; void init(o2::framework::InitContext&) { @@ -81,16 +67,19 @@ struct NucleiHistTask { } std::vector ptBinning = {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.8, 2.0, 2.2, 2.4, 2.8, 3.2, 3.6, 4., 5., 6., 8., 10., 12., 14.}; - std::vector ptBinning_reduced = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 1.0, 1.3, 1.6, 1.9, 2.2, 2.5, 2.8, 3.1, 3.4, 3.7, 4., 5., 6., 8., 10., 12., 14.}; + std::vector ptBinning_short = {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.8, 2.0, 2.2, 2.4, 2.8, 3.2, 3.6, 4}; + std::vector ptBinning_diff = {-14.0, -12.0, -10.0, -8.0, -6.0, -5.0, -4.0, -3.6, -3.2, -2.8, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.3, -1.2, -1.1, -1.0, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 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.8, 2.0, 2.2, 2.4, 2.8, 3.2, 3.6, 4., 5., 6., 8., 10., 12., 14.}; std::vector centBinning = {0., 1., 5., 10., 20., 30., 40., 50., 70., 100.}; std::vector etaBinning = {-1.0, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}; AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec ptAxis_reduced = {ptBinning_reduced, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec ptAxis_reduced = {ptBinning_short, "#it{p}_{T} (GeV/#it{c})"}; AxisSpec centAxis = {centBinning, "V0M (%)"}; AxisSpec centralityAxis = {100, 0.0, 100.0, "VT0C (%)"}; AxisSpec centralityAxis_extended = {105, 0.0, 105.0, "VT0C (%)"}; AxisSpec etaAxis = {etaBinning, "#eta"}; + AxisSpec PDGBINNING = {20, 0.0, 20.0, "PDG code"}; + AxisSpec ptAxis_diff = {ptBinning_diff, "#it{p}_{T,diff} (GeV/#it{c})"}; // +++++++++++++++++++++ Data ++++++++++++++++++++++++ @@ -325,92 +314,63 @@ struct NucleiHistTask { // +++++++++++++++++++++ MC ++++++++++++++++++++++++++ - // QA histograms - MC_spectra_reg.add("histRecVtxZData", "collision z position", HistType::kTH1F, {{200, -20., +20., "z position (cm)"}}); - MC_spectra_reconstructed_reg.add("histDcaVsPtData_particle", "dcaXY vs Pt (particle)", HistType::kTH2F, {ptAxis, {250, -0.5, 0.5, "dca"}}); - MC_spectra_reconstructed_reg.add("histDcaZVsPtData_particle", "dcaZ vs Pt (particle)", HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); - MC_spectra_reconstructed_reg.add("histDcaVsPtData_antiparticle", "dcaXY vs Pt (antiparticle)", HistType::kTH2F, {ptAxis, {250, -0.5, 0.5, "dca"}}); - MC_spectra_reconstructed_reg.add("histDcaZVsPtData_antiparticle", "dcaZ vs Pt (antiparticle)", HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); - - // MC generated - MC_proton_gen_reg.add("histPt", "p_{T} distribution (p)", HistType::kTH1F, {ptAxis}); - MC_aproton_gen_reg.add("histPt", "p_{T} distribution (antip)", HistType::kTH1F, {ptAxis}); - MC_deuteron_gen_reg.add("histPt", "p_{T} distribution (d)", HistType::kTH1F, {ptAxis}); - MC_adeuteron_gen_reg.add("histPt", "p_{T} distribution (antid)", HistType::kTH1F, {ptAxis}); - - // MC tracking - MC_proton_track_reg.add("histPt", "p_{T} distribution (p)", HistType::kTH1F, {ptAxis}); - MC_aproton_track_reg.add("histPt", "p_{T} distribution (antip)", HistType::kTH1F, {ptAxis}); - MC_deuteron_track_reg.add("histPt", "p_{T} distribution (d)", HistType::kTH1F, {ptAxis}); - MC_adeuteron_track_reg.add("histPt", "p_{T} distribution (antid)", HistType::kTH1F, {ptAxis}); - - MC_proton_track_reg.add("histTpcNsigmaData", "n-sigma TPC tracked (p)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{p}"}}); - MC_aproton_track_reg.add("histTpcNsigmaData", "n-sigma TPC tracked (antip)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{antip}"}}); - MC_deuteron_track_reg.add("histTpcNsigmaData", "n-sigma TPC tracked (d)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{d}"}}); - MC_adeuteron_track_reg.add("histTpcNsigmaData", "n-sigma TPC tracked (antid)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{antid}"}}); - - MC_proton_track_reg.add("histTofNsigmaData", "n-sigma TOF tracked (p)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{p}"}}); - MC_aproton_track_reg.add("histTofNsigmaData", "n-sigma TOF tracked (antip)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{antip}"}}); - MC_deuteron_track_reg.add("histTofNsigmaData", "n-sigma TOF tracked (d)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{d}"}}); - MC_adeuteron_track_reg.add("histTofNsigmaData", "n-sigma TOF tracked (antid)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{antid}"}}); - - // MC PID - MC_proton_PID_reg.add("histPt_tpc", "p_{T} distribution (p)", HistType::kTH1F, {ptAxis}); - MC_aproton_PID_reg.add("histPt_tpc", "p_{T} distribution (antip)", HistType::kTH1F, {ptAxis}); - MC_deuteron_PID_reg.add("histPt_tpc", "p_{T} distribution (d)", HistType::kTH1F, {ptAxis}); - MC_adeuteron_PID_reg.add("histPt_tpc", "p_{T} distribution (antid)", HistType::kTH1F, {ptAxis}); - - MC_proton_PID_reg.add("histPt_tof", "p_{T} distribution (p)", HistType::kTH1F, {ptAxis}); - MC_aproton_PID_reg.add("histPt_tof", "p_{T} distribution (antip)", HistType::kTH1F, {ptAxis}); - MC_deuteron_PID_reg.add("histPt_tof", "p_{T} distribution (d)", HistType::kTH1F, {ptAxis}); - MC_adeuteron_PID_reg.add("histPt_tof", "p_{T} distribution (antid)", HistType::kTH1F, {ptAxis}); - - MC_proton_PID_reg.add("histTpcNsigmaData", "n-sigma TPC PID (p)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{p}"}}); - MC_aproton_PID_reg.add("histTpcNsigmaData", "n-sigma TPC PID (antip)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{antip}"}}); - MC_deuteron_PID_reg.add("histTpcNsigmaData", "n-sigma TPC PID (d)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{d}"}}); - MC_adeuteron_PID_reg.add("histTpcNsigmaData", "n-sigma TPC PID (antid)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{antid}"}}); - - MC_proton_PID_reg.add("histTofNsigmaData", "n-sigma TOF PID (p)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{p}"}}); - MC_aproton_PID_reg.add("histTofNsigmaData", "n-sigma TOF PID (antip)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{antip}"}}); - MC_deuteron_PID_reg.add("histTofNsigmaData", "n-sigma TOF PID (d)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{d}"}}); - MC_adeuteron_PID_reg.add("histTofNsigmaData", "n-sigma TOF PID (antid)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{antid}"}}); - - // MC priary ratio - MC_proton_PR_reg.add("histDcaVsPtData", "dcaXY vs Pt (p)", HistType::kTH2F, {ptAxis, {250, -0.5, 0.5, "dca"}}); - MC_proton_PR_reg.add("histDcaZVsPtData", "dcaZ vs Pt (p)", HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); - MC_aproton_PR_reg.add("histDcaVsPtData", "dcaXY vs Pt (antip)", HistType::kTH2F, {ptAxis, {250, -0.5, 0.5, "dca"}}); - MC_aproton_PR_reg.add("histDcaZVsPtData", "dcaZ vs Pt (antip)", HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); - MC_deuteron_PR_reg.add("histDcaVsPtData", "dcaXY vs Pt (d)", HistType::kTH2F, {ptAxis, {250, -0.5, 0.5, "dca"}}); - MC_deuteron_PR_reg.add("histDcaZVsPtData", "dcaZ vs Pt (d)", HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); - MC_adeuteron_PR_reg.add("histDcaVsPtData", "dcaXY vs Pt (antid)", HistType::kTH2F, {ptAxis, {250, -0.5, 0.5, "dca"}}); - MC_adeuteron_PR_reg.add("histDcaZVsPtData", "dcaZ vs Pt (antid)", HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); - - MC_proton_PR_reg.add("histDcaVsPtData_isPP", "dcaXY vs Pt (p)", HistType::kTH2F, {ptAxis, {250, -0.5, 0.5, "dca"}}); - MC_proton_PR_reg.add("histDcaZVsPtData_isPP", "dcaZ vs Pt (p)", HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); - MC_aproton_PR_reg.add("histDcaVsPtData_isPP", "dcaXY vs Pt (antip)", HistType::kTH2F, {ptAxis, {250, -0.5, 0.5, "dca"}}); - MC_aproton_PR_reg.add("histDcaZVsPtData_isPP", "dcaZ vs Pt (antip)", HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); - MC_deuteron_PR_reg.add("histDcaVsPtData_isPP", "dcaXY vs Pt (d)", HistType::kTH2F, {ptAxis, {250, -0.5, 0.5, "dca"}}); - MC_deuteron_PR_reg.add("histDcaZVsPtData_isPP", "dcaZ vs Pt (d)", HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); - MC_adeuteron_PR_reg.add("histDcaVsPtData_isPP", "dcaXY vs Pt (antid)", HistType::kTH2F, {ptAxis, {250, -0.5, 0.5, "dca"}}); - MC_adeuteron_PR_reg.add("histDcaZVsPtData_isPP", "dcaZ vs Pt (antid)", HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); - - MC_proton_PR_reg.add("histDcaVsPtData_isDec", "dcaXY vs Pt (p)", HistType::kTH2F, {ptAxis, {250, -0.5, 0.5, "dca"}}); - MC_proton_PR_reg.add("histDcaZVsPtData_isDec", "dcaZ vs Pt (p)", HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); - MC_aproton_PR_reg.add("histDcaVsPtData_isDec", "dcaXY vs Pt (antip)", HistType::kTH2F, {ptAxis, {250, -0.5, 0.5, "dca"}}); - MC_aproton_PR_reg.add("histDcaZVsPtData_isDec", "dcaZ vs Pt (antip)", HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); - MC_deuteron_PR_reg.add("histDcaVsPtData_isDec", "dcaXY vs Pt (d)", HistType::kTH2F, {ptAxis, {250, -0.5, 0.5, "dca"}}); - MC_deuteron_PR_reg.add("histDcaZVsPtData_isDec", "dcaZ vs Pt (d)", HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); - MC_adeuteron_PR_reg.add("histDcaVsPtData_isDec", "dcaXY vs Pt (antid)", HistType::kTH2F, {ptAxis, {250, -0.5, 0.5, "dca"}}); - MC_adeuteron_PR_reg.add("histDcaZVsPtData_isDec", "dcaZ vs Pt (antid)", HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); - - MC_proton_PR_reg.add("histDcaVsPtData_isMat", "dcaXY vs Pt (p)", HistType::kTH2F, {ptAxis, {250, -0.5, 0.5, "dca"}}); - MC_proton_PR_reg.add("histDcaZVsPtData_isMat", "dcaZ vs Pt (p)", HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); - MC_aproton_PR_reg.add("histDcaVsPtData_isMat", "dcaXY vs Pt (antip)", HistType::kTH2F, {ptAxis, {250, -0.5, 0.5, "dca"}}); - MC_aproton_PR_reg.add("histDcaZVsPtData_isMat", "dcaZ vs Pt (antip)", HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); - MC_deuteron_PR_reg.add("histDcaVsPtData_isMat", "dcaXY vs Pt (d)", HistType::kTH2F, {ptAxis, {250, -0.5, 0.5, "dca"}}); - MC_deuteron_PR_reg.add("histDcaZVsPtData_isMat", "dcaZ vs Pt (d)", HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); - MC_adeuteron_PR_reg.add("histDcaVsPtData_isMat", "dcaXY vs Pt (antid)", HistType::kTH2F, {ptAxis, {250, -0.5, 0.5, "dca"}}); - MC_adeuteron_PR_reg.add("histDcaZVsPtData_isMat", "dcaZ vs Pt (antid)", HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); + // MC truth + MC_truth_reg.add("histPhi", "#phi", HistType::kTH2F, {{100, 0., 2. * TMath::Pi()}, PDGBINNING}); + MC_truth_reg.add("histEta", "#eta", HistType::kTH2F, {{102, -2.01, 2.01}, PDGBINNING}); + MC_truth_reg.add("histPt", "p_{t}", HistType::kTH2F, {ptAxis, PDGBINNING}); + MC_truth_reg.add("histRecVtxMC", "MC collision z position", HistType::kTH1F, {{400, -40., +40., "z position (cm)"}}); + + // MC reconstructed + MC_recon_reg.add("histPhi", "#phi", HistType::kTH2F, {{100, 0., 2. * TMath::Pi()}, PDGBINNING}); + MC_recon_reg.add("histEta", "#eta", HistType::kTH2F, {{102, -2.01, 2.01}, PDGBINNING}); + MC_recon_reg.add("histPt", "p_{t}", HistType::kTH2F, {ptAxis, PDGBINNING}); + MC_recon_reg.add("histDCA", "DCA xy", HistType::kTH3F, {ptAxis, {250, -0.5, 0.5, "dca"}, PDGBINNING}); + MC_recon_reg.add("histDCAz", "DCA z", HistType::kTH3F, {ptAxis, {1000, -2.0, 2.0, "dca"}, PDGBINNING}); + MC_recon_reg.add("histTpcSignalData", "Specific energy loss", HistType::kTH3F, {{600, -6., 6., "#it{p} (GeV/#it{c})"}, {5000, 0, 5000, "d#it{E} / d#it{X} (a. u.)"}, PDGBINNING}); + MC_recon_reg.add("histTofSignalData", "TOF signal", HistType::kTH3F, {{600, -6., 6., "#it{p} (GeV/#it{c})"}, {550, 0.0, 1.1, "#beta (TOF)"}, PDGBINNING}); + MC_recon_reg.add("histTOFm2", "TOF m^2 vs Pt", HistType::kTH3F, {ptAxis, {400, 0.0, 10.0, "m^2"}, PDGBINNING}); + MC_recon_reg.add("histNClusterTPC", "Number of Clusters in TPC vs Pt", HistType::kTH3F, {ptAxis, {80, 0.0, 160.0, "nCluster"}, PDGBINNING}); + MC_recon_reg.add("histNClusterITS", "Number of Clusters in ITS vs Pt", HistType::kTH3F, {ptAxis, {10, 0.0, 10.0, "ITS nCls"}, PDGBINNING}); + MC_recon_reg.add("histNClusterITSib", "Number of Clusters in ib of ITS vs Pt", HistType::kTH3F, {ptAxis, {10, 0.0, 10.0, "ITS ib nCls"}, PDGBINNING}); + MC_recon_reg.add("histTPCnClsFindable", "Findable TPC clusters", HistType::kTH3F, {ptAxis, {200, 0.0, 200.0, "nCluster"}, PDGBINNING}); + MC_recon_reg.add("histTPCnClsFindableMinusFound", "TPC Clusters: Findable - Found", HistType::kTH3F, {ptAxis, {60, 0.0, 60.0, "nCluster"}, PDGBINNING}); + MC_recon_reg.add("histTPCnClsFindableMinusCrossedRows", "TPC Clusters: Findable - crossed rows", HistType::kTH3F, {ptAxis, {60, 0.0, 60.0, "nCluster"}, PDGBINNING}); + MC_recon_reg.add("histTPCnClsShared", "Number of shared TPC clusters", HistType::kTH3F, {ptAxis, {70, 0.0, 70.0, "nCluster"}, PDGBINNING}); + MC_recon_reg.add("histTPCCrossedRowsOverFindableCls", "Ratio crossed rows over findable clusters", HistType::kTH2F, {{100, 0., 2.0, "Crossed Rows / Findable Cls"}, PDGBINNING}); + MC_recon_reg.add("histTPCFoundOverFindable", "Ratio of found over findable clusters", HistType::kTH2F, {{100, 0., 2.0, "Found Cls / Findable Cls"}, PDGBINNING}); + MC_recon_reg.add("histChi2TPC", "chi^2 TPC vs Pt", HistType::kTH3F, {ptAxis, {100, 0.0, 5.0, "chi^2"}, PDGBINNING}); + MC_recon_reg.add("histChi2ITS", "chi^2 ITS vs Pt", HistType::kTH3F, {ptAxis, {500, 0.0, 50.0, "chi^2"}, PDGBINNING}); + MC_recon_reg.add("histChi2ITSvsITSnCls", "chi^2 ITS vs ITS nCls", HistType::kTH2F, {{125, 0.0, 50.0, "chi^2"}, {10, 0.0, 10.0, "ITS nCls"}}); + MC_recon_reg.add("histChi2ITSvsITSibnCls", "chi^2 ITS vs ITS ib nCls", HistType::kTH2F, {{125, 0.0, 50.0, "chi^2"}, {10, 0.0, 10.0, "ITS ib nCls"}}); + MC_recon_reg.add("histChi2ITSvsITSnClsAll", "chi^2 ITS vs ITS nCls", HistType::kTH2F, {{125, 0.0, 50.0, "chi^2"}, {10, 0.0, 10.0, "ITS nCls"}}); + MC_recon_reg.add("histChi2TOF", "chi^2 TOF vs Pt", HistType::kTH3F, {ptAxis, {75, 0.0, 15.0, "chi^2"}, PDGBINNING}); + MC_recon_reg.add("histTrackLength", "Track length", HistType::kTH2F, {{350, 0., 700., "length (cm)"}, PDGBINNING}); + MC_recon_reg.add("histTPCFractionSharedCls", "Fraction of shared TPC clusters", HistType::kTH2F, {{100, -2.0, 2.0, "Shared Cls"}, PDGBINNING}); + MC_recon_reg.add("histTpcNsigmaDataPr", "TPC nSigma (p)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{p}"}}); + MC_recon_reg.add("histTpcNsigmaDataaPr", "TPC nSigma (antip)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{p}"}}); + MC_recon_reg.add("histTpcNsigmaDataDe", "TPC nSigma (d)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{d}"}}); + MC_recon_reg.add("histTpcNsigmaDataaDe", "TPC nSigma (antid)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{d}"}}); + MC_recon_reg.add("histTpcNsigmaDataTr", "TPC nSigma (t)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{t}"}}); + MC_recon_reg.add("histTpcNsigmaDataaTr", "TPC nSigma (antit)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{t}"}}); + MC_recon_reg.add("histTpcNsigmaDataHe", "TPC nSigma (He-3)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{He-3}"}}); + MC_recon_reg.add("histTpcNsigmaDataaHe", "TPC nSigma (antiHe-3)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{He-3}"}}); + MC_recon_reg.add("histTpcNsigmaDataAl", "TPC nSigma (He-4)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{He-4}"}}); + MC_recon_reg.add("histTpcNsigmaDataaAl", "TPC nSigma (antiHe-4)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{He-4}"}}); + MC_recon_reg.add("histTofNsigmaDataPr", "TOF nSigma (p)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{p}"}}); + MC_recon_reg.add("histTofNsigmaDataaPr", "TOF nSigma (antip)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{p}"}}); + MC_recon_reg.add("histTofNsigmaDataDe", "TOF nSigma (d)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{d}"}}); + MC_recon_reg.add("histTofNsigmaDataaDe", "TOF nSigma (antid)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{d}"}}); + MC_recon_reg.add("histTofNsigmaDataTr", "TOF nSigma (t)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{t}"}}); + MC_recon_reg.add("histTofNsigmaDataaTr", "TOF nSigma (antit)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{t}"}}); + MC_recon_reg.add("histTofNsigmaDataHe", "TOF nSigma (He-3)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{He-3}"}}); + MC_recon_reg.add("histTofNsigmaDataaHe", "TOF nSigma (antiHe-3)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{He-3}"}}); + MC_recon_reg.add("histTofNsigmaDataAl", "TOF nSigma (He-4)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{He-4}"}}); + MC_recon_reg.add("histTofNsigmaDataaAl", "TOF nSigma (antiHe-4)", HistType::kTH2F, {ptAxis, {160, -20., +20., "n#sigma_{He-4}"}}); + + // MC diff (truth - reconstructed) + MC_recon_diff_reg.add("histPhiDiff", "MC t", HistType::kTH2F, {ptAxis_diff, PDGBINNING}); + MC_recon_diff_reg.add("histEtaDiff", "MC t", HistType::kTH2F, {ptAxis_diff, PDGBINNING}); + MC_recon_diff_reg.add("histPtDiff", "MC t", HistType::kTH2F, {ptAxis_diff, PDGBINNING}); } // Configurables @@ -543,7 +503,7 @@ struct NucleiHistTask { float nSigmaHe3 = track.tpcNSigmaHe(); float nSigmaHe4 = track.tpcNSigmaAl(); - spectra_reg.fill(HIST("histTpcSignalData"), track.tpcInnerParam() * track.sign(), track.tpcSignal()); + spectra_reg.fill(HIST("histTpcSignalData"), track.pt() * track.sign(), track.tpcSignal()); spectra_reg.fill(HIST("histNClusterTPC"), track.pt(), track.tpcNClsCrossedRows()); spectra_reg.fill(HIST("histNClusterITS"), track.pt(), track.itsNCls()); spectra_reg.fill(HIST("histNClusterITSib"), track.pt(), track.itsNClsInnerBarrel()); @@ -621,7 +581,7 @@ struct NucleiHistTask { proton_reg.fill(HIST("histDcaVsPtData"), track.pt(), track.dcaXY()); proton_reg.fill(HIST("histDcaZVsPtData"), track.pt(), track.dcaZ()); - proton_reg.fill(HIST("histTpcSignalData"), track.tpcInnerParam(), track.tpcSignal()); + proton_reg.fill(HIST("histTpcSignalData"), track.pt(), track.tpcSignal()); proton_reg.fill(HIST("histNClusterTPC"), track.pt(), track.tpcNClsFound()); proton_reg.fill(HIST("histNClusterITS"), track.pt(), track.itsNCls()); proton_reg.fill(HIST("histNClusterITSib"), track.pt(), track.itsNClsInnerBarrel()); @@ -647,7 +607,7 @@ struct NucleiHistTask { Float_t beta = track.beta(); proton_reg.fill(HIST("histTOFm2"), track.pt(), TOFmass2); - proton_reg.fill(HIST("histTofSignalData"), track.tpcInnerParam(), beta); + proton_reg.fill(HIST("histTofSignalData"), track.pt(), beta); proton_reg.fill(HIST("histTofNsigmaData"), track.pt(), track.tofNSigmaPr()); } } @@ -661,7 +621,7 @@ struct NucleiHistTask { aproton_reg.fill(HIST("histDcaVsPtData"), track.pt(), track.dcaXY()); aproton_reg.fill(HIST("histDcaZVsPtData"), track.pt(), track.dcaZ()); - aproton_reg.fill(HIST("histTpcSignalData"), track.tpcInnerParam(), track.tpcSignal()); + aproton_reg.fill(HIST("histTpcSignalData"), track.pt(), track.tpcSignal()); aproton_reg.fill(HIST("histNClusterTPC"), track.pt(), track.tpcNClsFound()); aproton_reg.fill(HIST("histNClusterITS"), track.pt(), track.itsNCls()); aproton_reg.fill(HIST("histNClusterITSib"), track.pt(), track.itsNClsInnerBarrel()); @@ -687,7 +647,7 @@ struct NucleiHistTask { Float_t beta = track.beta(); aproton_reg.fill(HIST("histTOFm2"), track.pt(), TOFmass2); - aproton_reg.fill(HIST("histTofSignalData"), track.tpcInnerParam(), beta); + aproton_reg.fill(HIST("histTofSignalData"), track.pt(), beta); aproton_reg.fill(HIST("histTofNsigmaData"), track.pt(), track.tofNSigmaPr()); } } @@ -707,9 +667,8 @@ struct NucleiHistTask { } } - spectra_reg.fill(HIST("histTofSignalData"), track.tpcInnerParam() * track.sign(), track.beta()); + spectra_reg.fill(HIST("histTofSignalData"), track.pt() * track.sign(), track.beta()); } - } //************** check offline-trigger (skimming) condidition Deuteron ******************* @@ -725,7 +684,7 @@ struct NucleiHistTask { deuteron_reg.fill(HIST("histDcaVsPtData"), track.pt(), track.dcaXY()); deuteron_reg.fill(HIST("histDcaZVsPtData"), track.pt(), track.dcaZ()); - deuteron_reg.fill(HIST("histTpcSignalData"), track.tpcInnerParam(), track.tpcSignal()); + deuteron_reg.fill(HIST("histTpcSignalData"), track.pt(), track.tpcSignal()); deuteron_reg.fill(HIST("histNClusterTPC"), track.pt(), track.tpcNClsFound()); deuteron_reg.fill(HIST("histNClusterITS"), track.pt(), track.itsNCls()); deuteron_reg.fill(HIST("histNClusterITSib"), track.pt(), track.itsNClsInnerBarrel()); @@ -751,7 +710,7 @@ struct NucleiHistTask { Float_t beta = track.beta(); deuteron_reg.fill(HIST("histTOFm2"), track.pt(), TOFmass2); - deuteron_reg.fill(HIST("histTofSignalData"), track.tpcInnerParam(), beta); + deuteron_reg.fill(HIST("histTofSignalData"), track.pt(), beta); deuteron_reg.fill(HIST("histTofNsigmaData"), track.pt(), track.tofNSigmaDe()); } } @@ -765,7 +724,7 @@ struct NucleiHistTask { adeuteron_reg.fill(HIST("histDcaVsPtData"), track.pt(), track.dcaXY()); adeuteron_reg.fill(HIST("histDcaZVsPtData"), track.pt(), track.dcaZ()); - adeuteron_reg.fill(HIST("histTpcSignalData"), track.tpcInnerParam(), track.tpcSignal()); + adeuteron_reg.fill(HIST("histTpcSignalData"), track.pt(), track.tpcSignal()); adeuteron_reg.fill(HIST("histNClusterTPC"), track.pt(), track.tpcNClsFound()); adeuteron_reg.fill(HIST("histNClusterITS"), track.pt(), track.itsNCls()); adeuteron_reg.fill(HIST("histNClusterITSib"), track.pt(), track.itsNClsInnerBarrel()); @@ -791,7 +750,7 @@ struct NucleiHistTask { Float_t beta = track.beta(); adeuteron_reg.fill(HIST("histTOFm2"), track.pt(), TOFmass2); - adeuteron_reg.fill(HIST("histTofSignalData"), track.tpcInnerParam(), beta); + adeuteron_reg.fill(HIST("histTofSignalData"), track.pt(), beta); adeuteron_reg.fill(HIST("histTofNsigmaData"), track.pt(), track.tofNSigmaDe()); } } @@ -811,7 +770,7 @@ struct NucleiHistTask { } } - spectra_reg.fill(HIST("histTofSignalData"), track.tpcInnerParam() * track.sign(), track.beta()); + spectra_reg.fill(HIST("histTofSignalData"), track.pt() * track.sign(), track.beta()); } } @@ -828,7 +787,7 @@ struct NucleiHistTask { triton_reg.fill(HIST("histDcaVsPtData"), track.pt(), track.dcaXY()); triton_reg.fill(HIST("histDcaZVsPtData"), track.pt(), track.dcaZ()); - triton_reg.fill(HIST("histTpcSignalData"), track.tpcInnerParam(), track.tpcSignal()); + triton_reg.fill(HIST("histTpcSignalData"), track.pt(), track.tpcSignal()); triton_reg.fill(HIST("histNClusterTPC"), track.pt(), track.tpcNClsFound()); triton_reg.fill(HIST("histNClusterITS"), track.pt(), track.itsNCls()); triton_reg.fill(HIST("histNClusterITSib"), track.pt(), track.itsNClsInnerBarrel()); @@ -854,7 +813,7 @@ struct NucleiHistTask { Float_t beta = track.beta(); triton_reg.fill(HIST("histTOFm2"), track.pt(), TOFmass2); - triton_reg.fill(HIST("histTofSignalData"), track.tpcInnerParam(), beta); + triton_reg.fill(HIST("histTofSignalData"), track.pt(), beta); triton_reg.fill(HIST("histTofNsigmaData"), track.pt(), track.tofNSigmaTr()); } } @@ -868,7 +827,7 @@ struct NucleiHistTask { atriton_reg.fill(HIST("histDcaVsPtData"), track.pt(), track.dcaXY()); atriton_reg.fill(HIST("histDcaZVsPtData"), track.pt(), track.dcaZ()); - atriton_reg.fill(HIST("histTpcSignalData"), track.tpcInnerParam(), track.tpcSignal()); + atriton_reg.fill(HIST("histTpcSignalData"), track.pt(), track.tpcSignal()); atriton_reg.fill(HIST("histNClusterTPC"), track.pt(), track.tpcNClsFound()); atriton_reg.fill(HIST("histNClusterITS"), track.pt(), track.itsNCls()); atriton_reg.fill(HIST("histNClusterITSib"), track.pt(), track.itsNClsInnerBarrel()); @@ -894,7 +853,7 @@ struct NucleiHistTask { Float_t beta = track.beta(); atriton_reg.fill(HIST("histTOFm2"), track.pt(), TOFmass2); - atriton_reg.fill(HIST("histTofSignalData"), track.tpcInnerParam(), beta); + atriton_reg.fill(HIST("histTofSignalData"), track.pt(), beta); atriton_reg.fill(HIST("histTofNsigmaData"), track.pt(), track.tofNSigmaTr()); } } @@ -914,7 +873,7 @@ struct NucleiHistTask { } } - spectra_reg.fill(HIST("histTofSignalData"), track.tpcInnerParam() * track.sign(), track.beta()); + spectra_reg.fill(HIST("histTofSignalData"), track.pt() * track.sign(), track.beta()); } } @@ -931,7 +890,7 @@ struct NucleiHistTask { Helium3_reg.fill(HIST("histDcaVsPtData"), track.pt() * 2.0, track.dcaXY()); Helium3_reg.fill(HIST("histDcaZVsPtData"), track.pt() * 2.0, track.dcaZ()); - Helium3_reg.fill(HIST("histTpcSignalData"), track.tpcInnerParam() * 2.0, track.tpcSignal()); + Helium3_reg.fill(HIST("histTpcSignalData"), track.pt() * 2.0, track.tpcSignal()); Helium3_reg.fill(HIST("histNClusterTPC"), track.pt() * 2.0, track.tpcNClsFound()); Helium3_reg.fill(HIST("histNClusterITS"), track.pt() * 2.0, track.itsNCls()); Helium3_reg.fill(HIST("histNClusterITSib"), track.pt() * 2.0, track.itsNClsInnerBarrel()); @@ -957,7 +916,7 @@ struct NucleiHistTask { Float_t beta = track.beta(); Helium3_reg.fill(HIST("histTOFm2"), track.pt() * 2.0, TOFmass2); - Helium3_reg.fill(HIST("histTofSignalData"), track.tpcInnerParam() * 2.0, beta); + Helium3_reg.fill(HIST("histTofSignalData"), track.pt() * 2.0, beta); Helium3_reg.fill(HIST("histTofNsigmaData"), track.pt() * 2.0, track.tofNSigmaHe()); } } @@ -970,7 +929,7 @@ struct NucleiHistTask { keepEvent_antiHe3 = kTRUE; aHelium3_reg.fill(HIST("histDcaVsPtData"), track.pt() * 2.0, track.dcaXY()); aHelium3_reg.fill(HIST("histDcaZVsPtData"), track.pt() * 2.0, track.dcaZ()); - aHelium3_reg.fill(HIST("histTpcSignalData"), track.tpcInnerParam() * 2.0, track.tpcSignal()); + aHelium3_reg.fill(HIST("histTpcSignalData"), track.pt() * 2.0, track.tpcSignal()); aHelium3_reg.fill(HIST("histNClusterTPC"), track.pt() * 2.0, track.tpcNClsFound()); aHelium3_reg.fill(HIST("histNClusterITS"), track.pt() * 2.0, track.itsNCls()); aHelium3_reg.fill(HIST("histNClusterITSib"), track.pt() * 2.0, track.itsNClsInnerBarrel()); @@ -996,7 +955,7 @@ struct NucleiHistTask { Float_t beta = track.beta(); aHelium3_reg.fill(HIST("histTOFm2"), track.pt() * 2.0, TOFmass2); - aHelium3_reg.fill(HIST("histTofSignalData"), track.tpcInnerParam() * 2.0, beta); + aHelium3_reg.fill(HIST("histTofSignalData"), track.pt() * 2.0, beta); aHelium3_reg.fill(HIST("histTofNsigmaData"), track.pt() * 2.0, track.tofNSigmaHe()); } } @@ -1016,7 +975,7 @@ struct NucleiHistTask { } } - spectra_reg.fill(HIST("histTofSignalData"), track.tpcInnerParam() * 2.0 * track.sign(), track.beta()); + spectra_reg.fill(HIST("histTofSignalData"), track.pt() * 2.0 * track.sign(), track.beta()); } } @@ -1033,7 +992,7 @@ struct NucleiHistTask { Helium4_reg.fill(HIST("histDcaVsPtData"), track.pt() * 2.0, track.dcaXY()); Helium4_reg.fill(HIST("histDcaZVsPtData"), track.pt() * 2.0, track.dcaZ()); - Helium4_reg.fill(HIST("histTpcSignalData"), track.tpcInnerParam() * 2.0, track.tpcSignal()); + Helium4_reg.fill(HIST("histTpcSignalData"), track.pt() * 2.0, track.tpcSignal()); Helium4_reg.fill(HIST("histNClusterTPC"), track.pt() * 2.0, track.tpcNClsFound()); Helium4_reg.fill(HIST("histNClusterITS"), track.pt() * 2.0, track.itsNCls()); Helium4_reg.fill(HIST("histNClusterITSib"), track.pt() * 2.0, track.itsNClsInnerBarrel()); @@ -1059,7 +1018,7 @@ struct NucleiHistTask { Float_t beta = track.beta(); Helium4_reg.fill(HIST("histTOFm2"), track.pt() * 2.0, TOFmass2); - Helium4_reg.fill(HIST("histTofSignalData"), track.tpcInnerParam() * 2.0, beta); + Helium4_reg.fill(HIST("histTofSignalData"), track.pt() * 2.0, beta); Helium4_reg.fill(HIST("histTofNsigmaData"), track.pt() * 2.0, track.tofNSigmaAl()); } } @@ -1072,7 +1031,7 @@ struct NucleiHistTask { keepEvent_antiHe4 = kTRUE; aHelium4_reg.fill(HIST("histDcaVsPtData"), track.pt() * 2.0, track.dcaXY()); aHelium4_reg.fill(HIST("histDcaZVsPtData"), track.pt() * 2.0, track.dcaZ()); - aHelium4_reg.fill(HIST("histTpcSignalData"), track.tpcInnerParam() * 2.0, track.tpcSignal()); + aHelium4_reg.fill(HIST("histTpcSignalData"), track.pt() * 2.0, track.tpcSignal()); aHelium4_reg.fill(HIST("histNClusterTPC"), track.pt() * 2.0, track.tpcNClsFound()); aHelium4_reg.fill(HIST("histNClusterITS"), track.pt() * 2.0, track.itsNCls()); aHelium4_reg.fill(HIST("histNClusterITSib"), track.pt() * 2.0, track.itsNClsInnerBarrel()); @@ -1098,7 +1057,7 @@ struct NucleiHistTask { Float_t beta = track.beta(); aHelium4_reg.fill(HIST("histTOFm2"), track.pt() * 2.0, TOFmass2); - aHelium4_reg.fill(HIST("histTofSignalData"), track.tpcInnerParam() * 2.0, beta); + aHelium4_reg.fill(HIST("histTofSignalData"), track.pt() * 2.0, beta); aHelium4_reg.fill(HIST("histTofNsigmaData"), track.pt() * 2.0, track.tofNSigmaAl()); } } @@ -1118,7 +1077,7 @@ struct NucleiHistTask { } } - spectra_reg.fill(HIST("histTofSignalData"), track.tpcInnerParam() * 2.0 * track.sign(), track.beta()); + spectra_reg.fill(HIST("histTofSignalData"), track.pt() * 2.0 * track.sign(), track.beta()); } } @@ -1321,7 +1280,6 @@ struct NucleiHistTask { } } - //**************************************************************************************************** Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVertex); @@ -1346,451 +1304,102 @@ struct NucleiHistTask { } PROCESS_SWITCH(NucleiHistTask, processDataCent, "process data with centralities", false); - // MC - void processMC_generated(aod::McCollision const& mcCollision, aod::McParticles& mcParticles) + void processMC(soa::Join::iterator const& collisions, soa::Filtered> const& tracks, + aod::McParticles& mcParticles, aod::McCollisions const& mcCollisions) { - int particles = 0; - int primaryparticles = 0; - - MC_spectra_reg.fill(HIST("histRecVtxZData"), mcCollision.posZ()); - - for (auto& mcParticle : mcParticles) { - if (abs(mcParticle.eta()) > cfgCutEta) { - continue; - } - - if (mcParticle.isPhysicalPrimary()) { - if (mcParticle.pdgCode() == 2212) { - MC_proton_gen_reg.fill(HIST("histPt"), mcParticle.pt()); - } - if (mcParticle.pdgCode() == -2212) { - MC_aproton_gen_reg.fill(HIST("histPt"), mcParticle.pt()); - } - - if (mcParticle.pdgCode() == 1000010020) { - MC_deuteron_gen_reg.fill(HIST("histPt"), mcParticle.pt()); - } - - if (mcParticle.pdgCode() == -1000010020) { - MC_adeuteron_gen_reg.fill(HIST("histPt"), mcParticle.pt()); - } - - primaryparticles++; - } - particles++; - } - } - PROCESS_SWITCH(NucleiHistTask, processMC_generated, "process generated MC data", false); - - void processMC_tracked(soa::Join::iterator const& collision, soa::Filtered> const& tracks, aod::McParticles& mcParticles, aod::McCollisions const& mcCollisions) - { + MC_truth_reg.fill(HIST("histRecVtxMC"), collisions.posZ()); for (auto& track : tracks) { - const auto particle = track.mcParticle(); - if (!particle.isPhysicalPrimary()) { - continue; - } + const auto pdg = Form("%i", particle.pdgCode()); - float TPCnumberClsFound = track.tpcNClsFound(); - float TPC_nCls_Crossed_Rows = track.tpcNClsCrossedRows(); - float RatioCrossedRowsOverFindableTPC = track.tpcCrossedRowsOverFindableCls(); - float Chi2perClusterTPC = track.tpcChi2NCl(); - float Chi2perClusterITS = track.itsChi2NCl(); - - // track cuts - if (enable_PVcontributor_global && !(track.isPVContributor())) { + if (!particle.isPhysicalPrimary()) continue; - } - if (TPCnumberClsFound < minTPCnClsFound || TPC_nCls_Crossed_Rows < minNCrossedRowsTPC || RatioCrossedRowsOverFindableTPC < minRatioCrossedRowsTPC || RatioCrossedRowsOverFindableTPC > maxRatioCrossedRowsTPC || Chi2perClusterTPC > maxChi2TPC || Chi2perClusterITS > maxChi2ITS || !(track.passedTPCRefit()) || !(track.passedITSRefit()) || (track.itsNClsInnerBarrel()) < minReqClusterITSib || (track.itsNCls()) < minReqClusterITS) { - continue; - } - - // cut on rapidity - TLorentzVector lorentzVector_proton{}; - TLorentzVector lorentzVector_deuteron{}; - TLorentzVector lorentzVector_triton{}; - TLorentzVector lorentzVector_He3{}; - TLorentzVector lorentzVector_He4{}; - - lorentzVector_proton.SetPtEtaPhiM(track.pt(), track.eta(), track.phi(), constants::physics::MassProton); - lorentzVector_deuteron.SetPtEtaPhiM(track.pt(), track.eta(), track.phi(), constants::physics::MassDeuteron); - lorentzVector_triton.SetPtEtaPhiM(track.pt(), track.eta(), track.phi(), constants::physics::MassTriton); - lorentzVector_He3.SetPtEtaPhiM(track.pt() * 2.0, track.eta(), track.phi(), constants::physics::MassHelium3); - lorentzVector_He4.SetPtEtaPhiM(track.pt() * 2.0, track.eta(), track.phi(), constants::physics::MassAlpha); - - if (lorentzVector_proton.Rapidity() < yMin || lorentzVector_proton.Rapidity() > yMax || - lorentzVector_deuteron.Rapidity() < yMin || lorentzVector_deuteron.Rapidity() > yMax || - lorentzVector_triton.Rapidity() < yMin || lorentzVector_triton.Rapidity() > yMax || - lorentzVector_He3.Rapidity() < yMin || lorentzVector_He3.Rapidity() > yMax || - lorentzVector_He4.Rapidity() < yMin || lorentzVector_He4.Rapidity() > yMax) { - continue; - } - - // Proton - if (particle.pdgCode() == 2212) { - MC_proton_track_reg.fill(HIST("histPt"), track.pt()); - MC_proton_track_reg.fill(HIST("histTpcNsigmaData"), track.pt(), track.tpcNSigmaPr()); - MC_proton_track_reg.fill(HIST("histTofNsigmaData"), track.pt(), track.tofNSigmaPr()); - } - - // AntiProton - if (particle.pdgCode() == -2212) { - MC_aproton_track_reg.fill(HIST("histPt"), track.pt()); - MC_aproton_track_reg.fill(HIST("histTpcNsigmaData"), track.pt(), track.tpcNSigmaPr()); - MC_aproton_track_reg.fill(HIST("histTofNsigmaData"), track.pt(), track.tofNSigmaPr()); - } - - // Deuteron - if (particle.pdgCode() == 1000010020) { - MC_deuteron_track_reg.fill(HIST("histPt"), track.pt()); - MC_deuteron_track_reg.fill(HIST("histTpcNsigmaData"), track.pt(), track.tpcNSigmaDe()); - MC_deuteron_track_reg.fill(HIST("histTofNsigmaData"), track.pt(), track.tofNSigmaPr()); - } - - // Antideuteron - if (particle.pdgCode() == -1000010020) { - MC_adeuteron_track_reg.fill(HIST("histPt"), track.pt()); - MC_adeuteron_track_reg.fill(HIST("histTpcNsigmaData"), track.pt(), track.tpcNSigmaDe()); - MC_adeuteron_track_reg.fill(HIST("histTofNsigmaData"), track.pt(), track.tofNSigmaDe()); - } - } - } - PROCESS_SWITCH(NucleiHistTask, processMC_tracked, "process tracked MC data", false); - - void processMC_PID(soa::Join::iterator const& collision, soa::Filtered> const& tracks, aod::McParticles& mcParticles, aod::McCollisions const& mcCollisions) - { - - for (auto& track : tracks) { + histPDG->Fill(pdg, 1); + const float pdgbin = histPDG->GetXaxis()->GetBinCenter(histPDG->GetXaxis()->FindBin(pdg)); + + MC_truth_reg.fill(HIST("histPhi"), particle.phi(), pdgbin); + MC_truth_reg.fill(HIST("histEta"), particle.eta(), pdgbin); + MC_truth_reg.fill(HIST("histPt"), particle.pt(), pdgbin); + + MC_recon_reg.fill(HIST("histPhi"), track.phi(), pdgbin); + MC_recon_reg.fill(HIST("histEta"), track.eta(), pdgbin); + MC_recon_reg.fill(HIST("histPt"), track.pt(), pdgbin); + MC_recon_reg.fill(HIST("histDCA"), track.pt(), track.dcaXY(), pdgbin); + MC_recon_reg.fill(HIST("histDCAz"), track.pt(), track.dcaZ(), pdgbin); + MC_recon_reg.fill(HIST("histTpcSignalData"), track.pt() * track.sign(), track.tpcSignal(), pdgbin); + MC_recon_reg.fill(HIST("histNClusterTPC"), track.pt(), track.tpcNClsCrossedRows(), pdgbin); + MC_recon_reg.fill(HIST("histNClusterITS"), track.pt(), track.itsNCls(), pdgbin); + MC_recon_reg.fill(HIST("histNClusterITSib"), track.pt(), track.itsNClsInnerBarrel(), pdgbin); + MC_recon_reg.fill(HIST("histTPCnClsFindable"), track.pt(), track.tpcNClsFindable(), pdgbin); + MC_recon_reg.fill(HIST("histTPCnClsFindableMinusFound"), track.pt(), track.tpcNClsFindableMinusFound(), pdgbin); + MC_recon_reg.fill(HIST("histTPCnClsFindableMinusCrossedRows"), track.pt(), track.tpcNClsFindableMinusCrossedRows(), pdgbin); + MC_recon_reg.fill(HIST("histTPCnClsShared"), track.pt(), track.tpcNClsShared(), pdgbin); + MC_recon_reg.fill(HIST("histTPCCrossedRowsOverFindableCls"), track.tpcCrossedRowsOverFindableCls(), pdgbin); + MC_recon_reg.fill(HIST("histTPCFoundOverFindable"), track.tpcFoundOverFindableCls(), pdgbin); + MC_recon_reg.fill(HIST("histChi2TPC"), track.pt(), track.tpcChi2NCl(), pdgbin); + MC_recon_reg.fill(HIST("histChi2ITS"), track.pt(), track.itsChi2NCl(), pdgbin); + MC_recon_reg.fill(HIST("histChi2ITSvsITSnCls"), track.itsChi2NCl(), track.itsNCls()); + MC_recon_reg.fill(HIST("histChi2ITSvsITSibnCls"), track.itsChi2NCl(), track.itsNClsInnerBarrel()); + MC_recon_reg.fill(HIST("histChi2ITSvsITSnClsAll"), track.itsChi2NCl(), track.itsNCls()); + MC_recon_reg.fill(HIST("histChi2ITSvsITSnClsAll"), track.itsChi2NCl(), track.itsNClsInnerBarrel()); + MC_recon_reg.fill(HIST("histChi2TOF"), track.pt(), track.tofChi2(), pdgbin); + MC_recon_reg.fill(HIST("histTrackLength"), track.length(), pdgbin); + MC_recon_reg.fill(HIST("histTPCFractionSharedCls"), track.tpcFractionSharedCls(), pdgbin); if (track.sign() > 0) { - MC_spectra_reconstructed_reg.fill(HIST("histDcaZVsPtData_particle"), track.pt(), track.dcaZ()); - MC_spectra_reconstructed_reg.fill(HIST("histDcaVsPtData_particle"), track.pt(), track.dcaXY()); + MC_recon_reg.fill(HIST("histTpcNsigmaDataPr"), track.pt(), track.tpcNSigmaPr()); + MC_recon_reg.fill(HIST("histTpcNsigmaDataDe"), track.pt(), track.tpcNSigmaDe()); + MC_recon_reg.fill(HIST("histTpcNsigmaDataTr"), track.pt(), track.tpcNSigmaTr()); + MC_recon_reg.fill(HIST("histTpcNsigmaDataHe"), track.pt(), track.tpcNSigmaHe()); + MC_recon_reg.fill(HIST("histTpcNsigmaDataAl"), track.pt(), track.tpcNSigmaAl()); } - if (track.sign() < 0) { - MC_spectra_reconstructed_reg.fill(HIST("histDcaZVsPtData_antiparticle"), track.pt(), track.dcaZ()); - MC_spectra_reconstructed_reg.fill(HIST("histDcaVsPtData_antiparticle"), track.pt(), track.dcaXY()); - } - - const auto particle = track.mcParticle(); - if (!particle.isPhysicalPrimary()) { - continue; - } - - float TPCnumberClsFound = track.tpcNClsFound(); - float TPC_nCls_Crossed_Rows = track.tpcNClsCrossedRows(); - float RatioCrossedRowsOverFindableTPC = track.tpcCrossedRowsOverFindableCls(); - float Chi2perClusterTPC = track.tpcChi2NCl(); - float Chi2perClusterITS = track.itsChi2NCl(); - - // track cuts - if (enable_PVcontributor_global && !(track.isPVContributor())) { - continue; - } - - if (TPCnumberClsFound < minTPCnClsFound || TPC_nCls_Crossed_Rows < minNCrossedRowsTPC || RatioCrossedRowsOverFindableTPC < minRatioCrossedRowsTPC || RatioCrossedRowsOverFindableTPC > maxRatioCrossedRowsTPC || Chi2perClusterTPC > maxChi2TPC || Chi2perClusterITS > maxChi2ITS || !(track.passedTPCRefit()) || !(track.passedITSRefit()) || (track.itsNClsInnerBarrel()) < minReqClusterITSib || (track.itsNCls()) < minReqClusterITS) { - continue; - } - - // cut on rapidity - TLorentzVector lorentzVector_proton{}; - TLorentzVector lorentzVector_deuteron{}; - TLorentzVector lorentzVector_triton{}; - TLorentzVector lorentzVector_He3{}; - TLorentzVector lorentzVector_He4{}; - - lorentzVector_proton.SetPtEtaPhiM(track.pt(), track.eta(), track.phi(), constants::physics::MassProton); - lorentzVector_deuteron.SetPtEtaPhiM(track.pt(), track.eta(), track.phi(), constants::physics::MassDeuteron); - lorentzVector_triton.SetPtEtaPhiM(track.pt(), track.eta(), track.phi(), constants::physics::MassTriton); - lorentzVector_He3.SetPtEtaPhiM(track.pt() * 2.0, track.eta(), track.phi(), constants::physics::MassHelium3); - lorentzVector_He4.SetPtEtaPhiM(track.pt() * 2.0, track.eta(), track.phi(), constants::physics::MassAlpha); - - if (lorentzVector_proton.Rapidity() < yMin || lorentzVector_proton.Rapidity() > yMax || - lorentzVector_deuteron.Rapidity() < yMin || lorentzVector_deuteron.Rapidity() > yMax || - lorentzVector_triton.Rapidity() < yMin || lorentzVector_triton.Rapidity() > yMax || - lorentzVector_He3.Rapidity() < yMin || lorentzVector_He3.Rapidity() > yMax || - lorentzVector_He4.Rapidity() < yMin || lorentzVector_He4.Rapidity() > yMax) { - continue; - } - - float nSigmaProton = track.tpcNSigmaPr(); - float nSigmaProtonTOF = track.tofNSigmaPr(); - float nSigmaDeuteron = track.tpcNSigmaDe(); - float nSigmaDeuteronTOF = track.tofNSigmaDe(); - - // matter - if (track.sign() > 0) { - - // proton - MC_proton_PID_reg.fill(HIST("histTpcNsigmaData"), track.pt(), track.tpcNSigmaPr()); - if (nSigmaProton < nsigmacutHigh && nSigmaProton > nsigmacutLow) { - MC_proton_PID_reg.fill(HIST("histPt_tpc"), track.pt()); - - if (track.hasTOF()) { - - if (track.hasTRD() && (lastRequiredTrdCluster > 0)) { - int lastLayer = 0; - for (int l = 7; l >= 0; l--) { - if (track.trdPattern() & (1 << l)) { - lastLayer = l; - break; - } - } - if (lastLayer < lastRequiredTrdCluster) { - continue; - } - } - - MC_proton_PID_reg.fill(HIST("histTofNsigmaData"), track.pt(), track.tofNSigmaPr()); - if (nSigmaProtonTOF < nsigmacutHigh && nSigmaProtonTOF > nsigmacutLow) { - MC_proton_PID_reg.fill(HIST("histPt_tof"), track.pt()); - } - } - } - - // deuteron - MC_deuteron_PID_reg.fill(HIST("histTpcNsigmaData"), track.pt(), track.tpcNSigmaDe()); - if (nSigmaDeuteron < nsigmacutHigh && nSigmaDeuteron > nsigmacutLow) { - MC_deuteron_PID_reg.fill(HIST("histPt_tpc"), track.pt()); - - if (track.hasTOF()) { - - if (track.hasTRD() && (lastRequiredTrdCluster > 0)) { - int lastLayer = 0; - for (int l = 7; l >= 0; l--) { - if (track.trdPattern() & (1 << l)) { - lastLayer = l; - break; - } - } - if (lastLayer < lastRequiredTrdCluster) { - continue; - } - } - - MC_deuteron_PID_reg.fill(HIST("histTofNsigmaData"), track.pt(), track.tofNSigmaDe()); - if (nSigmaDeuteronTOF < (nsigmacutHigh - 1) && nSigmaDeuteronTOF > (nsigmacutLow + 1)) { - MC_deuteron_PID_reg.fill(HIST("histPt_tof"), track.pt()); - } - } - } + MC_recon_reg.fill(HIST("histTpcNsigmaDataaPr"), track.pt(), track.tpcNSigmaPr()); + MC_recon_reg.fill(HIST("histTpcNsigmaDataaDe"), track.pt(), track.tpcNSigmaDe()); + MC_recon_reg.fill(HIST("histTpcNsigmaDataaTr"), track.pt(), track.tpcNSigmaTr()); + MC_recon_reg.fill(HIST("histTpcNsigmaDataaHe"), track.pt(), track.tpcNSigmaHe()); + MC_recon_reg.fill(HIST("histTpcNsigmaDataaAl"), track.pt(), track.tpcNSigmaAl()); } - // antimatter - if (track.sign() < 0) { + if (track.hasTOF()) { + Float_t TOFmass2 = ((track.mass()) * (track.mass())); - // antiproton - MC_aproton_PID_reg.fill(HIST("histTpcNsigmaData"), track.pt(), track.tpcNSigmaPr()); - if (nSigmaProton < nsigmacutHigh && nSigmaProton > nsigmacutLow) { - MC_aproton_PID_reg.fill(HIST("histPt_tpc"), track.pt()); - - if (track.hasTOF()) { + MC_recon_reg.fill(HIST("histTOFm2"), track.pt(), TOFmass2, pdgbin); + MC_recon_reg.fill(HIST("histTofSignalData"), track.pt() * track.sign(), track.beta(), pdgbin); - if (track.hasTRD() && (lastRequiredTrdCluster > 0)) { - int lastLayer = 0; - for (int l = 7; l >= 0; l--) { - if (track.trdPattern() & (1 << l)) { - lastLayer = l; - break; - } - } - if (lastLayer < lastRequiredTrdCluster) { - continue; - } - } - - MC_aproton_PID_reg.fill(HIST("histTofNsigmaData"), track.pt(), track.tofNSigmaPr()); - if (nSigmaProtonTOF < nsigmacutHigh && nSigmaProtonTOF > nsigmacutLow) { - MC_aproton_PID_reg.fill(HIST("histPt_tof"), track.pt()); - } - } + if (track.sign() > 0) { + MC_recon_reg.fill(HIST("histTofNsigmaDataPr"), track.pt(), track.tofNSigmaPr()); + MC_recon_reg.fill(HIST("histTofNsigmaDataDe"), track.pt(), track.tofNSigmaDe()); + MC_recon_reg.fill(HIST("histTofNsigmaDataTr"), track.pt(), track.tofNSigmaTr()); + MC_recon_reg.fill(HIST("histTofNsigmaDataHe"), track.pt(), track.tofNSigmaHe()); + MC_recon_reg.fill(HIST("histTofNsigmaDataAl"), track.pt(), track.tofNSigmaAl()); } - - // antideuteron - MC_adeuteron_PID_reg.fill(HIST("histTpcNsigmaData"), track.pt(), track.tpcNSigmaDe()); - if (nSigmaDeuteron < nsigmacutHigh && nSigmaDeuteron > nsigmacutLow) { - MC_adeuteron_PID_reg.fill(HIST("histPt_tpc"), track.pt()); - - if (track.hasTOF()) { - - if (track.hasTRD() && (lastRequiredTrdCluster > 0)) { - int lastLayer = 0; - for (int l = 7; l >= 0; l--) { - if (track.trdPattern() & (1 << l)) { - lastLayer = l; - break; - } - } - if (lastLayer < lastRequiredTrdCluster) { - continue; - } - } - - MC_adeuteron_PID_reg.fill(HIST("histTofNsigmaData"), track.pt(), track.tofNSigmaDe()); - if (nSigmaDeuteronTOF < (nsigmacutHigh - 1) && nSigmaDeuteronTOF > (nsigmacutLow + 1)) { - MC_adeuteron_PID_reg.fill(HIST("histPt_tof"), track.pt()); - } - } + if (track.sign() < 0) { + MC_recon_reg.fill(HIST("histTofNsigmaDataaPr"), track.pt(), track.tofNSigmaPr()); + MC_recon_reg.fill(HIST("histTofNsigmaDataaDe"), track.pt(), track.tofNSigmaDe()); + MC_recon_reg.fill(HIST("histTofNsigmaDataaTr"), track.pt(), track.tofNSigmaTr()); + MC_recon_reg.fill(HIST("histTofNsigmaDataaHe"), track.pt(), track.tofNSigmaHe()); + MC_recon_reg.fill(HIST("histTofNsigmaDataaAl"), track.pt(), track.tofNSigmaAl()); } } - } - } - PROCESS_SWITCH(NucleiHistTask, processMC_PID, "process PID MC data", false); - void processMC_primary_fraction(soa::Join::iterator const& collision, soa::Filtered> const& tracks, aod::McParticles& mcParticles, aod::McCollisions const& mcCollisions) - { - - for (auto& track : tracks) { - - float TPCnumberClsFound = track.tpcNClsFound(); - float TPC_nCls_Crossed_Rows = track.tpcNClsCrossedRows(); - float RatioCrossedRowsOverFindableTPC = track.tpcCrossedRowsOverFindableCls(); - float Chi2perClusterTPC = track.tpcChi2NCl(); - float Chi2perClusterITS = track.itsChi2NCl(); - - // track cuts - if (enable_PVcontributor_global && !(track.isPVContributor())) { - continue; - } - - if (TPCnumberClsFound < minTPCnClsFound || TPC_nCls_Crossed_Rows < minNCrossedRowsTPC || RatioCrossedRowsOverFindableTPC < minRatioCrossedRowsTPC || RatioCrossedRowsOverFindableTPC > maxRatioCrossedRowsTPC || Chi2perClusterTPC > maxChi2TPC || Chi2perClusterITS > maxChi2ITS || !(track.passedTPCRefit()) || !(track.passedITSRefit()) || (track.itsNClsInnerBarrel()) < minReqClusterITSib || (track.itsNCls()) < minReqClusterITS) { - continue; - } - - // cut on rapidity - TLorentzVector lorentzVector_proton{}; - TLorentzVector lorentzVector_deuteron{}; - TLorentzVector lorentzVector_triton{}; - TLorentzVector lorentzVector_He3{}; - TLorentzVector lorentzVector_He4{}; - - lorentzVector_proton.SetPtEtaPhiM(track.pt(), track.eta(), track.phi(), constants::physics::MassProton); - lorentzVector_deuteron.SetPtEtaPhiM(track.pt(), track.eta(), track.phi(), constants::physics::MassDeuteron); - lorentzVector_triton.SetPtEtaPhiM(track.pt(), track.eta(), track.phi(), constants::physics::MassTriton); - lorentzVector_He3.SetPtEtaPhiM(track.pt() * 2.0, track.eta(), track.phi(), constants::physics::MassHelium3); - lorentzVector_He4.SetPtEtaPhiM(track.pt() * 2.0, track.eta(), track.phi(), constants::physics::MassAlpha); - - if (lorentzVector_proton.Rapidity() < yMin || lorentzVector_proton.Rapidity() > yMax || - lorentzVector_deuteron.Rapidity() < yMin || lorentzVector_deuteron.Rapidity() > yMax || - lorentzVector_triton.Rapidity() < yMin || lorentzVector_triton.Rapidity() > yMax || - lorentzVector_He3.Rapidity() < yMin || lorentzVector_He3.Rapidity() > yMax || - lorentzVector_He4.Rapidity() < yMin || lorentzVector_He4.Rapidity() > yMax) { - continue; - } - - const auto particle = track.mcParticle(); - - // Proton - if (particle.pdgCode() == 2212) { - MC_proton_PR_reg.fill(HIST("histDcaVsPtData"), track.pt(), track.dcaXY()); - MC_proton_PR_reg.fill(HIST("histDcaZVsPtData"), track.pt(), track.dcaZ()); + MC_recon_diff_reg.fill(HIST("histEtaDiff"), particle.eta() - track.eta(), pdgbin); + auto delta = particle.phi() - track.phi(); + if (delta > TMath::Pi()) { + delta -= 2 * TMath::Pi(); } - - // AntiProton - if (particle.pdgCode() == -2212) { - MC_aproton_PR_reg.fill(HIST("histDcaVsPtData"), track.pt(), track.dcaXY()); - MC_aproton_PR_reg.fill(HIST("histDcaZVsPtData"), track.pt(), track.dcaZ()); - } - - // Deuteron - if (particle.pdgCode() == 1000010020) { - MC_deuteron_PR_reg.fill(HIST("histDcaVsPtData"), track.pt(), track.dcaXY()); - MC_deuteron_PR_reg.fill(HIST("histDcaZVsPtData"), track.pt(), track.dcaZ()); - } - - // Antideuteron - if (particle.pdgCode() == -1000010020) { - MC_adeuteron_PR_reg.fill(HIST("histDcaVsPtData"), track.pt(), track.dcaXY()); - MC_adeuteron_PR_reg.fill(HIST("histDcaZVsPtData"), track.pt(), track.dcaZ()); + if (delta < -TMath::Pi()) { + delta += 2 * TMath::Pi(); } - if (particle.isPhysicalPrimary()) { // primary particles - - // Proton - if (particle.pdgCode() == 2212) { - MC_proton_PR_reg.fill(HIST("histDcaVsPtData_isPP"), track.pt(), track.dcaXY()); - MC_proton_PR_reg.fill(HIST("histDcaZVsPtData_isPP"), track.pt(), track.dcaZ()); - } - - // AntiProton - if (particle.pdgCode() == -2212) { - MC_aproton_PR_reg.fill(HIST("histDcaVsPtData_isPP"), track.pt(), track.dcaXY()); - MC_aproton_PR_reg.fill(HIST("histDcaZVsPtData_isPP"), track.pt(), track.dcaZ()); - } - - // Deuteron - if (particle.pdgCode() == 1000010020) { - MC_deuteron_PR_reg.fill(HIST("histDcaVsPtData_isPP"), track.pt(), track.dcaXY()); - MC_deuteron_PR_reg.fill(HIST("histDcaZVsPtData_isPP"), track.pt(), track.dcaZ()); - } - - // Antideuteron - if (particle.pdgCode() == -1000010020) { - MC_adeuteron_PR_reg.fill(HIST("histDcaVsPtData_isPP"), track.pt(), track.dcaXY()); - MC_adeuteron_PR_reg.fill(HIST("histDcaZVsPtData_isPP"), track.pt(), track.dcaZ()); - } - - } else { - - if (particle.getProcess() == 4) { // secondary from decay - - // Proton - if (particle.pdgCode() == 2212) { - MC_proton_PR_reg.fill(HIST("histDcaVsPtData_isDec"), track.pt(), track.dcaXY()); - MC_proton_PR_reg.fill(HIST("histDcaZVsPtData_isDec"), track.pt(), track.dcaZ()); - } - - // AntiProton - if (particle.pdgCode() == -2212) { - MC_aproton_PR_reg.fill(HIST("histDcaVsPtData_isDec"), track.pt(), track.dcaXY()); - MC_aproton_PR_reg.fill(HIST("histDcaZVsPtData_isDec"), track.pt(), track.dcaZ()); - } - - // Deuteron - if (particle.pdgCode() == 1000010020) { - MC_deuteron_PR_reg.fill(HIST("histDcaVsPtData_isDec"), track.pt(), track.dcaXY()); - MC_deuteron_PR_reg.fill(HIST("histDcaZVsPtData_isDec"), track.pt(), track.dcaZ()); - } - - // Antideuteron - if (particle.pdgCode() == -1000010020) { - MC_adeuteron_PR_reg.fill(HIST("histDcaVsPtData_isDec"), track.pt(), track.dcaXY()); - MC_adeuteron_PR_reg.fill(HIST("histDcaZVsPtData_isDec"), track.pt(), track.dcaZ()); - } - - } else { // secondary from material - - // Proton - if (particle.pdgCode() == 2212) { - MC_proton_PR_reg.fill(HIST("histDcaVsPtData_isMat"), track.pt(), track.dcaXY()); - MC_proton_PR_reg.fill(HIST("histDcaZVsPtData_isMat"), track.pt(), track.dcaZ()); - } - - // AntiProton - if (particle.pdgCode() == -2212) { - MC_aproton_PR_reg.fill(HIST("histDcaVsPtData_isMat"), track.pt(), track.dcaXY()); - MC_aproton_PR_reg.fill(HIST("histDcaZVsPtData_isMat"), track.pt(), track.dcaZ()); - } - - // Deuteron - if (particle.pdgCode() == 1000010020) { - MC_deuteron_PR_reg.fill(HIST("histDcaVsPtData_isMat"), track.pt(), track.dcaXY()); - MC_deuteron_PR_reg.fill(HIST("histDcaZVsPtData_isMat"), track.pt(), track.dcaZ()); - } - - // Antideuteron - if (particle.pdgCode() == -1000010020) { - MC_adeuteron_PR_reg.fill(HIST("histDcaVsPtData_isMat"), track.pt(), track.dcaXY()); - MC_adeuteron_PR_reg.fill(HIST("histDcaZVsPtData_isMat"), track.pt(), track.dcaZ()); - } - } - } + MC_recon_diff_reg.fill(HIST("histPhiDiff"), delta, pdgbin); + MC_recon_diff_reg.fill(HIST("histPtDiff"), particle.pt() - track.pt(), pdgbin); } } - PROCESS_SWITCH(NucleiHistTask, processMC_primary_fraction, "process MC primary fraction", false); + PROCESS_SWITCH(NucleiHistTask, processMC, "process MC", false); }; //**************************************************************************************************** diff --git a/PWGLF/Tasks/QAHistTask.cxx b/PWGLF/Tasks/Nuspex/QAHistTask.cxx similarity index 86% rename from PWGLF/Tasks/QAHistTask.cxx rename to PWGLF/Tasks/Nuspex/QAHistTask.cxx index d59d946aa86..614e3962054 100644 --- a/PWGLF/Tasks/QAHistTask.cxx +++ b/PWGLF/Tasks/Nuspex/QAHistTask.cxx @@ -75,11 +75,14 @@ struct QAHistTask { species = "He4"; std::vector ptBinning = {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.8, 2.0, 2.2, 2.4, 2.8, 3.2, 3.6, 4., 5., 6., 8., 10., 12., 14.}; + std::vector ptBinning_short = {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.8, 2.0, 2.2, 2.4, 2.8, 3.2}; std::vector ptBinning_diff = {-14.0, -12.0, -10.0, -8.0, -6.0, -5.0, -4.0, -3.6, -3.2, -2.8, -2.4, -2.2, -2.0, -1.8, -1.6, -1.4, -1.3, -1.2, -1.1, -1.0, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 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.8, 2.0, 2.2, 2.4, 2.8, 3.2, 3.6, 4., 5., 6., 8., 10., 12., 14.}; std::vector centBinning = {0., 1., 5., 10., 20., 30., 40., 50., 70., 100.}; std::vector etaBinning = {-1.0, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}; AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec ptAxis_short = {ptBinning_short, "Global #it{p}_{T} (GeV/#it{c})"}; + AxisSpec ptAxisITS_TPC = {ptBinning_short, "ITS-TPC #it{p}_{T} (GeV/#it{c})"}; AxisSpec centAxis = {centBinning, "V0M (%)"}; AxisSpec centralityAxis = {100, 0.0, 100.0, "VT0C (%)"}; AxisSpec centralityAxis_extended = {105, 0.0, 105.0, "VT0C (%)"}; @@ -111,11 +114,17 @@ struct QAHistTask { QA_reg.add("histTPCFractionSharedCls", "Fraction of shared TPC clusters", HistType::kTH1F, {{100, -2.0, 2.0, "Shared Cls"}}); QA_reg.add("histChi2TPC", "chi^2 TPC vs Pt", HistType::kTH2F, {ptAxis, {100, 0.0, 5.0, "chi^2"}}); QA_reg.add("histChi2ITS", "chi^2 ITS vs Pt", HistType::kTH2F, {ptAxis, {500, 0.0, 50.0, "chi^2"}}); + QA_reg.add("histChi2ITSvsITSnCls", "chi^2 ITS vs ITS nCls", HistType::kTH2F, {{125, 0.0, 50.0, "chi^2"}, {10, 0.0, 10.0, "ITS nCls"}}); + QA_reg.add("histChi2ITSvsITSibnCls", "chi^2 ITS vs ITS ib nCls", HistType::kTH2F, {{125, 0.0, 50.0, "chi^2"}, {10, 0.0, 10.0, "ITS ib nCls"}}); + QA_reg.add("histChi2ITSvsITSnClsAll", "chi^2 ITS vs ITS nCls", HistType::kTH2F, {{125, 0.0, 50.0, "chi^2"}, {10, 0.0, 10.0, "ITS nCls"}}); QA_reg.add("histChi2TOF", "chi^2 TOF vs Pt", HistType::kTH2F, {ptAxis, {75, 0.0, 15.0, "chi^2"}}); QA_reg.add("histEtaWithOverFlow", "Pseudorapidity 0 - 105%% centrality", HistType::kTH1F, {etaAxis}); QA_reg.add("histEta", "Pseudorapidity with centrality cut", HistType::kTH1F, {etaAxis}); QA_reg.add("histEta_cent", "Pseudorapidity vs Centrality", HistType::kTH2F, {centralityAxis_extended, etaAxis}); QA_reg.add("histTrackLength", "Track length", HistType::kTH1F, {{350, 0., 700., "length (cm)"}}); + QA_reg.add("histDcaVsPID", "DCA XY vs PID hypothesis", HistType::kTH2F, {{1000, -2.0, 2.0, "dca XY"}, {10, 0.0, 10.0, "PID ID"}}); + QA_reg.add("histDcaZVsPID", "DCA Z vs PID hypothesis", HistType::kTH2F, {{1000, -2.0, 2.0, "dca Z"}, {10, 0.0, 10.0, "PID ID"}}); + QA_reg.add("histpTCorralation", "global pT vs ITS-TPC pT", HistType::kTH2F, {ptAxis_short, ptAxisITS_TPC}); // QA choosen species (positive) QA_species_pos.add("histTpcSignalData", Form("Specific energy loss (%s)", species.c_str()), HistType::kTH2F, {{600, -6., 6., "#it{p} (GeV/#it{c})"}, {5000, 0, 5000, "d#it{E} / d#it{X} (a. u.)"}}); @@ -124,8 +133,8 @@ struct QAHistTask { QA_species_pos.add("histDcaZVsPtData", Form("dcaZ vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); QA_species_pos.add("histTOFm2", Form("TOF m^2 vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {400, 0.0, 10.0, "m^2"}}); QA_species_pos.add("histNClusterTPC", Form("Number of Clusters in TPC vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {80, 0.0, 160.0, "nCluster"}}); - QA_species_pos.add("histNClusterITS", Form("Number of Clusters in ITS vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {10, 0.0, 10.0, "nCluster"}}); - QA_species_pos.add("histNClusterITSib", Form("Number of Clusters in ib of ITS vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {10, 0.0, 10.0, "nCluster"}}); + QA_species_pos.add("histNClusterITS", Form("Number of Clusters in ITS vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {10, 0.0, 10.0, "ITS nCls"}}); + QA_species_pos.add("histNClusterITSib", Form("Number of Clusters in ib of ITS vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {10, 0.0, 10.0, "ITS ib nCls"}}); QA_species_pos.add("histTPCnClsFindable", Form("Findable TPC clusters (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {200, 0.0, 200.0, "nCluster"}}); QA_species_pos.add("histTPCnClsFindableMinusFound", Form("TPC Clusters: Findable - Found (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {60, 0.0, 60.0, "nCluster"}}); QA_species_pos.add("histTPCnClsFindableMinusCrossedRows", Form("TPC Clusters: Findable - crossed rows (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {60, 0.0, 60.0, "nCluster"}}); @@ -134,12 +143,16 @@ struct QAHistTask { QA_species_pos.add("histTPCFoundOverFindable", Form("Ratio of found over findable clusters (%s)", species.c_str()), HistType::kTH1F, {{100, 0., 2.0, "Found Cls / Findable Cls"}}); QA_species_pos.add("histTPCFractionSharedCls", Form("Fraction of shared TPC clusters (%s)", species.c_str()), HistType::kTH1F, {{100, -2.0, 2.0, "Shared Cls"}}); QA_species_pos.add("histChi2TPC", Form("chi^2 TPC vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {100, 0.0, 5.0, "chi^2"}}); - QA_species_pos.add("histChi2ITS", Form("chi^2 ITS vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {500, 0.0, 50.0, "chi^2"}}); + QA_species_pos.add("histChi2ITS", Form("chi^2 ITS vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {125, 0.0, 50.0, "chi^2"}}); + QA_species_pos.add("histChi2ITSvsITSnCls", "chi^2 ITS vs ITS nCls", HistType::kTH2F, {{125, 0.0, 50.0, "chi^2"}, {10, 0.0, 10.0, "ITS nCls"}}); + QA_species_pos.add("histChi2ITSvsITSibnCls", "chi^2 ITS vs ITS ib nCls", HistType::kTH2F, {{125, 0.0, 50.0, "chi^2"}, {10, 0.0, 10.0, "ITS ib nCls"}}); + QA_species_pos.add("histChi2ITSvsITSnClsAll", "chi^2 ITS vs ITS nCls", HistType::kTH2F, {{125, 0.0, 50.0, "chi^2"}, {10, 0.0, 10.0, "ITS nCls"}}); QA_species_pos.add("histChi2TOF", Form("chi^2 TOF vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {75, 0.0, 15.0, "chi^2"}}); QA_species_pos.add("histEtaWithOverFlow", Form("Pseudorapidity 0 - 105%% centrality (%s)", species.c_str()), HistType::kTH1F, {etaAxis}); QA_species_pos.add("histEta", Form("Pseudorapidity with centrality cut (%s)", species.c_str()), HistType::kTH1F, {etaAxis}); QA_species_pos.add("histEta_cent", Form("Pseudorapidity vs Centrality (%s)", species.c_str()), HistType::kTH2F, {centralityAxis_extended, etaAxis}); QA_species_pos.add("histTrackLength", Form("Track length (%s)", species.c_str()), HistType::kTH1F, {{350, 0., 700., "length (cm)"}}); + QA_species_pos.add("histpTCorralation", "global pT vs ITS-TPC pT", HistType::kTH2F, {ptAxis_short, ptAxisITS_TPC}); // QA choosen species (negative) QA_species_neg.add("histTpcSignalData", Form("Specific energy loss (anti-%s)", species.c_str()), HistType::kTH2F, {{600, -6., 6., "#it{p} (GeV/#it{c})"}, {5000, 0, 5000, "d#it{E} / d#it{X} (a. u.)"}}); @@ -148,8 +161,8 @@ struct QAHistTask { QA_species_neg.add("histDcaZVsPtData", Form("dcaZ vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {1000, -2.0, 2.0, "dca"}}); QA_species_neg.add("histTOFm2", Form("TOF m^2 vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {400, 0.0, 10.0, "m^2"}}); QA_species_neg.add("histNClusterTPC", Form("Number of Clusters in TPC vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {80, 0.0, 160.0, "nCluster"}}); - QA_species_neg.add("histNClusterITS", Form("Number of Clusters in ITS vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {10, 0.0, 10.0, "nCluster"}}); - QA_species_neg.add("histNClusterITSib", Form("Number of Clusters in ib of ITS vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {10, 0.0, 10.0, "nCluster"}}); + QA_species_neg.add("histNClusterITS", Form("Number of Clusters in ITS vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {10, 0.0, 10.0, "ITS nCls"}}); + QA_species_neg.add("histNClusterITSib", Form("Number of Clusters in ib of ITS vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {10, 0.0, 10.0, "ITS ib nCls"}}); QA_species_neg.add("histTPCnClsFindable", Form("Findable TPC clusters (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {200, 0.0, 200.0, "nCluster"}}); QA_species_neg.add("histTPCnClsFindableMinusFound", Form("TPC Clusters: Findable - Found (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {60, 0.0, 60.0, "nCluster"}}); QA_species_neg.add("histTPCnClsFindableMinusCrossedRows", Form("TPC Clusters: Findable - crossed rows (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {60, 0.0, 60.0, "nCluster"}}); @@ -158,12 +171,16 @@ struct QAHistTask { QA_species_neg.add("histTPCFoundOverFindable", Form("Ratio of found over findable clusters (%s)", species.c_str()), HistType::kTH1F, {{100, 0., 2.0, "Found Cls / Findable Cls"}}); QA_species_neg.add("histTPCFractionSharedCls", Form("Fraction of shared TPC clusters (%s)", species.c_str()), HistType::kTH1F, {{100, -2.0, 2.0, "Shared Cls"}}); QA_species_neg.add("histChi2TPC", Form("chi^2 TPC vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {100, 0.0, 5.0, "chi^2"}}); - QA_species_neg.add("histChi2ITS", Form("chi^2 ITS vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {500, 0.0, 50.0, "chi^2"}}); + QA_species_neg.add("histChi2ITS", Form("chi^2 ITS vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {125, 0.0, 50.0, "chi^2"}}); + QA_species_neg.add("histChi2ITSvsITSnCls", "chi^2 ITS vs ITS nCls", HistType::kTH2F, {{125, 0.0, 50.0, "chi^2"}, {10, 0.0, 10.0, "ITS nCls"}}); + QA_species_neg.add("histChi2ITSvsITSibnCls", "chi^2 ITS vs ITS ib nCls", HistType::kTH2F, {{125, 0.0, 50.0, "chi^2"}, {10, 0.0, 10.0, "ITS ib nCls"}}); + QA_species_neg.add("histChi2ITSvsITSnClsAll", "chi^2 ITS vs ITS nCls", HistType::kTH2F, {{125, 0.0, 50.0, "chi^2"}, {10, 0.0, 10.0, "ITS nCls"}}); QA_species_neg.add("histChi2TOF", Form("chi^2 TOF vs Pt (%s)", species.c_str()), HistType::kTH2F, {ptAxis, {75, 0.0, 15.0, "chi^2"}}); QA_species_neg.add("histEtaWithOverFlow", Form("Pseudorapidity 0 - 105%% centrality (%s)", species.c_str()), HistType::kTH1F, {etaAxis}); QA_species_neg.add("histEta", Form("Pseudorapidity with centrality cut (%s)", species.c_str()), HistType::kTH1F, {etaAxis}); QA_species_neg.add("histEta_cent", Form("Pseudorapidity vs Centrality (%s)", species.c_str()), HistType::kTH2F, {centralityAxis_extended, etaAxis}); QA_species_neg.add("histTrackLength", Form("Track length (%s)", species.c_str()), HistType::kTH1F, {{350, 0., 700., "length (cm)"}}); + QA_species_neg.add("histpTCorralation", "global pT vs ITS-TPC pT", HistType::kTH2F, {ptAxis_short, ptAxisITS_TPC}); // MC truth MC_truth_reg.add("histPhi", "#phi", HistType::kTH2F, {{100, 0., 2. * TMath::Pi()}, PDGBINNING}); @@ -181,8 +198,8 @@ struct QAHistTask { MC_recon_reg.add("histTofSignalData", "TOF signal", HistType::kTH3F, {{600, -6., 6., "#it{p} (GeV/#it{c})"}, {550, 0.0, 1.1, "#beta (TOF)"}, PDGBINNING}); MC_recon_reg.add("histTOFm2", "TOF m^2 vs Pt", HistType::kTH3F, {ptAxis, {400, 0.0, 10.0, "m^2"}, PDGBINNING}); MC_recon_reg.add("histNClusterTPC", "Number of Clusters in TPC vs Pt", HistType::kTH3F, {ptAxis, {80, 0.0, 160.0, "nCluster"}, PDGBINNING}); - MC_recon_reg.add("histNClusterITS", "Number of Clusters in ITS vs Pt", HistType::kTH3F, {ptAxis, {10, 0.0, 10.0, "nCluster"}, PDGBINNING}); - MC_recon_reg.add("histNClusterITSib", "Number of Clusters in ib of ITS vs Pt", HistType::kTH3F, {ptAxis, {10, 0.0, 10.0, "nCluster"}, PDGBINNING}); + MC_recon_reg.add("histNClusterITS", "Number of Clusters in ITS vs Pt", HistType::kTH3F, {ptAxis, {10, 0.0, 10.0, "ITS nCls"}, PDGBINNING}); + MC_recon_reg.add("histNClusterITSib", "Number of Clusters in ib of ITS vs Pt", HistType::kTH3F, {ptAxis, {10, 0.0, 10.0, "ITS ib nCls"}, PDGBINNING}); MC_recon_reg.add("histTPCnClsFindable", "Findable TPC clusters", HistType::kTH3F, {ptAxis, {200, 0.0, 200.0, "nCluster"}, PDGBINNING}); MC_recon_reg.add("histTPCnClsFindableMinusFound", "TPC Clusters: Findable - Found", HistType::kTH3F, {ptAxis, {60, 0.0, 60.0, "nCluster"}, PDGBINNING}); MC_recon_reg.add("histTPCnClsFindableMinusCrossedRows", "TPC Clusters: Findable - crossed rows", HistType::kTH3F, {ptAxis, {60, 0.0, 60.0, "nCluster"}, PDGBINNING}); @@ -191,9 +208,13 @@ struct QAHistTask { MC_recon_reg.add("histTPCFoundOverFindable", "Ratio of found over findable clusters", HistType::kTH2F, {{100, 0., 2.0, "Found Cls / Findable Cls"}, PDGBINNING}); MC_recon_reg.add("histChi2TPC", "chi^2 TPC vs Pt", HistType::kTH3F, {ptAxis, {100, 0.0, 5.0, "chi^2"}, PDGBINNING}); MC_recon_reg.add("histChi2ITS", "chi^2 ITS vs Pt", HistType::kTH3F, {ptAxis, {500, 0.0, 50.0, "chi^2"}, PDGBINNING}); + MC_recon_reg.add("histChi2ITSvsITSnCls", "chi^2 ITS vs ITS nCls", HistType::kTH2F, {{125, 0.0, 50.0, "chi^2"}, {10, 0.0, 10.0, "ITS nCls"}}); + MC_recon_reg.add("histChi2ITSvsITSibnCls", "chi^2 ITS vs ITS ib nCls", HistType::kTH2F, {{125, 0.0, 50.0, "chi^2"}, {10, 0.0, 10.0, "ITS ib nCls"}}); + MC_recon_reg.add("histChi2ITSvsITSnClsAll", "chi^2 ITS vs ITS nCls", HistType::kTH2F, {{125, 0.0, 50.0, "chi^2"}, {10, 0.0, 10.0, "ITS nCls"}}); MC_recon_reg.add("histChi2TOF", "chi^2 TOF vs Pt", HistType::kTH3F, {ptAxis, {75, 0.0, 15.0, "chi^2"}, PDGBINNING}); MC_recon_reg.add("histTrackLength", "Track length", HistType::kTH2F, {{350, 0., 700., "length (cm)"}, PDGBINNING}); MC_recon_reg.add("histTPCFractionSharedCls", "Fraction of shared TPC clusters", HistType::kTH2F, {{100, -2.0, 2.0, "Shared Cls"}, PDGBINNING}); + MC_recon_reg.add("histpTCorralation", "global pT vs ITS-TPC pT", HistType::kTH2F, {ptAxis_short, ptAxisITS_TPC}); // MC diff (truth - reconstructed) MC_recon_diff_reg.add("histPhiDiff", "MC t", HistType::kTH2F, {ptAxis_diff, PDGBINNING}); @@ -259,6 +280,10 @@ struct QAHistTask { for (auto track : tracks) { // start loop over tracks + QA_reg.fill(HIST("histDcaVsPID"), track.dcaXY(), track.pidForTracking()); + QA_reg.fill(HIST("histDcaZVsPID"), track.dcaZ(), track.pidForTracking()); + QA_reg.fill(HIST("histpTCorralation"), track.pt(), track.tpcInnerParam()); + float nSigmaSpecies = 999.0; if (process_pion) @@ -333,12 +358,16 @@ struct QAHistTask { if (track.pt() < pTmin || track.pt() > pTmax) continue; - QA_reg.fill(HIST("histTpcSignalData"), track.tpcInnerParam() * track.sign(), track.tpcSignal()); + QA_reg.fill(HIST("histTpcSignalData"), track.pt() * track.sign(), track.tpcSignal()); QA_reg.fill(HIST("histNClusterTPC"), track.pt(), track.tpcNClsCrossedRows()); QA_reg.fill(HIST("histNClusterITS"), track.pt(), track.itsNCls()); QA_reg.fill(HIST("histNClusterITSib"), track.pt(), track.itsNClsInnerBarrel()); QA_reg.fill(HIST("histChi2TPC"), track.pt(), track.tpcChi2NCl()); QA_reg.fill(HIST("histChi2ITS"), track.pt(), track.itsChi2NCl()); + QA_reg.fill(HIST("histChi2ITSvsITSnCls"), track.itsChi2NCl(), track.itsNCls()); + QA_reg.fill(HIST("histChi2ITSvsITSibnCls"), track.itsChi2NCl(), track.itsNClsInnerBarrel()); + QA_reg.fill(HIST("histChi2ITSvsITSnClsAll"), track.itsChi2NCl(), track.itsNCls()); + QA_reg.fill(HIST("histChi2ITSvsITSnClsAll"), track.itsChi2NCl(), track.itsNClsInnerBarrel()); QA_reg.fill(HIST("histTPCnClsFindable"), track.pt(), track.tpcNClsFindable()); QA_reg.fill(HIST("histTPCnClsFindableMinusFound"), track.pt(), track.tpcNClsFindableMinusFound()); QA_reg.fill(HIST("histTPCnClsFindableMinusCrossedRows"), track.pt(), track.tpcNClsFindableMinusCrossedRows()); @@ -367,7 +396,7 @@ struct QAHistTask { Float_t TOFmass2 = ((track.mass()) * (track.mass())); QA_reg.fill(HIST("histTOFm2"), track.pt(), TOFmass2); - QA_reg.fill(HIST("histTofSignalData"), track.tpcInnerParam() * track.sign(), track.beta()); + QA_reg.fill(HIST("histTofSignalData"), track.pt() * track.sign(), track.beta()); } // fill QA histograms @@ -375,12 +404,16 @@ struct QAHistTask { if (track.sign() > 0) { QA_species_pos.fill(HIST("histDcaVsPtData"), track.pt(), track.dcaXY()); QA_species_pos.fill(HIST("histDcaZVsPtData"), track.pt(), track.dcaZ()); - QA_species_pos.fill(HIST("histTpcSignalData"), track.tpcInnerParam(), track.tpcSignal()); + QA_species_pos.fill(HIST("histTpcSignalData"), track.pt(), track.tpcSignal()); QA_species_pos.fill(HIST("histNClusterTPC"), track.pt(), track.tpcNClsCrossedRows()); QA_species_pos.fill(HIST("histNClusterITS"), track.pt(), track.itsNCls()); QA_species_pos.fill(HIST("histNClusterITSib"), track.pt(), track.itsNClsInnerBarrel()); QA_species_pos.fill(HIST("histChi2TPC"), track.pt(), track.tpcChi2NCl()); QA_species_pos.fill(HIST("histChi2ITS"), track.pt(), track.itsChi2NCl()); + QA_species_pos.fill(HIST("histChi2ITSvsITSnCls"), track.itsChi2NCl(), track.itsNCls()); + QA_species_pos.fill(HIST("histChi2ITSvsITSibnCls"), track.itsChi2NCl(), track.itsNClsInnerBarrel()); + QA_species_pos.fill(HIST("histChi2ITSvsITSnClsAll"), track.itsChi2NCl(), track.itsNCls()); + QA_species_pos.fill(HIST("histChi2ITSvsITSnClsAll"), track.itsChi2NCl(), track.itsNClsInnerBarrel()); QA_species_pos.fill(HIST("histTPCnClsFindable"), track.pt(), track.tpcNClsFindable()); QA_species_pos.fill(HIST("histTPCnClsFindableMinusFound"), track.pt(), track.tpcNClsFindableMinusFound()); QA_species_pos.fill(HIST("histTPCnClsFindableMinusCrossedRows"), track.pt(), track.tpcNClsFindableMinusCrossedRows()); @@ -390,6 +423,7 @@ struct QAHistTask { QA_species_pos.fill(HIST("histTPCCrossedRowsOverFindableCls"), track.tpcCrossedRowsOverFindableCls()); QA_species_pos.fill(HIST("histTPCFoundOverFindable"), track.tpcFoundOverFindableCls()); QA_species_pos.fill(HIST("histTPCFractionSharedCls"), track.tpcFractionSharedCls()); + QA_species_pos.fill(HIST("histpTCorralation"), track.pt(), track.tpcInnerParam()); if (track.hasTOF()) { @@ -409,18 +443,22 @@ struct QAHistTask { Float_t TOFmass2 = ((track.mass()) * (track.mass())); QA_species_pos.fill(HIST("histTOFm2"), track.pt(), TOFmass2); - QA_species_pos.fill(HIST("histTofSignalData"), track.tpcInnerParam() * track.sign(), track.beta()); + QA_species_pos.fill(HIST("histTofSignalData"), track.pt() * track.sign(), track.beta()); } } if (track.sign() < 0) { QA_species_neg.fill(HIST("histDcaVsPtData"), track.pt(), track.dcaXY()); QA_species_neg.fill(HIST("histDcaZVsPtData"), track.pt(), track.dcaZ()); - QA_species_neg.fill(HIST("histTpcSignalData"), track.tpcInnerParam(), track.tpcSignal()); + QA_species_neg.fill(HIST("histTpcSignalData"), track.pt(), track.tpcSignal()); QA_species_neg.fill(HIST("histNClusterTPC"), track.pt(), track.tpcNClsCrossedRows()); QA_species_neg.fill(HIST("histNClusterITS"), track.pt(), track.itsNCls()); QA_species_neg.fill(HIST("histNClusterITSib"), track.pt(), track.itsNClsInnerBarrel()); QA_species_neg.fill(HIST("histChi2TPC"), track.pt(), track.tpcChi2NCl()); QA_species_neg.fill(HIST("histChi2ITS"), track.pt(), track.itsChi2NCl()); + QA_species_neg.fill(HIST("histChi2ITSvsITSnCls"), track.itsChi2NCl(), track.itsNCls()); + QA_species_neg.fill(HIST("histChi2ITSvsITSibnCls"), track.itsChi2NCl(), track.itsNClsInnerBarrel()); + QA_species_neg.fill(HIST("histChi2ITSvsITSnClsAll"), track.itsChi2NCl(), track.itsNCls()); + QA_species_neg.fill(HIST("histChi2ITSvsITSnClsAll"), track.itsChi2NCl(), track.itsNClsInnerBarrel()); QA_species_neg.fill(HIST("histTPCnClsFindable"), track.pt(), track.tpcNClsFindable()); QA_species_neg.fill(HIST("histTPCnClsFindableMinusFound"), track.pt(), track.tpcNClsFindableMinusFound()); QA_species_neg.fill(HIST("histTPCnClsFindableMinusCrossedRows"), track.pt(), track.tpcNClsFindableMinusCrossedRows()); @@ -430,6 +468,7 @@ struct QAHistTask { QA_species_neg.fill(HIST("histTPCCrossedRowsOverFindableCls"), track.tpcCrossedRowsOverFindableCls()); QA_species_neg.fill(HIST("histTPCFoundOverFindable"), track.tpcFoundOverFindableCls()); QA_species_neg.fill(HIST("histTPCFractionSharedCls"), track.tpcFractionSharedCls()); + QA_species_neg.fill(HIST("histpTCorralation"), track.pt(), track.tpcInnerParam()); if (track.hasTOF()) { @@ -449,7 +488,7 @@ struct QAHistTask { Float_t TOFmass2 = ((track.mass()) * (track.mass())); QA_species_neg.fill(HIST("histTOFm2"), track.pt(), TOFmass2); - QA_species_neg.fill(HIST("histTofSignalData"), track.tpcInnerParam() * track.sign(), track.beta()); + QA_species_neg.fill(HIST("histTofSignalData"), track.pt() * track.sign(), track.beta()); } } } @@ -484,7 +523,7 @@ struct QAHistTask { } } - //**************************************************************************************************** + //******************************************************************************************************* Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVertex); Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta && requireGlobalTrackWoDCAInFilter()); @@ -537,7 +576,7 @@ struct QAHistTask { MC_recon_reg.fill(HIST("histPt"), track.pt(), pdgbin); MC_recon_reg.fill(HIST("histDCA"), track.pt(), track.dcaXY(), pdgbin); MC_recon_reg.fill(HIST("histDCAz"), track.pt(), track.dcaZ(), pdgbin); - MC_recon_reg.fill(HIST("histTpcSignalData"), track.tpcInnerParam(), track.tpcSignal(), pdgbin); + MC_recon_reg.fill(HIST("histTpcSignalData"), track.pt(), track.tpcSignal(), pdgbin); MC_recon_reg.fill(HIST("histNClusterTPC"), track.pt(), track.tpcNClsCrossedRows(), pdgbin); MC_recon_reg.fill(HIST("histNClusterITS"), track.pt(), track.itsNCls(), pdgbin); MC_recon_reg.fill(HIST("histNClusterITSib"), track.pt(), track.itsNClsInnerBarrel(), pdgbin); @@ -549,15 +588,20 @@ struct QAHistTask { MC_recon_reg.fill(HIST("histTPCFoundOverFindable"), track.tpcFoundOverFindableCls(), pdgbin); MC_recon_reg.fill(HIST("histChi2TPC"), track.pt(), track.tpcChi2NCl(), pdgbin); MC_recon_reg.fill(HIST("histChi2ITS"), track.pt(), track.itsChi2NCl(), pdgbin); + MC_recon_reg.fill(HIST("histChi2ITSvsITSnCls"), track.itsChi2NCl(), track.itsNCls()); + MC_recon_reg.fill(HIST("histChi2ITSvsITSibnCls"), track.itsChi2NCl(), track.itsNClsInnerBarrel()); + MC_recon_reg.fill(HIST("histChi2ITSvsITSnClsAll"), track.itsChi2NCl(), track.itsNCls()); + MC_recon_reg.fill(HIST("histChi2ITSvsITSnClsAll"), track.itsChi2NCl(), track.itsNClsInnerBarrel()); MC_recon_reg.fill(HIST("histChi2TOF"), track.pt(), track.tofChi2(), pdgbin); MC_recon_reg.fill(HIST("histTrackLength"), track.length(), pdgbin); MC_recon_reg.fill(HIST("histTPCFractionSharedCls"), track.tpcFractionSharedCls(), pdgbin); + MC_recon_reg.fill(HIST("histpTCorralation"), track.pt(), track.tpcInnerParam()); if (track.hasTOF()) { Float_t TOFmass2 = ((track.mass()) * (track.mass())); MC_recon_reg.fill(HIST("histTOFm2"), track.pt(), TOFmass2, pdgbin); - MC_recon_reg.fill(HIST("histTofSignalData"), track.tpcInnerParam(), track.beta(), pdgbin); + MC_recon_reg.fill(HIST("histTofSignalData"), track.pt(), track.beta(), pdgbin); } MC_recon_diff_reg.fill(HIST("histEtaDiff"), particle.eta() - track.eta(), pdgbin); diff --git a/PWGLF/Tasks/Nuspex/antidLambdaEbye.cxx b/PWGLF/Tasks/Nuspex/antidLambdaEbye.cxx new file mode 100644 index 00000000000..c114183d49d --- /dev/null +++ b/PWGLF/Tasks/Nuspex/antidLambdaEbye.cxx @@ -0,0 +1,399 @@ +// 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. + +#include + +#include "Framework/runDataProcessing.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/DataModel/EventSelection.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "DetectorsBase/Propagator.h" +#include "DetectorsBase/GeometryManager.h" +#include "DataFormatsParameters/GRPObject.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "CCDB/BasicCCDBManager.h" +#include "DataFormatsTPC/BetheBlochAleph.h" +#include "Common/Core/PID/PIDTOF.h" +#include "Common/TableProducer/PID/pidTOFBase.h" + +#include "Common/Core/PID/TPCPIDResponse.h" +#include "Common/DataModel/PIDResponse.h" + +#include "TDatabasePDG.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +using TracksFull = soa::Join; + +namespace +{ +// constexpr double betheBlochDefault[1][6]{{-1.e32, -1.e32, -1.e32, -1.e32, -1.e32, -1.e32}}; +constexpr double betheBlochDefault[1][6]{{-136.71, 0.441, 0.2269, 1.347, 0.8035, 0.09}}; +static const std::vector betheBlochParNames{"p0", "p1", "p2", "p3", "p4", "resolution"}; +static const std::vector particleNamesBB{"d"}; +static const std::vector pidHypotheses{"Electron", "Muon", "Pion", "Kaon", "Proton", "Deuteron", "Triton", "He3", "Alpha", "Pion0", "Photon", "K0", "Lambda", "HyperTriton", "Hyperhydrog4", "XiMinus", "OmegaMinus"}; +} // namespace + +struct antidLambdaEbye { + Service ccdb; + o2::pid::tof::Beta responseBeta; + + Configurable cfgMaterialCorrection{"cfgMaterialCorrection", static_cast(o2::base::Propagator::MatCorrType::USEMatCorrNONE), "Type of material correction"}; + + ConfigurableAxis zVtxAxis{"zVtxBins", {100, -20.f, 20.f}, "Binning for the vertex z in cm"}; + ConfigurableAxis massLambdaAxis{"massLambdaAxis", {400, o2::constants::physics::MassLambda0 - 0.03f, o2::constants::physics::MassLambda0 + 0.03f}, "binning for the lambda invariant-mass"}; + ConfigurableAxis centAxis{"centAxis", {106, 0, 106}, "binning for the centrality"}; + + ConfigurableAxis cosPaAxis{"cosPaAxis", {1e3, 0.95f, 1.00f}, "binning for the cosPa axis"}; + ConfigurableAxis radiusAxis{"radiusAxis", {1e3, 0.f, 100.f}, "binning for the radius axis"}; + ConfigurableAxis dcaV0daughAxis{"dcaV0daughAxis", {2e2, 0.f, 2.f}, "binning for the dca of V0 daughters"}; + ConfigurableAxis dcaDaughPvAxis{"dcaDaughPvAxis", {1e3, -10.f, 10.f}, "binning for the dca of positive daughter to PV"}; + + Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {betheBlochDefault[0], 1, 6, particleNamesBB, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for He3"}; + ConfigurableAxis tpcNsigmaAxis{"tpcNsigmaAxis", {100, -5.f, 5.f}, "tpc nsigma axis"}; + // ConfigurableAxis tofNsigmaAxis{"tofNsigmaAxis", {100, -5.f, 5.f}, "tof nsigma axis"}; + ConfigurableAxis tofMassAxis{"tofMassAxis", {1000, 0., 3.f}, "tof mass axis"}; + ConfigurableAxis momAxis{"momAxis", {60., 0.f, 3.f}, "momentum axis binning"}; + ConfigurableAxis momAxisFine{"momAxisFine", {5.e2, 0.f, 5.f}, "momentum axis binning"}; + ConfigurableAxis momResAxis{"momResAxis", {1.e2, -1.f, 1.f}, "momentum resolution binning"}; + ConfigurableAxis tpcAxis{"tpcAxis", {4.e2, 0.f, 4.e3f}, "tpc signal axis binning"}; + ConfigurableAxis tofAxis{"tofAxis", {1.e3, 0.f, 1.f}, "tof signal axis binning"}; + ConfigurableAxis trackingPidAxis{"trackingPidAxis", {static_cast(pidHypotheses.size()), 0, static_cast(pidHypotheses.size())}, "tracking pid hypothesis binning"}; + + // CCDB options + Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; + 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 pidPath{"pidPath", "", "Path to the PID response object"}; + + Configurable zVtxMax{"zVtxMax", 10.0f, "maximum z position of the primary vertex"}; + Configurable etaMax{"etaMax", 0.8f, "maximum eta"}; + + Configurable antidPtMin{"antidPtMin", 0.8f, "minimum antideuteron pT (GeV/c)"}; + Configurable antidPtTof{"antidPtTof", 1.0f, "antideuteron pT to switch to TOF pid (GeV/c) "}; + Configurable antidPtMax{"antidPtMax", 1.8f, "maximum antideuteron pT (GeV/c)"}; + + Configurable lambdaPtMin{"lambdaPtMin", 0.5f, "minimum (anti)lambda pT (GeV/c)"}; + Configurable lambdaPtMax{"lambdaPtMax", 3.0f, "maximum (anti)lambda pT (GeV/c)"}; + + Configurable antidNcrossedRows{"antidNcrossedRows", 70, "Minimum number of crossed TPC rows"}; + Configurable antidNclusItsCut{"antidNclusITScut", 5, "Minimum number of ITS clusters"}; + Configurable antidNclusTpcCut{"antidNclusTPCcut", 70, "Minimum number of TPC clusters"}; + Configurable antidNsigmaTpcCut{"antidNsigmaTpcCut", 4.f, "TPC PID cut"}; + Configurable antidNsigmaTofCut{"antidNsigmaTofCut", 4.f, "TOF PID cut"}; + Configurable antidDcaCut{"antidDcaCut", 0.1f, "DCA antid to PV"}; + Configurable tpcInnerParamMax{"tpcInnerParamMax", 0.6f, "(temporary) tpc inner param cut"}; + Configurable tofMassMax{"tofMassMax", 0.3f, "(temporary) tof mass cut"}; + + Configurable v0setting_dcav0dau{"v0setting_dcav0dau", 1, "DCA V0 Daughters"}; + Configurable v0setting_dcapostopv{"v0setting_dcapostopv", 0.1f, "DCA Pos To PV"}; + Configurable v0setting_dcanegtopv{"v0setting_dcanegtopv", 0.1f, "DCA Neg To PV"}; + Configurable v0setting_cospa{"v0setting_cospa", 0.98, "V0 CosPA"}; + Configurable v0setting_radius{"v0setting_radius", 0.5f, "v0radius"}; + Configurable lambdaMassCut{"lambdaMassCut", 0.005f, "maximum deviation from PDG mass"}; + + int mRunNumber; + float d_bz; + + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + Filter preFilterV0 = (nabs(aod::v0data::dcapostopv) > v0setting_dcapostopv && + nabs(aod::v0data::dcanegtopv) > v0setting_dcanegtopv && + aod::v0data::dcaV0daughters < v0setting_dcav0dau); + + template + bool selectLambda(RecV0 const& v0) // TODO: apply ML + { + if (std::abs(v0.eta()) > etaMax || + v0.v0cosPA() < v0setting_cospa || + v0.v0radius() < v0setting_radius) { + return false; + } + auto mLambda = v0.alpha() > 0 ? v0.mLambda() : v0.mAntiLambda(); + if (std::abs(mLambda - o2::constants::physics::MassLambda0) > lambdaMassCut) { + return false; + } + return true; + } + + template + bool selectAntid(T const& track) + { + if (std::abs(track.eta()) > etaMax) { + return false; + } + if (track.sign() > 0.) { + return false; + } + if (track.itsNCls() < antidNclusItsCut || + track.tpcNClsFound() < antidNclusTpcCut || + track.tpcNClsCrossedRows() < antidNcrossedRows || + track.tpcNClsCrossedRows() < 0.8 * track.tpcNClsFindable() || + track.tpcChi2NCl() > 4.f || + track.itsChi2NCl() > 36.f) { + return false; + } + return true; + } + + void init(o2::framework::InitContext&) + { + ccdb->setURL(ccdburl); + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + ccdb->setFatalWhenNull(false); + + mRunNumber = 0; + d_bz = 0; + + histos.add("zVtx", ";#it{z}_{vtx} (cm);Entries", HistType::kTH1F, {zVtxAxis}); + + histos.add("nEv", ";#it{N}_{ev};Entries", {HistType::kTH1D}, {centAxis}); + + histos.add("q1antid", ";Centrality (%);#it{q}_{1}(#bar{d})", {HistType::kTH1D}, {centAxis}); + histos.add("q1sqantid", ";Centrality (%);#it{q}_{1}^{2}(#bar{d})", {HistType::kTH1D}, {centAxis}); + histos.add("q2antid", ";Centrality (%);#it{q}_{2}(#bar{d})", {HistType::kTH1D}, {centAxis}); + + histos.add("q1antiL", ";Centrality (%);#it{q}_{1}(#bar{#Lambda})", {HistType::kTH1D}, {centAxis}); + histos.add("q1sqantiL", ";Centrality (%);#it{q}_{1}^{2}(#bar{#Lambda})", {HistType::kTH1D}, {centAxis}); + histos.add("q2antiL", ";Centrality (%);#it{q}_{2}(#bar{#Lambda})", {HistType::kTH1D}, {centAxis}); + + histos.add("q1L", ";Centrality (%);#it{q}_{1}(#Lambda)", {HistType::kTH1D}, {centAxis}); + histos.add("q1sqL", ";Centrality (%);#it{q}_{1}^{2}(#Lambda)", {HistType::kTH1D}, {centAxis}); + histos.add("q2L", ";Centrality (%);#it{q}_{2}(#Lambda)", {HistType::kTH1D}, {centAxis}); + + histos.add("q11Lantid", ";Centrality (%);#it{q}_{11}(#Lambda, #bar{d})", {HistType::kTH1D}, {centAxis}); + histos.add("q11antiLantid", ";Centrality (%);#it{q}_{11}(#bar{#Lambda}, #bar{d})", {HistType::kTH1D}, {centAxis}); + + // v0 QA + histos.add("massLambda", ";#it{M}(p + #pi^{-}) (GeV/#it{c}^{2});Entries", {HistType::kTH1F, {massLambdaAxis}}); + histos.add("cosPa", ";cosPa;Entries", {HistType::kTH1F}, {cosPaAxis}); + histos.add("radius", ";radius;Entries", {HistType::kTH1F}, {radiusAxis}); + histos.add("dcaV0daugh", ";dcaV0daugh;Entries", {HistType::kTH1F}, {dcaV0daughAxis}); + histos.add("dcaPosPv", ";dcaPosPv;Entries", {HistType::kTH1F}, {dcaDaughPvAxis}); + histos.add("dcaNegPv", ";dcaNegPv;Entries", {HistType::kTH1F}, {dcaDaughPvAxis}); + + // antid QA + histos.add("tpcNsigma", ";#it{p}_{TPC} (GeV/#it{c});tpcNsigma", {HistType::kTH2F}, {momAxis, tpcNsigmaAxis}); + histos.add("tpcNsigmaGlo", ";#it{p}_{T} (GeV/#it{c});tpcNsigma", {HistType::kTH2F}, {momAxis, tpcNsigmaAxis}); + // histos.add("tofNsigma", ";#it{p}_{glo};tofNsigma;Entries", {HistType::kTH2F}, {momAxis, tofNsigmaAxis}); + histos.add("tofMass", ";#it{p}_{glo} (GeV/#it{c});Mass (GeV/#it{c}^{2});Entries", {HistType::kTH2F}, {momAxis, tofMassAxis}); + histos.add("tofMassFull", ";#it{p}_{glo} (GeV/#it{c});Mass (GeV/#it{c}^{2});Entries", {HistType::kTH2F}, {momAxis, tofMassAxis}); + auto hmomCorr = histos.add("momCorr", ";#it{p}_{glo} (GeV/#it{c});#it{p}_{TPC} - #it{p}_{glo} (GeV/#it{c});", {HistType::kTH3F}, {momAxisFine, momResAxis, trackingPidAxis}); + histos.add("tpcSignal", ";#it{p}_{TPC} (GeV/#it{c});TPC signal (a.u.)", {HistType::kTH2F}, {momAxisFine, tpcAxis}); + histos.add("tpcSignalBkg", ";#it{p}_{TPC} (GeV/#it{c});TPC signal (a.u.)", {HistType::kTH2F}, {momAxisFine, tpcAxis}); + auto htpcSignal_glo = histos.add("tpcSignal_glo", ";#it{p}_{glo} (GeV/#it{c});TPC signal (a.u.);", {HistType::kTH3F}, {momAxisFine, tpcAxis, trackingPidAxis}); + auto htpcSignalBkg_glo = histos.add("tpcSignalBkg_glo", ";#it{p}_{glo} (GeV/#it{c});TPC signal (a.u.);", {HistType::kTH3F}, {momAxisFine, tpcAxis, trackingPidAxis}); + histos.add("tofSignal", ";#it{p}_{TPC} (GeV/#it{c});TOF signal (a.u.)", {HistType::kTH2F}, {momAxisFine, tofAxis}); + histos.add("tofSignal_glo", ";#it{p}_{T} (GeV/#it{c});TOF signal (a.u.)", {HistType::kTH2F}, {momAxisFine, tofAxis}); + + for (int i{1}; i < hmomCorr->GetNbinsZ() + 1; ++i) { + hmomCorr->GetZaxis()->SetBinLabel(i, pidHypotheses[i - 1].data()); + htpcSignal_glo->GetZaxis()->SetBinLabel(i, pidHypotheses[i - 1].data()); + htpcSignalBkg_glo->GetZaxis()->SetBinLabel(i, pidHypotheses[i - 1].data()); + } + } + + void initCCDB(aod::BCsWithTimestamps::iterator const& bc) + { + if (mRunNumber == bc.runNumber()) { + return; + } + auto run3grp_timestamp = bc.timestamp(); + + o2::parameters::GRPObject* grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); + o2::parameters::GRPMagField* grpmag = 0x0; + if (grpo) { + o2::base::Propagator::initFieldFromGRP(grpo); + if (d_bz_input < -990) { + // 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 { + d_bz = d_bz_input; + } + } 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); + if (d_bz_input < -990) { + // 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"; + } else { + d_bz = d_bz_input; + } + } + mRunNumber = bc.runNumber(); + } + + void process(soa::Join::iterator const& collision, TracksFull const& tracks, soa::Filtered const& V0s, aod::BCsWithTimestamps const&) + { + auto bc = collision.bc_as(); + initCCDB(bc); + + if (!collision.sel8()) + return; + + if (std::abs(collision.posZ()) > zVtxMax) + return; + + const o2::math_utils::Point3D collVtx{collision.posX(), collision.posY(), collision.posZ()}; + + histos.fill(HIST("zVtx"), collision.posZ()); + + double q1antid{0.}, q2antid{0.}; + for (const auto& track : tracks) { + if (!selectAntid(track)) { + continue; + } + + auto trackParCov = getTrackParCov(track); + gpu::gpustd::array dcaInfo; + o2::base::Propagator::Instance()->propagateToDCABxByBz(collVtx, trackParCov, 2.f, static_cast(cfgMaterialCorrection.value), &dcaInfo); + + float dcaXYZ = dcaInfo[0]; + if (std::abs(dcaXYZ) > antidDcaCut) { + continue; + } + + histos.fill(HIST("tpcSignal"), track.tpcInnerParam(), track.tpcSignal()); + histos.fill(HIST("tpcSignal_glo"), trackParCov.getP(), track.tpcSignal(), track.pidForTracking()); + + if (trackParCov.getPt() < antidPtMin || trackParCov.getPt() > antidPtMax) { + continue; + } + + double expBethe{tpc::BetheBlochAleph(static_cast(track.tpcInnerParam() / constants::physics::MassDeuteron), cfgBetheBlochParams->get("d", "p0"), cfgBetheBlochParams->get("d", "p1"), cfgBetheBlochParams->get("d", "p2"), cfgBetheBlochParams->get("d", "p3"), cfgBetheBlochParams->get("d", "p4"))}; + double expSigma{expBethe * cfgBetheBlochParams->get("d", "resolution")}; + auto nSigmaTPC = static_cast((track.tpcSignal() - expBethe) / expSigma); + + float beta{track.hasTOF() ? responseBeta.GetBeta(track) : -999.f}; + beta = std::min(1.f - 1.e-6f, std::max(1.e-4f, beta)); + float mass{track.tpcInnerParam() * std::sqrt(1.f / (beta * beta) - 1.f)}; + bool hasTof = track.hasTOF() && track.tofChi2() < 3; + + if (std::abs(nSigmaTPC) > antidNsigmaTpcCut) { + continue; + } + histos.fill(HIST("tpcNsigma"), track.tpcInnerParam(), nSigmaTPC); + histos.fill(HIST("momCorr"), trackParCov.getP(), track.tpcInnerParam() - trackParCov.getP(), track.pidForTracking()); + // check contamination + if (track.tpcInnerParam() < tpcInnerParamMax) { + histos.fill(HIST("tpcSignalBkg"), track.tpcInnerParam(), track.tpcSignal()); + histos.fill(HIST("tpcSignalBkg_glo"), trackParCov.getP(), track.tpcSignal(), track.pidForTracking()); + } + + if (trackParCov.getPt() > antidPtTof && hasTof) { + histos.fill(HIST("tofSignal_glo"), trackParCov.getP(), beta); + histos.fill(HIST("tofSignal"), track.tpcInnerParam(), beta); + } + + // temporary cut to reject fake matches + if (track.tpcInnerParam() < tpcInnerParamMax) { + continue; + } + if (trackParCov.getPt() > antidPtTof && !track.hasTOF()) { + continue; + } + histos.fill(HIST("tofMassFull"), trackParCov.getPt(), mass); + if (trackParCov.getPt() > antidPtTof && track.tofChi2() > 3) { + continue; + } + histos.fill(HIST("tofMass"), trackParCov.getPt(), mass); + + if (trackParCov.getPt() <= antidPtTof || (trackParCov.getPt() > antidPtTof && hasTof && std::abs(mass - o2::constants::physics::MassDeuteron) < tofMassMax)) { + histos.fill(HIST("tpcNsigmaGlo"), trackParCov.getPt(), nSigmaTPC); + q1antid += 1.; // TODO: correct for efficiency + q2antid += 1.; + } + } + + double q1L{0.}, q2L{0.}, q1antiL{0.}, q2antiL{0.}; + std::vector trkId; + for (const auto& v0 : V0s) { + if (v0.pt() < lambdaPtMin || v0.pt() > lambdaPtMax) { + continue; + } + + if (!selectLambda(v0)) { + continue; + } + + auto pos = v0.template posTrack_as(); + auto neg = v0.template negTrack_as(); + if (std::abs(pos.eta()) > etaMax || std::abs(pos.eta()) > etaMax) { + continue; + } + + bool matter = v0.alpha() > 0; + + histos.fill(HIST("massLambda"), matter ? v0.mLambda() : v0.mAntiLambda()); + histos.fill(HIST("cosPa"), v0.v0cosPA()); + histos.fill(HIST("radius"), v0.v0radius()); + histos.fill(HIST("dcaV0daugh"), v0.dcaV0daughters()); + histos.fill(HIST("dcaPosPv"), v0.dcapostopv()); + histos.fill(HIST("dcaNegPv"), v0.dcanegtopv()); + + if (matter) { + q1L += 1.; // TODO: correct for efficiency + q2L += 1.; + } else { + q1antiL += 1.; // TODO: correct for efficiency + q2antiL += 1.; + } + + trkId.emplace_back(pos.globalIndex()); + trkId.emplace_back(neg.globalIndex()); + } + + // reject events having multiple v0s from same tracks (TODO: also across collisions?) + std::sort(trkId.begin(), trkId.end()); + if (std::adjacent_find(trkId.begin(), trkId.end()) != trkId.end()) { + return; + } + + histos.fill(HIST("nEv"), collision.centFT0C()); + + histos.fill(HIST("q1antid"), collision.centFT0C(), q1antid); + histos.fill(HIST("q1sqantid"), collision.centFT0C(), std::pow(q1antid, 2)); + histos.fill(HIST("q2antid"), collision.centFT0C(), q2antid); + + histos.fill(HIST("q1L"), collision.centFT0C(), q1L); + histos.fill(HIST("q1sqL"), collision.centFT0C(), std::pow(q1L, 2)); + histos.fill(HIST("q2L"), collision.centFT0C(), q2L); + + histos.fill(HIST("q1antiL"), collision.centFT0C(), q1antiL); + histos.fill(HIST("q1sqantiL"), collision.centFT0C(), std::pow(q1antiL, 2)); + histos.fill(HIST("q2antiL"), collision.centFT0C(), q2antiL); + + histos.fill(HIST("q11Lantid"), collision.centFT0C(), q1L * q1antid); + histos.fill(HIST("q11antiLantid"), collision.centFT0C(), q1antiL * q1antid); + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/Tasks/helium_flow.cxx b/PWGLF/Tasks/Nuspex/helium_flow.cxx similarity index 100% rename from PWGLF/Tasks/helium_flow.cxx rename to PWGLF/Tasks/Nuspex/helium_flow.cxx diff --git a/PWGLF/Tasks/hyhe4analysis.cxx b/PWGLF/Tasks/Nuspex/hyhe4analysis.cxx similarity index 100% rename from PWGLF/Tasks/hyhe4analysis.cxx rename to PWGLF/Tasks/Nuspex/hyhe4analysis.cxx diff --git a/PWGLF/Tasks/Nuspex/hypertriton3bodyMCQA.cxx b/PWGLF/Tasks/Nuspex/hypertriton3bodyMCQA.cxx new file mode 100644 index 00000000000..56a626d5009 --- /dev/null +++ b/PWGLF/Tasks/Nuspex/hypertriton3bodyMCQA.cxx @@ -0,0 +1,652 @@ +// 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 perform a check for all mcparticles and tracks +// which has corresponding mcparticles to find out the properties +// of hypertriton 3-body decay +// +// author: yuanzhe.wang@cern.ch + +#include +#include +#include +#include + +#include "Framework/runDataProcessing.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 "PWGLF/DataModel/LFStrangenessTables.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 "CommonConstants/PhysicsConstants.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using std::array; + +using FullTracksExtIU = soa::Join; +using MCLabeledFullTracksExtIU = soa::Join; + +template +bool is3bodyDecayedH3L(TMCParticle const& particle) +{ + if (particle.pdgCode() != 1010010030 && particle.pdgCode() != -1010010030) { + return false; + } + bool haveProton = false, havePion = false, haveDeuteron = false; + bool haveAntiProton = false, haveAntiPion = false, haveAntiDeuteron = false; + for (auto& mcparticleDaughter : particle.template daughters_as()) { + if (mcparticleDaughter.pdgCode() == 2212) + haveProton = true; + if (mcparticleDaughter.pdgCode() == -2212) + haveAntiProton = true; + if (mcparticleDaughter.pdgCode() == 211) + havePion = true; + if (mcparticleDaughter.pdgCode() == -211) + haveAntiPion = true; + if (mcparticleDaughter.pdgCode() == 1000010020) + haveDeuteron = true; + if (mcparticleDaughter.pdgCode() == -1000010020) + haveAntiDeuteron = true; + } + if (haveProton && haveAntiPion && haveDeuteron && particle.pdgCode() == 1010010030) { + return true; + } else if (haveAntiProton && havePion && haveAntiDeuteron && particle.pdgCode() == -1010010030) { + return true; + } + return false; +} + +template +bool isPairedH3LDaughters(TMCParticle const& mctrack0, TMCParticle const& mctrack1, TMCParticle const& mctrack2) +{ + for (auto& particleMother : mctrack0.template mothers_as()) { + if (!(particleMother.pdgCode() == 1010010030 && mctrack0.pdgCode() == 2212 && mctrack1.pdgCode() == -211 && mctrack2.pdgCode() == 1000010020) && + !(particleMother.pdgCode() == -1010010030 && mctrack0.pdgCode() == -2212 && mctrack1.pdgCode() == 211 && mctrack2.pdgCode() == -1000010020)) { + continue; + } + bool flag1 = false, flag2 = false; + for (auto& mcparticleDaughter : particleMother.template daughters_as()) { + if (mcparticleDaughter.globalIndex() == mctrack1.globalIndex()) + flag1 = true; + if (mcparticleDaughter.globalIndex() == mctrack2.globalIndex()) + flag2 = true; + } + if (!flag1 || !flag2) + continue; + // move the requirement in mass region into the loop to draw a histogram + // double hypertritonMCMass = RecoDecay::m(array{array{mctrack0.px(), mctrack0.py(), mctrack0.pz()}, array{mctrack1.px(), mctrack1.py(), mctrack1.pz()}, array{mctrack2.px(), mctrack2.py(), mctrack2.pz()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged, o2::constants::physics::MassDeuteron}); + // if (hypertritonMCMass > 2.990 && hypertritonMCMass < 2.993) + return true; + } + return false; +} + +// check the properties of daughters candidates and true daughters +struct hypertriton3bodyTrackMcinfo { + // Basic checks + HistogramRegistry registry{ + "registry", + { + {"hTotalCollCounter", "hTotalCollCounter", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, + {"hParticleCount", "hParticleCount", {HistType::kTH1F, {{7, 0.0f, 7.0f}}}}, + + {"hTPCNClsCrossedRows", "hTPCNClsCrossedRows", {HistType::kTH1F, {{240, 0.0f, 240.0f}}}}, + {"hTrackEta", "hTrackEta", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, + {"hTrackITSNcls", "hTrackITSNcls", {HistType::kTH1F, {{10, 0.0f, 10.0f}}}}, + {"hTrackMcRapidity", "hTrackMcRapidity", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, + {"hTrackNsigmaProton", "hTrackNsigmaProton", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, + {"hTrackNsigmaPion", "hTrackNsigmaPion", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, + {"hTrackNsigmaDeuteron", "hTrackNsigmaDeuteron", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, + + {"hHypertritonEta", "hHypertritomEta", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, + {"hHypertritonMcRapidity", "hHypertritonMcRapidity", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, + {"hHypertritonMcPt", "hHypertritonMcPt", {HistType::kTH1F, {{300, 0.0f, 15.0f}}}}, + + {"hProtonCount", "hProtonCount", {HistType::kTH1F, {{6, 0.0f, 6.0f}}}}, + {"hProtonPt", "hProtonPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hProtonP", "hProtonP", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hProtonMcPt", "hProtonMcPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hProtonMcP", "hProtonMcP", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hProtonEta", "hProtonEta", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, + {"hProtonMcRapidity", "hProtonMcRapidity", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, + {"hProtonNsigmaProton", "hProtonNsigmaProton", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, + {"hProtonTPCNClsCrossedRows", "hProtonTPCNClsCrossedRows", {HistType::kTH1F, {{240, 0.0f, 240.0f}}}}, + {"hProtonTPCBB", "hProtonTPCBB", {HistType::kTH2F, {{320, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, + {"hProtonTPCBBAfterTPCNclsCut", "hProtonTPCBBAfterTPCNclsCut", {HistType::kTH2F, {{320, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, + {"hDauProtonPt", "hDauProtonPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hDauProtonMcPt", "hDauProtonMcPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hDauProtonNsigmaProton", "hDauProtonNsigmaProton", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, + {"hDauProtonTPCVsPt", "hDauProtonTPCVsPt", {HistType::kTH2F, {{50, 0.0f, 5.0f, "#it{p}_{T} (GeV/c)"}, {240, -6.0f, 6.0f, "TPC n#sigma"}}}}, + + {"hPionCount", "hPionCount", {HistType::kTH1F, {{7, 0.0f, 7.0f}}}}, + {"hPionPt", "hPionPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hPionP", "hPionP", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hPionMcPt", "hPionMcPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hPionMcP", "hPionMcP", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hPionEta", "hPionEta", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, + {"hPionMcRapidity", "hPionMcRapidity", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, + {"hPionNsigmaPion", "hPionNsigmaPion", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, + {"hPionTPCNClsCrossedRows", "hPionTPCNClsCrossedRows", {HistType::kTH1F, {{240, 0.0f, 240.0f}}}}, + {"hPionTPCBB", "hPionTPCBB", {HistType::kTH2F, {{320, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, + {"hPionTPCBBAfterTPCNclsCut", "hPionTPCBBAfterTPCNclsCut", {HistType::kTH2F, {{320, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, + {"hDauPionPt", "hDauPionPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hDauPionMcPt", "hDauPionMcPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hDauPionNsigmaPion", "hDauPionNsigmaPion", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, + {"hDauPionTPCVsPt", "hDauPionTPCVsPt", {HistType::kTH2F, {{20, 0.0f, 2.0f, "#it{p}_{T} (GeV/c)"}, {240, -6.0f, 6.0f, "TPC n#sigma"}}}}, + + {"hDeuteronCount", "hDeuteronCount", {HistType::kTH1F, {{7, 0.0f, 7.0f}}}}, + {"hDeuteronPt", "hDeuteronPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hDeuteronP", "hDeuteronP", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hDeuteronMcPt", "hDeuteronMcPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hDeuteronMcP", "hDeuteronMcP", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hDeuteronEta", "hDeuteronEta", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, + {"hDeuteronMcRapidity", "hDeuteronMcRapidity", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, + {"hDeuteronNsigmaDeuteron", "hDeuteronNsigmaDeuteron", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, + {"hDeuteronTPCNClsCrossedRows", "hDeuteronTPCNClsCrossedRows", {HistType::kTH1F, {{240, 0.0f, 240.0f}}}}, + {"hDeuteronTPCBB", "hDeuteronTPCBB", {HistType::kTH2F, {{320, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, + {"hDeuteronTPCBBAfterTPCNclsCut", "hDeuteronTPCBBAfterTPCNclsCut", {HistType::kTH2F, {{320, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, + {"hDauDeuteronPt", "hDauDeuteronPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hDauDeuteronMcPt", "hDauDeuteronMcPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hDauDeuteronTPCVsPt", "hDauDeuteronTPCVsPt", {HistType::kTH2F, {{80, 0.0f, 8.0f, "#it{p}_{T} (GeV/c)"}, {240, -6.0f, 6.0f, "TPC n#sigma"}}}}, + {"hDauDeuteronTOFNSigmaVsP", "hDauDeuteronTOFNSigmaVsP", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {200, -100.0f, 100.0f, "TPC n#sigma"}}}}, + {"hDauDeuteronTOFNSigmaVsPifhasTOF", "hDauDeuteronTOFNSigmaVsPifhasTOF", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {200, -100.0f, 100.0f, "TPC n#sigma"}}}}, + + {"hTPCBB", "hTPCBB", {HistType::kTH2F, {{120, -8.0f, 8.0f, "p/z(GeV/c)"}, {100, 0.0f, 1000.0f, "TPCSignal"}}}}, + + {"hPairedH3LDaughers", "hPairedH3LDaughers", {HistType::kTH1F, {{3, 0.0f, 3.0f}}}}, + {"hPairedH3LDaughersInvMass", "hPairedH3LDaughersInvMass", {HistType::kTH1F, {{300, 2.9f, 3.2f}}}}, + {"hDuplicatedH3LDaughers", "hDuplicatedH3LDaughers", {HistType::kTH1F, {{3, 0.0f, 3.0f}}}}, + }, + }; + + void init(InitContext&) + { + registry.get(HIST("hParticleCount"))->GetXaxis()->SetBinLabel(1, "Readin"); + registry.get(HIST("hParticleCount"))->GetXaxis()->SetBinLabel(2, "Has_mcparticle"); + registry.get(HIST("hParticleCount"))->GetXaxis()->SetBinLabel(3, "Rapidity Cut"); + registry.get(HIST("hParticleCount"))->GetXaxis()->SetBinLabel(4, "McisHypertriton"); + registry.get(HIST("hParticleCount"))->GetXaxis()->SetBinLabel(5, "McisProton"); + registry.get(HIST("hParticleCount"))->GetXaxis()->SetBinLabel(6, "McisPion"); + registry.get(HIST("hParticleCount"))->GetXaxis()->SetBinLabel(7, "McisDeuteron"); + + TString TrackCounterbinLabel[6] = {"hasMom", "FromHypertriton", "TPCNcls", "Eta", "Pt", "TPCPID"}; + for (int i{0}; i < 6; i++) { + registry.get(HIST("hProtonCount"))->GetXaxis()->SetBinLabel(i + 1, TrackCounterbinLabel[i]); + registry.get(HIST("hPionCount"))->GetXaxis()->SetBinLabel(i + 1, TrackCounterbinLabel[i]); + registry.get(HIST("hDeuteronCount"))->GetXaxis()->SetBinLabel(i + 1, TrackCounterbinLabel[i]); + } + registry.get(HIST("hPionCount"))->GetXaxis()->SetBinLabel(7, "DcatoPV"); + registry.get(HIST("hDeuteronCount"))->GetXaxis()->SetBinLabel(7, "hasTOF"); + registry.get(HIST("hDuplicatedH3LDaughers"))->GetXaxis()->SetBinLabel(1, "proton"); + registry.get(HIST("hDuplicatedH3LDaughers"))->GetXaxis()->SetBinLabel(2, "pion"); + registry.get(HIST("hDuplicatedH3LDaughers"))->GetXaxis()->SetBinLabel(3, "deuteron"); + } + + Configurable dcapiontopv{"dcapiontopv", .05, "DCA Pion To PV"}; + Configurable minProtonPt{"minProtonPt", 0.3, "minProtonPt"}; + Configurable maxProtonPt{"maxProtonPt", 5, "maxProtonPt"}; + Configurable minPionPt{"minPionPt", 0.1, "minPionPt"}; + Configurable maxPionPt{"maxPionPt", 1.2, "maxPionPt"}; + Configurable minDeuteronPt{"minDeuteronPt", 0.6, "minDeuteronPt"}; + Configurable maxDeuteronPt{"maxDeuteronPt", 10, "maxDeuteronPt"}; + Configurable event_sel8_selection{"event_sel8_selection", true, "event selection count post sel8 cut"}; + + struct Indexdaughters { // check duplicated paired daughters + int64_t index0; + int64_t index1; + int64_t index2; + bool operator==(const Indexdaughters& t) const + { + return (this->index0 == t.index0 && this->index1 == t.index1 && this->index2 == t.index2); + } + }; + + void process(soa::Join::iterator const& collision, aod::McParticles const& particlesMC, MCLabeledFullTracksExtIU const& tracks) + { + + registry.fill(HIST("hTotalCollCounter"), 0.5); + if (event_sel8_selection && !collision.sel8()) { + return; + } + registry.fill(HIST("hTotalCollCounter"), 1.5); + + std::vector protons, pions, deuterons; // index for daughter tracks + std::unordered_set set_proton, set_pion, set_deuteron; // check duplicated daughters + int itrack = 0; + + for (auto& track : tracks) { + registry.fill(HIST("hParticleCount"), 0.5); + registry.fill(HIST("hTrackITSNcls"), track.itsNCls()); + registry.fill(HIST("hTPCNClsCrossedRows"), track.tpcNClsCrossedRows()); + registry.fill(HIST("hTrackNsigmaDeuteron"), track.tpcNSigmaDe()); + registry.fill(HIST("hTrackNsigmaProton"), track.tpcNSigmaPr()); + registry.fill(HIST("hTrackNsigmaPion"), track.tpcNSigmaPi()); + + if (!track.has_mcParticle()) { + continue; + } + registry.fill(HIST("hParticleCount"), 1.5); + auto mcparticle = track.mcParticle_as(); + registry.fill(HIST("hTPCBB"), track.p() * track.sign(), track.tpcSignal()); + + // if (TMath::Abs(mcparticle.y()) > 0.9) {continue;} + registry.fill(HIST("hParticleCount"), 2.5); + registry.fill(HIST("hTrackEta"), track.eta()); + registry.fill(HIST("hTrackMcRapidity"), mcparticle.y()); + + // Hypertriton detected directly + if (mcparticle.pdgCode() == 1010010030 || mcparticle.pdgCode() == -1010010030) { + registry.fill(HIST("hParticleCount"), 3.5); + registry.fill(HIST("hHypertritonMcPt"), mcparticle.pt()); + registry.fill(HIST("hHypertritonEta"), track.eta()); + registry.fill(HIST("hHypertritonMcRapidity"), mcparticle.y()); + } + + // Proton + if (mcparticle.pdgCode() == 2212 || mcparticle.pdgCode() == -2212) { + registry.fill(HIST("hParticleCount"), 4.5); + if (track.tpcNClsCrossedRows() > 70) { + registry.fill(HIST("hProtonTPCBBAfterTPCNclsCut"), track.p() * track.sign(), track.tpcSignal()); + } + + if (mcparticle.has_mothers()) { + registry.fill(HIST("hProtonCount"), 0.5); + for (auto& particleMother : mcparticle.mothers_as()) { + bool flag_H3L = is3bodyDecayedH3L(particleMother); + if (!flag_H3L) { + continue; + } + protons.push_back(itrack); + auto p = set_proton.insert(mcparticle.globalIndex()); + if (p.second == false) + registry.fill(HIST("hDuplicatedH3LDaughers"), 0); + registry.fill(HIST("hProtonCount"), 1.5); + registry.fill(HIST("hDauProtonPt"), track.pt()); + registry.fill(HIST("hDauProtonMcPt"), mcparticle.pt()); + registry.fill(HIST("hDauProtonNsigmaProton"), track.tpcNSigmaPr()); + registry.fill(HIST("hDauProtonTPCVsPt"), track.pt(), track.tpcNSigmaPr()); + if (track.tpcNClsCrossedRows() < 70) { + continue; + } + registry.fill(HIST("hProtonCount"), 2.5); + if (TMath::Abs(track.eta()) > 0.9) { + continue; + } + registry.fill(HIST("hProtonCount"), 3.5); + if (track.pt() < minProtonPt || track.pt() > maxProtonPt) { + continue; + } + registry.fill(HIST("hProtonCount"), 4.5); + if (TMath::Abs(track.tpcNSigmaPr()) > 5) { + continue; + } + registry.fill(HIST("hProtonCount"), 5.5); + } + } + + registry.fill(HIST("hProtonMcPt"), mcparticle.pt()); + registry.fill(HIST("hProtonMcP"), mcparticle.p()); + registry.fill(HIST("hProtonPt"), track.pt()); + registry.fill(HIST("hProtonP"), track.p()); + + registry.fill(HIST("hProtonNsigmaProton"), track.tpcNSigmaPr()); + registry.fill(HIST("hProtonTPCNClsCrossedRows"), track.tpcNClsCrossedRows()); + registry.fill(HIST("hProtonEta"), track.eta()); + registry.fill(HIST("hProtonMcRapidity"), mcparticle.y()); + registry.fill(HIST("hProtonTPCBB"), track.p() * track.sign(), track.tpcSignal()); + } + + // Pion + if (mcparticle.pdgCode() == 211 || mcparticle.pdgCode() == -211) { + registry.fill(HIST("hParticleCount"), 5.5); + if (track.tpcNClsCrossedRows() > 70) { + registry.fill(HIST("hPionTPCBBAfterTPCNclsCut"), track.p() * track.sign(), track.tpcSignal()); + } + + if (mcparticle.has_mothers()) { + registry.fill(HIST("hPionCount"), 0.5); + for (auto& particleMother : mcparticle.mothers_as()) { + bool flag_H3L = is3bodyDecayedH3L(particleMother); + if (!flag_H3L) { + continue; + } + pions.push_back(itrack); + auto p = set_pion.insert(mcparticle.globalIndex()); + if (p.second == false) + registry.fill(HIST("hDuplicatedH3LDaughers"), 1); + registry.fill(HIST("hPionCount"), 1.5); + registry.fill(HIST("hDauPionPt"), track.pt()); + registry.fill(HIST("hDauPionMcPt"), mcparticle.pt()); + registry.fill(HIST("hDauPionTPCVsPt"), track.pt(), track.tpcNSigmaPi()); + if (track.tpcNClsCrossedRows() < 70) { + continue; + } + registry.fill(HIST("hPionCount"), 2.5); + if (TMath::Abs(track.eta()) > 0.9) { + continue; + } + registry.fill(HIST("hPionCount"), 3.5); + if (track.pt() < minPionPt || track.pt() > maxPionPt) { + continue; + } + registry.fill(HIST("hPionCount"), 4.5); + if (TMath::Abs(track.tpcNSigmaPi()) > 5) { + continue; + } + registry.fill(HIST("hPionCount"), 5.5); + if (TMath::Abs(track.dcaXY()) < dcapiontopv) { + continue; + } + registry.fill(HIST("hPionCount"), 6.5); + } + } + + registry.fill(HIST("hPionMcPt"), mcparticle.pt()); + registry.fill(HIST("hPionMcP"), mcparticle.p()); + registry.fill(HIST("hPionPt"), track.pt()); + registry.fill(HIST("hPionP"), track.p()); + + registry.fill(HIST("hPionNsigmaPion"), track.tpcNSigmaPi()); + registry.fill(HIST("hPionTPCNClsCrossedRows"), track.tpcNClsCrossedRows()); + registry.fill(HIST("hPionEta"), track.eta()); + registry.fill(HIST("hPionMcRapidity"), mcparticle.y()); + registry.fill(HIST("hPionTPCBB"), track.p() * track.sign(), track.tpcSignal()); + } + + // Deuteron + if (mcparticle.pdgCode() == 1000010020 || mcparticle.pdgCode() == -1000010020) { + registry.fill(HIST("hParticleCount"), 6.5); + if (track.tpcNClsCrossedRows() > 70) { + registry.fill(HIST("hDeuteronTPCBBAfterTPCNclsCut"), track.p() * track.sign(), track.tpcSignal()); + } + + if (mcparticle.has_mothers()) { + registry.fill(HIST("hDeuteronCount"), 0.5); + for (auto& particleMother : mcparticle.mothers_as()) { + bool flag_H3L = is3bodyDecayedH3L(particleMother); + if (!flag_H3L) { + continue; + } + deuterons.push_back(itrack); + auto p = set_deuteron.insert(mcparticle.globalIndex()); + if (p.second == false) + registry.fill(HIST("hDuplicatedH3LDaughers"), 2); + registry.fill(HIST("hDeuteronCount"), 1.5); + registry.fill(HIST("hDauDeuteronPt"), track.pt()); + registry.fill(HIST("hDauDeuteronMcPt"), mcparticle.pt()); + registry.fill(HIST("hDauDeuteronTPCVsPt"), track.pt(), track.tpcNSigmaDe()); + registry.fill(HIST("hDauDeuteronTOFNSigmaVsP"), track.sign() * track.p(), track.tofNSigmaDe()); + if (track.hasTOF()) { + registry.fill(HIST("hDauDeuteronTOFNSigmaVsPifhasTOF"), track.sign() * track.p(), track.tofNSigmaDe()); + } + if (track.tpcNClsCrossedRows() < 70) { + continue; + } + registry.fill(HIST("hDeuteronCount"), 2.5); + if (TMath::Abs(track.eta()) > 0.9) { + continue; + } + registry.fill(HIST("hDeuteronCount"), 3.5); + if (track.pt() < minDeuteronPt || track.pt() > maxDeuteronPt) { + continue; + } + registry.fill(HIST("hDeuteronCount"), 4.5); + if (TMath::Abs(track.tpcNSigmaDe()) > 5) { + continue; + } + registry.fill(HIST("hDeuteronCount"), 5.5); + if (track.hasTOF()) { + continue; + } + registry.fill(HIST("hDeuteronCount"), 6.5); + } + } + + registry.fill(HIST("hDeuteronMcPt"), mcparticle.pt()); + registry.fill(HIST("hDeuteronMcP"), mcparticle.p()); + registry.fill(HIST("hDeuteronPt"), track.pt()); + registry.fill(HIST("hDeuteronP"), track.p()); + + registry.fill(HIST("hDeuteronNsigmaDeuteron"), track.tpcNSigmaDe()); + registry.fill(HIST("hDeuteronTPCNClsCrossedRows"), track.tpcNClsCrossedRows()); + registry.fill(HIST("hDeuteronEta"), track.eta()); + registry.fill(HIST("hDeuteronMcRapidity"), mcparticle.y()); + registry.fill(HIST("hDeuteronTPCBB"), track.p() * track.sign(), track.tpcSignal()); + } + ++itrack; + } + + std::vector set_pair; + for (size_t iproton = 0; iproton < protons.size(); iproton++) { + auto track0 = tracks.iteratorAt(protons[iproton]); + auto mctrack0 = track0.mcParticle_as(); + for (size_t ipion = 0; ipion < pions.size(); ipion++) { + auto track1 = tracks.iteratorAt(pions[ipion]); + auto mctrack1 = track1.mcParticle_as(); + for (size_t ideuteron = 0; ideuteron < deuterons.size(); ideuteron++) { + auto track2 = tracks.iteratorAt(deuterons[ideuteron]); + auto mctrack2 = track2.mcParticle_as(); + if (isPairedH3LDaughters(mctrack0, mctrack1, mctrack2)) { + registry.fill(HIST("hPairedH3LDaughers"), 0); + // MC mass cut, to check if the daughters are from materials + double hypertritonMCMass = RecoDecay::m(array{array{mctrack0.px(), mctrack0.py(), mctrack0.pz()}, array{mctrack1.px(), mctrack1.py(), mctrack1.pz()}, array{mctrack2.px(), mctrack2.py(), mctrack2.pz()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged, o2::constants::physics::MassDeuteron}); + registry.fill(HIST("hPairedH3LDaughersInvMass"), hypertritonMCMass); + if (hypertritonMCMass < 2.990 || hypertritonMCMass > 2.993) + continue; + registry.fill(HIST("hPairedH3LDaughers"), 1); + // duplicated daughters check + Indexdaughters temp = {mctrack0.globalIndex(), mctrack1.globalIndex(), mctrack2.globalIndex()}; + auto p = std::find(set_pair.begin(), set_pair.end(), temp); + if (p == set_pair.end()) { + set_pair.push_back(temp); + registry.fill(HIST("hPairedH3LDaughers"), 2); + } + } + } + } + } + } +}; + +// check the performance of mcparticle +struct hypertriton3bodyMcParticleCount { + // Basic checks + HistogramRegistry registry{ + "registry", + { + {"hTotalMcCollCounter", "hTotalMcCollCounter", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, + + {"h3dMCDecayedHypertriton", "h3dMCDecayedHypertriton", {HistType::kTH3F, {{20, -1.0f, 1.0f, "Rapidity"}, {200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {50, 0.0f, 50.0f, "ct(cm)"}}}}, + {"hMcPhysicalPrimaryParticleCount", "hMcPhysicalPrimaryParticleCount", {HistType::kTH1F, {{8, 0.0f, 8.0f}}}}, + + {"hMcHypertritonCount", "hMcHypertritonCount", {HistType::kTH1F, {{9, 0.0f, 9.0f}}}}, + {"hMcHypertritonPt", "hMcHypertritonPt", {HistType::kTH1F, {{300, 0.0f, 15.0f}}}}, + {"hMcProtonPt", "hMcProtonPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hMcPionPt", "hMcPionPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hMcDeuteronPt", "hMcDeuteronPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + + {"hMcRecoInvMass", "hMcRecoInvMass", {HistType::kTH1F, {{100, 2.95, 3.05f}}}}, + }, + }; + + void init(InitContext&) + { + registry.get(HIST("hTotalMcCollCounter"))->GetXaxis()->SetBinLabel(1, "Total Count"); + registry.get(HIST("hTotalMcCollCounter"))->GetXaxis()->SetBinLabel(2, "Recoonstructed"); + + registry.get(HIST("hMcPhysicalPrimaryParticleCount"))->GetXaxis()->SetBinLabel(1, "Readin"); + registry.get(HIST("hMcPhysicalPrimaryParticleCount"))->GetXaxis()->SetBinLabel(2, "IsPhysicalPrimary"); + registry.get(HIST("hMcPhysicalPrimaryParticleCount"))->GetXaxis()->SetBinLabel(3, "y<0.9(off)"); + registry.get(HIST("hMcPhysicalPrimaryParticleCount"))->GetXaxis()->SetBinLabel(4, "(Anti)Proton"); + registry.get(HIST("hMcPhysicalPrimaryParticleCount"))->GetXaxis()->SetBinLabel(5, "(Anti)Pion"); + registry.get(HIST("hMcPhysicalPrimaryParticleCount"))->GetXaxis()->SetBinLabel(6, "(Anti)Deuteron"); + registry.get(HIST("hMcPhysicalPrimaryParticleCount"))->GetXaxis()->SetBinLabel(7, "(Anti)Hypertriton"); + registry.get(HIST("hMcPhysicalPrimaryParticleCount"))->GetXaxis()->SetBinLabel(8, "HasDaughter"); + registry.get(HIST("hMcHypertritonCount"))->GetXaxis()->SetBinLabel(1, "Hypertriton All"); + registry.get(HIST("hMcHypertritonCount"))->GetXaxis()->SetBinLabel(2, "Matter All"); + registry.get(HIST("hMcHypertritonCount"))->GetXaxis()->SetBinLabel(3, "AntiMatter All"); + registry.get(HIST("hMcHypertritonCount"))->GetXaxis()->SetBinLabel(4, "confirm to 3-body decay"); + registry.get(HIST("hMcHypertritonCount"))->GetXaxis()->SetBinLabel(5, "Matter"); + registry.get(HIST("hMcHypertritonCount"))->GetXaxis()->SetBinLabel(6, "AntiMatter"); + registry.get(HIST("hMcHypertritonCount"))->GetXaxis()->SetBinLabel(7, "Rapidity"); + registry.get(HIST("hMcHypertritonCount"))->GetXaxis()->SetBinLabel(8, "Lifetime"); + registry.get(HIST("hMcHypertritonCount"))->GetXaxis()->SetBinLabel(9, "PtCut"); + } + + Configurable rapidityMCcut{"rapidityMCcut", 1, "rapidity cut MC count"}; + Configurable event_sel8_selection{"event_sel8_selection", true, "event selection count post sel8 cut"}; + + void process(aod::McCollision const& mcCollision, aod::McParticles const& particlesMC, const soa::SmallGroups>& collisions) + { + std::vector SelectedEvents(collisions.size()); + int nevts = 0; + for (const auto& collision : collisions) { + if (event_sel8_selection && !collision.sel8()) { + continue; + } + SelectedEvents[nevts++] = collision.mcCollision_as().globalIndex(); + } + SelectedEvents.resize(nevts); + + registry.fill(HIST("hTotalMcCollCounter"), 0.5); + + const auto evtReconstructedAndSelected = std::find(SelectedEvents.begin(), SelectedEvents.end(), mcCollision.globalIndex()) != SelectedEvents.end(); + if (evtReconstructedAndSelected) { // Check that the event is reconstructed and that the reconstructed events pass the selection + registry.fill(HIST("hTotalMcCollCounter"), 1.5); + // return; + } + + for (auto& mcparticle : particlesMC) { + + registry.fill(HIST("hMcPhysicalPrimaryParticleCount"), 0.5); + + if (mcparticle.pdgCode() == 2212 || mcparticle.pdgCode() == -2212) { + registry.fill(HIST("hMcProtonPt"), mcparticle.pt()); + } + if (mcparticle.pdgCode() == 211 || mcparticle.pdgCode() == -211) { + registry.fill(HIST("hMcPionPt"), mcparticle.pt()); + } + if (mcparticle.pdgCode() == 1000010020 || mcparticle.pdgCode() == -1000010020) { + registry.fill(HIST("hMcDeuteronPt"), mcparticle.pt()); + } + if (mcparticle.pdgCode() == 1010010030) { + registry.fill(HIST("hMcHypertritonCount"), 1.5); + } else if (mcparticle.pdgCode() == -1010010030) { + registry.fill(HIST("hMcHypertritonCount"), 2.5); + } + if (mcparticle.pdgCode() == 1010010030 || mcparticle.pdgCode() == -1010010030) { + registry.fill(HIST("hMcHypertritonCount"), 0.5); + registry.fill(HIST("hMcHypertritonPt"), mcparticle.pt()); + + double dauDeuteronPos[3] = {-999, -999, -999}; + double dauProtonMom[3] = {-999, -999, -999}; + double dauPionMom[3] = {-999, -999, -999}; + double dauDeuteronMom[3] = {-999, -999, -999}; + double MClifetime = 999; + bool flag_H3L = is3bodyDecayedH3L(mcparticle); + if (!flag_H3L) { + continue; + } + for (auto& mcparticleDaughter : mcparticle.daughters_as()) { + if (std::abs(mcparticleDaughter.pdgCode()) == 2212) { + dauProtonMom[0] = mcparticleDaughter.px(); + dauProtonMom[1] = mcparticleDaughter.py(); + dauProtonMom[2] = mcparticleDaughter.pz(); + } + if (std::abs(mcparticleDaughter.pdgCode()) == 211) { + dauPionMom[0] = mcparticleDaughter.px(); + dauPionMom[1] = mcparticleDaughter.py(); + dauPionMom[2] = mcparticleDaughter.pz(); + } + if (std::abs(mcparticleDaughter.pdgCode()) == 1000010020) { + dauDeuteronPos[0] = mcparticleDaughter.vx(); + dauDeuteronPos[1] = mcparticleDaughter.vy(); + dauDeuteronPos[2] = mcparticleDaughter.vz(); + dauDeuteronMom[0] = mcparticleDaughter.px(); + dauDeuteronMom[1] = mcparticleDaughter.py(); + dauDeuteronMom[2] = mcparticleDaughter.pz(); + } + } + if (mcparticle.pdgCode() == 1010010030) { + registry.fill(HIST("hMcHypertritonCount"), 3.5); + registry.fill(HIST("hMcHypertritonCount"), 4.5); + } + if (mcparticle.pdgCode() == -1010010030) { + registry.fill(HIST("hMcHypertritonCount"), 3.5); + registry.fill(HIST("hMcHypertritonCount"), 5.5); + } + MClifetime = RecoDecay::sqrtSumOfSquares(dauDeuteronPos[0] - mcparticle.vx(), dauDeuteronPos[1] - mcparticle.vy(), dauDeuteronPos[2] - mcparticle.vz()) * o2::constants::physics::MassHyperTriton / mcparticle.p(); + registry.fill(HIST("hMcRecoInvMass"), RecoDecay::m(array{array{dauProtonMom[0], dauProtonMom[1], dauProtonMom[2]}, array{dauPionMom[0], dauPionMom[1], dauPionMom[2]}, array{dauDeuteronMom[0], dauDeuteronMom[1], dauDeuteronMom[2]}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged, o2::constants::physics::MassDeuteron})); + registry.fill(HIST("h3dMCDecayedHypertriton"), mcparticle.y(), mcparticle.pt(), MClifetime); + + int daughterPionCount = 0; + for (auto& mcparticleDaughter : mcparticle.daughters_as()) { + if (std::abs(mcparticleDaughter.pdgCode()) == 211) { + daughterPionCount++; + } + } + + // Count for hypertriton N_gen + if (TMath::Abs(mcparticle.y()) < 1) { + registry.fill(HIST("hMcHypertritonCount"), 6.5); + if (MClifetime < 40) { + registry.fill(HIST("hMcHypertritonCount"), 7.5); + if (mcparticle.pt() > 1 && mcparticle.pt() < 10) { + registry.fill(HIST("hMcHypertritonCount"), 8.5); + } + } + } + } + + if (!mcparticle.isPhysicalPrimary()) { + continue; + } + registry.fill(HIST("hMcPhysicalPrimaryParticleCount"), 1.5); + if (TMath::Abs(mcparticle.y()) > rapidityMCcut) { + continue; + } + registry.fill(HIST("hMcPhysicalPrimaryParticleCount"), 2.5); + + if (mcparticle.pdgCode() == 211 || mcparticle.pdgCode() == -211) { + registry.fill(HIST("hMcPhysicalPrimaryParticleCount"), 3.5); + } else if (mcparticle.pdgCode() == 2212 || mcparticle.pdgCode() == -2212) { + registry.fill(HIST("hMcPhysicalPrimaryParticleCount"), 4.5); + } else if (mcparticle.pdgCode() == 1000010020 || mcparticle.pdgCode() == -1000010020) { + registry.fill(HIST("hMcPhysicalPrimaryParticleCount"), 5.5); + } else if (mcparticle.pdgCode() == 1010010030 || mcparticle.pdgCode() == -1010010030) { + registry.fill(HIST("hMcPhysicalPrimaryParticleCount"), 6.5); + } + + if (!mcparticle.has_daughters()) { + continue; + } + registry.fill(HIST("hMcPhysicalPrimaryParticleCount"), 7.5); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + }; +} diff --git a/PWGLF/Tasks/Nuspex/hypertriton3bodyanalysis.cxx b/PWGLF/Tasks/Nuspex/hypertriton3bodyanalysis.cxx new file mode 100644 index 00000000000..fa5051da954 --- /dev/null +++ b/PWGLF/Tasks/Nuspex/hypertriton3bodyanalysis.cxx @@ -0,0 +1,632 @@ +// 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. +// +// StoredVtx3BodyDatas analysis task +// ======================== +// +// This code loops over a StoredVtx3BodyDatas table and produces some +// standard analysis output. It requires either +// the hypertriton3bodybuilder or hypertriton3bodyfinder (not recommended) tasks +// to have been executed in the workflow (before). +// +// author: yuanzhe.wang@cern.ch +// + +#include +#include +#include + +#include "Framework/runDataProcessing.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 "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/Vtx3BodyTables.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 "CommonConstants/PhysicsConstants.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using std::array; + +using FullTracksExtIU = soa::Join; +using MCLabeledFullTracksExtIU = soa::Join; + +struct hypertriton3bodyQa { + // Basic checks + HistogramRegistry registry{ + "registry", + { + {"hVtxRadius", "hVtxRadius", {HistType::kTH1F, {{1000, 0.0f, 100.0f, "cm"}}}}, + {"hVtxCosPA", "hVtxCosPA", {HistType::kTH1F, {{1000, 0.9f, 1.0f}}}}, + {"hPtProton", "hPtProton", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hPtAntiPion", "hPtAntiPion", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hPtDeuteron", "hPtDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hPtAntiProton", "hPtAntiProton", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hPtPion", "hPtPion", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hPtAntiDeuteron", "hPtAntiDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hDCAProtonToPV", "hDCAProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, + {"hDCAPionToPV", "hDCAPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, + {"hDCADeuteronToPV", "hDCADeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, + {"hProtonTPCNcls", "hProtonTPCNcls", {HistType::kTH1F, {{300, 0, 300, "TPC cluster"}}}}, + {"hPionTPCNcls", "hPionTPCNcls", {HistType::kTH1F, {{300, 0, 300, "TPC cluster"}}}}, + {"hDeuteronTPCNcls", "hDeuteronTPCNcls", {HistType::kTH1F, {{300, 0, 300, "TPC cluster"}}}}, + {"hDCAVtxDau", "hDCAVtxDau", {HistType::kTH1F, {{1000, 0.0f, 10.0f, "cm^{2}"}}}}, + {"hVtxPt", "hVtxPt", {HistType::kTH1F, {{200, 0.0f, 10.0f, "p_{T}"}}}}, + {"hTrack0Pt", "hTrack0Pt", {HistType::kTH1F, {{200, 0.0f, 10.0f, "p_{T}"}}}}, + {"hTrack1Pt", "hTrack1Pt", {HistType::kTH1F, {{200, 0.0f, 10.0f, "p_{T}"}}}}, + {"hTrack2Pt", "hTrack2Pt", {HistType::kTH1F, {{200, 0.0f, 10.0f, "p_{T}"}}}}, + {"hTOFPIDDeuteron", "hTOFPIDDeuteron", {HistType::kTH1F, {{2000, -100.0f, 100.0f}}}}, + {"hDeuTOFNsigma", "Deuteron TOF Nsigma distribution", {HistType::kTH2F, {{1200, -6, 6, "#it{p} (GeV/#it{c})"}, {2000, -100, 100, "TOF n#sigma"}}}}, + {"hDeuTOFNsigmaWithTPC", "Deuteron TOF Nsigma distribution", {HistType::kTH2F, {{1200, -6, 6, "#it{p} (GeV/#it{c})"}, {1000, -100, 100, "TOF n#sigma"}}}}, + }, + }; + void init(InitContext const&) + { + AxisSpec massAxis = {120, 2.9f, 3.2f, "Inv. Mass (GeV/c^{2})"}; + registry.add("hMassHypertriton", "hMassHypertriton", {HistType::kTH1F, {massAxis}}); + registry.add("hMassAntiHypertriton", "hMassAntiHypertriton", {HistType::kTH1F, {massAxis}}); + } + void process(aod::Collision const& collision, aod::Vtx3BodyDatas const& vtx3bodydatas, FullTracksExtIU const& tracks) + { + for (auto& vtx : vtx3bodydatas) { + auto track0 = vtx.track0_as(); + auto track1 = vtx.track1_as(); + auto track2 = vtx.track2_as(); + + registry.fill(HIST("hVtxRadius"), vtx.vtxradius()); + registry.fill(HIST("hVtxCosPA"), vtx.vtxcosPA(collision.posX(), collision.posY(), collision.posZ())); + registry.fill(HIST("hDCAVtxDau"), vtx.dcaVtxdaughters()); + registry.fill(HIST("hVtxPt"), vtx.pt()); + registry.fill(HIST("hTrack0Pt"), vtx.track0pt()); + registry.fill(HIST("hTrack1Pt"), vtx.track1pt()); + registry.fill(HIST("hTrack2Pt"), vtx.track2pt()); + registry.fill(HIST("hMassHypertriton"), vtx.mHypertriton()); + registry.fill(HIST("hMassAntiHypertriton"), vtx.mAntiHypertriton()); + registry.fill(HIST("hTOFPIDDeuteron"), track2.tofNSigmaDe()); + registry.fill(HIST("hDeuTOFNsigma"), track2.tpcInnerParam() * track2.sign(), track2.tofNSigmaDe()); + if (std::abs(track2.tpcNSigmaDe()) < 5) { + registry.fill(HIST("hDeuTOFNsigmaWithTPC"), track2.tpcInnerParam() * track2.sign(), track2.tofNSigmaDe()); + } + if (track2.sign() > 0) { + registry.fill(HIST("hPtProton"), track0.pt()); + registry.fill(HIST("hPtAntiPion"), track1.pt()); + registry.fill(HIST("hPtDeuteron"), track2.pt()); + registry.fill(HIST("hDCAProtonToPV"), vtx.dcatrack0topv()); + registry.fill(HIST("hDCAPionToPV"), vtx.dcatrack1topv()); + registry.fill(HIST("hProtonTPCNcls"), track0.tpcNClsCrossedRows()); + registry.fill(HIST("hPionTPCNcls"), track1.tpcNClsCrossedRows()); + } else { + registry.fill(HIST("hPtPion"), track0.pt()); + registry.fill(HIST("hPtAntiProton"), track1.pt()); + registry.fill(HIST("hPtAntiDeuteron"), track2.pt()); + registry.fill(HIST("hDCAProtonToPV"), vtx.dcatrack1topv()); + registry.fill(HIST("hDCAPionToPV"), vtx.dcatrack0topv()); + registry.fill(HIST("hProtonTPCNcls"), track1.tpcNClsCrossedRows()); + registry.fill(HIST("hPionTPCNcls"), track0.tpcNClsCrossedRows()); + } + registry.fill(HIST("hDCADeuteronToPV"), vtx.dcatrack2topv()); + registry.fill(HIST("hDeuteronTPCNcls"), track2.tpcNClsCrossedRows()); + } + } +}; + +struct hypertriton3bodyAnalysis { + + // Selection criteria + Configurable vtxcospa{"vtxcospa", 0.99, "Vtx CosPA"}; // double -> N.B. dcos(x)/dx = 0 at x=0) + Configurable dcavtxdau{"dcavtxdau", 1.0, "DCA Vtx Daughters"}; // loose cut + Configurable dcapiontopv{"dcapiontopv", .00, "DCA Pion To PV"}; + Configurable etacut{"etacut", 1, "etacut"}; + Configurable rapiditycut{"rapiditycut", 1, "rapiditycut"}; + Configurable TofPidNsigmaMin{"TofPidNsigmaMin", -4, "TofPidNsigmaMin"}; + Configurable TofPidNsigmaMax{"TofPidNsigmaMax", 4, "TofPidNsigmaMax"}; + Configurable TpcPidNsigmaCut{"TpcPidNsigmaCut", 5, "TpcPidNsigmaCut"}; + Configurable event_sel8_selection{"event_sel8_selection", true, "event selection count post sel8 cut"}; + Configurable lifetimecut{"lifetimecut", 40., "lifetimecut"}; // ct + Configurable minProtonPt{"minProtonPt", 0.3, "minProtonPt"}; + Configurable maxProtonPt{"maxProtonPt", 5, "maxProtonPt"}; + Configurable minPionPt{"minPionPt", 0.1, "minPionPt"}; + Configurable maxPionPt{"maxPionPt", 1.2, "maxPionPt"}; + Configurable minDeuteronPt{"minDeuteronPt", 0.6, "minDeuteronPt"}; + Configurable maxDeuteronPt{"maxDeuteronPt", 10, "maxDeuteronPt"}; + Configurable minDeuteronPUseTOF{"minDeuteronPUseTOF", 1, "minDeuteronPt Enable TOF PID"}; + Configurable h3LMassLowerlimit{"h3LMassLowerlimit", 2.96, "Hypertriton mass lower limit"}; + Configurable h3LMassUpperlimit{"h3LMassUpperlimit", 3.04, "Hypertriton mass upper limit"}; + Configurable mincrossedrowsproton{"mincrossedrowsproton", 90, "min tpc crossed rows for pion"}; + Configurable mincrossedrowspion{"mincrossedrowspion", 70, "min tpc crossed rows"}; + Configurable mincrossedrowsdeuteron{"mincrossedrowsdeuteron", 100, "min tpc crossed rows for deuteron"}; + + Configurable mcsigma{"mcsigma", 0.0015, "sigma of mc invariant mass fit"}; // obtained from MC + + HistogramRegistry registry{ + "registry", + { + {"hEventCounter", "hEventCounter", {HistType::kTH1F, {{3, 0.0f, 3.0f}}}}, + {"hCandidatesCounter", "hCandidatesCounter", {HistType::kTH1F, {{12, 0.0f, 12.0f}}}}, + {"hMassHypertriton", "hMassHypertriton", {HistType::kTH1F, {{80, 2.96f, 3.04f}}}}, + {"hMassAntiHypertriton", "hMassAntiHypertriton", {HistType::kTH1F, {{80, 2.96f, 3.04f}}}}, + {"hMassHypertritonTotal", "hMassHypertritonTotal", {HistType::kTH1F, {{300, 2.9f, 3.2f}}}}, + {"hPtProton", "hPtProton", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hPtAntiPion", "hPtAntiPion", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hPtDeuteron", "hPtDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hPtAntiProton", "hPtAntiProton", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hPtPion", "hPtPion", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hPtAntiDeuteron", "hPtAntiDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hDCAProtonToPV", "hDCAProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, + {"hDCAPionToPV", "hDCAPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, + {"hDCADeuteronToPV", "hDCADeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, + {"hProtonTPCNcls", "hProtonTPCNcls", {HistType::kTH1F, {{180, 0, 180, "TPC cluster"}}}}, + {"hPionTPCNcls", "hPionTPCNcls", {HistType::kTH1F, {{180, 0, 180, "TPC cluster"}}}}, + {"hDeuteronTPCNcls", "hDeuteronTPCNcls", {HistType::kTH1F, {{180, 0, 180, "TPC cluster"}}}}, + {"hVtxCosPA", "hVtxCosPA", {HistType::kTH1F, {{1000, 0.9f, 1.0f}}}}, + {"hDCAVtxDau", "hDCAVtxDau", {HistType::kTH1F, {{1000, 0.0f, 10.0f, "cm^{2}"}}}}, + {"hTOFPIDDeuteron", "hTOFPIDDeuteron", {HistType::kTH1F, {{2000, -100.0f, 100.0f}}}}, + {"hTPCPIDProton", "hTPCPIDProton", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, + {"hTPCPIDPion", "hTPCPIDPion", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, + {"hTPCPIDDeuteron", "hTPCPIDDeuteron", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, + {"hProtonTPCBB", "hProtonTPCBB", {HistType::kTH2F, {{160, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, + {"hPionTPCBB", "hPionTPCBB", {HistType::kTH2F, {{160, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, + {"hDeuteronTPCBB", "hDeuteronTPCBB", {HistType::kTH2F, {{160, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, + {"hProtonTPCVsPt", "hProtonTPCVsPt", {HistType::kTH2F, {{50, 0.0f, 5.0f, "#it{p}_{T} (GeV/c)"}, {240, -6.0f, 6.0f, "TPC n#sigma"}}}}, + {"hPionTPCVsPt", "hPionTPCVsPt", {HistType::kTH2F, {{20, 0.0f, 2.0f, "#it{p}_{T} (GeV/c)"}, {240, -6.0f, 6.0f, "TPC n#sigma"}}}}, + {"hDeuteronTPCVsPt", "hDeuteronTPCVsPt", {HistType::kTH2F, {{80, 0.0f, 8.0f, "#it{p}_{T} (GeV/c)"}, {240, -6.0f, 6.0f, "TPC n#sigma"}}}}, + {"hDeuteronTOFVsPBeforeTOFCut", "hDeuteronTOFVsPBeforeTOFCut", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {40, -10.0f, 10.0f, "TOF n#sigma"}}}}, + {"hDeuteronTOFVsPAtferTOFCut", "hDeuteronTOFVsPAtferTOFCut", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {40, -10.0f, 10.0f, "TOF n#sigma"}}}}, + + {"hDalitz", "hDalitz", {HistType::kTH2F, {{120, 7.85, 8.45, "M^{2}(dp) (GeV^{2}/c^{4})"}, {60, 1.1, 1.4, "M^{2}(p#pi) (GeV^{2}/c^{4})"}}}}, + {"h3dMassHypertriton", "h3dMassHypertriton", {HistType::kTH3F, {{20, 0.0f, 100.0f, "Cent (%)"}, {200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}}}}, + {"h3dMassAntiHypertriton", "h3dMassAntiHypertriton", {HistType::kTH3F, {{20, 0.0f, 100.0f, "Cent (%)"}, {200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}}}}, + {"h3dTotalHypertriton", "h3dTotalHypertriton", {HistType::kTH3F, {{50, 0, 50, "ct(cm)"}, {200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}}}}, + + {"hTrueHypertritonCounter", "hTrueHypertritonCounter", {HistType::kTH1F, {{12, 0.0f, 12.0f}}}}, + {"hDeuteronTOFVsPBeforeTOFCutSig", "hDeuteronTOFVsPBeforeTOFCutSig", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {40, -10.0f, 10.0f, "TOF n#sigma"}}}}, + {"hDeuteronTOFVsPAtferTOFCutSig", "hDeuteronTOFVsPAtferTOFCutSig", {HistType::kTH2F, {{40, -10.0f, 10.0f, "p/z (GeV/c)"}, {40, -10.0f, 10.0f, "TOF n#sigma"}}}}, + {"h3dTotalTrueHypertriton", "h3dTotalTrueHypertriton", {HistType::kTH3F, {{50, 0, 50, "ct(cm)"}, {200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}}}}, + + // for mcparticles information + {"hGeneratedHypertritonCounter", "hGeneratedHypertritonCounter", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, + {"hPtGeneratedHypertriton", "hPtGeneratedHypertriton", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hctGeneratedHypertriton", "hctGeneratedHypertriton", {HistType::kTH1F, {{50, 0, 50, "ct(cm)"}}}}, + {"hEtaGeneratedHypertriton", "hEtaGeneratedHypertriton", {HistType::kTH1F, {{40, -2.0f, 2.0f}}}}, + {"hRapidityGeneratedHypertriton", "hRapidityGeneratedHypertriton", {HistType::kTH1F, {{40, -2.0f, 2.0f}}}}, + {"hPtGeneratedAntiHypertriton", "hPtGeneratedAntiHypertriton", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, + {"hctGeneratedAntiHypertriton", "hctGeneratedAntiHypertriton", {HistType::kTH1F, {{50, 0, 50, "ct(cm)"}}}}, + {"hEtaGeneratedAntiHypertriton", "hEtaGeneratedAntiHypertriton", {HistType::kTH1F, {{40, -2.0f, 2.0f}}}}, + {"hRapidityGeneratedAntiHypertriton", "hRapidityGeneratedAntiHypertriton", {HistType::kTH1F, {{40, -2.0f, 2.0f}}}}, + }, + }; + + //------------------------------------------------------------------ + // Fill stats histograms + enum vtxstep { kCandAll = 0, + kCandCosPA, + kCandDauEta, + kCandRapidity, + kCandct, + kCandDcaDau, + kCandTOFPID, + kCandTPCPID, + kCandTPCNcls, + kCandDauPt, + kCandDcaToPV, + kCandInvMass, + kNCandSteps }; + + struct { + std::array candstats; + std::array truecandstats; + } statisticsRegistry; + + void resetHistos() + { + for (Int_t ii = 0; ii < kNCandSteps; ii++) { + statisticsRegistry.candstats[ii] = 0; + statisticsRegistry.truecandstats[ii] = 0; + } + } + void FillCandCounter(int kn, bool istrue = false) + { + statisticsRegistry.candstats[kn]++; + if (istrue) { + statisticsRegistry.truecandstats[kn]++; + } + } + void fillHistos() + { + for (Int_t ii = 0; ii < kNCandSteps; ii++) { + registry.fill(HIST("hCandidatesCounter"), ii, statisticsRegistry.candstats[ii]); + registry.fill(HIST("hTrueHypertritonCounter"), ii, statisticsRegistry.truecandstats[ii]); + } + } + + Configurable saveDcaHist{"saveDcaHist", 1, "saveDcaHist"}; + ConfigurableAxis dcaBinning{"dca-binning", {200, 0.0f, 1.0f}, ""}; + ConfigurableAxis ptBinning{"pt-binning", {200, 0.0f, 10.0f}, ""}; + + void init(InitContext const&) + { + AxisSpec dcaAxis = {dcaBinning, "DCA (cm)"}; + AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/c)"}; + AxisSpec massAxisHypertriton = {80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}; + + if (saveDcaHist == 1) { + registry.add("h3dMassHypertritonDca", "h3dMassHypertritonDca", {HistType::kTH3F, {dcaAxis, ptAxis, massAxisHypertriton}}); + registry.add("h3dMassAntiHypertritonDca", "h3dMassAntiHypertritonDca", {HistType::kTH3F, {dcaAxis, ptAxis, massAxisHypertriton}}); + } + + TString CandCounterbinLabel[12] = {"Total", "VtxCosPA", "TrackEta", "MomRapidity", "Lifetime", "VtxDcaDau", "d TOFPID", "TPCPID", "TPCNcls", "DauPt", "PionDcatoPV", "InvMass"}; + for (int i{0}; i < kNCandSteps; i++) { + registry.get(HIST("hCandidatesCounter"))->GetXaxis()->SetBinLabel(i + 1, CandCounterbinLabel[i]); + registry.get(HIST("hTrueHypertritonCounter"))->GetXaxis()->SetBinLabel(i + 1, CandCounterbinLabel[i]); + } + + registry.get(HIST("hGeneratedHypertritonCounter"))->GetXaxis()->SetBinLabel(1, "Total"); + registry.get(HIST("hGeneratedHypertritonCounter"))->GetXaxis()->SetBinLabel(2, "3-body decay"); + } + + //------------------------------------------------------------------ + Preslice perCollisionVtx3BodyDatas = o2::aod::vtx3body::collisionId; + //------------------------------------------------------------------ + // Analysis process for a single candidate + template + void CandidateAnalysis(TCollisionTable const& dCollision, TCandTable const& candData, bool& if_hasvtx, bool isTrueCand = false, double MClifetime = -1, double lPt = -1) + { + + FillCandCounter(kCandAll, isTrueCand); + + auto track0 = candData.template track0_as(); + auto track1 = candData.template track1_as(); + auto track2 = candData.template track2_as(); + + auto& trackProton = (track2.sign() > 0) ? track0 : track1; + auto& trackPion = (track2.sign() > 0) ? track1 : track0; + auto& trackDeuteron = track2; + + if (candData.vtxcosPA(dCollision.posX(), dCollision.posY(), dCollision.posZ()) < vtxcospa) { + return; + } + FillCandCounter(kCandCosPA, isTrueCand); + if (TMath::Abs(trackProton.eta()) > etacut || TMath::Abs(trackPion.eta()) > etacut || TMath::Abs(trackDeuteron.eta()) > etacut) { + return; + } + FillCandCounter(kCandDauEta, isTrueCand); + if (TMath::Abs(candData.yHypertriton()) > rapiditycut) { + return; + } + FillCandCounter(kCandRapidity, isTrueCand); + double ct = candData.distovertotmom(dCollision.posX(), dCollision.posY(), dCollision.posZ()) * o2::constants::physics::MassHyperTriton; + if (ct > lifetimecut) { + return; + } + FillCandCounter(kCandct, isTrueCand); + if (candData.dcaVtxdaughters() > dcavtxdau) { + return; + } + FillCandCounter(kCandDcaDau, isTrueCand); + + registry.fill(HIST("hDeuteronTOFVsPBeforeTOFCut"), trackDeuteron.sign() * trackDeuteron.p(), trackDeuteron.tofNSigmaDe()); + if (isTrueCand) { + registry.fill(HIST("hDeuteronTOFVsPBeforeTOFCutSig"), trackDeuteron.sign() * trackDeuteron.p(), trackDeuteron.tofNSigmaDe()); + } + if ((trackDeuteron.tofNSigmaDe() < TofPidNsigmaMin || trackDeuteron.tofNSigmaDe() > TofPidNsigmaMax) && trackDeuteron.p() > minDeuteronPUseTOF) { + return; + } + FillCandCounter(kCandTOFPID, isTrueCand); + registry.fill(HIST("hDeuteronTOFVsPAtferTOFCut"), trackDeuteron.sign() * trackDeuteron.p(), trackDeuteron.tofNSigmaDe()); + if (isTrueCand) { + registry.fill(HIST("hDeuteronTOFVsPAtferTOFCutSig"), trackDeuteron.sign() * trackDeuteron.p(), trackDeuteron.tofNSigmaDe()); + } + + if (TMath::Abs(trackProton.tpcNSigmaPr()) > TpcPidNsigmaCut || TMath::Abs(trackPion.tpcNSigmaPi()) > TpcPidNsigmaCut || TMath::Abs(trackDeuteron.tpcNSigmaDe()) > TpcPidNsigmaCut) { + return; + } + FillCandCounter(kCandTPCPID, isTrueCand); + + if (trackProton.tpcNClsCrossedRows() < mincrossedrowsproton || trackPion.tpcNClsCrossedRows() < mincrossedrowspion || trackDeuteron.tpcNClsCrossedRows() < mincrossedrowsdeuteron) { + return; + } + FillCandCounter(kCandTPCNcls, isTrueCand); + + if (trackProton.pt() < minProtonPt || trackProton.pt() > maxProtonPt || trackPion.pt() < minPionPt || trackPion.pt() > maxPionPt || trackDeuteron.pt() < minDeuteronPt || trackDeuteron.pt() > maxDeuteronPt) { + return; + } + FillCandCounter(kCandDauPt, isTrueCand); + + double dcapion = (track2.sign() > 0) ? candData.dcatrack1topv() : candData.dcatrack0topv(); + if (TMath::Abs(dcapion) < dcapiontopv) { + return; + } + FillCandCounter(kCandDcaToPV, isTrueCand); + + // 3sigma region for Dalitz plot + double lowersignallimit = o2::constants::physics::MassHyperTriton - 3 * mcsigma; + double uppersignallimit = o2::constants::physics::MassHyperTriton + 3 * mcsigma; + + // Hypertriton + if ((track2.sign() > 0 && candData.mHypertriton() > h3LMassLowerlimit && candData.mHypertriton() < h3LMassUpperlimit)) { + if_hasvtx = true; + FillCandCounter(kCandInvMass, isTrueCand); + + registry.fill(HIST("hPtProton"), trackProton.pt()); + registry.fill(HIST("hPtAntiPion"), trackPion.pt()); + registry.fill(HIST("hPtDeuteron"), trackDeuteron.pt()); + registry.fill(HIST("hDCAProtonToPV"), candData.dcatrack0topv()); + registry.fill(HIST("hDCAPionToPV"), candData.dcatrack1topv()); + + registry.fill(HIST("hMassHypertriton"), candData.mHypertriton()); + registry.fill(HIST("hMassHypertritonTotal"), candData.mHypertriton()); + registry.fill(HIST("h3dMassHypertriton"), 0., candData.pt(), candData.mHypertriton()); // dCollision.centV0M() instead of 0. once available + registry.fill(HIST("h3dTotalHypertriton"), ct, candData.pt(), candData.mHypertriton()); + if (candData.mHypertriton() > lowersignallimit && candData.mHypertriton() < uppersignallimit) { + registry.fill(HIST("hDalitz"), RecoDecay::m2(array{array{candData.pxtrack0(), candData.pytrack0(), candData.pztrack0()}, array{candData.pxtrack2(), candData.pytrack2(), candData.pztrack2()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassDeuteron}), RecoDecay::m2(array{array{candData.pxtrack0(), candData.pytrack0(), candData.pztrack0()}, array{candData.pxtrack1(), candData.pytrack1(), candData.pztrack1()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged})); + } + if (isTrueCand) { + registry.fill(HIST("h3dTotalTrueHypertriton"), MClifetime, lPt, candData.mHypertriton()); + } + if (saveDcaHist == 1) { + registry.fill(HIST("h3dMassHypertritonDca"), candData.dcaVtxdaughters(), candData.pt(), candData.mHypertriton()); + } + } else if ((track2.sign() < 0 && candData.mAntiHypertriton() > h3LMassLowerlimit && candData.mAntiHypertriton() < h3LMassUpperlimit)) { + // AntiHypertriton + if_hasvtx = true; + FillCandCounter(kCandInvMass, isTrueCand); + + registry.fill(HIST("hPtAntiProton"), trackProton.pt()); + registry.fill(HIST("hPtPion"), trackPion.pt()); + registry.fill(HIST("hPtAntiDeuteron"), trackDeuteron.pt()); + registry.fill(HIST("hDCAProtonToPV"), candData.dcatrack1topv()); + registry.fill(HIST("hDCAPionToPV"), candData.dcatrack0topv()); + + registry.fill(HIST("hMassAntiHypertriton"), candData.mAntiHypertriton()); + registry.fill(HIST("hMassHypertritonTotal"), candData.mAntiHypertriton()); + registry.fill(HIST("h3dMassAntiHypertriton"), 0., candData.pt(), candData.mAntiHypertriton()); // dCollision.centV0M() instead of 0. once available + registry.fill(HIST("h3dTotalHypertriton"), ct, candData.pt(), candData.mAntiHypertriton()); + if (candData.mAntiHypertriton() > lowersignallimit && candData.mAntiHypertriton() < uppersignallimit) { + registry.fill(HIST("hDalitz"), RecoDecay::m2(array{array{candData.pxtrack1(), candData.pytrack1(), candData.pztrack1()}, array{candData.pxtrack2(), candData.pytrack2(), candData.pztrack2()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassDeuteron}), RecoDecay::m2(array{array{candData.pxtrack1(), candData.pytrack1(), candData.pztrack1()}, array{candData.pxtrack0(), candData.pytrack0(), candData.pztrack0()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged})); + } + if (isTrueCand) { + registry.fill(HIST("h3dTotalTrueHypertriton"), MClifetime, lPt, candData.mHypertriton()); + } + if (saveDcaHist == 1) { + registry.fill(HIST("h3dMassAntiHypertritonDca"), candData.dcaVtxdaughters(), candData.pt(), candData.mAntiHypertriton()); + } + } else { + return; + } + registry.fill(HIST("hDCADeuteronToPV"), candData.dcatrack2topv()); + registry.fill(HIST("hVtxCosPA"), candData.vtxcosPA(dCollision.posX(), dCollision.posY(), dCollision.posZ())); + registry.fill(HIST("hDCAVtxDau"), candData.dcaVtxdaughters()); + registry.fill(HIST("hProtonTPCNcls"), trackProton.tpcNClsCrossedRows()); + registry.fill(HIST("hPionTPCNcls"), trackPion.tpcNClsCrossedRows()); + registry.fill(HIST("hDeuteronTPCNcls"), trackDeuteron.tpcNClsCrossedRows()); + registry.fill(HIST("hTPCPIDProton"), trackProton.tpcNSigmaPr()); + registry.fill(HIST("hTPCPIDPion"), trackPion.tpcNSigmaPi()); + registry.fill(HIST("hTPCPIDDeuteron"), trackDeuteron.tpcNSigmaDe()); + registry.fill(HIST("hProtonTPCBB"), trackProton.sign() * trackProton.p(), trackProton.tpcSignal()); + registry.fill(HIST("hPionTPCBB"), trackPion.sign() * trackPion.p(), trackPion.tpcSignal()); + registry.fill(HIST("hDeuteronTPCBB"), trackDeuteron.sign() * trackDeuteron.p(), trackDeuteron.tpcSignal()); + registry.fill(HIST("hProtonTPCVsPt"), trackProton.pt(), trackProton.tpcNSigmaPr()); + registry.fill(HIST("hPionTPCVsPt"), trackProton.pt(), trackPion.tpcNSigmaPi()); + registry.fill(HIST("hDeuteronTPCVsPt"), trackDeuteron.pt(), trackDeuteron.tpcNSigmaDe()); + registry.fill(HIST("hTOFPIDDeuteron"), trackDeuteron.tofNSigmaDe()); + } + + //------------------------------------------------------------------ + // collect information for generated hypertriton (should be called after event selection) + void GetGeneratedH3LInfo(aod::McParticles const& particlesMC) + { + for (auto& mcparticle : particlesMC) { + if (mcparticle.pdgCode() != 1010010030 && mcparticle.pdgCode() != -1010010030) { + continue; + } + registry.fill(HIST("hGeneratedHypertritonCounter"), 0.5); + + bool haveProton = false, havePion = false, haveDeuteron = false; + bool haveAntiProton = false, haveAntiPion = false, haveAntiDeuteron = false; + double MClifetime = -1; + for (auto& mcparticleDaughter : mcparticle.template daughters_as()) { + if (mcparticleDaughter.pdgCode() == 2212) + haveProton = true; + if (mcparticleDaughter.pdgCode() == -2212) + haveAntiProton = true; + if (mcparticleDaughter.pdgCode() == 211) + havePion = true; + if (mcparticleDaughter.pdgCode() == -211) + haveAntiPion = true; + if (mcparticleDaughter.pdgCode() == 1000010020) { + haveDeuteron = true; + MClifetime = RecoDecay::sqrtSumOfSquares(mcparticleDaughter.vx() - mcparticle.vx(), mcparticleDaughter.vy() - mcparticle.vy(), mcparticleDaughter.vz() - mcparticle.vz()) * o2::constants::physics::MassHyperTriton / mcparticle.p(); + } + if (mcparticleDaughter.pdgCode() == -1000010020) { + haveAntiDeuteron = true; + MClifetime = RecoDecay::sqrtSumOfSquares(mcparticleDaughter.vx() - mcparticle.vx(), mcparticleDaughter.vy() - mcparticle.vy(), mcparticleDaughter.vz() - mcparticle.vz()) * o2::constants::physics::MassHyperTriton / mcparticle.p(); + } + } + if (haveProton && haveAntiPion && haveDeuteron && mcparticle.pdgCode() == 1010010030) { + registry.fill(HIST("hGeneratedHypertritonCounter"), 1.5); + registry.fill(HIST("hPtGeneratedHypertriton"), mcparticle.pt()); + registry.fill(HIST("hctGeneratedHypertriton"), MClifetime); + registry.fill(HIST("hEtaGeneratedHypertriton"), mcparticle.eta()); + registry.fill(HIST("hRapidityGeneratedHypertriton"), mcparticle.y()); + } else if (haveAntiProton && havePion && haveAntiDeuteron && mcparticle.pdgCode() == -1010010030) { + registry.fill(HIST("hGeneratedHypertritonCounter"), 1.5); + registry.fill(HIST("hPtGeneratedAntiHypertriton"), mcparticle.pt()); + registry.fill(HIST("hctGeneratedAntiHypertriton"), MClifetime); + registry.fill(HIST("hEtaGeneratedAntiHypertriton"), mcparticle.eta()); + registry.fill(HIST("hRapidityGeneratedAntiHypertriton"), mcparticle.y()); + } + } + } + + //------------------------------------------------------------------ + // process real data analysis + void processData(soa::Join::iterator const& collision, aod::Vtx3BodyDatas const& vtx3bodydatas, FullTracksExtIU const& tracks) + { + registry.fill(HIST("hEventCounter"), 0.5); + if (event_sel8_selection && !collision.sel8()) { + return; + } + registry.fill(HIST("hEventCounter"), 1.5); + + bool if_hasvtx = false; + + for (auto& vtx : vtx3bodydatas) { + CandidateAnalysis(collision, vtx, if_hasvtx); + } + + if (if_hasvtx) + registry.fill(HIST("hEventCounter"), 2.5); + fillHistos(); + resetHistos(); + } + PROCESS_SWITCH(hypertriton3bodyAnalysis, processData, "Real data analysis", true); + + //------------------------------------------------------------------ + // process mc analysis + void processMC(soa::Join const& collisions, aod::Vtx3BodyDatas const& vtx3bodydatas, aod::McParticles const& particlesMC, MCLabeledFullTracksExtIU const& tracks) + { + GetGeneratedH3LInfo(particlesMC); + + for (const auto& collision : collisions) { + registry.fill(HIST("hEventCounter"), 0.5); + if (event_sel8_selection && !collision.sel8()) { + continue; + } + registry.fill(HIST("hEventCounter"), 1.5); + + bool if_hasvtx = false; + auto vtxsthiscol = vtx3bodydatas.sliceBy(perCollisionVtx3BodyDatas, collision.globalIndex()); + + for (auto& vtx : vtxsthiscol) { + // int lLabel = -1; + int lPDG = -1; + float lPt = -1; + double MClifetime = -1; + bool isTrueCand = false; + auto track0 = vtx.track0_as(); + auto track1 = vtx.track1_as(); + auto track2 = vtx.track2_as(); + if (track0.has_mcParticle() && track1.has_mcParticle() && track2.has_mcParticle()) { + auto lMCTrack0 = track0.mcParticle_as(); + auto lMCTrack1 = track1.mcParticle_as(); + auto lMCTrack2 = track2.mcParticle_as(); + if (lMCTrack0.has_mothers() && lMCTrack1.has_mothers() && lMCTrack2.has_mothers()) { + for (auto& lMother0 : lMCTrack0.mothers_as()) { + for (auto& lMother1 : lMCTrack1.mothers_as()) { + for (auto& lMother2 : lMCTrack2.mothers_as()) { + if (lMother0.globalIndex() == lMother1.globalIndex() && lMother0.globalIndex() == lMother2.globalIndex()) { + // lLabel = lMother1.globalIndex(); + lPt = lMother1.pt(); + lPDG = lMother1.pdgCode(); + if ((lPDG == 1010010030 && lMCTrack0.pdgCode() == 2212 && lMCTrack1.pdgCode() == -211 && lMCTrack2.pdgCode() == 1000010020) || + (lPDG == -1010010030 && lMCTrack0.pdgCode() == 211 && lMCTrack1.pdgCode() == -2212 && lMCTrack2.pdgCode() == -1000010020)) { + isTrueCand = true; + MClifetime = RecoDecay::sqrtSumOfSquares(lMCTrack2.vx() - lMother2.vx(), lMCTrack2.vy() - lMother2.vy(), lMCTrack2.vz() - lMother2.vz()) * o2::constants::physics::MassHyperTriton / lMother2.p(); + } + } + } + } + } + } + } + + CandidateAnalysis(collision, vtx, if_hasvtx, isTrueCand, MClifetime, lPt); + } + + if (if_hasvtx) + registry.fill(HIST("hEventCounter"), 2.5); + fillHistos(); + resetHistos(); + } + } + PROCESS_SWITCH(hypertriton3bodyAnalysis, processMC, "MC analysis", false); +}; + +// check vtx3body with mclabels +struct hypertriton3bodyLabelCheck { + HistogramRegistry registry{ + "registry", + { + {"hLabeledVtxCounter", "hLabeledVtxCounter", {HistType::kTH1F, {{3, 0.0f, 3.0f}}}}, + {"hMassTrueH3L", "hMassTrueH3L", {HistType::kTH1F, {{80, 2.96f, 3.04f}}}}, + {"hMassTrueH3LMatter", "hMassTrueH3LMatter", {HistType::kTH1F, {{80, 2.96f, 3.04f}}}}, + {"hMassTrueH3LAntiMatter", "hMassTrueH3LAntiMatter", {HistType::kTH1F, {{80, 2.96f, 3.04f}}}}, + }, + }; + + void init(InitContext const&) + { + registry.get(HIST("hLabeledVtxCounter"))->GetXaxis()->SetBinLabel(1, "Readin"); + registry.get(HIST("hLabeledVtxCounter"))->GetXaxis()->SetBinLabel(2, "TrueMCH3L"); + registry.get(HIST("hLabeledVtxCounter"))->GetXaxis()->SetBinLabel(3, "Nonrepetitive"); + } + + Configurable event_sel8_selection{"event_sel8_selection", true, "event selection count post sel8 cut"}; + + void process(soa::Join::iterator const& collision) + { + // dummy function + } + PROCESS_SWITCH(hypertriton3bodyLabelCheck, process, "Donot check MC label tables", true); + + void processCheckLabel(soa::Join::iterator const& collision, soa::Join const& vtx3bodydatas, MCLabeledFullTracksExtIU const& tracks, aod::McParticles const& particlesMC) + { + if (event_sel8_selection && !collision.sel8()) { + return; + } + + std::vector set_mothertrack; + for (auto& vtx : vtx3bodydatas) { + registry.fill(HIST("hLabeledVtxCounter"), 0.5); + if (vtx.mcParticleId() != -1) { + auto mcparticle = vtx.mcParticle_as(); + if (mcparticle.pdgCode() == 1010010030) { + registry.fill(HIST("hLabeledVtxCounter"), 1.5); + registry.fill(HIST("hMassTrueH3L"), vtx.mHypertriton()); + registry.fill(HIST("hMassTrueH3LMatter"), vtx.mHypertriton()); + auto p = std::find(set_mothertrack.begin(), set_mothertrack.end(), mcparticle.globalIndex()); + if (p == set_mothertrack.end()) { + set_mothertrack.push_back(mcparticle.globalIndex()); + registry.fill(HIST("hLabeledVtxCounter"), 2.5); + } + } else if (mcparticle.pdgCode() == -1010010030) { + registry.fill(HIST("hLabeledVtxCounter"), 1.5); + registry.fill(HIST("hMassTrueH3L"), vtx.mAntiHypertriton()); + registry.fill(HIST("hMassTrueH3LAntiMatter"), vtx.mAntiHypertriton()); + auto p = std::find(set_mothertrack.begin(), set_mothertrack.end(), mcparticle.globalIndex()); + if (p == set_mothertrack.end()) { + set_mothertrack.push_back(mcparticle.globalIndex()); + registry.fill(HIST("hLabeledVtxCounter"), 2.5); + } + } + } + } + } + PROCESS_SWITCH(hypertriton3bodyLabelCheck, processCheckLabel, "Check MC label tables", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc), + }; +} diff --git a/PWGLF/Tasks/hypertritonAnalysis.cxx b/PWGLF/Tasks/Nuspex/hypertritonAnalysis.cxx similarity index 100% rename from PWGLF/Tasks/hypertritonAnalysis.cxx rename to PWGLF/Tasks/Nuspex/hypertritonAnalysis.cxx diff --git a/PWGLF/Tasks/identifiedraa.cxx b/PWGLF/Tasks/Nuspex/identifiedraa.cxx similarity index 100% rename from PWGLF/Tasks/identifiedraa.cxx rename to PWGLF/Tasks/Nuspex/identifiedraa.cxx diff --git a/PWGLF/Tasks/mcspectraefficiency.cxx b/PWGLF/Tasks/Nuspex/mcspectraefficiency.cxx similarity index 100% rename from PWGLF/Tasks/mcspectraefficiency.cxx rename to PWGLF/Tasks/Nuspex/mcspectraefficiency.cxx diff --git a/PWGLF/Tasks/Nuspex/nucleiFlow.cxx b/PWGLF/Tasks/Nuspex/nucleiFlow.cxx new file mode 100644 index 00000000000..85729edf30d --- /dev/null +++ b/PWGLF/Tasks/Nuspex/nucleiFlow.cxx @@ -0,0 +1,283 @@ +// 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 nuclei_flow.cxx +/// \brief Measure flow of nuclei using LFSlimNucleiTable data format +/// + +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/Configurable.h" +#include "DataFormatsTPC/BetheBlochAleph.h" +#include "PWGLF/DataModel/LFSlimNucleiTables.h" +#include "Common/Core/EventPlaneHelper.h" +#include "TMath.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::constants::physics; + +namespace nuclei_spectra +{ + +constexpr float charges[5]{1.f, 1.f, 1.f, 2.f, 2.f}; + +constexpr float masses[5]{MassProton, MassDeuteron, MassTriton, MassHelium3, MassAlpha}; + +constexpr float bbMomScalingDefault[5][2]{ + {1., 1.}, + {1., 1.}, + {1., 1.}, + {1., 1.}, + {1., 1.}}; + +constexpr float betheBlochDefault[5][6]{ + {-1.e32, -1.e32, -1.e32, -1.e32, -1.e32, -1.e32}, + {-1.e32, -1.e32, -1.e32, -1.e32, -1.e32, -1.e32}, + {-1.e32, -1.e32, -1.e32, -1.e32, -1.e32, -1.e32}, + {-1.e32, -1.e32, -1.e32, -1.e32, -1.e32, -1.e32}, + {-1.e32, -1.e32, -1.e32, -1.e32, -1.e32, -1.e32}}; + +static const std::vector names{"proton", "deuteron", "triton", "He3", "alpha"}; +static const std::vector chargeLabelNames{"Positive", "Negative"}; +static const std::vector betheBlochParNames{"p0", "p1", "p2", "p3", "p4", "resolution"}; + +enum CandBits { + kProton = BIT(0), + kDeuteron = BIT(1), + kTriton = BIT(2), + kHe3 = BIT(3), + kHe4 = BIT(4), + kHasTOF = BIT(5), + kIsReconstructed = BIT(6), + kIsAmbiguous = BIT(7), /// just a placeholder now + kPositive = BIT(8), + kIsPhysicalPrimary = BIT(9), /// MC flags starting from the second half of the short + kIsSecondaryFromMaterial = BIT(10), + kIsSecondaryFromWeakDecay = BIT(11) /// the last 4 bits are reserved for the PID in tracking +}; + +} // namespace nuclei_spectra + +namespace flow +{ +enum kDetector { + kFV0A = 0, + kFT0M = 1, + kFT0A = 2, + kFT0C = 3, + kTPCpos = 4, + kTPCneg = 5 +}; +} // namespace flow + +struct nucleiFlow { + + Configurable cfgCentDetector{"cfgCentDetector", 0, "Detector for centrality estimation (FV0A: 0, FT0M: 1, FT0A: 2, FT0C: 3)"}; + Configurable cfgHarmonic{"cfgHarmonic", 2, "cfgHarmonic number"}; + Configurable cfgQvecDetector{"cfgQvecDetector", 0, "Detector for Q vector estimation (FV0A: 0, FT0M: 1, FT0A: 2, FT0C: 3, TPC Pos: 4, TPC Neg: 5)"}; + Configurable cfgSpecies{"cfgSpecies", 3, "Species under study (proton: 0, deuteron: 1, triton: 2, helion: 3, alpha: 4)"}; + + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + ConfigurableAxis nSigmaBins{"nSigmaBins", {200, -5.f, 5.f}, "Binning for n sigma"}; + ConfigurableAxis centBins{"centBins", {111, -0.5f, 110.5f}, "Binning for centrality"}; + ConfigurableAxis ptBins{"ptBins", {50, 0.f, 5.f}, "Binning for pt"}; + ConfigurableAxis spBins{"spBins", {100, -1.f, 1.f}, "Binning for scalar product"}; + + /// \brief momentum scaling-factor for TPC Bethe-Bloch + Configurable> cfgMomentumScalingBetheBloch{"cfgMomentumScalingBetheBloch", {nuclei_spectra::bbMomScalingDefault[0], 5, 2, nuclei_spectra::names, nuclei_spectra::chargeLabelNames}, "TPC Bethe-Bloch momentum scaling for light nuclei"}; + + /// \brief bethe-bloch parameters + Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {nuclei_spectra::betheBlochDefault[0], 5, 6, nuclei_spectra::names, nuclei_spectra::betheBlochParNames}, "TPC Bethe-Bloch parameterisation for light nuclei"}; + + EventPlaneHelper epHelper; + + /// \brief Get n-sigma TPC + /// \tparam T type for the collision + /// \param candidate track candidate + /// \param iSpecies 0: proton, 1: deuteron, 2: triton, 3: He3, 4: Alpha + /// \param iCharge 0: positive, 1: negative + /// \return n-sigma TPC for candidates with iSpecies hypothesis + template + float getNSigmaTPC(const T& candidate, int iSpecies, int iCharge) + { + float scaling_factor = nuclei_spectra::charges[iSpecies] * cfgMomentumScalingBetheBloch->get(iSpecies, iCharge) / nuclei_spectra::masses[iSpecies]; + + float expTPCSignal = o2::tpc::BetheBlochAleph(static_cast(candidate.tpcInnerParam() * scaling_factor), + cfgBetheBlochParams->get(iSpecies, 0u), + cfgBetheBlochParams->get(iSpecies, 1u), + cfgBetheBlochParams->get(iSpecies, 2u), + cfgBetheBlochParams->get(iSpecies, 3u), + cfgBetheBlochParams->get(iSpecies, 4u)); + float resolutionTPC{expTPCSignal * cfgBetheBlochParams->get(iSpecies, 5u)}; + return static_cast((candidate.tpcSignal() - expTPCSignal) / resolutionTPC); + } + + /// \brief Get the centrality with the selected detector + /// \param collision collision with the centrality information + /// \return centrality expressed in percentage + float getRefCentrality(aod::NucleiFlowColl const& collision) + { + float cent = -999.; + switch (cfgCentDetector) { + case flow::kDetector::kFV0A: + cent = collision.centFV0A(); + break; + case flow::kDetector::kFT0M: + cent = collision.centFT0M(); + break; + case flow::kDetector::kFT0A: + cent = collision.centFT0A(); + break; + case flow::kDetector::kFT0C: + cent = collision.centFT0C(); + break; + default: + LOG(warning) << "Centrality estimator not valid. Possible values are V0A, T0M, T0A, T0C. Fallback to V0A"; + cent = collision.centFV0A(); + break; + } + return cent; + } + + /// \brief Get the Q vector etimated with a particular detector + /// \param collision collision with the Q vector information + /// \return Q vector in format {x, y} + std::vector getQvec(aod::NucleiFlowColl const& collision, int detector) + { + float xQvec = -999.; + float yQvec = -999.; + float amplQvec = -999.; + switch (detector) { + case flow::kDetector::kFV0A: + xQvec = collision.xQvecFV0A(); + yQvec = collision.yQvecFV0A(); + amplQvec = collision.amplQvecFV0A(); + break; + case flow::kDetector::kFT0M: + xQvec = collision.xQvecFT0M(); + yQvec = collision.yQvecFT0M(); + amplQvec = collision.amplQvecFT0M(); + break; + case flow::kDetector::kFT0A: + xQvec = collision.xQvecFT0A(); + yQvec = collision.yQvecFT0A(); + amplQvec = collision.amplQvecFT0A(); + break; + case flow::kDetector::kFT0C: + xQvec = collision.xQvecFT0M(); + yQvec = collision.yQvecFT0M(); + amplQvec = collision.amplQvecFT0M(); + break; + case flow::kDetector::kTPCpos: + xQvec = collision.xQvecTPCpos(); + yQvec = collision.yQvecTPCpos(); + amplQvec = collision.amplQvecTPCpos(); + break; + case flow::kDetector::kTPCneg: + xQvec = collision.xQvecTPCneg(); + yQvec = collision.yQvecTPCneg(); + amplQvec = collision.amplQvecTPCneg(); + break; + default: + LOG(warning) << "Q vector estimator not valid. Please choose between FV0A, FT0M, FT0A, FT0C, TPC Pos, TPC Neg. Fallback to FV0A"; + xQvec = collision.xQvecFV0A(); + yQvec = collision.yQvecFV0A(); + amplQvec = collision.amplQvecFV0A(); + break; + } + return {xQvec, yQvec, amplQvec}; + } + + void init(o2::framework::InitContext&) + { + const AxisSpec nSigmaTPCHe3Axis{nSigmaBins, "n{#sigma}_{TPC}({}^{3}He)"}; + const AxisSpec ptAxis{ptBins, "#it{p}_{T} (GeV/#it{c})"}; + const AxisSpec centAxis{centBins, "centrality(%)"}; + const AxisSpec FT0AspAxis{spBins, "#hat{u}_{2} #upoint #vec{Q}_{2}^{FT0A}"}; + const AxisSpec FT0CspAxis{spBins, "#hat{u}_{2} #upoint #vec{Q}_{2}^{FT0C}"}; + const AxisSpec FV0AspAxis{spBins, "#hat{u}_{2} #upoint #vec{Q}_{2}^{FV0A}"}; + + histos.add("hCentFV0A", "FV0A", HistType::kTH1F, {centAxis}); + histos.add("hCentFT0M", "FT0M", HistType::kTH1F, {centAxis}); + histos.add("hCentFT0A", "FT0A", HistType::kTH1F, {centAxis}); + histos.add("hCentFT0C", "FT0C", HistType::kTH1F, {centAxis}); + + histos.add("hSpFT0AvsNsigmaHe3VsPtvsCent", "", HistType::kTHnSparseF, {FT0AspAxis, nSigmaTPCHe3Axis, ptAxis, centAxis}); + histos.add("hSpFT0CvsNsigmaHe3VsPtvsCent", "", HistType::kTHnSparseF, {FT0CspAxis, nSigmaTPCHe3Axis, ptAxis, centAxis}); + histos.add("hSpFV0AvsNsigmaHe3VsPtvsCent", "", HistType::kTHnSparseF, {FV0AspAxis, nSigmaTPCHe3Axis, ptAxis, centAxis}); + } + + void process(aod::NucleiFlowColl const& coll, aod::NucleiTable const& tracks) + { + histos.fill(HIST("hCentFV0A"), coll.centFV0A()); + histos.fill(HIST("hCentFT0M"), coll.centFT0M()); + histos.fill(HIST("hCentFT0A"), coll.centFT0A()); + histos.fill(HIST("hCentFT0C"), coll.centFT0C()); + + // Select the centrality value to be stored in the output histograms + float ref_cent = getRefCentrality(coll); + + // Get event plane with T0A + std::vector qVecFT0A = getQvec(coll, flow::kDetector::kFT0A); + float xQvecFT0A = qVecFT0A[0]; + float yQvecFT0A = qVecFT0A[1]; + // float amplQvecFT0A = qVecFT0A[2]; + // float evtPlFT0A = epHelper.GetEventPlane(xQvecFT0A, yQvecFT0A, cfgHarmonic); + + // Get event plane with T0C + std::vector qVecFT0C = getQvec(coll, flow::kDetector::kFT0C); + float xQvecFT0C = qVecFT0C[0]; + float yQvecFT0C = qVecFT0C[1]; + // float amplQvecFT0C = qVecFT0C[2]; + // float evtPlFT0C = epHelper.GetEventPlane(xQvecFT0C, yQvecFT0C, cfgHarmonic); + + // Get event plane with V0A + std::vector qVecFV0A = getQvec(coll, flow::kDetector::kFV0A); + float xQvecFV0A = qVecFV0A[0]; + float yQvecFV0A = qVecFV0A[1]; + // float amplQvecFV0A = qVecFV0A[2]; + // float evtPlFV0A = epHelper.GetEventPlane(xQvecFV0A, yQvecFV0A, cfgHarmonic); + + for (auto track : tracks) { + + // Get candidate vector + float xCandVec = TMath::Cos(cfgHarmonic * track.phi()); + float yCandVec = TMath::Sin(cfgHarmonic * track.phi()); + + // Get scalar products for different event planes + float spFT0A = xCandVec * xQvecFT0A + yCandVec * yQvecFT0A; + float spFT0C = xCandVec * xQvecFT0C + yCandVec * yQvecFT0C; + float spFV0A = xCandVec * xQvecFV0A + yCandVec * yQvecFV0A; + + // Get candidate info + int iCharge = (track.flags() & nuclei_spectra::CandBits::kPositive) ? 0 : 1; + float nSigmaTPC = getNSigmaTPC(track, cfgSpecies, iCharge); + float pt = track.pt(); + + // Fill relevant histograms + histos.fill(HIST("hSpFT0AvsNsigmaHe3VsPtvsCent"), spFT0A, nSigmaTPC, pt, ref_cent); + histos.fill(HIST("hSpFT0CvsNsigmaHe3VsPtvsCent"), spFT0C, nSigmaTPC, pt, ref_cent); + histos.fill(HIST("hSpFV0AvsNsigmaHe3VsPtvsCent"), spFV0A, nSigmaTPC, pt, ref_cent); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc, TaskName{"nucleiFlow"})}; +} diff --git a/PWGLF/Tasks/nuclei_in_jets.cxx b/PWGLF/Tasks/Nuspex/nuclei_in_jets.cxx similarity index 98% rename from PWGLF/Tasks/nuclei_in_jets.cxx rename to PWGLF/Tasks/Nuspex/nuclei_in_jets.cxx index 173b351b539..ec47f9fece8 100644 --- a/PWGLF/Tasks/nuclei_in_jets.cxx +++ b/PWGLF/Tasks/Nuspex/nuclei_in_jets.cxx @@ -459,8 +459,8 @@ struct nuclei_in_jets { // Number of Stored Particles int nParticles = static_cast(particle_ID.size()); - // Event Counter: Skip Events with less than 2 Particles - if (nParticles < 2) + // Event Counter: Skip Events with 0 Particles + if (nParticles < 1) return; registryQC.fill(HIST("number_of_events_data"), 4.5); @@ -549,11 +549,6 @@ struct nuclei_in_jets { // Multiplicity inside Jet + UE int nParticlesJetUE = static_cast(jet_particle_ID.size()); - // Event Counter: Skip Events with only 1 Particle inside jet cone - if (nParticlesJetUE < 2) - return; - registryQC.fill(HIST("number_of_events_data"), 6.5); - // QA Plots registryQC.fill(HIST("eta_leading"), p_leading.Eta()); registryQC.fill(HIST("phi_leading"), TVector2::Phi_0_2pi(p_leading.Phi())); @@ -578,14 +573,14 @@ struct nuclei_in_jets { // Event Counter: Skip Events with Rmax=0 if (Rmax == 0) return; - registryQC.fill(HIST("number_of_events_data"), 7.5); + registryQC.fill(HIST("number_of_events_data"), 6.5); registryQC.fill(HIST("r_max_jet"), Rmax); // Event Counter: Skip Events with jet not fully inside acceptance float eta_jet_axis = p_leading.Eta(); if ((TMath::Abs(eta_jet_axis) + Rmax_jet_ue) > max_eta) return; - registryQC.fill(HIST("number_of_events_data"), 8.5); + registryQC.fill(HIST("number_of_events_data"), 7.5); // Fill Jet Multiplicity registryQC.fill(HIST("jet_plus_ue_multiplicity"), nParticlesJetAndUE); @@ -681,7 +676,7 @@ struct nuclei_in_jets { if (particle_of_interest == nucleus::proton) { if (pt < 1.0) registryData.fill(HIST("antiproton_jet_tpc"), pt, nsigmaTPCPr, jet_Nch); - if (pt >= 1.0 && nsigmaTPCPr > min_nsigmaTPC && nsigmaTPCPr < max_nsigmaTPC && jet_track.hasTOF()) + if (pt >= 0.5 && nsigmaTPCPr > min_nsigmaTPC && nsigmaTPCPr < max_nsigmaTPC && jet_track.hasTOF()) registryData.fill(HIST("antiproton_jet_tof"), pt, nsigmaTOFPr, jet_Nch); } @@ -689,7 +684,7 @@ struct nuclei_in_jets { if (particle_of_interest == nucleus::deuteron) { if (pt < 1.0) registryData.fill(HIST("antideuteron_jet_tpc"), pt, nsigmaTPCDe, jet_Nch); - if (pt >= 1.0 && nsigmaTPCDe > min_nsigmaTPC && nsigmaTPCDe < max_nsigmaTPC && jet_track.hasTOF()) + if (pt >= 0.5 && nsigmaTPCDe > min_nsigmaTPC && nsigmaTPCDe < max_nsigmaTPC && jet_track.hasTOF()) registryData.fill(HIST("antideuteron_jet_tof"), pt, nsigmaTOFDe, jet_Nch); } @@ -733,7 +728,7 @@ struct nuclei_in_jets { if (particle_of_interest == nucleus::proton) { if (pt < 1.0) registryData.fill(HIST("antiproton_ue_tpc"), pt, nsigmaTPCPr, jet_Nch); - if (pt >= 1.0 && nsigmaTPCPr > min_nsigmaTPC && nsigmaTPCPr < max_nsigmaTPC && ue_track.hasTOF()) + if (pt >= 0.5 && nsigmaTPCPr > min_nsigmaTPC && nsigmaTPCPr < max_nsigmaTPC && ue_track.hasTOF()) registryData.fill(HIST("antiproton_ue_tof"), pt, nsigmaTOFPr, jet_Nch); } @@ -741,7 +736,7 @@ struct nuclei_in_jets { if (particle_of_interest == nucleus::deuteron) { if (pt < 1.0) registryData.fill(HIST("antideuteron_ue_tpc"), pt, nsigmaTPCDe, jet_Nch); - if (pt >= 1.0 && nsigmaTPCDe > min_nsigmaTPC && nsigmaTPCDe < max_nsigmaTPC && ue_track.hasTOF()) + if (pt >= 0.5 && nsigmaTPCDe > min_nsigmaTPC && nsigmaTPCDe < max_nsigmaTPC && ue_track.hasTOF()) registryData.fill(HIST("antideuteron_ue_tof"), pt, nsigmaTOFDe, jet_Nch); } diff --git a/PWGLF/Tasks/spectraCharged.cxx b/PWGLF/Tasks/Nuspex/spectraCharged.cxx similarity index 100% rename from PWGLF/Tasks/spectraCharged.cxx rename to PWGLF/Tasks/Nuspex/spectraCharged.cxx diff --git a/PWGLF/Tasks/spectraTOF.cxx b/PWGLF/Tasks/Nuspex/spectraTOF.cxx similarity index 99% rename from PWGLF/Tasks/spectraTOF.cxx rename to PWGLF/Tasks/Nuspex/spectraTOF.cxx index fd5f2e7a833..f2644a6b446 100644 --- a/PWGLF/Tasks/spectraTOF.cxx +++ b/PWGLF/Tasks/Nuspex/spectraTOF.cxx @@ -1296,7 +1296,7 @@ struct tofSpectra { } template - void fillParticleHistograms_MC(ParticleType const& mcParticle, CollisionCandidateMC::iterator const& collision) + void fillParticleHistograms_MC(ParticleType const& mcParticle) { switch (i) { @@ -1356,15 +1356,11 @@ struct tofSpectra { break; } - //************************************RD************************************************** - const float multiplicity = getMultiplicity(collision); - - //************************************RD************************************************** - if (mcParticle.pdgCode() != PDGs[i]) { return; } + const float multiplicity = 0.f; if (!mcParticle.isPhysicalPrimary()) { if (mcParticle.getProcess() == 4) { if (makeTHnSparseChoice) { @@ -1592,7 +1588,7 @@ struct tofSpectra { continue; } static_for<0, 17>([&](auto i) { - fillParticleHistograms_MC(mcParticle, mcParticle.mcCollision_as()); + fillParticleHistograms_MC(mcParticle); }); } diff --git a/PWGLF/Tasks/spectraTOFRun2.cxx b/PWGLF/Tasks/Nuspex/spectraTOFRun2.cxx similarity index 100% rename from PWGLF/Tasks/spectraTOFRun2.cxx rename to PWGLF/Tasks/Nuspex/spectraTOFRun2.cxx diff --git a/PWGLF/Tasks/spectraTPC.cxx b/PWGLF/Tasks/Nuspex/spectraTPC.cxx similarity index 100% rename from PWGLF/Tasks/spectraTPC.cxx rename to PWGLF/Tasks/Nuspex/spectraTPC.cxx diff --git a/PWGLF/Tasks/spectraTPCPiKaPr.cxx b/PWGLF/Tasks/Nuspex/spectraTPCPiKaPr.cxx similarity index 99% rename from PWGLF/Tasks/spectraTPCPiKaPr.cxx rename to PWGLF/Tasks/Nuspex/spectraTPCPiKaPr.cxx index db9a690816d..0b856a92e6b 100644 --- a/PWGLF/Tasks/spectraTPCPiKaPr.cxx +++ b/PWGLF/Tasks/Nuspex/spectraTPCPiKaPr.cxx @@ -56,7 +56,7 @@ struct tpcSpectraPiKaPr { histos.fill(HIST(hpt[i]), track.pt()); } - //Defining filters and input + // Defining filters and input Configurable cfgNSigmaCut{"cfgNSigmaCut", 3, "Value of the Nsigma cut"}; Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; diff --git a/PWGLF/Tasks/spectraTPCtiny.cxx b/PWGLF/Tasks/Nuspex/spectraTPCtiny.cxx similarity index 99% rename from PWGLF/Tasks/spectraTPCtiny.cxx rename to PWGLF/Tasks/Nuspex/spectraTPCtiny.cxx index ae27f78d92b..12fc53f6bfc 100644 --- a/PWGLF/Tasks/spectraTPCtiny.cxx +++ b/PWGLF/Tasks/Nuspex/spectraTPCtiny.cxx @@ -65,7 +65,7 @@ struct tpcSpectraTiny { histos.fill(HIST(hpt[i]), track.pt()); } - //Defining filters and input + // Defining filters and input Configurable cfgNSigmaCut{"cfgNSigmaCut", 3, "Value of the Nsigma cut"}; Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; diff --git a/PWGLF/Tasks/spectraTPCtinyPiKaPr.cxx b/PWGLF/Tasks/Nuspex/spectraTPCtinyPiKaPr.cxx similarity index 99% rename from PWGLF/Tasks/spectraTPCtinyPiKaPr.cxx rename to PWGLF/Tasks/Nuspex/spectraTPCtinyPiKaPr.cxx index f386e87dcbe..328b44d5477 100644 --- a/PWGLF/Tasks/spectraTPCtinyPiKaPr.cxx +++ b/PWGLF/Tasks/Nuspex/spectraTPCtinyPiKaPr.cxx @@ -56,7 +56,7 @@ struct tpcSpectraTinyPiKaPr { histos.fill(HIST(hpt[i]), track.pt()); } - //Defining filters and input + // Defining filters and input Configurable cfgNSigmaCut{"cfgNSigmaCut", 3, "Value of the Nsigma cut"}; Configurable cfgCutVertex{"cfgCutVertex", 10.0f, "Accepted z-vertex range"}; Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta range for tracks"}; diff --git a/PWGLF/Tasks/QC/CMakeLists.txt b/PWGLF/Tasks/QC/CMakeLists.txt index 41e8287a954..22c48a048f9 100644 --- a/PWGLF/Tasks/QC/CMakeLists.txt +++ b/PWGLF/Tasks/QC/CMakeLists.txt @@ -10,66 +10,76 @@ # or submit itself to any jurisdiction. o2physics_add_dpl_workflow(v0cascades-qa - SOURCES v0cascadesqa.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) + SOURCES v0cascadesqa.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(track-checks - SOURCES trackchecks.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) + SOURCES trackchecks.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(resonanceqa - SOURCES resonanceqa.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) + SOURCES resonanceqa.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(pid-qa - SOURCES lfpidqa.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) + SOURCES lfpidqa.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(strarecostudy - SOURCES straRecoStudy.cxx - PUBLIC_LINK_LIBRARIES O2::DetectorsBase O2Physics::AnalysisCore - COMPONENT_NAME Analysis) + SOURCES straRecoStudy.cxx + PUBLIC_LINK_LIBRARIES O2::DetectorsBase O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(kfperformancestudy - SOURCES kfPerformanceStudy.cxx - PUBLIC_LINK_LIBRARIES O2::DetectorsBase O2Physics::AnalysisCore - COMPONENT_NAME Analysis) + SOURCES kfPerformanceStudy.cxx + PUBLIC_LINK_LIBRARIES O2::DetectorsBase O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(its-tpc-matching-qa + SOURCES lfITSTPCMatchingQA.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(lfpropstudy - SOURCES lfpropStudy.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) + SOURCES lfpropStudy.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(tpc-dedx-postcalibration - SOURCES tpc_dEdx_postcalibration.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) + SOURCES tpc_dEdx_postcalibration.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(tpc-dedx-qa - SOURCES tpc_dedx_qa.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) + SOURCES tpc_dedx_qa.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(vertexqa - SOURCES vertexQA.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) + SOURCES vertexQA.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(efficiencyqa - SOURCES efficiencyQA.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) + SOURCES efficiencyQA.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(strangenessqcpp - SOURCES strangenessQCPP.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) + SOURCES strangenessQCPP.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) o2physics_add_dpl_workflow(strangepidqa - SOURCES strangepidqa.cxx - PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore - COMPONENT_NAME Analysis) + SOURCES strangepidqa.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(stqa + SOURCES stqa.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::ReconstructionDataFormats O2Physics::AnalysisCore + COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGLF/Tasks/QC/efficiencyQA.cxx b/PWGLF/Tasks/QC/efficiencyQA.cxx index 05d8db62a27..ea0978994f0 100644 --- a/PWGLF/Tasks/QC/efficiencyQA.cxx +++ b/PWGLF/Tasks/QC/efficiencyQA.cxx @@ -36,17 +36,19 @@ using namespace o2::framework; using namespace o2::framework::expressions; using std::array; using TracksFull = soa::Join; +using SelCollisions = soa::Join; namespace { const float piMass = o2::constants::physics::MassPionCharged; -std::shared_ptr hPiRec; -std::shared_ptr hPiRecMass; +std::shared_ptr hPiRec; +std::shared_ptr hPiRecMass; std::shared_ptr hTagCuts; std::shared_ptr hTpcSegment; std::shared_ptr hPtRes; std::shared_ptr hEtaRes; std::shared_ptr hPhiRes; +std::shared_ptr hPiRecSec; float invMass2Body(std::array& momA, std::array const& momB, std::array const& momC, float const& massB, float const& massC) { float p2B = momB[0] * momB[0] + momB[1] * momB[1] + momB[2] * momB[2]; @@ -66,6 +68,7 @@ struct ProbeTrack { uint64_t globalIndex; uint64_t globalIndexTpc; int32_t collIndex; + int64_t bcIndex; float p; float pt; float pProp; @@ -76,6 +79,8 @@ struct ProbeTrack { float vtx0; float vtx1; float vtx2; + float time; + float timeRes; uint8_t detectorMap; uint64_t globalIndexTag; }; @@ -107,6 +112,7 @@ struct efficiencyQA { Configurable findTpcLeg{"findTpcLeg", false, "toggle search of missing tpc segment"}; Configurable useTpcTracksFromSameColl{"useTpcTracksFromSameColl", true, "toggle post-matching to tpc segment associated to collision"}; + Configurable useCollisionWindow{"useCollisionWindow", false, "toogle collision window in re-matching"}; Configurable propToTPCinnerWall{"propToTPCinnerWall", false, "toggle propagation of tracks to the TPC inner wall"}; Configurable refitVertex{"refitVertex", false, "toggle refit of decay vertex using tag and tpc prolongation"}; Configurable ptWindow{"ptWindow", 0.05f, "pt window to search tpc segment"}; @@ -116,6 +122,8 @@ struct efficiencyQA { Configurable cosPaWindow{"cosPaWindow", 0.8f, "cosPa window to search tpc segment"}; Configurable collIdWindow{"collIdWindow", 6, "collision index window to search tpc segment"}; + Configurable trackTimingCut{"trackTimingCut", 3.f, "track timing cut, number of sigmas"}; + // CCDB options Configurable d_bz_input{"d_bz", -999, "bz field, -999 is automatic"}; Configurable ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; @@ -138,6 +146,9 @@ struct efficiencyQA { ConfigurableAxis phiResAxis{"phiResAxis", {800, -4.f, 4.f}, "binning for the phi resolution of V0 daughter tracks"}; ConfigurableAxis cosPaAxis{"cosPaAxis", {1000, -1.f, 1.f}, "binning for the cosine of pointing angle"}; ConfigurableAxis collIdResAxis{"collIdResAxis", {1.e2, -50., 50.}, "binning for the collision ID resolution"}; + ConfigurableAxis timeResAxis{"timeResAxis", {1000, -50., 50.}, "binning for the collision ID resolution"}; + + ConfigurableAxis nGenRecAxis{"nGenRecAxis", {20, 0, 20}, "binning for the detector response matrix axis"}; HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; @@ -147,6 +158,9 @@ struct efficiencyQA { Preslice perCollisionV0s = o2::aod::v0::collisionId; Preslice perCollisionTracks = o2::aod::track::collisionId; + double LHCRFFreq = 400.789e6; + double LHCBunchSpacingNS = 10 * 1.e9 / LHCRFFreq; + void init(InitContext const&) { ccdb->setURL(ccdburl); @@ -155,17 +169,20 @@ struct efficiencyQA { ccdb->setFatalWhenNull(false); histos.add("zVtx", ";#it{z}_{vtx} (cm);Entries", HistType::kTH1F, {zVtxAxis}); - hPiRec = histos.add("piRec", ";;#it{p}_{T} (GeV/#it{c});Entries", HistType::kTH2F, {recAxis, ptAxis}); + hPiRec = histos.add("piRec", ";;#it{p}_{T} (GeV/#it{c});#it{#eta}", HistType::kTH3F, {recAxis, ptAxis, etaAxis}); std::string binLabels[]{"Decays", "ITS", "ITS only", "TPC", "TPC only", "ITS+TPC", "TPC+TOF", " "}; for (int iB{0}; iB < hPiRec->GetNbinsX(); ++iB) { hPiRec->GetXaxis()->SetBinLabel(iB + 1, binLabels[iB].data()); } if (doprocessMcTracks) { + hPiRecSec = histos.add("piRecSec", ";;#it{p}_{T} (GeV/#it{c});#it{#eta}", HistType::kTH3F, {recAxis, ptAxis, etaAxis}); hPiRec->GetXaxis()->SetBinLabel(1, "Generated"); + hPiRecSec->GetXaxis()->SetBinLabel(1, "Generated"); hPtRes = histos.add("ptRes", ";;#it{p}_{T}^{rec} (GeV/#it{c});#it{p}_{T}^{rec} - #it{p}_{T}^{MC} (GeV/#it{c})", HistType::kTH3F, {recAxis, ptAxis, ptResAxis}); hEtaRes = histos.add("etaRes", ";;#it{p}_{T}^{rec} (GeV/#it{c});#eta^{rec} - #eta^{MC} (rad)", HistType::kTH3F, {recAxis, ptAxis, etaResAxis}); hPhiRes = histos.add("phiRes", ";;#it{p}_{T}^{rec} (GeV/#it{c});#phi^{rec} - #phi^{MC} (rad)", HistType::kTH3F, {recAxis, ptAxis, phiResAxis}); for (int iB{1}; iB < hPtRes->GetNbinsX(); ++iB) { + hPiRecSec->GetXaxis()->SetBinLabel(iB + 1, binLabels[iB].data()); hPtRes->GetXaxis()->SetBinLabel(iB + 1, binLabels[iB].data()); hEtaRes->GetXaxis()->SetBinLabel(iB + 1, binLabels[iB].data()); hPhiRes->GetXaxis()->SetBinLabel(iB + 1, binLabels[iB].data()); @@ -192,7 +209,7 @@ struct efficiencyQA { fitter.setMatCorrType(static_cast(mat)); histos.add("massV0", ";#it{M}(#pi^{+} + #pi^{-}) (GeV/#it{c}^{2});Entries", HistType::kTH1F, {massK0sAxis}); - hPiRecMass = histos.add("piRecMass", ";;#it{p}_{T} (GeV/#it{c});#it{M}(#pi^{+} + #pi^{-}) (GeV/#it{c}^{2})", HistType::kTH3F, {recAxis, ptAxis, massK0sAxis}); + hPiRecMass = histos.add("piRecMass", ";;#it{p}_{T} (GeV/#it{c});#it{#eta};#it{M}(#pi^{+} + #pi^{-}) (GeV/#it{c}^{2})", HistType::kTHnSparseF, {recAxis, ptAxis, etaAxis, massK0sAxis}); hTagCuts = histos.add("tagCuts", ";;#it{p}_{T} (GeV/#it{c})", HistType::kTH2F, {recAxis, ptAxis}); histos.add("massTagTpc", ";#it{p} (GeV/#it{c});#it{M}(#pi^{+} + #pi^{-}) (GeV/#it{c}^{2})", HistType::kTH2F, {ptAxis, massK0sAxis}); @@ -204,10 +221,10 @@ struct efficiencyQA { for (int iB{0}; iB < hTagCuts->GetNbinsX(); ++iB) { hTagCuts->GetXaxis()->SetBinLabel(iB + 1, binLabelsTag[iB].data()); } - for (int iB{0}; iB < hPiRecMass->GetNbinsX(); ++iB) { - hPiRecMass->GetXaxis()->SetBinLabel(iB + 1, binLabels[iB].data()); + for (int iB{0}; iB < hPiRecMass->GetAxis(0)->GetNbins(); ++iB) { + hPiRecMass->GetAxis(0)->SetBinLabel(iB + 1, binLabels[iB].data()); } - hPiRecMass->GetXaxis()->SetBinLabel(8, "ITS w/ TPC leg"); + hPiRecMass->GetAxis(0)->SetBinLabel(8, "ITS w/ TPC leg"); if (doprocessTagAndProbeMC) { std::string binLabelsTpc[]{"hasTPCsegment", "foundTPCsegment", "allFoundTPCsegment", "foundTPCsegment (w/ fake)"}; @@ -225,7 +242,10 @@ struct efficiencyQA { histos.add("ptEtaPhiTpcIts", ";#it{p}^{TPC}_{T} - #it{p}^{ITS}_{T} (GeV/#it{c});#eta^{TPC} - #eta^{ITS};#phi^{TPC} - #phi^{ITS} (rad)", HistType::kTH3F, {ptResAxis, etaResAxis, phiResAxis}); histos.add("collTpcIts", ";ID_{coll}^{TPC} - ID_{coll}^{ITS};Entries", HistType::kTH1F, {collIdResAxis}); histos.add("collTpcV0", ";ID_{coll}^{TPC} - ID_{coll}^{V0};Entries", HistType::kTH1F, {collIdResAxis}); + histos.add("timeTpcIts", ";(#it{t}^{TPC} - #it{t}^{ITS}) / #sigma (a.u.);Entries", HistType::kTH1F, {timeResAxis}); } + + histos.add("detRespMatrix", ";#it{N}_{gen};#it{N}_{rec}", HistType::kTH2F, {nGenRecAxis, nGenRecAxis}); } } @@ -291,8 +311,34 @@ struct efficiencyQA { } template - void fillTagAndProbe(soa::Join::iterator const& collision, aod::V0s const& V0s, TracksFull const& tracks) + void fillHistTrack(T const& track, std::shared_ptr hist, float const& y, float const& z = 1, float const& t = 1) + { + bool itsAccept = !(track.itsChi2NCl() > 36. || track.itsNCls() < 4); + bool tpcAccept = !(track.tpcCrossedRowsOverFindableCls() < 0.8 || track.tpcNClsCrossedRows() < 70 || track.tpcChi2NCl() > 4. || track.tpcNClsFound() < 90); + if (track.hasITS()) { + hist->Fill(std::array{1., y, z, t}.data()); + } + if (track.hasITS() && itsAccept && !track.hasTPC()) { + hist->Fill(std::array{2., y, z, t}.data()); + } + if (track.hasTPC() && tpcAccept) { + hist->Fill(std::array{3., y, z, t}.data()); + if (!track.hasITS()) { + hist->Fill(std::array{4., y, z, t}.data()); + } + if (track.hasITS() && itsAccept) { + hist->Fill(std::array{5., y, z, t}.data()); + } + if (track.hasTOF() && !track.hasITS()) { + hist->Fill(std::array{6., y, z, t}.data()); + } + } + } + + template + void fillTagAndProbe(SelCollisions::iterator const& collision, aod::V0s const& V0s, TracksFull const& tracks, SelCollisions const&) { + float nGenRec[]{0.f, 0.f}; auto tpcTracks = useTpcTracksFromSameColl ? tracks.sliceBy(perCollisionTracks, collision.globalIndex()) : tracks; for (auto& v0 : V0s) { auto posTrack = v0.posTrack_as(); @@ -403,8 +449,11 @@ struct efficiencyQA { histos.fill(HIST("massV0"), massV0); + nGenRec[0] += 1.f; + auto trackPt = probeTrack.sign() * std::hypot(momProbe[0], momProbe[1]); auto trackP = probeTrack.sign() * std::hypot(trackPt, momProbe[2]); + auto trackEta = probeTrackCov.getEta(); ProbeTrack probe; probe.globalIndex = probeTrack.globalIndex(); @@ -417,7 +466,15 @@ struct efficiencyQA { probe.vtx0 = vtx[0]; probe.vtx1 = vtx[1]; probe.vtx2 = vtx[2]; + probe.time = probeTrack.trackTime(); + probe.timeRes = probeTrack.trackTimeRes(); probe.collIndex = probeTrack.collisionId(); + if (probeTrack.has_collision()) { + auto collisionIts = probeTrack.template collision_as(); + probe.bcIndex = int64_t(collisionIts.bcId()); + } else { + continue; // TODO: check ambiguous tracks (?) + } if (probeTrack.hasITS() && !probeTrack.hasTPC() && findTpcLeg) { auto acceptIts = !(probeTrack.itsChi2NCl() > 36. || probeTrack.itsNCls() < 4); @@ -431,6 +488,18 @@ struct efficiencyQA { if (std::abs(tpcTrack.collisionId() - probeTrack.collisionId()) > collIdWindow) { continue; } + if (!useCollisionWindow) { + if (!tpcTrack.has_collision()) { + continue; + } + auto collisionTpc = tpcTrack.template collision_as(); + auto bcTpc = int64_t(collisionTpc.bcId()); + float tdiff = (bcTpc - probe.bcIndex) * LHCBunchSpacingNS + tpcTrack.trackTime() - probe.time; + float nsigmaT = tdiff / std::sqrt(std::pow(tpcTrack.trackTimeRes(), 2) + std::pow(probe.timeRes, 2)); + if (nsigmaT > trackTimingCut) { + continue; + } + } if (std::abs(tpcTrack.eta()) > etaMax) { continue; } @@ -522,23 +591,29 @@ struct efficiencyQA { } } - hPiRecMass->Fill(0., trackPt, massV0); + hPiRecMass->Fill(0., trackPt, trackEta, massV0); if (probe.globalIndexTpc > 0) { - hPiRecMass->Fill(7., trackPt, massV0); + hPiRecMass->Fill(7., trackPt, trackEta, massV0); } - fillHistTrack(probeTrack, hPiRecMass, trackPt, massV0); + fillHistTrack(probeTrack, hPiRecMass, trackPt, trackEta, massV0); if (std::abs(massV0 - o2::constants::physics::MassKaonNeutral) < massMax) { probeTracks.push_back(probe); - hPiRec->Fill(0., trackPt); - fillHistTrack(probeTrack, hPiRec, trackPt); + hPiRec->Fill(0., trackPt, trackEta); + fillHistTrack(probeTrack, hPiRec, trackPt, trackEta); if (probe.globalIndexTpc > 0) { - hPiRec->Fill(7., trackPt); + hPiRec->Fill(7., trackPt, trackEta); + } + bool itsAccept = !(probeTrack.itsChi2NCl() > 36. || probeTrack.itsNCls() < 4); + bool tpcAccept = !(probeTrack.tpcCrossedRowsOverFindableCls() < 0.8 || probeTrack.tpcNClsCrossedRows() < 70 || probeTrack.tpcChi2NCl() > 4. || probeTrack.tpcNClsFound() < 90); + if (probeTrack.hasITS() && probeTrack.hasTPC() && itsAccept && tpcAccept) { + nGenRec[1] += 1.f; } } } + histos.fill(HIST("detRespMatrix"), nGenRec[0], nGenRec[1]); } - void fillProbeMC(soa::Join::iterator const& collision, TracksFull const& tracks, aod::McTrackLabels const& trackLabelsMC, aod::McParticles const& particlesMC) + void fillProbeMC(SelCollisions::iterator const& collision, TracksFull const& tracks, aod::McTrackLabels const& trackLabelsMC, aod::McParticles const& particlesMC, SelCollisions const&) { auto tracks_thisEvent = useTpcTracksFromSameColl ? tracks.sliceBy(perCollisionTracks, collision.globalIndex()) : tracks; @@ -582,6 +657,11 @@ struct efficiencyQA { histos.fill(HIST("collTpcIts"), tpcTrack.collisionId() - probeTrack.collIndex); histos.fill(HIST("collTpcV0"), tpcTrack.collisionId() - collision.globalIndex()); + auto collisionTpc = tpcTrack.template collision_as(); + float tdiff = (int64_t(collisionTpc.bcId()) - probeTrack.bcIndex) * LHCBunchSpacingNS + tpcTrack.trackTime() - probeTrack.time; + float nsigmaT = tdiff / std::sqrt(std::pow(tpcTrack.trackTimeRes(), 2) + std::pow(probeTrack.timeRes, 2)); + histos.fill(HIST("timeTpcIts"), nsigmaT); + auto trackCov = getTrackParCov(tpcTrack); gpu::gpustd::array dcaInfo; if (propToTPCinnerWall) { @@ -648,7 +728,7 @@ struct efficiencyQA { } } - void processTagAndProbe(soa::Join const& collisions, aod::V0s const& V0s, TracksFull const& tracks, aod::BCsWithTimestamps const&) + void processTagAndProbe(SelCollisions const& collisions, aod::V0s const& V0s, TracksFull const& tracks, aod::BCsWithTimestamps const&) { for (const auto& collision : collisions) { probeTracks.clear(); @@ -667,12 +747,12 @@ struct efficiencyQA { const uint64_t collIdx = collision.globalIndex(); auto V0Table_thisCollision = V0s.sliceBy(perCollisionV0s, collIdx); V0Table_thisCollision.bindExternalIndices(&tracks); - fillTagAndProbe(collision, V0Table_thisCollision, tracks); + fillTagAndProbe(collision, V0Table_thisCollision, tracks, collisions); } } PROCESS_SWITCH(efficiencyQA, processTagAndProbe, "Tag and probe analysis", true); - void processTagAndProbeMC(soa::Join const& collisions, aod::V0s const& V0s, TracksFull const& tracks, aod::BCsWithTimestamps const&, aod::McTrackLabels const& trackLabelsMC, aod::McParticles const& particlesMC) + void processTagAndProbeMC(SelCollisions const& collisions, aod::V0s const& V0s, TracksFull const& tracks, aod::BCsWithTimestamps const&, aod::McTrackLabels const& trackLabelsMC, aod::McParticles const& particlesMC) { for (const auto& collision : collisions) { probeTracks.clear(); @@ -691,14 +771,14 @@ struct efficiencyQA { const uint64_t collIdx = collision.globalIndex(); auto V0Table_thisCollision = V0s.sliceBy(perCollisionV0s, collIdx); V0Table_thisCollision.bindExternalIndices(&tracks); - fillTagAndProbe(collision, V0Table_thisCollision, tracks); + fillTagAndProbe(collision, V0Table_thisCollision, tracks, collisions); - fillProbeMC(collision, tracks, trackLabelsMC, particlesMC); + fillProbeMC(collision, tracks, trackLabelsMC, particlesMC, collisions); } } PROCESS_SWITCH(efficiencyQA, processTagAndProbeMC, "Tag and probe analysis on MC", false); - void processMcTracks(soa::Join const& collisions, TracksFull const& tracks, aod::BCsWithTimestamps const&, aod::McTrackLabels const& trackLabelsMC, aod::McParticles const& particlesMC) + void processMcTracks(SelCollisions const& collisions, TracksFull const& tracks, aod::BCsWithTimestamps const&, aod::McTrackLabels const& trackLabelsMC, aod::McParticles const& particlesMC) { for (const auto& collision : collisions) { auto bc = collision.bc_as(); @@ -731,9 +811,6 @@ struct efficiencyQA { if (std::abs(mcTrack.pdgCode()) != 211) { continue; } - if (!mcTrack.isPhysicalPrimary()) { - continue; - } const o2::math_utils::Point3D collVtx{collision.posX(), collision.posY(), collision.posZ()}; auto trackParCov = getTrackParCov(track); @@ -741,11 +818,25 @@ struct efficiencyQA { o2::base::Propagator::Instance()->propagateToDCA(collVtx, trackParCov, d_bz, 2.f, static_cast(cfgMaterialCorrection.value), &dcaInfo); auto trackPt = track.sign() * trackParCov.getPt(); - fillHistTrack(track, hPiRec, trackPt); - - fillHistTrack(track, hPtRes, track.sign() * trackParCov.getPt(), trackParCov.getPt() - mcTrack.pt()); - fillHistTrack(track, hEtaRes, track.sign() * trackParCov.getPt(), trackParCov.getEta() - mcTrack.eta()); - fillHistTrack(track, hPhiRes, track.sign() * trackParCov.getPt(), trackParCov.getPhi() - mcTrack.phi()); + auto trackEta = trackParCov.getEta(); + if (mcTrack.isPhysicalPrimary()) { + fillHistTrack(track, hPiRec, trackPt, trackEta); + fillHistTrack(track, hPtRes, track.sign() * trackParCov.getPt(), trackParCov.getPt() - mcTrack.pt()); + fillHistTrack(track, hEtaRes, track.sign() * trackParCov.getPt(), trackParCov.getEta() - mcTrack.eta()); + fillHistTrack(track, hPhiRes, track.sign() * trackParCov.getPt(), trackParCov.getPhi() - mcTrack.phi()); + } else { + for (auto& mother : mcTrack.template mothers_as()) { + if (mother.pdgCode() != 310) { + continue; + } + auto radius = std::hypot(mcTrack.vx(), mcTrack.vy()); + if (radius > v0radiusMax) { + continue; + } + fillHistTrack(track, hPiRecSec, trackPt, trackEta); + break; + } + } } } } @@ -758,10 +849,21 @@ struct efficiencyQA { if (std::abs(pdgCode) != 211) { continue; } - if (!partMC.isPhysicalPrimary()) { - continue; + if (partMC.isPhysicalPrimary()) { + hPiRec->Fill(0., pdgCode / std::abs(pdgCode) * partMC.pt(), partMC.eta()); + } else { + for (auto& mother : partMC.template mothers_as()) { + if (mother.pdgCode() != 310) { + continue; + } + auto radius = std::hypot(partMC.vx(), partMC.vy()); + if (radius > v0radiusMax) { + continue; + } + hPiRecSec->Fill(0., pdgCode / std::abs(pdgCode) * partMC.pt(), partMC.eta()); + break; + } } - hPiRec->Fill(0., pdgCode / std::abs(pdgCode) * partMC.pt()); } } PROCESS_SWITCH(efficiencyQA, processMcTracks, "MC tracks analysis", false); diff --git a/PWGLF/Tasks/QC/lfITSTPCMatchingQA.cxx b/PWGLF/Tasks/QC/lfITSTPCMatchingQA.cxx new file mode 100644 index 00000000000..9dc152e0935 --- /dev/null +++ b/PWGLF/Tasks/QC/lfITSTPCMatchingQA.cxx @@ -0,0 +1,233 @@ +// 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. + +#include + +#include "Framework/runDataProcessing.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/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "DataFormatsTPC/BetheBlochAleph.h" +#include "Common/Core/PID/PIDTOF.h" +#include "Common/TableProducer/PID/pidTOFBase.h" + +#include "Common/Core/PID/TPCPIDResponse.h" +#include "Common/DataModel/PIDResponse.h" + +#include "TDatabasePDG.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +using TracksFull = soa::Join; + +namespace +{ +// PID custom parametrisation for d and He3 +constexpr double betheBlochDefault[2][6]{ + {-136.71, 0.441, 0.2269, 1.347, 0.8035, 0.09}, + {-321.34, 0.6539, 1.591, 0.8225, 2.363, 0.09}}; +static const std::vector betheBlochParNames{"p0", "p1", "p2", "p3", "p4", "resolution"}; +static const std::vector particleNamesBB{"d", "He3"}; +static const std::vector pidHypotheses{"Electron", "Muon", "Pion", "Kaon", "Proton", "Deuteron", "Triton", "He3", "Alpha", "Pion0", "Photon", "K0", "Lambda", "HyperTriton", "Hyperhydrog4", "XiMinus", "OmegaMinus"}; +} // namespace + +struct lfmatchingqa { + + // ConfigurableAxis for the histograms + ConfigurableAxis zVtxAxis{"zVtxBins", {100, -20.f, 20.f}, "Binning for the vertex z in cm"}; + Configurable> cfgBetheBlochParams{"cfgBetheBlochParams", {betheBlochDefault[0], 2, 6, particleNamesBB, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for d and He3"}; + ConfigurableAxis tpcNsigmaAxis{"tpcNsigmaAxis", {100, -4.f, 4.f}, "tpc nsigma axis"}; + ConfigurableAxis momAxis{"momAxis", {60., -3.f, 3.f}, "momentum axis binning"}; + ConfigurableAxis momAxisFine{"momAxisFine", {2.e3, -5.f, 5.f}, "momentum axis binning"}; + ConfigurableAxis momResAxis{"momResAxis", {2.e2, -2.f, 2.f}, "momentum resolution binning"}; + ConfigurableAxis tpcAxis{"tpcAxis", {4e3, 0.f, 4.e3f}, "tpc signal axis binning"}; + ConfigurableAxis dcaAxis{"dcaAxis", {100, -0.1f, 0.1f}, "dca axis binning"}; + ConfigurableAxis itsClusSizeAxis{"itsClusSizeAxis", {90, 1, 15}, "its cluster size axis binning"}; + ConfigurableAxis trackingPidAxis{"trackingPidAxis", {static_cast(pidHypotheses.size()), 0, static_cast(pidHypotheses.size())}, "tracking pid hypothesis binning"}; + + // Cut values + Configurable zVtxMax{"zVtxMax", 10.0f, "maximum z position of the primary vertex"}; + Configurable etaMax{"etaMax", 0.8f, "maximum eta"}; + Configurable ptMin{"ptMin", 0.05f, "minimum pT (GeV/c)"}; + Configurable nClusITSCut{"nClusITSCut", 7, "Minimum number of ITS clusters"}; + Configurable nClusTPCCut{"nClusTPCCut", 70, "Minimum number of TPC clusters"}; + Configurable dcaCut{"dcaCut", 0.1f, "DCA to PV"}; + + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + template + bool selectTrack(T const& track) + { + if (std::abs(track.eta()) > etaMax || track.pt() < ptMin || std::abs(track.dcaXY()) > dcaCut) { + return false; + } + if (track.itsNCls() < nClusITSCut || + track.tpcNClsFound() < nClusTPCCut || + track.tpcNClsCrossedRows() < 100 || + track.tpcNClsCrossedRows() < 0.8 * track.tpcNClsFindable() || + track.tpcChi2NCl() > 4.f || + track.itsChi2NCl() > 36.f) { + return false; + } + return true; + } + + template + float getITSClSize(T const& track) + { + float sum{0.f}; + for (int iL{0}; iL < 6; ++iL) { + sum += (track.itsClusterSizes() >> (iL * 4)) & 0xf; + } + return sum / track.itsNCls(); + } + + void init(o2::framework::InitContext&) + { + histos.add("zVtx", ";#it{z}_{vtx} (cm);Entries", HistType::kTH1F, {zVtxAxis}); + + histos.add("tpcSignal", ";#it{p}_{TPC} (GeV/#it{c});TPC signal (a.u.)", {HistType::kTH2F}, {momAxisFine, tpcAxis}); + histos.add("tpcSignalPIDHypo", ";#it{p}_{TPC} (GeV/#it{c});TPC signal (a.u.); PID hypothesis", {HistType::kTH3F}, {momAxisFine, tpcAxis, trackingPidAxis}); + histos.add("tpcNsigmaPi", ";#it{p}_{TPC}; #it{p}_{GLO}; n#sigma_{TPC} (#pi)", {HistType::kTH3F, {momAxis, momAxis, tpcNsigmaAxis}}); + histos.add("tpcNsigmaKa", ";#it{p}_{TPC}; #it{p}_{GLO}; n#sigma_{TPC} (K)", {HistType::kTH3F, {momAxis, momAxis, tpcNsigmaAxis}}); + histos.add("tpcNsigmaPr", ";#it{p}_{TPC}; #it{p}_{GLO}; n#sigma_{TPC} (p)", {HistType::kTH3F, {momAxis, momAxis, tpcNsigmaAxis}}); + histos.add("tpcNsigmaDe", ";#it{p}_{TPC}; #it{p}_{GLO}; n#sigma_{TPC} (d)", {HistType::kTH3F, {momAxis, momAxis, tpcNsigmaAxis}}); + histos.add("tpcNsigmaHe", ";#it{p}_{TPC}; #it{p}_{GLO}; n#sigma_{TPC} (He3)", {HistType::kTH3F, {momAxis, momAxis, tpcNsigmaAxis}}); + + auto pidHypoPi = histos.add("pidHypoPi", ";#it{p}_{TPC} (GeV/#it{c}); n#sigma_{TPC} (#pi);", {HistType::kTH3F}, {momAxisFine, tpcNsigmaAxis, trackingPidAxis}); + auto pidHypoKa = histos.add("pidHypoKa", ";#it{p}_{TPC} (GeV/#it{c}); n#sigma_{TPC} (K);", {HistType::kTH3F}, {momAxisFine, tpcNsigmaAxis, trackingPidAxis}); + auto pidHypoPr = histos.add("pidHypoPr", ";#it{p}_{TPC} (GeV/#it{c}); n#sigma_{TPC} (p);", {HistType::kTH3F}, {momAxisFine, tpcNsigmaAxis, trackingPidAxis}); + auto pidHypoDe = histos.add("pidHypoDe", ";#it{p}_{TPC} (GeV/#it{c}); n#sigma_{TPC} (d);", {HistType::kTH3F}, {momAxisFine, tpcNsigmaAxis, trackingPidAxis}); + auto pidHypoHe = histos.add("pidHypoHe", ";#it{p}_{TPC} (GeV/#it{c}); n#sigma_{TPC} (He3);", {HistType::kTH3F}, {momAxisFine, tpcNsigmaAxis, trackingPidAxis}); + for (int i{1}; i < pidHypoPi->GetNbinsZ() + 1; ++i) { + pidHypoPi->GetZaxis()->SetBinLabel(i, pidHypotheses[i - 1].data()); + pidHypoKa->GetZaxis()->SetBinLabel(i, pidHypotheses[i - 1].data()); + pidHypoPr->GetZaxis()->SetBinLabel(i, pidHypotheses[i - 1].data()); + pidHypoDe->GetZaxis()->SetBinLabel(i, pidHypotheses[i - 1].data()); + pidHypoHe->GetZaxis()->SetBinLabel(i, pidHypotheses[i - 1].data()); + } + + histos.add("momCorrPi", ";#it{p}_{TPC} (GeV/#it{c}); #it{p}_{GLO} (GeV/#it{c});#it{p}_{TPC} - #it{p}_{glo} (GeV/#it{c})", {HistType::kTH3F, {momAxis, momAxis, momResAxis}}); + histos.add("momCorrKa", ";#it{p}_{TPC} (GeV/#it{c}); #it{p}_{GLO} (GeV/#it{c});#it{p}_{TPC} - #it{p}_{glo} (GeV/#it{c})", {HistType::kTH3F, {momAxis, momAxis, momResAxis}}); + histos.add("momCorrPr", ";#it{p}_{TPC} (GeV/#it{c}); #it{p}_{GLO} (GeV/#it{c});#it{p}_{TPC} - #it{p}_{glo} (GeV/#it{c})", {HistType::kTH3F, {momAxis, momAxis, momResAxis}}); + histos.add("momCorrDe", ";#it{p}_{TPC} (GeV/#it{c}); #it{p}_{GLO} (GeV/#it{c});#it{p}_{TPC} - #it{p}_{glo} (GeV/#it{c})", {HistType::kTH3F, {momAxis, momAxis, momResAxis}}); + histos.add("momCorrHe", ";#it{p}_{TPC} (GeV/#it{c}); #it{p}_{GLO} (GeV/#it{c});#it{p}_{TPC} - #it{p}_{glo} (GeV/#it{c})", {HistType::kTH3F, {momAxis, momAxis, momResAxis}}); + + histos.add("dcaPi", "; #it{p}_{GLO} (GeV/#it{c});#it{p}_{TPC} - #it{p}_{glo} (GeV/#it{c}); DCA_{xy} (cm)", {HistType::kTH3F, {momAxis, momResAxis, dcaAxis}}); + histos.add("dcaKa", "; #it{p}_{GLO} (GeV/#it{c});#it{p}_{TPC} - #it{p}_{glo} (GeV/#it{c}); DCA_{xy} (cm)", {HistType::kTH3F, {momAxis, momResAxis, dcaAxis}}); + histos.add("dcaPr", "; #it{p}_{GLO} (GeV/#it{c});#it{p}_{TPC} - #it{p}_{glo} (GeV/#it{c}); DCA_{xy} (cm)", {HistType::kTH3F, {momAxis, momResAxis, dcaAxis}}); + histos.add("dcaDe", "; #it{p}_{GLO} (GeV/#it{c});#it{p}_{TPC} - #it{p}_{glo} (GeV/#it{c}); DCA_{xy} (cm)", {HistType::kTH3F, {momAxis, momResAxis, dcaAxis}}); + histos.add("dcaHe", "; #it{p}_{GLO} (GeV/#it{c});#it{p}_{TPC} - #it{p}_{glo} (GeV/#it{c}); DCA_{xy} (cm)", {HistType::kTH3F, {momAxis, momResAxis, dcaAxis}}); + + histos.add("itsClusSizePi", ";#it{p}_{TPC} (GeV/#it{c}); #it{p}_{GLO} (GeV/#it{c}); x cos(#lambda) (#pi)", {HistType::kTH3F, {momAxis, momAxis, itsClusSizeAxis}}); + histos.add("itsClusSizeKa", ";#it{p}_{TPC} (GeV/#it{c}); #it{p}_{GLO} (GeV/#it{c}); x cos(#lambda) (K)", {HistType::kTH3F, {momAxis, momAxis, itsClusSizeAxis}}); + histos.add("itsClusSizePr", ";#it{p}_{TPC} (GeV/#it{c}); #it{p}_{GLO} (GeV/#it{c}); x cos(#lambda) (p)", {HistType::kTH3F, {momAxis, momAxis, itsClusSizeAxis}}); + histos.add("itsClusSizeDe", ";#it{p}_{TPC} (GeV/#it{c}); #it{p}_{GLO} (GeV/#it{c}); x cos(#lambda) (d)", {HistType::kTH3F, {momAxis, momAxis, itsClusSizeAxis}}); + histos.add("itsClusSizeHe", ";#it{p}_{TPC} (GeV/#it{c}); #it{p}_{GLO} (GeV/#it{c}); x cos(#lambda) (He3)", {HistType::kTH3F, {momAxis, momAxis, itsClusSizeAxis}}); + } + + void process(soa::Join::iterator const& collision, TracksFull const& tracks, aod::BCs const&) + { + + if (!collision.sel8()) + return; + + if (std::abs(collision.posZ()) > zVtxMax) + return; + + histos.fill(HIST("zVtx"), collision.posZ()); + + for (const auto& track : tracks) { + if (!selectTrack(track)) { + continue; + } + + auto sign = track.sign(); + auto signTPCMom = sign * track.tpcInnerParam(); + auto signGloMom = sign * track.p(); + + // compute custom tpcNsigmaDeu and tpcNsigmaHe3 + double expBetheDeu{tpc::BetheBlochAleph(static_cast(track.tpcInnerParam() / constants::physics::MassDeuteron), cfgBetheBlochParams->get("d", "p0"), cfgBetheBlochParams->get("d", "p1"), cfgBetheBlochParams->get("d", "p2"), cfgBetheBlochParams->get("d", "p3"), cfgBetheBlochParams->get("d", "p4"))}; + double expSigmaDeu{expBetheDeu * cfgBetheBlochParams->get("d", "resolution")}; + double expBetheHe3{tpc::BetheBlochAleph(static_cast(track.tpcInnerParam() / constants::physics::MassHelium3), cfgBetheBlochParams->get("He3", "p0"), cfgBetheBlochParams->get("He3", "p1"), cfgBetheBlochParams->get("He3", "p2"), cfgBetheBlochParams->get("He3", "p3"), cfgBetheBlochParams->get("He3", "p4"))}; + double expSigmaHe3{expBetheHe3 * cfgBetheBlochParams->get("He3", "resolution")}; + auto tpcNSigmaDeu = static_cast((track.tpcSignal() - expBetheDeu) / expSigmaDeu); + auto tpcNSigmaHe3 = static_cast((track.tpcSignal() - expBetheHe3) / expSigmaHe3); + + // filling the nsigma histograms + histos.fill(HIST("tpcSignal"), signTPCMom, track.tpcSignal()); + histos.fill(HIST("tpcSignalPIDHypo"), signTPCMom, track.tpcSignal(), track.pidForTracking()); + if (abs(track.tpcNSigmaPi()) < 4) { + histos.fill(HIST("tpcNsigmaPi"), signTPCMom, signGloMom, track.tpcNSigmaPi()); + histos.fill(HIST("pidHypoPi"), signTPCMom, track.tpcNSigmaPi(), track.pidForTracking()); + } + if (abs(track.tpcNSigmaKa()) < 4) { + histos.fill(HIST("tpcNsigmaKa"), signTPCMom, signGloMom, track.tpcNSigmaKa()); + histos.fill(HIST("pidHypoKa"), signTPCMom, track.tpcNSigmaKa(), track.pidForTracking()); + } + if (abs(track.tpcNSigmaPr()) < 4) { + histos.fill(HIST("tpcNsigmaPr"), signTPCMom, signGloMom, track.tpcNSigmaPr()); + histos.fill(HIST("pidHypoPr"), signTPCMom, track.tpcNSigmaPr(), track.pidForTracking()); + } + if (abs(tpcNSigmaDeu) < 4) { + histos.fill(HIST("tpcNsigmaDe"), signTPCMom, signGloMom, tpcNSigmaDeu); + histos.fill(HIST("pidHypoDe"), signTPCMom, tpcNSigmaDeu, track.pidForTracking()); + } + if (abs(tpcNSigmaHe3) < 4) { + histos.fill(HIST("tpcNsigmaHe"), signTPCMom, signGloMom, tpcNSigmaHe3); + histos.fill(HIST("pidHypoHe"), signTPCMom, tpcNSigmaHe3, track.pidForTracking()); + } + + // Filling the mom corr and cl sizes histograms (nSigma < 2 required) + // calculating cos(L) of the track + float cosL = 1 / std::sqrt(1.f + track.tgl() * track.tgl()); + + if (abs(track.tpcNSigmaPi()) < 2) { + histos.fill(HIST("momCorrPi"), signTPCMom, signGloMom, track.tpcInnerParam() - track.p()); + histos.fill(HIST("dcaPi"), signGloMom, track.tpcInnerParam() - track.p(), track.dcaXY()); + histos.fill(HIST("itsClusSizePi"), signTPCMom, signGloMom, getITSClSize(track) * cosL); + } + if (abs(track.tpcNSigmaKa()) < 2) { + histos.fill(HIST("momCorrKa"), signTPCMom, signGloMom, track.tpcInnerParam() - track.p()); + histos.fill(HIST("dcaKa"), signGloMom, track.tpcInnerParam() - track.p(), track.dcaXY()); + histos.fill(HIST("itsClusSizeKa"), signTPCMom, signGloMom, getITSClSize(track) * cosL); + } + if (abs(track.tpcNSigmaPr()) < 2) { + histos.fill(HIST("momCorrPr"), signTPCMom, signGloMom, track.tpcInnerParam() - track.p()); + histos.fill(HIST("dcaPr"), signGloMom, track.tpcInnerParam() - track.p(), track.dcaXY()); + histos.fill(HIST("itsClusSizePr"), signTPCMom, signGloMom, getITSClSize(track) * cosL); + } + if (abs(tpcNSigmaDeu) < 2) { + histos.fill(HIST("momCorrDe"), signTPCMom, signGloMom, track.tpcInnerParam() - track.p()); + histos.fill(HIST("dcaDe"), signGloMom, track.tpcInnerParam() - track.p(), track.dcaXY()); + histos.fill(HIST("itsClusSizeDe"), signTPCMom, signGloMom, getITSClSize(track) * cosL); + } + if (abs(tpcNSigmaHe3) < 2) { + histos.fill(HIST("momCorrHe"), signTPCMom, signGloMom, track.tpcInnerParam() - track.p()); + histos.fill(HIST("dcaHe"), signGloMom, track.tpcInnerParam() - track.p(), track.dcaXY()); + histos.fill(HIST("itsClusSizeHe"), signTPCMom, signGloMom, getITSClSize(track) * cosL); + } + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/Tasks/stqa.cxx b/PWGLF/Tasks/QC/stqa.cxx similarity index 100% rename from PWGLF/Tasks/stqa.cxx rename to PWGLF/Tasks/QC/stqa.cxx diff --git a/PWGLF/Tasks/Resonances/CMakeLists.txt b/PWGLF/Tasks/Resonances/CMakeLists.txt new file mode 100644 index 00000000000..faae0fcac1e --- /dev/null +++ b/PWGLF/Tasks/Resonances/CMakeLists.txt @@ -0,0 +1,85 @@ +# 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(rsnanalysis + SOURCES rsnanalysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(phianalysis + SOURCES phianalysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(k892analysis + SOURCES k892analysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(k892pmanalysis + SOURCES k892pmanalysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(lambda1520analysis + SOURCES lambda1520analysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(k1analysis + SOURCES k1analysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(phianalysisrun3 + SOURCES phianalysisrun3.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(f0980analysis + SOURCES f0980analysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(lambda1520spherocityanalysis + SOURCES lambda1520SpherocityAnalysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(delta-analysis + SOURCES deltaanalysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(rhoanalysis + SOURCES rhoanalysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(phi-analysis-thnsparse + SOURCES phianalysisTHnSparse.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(f1protoncorrelation + SOURCES f1protoncorrelation.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(chargedkstaranalysis + SOURCES chargedkstaranalysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(lambda1520-pbpb + SOURCES lambda1520_PbPb.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGLF/Tasks/chargedkstaranalysis.cxx b/PWGLF/Tasks/Resonances/chargedkstaranalysis.cxx similarity index 96% rename from PWGLF/Tasks/chargedkstaranalysis.cxx rename to PWGLF/Tasks/Resonances/chargedkstaranalysis.cxx index 497b607698c..c9646abb385 100644 --- a/PWGLF/Tasks/chargedkstaranalysis.cxx +++ b/PWGLF/Tasks/Resonances/chargedkstaranalysis.cxx @@ -341,7 +341,7 @@ struct chargedkstaranalysis { // Defining filters for events (event selection) // Processed events will be already fulfilling the event selection // requirements - Filter eventFilter = (o2::aod::evsel::sel8 == true); + // Filter eventFilter = (o2::aod::evsel::sel8 == true); Filter posZFilter = (nabs(o2::aod::collision::posZ) < cutzvertex); Filter acceptanceFilter = @@ -351,7 +351,7 @@ struct chargedkstaranalysis { using EventCandidates = soa::Filtered< soa::Join>; + aod::CentFT0Ms, aod::CentFT0As, aod::CentFT0Cs>>; using TrackCandidates = soa::Filtered< soa::Join>; @@ -363,20 +363,20 @@ struct chargedkstaranalysis { "vertex axis for bin"}; ConfigurableAxis axisMultiplicityClass{ "axisMultiplicityClass", - {20, 0, 100}, + {1, 0, 100}, "multiplicity percentile for bin"}; ConfigurableAxis axisMultiplicity{ "axisMultiplicity", - {2000, 0, 10000}, + {2, 0, 100}, "TPC multiplicity for bin"}; using BinningTypeTPCMultiplicity = ColumnBinningPolicy; - using BinningTypeVertexContributor = - ColumnBinningPolicy; + // using BinningTypeVertexContributor = + // ColumnBinningPolicy; using BinningTypeCentralityM = ColumnBinningPolicy; - using BinningTypeCentralityC = + using BinningTypeVertexContributor = ColumnBinningPolicy; BinningTypeVertexContributor binningOnPositions{ @@ -397,6 +397,8 @@ struct chargedkstaranalysis { std::vector pions, kshorts; std::vector PionIndex = {}; + std::vector PioncollIndex = {}; + std::vector V0collIndex = {}; std::vector KshortPosDaughIndex = {}; std::vector KshortNegDaughIndex = {}; @@ -438,6 +440,7 @@ struct chargedkstaranalysis { massPi); pions.push_back(temp1); PionIndex.push_back(track1.globalIndex()); + PioncollIndex.push_back(track1.collisionId()); } // track loop ends @@ -461,6 +464,7 @@ struct chargedkstaranalysis { ROOT::Math::PtEtaPhiMVector temp2(v0.pt(), v0.eta(), v0.phi(), massK0s); kshorts.push_back(temp2); + V0collIndex.push_back(v0.collisionId()); KshortPosDaughIndex.push_back(postrack.globalIndex()); KshortNegDaughIndex.push_back(negtrack.globalIndex()); } @@ -475,6 +479,8 @@ struct chargedkstaranalysis { continue; if (PionIndex.at(i1) == KshortNegDaughIndex.at(i3)) continue; + if (PioncollIndex.at(i1) != V0collIndex.at(i3)) + continue; CKSVector = pions.at(i1) + kshorts.at(i3); if (TMath::Abs(CKSVector.Rapidity()) < 0.5) { @@ -513,7 +519,9 @@ struct chargedkstaranalysis { for (auto& [t1, t2] : o2::soa::combinations( o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { - if (!(selectionTrack(t1) || selectionPID(t1))) + if (!(selectionTrack(t1))) + continue; + if (!(selectionPID(t1))) continue; if (!SelectionV0(c2, t2, multiplicity)) continue; diff --git a/PWGLF/Tasks/deltaanalysis.cxx b/PWGLF/Tasks/Resonances/deltaanalysis.cxx similarity index 100% rename from PWGLF/Tasks/deltaanalysis.cxx rename to PWGLF/Tasks/Resonances/deltaanalysis.cxx diff --git a/PWGLF/Tasks/f0980analysis.cxx b/PWGLF/Tasks/Resonances/f0980analysis.cxx similarity index 100% rename from PWGLF/Tasks/f0980analysis.cxx rename to PWGLF/Tasks/Resonances/f0980analysis.cxx diff --git a/PWGLF/Tasks/f1protoncorrelation.cxx b/PWGLF/Tasks/Resonances/f1protoncorrelation.cxx similarity index 100% rename from PWGLF/Tasks/f1protoncorrelation.cxx rename to PWGLF/Tasks/Resonances/f1protoncorrelation.cxx diff --git a/PWGLF/Tasks/k1analysis.cxx b/PWGLF/Tasks/Resonances/k1analysis.cxx similarity index 98% rename from PWGLF/Tasks/k1analysis.cxx rename to PWGLF/Tasks/Resonances/k1analysis.cxx index eb8117ee717..e3599531046 100644 --- a/PWGLF/Tasks/k1analysis.cxx +++ b/PWGLF/Tasks/Resonances/k1analysis.cxx @@ -53,14 +53,14 @@ struct k1analysis { Configurable cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 0.1, "Track DCAz cut to PV Maximum"}; Configurable cMinDCAzToPVcut{"cMinDCAzToPVcut", 0.0, "Track DCAz cut to PV Minimum"}; /// PID Selections - Configurable cMaxTPCnSigmaPion{"cMaxTPCnSigmaPion", 3.0, "TPC nSigma cut for Pion"}; // TPC - Configurable cMaxTOFnSigmaPion{"cMaxTOFnSigmaPion", 3.0, "TOF nSigma cut for Pion"}; // TOF + Configurable cMaxTPCnSigmaPion{"cMaxTPCnSigmaPion", 3.0, "TPC nSigma cut for Pion"}; // TPC + Configurable cMaxTOFnSigmaPion{"cMaxTOFnSigmaPion", 3.0, "TOF nSigma cut for Pion"}; // TOF Configurable nsigmaCutCombinedPion{"nsigmaCutCombinedPion", -999, "Combined nSigma cut for Pion"}; // Combined Configurable cUseOnlyTOFTrackPi{"cUseOnlyTOFTrackPi", false, "Use only TOF track for PID selection"}; // Use only TOF track for Pion PID selection Configurable cUseOnlyTOFTrackKa{"cUseOnlyTOFTrackKa", false, "Use only TOF track for PID selection"}; // Use only TOF track for Kaon PID selection // Kaon - Configurable cMaxTPCnSigmaKaon{"cMaxTPCnSigmaKaon", 3.0, "TPC nSigma cut for Kaon"}; // TPC - Configurable cMaxTOFnSigmaKaon{"cMaxTOFnSigmaKaon", 3.0, "TOF nSigma cut for Kaon"}; // TOF + Configurable cMaxTPCnSigmaKaon{"cMaxTPCnSigmaKaon", 3.0, "TPC nSigma cut for Kaon"}; // TPC + Configurable cMaxTOFnSigmaKaon{"cMaxTOFnSigmaKaon", 3.0, "TOF nSigma cut for Kaon"}; // TOF Configurable nsigmaCutCombinedKaon{"nsigmaCutCombinedKaon", -999, "Combined nSigma cut for Kaon"}; // Combined // Track selections Configurable cfgPrimaryTrack{"cfgPrimaryTrack", true, "Primary track selection"}; // kGoldenChi2 | kDCAxy | kDCAz @@ -343,12 +343,12 @@ struct k1analysis { if (trk1.sign() > 0) { // Positive pion if (trk2.sign() > 0) // Positive kaon histos.fill(HIST("hK892invmass_PP"), multiplicity, lResonanceK892.Pt(), lResonanceK892.M()); - else // Negative kaon - histos.fill(HIST("hK892invmass_PN"), multiplicity, lResonanceK892.Pt(), lResonanceK892.M()); // Anti-K(892)0 - } else { // Negative pion - if (trk2.sign() > 0) // Positive kaon - histos.fill(HIST("hK892invmass_NP"), multiplicity, lResonanceK892.Pt(), lResonanceK892.M()); // K(892)0 - else // Negative kaon + else // Negative kaon + histos.fill(HIST("hK892invmass_PN"), multiplicity, lResonanceK892.Pt(), lResonanceK892.M()); // Anti-K(892)0 + } else { // Negative pion + if (trk2.sign() > 0) // Positive kaon + histos.fill(HIST("hK892invmass_NP"), multiplicity, lResonanceK892.Pt(), lResonanceK892.M()); // K(892)0 + else // Negative kaon histos.fill(HIST("hK892invmass_NN"), multiplicity, lResonanceK892.Pt(), lResonanceK892.M()); } } diff --git a/PWGLF/Tasks/k892analysis.cxx b/PWGLF/Tasks/Resonances/k892analysis.cxx similarity index 99% rename from PWGLF/Tasks/k892analysis.cxx rename to PWGLF/Tasks/Resonances/k892analysis.cxx index a298f4b9354..4941eb9734a 100644 --- a/PWGLF/Tasks/k892analysis.cxx +++ b/PWGLF/Tasks/Resonances/k892analysis.cxx @@ -63,14 +63,14 @@ struct k892analysis { Configurable cMaxDCAzToPVcut{"cMaxDCAzToPVcut", 2.0, "Track DCAz cut to PV Maximum"}; Configurable cMinDCAzToPVcut{"cMinDCAzToPVcut", 0.0, "Track DCAz cut to PV Minimum"}; /// PID Selections - Configurable cMaxTPCnSigmaPion{"cMaxTPCnSigmaPion", 3.0, "TPC nSigma cut for Pion"}; // TPC - Configurable cMaxTOFnSigmaPion{"cMaxTOFnSigmaPion", 3.0, "TOF nSigma cut for Pion"}; // TOF + Configurable cMaxTPCnSigmaPion{"cMaxTPCnSigmaPion", 3.0, "TPC nSigma cut for Pion"}; // TPC + Configurable cMaxTOFnSigmaPion{"cMaxTOFnSigmaPion", 3.0, "TOF nSigma cut for Pion"}; // TOF Configurable nsigmaCutCombinedPion{"nsigmaCutCombinedPion", -999, "Combined nSigma cut for Pion"}; // Combined Configurable cUseOnlyTOFTrackPi{"cUseOnlyTOFTrackPi", false, "Use only TOF track for PID selection"}; // Use only TOF track for Pion PID selection Configurable cUseOnlyTOFTrackKa{"cUseOnlyTOFTrackKa", false, "Use only TOF track for PID selection"}; // Use only TOF track for Kaon PID selection // Kaon - Configurable cMaxTPCnSigmaKaon{"cMaxTPCnSigmaKaon", 3.0, "TPC nSigma cut for Kaon"}; // TPC - Configurable cMaxTOFnSigmaKaon{"cMaxTOFnSigmaKaon", 3.0, "TOF nSigma cut for Kaon"}; // TOF + Configurable cMaxTPCnSigmaKaon{"cMaxTPCnSigmaKaon", 3.0, "TPC nSigma cut for Kaon"}; // TPC + Configurable cMaxTOFnSigmaKaon{"cMaxTOFnSigmaKaon", 3.0, "TOF nSigma cut for Kaon"}; // TOF Configurable nsigmaCutCombinedKaon{"nsigmaCutCombinedKaon", -999, "Combined nSigma cut for Kaon"}; // Combined // Track selections Configurable cfgPrimaryTrack{"cfgPrimaryTrack", true, "Primary track selection"}; // kGoldenChi2 | kDCAxy | kDCAz diff --git a/PWGLF/Tasks/k892pmanalysis.cxx b/PWGLF/Tasks/Resonances/k892pmanalysis.cxx similarity index 100% rename from PWGLF/Tasks/k892pmanalysis.cxx rename to PWGLF/Tasks/Resonances/k892pmanalysis.cxx diff --git a/PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx b/PWGLF/Tasks/Resonances/lambda1520SpherocityAnalysis.cxx similarity index 88% rename from PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx rename to PWGLF/Tasks/Resonances/lambda1520SpherocityAnalysis.cxx index 0472d0fb481..646ce2a87a6 100644 --- a/PWGLF/Tasks/lambda1520SpherocityAnalysis.cxx +++ b/PWGLF/Tasks/Resonances/lambda1520SpherocityAnalysis.cxx @@ -49,7 +49,6 @@ struct lambdaAnalysis { Configurable cEtaCut{"cEtaCut", 0.8, "Pseudorapidity cut"}; Configurable cDcaz{"cDcazMin", 1., "Minimum DCAz"}; Configurable cDcaxy{"cDcaxyMin", 0.1, "Minimum DCAxy"}; - Configurable cPIDprecut{"cPIDprecut", 5, "Preselection PID TPC TOF cut"}; Configurable cKinCuts{"cKinCuts", false, "Kinematic Cuts for p-K pair opening angle"}; Configurable cPrimaryTrack{"cPrimaryTrack", true, "Primary track selection"}; // kGoldenChi2 | kDCAxy | kDCAz Configurable cGlobalWoDCATrack{"cGlobalWoDCATrack", true, "Global track selection without DCA"}; // kQualityTracks (kTrackType | kTPCNCls | kTPCCrossedRows | kTPCCrossedRowsOverNCls | kTPCChi2NDF | kTPCRefit | kITSNCls | kITSChi2NDF | kITSRefit | kITSHits) | kInAcceptanceTracks (kPtRange | kEtaRange) @@ -59,7 +58,8 @@ struct lambdaAnalysis { Configurable cUseOnlyTOFTrackPr{"cUseOnlyTOFTrackPr", false, "Use only TOF track for PID selection"}; // Use only TOF track for Proton PID selection Configurable cUseOnlyTOFTrackKa{"cUseOnlyTOFTrackKa", false, "Use only TOF track for PID selection"}; // Use only TOF track for Kaon PID selection Configurable cUseTpcOnly{"cUseTpcOnly", false, "Use TPC Only selection"}; // TPC And TOF tracks - Configurable cRejNsigma{"cRejNsigma", 1.0, "Reject tracks to improve purity of PID"}; // Reject missidentified particles when tpc bands merge + Configurable cRejNsigmaTpc{"cRejNsigmaTpc", 3.0, "Reject tracks to improve purity of TPC PID"}; // Reject missidentified particles when tpc bands merge + Configurable cRejNsigmaTof{"cRejNsigmaTof", 3.0, "Reject tracks to improve purity of TOF PID"}; // Reject missidentified particles when tpc bands merge // Proton Configurable cMaxTPCnSigmaProton{"cMaxTPCnSigmaProton", 3.0, "TPC nSigma cut for Proton"}; // TPC Configurable cMaxTOFnSigmaProton{"cMaxTOFnSigmaProton", 3.0, "TOF nSigma cut for Proton"}; // TOF @@ -88,15 +88,15 @@ struct lambdaAnalysis { // Define Axis. const AxisSpec axisSp(nBinsSp, 0., 1., "S_{0}"); const AxisSpec axisCent(105, 0, 105, "FT0M (%)"); - const AxisSpec axisP_pid(400, 0., 4., "p (GeV/c)"); - const AxisSpec axisPt_pid(400, 0., 4., "p_{T} (GeV/c)"); + const AxisSpec axisP_pid(200, 0., 10., "p (GeV/c)"); + const AxisSpec axisPt_pid(200, 0., 10., "p_{T} (GeV/c)"); const AxisSpec axisPt(nBinsPt, 0., 10., "p_{T} (GeV/c)"); const AxisSpec axisEta(40, -1, 1, "#eta"); const AxisSpec axisDCAz(500, -0.5, 0.5, {"DCA_{z} (cm)"}); const AxisSpec axisDCAxy(240, -0.12, 0.12, {"DCA_{xy} (cm)"}); const AxisSpec axisTPCNCls(200, 0, 200, {"TPCNCls"}); - const AxisSpec axisTPCNsigma(120, -6, 6, {"n#sigma^{TPC}"}); - const AxisSpec axisTOFNsigma(120, -6, 6, {"n#sigma^{TOF}"}); + const AxisSpec axisTPCNsigma(401, -10.025, 10.025, {"n#sigma^{TPC}"}); + const AxisSpec axisTOFNsigma(401, -10.025, 10.025, {"n#sigma^{TOF}"}); const AxisSpec axisdEdx(380, 10, 200, {"#frac{dE}{dx}"}); const AxisSpec axisInvM(nBinsInvM, 1.44, 2.04, {"M_{inv} (GeV/c^{2})"}); @@ -115,7 +115,7 @@ struct lambdaAnalysis { histos.add("QAbefore/Kaon/h2d_ka_nsigma_tof_vs_tpc", "n#sigma^{TPC} vs n#sigma^{TOF} Kaons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); // QA After - histos.add("QAafter/Proton/h1d_pr_pt", "p_{T}-spectra Protons", kTH1F, {axisPt}); + histos.add("QAafter/Proton/h1d_pr_pt", "p_{T}-spectra Protons", kTH1F, {axisPt_pid}); histos.add("QAafter/Proton/h2d_pr_dca_z", "dca_{z} Protons", kTH2F, {axisPt_pid, axisDCAz}); histos.add("QAafter/Proton/h2d_pr_dca_xy", "dca_{xy} Protons", kTH2F, {axisPt_pid, axisDCAxy}); histos.add("QAafter/Proton/h2d_pr_dEdx_p", "TPC Signal Protons", kTH2F, {axisP_pid, axisdEdx}); @@ -124,7 +124,7 @@ struct lambdaAnalysis { histos.add("QAafter/Proton/h2d_pr_nsigma_tof_pt", " Protons", kTH2F, {axisPt_pid, axisTOFNsigma}); histos.add("QAafter/Proton/h2d_pr_nsigma_tof_p", " Protons", kTH2F, {axisP_pid, axisTOFNsigma}); histos.add("QAafter/Proton/h2d_pr_nsigma_tof_vs_tpc", "n#sigma(TOF) vs n#sigma(TPC) Protons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); - histos.add("QAafter/Kaon/h1d_ka_pt", "p_{T}-spectra Kaons", kTH1F, {axisPt}); + histos.add("QAafter/Kaon/h1d_ka_pt", "p_{T}-spectra Kaons", kTH1F, {axisPt_pid}); histos.add("QAafter/Kaon/h2d_ka_dca_z", "dca_{z} Kaons", kTH2F, {axisPt_pid, axisDCAz}); histos.add("QAafter/Kaon/h2d_ka_dca_xy", "dca_{xy} Kaons", kTH2F, {axisPt_pid, axisDCAxy}); histos.add("QAafter/Kaon/h2d_ka_dEdx_p", "TPC Signal Kaon", kTH2F, {axisP_pid, axisdEdx}); @@ -134,6 +134,14 @@ struct lambdaAnalysis { histos.add("QAafter/Kaon/h2d_ka_nsigma_tof_p", " Kaons", kTH2F, {axisP_pid, axisTOFNsigma}); histos.add("QAafter/Kaon/h2d_ka_nsigma_tof_vs_tpc", "n#sigma(TOF) vs n#sigma(TPC) Kaons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); + // QA checks for protons and kaons + histos.add("QAChecks/h1d_pr_pt", "p_{T}-spectra Protons", kTH1F, {axisPt_pid}); + histos.add("QAChecks/h1d_ka_pt", "p_{T}-spectra Kaons", kTH1F, {axisPt_pid}); + histos.add("QAChecks/h1d_pr_rec_pt", "Reconstructed p_{T}-spectra Protons", kTH1F, {axisPt_pid}); + histos.add("QAChecks/h1d_ka_rec_pt", "Recondstucted p_{T}-spectra Kaons", kTH1F, {axisPt_pid}); + histos.add("QAChecks/h1d_pr_gen_pt", "Generated p_{T}-spectra Protons", kTH1F, {axisPt_pid}); + histos.add("QAChecks/h1d_ka_gen_pt", "Generated p_{T}-spectra Kaons", kTH1F, {axisPt_pid}); + // Analysis // Lambda Invariant Mass histos.add("Analysis/h1d_lstar_invm_US", "#Lambda(1520) M_{inv}", kTH1D, {axisInvM}); @@ -209,10 +217,10 @@ struct lambdaAnalysis { float tpcTofNsigmaKa = tpcNsigmaKa * tpcNsigmaKa + tofNsigmaKa * tofNsigmaKa; float tpcTofNsigmaPr = tpcNsigmaPr * tpcNsigmaPr + tofNsigmaPr * tofNsigmaPr; float combinedCut = nsigmaCutCombinedProton * nsigmaCutCombinedProton; - float combinedRejCut = cRejNsigma * cRejNsigma; + float combinedRejCut = cRejNsigmaTof * cRejNsigmaTpc; if (!cUseTpcOnly && candidate.hasTOF()) { - if (tofNsigmaPr < cMaxTOFnSigmaProton && tofNsigmaPi > cRejNsigma && tofNsigmaKa > cRejNsigma) { + if (tofNsigmaPr < cMaxTOFnSigmaProton && tofNsigmaPi > cRejNsigmaTof && tofNsigmaKa > cRejNsigmaTof) { tofPIDPassed = true; } // square cut @@ -227,12 +235,12 @@ struct lambdaAnalysis { } else { tofPIDPassed = true; if (cUseTpcOnly) { - if (tpcNsigmaPr < cMaxTPCnSigmaProton && tpcNsigmaPi > cRejNsigma && tpcNsigmaKa > cRejNsigma) { + if (tpcNsigmaPr < cMaxTPCnSigmaProton && tpcNsigmaPi > cRejNsigmaTpc && tpcNsigmaKa > cRejNsigmaTpc) { tpcPIDPassed = true; } } else { for (int i = 0; i < nitr - 1; ++i) { - if (p >= tpcPIDp[i] && p < tpcPIDp[i + 1] && (tpcNsigmaPr < tpcPIDcut[i] && tpcNsigmaPi > cRejNsigma && tpcNsigmaKa > cRejNsigma)) { + if (p >= tpcPIDp[i] && p < tpcPIDp[i + 1] && (tpcNsigmaPr < tpcPIDcut[i] && tpcNsigmaPi > cRejNsigmaTpc && tpcNsigmaKa > cRejNsigmaTpc)) { tpcPIDPassed = true; } } @@ -262,10 +270,10 @@ struct lambdaAnalysis { float tpcTofNsigmaKa = tpcNsigmaKa * tpcNsigmaKa + tofNsigmaKa * tofNsigmaKa; float tpcTofNsigmaPr = tpcNsigmaPr * tpcNsigmaPr + tofNsigmaPr * tofNsigmaPr; float combinedCut = nsigmaCutCombinedKaon * nsigmaCutCombinedKaon; - float combinedRejCut = cRejNsigma * cRejNsigma; + float combinedRejCut = cRejNsigmaTpc * cRejNsigmaTof; if (!cUseTpcOnly && candidate.hasTOF()) { - if (tofNsigmaKa < cMaxTOFnSigmaKaon && tofNsigmaPi > cRejNsigma && tofNsigmaPr > cRejNsigma) { + if (tofNsigmaKa < cMaxTOFnSigmaKaon && tofNsigmaPi > cRejNsigmaTof && tofNsigmaPr > cRejNsigmaTof) { tofPIDPassed = true; } // square cut @@ -280,12 +288,12 @@ struct lambdaAnalysis { } else { tofPIDPassed = true; if (cUseTpcOnly) { - if (tpcNsigmaKa < cMaxTPCnSigmaKaon && tpcNsigmaPi > cRejNsigma && tpcNsigmaPr > cRejNsigma) { + if (tpcNsigmaKa < cMaxTPCnSigmaKaon && tpcNsigmaPi > cRejNsigmaTpc && tpcNsigmaPr > cRejNsigmaTpc) { tpcPIDPassed = true; } } else { for (int i = 0; i < nitr - 1; ++i) { - if (p >= tpcPIDp[i] && p < tpcPIDp[i + 1] && (tpcNsigmaKa < tpcPIDcut[i] && tpcNsigmaPi > cRejNsigma && tpcNsigmaPr > cRejNsigma)) { + if (p >= tpcPIDp[i] && p < tpcPIDp[i + 1] && (tpcNsigmaKa < tpcPIDcut[i] && tpcNsigmaPi > cRejNsigmaTpc && tpcNsigmaPr > cRejNsigmaTpc)) { tpcPIDPassed = true; } } @@ -419,13 +427,13 @@ struct lambdaAnalysis { } if constexpr (mc) { - if (abs(trkPr.pdgCode()) != 2212 || abs(trkKa.pdgCode()) != 321) + if (std::abs(trkPr.pdgCode()) != 2212 || std::abs(trkKa.pdgCode()) != 321) continue; if (trkPr.motherId() != trkKa.motherId()) continue; - if (abs(trkPr.motherPDG()) != 3124) // L* pdg_code = 3124 + if (std::abs(trkPr.motherPDG()) != 3124) // L* pdg_code = 3124 continue; // MC histograms @@ -451,6 +459,22 @@ struct lambdaAnalysis { histos.fill(HIST("Event/h2d_sph_vs_multpercentile"), collision.cent(), collision.spherocity()); fillDataHistos(tracks, tracks, collision.spherocity(), collision.cent()); + + // get proton and kaon pT-spectra + for (auto const& track : tracks) { + if (!selTracks(track)) + continue; + + float p = TMath::Sqrt(track.px() * track.px() + track.py() * track.py() + track.pz() * track.pz()); + + if (selectionPIDKaon(track, p)) { + histos.fill(HIST("QAChecks/h1d_ka_pt"), track.pt()); + } + + if (selectionPIDProton(track, p)) { + histos.fill(HIST("QAChecks/h1d_pr_pt"), track.pt()); + } + } } PROCESS_SWITCH(lambdaAnalysis, processData, "Process for Same Event Data", true); @@ -460,6 +484,31 @@ struct lambdaAnalysis { { histos.fill(HIST("Event/h1d_rec_sph"), collision.spherocity()); fillDataHistos(tracks, tracks, collision.spherocity(), collision.cent()); + + // get MC pT-spectra + for (auto const& track : tracks) { + + // get the generated level pT spectra of protons and kaons + if (std::abs(track.pdgCode()) == 321) + histos.fill(HIST("QAChecks/h1d_ka_gen_pt"), track.pt()); + + if (std::abs(track.pdgCode()) == 2212) + histos.fill(HIST("QAChecks/h1d_pr_gen_pt"), track.pt()); + + // get the reconstructed level pT spectra of protons and kaons + if (!selTracks(track)) + continue; + + float p = TMath::Sqrt(track.px() * track.px() + track.py() * track.py() + track.pz() * track.pz()); + + if (selectionPIDKaon(track, p) && std::abs(track.pdgCode()) == 321) { + histos.fill(HIST("QAChecks/h1d_ka_rec_pt"), track.pt()); + } + + if (selectionPIDProton(track, p) && std::abs(track.pdgCode()) == 2212) { + histos.fill(HIST("QAChecks/h1d_pr_rec_pt"), track.pt()); + } + } } PROCESS_SWITCH(lambdaAnalysis, processMC, "Process Event for MC", false); diff --git a/PWGLF/Tasks/Resonances/lambda1520_PbPb.cxx b/PWGLF/Tasks/Resonances/lambda1520_PbPb.cxx new file mode 100644 index 00000000000..2fe41e136f4 --- /dev/null +++ b/PWGLF/Tasks/Resonances/lambda1520_PbPb.cxx @@ -0,0 +1,590 @@ +// 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 +/// /// Invariant Mass Reconstruction of Lambda(1520) Resonance. +/// +/// \author Yash Patley +/// \author Naisr Mehdi Malik + +#include +#include +#include + +#include "Common/DataModel/PIDResponse.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 "CommonConstants/PhysicsConstants.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::constants::physics; + +struct lambdaAnalysis_pb { + + SliceCache cache; + Preslice perRCol = aod::resodaughter::resoCollisionId; + Preslice perCollision = aod::track::collisionId; + + // Configurables. + Configurable nBinsPt{"nBinsPt", 100, "N bins in pT histogram"}; + Configurable nBinsInvM{"nBinsInvM", 120, "N bins in InvMass histogram"}; + Configurable nBinsSp{"nBinsSp", 120, "N bins in spherocity histogram"}; + Configurable doRotate{"doRotate", true, "rotated inv mass spectra"}; + + // Tracks + Configurable cPtMin{"cPtMin", 0.15, "Minimum Track pT"}; + Configurable cEtaCut{"cEtaCut", 0.8, "Pseudorapidity cut"}; + Configurable cDcaz{"cDcazMin", 1., "Minimum DCAz"}; + Configurable cDcaxy{"cDcaxyMin", 0.1, "Minimum DCAxy"}; + Configurable cKinCuts{"cKinCuts", false, "Kinematic Cuts for p-K pair opening angle"}; + Configurable cITSRefit{"cITSRefit", false, "ITS TPC refit"}; + Configurable cTPCRefit{"cTPCRefit", false, "ITS TPC refit"}; + Configurable cPrimaryTrack{"cPrimaryTrack", true, "Primary track selection"}; // kGoldenChi2 | kDCAxy | kDCAz + Configurable cGlobalWoDCATrack{"cGlobalWoDCATrack", true, "Global track selection without DCA"}; // kQualityTracks (kTrackType | kTPCNCls | kTPCCrossedRows | kTPCCrossedRowsOverNCls | kTPCChi2NDF | kTPCRefit | kITSNCls | kITSChi2NDF | kITSRefit | kITSHits) | kInAcceptanceTracks (kPtRange | kEtaRange) + Configurable cPVContributor{"cPVContributor", true, "PV contributor track selection"}; // PV Contriuibutor + + // PID Selections + Configurable cUseOnlyTOFTrackPr{"cUseOnlyTOFTrackPr", false, "Use only TOF track for PID selection"}; // Use only TOF track for Proton PID selection + Configurable cUseOnlyTOFTrackKa{"cUseOnlyTOFTrackKa", false, "Use only TOF track for PID selection"}; // Use only TOF track for Kaon PID selection + Configurable cUseTpcOnly{"cUseTpcOnly", false, "Use TPC Only selection"}; // TPC And TOF tracks + Configurable cRejNsigmaTpc{"cRejNsigmaTpc", 3.0, "Reject tracks to improve purity of TPC PID"}; // Reject missidentified particles when tpc bands merge + Configurable cRejNsigmaTof{"cRejNsigmaTof", 3.0, "Reject tracks to improve purity of TOF PID"}; // Reject missidentified particles when tpc bands merge + // Proton + Configurable cMaxTPCnSigmaProton{"cMaxTPCnSigmaProton", 3.0, "TPC nSigma cut for Proton"}; // TPC + Configurable cMaxTOFnSigmaProton{"cMaxTOFnSigmaProton", 3.0, "TOF nSigma cut for Proton"}; // TOF + Configurable nsigmaCutCombinedProton{"nsigmaCutCombinedProton", 3.0, "Combined nSigma cut for Proton"}; // Combined + Configurable> protonTPCPIDp{"protonTPCPIDp", {0, 0.5, 0.7, 0.8}, "p dependent TPC cuts protons"}; + Configurable> protonTPCPIDcut{"protonTPCPIDcut", {5., 3.5, 2.5}, "TPC nsigma cuts protons"}; + // Kaon + Configurable cMaxTPCnSigmaKaon{"cMaxTPCnSigmaKaon", 3.0, "TPC nSigma cut for Kaon"}; // TPC + Configurable cMaxTOFnSigmaKaon{"cMaxTOFnSigmaKaon", 3.0, "TOF nSigma cut for Kaon"}; // TOF + Configurable nsigmaCutCombinedKaon{"nsigmaCutCombinedKaon", 3.0, "Combined nSigma cut for Kaon"}; // Combined + Configurable> kaonTPCPIDp{"kaonTPCPIDp", {0., 0.25, 0.3, 0.45}, "pT dependent TPC cuts kaons"}; + Configurable> kaonTPCPIDcut{"kaonTPCPIDcut", {6, 3.5, 2.5}, "TPC nsigma cuts kaons"}; + // Event Mixing. + Configurable cMixnoBin{"cMixnoBin", false, " BinsType to be mixed"}; + Configurable cNumMixEv{"cNumMixEv", 20, "Number of Events to be mixed"}; + Configurable MultDiff{"nMultDiffn", 10, "mult diff"}; + Configurable VzDiff{"VzDiff", 1, "vz diff"}; + ConfigurableAxis cMixVtxBins{"cMixVtxBins", {VARIABLE_WIDTH, -10.0f, -9.f, -8.f, -7.f, -6.f, -5.f, -4.f, -3.f, -2.f, -1.f, 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f}, "Mixing bins - z-vertex"}; + ConfigurableAxis cMixMultBins{"cMixMultBins", {VARIABLE_WIDTH, 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 200.0f}, "Mixing bins - multiplicity"}; + + // Histogram Registry. + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + void init(InitContext const&) + { + + // Define Axis. + const AxisSpec axisCent(110, 0, 110, "FT0 (%)"); + const AxisSpec axisP_pid(200, 0., 10., "p (GeV/c)"); + const AxisSpec axisPt_pid(200, 0., 10., "p_{T} (GeV/c)"); + const AxisSpec axisPt(nBinsPt, 0., 10., "p_{T} (GeV/c)"); + const AxisSpec axisEta(40, -1, 1, "#eta"); + const AxisSpec axisDCAz(500, -0.5, 0.5, {"DCA_{z} (cm)"}); + const AxisSpec axisDCAxy(240, -0.12, 0.12, {"DCA_{xy} (cm)"}); + const AxisSpec axisTPCNCls(200, 0, 200, {"TPCNCls"}); + const AxisSpec axisTPCNsigma(401, -10.025, 10.025, {"n#sigma^{TPC}"}); + const AxisSpec axisTOFNsigma(401, -10.025, 10.025, {"n#sigma^{TOF}"}); + const AxisSpec axisdEdx(380, 10, 200, {"#frac{dE}{dx}"}); + const AxisSpec axisInvM(nBinsInvM, 1.44, 2.04, {"M_{inv} (GeV/c^{2})"}); + + // Create Histograms. + // Event + histos.add("Event/h1d_ft0_mult_percentile", "FT0 (%)", kTH1F, {axisCent}); + + histos.add("Event/mixing_vzVsmultpercentile", "FT0(%)", kTH1F, {axisCent}); + + // QA Before + histos.add("QAbefore/Proton/h2d_pr_nsigma_tpc_p", "n#sigma^{TPC} Protons", kTH2F, {axisP_pid, axisTPCNsigma}); + histos.add("QAbefore/Proton/h2d_pr_nsigma_tof_p", "n#sigma^{TOF} Protons", kTH2F, {axisP_pid, axisTOFNsigma}); + histos.add("QAbefore/Proton/h2d_pr_nsigma_tof_vs_tpc", "n#sigma^{TPC} vs n#sigma^{TOF} Protons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); + histos.add("QAbefore/Kaon/h2d_ka_nsigma_tpc_p", "n#sigma^{TPC} Kaons", kTH2F, {axisP_pid, axisTPCNsigma}); + histos.add("QAbefore/Kaon/h2d_ka_nsigma_tof_p", "n#sigma^{TOF} Kaons", kTH2F, {axisP_pid, axisTOFNsigma}); + histos.add("QAbefore/Kaon/h2d_ka_nsigma_tof_vs_tpc", "n#sigma^{TPC} vs n#sigma^{TOF} Kaons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); + + // QA After + histos.add("QAafter/Proton/h1d_pr_pt", "p_{T}-spectra Protons", kTH1F, {axisPt_pid}); + histos.add("QAafter/Proton/h2d_pr_dca_z", "dca_{z} Protons", kTH2F, {axisPt_pid, axisDCAz}); + histos.add("QAafter/Proton/h2d_pr_dca_xy", "dca_{xy} Protons", kTH2F, {axisPt_pid, axisDCAxy}); + histos.add("QAafter/Proton/h2d_pr_dEdx_p", "TPC Signal Protons", kTH2F, {axisP_pid, axisdEdx}); + histos.add("QAafter/Proton/h2d_pr_nsigma_tpc_pt", " Protons", kTH2F, {axisPt_pid, axisTPCNsigma}); + histos.add("QAafter/Proton/h2d_pr_nsigma_tpc_p", " Protons", kTH2F, {axisP_pid, axisTPCNsigma}); + histos.add("QAafter/Proton/h2d_pr_nsigma_tof_pt", " Protons", kTH2F, {axisPt_pid, axisTOFNsigma}); + histos.add("QAafter/Proton/h2d_pr_nsigma_tof_p", " Protons", kTH2F, {axisP_pid, axisTOFNsigma}); + histos.add("QAafter/Proton/h2d_pr_nsigma_tof_vs_tpc", "n#sigma(TOF) vs n#sigma(TPC) Protons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); + histos.add("QAafter/Kaon/h1d_ka_pt", "p_{T}-spectra Kaons", kTH1F, {axisPt_pid}); + histos.add("QAafter/Kaon/h2d_ka_dca_z", "dca_{z} Kaons", kTH2F, {axisPt_pid, axisDCAz}); + histos.add("QAafter/Kaon/h2d_ka_dca_xy", "dca_{xy} Kaons", kTH2F, {axisPt_pid, axisDCAxy}); + histos.add("QAafter/Kaon/h2d_ka_dEdx_p", "TPC Signal Kaon", kTH2F, {axisP_pid, axisdEdx}); + histos.add("QAafter/Kaon/h2d_ka_nsigma_tpc_pt", " Kaons", kTH2F, {axisPt_pid, axisTPCNsigma}); + histos.add("QAafter/Kaon/h2d_ka_nsigma_tpc_p", " Kaons", kTH2F, {axisP_pid, axisTPCNsigma}); + histos.add("QAafter/Kaon/h2d_ka_nsigma_tof_pt", " Kaons", kTH2F, {axisPt_pid, axisTOFNsigma}); + histos.add("QAafter/Kaon/h2d_ka_nsigma_tof_p", " Kaons", kTH2F, {axisP_pid, axisTOFNsigma}); + histos.add("QAafter/Kaon/h2d_ka_nsigma_tof_vs_tpc", "n#sigma(TOF) vs n#sigma(TPC) Kaons", kTH2F, {axisTPCNsigma, axisTOFNsigma}); + + // QA checks for protons and kaons + histos.add("QAChecks/h1d_pr_pt", "p_{T}-spectra Protons", kTH1F, {axisPt_pid}); + histos.add("QAChecks/h1d_ka_pt", "p_{T}-spectra Kaons", kTH1F, {axisPt_pid}); + histos.add("QAChecks/h1d_pr_rec_pt", "Reconstructed p_{T}-spectra Protons", kTH1F, {axisPt_pid}); + histos.add("QAChecks/h1d_ka_rec_pt", "Recondstucted p_{T}-spectra Kaons", kTH1F, {axisPt_pid}); + histos.add("QAChecks/h1d_pr_gen_pt", "Generated p_{T}-spectra Protons", kTH1F, {axisPt_pid}); + histos.add("QAChecks/h1d_ka_gen_pt", "Generated p_{T}-spectra Kaons", kTH1F, {axisPt_pid}); + + // Analysis + // Lambda Invariant Mass + histos.add("Analysis/h1d_lstar_invm_US", "#Lambda(1520) M_{inv}", kTH1D, {axisInvM}); + histos.add("Analysis/h1d_lstar_invm_PP", "Like Signs M_{inv} p K^{+}", kTH1D, {axisInvM}); + histos.add("Analysis/h1d_lstar_invm_MM", "Like Signs M_{inv} #bar{p} K^{-}", kTH1D, {axisInvM}); + histos.add("Analysis/h1d_lstar_invm_rot", "Rotated Spectra", kTH1D, {axisInvM}); + histos.add("Analysis/h1d_lstar_invm_US_mix", "Mixed Events M_{inv}", kTH1D, {axisInvM}); + histos.add("Analysis/h1d_lstar_invm_LS_mix", "Mixed Events M_{inv}", kTH1D, {axisInvM}); + histos.add("Analysis/h4d_lstar_invm_US", "THn #Lambda(1520)", kTHnSparseD, {axisInvM, axisPt, axisCent}); + histos.add("Analysis/h4d_lstar_invm_PP", "THn Like Signs p K^{+}", kTHnSparseD, {axisInvM, axisPt, axisCent}); + histos.add("Analysis/h4d_lstar_invm_MM", "THn Like Signs #bar{p} K^{-}", kTHnSparseD, {axisInvM, axisPt, axisCent}); + histos.add("Analysis/h4d_lstar_invm_rot", "THn Rotated", kTHnSparseD, {axisInvM, axisPt, axisCent}); + histos.add("Analysis/h4d_lstar_invm_US_mix", "THn Mixed Events", kTHnSparseD, {axisInvM, axisPt, axisCent}); + histos.add("Analysis/h4d_lstar_invm_LS_mix", "THn Mixed Events", kTHnSparseD, {axisInvM, axisPt, axisCent}); + + // MC + if (doprocessMC) { + + histos.add("Event/h1d_rec_cent", "Reconstructed FT0(%)", kTH2F, {axisCent}); + histos.add("Analysis/h1d_gen_lstar", "Generated #Lambda(1520) p_{T}", kTH1D, {axisPt}); + histos.add("Analysis/h1d_gen_lstar_anti", "Generated #bar{#Lambda}(1520) p_{T}", kTH1D, {axisPt}); + histos.add("Analysis/h1d_rec_lstar", "Reconstructed #Lambda(1520) p_{T}", kTH1D, {axisPt}); + histos.add("Analysis/h1d_rec_lstar_anti", "Reconstructed #bar{#Lambda}(1520) p_{T}", kTH1D, {axisPt}); + histos.add("Analysis/h1d_rec_invm_lstar", "Recostructed #Lambda(1520)", kTH1D, {axisInvM}); + histos.add("Analysis/h1d_rec_invm_lstar_anti", "Recostructed #bar{#Lambda}(1520)", kTH1D, {axisInvM}); + } + } + + template + bool selTracks(T const& track) + { + + if (track.pt() < cPtMin) + return false; + + if (std::abs(track.eta()) > cEtaCut) + return false; + + if (std::abs(track.dcaZ()) > cDcaz) + return false; + + if (std::abs(track.dcaXY()) > cDcaxy) + return false; + + if (cPrimaryTrack && !track.isPrimaryTrack()) + return false; + + if (cGlobalWoDCATrack && !track.isGlobalTrackWoDCA()) + return false; + + if (cPVContributor && !track.isPVContributor()) + return false; + + return true; + } + // PID selection tools + template + bool selectionPIDProton(const T& candidate, float p) + { + bool tpcPIDPassed{false}, tofPIDPassed{false}; + auto tpcPIDp = static_cast>(protonTPCPIDp); + auto tpcPIDcut = static_cast>(protonTPCPIDcut); + int nitr = static_cast(tpcPIDp.size()); + + float tpcNsigmaPi = std::abs(candidate.tpcNSigmaPi()); + float tpcNsigmaKa = std::abs(candidate.tpcNSigmaKa()); + float tpcNsigmaPr = std::abs(candidate.tpcNSigmaPr()); + float tofNsigmaPi = std::abs(candidate.tofNSigmaPi()); + float tofNsigmaKa = std::abs(candidate.tofNSigmaKa()); + float tofNsigmaPr = std::abs(candidate.tofNSigmaPr()); + + float tpcTofNsigmaPi = tpcNsigmaPi * tpcNsigmaPi + tofNsigmaPi * tofNsigmaPi; + float tpcTofNsigmaKa = tpcNsigmaKa * tpcNsigmaKa + tofNsigmaKa * tofNsigmaKa; + float tpcTofNsigmaPr = tpcNsigmaPr * tpcNsigmaPr + tofNsigmaPr * tofNsigmaPr; + float combinedCut = nsigmaCutCombinedProton * nsigmaCutCombinedProton; + float combinedRejCut = cRejNsigmaTof * cRejNsigmaTpc; + + if (!cUseTpcOnly && candidate.hasTOF()) { + if (tofNsigmaPr < cMaxTOFnSigmaProton && tofNsigmaPi > cRejNsigmaTof && tofNsigmaKa > cRejNsigmaTof) { + tofPIDPassed = true; + } + // square cut + if ((nsigmaCutCombinedProton < 0) && (tpcNsigmaPr < cMaxTPCnSigmaProton)) { + tpcPIDPassed = true; + } + // circular cut + if ((nsigmaCutCombinedProton > 0) && (tpcTofNsigmaPr < combinedCut && tpcTofNsigmaPi > combinedRejCut && tpcTofNsigmaKa > combinedRejCut)) { + tofPIDPassed = true; + tpcPIDPassed = true; + } + } else { + tofPIDPassed = true; + if (cUseTpcOnly) { + if (tpcNsigmaPr < cMaxTPCnSigmaProton && tpcNsigmaPi > cRejNsigmaTpc && tpcNsigmaKa > cRejNsigmaTpc) { + tpcPIDPassed = true; + } + } else { + for (int i = 0; i < nitr - 1; ++i) { + if (p >= tpcPIDp[i] && p < tpcPIDp[i + 1] && (tpcNsigmaPr < tpcPIDcut[i] && tpcNsigmaPi > cRejNsigmaTpc && tpcNsigmaKa > cRejNsigmaTpc)) { + tpcPIDPassed = true; + } + } + } + } + if (tpcPIDPassed && tofPIDPassed) { + return true; + } + return false; + } + template + bool selectionPIDKaon(const T& candidate, float p) + { + bool tpcPIDPassed{false}, tofPIDPassed{false}; + auto tpcPIDp = static_cast>(kaonTPCPIDp); + auto tpcPIDcut = static_cast>(kaonTPCPIDcut); + int nitr = static_cast(tpcPIDp.size()); + + float tpcNsigmaPi = std::abs(candidate.tpcNSigmaPi()); + float tpcNsigmaKa = std::abs(candidate.tpcNSigmaKa()); + float tpcNsigmaPr = std::abs(candidate.tpcNSigmaPr()); + float tofNsigmaPi = std::abs(candidate.tofNSigmaPi()); + float tofNsigmaKa = std::abs(candidate.tofNSigmaKa()); + float tofNsigmaPr = std::abs(candidate.tofNSigmaPr()); + // float tofNsigmaEl = std::abs(); + + float tpcTofNsigmaPi = tpcNsigmaPi * tpcNsigmaPi + tofNsigmaPi * tofNsigmaPi; + float tpcTofNsigmaKa = tpcNsigmaKa * tpcNsigmaKa + tofNsigmaKa * tofNsigmaKa; + float tpcTofNsigmaPr = tpcNsigmaPr * tpcNsigmaPr + tofNsigmaPr * tofNsigmaPr; + float combinedCut = nsigmaCutCombinedKaon * nsigmaCutCombinedKaon; + float combinedRejCut = cRejNsigmaTpc * cRejNsigmaTof; + + if (!cUseTpcOnly && candidate.hasTOF()) { + if (tofNsigmaKa < cMaxTOFnSigmaKaon && tofNsigmaPi > cRejNsigmaTof && tofNsigmaPr > cRejNsigmaTof) { + tofPIDPassed = true; + } + // square cut + if ((nsigmaCutCombinedKaon < 0) && (tpcNsigmaKa < cMaxTPCnSigmaKaon)) { + tpcPIDPassed = true; + } + // circular + if ((nsigmaCutCombinedKaon > 0) && (tpcTofNsigmaKa < combinedCut && tpcTofNsigmaPi > combinedRejCut && tpcTofNsigmaPr > combinedRejCut)) { + tofPIDPassed = true; + tpcPIDPassed = true; + } + } else { + tofPIDPassed = true; + if (cUseTpcOnly) { + if (tpcNsigmaKa < cMaxTPCnSigmaKaon && tpcNsigmaPi > cRejNsigmaTpc && tpcNsigmaPr > cRejNsigmaTpc) { + tpcPIDPassed = true; + } + } else { + for (int i = 0; i < nitr - 1; ++i) { + if (p >= tpcPIDp[i] && p < tpcPIDp[i + 1] && (tpcNsigmaKa < tpcPIDcut[i] && tpcNsigmaPi > cRejNsigmaTpc && tpcNsigmaPr > cRejNsigmaTpc)) { + tpcPIDPassed = true; + } + } + } + } + if (tpcPIDPassed && tofPIDPassed) { + return true; + } + return false; + } + + template + void fillDataHistos(trackType const& trk1, trackType const& trk2, float const& mult) + { + TLorentzVector p1, p2, p; + TRandom* rn = new TRandom(); + float p_ptot = 0., k_ptot = 0.; + + for (auto const& [trkPr, trkKa] : soa::combinations(soa::CombinationsFullIndexPolicy(trk1, trk2))) { + // Do not analyse same index tracks. + if (trkPr.index() == trkKa.index() && !mix) + continue; + + // pT, DCA, Global Tracks and PVcontrib selection. + if (!selTracks(trkPr) || !selTracks(trkKa)) + continue; + + if (cITSRefit && !trkPr.passedITSRefit()) + continue; + if (cITSRefit && !trkKa.passedITSRefit()) + continue; + if (cTPCRefit && !trkPr.passedTPCRefit()) + continue; + if (cTPCRefit && !trkKa.passedTPCRefit()) + continue; + + p_ptot = TMath::Sqrt(trkPr.px() * trkPr.px() + trkPr.py() * trkPr.py() + trkPr.pz() * trkPr.pz()); + k_ptot = TMath::Sqrt(trkKa.px() * trkKa.px() + trkKa.py() * trkKa.py() + trkKa.pz() * trkKa.pz()); + + // Fill QA before track selection. + if (!mix) { + histos.fill(HIST("QAbefore/Proton/h2d_pr_nsigma_tpc_p"), p_ptot, trkPr.tpcNSigmaPr()); + if (trkPr.hasTOF()) { + histos.fill(HIST("QAbefore/Proton/h2d_pr_nsigma_tof_p"), p_ptot, trkPr.tofNSigmaPr()); + histos.fill(HIST("QAbefore/Proton/h2d_pr_nsigma_tof_vs_tpc"), trkPr.tpcNSigmaPr(), trkPr.tofNSigmaPr()); + } + histos.fill(HIST("QAbefore/Kaon/h2d_ka_nsigma_tpc_p"), k_ptot, trkKa.tpcNSigmaKa()); + if (trkKa.hasTOF()) { + histos.fill(HIST("QAbefore/Kaon/h2d_ka_nsigma_tof_p"), k_ptot, trkKa.tofNSigmaKa()); + histos.fill(HIST("QAbefore/Kaon/h2d_ka_nsigma_tof_vs_tpc"), trkKa.tpcNSigmaKa(), trkKa.tofNSigmaKa()); + } + } + + // Apply PID Selection + if (cUseOnlyTOFTrackPr && !trkPr.hasTOF()) + continue; + if (cUseOnlyTOFTrackKa && !trkKa.hasTOF()) + continue; + if (!selectionPIDProton(trkPr, p_ptot) || !selectionPIDKaon(trkKa, k_ptot)) + continue; + + // Fill QA after track selection. + if constexpr (!mix) { + // Proton + histos.fill(HIST("QAafter/Proton/h1d_pr_pt"), trkPr.pt()); + histos.fill(HIST("QAafter/Proton/h2d_pr_dca_z"), trkPr.pt(), trkPr.dcaZ()); + histos.fill(HIST("QAafter/Proton/h2d_pr_dca_xy"), trkPr.pt(), trkPr.dcaXY()); + histos.fill(HIST("QAafter/Proton/h2d_pr_dEdx_p"), p_ptot, trkPr.tpcSignal()); + histos.fill(HIST("QAafter/Proton/h2d_pr_nsigma_tpc_p"), p_ptot, trkPr.tpcNSigmaPr()); + histos.fill(HIST("QAafter/Proton/h2d_pr_nsigma_tpc_pt"), trkPr.pt(), trkPr.tpcNSigmaPr()); + if (!cUseTpcOnly && trkPr.hasTOF()) { + histos.fill(HIST("QAafter/Proton/h2d_pr_nsigma_tof_p"), p_ptot, trkPr.tofNSigmaPr()); + histos.fill(HIST("QAafter/Proton/h2d_pr_nsigma_tof_pt"), trkPr.pt(), trkPr.tofNSigmaPr()); + histos.fill(HIST("QAafter/Proton/h2d_pr_nsigma_tof_vs_tpc"), trkPr.tpcNSigmaPr(), trkPr.tofNSigmaPr()); + } + // Kaon + histos.fill(HIST("QAafter/Kaon/h1d_ka_pt"), trkKa.pt()); + histos.fill(HIST("QAafter/Kaon/h2d_ka_dca_z"), trkKa.pt(), trkKa.dcaZ()); + histos.fill(HIST("QAafter/Kaon/h2d_ka_dca_xy"), trkKa.pt(), trkKa.dcaXY()); + histos.fill(HIST("QAafter/Kaon/h2d_ka_dEdx_p"), k_ptot, trkKa.tpcSignal()); + histos.fill(HIST("QAafter/Kaon/h2d_ka_nsigma_tpc_p"), k_ptot, trkKa.tpcNSigmaKa()); + histos.fill(HIST("QAafter/Kaon/h2d_ka_nsigma_tpc_pt"), trkKa.pt(), trkKa.tpcNSigmaKa()); + if (!cUseTpcOnly && trkKa.hasTOF()) { + histos.fill(HIST("QAafter/Kaon/h2d_ka_nsigma_tof_p"), k_ptot, trkKa.tofNSigmaKa()); + histos.fill(HIST("QAafter/Kaon/h2d_ka_nsigma_tof_pt"), trkKa.pt(), trkKa.tofNSigmaKa()); + histos.fill(HIST("QAafter/Kaon/h2d_ka_nsigma_tof_vs_tpc"), trkKa.tpcNSigmaKa(), trkKa.tofNSigmaKa()); + } + } + + // Invariant mass reconstruction. + p1.SetXYZM(trkPr.px(), trkPr.py(), trkPr.pz(), MassProton); + p2.SetXYZM(trkKa.px(), trkKa.py(), trkKa.pz(), MassKaonCharged); + p = p1 + p2; + + if (std::abs(p.Rapidity()) > 0.5) + continue; + + // Apply kinematic cuts. + if (cKinCuts) { + TVector3 v1(trkPr.px(), trkPr.py(), trkPr.pz()); + TVector3 v2(trkKa.px(), trkKa.py(), trkKa.pz()); + float alpha = v1.Angle(v2); + if (alpha > 1.4 && alpha < 2.4) + continue; + } + + // Fill Invariant Mass Histograms. + if constexpr (!mix && !mc) { + if (trkPr.sign() * trkKa.sign() < 0) { + histos.fill(HIST("Analysis/h1d_lstar_invm_US"), p.M()); + histos.fill(HIST("Analysis/h4d_lstar_invm_US"), p.M(), p.Pt(), mult); + if (doRotate) { + float theta = rn->Uniform(1.56, 1.58); + p1.RotateZ(theta); + p = p1 + p2; + if (std::abs(p.Rapidity()) < 0.5) { + histos.fill(HIST("Analysis/h1d_lstar_invm_rot"), p.M()); + histos.fill(HIST("Analysis/h4d_lstar_invm_rot"), p.M(), p.Pt(), mult); + } + } + } else { + if (trkPr.sign() == 1) { + histos.fill(HIST("Analysis/h1d_lstar_invm_PP"), p.M()); + histos.fill(HIST("Analysis/h4d_lstar_invm_PP"), p.M(), p.Pt(), mult); + } else { + histos.fill(HIST("Analysis/h1d_lstar_invm_MM"), p.M()); + histos.fill(HIST("Analysis/h4d_lstar_invm_MM"), p.M(), p.Pt(), mult); + } + } + } + + if constexpr (mix) { + if (trkPr.sign() * trkKa.sign() < 0) { + histos.fill(HIST("Analysis/h1d_lstar_invm_US_mix"), p.M()); + histos.fill(HIST("Analysis/h4d_lstar_invm_US_mix"), p.M(), p.Pt(), mult); + } else { + histos.fill(HIST("Analysis/h1d_lstar_invm_LS_mix"), p.M()); + histos.fill(HIST("Analysis/h4d_lstar_invm_LS_mix"), p.M(), p.Pt(), mult); + } + } + + if constexpr (mc) { + if (std::abs(trkPr.pdgCode()) != 2212 || std::abs(trkKa.pdgCode()) != 321) + continue; + + if (trkPr.motherId() != trkKa.motherId()) + continue; + + if (std::abs(trkPr.motherPDG()) != 3124) // L* pdg_code = 3124 + continue; + + // MC histograms + if (trkPr.motherPDG() > 0) { + histos.fill(HIST("Analysis/h1d_rec_lstar"), p.Pt()); + histos.fill(HIST("Analysis/h1d_rec_invm_lstar"), p.M()); + } else { + histos.fill(HIST("Analysis/h1d_rec_lstar_anti"), p.Pt()); + histos.fill(HIST("Analysis/h1d_rec_invm_lstar_anti"), p.M()); + } + } + } + } + + using resoCols = aod::ResoCollisions; + using resoTracks = aod::ResoTracks; + + void processData(resoCols::iterator const& collision, resoTracks const& tracks) + { + + histos.fill(HIST("Event/h1d_ft0_mult_percentile"), collision.cent()); + fillDataHistos(tracks, tracks, collision.cent()); + + // get proton and kaon pT-spectra + for (auto const& track : tracks) { + if (!selTracks(track)) + continue; + + float p = TMath::Sqrt(track.px() * track.px() + track.py() * track.py() + track.pz() * track.pz()); + + if (selectionPIDKaon(track, p)) { + histos.fill(HIST("QAChecks/h1d_ka_pt"), track.pt()); + } + + if (selectionPIDProton(track, p)) { + histos.fill(HIST("QAChecks/h1d_pr_pt"), track.pt()); + } + } + } + + PROCESS_SWITCH(lambdaAnalysis_pb, processData, "Process for Same Event Data", true); + + void processMC(resoCols::iterator const& collision, + soa::Join const& tracks) + { + + fillDataHistos(tracks, tracks, collision.cent()); + + // get MC pT-spectra + for (auto const& track : tracks) { + + // get the generated level pT spectra of protons and kaons + if (std::abs(track.pdgCode()) == 321) + histos.fill(HIST("QAChecks/h1d_ka_gen_pt"), track.pt()); + + if (std::abs(track.pdgCode()) == 2212) + histos.fill(HIST("QAChecks/h1d_pr_gen_pt"), track.pt()); + + // get the reconstructed level pT spectra of protons and kaons + if (!selTracks(track)) + continue; + + float p = TMath::Sqrt(track.px() * track.px() + track.py() * track.py() + track.pz() * track.pz()); + + if (selectionPIDKaon(track, p) && std::abs(track.pdgCode()) == 321) { + histos.fill(HIST("QAChecks/h1d_ka_rec_pt"), track.pt()); + } + + if (selectionPIDProton(track, p) && std::abs(track.pdgCode()) == 2212) { + histos.fill(HIST("QAChecks/h1d_pr_rec_pt"), track.pt()); + } + } + } + PROCESS_SWITCH(lambdaAnalysis_pb, processMC, "Process Event for MC", false); + + void processMCTrue(aod::ResoMCParents const& resoParents) + { + + for (auto const& part : resoParents) { + + if (abs(part.pdgCode()) != 3124) // // L* pdg_code = 3124 + continue; + if (abs(part.y()) > 0.5) { // rapidity cut + continue; + } + + bool pass1 = false; + bool pass2 = false; + + if (abs(part.daughterPDG1()) == 2212 || abs(part.daughterPDG2()) == 2212) { // At least one decay to Proton + pass1 = true; + } + if (abs(part.daughterPDG1()) == 321 || abs(part.daughterPDG2()) == 321) { // At least one decay to Kaon + pass2 = true; + } + + if (!pass1 || !pass2) // If we have both decay products + continue; + + if (part.pdgCode() > 0) + histos.fill(HIST("Analysis/h1d_gen_lstar"), part.pt()); + else + histos.fill(HIST("Analysis/h1d_gen_lstar_anti"), part.pt()); + } + } + PROCESS_SWITCH(lambdaAnalysis_pb, processMCTrue, "Process Event for MC", false); + + // Processing Event Mixing + + using BinningType2 = ColumnBinningPolicy; + void processMix(resoCols& collisions, resoTracks const& tracks) + { + + LOGF(debug, "Event Mixing Started"); + + BinningType2 binningPositions2{{cMixVtxBins, cMixMultBins}, true}; + auto tracksTuple = std::make_tuple(tracks); + if (cMixnoBin) { + SameKindPair pairs{binningPositions2, cNumMixEv, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto& [c1, t1, c2, t2] : pairs) { + if (abs(c1.size() - c2.size()) > MultDiff || abs(c1.posZ() - c2.posZ()) > VzDiff) + continue; + histos.fill(HIST("Event/mixing_vzVsmultpercentile"), c1.cent()); + fillDataHistos(t1, t2, c1.cent()); + } + } else { + SameKindPair pairs{binningPositions2, cNumMixEv, -1, collisions, tracksTuple, &cache}; // -1 is the number of the bin to skip + for (auto& [c1, t1, c2, t2] : pairs) { + histos.fill(HIST("Event/mixing_vzVsmultpercentile"), c1.cent()); + fillDataHistos(t1, t2, c1.cent()); + } + } + } + + PROCESS_SWITCH(lambdaAnalysis_pb, processMix, "Process for Mixed Events", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/Tasks/lambda1520analysis.cxx b/PWGLF/Tasks/Resonances/lambda1520analysis.cxx similarity index 100% rename from PWGLF/Tasks/lambda1520analysis.cxx rename to PWGLF/Tasks/Resonances/lambda1520analysis.cxx diff --git a/PWGLF/Tasks/phianalysis.cxx b/PWGLF/Tasks/Resonances/phianalysis.cxx similarity index 100% rename from PWGLF/Tasks/phianalysis.cxx rename to PWGLF/Tasks/Resonances/phianalysis.cxx diff --git a/PWGLF/Tasks/phianalysisTHnSparse.cxx b/PWGLF/Tasks/Resonances/phianalysisTHnSparse.cxx similarity index 100% rename from PWGLF/Tasks/phianalysisTHnSparse.cxx rename to PWGLF/Tasks/Resonances/phianalysisTHnSparse.cxx diff --git a/PWGLF/Tasks/phianalysisrun3.cxx b/PWGLF/Tasks/Resonances/phianalysisrun3.cxx similarity index 84% rename from PWGLF/Tasks/phianalysisrun3.cxx rename to PWGLF/Tasks/Resonances/phianalysisrun3.cxx index 1dedfabd679..66f3f7124e1 100644 --- a/PWGLF/Tasks/phianalysisrun3.cxx +++ b/PWGLF/Tasks/Resonances/phianalysisrun3.cxx @@ -27,7 +27,7 @@ #include #include #include - +#include #include #include #include @@ -71,6 +71,8 @@ struct phianalysisrun3 { Configurable ismanualDCAcut{"ismanualDCAcut", true, "ismanualDCAcut"}; Configurable isITSOnlycut{"isITSOnlycut", true, "isITSOnlycut"}; Configurable cfgITScluster{"cfgITScluster", 0, "Number of ITS cluster"}; + Configurable isDeepAngle{"isDeepAngle", false, "Deep Angle cut"}; + Configurable cfgDeepAngle{"cfgDeepAngle", 0.04, "Deep Angle cut value"}; // MC Configurable isMC{"isMC", false, "Run MC"}; void init(o2::framework::InitContext&) @@ -98,8 +100,9 @@ struct phianalysisrun3 { histos.add("h3PhiInvMassMixedCside", "Invariant mass of Phi meson Mixed C side", kTH3F, {{201, -0.5, 200.5}, {100, 0.0f, 10.0f}, {200, 0.9, 1.1}}); } } else if (isMC) { - histos.add("hMC", "MC Event statistics", kTH1F, {{2, 0.0f, 2.0f}}); + histos.add("hMC", "MC Event statistics", kTH1F, {{5, 0.0f, 4.0f}}); histos.add("h1PhiGen", "Phi meson Gen", kTH1F, {{100, 0.0f, 10.0f}}); + histos.add("h1PhiGensamecoll", "Phi meson Gen same coll", kTH1F, {{100, 0.0f, 10.0f}}); histos.add("h2PhiRec", "Phi meson Rec", kTH2F, {{100, 0.0f, 10.0f}, {200, -0.1, 0.1}}); } } @@ -138,6 +141,23 @@ struct phianalysisrun3 { } 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; + } template void FillinvMass(const T1& candidate1, const T2& candidate2, float multiplicity, bool unlike, bool mix, bool likesign, bool rotation, float massd1, float massd2) { @@ -217,7 +237,7 @@ struct phianalysisrun3 { // BinningType binningOnPositions{{axisVertex, axisMultiplicityClass}, true}; // using BinningTypeTPCMultiplicity = ColumnBinningPolicy; - using BinningTypeVertexContributor = ColumnBinningPolicy; + using BinningTypeVertexContributor = ColumnBinningPolicy; // using BinningTypeCentrality = ColumnBinningPolicy; // using BinningType = ColumnBinningPolicy; @@ -230,9 +250,9 @@ struct phianalysisrun3 { } float multiplicity; if (cfgMultFT0) - multiplicity = collision.multZeqFT0A() + collision.multZeqFT0C(); + multiplicity = collision.centFT0C(); if (!cfgMultFT0) - multiplicity = collision.centFT0M(); + multiplicity = collision.numContrib(); histos.fill(HIST("hCentrality"), multiplicity); histos.fill(HIST("hNcontributor"), collision.numContrib()); histos.fill(HIST("hVtxZ"), collision.posZ()); @@ -254,6 +274,9 @@ struct phianalysisrun3 { if (track2ID <= track1ID) { continue; } + if (!selectionPair(track1, track2)) { + continue; + } bool unlike = true; bool mix = false; bool likesign = true; @@ -285,9 +308,9 @@ struct phianalysisrun3 { float multiplicity; if (cfgMultFT0) - multiplicity = c1.multZeqFT0A() + c1.multZeqFT0C(); + multiplicity = c1.centFT0C(); if (!cfgMultFT0) - multiplicity = c1.centFT0M(); + multiplicity = c1.numContrib(); for (auto& [t1, t2] : o2::soa::combinations(o2::soa::CombinationsFullIndexPolicy(tracks1, tracks2))) { bool unlike = false; @@ -300,6 +323,9 @@ struct phianalysisrun3 { if (!selectionTrack(t2)) { continue; } + if (!selectionPair(t1, t2)) { + continue; + } if (isITSOnlycut) { FillinvMass(t1, t2, multiplicity, unlike, mix, likesign, rotation, massKa, massKa); } @@ -311,38 +337,64 @@ struct phianalysisrun3 { } PROCESS_SWITCH(phianalysisrun3, processMixedEvent, "Process Mixed event", false); - void processGen(aod::McCollision const& mcCollision, aod::McParticles& mcParticles) + void processGen(aod::McCollision const& mcCollision, aod::McParticles& mcParticles, const soa::SmallGroups& collisions) { + histos.fill(HIST("hMC"), 0.5); if (std::abs(mcCollision.posZ()) < cfgCutVertex) { - histos.fill(HIST("hMC"), 0.5); - for (auto& mcParticle : mcParticles) { - - if (std::abs(mcParticle.y()) > 0.5) { - continue; - } - if (mcParticle.pdgCode() != 333) { - continue; + histos.fill(HIST("hMC"), 1.5); + } + int Nchinel = 0; + for (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; } - auto kDaughters = mcParticle.daughters_as(); - if (kDaughters.size() != 2) { + } + } + if (Nchinel > 0 && std::abs(mcCollision.posZ()) < cfgCutVertex) + histos.fill(HIST("hMC"), 2.5); + std::vector SelectedEvents(collisions.size()); + int nevts = 0; + for (const auto& collision : collisions) { + if (!collision.sel8() || std::abs(collision.mcCollision().posZ()) > cfgCutVertex) { + continue; + } + SelectedEvents[nevts++] = collision.mcCollision_as().globalIndex(); + } + SelectedEvents.resize(nevts); + const auto evtReconstructedAndSelected = std::find(SelectedEvents.begin(), SelectedEvents.end(), mcCollision.globalIndex()) != SelectedEvents.end(); + + if (!evtReconstructedAndSelected) { // Check that the event is reconstructed and that the reconstructed events pass the selection + return; + } + histos.fill(HIST("hMC"), 3.5); + for (auto& mcParticle : mcParticles) { + if (std::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; } - auto daughtp = false; - auto daughtm = false; - for (auto kCurrentDaughter : kDaughters) { - if (!kCurrentDaughter.isPhysicalPrimary()) { - continue; - } - if (kCurrentDaughter.pdgCode() == +321) { - daughtp = true; - } else if (kCurrentDaughter.pdgCode() == -321) { - daughtm = true; - } - } - if (daughtp && daughtm) { - histos.fill(HIST("h1PhiGen"), mcParticle.pt()); + if (kCurrentDaughter.pdgCode() == +321) { + daughtp = true; + } else if (kCurrentDaughter.pdgCode() == -321) { + daughtm = true; } } + if (daughtp && daughtm) { + histos.fill(HIST("h1PhiGen"), mcParticle.pt()); + } } } @@ -355,7 +407,7 @@ struct phianalysisrun3 { if (std::abs(collision.mcCollision().posZ()) > cfgCutVertex || !collision.sel8()) { return; } - histos.fill(HIST("hMC"), 1.5); + histos.fill(HIST("hMC"), 4.5); for (auto track1 : tracks) { if (!selectionTrack(track1)) { continue; @@ -375,6 +427,9 @@ struct phianalysisrun3 { if (track2ID <= track1ID) { continue; } + if (!selectionPair(track1, track2)) { + continue; + } if (track1.sign() * track2.sign() > 0) { continue; } diff --git a/PWGLF/Tasks/rhoanalysis.cxx b/PWGLF/Tasks/Resonances/rhoanalysis.cxx similarity index 100% rename from PWGLF/Tasks/rhoanalysis.cxx rename to PWGLF/Tasks/Resonances/rhoanalysis.cxx diff --git a/PWGLF/Tasks/rsnanalysis.cxx b/PWGLF/Tasks/Resonances/rsnanalysis.cxx similarity index 99% rename from PWGLF/Tasks/rsnanalysis.cxx rename to PWGLF/Tasks/Resonances/rsnanalysis.cxx index c121d5bfe78..c09b1c4aa3e 100644 --- a/PWGLF/Tasks/rsnanalysis.cxx +++ b/PWGLF/Tasks/Resonances/rsnanalysis.cxx @@ -829,8 +829,8 @@ struct rsn_analysis { return false; // // Custom Selection - //if ( fabs(kCurrentTrack.eta()) > kTrackEta ) return false; - //if ( fabs(kCurrentTrack.pt()) > kTrackPT ) return false; + // if ( fabs(kCurrentTrack.eta()) > kTrackEta ) return false; + // if ( fabs(kCurrentTrack.pt()) > kTrackPT ) return false; // // QA Plots // --- General diff --git a/PWGLF/Tasks/Strangeness/CMakeLists.txt b/PWGLF/Tasks/Strangeness/CMakeLists.txt new file mode 100644 index 00000000000..3458c3dfb81 --- /dev/null +++ b/PWGLF/Tasks/Strangeness/CMakeLists.txt @@ -0,0 +1,80 @@ +# 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(hyperon-reco-test + SOURCES hyperon-reco-test.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(derivedlambdakzeroanalysis + SOURCES derivedlambdakzeroanalysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(lambdakzeroanalysis-mc + SOURCES lambdakzeroanalysisMC.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(cascadeanalysis + SOURCES cascadeanalysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(cascadeanalysismc + SOURCES cascadeanalysisMC.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(v0postprocessing + SOURCES v0postprocessing.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(cascadecorrelations + SOURCES cascadecorrelations.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(non-prompt-cascade + SOURCES nonPromptCascade.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::ReconstructionDataFormats O2Physics::AnalysisCore O2::DetectorsBase + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(kinkanalysis + SOURCES kinkAnalysis.cxx + PUBLIC_LINK_LIBRARIES O2::DCAFitter O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(k0mixedevents + SOURCES k0_mixed_events.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(vzero-cascade-absorption + SOURCES vzero_cascade_absorption.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(derivedcascadeanalysis + SOURCES derivedcascadeanalysis.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(cascpostprocessing + SOURCES cascpostprocessing.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(hstrangecorrelation + SOURCES hStrangeCorrelation.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsBase O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGLF/Tasks/cascadeanalysis.cxx b/PWGLF/Tasks/Strangeness/cascadeanalysis.cxx similarity index 100% rename from PWGLF/Tasks/cascadeanalysis.cxx rename to PWGLF/Tasks/Strangeness/cascadeanalysis.cxx diff --git a/PWGLF/Tasks/cascadeanalysisMC.cxx b/PWGLF/Tasks/Strangeness/cascadeanalysisMC.cxx similarity index 100% rename from PWGLF/Tasks/cascadeanalysisMC.cxx rename to PWGLF/Tasks/Strangeness/cascadeanalysisMC.cxx diff --git a/PWGLF/Tasks/cascadecorrelations.cxx b/PWGLF/Tasks/Strangeness/cascadecorrelations.cxx similarity index 66% rename from PWGLF/Tasks/cascadecorrelations.cxx rename to PWGLF/Tasks/Strangeness/cascadecorrelations.cxx index 86fa65a796c..60549ed50b9 100644 --- a/PWGLF/Tasks/cascadecorrelations.cxx +++ b/PWGLF/Tasks/Strangeness/cascadecorrelations.cxx @@ -54,7 +54,7 @@ using FullTracksExtWithPID = soa::Join; // Add a column to the cascdataext table: IsSelected. -// 0 = not selected, 1 = Xi, 2 = Omega, 3 = both +// 0 = not selected, 1 = Xi, 2 = both, 3 = Omega namespace o2::aod { namespace cascadeflags @@ -75,44 +75,119 @@ struct cascadeSelector { Configurable tpcNsigmaPion{"tpcNsigmaPion", 3, "TPC NSigma pion <- lambda"}; Configurable minTPCCrossedRows{"minTPCCrossedRows", 80, "min N TPC crossed rows"}; // TODO: finetune! 80 > 159/2, so no split tracks? Configurable minITSClusters{"minITSClusters", 4, "minimum number of ITS clusters"}; - // Configurable doTPConly{"doTPConly", false, "use TPC-only tracks"}; // TODO: maybe do this for high pT only? as cascade decays after IB // Selection criteria - compatible with core wagon autodetect - copied from cascadeanalysis.cxx //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* - Configurable v0setting_cospa{"v0setting_cospa", 0.95, "v0setting_cospa"}; + Configurable v0setting_cospa{"v0setting_cospa", 0.995, "v0setting_cospa"}; Configurable v0setting_dcav0dau{"v0setting_dcav0dau", 1.0, "v0setting_dcav0dau"}; Configurable v0setting_dcapostopv{"v0setting_dcapostopv", 0.1, "v0setting_dcapostopv"}; Configurable v0setting_dcanegtopv{"v0setting_dcanegtopv", 0.1, "v0setting_dcanegtopv"}; Configurable v0setting_radius{"v0setting_radius", 0.9, "v0setting_radius"}; Configurable cascadesetting_cospa{"cascadesetting_cospa", 0.95, "cascadesetting_cospa"}; Configurable cascadesetting_dcacascdau{"cascadesetting_dcacascdau", 1.0, "cascadesetting_dcacascdau"}; - Configurable cascadesetting_dcabachtopv{"cascadesetting_dcabachtopv", 0.1, "cascadesetting_dcabachtopv"}; - Configurable cascadesetting_cascradius{"cascadesetting_cascradius", 0.5, "cascadesetting_cascradius"}; + Configurable cascadesetting_dcabachtopv{"cascadesetting_dcabachtopv", 0.05, "cascadesetting_dcabachtopv"}; + Configurable cascadesetting_cascradius{"cascadesetting_cascradius", 0.9, "cascadesetting_cascradius"}; Configurable cascadesetting_v0masswindow{"cascadesetting_v0masswindow", 0.01, "cascadesetting_v0masswindow"}; Configurable cascadesetting_mindcav0topv{"cascadesetting_mindcav0topv", 0.01, "cascadesetting_mindcav0topv"}; //*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+*+-+* + // TODO: variables as function of Omega mass, only do Xi for now + AxisSpec vertexAxis = {100, -10.0f, 10.0f, "cm"}; + AxisSpec dcaAxis = {50, 0.0f, 5.0f, "cm"}; + AxisSpec invMassAxis = {100, 1.25f, 1.45f, "Inv. Mass (GeV/c^{2})"}; + AxisSpec ptAxis = {100, 0, 15, "#it{p}_{T}"}; + HistogramRegistry registry{ + "registry", + { + // basic selection variables + {"hV0Radius", "hV0Radius", {HistType::kTH3F, {{100, 0.0f, 100.0f, "cm"}, invMassAxis, ptAxis}}}, + {"hCascRadius", "hCascRadius", {HistType::kTH3F, {{100, 0.0f, 100.0f, "cm"}, invMassAxis, ptAxis}}}, + {"hV0CosPA", "hV0CosPA", {HistType::kTH3F, {{100, 0.95f, 1.0f}, invMassAxis, ptAxis}}}, + {"hCascCosPA", "hCascCosPA", {HistType::kTH3F, {{100, 0.95f, 1.0f}, invMassAxis, ptAxis}}}, + {"hDCAPosToPV", "hDCAPosToPV", {HistType::kTH3F, {vertexAxis, invMassAxis, ptAxis}}}, + {"hDCANegToPV", "hDCANegToPV", {HistType::kTH3F, {vertexAxis, invMassAxis, ptAxis}}}, + {"hDCABachToPV", "hDCABachToPV", {HistType::kTH3F, {vertexAxis, invMassAxis, ptAxis}}}, + {"hDCAV0ToPV", "hDCAV0ToPV", {HistType::kTH3F, {vertexAxis, invMassAxis, ptAxis}}}, + {"hDCAV0Dau", "hDCAV0Dau", {HistType::kTH3F, {dcaAxis, invMassAxis, ptAxis}}}, + {"hDCACascDau", "hDCACascDau", {HistType::kTH3F, {dcaAxis, invMassAxis, ptAxis}}}, + {"hLambdaMass", "hLambdaMass", {HistType::kTH3F, {{100, 1.0f, 1.2f, "Inv. Mass (GeV/c^{2})"}, invMassAxis, ptAxis}}}, + + // invariant mass per cut, start with Xi + {"hMassXi0", "Xi inv mass before selections", {HistType::kTH2F, {invMassAxis, ptAxis}}}, + {"hMassXi1", "Xi inv mass after TPCnCrossedRows cut", {HistType::kTH2F, {invMassAxis, ptAxis}}}, + {"hMassXi2", "Xi inv mass after ITSnClusters cut", {HistType::kTH2F, {invMassAxis, ptAxis}}}, + {"hMassXi3", "Xi inv mass after topo cuts", {HistType::kTH2F, {invMassAxis, ptAxis}}}, + {"hMassXi4", "Xi inv mass after V0 daughters PID cut", {HistType::kTH2F, {invMassAxis, ptAxis}}}, + {"hMassXi5", "Xi inv mass after bachelor PID cut", {HistType::kTH2F, {invMassAxis, ptAxis}}}, + + // ITS & TPC clusters, with Xi inv mass + {"hTPCnCrossedRowsPos", "hTPCnCrossedRowsPos", {HistType::kTH3F, {{160, -0.5, 159.5, "TPC crossed rows"}, invMassAxis, ptAxis}}}, + {"hTPCnCrossedRowsNeg", "hTPCnCrossedRowsNeg", {HistType::kTH3F, {{160, -0.5, 159.5, "TPC crossed rows"}, invMassAxis, ptAxis}}}, + {"hTPCnCrossedRowsBach", "hTPCnCrossedRowsBach", {HistType::kTH3F, {{160, -0.5, 159.5, "TPC crossed rows"}, invMassAxis, ptAxis}}}, + {"hITSnClustersPos", "hITSnClustersPos", {HistType::kTH3F, {{8, -0.5, 7.5, "number of ITS clusters"}, invMassAxis, ptAxis}}}, + {"hITSnClustersNeg", "hITSnClustersNeg", {HistType::kTH3F, {{8, -0.5, 7.5, "number of ITS clusters"}, invMassAxis, ptAxis}}}, + {"hITSnClustersBach", "hITSnClustersBach", {HistType::kTH3F, {{8, -0.5, 7.5, "number of ITS clusters"}, invMassAxis, ptAxis}}}, + }, + }; + + // Keep track of which selections the candidates pass + void init(InitContext const&) + { + auto h = registry.add("hSelectionStatus", "hSelectionStatus", HistType::kTH1I, {{10, 0, 10, "status"}}); + h->GetXaxis()->SetBinLabel(1, "All"); + h->GetXaxis()->SetBinLabel(2, "nTPC OK"); + h->GetXaxis()->SetBinLabel(3, "nITS OK"); + h->GetXaxis()->SetBinLabel(4, "Topo OK"); + h->GetXaxis()->SetBinLabel(5, "V0 PID OK"); + h->GetXaxis()->SetBinLabel(6, "Bach PID OK"); + } void process(soa::Join::iterator const& collision, aod::CascDataExt const& Cascades, FullTracksExtIUWithPID const&) { for (auto& casc : Cascades) { - // TODO: make QA histo with info on where cascades fail selections - // Let's try to do some PID & track quality cuts // these are the tracks: auto bachTrack = casc.bachelor_as(); auto posTrack = casc.posTrack_as(); auto negTrack = casc.negTrack_as(); + // topo variables before cuts: + registry.fill(HIST("hV0Radius"), casc.v0radius(), casc.mXi(), casc.pt()); + registry.fill(HIST("hCascRadius"), casc.cascradius(), casc.mXi(), casc.pt()); + registry.fill(HIST("hV0CosPA"), casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()), casc.mXi(), casc.pt()); + registry.fill(HIST("hCascCosPA"), casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()), casc.mXi(), casc.pt()); + registry.fill(HIST("hDCAPosToPV"), casc.dcapostopv(), casc.mXi(), casc.pt()); + registry.fill(HIST("hDCANegToPV"), casc.dcanegtopv(), casc.mXi(), casc.pt()); + registry.fill(HIST("hDCABachToPV"), casc.dcabachtopv(), casc.mXi(), casc.pt()); + registry.fill(HIST("hDCAV0ToPV"), casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ()), casc.mXi(), casc.pt()); + registry.fill(HIST("hDCAV0Dau"), casc.dcaV0daughters(), casc.mXi(), casc.pt()); + registry.fill(HIST("hDCACascDau"), casc.dcacascdaughters(), casc.mXi(), casc.pt()); + registry.fill(HIST("hLambdaMass"), casc.mLambda(), casc.mXi(), casc.pt()); + + registry.fill(HIST("hITSnClustersPos"), posTrack.itsNCls(), casc.mXi(), casc.pt()); + registry.fill(HIST("hITSnClustersNeg"), negTrack.itsNCls(), casc.mXi(), casc.pt()); + registry.fill(HIST("hITSnClustersBach"), bachTrack.itsNCls(), casc.mXi(), casc.pt()); + registry.fill(HIST("hTPCnCrossedRowsPos"), posTrack.tpcNClsCrossedRows(), casc.mXi(), casc.pt()); + registry.fill(HIST("hTPCnCrossedRowsNeg"), negTrack.tpcNClsCrossedRows(), casc.mXi(), casc.pt()); + registry.fill(HIST("hTPCnCrossedRowsBach"), bachTrack.tpcNClsCrossedRows(), casc.mXi(), casc.pt()); + + registry.fill(HIST("hSelectionStatus"), 0); // all the cascade before selections + registry.fill(HIST("hMassXi0"), casc.mXi(), casc.pt()); + // TPC N crossed rows if (posTrack.tpcNClsCrossedRows() < minTPCCrossedRows || negTrack.tpcNClsCrossedRows() < minTPCCrossedRows || bachTrack.tpcNClsCrossedRows() < minTPCCrossedRows) { cascflags(0); continue; } + registry.fill(HIST("hSelectionStatus"), 1); // passes nTPC crossed rows + registry.fill(HIST("hMassXi1"), casc.mXi(), casc.pt()); + // ITS N clusters if (posTrack.itsNCls() < minITSClusters || negTrack.itsNCls() < minITSClusters || bachTrack.itsNCls() < minITSClusters) { cascflags(0); continue; } + registry.fill(HIST("hSelectionStatus"), 2); // passes nITS clusters + registry.fill(HIST("hMassXi2"), casc.mXi(), casc.pt()); //// TOPO CUTS //// TODO: improve! double pvx = collision.posX(); @@ -128,10 +203,12 @@ struct cascadeSelector { cascflags(0); continue; } + registry.fill(HIST("hSelectionStatus"), 3); // passes topo + registry.fill(HIST("hMassXi3"), casc.mXi(), casc.pt()); // TODO: TOF (for pT > 2 GeV per track?) - //// TPC //// + //// TPC PID //// // Lambda check if (casc.sign() < 0) { // Proton check: @@ -156,17 +233,25 @@ struct cascadeSelector { continue; } } + registry.fill(HIST("hSelectionStatus"), 4); // fails at 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! - cascflags(3); + cascflags(2); + registry.fill(HIST("hSelectionStatus"), 5); // passes bach PID + registry.fill(HIST("hMassXi5"), casc.mXi(), casc.pt()); continue; } cascflags(1); + registry.fill(HIST("hSelectionStatus"), 5); // passes bach PID + registry.fill(HIST("hMassXi5"), casc.mXi(), casc.pt()); continue; } else if (TMath::Abs(bachTrack.tpcNSigmaKa()) < tpcNsigmaBachelor) { - cascflags(2); + cascflags(3); + registry.fill(HIST("hSelectionStatus"), 5); // passes bach PID continue; } // if we reach here, the bachelor was neither pion nor kaon @@ -176,12 +261,12 @@ struct cascadeSelector { }; // struct struct cascadeCorrelations { - AxisSpec invMassAxis = {3000, 0.0f, 3.0f, "Inv. Mass (GeV/c^{2})"}; + AxisSpec invMassAxis = {2000, 1.0f, 3.0f, "Inv. Mass (GeV/c^{2})"}; AxisSpec deltaPhiAxis = {100, -PI / 2, 1.5 * PI, "#Delta#varphi"}; AxisSpec deltaEtaAxis = {40, -2, 2, "#Delta#eta"}; AxisSpec ptAxis = {200, 0, 15, "#it{p}_{T}"}; AxisSpec selectionFlagAxis = {4, -0.5f, 3.5f, "Selection flag of casc candidate"}; - AxisSpec vertexAxis = {1000, -10.0f, 10.0f, "cm"}; + AxisSpec vertexAxis = {200, -10.0f, 10.0f, "cm"}; AxisSpec multiplicityAxis{100, 0, 100, "Multiplicity (MultFT0M?)"}; HistogramRegistry registry{ @@ -196,18 +281,19 @@ struct cascadeCorrelations { // basic selection variables {"hV0Radius", "hV0Radius", {HistType::kTH1F, {{1000, 0.0f, 100.0f, "cm"}}}}, {"hCascRadius", "hCascRadius", {HistType::kTH1F, {{1000, 0.0f, 100.0f, "cm"}}}}, - {"hV0CosPA", "hV0CosPA", {HistType::kTH1F, {{1000, 0.95f, 1.0f}}}}, - {"hCascCosPA", "hCascCosPA", {HistType::kTH1F, {{1000, 0.95f, 1.0f}}}}, + {"hV0CosPA", "hV0CosPA", {HistType::kTH1F, {{100, 0.95f, 1.0f}}}}, + {"hCascCosPA", "hCascCosPA", {HistType::kTH1F, {{100, 0.95f, 1.0f}}}}, {"hDCAPosToPV", "hDCAPosToPV", {HistType::kTH1F, {vertexAxis}}}, {"hDCANegToPV", "hDCANegToPV", {HistType::kTH1F, {vertexAxis}}}, {"hDCABachToPV", "hDCABachToPV", {HistType::kTH1F, {vertexAxis}}}, {"hDCAV0ToPV", "hDCAV0ToPV", {HistType::kTH1F, {vertexAxis}}}, - {"hDCAV0Dau", "hDCAV0Dau", {HistType::kTH1F, {{1000, 0.0f, 10.0f, "cm^{2}"}}}}, - {"hDCACascDau", "hDCACascDau", {HistType::kTH1F, {{1000, 0.0f, 10.0f, "cm^{2}"}}}}, - {"hLambdaMass", "hLambdaMass", {HistType::kTH1F, {{1000, 0.0f, 10.0f, "Inv. Mass (GeV/c^{2})"}}}}, + {"hDCAV0Dau", "hDCAV0Dau", {HistType::kTH1F, {{100, 0.0f, 10.0f, "cm^{2}"}}}}, + {"hDCACascDau", "hDCACascDau", {HistType::kTH1F, {{100, 0.0f, 10.0f, "cm^{2}"}}}}, + {"hLambdaMass", "hLambdaMass", {HistType::kTH1F, {{500, 1.0f, 1.5f, "Inv. Mass (GeV/c^{2})"}}}}, {"hSelectionFlag", "hSelectionFlag", {HistType::kTH1I, {selectionFlagAxis}}}, - {"hAutoCorrelation", "hAutoCorrelation", {HistType::kTH1I, {{4, -0.5f, 3.5f, "Types of autocorrelation"}}}}, + {"hAutoCorrelation", "hAutoCorrelation", {HistType::kTH1I, {{4, -0.5f, 3.5f, "Types of SS autocorrelation"}}}}, + {"hAutoCorrelationOS", "hAutoCorrelationOS", {HistType::kTH1I, {{2, -1.f, 1.f, "Charge of OS autocorrelated track"}}}}, {"hPhi", "hPhi", {HistType::kTH1F, {{100, 0, 2 * PI, "#varphi"}}}}, {"hEta", "hEta", {HistType::kTH1F, {{100, -2, 2, "#eta"}}}}, @@ -237,7 +323,7 @@ struct cascadeCorrelations { // Some QA on the cascades for (auto& casc : Cascades) { - if (casc.isSelected() != 2) { // not exclusively an Omega --> consistent with Xi or both + if (casc.isSelected() <= 2) { // not exclusively an Omega --> consistent with Xi or both if (casc.sign() < 0) { registry.fill(HIST("hMassXiMinus"), casc.mXi(), casc.pt()); } else { @@ -296,13 +382,39 @@ struct cascadeCorrelations { // Fill the correct histograms based on same-sign or opposite-sign if (trigger.sign() * assoc.sign() < 0) { // opposite-sign + // check for autocorrelations between mis-identified kaons (omega bach) and protons (lambda daughter) TODO: improve logic? + if (trigger.isSelected() >= 2) { + if (trigger.sign() > 0 && trigger.bachelorId() == posIdAssoc) { + // K+ from trigger Omega is the same as proton from assoc lambda + registry.fill(HIST("hAutoCorrelationOS"), 1); + continue; + } + if (trigger.sign() < 0 && trigger.bachelorId() == negIdAssoc) { + // K- from trigger Omega is the same as antiproton from assoc antilambda + registry.fill(HIST("hAutoCorrelationOS"), -1); + continue; + } + } + if (assoc.isSelected() >= 2) { + if (assoc.sign() > 0 && assoc.bachelorId() == posIdTrigg) { + // K+ from assoc Omega is the same as proton from trigger lambda + registry.fill(HIST("hAutoCorrelationOS"), 1); + continue; + } + if (assoc.sign() < 0 && assoc.bachelorId() == negIdTrigg) { + // K- from assoc Omega is the same as antiproton from trigger antilambda + registry.fill(HIST("hAutoCorrelationOS"), -1); + continue; + } + } + registry.fill(HIST("hDeltaPhiOS"), dphi); registry.fill(HIST("hXiXiOS"), dphi, deta, trigger.pt(), assoc.pt(), invMassXiTrigg, invMassXiAssoc, trigger.isSelected(), assoc.isSelected(), collision.posZ(), collision.multFT0M()); registry.fill(HIST("hXiOmOS"), dphi, deta, trigger.pt(), assoc.pt(), invMassXiTrigg, invMassOmAssoc, trigger.isSelected(), assoc.isSelected(), collision.posZ(), collision.multFT0M()); registry.fill(HIST("hOmXiOS"), dphi, deta, trigger.pt(), assoc.pt(), invMassOmTrigg, invMassXiAssoc, trigger.isSelected(), assoc.isSelected(), collision.posZ(), collision.multFT0M()); registry.fill(HIST("hOmOmOS"), dphi, deta, trigger.pt(), assoc.pt(), invMassOmTrigg, invMassOmAssoc, trigger.isSelected(), assoc.isSelected(), collision.posZ(), collision.multFT0M()); } else { // same-sign - // make sure to check for autocorrelations - only possible in same-sign correlations + // make sure to check for autocorrelations - only possible in same-sign correlations (if PID is correct) if (posIdTrigg == posIdAssoc && negIdTrigg == negIdAssoc) { // LOGF(info, "same v0 in SS correlation! %d %d", v0dataTrigg.v0Id(), v0dataAssoc.v0Id()); registry.fill(HIST("hAutoCorrelation"), 0); diff --git a/PWGLF/Tasks/cascpostprocessing.cxx b/PWGLF/Tasks/Strangeness/cascpostprocessing.cxx similarity index 100% rename from PWGLF/Tasks/cascpostprocessing.cxx rename to PWGLF/Tasks/Strangeness/cascpostprocessing.cxx diff --git a/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx b/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx new file mode 100644 index 00000000000..b3322a9bce3 --- /dev/null +++ b/PWGLF/Tasks/Strangeness/derivedcascadeanalysis.cxx @@ -0,0 +1,821 @@ +// 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. +// +/// \ post processing for Cascade analysis runing on derived data +/// \author Lucia Anna Tarasovicova (lucia.anna.husova@cern.ch) + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/O2DatabasePDGPlugin.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 "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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Framework/ASoAHelpers.h" + +// constants +const float ctauxiPDG = 4.91; // from PDG +const float ctauomegaPDG = 2.461; // from PDG + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using std::array; + +struct derivedCascadeAnalysis { + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + Configurable zVertexCut{"zVertexCut", 10, "Cut on PV position"}; + + ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for QA histograms"}; + + ConfigurableAxis vertexZ{"vertexZ", {30, -15.0f, 15.0f}, ""}; + ConfigurableAxis axisXiMass{"axisXiMass", {200, 1.222f, 1.422f}, ""}; + ConfigurableAxis axisOmegaMass{"axisOmegaMass", {200, 1.572f, 1.772f}, ""}; + + Configurable isXi{"isXi", 1, "Apply cuts for Xi identification"}; + Configurable isMC{"isMC", false, "MC data are processed"}; + Configurable doPtDepCutStudy{"doPtDepCutStudy", false, "Fill histogram with a cutting paramer"}; + + Configurable minPt{"minPt", 0.0f, "minPt"}; + Configurable masswin{"masswin", 0.05, "Mass window limit"}; + Configurable lambdaMassWin{"lambdaMassWin", 0.005, "V0 Mass window limit"}; + Configurable rapCut{"rapCut", 0.5, "Rapidity acceptance"}; + Configurable etaDauCut{"etaDauCut", 0.8, "Pseudorapidity acceptance of the cascade daughters"}; + Configurable dcaBaryonToPV{"dcaBaryonToPV", 0.05, "DCA of baryon doughter track To PV"}; + Configurable dcaMesonToPV{"dcaMesonToPV", 0.1, "DCA of meson doughter track To PV"}; + Configurable dcaBachToPV{"dcaBachToPV", 0.04, "DCA Bach To PV"}; + Configurable casccospa{"casccospa", 0.97, "Casc CosPA"}; + Configurable v0cospa{"v0cospa", 0.97, "V0 CosPA"}; + Configurable dcacascdau{"dcacascdau", 1., "DCA Casc Daughters"}; + Configurable dcav0dau{"dcav0dau", 1.5, "DCA V0 Daughters"}; + Configurable dcaV0ToPV{"dcaV0ToPV", 0.06, "DCA V0 To PV"}; + Configurable minRadius{"minRadius", 1.4f, "minRadius"}; + Configurable maxRadius{"maxRadius", 100.0f, "maxRadius"}; + Configurable minV0Radius{"minV0Radius", 1.2f, "V0 transverse decay radius, minimum"}; + Configurable maxV0Radius{"maxV0Radius", 100.0f, "V0 transverse decay radius, maximum"}; + Configurable nsigmatpcPi{"nsigmatpcPi", 5, "N sigma TPC Pion"}; + Configurable nsigmatpcPr{"nsigmatpcPr", 5, "N sigma TPC Proton"}; + Configurable nsigmatpcKa{"nsigmatpcKa", 5, "N sigma TPC Kaon"}; + Configurable bachBaryonCosPA{"bachBaryonCosPA", 0.9999, "Bachelor baryon CosPA"}; + Configurable bachBaryonDCAxyToPV{"bachBaryonDCAxyToPV", 0.05, "DCA bachelor baryon to PV"}; + Configurable mintpccrrows{"mintpccrrows", 50, "min N TPC crossed rows"}; + Configurable dooobrej{"dooobrej", 0, "OOB rejection: 0 no selection, 1 = ITS||TOF, 2 = TOF only for pT > ptthrtof"}; + Configurable ptthrtof{"ptthrtof", 2, "Pt threshold for applying only tof oob rejection"}; + Configurable proplifetime{"proplifetime", 3, "ctau/"}; + Configurable rejcomp{"rejcomp", 0.008, "Competing Cascade rejection"}; + + Configurable doPtDepCosPaCut{"doPtDepCosPaCut", false, "Enable pt dependent cos PA cut"}; + Configurable doPtDepCascRadiusCut{"doPtDepCascRadiusCut", false, "Enable pt dependent cascade radius cut"}; + Configurable doPtDepV0CosPaCut{"doPtDepV0CosPaCut", false, "Enable pt dependent cos PA cut of the V0 daughter"}; + Configurable doPtDepDCAcascDauCut{"doPtDepDCAcascDauCut", false, "Enable pt dependent DCA cascade daughter cut"}; + Configurable doDCAdauToPVCut{"doDCAdauToPVCut", true, "Enable cut DCA daughter track to PV"}; + Configurable doCascadeCosPaCut{"doCascadeCosPaCut", true, "Enable cos PA cut"}; + Configurable doV0CosPaCut{"doV0CosPaCut", true, "Enable cos PA cut for the V0 daughter"}; + Configurable doDCACascadeDauCut{"doDCACascadeDauCut", true, "Enable cut DCA betweenn daughter tracks"}; + Configurable doDCAV0DauCut{"doDCAV0DauCut", true, "Enable cut DCA betweenn V0 daughter tracks"}; + Configurable doCascadeRadiusCut{"doCascadeRadiusCut", true, "Enable cut on the cascade radius"}; + Configurable doV0RadiusCut{"doV0RadiusCut", true, "Enable cut on the V0 radius"}; + Configurable doDCAV0ToPVCut{"doDCAV0ToPVCut", true, "Enable cut DCA of V0 to PV"}; + Configurable doNTPCSigmaCut{"doNTPCSigmaCut", false, "Enable cut N sigma TPC"}; + Configurable doBachelorBaryonCut{"doBachelorBaryonCut", true, "Enable Bachelor-Baryon cut "}; + Configurable doProperLifeTimeCut{"doProperLifeTimeCut", true, "Enable proper life-time cut "}; + + Configurable cosPApar0{"cosPApar0", 0.247403, "const par for pt dep cosPA cut"}; + Configurable cosPApar1{"cosPApar1", -0.068957, "linear par for pt dep cosPA cut"}; + Configurable cosPApar2{"cosPApar2", 0.004934, "quadratic par for pt dep cosPA cut"}; + + Configurable cosPAV0par0{"cosPAV0par0", 0.246642, "const par for pt dep V0cosPA cut"}; + Configurable cosPAV0par1{"cosPAV0par1", -0.056284, "linear par for pt dep V0cosPA cut"}; + Configurable cosPAV0par2{"cosPAV0par2", 0.00339345, "quadratic par for pt dep V0cosPA cut"}; + + Configurable parCascRadius0{"parCascRadius0", 1.216159, "const par for pt dep radius cut"}; + Configurable parCascRadius1{"parCascRadius1", 0.064462, "linear par for pt dep radius cut"}; + + Configurable dcaCacsDauPar{"dcaCacsDauPar", 0.404424, " par for pt dep DCA cascade daughter cut"}; + + Service pdgDB; + + void init(InitContext const&) + { + histos.add("hEventVertexZ", "hEventVertexZ", kTH1F, {vertexZ}); + histos.add("hEventCentrality", "hEventCentrality", kTH1F, {{101, 0, 101}}); + histos.add("hEventSelection", "hEventSelection", kTH1F, {{4, 0, 4}}); + + histos.add("hCandidate", "hCandidate", HistType::kTH1D, {{22, -0.5, 21.5}}); + + TString CutLabel[22] = {"All", "MassWin", "y", "DCACascDau", "DCAV0Dau", "rCasc", "rCascMax", "rV0", "rV0Max", "LambdaMass", "Bach-baryon", "V0CosPA", "CompDecayMass", "DCADauToPV", "EtaDau", "CascCosPA", "DCAV0ToPV", "nSigmaTPCV0Dau", "NTPCrows", "OOBRej", "nSigmaTPCbachelor", "ctau"}; + for (Int_t i = 1; i <= histos.get(HIST("hCandidate"))->GetNbinsX(); i++) { + histos.get(HIST("hCandidate"))->GetXaxis()->SetBinLabel(i, CutLabel[i - 1]); + } + + histos.add("InvMassBefSel/hNegativeCascade", "hNegativeCascade", HistType::kTH3F, {axisPt, axisXiMass, {101, 0, 101}}); + histos.add("InvMassBefSel/hPositiveCascade", "hPositiveCascade", {HistType::kTH3F, {axisPt, axisXiMass, {101, 0, 101}}}); + + if (!isXi) { + histos.get(HIST("InvMassBefSel/hNegativeCascade"))->GetYaxis()->Set(200, 1.572f, 1.772f); + histos.get(HIST("InvMassBefSel/hPositiveCascade"))->GetYaxis()->Set(200, 1.572f, 1.772f); + } + + histos.addClone("InvMassBefSel/", "InvMassAfterSel/"); + if (isMC) + histos.addClone("InvMassBefSel/", "InvMassAfterSelMCrecTruth/"); + + if (doPtDepCutStudy && !doProperLifeTimeCut) { + histos.add("PtDepCutStudy/hNegativeCascadeProperLifeTime", "hNegativeCascadeProperLifeTime", HistType::kTH3F, {axisPt, axisXiMass, {100, 0, 10}}); + histos.add("PtDepCutStudy/hPositiveCascadeProperLifeTime", "hPositiveCascadeProperLifeTime", {HistType::kTH3F, {axisPt, axisXiMass, {100, 0, 10}}}); + if (!isXi) { + histos.get(HIST("PtDepCutStudy/hNegativeCascadeProperLifeTime"))->GetYaxis()->Set(200, 1.572f, 1.772f); + histos.get(HIST("PtDepCutStudy/hPositiveCascadeProperLifeTime"))->GetYaxis()->Set(200, 1.572f, 1.772f); + } + } + if (doPtDepCutStudy && !doBachelorBaryonCut) { + histos.add("PtDepCutStudy/hNegativeBachelorBaryonDCA", "hNegativeBachelorBaryonDCA", HistType::kTH3F, {axisPt, axisXiMass, {40, 0, 1}}); + histos.add("PtDepCutStudy/hPositiveBachelorBaryonDCA", "hPositiveBachelorBaryonDCA", {HistType::kTH3F, {axisPt, axisXiMass, {40, 0, 1}}}); + if (!isXi) { + histos.get(HIST("PtDepCutStudy/hNegativeBachelorBaryonDCA"))->GetYaxis()->Set(200, 1.572f, 1.772f); + histos.get(HIST("PtDepCutStudy/hPositiveBachelorBaryonDCA"))->GetYaxis()->Set(200, 1.572f, 1.772f); + } + } + if (doPtDepCutStudy && !doDCAV0ToPVCut) { + histos.add("PtDepCutStudy/hNegativeDCAV0ToPV", "hNegativeDCAV0ToPV", HistType::kTH3F, {axisPt, axisXiMass, {40, 0, 1}}); + histos.add("PtDepCutStudy/hPositiveDCAV0ToPV", "hPositiveDCAV0ToPV", {HistType::kTH3F, {axisPt, axisXiMass, {40, 0, 1}}}); + if (!isXi) { + histos.get(HIST("PtDepCutStudy/hNegativeDCAV0ToPV"))->GetYaxis()->Set(200, 1.572f, 1.772f); + histos.get(HIST("PtDepCutStudy/hPositiveDCAV0ToPV"))->GetYaxis()->Set(200, 1.572f, 1.772f); + } + } + if (doPtDepCutStudy && !doV0RadiusCut) { + histos.add("PtDepCutStudy/hNegativeV0Radius", "hNegativeV0Radius", HistType::kTH3F, {axisPt, axisXiMass, {20, 0, 10}}); + histos.add("PtDepCutStudy/hPositiveV0Radius", "hPositiveV0Radius", {HistType::kTH3F, {axisPt, axisXiMass, {20, 0, 10}}}); + if (!isXi) { + histos.get(HIST("PtDepCutStudy/hNegativeV0Radius"))->GetYaxis()->Set(200, 1.572f, 1.772f); + histos.get(HIST("PtDepCutStudy/hPositiveV0Radius"))->GetYaxis()->Set(200, 1.572f, 1.772f); + } + } + if (doPtDepCutStudy && !doCascadeRadiusCut) { + histos.add("PtDepCutStudy/hNegativeCascadeRadius", "hNegativeCascadeRadius", HistType::kTH3F, {axisPt, axisXiMass, {50, 0, 5}}); + histos.add("PtDepCutStudy/hPositiveCascadeRadius", "hPositiveCascadeRadius", {HistType::kTH3F, {axisPt, axisXiMass, {50, 0, 5}}}); + if (!isXi) { + histos.get(HIST("PtDepCutStudy/hNegativeCascadeRadius"))->GetYaxis()->Set(200, 1.572f, 1.772f); + histos.get(HIST("PtDepCutStudy/hPositiveCascadeRadius"))->GetYaxis()->Set(200, 1.572f, 1.772f); + } + } + + if (doPtDepCutStudy && !doDCAV0DauCut) { + histos.add("PtDepCutStudy/hNegativeDCAV0Daughters", "hNegativeDCAV0Daughters", HistType::kTH3F, {axisPt, axisXiMass, {50, 0, 5}}); + histos.add("PtDepCutStudy/hPositiveDCAV0Daughters", "hPositiveDCAV0Daughters", {HistType::kTH3F, {axisPt, axisXiMass, {50, 0, 5}}}); + if (!isXi) { + histos.get(HIST("PtDepCutStudy/hNegativeDCAV0Daughters"))->GetYaxis()->Set(200, 1.572f, 1.772f); + histos.get(HIST("PtDepCutStudy/hPositiveDCAV0Daughters"))->GetYaxis()->Set(200, 1.572f, 1.772f); + } + } + + if (doPtDepCutStudy && !doDCACascadeDauCut) { + histos.add("PtDepCutStudy/hNegativeDCACascDaughters", "hNegativeDCACascDaughters", {HistType::kTH3F, {axisPt, axisXiMass, {20, 0, 1}}}); + histos.add("PtDepCutStudy/hPositiveDCACascDaughters", "hPositiveDCACascDaughters", {HistType::kTH3F, {axisPt, axisXiMass, {20, 0, 1}}}); + if (!isXi) { + histos.get(HIST("PtDepCutStudy/hPositiveDCACascDaughters"))->GetYaxis()->Set(200, 1.572f, 1.772f); + histos.get(HIST("PtDepCutStudy/hNegativeDCACascDaughters"))->GetYaxis()->Set(200, 1.572f, 1.772f); + } + } + + if (doPtDepCutStudy && !doV0CosPaCut) { + histos.add("PtDepCutStudy/hNegativeV0pa", "hNegativeV0pa", HistType::kTH3F, {axisPt, axisXiMass, {40, 0, 0.4}}); + histos.add("PtDepCutStudy/hPositiveV0pa", "hPositiveV0pa", {HistType::kTH3F, {axisPt, axisXiMass, {40, 0, 0.4}}}); + if (!isXi) { + histos.get(HIST("PtDepCutStudy/hNegativeV0pa"))->GetYaxis()->Set(200, 1.572f, 1.772f); + histos.get(HIST("PtDepCutStudy/hPositiveV0pa"))->GetYaxis()->Set(200, 1.572f, 1.772f); + } + } + if (doPtDepCutStudy && !doDCAdauToPVCut) { + histos.add("PtDepCutStudy/hNegativeDCABachelorToPV", "hNegativeDCABachelorToPV", HistType::kTH3F, {axisPt, axisXiMass, {50, 0, 0.5}}); + histos.add("PtDepCutStudy/hNegativeDCABaryonToPV", "hNegativeDCABaryonToPV", HistType::kTH3F, {axisPt, axisXiMass, {50, 0, 0.5}}); + histos.add("PtDepCutStudy/hNegativeDCAMesonToPV", "hNegativeDCAMesonToPV", HistType::kTH3F, {axisPt, axisXiMass, {50, 0, 0.5}}); + histos.add("PtDepCutStudy/hPositiveDCABachelorToPV", "hPositiveDCABachelorToPV", {HistType::kTH3F, {axisPt, axisXiMass, {50, 0, 0.5}}}); + histos.add("PtDepCutStudy/hPositiveDCABaryonToPV", "hPositiveDCABaryonToPV", HistType::kTH3F, {axisPt, axisXiMass, {50, 0, 0.5}}); + histos.add("PtDepCutStudy/hPositiveDCAMesonToPV", "hPositiveDCAMesonToPV", HistType::kTH3F, {axisPt, axisXiMass, {50, 0, 0.5}}); + if (!isXi) { + histos.get(HIST("PtDepCutStudy/hNegativeDCABachelorToPV"))->GetYaxis()->Set(200, 1.572f, 1.772f); + histos.get(HIST("PtDepCutStudy/hNegativeDCABaryonToPV"))->GetYaxis()->Set(200, 1.572f, 1.772f); + histos.get(HIST("PtDepCutStudy/hNegativeDCAMesonToPV"))->GetYaxis()->Set(200, 1.572f, 1.772f); + histos.get(HIST("PtDepCutStudy/hPositiveDCABachelorToPV"))->GetYaxis()->Set(200, 1.572f, 1.772f); + histos.get(HIST("PtDepCutStudy/hPositiveDCABaryonToPV"))->GetYaxis()->Set(200, 1.572f, 1.772f); + histos.get(HIST("PtDepCutStudy/hPositiveDCAMesonToPV"))->GetYaxis()->Set(200, 1.572f, 1.772f); + } + } + + if (doPtDepCutStudy && !doCascadeCosPaCut) { + histos.add("PtDepCutStudy/hNegativeCascPA", "hNegativeCascPA", HistType::kTH3F, {axisPt, axisXiMass, {40, 0, 0.4}}); + histos.add("PtDepCutStudy/hPositiveCascPA", "hPositiveCascPA", {HistType::kTH3F, {axisPt, axisXiMass, {40, 0, 0.4}}}); + if (!isXi) { + histos.get(HIST("PtDepCutStudy/hNegativeCascPA"))->GetYaxis()->Set(200, 1.572f, 1.772f); + histos.get(HIST("PtDepCutStudy/hPositiveCascPA"))->GetYaxis()->Set(200, 1.572f, 1.772f); + } + } + + if (isMC) { + histos.addClone("PtDepCutStudy/", "PtDepCutStudyMCTruth/"); + histos.add("hNegativeCascadePtForEfficiency", "hNegativeCascadePtForEfficiency", HistType::kTH2F, {axisPt, {101, 0, 101}}); + histos.add("hPositiveCascadePtForEfficiency", "hPositiveCascadePtForEfficiency", {HistType::kTH2F, {axisPt, {101, 0, 101}}}); + } + } + template + bool IsCosPAAccepted(TCascade casc, float x, float y, float z, bool ptdepcut, bool isCascPa) + { + + if (ptdepcut) { + double ptdepCut; + if (isCascPa) + ptdepCut = cosPApar0 + cosPApar1 * casc.pt() + cosPApar2 * TMath::Power(casc.pt(), 2); + else + ptdepCut = cosPAV0par0 + cosPAV0par1 * casc.pt() + cosPAV0par2 * TMath::Power(casc.pt(), 2); + if (ptdepCut > 0.3 && casc.pt() < 0.5) + ptdepCut = 0.3; + if (ptdepCut < 0.012 || casc.pt() > 7) + ptdepCut = 0.012; + if (isCascPa && casc.casccosPA(x, y, z) < TMath::Cos(ptdepCut)) + return false; + if (!isCascPa && casc.v0cosPA(x, y, z) < TMath::Cos(ptdepCut)) + return false; + } else if (isCascPa && casc.casccosPA(x, y, z) < casccospa) + return false; + else if (!isCascPa && casc.v0cosPA(x, y, z) < v0cospa) + return false; + + return true; + } + template + bool IsEventAccepted(TCollision coll, bool sel) + { + histos.fill(HIST("hEventSelection"), 0.5 /* all collisions */); + if (!sel) { + return false; + } + histos.fill(HIST("hEventSelection"), 1.5 /* collisions after sel*/); + if (TMath::Abs(coll.posZ()) > zVertexCut) { + return false; + } + histos.fill(HIST("hEventVertexZ"), coll.posZ()); + histos.fill(HIST("hEventSelection"), 2.5 /* collisions after sel pvz sel*/); + + if (coll.centFT0C() > 100) { + return false; + } + histos.fill(HIST("hEventCentrality"), coll.centFT0C()); + histos.fill(HIST("hEventSelection"), 3.5 /* collisions after sel centrality sel*/); + return true; + } + + template + bool IsCascadeCandidateAccepted(TCascade casc, int counter, float centrality) + { + + if (isXi) { + if (TMath::Abs(casc.mXi() - pdgDB->Mass(3312)) > masswin) { + return false; + } + histos.fill(HIST("hCandidate"), ++counter); + if (TMath::Abs(casc.yXi()) > rapCut) + return false; + histos.fill(HIST("hCandidate"), ++counter); + } else { + if (TMath::Abs(casc.mOmega() - pdgDB->Mass(3334)) > masswin) { + return false; + } + histos.fill(HIST("hCandidate"), ++counter); + if (TMath::Abs(casc.yOmega()) > rapCut) + return false; + histos.fill(HIST("hCandidate"), ++counter); + } + + if (doDCACascadeDauCut) { + if (doPtDepDCAcascDauCut) { + float ptDepCut = dcaCacsDauPar / casc.pt(); + if (casc.dcacascdaughters() > ptDepCut) + return false; + } else if (casc.dcacascdaughters() > dcacascdau) + return false; + histos.fill(HIST("hCandidate"), ++counter); + } else + ++counter; + + if (doDCAV0DauCut) { + if (casc.dcaV0daughters() > dcav0dau) + return false; + histos.fill(HIST("hCandidate"), ++counter); + } else + ++counter; + + if (doCascadeRadiusCut) { + if (doPtDepCascRadiusCut) { + double ptdepminRadius = parCascRadius0 + parCascRadius1 * casc.pt(); + if (casc.cascradius() < ptdepminRadius) + return false; + } else if (casc.cascradius() < minRadius) + return false; + histos.fill(HIST("hCandidate"), ++counter); + + if (casc.cascradius() > maxRadius) + return false; + histos.fill(HIST("hCandidate"), ++counter); + } else + counter += 2; + + if (doV0RadiusCut) { + if (casc.v0radius() < minV0Radius) + return false; + histos.fill(HIST("hCandidate"), ++counter); + if (casc.v0radius() > maxV0Radius) + return false; + histos.fill(HIST("hCandidate"), ++counter); + } else + counter += 2; + + if (TMath::Abs(casc.mLambda() - pdgDB->Mass(3122)) > lambdaMassWin) + return false; + histos.fill(HIST("hCandidate"), ++counter); + + if (doBachelorBaryonCut) { + if ((casc.bachBaryonCosPA() > bachBaryonCosPA || TMath::Abs(casc.bachBaryonDCAxyToPV()) < bachBaryonDCAxyToPV)) { // Bach-baryon selection if required + return false; + } + histos.fill(HIST("hCandidate"), ++counter); + } else + ++counter; + + if (doV0CosPaCut) { + if (!IsCosPAAccepted(casc, casc.x(), casc.y(), casc.z(), doPtDepV0CosPaCut, false)) + return false; + histos.fill(HIST("hCandidate"), ++counter); + } else + ++counter; + + if (isXi) { + if (TMath::Abs(casc.mOmega() - pdgDB->Mass(3334)) < rejcomp) + return false; + histos.fill(HIST("hCandidate"), ++counter); + } else { + if (TMath::Abs(casc.mXi() - pdgDB->Mass(3312)) < rejcomp) + return false; + histos.fill(HIST("hCandidate"), ++counter); + } + + if (doDCAdauToPVCut) { + if (TMath::Abs(casc.dcabachtopv()) < dcaBachToPV) + return false; + if (casc.sign() > 0 && (TMath::Abs(casc.dcanegtopv()) < dcaBaryonToPV || TMath::Abs(casc.dcapostopv()) < dcaMesonToPV)) + return false; + if (casc.sign() < 0 && (TMath::Abs(casc.dcapostopv()) < dcaBaryonToPV || TMath::Abs(casc.dcanegtopv()) < dcaMesonToPV)) + return false; + histos.fill(HIST("hCandidate"), ++counter); + } else + ++counter; + + return true; + } + + void processCascades(soa::Join::iterator const& coll, soa::Join const& Cascades, soa::Join const&) + { + + if (!IsEventAccepted(coll, coll.sel8())) + return; + + for (auto& casc : Cascades) { + + int counter = -1; + histos.fill(HIST("hCandidate"), ++counter); + + double invmass; + if (isXi) + invmass = casc.mXi(); + else + invmass = casc.mOmega(); + // To have trace of how it was before selections + if (casc.sign() < 0) { + histos.fill(HIST("InvMassBefSel/hNegativeCascade"), casc.pt(), invmass, coll.centFT0C()); + } + if (casc.sign() > 0) { + histos.fill(HIST("InvMassBefSel/hPositiveCascade"), casc.pt(), invmass, coll.centFT0C()); + } + + if (!IsCascadeCandidateAccepted(casc, counter, coll.centFT0C())) + continue; + counter += 13; + + auto negExtra = casc.negTrackExtra_as>(); + auto posExtra = casc.posTrackExtra_as>(); + auto bachExtra = casc.bachTrackExtra_as>(); + + auto poseta = RecoDecay::eta(std::array{casc.pxpos(), casc.pypos(), casc.pzpos()}); + auto negeta = RecoDecay::eta(std::array{casc.pxneg(), casc.pyneg(), casc.pzneg()}); + auto bacheta = RecoDecay::eta(std::array{casc.pxbach(), casc.pybach(), casc.pzbach()}); + if (TMath::Abs(poseta) > etaDauCut || TMath::Abs(negeta) > etaDauCut || TMath::Abs(bacheta) > etaDauCut) + continue; + histos.fill(HIST("hCandidate"), ++counter); + + if (doCascadeCosPaCut) { + if (!IsCosPAAccepted(casc, coll.posX(), coll.posY(), coll.posZ(), doPtDepCosPaCut, true)) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } else + ++counter; + + if (doDCAV0ToPVCut) { + if (TMath::Abs(casc.dcav0topv(coll.posX(), coll.posY(), coll.posZ())) < dcaV0ToPV) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } else + ++counter; + + if (doNTPCSigmaCut) { + if (casc.sign() < 0) { + if (TMath::Abs(posExtra.tpcNSigmaPr()) > nsigmatpcPr || TMath::Abs(negExtra.tpcNSigmaPi()) > nsigmatpcPi) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } else if (casc.sign() > 0) { + if (TMath::Abs(posExtra.tpcNSigmaPi()) > nsigmatpcPi || TMath::Abs(negExtra.tpcNSigmaPr()) > nsigmatpcPr) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } + } else + ++counter; + + if (posExtra.tpcCrossedRows() < mintpccrrows || negExtra.tpcCrossedRows() < mintpccrrows || bachExtra.tpcCrossedRows() < mintpccrrows) + continue; + histos.fill(HIST("hCandidate"), ++counter); + + bool kHasTOF = (posExtra.hasTOF() || negExtra.hasTOF() || bachExtra.hasTOF()); + bool kHasITS = (posExtra.hasITS() || negExtra.hasITS() || bachExtra.hasITS()); + if (dooobrej == 1) { + if (!kHasTOF && !kHasITS) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } else if (dooobrej == 2) { + if (!kHasTOF && (casc.pt() > ptthrtof)) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } else { + ++counter; + } + + float cascpos = std::hypot(casc.x() - coll.posX(), casc.y() - coll.posY(), casc.z() - coll.posZ()); + float cascptotmom = std::hypot(casc.px(), casc.py(), casc.pz()); + float ctau = -10; + + if (isXi) { + if (doNTPCSigmaCut) { + if (TMath::Abs(bachExtra.tpcNSigmaPi()) > nsigmatpcPi) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } else + ++counter; + + ctau = pdgDB->Mass(3312) * cascpos / ((cascptotmom + 1e-13) * ctauxiPDG); + if (doProperLifeTimeCut) { + if (ctau > proplifetime) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } else { + ++counter; + } + } else { + if (doNTPCSigmaCut) { + if (TMath::Abs(bachExtra.tpcNSigmaKa()) > nsigmatpcKa) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } else + ++counter; + + ctau = pdgDB->Mass(3334) * cascpos / ((cascptotmom + 1e-13) * ctauomegaPDG); + if (doProperLifeTimeCut) { + if (ctau > proplifetime) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } else + ++counter; + } + + if (casc.sign() < 0) { + histos.fill(HIST("InvMassAfterSel/hNegativeCascade"), casc.pt(), invmass, coll.centFT0C()); + if (!doBachelorBaryonCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hNegativeBachelorBaryonDCA"), casc.pt(), invmass, casc.bachBaryonDCAxyToPV()); + if (!doDCAV0ToPVCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hNegativeDCAV0ToPV"), casc.pt(), invmass, TMath::Abs(casc.dcav0topv(casc.x(), casc.y(), casc.z()))); + if (!doV0RadiusCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hNegativeV0Radius"), casc.pt(), invmass, casc.v0radius()); + if (!doCascadeRadiusCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hNegativeCascadeRadius"), casc.pt(), invmass, casc.cascradius()); + if (!doDCAV0DauCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hNegativeDCAV0Daughters"), casc.pt(), invmass, casc.dcaV0daughters()); + if (!doDCACascadeDauCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hNegativeDCACascDaughters"), casc.pt(), invmass, casc.dcacascdaughters()); + if (!doV0CosPaCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hNegativeV0pa"), casc.pt(), invmass, TMath::ACos(casc.v0cosPA(casc.x(), casc.y(), casc.z()))); + if (!doCascadeCosPaCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hNegativeCascPA"), casc.pt(), invmass, TMath::ACos(casc.casccosPA(coll.posX(), coll.posY(), coll.posZ()))); + if (!doDCAdauToPVCut && doPtDepCutStudy) { + histos.fill(HIST("PtDepCutStudy/hNegativeDCABachelorToPV"), casc.pt(), invmass, casc.dcabachtopv()); + histos.fill(HIST("PtDepCutStudy/hNegativeDCAMesonToPV"), casc.pt(), invmass, casc.dcanegtopv()); + histos.fill(HIST("PtDepCutStudy/hNegativeDCABaryonToPV"), casc.pt(), invmass, casc.dcapostopv()); + } + if (!doProperLifeTimeCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hNegativeCascadeProperLifeTime"), casc.pt(), invmass, ctau); + } else { + histos.fill(HIST("InvMassAfterSel/hPositiveCascade"), casc.pt(), invmass, coll.centFT0C()); + if (!doBachelorBaryonCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hPositiveBachelorBaryonDCA"), casc.pt(), invmass, casc.bachBaryonDCAxyToPV()); + if (!doDCAV0ToPVCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hPositiveDCAV0ToPV"), casc.pt(), invmass, TMath::Abs(casc.dcav0topv(casc.x(), casc.y(), casc.z()))); + if (!doV0RadiusCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hPositiveV0Radius"), casc.pt(), invmass, casc.v0radius()); + if (!doCascadeRadiusCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hPositiveCascadeRadius"), casc.pt(), invmass, casc.cascradius()); + if (!doDCAV0DauCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hPositiveDCAV0Daughters"), casc.pt(), invmass, casc.dcaV0daughters()); + if (!doDCACascadeDauCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hPositiveDCACascDaughters"), casc.pt(), invmass, casc.dcacascdaughters()); + if (!doV0CosPaCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hPositiveV0pa"), casc.pt(), invmass, TMath::ACos(casc.v0cosPA(casc.x(), casc.y(), casc.z()))); + if (!doCascadeCosPaCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hPositiveCascPA"), casc.pt(), invmass, TMath::ACos(casc.casccosPA(coll.posX(), coll.posY(), coll.posZ()))); + if (!doDCAdauToPVCut && doPtDepCutStudy) { + histos.fill(HIST("PtDepCutStudy/hPositiveDCABachelorToPV"), casc.pt(), invmass, casc.dcabachtopv()); + histos.fill(HIST("PtDepCutStudy/hPositiveDCAMesonToPV"), casc.pt(), invmass, casc.dcapostopv()); + histos.fill(HIST("PtDepCutStudy/hPositiveDCABaryonToPV"), casc.pt(), invmass, casc.dcanegtopv()); + } + if (!doProperLifeTimeCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hPositiveCascadeProperLifeTime"), casc.pt(), invmass, ctau); + } + } + } + void processCascadesMCrec(soa::Join::iterator const& coll, soa::Join const& Cascades, soa::Join const&) + { + if (!IsEventAccepted(coll, true)) + return; + + for (auto& casc : Cascades) { + + int counter = -1; + histos.fill(HIST("hCandidate"), ++counter); + + // To have trace of how it was before selections + if (casc.sign() < 0) { + if (isXi) + histos.fill(HIST("InvMassBefSel/hNegativeCascade"), casc.pt(), casc.mXi(), coll.centFT0C()); + else + histos.fill(HIST("InvMassBefSel/hNegativeCascade"), casc.pt(), casc.mOmega(), coll.centFT0C()); + } + if (casc.sign() > 0) { + if (isXi) + histos.fill(HIST("InvMassBefSel/hPositiveCascade"), casc.pt(), casc.mXi(), coll.centFT0C()); + else + histos.fill(HIST("InvMassBefSel/hPositiveCascade"), casc.pt(), casc.mOmega(), coll.centFT0C()); + } + + if (!IsCascadeCandidateAccepted(casc, counter, coll.centFT0C())) + continue; + counter += 13; + + auto negExtra = casc.negTrackExtra_as>(); + auto posExtra = casc.posTrackExtra_as>(); + auto bachExtra = casc.bachTrackExtra_as>(); + + auto poseta = RecoDecay::eta(std::array{casc.pxpos(), casc.pypos(), casc.pzpos()}); + auto negeta = RecoDecay::eta(std::array{casc.pxneg(), casc.pyneg(), casc.pzneg()}); + auto bacheta = RecoDecay::eta(std::array{casc.pxbach(), casc.pybach(), casc.pzbach()}); + if (TMath::Abs(poseta) > etaDauCut || TMath::Abs(negeta) > etaDauCut || TMath::Abs(bacheta) > etaDauCut) + continue; + histos.fill(HIST("hCandidate"), ++counter); + + if (doCascadeCosPaCut) { + if (!IsCosPAAccepted(casc, coll.posX(), coll.posY(), coll.posZ(), doPtDepCosPaCut, true)) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } else + ++counter; + + if (doDCAV0ToPVCut) { + if (TMath::Abs(casc.dcav0topv(coll.posX(), coll.posY(), coll.posZ())) < dcaV0ToPV) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } else + ++counter; + + if (doNTPCSigmaCut) { + if (casc.sign() < 0) { + if (TMath::Abs(posExtra.tpcNSigmaPr()) > nsigmatpcPr || TMath::Abs(negExtra.tpcNSigmaPi()) > nsigmatpcPi) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } else if (casc.sign() > 0) { + if (TMath::Abs(posExtra.tpcNSigmaPi()) > nsigmatpcPi || TMath::Abs(negExtra.tpcNSigmaPr()) > nsigmatpcPr) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } + } else + ++counter; + + if (posExtra.tpcCrossedRows() < mintpccrrows || negExtra.tpcCrossedRows() < mintpccrrows || bachExtra.tpcCrossedRows() < mintpccrrows) + continue; + histos.fill(HIST("hCandidate"), ++counter); + + bool kHasTOF = (posExtra.hasTOF() || negExtra.hasTOF() || bachExtra.hasTOF()); + bool kHasITS = (posExtra.hasITS() || negExtra.hasITS() || bachExtra.hasITS()); + if (dooobrej == 1) { + if (!kHasTOF && !kHasITS) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } else if (dooobrej == 2) { + if (!kHasTOF && (casc.pt() > ptthrtof)) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } else { + ++counter; + } + + double invmass; + float cascpos = std::hypot(casc.x() - coll.posX(), casc.y() - coll.posY(), casc.z() - coll.posZ()); + float cascptotmom = std::hypot(casc.px(), casc.py(), casc.pz()); + float ctau = -10; + + if (isXi) { + if (doNTPCSigmaCut) { + if (TMath::Abs(bachExtra.tpcNSigmaPi()) > nsigmatpcPi) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } else + ++counter; + + ctau = pdgDB->Mass(3312) * cascpos / ((cascptotmom + 1e-13) * ctauxiPDG); + if (doProperLifeTimeCut) { + if (ctau > proplifetime) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } else { + ++counter; + } + + invmass = casc.mXi(); + } else { + if (doNTPCSigmaCut) { + if (TMath::Abs(bachExtra.tpcNSigmaKa()) > nsigmatpcKa) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } else + ++counter; + ctau = pdgDB->Mass(3334) * cascpos / ((cascptotmom + 1e-13) * ctauomegaPDG); + if (doProperLifeTimeCut) { + if (ctau > proplifetime) + continue; + histos.fill(HIST("hCandidate"), ++counter); + } else + ++counter; + invmass = casc.mOmega(); + } + + if (casc.sign() < 0) { + histos.fill(HIST("InvMassAfterSel/hNegativeCascade"), casc.pt(), invmass, coll.centFT0C()); + if (!doBachelorBaryonCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hNegativeBachelorBaryonDCA"), casc.pt(), invmass, casc.bachBaryonDCAxyToPV()); + if (!doDCAV0ToPVCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hNegativeDCAV0ToPV"), casc.pt(), invmass, TMath::Abs(casc.dcav0topv(casc.x(), casc.y(), casc.z()))); + if (!doV0RadiusCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hNegativeV0Radius"), casc.pt(), invmass, casc.v0radius()); + if (!doCascadeRadiusCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hNegativeCascadeRadius"), casc.pt(), invmass, casc.cascradius()); + if (!doDCAV0DauCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hNegativeDCAV0Daughters"), casc.pt(), invmass, casc.dcaV0daughters()); + if (!doDCACascadeDauCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hNegativeDCACascDaughters"), casc.pt(), invmass, casc.dcacascdaughters()); + if (!doV0CosPaCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hNegativeV0pa"), casc.pt(), invmass, TMath::ACos(casc.v0cosPA(casc.x(), casc.y(), casc.z()))); + if (!doCascadeCosPaCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hNegativeCascPA"), casc.pt(), invmass, TMath::ACos(casc.casccosPA(coll.posX(), coll.posY(), coll.posZ()))); + if (!doDCAdauToPVCut && doPtDepCutStudy) { + histos.fill(HIST("PtDepCutStudy/hNegativeDCABachelorToPV"), casc.pt(), invmass, casc.dcabachtopv()); + histos.fill(HIST("PtDepCutStudy/hNegativeDCAMesonToPV"), casc.pt(), invmass, casc.dcanegtopv()); + histos.fill(HIST("PtDepCutStudy/hNegativeDCABaryonToPV"), casc.pt(), invmass, casc.dcapostopv()); + } + if (!doProperLifeTimeCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hNegativeCascadeProperLifeTime"), casc.pt(), invmass, ctau); + if (casc.isPhysicalPrimary()) { + if ((isXi && casc.pdgCode() == 3312) || (!isXi && casc.pdgCode() == 3334)) { + histos.fill(HIST("InvMassAfterSelMCrecTruth/hNegativeCascade"), casc.pt(), invmass, coll.centFT0C()); + if (!doBachelorBaryonCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudyMCTruth/hNegativeBachelorBaryonDCA"), casc.pt(), invmass, casc.bachBaryonDCAxyToPV()); + if (!doDCAV0ToPVCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudyMCTruth/hNegativeDCAV0ToPV"), casc.pt(), invmass, TMath::Abs(casc.dcav0topv(casc.x(), casc.y(), casc.z()))); + if (!doV0RadiusCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudyMCTruth/hNegativeV0Radius"), casc.pt(), invmass, casc.v0radius()); + if (!doCascadeRadiusCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudyMCTruth/hNegativeCascadeRadius"), casc.pt(), invmass, casc.cascradius()); + if (!doDCAV0DauCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudyMCTruth/hNegativeDCAV0Daughters"), casc.pt(), invmass, casc.dcaV0daughters()); + if (!doDCACascadeDauCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudyMCTruth/hNegativeDCACascDaughters"), casc.pt(), invmass, casc.dcacascdaughters()); + if (!doV0CosPaCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudyMCTruth/hNegativeV0pa"), casc.pt(), invmass, TMath::ACos(casc.v0cosPA(casc.x(), casc.y(), casc.z()))); + if (!doCascadeCosPaCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudyMCTruth/hNegativeCascPA"), casc.pt(), invmass, TMath::ACos(casc.casccosPA(coll.posX(), coll.posY(), coll.posZ()))); + if (!doDCAdauToPVCut && doPtDepCutStudy) { + histos.fill(HIST("PtDepCutStudyMCTruth/hNegativeDCABachelorToPV"), casc.pt(), invmass, casc.dcabachtopv()); + histos.fill(HIST("PtDepCutStudyMCTruth/hNegativeDCAMesonToPV"), casc.pt(), invmass, casc.dcanegtopv()); + histos.fill(HIST("PtDepCutStudyMCTruth/hNegativeDCABaryonToPV"), casc.pt(), invmass, casc.dcapostopv()); + } + if (!doProperLifeTimeCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudyMCTruth/hNegativeCascadeProperLifeTime"), casc.pt(), invmass, ctau); + } + } + } else { + histos.fill(HIST("InvMassAfterSel/hPositiveCascade"), casc.pt(), invmass, coll.centFT0C()); + if (!doBachelorBaryonCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hPositiveBachelorBaryonDCA"), casc.pt(), invmass, casc.bachBaryonDCAxyToPV()); + if (!doDCAV0ToPVCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hPositiveDCAV0ToPV"), casc.pt(), invmass, TMath::Abs(casc.dcav0topv(casc.x(), casc.y(), casc.z()))); + if (!doV0RadiusCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hPositiveV0Radius"), casc.pt(), invmass, casc.v0radius()); + if (!doCascadeRadiusCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hPositiveCascadeRadius"), casc.pt(), invmass, casc.cascradius()); + if (!doDCAV0DauCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hPositiveDCAV0Daughters"), casc.pt(), invmass, casc.dcaV0daughters()); + if (!doDCACascadeDauCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hPositiveDCACascDaughters"), casc.pt(), invmass, casc.dcacascdaughters()); + if (!doV0CosPaCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hPositiveV0pa"), casc.pt(), invmass, TMath::ACos(casc.v0cosPA(casc.x(), casc.y(), casc.z()))); + if (!doCascadeCosPaCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hPositiveCascPA"), casc.pt(), invmass, TMath::ACos(casc.casccosPA(coll.posX(), coll.posY(), coll.posZ()))); + if (!doDCAdauToPVCut && doPtDepCutStudy) { + histos.fill(HIST("PtDepCutStudy/hPositiveDCABachelorToPV"), casc.pt(), invmass, casc.dcabachtopv()); + histos.fill(HIST("PtDepCutStudy/hPositiveDCAMesonToPV"), casc.pt(), invmass, casc.dcapostopv()); + histos.fill(HIST("PtDepCutStudy/hPositiveDCABaryonToPV"), casc.pt(), invmass, casc.dcanegtopv()); + } + if (!doProperLifeTimeCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudy/hPositiveCascadeProperLifeTime"), casc.pt(), invmass, ctau); + if (casc.isPhysicalPrimary()) { + if ((isXi && casc.pdgCode() == -3312) || (!isXi && casc.pdgCode() == -3334)) { + histos.fill(HIST("InvMassAfterSelMCrecTruth/hPositiveCascade"), casc.pt(), invmass, coll.centFT0C()); + if (!doBachelorBaryonCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudyMCTruth/hPositiveBachelorBaryonDCA"), casc.pt(), invmass, casc.bachBaryonDCAxyToPV()); + if (!doDCAV0ToPVCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudyMCTruth/hPositiveDCAV0ToPV"), casc.pt(), invmass, TMath::Abs(casc.dcav0topv(casc.x(), casc.y(), casc.z()))); + if (!doV0RadiusCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudyMCTruth/hPositiveV0Radius"), casc.pt(), invmass, casc.v0radius()); + if (!doCascadeRadiusCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudyMCTruth/hPositiveCascadeRadius"), casc.pt(), invmass, casc.cascradius()); + if (!doDCAV0DauCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudyMCTruth/hPositiveDCAV0Daughters"), casc.pt(), invmass, casc.dcaV0daughters()); + if (!doDCACascadeDauCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudyMCTruth/hPositiveDCACascDaughters"), casc.pt(), invmass, casc.dcacascdaughters()); + if (!doV0CosPaCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudyMCTruth/hPositiveV0pa"), casc.pt(), invmass, TMath::ACos(casc.v0cosPA(casc.x(), casc.y(), casc.z()))); + if (!doCascadeCosPaCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudyMCTruth/hPositiveCascPA"), casc.pt(), invmass, TMath::ACos(casc.casccosPA(coll.posX(), coll.posY(), coll.posZ()))); + if (!doDCAdauToPVCut && doPtDepCutStudy) { + histos.fill(HIST("PtDepCutStudyMCTruth/hPositiveDCABachelorToPV"), casc.pt(), invmass, casc.dcabachtopv()); + histos.fill(HIST("PtDepCutStudyMCTruth/hPositiveDCAMesonToPV"), casc.pt(), invmass, casc.dcapostopv()); + histos.fill(HIST("PtDepCutStudyMCTruth/hPositiveDCABaryonToPV"), casc.pt(), invmass, casc.dcanegtopv()); + } + if (!doProperLifeTimeCut && doPtDepCutStudy) + histos.fill(HIST("PtDepCutStudyMCTruth/hPositiveCascadeProperLifeTime"), casc.pt(), invmass, ctau); + } + } + } + } + } + + PROCESS_SWITCH(derivedCascadeAnalysis, processCascades, "cascade analysis, run3 data ", true); + PROCESS_SWITCH(derivedCascadeAnalysis, processCascadesMCrec, "cascade analysis, run3 rec MC", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx b/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx new file mode 100644 index 00000000000..7e70ac564b9 --- /dev/null +++ b/PWGLF/Tasks/Strangeness/derivedlambdakzeroanalysis.cxx @@ -0,0 +1,449 @@ +// 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. +// +// V0 analysis task +// ================ +// +// This code loops over a V0Cores table and produces some +// standard analysis output. It is meant to be run over +// derived data. +// +// Comments, questions, complaints, suggestions? +// Please write to: +// romain.schotter@cern.ch +// david.dobrigkeit.chinellato@cern.ch +// +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/ASoAHelpers.h" +#include "ReconstructionDataFormats/Track.h" +#include "CommonConstants/PhysicsConstants.h" +#include "Common/Core/trackUtilities.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" +#include "Common/Core/TrackSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/PIDResponse.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Framework/ASoAHelpers.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using std::array; + +using dauTracks = soa::Join; +using v0Candidates = soa::Join; +using v0MCCandidates = soa::Join; + +// simple checkers +#define bitset(var, nbit) ((var) |= (1 << (nbit))) +#define bitcheck(var, nbit) ((var) & (1 << (nbit))) + +struct derivedlambdakzeroanalysis { + HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + // master analysis switches + Configurable analyseK0Short{"analyseK0Short", true, "process K0Short-like candidates"}; + Configurable analyseLambda{"analyseLambda", true, "process Lambda-like candidates"}; + Configurable analyseAntiLambda{"analyseAntiLambda", true, "process AntiLambda-like candidates"}; + + // Selection criteria: acceptance + Configurable rapidityCut{"rapidityCut", 0.5, "rapidity"}; + Configurable daughterEtaCut{"daughterEtaCut", 0.8, "max eta for daughters"}; + + // Standard 5 topological criteria + 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)"}; + + // Additional selection on the AP plot (exclusive for K0Short) + // original equation: lArmPt*5>TMath::Abs(lArmAlpha) + Configurable armPodCut{"armPodCut", 5.0f, "pT * (cut) > |alpha|, AP cut. Negative: no cut"}; + + // PID (TPC) + Configurable TpcPidNsigmaCut{"TpcPidNsigmaCut", 5, "TpcPidNsigmaCut"}; + + Configurable doQA{"doQA", true, "do topological variable QA histograms"}; + Configurable qaMinPt{"qaMinPt", 0.0f, "minimum pT for QA plots"}; + Configurable qaMaxPt{"qaMaxPt", 0.0f, "maximum pT for QA plots"}; + + // for MC + Configurable doMCAssociation{"doMCAssociation", true, "if MC, do MC association"}; + + static constexpr float defaultLifetimeCuts[1][2] = {{30., 20.}}; + Configurable> lifetimecut{"lifetimecut", {defaultLifetimeCuts[0], 2, {"lifetimecutLambda", "lifetimecutK0S"}}, "lifetimecut"}; + + 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 analysis"}; + 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"}; + + // topological variable QA axes + ConfigurableAxis axisDCAtoPV{"axisDCAtoPV", {20, 0.0f, 1.0f}, "DCA (cm)"}; + ConfigurableAxis axisDCAdau{"axisDCAdau", {20, 0.0f, 2.0f}, "DCA (cm)"}; + ConfigurableAxis axisPointingAngle{"axisPointingAngle", {20, 0.0f, 2.0f}, "pointing angle (rad)"}; + ConfigurableAxis axisV0Radius{"axisV0Radius", {20, 0.0f, 60.0f}, "V0 2D radius (cm)"}; + + // AP plot axes + ConfigurableAxis axisAPAlpha{"axisAPAlpha", {220, -1.1f, 1.1f}, "V0 AP alpha"}; + ConfigurableAxis axisAPQt{"axisAPQt", {220, 0.0f, 0.5f}, "V0 AP alpha"}; + + enum species { spK0Short = 0, + spLambda, + spAntiLambda }; + + enum selection { selCosPA = 0, + selRadius, + selDCANegToPV, + selDCAPosToPV, + selDCAV0Dau, + selK0ShortRapidity, + selLambdaRapidity, + selK0ShortTPC, + selLambdaTPC, + selAntiLambdaTPC, + selK0ShortCTau, + selLambdaCTau, + selK0ShortArmenteros, + selConsiderK0Short, // for mc tagging + selConsiderLambda, // for mc tagging + selConsiderAntiLambda // for mc tagging + }; // all bits used + + uint16_t maskTopological; + uint16_t maskTopoNoV0Radius; + uint16_t maskTopoNoDCANegToPV; + uint16_t maskTopoNoDCAPosToPV; + uint16_t maskTopoNoCosPA; + uint16_t maskTopoNoDCAV0Dau; + + uint16_t maskK0ShortSpecific; + uint16_t maskLambdaSpecific; + uint16_t maskAntiLambdaSpecific; + + uint16_t maskSelectionK0Short; + uint16_t maskSelectionLambda; + uint16_t maskSelectionAntiLambda; + + void init(InitContext const&) + { + // initialise bit masks + maskTopological = (1 << selCosPA) | (1 << selRadius) | (1 << selDCANegToPV) | (1 << selDCAPosToPV) | (1 << selDCAV0Dau); + maskTopoNoV0Radius = (1 << selCosPA) | (1 << selDCANegToPV) | (1 << selDCAPosToPV) | (1 << selDCAV0Dau); + maskTopoNoDCANegToPV = (1 << selCosPA) | (1 << selRadius) | (1 << selDCAPosToPV) | (1 << selDCAV0Dau); + maskTopoNoDCAPosToPV = (1 << selCosPA) | (1 << selRadius) | (1 << selDCANegToPV) | (1 << selDCAV0Dau); + maskTopoNoCosPA = (1 << selRadius) | (1 << selDCANegToPV) | (1 << selDCAPosToPV) | (1 << selDCAV0Dau); + maskTopoNoDCAV0Dau = (1 << selCosPA) | (1 << selRadius) | (1 << selDCANegToPV) | (1 << selDCAPosToPV); + + maskK0ShortSpecific = (1 << selK0ShortRapidity) | (1 << selK0ShortTPC) | (1 << selK0ShortCTau) | (1 << selK0ShortArmenteros) | (1 << selConsiderK0Short); + maskLambdaSpecific = (1 << selLambdaRapidity) | (1 << selLambdaTPC) | (1 << selLambdaCTau) | (1 << selConsiderLambda); + maskAntiLambdaSpecific = (1 << selLambdaRapidity) | (1 << selAntiLambdaTPC) | (1 << selLambdaCTau) | (1 << selConsiderAntiLambda); + + maskSelectionK0Short = maskTopological | maskK0ShortSpecific; + maskSelectionLambda = maskTopological | maskLambdaSpecific; + maskSelectionAntiLambda = maskTopological | maskAntiLambdaSpecific; + + // Event Counters + histos.add("hEventSelection", "hEventSelection", kTH1F, {{3, -0.5f, +2.5f}}); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(2, "sel8 cut"); + histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(3, "posZ cut"); + + histos.add("hEventCentrality", "hEventCentrality", kTH1F, {{100, 0.0f, +100.0f}}); + + // histograms versus mass + if (analyseK0Short) + histos.add("h3dMassK0Short", "h3dMassK0Short", kTH3F, {axisCentrality, axisPt, axisK0Mass}); + if (analyseLambda) + histos.add("h3dMassLambda", "h3dMassLambda", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); + if (analyseAntiLambda) + histos.add("h3dMassAntiLambda", "h3dMassAntiLambda", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); + + // demo // fast + histos.add("hMassK0Short", "hMassK0Short", kTH1F, {axisK0Mass}); + + // QA histograms if requested + if (doQA) { + // initialize for K0short... + if (analyseK0Short) { + histos.add("K0Short/h4dPosDCAToPV", "h4dPosDCAToPV", kTHnF, {axisCentrality, axisPtCoarse, axisK0Mass, axisDCAtoPV}); + histos.add("K0Short/h4dNegDCAToPV", "h4dNegDCAToPV", kTHnF, {axisCentrality, axisPtCoarse, axisK0Mass, axisDCAtoPV}); + histos.add("K0Short/h4dDCADaughters", "h4dDCADaughters", kTHnF, {axisCentrality, axisPtCoarse, axisK0Mass, axisDCAdau}); + histos.add("K0Short/h4dPointingAngle", "h4dPointingAngle", kTHnF, {axisCentrality, axisPtCoarse, axisK0Mass, axisPointingAngle}); + histos.add("K0Short/h4dV0Radius", "h4dV0Radius", kTHnF, {axisCentrality, axisPtCoarse, axisK0Mass, axisV0Radius}); + } + if (analyseLambda) { + histos.add("Lambda/h4dPosDCAToPV", "h4dPosDCAToPV", kTHnF, {axisCentrality, axisPtCoarse, axisLambdaMass, axisDCAtoPV}); + histos.add("Lambda/h4dNegDCAToPV", "h4dNegDCAToPV", kTHnF, {axisCentrality, axisPtCoarse, axisLambdaMass, axisDCAtoPV}); + histos.add("Lambda/h4dDCADaughters", "h4dDCADaughters", kTHnF, {axisCentrality, axisPtCoarse, axisLambdaMass, axisDCAdau}); + histos.add("Lambda/h4dPointingAngle", "h4dPointingAngle", kTHnF, {axisCentrality, axisPtCoarse, axisLambdaMass, axisPointingAngle}); + histos.add("Lambda/h4dV0Radius", "h4dV0Radius", kTHnF, {axisCentrality, axisPtCoarse, axisLambdaMass, axisV0Radius}); + } + if (analyseAntiLambda) { + histos.add("AntiLambda/h4dPosDCAToPV", "h4dPosDCAToPV", kTHnF, {axisCentrality, axisPtCoarse, axisLambdaMass, axisDCAtoPV}); + histos.add("AntiLambda/h4dNegDCAToPV", "h4dNegDCAToPV", kTHnF, {axisCentrality, axisPtCoarse, axisLambdaMass, axisDCAtoPV}); + histos.add("AntiLambda/h4dDCADaughters", "h4dDCADaughters", kTHnF, {axisCentrality, axisPtCoarse, axisLambdaMass, axisDCAdau}); + histos.add("AntiLambda/h4dPointingAngle", "h4dPointingAngle", kTHnF, {axisCentrality, axisPtCoarse, axisLambdaMass, axisPointingAngle}); + histos.add("AntiLambda/h4dV0Radius", "h4dV0Radius", kTHnF, {axisCentrality, axisPtCoarse, axisLambdaMass, axisV0Radius}); + } + + // Check if doing the right thing in AP space please + histos.add("GeneralQA/h2dArmenterosAll", "h2dArmenterosAll", kTH2F, {axisAPAlpha, axisAPQt}); + histos.add("GeneralQA/h2dArmenterosSelected", "h2dArmenterosSelected", kTH2F, {axisAPAlpha, axisAPQt}); + } + } + + template + bool compatibleTPC(TV0 v0, int sp) + { + float pidPos = TMath::Abs(v0.template posTrackExtra_as().tpcNSigmaPi()); + float pidNeg = TMath::Abs(v0.template negTrackExtra_as().tpcNSigmaPi()); + + if (sp == spLambda) + pidPos = TMath::Abs(v0.template posTrackExtra_as().tpcNSigmaPr()); + if (sp == spAntiLambda) + pidNeg = TMath::Abs(v0.template negTrackExtra_as().tpcNSigmaPr()); + + if (pidPos < TpcPidNsigmaCut && pidNeg < TpcPidNsigmaCut) + return true; + + // if not, then not + return false; + } + + template + uint16_t computeReconstructionBitmap(TV0 v0, TCollision collision) + // precalculate this information so that a check is one mask operation, not many + { + uint16_t bitMap = 0; + // Base topological variables + if (v0.v0radius() > v0radius) + bitset(bitMap, selRadius); + if (TMath::Abs(v0.dcapostopv()) > dcapostopv) + bitset(bitMap, selDCAPosToPV); + if (TMath::Abs(v0.dcanegtopv()) > dcanegtopv) + bitset(bitMap, selDCANegToPV); + if (v0.v0cosPA() > v0cospa) + bitset(bitMap, selCosPA); + if (v0.dcaV0daughters() < dcav0dau) + bitset(bitMap, selDCAV0Dau); + + // rapidity + if (TMath::Abs(v0.yLambda()) < rapidityCut) + bitset(bitMap, selLambdaRapidity); + if (TMath::Abs(v0.yK0Short()) < rapidityCut) + bitset(bitMap, selK0ShortRapidity); + + // TPC PID + if (compatibleTPC(v0, spK0Short)) + bitset(bitMap, selK0ShortTPC); + if (compatibleTPC(v0, spLambda)) + bitset(bitMap, selLambdaTPC); + if (compatibleTPC(v0, spAntiLambda)) + bitset(bitMap, selAntiLambdaTPC); + + // proper lifetime + if (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0 < lifetimecut->get("lifetimecutLambda")) + bitset(bitMap, selLambdaCTau); + if (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short < lifetimecut->get("lifetimecutK0S")) + bitset(bitMap, selK0ShortCTau); + + // armenteros + if (v0.qtarm() * armPodCut > TMath::Abs(v0.alpha()) || armPodCut < 1e-4) + bitset(bitMap, selK0ShortArmenteros); + + return bitMap; + } + + template + uint16_t computeMCAssociation(TV0 v0) + // precalculate this information so that a check is one mask operation, not many + { + uint16_t bitMap = 0; + // check for specific particle species + + if (v0.pdgCode() == 310 && v0.pdgCodePositive() == 211 && v0.pdgCodeNegative() == -211 && v0.isPhysicalPrimary()) { + bitset(bitMap, selConsiderK0Short); + } + if (v0.pdgCode() == 3122 && v0.pdgCodePositive() == 2212 && v0.pdgCodeNegative() == -211 && v0.isPhysicalPrimary()) { + bitset(bitMap, selConsiderLambda); + } + if (v0.pdgCode() == -3122 && v0.pdgCodePositive() == 211 && v0.pdgCodeNegative() == -2212 && v0.isPhysicalPrimary()) { + bitset(bitMap, selConsiderAntiLambda); + } + return bitMap; + } + + bool verifyMask(uint16_t bitmap, uint16_t mask) + { + return (bitmap & mask) == mask; + } + + template + void analyseCandidate(TV0 v0, TCollision collision, uint16_t selMap) + // precalculate this information so that a check is one mask operation, not many + { + // __________________________________________ + // main analysis + if (verifyMask(selMap, maskSelectionK0Short) && analyseK0Short) { + histos.fill(HIST("GeneralQA/h2dArmenterosSelected"), v0.alpha(), v0.qtarm()); // cross-check + histos.fill(HIST("h3dMassK0Short"), collision.centFT0C(), v0.pt(), v0.mK0Short()); + histos.fill(HIST("hMassK0Short"), v0.mK0Short()); + } + if (verifyMask(selMap, maskSelectionLambda) && analyseLambda) { + histos.fill(HIST("h3dMassLambda"), collision.centFT0C(), v0.pt(), v0.mLambda()); + } + if (verifyMask(selMap, maskSelectionAntiLambda) && analyseAntiLambda) { + histos.fill(HIST("h3dMassAntiLambda"), collision.centFT0C(), v0.pt(), v0.mAntiLambda()); + } + + // __________________________________________ + // do systematics / qa plots + if (doQA) { + if (analyseK0Short) { + if (verifyMask(selMap, maskTopoNoV0Radius | maskK0ShortSpecific)) + histos.fill(HIST("K0Short/h4dV0Radius"), collision.centFT0C(), v0.pt(), v0.mK0Short(), v0.v0radius()); + if (verifyMask(selMap, maskTopoNoDCAPosToPV | maskK0ShortSpecific)) + histos.fill(HIST("K0Short/h4dPosDCAToPV"), collision.centFT0C(), v0.pt(), v0.mK0Short(), TMath::Abs(v0.dcapostopv())); + if (verifyMask(selMap, maskTopoNoDCANegToPV | maskK0ShortSpecific)) + histos.fill(HIST("K0Short/h4dNegDCAToPV"), collision.centFT0C(), v0.pt(), v0.mK0Short(), TMath::Abs(v0.dcanegtopv())); + if (verifyMask(selMap, maskTopoNoCosPA | maskK0ShortSpecific)) + histos.fill(HIST("K0Short/h4dPointingAngle"), collision.centFT0C(), v0.pt(), v0.mK0Short(), TMath::ACos(v0.v0cosPA())); + if (verifyMask(selMap, maskTopoNoDCAV0Dau | maskK0ShortSpecific)) + histos.fill(HIST("K0Short/h4dDCADaughters"), collision.centFT0C(), v0.pt(), v0.mK0Short(), v0.dcaV0daughters()); + } + + if (analyseLambda) { + if (verifyMask(selMap, maskTopoNoV0Radius | maskLambdaSpecific)) + histos.fill(HIST("Lambda/h4dV0Radius"), collision.centFT0C(), v0.pt(), v0.mLambda(), v0.v0radius()); + if (verifyMask(selMap, maskTopoNoDCAPosToPV | maskLambdaSpecific)) + histos.fill(HIST("Lambda/h4dPosDCAToPV"), collision.centFT0C(), v0.pt(), v0.mLambda(), TMath::Abs(v0.dcapostopv())); + if (verifyMask(selMap, maskTopoNoDCANegToPV | maskLambdaSpecific)) + histos.fill(HIST("Lambda/h4dNegDCAToPV"), collision.centFT0C(), v0.pt(), v0.mLambda(), TMath::Abs(v0.dcanegtopv())); + if (verifyMask(selMap, maskTopoNoCosPA | maskLambdaSpecific)) + histos.fill(HIST("Lambda/h4dPointingAngle"), collision.centFT0C(), v0.pt(), v0.mLambda(), TMath::ACos(v0.v0cosPA())); + if (verifyMask(selMap, maskTopoNoDCAV0Dau | maskLambdaSpecific)) + histos.fill(HIST("Lambda/h4dDCADaughters"), collision.centFT0C(), v0.pt(), v0.mLambda(), v0.dcaV0daughters()); + } + if (analyseAntiLambda) { + if (verifyMask(selMap, maskTopoNoV0Radius | maskAntiLambdaSpecific)) + histos.fill(HIST("AntiLambda/h4dV0Radius"), collision.centFT0C(), v0.pt(), v0.mAntiLambda(), v0.v0radius()); + if (verifyMask(selMap, maskTopoNoDCAPosToPV | maskAntiLambdaSpecific)) + histos.fill(HIST("AntiLambda/h4dPosDCAToPV"), collision.centFT0C(), v0.pt(), v0.mAntiLambda(), TMath::Abs(v0.dcapostopv())); + if (verifyMask(selMap, maskTopoNoDCANegToPV | maskAntiLambdaSpecific)) + histos.fill(HIST("AntiLambda/h4dNegDCAToPV"), collision.centFT0C(), v0.pt(), v0.mAntiLambda(), TMath::Abs(v0.dcanegtopv())); + if (verifyMask(selMap, maskTopoNoCosPA | maskAntiLambdaSpecific)) + histos.fill(HIST("AntiLambda/h4dPointingAngle"), collision.centFT0C(), v0.pt(), v0.mAntiLambda(), TMath::ACos(v0.v0cosPA())); + if (verifyMask(selMap, maskTopoNoDCAV0Dau | maskAntiLambdaSpecific)) + histos.fill(HIST("AntiLambda/h4dDCADaughters"), collision.centFT0C(), v0.pt(), v0.mAntiLambda(), v0.dcaV0daughters()); + } + } // end systematics / qa + } + + // ______________________________________________________ + // Real data processing - no MC subscription + void processRealData(soa::Join::iterator const& collision, v0Candidates const& fullV0s, dauTracks const&) + { + histos.fill(HIST("hEventSelection"), 0. /* all collisions */); + if (!collision.sel8()) { + return; + } + histos.fill(HIST("hEventSelection"), 1 /* sel8 collisions */); + + if (std::abs(collision.posZ()) > 10.f) { + return; + } + histos.fill(HIST("hEventSelection"), 2 /* vertex-Z selected */); + histos.fill(HIST("hEventCentrality"), collision.centFT0C()); + + // __________________________________________ + // perform main analysis + for (auto& v0 : fullV0s) { + if (std::abs(v0.negativeeta()) > daughterEtaCut || std::abs(v0.positiveeta()) > daughterEtaCut) + continue; // remove acceptance that's badly reproduced by MC / superfluous in future + + // fill AP plot for all V0s + histos.fill(HIST("GeneralQA/h2dArmenterosAll"), v0.alpha(), v0.qtarm()); + + uint16_t selMap = computeReconstructionBitmap(v0, collision); + + // consider for histograms for all species + selMap = selMap | (1 << selConsiderK0Short) | (1 << selConsiderLambda) | (1 << selConsiderAntiLambda); + + analyseCandidate(v0, collision, selMap); + } // end v0 loop + } + + // ______________________________________________________ + // Simulated processing (subscribes to MC information too) + void processMonteCarlo(soa::Join::iterator const& collision, v0MCCandidates const& fullV0s, dauTracks const&) + { + histos.fill(HIST("hEventSelection"), 0. /* all collisions */); + if (!collision.sel8()) { + return; + } + histos.fill(HIST("hEventSelection"), 1 /* sel8 collisions */); + + if (std::abs(collision.posZ()) > 10.f) { + return; + } + histos.fill(HIST("hEventSelection"), 2 /* vertex-Z selected */); + histos.fill(HIST("hEventCentrality"), collision.centFT0C()); + + // __________________________________________ + // perform main analysis + for (auto& v0 : fullV0s) { + if (std::abs(v0.negativeeta()) > daughterEtaCut || std::abs(v0.positiveeta()) > daughterEtaCut) + continue; // remove acceptance that's badly reproduced by MC / superfluous in future + + // fill AP plot for all V0s + histos.fill(HIST("GeneralQA/h2dArmenterosAll"), v0.alpha(), v0.qtarm()); + + uint16_t selMap = computeReconstructionBitmap(v0, collision); + + // consider only associated candidates if asked to do so + if (doMCAssociation) { + selMap = selMap | computeMCAssociation(v0); + } else { + selMap = selMap | (1 << selConsiderK0Short) | (1 << selConsiderLambda) | (1 << selConsiderAntiLambda); + } + + analyseCandidate(v0, collision, selMap); + } // end v0 loop + } + + PROCESS_SWITCH(derivedlambdakzeroanalysis, processRealData, "process as if real data", true); + PROCESS_SWITCH(derivedlambdakzeroanalysis, processMonteCarlo, "process as if MC", false); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/Tasks/hStrangeCorrelation.cxx b/PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx similarity index 100% rename from PWGLF/Tasks/hStrangeCorrelation.cxx rename to PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx diff --git a/PWGLF/Tasks/hyperon-reco-test.cxx b/PWGLF/Tasks/Strangeness/hyperon-reco-test.cxx similarity index 100% rename from PWGLF/Tasks/hyperon-reco-test.cxx rename to PWGLF/Tasks/Strangeness/hyperon-reco-test.cxx diff --git a/PWGLF/Tasks/Strangeness/k0_mixed_events.cxx b/PWGLF/Tasks/Strangeness/k0_mixed_events.cxx new file mode 100644 index 00000000000..708a0b3981b --- /dev/null +++ b/PWGLF/Tasks/Strangeness/k0_mixed_events.cxx @@ -0,0 +1,450 @@ +// 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 Femto3D pair mixing task +/// \author Sofia Tomassini, Gleb Romanenko, Nicolò Jacazio +/// \since 31 May 2023 + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include +#include + +#include "Framework/ASoA.h" +#include "MathUtils/Utils.h" +#include "Framework/DataTypes.h" +#include "Common/DataModel/Multiplicity.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/Expressions.h" + +#include "Framework/StaticFor.h" +#include "PWGCF/Femto3D/DataModel/singletrackselector.h" + +#include +#include "TLorentzVector.h" +#include "TDatabasePDG.h" +#include "PWGCF/Femto3D/Core/femto3dPairTask.h" + +using namespace o2; +using namespace o2::soa; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; + +using FilteredCollisions = aod::SingleCollSels; +using FilteredTracks = aod::SingleTrackSels; + +typedef std::shared_ptr::iterator> trkType; +typedef std::shared_ptr::iterator> colType; + +using MyFemtoPair = o2::aod::singletrackselector::FemtoPair; + +class ResoPair : public MyFemtoPair +{ + public: + ResoPair() {} + ResoPair(trkType const& first, trkType const& second) : MyFemtoPair(first, second) + { + SetPair(first, second); + }; + ResoPair(trkType const& first, trkType const& second, const bool& isidentical) : MyFemtoPair(first, second, isidentical){}; + bool IsClosePair() const { return MyFemtoPair::IsClosePair(_deta, _dphi, _radius); } + void SetEtaDiff(const float deta) { _deta = deta; } + void SetPhiStarDiff(const float dphi) { _dphi = dphi; } + void SetPair(trkType const& first, trkType const& second) + { + MyFemtoPair::SetPair(first, second); + lDecayDaughter1.SetPtEtaPhiM(first->pt(), first->eta(), first->phi(), particle_mass(GetPDG1())); + lDecayDaughter2.SetPtEtaPhiM(second->pt(), second->eta(), second->phi(), particle_mass(GetPDG2())); + lResonance = lDecayDaughter1 + lDecayDaughter2; + } + float GetInvMass() const + { + // LOG(info) << "Mass = " << lResonance.M() << " 1 " << lDecayDaughter1.M() << " 2 " << lDecayDaughter2.M(); + return lResonance.M(); + } + float GetPt() const { return lResonance.Pt(); } + float GetRapidity() const { return lResonance.Rapidity(); } + + private: + TLorentzVector lDecayDaughter1, lDecayDaughter2, lResonance; + float _deta = 0.01; + float _dphi = 0.01; + float _radius = 1.2; +}; + +struct K0MixedEvents { + // using allinfo = soa::Join; // aod::pidTPCPr + /// Construct a registry object with direct declaration + HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject}; + + Configurable _min_P{"min_P", 0.0, "lower mometum limit"}; + Configurable _max_P{"max_P", 100.0, "upper mometum limit"}; + Configurable _eta{"eta", 100.0, "abs eta value limit"}; + Configurable _dcaXY{"dcaXY", 1000.0, "abs dcaXY value limit"}; + Configurable _dcaXYmin{"dcaXYmin", -0.1, "abs dcaXY min. value limit"}; + Configurable _dcaZ{"dcaZ", 1000.0, "abs dcaZ value limit"}; + Configurable _dcaZmin{"dcaZmin", -0.1, "abs dcaZ min. value limit"}; + Configurable _tpcNClsFound{"minTpcNClsFound", 0, "minimum allowed number of TPC clasters"}; + Configurable _tpcChi2NCl{"tpcChi2NCl", 100.0, "upper limit for chi2 value of a fit over TPC clasters"}; + Configurable _tpcCrossedRowsOverFindableCls{"tpcCrossedRowsOverFindableCls", 0, "lower limit of TPC CrossedRows/FindableCls value"}; + Configurable _tpcNClsShared{"maxTpcNClsShared", 100, "maximum allowed number of TPC shared clasters"}; + Configurable _itsNCls{"minItsNCls", 0, "minimum allowed number of ITS clasters"}; + Configurable _itsChi2NCl{"itsChi2NCl", 100.0, "upper limit for chi2 value of a fit over ITS clasters"}; + Configurable _vertexZ{"VertexZ", 10.0, "abs vertexZ value limit"}; + Configurable _maxy{"_maxy", 100.0, "maximum y of both particles in a pair"}; + + Configurable _sign_1{"sign_1", 1, "sign of the first particle in a pair"}; + Configurable _particlePDG_1{"particlePDG_1", 2212, "PDG code of the first particle in a pair to perform PID for (only proton and deurton are supported now)"}; + Configurable> _tpcNSigma_1{"tpcNSigma_1", std::vector{-3.0f, 3.0f}, "first particle PID: Nsigma range in TPC before the TOF is used"}; + Configurable _PIDtrshld_1{"PIDtrshld_1", 10.0, "first particle PID: value of momentum from which the PID is done with TOF (before that only TPC is used)"}; + Configurable> _tofNSigma_1{"tofNSigma_1", std::vector{-3.0f, 3.0f}, "first particle PID: Nsigma range in TOF"}; + + Configurable _sign_2{"sign_2", 1, "sign of the second particle in a pair"}; + Configurable _particlePDG_2{"particlePDG_2", 2212, "PDG code of the second particle in a pair to perform PID for (only proton and deurton are supported now)"}; + Configurable> _tpcNSigma_2{"tpcNSigma_2", std::vector{-3.0f, 3.0f}, "second particle PID: Nsigma range in TPC before the TOF is used"}; + Configurable _PIDtrshld_2{"PIDtrshld_2", 10.0, "second particle PID: value of momentum from which the PID is done with TOF (before that only TPC is used)"}; + Configurable> _tofNSigma_2{"tofNSigma_2", std::vector{-3.0f, 3.0f}, "second particle PID: Nsigma range in TOF"}; + + Configurable _particlePDGtoReject{"particlePDGtoRejectFromSecond", 0, "applied only if the particles are non-identical and only to the second particle in the pair!!!"}; + Configurable> _rejectWithinNsigmaTOF{"rejectWithinNsigmaTOF", std::vector{-0.0f, 0.0f}, "TOF rejection Nsigma range for the particle specified with PDG to be rejected"}; + + Configurable _deta{"deta", 0.01, "minimum allowed defference in eta between two tracks in a pair"}; + Configurable _dphi{"dphi", 0.01, "minimum allowed defference in phi_star between two tracks in a pair"}; + Configurable _radiusTPC{"radiusTPC", 1.2, "TPC radius to calculate phi_star for"}; + + Configurable doMixedEvent{"doMixedEvent", false, "Do the mixed event"}; + Configurable _multbinwidth{"multbinwidth", 50, "width of multiplicity bins within which the mixing is done"}; + Configurable _vertexbinwidth{"vertexbinwidth", 2, "width of vertexZ bins within which the mixing is done"}; + + // Binnings + ConfigurableAxis CFkStarBinning{"CFkStarBinning", {500, 0.4, 0.6}, "k* binning of the CF (Nbins, lowlimit, uplimit)"}; + ConfigurableAxis ptBinning{"ptBinning", {1000, 0.f, 10.f}, "pT binning (Nbins, lowlimit, uplimit)"}; + ConfigurableAxis dcaXyBinning{"dcaXyBinning", {100, -1.f, 1.f}, "dcaXY binning (Nbins, lowlimit, uplimit)"}; + + bool IsIdentical; + + std::pair> TPCcuts_1; + std::pair> TOFcuts_1; + + std::pair> TPCcuts_2; + std::pair> TOFcuts_2; + + std::map> selectedtracks_1; + std::map> selectedtracks_2; + std::map, std::vector> mixbins; + + std::unique_ptr Pair = std::make_unique(); + + Filter pFilter = o2::aod::singletrackselector::p > _min_P&& o2::aod::singletrackselector::p < _max_P; + Filter etaFilter = nabs(o2::aod::singletrackselector::eta) < _eta; + Filter tpcTrkFilter = o2::aod::singletrackselector::tpcNClsFound >= _tpcNClsFound && o2::aod::singletrackselector::tpcNClsShared <= (uint8_t)_tpcNClsShared; + Filter itsNClsFilter = o2::aod::singletrackselector::itsNCls >= (uint8_t)_itsNCls; + + Filter vertexFilter = nabs(o2::aod::singletrackselector::posZ) < _vertexZ; + + const char* pdgToSymbol(const int pdg) + { + switch (std::abs(pdg)) { + case 211: + return "#pi"; + case 321: + return "K"; + case 2212: + return "p"; + case 1000010020: + return "d"; + } + return "X"; + } + + void init(o2::framework::InitContext&) + { + IsIdentical = (_sign_1 * _particlePDG_1 == _sign_2 * _particlePDG_2); + LOG(info) << "IsIdentical=" << IsIdentical << "; sign1=" << _sign_1 << "; Pdg1=" << _particlePDG_1 << "; total1=" << _sign_1 * _particlePDG_1 << " -- Pdg2=" << _particlePDG_2 << "; sign2=" << _sign_2 << "; total2=" << _sign_2 * _particlePDG_2; + + Pair->SetIdentical(IsIdentical); + Pair->SetPDG1(_particlePDG_1); + Pair->SetPDG2(_particlePDG_2); + Pair->SetEtaDiff(1); + + TPCcuts_1 = std::make_pair(_particlePDG_1, _tpcNSigma_1); + TOFcuts_1 = std::make_pair(_particlePDG_1, _tofNSigma_1); + TPCcuts_2 = std::make_pair(_particlePDG_2, _tpcNSigma_2); + TOFcuts_2 = std::make_pair(_particlePDG_2, _tofNSigma_2); + + const AxisSpec invMassAxis{CFkStarBinning, "Inv. mass (GeV/c^{2})"}; + const AxisSpec ptAxis{ptBinning, "#it{p}_{T} (GeV/c)"}; + const AxisSpec dcaXyAxis{dcaXyBinning, "DCA_{xy} (cm)"}; + + registry.add("Trks", "Trks", kTH1D, {{2, 0.5, 2.5, "Tracks"}}); + registry.add("VTXc", "VTXc", kTH1F, {{100, -20., 20., "vtx"}}); + registry.add("VTX", "VTX", kTH1F, {{100, -20., 20., "vtx"}}); + registry.add("SEcand", "SEcand", kTH1F, {{2, 0.5, 2.5}}); + registry.add("SE", "SE", kTH1F, {invMassAxis}); + registry.add("ME", "ME", kTH1F, {invMassAxis}); + registry.add("SEvsPt", "SEvsPt", kTH2D, {invMassAxis, ptAxis}); + registry.add("MEvsPt", "MEvsPt", kTH2D, {invMassAxis, ptAxis}); + registry.add("eta", Form("eta_%i", (int)_particlePDG_1), kTH2F, {ptAxis, {100, -10., 10., "#eta"}}); + registry.add("p_first", Form("p_%i", (int)_particlePDG_1), kTH1F, {ptAxis}); + registry.add("dcaXY_first", Form("dca_%i", (int)_particlePDG_1), kTH2F, {ptAxis, dcaXyAxis}); + registry.add("nsigmaTOF_first", Form("nsigmaTOF_%i", (int)_particlePDG_1), kTH2F, {ptAxis, {100, -10., 10., Form("N#sigma_{TOF}(%s))", pdgToSymbol(_particlePDG_1))}}); + registry.add("nsigmaTPC_first", Form("nsigmaTPC_%i", (int)_particlePDG_1), kTH2F, {ptAxis, {100, -10., 10., Form("N#sigma_{TPC}(%s))", pdgToSymbol(_particlePDG_1))}}); + registry.add("rapidity_first", Form("rapidity_%i", (int)_particlePDG_1), kTH2F, {ptAxis, {100, -10., 10., Form("y(%s)", pdgToSymbol(_particlePDG_1))}}); + + if (!IsIdentical) { + registry.add("p_second", Form("p_%i", (int)_particlePDG_2), kTH1F, {ptAxis}); + registry.add("dcaXY_second", Form("dca_%i", (int)_particlePDG_2), kTH2F, {ptAxis, dcaXyAxis}); + registry.add("nsigmaTOF_second", Form("nsigmaTOF_%i", (int)_particlePDG_2), kTH2F, {ptAxis, {100, -10., 10., Form("N#sigma_{TOF}(%s))", pdgToSymbol(_particlePDG_2))}}); + registry.add("nsigmaTPC_second", Form("nsigmaTPC_%i", (int)_particlePDG_2), kTH2F, {ptAxis, {100, -10., 10., Form("N#sigma_{TPC}(%s))", pdgToSymbol(_particlePDG_2))}}); + registry.add("rapidity_second", Form("rapidity_%i", (int)_particlePDG_2), kTH2F, {ptAxis, {100, -10., 10., Form("y(%s)", pdgToSymbol(_particlePDG_2))}}); + } + } + + template + void mixTracks(Type const& tracks) + { // template for identical particles from the same collision + + for (long unsigned int ii = 0; ii < tracks.size(); ii++) { // nested loop for all the combinations + for (long unsigned int iii = ii + 1; iii < tracks.size(); iii++) { + + Pair->SetPair(tracks[ii], tracks[iii]); + + registry.fill(HIST("SEcand"), 1.f); + if (!Pair->IsClosePair()) { + continue; + } + if (std::abs(Pair->GetRapidity()) > 0.5f) { + continue; + } + registry.fill(HIST("SEcand"), 2.f); + registry.fill(HIST("SE"), Pair->GetInvMass()); // close pair rejection and fillig the SE histo + registry.fill(HIST("SEvsPt"), Pair->GetInvMass(), Pair->GetPt()); // close pair rejection and fillig the SE histo + } + } + } + + template + void mixTracks(Type const& tracks1, Type const& tracks2) + { + for (auto ii : tracks1) { + for (auto iii : tracks2) { + + Pair->SetPair(ii, iii); + + if constexpr (isSameEvent) { + registry.fill(HIST("SEcand"), 1.f); + } + if (!Pair->IsClosePair()) { + continue; + } + if (std::abs(Pair->GetRapidity()) > 0.5f) { + continue; + } + if constexpr (isSameEvent) { + registry.fill(HIST("SEcand"), 2.f); + registry.fill(HIST("SE"), Pair->GetInvMass()); + registry.fill(HIST("SEvsPt"), Pair->GetInvMass(), Pair->GetPt()); + } else { + registry.fill(HIST("ME"), Pair->GetInvMass()); + registry.fill(HIST("MEvsPt"), Pair->GetInvMass(), Pair->GetPt()); + } + } + } + } + + void process(soa::Filtered const& collisions, soa::Filtered const& tracks) + { + if (_particlePDG_1 == 0 || _particlePDG_2 == 0) + LOGF(fatal, "One of passed PDG is 0!!!"); + registry.fill(HIST("Trks"), 2.f, tracks.size()); + for (auto c : collisions) { + registry.fill(HIST("VTXc"), c.posZ()); + } + + for (auto track : tracks) { + if (track.itsChi2NCl() > _itsChi2NCl) { + continue; + } + if (track.tpcChi2NCl() > _tpcChi2NCl) { + continue; + } + if (track.tpcCrossedRowsOverFindableCls() < _tpcCrossedRowsOverFindableCls) { + continue; + } + if (track.dcaXY() < _dcaXYmin || track.dcaXY() > _dcaXY) { + continue; + } + if (track.dcaZ() < _dcaZmin || track.dcaZ() > _dcaZ) { + continue; + } + + registry.fill(HIST("Trks"), 1); + registry.fill(HIST("VTX"), track.singleCollSel().posZ()); + if (abs(track.singleCollSel().posZ()) > _vertexZ) + continue; + registry.fill(HIST("eta"), track.pt(), track.eta()); + if (abs(track.rapidity(particle_mass(_particlePDG_1))) > _maxy) { + continue; + } + registry.fill(HIST("rapidity_first"), track.pt(), track.rapidity(particle_mass(_particlePDG_1))); + + if ((track.sign() == _sign_1) && + (track.p() < _PIDtrshld_1 ? o2::aod::singletrackselector::TPCselection(track, TPCcuts_1) : o2::aod::singletrackselector::TOFselection(track, TOFcuts_1))) { // filling the map: eventID <-> selected particles1 + selectedtracks_1[track.singleCollSelId()].push_back(std::make_shared(track)); + + registry.fill(HIST("p_first"), track.p()); + registry.fill(HIST("dcaXY_first"), track.pt(), track.dcaXY()); + switch (_particlePDG_1) { + case 211: + registry.fill(HIST("nsigmaTOF_first"), track.p(), track.tofNSigmaPi()); + registry.fill(HIST("nsigmaTPC_first"), track.p(), track.tpcNSigmaPi()); + break; + case 321: + registry.fill(HIST("nsigmaTOF_first"), track.p(), track.tofNSigmaKa()); + registry.fill(HIST("nsigmaTPC_first"), track.p(), track.tpcNSigmaKa()); + break; + case 2212: + registry.fill(HIST("nsigmaTOF_first"), track.p(), track.tofNSigmaPr()); + registry.fill(HIST("nsigmaTPC_first"), track.p(), track.tpcNSigmaPr()); + break; + case 1000010020: + registry.fill(HIST("nsigmaTOF_first"), track.p(), track.tofNSigmaDe()); + registry.fill(HIST("nsigmaTPC_first"), track.p(), track.tpcNSigmaDe()); + break; + default: + LOG(fatal) << "PDG code 1: " << _particlePDG_1 << " is not supported!!!"; + } + } + + if (IsIdentical) + continue; + else if ((track.sign() == _sign_2) && + (_particlePDGtoReject != 0 || !TOFselection(track, std::make_pair(_particlePDGtoReject, _rejectWithinNsigmaTOF))) && + (track.p() < _PIDtrshld_2 ? o2::aod::singletrackselector::TPCselection(track, TPCcuts_2) : o2::aod::singletrackselector::TOFselection(track, TOFcuts_2))) { // filling the map: eventID <-> selected particles2 if (see condition above ^) + selectedtracks_2[track.singleCollSelId()].push_back(std::make_shared(track)); + + registry.fill(HIST("p_second"), track.p()); + registry.fill(HIST("dcaXY_second"), track.pt(), track.dcaXY()); + switch (_particlePDG_2) { + case 211: + registry.fill(HIST("nsigmaTOF_second"), track.p(), track.tofNSigmaPi()); + registry.fill(HIST("nsigmaTPC_second"), track.p(), track.tpcNSigmaPi()); + break; + case 321: + registry.fill(HIST("nsigmaTOF_second"), track.p(), track.tofNSigmaKa()); + registry.fill(HIST("nsigmaTPC_second"), track.p(), track.tpcNSigmaKa()); + break; + case 2212: + registry.fill(HIST("nsigmaTOF_second"), track.p(), track.tofNSigmaPr()); + registry.fill(HIST("nsigmaTPC_second"), track.p(), track.tpcNSigmaPr()); + break; + case 1000010020: + registry.fill(HIST("nsigmaTOF_second"), track.p(), track.tofNSigmaDe()); + registry.fill(HIST("nsigmaTPC_second"), track.p(), track.tpcNSigmaDe()); + break; + default: + LOG(fatal) << "PDG code 2: " << _particlePDG_2 << " is not supported!!!"; + } + } + } + + for (auto collision : collisions) { + if (selectedtracks_1.find(collision.globalIndex()) == selectedtracks_1.end()) { + if (IsIdentical) + continue; + else if (selectedtracks_2.find(collision.globalIndex()) == selectedtracks_2.end()) + continue; + } + + mixbins[std::pair{round(collision.posZ() / _vertexbinwidth), floor(collision.mult() / _multbinwidth)}].push_back(std::make_shared(collision)); + } + + //====================================== mixing starts here ====================================== + + if (IsIdentical) { //====================================== mixing identical ====================================== + + for (auto i = mixbins.begin(); i != mixbins.end(); i++) { // iterating over all vertex&mult bins + + for (long unsigned int indx1 = 0; indx1 < (i->second).size(); indx1++) { // loop over all the events in each vertex&mult bin + + auto col1 = (i->second)[indx1]; + + Pair->SetMagField1(col1->magField()); + Pair->SetMagField2(col1->magField()); + + mixTracks(selectedtracks_1[col1->index()]); // mixing SE identical + if (!doMixedEvent) { + continue; + } + + for (long unsigned int indx2 = indx1 + 1; indx2 < (i->second).size(); indx2++) { // nested loop for all the combinations of collisions in a chosen mult/vertex bin + + auto col2 = (i->second)[indx2]; + + Pair->SetMagField2(col2->magField()); + mixTracks(selectedtracks_1[col1->index()], selectedtracks_1[col2->index()]); // mixing ME identical + } + } + } + + } //====================================== end of mixing identical ====================================== + + else { //====================================== mixing non-identical ====================================== + + for (auto i = mixbins.begin(); i != mixbins.end(); i++) { // iterating over all vertex&mult bins + + for (long unsigned int indx1 = 0; indx1 < (i->second).size(); indx1++) { // loop over all the events in each vertex&mult bin + + auto col1 = (i->second)[indx1]; + + Pair->SetMagField1(col1->magField()); + Pair->SetMagField2(col1->magField()); + + mixTracks(selectedtracks_1[col1->index()], selectedtracks_2[col1->index()]); // mixing SE non-identical + if (!doMixedEvent) { + continue; + } + + for (long unsigned int indx2 = indx1 + 1; indx2 < (i->second).size(); indx2++) { // nested loop for all the combinations of collisions in a chosen mult/vertex bin + + auto col2 = (i->second)[indx2]; + + Pair->SetMagField2(col2->magField()); + mixTracks(selectedtracks_1[col1->index()], selectedtracks_2[col2->index()]); // mixing ME non-identical + } + } + } + + } //====================================== end of mixing non-identical ====================================== + + // clearing up + for (auto i = selectedtracks_1.begin(); i != selectedtracks_1.end(); i++) + (i->second).clear(); + selectedtracks_1.clear(); + + if (!IsIdentical) { + for (auto i = selectedtracks_2.begin(); i != selectedtracks_2.end(); i++) + (i->second).clear(); + selectedtracks_2.clear(); + } + + for (auto i = mixbins.begin(); i != mixbins.end(); i++) + (i->second).clear(); + mixbins.clear(); + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{adaptAnalysisTask(cfgc)}; +} diff --git a/PWGLF/Tasks/kinkAnalysis.cxx b/PWGLF/Tasks/Strangeness/kinkAnalysis.cxx similarity index 100% rename from PWGLF/Tasks/kinkAnalysis.cxx rename to PWGLF/Tasks/Strangeness/kinkAnalysis.cxx diff --git a/PWGLF/Tasks/lambdakzeroanalysisMC.cxx b/PWGLF/Tasks/Strangeness/lambdakzeroanalysisMC.cxx similarity index 100% rename from PWGLF/Tasks/lambdakzeroanalysisMC.cxx rename to PWGLF/Tasks/Strangeness/lambdakzeroanalysisMC.cxx diff --git a/PWGLF/Tasks/nonPromptCascade.cxx b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx similarity index 98% rename from PWGLF/Tasks/nonPromptCascade.cxx rename to PWGLF/Tasks/Strangeness/nonPromptCascade.cxx index cd7f79e8073..799bb6c2173 100644 --- a/PWGLF/Tasks/nonPromptCascade.cxx +++ b/PWGLF/Tasks/Strangeness/nonPromptCascade.cxx @@ -724,31 +724,38 @@ struct NonPromptCascadeTask { // QA PID float nSigmaTPC[nParticles]{bachelor.tpcNSigmaKa(), bachelor.tpcNSigmaPi(), protonTrack.tpcNSigmaPr(), pionTrack.tpcNSigmaPi()}; + bool isBachelorSurvived = false; if (isOmega) { if (bachelor.hasTPC()) { LOG(debug) << "TPCSignal bachelor " << bachelor.sign() << "/" << bachelor.tpcInnerParam() << "/" << bachelor.tpcSignal(); - if (nSigmaTPC[0] < cfgCutsPID->get(0u, 0u) || nSigmaTPC[0] > cfgCutsPID->get(0u, 1u)) { - continue; + if (nSigmaTPC[0] > cfgCutsPID->get(0u, 0u) && nSigmaTPC[0] < cfgCutsPID->get(0u, 1u)) { + registry.fill(HIST("h_PIDcutsOmega"), 3, massOmega); + isBachelorSurvived = true; } } - registry.fill(HIST("h_PIDcutsOmega"), 3, massOmega); } if (bachelor.hasTPC()) { LOG(debug) << "TPCSignal bachelor " << bachelor.sign() << "/" << bachelor.tpcInnerParam() << "/" << bachelor.tpcSignal(); - if (nSigmaTPC[1] < cfgCutsPID->get(1u, 0u) || nSigmaTPC[1] > cfgCutsPID->get(1u, 1u)) { - continue; + if (nSigmaTPC[1] > cfgCutsPID->get(1u, 0u) && nSigmaTPC[1] < cfgCutsPID->get(1u, 1u)) { + registry.fill(HIST("h_PIDcutsXi"), 3, massXi); + isBachelorSurvived = true; } } - registry.fill(HIST("h_PIDcutsXi"), 3, massXi); + + if (!isBachelorSurvived) { + continue; + } LOG(debug) << "TPCSignal protonTrack " << protonTrack.sign() << "/" << protonTrack.tpcInnerParam() << "/" << protonTrack.tpcSignal(); if (nSigmaTPC[2] < cfgCutsPID->get(2u, 0u) || nSigmaTPC[2] > cfgCutsPID->get(2u, 1u)) { continue; } + if (isOmega) { + registry.fill(HIST("h_PIDcutsOmega"), 4, massOmega); + } registry.fill(HIST("h_PIDcutsXi"), 4, massXi); - registry.fill(HIST("h_PIDcutsOmega"), 4, massOmega); LOG(debug) << "TPCSignal ntrack " << pionTrack.sign() << "/" << pionTrack.tpcInnerParam() << "/" << pionTrack.tpcSignal(); if (nSigmaTPC[3] < cfgCutsPID->get(3u, 0u) || nSigmaTPC[3] > cfgCutsPID->get(3u, 1u)) { diff --git a/PWGLF/Tasks/v0postprocessing.cxx b/PWGLF/Tasks/Strangeness/v0postprocessing.cxx similarity index 100% rename from PWGLF/Tasks/v0postprocessing.cxx rename to PWGLF/Tasks/Strangeness/v0postprocessing.cxx diff --git a/PWGLF/Tasks/vzero_cascade_absorption.cxx b/PWGLF/Tasks/Strangeness/vzero_cascade_absorption.cxx similarity index 100% rename from PWGLF/Tasks/vzero_cascade_absorption.cxx rename to PWGLF/Tasks/Strangeness/vzero_cascade_absorption.cxx diff --git a/PWGLF/Tasks/hypertriton3bodyMCQA.cxx b/PWGLF/Tasks/hypertriton3bodyMCQA.cxx deleted file mode 100644 index 4c1b0884a53..00000000000 --- a/PWGLF/Tasks/hypertriton3bodyMCQA.cxx +++ /dev/null @@ -1,1029 +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. -// -// Example StoredVtx3BodyDatas analysis task -// ======================== -// -// This code loops over a StoredVtx3BodyDatas table and produces some -// standard analysis output. It requires either -// the hypertriton3bodybuilder or hypertriton3bodyfinder (not recommaended) tasks -// to have been executed in the workflow (before). -// -// author: yuanzhe.wang@cern.ch - -#include -#include -#include - -#include "Framework/runDataProcessing.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 "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/Vtx3BodyTables.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 "CommonConstants/PhysicsConstants.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; -using std::array; - -using MyTracks = soa::Join; - -template -bool is3bodyDecayedH3L(TMCParticle const& particle) -{ - if (particle.pdgCode() != 1010010030 && particle.pdgCode() != -1010010030) { - return false; - } - bool haveProton = false, havePion = false, haveDeuteron = false; - bool haveAntiProton = false, haveAntiPion = false, haveAntiDeuteron = false; - for (auto& mcparticleDaughter : particle.template daughters_as()) { - if (mcparticleDaughter.pdgCode() == 2212) - haveProton = true; - if (mcparticleDaughter.pdgCode() == -2212) - haveAntiProton = true; - if (mcparticleDaughter.pdgCode() == 211) - havePion = true; - if (mcparticleDaughter.pdgCode() == -211) - haveAntiPion = true; - if (mcparticleDaughter.pdgCode() == 1000010020) - haveDeuteron = true; - if (mcparticleDaughter.pdgCode() == -1000010020) - haveAntiDeuteron = true; - } - if (haveProton && haveAntiPion && haveDeuteron && particle.pdgCode() == 1010010030) { - return true; - } else if (haveAntiProton && havePion && haveAntiDeuteron && particle.pdgCode() == -1010010030) { - return true; - } - return false; -} - -/* template - bool is3bodyDecayedH3L(TMCParticle const& mctrack0, TMCParticle const& mctrack1, TMCParticle const& mctrack2) - { - bool flag = false; - for (auto& particleMother : mctrack0.mothers_as()) { - if (particleMother.pdgCode() != 1010010030 && particleMother.pdgCode() != -1010010030) { - continue; - } - bool flag1 = false, flag2 = false; - for (auto& mcparticleDaughter : particle.template daughters_as()) { - if(mcparticleDaughter.globalIndex() == mctrack1.globalIndex()) - flag1 = true; - if(mcparticleDaughter.globalIndex() == mctrack2.globalIndex()) - flag2 = true; - } - if (flag1 && flag2) - flag = true; - } - return flag; - }*/ - -struct hypertriton3bodyQaMc { - // Basic checks - HistogramRegistry registry{ - "registry", - { - {"hVtxRadius", "hVtxRadius", {HistType::kTH1F, {{1000, 0.0f, 100.0f, "cm"}}}}, - {"hVtxCosPA", "hVtxCosPA", {HistType::kTH1F, {{1000, 0.95f, 1.0f}}}}, - {"hDCATrack0ToPV", "hDCAPosToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCATrack1ToPV", "hDCANegToPV", {HistType::kTH1F, {{1000, 10.0f, 10.0f, "cm"}}}}, - {"hDCATrack2ToPV", "hDCANegToPV", {HistType::kTH1F, {{1000, 10.0f, 10.0f, "cm"}}}}, - {"hDCAVtxDau", "hDCAVtxDau", {HistType::kTH1F, {{1000, 0.0f, 10.0f, "cm^{2}"}}}}, - {"hVtxPt", "hVtxPt", {HistType::kTH1F, {{200, 0.0f, 10.0f, "p_{T}"}}}}, - {"hTrack0Pt", "hTrack0Pt", {HistType::kTH1F, {{200, 0.0f, 10.0f, "p_{T}"}}}}, - {"hTrack1Pt", "hTrack1Pt", {HistType::kTH1F, {{200, 0.0f, 10.0f, "p_{T}"}}}}, - {"hTrack2Pt", "hTrack2Pt", {HistType::kTH1F, {{200, 0.0f, 10.0f, "p_{T}"}}}}, - }, - }; - void init(InitContext const&) - { - AxisSpec massAxis = {120, 2.9f, 3.2f, "Inv. Mass (GeV/c^{2})"}; - - registry.add("hMassHypertriton", "hMassHypertriton", {HistType::kTH1F, {massAxis}}); - registry.add("hMassAntiHypertriton", "hMassAntiHypertriton", {HistType::kTH1F, {massAxis}}); - } - void process(aod::Collision const& collision, aod::Vtx3BodyDatas const& vtx3bodydatas, MyTracks const& tracks) - { - - for (auto& vtx : vtx3bodydatas) { - registry.fill(HIST("hVtxRadius"), vtx.vtxradius()); - registry.fill(HIST("hVtxCosPA"), vtx.vtxcosPA(collision.posX(), collision.posY(), collision.posZ())); - registry.fill(HIST("hDCATrack0ToPV"), vtx.dcatrack0topv()); - registry.fill(HIST("hDCATrack1ToPV"), vtx.dcatrack1topv()); - registry.fill(HIST("hDCATrack2ToPV"), vtx.dcatrack2topv()); - registry.fill(HIST("hDCAVtxDau"), vtx.dcaVtxdaughters()); - registry.fill(HIST("hVtxPt"), vtx.pt()); - registry.fill(HIST("hTrack0Pt"), vtx.track0pt()); - registry.fill(HIST("hTrack1Pt"), vtx.track1pt()); - registry.fill(HIST("hTrack2Pt"), vtx.track2pt()); - registry.fill(HIST("hMassHypertriton"), vtx.mHypertriton()); - registry.fill(HIST("hMassAntiHypertriton"), vtx.mAntiHypertriton()); - } - } -}; - -struct hypertriton3bodyAnalysisMc { - - // Selection criteria - Configurable vtxcospa{"vtxcospa", 0.9, "Vtx CosPA"}; // double -> N.B. dcos(x)/dx = 0 at x=0) - Configurable dcavtxdau{"dcavtxdau", 1.0, "DCA Vtx Daughters"}; // loose cut - Configurable dcapiontopv{"dcapiontopv", .00, "DCA Pion To PV"}; - Configurable etacut{"etacut", 1, "etacut"}; - Configurable rapidity{"rapidity", 1, "rapidity"}; - Configurable TofPidNsigmaMin{"TofPidNsigmaMin", -4, "TofPidNsigmaMin"}; - Configurable TofPidNsigmaMax{"TofPidNsigmaMax", 8, "TofPidNsigmaMax"}; - Configurable TpcPidNsigmaCut{"TpcPidNsigmaCut", 5, "TpcPidNsigmaCut"}; - Configurable eventSelection{"eventSelection", true, "event selection"}; - Configurable lifetimecut{"lifetimecut", 40., "lifetimecut"}; - Configurable minProtonPt{"minProtonPt", 0.3, "minProtonPt"}; - Configurable maxProtonPt{"maxProtonPt", 5, "maxProtonPt"}; - Configurable minPionPt{"minPionPt", 0.1, "minPionPt"}; - Configurable maxPionPt{"maxPionPt", 1.2, "maxPionPt"}; - Configurable minDeuteronPt{"minDeuteronPt", 0.6, "minDeuteronPt"}; - Configurable maxDeuteronPt{"maxDeuteronPt", 10, "maxDeuteronPt"}; - Configurable minDeuteronPUseTOF{"minDeuteronPUseTOF", 1, "minDeuteronPt Enable TOF PID"}; - Configurable h3LMassLowerlimit{"h3LMassLowerlimit", 2.96, "Hypertriton mass lower limit"}; - Configurable h3LMassUpperlimit{"h3LMassUpperlimit", 3.04, "Hypertriton mass upper limit"}; - Configurable mincrossedrowsproton{"mincrossedrowsproton", 90, "min tpc crossed rows for pion"}; - Configurable mincrossedrowspion{"mincrossedrowspion", 70, "min tpc crossed rows"}; - Configurable mincrossedrowsdeuteron{"mincrossedrowsdeuteron", 100, "min tpc crossed rows for deuteron"}; - Configurable mcsigma{"mcsigma", 0.0015, "sigma of mc invariant mass fit"}; // obtained from MC - - HistogramRegistry registry{ - "registry", - { - {"hSelectedEventCounter", "hSelectedEventCounter", {HistType::kTH1F, {{3, 0.0f, 3.0f}}}}, - {"hSelectedCandidatesCounter", "hSelectedCandidatesCounter", {HistType::kTH1F, {{11, 0.0f, 11.0f}}}}, - {"hSelectedTrueHypertritonCounter", "hSelectedTrueHypertritonCounter", {HistType::kTH1F, {{11, 0.0f, 11.0f}}}}, - {"hTestCounter", "hTestCounter", {HistType::kTH1F, {{9, 0.0f, 9.0f}}}}, - {"hMassHypertriton", "hMassHypertriton", {HistType::kTH1F, {{80, 2.96f, 3.04f}}}}, - {"hMassAntiHypertriton", "hMassAntiHypertriton", {HistType::kTH1F, {{80, 2.96f, 3.04f}}}}, - {"hMassHypertritonTotal", "hMassHypertritonTotal", {HistType::kTH1F, {{300, 2.9f, 3.2f}}}}, - {"hPtProton", "hPtProton", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtAntiPion", "hPtAntiPion", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtDeuteron", "hPtDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtAntiProton", "hPtAntiProton", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtPion", "hPtPion", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtAntiDeuteron", "hPtAntiDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDCAProtonToPV", "hDCAProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCAPionToPV", "hDCAPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCADeuteronToPV", "hDCADeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hProtonTPCNcls", "hProtonTPCNcls", {HistType::kTH1F, {{180, 0, 180, "TPC cluster"}}}}, - {"hPionTPCNcls", "hPionTPCNcls", {HistType::kTH1F, {{180, 0, 180, "TPC cluster"}}}}, - {"hDeuteronTPCNcls", "hDeuteronTPCNcls", {HistType::kTH1F, {{180, 0, 180, "TPC cluster"}}}}, - {"hVtxCosPA", "hVtxCosPA", {HistType::kTH1F, {{1000, 0.9f, 1.0f}}}}, - {"hDCAVtxDau", "hDCAVtxDau", {HistType::kTH1F, {{1000, 0.0f, 10.0f, "cm^{2}"}}}}, - {"hTOFPIDDeuteron", "hTOFPIDDeuteron", {HistType::kTH1F, {{2000, -100.0f, 100.0f}}}}, - {"hTPCPIDProton", "hTPCPIDProton", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, - {"hTPCPIDPion", "hTPCPIDPion", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, - {"hTPCPIDDeuteron", "hTPCPIDDeuteron", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, - {"hProtonTPCBB", "hProtonTPCBB", {HistType::kTH2F, {{160, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hPionTPCBB", "hPionTPCBB", {HistType::kTH2F, {{160, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hDeuteronTPCBB", "hDeuteronTPCBB", {HistType::kTH2F, {{160, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hProtonTPCVsPt", "hProtonTPCVsPt", {HistType::kTH2F, {{50, 0.0f, 5.0f, "#it{p}_{T} (GeV/c)"}, {240, -6.0f, 6.0f, "TPC n#sigma"}}}}, - {"hPionTPCVsPt", "hPionTPCVsPt", {HistType::kTH2F, {{20, 0.0f, 2.0f, "#it{p}_{T} (GeV/c)"}, {240, -6.0f, 6.0f, "TPC n#sigma"}}}}, - {"hDeuteronTPCVsPt", "hDeuteronTPCVsPt", {HistType::kTH2F, {{80, 0.0f, 8.0f, "#it{p}_{T} (GeV/c)"}, {240, -6.0f, 6.0f, "TPC n#sigma"}}}}, - - {"hDalitz", "hDalitz", {HistType::kTH2F, {{120, 7.85, 8.45, "M^{2}(dp) (GeV^{2}/c^{4})"}, {60, 1.1, 1.4, "M^{2}(p#pi) (GeV^{2}/c^{4})"}}}}, - {"h3dMassHypertriton", "h3dMassHypertriton", {HistType::kTH3F, {{20, 0.0f, 100.0f, "Cent (%)"}, {200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}}}}, - {"h3dMassAntiHypertriton", "h3dMassAntiHypertriton", {HistType::kTH3F, {{20, 0.0f, 100.0f, "Cent (%)"}, {200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}}}}, - {"h3dTotalHypertriton", "h3dTotalHypertriton", {HistType::kTH3F, {{50, 0, 50, "ct(cm)"}, {200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}}}}, - {"h3dTotalTrueHypertriton", "h3dTotalTrueHypertriton", {HistType::kTH3F, {{50, 0, 50, "ct(cm)"}, {200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}}}}, - }, - }; - - //------------------------------------------------------------------ - // Fill stats histograms - enum vtxstep { kCandAll = 0, - kCandCosPA, - kCandDauEta, - kCandRapidity, - kCandct, - kCandDcaDau, - kCandTOFPID, - kCandTPCPID, - kCandTPCNcls, - kCandDauPt, - kCandDcaToPV, - kNVtxSteps }; - - Configurable saveDcaHist{"saveDcaHist", 0, "saveDcaHist"}; - ConfigurableAxis dcaBinning{"dca-binning", {200, 0.0f, 1.0f}, ""}; - ConfigurableAxis ptBinning{"pt-binning", {200, 0.0f, 10.0f}, ""}; - - void FillCandCounter(int kn, bool istrue = false) - { - registry.fill(HIST("hSelectedCandidatesCounter"), kn); - if (istrue) { - registry.fill(HIST("hSelectedTrueHypertritonCounter"), kn); - } - } - - void init(InitContext const&) - { - AxisSpec dcaAxis = {dcaBinning, "DCA (cm)"}; - AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/c)"}; - AxisSpec massAxisHypertriton = {80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}; - - if (saveDcaHist == 1) { - registry.add("h3dMassHypertritonDca", "h3dMassHypertritonDca", {HistType::kTH3F, {dcaAxis, ptAxis, massAxisHypertriton}}); - registry.add("h3dMassAntiHypertritonDca", "h3dMassAntiHypertritonDca", {HistType::kTH3F, {dcaAxis, ptAxis, massAxisHypertriton}}); - } - - TString CandCounterbinLabel[11] = {"Total", "VtxCosPA", "TrackEta", "MomRapidity", "Lifetime", "DcaV0Dau", "d TOFPID", "TPCPID&Mass", "TPCNcls", "DauPt", "PionDcatoPV"}; - for (int i{0}; i < kNVtxSteps; i++) { - registry.get(HIST("hSelectedCandidatesCounter"))->GetXaxis()->SetBinLabel(i + 1, CandCounterbinLabel[i]); - registry.get(HIST("hSelectedTrueHypertritonCounter"))->GetXaxis()->SetBinLabel(i + 1, CandCounterbinLabel[i]); - } - } - - void process(soa::Join::iterator const& collision, aod::Vtx3BodyDatas const& vtx3bodydatas, MyTracks const& tracks, aod::McParticles const& particlesMC) - { - registry.fill(HIST("hSelectedEventCounter"), 0.5); - if (eventSelection && !collision.sel8()) { - return; - } - registry.fill(HIST("hSelectedEventCounter"), 1.5); - - bool if_hasvtx = false; - - for (auto& vtx : vtx3bodydatas) { - // couldn't filter cosPA and radius variables (dynamic columns) - - // int lLabel = -1; - int lPDG = -1; - float lPt = -1; - double MClifetime = -1; - bool isFromHypertriton = false; - auto track0 = vtx.track0_as(); - auto track1 = vtx.track1_as(); - auto track2 = vtx.track2_as(); - if (track0.has_mcParticle() && track1.has_mcParticle() && track2.has_mcParticle()) { - auto lMCTrack0 = track0.mcParticle_as(); - auto lMCTrack1 = track1.mcParticle_as(); - auto lMCTrack2 = track2.mcParticle_as(); - if (lMCTrack0.has_mothers() && lMCTrack1.has_mothers() && lMCTrack2.has_mothers()) { - for (auto& lMother0 : lMCTrack0.mothers_as()) { - for (auto& lMother1 : lMCTrack1.mothers_as()) { - for (auto& lMother2 : lMCTrack2.mothers_as()) { - if (lMother0.globalIndex() == lMother1.globalIndex() && lMother0.globalIndex() == lMother2.globalIndex()) { - // lLabel = lMother1.globalIndex(); - lPt = lMother1.pt(); - lPDG = lMother1.pdgCode(); - if ((lPDG == 1010010030 && lMCTrack0.pdgCode() == 2212 && lMCTrack1.pdgCode() == -211 && lMCTrack2.pdgCode() == 1000010020) || - (lPDG == -1010010030 && lMCTrack0.pdgCode() == 211 && lMCTrack1.pdgCode() == -2212 && lMCTrack2.pdgCode() == -1000010020)) { - isFromHypertriton = true; - MClifetime = RecoDecay::sqrtSumOfSquares(lMCTrack2.vx() - lMother2.vx(), lMCTrack2.vy() - lMother2.vy(), lMCTrack2.vz() - lMother2.vz()) * o2::constants::physics::MassHyperTriton / lMother2.p(); - } - } - } - } - } - } - } - - FillCandCounter(kCandAll, isFromHypertriton); - - if (vtx.vtxcosPA(collision.posX(), collision.posY(), collision.posZ()) < vtxcospa) { - continue; - } - FillCandCounter(kCandCosPA, isFromHypertriton); - if (TMath::Abs(vtx.track0_as().eta()) > etacut || TMath::Abs(vtx.track1_as().eta()) > etacut || TMath::Abs(vtx.track2_as().eta()) > etacut) { - continue; - } - FillCandCounter(kCandDauEta, isFromHypertriton); - if (TMath::Abs(vtx.yHypertriton()) > rapidity) { - continue; - } - FillCandCounter(kCandRapidity, isFromHypertriton); - double ct = vtx.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassHyperTriton; - if (ct > lifetimecut) { - continue; - } - FillCandCounter(kCandct, isFromHypertriton); - if (vtx.dcaVtxdaughters() > dcavtxdau) { - continue; - } - FillCandCounter(kCandDcaDau, isFromHypertriton); - if ((track2.tofNSigmaDe() < TofPidNsigmaMin || track2.tofNSigmaDe() > TofPidNsigmaMax) && track2.p() > minDeuteronPUseTOF) { - continue; - } - FillCandCounter(kCandTOFPID, isFromHypertriton); - - // 3sigma region for Dalitz plot - double lowerlimit = o2::constants::physics::MassHyperTriton - 3 * mcsigma; - double upperlimit = o2::constants::physics::MassHyperTriton + 3 * mcsigma; - - // Hypertriton - if (TMath::Abs(vtx.track0_as().tpcNSigmaPr()) < TpcPidNsigmaCut && TMath::Abs(vtx.track1_as().tpcNSigmaPi()) < TpcPidNsigmaCut && TMath::Abs(vtx.track2_as().tpcNSigmaDe()) < TpcPidNsigmaCut && vtx.mHypertriton() > h3LMassLowerlimit && vtx.mHypertriton() < h3LMassUpperlimit) { - - FillCandCounter(kCandTPCPID, isFromHypertriton); - - if (track0.tpcNClsCrossedRows() > mincrossedrowsproton && track1.tpcNClsCrossedRows() > mincrossedrowspion && track2.tpcNClsCrossedRows() > mincrossedrowsdeuteron) { - - FillCandCounter(kCandTPCNcls, isFromHypertriton); - - registry.fill(HIST("hTestCounter"), 0.5); - if (vtx.track1pt() > minPionPt && vtx.track1pt() < maxPionPt) { - registry.fill(HIST("hTestCounter"), 1.5); - if (vtx.track0pt() > minProtonPt && vtx.track0pt() < maxProtonPt) { - registry.fill(HIST("hTestCounter"), 2.5); - if (vtx.track2pt() > minDeuteronPt && vtx.track2pt() < maxDeuteronPt) { - registry.fill(HIST("hTestCounter"), 3.5); - } - } - } - - if (vtx.track0pt() > minProtonPt && vtx.track0pt() < maxProtonPt && vtx.track1pt() > minPionPt && vtx.track1pt() < maxPionPt && vtx.track2pt() > minDeuteronPt && vtx.track2pt() < maxDeuteronPt) { - FillCandCounter(kCandDauPt, isFromHypertriton); - - if (TMath::Abs(vtx.dcatrack1topv()) > dcapiontopv) { - if_hasvtx = true; - FillCandCounter(kCandDcaToPV, isFromHypertriton); - - registry.fill(HIST("hVtxCosPA"), vtx.vtxcosPA(collision.posX(), collision.posY(), collision.posZ())); - registry.fill(HIST("hDCAVtxDau"), vtx.dcaVtxdaughters()); - registry.fill(HIST("hPtProton"), vtx.track0pt()); - registry.fill(HIST("hPtAntiPion"), vtx.track1pt()); - registry.fill(HIST("hPtDeuteron"), vtx.track2pt()); - registry.fill(HIST("hDCAProtonToPV"), vtx.dcatrack0topv()); - registry.fill(HIST("hDCAPionToPV"), vtx.dcatrack1topv()); - registry.fill(HIST("hDCADeuteronToPV"), vtx.dcatrack2topv()); - registry.fill(HIST("hProtonTPCNcls"), track0.tpcNClsCrossedRows()); - registry.fill(HIST("hPionTPCNcls"), track1.tpcNClsCrossedRows()); - registry.fill(HIST("hDeuteronTPCNcls"), track2.tpcNClsCrossedRows()); - registry.fill(HIST("hTOFPIDDeuteron"), track2.tofNSigmaDe()); - registry.fill(HIST("hTPCPIDProton"), track0.tpcNSigmaPr()); - registry.fill(HIST("hTPCPIDPion"), track1.tpcNSigmaPi()); - registry.fill(HIST("hTPCPIDDeuteron"), track2.tpcNSigmaDe()); - registry.fill(HIST("hProtonTPCBB"), track0.p(), track0.tpcSignal()); - registry.fill(HIST("hPionTPCBB"), -track1.p(), track1.tpcSignal()); - registry.fill(HIST("hDeuteronTPCBB"), track2.p(), track0.tpcSignal()); - registry.fill(HIST("hProtonTPCVsPt"), vtx.track0pt(), track0.tpcNSigmaPr()); - registry.fill(HIST("hPionTPCVsPt"), vtx.track1pt(), track1.tpcNSigmaPi()); - registry.fill(HIST("hDeuteronTPCVsPt"), vtx.track2pt(), track2.tpcNSigmaDe()); - registry.fill(HIST("hMassHypertriton"), vtx.mHypertriton()); - registry.fill(HIST("hMassHypertritonTotal"), vtx.mHypertriton()); - registry.fill(HIST("h3dMassHypertriton"), 0., vtx.pt(), vtx.mHypertriton()); // collision.centV0M() instead of 0. once available - registry.fill(HIST("h3dTotalHypertriton"), ct, vtx.pt(), vtx.mHypertriton()); - if (vtx.mHypertriton() > lowerlimit && vtx.mHypertriton() < upperlimit) { - registry.fill(HIST("hDalitz"), RecoDecay::m2(array{array{vtx.pxtrack0(), vtx.pytrack0(), vtx.pztrack0()}, array{vtx.pxtrack2(), vtx.pytrack2(), vtx.pztrack2()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassDeuteron}), - RecoDecay::m2(array{array{vtx.pxtrack0(), vtx.pytrack0(), vtx.pztrack0()}, array{vtx.pxtrack1(), vtx.pytrack1(), vtx.pztrack1()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged})); - } - - if (isFromHypertriton) { - registry.fill(HIST("h3dTotalTrueHypertriton"), MClifetime, lPt, vtx.mHypertriton()); - } - if (saveDcaHist == 1) { - registry.fill(HIST("h3dMassHypertritonDca"), vtx.dcaVtxdaughters(), vtx.pt(), vtx.mHypertriton()); - } - } - } - } - } - - // AntiHypertriton - if (TMath::Abs(vtx.track0_as().tpcNSigmaPi()) < TpcPidNsigmaCut && TMath::Abs(vtx.track1_as().tpcNSigmaPr()) < TpcPidNsigmaCut && TMath::Abs(vtx.track2_as().tpcNSigmaDe()) < TpcPidNsigmaCut && vtx.mAntiHypertriton() > h3LMassLowerlimit && vtx.mAntiHypertriton() < h3LMassUpperlimit) { - FillCandCounter(kCandTPCPID, isFromHypertriton); - - if (track0.tpcNClsCrossedRows() > mincrossedrowspion && track1.tpcNClsCrossedRows() > mincrossedrowsproton && track2.tpcNClsCrossedRows() > mincrossedrowsdeuteron) { - - FillCandCounter(kCandTPCNcls, isFromHypertriton); - - registry.fill(HIST("hTestCounter"), 0.5); - if (vtx.track0pt() > minPionPt && vtx.track0pt() < maxPionPt) { - registry.fill(HIST("hTestCounter"), 1.5); - if (vtx.track1pt() > minProtonPt && vtx.track1pt() < maxProtonPt) { - registry.fill(HIST("hTestCounter"), 2.5); - if (vtx.track2pt() > minDeuteronPt && vtx.track2pt() < maxDeuteronPt) { - registry.fill(HIST("hTestCounter"), 3.5); - } - } - } - - if (vtx.track0pt() > minPionPt && vtx.track0pt() < maxPionPt && vtx.track1pt() > minProtonPt && vtx.track1pt() < maxProtonPt && vtx.track2pt() > minDeuteronPt && vtx.track2pt() < maxDeuteronPt) { - FillCandCounter(kCandDauPt, isFromHypertriton); - - if (TMath::Abs(vtx.dcatrack0topv()) > dcapiontopv) { - if_hasvtx = true; - FillCandCounter(kCandDcaToPV, isFromHypertriton); - - registry.fill(HIST("hVtxCosPA"), vtx.vtxcosPA(collision.posX(), collision.posY(), collision.posZ())); - registry.fill(HIST("hDCAVtxDau"), vtx.dcaVtxdaughters()); - registry.fill(HIST("hPtAntiProton"), vtx.track1pt()); - registry.fill(HIST("hPtPion"), vtx.track0pt()); - registry.fill(HIST("hPtAntiDeuteron"), vtx.track2pt()); - registry.fill(HIST("hDCAProtonToPV"), vtx.dcatrack1topv()); - registry.fill(HIST("hDCAPionToPV"), vtx.dcatrack0topv()); - registry.fill(HIST("hDCADeuteronToPV"), vtx.dcatrack2topv()); - registry.fill(HIST("hProtonTPCNcls"), track1.tpcNClsCrossedRows()); - registry.fill(HIST("hPionTPCNcls"), track0.tpcNClsCrossedRows()); - registry.fill(HIST("hDeuteronTPCNcls"), track2.tpcNClsCrossedRows()); - registry.fill(HIST("hTOFPIDDeuteron"), track2.tofNSigmaDe()); - registry.fill(HIST("hTPCPIDProton"), track1.tpcNSigmaPr()); - registry.fill(HIST("hTPCPIDPion"), track0.tpcNSigmaPi()); - registry.fill(HIST("hTPCPIDDeuteron"), track2.tpcNSigmaDe()); - registry.fill(HIST("hProtonTPCBB"), -track1.p(), track1.tpcSignal()); - registry.fill(HIST("hPionTPCBB"), track0.p(), track0.tpcSignal()); - registry.fill(HIST("hDeuteronTPCBB"), -track2.p(), track0.tpcSignal()); - registry.fill(HIST("hProtonTPCVsPt"), vtx.track1pt(), track1.tpcNSigmaPr()); - registry.fill(HIST("hPionTPCVsPt"), vtx.track0pt(), track0.tpcNSigmaPi()); - registry.fill(HIST("hDeuteronTPCVsPt"), vtx.track2pt(), track2.tpcNSigmaDe()); - registry.fill(HIST("hMassAntiHypertriton"), vtx.mAntiHypertriton()); - registry.fill(HIST("hMassHypertritonTotal"), vtx.mAntiHypertriton()); - registry.fill(HIST("h3dMassAntiHypertriton"), 0., vtx.pt(), vtx.mAntiHypertriton()); // collision.centV0M() instead of 0. once available - registry.fill(HIST("h3dTotalHypertriton"), ct, vtx.pt(), vtx.mAntiHypertriton()); - if (vtx.mAntiHypertriton() > lowerlimit && vtx.mAntiHypertriton() < upperlimit) { - registry.fill(HIST("hDalitz"), RecoDecay::m2(array{array{vtx.pxtrack1(), vtx.pytrack1(), vtx.pztrack1()}, array{vtx.pxtrack2(), vtx.pytrack2(), vtx.pztrack2()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassDeuteron}), - RecoDecay::m2(array{array{vtx.pxtrack1(), vtx.pytrack1(), vtx.pztrack1()}, array{vtx.pxtrack0(), vtx.pytrack0(), vtx.pztrack0()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged})); - } - - if (isFromHypertriton) { - registry.fill(HIST("h3dTotalTrueHypertriton"), MClifetime, lPt, vtx.mAntiHypertriton()); - } - if (saveDcaHist == 1) { - registry.fill(HIST("h3dMassAntiHypertritonDca"), vtx.dcaVtxdaughters(), vtx.pt(), vtx.mAntiHypertriton()); - } - } - } - } - } - } - - if (if_hasvtx) - registry.fill(HIST("hSelectedEventCounter"), 2.5); - } -}; - -// check vtx3body with mclabels -struct hypertriton3bodyLabelCheck { - HistogramRegistry registry{ - "registry", - { - {"hLabeledVtxCounter", "hLabeledVtxCounter", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, - {"hMassTrueH3L", "hMassTrueH3L", {HistType::kTH1F, {{80, 2.96f, 3.04f}}}}, - {"hMassTrueH3LMatter", "hMassTrueH3LMatter", {HistType::kTH1F, {{80, 2.96f, 3.04f}}}}, - {"hMassTrueH3LAntiMatter", "hMassTrueH3LAntiMatter", {HistType::kTH1F, {{80, 2.96f, 3.04f}}}}, - }, - }; - - void init(InitContext const&) - { - registry.get(HIST("hLabeledVtxCounter"))->GetXaxis()->SetBinLabel(1, "Readin"); - registry.get(HIST("hLabeledVtxCounter"))->GetXaxis()->SetBinLabel(2, "TrueMCH3L"); - } - - Configurable eventSelection{"eventSelection", true, "event selection"}; - - void process(soa::Join::iterator const& collision) - { - // dummy function - } - PROCESS_SWITCH(hypertriton3bodyLabelCheck, process, "Donot check MC label tables", true); - - void processCheckLabel(soa::Join::iterator const& collision, soa::Join const& vtx3bodydatas, MyTracks const& tracks, aod::McParticles const& particlesMC) - { - if (eventSelection && !collision.sel8()) { - return; - } - - for (auto& vtx : vtx3bodydatas) { - registry.fill(HIST("hLabeledVtxCounter"), 0.5); - if (vtx.mcParticleId() != -1) { - auto mcparticle = vtx.mcParticle_as(); - if (mcparticle.pdgCode() == 1010010030) { - registry.fill(HIST("hLabeledVtxCounter"), 1.5); - registry.fill(HIST("hMassTrueH3L"), vtx.mHypertriton()); - registry.fill(HIST("hMassTrueH3LMatter"), vtx.mHypertriton()); - } else if (mcparticle.pdgCode() == -1010010030) { - registry.fill(HIST("hLabeledVtxCounter"), 1.5); - registry.fill(HIST("hMassTrueH3L"), vtx.mAntiHypertriton()); - registry.fill(HIST("hMassTrueH3LAntiMatter"), vtx.mAntiHypertriton()); - } - } - } - } - PROCESS_SWITCH(hypertriton3bodyLabelCheck, processCheckLabel, "Check MC label tables", false); -}; - -// check the properties of daughters candidates and true daughters -struct hypertriton3bodyTrackMcinfo { - // Basic checks - HistogramRegistry registry{ - "registry", - { - {"hTotalCollCounter", "hTotalCollCounter", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, - {"hParticleCount", "hParticleCount", {HistType::kTH1F, {{7, 0.0f, 7.0f}}}}, - - {"hTPCNClsCrossedRows", "hTPCNClsCrossedRows", {HistType::kTH1F, {{240, 0.0f, 240.0f}}}}, - {"hTrackEta", "hTrackEta", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hTrackITSNcls", "hTrackITSNcls", {HistType::kTH1F, {{10, 0.0f, 10.0f}}}}, - {"hTrackMcRapidity", "hTrackMcRapidity", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hTrackNsigmaProton", "hTrackNsigmaProton", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, - {"hTrackNsigmaPion", "hTrackNsigmaPion", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, - {"hTrackNsigmaDeuteron", "hTrackNsigmaDeuteron", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, - - {"hHypertritonEta", "hHypertritomEta", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hHypertritonMcRapidity", "hHypertritonMcRapidity", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hHypertritonMcPt", "hHypertritonMcPt", {HistType::kTH1F, {{300, 0.0f, 15.0f}}}}, - - {"hProtonCount", "hProtonCount", {HistType::kTH1F, {{6, 0.0f, 6.0f}}}}, - {"hProtonPt", "hProtonPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hProtonP", "hProtonP", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hProtonMcPt", "hProtonMcPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hProtonMcP", "hProtonMcP", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hProtonEta", "hProtonEta", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hProtonMcRapidity", "hProtonMcRapidity", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hProtonNsigmaProton", "hProtonNsigmaProton", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, - {"hProtonTPCNClsCrossedRows", "hProtonTPCNClsCrossedRows", {HistType::kTH1F, {{240, 0.0f, 240.0f}}}}, - {"hProtonTPCBB", "hProtonTPCBB", {HistType::kTH2F, {{320, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hProtonTPCBBAfterTPCNclsCut", "hProtonTPCBBAfterTPCNclsCut", {HistType::kTH2F, {{320, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hDauProtonPt", "hDauProtonPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDauProtonMcPt", "hDauProtonMcPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDauProtonNsigmaProton", "hDauProtonNsigmaProton", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, - {"hDauProtonTPCVsPt", "hDauProtonTPCVsPt", {HistType::kTH2F, {{50, 0.0f, 5.0f, "#it{p}_{T} (GeV/c)"}, {240, -6.0f, 6.0f, "TPC n#sigma"}}}}, - - {"hPionCount", "hPionCount", {HistType::kTH1F, {{7, 0.0f, 7.0f}}}}, - {"hPionPt", "hPionPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPionP", "hPionP", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPionMcPt", "hPionMcPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPionMcP", "hPionMcP", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPionEta", "hPionEta", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hPionMcRapidity", "hPionMcRapidity", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hPionNsigmaPion", "hPionNsigmaPion", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, - {"hPionTPCNClsCrossedRows", "hPionTPCNClsCrossedRows", {HistType::kTH1F, {{240, 0.0f, 240.0f}}}}, - {"hPionTPCBB", "hPionTPCBB", {HistType::kTH2F, {{320, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hPionTPCBBAfterTPCNclsCut", "hPionTPCBBAfterTPCNclsCut", {HistType::kTH2F, {{320, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hDauPionPt", "hDauPionPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDauPionMcPt", "hDauPionMcPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDauPionNsigmaPion", "hDauPionNsigmaPion", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, - {"hDauPionTPCVsPt", "hDauPionTPCVsPt", {HistType::kTH2F, {{20, 0.0f, 2.0f, "#it{p}_{T} (GeV/c)"}, {240, -6.0f, 6.0f, "TPC n#sigma"}}}}, - - {"hDeuteronCount", "hDeuteronCount", {HistType::kTH1F, {{6, 0.0f, 6.0f}}}}, - {"hDeuteronPt", "hDeuteronPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDeuteronP", "hDeuteronP", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDeuteronMcPt", "hDeuteronMcPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDeuteronMcP", "hDeuteronMcP", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDeuteronEta", "hDeuteronEta", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hDeuteronMcRapidity", "hDeuteronMcRapidity", {HistType::kTH1F, {{200, -10.0f, 10.0f}}}}, - {"hDeuteronNsigmaDeuteron", "hDeuteronNsigmaDeuteron", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, - {"hDeuteronTPCNClsCrossedRows", "hDeuteronTPCNClsCrossedRows", {HistType::kTH1F, {{240, 0.0f, 240.0f}}}}, - {"hDeuteronTPCBB", "hDeuteronTPCBB", {HistType::kTH2F, {{320, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hDeuteronTPCBBAfterTPCNclsCut", "hDeuteronTPCBBAfterTPCNclsCut", {HistType::kTH2F, {{320, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hDauDeuteronPt", "hDauDeuteronPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDauDeuteronMcPt", "hDauDeuteronMcPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDauDeuteronTPCVsPt", "hDauDeuteronTPCVsPt", {HistType::kTH2F, {{80, 0.0f, 8.0f, "#it{p}_{T} (GeV/c)"}, {240, -6.0f, 6.0f, "TPC n#sigma"}}}}, - - {"hTPCBB", "hTPCBB", {HistType::kTH2F, {{120, -8.0f, 8.0f, "p/z(GeV/c)"}, {100, 0.0f, 1000.0f, "TPCSignal"}}}}, - }, - }; - - void init(InitContext&) - { - registry.get(HIST("hParticleCount"))->GetXaxis()->SetBinLabel(1, "Readin"); - registry.get(HIST("hParticleCount"))->GetXaxis()->SetBinLabel(2, "Has_mcparticle"); - registry.get(HIST("hParticleCount"))->GetXaxis()->SetBinLabel(3, "Rapidity Cut(off)"); - registry.get(HIST("hParticleCount"))->GetXaxis()->SetBinLabel(4, "McisHypertriton"); - registry.get(HIST("hParticleCount"))->GetXaxis()->SetBinLabel(5, "McisProton"); - registry.get(HIST("hParticleCount"))->GetXaxis()->SetBinLabel(6, "McisPion"); - registry.get(HIST("hParticleCount"))->GetXaxis()->SetBinLabel(7, "McisDeuteron"); - - registry.get(HIST("hProtonCount"))->GetXaxis()->SetBinLabel(1, "hasMom"); - registry.get(HIST("hProtonCount"))->GetXaxis()->SetBinLabel(2, "FromHypertriton"); - registry.get(HIST("hProtonCount"))->GetXaxis()->SetBinLabel(3, "TPCNcls"); - registry.get(HIST("hProtonCount"))->GetXaxis()->SetBinLabel(4, "Eta"); - registry.get(HIST("hProtonCount"))->GetXaxis()->SetBinLabel(5, "Pt"); - registry.get(HIST("hProtonCount"))->GetXaxis()->SetBinLabel(6, "TPCPID"); - registry.get(HIST("hPionCount"))->GetXaxis()->SetBinLabel(1, "hasMom"); - registry.get(HIST("hPionCount"))->GetXaxis()->SetBinLabel(2, "FromHypertriton"); - registry.get(HIST("hPionCount"))->GetXaxis()->SetBinLabel(3, "TPCNcls"); - registry.get(HIST("hPionCount"))->GetXaxis()->SetBinLabel(4, "Eta"); - registry.get(HIST("hPionCount"))->GetXaxis()->SetBinLabel(5, "Pt"); - registry.get(HIST("hPionCount"))->GetXaxis()->SetBinLabel(6, "TPCPID"); - registry.get(HIST("hPionCount"))->GetXaxis()->SetBinLabel(7, "DcatoPV"); - registry.get(HIST("hDeuteronCount"))->GetXaxis()->SetBinLabel(1, "hasMom"); - registry.get(HIST("hDeuteronCount"))->GetXaxis()->SetBinLabel(2, "FromHypertriton"); - registry.get(HIST("hDeuteronCount"))->GetXaxis()->SetBinLabel(3, "TPCNcls"); - registry.get(HIST("hDeuteronCount"))->GetXaxis()->SetBinLabel(4, "Eta"); - registry.get(HIST("hDeuteronCount"))->GetXaxis()->SetBinLabel(5, "Pt"); - registry.get(HIST("hDeuteronCount"))->GetXaxis()->SetBinLabel(6, "TPCPID"); - } - - Configurable dcapiontopv{"dcapiontopv", .05, "DCA Pion To PV"}; - Configurable minProtonPt{"minProtonPt", 0.3, "minProtonPt"}; - Configurable maxProtonPt{"maxProtonPt", 5, "maxProtonPt"}; - Configurable minPionPt{"minPionPt", 0.1, "minPionPt"}; - Configurable maxPionPt{"maxPionPt", 1.2, "maxPionPt"}; - Configurable minDeuteronPt{"minDeuteronPt", 0.6, "minDeuteronPt"}; - Configurable maxDeuteronPt{"maxDeuteronPt", 10, "maxDeuteronPt"}; - Configurable eventSelection{"eventSelection", true, "event selection"}; - - void process(soa::Join::iterator const& collision, aod::McParticles const& mcparticles, MyTracks const& tracks) - { - - registry.fill(HIST("hTotalCollCounter"), 0.5); - if (eventSelection && !collision.sel8()) { - return; - } - registry.fill(HIST("hTotalCollCounter"), 1.5); - - std::vector protons, pions, deuterons; // index for daughter tracks - - for (auto& track : tracks) { - registry.fill(HIST("hParticleCount"), 0.5); - registry.fill(HIST("hTrackITSNcls"), track.itsNCls()); - registry.fill(HIST("hTPCNClsCrossedRows"), track.tpcNClsCrossedRows()); - registry.fill(HIST("hTrackNsigmaDeuteron"), track.tpcNSigmaDe()); - registry.fill(HIST("hTrackNsigmaProton"), track.tpcNSigmaPr()); - registry.fill(HIST("hTrackNsigmaPion"), track.tpcNSigmaPi()); - - if (!track.has_mcParticle()) { - continue; - } - registry.fill(HIST("hParticleCount"), 1.5); - auto mcparticle = track.mcParticle_as(); - registry.fill(HIST("hTPCBB"), track.p() * track.sign(), track.tpcSignal()); - - // if (TMath::Abs(mcparticle.y()) > 0.9) {continue;} - registry.fill(HIST("hParticleCount"), 2.5); - registry.fill(HIST("hTrackEta"), track.eta()); - registry.fill(HIST("hTrackMcRapidity"), mcparticle.y()); - - // Hypertriton detected directly - if (mcparticle.pdgCode() == 1010010030 || mcparticle.pdgCode() == -1010010030) { - registry.fill(HIST("hParticleCount"), 3.5); - registry.fill(HIST("hHypertritonMcPt"), mcparticle.pt()); - registry.fill(HIST("hHypertritonEta"), track.eta()); - registry.fill(HIST("hHypertritonMcRapidity"), mcparticle.y()); - } - - // Proton - if (mcparticle.pdgCode() == 2212 || mcparticle.pdgCode() == -2212) { - registry.fill(HIST("hParticleCount"), 4.5); - if (track.tpcNClsCrossedRows() > 70) { - registry.fill(HIST("hProtonTPCBBAfterTPCNclsCut"), track.p() * track.sign(), track.tpcSignal()); - } - - if (mcparticle.has_mothers()) { - registry.fill(HIST("hProtonCount"), 0.5); - for (auto& particleMother : mcparticle.mothers_as()) { - bool flag_H3L = is3bodyDecayedH3L(particleMother); - if (!flag_H3L) { - continue; - } - protons.push_back(track.globalIndex()); - registry.fill(HIST("hProtonCount"), 1.5); - registry.fill(HIST("hDauProtonPt"), track.pt()); - registry.fill(HIST("hDauProtonMcPt"), mcparticle.pt()); - registry.fill(HIST("hDauProtonNsigmaProton"), track.tpcNSigmaPr()); - registry.fill(HIST("hDauProtonTPCVsPt"), track.pt(), track.tpcNSigmaPr()); - if (track.tpcNClsCrossedRows() < 70) { - continue; - } - registry.fill(HIST("hProtonCount"), 2.5); - if (TMath::Abs(track.eta()) > 0.9) { - continue; - } - registry.fill(HIST("hProtonCount"), 3.5); - if (track.pt() < minProtonPt || track.pt() > maxProtonPt) { - continue; - } - registry.fill(HIST("hProtonCount"), 4.5); - if (TMath::Abs(track.tpcNSigmaPr()) > 5) { - continue; - } - registry.fill(HIST("hProtonCount"), 5.5); - } - } - - registry.fill(HIST("hProtonMcPt"), mcparticle.pt()); - registry.fill(HIST("hProtonMcP"), mcparticle.p()); - registry.fill(HIST("hProtonPt"), track.pt()); - registry.fill(HIST("hProtonP"), track.p()); - - registry.fill(HIST("hProtonNsigmaProton"), track.tpcNSigmaPr()); - registry.fill(HIST("hProtonTPCNClsCrossedRows"), track.tpcNClsCrossedRows()); - registry.fill(HIST("hProtonEta"), track.eta()); - registry.fill(HIST("hProtonMcRapidity"), mcparticle.y()); - registry.fill(HIST("hProtonTPCBB"), track.p() * track.sign(), track.tpcSignal()); - } - - // Pion - if (mcparticle.pdgCode() == 211 || mcparticle.pdgCode() == -211) { - registry.fill(HIST("hParticleCount"), 5.5); - if (track.tpcNClsCrossedRows() > 70) { - registry.fill(HIST("hPionTPCBBAfterTPCNclsCut"), track.p() * track.sign(), track.tpcSignal()); - } - - if (mcparticle.has_mothers()) { - registry.fill(HIST("hPionCount"), 0.5); - for (auto& particleMother : mcparticle.mothers_as()) { - bool flag_H3L = is3bodyDecayedH3L(particleMother); - if (!flag_H3L) { - continue; - } - pions.push_back(track.globalIndex()); - registry.fill(HIST("hPionCount"), 1.5); - registry.fill(HIST("hDauPionPt"), track.pt()); - registry.fill(HIST("hDauPionMcPt"), mcparticle.pt()); - registry.fill(HIST("hDauPionTPCVsPt"), track.pt(), track.tpcNSigmaPi()); - if (track.tpcNClsCrossedRows() < 70) { - continue; - } - registry.fill(HIST("hPionCount"), 2.5); - if (TMath::Abs(track.eta()) > 0.9) { - continue; - } - registry.fill(HIST("hPionCount"), 3.5); - if (track.pt() < minPionPt || track.pt() > maxPionPt) { - continue; - } - registry.fill(HIST("hPionCount"), 4.5); - if (TMath::Abs(track.tpcNSigmaPi()) > 5) { - continue; - } - registry.fill(HIST("hPionCount"), 5.5); - if (TMath::Abs(track.dcaXY()) < dcapiontopv) { - continue; - } - registry.fill(HIST("hPionCount"), 6.5); - } - } - - registry.fill(HIST("hPionMcPt"), mcparticle.pt()); - registry.fill(HIST("hPionMcP"), mcparticle.p()); - registry.fill(HIST("hPionPt"), track.pt()); - registry.fill(HIST("hPionP"), track.p()); - - registry.fill(HIST("hPionNsigmaPion"), track.tpcNSigmaPi()); - registry.fill(HIST("hPionTPCNClsCrossedRows"), track.tpcNClsCrossedRows()); - registry.fill(HIST("hPionEta"), track.eta()); - registry.fill(HIST("hPionMcRapidity"), mcparticle.y()); - registry.fill(HIST("hPionTPCBB"), track.p() * track.sign(), track.tpcSignal()); - } - - // Deuteron - if (mcparticle.pdgCode() == 1000010020 || mcparticle.pdgCode() == -1000010020) { - registry.fill(HIST("hParticleCount"), 6.5); - if (track.tpcNClsCrossedRows() > 70) { - registry.fill(HIST("hDeuteronTPCBBAfterTPCNclsCut"), track.p() * track.sign(), track.tpcSignal()); - } - - if (mcparticle.has_mothers()) { - registry.fill(HIST("hDeuteronCount"), 0.5); - for (auto& particleMother : mcparticle.mothers_as()) { - bool flag_H3L = is3bodyDecayedH3L(particleMother); - if (!flag_H3L) { - continue; - } - deuterons.push_back(track.globalIndex()); - registry.fill(HIST("hDeuteronCount"), 1.5); - registry.fill(HIST("hDauDeuteronPt"), track.pt()); - registry.fill(HIST("hDauDeuteronMcPt"), mcparticle.pt()); - registry.fill(HIST("hDauDeuteronTPCVsPt"), track.pt(), track.tpcNSigmaDe()); - if (track.tpcNClsCrossedRows() < 70) { - continue; - } - registry.fill(HIST("hDeuteronCount"), 2.5); - if (TMath::Abs(track.eta()) > 0.9) { - continue; - } - registry.fill(HIST("hDeuteronCount"), 3.5); - if (track.pt() < minDeuteronPt || track.pt() > maxDeuteronPt) { - continue; - } - registry.fill(HIST("hDeuteronCount"), 4.5); - if (TMath::Abs(track.tpcNSigmaDe()) > 5) { - continue; - } - registry.fill(HIST("hDeuteronCount"), 5.5); - } - } - - registry.fill(HIST("hDeuteronMcPt"), mcparticle.pt()); - registry.fill(HIST("hDeuteronMcP"), mcparticle.p()); - registry.fill(HIST("hDeuteronPt"), track.pt()); - registry.fill(HIST("hDeuteronP"), track.p()); - - registry.fill(HIST("hDeuteronNsigmaDeuteron"), track.tpcNSigmaDe()); - registry.fill(HIST("hDeuteronTPCNClsCrossedRows"), track.tpcNClsCrossedRows()); - registry.fill(HIST("hDeuteronEta"), track.eta()); - registry.fill(HIST("hDeuteronMcRapidity"), mcparticle.y()); - registry.fill(HIST("hDeuteronTPCBB"), track.p() * track.sign(), track.tpcSignal()); - } - - /*for(int iproton = 0; iproton < protons.size(); iproton++){ - for(int ipion = 0; ipion < pions.size(); ipion++){ - for(int ideuteron = 0; ideuteron < deuterons.size(); ideuteron++){ - auto track0 = tracks.A - if(!isPaired3body() - } - } - }*/ - } - } -}; - -// check the performance of mcparticle -struct hypertriton3bodyMcParticleCount { - // Basic checks - HistogramRegistry registry{ - "registry", - { - {"hTotalMcCollCounter", "hTotalMcCollCounter", {HistType::kTH1F, {{2, 0.0f, 2.0f}}}}, - - {"h3dMCDecayedHypertriton", "h3dMCDecayedHypertriton", {HistType::kTH3F, {{20, -1.0f, 1.0f, "Rapidity"}, {200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {50, 0.0f, 50.0f, "ct(cm)"}}}}, - {"hMcPhysicalPrimaryParticleCount", "hMcPhysicalPrimaryParticleCount", {HistType::kTH1F, {{8, 0.0f, 8.0f}}}}, - - {"hMcHypertritonCount", "hMcHypertritonCount", {HistType::kTH1F, {{8, 0.0f, 8.0f}}}}, - {"hMcHypertritonPt", "hMcHypertritonPt", {HistType::kTH1F, {{300, 0.0f, 15.0f}}}}, - {"hMcProtonPt", "hMcProtonPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hMcPionPt", "hMcPionPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hMcDeuteronPt", "hMcDeuteronPt", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - - {"hMcRecoInvMass", "hMcRecoInvMass", {HistType::kTH1F, {{100, 2.95, 3.05f}}}}, - }, - }; - - void init(InitContext&) - { - registry.get(HIST("hTotalMcCollCounter"))->GetXaxis()->SetBinLabel(1, "Total Count"); - registry.get(HIST("hTotalMcCollCounter"))->GetXaxis()->SetBinLabel(2, "Recoonstructed"); - - registry.get(HIST("hMcPhysicalPrimaryParticleCount"))->GetXaxis()->SetBinLabel(1, "Readin"); - registry.get(HIST("hMcPhysicalPrimaryParticleCount"))->GetXaxis()->SetBinLabel(2, "IsPhysicalPrimary"); - registry.get(HIST("hMcPhysicalPrimaryParticleCount"))->GetXaxis()->SetBinLabel(3, "y<0.9(off)"); - registry.get(HIST("hMcPhysicalPrimaryParticleCount"))->GetXaxis()->SetBinLabel(4, "(Anti)Proton"); - registry.get(HIST("hMcPhysicalPrimaryParticleCount"))->GetXaxis()->SetBinLabel(5, "(Anti)Pion"); - registry.get(HIST("hMcPhysicalPrimaryParticleCount"))->GetXaxis()->SetBinLabel(6, "(Anti)Deuteron"); - registry.get(HIST("hMcPhysicalPrimaryParticleCount"))->GetXaxis()->SetBinLabel(7, "(Anti)Hypertriton"); - registry.get(HIST("hMcPhysicalPrimaryParticleCount"))->GetXaxis()->SetBinLabel(8, "HasDaughter"); - registry.get(HIST("hMcHypertritonCount"))->GetXaxis()->SetBinLabel(1, "Hypertriton All"); - registry.get(HIST("hMcHypertritonCount"))->GetXaxis()->SetBinLabel(2, "AntiHypertriton All"); - registry.get(HIST("hMcHypertritonCount"))->GetXaxis()->SetBinLabel(3, "confirm to 3-body decay"); - registry.get(HIST("hMcHypertritonCount"))->GetXaxis()->SetBinLabel(4, "Hypertriton"); - registry.get(HIST("hMcHypertritonCount"))->GetXaxis()->SetBinLabel(5, "AntiHypertriton"); - registry.get(HIST("hMcHypertritonCount"))->GetXaxis()->SetBinLabel(6, "Rapidity"); - registry.get(HIST("hMcHypertritonCount"))->GetXaxis()->SetBinLabel(7, "Lifetime"); - registry.get(HIST("hMcHypertritonCount"))->GetXaxis()->SetBinLabel(8, "PtCut"); - } - - Configurable rapidityMCcut{"rapidityMCcut", 0.9, "rapidity cut MC count"}; - Configurable eventSelectionMC{"eventSelectionMC", true, "event selection MC count"}; - - void process(aod::McCollision const& mcCollision, aod::McParticles const& mcParticles, const soa::SmallGroups>& collisions) - { - std::vector SelectedEvents(collisions.size()); - int nevts = 0; - for (const auto& collision : collisions) { - if (eventSelectionMC && !collision.sel8()) { - continue; - } - SelectedEvents[nevts++] = collision.mcCollision_as().globalIndex(); - } - SelectedEvents.resize(nevts); - - registry.fill(HIST("hTotalMcCollCounter"), 0.5); - - const auto evtReconstructedAndSelected = std::find(SelectedEvents.begin(), SelectedEvents.end(), mcCollision.globalIndex()) != SelectedEvents.end(); - if (evtReconstructedAndSelected) { // Check that the event is reconstructed and that the reconstructed events pass the selection - registry.fill(HIST("hTotalMcCollCounter"), 1.5); - // return; - } - - for (auto& mcparticle : mcParticles) { - - registry.fill(HIST("hMcPhysicalPrimaryParticleCount"), 0.5); - - if (mcparticle.pdgCode() == 2212 || mcparticle.pdgCode() == -2212) { - registry.fill(HIST("hMcProtonPt"), mcparticle.pt()); - } - if (mcparticle.pdgCode() == 211 || mcparticle.pdgCode() == -211) { - registry.fill(HIST("hMcPionPt"), mcparticle.pt()); - } - if (mcparticle.pdgCode() == 1000010020 || mcparticle.pdgCode() == -1000010020) { - registry.fill(HIST("hMcDeuteronPt"), mcparticle.pt()); - } - if (mcparticle.pdgCode() == 1010010030) { - registry.fill(HIST("hMcHypertritonCount"), 1.5); - } else if (mcparticle.pdgCode() == -1010010030) { - registry.fill(HIST("hMcHypertritonCount"), 2.5); - } - if (mcparticle.pdgCode() == 1010010030 || mcparticle.pdgCode() == -1010010030) { - registry.fill(HIST("hMcHypertritonCount"), 0.5); - registry.fill(HIST("hMcHypertritonPt"), mcparticle.pt()); - - double dauDeuteronPos[3] = {-999, -999, -999}; - double dauProtonMom[3] = {-999, -999, -999}; - double dauPionMom[3] = {-999, -999, -999}; - double dauDeuteronMom[3] = {-999, -999, -999}; - double MClifetime = 999; - bool flag_H3L = is3bodyDecayedH3L(mcparticle); - if (!flag_H3L) { - continue; - } - for (auto& mcparticleDaughter : mcparticle.daughters_as()) { - if (std::abs(mcparticleDaughter.pdgCode()) == 2212) { - dauProtonMom[0] = mcparticleDaughter.px(); - dauProtonMom[1] = mcparticleDaughter.py(); - dauProtonMom[2] = mcparticleDaughter.pz(); - } - if (std::abs(mcparticleDaughter.pdgCode()) == 211) { - dauPionMom[0] = mcparticleDaughter.px(); - dauPionMom[1] = mcparticleDaughter.py(); - dauPionMom[2] = mcparticleDaughter.pz(); - } - if (std::abs(mcparticleDaughter.pdgCode()) == 1000010020) { - dauDeuteronPos[0] = mcparticleDaughter.vx(); - dauDeuteronPos[1] = mcparticleDaughter.vy(); - dauDeuteronPos[2] = mcparticleDaughter.vz(); - dauDeuteronMom[0] = mcparticleDaughter.px(); - dauDeuteronMom[1] = mcparticleDaughter.py(); - dauDeuteronMom[2] = mcparticleDaughter.pz(); - } - } - if (mcparticle.pdgCode() == 1010010030) { - registry.fill(HIST("hMcHypertritonCount"), 3.5); - registry.fill(HIST("hMcHypertritonCount"), 4.5); - } - if (mcparticle.pdgCode() == -1010010030) { - registry.fill(HIST("hMcHypertritonCount"), 3.5); - registry.fill(HIST("hMcHypertritonCount"), 5.5); - } - MClifetime = RecoDecay::sqrtSumOfSquares(dauDeuteronPos[0] - mcparticle.vx(), dauDeuteronPos[1] - mcparticle.vy(), dauDeuteronPos[2] - mcparticle.vz()) * o2::constants::physics::MassHyperTriton / mcparticle.p(); - registry.fill(HIST("hMcRecoInvMass"), RecoDecay::m(array{array{dauProtonMom[0], dauProtonMom[1], dauProtonMom[2]}, array{dauPionMom[0], dauPionMom[1], dauPionMom[2]}, array{dauDeuteronMom[0], dauDeuteronMom[1], dauDeuteronMom[2]}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged, o2::constants::physics::MassDeuteron})); - registry.fill(HIST("h3dMCDecayedHypertriton"), mcparticle.y(), mcparticle.pt(), MClifetime); - - int daughterPionCount = 0; - for (auto& mcparticleDaughter : mcparticle.daughters_as()) { - if (std::abs(mcparticleDaughter.pdgCode()) == 211) { - daughterPionCount++; - } - } - - // Count for hypertriton N_gen - if (TMath::Abs(mcparticle.y()) < 1) { - registry.fill(HIST("hMcHypertritonCount"), 6.5); - if (MClifetime < 40) { - registry.fill(HIST("hMcHypertritonCount"), 7.5); - if (mcparticle.pt() > 1 && mcparticle.pt() < 10) { - registry.fill(HIST("hMcHypertritonCount"), 8.5); - } - } - } - } - - if (!mcparticle.isPhysicalPrimary()) { - continue; - } - registry.fill(HIST("hMcPhysicalPrimaryParticleCount"), 1.5); - // if (TMath::Abs(mcparticle.y()) > rapidityMCcut) {continue;} - registry.fill(HIST("hMcPhysicalPrimaryParticleCount"), 2.5); - - if (mcparticle.pdgCode() == 211 || mcparticle.pdgCode() == -211) { - registry.fill(HIST("hMcPhysicalPrimaryParticleCount"), 3.5); - } else if (mcparticle.pdgCode() == 2212 || mcparticle.pdgCode() == -2212) { - registry.fill(HIST("hMcPhysicalPrimaryParticleCount"), 4.5); - } else if (mcparticle.pdgCode() == 1000010020 || mcparticle.pdgCode() == -1000010020) { - registry.fill(HIST("hMcPhysicalPrimaryParticleCount"), 5.5); - } else if (mcparticle.pdgCode() == 1010010030 || mcparticle.pdgCode() == -1010010030) { - registry.fill(HIST("hMcPhysicalPrimaryParticleCount"), 6.5); - } - - if (!mcparticle.has_daughters()) { - continue; - } - registry.fill(HIST("hMcPhysicalPrimaryParticleCount"), 7.5); - } - } -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - }; -} diff --git a/PWGLF/Tasks/hypertriton3bodyanalysis.cxx b/PWGLF/Tasks/hypertriton3bodyanalysis.cxx deleted file mode 100644 index 97cb130d10d..00000000000 --- a/PWGLF/Tasks/hypertriton3bodyanalysis.cxx +++ /dev/null @@ -1,400 +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. -// -// Example StoredVtx3BodyDatas analysis task -// ======================== -// -// This code loops over a StoredVtx3BodyDatas table and produces some -// standard analysis output. It requires either -// the hypertriton3bodybuilder or hypertriton3bodyfinder (not recommaended) tasks -// to have been executed in the workflow (before). -// -// author: yuanzhe.wang@cern.ch -// - -#include -#include -#include - -#include "Framework/runDataProcessing.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 "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/Vtx3BodyTables.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 "CommonConstants/PhysicsConstants.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; -using std::array; - -using MyTracks = soa::Join; - -struct hypertriton3bodyQa { - // Basic checks - HistogramRegistry registry{ - "registry", - { - {"hVtxRadius", "hVtxRadius", {HistType::kTH1F, {{1000, 0.0f, 100.0f, "cm"}}}}, - {"hVtxCosPA", "hVtxCosPA", {HistType::kTH1F, {{1000, 0.9f, 1.0f}}}}, - {"hPtProton", "hPtProton", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtAntiPion", "hPtAntiPion", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtDeuteron", "hPtDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtAntiProton", "hPtAntiProton", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtPion", "hPtPion", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtAntiDeuteron", "hPtAntiDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDCAProtonToPV", "hDCAProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCAPionToPV", "hDCAPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCADeuteronToPV", "hDCADeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hProtonTPCNcls", "hProtonTPCNcls", {HistType::kTH1F, {{300, 0, 300, "TPC cluster"}}}}, - {"hPionTPCNcls", "hPionTPCNcls", {HistType::kTH1F, {{300, 0, 300, "TPC cluster"}}}}, - {"hDeuteronTPCNcls", "hDeuteronTPCNcls", {HistType::kTH1F, {{300, 0, 300, "TPC cluster"}}}}, - {"hDCAVtxDau", "hDCAVtxDau", {HistType::kTH1F, {{1000, 0.0f, 10.0f, "cm^{2}"}}}}, - {"hVtxPt", "hVtxPt", {HistType::kTH1F, {{200, 0.0f, 10.0f, "p_{T}"}}}}, - {"hTrack0Pt", "hTrack0Pt", {HistType::kTH1F, {{200, 0.0f, 10.0f, "p_{T}"}}}}, - {"hTrack1Pt", "hTrack1Pt", {HistType::kTH1F, {{200, 0.0f, 10.0f, "p_{T}"}}}}, - {"hTrack2Pt", "hTrack2Pt", {HistType::kTH1F, {{200, 0.0f, 10.0f, "p_{T}"}}}}, - {"hTOFPIDDeuteron", "hTOFPIDDeuteron", {HistType::kTH1F, {{2000, -100.0f, 100.0f}}}}, - {"hDeuTOFNsigma", "Deuteron TOF Nsigma distribution", {HistType::kTH2F, {{1200, -6, 6, "#it{p} (GeV/#it{c})"}, {2000, -100, 100, "TOF n#sigma"}}}}, - {"hTOFPIDDeuteronWithTPC", "hTOFPIDDeuteronWithTPC", {HistType::kTH1F, {{2000, -100.0f, 100.0f}}}}, - {"hDeuTOFNsigmaWithTPC", "Deuteron TOF Nsigma distribution", {HistType::kTH2F, {{1200, -6, 6, "#it{p} (GeV/#it{c})"}, {2000, -100, 100, "TOF n#sigma"}}}}, - }, - }; - void init(InitContext const&) - { - AxisSpec massAxis = {120, 2.9f, 3.2f, "Inv. Mass (GeV/c^{2})"}; - registry.add("hMassHypertriton", "hMassHypertriton", {HistType::kTH1F, {massAxis}}); - registry.add("hMassAntiHypertriton", "hMassAntiHypertriton", {HistType::kTH1F, {massAxis}}); - } - void process(aod::Collision const& collision, aod::Vtx3BodyDatas const& vtx3bodydatas, MyTracks const& tracks) - { - for (auto& vtx : vtx3bodydatas) { - auto track0 = vtx.track0_as(); - auto track1 = vtx.track1_as(); - auto track2 = vtx.track2_as(); - - registry.fill(HIST("hVtxRadius"), vtx.vtxradius()); - registry.fill(HIST("hVtxCosPA"), vtx.vtxcosPA(collision.posX(), collision.posY(), collision.posZ())); - registry.fill(HIST("hDCAVtxDau"), vtx.dcaVtxdaughters()); - registry.fill(HIST("hVtxPt"), vtx.pt()); - registry.fill(HIST("hTrack0Pt"), vtx.track0pt()); - registry.fill(HIST("hTrack1Pt"), vtx.track1pt()); - registry.fill(HIST("hTrack2Pt"), vtx.track2pt()); - registry.fill(HIST("hMassHypertriton"), vtx.mHypertriton()); - registry.fill(HIST("hMassAntiHypertriton"), vtx.mAntiHypertriton()); - registry.fill(HIST("hTOFPIDDeuteron"), track2.tofNSigmaDe()); - registry.fill(HIST("hDeuTOFNsigma"), track2.tpcInnerParam() * track2.sign(), track2.tofNSigmaDe()); - if (std::abs(track2.tpcNSigmaDe()) < 5) { - registry.fill(HIST("hTOFPIDDeuteronWithTPC"), track2.tofNSigmaDe()); - registry.fill(HIST("hDeuTOFNsigmaWithTPC"), track2.tpcInnerParam() * track2.sign(), track2.tofNSigmaDe()); - } - if (track2.sign() > 0) { - registry.fill(HIST("hPtProton"), track0.pt()); - registry.fill(HIST("hPtAntiPion"), track1.pt()); - registry.fill(HIST("hPtDeuteron"), track2.pt()); - registry.fill(HIST("hDCAProtonToPV"), vtx.dcatrack0topv()); - registry.fill(HIST("hDCAPionToPV"), vtx.dcatrack1topv()); - registry.fill(HIST("hProtonTPCNcls"), track0.tpcNClsCrossedRows()); - registry.fill(HIST("hPionTPCNcls"), track1.tpcNClsCrossedRows()); - } else { - registry.fill(HIST("hPtPion"), track0.pt()); - registry.fill(HIST("hPtAntiProton"), track1.pt()); - registry.fill(HIST("hPtAntiDeuteron"), track2.pt()); - registry.fill(HIST("hDCAProtonToPV"), vtx.dcatrack1topv()); - registry.fill(HIST("hDCAPionToPV"), vtx.dcatrack0topv()); - registry.fill(HIST("hProtonTPCNcls"), track1.tpcNClsCrossedRows()); - registry.fill(HIST("hPionTPCNcls"), track0.tpcNClsCrossedRows()); - } - registry.fill(HIST("hDCADeuteronToPV"), vtx.dcatrack2topv()); - registry.fill(HIST("hDeuteronTPCNcls"), track2.tpcNClsCrossedRows()); - } - } -}; - -struct hypertriton3bodyAnalysis { - - // Selection criteria - Configurable vtxcospa{"vtxcospa", 0.9, "Vtx CosPA"}; // double -> N.B. dcos(x)/dx = 0 at x=0) - Configurable dcavtxdau{"dcavtxdau", 1.0, "DCA Vtx Daughters"}; // loose cut - Configurable dcapiontopv{"dcapiontopv", .00, "DCA Pion To PV"}; - Configurable etacut{"etacut", 1, "etacut"}; - Configurable rapidity{"rapidity", 1, "rapidity"}; - Configurable TofPidNsigmaMin{"TofPidNsigmaMin", -4, "TofPidNsigmaMin"}; - Configurable TofPidNsigmaMax{"TofPidNsigmaMax", 8, "TofPidNsigmaMax"}; - Configurable TpcPidNsigmaCut{"TpcPidNsigmaCut", 5, "TpcPidNsigmaCut"}; - Configurable eventSelection{"eventSelection", true, "event selection"}; - Configurable lifetimecut{"lifetimecut", 40., "lifetimecut"}; // ct - Configurable minProtonPt{"minProtonPt", 0.3, "minProtonPt"}; - Configurable maxProtonPt{"maxProtonPt", 5, "maxProtonPt"}; - Configurable minPionPt{"minPionPt", 0.1, "minPionPt"}; - Configurable maxPionPt{"maxPionPt", 1.2, "maxPionPt"}; - Configurable minDeuteronPt{"minDeuteronPt", 0.6, "minDeuteronPt"}; - Configurable maxDeuteronPt{"maxDeuteronPt", 10, "maxDeuteronPt"}; - Configurable minDeuteronPUseTOF{"minDeuteronPUseTOF", 1, "minDeuteronPt Enable TOF PID"}; - Configurable h3LMassLowerlimit{"h3LMassLowerlimit", 2.96, "Hypertriton mass lower limit"}; - Configurable h3LMassUpperlimit{"h3LMassUpperlimit", 3.04, "Hypertriton mass upper limit"}; - Configurable mincrossedrowsproton{"mincrossedrowsproton", 90, "min tpc crossed rows for pion"}; - Configurable mincrossedrowspion{"mincrossedrowspion", 70, "min tpc crossed rows"}; - Configurable mincrossedrowsdeuteron{"mincrossedrowsdeuteron", 100, "min tpc crossed rows for deuteron"}; - - Configurable mcsigma{"mcsigma", 0.0015, "sigma of mc invariant mass fit"}; // obtained from MC - - HistogramRegistry registry{ - "registry", - { - {"hSelectedEventCounter", "hSelectedEventCounter", {HistType::kTH1F, {{3, 0.0f, 3.0f}}}}, - {"hSelectedCandidatesCounter", "hSelectedCandidatesCounter", {HistType::kTH1F, {{11, 0.0f, 11.0f}}}}, - {"hMassHypertriton", "hMassHypertriton", {HistType::kTH1F, {{80, 2.96f, 3.04f}}}}, - {"hMassAntiHypertriton", "hMassAntiHypertriton", {HistType::kTH1F, {{80, 2.96f, 3.04f}}}}, - {"hMassHypertritonTotal", "hMassHypertritonTotal", {HistType::kTH1F, {{300, 2.9f, 3.2f}}}}, - {"hPtProton", "hPtProton", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtAntiPion", "hPtAntiPion", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtDeuteron", "hPtDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtAntiProton", "hPtAntiProton", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtPion", "hPtPion", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hPtAntiDeuteron", "hPtAntiDeuteron", {HistType::kTH1F, {{200, 0.0f, 10.0f}}}}, - {"hDCAProtonToPV", "hDCAProtonToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCAPionToPV", "hDCAPionToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hDCADeuteronToPV", "hDCADeuteronToPV", {HistType::kTH1F, {{1000, -10.0f, 10.0f, "cm"}}}}, - {"hProtonTPCNcls", "hProtonTPCNcls", {HistType::kTH1F, {{180, 0, 180, "TPC cluster"}}}}, - {"hPionTPCNcls", "hPionTPCNcls", {HistType::kTH1F, {{180, 0, 180, "TPC cluster"}}}}, - {"hDeuteronTPCNcls", "hDeuteronTPCNcls", {HistType::kTH1F, {{180, 0, 180, "TPC cluster"}}}}, - {"hVtxCosPA", "hVtxCosPA", {HistType::kTH1F, {{1000, 0.9f, 1.0f}}}}, - {"hDCAVtxDau", "hDCAVtxDau", {HistType::kTH1F, {{1000, 0.0f, 10.0f, "cm^{2}"}}}}, - {"hTOFPIDDeuteron", "hTOFPIDDeuteron", {HistType::kTH1F, {{2000, -100.0f, 100.0f}}}}, - {"hTPCPIDProton", "hTPCPIDProton", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, - {"hTPCPIDPion", "hTPCPIDPion", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, - {"hTPCPIDDeuteron", "hTPCPIDDeuteron", {HistType::kTH1F, {{240, -6.0f, 6.0f}}}}, - {"hProtonTPCBB", "hProtonTPCBB", {HistType::kTH2F, {{160, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hPionTPCBB", "hPionTPCBB", {HistType::kTH2F, {{160, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hDeuteronTPCBB", "hDeuteronTPCBB", {HistType::kTH2F, {{160, -8.0f, 8.0f, "p/z(GeV/c)"}, {200, 0.0f, 1000.0f, "TPCSignal"}}}}, - {"hProtonTPCVsPt", "hProtonTPCVsPt", {HistType::kTH2F, {{50, 0.0f, 5.0f, "#it{p}_{T} (GeV/c)"}, {240, -6.0f, 6.0f, "TPC n#sigma"}}}}, - {"hPionTPCVsPt", "hPionTPCVsPt", {HistType::kTH2F, {{20, 0.0f, 2.0f, "#it{p}_{T} (GeV/c)"}, {240, -6.0f, 6.0f, "TPC n#sigma"}}}}, - {"hDeuteronTPCVsPt", "hDeuteronTPCVsPt", {HistType::kTH2F, {{80, 0.0f, 8.0f, "#it{p}_{T} (GeV/c)"}, {240, -6.0f, 6.0f, "TPC n#sigma"}}}}, - {"hDalitz", "hDalitz", {HistType::kTH2F, {{120, 7.85, 8.45, "M^{2}(dp) (GeV^{2}/c^{4})"}, {60, 1.1, 1.4, "M^{2}(p#pi) (GeV^{2}/c^{4})"}}}}, - {"h3dMassHypertriton", "h3dMassHypertriton", {HistType::kTH3F, {{20, 0.0f, 100.0f, "Cent (%)"}, {200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}}}}, - {"h3dMassAntiHypertriton", "h3dMassAntiHypertriton", {HistType::kTH3F, {{20, 0.0f, 100.0f, "Cent (%)"}, {200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}}}}, - {"h3dTotalHypertriton", "h3dTotalHypertriton", {HistType::kTH3F, {{50, 0, 50, "ct(cm)"}, {200, 0.0f, 10.0f, "#it{p}_{T} (GeV/c)"}, {80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}}}}, - }, - }; - - //------------------------------------------------------------------ - // Fill stats histograms - enum vtxstep { kCandAll = 0, - kCandCosPA, - kCandDauEta, - kCandRapidity, - kCandct, - kCandDcaDau, - kCandTOFPID, - kCandTPCPID, - kCandTPCNcls, - kCandDauPt, - kCandDcaToPV, - kNVtxSteps }; - - Configurable saveDcaHist{"saveDcaHist", 1, "saveDcaHist"}; - ConfigurableAxis dcaBinning{"dca-binning", {200, 0.0f, 1.0f}, ""}; - ConfigurableAxis ptBinning{"pt-binning", {200, 0.0f, 10.0f}, ""}; - - void init(InitContext const&) - { - AxisSpec dcaAxis = {dcaBinning, "DCA (cm)"}; - AxisSpec ptAxis = {ptBinning, "#it{p}_{T} (GeV/c)"}; - AxisSpec massAxisHypertriton = {80, 2.96f, 3.04f, "Inv. Mass (GeV/c^{2})"}; - - if (saveDcaHist == 1) { - registry.add("h3dMassHypertritonDca", "h3dMassHypertritonDca", {HistType::kTH3F, {dcaAxis, ptAxis, massAxisHypertriton}}); - registry.add("h3dMassAntiHypertritonDca", "h3dMassAntiHypertritonDca", {HistType::kTH3F, {dcaAxis, ptAxis, massAxisHypertriton}}); - } - - TString CandCounterbinLabel[11] = {"Total", "VtxCosPA", "TrackEta", "MomRapidity", "Lifetime", "DcaV0Dau", "d TOFPID", "TPCPID&Mass", "TPCNcls", "DauPt", "PionDcatoPV"}; - for (int i{0}; i < kNVtxSteps; i++) { - registry.get(HIST("hSelectedCandidatesCounter"))->GetXaxis()->SetBinLabel(i + 1, CandCounterbinLabel[i]); - } - } - - void process(soa::Join::iterator const& collision, aod::Vtx3BodyDatas const& vtx3bodydatas, MyTracks const& tracks) - { - registry.fill(HIST("hSelectedEventCounter"), 0.5); - if (eventSelection && !collision.sel8()) { - return; - } - registry.fill(HIST("hSelectedEventCounter"), 1.5); - - bool if_hasvtx = false; - - for (auto& vtx : vtx3bodydatas) { - - auto track0 = vtx.track0_as(); - auto track1 = vtx.track1_as(); - auto track2 = vtx.track2_as(); - - registry.fill(HIST("hSelectedCandidatesCounter"), kCandAll); - if (vtx.vtxcosPA(collision.posX(), collision.posY(), collision.posZ()) < vtxcospa) { - continue; - } - registry.fill(HIST("hSelectedCandidatesCounter"), kCandCosPA); - if (TMath::Abs(track0.eta()) > etacut || TMath::Abs(track1.eta()) > etacut || TMath::Abs(track2.eta()) > etacut) { - continue; - } - registry.fill(HIST("hSelectedCandidatesCounter"), kCandDauEta); - if (TMath::Abs(vtx.yHypertriton()) > rapidity) { - continue; - } - registry.fill(HIST("hSelectedCandidatesCounter"), kCandRapidity); - double ct = vtx.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassHyperTriton; - if (ct > lifetimecut) { - continue; - } - registry.fill(HIST("hSelectedCandidatesCounter"), kCandct); - if (vtx.dcaVtxdaughters() > dcavtxdau) { - continue; - } - registry.fill(HIST("hSelectedCandidatesCounter"), kCandDcaDau); - if ((track2.tofNSigmaDe() < TofPidNsigmaMin || track2.tofNSigmaDe() > TofPidNsigmaMax) && track2.p() > minDeuteronPUseTOF) { - continue; - } - registry.fill(HIST("hSelectedCandidatesCounter"), kCandTOFPID); - - // 3sigma region for Dalitz plot - double lowersignallimit = o2::constants::physics::MassHyperTriton - 3 * mcsigma; - double uppersignallimit = o2::constants::physics::MassHyperTriton + 3 * mcsigma; - - // Hypertriton - if (TMath::Abs(track0.tpcNSigmaPr()) < TpcPidNsigmaCut && TMath::Abs(track1.tpcNSigmaPi()) < TpcPidNsigmaCut && TMath::Abs(track2.tpcNSigmaDe()) < TpcPidNsigmaCut && vtx.mHypertriton() > h3LMassLowerlimit && vtx.mHypertriton() < h3LMassUpperlimit) { - - registry.fill(HIST("hSelectedCandidatesCounter"), kCandTPCPID); - - if (track0.tpcNClsCrossedRows() > mincrossedrowsproton && track1.tpcNClsCrossedRows() > mincrossedrowspion && track2.tpcNClsCrossedRows() > mincrossedrowsdeuteron) { - - registry.fill(HIST("hSelectedCandidatesCounter"), kCandTPCNcls); - - if (vtx.track0pt() > minProtonPt && vtx.track0pt() < maxProtonPt && vtx.track1pt() > minPionPt && vtx.track1pt() < maxPionPt && vtx.track2pt() > minDeuteronPt && vtx.track2pt() < maxDeuteronPt) { - registry.fill(HIST("hSelectedCandidatesCounter"), kCandDauPt); - - if (TMath::Abs(vtx.dcatrack1topv()) > dcapiontopv) { - if_hasvtx = true; - registry.fill(HIST("hSelectedCandidatesCounter"), kCandDcaToPV); - - registry.fill(HIST("hVtxCosPA"), vtx.vtxcosPA(collision.posX(), collision.posY(), collision.posZ())); - registry.fill(HIST("hDCAVtxDau"), vtx.dcaVtxdaughters()); - registry.fill(HIST("hPtProton"), vtx.track0pt()); - registry.fill(HIST("hPtAntiPion"), vtx.track1pt()); - registry.fill(HIST("hPtDeuteron"), vtx.track2pt()); - registry.fill(HIST("hDCAProtonToPV"), vtx.dcatrack0topv()); - registry.fill(HIST("hDCAPionToPV"), vtx.dcatrack1topv()); - registry.fill(HIST("hDCADeuteronToPV"), vtx.dcatrack2topv()); - registry.fill(HIST("hProtonTPCNcls"), track0.tpcNClsCrossedRows()); - registry.fill(HIST("hPionTPCNcls"), track1.tpcNClsCrossedRows()); - registry.fill(HIST("hDeuteronTPCNcls"), track2.tpcNClsCrossedRows()); - registry.fill(HIST("hTOFPIDDeuteron"), track2.tofNSigmaDe()); - registry.fill(HIST("hTPCPIDProton"), track0.tpcNSigmaPr()); - registry.fill(HIST("hTPCPIDPion"), track1.tpcNSigmaPi()); - registry.fill(HIST("hTPCPIDDeuteron"), track2.tpcNSigmaDe()); - registry.fill(HIST("hProtonTPCBB"), track0.p(), track0.tpcSignal()); - registry.fill(HIST("hPionTPCBB"), -track1.p(), track1.tpcSignal()); - registry.fill(HIST("hDeuteronTPCBB"), track2.p(), track0.tpcSignal()); - registry.fill(HIST("hProtonTPCVsPt"), vtx.track0pt(), track0.tpcNSigmaPr()); - registry.fill(HIST("hPionTPCVsPt"), vtx.track1pt(), track1.tpcNSigmaPi()); - registry.fill(HIST("hDeuteronTPCVsPt"), vtx.track2pt(), track2.tpcNSigmaDe()); - registry.fill(HIST("hMassHypertriton"), vtx.mHypertriton()); - registry.fill(HIST("hMassHypertritonTotal"), vtx.mHypertriton()); - registry.fill(HIST("h3dMassHypertriton"), 0., vtx.pt(), vtx.mHypertriton()); // collision.centV0M() instead of 0. once available - registry.fill(HIST("h3dTotalHypertriton"), ct, vtx.pt(), vtx.mHypertriton()); - if (vtx.mHypertriton() > lowersignallimit && vtx.mHypertriton() < uppersignallimit) { - registry.fill(HIST("hDalitz"), RecoDecay::m2(array{array{vtx.pxtrack0(), vtx.pytrack0(), vtx.pztrack0()}, array{vtx.pxtrack2(), vtx.pytrack2(), vtx.pztrack2()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassDeuteron}), - RecoDecay::m2(array{array{vtx.pxtrack0(), vtx.pytrack0(), vtx.pztrack0()}, array{vtx.pxtrack1(), vtx.pytrack1(), vtx.pztrack1()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged})); - } - - if (saveDcaHist == 1) { - registry.fill(HIST("h3dMassHypertritonDca"), vtx.dcaVtxdaughters(), vtx.pt(), vtx.mHypertriton()); - } - } - } - } - } - - // AntiHypertriton - if (TMath::Abs(track0.tpcNSigmaPi()) < TpcPidNsigmaCut && TMath::Abs(track1.tpcNSigmaPr()) < TpcPidNsigmaCut && TMath::Abs(track2.tpcNSigmaDe()) < TpcPidNsigmaCut && vtx.mAntiHypertriton() > h3LMassLowerlimit && vtx.mAntiHypertriton() < h3LMassUpperlimit) { - - registry.fill(HIST("hSelectedCandidatesCounter"), kCandTPCPID); - - if (track0.tpcNClsCrossedRows() > mincrossedrowspion && track1.tpcNClsCrossedRows() > mincrossedrowsproton && track2.tpcNClsCrossedRows() > mincrossedrowsdeuteron) { - - registry.fill(HIST("hSelectedCandidatesCounter"), kCandTPCNcls); - - if (vtx.track0pt() > minPionPt && vtx.track0pt() < maxPionPt && vtx.track1pt() > minProtonPt && vtx.track1pt() < maxProtonPt && vtx.track2pt() > minDeuteronPt && vtx.track2pt() < maxDeuteronPt) { - registry.fill(HIST("hSelectedCandidatesCounter"), kCandDauPt); - if (TMath::Abs(vtx.dcatrack0topv()) > dcapiontopv) { - if_hasvtx = true; - registry.fill(HIST("hSelectedCandidatesCounter"), kCandDcaToPV); - - registry.fill(HIST("hVtxCosPA"), vtx.vtxcosPA(collision.posX(), collision.posY(), collision.posZ())); - registry.fill(HIST("hDCAVtxDau"), vtx.dcaVtxdaughters()); - registry.fill(HIST("hPtAntiProton"), vtx.track1pt()); - registry.fill(HIST("hPtPion"), vtx.track0pt()); - registry.fill(HIST("hPtAntiDeuteron"), vtx.track2pt()); - registry.fill(HIST("hDCAProtonToPV"), vtx.dcatrack1topv()); - registry.fill(HIST("hDCAPionToPV"), vtx.dcatrack0topv()); - registry.fill(HIST("hDCADeuteronToPV"), vtx.dcatrack2topv()); - registry.fill(HIST("hProtonTPCNcls"), track1.tpcNClsCrossedRows()); - registry.fill(HIST("hPionTPCNcls"), track0.tpcNClsCrossedRows()); - registry.fill(HIST("hDeuteronTPCNcls"), track2.tpcNClsCrossedRows()); - registry.fill(HIST("hTOFPIDDeuteron"), track2.tofNSigmaDe()); - registry.fill(HIST("hTPCPIDProton"), track1.tpcNSigmaPr()); - registry.fill(HIST("hTPCPIDPion"), track0.tpcNSigmaPi()); - registry.fill(HIST("hTPCPIDDeuteron"), track2.tpcNSigmaDe()); - registry.fill(HIST("hProtonTPCBB"), -track1.p(), track1.tpcSignal()); - registry.fill(HIST("hPionTPCBB"), track0.p(), track0.tpcSignal()); - registry.fill(HIST("hDeuteronTPCBB"), -track2.p(), track0.tpcSignal()); - registry.fill(HIST("hProtonTPCVsPt"), vtx.track1pt(), track1.tpcNSigmaPr()); - registry.fill(HIST("hPionTPCVsPt"), vtx.track0pt(), track0.tpcNSigmaPi()); - registry.fill(HIST("hDeuteronTPCVsPt"), vtx.track2pt(), track2.tpcNSigmaDe()); - registry.fill(HIST("hMassAntiHypertriton"), vtx.mAntiHypertriton()); - registry.fill(HIST("hMassHypertritonTotal"), vtx.mAntiHypertriton()); - registry.fill(HIST("h3dMassAntiHypertriton"), 0., vtx.pt(), vtx.mAntiHypertriton()); // collision.centV0M() instead of 0. once available - registry.fill(HIST("h3dTotalHypertriton"), ct, vtx.pt(), vtx.mAntiHypertriton()); - if (vtx.mAntiHypertriton() > lowersignallimit && vtx.mAntiHypertriton() < uppersignallimit) { - registry.fill(HIST("hDalitz"), RecoDecay::m2(array{array{vtx.pxtrack1(), vtx.pytrack1(), vtx.pztrack1()}, array{vtx.pxtrack2(), vtx.pytrack2(), vtx.pztrack2()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassDeuteron}), - RecoDecay::m2(array{array{vtx.pxtrack1(), vtx.pytrack1(), vtx.pztrack1()}, array{vtx.pxtrack0(), vtx.pytrack0(), vtx.pztrack0()}}, array{o2::constants::physics::MassProton, o2::constants::physics::MassPionCharged})); - } - - if (saveDcaHist == 1) { - registry.fill(HIST("h3dMassAntiHypertritonDca"), vtx.dcaVtxdaughters(), vtx.pt(), vtx.mAntiHypertriton()); - } - } - } - } - } - } - - if (if_hasvtx) - registry.fill(HIST("hSelectedEventCounter"), 2.5); - } -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc), - adaptAnalysisTask(cfgc), - }; -} diff --git a/PWGLF/Tasks/lambdakzeroanalysis.cxx b/PWGLF/Tasks/lambdakzeroanalysis.cxx deleted file mode 100644 index c427b051579..00000000000 --- a/PWGLF/Tasks/lambdakzeroanalysis.cxx +++ /dev/null @@ -1,141 +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. -// -// Example V0 analysis task -// ======================== -// -// This code loops over a V0Data table and produces some -// standard analysis output. It is meant to be run over -// derived data. -// -// Comments, questions, complaints, suggestions? -// Please write to: -// david.dobrigkeit.chinellato@cern.ch -// -#include "Framework/runDataProcessing.h" -#include "Framework/AnalysisTask.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/ASoAHelpers.h" -#include "ReconstructionDataFormats/Track.h" -#include "CommonConstants/PhysicsConstants.h" -#include "Common/Core/trackUtilities.h" -#include "PWGLF/DataModel/LFStrangenessTables.h" -#include "PWGLF/DataModel/LFStrangenessPIDTables.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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "Framework/ASoAHelpers.h" - -using namespace o2; -using namespace o2::framework; -using namespace o2::framework::expressions; -using std::array; - -using dauTracks = soa::Join; - -struct lambdakzeroAnalysis { - - HistogramRegistry histos{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; - - ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.2f, 2.4f, 2.6f, 2.8f, 3.0f, 3.2f, 3.4f, 3.6f, 3.8f, 4.0f, 4.4f, 4.8f, 5.2f, 5.6f, 6.0f, 6.5f, 7.0f, 7.5f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 17.0f, 19.0f, 21.0f, 23.0f, 25.0f, 30.0f, 35.0f, 40.0f, 50.0f}, "pt axis for QA histograms"}; - ConfigurableAxis axisK0Mass{"axisK0Mass", {200, 0.4f, 0.6f}, ""}; - ConfigurableAxis axisLambdaMass{"axisLambdaMass", {200, 1.101f, 1.131f}, ""}; - ConfigurableAxis axisCentrality{"axisCentrality", {100, 0.0f, 100.0f}, ""}; - - void init(InitContext const&) - { - // Event Counters - histos.add("hEventSelection", "hEventSelection", kTH1F, {{2, -0.5f, +1.5f}}); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(1, "All collisions"); - histos.get(HIST("hEventSelection"))->GetXaxis()->SetBinLabel(2, "posZ cut"); - - histos.add("hEventCentrality", "hEventCentrality", kTH1F, {{100, 0.0f, +100.0f}}); - - histos.add("h3dMassK0Short", "h3dMassK0Short", kTH3F, {axisCentrality, axisPt, axisK0Mass}); - histos.add("h3dMassLambda", "h3dMassLambda", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); - histos.add("h3dMassAntiLambda", "h3dMassAntiLambda", kTH3F, {axisCentrality, axisPt, axisLambdaMass}); - - // Extra QA histograms to be added - } - - // Selection criteria - Configurable v0cospa{"v0cospa", 0.995, "V0 CosPA"}; // double -> N.B. dcos(x)/dx = 0 at x=0) - Configurable dcav0dau{"dcav0dau", 1.0, "DCA V0 Daughters"}; - Configurable dcanegtopv{"dcanegtopv", .1, "DCA Neg To PV"}; - Configurable dcapostopv{"dcapostopv", .1, "DCA Pos To PV"}; - Configurable v0radius{"v0radius", 5.0, "v0radius"}; - Configurable rapidity{"rapidity", 0.5, "rapidity"}; - Configurable saveDcaHist{"saveDcaHist", 0, "saveDcaHist"}; - Configurable TpcPidNsigmaCut{"TpcPidNsigmaCut", 5, "TpcPidNsigmaCut"}; - Configurable boolArmenterosCut{"boolArmenterosCut", true, "cut on Armenteros-Podolanski graph"}; - Configurable paramArmenterosCut{"paramArmenterosCut", 0.2, "parameter Armenteros Cut"}; - - static constexpr float defaultLifetimeCuts[1][2] = {{25., 20.}}; - Configurable> lifetimecut{"lifetimecut", {defaultLifetimeCuts[0], 2, {"lifetimecutLambda", "lifetimecutK0S"}}, "lifetimecut"}; - - Filter preFilterV0 = nabs(aod::v0data::dcapostopv) > dcapostopv&& nabs(aod::v0data::dcanegtopv) > dcanegtopv&& aod::v0data::dcaV0daughters < dcav0dau; - - void process(soa::Join::iterator const& collision, soa::Filtered> const& fullV0s, dauTracks const&) - { - histos.fill(HIST("hEventSelection"), 0.5); - if (abs(collision.posZ()) > 10.f) { // 10cm - return; - } - histos.fill(HIST("hEventSelection"), 1.5); - histos.fill(HIST("hEventCentrality"), collision.centFT0C()); - - for (auto& v0 : fullV0s) { - // FIXME: could not find out how to filter cosPA and radius variables (dynamic columns) - if (v0.v0radius() > v0radius && v0.v0cosPA() > v0cospa) { - if (TMath::Abs(v0.yLambda()) < rapidity) { - if (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassLambda0 < lifetimecut->get("lifetimecutLambda")) { - // Lambda - if (TMath::Abs(v0.posTrackExtra_as().tpcNSigmaPr()) < TpcPidNsigmaCut && TMath::Abs(v0.negTrackExtra_as().tpcNSigmaPi()) < TpcPidNsigmaCut) { - histos.fill(HIST("h3dMassLambda"), collision.centFT0C(), v0.pt(), v0.mLambda()); - } - // AntiLambda - if (TMath::Abs(v0.negTrackExtra_as().tpcNSigmaPr()) < TpcPidNsigmaCut && TMath::Abs(v0.posTrackExtra_as().tpcNSigmaPi()) < TpcPidNsigmaCut) { - histos.fill(HIST("h3dMassAntiLambda"), collision.centFT0C(), v0.pt(), v0.mAntiLambda()); - } - } - } - - // K0Short - if (TMath::Abs(v0.yK0Short()) < rapidity) { - if (v0.distovertotmom(collision.posX(), collision.posY(), collision.posZ()) * o2::constants::physics::MassK0Short < lifetimecut->get("lifetimecutK0S")) { - if (TMath::Abs(v0.negTrackExtra_as().tpcNSigmaPi()) < TpcPidNsigmaCut && TMath::Abs(v0.posTrackExtra_as().tpcNSigmaPi()) < TpcPidNsigmaCut) { - histos.fill(HIST("h3dMassK0Short"), collision.centFT0C(), v0.pt(), v0.mK0Short()); - } - } - } - } - } - } -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc)}; -} diff --git a/PWGMM/Lumi/Tasks/CMakeLists.txt b/PWGMM/Lumi/Tasks/CMakeLists.txt index 154414e30cd..87b7e7fe919 100644 --- a/PWGMM/Lumi/Tasks/CMakeLists.txt +++ b/PWGMM/Lumi/Tasks/CMakeLists.txt @@ -34,3 +34,9 @@ o2physics_add_dpl_workflow(fitvdm O2::DetectorsCommonDataFormats O2::DetectorsVertexing COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(lumistab + SOURCES lumiStability.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore + O2::ReconstructionDataFormats + COMPONENT_NAME Analysis) \ No newline at end of file diff --git a/PWGMM/Lumi/Tasks/lumiStability.cxx b/PWGMM/Lumi/Tasks/lumiStability.cxx new file mode 100644 index 00000000000..dc80cf5811d --- /dev/null +++ b/PWGMM/Lumi/Tasks/lumiStability.cxx @@ -0,0 +1,84 @@ +// 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 This task is an empty skeleton that fills a simple eta histogram. +/// it is meant to be a blank page for further developments. +/// \author everyone + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Framework/ASoAHelpers.h" +#include "DataFormatsFDD/Digit.h" +#include "Framework/ASoA.h" + +using namespace o2; +using namespace o2::framework; +using BCsWithTimestamps = soa::Join; + +int nBCsPerOrbit = 3564; + +struct lumiStabilityTask { + // Histogram registry: an object to hold your histograms + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject}; + + void init(InitContext const&) + { + const AxisSpec axisFDDTrigggerVertex{nBCsPerOrbit + 1, 0.5f, nBCsPerOrbit + 0.5f}; + const AxisSpec axisFT0TrigggerVertex{nBCsPerOrbit + 1, 0.5f, nBCsPerOrbit + 0.5f}; + + // histo about triggers + histos.add("FDD/bcVertexTrigger", "vertex trigger per BC (FDD);BC in FDD; counts", kTH1F, {axisFDDTrigggerVertex}); + histos.add("FT0/bcVertexTrigger", "vertex trigger per BC (FT0);BC in FDD; counts", kTH1F, {axisFT0TrigggerVertex}); + } + + void process(aod::FT0s const& ft0s, aod::FDDs const& fdds, aod::BCsWithTimestamps const&) + { + for (auto const& fdd : fdds) { + auto bc = fdd.bc_as(); + if (!bc.timestamp()) + continue; + + Long64_t globalBC = bc.globalBC(); + int localBC = globalBC % nBCsPerOrbit; + + std::bitset<8> fddTriggers = fdd.triggerMask(); + bool vertex = fddTriggers[o2::fdd::Triggers::bitVertex]; + + if (vertex) { + histos.fill(HIST("FDD/bcVertexTrigger"), localBC); + } // vertex true + } // loop over FDD events + + for (auto const& ft0 : ft0s) { + auto bc = ft0.bc_as(); + if (!bc.timestamp()) + continue; + + Long64_t globalBC = bc.globalBC(); + int localBC = globalBC % nBCsPerOrbit; + + std::bitset<8> fT0Triggers = ft0.triggerMask(); + bool vertex = fT0Triggers[o2::fdd::Triggers::bitVertex]; + + if (vertex) { + histos.fill(HIST("FT0/bcVertexTrigger"), localBC); + } // vertex true + } // loop over FT0 events + } // end process +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGMM/Mult/Tasks/CMakeLists.txt b/PWGMM/Mult/Tasks/CMakeLists.txt index a4268d96a5c..fe4722abe80 100644 --- a/PWGMM/Mult/Tasks/CMakeLists.txt +++ b/PWGMM/Mult/Tasks/CMakeLists.txt @@ -64,3 +64,8 @@ o2physics_add_dpl_workflow(multiplicity-pb-pb SOURCES multiplicityPbPb.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(flattenicty-chrg + SOURCES flattenicty-chrg.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME Analysis) diff --git a/PWGMM/Mult/Tasks/dndeta-hi.cxx b/PWGMM/Mult/Tasks/dndeta-hi.cxx index aee7468ee12..75b7fe9a587 100644 --- a/PWGMM/Mult/Tasks/dndeta-hi.cxx +++ b/PWGMM/Mult/Tasks/dndeta-hi.cxx @@ -56,7 +56,6 @@ using namespace o2::framework::expressions; using namespace o2::aod::track; using namespace o2::aod; -using namespace o2::aod::evsel; using namespace o2::analysis; using BCsRun3 = soa::Join; @@ -145,7 +144,7 @@ static constexpr bool hasCent() } } // namespace -AxisSpec ZAxis = {{-30, -20, -15, -10, -7, -5, -3, -2, -1, 0, 1, 2, 3, 5, 7, 10, 15, 20, 30}, "Z (cm)", "zaxis"}; +AxisSpec ZAxis = {{-30, -20, -15, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 30}, "Z (cm)", "zaxis"}; AxisSpec DeltaZAxis = {61, -6.1, 6.1, "", "deltaz axis"}; AxisSpec DCAAxis = {601, -3.01, 3.01, "", "DCA axis"}; AxisSpec EtaAxis = {80, -4.0, 4.0, "#eta", "eta axis"}; @@ -156,7 +155,7 @@ AxisSpec EvtClassAxis = {kECend - 1, kECbegin + 0.5, kECend - 0.5, "", "event cl AxisSpec TrigClassAxis = {kTrigend - 1, kTrigbegin + 0.5, kTrigend - 0.5, "", "trigger class"}; AxisSpec ParticleTypeAxis = {kParTypeend - 1, kParTypebegin + 0.5, kParTypeend - 0.5, "", "Particle type"}; std::vector centBinningPbPb = {0, 1, 2, 3, 4, 5, 10, 20, 30, 40, 50, 60, 70, 80, 100}; -std::vector centBinning = {0., 0.01, 0.1, 1.0, 5.0, 10., 15., 20., 25., 30., 35., 40., 45., 50., 70., 100.0}; +std::vector centBinning = {0., 0.01, 0.1, 1.0, 5.0, 10., 15, 20., 25, 30., 35., 40., 45., 50., 70., 100.0}; AxisSpec CentAxis = {centBinning, "", "centrality"}; AxisSpec CentAxisPbPb = {centBinningPbPb, "", "centrality"}; AxisSpec SpeciesAxis = {kSpeciesend - 1, kSpeciesbegin + 0.5, kSpeciesend - 0.5, "", "species class"}; @@ -201,19 +200,25 @@ struct MultiplicityCounter { Configurable etadau{"etadau", 4, "Eta Daughters"}; Configurable rapidity{"v0rapidity", 0.5, "V0 rapidity"}; - Configurable mftanalysis{"mftanalysis", false, "mft analysis switch"}; + // Configurable mftanalysis{"mftanalysis", false, "mft analysis switch"}; Configurable zvtxcut{"zvtxcut", false, "z vtx cut < 10cm"}; HistogramRegistry registry{ "registry", - {{"Selection", ";status;events", {HistType::kTH1F, {{17, 0.5, 17.5}}}}}}; + {{"Selection", ";status;events", {HistType::kTH1F, {{17, 0.5, 17.5}}}} + + }}; std::vector usedTracksIds; void init(InitContext&) { registry.add({"hetaresponse", ";etaresponse", {HistType::kTH2D, {{80, -4, 4}, {80, -4, 4}}}}); - registry.add({"hft0multiplicity", ";multiplicity", {HistType::kTH1D, {{20000, 0, 200000}}}}); - registry.add({"hcentrality", IsPbPb ? " ; centrality_FT0C (%) " : "; centrality_FT0M", {HistType::kTH1F, {{1001, -0.05, 100.05}}}}); + registry.add({"hft0multiplicity", ";multiplicity", {HistType::kTH1D, {{10000, 0, 100000}}}}); + registry.add({"hcentrality", IsPbPb ? " ; centrality_FT0C (%) " : "; centrality_FT0M", {HistType::kTH1F, {{10000, 0, 100}}}}); + registry.add({"hcentralityvscentraldndeta", IsPbPb ? " ; centrality_FT0C (%) " : "; centrality_FT0M", {HistType::kTH2F, { + {100, 0, 100}, + {100, 0, 100}, + }}}); registry.add({"hrecdndeta", "evntclass; triggerclass; zvtex, eta", {HistType::kTHnSparseD, {EvtClassAxis, TrigClassAxis, ZAxis, EtaAxis, IsPbPb ? CentAxisPbPb : CentAxis, ParticleTypeAxis, phibin}}}); registry.add({"hreczvtx", "evntclass; triggerclass; zvtex", {HistType::kTHnSparseD, {EvtClassAxis, TrigClassAxis, ZAxis, IsPbPb ? CentAxisPbPb : CentAxis}}}); registry.add({"hphieta", "; #varphi; #eta; tracks", {HistType::kTHnSparseD, {EvtClassAxis, TrigClassAxis, PhiAxis, EtaAxis, IsPbPb ? CentAxisPbPb : CentAxis}}}); @@ -222,6 +227,15 @@ struct MultiplicityCounter { registry.add({"hgenzvtx", "evntclass; zvtex", {HistType::kTHnSparseD, {EvtClassAxis, ZAxis, IsPbPb ? CentAxisPbPb : CentAxis}}}); registry.add({"hv0mass", "etaaxis; invmass", {HistType::kTHnSparseD, {IsPbPb ? CentAxisPbPb : CentAxis, SpeciesAxis, V0EtaAxis, MassAxis}}}); + registry.add({"recetaINELg0Sel8recz10", ";etaresponse", {HistType::kTH2D, {EtaAxis, ZAxis}}}); + registry.add({"genetaINELg0Sel8recz10", ";etaresponse", {HistType::kTH2D, {EtaAxis, ZAxis}}}); + registry.add({"genetaINELg0Sel8genz10", ";etaresponse", {HistType::kTH2D, {EtaAxis, ZAxis}}}); + registry.add({"genetaINELg0genz10", ";etaresponse", {HistType::kTH2D, {EtaAxis, ZAxis}}}); + + registry.add({"reczINELg0Sel8", ";z", {HistType::kTH1D, {ZAxis}}}); + registry.add({"genzINELg0Sel8", ";z", {HistType::kTH1D, {ZAxis}}}); + registry.add({"genzINELg0", ";z", {HistType::kTH1D, {ZAxis}}}); + registry.add({"hcentmult", ";status;events", {HistType::kTH1D, {{100, 0, 100}}}}); const int nbins = 50; std::vector logbins(nbins + 1, 0); Double_t low = 0.01; @@ -235,6 +249,8 @@ struct MultiplicityCounter { registry.add({"hrecdndpt", " pt", {HistType::kTH1D, {ptbins2}}}); registry.add({"hdndptefficiency", " pt", {HistType::kTH1D, {ptbins2}}}); registry.add({"hgendndpt", " pt", {HistType::kTH1D, {{ptbins2}}}}); + registry.add({"hgendndpt2", " pt", {HistType::kTH1D, {{ptbins2}}}}); + registry.add({"hgendndpt05", " pt", {HistType::kTH1D, {{ptbins2}}}}); auto hstat = registry.get(HIST("Selection")); auto* x = hstat->GetXaxis(); @@ -257,51 +273,20 @@ struct MultiplicityCounter { x->SetBinLabel(17, "K0Sz10eta05"); } - expressions::Filter trackSelectionProper = ((aod::track::trackCutFlag & trackSelectionITS) == trackSelectionITS) && ifnode(ncheckbit(aod::track::detectorMap, (uint8_t)o2::aod::track::TPC), ncheckbit(aod::track::trackCutFlag, trackSelectionTPC), true) && ncheckbit(aod::track::trackCutFlag, trackSelectionDCA); - - // static constexpr TrackSelectionFlags::flagtype trackSelectionITS = - // TrackSelectionFlags::kITSNCls | TrackSelectionFlags::kITSChi2NDF | - // TrackSelectionFlags::kITSHits; - - // static constexpr TrackSelectionFlags::flagtype trackSelectionTPC = - // TrackSelectionFlags::kTPCNCls | - // TrackSelectionFlags::kTPCCrossedRowsOverNCls | - // TrackSelectionFlags::kTPCChi2NDF; - - // static constexpr TrackSelectionFlags::flagtype trackSelectionDCA = - // TrackSelectionFlags::kDCAz | TrackSelectionFlags::kDCAxy; - - // expressions::Filter trackSelectionProper = (aod::track::trackCutFlag & TrackSelectionFlags::kQualityTracks) == TrackSelectionFlags::kQualityTracks ; - // Filter trackSelectionProper = ncheckbit(aod::track::trackCutFlag, trackSelectionDCA); - - // expressions::Filter trackSelectionProper = requireGlobalTrackWoPtEtaInFilter(); - // expressions::Filter atrackFilter = (aod::track::bestCollisionId >= 0) && - // (nabs(aod::track::bestDCAZ) <= 2.f) && - // (nabs(aod::track::bestDCAXY) <= ((0.0105f + 0.0350f / npow(aod::track::pts, 1.1f)))); - // expressions::Filter primaries = (aod::mcparticle::flags & (uint8_t)o2::aod::mcparticle::enums::PhysicalPrimary) == (uint8_t)o2::aod::mcparticle::enums::PhysicalPrimary; + expressions::Filter trackSelectionProper = ((aod::track::trackCutFlag & trackSelectionITS) == trackSelectionITS) && ifnode(ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::TPC), ncheckbit(aod::track::trackCutFlag, trackSelectionTPC), true) && ncheckbit(aod::track::trackCutFlag, trackSelectionDCA); expressions::Filter preFilterV0 = nabs(aod::v0data::dcapostopv) > dcapostopv&& nabs(aod::v0data::dcanegtopv) > dcanegtopv&& aod::v0data::dcaV0daughters < dcav0dau; Partition mcSample = nabs(aod::mcparticle::eta) < estimatorEta; Partition tSample = nabs(aod::track::eta) < estimatorEta; - // Partition tSample2 = (aod::fwdtrack::eta < -2.f) && (aod::fwdtrack::eta > -4.f); Partition tSample3 = nabs(aod::track::eta) < estimatorEta; - // Partition> lsample = nabs(aod::track::eta) < estimatorEta; - - // Preslice perCol = aod::track::collisionId; - // Preslice> mcmfttracks_slice = o2::aod::fwdtrack::collisionId; - // Preslice> mctracks_slice = aod::track::collisionId; - // Preslice mcparticle_slice = o2::aod::mcparticle::mcCollisionId; - // Preslice> tracks_slice = aod::track::collisionId; - // Preslice mfttracks_slice = o2::aod::fwdtrack::collisionId; - void processEventStat( FullBCs const& bcs, soa::Join const& collisions) { std::vector::iterator> cols; for (auto& bc : bcs) { - if (!useEvSel || (bc.selection_bit(kIsBBT0A) & - bc.selection_bit(kIsBBT0C)) != 0) { + if (!useEvSel || (bc.selection_bit(o2::aod::evsel::kIsBBT0A) & + bc.selection_bit(o2::aod::evsel::kIsBBT0C)) != 0) { registry.fill(HIST("Selection"), 5.); cols.clear(); for (auto& collision : collisions) { @@ -337,7 +322,6 @@ struct MultiplicityCounter { Bool_1d btrigc(kTrigend, false); registry.fill(HIST("Selection"), 1.); auto z = collision.posZ(); - // auto permfttracks = tSample2->sliceByCached(aod::fwdtrack::collisionId, collision.globalIndex(), cache); auto pertracks = tSample3->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); auto Ntrk = 0; @@ -348,7 +332,7 @@ struct MultiplicityCounter { registry.fill(HIST("Selection"), 3.); } } - if (btrigc[kSel8] && fabs(z) < 10) + if (btrigc[kSel8] && std::abs(z) < 10) registry.fill(HIST("hft0multiplicity"), collision.multFT0C()); for (auto& track : pertracks) { @@ -361,8 +345,10 @@ struct MultiplicityCounter { if (btrigc[kSel8]) btrigc[kSel8g0] = true; } + if (btrigc[kSel8]) + registry.fill(HIST("reczINELg0Sel8"), z); - float cent = -1; + auto cent = -1.f; if (IsPbPb) { if constexpr (C::template contains()) cent = collision.centFT0C(); @@ -378,6 +364,8 @@ struct MultiplicityCounter { } else { if (std::abs(z) < 10 && btrigc[kSel8g0]) registry.fill(HIST("hcentrality"), cent); + if (std::abs(z) < 10 && btrigc[kSel8g0]) + registry.fill(HIST("hcentralityvscentraldndeta"), cent, Ntrk); } for (auto itrigc = 1u; itrigc < kTrigend; itrigc++) { if (btrigc[itrigc]) @@ -387,11 +375,11 @@ struct MultiplicityCounter { for (auto& track : pertracks) { if (btrigc[kSel8] && std::abs(track.eta()) < 0.8 && std::abs(z) < 10) registry.fill(HIST("hrecdndpt"), track.pt()); + if (btrigc[kSel8]) + registry.fill(HIST("recetaINELg0Sel8recz10"), track.eta(), z); + for (auto itrigc = 1u; itrigc < kTrigend; itrigc++) { if (btrigc[itrigc]) { - // if (track.phi()>3.08 && track.phi()<3.14) { - // continue; - // } registry.fill(HIST("hphieta"), Double_t(kDATA), Double_t(itrigc), track.phi(), track.eta(), cent); registry.fill(HIST("hrecdndeta"), Double_t(kDATA), Double_t(itrigc), z, track.eta(), cent, Double_t(kParDATA), track.phi()); } @@ -400,34 +388,20 @@ struct MultiplicityCounter { } } - // template - // PresliceUnsorted perMcCol = aod::mccollisionlabel::mcCollisionId; - // PresliceUnsorted> perMcCol = o2::aod::mccollisionlabel::mcCollisionId; PresliceUnsorted> perMcCol = o2::aod::mccollisionlabel::mcCollisionId; Preslice perMCColparticles = aod::mcparticle::mcCollisionId; void processMCCounting( - aod::McCollisions const& mcCollisions, soa::Join const& collisions, Particles const& mcParticles - //, soa::Filtered const& mcParticles - , - FiLTracks const& tracks - //, FiTracks const& tracks - //, DaughterTracks const& - // soa::SmallGroups const& atracks, - // soa::Join const& mfttracks - ) + aod::McCollisions const& mcCollisions, soa::Join const& collisions, Particles const& mcParticles, + FiLTracks const& tracks) { - //[[maybe_unused]] constexpr bool hasCentrality = C::template contains() || C::template contains() || hasCent(); for (auto& mcCollision : mcCollisions) { Bool_1d bevtc(kECend, false); bevtc[kINEL] = true; registry.fill(HIST("Selection"), 1.); - // auto z = collision.posZ(); auto mcz = mcCollision.posZ(); auto genz = mcz; - // auto cent = -1; - auto Ntrk_gen = 0; auto particles = mcParticles.sliceByCached(aod::mcparticle::mcCollisionId, mcCollision.globalIndex(), cache); for (auto& particle : particles) { @@ -448,11 +422,11 @@ struct MultiplicityCounter { } if (bevtc[kINEL]) registry.fill(HIST("Selection"), 9); - if (bevtc[kINEL] && fabs(mcz) < 10) + if (bevtc[kINEL] && std::abs(mcz) < 10) registry.fill(HIST("Selection"), 11); if (bevtc[kINELg0]) registry.fill(HIST("Selection"), 10); - if (bevtc[kINELg0] && fabs(mcz) < 10) + if (bevtc[kINELg0] && std::abs(mcz) < 10) registry.fill(HIST("Selection"), 12); for (auto& particle : particles) { if (!particle.isPhysicalPrimary()) @@ -460,18 +434,25 @@ struct MultiplicityCounter { auto kp = pdg->GetParticle(particle.pdgCode()); if (kp != nullptr) { if (std::abs(kp->Charge()) >= 3) { - // if (bevtc[kINEL] == true && btrigc[kSel8] == true && std::abs(particle.eta())<0.8 && std::abs(mcz)<10 && particle.has_tracks()) registry.fill(HIST("hdndptefficiency"), particle.pt()); - if (bevtc[kINEL] && std::abs(particle.eta()) < 0.8 && std::abs(mcz) < 10) + if (bevtc[kINEL] && std::abs(particle.eta()) < 0.8 && std::abs(mcz) < 10) { registry.fill(HIST("hgendndpt"), particle.pt()); + if (particle.pt() < 0.1) { + registry.fill(HIST("hgendndpt2"), particle.pt(), -10.0 * particle.pt() + 2); + registry.fill(HIST("hgendndpt05"), particle.pt(), 5.0 * particle.pt() + 0.5); + } else { + registry.fill(HIST("hgendndpt2"), particle.pt()); + registry.fill(HIST("hgendndpt05"), particle.pt()); + } + } } } } auto collisionsample = collisions.sliceBy(perMcCol, mcCollision.globalIndex()); - auto cent = -1; + auto cent = -1.f; if (collisionsample.size() != 1) { - cent = -1; + cent = -1.0; } else { for (auto& collision : collisionsample) { if (IsPbPb) { @@ -480,6 +461,14 @@ struct MultiplicityCounter { } else { if constexpr (MyCollisionsCent::template contains()) cent = collision.centFT0M(); + + auto Ntrk_rec = 0; + auto trackspart = tracks.sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + for (auto& track : trackspart) { + if (std::abs(track.eta()) < 1) { + Ntrk_rec++; + } + } } } } @@ -488,6 +477,7 @@ struct MultiplicityCounter { registry.fill(HIST("hgenzvtx"), Double_t(ievtc), genz, cent); } Int_t pid = 0; + std::vector particleetas; for (auto& particle : particles) { auto p = pdg->GetParticle(particle.pdgCode()); if (std::abs(particle.pdgCode()) == 310 && std::abs(particle.eta()) < 0.5 && std::abs(genz) < 10) @@ -514,7 +504,6 @@ struct MultiplicityCounter { if (std::abs(p->Charge()) >= 3) { for (auto ievtc = 1u; ievtc < kECend; ievtc++) { if (bevtc[ievtc]) { - // if (particle.phi()>3.08 && particle.phi()<3.14) continue; registry.fill(HIST("hgendndeta"), Double_t(ievtc), genz, particle.eta(), cent, Double_t(pid), kNoPtVar, particle.phi()); if (particle.pt() < 0.1) { registry.fill(HIST("hgendndeta"), Double_t(ievtc), genz, particle.eta(), cent, Double_t(pid), kPtUp, particle.phi(), -10.0 * particle.pt() + 2); @@ -526,22 +515,27 @@ struct MultiplicityCounter { } } } + if (pid >= kPion && pid <= kOPar) + particleetas.push_back(particle.eta()); } } } - // if (collisionsample.size()>=2) continue; - for (auto& collision : collisionsample) { - // ncoll++; - // if (!collision.has_mcCollision()) continue; - auto cent = -1; + auto cent = -1.f; if (IsPbPb) { if constexpr (MyCollisionsCent::template contains()) cent = collision.centFT0C(); } else { if constexpr (MyCollisionsCent::template contains()) cent = collision.centFT0M(); + auto Ntrk_rec = 0; + auto trackspart = tracks.sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + for (auto& track : trackspart) { + if (std::abs(track.eta()) < 1) { + Ntrk_rec++; + } + } } Bool_1d btrigc(kTrigend, false); @@ -553,16 +547,25 @@ struct MultiplicityCounter { registry.fill(HIST("Selection"), 3.); } } - if (bevtc[kINEL] && btrigc[kSel8] && fabs(z) < 10) + if (bevtc[kINEL] && btrigc[kSel8] && std::abs(z) < 10) registry.fill(HIST("hft0multiplicity"), collision.multFT0C()); + if (collisionsample.size() == 1 && bevtc[kINELg0] && btrigc[kSel8]) { + for (auto eta : particleetas) { + registry.fill(HIST("genetaINELg0Sel8recz10"), eta, z); + registry.fill(HIST("genetaINELg0Sel8genz10"), eta, mcz); + } + registry.fill(HIST("reczINELg0Sel8"), z); + registry.fill(HIST("genzINELg0Sel8"), genz); + } + if (collisionsample.size() == 1 && bevtc[kINELg0]) { + for (auto eta : particleetas) { + registry.fill(HIST("genetaINELg0genz10"), eta, mcz); + } + registry.fill(HIST("genzINELg0"), genz); + } auto Ntrk_rec = 0; - // auto trackspart = lsample->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - // auto trackspart = mctracks_slice->sliceByCached(aod::track::collisionId, collision.globalIndex(),cache); - // auto trackspart = lsample->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); auto trackspart = tracks.sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); - // trackspart.bindExternalIndices(&mcParticles); - // cout<trackpers->"> for (auto& track : trackspart) { if (std::abs(track.eta()) < 1) { Ntrk_rec++; @@ -570,7 +573,6 @@ struct MultiplicityCounter { } if (Ntrk_rec > 0) { - // registry.fill(HIST("Selection"), 3.); if (btrigc[kSel8]) btrigc[kSel8g0] = true; } @@ -584,11 +586,11 @@ struct MultiplicityCounter { if (bevtc[kINEL] && btrigc[kSel8]) registry.fill(HIST("Selection"), 13); - if (bevtc[kINEL] && btrigc[kSel8] && fabs(z) < 10) + if (bevtc[kINEL] && btrigc[kSel8] && std::abs(z) < 10) registry.fill(HIST("Selection"), 15); if (bevtc[kINELg0] && btrigc[kSel8g0]) registry.fill(HIST("Selection"), 14); - if (bevtc[kINELg0] && btrigc[kSel8g0] && fabs(z) < 10) + if (bevtc[kINELg0] && btrigc[kSel8g0] && std::abs(z) < 10) registry.fill(HIST("Selection"), 16); for (auto ievtc = 1u; ievtc < kECend; ievtc++) { @@ -603,9 +605,6 @@ struct MultiplicityCounter { if (track.has_mcParticle()) { Int_t pid = kBkg; auto particle = track.template mcParticle_as(); - if (bevtc[kINEL] && btrigc[kSel8] && std::abs(track.eta()) < 0.8 && std::abs(z) < 10) - registry.fill(HIST("hdndptefficiency"), particle.pt()); - if (particle.isPhysicalPrimary()) { switch (std::abs(particle.pdgCode())) { case 211: @@ -629,17 +628,19 @@ struct MultiplicityCounter { auto pdg_mother = mother.pdgCode(); if (pdg_mother == 310 || std::abs(pdg_mother) == 3122) { pid = kMotherStrange; - // cout<< "MotherIDS : "<3.08 && track.phi()<3.14) continue; registry.fill(HIST("hrecdndeta"), Double_t(ievtc), Double_t(itrigc), z, particle.eta(), cent, Double_t(pid), particle.phi()); registry.fill(HIST("hphieta"), Double_t(ievtc), Double_t(itrigc), track.phi(), track.eta(), cent); } @@ -650,29 +651,11 @@ struct MultiplicityCounter { for (auto ievtc = 1u; ievtc < kECend; ievtc++) { for (auto itrigc = 1u; itrigc < kTrigend; itrigc++) { if (bevtc[ievtc] && btrigc[itrigc]) { - // if (track.phi()>3.08 && track.phi()<3.14) continue; registry.fill(HIST("hrecdndeta"), Double_t(ievtc), Double_t(itrigc), z, track.eta(), cent, Double_t(kBkg), track.phi()); } } } } - - // registry.fill(HIST("Tracks/ProcessMCCounting/hStatusCode"), Double_t(kINEL), Double_t(kAll), track.template mcParticle_as().getGenStatusCode()); - // registry.fill(HIST("Tracks/ProcessMCCounting/hMCStatusCode"), Double_t(kINEL), Double_t(kAll), track.template mcParticle_as().getHepMCStatusCode()); - // registrfill(HIST("Tracks/ProcessMCCounting/hProcessCode"), Double_t(kINEL), Double_t(kAll), track.template mcParticle_as().getProcess()); - // } - // else{ - // for (auto ievtc = 1u; ievtc < kECend; ievtc++) - // { - // for (auto itrigc = 1u; itrigc < kTrigend; itrigc++) - // { - // if (bevtc[ievtc] == true && btrigc[itrigc] == true){ - // registry.fill(HIST("hrecdndeta"), Double_t(ievtc), Double_t(itrigc), z, track.eta(),cent, Double_t(kBkg), track.pt()); - // } - // } - // } - - //} } } } @@ -703,44 +686,10 @@ struct MultiplicityCounter { MyCollisionsCent const& collisions, FiTracks const& tracks) { - // runCounting(collisions, tracks, fullV0s, mfttracks); runCounting(collisions, tracks); } PROCESS_SWITCH(MultiplicityCounter, processCounting, "Count tracks with Centrality", false); - /*void processMCCounting( - //aod::McCollisions::iterator const& mccollision - //, soa::Join const& collisions - //, Particles const& mcParticles - //, soa::Filtered const& Fitrks - //, DaughterTracks const& Dautrks - //soa::SmallGroups const& atracks, - //soa::Join const& mfttracks - //) - aod::McCollisions::iterator const& mcCollision - , o2::soa::SmallGroups> const& collisions - , Particles const& particles - //, soa::Filtered const& Fitrks - , FiTracks const& Fitrks - ) - { - // runMCCounting(collisions, MCCollisions, fullV0s, mcParticles, Fitrks, Dautrks, atracks, mfttracks); - //runMCCounting(collisions - runMCCounting(mcCollision - , collisions - , particles - , Fitrks - //, Dautrks - //, atracks - //, mfttracks - ); - - }*/ - - // void processGen( - // aod::McCollisions::iterator const& mcCollision, - // o2::soa::SmallGroups> const& collisions, - // Particles const& mcParticles, FiTracks const& tracks) void processGen( aod::McCollisions::iterator const& mcCollision, Particles const& mcParticles) { @@ -759,7 +708,6 @@ struct MultiplicityCounter { } } } - // cout<<"INEL? "<0? "<GetParticle(particle.pdgCode()); - if (std::abs(particle.pdgCode()) == 310 && fabs(particle.eta()) < 0.5 && fabs(genz) < 10) + if (std::abs(particle.pdgCode()) == 310 && std::abs(particle.eta()) < 0.5 && std::abs(genz) < 10) registry.fill(HIST("Selection"), 17.); if (!particle.isPhysicalPrimary()) { continue; @@ -791,7 +739,6 @@ struct MultiplicityCounter { if (std::abs(p->Charge()) >= 3) { for (auto ievtc = 1u; ievtc < kECend; ievtc++) { if (bevtc[ievtc]) { - // if (particle.phi()>3.08 && particle.phi()<3.14) continue; registry.fill(HIST("hgendndeta"), Double_t(ievtc), genz, particle.eta(), -1.0, Double_t(pid), kNoPtVar, particle.phi()); if (particle.pt() < 0.1) { registry.fill(HIST("hgendndeta"), Double_t(ievtc), genz, particle.eta(), -1.0, Double_t(pid), kPtUp, particle.phi(), 2.0); @@ -811,7 +758,7 @@ struct MultiplicityCounter { void processV0Counting( MyCollisionsCent const& collisions, - soa::Filtered const& fullV0s, + aod::V0Datas const& fullV0s, FiTracks const& tracks) { for (auto& collision : collisions) { @@ -819,7 +766,7 @@ struct MultiplicityCounter { continue; auto z = collision.posZ(); - auto cent = -1; + auto cent = -1.f; if (IsPbPb) { if constexpr (MyCollisionsCent::template contains()) cent = collision.centFT0C(); @@ -829,15 +776,7 @@ struct MultiplicityCounter { } for (auto& v0 : fullV0s) { - - auto pTrack = v0.template posTrack_as(); - auto nTrack = v0.template negTrack_as(); - - if (v0.v0radius() > v0radius && - v0.v0cosPA() > v0cospa && - abs(pTrack.eta()) < etadau && - abs(nTrack.eta()) < etadau && fabs(z) < 10 && fabs(v0.eta()) < 0.5) { - + if (std::abs(z) < 10) { registry.fill(HIST("hv0mass"), cent, Double_t(kK0short), v0.eta(), Double_t(v0.mK0Short())); registry.fill(HIST("hv0mass"), cent, Double_t(kLambda), v0.eta(), Double_t(v0.mLambda())); registry.fill(HIST("hv0mass"), cent, Double_t(kAntilambda), v0.eta(), Double_t(v0.mAntiLambda())); @@ -856,7 +795,7 @@ struct MultiplicityCounter { DaughterTracks const& Dautrks) { for (auto& collision : collisions) { - auto cent = -1.0; + auto cent = -1.f; if (IsPbPb) { if constexpr (MyCollisionsCent::template contains()) @@ -866,8 +805,6 @@ struct MultiplicityCounter { cent = collision.centFT0M(); } - // auto mcCollision = collision.mcCollision(); - if (useEvSel && !collision.sel8()) // event selection cut continue; if (!collision.has_mcCollision()) // check mc particle diff --git a/PWGMM/Mult/Tasks/dndeta.cxx b/PWGMM/Mult/Tasks/dndeta.cxx index ab6fea3300e..443611f5a2e 100644 --- a/PWGMM/Mult/Tasks/dndeta.cxx +++ b/PWGMM/Mult/Tasks/dndeta.cxx @@ -50,11 +50,13 @@ struct MultiplicityCounter { Configurable estimatorEta{"estimatorEta", 1.0, "eta range for INEL>0 sample definition"}; Configurable dcaZ{"dcaZ", 0.2f, "Custom DCA Z cut (ignored if negative)"}; Configurable useEvSel{"useEvSel", true, "use event selection"}; - Configurable fillResponse{"fillResponse", false, "Fill response matrix"}; - Configurable responseStudy{"responseStudy", false, "Fill multi-estimator response"}; ConfigurableAxis multBinning{"multBinning", {301, -0.5, 300.5}, ""}; ConfigurableAxis centBinning{"centBinning", {VARIABLE_WIDTH, 0, 10, 20, 30, 40, 50, 60, 70, 80, 100}, ""}; + Configurable fillResponse{"fillResponse", true, "Fill respons matrix"}; + Configurable addFT0{"addFT0", false, "add FT0 estimators"}; + Configurable addFDD{"addFDD", false, "add FDD estimators"}; + HistogramRegistry commonRegistry{ "Common", { @@ -82,7 +84,6 @@ struct MultiplicityCounter { std::vector usedTracksIdsDF; std::vector usedTracksIdsDFMC; std::vector usedTracksIdsDFMCEff; - void init(InitContext&) { AxisSpec MultAxis = {multBinning}; @@ -178,11 +179,16 @@ struct MultiplicityCounter { inclusiveRegistry.add({NotFoundZvtx.data(), " ; Z_{vtx} (cm)", {HistType::kTH1F, {ZAxis}}}); if (fillResponse) { - inclusiveRegistry.add({Response.data(), " ; N_{rec}; N_{gen}; Z_{vtx} (cm)", {HistType::kTHnSparseF, {MultAxis, MultAxis, ZAxis}}}); inclusiveRegistry.add({EfficiencyMult.data(), " ; N_{gen}; Z_{vtx} (cm)", {HistType::kTH2F, {MultAxis, ZAxis}}}); inclusiveRegistry.add({SplitMult.data(), " ; N_{gen} ; Z_{vtx} (cm)", {HistType::kTH2F, {MultAxis, ZAxis}}}); - if (responseStudy) { - inclusiveRegistry.add({MultiResponse.data(), " ; N_{gen}; N_{rec}; N_{PV cont}; N_{FT0A}; N_{FT0C}; N_{FDA}; N_{FDC}; Z_{vtx} (cm)", {HistType::kTHnSparseF, {MultAxis, MultAxis, MultAxis, FT0AAxis, FT0CAxis, FDAAxis, FDCAxis, ZAxis}}}); + if (addFT0 && !addFDD) { + inclusiveRegistry.add({Response.data(), " ; N_{rec}; N_{PV cont}; N_{gen}; N_{FT0A}; N_{FT0C}; Z_{vtx} (cm)", {HistType::kTHnSparseF, {MultAxis, MultAxis, MultAxis, FT0AAxis, FT0CAxis, ZAxis}}}); + } else if (addFDD && !addFT0) { + inclusiveRegistry.add({Response.data(), " ; N_{rec}; N_{PV cont}; N_{gen}; N_{FDA}; N_{FDC}; Z_{vtx} (cm)", {HistType::kTHnSparseF, {MultAxis, MultAxis, MultAxis, FDAAxis, FDCAxis, ZAxis}}}); + } else if (addFT0 && addFDD) { + inclusiveRegistry.add({Response.data(), " ; N_{rec}; N_{PV cont}; N_{gen}; N_{FT0A}; N_{FT0C}; N_{FDA}; N_{FDC}; Z_{vtx} (cm)", {HistType::kTHnSparseF, {MultAxis, MultAxis, MultAxis, FT0AAxis, FT0CAxis, FDAAxis, FDCAxis, ZAxis}}}); + } else { + inclusiveRegistry.add({Response.data(), " ; N_{rec}; N_{PV cont}; N_{gen}; Z_{vtx} (cm)", {HistType::kTHnSparseF, {MultAxis, MultAxis, MultAxis, ZAxis}}}); } } @@ -196,8 +202,8 @@ struct MultiplicityCounter { x->SetBinLabel(static_cast(EvEffBins::kSelectedPVgt0), EvEffBinLabels[static_cast(EvEffBins::kSelectedPVgt0)].data()); } - if (doprocessGenAmbiguousFT0C || doprocessAmbiguousGenFT0M || doprocessGenAmbiguousFT0Chi || doprocessGenAmbiguousFT0Mhi || - doprocessGenFT0CNoAmb || doprocessGenFT0M || doprocessGenFT0Chi || doprocessGenFT0Mhi) { + if (doprocessGenAmbiguousFT0C || doprocessGenAmbiguousFT0M || doprocessGenAmbiguousFT0Chi || doprocessGenAmbiguousFT0Mhi || + doprocessGenFT0C || doprocessGenFT0M || doprocessGenFT0Chi || doprocessGenFT0Mhi) { binnedRegistry.add({NtrkZvtxGen.data(), "; N_{trk}; Z_{vtx} (cm); centrality", {HistType::kTHnSparseF, {MultAxis, ZAxis, CentAxis}}}); binnedRegistry.add({NtrkZvtxGen_t.data(), "; N_{part}; Z_{vtx} (cm); centrality", {HistType::kTHnSparseF, {MultAxis, ZAxis, CentAxis}}}); binnedRegistry.add({EtaZvtxGen.data(), "; #eta; Z_{vtx} (cm); centrality", {HistType::kTHnSparseF, {EtaAxis, ZAxis, CentAxis}}}); @@ -214,11 +220,16 @@ struct MultiplicityCounter { binnedRegistry.add({NotFoundZvtx.data(), " ; Z_{vtx} (cm); centrality; events", {HistType::kTH2F, {ZAxis, CentAxis}}}); if (fillResponse) { - binnedRegistry.add({Response.data(), " ; N_{rec}; N_{gen}; Z_{vtx} (cm); centrality", {HistType::kTHnSparseF, {MultAxis, MultAxis, ZAxis, CentAxis}}}); binnedRegistry.add({EfficiencyMult.data(), " ; N_{gen}; Z_{vtx} (cm); centrality", {HistType::kTHnSparseF, {MultAxis, ZAxis, CentAxis}}}); binnedRegistry.add({SplitMult.data(), " ; N_{gen} ; Z_{vtx} (cm); centrality", {HistType::kTHnSparseF, {MultAxis, ZAxis, CentAxis}}}); - if (responseStudy) { - binnedRegistry.add({MultiResponse.data(), " ; N_{gen}; N_{rec}, N_{PV cont}; N_{FT0A}; N_{FT0C}; N_{FDA}; N_{FDC}; Z_{vtx} (cm); centrality", {HistType::kTHnSparseF, {MultAxis, MultAxis, MultAxis, FT0AAxis, FT0CAxis, FDAAxis, FDCAxis, ZAxis, CentAxis}}}); + if (addFT0 && !addFDD) { + binnedRegistry.add({Response.data(), " ; N_{rec}; N_{PV cont}; N_{gen}; N_{FT0A}; N_{FT0C}; Z_{vtx} (cm); centrality", {HistType::kTHnSparseF, {MultAxis, MultAxis, MultAxis, FT0AAxis, FT0CAxis, ZAxis, CentAxis}}}); + } else if (addFDD && !addFT0) { + binnedRegistry.add({Response.data(), " ; N_{rec}; N_{PV cont}; N_{gen}; N_{FDA}; N_{FDC}; Z_{vtx} (cm); centrality", {HistType::kTHnSparseF, {MultAxis, MultAxis, MultAxis, FDAAxis, FDCAxis, ZAxis, CentAxis}}}); + } else if (addFT0 && addFDD) { + binnedRegistry.add({Response.data(), " ; N_{rec}; N_{PV cont}; N_{gen}; N_{FT0A}; N_{FT0C}; N_{FDA}; N_{FDC}; Z_{vtx} (cm); centrality", {HistType::kTHnSparseF, {MultAxis, MultAxis, MultAxis, FT0AAxis, FT0CAxis, FDAAxis, FDCAxis, ZAxis, CentAxis}}}); + } else { + binnedRegistry.add({Response.data(), " ; N_{rec}; N_{PV cont}; N_{gen}; Z_{vtx} (cm); centrality", {HistType::kTHnSparseF, {MultAxis, MultAxis, ZAxis, CentAxis}}}); } } @@ -1001,7 +1012,7 @@ struct MultiplicityCounter { template void fillFIT(CIT const& collision, std::vector& ft0as, std::vector& ft0cs, std::vector& fddas, std::vector& fddcs) { - if (collision.has_foundFT0()) { + if (addFT0 && collision.has_foundFT0()) { auto ft0 = collision.foundFT0(); float tA = 0; float tC = 0; @@ -1017,7 +1028,7 @@ struct MultiplicityCounter { ft0as.emplace_back(-1); ft0cs.emplace_back(-1); } - if (collision.has_foundFDD()) { + if (addFDD && collision.has_foundFDD()) { auto fdd = collision.foundFDD(); float tA = 0; float tC = 0; @@ -1110,22 +1121,6 @@ struct MultiplicityCounter { c_gen = mcCollision.centrality(); } - auto nCharged = countParticles(particles); - if constexpr (hasRecoCent()) { - binnedRegistry.fill(HIST(NtrkZvtxGen_t), nCharged, mcCollision.posZ(), c_gen); - binnedRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kGen), c_gen); - } else { - inclusiveRegistry.fill(HIST(NtrkZvtxGen_t), nCharged, mcCollision.posZ()); - inclusiveRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kGen)); - } - - if (nCharged > 0) { - if constexpr (hasRecoCent()) { - binnedRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kGengt0), c_gen); - } else { - inclusiveRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kGengt0)); - } - } bool atLeastOne = false; bool atLeastOne_gt0 = false; bool atLeastOne_PVgt0 = false; @@ -1179,9 +1174,7 @@ struct MultiplicityCounter { auto Nrec = countTracksAmbiguous(perCollisionSample, perCollisionASample, z, c_rec); NrecPerCol.emplace_back(Nrec); NPVPerCol.emplace_back(collision.numContrib()); - if (responseStudy) { - fillFIT(collision, NFT0APerCol, NFT0CPerCol, NFDDAPerCol, NFDDCPerCol); - } + fillFIT(collision, NFT0APerCol, NFT0CPerCol, NFDDAPerCol, NFDDCPerCol); if constexpr (hasRecoCent()) { binnedRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kSelected), c_gen); @@ -1206,19 +1199,46 @@ struct MultiplicityCounter { } } + auto nCharged = countParticles(particles); + if constexpr (hasRecoCent()) { + binnedRegistry.fill(HIST(NtrkZvtxGen_t), nCharged, mcCollision.posZ(), c_gen); + binnedRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kGen), c_gen); + } else { + inclusiveRegistry.fill(HIST(NtrkZvtxGen_t), nCharged, mcCollision.posZ()); + inclusiveRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kGen)); + } + + if (nCharged > 0) { + if constexpr (hasRecoCent()) { + binnedRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kGengt0), c_gen); + } else { + inclusiveRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kGengt0)); + } + } + if (fillResponse) { for (auto i = 0U; i < NrecPerCol.size(); ++i) { if constexpr (hasRecoCent()) { - binnedRegistry.fill(HIST(Response), NrecPerCol[i], nCharged, mcCollision.posZ(), c_recPerCol[i]); binnedRegistry.fill(HIST(EfficiencyMult), nCharged, mcCollision.posZ(), c_recPerCol[i]); - if (responseStudy) { - binnedRegistry.fill(HIST(MultiResponse), nCharged, NrecPerCol[i], NPVPerCol[i], NFT0APerCol[i], NFT0CPerCol[i], NFDDAPerCol[i], NFDDCPerCol[i], mcCollision.posZ(), c_recPerCol[i]); + if (addFT0 && !addFDD) { + binnedRegistry.fill(HIST(Response), NrecPerCol[i], NPVPerCol[i], nCharged, NFT0APerCol[i], NFT0CPerCol[i], mcCollision.posZ(), c_recPerCol[i]); + } else if (addFDD && !addFT0) { + binnedRegistry.fill(HIST(Response), NrecPerCol[i], NPVPerCol[i], nCharged, NFDDAPerCol[i], NFDDCPerCol[i], mcCollision.posZ(), c_recPerCol[i]); + } else if (addFT0 && addFDD) { + binnedRegistry.fill(HIST(Response), NrecPerCol[i], NPVPerCol[i], nCharged, NFT0APerCol[i], NFT0CPerCol[i], NFDDAPerCol[i], NFDDCPerCol[i], mcCollision.posZ(), c_recPerCol[i]); + } else { + binnedRegistry.fill(HIST(Response), NrecPerCol[i], NPVPerCol[i], nCharged, mcCollision.posZ(), c_recPerCol[i]); } } else { - inclusiveRegistry.fill(HIST(Response), NrecPerCol[i], nCharged, mcCollision.posZ()); inclusiveRegistry.fill(HIST(EfficiencyMult), nCharged, mcCollision.posZ()); - if (responseStudy) { - inclusiveRegistry.fill(HIST(MultiResponse), nCharged, NrecPerCol[i], NPVPerCol[i], NFT0APerCol[i], NFT0CPerCol[i], NFDDAPerCol[i], NFDDCPerCol[i], mcCollision.posZ()); + if (addFT0 && !addFDD) { + inclusiveRegistry.fill(HIST(Response), NrecPerCol[i], NPVPerCol[i], nCharged, NFT0APerCol[i], NFT0CPerCol[i], mcCollision.posZ()); + } else if (addFDD && !addFT0) { + inclusiveRegistry.fill(HIST(Response), NrecPerCol[i], NPVPerCol[i], nCharged, NFDDAPerCol[i], NFDDCPerCol[i], mcCollision.posZ()); + } else if (addFT0 && addFDD) { + inclusiveRegistry.fill(HIST(Response), NrecPerCol[i], NPVPerCol[i], nCharged, NFT0APerCol[i], NFT0CPerCol[i], NFDDAPerCol[i], NFDDCPerCol[i], mcCollision.posZ()); + } else { + inclusiveRegistry.fill(HIST(Response), NrecPerCol[i], NPVPerCol[i], nCharged, mcCollision.posZ()); } } } @@ -1255,22 +1275,6 @@ struct MultiplicityCounter { c_gen = mcCollision.centrality(); } - auto nCharged = countParticles(particles); - if constexpr (hasRecoCent()) { - binnedRegistry.fill(HIST(NtrkZvtxGen_t), nCharged, mcCollision.posZ(), c_gen); - binnedRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kGen), c_gen); - } else { - inclusiveRegistry.fill(HIST(NtrkZvtxGen_t), nCharged, mcCollision.posZ()); - inclusiveRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kGen)); - } - - if (nCharged > 0) { - if constexpr (hasRecoCent()) { - binnedRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kGengt0), c_gen); - } else { - inclusiveRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kGengt0)); - } - } bool atLeastOne = false; bool atLeastOne_gt0 = false; bool atLeastOne_PVgt0 = false; @@ -1323,9 +1327,7 @@ struct MultiplicityCounter { auto Nrec = countTracks(perCollisionSample, z, c_rec); NrecPerCol.emplace_back(Nrec); NPVPerCol.emplace_back(collision.numContrib()); - if (responseStudy) { - fillFIT(collision, NFT0APerCol, NFT0CPerCol, NFDDAPerCol, NFDDCPerCol); - } + fillFIT(collision, NFT0APerCol, NFT0CPerCol, NFDDAPerCol, NFDDCPerCol); if constexpr (hasRecoCent()) { binnedRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kSelected), c_gen); @@ -1350,19 +1352,46 @@ struct MultiplicityCounter { } } + auto nCharged = countParticles(particles); + if constexpr (hasRecoCent()) { + binnedRegistry.fill(HIST(NtrkZvtxGen_t), nCharged, mcCollision.posZ(), c_gen); + binnedRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kGen), c_gen); + } else { + inclusiveRegistry.fill(HIST(NtrkZvtxGen_t), nCharged, mcCollision.posZ()); + inclusiveRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kGen)); + } + + if (nCharged > 0) { + if constexpr (hasRecoCent()) { + binnedRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kGengt0), c_gen); + } else { + inclusiveRegistry.fill(HIST(Efficiency), static_cast(EvEffBins::kGengt0)); + } + } + if (fillResponse) { for (auto i = 0U; i < NrecPerCol.size(); ++i) { if constexpr (hasRecoCent()) { - binnedRegistry.fill(HIST(Response), NrecPerCol[i], nCharged, mcCollision.posZ(), c_recPerCol[i]); binnedRegistry.fill(HIST(EfficiencyMult), nCharged, mcCollision.posZ(), c_recPerCol[i]); - if (responseStudy) { - binnedRegistry.fill(HIST(MultiResponse), nCharged, NrecPerCol[i], NPVPerCol[i], NFT0APerCol[i], NFT0CPerCol[i], NFDDAPerCol[i], NFDDCPerCol[i], mcCollision.posZ(), c_recPerCol[i]); + if (addFT0 && !addFDD) { + binnedRegistry.fill(HIST(Response), NrecPerCol[i], NPVPerCol[i], nCharged, NFT0APerCol[i], NFT0CPerCol[i], mcCollision.posZ(), c_recPerCol[i]); + } else if (addFDD && !addFT0) { + binnedRegistry.fill(HIST(Response), NrecPerCol[i], NPVPerCol[i], nCharged, NFDDAPerCol[i], NFDDCPerCol[i], mcCollision.posZ(), c_recPerCol[i]); + } else if (addFT0 && addFDD) { + binnedRegistry.fill(HIST(Response), NrecPerCol[i], NPVPerCol[i], nCharged, NFT0APerCol[i], NFT0CPerCol[i], NFDDAPerCol[i], NFDDCPerCol[i], mcCollision.posZ(), c_recPerCol[i]); + } else { + binnedRegistry.fill(HIST(Response), NrecPerCol[i], NPVPerCol[i], nCharged, mcCollision.posZ(), c_recPerCol[i]); } } else { - inclusiveRegistry.fill(HIST(Response), NrecPerCol[i], nCharged, mcCollision.posZ()); inclusiveRegistry.fill(HIST(EfficiencyMult), nCharged, mcCollision.posZ()); - if (responseStudy) { - inclusiveRegistry.fill(HIST(MultiResponse), nCharged, NrecPerCol[i], NPVPerCol[i], NFT0APerCol[i], NFT0CPerCol[i], NFDDAPerCol[i], NFDDCPerCol[i], mcCollision.posZ()); + if (addFT0 && !addFDD) { + inclusiveRegistry.fill(HIST(Response), NrecPerCol[i], NPVPerCol[i], nCharged, NFT0APerCol[i], NFT0CPerCol[i], mcCollision.posZ()); + } else if (addFDD && !addFT0) { + inclusiveRegistry.fill(HIST(Response), NrecPerCol[i], NPVPerCol[i], nCharged, NFDDAPerCol[i], NFDDCPerCol[i], mcCollision.posZ()); + } else if (addFT0 && addFDD) { + inclusiveRegistry.fill(HIST(Response), NrecPerCol[i], NPVPerCol[i], nCharged, NFT0APerCol[i], NFT0CPerCol[i], NFDDAPerCol[i], NFDDCPerCol[i], mcCollision.posZ()); + } else { + inclusiveRegistry.fill(HIST(Response), NrecPerCol[i], NPVPerCol[i], nCharged, mcCollision.posZ()); } } } @@ -1417,7 +1446,7 @@ struct MultiplicityCounter { PROCESS_SWITCH(MultiplicityCounter, processGenAmbiguousFT0C, "Process generator-level info (FT0C centrality)", false); - void processGenFT0CNoAmb( + void processGenFT0C( MC::iterator const& mcCollision, o2::soa::SmallGroups> const& collisions, Particles const& particles, FiTracks const& tracks, aod::FT0s const&, aod::FDDs const&) @@ -1425,9 +1454,9 @@ struct MultiplicityCounter { processGenGeneral(mcCollision, collisions, particles, tracks); } - PROCESS_SWITCH(MultiplicityCounter, processGenFT0CNoAmb, "Process generator-level info (FT0C centrality) w/o ambiguous", false); + PROCESS_SWITCH(MultiplicityCounter, processGenFT0C, "Process generator-level info (FT0C centrality) w/o ambiguous", false); - void processAmbiguousGenFT0M( + void processGenAmbiguousFT0M( MC::iterator const& mcCollision, o2::soa::SmallGroups> const& collisions, Particles const& particles, FiTracks const& tracks, FiReTracks const& atracks, aod::FT0s const&, aod::FDDs const&) @@ -1435,7 +1464,7 @@ struct MultiplicityCounter { processGenGeneralAmbiguous(mcCollision, collisions, particles, tracks, atracks); } - PROCESS_SWITCH(MultiplicityCounter, processAmbiguousGenFT0M, "Process generator-level info (FT0M centrality)", false); + PROCESS_SWITCH(MultiplicityCounter, processGenAmbiguousFT0M, "Process generator-level info (FT0M centrality)", false); void processGenFT0M( MC::iterator const& mcCollision, diff --git a/PWGMM/Mult/Tasks/flattenicty-chrg.cxx b/PWGMM/Mult/Tasks/flattenicty-chrg.cxx new file mode 100644 index 00000000000..271e1fc9bf1 --- /dev/null +++ b/PWGMM/Mult/Tasks/flattenicty-chrg.cxx @@ -0,0 +1,552 @@ +// 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. +// +// 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 flatenicty-chrg.cxx +// \author Gyula Bencedi +// +// \brief Task to produce inclusive charged particle pT +// distributions as a function of charged-particle flattenicity +// +// \since 2024 + +#include +#include +#include +#include + +#include "EventFiltering/filterTables.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/StaticFor.h" +#include "Framework/runDataProcessing.h" + +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "DataFormatsFT0/Digit.h" +#include "ReconstructionDataFormats/Track.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::aod::track; + +float meanMultT0A = 0.f; +float meanMultT0C = 0.f; +float meanMultV0A = 0.f; + +struct FlattenictyCharged { + + HistogramRegistry flatchrg{ + "flatchrg", + {}, + OutputObjHandlingPolicy::AnalysisObject, + true, + true}; + + TrackSelection mTrackSelector; + + Configurable cutTrkEta{"cutTrkEta", 0.8f, "Eta range for tracks"}; + Configurable cutTrkPtMin{"cutTrkPtMin", 0.15f, "Minimum pT of tracks"}; + // Configurable cutTrkMult{"cutTrkMult", 200, "max measured + // multiplicity"}; + Configurable cutVtxzMin{"cutVtxzMin", -10.f, + "Minimum value for z-vertex"}; + Configurable cutVtxzMax{"cutVtxzMax", 10.f, + "Maximum value for z-vertex"}; + + ConfigurableAxis multBins{"multBins", {1001, -0.5, 1000.5}, ""}; + + Configurable sel8{"sel8", 1, "apply sel8 event selection"}; + Configurable selt0vtx{"selt0vtx", 0, "apply T0 vertext trigger"}; + Configurable selt0time{"selt0time", 0, "apply 1ns cut T0A and T0C"}; + + // // Configurable avPyT0A{"avPyT0A", 8.16, "nch from pythia T0A"}; + Configurable avPyT0C{"avPyT0C", 8.83, "nch from pythia T0C"}; + Configurable avPyFV0{"avPyFV0", 21.44, "nch from pythia FV0"}; + + Configurable url{"ccdb-url", "http://alice-ccdb.cern.ch", + "URL of the CCDB database"}; + + o2::ccdb::CcdbApi ccdbApi; + Service ccdb; + + void init(InitContext&) + { + ccdbApi.init(o2::base::NameConf::getCCDBServer()); + ccdb->setURL(url.value); // + ccdb->setCaching(true); + ccdb->setLocalObjectValidityChecking(); + if (!ccdbApi.isHostReachable()) { + LOGF(fatal, "CCDB host %s is not reacheable, cannot go forward", + url.value.data()); + } + + mTrackSelector.SetPtRange(0.15f, 1e10f); + mTrackSelector.SetEtaRange(-0.8f, 0.8f); + mTrackSelector.SetRequireITSRefit(true); + mTrackSelector.SetRequireTPCRefit(true); + mTrackSelector.SetRequireGoldenChi2(false); + mTrackSelector.SetMinNClustersTPC(60); + mTrackSelector.SetMinNCrossedRowsTPC(70); + mTrackSelector.SetMinNCrossedRowsOverFindableClustersTPC(0.8f); + mTrackSelector.SetMaxChi2PerClusterTPC(4.f); + mTrackSelector.SetRequireHitsInITSLayers( + 1, {0, 1}); // one hit in any SPD layer + mTrackSelector.SetMaxChi2PerClusterITS(36.f); + mTrackSelector.SetMaxDcaXY(1.f); + mTrackSelector.SetMaxDcaZ(1.f); + + std::vector ptBinEdges = { + 0.0, 0.1, 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, 2.0, 2.2, 2.4, 2.6, + 2.8, 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, 22.0, 24.0, 26.0, 30.0}; + const AxisSpec PtAxis{ptBinEdges, "#it{p}_{T} (GeV/#it{c})", "pt"}; + const AxisSpec ZAxis = {40, -20.0, 20.0}; + const AxisSpec PhiAxis = {600, 0, 2 * M_PI}; + const AxisSpec EtaAxisGlobal = {50, -5.0, 5.0}; + const AxisSpec EtaAxis = {20, 2.2, 5.1}; // FV0 + const AxisSpec CombEstAxis = {500, -0.5, 499.5}; + AxisSpec MultAxis = {multBins, "N_{trk}"}; + + flatchrg.add("hMultFV0", "hMultFV0", HistType::kTH1F, + {{1000, -0.5, 99999.5, "FV0 amplitude"}}); + flatchrg.add("hMultFV01to4Ring", "hMultFV01to4Ring", HistType::kTH1F, + {{1000, -0.5, 99999.5, "FV0 amplitude (rings 1-4)"}}); + flatchrg.add("hMultFV05Ring", "hMultFV05Ring", HistType::kTH1F, + {{1000, -0.5, 99999.5, "FV0 amplitude (ring 5)"}}); + + flatchrg.add("hMultFV0sel", "hMultFV0sel", HistType::kTH1F, + {{1000, -0.5, 99999.5, "FV0 amplitude"}}); + flatchrg.add("hMultFV01to4Ringsel", "hMultFV01to4Ringsel", HistType::kTH1F, + {{1000, -0.5, 99999.5, "FV0 amplitude (rings 1-4)"}}); + flatchrg.add("hMultFV05Ringsel", "hMultFV05Ringsel", HistType::kTH1F, + {{1000, -0.5, 99999.5, "FV0 amplitude (ring 5)"}}); + + flatchrg.add("hT0C_time", "T0C_time", HistType::kTH1F, + {{160, -40., 40., "FT0C time"}}); + flatchrg.add("hT0A_time", "T0A_time", HistType::kTH1F, + {{160, -40., 40., "FT0C time"}}); + flatchrg.add("hT0C_time_sel", "T0C_time", HistType::kTH1F, + {{160, -40., 40., "FT0C time"}}); + flatchrg.add("hT0A_time_sel", "T0A_time", HistType::kTH1F, + {{160, -40., 40., "FT0C time"}}); + + flatchrg.add("hAmpT0AVsCh", "", HistType::kTH2F, + {{24, -0.5, 23.5, "ch"}, + {600, -0.5, +5999.5, "FT0A amplitude vs channel"}}); + flatchrg.add("hFT0A", "FT0A", HistType::kTH1F, + {{600, -0.5, 599.5, "FT0A amplitudes"}}); + + flatchrg.add("hAmpT0CVsCh", "", HistType::kTH2F, + {{28, -0.5, 27.5, "ch"}, + {600, -0.5, +5999.5, "FT0C amplitude vs channel"}}); + flatchrg.add("hFT0C", "FT0C", HistType::kTH1F, + {{600, -0.5, 599.5, "FT0C amplitudes"}}); + + flatchrg.add("hMultFT0C", "hMultFT0C", HistType::kTH1F, + {{600, -0.5, 5999.5, "FT0C amplitude"}}); + flatchrg.add("hMultFT0Csel", "hMultFT0C", HistType::kTH1F, + {{600, -0.5, 5999.5, "FT0C amplitude"}}); + flatchrg.add("hMultFT0A", "hMultFT0A", HistType::kTH1F, + {{600, -0.5, 5999.5, "FT0A amplitude"}}); + flatchrg.add("hMultFT0Asel", "hMultFT0A", HistType::kTH1F, + {{600, -0.5, 5999.5, "FT0A amplitude"}}); + + flatchrg.add("h1flatencityFV0", "", HistType::kTH1F, + {{102, -0.01, 1.01, "1-flatencityFV0"}}); + flatchrg.add("h1flatencityFT0A", "", HistType::kTH1F, + {{102, -0.01, 1.01, "1-flatencityFT0A"}}); + flatchrg.add("h1flatencityFT0C", "", HistType::kTH1F, + {{102, -0.01, 1.01, "1-flatencityFT0C"}}); + flatchrg.add("h1flatencityFV0FT0C", "", HistType::kTH1F, + {{102, -0.01, 1.01, "1-flatencityFV0FT0C"}}); + flatchrg.add("hFV0FT0C", "", HistType::kTH1F, + {{102, -0.5, 499.5, "FV0_FT0C"}}); + + flatchrg.add("hPtVsFV0FT0C", " ; #it{p}_{T} (GeV/#it{c}); FV0_FT0C", + HistType::kTH2F, + {{500, -0.5, 499.5, "fv0ft0c"}, + {100, -0.5, 99.5, "#it{p}_{T} (GeV/#it{c})"}}); + flatchrg.add("hPtVs1flatencityFV0", " ; #it{p}_{T} (GeV/#it{c}); FV0_FT0C", + HistType::kTH2F, + {{102, -0.01, 1.01, "1flatFV0"}, + {100, -0.5, 99.5, "#it{p}_{T} (GeV/#it{c})"}}); + + // event level histos + flatchrg.add({"Events/selection", + ";status;events", + {HistType::kTH1F, {{4, 0.5, 4.5}}}}); + auto hstat = flatchrg.get(HIST("Events/selection")); + auto* x = hstat->GetXaxis(); + x->SetBinLabel(1, "All"); + x->SetBinLabel(2, "Selected trigger"); + x->SetBinLabel(3, "Selected zvtx"); + x->SetBinLabel(4, "Selected INEL>0"); + + // track level histos + flatchrg.add( + {"Tracks/VtxZ", " ; #it{z}_{vtx} (cm)", {HistType::kTH1F, {ZAxis}}}); + flatchrg.add({"Tracks/EtaVtxZGlobal", + "; #eta; #it{z}_{vtx} (cm); tracks", + {HistType::kTH2F, {EtaAxisGlobal, ZAxis}}}); + flatchrg.add({"Tracks/EtaGlobal", + "; #eta; #it{z}_{vtx} (cm); tracks", + {HistType::kTH1F, {EtaAxisGlobal}}}); + flatchrg.add({"Tracks/PhiEtaGlobal", + "; #varphi; #eta; tracks", + {HistType::kTH2F, {PhiAxis, EtaAxisGlobal}}}); + flatchrg.add({"Tracks/PtEtaGlobal", + " ; #it{p}_{T} (GeV/#it{c}); #eta", + {HistType::kTH2F, {PtAxis, EtaAxisGlobal}}}); + } + + int getT0ASector(int i_ch) + { + int i_sec_t0a = -1; + for (int i_sec = 0; i_sec < 24; ++i_sec) { + if (i_ch >= 4 * i_sec && i_ch <= 3 + 4 * i_sec) { + i_sec_t0a = i_sec; + break; + } + } + return i_sec_t0a; + } + + int getT0CSector(int i_ch) + { + int i_sec_t0c = -1; + for (int i_sec = 0; i_sec < 28; ++i_sec) { + if (i_ch >= 4 * i_sec && i_ch <= 3 + 4 * i_sec) { + i_sec_t0c = i_sec; + break; + } + } + return i_sec_t0c; + } + + float GetFlatenicity(float signals[], int entries) + { + float flat = 9999; + float mRho = 0; + for (int iCell = 0; iCell < entries; ++iCell) { + mRho += 1.0 * signals[iCell]; + } + // average activity per cell + mRho /= (1.0 * entries); + if (mRho <= 0) { + return 9999; + } + // get sigma + float sRho_tmp = 0; + for (int iCell = 0; iCell < entries; ++iCell) { + sRho_tmp += (1.0 * signals[iCell] - mRho) * (1.0 * signals[iCell] - mRho); + } + sRho_tmp /= (1.0 * entries * entries); + float sRho = sqrt(sRho_tmp); + if (mRho > 0) { + flat = sRho / mRho; + } + return flat; + } + + Filter trackFilter = + (nabs(aod::track::eta) < cutTrkEta) && (aod::track::pt > cutTrkPtMin); + using TrackTableData = + soa::Filtered>; + using CollisionTableData = soa::Join; + + void process(CollisionTableData::iterator const& collision, + TrackTableData const& tracks, + soa::Join const& bcs, + /*aod::MFTTracks const& mfttracks,*/ aod::FT0s const& ft0s, + aod::FV0As const& fv0s) + { + LOGF(debug, " Collision %d", collision.globalIndex()); + + auto bc = collision.template bc_as(); + + meanMultT0C = 0.f; + auto vMeanMultT0C = ccdb->getForTimeStamp>( + "Users/e/ekryshen/meanT0C", bc.timestamp()); + meanMultT0C = (*vMeanMultT0C)[0]; + + // meanMultT0A = 0.f; + // auto vMeanMultT0A = + // ccdb->getForTimeStamp>("Users/e/ekryshen/meanT0A", + // bc.timestamp()); meanMultT0A = (*vMeanMultT0A)[0]; + + meanMultV0A = 0.f; + auto vMeanMultV0A = ccdb->getForTimeStamp>( + "Users/e/ekryshen/meanV0A", bc.timestamp()); + meanMultV0A = (*vMeanMultV0A)[0]; + + // float fac_FT0A_ebe = 1.; + float fac_FT0C_ebe = 1.; + float fac_FV0_ebe = 1.; + + // if (meanMultT0A > 0) { + // fac_FT0A_ebe = avPyT0A / meanMultT0A; + // } + if (meanMultT0C > 0) { + fac_FT0C_ebe = avPyT0C / meanMultT0C; + } + if (meanMultV0A > 0) { + fac_FV0_ebe = avPyFV0 / meanMultV0A; + } + + bool isAcceptedEvent = false; + flatchrg.fill(HIST("Events/selection"), 1.); + + if (collision.sel8()) { + isAcceptedEvent = true; + } + + if (!isAcceptedEvent) { + return; + } + + flatchrg.fill(HIST("Events/selection"), 2.); + + auto vtxZ = collision.posZ(); + flatchrg.fill(HIST("Tracks/VtxZ"), vtxZ); + + bool isGoodEvent = false; + if (vtxZ > cutVtxzMin && vtxZ < cutVtxzMax) { + isGoodEvent = true; + } + + if (!isGoodEvent) { + return; + } + + flatchrg.fill(HIST("Events/selection"), 3.); + + //__________ FT0 mult. esimator + // + float sumAmpFT0A = 0.f; + float sumAmpFT0C = 0.f; + bool isOkTimeFT0 = false; + bool isOkvtxtrig = false; + bool isOkFV0OrA = false; + + if (collision.has_foundFT0()) { + auto ft0 = collision.foundFT0(); + std::bitset<8> triggers = ft0.triggerMask(); + isOkvtxtrig = triggers[o2::fit::Triggers::bitVertex]; + float t0_a = ft0.timeA(); + float t0_c = ft0.timeC(); + if (abs(t0_a) < 1. && abs(t0_c) < 1.) { + isOkTimeFT0 = true; + } + flatchrg.fill(HIST("hT0C_time"), t0_c); + flatchrg.fill(HIST("hT0A_time"), t0_a); + + for (std::size_t i_a = 0; i_a < ft0.amplitudeA().size(); i_a++) { + float amplitude = ft0.amplitudeA()[i_a]; + sumAmpFT0A += amplitude; + } + for (std::size_t i_c = 0; i_c < ft0.amplitudeC().size(); i_c++) { + float amplitude = ft0.amplitudeC()[i_c]; + sumAmpFT0C += amplitude; + } + flatchrg.fill(HIST("hMultFT0A"), sumAmpFT0A); + flatchrg.fill(HIST("hMultFT0C"), sumAmpFT0C); + } + + //__________ FLATTENICITY - FV0 mult. esimator + // + + double flatenicity_fv0 = 9999.; + float sumAmpFV0 = 0; + float sumAmpFV01to4Ring = 0; + float sumAmpFV05Ring = 0; + int innerFV0 = 32; + + const int nCells = 48; + float RhoLattice[nCells]; + for (Int_t iCh = 0; iCh < nCells; iCh++) { + RhoLattice[iCh] = 0; + } + + if (collision.has_foundFV0()) { + auto fv0 = collision.foundFV0(); + std::bitset<8> fV0Triggers = fv0.triggerMask(); + isOkFV0OrA = fV0Triggers[o2::fit::Triggers::bitA]; + // LOGP(info, "amplitude.size()={}", fv0.amplitude().size()); + for (std::size_t ich = 0; ich < fv0.amplitude().size(); ich++) { + int channelv0 = fv0.channel()[ich]; + float ampl_ch = fv0.amplitude()[ich]; + sumAmpFV0 += ampl_ch; + if (channelv0 < innerFV0) { + RhoLattice[channelv0] = ampl_ch; + sumAmpFV01to4Ring += ampl_ch; + } else { + RhoLattice[channelv0] = ampl_ch / 2.0; // two channels per bin + sumAmpFV05Ring += ampl_ch; + } + } + flatenicity_fv0 = GetFlatenicity(RhoLattice, nCells); + } + + flatchrg.fill(HIST("h1flatencityFV0"), 1. - flatenicity_fv0); + + flatchrg.fill(HIST("hMultFV0"), sumAmpFV0); + flatchrg.fill(HIST("hMultFV01to4Ring"), sumAmpFV01to4Ring); + flatchrg.fill(HIST("hMultFV05Ring"), sumAmpFV05Ring); + + if (selt0vtx && !isOkvtxtrig && !isOkFV0OrA) { + return; + } + if (selt0time && !isOkTimeFT0) { // to reduce beam-gas background + return; + } + if (sel8 && !collision.sel8()) { + return; + } + + flatchrg.fill(HIST("hMultFV0sel"), sumAmpFV0); + flatchrg.fill(HIST("hMultFV01to4Ringsel"), sumAmpFV01to4Ring); + flatchrg.fill(HIST("hMultFV05Ringsel"), sumAmpFV05Ring); + + //__________ FLATTENICITY - FT0 mult. esimator + // + + const int nCellsT0A = 24; + float RhoLatticeT0A[nCellsT0A]; + for (int iCh = 0; iCh < nCellsT0A; iCh++) { + RhoLatticeT0A[iCh] = 0.0; + } + const int nCellsT0C = 28; + float RhoLatticeT0C[nCellsT0C]; + for (int iCh = 0; iCh < nCellsT0C; iCh++) { + RhoLatticeT0C[iCh] = 0.0; + } + + float sumAmpFT0Asel = 0.f; + float sumAmpFT0Csel = 0.f; + if (collision.has_foundFT0()) { + auto ft0 = collision.foundFT0(); + float t0_a = ft0.timeA(); + float t0_c = ft0.timeC(); + flatchrg.fill(HIST("hT0C_time_sel"), t0_c); + flatchrg.fill(HIST("hT0A_time_sel"), t0_a); + + for (std::size_t i_a = 0; i_a < ft0.amplitudeA().size(); i_a++) { + float amplitude = ft0.amplitudeA()[i_a]; + uint8_t channel = ft0.channelA()[i_a]; + int sector = getT0ASector(channel); + if (sector >= 0 && sector < 24) { + RhoLatticeT0A[sector] += amplitude; + flatchrg.fill(HIST("hAmpT0AVsCh"), sector, amplitude); + } + sumAmpFT0Asel += amplitude; + flatchrg.fill(HIST("hFT0A"), amplitude); + } + flatchrg.fill(HIST("hMultFT0Asel"), sumAmpFT0Asel); + + for (std::size_t i_c = 0; i_c < ft0.amplitudeC().size(); i_c++) { + float amplitude = ft0.amplitudeC()[i_c]; + uint8_t channel = ft0.channelC()[i_c]; + int sector = getT0CSector(channel); + if (sector >= 0 && sector < 28) { + RhoLatticeT0C[sector] += amplitude; + flatchrg.fill(HIST("hAmpT0CVsCh"), sector, amplitude); + } + sumAmpFT0Csel += amplitude; + flatchrg.fill(HIST("hFT0C"), amplitude); + } + flatchrg.fill(HIST("hMultFT0Csel"), sumAmpFT0Csel); + } + float flatenicity_t0a = GetFlatenicity(RhoLatticeT0A, nCellsT0A); + float flatenicity_t0c = GetFlatenicity(RhoLatticeT0C, nCellsT0C); + + flatchrg.fill(HIST("h1flatencityFT0A"), 1. - flatenicity_t0a); + flatchrg.fill(HIST("h1flatencityFT0C"), 1. - flatenicity_t0c); + + //__________ FLATTENICITY - combined + + float combest = 0.; + + // option 1 + flatchrg.fill(HIST("h1flatencityFV0FT0C"), + (1.0 - (flatenicity_fv0 + flatenicity_t0c) / 2.0)); + + // option 2 + const int nEta = 2; // FT0C + FV0 + float weightsEta[nEta] = {0.0490638, 0.00353962}; + float factebye[nEta] = {0., 0.}; + float deltaEeta[nEta] = {1.1, 2.9}; + float ampl[nEta] = {0, 0}; + + if (collision.has_foundFV0() && collision.has_foundFT0()) { + + float all_weights = 0; + ampl[0] = sumAmpFT0C; + ampl[1] = sumAmpFV0; + factebye[0] = fac_FT0C_ebe; + factebye[1] = fac_FV0_ebe; + + if (sumAmpFT0C > 0 && sumAmpFV0 > 0) { + for (int ie = 0; ie < nEta; ++ie) { + if (meanMultV0A > 0 && meanMultT0C > 0) { + combest += ampl[ie] * weightsEta[ie] / deltaEeta[ie]; + } else { + combest += ampl[ie] * factebye[ie] / deltaEeta[ie]; + } + all_weights += weightsEta[ie]; + } + combest /= all_weights; + } + } + + flatchrg.fill(HIST("hFV0FT0C"), combest); + + for (auto& track : tracks) { + // if (!track.isGlobalTrack()) { + if (!mTrackSelector.IsSelected(track)) { + continue; + } + + if (!track.isPVContributor()) { + continue; + } + + flatchrg.fill(HIST("Tracks/EtaGlobal"), track.eta()); + flatchrg.fill(HIST("Tracks/EtaVtxZGlobal"), track.eta(), vtxZ); + flatchrg.fill(HIST("Tracks/PtEtaGlobal"), track.pt(), track.eta()); + + float phi = track.phi(); + o2::math_utils::bringTo02Pi(phi); + flatchrg.fill(HIST("Tracks/PhiEtaGlobal"), phi, track.eta()); + + flatchrg.fill(HIST("hPtVsFV0FT0C"), combest, track.pt()); + flatchrg.fill(HIST("hPtVs1flatencityFV0"), 1. - flatenicity_fv0, + track.pt()); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{// adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGMM/Mult/Tasks/multiplicityPbPb.cxx b/PWGMM/Mult/Tasks/multiplicityPbPb.cxx index 624a6d575ff..32d1abdea35 100644 --- a/PWGMM/Mult/Tasks/multiplicityPbPb.cxx +++ b/PWGMM/Mult/Tasks/multiplicityPbPb.cxx @@ -68,6 +68,7 @@ struct multiplicityPbPb { histos.add("etaHistogram", "; ", kTH1F, {axisEta}); histos.add("MCGENetaHistogram", "; ", kTH1F, {axisEta}); histos.add("ptHistogram", "; ", kTH1F, {axisPt}); + histos.add("MCGENptHistogram", "; ", kTH1F, {axisPt}); // histos.add("eventCounter", "eventCounter", kTH1F, {axisCounter}); histos.add("MCGENeventCounter", "eventCounter", kTH1F, {axisCounter}); @@ -76,9 +77,11 @@ struct multiplicityPbPb { histos.add("DCAz", "; DCA_{z} (cm)", kTH1F, {axisDCAz}); // do not know how: histos.add("Multiplicity", "; tracks; events", kTH1F, {axisNtrk}); + histos.add("MCGENMultiplicity", "; tracks; events", kTH1F, {axisNtrk}); histos.add("PhiTracks", "; #phi; tracks", kTH1F, {axisPhi}); histos.add("ZvtxEvents", "; Z_{vtx} (cm); events", kTH1F, {axisZvtx}); + histos.add("MCGENZvtxEvents", "; Z_{vtx} (cm); events", kTH1F, {axisZvtx}); histos.add("EtaZvtxTracks", "; #eta; Z_{vtx} (cm); tracks", kTH2F, {axisEta, axisZvtx}); histos.add("NtrkZvtxEvents", "; N_{trk}; Z_{vtx} (cm); events", kTH2F, {axisNtrk, axisZvtx}); @@ -87,6 +90,7 @@ struct multiplicityPbPb { histos.add("MCGENNtrkZvtxEvents", "; N_{trk}; Z_{vtx} (cm); events", kTH2F, {axisNtrk, axisZvtx}); histos.add("PhiEtaTracks", "; #phi; #eta; tracks", kTH2F, {axisPhi, axisEta}); + histos.add("MCGENPhiEtaTracks", "; #phi; #eta; tracks", kTH2F, {axisPhi, axisEta}); } // void process(aod::Collision const& collision, soa::Filtered const& tracks, aod::McParticles const&) @@ -131,14 +135,20 @@ struct multiplicityPbPb { int MCparticleCounter = 0; histos.fill(HIST("MCGENeventCounter"), 0.5); + histos.fill(HIST("MCGENZvtxEvents"), mcCollision.posZ()); for (auto& mcParticle : mcParticles) { ++MCparticleCounter; if (mcParticle.isPhysicalPrimary()) { histos.fill(HIST("MCGENetaHistogram"), mcParticle.eta()); + histos.fill(HIST("MCGENptHistogram"), mcParticle.pt()); + histos.fill(HIST("MCGENEtaZvtxTracks"), mcParticle.eta(), mcCollision.posZ()); + histos.fill(HIST("MCGENPhiEtaTracks"), mcParticle.phi(), mcParticle.eta()); } } + histos.fill(HIST("MCGENMultiplicity"), MCparticleCounter); + histos.fill(HIST("MCGENNtrkZvtxEvents"), MCparticleCounter, mcCollision.posZ()); } PROCESS_SWITCH(multiplicityPbPb, processMCGEN, "process for GEN MC data", true); diff --git a/PWGMM/UE/Tasks/ue-zdc-analysys.cxx b/PWGMM/UE/Tasks/ue-zdc-analysys.cxx index 7d668bc267a..30c01e333cd 100644 --- a/PWGMM/UE/Tasks/ue-zdc-analysys.cxx +++ b/PWGMM/UE/Tasks/ue-zdc-analysys.cxx @@ -16,13 +16,14 @@ #include "Framework/AnalysisDataModel.h" #include "Framework/HistogramRegistry.h" #include "Framework/runDataProcessing.h" - #include "Common/DataModel/EventSelection.h" -//#include "Common/CCDB/EventSelectionParams.h" -//#include "Common/CCDB/TriggerAliases.h" -#include "CCDB/BasicCCDBManager.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "Common/CCDB/TriggerAliases.h" #include "Common/DataModel/Centrality.h" #include "Common/DataModel/Multiplicity.h" +#include "Common/Core/TrackSelection.h" +#include "ReconstructionDataFormats/GlobalTrackID.h" +#include "ReconstructionDataFormats/Track.h" #include "TH1F.h" #include "TH2F.h" @@ -31,90 +32,101 @@ using namespace o2; using namespace o2::framework; using namespace o2::framework::expressions; +using namespace o2::aod::track; +using namespace o2::aod::evsel; -using BCsWithBcSels = soa::Join; -// using BCsRun3 = soa::Join; -using BCsWithRun3Matchings = soa::Join; +using BCsRun3 = soa::Join; +// using BCsWithRun3Matchings = soa::Join; +using ColEvSels = soa::Join; struct ZDCAnalysis { - // Configurable for number of bins - Configurable nBins1{"nBins1", 400, "Nbins1"}; - Configurable nBins2{"nBins2", 800, "Nbins2"}; - // CInfigurable maximum limit - Configurable MaxZN{"MaxZN", 4000, "Max ZN signal"}; - Configurable MaxZP{"MaxZP", 3000, "Max ZP signal"}; + // Configurable number of bins + Configurable nBinsADC{"nBinsADC", 1000, "nbinsADC"}; + Configurable nBinsAmp{"nBinsAmp", 1025, "nbinsAmp"}; + Configurable nBinsTDC{"nBinsTDC", 480, "nbinsTDC"}; + Configurable nBinsFit{"nBinsFit", 1000, "nbinsFit"}; + // Configurable flags + Configurable TDCcut{"TDCcut", false, "Flag for TDC cut"}; + // Configurable limits + Configurable MaxZN{"MaxZN", 4099.5, "Max ZN signal"}; + Configurable MaxZP{"MaxZP", 3099.5, "Max ZP signal"}; + Configurable MaxZEM{"MaxZEM", 3099.5, "Max ZEM signal"}; + Configurable tdcZNmincut{"tdcZNmincut", -4.0, "Min ZN TDC cut"}; + Configurable tdcZNmaxcut{"tdcZNmaxcut", -4.0, "Max ZN TDC cut"}; + Configurable tdcZPmincut{"tdcZPmincut", -4.0, "Min ZP TDC cut"}; + Configurable tdcZPmaxcut{"tdcZPmaxcut", -4.0, "Max ZP TDC cut"}; + // Configurable MaxMultFV0{"MaxMultFV0", 3000, "Max FV0 signal"}; Configurable MaxMultFT0{"MaxMultFT0", 3000, "Max FT0 signal"}; Configurable MaxMultFDD{"MaxMultFDD", 80000, "Max FDD signal"}; - Configurable MaxMultNTracks{"MaxMultNTracks", 1000, "Max Ntracks"}; - - HistogramRegistry registry; + // + HistogramRegistry registry{"Histos", {}, OutputObjHandlingPolicy::AnalysisObject}; void init(InitContext const&) { if (doprocessZdcAuto) { // Check if the process function for ZDCAuto is enabled - registry.add("ZNApmc", "ZNApmc", {HistType::kTH1F, {{nBins1, -10., MaxZN}}}); - registry.add("ZPApmc", "ZPApmc", {HistType::kTH1F, {{nBins1, -10., MaxZP}}}); - registry.add("ZNCpmc", "ZNCpmc", {HistType::kTH1F, {{nBins1, -10., MaxZN}}}); - registry.add("ZPCpmc", "ZPCpmc", {HistType::kTH1F, {{nBins1, -10., MaxZP}}}); - registry.add("ZEM1", "ZEM1", {HistType::kTH1F, {{nBins1, -10., MaxZP}}}); - registry.add("ZEM2", "ZEM2", {HistType::kTH1F, {{nBins1, -10., MaxZP}}}); - registry.add("ZNvsZEM", "ZNvsZEM", {HistType::kTH2F, {{{nBins1, -10., MaxZP}, {nBins1, -10., MaxZN}}}}); - registry.add("ZNAvsZNC", "ZNAvsZNC", {HistType::kTH2F, {{{nBins1, -10., MaxZN}, {nBins1, -10., MaxZN}}}}); - registry.add("ZPAvsZPC", "ZPAvsZPC", {HistType::kTH2F, {{{nBins1, -10., MaxZP}, {nBins1, -10., MaxZP}}}}); - registry.add("ZNAvsZPA", "ZNAvsZPA", {HistType::kTH2F, {{{nBins1, -10., MaxZP}, {nBins1, -10., MaxZN}}}}); - registry.add("ZNCvsZPC", "ZNCvsZPC", {HistType::kTH2F, {{{nBins1, -10., MaxZP}, {nBins1, -10., MaxZN}}}}); + registry.add("ZNApmc", "ZNApmc; ZNA amplitude; Entries", {HistType::kTH1F, {{nBinsAmp, -0.5, MaxZN}}}); + registry.add("ZPApmc", "ZPApmc; ZPA amplitude; Entries", {HistType::kTH1F, {{nBinsAmp, -0.5, MaxZP}}}); + registry.add("ZNCpmc", "ZNCpmc; ZNC amplitude; Entries", {HistType::kTH1F, {{nBinsAmp, -0.5, MaxZN}}}); + registry.add("ZPCpmc", "ZPCpmc; ZPC amplitude; Entries", {HistType::kTH1F, {{nBinsAmp, -0.5, MaxZP}}}); + registry.add("ZEM1", "ZEM1; ZEM1 amplitude; Entries", {HistType::kTH1F, {{nBinsAmp, -0.5, MaxZEM}}}); + registry.add("ZEM2", "ZEM2; ZEM2 amplitude; Entries", {HistType::kTH1F, {{nBinsAmp, -0.5, MaxZEM}}}); + registry.add("ZNvsZEM", "ZNvsZEM; ZEM; ZNA+ZNC", {HistType::kTH2F, {{{nBinsAmp, -0.5, MaxZEM}, {nBinsAmp, -0.5, 2. * MaxZN}}}}); + registry.add("ZNAvsZNC", "ZNAvsZNC; ZNC; ZNA", {HistType::kTH2F, {{{nBinsAmp, -0.5, MaxZN}, {nBinsAmp, -0.5, MaxZN}}}}); + registry.add("ZPAvsZPC", "ZPAvsZPC; ZPC; ZPA", {HistType::kTH2F, {{{nBinsAmp, -0.5, MaxZP}, {nBinsAmp, -0.5, MaxZP}}}}); + registry.add("ZNAvsZPA", "ZNAvsZPA; ZPA; ZNA", {HistType::kTH2F, {{{nBinsAmp, -0.5, MaxZP}, {nBinsAmp, -0.5, MaxZN}}}}); + registry.add("ZNCvsZPC", "ZNCvsZPC; ZPC; ZNC", {HistType::kTH2F, {{{nBinsAmp, -0.5, MaxZP}, {nBinsAmp, -0.5, MaxZN}}}}); // - registry.add("ZNCcvsZNCsum", "ZNCcvsZNCsum", {HistType::kTH2F, {{{nBins1, -10., 3. * MaxZN}, {nBins1, -10., 3. * MaxZN}}}}); - registry.add("ZNAcvsZNAsum", "ZNAcvsZNAsum", {HistType::kTH2F, {{{nBins1, -10., 3. * MaxZN}, {nBins1, -10., 3. * MaxZN}}}}); - registry.add("ZPCcvsZPCsum", "ZPCcvsZPCsum", {HistType::kTH2F, {{{nBins1, -10., 3. * MaxZP}, {nBins1, -10., 3. * MaxZP}}}}); - registry.add("ZPAcvsZPAsum", "ZPAcvsZPAsum", {HistType::kTH2F, {{{nBins1, -10., 3. * MaxZP}, {nBins1, -10., 3. * MaxZP}}}}); + registry.add("ZNCcvsZNCsum", "ZNCcvsZNCsum; ZNCC ADC; ZNCsum", {HistType::kTH2F, {{{nBinsADC, -0.5, 3. * MaxZN}, {nBinsADC, -0.5, 3. * MaxZN}}}}); + registry.add("ZNAcvsZNAsum", "ZNAcvsZNAsum ZNAC ADC; ZNAsum", {HistType::kTH2F, {{{nBinsADC, -0.5, 3. * MaxZN}, {nBinsADC, -0.5, 3. * MaxZN}}}}); + registry.add("ZPCcvsZPCsum", "ZPCcvsZPCsum ZPCC ADC; ZPCsum", {HistType::kTH2F, {{{nBinsADC, -0.5, 3. * MaxZP}, {nBinsADC, -0.5, 3. * MaxZP}}}}); + registry.add("ZPAcvsZPAsum", "ZPAcvsZPAsum ZPAC ADC; ZPAsum", {HistType::kTH2F, {{{nBinsADC, -0.5, 3. * MaxZP}, {nBinsADC, -0.5, 3. * MaxZP}}}}); // - registry.add("ZNCadcvstdc", "ZNCadcvstdc", {HistType::kTH2F, {{{400, -50., 50.}, {nBins1, -10., MaxZN}}}}); - registry.add("ZNAadcvstdc", "ZNAadcvstdc", {HistType::kTH2F, {{{400, -50., 50.}, {nBins1, -10., MaxZN}}}}); - registry.add("ZPCadcvstdc", "ZPCadcvstdc", {HistType::kTH2F, {{{400, -50., 50.}, {nBins1, -10., MaxZP}}}}); - registry.add("ZPAadcvstdc", "ZPAadcvstdc", {HistType::kTH2F, {{{400, -50., 50.}, {nBins1, -10., MaxZP}}}}); - registry.add("ZEM1adcvstdc", "ZEM1adcvstdc", {HistType::kTH2F, {{{400, -50., 50.}, {nBins1, -10., MaxZP}}}}); - registry.add("ZEM2adcvstdc", "ZEM2adcvstdc", {HistType::kTH2F, {{{400, -50., 50.}, {nBins1, -10., MaxZP}}}}); + registry.add("ZNCvstdc", "ZNCvstdc; ZNC amplitude; ZNC TDC", {HistType::kTH2F, {{{480, -13.5, 11.45}, {nBinsAmp, -0.5, MaxZN}}}}); + registry.add("ZNAvstdc", "ZNAvstdc; ZNA amplitude; ZNA TDC", {HistType::kTH2F, {{{480, -13.5, 11.45}, {nBinsAmp, -0.5, MaxZN}}}}); + registry.add("ZPCvstdc", "ZPCvstdc; ZPC amplitude; ZPC TDC", {HistType::kTH2F, {{{480, -13.5, 11.45}, {nBinsAmp, -0.5, MaxZP}}}}); + registry.add("ZPAvstdc", "ZPAvstdc; ZPA amplitude; ZPA TDC", {HistType::kTH2F, {{{480, -13.5, 11.45}, {nBinsAmp, -0.5, MaxZP}}}}); + registry.add("ZEM1vstdc", "ZEM1vstdc; ZEM1 amplitude; ZEM1 TDC", {HistType::kTH2F, {{{480, -13.5, 11.45}, {nBinsAmp, -0.5, MaxZEM}}}}); + registry.add("ZEM2vstdc", "ZEM2vstdc; ZEM2 amplitude; ZEM2 TDC", {HistType::kTH2F, {{{480, -13.5, 11.45}, {nBinsAmp, -0.5, MaxZEM}}}}); } if (doprocessZdcBcAss) { // Check if the process function for ZDCBcAss is enabled - registry.add("ZNAbc", "ZNAbc", {HistType::kTH1F, {{nBins1, -10., MaxZN}}}); - registry.add("ZNCbc", "ZNCbc", {HistType::kTH1F, {{nBins1, -10., MaxZN}}}); - registry.add("ZPAbc", "ZPAbc", {HistType::kTH1F, {{nBins1, -10., MaxZP}}}); - registry.add("ZPCbc", "ZPCbc", {HistType::kTH1F, {{nBins1, -10., MaxZP}}}); - registry.add("ZEM1bc", "ZEM1bc", {HistType::kTH1F, {{nBins1, -10., MaxZP}}}); - registry.add("ZEM2bc", "ZEM2bc", {HistType::kTH1F, {{nBins1, -10., MaxZP}}}); - registry.add("ZNvsZEMbc", "ZNvsZEMbc", {HistType::kTH2F, {{{nBins1, -10., MaxZP}, {nBins1, -10., MaxZN}}}}); - registry.add("ZNAvsZNCbc", "ZNAvsZNCbc", {HistType::kTH2F, {{{nBins1, -10., MaxZN}, {nBins1, -10., MaxZN}}}}); - registry.add("ZPAvsZPCbc", "ZPAvsZPCbc", {HistType::kTH2F, {{{nBins1, -10., MaxZP}, {nBins1, -10., MaxZP}}}}); - registry.add("ZNAvsZPAbc", "ZNAvsZPAbc", {HistType::kTH2F, {{{nBins1, -10., MaxZP}, {nBins1, -10., MaxZN}}}}); - registry.add("ZNCvsZPCbc", "ZNCvsZPCbc", {HistType::kTH2F, {{{nBins1, -10., MaxZP}, {nBins1, -10., MaxZN}}}}); + registry.add("ZNAbc", "ZNAbc; ZNA amplitude; Entries", {HistType::kTH1F, {{nBinsAmp, -0.5, MaxZN}}}); + registry.add("ZNCbc", "ZNCbc; ZNC amplitude; Entries", {HistType::kTH1F, {{nBinsAmp, -0.5, MaxZN}}}); + registry.add("ZPAbc", "ZPAbc; ZPA amplitude; Entries", {HistType::kTH1F, {{nBinsAmp, -0.5, MaxZP}}}); + registry.add("ZPCbc", "ZPCbc; ZPC amplitude; Entries", {HistType::kTH1F, {{nBinsAmp, -0.5, MaxZP}}}); + registry.add("ZEM1bc", "ZEM1bc; ZEM1 amplitude; Entries", {HistType::kTH1F, {{nBinsAmp, -0.5, MaxZEM}}}); + registry.add("ZEM2bc", "ZEM2bc; ZEM2 amplitude; Entries", {HistType::kTH1F, {{nBinsAmp, -0.5, MaxZEM}}}); + registry.add("ZNvsZEMbc", "ZNvsZEMbc; ZEM; ZNA+ZNC", {HistType::kTH2F, {{{nBinsAmp, -0.5, MaxZEM}, {nBinsAmp, -0.5, 2.0 * MaxZN}}}}); + registry.add("ZNAvsZNCbc", "ZNAvsZNCbc; ZNC; ZNA", {HistType::kTH2F, {{{nBinsAmp, -0.5, MaxZN}, {nBinsAmp, -0.5, MaxZN}}}}); + registry.add("ZPAvsZPCbc", "ZPAvsZPCbc; ZPC; ZPA", {HistType::kTH2F, {{{nBinsAmp, -0.5, MaxZP}, {nBinsAmp, -0.5, MaxZP}}}}); + registry.add("ZNAvsZPAbc", "ZNAvsZPAbc; ZPA; ZNA", {HistType::kTH2F, {{{nBinsAmp, -0.5, MaxZP}, {nBinsAmp, -0.5, MaxZN}}}}); + registry.add("ZNCvsZPCbc", "ZNCvsZPCbc; ZPC; ZNC", {HistType::kTH2F, {{{nBinsAmp, -0.5, MaxZP}, {nBinsAmp, -0.5, MaxZN}}}}); } if (doprocessZdcCollAss) { // Check if the process function for ZDCCollAss is enabled - registry.add("ZNAcoll", "ZNAcoll", {HistType::kTH1F, {{nBins1, -10., MaxZN}}}); - registry.add("ZPAcoll", "ZPAcoll", {HistType::kTH1F, {{nBins1, -10., MaxZP}}}); - registry.add("ZNCcoll", "ZNCcoll", {HistType::kTH1F, {{nBins1, -10., MaxZN}}}); - registry.add("ZPCcoll", "ZPCcoll", {HistType::kTH1F, {{nBins1, -10., MaxZP}}}); - registry.add("ZEM1coll", "ZEM1coll", {HistType::kTH1F, {{nBins1, -10., MaxZP}}}); - registry.add("ZEM2coll", "ZEM2coll", {HistType::kTH1F, {{nBins1, -10., MaxZP}}}); - registry.add("ZNvsZEMcoll", "ZNvsZEMcoll", {HistType::kTH2F, {{{nBins1, -10., MaxZP}, {nBins1, -10., MaxZN}}}}); - registry.add("ZNAvsZNCcoll", "ZNAvsZNCcoll", {HistType::kTH2F, {{{nBins1, -10., MaxZN}, {nBins1, -10., MaxZN}}}}); - registry.add("ZPAvsZPCcoll", "ZPAvsZPCcoll", {HistType::kTH2F, {{{nBins1, -10., MaxZP}, {nBins1, -10., MaxZP}}}}); - registry.add("ZNAvsZPAcoll", "ZNAvsZPAcoll", {HistType::kTH2F, {{{nBins1, -10., MaxZP}, {nBins1, -10., MaxZN}}}}); - registry.add("ZNCvsZPCcoll", "ZNCvsZPCcoll", {HistType::kTH2F, {{{nBins1, -10., MaxZP}, {nBins1, -10., MaxZN}}}}); + registry.add("ZNAcoll", "ZNAcoll; ZNA amplitude; Entries", {HistType::kTH1F, {{nBinsAmp, -0.5, MaxZN}}}); + registry.add("ZPAcoll", "ZPAcoll; ZPA amplitude; Entries", {HistType::kTH1F, {{nBinsAmp, -0.5, MaxZP}}}); + registry.add("ZNCcoll", "ZNCcoll; ZNC amplitude; Entries", {HistType::kTH1F, {{nBinsAmp, -0.5, MaxZN}}}); + registry.add("ZPCcoll", "ZPCcoll; ZPC amplitude; Entries", {HistType::kTH1F, {{nBinsAmp, -0.5, MaxZP}}}); + registry.add("ZEM1coll", "ZEM1coll; ZEM1 amplitude; Entries", {HistType::kTH1F, {{nBinsAmp, -0.5, MaxZEM}}}); + registry.add("ZEM2coll", "ZEM2coll; ZEM2 amplitude; Entries", {HistType::kTH1F, {{nBinsAmp, -0.5, MaxZEM}}}); + registry.add("ZNvsZEMcoll", "ZNvsZEMcoll; ZEM; ZNA+ZNC", {HistType::kTH2F, {{{nBinsAmp, -0.5, MaxZEM}, {nBinsAmp, -0.5, 2. * MaxZN}}}}); + registry.add("ZNAvsZNCcoll", "ZNAvsZNCcoll; ZNC; ZNA", {HistType::kTH2F, {{{nBinsAmp, -0.5, MaxZN}, {nBinsAmp, -0.5, MaxZN}}}}); + registry.add("ZPAvsZPCcoll", "ZPAvsZPCcoll; ZPA; ZPC", {HistType::kTH2F, {{{nBinsAmp, -0.5, MaxZP}, {nBinsAmp, -0.5, MaxZP}}}}); + registry.add("ZNAvsZPAcoll", "ZNAvsZPAcoll; ZPA; ZNA", {HistType::kTH2F, {{{nBinsAmp, -0.5, MaxZP}, {nBinsAmp, -0.5, MaxZN}}}}); + registry.add("ZNCvsZPCcoll", "ZNCvsZPCcoll; ZPC; ZNC", {HistType::kTH2F, {{{nBinsAmp, -0.5, MaxZP}, {nBinsAmp, -0.5, MaxZN}}}}); // - registry.add("ZNCadcvstdccoll", "ZNCadcvstdccoll", {HistType::kTH2F, {{{400, -50., 50.}, {nBins1, -10., MaxZN}}}}); - registry.add("ZNAadcvstdccoll", "ZNAadcvstdccoll", {HistType::kTH2F, {{{400, -50., 50.}, {nBins1, -10., MaxZN}}}}); - registry.add("ZPCadcvstdccoll", "ZPCadcvstdccoll", {HistType::kTH2F, {{{400, -50., 50.}, {nBins1, -10., MaxZP}}}}); - registry.add("ZPAadcvstdccoll", "ZPAadcvstdccoll", {HistType::kTH2F, {{{400, -50., 50.}, {nBins1, -10., MaxZP}}}}); - registry.add("ZEM1adcvstdccoll", "ZEM1adcvstdccoll", {HistType::kTH2F, {{{400, -50., 50.}, {nBins1, -10., MaxZP}}}}); - registry.add("ZEM2adcvstdccoll", "ZEM2adcvstdccoll", {HistType::kTH2F, {{{400, -50., 50.}, {nBins1, -10., MaxZP}}}}); + registry.add("ZNCvstdccoll", "ZNCvstdccoll", {HistType::kTH2F, {{{nBinsTDC, -13.5, 11.45}, {nBinsAmp, -0.5, MaxZN}}}}); + registry.add("ZNAvstdccoll", "ZNAvstdccoll", {HistType::kTH2F, {{{nBinsTDC, -13.5, 11.45}, {nBinsAmp, -0.5, MaxZN}}}}); + registry.add("ZPCvstdccoll", "ZPCvstdccoll", {HistType::kTH2F, {{{nBinsTDC, -13.5, 11.45}, {nBinsAmp, -0.5, MaxZP}}}}); + registry.add("ZPAvstdccoll", "ZPAvstdccoll", {HistType::kTH2F, {{{nBinsTDC, -13.5, 11.45}, {nBinsAmp, -0.5, MaxZP}}}}); + registry.add("ZEM1vstdccoll", "ZEM1vstdccoll", {HistType::kTH2F, {{{nBinsTDC, -13.5, 11.45}, {nBinsAmp, -0.5, MaxZEM}}}}); + registry.add("ZEM2vstdccoll", "ZEM2vstdccoll", {HistType::kTH2F, {{{nBinsTDC, -13.5, 11.45}, {nBinsAmp, -0.5, MaxZEM}}}}); } if (doprocessZdcCorrela) { // Check if the process function for ZDCCollCorrela is enabled - registry.add("ZNvsFV0Acorrel", "ZNvsFV0Acorrel", {HistType::kTH2F, {{{nBins2, 0., MaxMultFV0}, {nBins2, -10., MaxZN}}}}); - registry.add("ZNvsFT0correl", "ZNvsFT0correl", {HistType::kTH2F, {{{nBins2, 0., MaxMultFT0}, {nBins2, -10., MaxZN}}}}); - registry.add("ZNvsFDDcorrel", "ZNvsFDDcorrel", {HistType::kTH2F, {{{nBins2, 0., MaxMultFDD}, {nBins2, -10., MaxZN}}}}); + registry.add("ZNvsFV0Acorrel", "ZNvsFV0Acorrel", {HistType::kTH2F, {{{nBinsFit, 0., MaxMultFV0}, {nBinsAmp, -0.5, 2. * MaxZN}}}}); + registry.add("ZNvsFT0correl", "ZNvsFT0correl", {HistType::kTH2F, {{{nBinsFit, 0., MaxMultFT0}, {nBinsAmp, -0.5, 2. * MaxZN}}}}); + registry.add("ZNvsFDDcorrel", "ZNvsFDDcorrel", {HistType::kTH2F, {{{nBinsFit, 0., MaxMultFDD}, {nBinsAmp, -0.5, 2. * MaxZN}}}}); } } @@ -141,22 +153,19 @@ struct ZDCAnalysis { registry.get(HIST("ZPCcvsZPCsum"))->Fill(sumZPC, zdc.energyCommonZPC()); registry.get(HIST("ZPAcvsZPAsum"))->Fill(sumZPA, zdc.energyCommonZPA()); // - registry.get(HIST("ZNCadcvstdc"))->Fill(zdc.timeZNC(), zdc.amplitudeZNC()); - registry.get(HIST("ZNAadcvstdc"))->Fill(zdc.timeZNA(), zdc.amplitudeZNA()); - registry.get(HIST("ZPCadcvstdc"))->Fill(zdc.timeZPC(), zdc.amplitudeZPC()); - registry.get(HIST("ZPAadcvstdc"))->Fill(zdc.timeZPA(), zdc.amplitudeZPA()); - registry.get(HIST("ZEM1adcvstdc"))->Fill(zdc.timeZEM1(), zdc.amplitudeZEM1()); - registry.get(HIST("ZEM2adcvstdc"))->Fill(zdc.timeZEM2(), zdc.amplitudeZEM2()); + registry.get(HIST("ZNCvstdc"))->Fill(zdc.timeZNC(), zdc.amplitudeZNC()); + registry.get(HIST("ZNAvstdc"))->Fill(zdc.timeZNA(), zdc.amplitudeZNA()); + registry.get(HIST("ZPCvstdc"))->Fill(zdc.timeZPC(), zdc.amplitudeZPC()); + registry.get(HIST("ZPAvstdc"))->Fill(zdc.timeZPA(), zdc.amplitudeZPA()); + registry.get(HIST("ZEM1vstdc"))->Fill(zdc.timeZEM1(), zdc.amplitudeZEM1()); + registry.get(HIST("ZEM2vstdc"))->Fill(zdc.timeZEM2(), zdc.amplitudeZEM2()); } /// name, description, function pointer, default value /// note that it has to be declared after the function, so that the pointer is known - PROCESS_SWITCH(ZDCAnalysis, processZdcAuto, "Processing ZDC autotriggered events", true); + PROCESS_SWITCH(ZDCAnalysis, processZdcAuto, "Processing ZDC auto-triggered events", true); void processZdcBcAss( - // soa::Join const& bcs, - // BCsRun3 const& bcs, - // BCsWithBcSels const& bcs, - BCsWithRun3Matchings const& bcs, + BCsRun3 const& bcs, aod::Zdcs const& zdcs) { for (const auto& bc : bcs) { @@ -179,41 +188,69 @@ struct ZDCAnalysis { PROCESS_SWITCH(ZDCAnalysis, processZdcBcAss, "Processing ZDC w. BC association", true); void processZdcCollAss( - soa::Join::iterator const& collision, + ColEvSels const& cols, + BCsRun3 const& bcs, aod::Zdcs const& zdcs) { - if (collision.foundZDCId() >= 0) { - registry.get(HIST("ZNAcoll"))->Fill(collision.foundZDC().amplitudeZNA()); - registry.get(HIST("ZNCcoll"))->Fill(collision.foundZDC().amplitudeZNC()); - registry.get(HIST("ZPAcoll"))->Fill(collision.foundZDC().amplitudeZPA()); - registry.get(HIST("ZPCcoll"))->Fill(collision.foundZDC().amplitudeZPC()); - registry.get(HIST("ZEM1coll"))->Fill(collision.foundZDC().amplitudeZEM1()); - registry.get(HIST("ZEM2coll"))->Fill(collision.foundZDC().amplitudeZEM2()); - registry.get(HIST("ZNvsZEMcoll"))->Fill(collision.foundZDC().amplitudeZEM1() + collision.foundZDC().amplitudeZEM2(), collision.foundZDC().amplitudeZNA() + collision.foundZDC().amplitudeZNC()); - registry.get(HIST("ZNAvsZNCcoll"))->Fill(collision.foundZDC().amplitudeZNC(), collision.foundZDC().amplitudeZNA()); - registry.get(HIST("ZPAvsZPCcoll"))->Fill(collision.foundZDC().amplitudeZPC(), collision.foundZDC().amplitudeZPA()); - registry.get(HIST("ZNAvsZPAcoll"))->Fill(collision.foundZDC().amplitudeZPA(), collision.foundZDC().amplitudeZNA()); - registry.get(HIST("ZNCvsZPCcoll"))->Fill(collision.foundZDC().amplitudeZPC(), collision.foundZDC().amplitudeZNC()); - // - registry.get(HIST("ZNCadcvstdccoll"))->Fill(collision.foundZDC().timeZNC(), collision.foundZDC().amplitudeZNC()); - registry.get(HIST("ZNAadcvstdccoll"))->Fill(collision.foundZDC().timeZNA(), collision.foundZDC().amplitudeZNA()); - registry.get(HIST("ZPCadcvstdccoll"))->Fill(collision.foundZDC().timeZPC(), collision.foundZDC().amplitudeZPC()); - registry.get(HIST("ZPAadcvstdccoll"))->Fill(collision.foundZDC().timeZPA(), collision.foundZDC().amplitudeZPA()); - registry.get(HIST("ZEM1adcvstdccoll"))->Fill(collision.foundZDC().timeZEM1(), collision.foundZDC().amplitudeZEM1()); - registry.get(HIST("ZEM2adcvstdccoll"))->Fill(collision.foundZDC().timeZEM2(), collision.foundZDC().amplitudeZEM2()); + // collision-based event selection + for (auto& collision : cols) { + const auto& foundBC = collision.foundBC_as(); + if (foundBC.has_zdc()) { + const auto& zdcread = foundBC.zdc(); + if (TDCcut) { + if ((zdcread.timeZNA() >= tdcZNmincut) && (zdcread.timeZNA() <= tdcZNmaxcut)) + registry.get(HIST("ZNAcoll"))->Fill(zdcread.amplitudeZNA()); + if ((zdcread.timeZNC() >= tdcZNmincut) && (zdcread.timeZNC() <= tdcZNmaxcut)) + registry.get(HIST("ZNCcoll"))->Fill(zdcread.amplitudeZNC()); + if ((zdcread.timeZPA() >= tdcZPmincut) && (zdcread.timeZPA() <= tdcZPmaxcut)) + registry.get(HIST("ZPAcoll"))->Fill(zdcread.amplitudeZPA()); + if ((zdcread.timeZPC() >= tdcZPmincut) && (zdcread.timeZPC() <= tdcZPmaxcut)) + registry.get(HIST("ZPCcoll"))->Fill(zdcread.amplitudeZPC()); + if (((zdcread.timeZNC() >= tdcZNmincut) && (zdcread.timeZNC() <= tdcZNmaxcut)) && ((zdcread.timeZNA() >= tdcZNmincut) && (zdcread.timeZNA() <= tdcZNmaxcut))) + registry.get(HIST("ZNvsZEMcoll"))->Fill(zdcread.amplitudeZEM1() + zdcread.amplitudeZEM2(), zdcread.amplitudeZNA() + zdcread.amplitudeZNC()); + if (((zdcread.timeZNC() >= tdcZNmincut) && (zdcread.timeZNC() <= tdcZNmaxcut)) && ((zdcread.timeZNA() >= tdcZNmincut) && (zdcread.timeZNA() <= tdcZNmaxcut))) + registry.get(HIST("ZNAvsZNCcoll"))->Fill(zdcread.amplitudeZNC(), zdcread.amplitudeZNA()); + if (((zdcread.timeZPC() >= tdcZPmincut) && (zdcread.timeZPC() <= tdcZPmaxcut)) && ((zdcread.timeZPA() >= tdcZPmincut) && (zdcread.timeZPA() <= tdcZPmaxcut))) + registry.get(HIST("ZPAvsZPCcoll"))->Fill(zdcread.amplitudeZPC(), zdcread.amplitudeZPA()); + if ((zdcread.timeZNA() >= tdcZNmincut) && (zdcread.timeZNA() <= tdcZNmaxcut)) + registry.get(HIST("ZNAvsZPAcoll"))->Fill(zdcread.amplitudeZPA(), zdcread.amplitudeZNA()); + if ((zdcread.timeZNC() >= tdcZNmincut) && (zdcread.timeZNC() <= tdcZNmaxcut)) + registry.get(HIST("ZNCvsZPCcoll"))->Fill(zdcread.amplitudeZPC(), zdcread.amplitudeZNC()); + // + } else { + registry.get(HIST("ZNAcoll"))->Fill(zdcread.amplitudeZNA()); + registry.get(HIST("ZNCcoll"))->Fill(zdcread.amplitudeZNC()); + registry.get(HIST("ZPAcoll"))->Fill(zdcread.amplitudeZPA()); + registry.get(HIST("ZPCcoll"))->Fill(zdcread.amplitudeZPC()); + registry.get(HIST("ZNvsZEMcoll"))->Fill(zdcread.amplitudeZEM1() + zdcread.amplitudeZEM2(), zdcread.amplitudeZNA() + zdcread.amplitudeZNC()); + registry.get(HIST("ZNAvsZNCcoll"))->Fill(zdcread.amplitudeZNC(), zdcread.amplitudeZNA()); + registry.get(HIST("ZPAvsZPCcoll"))->Fill(zdcread.amplitudeZPC(), zdcread.amplitudeZPA()); + registry.get(HIST("ZNAvsZPAcoll"))->Fill(zdcread.amplitudeZPA(), zdcread.amplitudeZNA()); + registry.get(HIST("ZNCvsZPCcoll"))->Fill(zdcread.amplitudeZPC(), zdcread.amplitudeZNC()); + } + registry.get(HIST("ZEM1coll"))->Fill(zdcread.amplitudeZEM1()); + registry.get(HIST("ZEM2coll"))->Fill(zdcread.amplitudeZEM2()); + // + registry.get(HIST("ZNCvstdccoll"))->Fill(zdcread.timeZNC(), zdcread.amplitudeZNC()); + registry.get(HIST("ZNAvstdccoll"))->Fill(zdcread.timeZNA(), zdcread.amplitudeZNA()); + registry.get(HIST("ZPCvstdccoll"))->Fill(zdcread.timeZPC(), zdcread.amplitudeZPC()); + registry.get(HIST("ZPAvstdccoll"))->Fill(zdcread.timeZPA(), zdcread.amplitudeZPA()); + registry.get(HIST("ZEM1vstdccoll"))->Fill(zdcread.timeZEM1(), zdcread.amplitudeZEM1()); + registry.get(HIST("ZEM2vstdccoll"))->Fill(zdcread.timeZEM2(), zdcread.amplitudeZEM2()); + } } } PROCESS_SWITCH(ZDCAnalysis, processZdcCollAss, "Processing ZDC w. collision association", true); void processZdcCorrela( soa::Join::iterator const& coll, - BCsWithRun3Matchings const& bcs, + BCsRun3 const& bcs, aod::Zdcs const& zdcs, aod::FV0As const& fv0as, aod::FT0s const& ft0s, aod::FDDs const& fdds) { - const auto& foundBC = coll.foundBC_as(); + const auto& foundBC = coll.foundBC_as(); // FT0 float multT0A = 0; @@ -252,12 +289,13 @@ struct ZDCAnalysis { } if (foundBC.has_zdc()) { - registry.get(HIST("ZNvsFV0Acorrel"))->Fill(multV0A / 100., foundBC.zdc().amplitudeZNA() + foundBC.zdc().amplitudeZNC()); - registry.get(HIST("ZNvsFT0correl"))->Fill((multT0A + multT0C) / 100., foundBC.zdc().amplitudeZNC() + foundBC.zdc().amplitudeZNA()); - registry.get(HIST("ZNvsFDDcorrel"))->Fill(multFDC + multFDA, foundBC.zdc().amplitudeZNC() + foundBC.zdc().amplitudeZNA()); + const auto& zdcread = foundBC.zdc(); + registry.get(HIST("ZNvsFV0Acorrel"))->Fill(multV0A / 100., zdcread.amplitudeZNA() + zdcread.amplitudeZNC()); + registry.get(HIST("ZNvsFT0correl"))->Fill((multT0A + multT0C) / 100., zdcread.amplitudeZNC() + zdcread.amplitudeZNA()); + registry.get(HIST("ZNvsFDDcorrel"))->Fill(multFDC + multFDA, zdcread.amplitudeZNC() + zdcread.amplitudeZNA()); } } - PROCESS_SWITCH(ZDCAnalysis, processZdcCorrela, "Processing ZDC vs. mult. w. association", true); + PROCESS_SWITCH(ZDCAnalysis, processZdcCorrela, "Processing ZDC vs. mult. w. collision association", true); }; WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) diff --git a/PWGUD/Core/DGSelector.h b/PWGUD/Core/DGSelector.h index 0bb7e80bde2..57892e0771d 100644 --- a/PWGUD/Core/DGSelector.h +++ b/PWGUD/Core/DGSelector.h @@ -36,7 +36,7 @@ class DGSelector return 1; } - // Function to check if collisions passes DG filter + // Function to check if collision passes DG filter template int IsSelected(DGCutparHolder diffCuts, CC& collision, BCs& bcRange, TCs& tracks, FWs& fwdtracks) { @@ -50,43 +50,9 @@ class DGSelector // 1 TSC // 2 TCE // 3 TOR - int vetoToApply = -1; - if (diffCuts.withTVX()) { - vetoToApply = 0; - } else if (diffCuts.withTSC()) { - vetoToApply = 1; - } else if (diffCuts.withTCE()) { - vetoToApply = 2; - } else if (diffCuts.withTOR()) { - vetoToApply = 3; - } - if (vetoToApply >= 0) { - for (auto const& bc : bcRange) { - switch (vetoToApply) { - case 0: - if (udhelpers::TVX(bc)) { - return 1; - } - break; - case 1: - if (udhelpers::TSC(bc)) { - return 1; - } - break; - case 2: - if (udhelpers::TCE(bc)) { - return 1; - } - break; - case 3: - if (!udhelpers::cleanFIT(bc, diffCuts.maxFITtime(), diffCuts.FITAmpLimits())) { - return 1; - } - break; - default: - LOGF(info, "Invalid veto trigger value: %d", vetoToApply); - break; - } + for (auto const& bc : bcRange) { + if (udhelpers::FITveto(bc, diffCuts)) { + return 1; } } @@ -188,10 +154,15 @@ class DGSelector template int IsSelected(DGCutparHolder diffCuts, BCs& bcRange, TCs& tracks, FWs& fwdtracks) { - // check that there are no FIT signals in bcRange + // return if FIT veto is found in any of the compatible BCs // Double Gap (DG) condition + // 4 types of vetoes: + // 0 TVX + // 1 TSC + // 2 TCE + // 3 TOR for (auto const& bc : bcRange) { - if (!udhelpers::cleanFIT(bc, diffCuts.maxFITtime(), diffCuts.FITAmpLimits())) { + if (udhelpers::FITveto(bc, diffCuts)) { return 1; } } diff --git a/PWGUD/Core/UDHelpers.h b/PWGUD/Core/UDHelpers.h index 408dce94f9f..6c5b524bd74 100644 --- a/PWGUD/Core/UDHelpers.h +++ b/PWGUD/Core/UDHelpers.h @@ -295,28 +295,32 @@ bool hasGoodPID(DGCutparHolder diffCuts, TC track) } // ----------------------------------------------------------------------------- -float FV0AmplitudeA(aod::FV0A&& fv0) +template +float FV0AmplitudeA(TFV0 fv0) { const auto& ampsA = fv0.amplitude(); return std::accumulate(ampsA.begin(), ampsA.end(), 0.f); } // ----------------------------------------------------------------------------- -float FT0AmplitudeA(aod::FT0&& ft0) +template +float FT0AmplitudeA(TFT0 ft0) { const auto& ampsA = ft0.amplitudeA(); return std::accumulate(ampsA.begin(), ampsA.end(), 0.f); } // ----------------------------------------------------------------------------- -float FT0AmplitudeC(aod::FT0&& ft0) +template +float FT0AmplitudeC(TFT0 ft0) { const auto& ampsC = ft0.amplitudeC(); return std::accumulate(ampsC.begin(), ampsC.end(), 0.f); } // ----------------------------------------------------------------------------- -float FDDAmplitudeA(aod::FDD&& fdd) +template +float FDDAmplitudeA(TFDD fdd) { float totAmplitude = 0; for (auto amp : fdd.chargeA()) { @@ -327,7 +331,8 @@ float FDDAmplitudeA(aod::FDD&& fdd) } // ----------------------------------------------------------------------------- -float FDDAmplitudeC(aod::FDD&& fdd) +template +float FDDAmplitudeC(TFDD fdd) { float totAmplitude = 0; for (auto amp : fdd.chargeC()) { @@ -510,11 +515,39 @@ bool TCE(T& bc) template bool TOR(T& bc, float maxFITtime, std::vector lims) { - auto torA = !cleanFT0A(bc, maxFITtime, lims); - auto torC = !cleanFT0C(bc, maxFITtime, lims); + auto torA = !cleanFT0A(bc, maxFITtime, lims[1]); + auto torC = !cleanFT0C(bc, maxFITtime, lims[2]); return torA || torC; } +// ----------------------------------------------------------------------------- +// returns true if veto is active +// return false if veto is not active +template +bool FITveto(T const& bc, DGCutparHolder const& diffCuts) +{ + // return if FIT veto is found in bc + // Double Gap (DG) condition + // 4 types of vetoes: + // 0 TVX + // 1 TSC + // 2 TCE + // 3 TOR + if (diffCuts.withTVX()) { + return TVX(bc); + } + if (diffCuts.withTSC()) { + return TSC(bc); + } + if (diffCuts.withTCE()) { + return TCE(bc); + } + if (diffCuts.withTOR()) { + return !cleanFIT(bc, diffCuts.maxFITtime(), diffCuts.FITAmpLimits()); + } + return false; +} + // ----------------------------------------------------------------------------- // fill BB and BG information into FITInfo template diff --git a/PWGUD/Core/UPCHelpers.h b/PWGUD/Core/UPCHelpers.h index fff78b297f7..03ff2475c8c 100644 --- a/PWGUD/Core/UPCHelpers.h +++ b/PWGUD/Core/UPCHelpers.h @@ -92,10 +92,11 @@ struct FITInfo { int32_t distClosestBcTSC = 999; int32_t distClosestBcTVX = 999; int32_t distClosestBcV0A = 999; + int32_t distClosestBcT0A = 999; }; -template -void applyFwdCuts(UPCCutparHolder& upcCuts, const ForwardTracks::iterator& track, TSelectorsArray& fwdSelectors) +template +void applyFwdCuts(UPCCutparHolder& upcCuts, const T& track, TSelectorsArray& fwdSelectors) { fwdSelectors[kFwdSelPt] = track.pt() > upcCuts.getFwdPtLow() && track.pt() < upcCuts.getFwdPtHigh(); // check pt fwdSelectors[kFwdSelEta] = track.eta() > upcCuts.getFwdEtaLow() && track.eta() < upcCuts.getFwdEtaHigh(); // check pseudorapidity @@ -104,8 +105,8 @@ void applyFwdCuts(UPCCutparHolder& upcCuts, const ForwardTracks::iterator& track fwdSelectors[kFwdSelChi2] = track.chi2() > upcCuts.getFwdChi2Low() && track.chi2() < upcCuts.getFwdChi2High(); // check chi2 } -template -void applyBarrelCuts(UPCCutparHolder& upcCuts, const BarrelTracks::iterator& track, TSelectorsArray& barrelSelectors) +template +void applyBarrelCuts(UPCCutparHolder& upcCuts, const T& track, TSelectorsArray& barrelSelectors) { barrelSelectors[kAmbiguous] = true; if (upcCuts.getAmbigSwitch()) diff --git a/PWGUD/Core/UPCTauCentralBarrelHelperRL.h b/PWGUD/Core/UPCTauCentralBarrelHelperRL.h new file mode 100644 index 00000000000..7c19cb98164 --- /dev/null +++ b/PWGUD/Core/UPCTauCentralBarrelHelperRL.h @@ -0,0 +1,178 @@ +// 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 +/// \author Roman Lavicka, roman.lavicka@cern.ch +/// \since 27.10.2022 + +#ifndef PWGUD_CORE_UPCTAUCENTRALBARRELHELPERRL_H_ +#define PWGUD_CORE_UPCTAUCENTRALBARRELHELPERRL_H_ + +#include +#include + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +enum MyParticle { + P_ELECTRON = 0, + P_MUON = 1, + P_PION = 2, + P_KAON = 3, + P_PROTON = 4 +}; + +void printLargeMessage(std::string info) +// Helper to printf info message to terminal +{ + LOGF(info, "################################### %s ###################################", info); +} + +void printMediumMessage(std::string info) +// Helper to printf info message to terminal +{ + LOGF(info, "+++++++++++++ %s +++++++++++++", info); +} + +template +int testPIDhypothesis(T trackPIDinfo, float nSigmaShift = 0., bool isMC = false) +// Choose, which particle it is according to PID +{ + float nSigmaTPC[5]; + nSigmaTPC[P_ELECTRON] = std::abs(trackPIDinfo.tpcNSigmaEl()); + nSigmaTPC[P_MUON] = std::abs(trackPIDinfo.tpcNSigmaMu()); + nSigmaTPC[P_PION] = std::abs(trackPIDinfo.tpcNSigmaPi()); + nSigmaTPC[P_KAON] = std::abs(trackPIDinfo.tpcNSigmaKa()); + nSigmaTPC[P_PROTON] = std::abs(trackPIDinfo.tpcNSigmaPr()); + // Correction if TPC tuneOnData is wrong + if (isMC) { + for (int i = 0; i < 5; i++) + nSigmaTPC[i] -= nSigmaShift; + } + int enumChoiceTPC = std::distance(std::begin(nSigmaTPC), + std::min_element(std::begin(nSigmaTPC), std::end(nSigmaTPC))); + + float nSigmaTOF[5]; + nSigmaTOF[P_ELECTRON] = std::abs(trackPIDinfo.tofNSigmaEl()); + nSigmaTOF[P_MUON] = std::abs(trackPIDinfo.tofNSigmaMu()); + nSigmaTOF[P_PION] = std::abs(trackPIDinfo.tofNSigmaPi()); + nSigmaTOF[P_KAON] = std::abs(trackPIDinfo.tofNSigmaKa()); + nSigmaTOF[P_PROTON] = std::abs(trackPIDinfo.tofNSigmaPr()); + int enumChoiceTOF = std::distance(std::begin(nSigmaTOF), + std::min_element(std::begin(nSigmaTOF), std::end(nSigmaTOF))); + + if (trackPIDinfo.hasTPC() || trackPIDinfo.hasTOF()) { + if (trackPIDinfo.hasTOF()) { + return enumChoiceTOF; + } else { + return enumChoiceTPC; + } + } else { + LOGF(debug, "testPIDhypothesis failed - track did not leave information in TPC or TOF"); + return -1; + } +} + +template +int trackPDG(T trackPIDinfo) +// using testPIDhypothesis, reads enumMyParticle and return pdg value +{ + if (testPIDhypothesis(trackPIDinfo) == P_ELECTRON) { + return 11; + } else if (testPIDhypothesis(trackPIDinfo) == P_MUON) { + return 13; + } else if (testPIDhypothesis(trackPIDinfo) == P_PION) { + return 211; + } else if (testPIDhypothesis(trackPIDinfo) == P_KAON) { + return 321; + } else if (testPIDhypothesis(trackPIDinfo) == P_PROTON) { + return 2212; + } else { + printMediumMessage("Something is wrong with track PDG selector"); + return -1.; + } +} + +int enumMyParticle(int valuePDG) +// reads pdg value and returns particle number as in enumMyParticle +{ + if (std::abs(valuePDG) == 11) { + return P_ELECTRON; + } else if (std::abs(valuePDG) == 13) { + return P_MUON; + } else if (std::abs(valuePDG) == 211) { + return P_PION; + } else if (std::abs(valuePDG) == 321) { + return P_KAON; + } else if (std::abs(valuePDG) == 2212) { + return P_PROTON; + } else { + printMediumMessage("PDG value not found in enumMyParticle. Returning -1."); + return -1.; + } +} + +float momentum(float px, float py, float pz) +// Just a simple function to return momentum +{ + return std::sqrt(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 phi(float px, float py) +// Just a simple function to return azimuthal angle +{ + if (px != 0) + return std::atan(py / px); + return -999.; +} + +float eta(float px, float py, float pz) +// Just a simple function to return pseudorapidity +{ + float eta = -999.; + float mom = momentum(px, py, pz); + if (mom != 0) + eta = std::atanh(pz / mom); + if (-1. < eta && eta < 1.) + return eta; + return -999.; +} + +float energy(float mass, float px, float py, float pz) +// Just a simple function to return track energy +{ + return std::sqrt(mass * mass + px * px + py * py + pz * pz); +} + +float rapidity(float mass, float px, float py, float pz) +// Just a simple function to return track rapidity +{ + return 0.5 * std::log((energy(mass, px, py, pz) + pz) / (energy(mass, px, py, pz) - pz)); +} + +double calculateAcoplanarity(double phi_trk1, double phi_trk2) +// Function to calculate acoplanarity of two tracks based on phi of both tracks, which is in interval (0,2*pi) +{ + double aco = std::abs(phi_trk1 - phi_trk2); + if (aco <= o2::constants::math::PI) + return aco; + else + return (o2::constants::math::TwoPI - aco); +} + +#endif // PWGUD_CORE_UPCTAUCENTRALBARRELHELPERRL_H_ diff --git a/PWGUD/DataModel/UDTables.h b/PWGUD/DataModel/UDTables.h index 77ad6e9d5f8..1f3d5a7db98 100644 --- a/PWGUD/DataModel/UDTables.h +++ b/PWGUD/DataModel/UDTables.h @@ -140,6 +140,11 @@ DECLARE_SOA_COLUMN(DBcTVX, dBcTVX, int32_t); //! distance to closest TVX DECLARE_SOA_COLUMN(DBcV0A, dBcV0A, int32_t); //! distance to closest V0A DECLARE_SOA_COLUMN(DBcT0A, dBcT0A, int32_t); //! distance to closest T0A +DECLARE_SOA_COLUMN(AmplitudesT0A, amplitudesT0A, std::vector); //! total T0A amplitudes in neighbouring BCs +DECLARE_SOA_COLUMN(AmplitudesV0A, amplitudesV0A, std::vector); //! total V0A amplitudes in neighbouring BCs +DECLARE_SOA_COLUMN(AmpRelBCsT0A, ampRelBCsT0A, std::vector); //! glob. BC w.r.t. candidate BC, size = size of amplitudes +DECLARE_SOA_COLUMN(AmpRelBCsV0A, ampRelBCsV0A, std::vector); //! glob. BC w.r.t. candidate BC, size = size of amplitudes + DECLARE_SOA_INDEX_COLUMN(Collision, collision); DECLARE_SOA_INDEX_COLUMN(UDMcCollision, udMcCollision); @@ -181,12 +186,21 @@ DECLARE_SOA_TABLE(UDCollisionsSels, "AOD", "UDCOLLISIONSEL", udcollision::BBFV0A, udcollision::BGFV0A, udcollision::BBFDDA, udcollision::BBFDDC, udcollision::BGFDDA, udcollision::BGFDDC); -DECLARE_SOA_TABLE(UDCollisionsSelsExtra, "AOD", "UDCOLSELEXTRA", +// central barrel-specific selections +DECLARE_SOA_TABLE(UDCollisionsSelsCent, "AOD", "UDCOLSELCNT", udcollision::DBcTOR, udcollision::DBcTSC, udcollision::DBcTVX, + udcollision::DBcV0A); + +// forward-specific selections +DECLARE_SOA_TABLE(UDCollisionsSelsFwd, "AOD", "UDCOLSELFWD", udcollision::DBcV0A, - udcollision::DBcT0A); + udcollision::DBcT0A, + udcollision::AmplitudesT0A, + udcollision::AmpRelBCsT0A, + udcollision::AmplitudesV0A, + udcollision::AmpRelBCsV0A); DECLARE_SOA_TABLE(UDCollsLabels, "AOD", "UDCOLLSLABEL", udcollision::CollisionId); @@ -197,7 +211,8 @@ DECLARE_SOA_TABLE(UDMcCollsLabels, "AOD", "UDMCCOLLSLABEL", using UDCollision = UDCollisions::iterator; using SGCollision = SGCollisions::iterator; using UDCollisionsSel = UDCollisionsSels::iterator; -using UDCollisionsSelExtra = UDCollisionsSelsExtra::iterator; +using UDCollisionsSelCent = UDCollisionsSelsCent::iterator; +using UDCollisionsSelFwd = UDCollisionsSelsFwd::iterator; using UDCollsLabel = UDCollsLabels::iterator; using UDMcCollsLabel = UDMcCollsLabels::iterator; @@ -353,6 +368,31 @@ DECLARE_SOA_TABLE(UDFwdTracksExtra, "AOD", "UDFWDTRACKEXTRA", using UDFwdTrack = UDFwdTracks::iterator; using UDFwdTrackExtra = UDFwdTracksExtra::iterator; +DECLARE_SOA_TABLE(UDFwdTracksProp, "AOD", "UDFWDTRACKPROP", + o2::soa::Index<>, fwdtrack::CollisionId, fwdtrack::TrackType, + fwdtrack::X, fwdtrack::Y, fwdtrack::Z, fwdtrack::Phi, fwdtrack::Tgl, + fwdtrack::Signed1Pt, + fwdtrack::Px, + fwdtrack::Py, + fwdtrack::Pz, + fwdtrack::Sign, + fwdtrack::Eta, + fwdtrack::Pt, + fwdtrack::P, + fwdtrack::NClusters, fwdtrack::PDca, fwdtrack::RAtAbsorberEnd, + fwdtrack::Chi2, fwdtrack::Chi2MatchMCHMID, fwdtrack::Chi2MatchMCHMFT, + fwdtrack::MatchScoreMCHMFT, fwdtrack::MFTTrackId, fwdtrack::MCHTrackId, + fwdtrack::MCHBitMap, fwdtrack::MIDBoards, fwdtrack::MIDBitMap, + fwdtrack::TrackTime, fwdtrack::TrackTimeRes); + +DECLARE_SOA_TABLE(UDFwdTracksCovProp, "AOD", "UDFWDTRKCOVPROP", + fwdtrack::SigmaX, fwdtrack::SigmaY, fwdtrack::SigmaTgl, fwdtrack::SigmaPhi, fwdtrack::Sigma1Pt, + fwdtrack::RhoXY, fwdtrack::RhoPhiY, fwdtrack::RhoPhiX, fwdtrack::RhoTglX, fwdtrack::RhoTglY, + fwdtrack::RhoTglPhi, fwdtrack::Rho1PtX, fwdtrack::Rho1PtY, fwdtrack::Rho1PtPhi, fwdtrack::Rho1PtTgl); + +using UDFwdTrackProp = UDFwdTracksProp::iterator; +using UDFwdTrackCovProp = UDFwdTracksCovProp::iterator; + namespace udmcfwdtracklabel { DECLARE_SOA_INDEX_COLUMN(UDMcParticle, udMcParticle); @@ -373,6 +413,11 @@ DECLARE_SOA_COLUMN(ChannelE, channelE, std::vector); //! Channel IDs wh DECLARE_SOA_COLUMN(Amplitude, amplitude, std::vector); //! Amplitudes of non-zero channels. The channel IDs are given in ChannelT (at the same index) DECLARE_SOA_COLUMN(Time, time, std::vector); //! Times of non-zero channels. The channel IDs are given in ChannelT (at the same index) DECLARE_SOA_COLUMN(ChannelT, channelT, std::vector); //! Channel IDs which had non-zero amplitudes. There are at maximum 26 channels. + +DECLARE_SOA_COLUMN(TimeZNA, timeZNA, float); +DECLARE_SOA_COLUMN(TimeZNC, timeZNC, float); +DECLARE_SOA_COLUMN(EnergyCommonZNA, energyCommonZNA, float); +DECLARE_SOA_COLUMN(EnergyCommonZNC, energyCommonZNC, float); } // namespace udzdc DECLARE_SOA_TABLE(UDZdcs, "AOD", "UDZDC", //! ZDC information @@ -407,6 +452,16 @@ DECLARE_SOA_TABLE(UDZdcs, "AOD", "UDZDC", //! ZDC information using UDZdc = UDZdcs::iterator; +// reduced ZDC table +DECLARE_SOA_TABLE(UDZdcsReduced, "AOD", "UDZDCREDUCE", + udzdc::UDCollisionId, + udzdc::TimeZNA, + udzdc::TimeZNC, + udzdc::EnergyCommonZNA, + udzdc::EnergyCommonZNC); + +using UDZdcReduced = UDZdcsReduced::iterator; + } // namespace o2::aod #endif // PWGUD_DATAMODEL_UDTABLES_H_ diff --git a/PWGUD/TableProducer/CMakeLists.txt b/PWGUD/TableProducer/CMakeLists.txt index ba4413edbf3..2406868718c 100644 --- a/PWGUD/TableProducer/CMakeLists.txt +++ b/PWGUD/TableProducer/CMakeLists.txt @@ -28,3 +28,8 @@ o2physics_add_dpl_workflow(upccand-producer SOURCES UPCCandidateProducer.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::UPCCutparHolder COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(fwdtrack-propagation + SOURCES fwdTrackPropagation.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::GlobalTracking + COMPONENT_NAME Analysis) diff --git a/PWGUD/TableProducer/DGCandProducer.cxx b/PWGUD/TableProducer/DGCandProducer.cxx index aec55e0c8af..4c319873ef2 100644 --- a/PWGUD/TableProducer/DGCandProducer.cxx +++ b/PWGUD/TableProducer/DGCandProducer.cxx @@ -11,7 +11,6 @@ // // \brief Saves relevant information of DG candidates // \author Paul Buehler, paul.buehler@oeaw.ac.at -// \since 20.05.2022 #include "Framework/runDataProcessing.h" #include "Framework/AnalysisTask.h" @@ -129,6 +128,53 @@ struct DGCandProducer { outputTracksLabel(track.globalIndex()); } + template + void fillFIThistograms(TBC const& bc) + { + std::array triggers{{true, udhelpers::TOR(bc, diffCuts.maxFITtime(), diffCuts.FITAmpLimits()), + udhelpers::TVX(bc), udhelpers::TSC(bc), udhelpers::TCE(bc)}}; + + if (bc.has_foundFV0()) { + auto fv0 = bc.foundFV0(); + auto ampA = udhelpers::FV0AmplitudeA(fv0); + registry.get(HIST("reco/fv0"))->Fill(ampA, 0); + registry.get(HIST("reco/fv0"))->Fill(ampA, triggers[1] ? 1 : 5); + registry.get(HIST("reco/fv0"))->Fill(ampA, triggers[2] ? 2 : 6); + registry.get(HIST("reco/fv0"))->Fill(ampA, triggers[3] ? 3 : 7); + registry.get(HIST("reco/fv0"))->Fill(ampA, triggers[4] ? 4 : 8); + } + if (bc.has_foundFT0()) { + auto ft0 = bc.foundFT0(); + auto ampA = udhelpers::FT0AmplitudeA(ft0); + auto ampC = udhelpers::FT0AmplitudeC(ft0); + registry.get(HIST("reco/ft0A"))->Fill(ampA, 0); + registry.get(HIST("reco/ft0C"))->Fill(ampC, 0); + registry.get(HIST("reco/ft0A"))->Fill(ampA, triggers[1] ? 1 : 5); + registry.get(HIST("reco/ft0C"))->Fill(ampC, triggers[1] ? 1 : 5); + registry.get(HIST("reco/ft0A"))->Fill(ampA, triggers[2] ? 2 : 6); + registry.get(HIST("reco/ft0C"))->Fill(ampC, triggers[2] ? 2 : 6); + registry.get(HIST("reco/ft0A"))->Fill(ampA, triggers[3] ? 3 : 7); + registry.get(HIST("reco/ft0C"))->Fill(ampC, triggers[3] ? 3 : 7); + registry.get(HIST("reco/ft0A"))->Fill(ampA, triggers[4] ? 4 : 8); + registry.get(HIST("reco/ft0C"))->Fill(ampC, triggers[4] ? 4 : 8); + } + if (bc.has_foundFDD()) { + auto fdd = bc.foundFDD(); + auto ampA = udhelpers::FDDAmplitudeA(fdd); + auto ampC = udhelpers::FDDAmplitudeC(fdd); + registry.get(HIST("reco/fddA"))->Fill(ampA, 0); + registry.get(HIST("reco/fddC"))->Fill(ampC, 0); + registry.get(HIST("reco/fddA"))->Fill(ampA, triggers[1] ? 1 : 5); + registry.get(HIST("reco/fddC"))->Fill(ampC, triggers[1] ? 1 : 5); + registry.get(HIST("reco/fddA"))->Fill(ampA, triggers[2] ? 2 : 6); + registry.get(HIST("reco/fddC"))->Fill(ampC, triggers[2] ? 2 : 6); + registry.get(HIST("reco/fddA"))->Fill(ampA, triggers[3] ? 3 : 7); + registry.get(HIST("reco/fddC"))->Fill(ampC, triggers[3] ? 3 : 7); + registry.get(HIST("reco/fddA"))->Fill(ampA, triggers[4] ? 4 : 8); + registry.get(HIST("reco/fddC"))->Fill(ampC, triggers[4] ? 4 : 8); + } + } + void init(InitContext&) { diffCuts = (DGCutparHolder)DGCuts; @@ -139,6 +185,18 @@ struct DGCandProducer { registry.add("reco/TPCsignal1", "2 prong events, TPC signal versus p_{T} of particle 1", {HistType::kTH2F, {{200, -3., 3.}, {200, 0., 100.0}}}); registry.add("reco/TPCsignal2", "2 prong events, TPC signal versus p_{T} of particle 2", {HistType::kTH2F, {{200, -3., 3.}, {200, 0., 100.0}}}); registry.add("reco/sig1VsSig2TPC", "2 prong events, TPC signal versus TPC signal", {HistType::kTH2F, {{100, 0., 100.}, {100, 0., 100.}}}); + + // FIT amplitudes + // 0: unconditional + // 1: TOR 5: no TOR + // 2: TVX 6: no TVX + // 3: TSC 7: no TSC + // 4: TCE 8: no TCE + registry.add("reco/fv0", "FV0 amplitudes", {HistType::kTH2F, {{20001, -0.5, 20000.5}, {9, -0.5, 8.5}}}); + registry.add("reco/ft0A", "FT0A amplitudes", {HistType::kTH2F, {{20001, -0.5, 20000.5}, {9, -0.5, 8.5}}}); + registry.add("reco/ft0C", "FT0C amplitudes", {HistType::kTH2F, {{20001, -0.5, 20000.5}, {9, -0.5, 8.5}}}); + registry.add("reco/fddA", "FDDA amplitudes", {HistType::kTH2F, {{20001, -0.5, 20000.5}, {9, -0.5, 8.5}}}); + registry.add("reco/fddC", "FDDC amplitudes", {HistType::kTH2F, {{20001, -0.5, 20000.5}, {9, -0.5, 8.5}}}); } // process function for real data @@ -153,6 +211,9 @@ struct DGCandProducer { auto bc = collision.foundBC_as(); LOGF(debug, " BC id %d", bc.globalBC()); + // fill FIT histograms + fillFIThistograms(bc); + // obtain slice of compatible BCs auto bcRange = udhelpers::compatibleBCs(collision, diffCuts.NDtcoll(), bcs, diffCuts.minNBCs()); LOGF(debug, " Size of bcRange %d", bcRange.size()); @@ -420,6 +481,10 @@ struct McDGCandProducer { LOGF(info, "Number of McCollisions %d", mccols.size()); LOGF(info, "Number of DG candidates %d", dgcands.size()); LOGF(info, "Number of UD tracks %d", udtracks.size()); + if (dgcands.size() <= 0) { + LOGF(info, "No DG candidates to save!"); + return; + } // use a hash table to keep track of the McCollisions which have been added to the UDMcCollision table // {McCollisionId : udMcCollisionId} diff --git a/PWGUD/TableProducer/UPCCandidateProducer.cxx b/PWGUD/TableProducer/UPCCandidateProducer.cxx index 8f679010bf3..ff81786fc3f 100644 --- a/PWGUD/TableProducer/UPCCandidateProducer.cxx +++ b/PWGUD/TableProducer/UPCCandidateProducer.cxx @@ -45,7 +45,10 @@ struct UpcCandProducer { Produces eventCandidates; Produces eventCandidatesSels; - Produces eventCandidatesSelsExtra; + Produces eventCandidatesSelsCent; + Produces eventCandidatesSelsFwd; + + Produces udZdcsReduced; std::vector fwdSelectors; std::vector barrelSelectors; @@ -64,6 +67,7 @@ struct UpcCandProducer { Configurable fFilterTVX{"filterTVX", -1, "Filter candidates by FT0 TVX"}; Configurable fFilterFV0{"filterFV0", -1, "Filter candidates by FV0A"}; + Configurable fBCWindowFITAmps{"bcWindowFITAmps", 20, "BC range for T0A/V0A amplitudes array [-range, +(range-1)]"}; Configurable fBcWindowMCH{"bcWindowMCH", 20, "Time window for MCH-MID to MCH-only matching for Muon candidates"}; Configurable fBcWindowITSTPC{"bcWindowITSTPC", 20, "Time window for TOF/ITS-TPC to ITS-TPC matching for Central candidates"}; @@ -82,7 +86,7 @@ struct UpcCandProducer { using BCsWithBcSels = o2::soa::Join; - using ForwardTracks = o2::soa::Join; + using ForwardTracks = o2::soa::Join; using BarrelTracks = o2::soa::Join(HIST("hCountersTrg"))->GetXaxis()->SetBinLabel(1, "TCE"); + const AxisSpec axisBcDist{201, 0.5, 200.5, ""}; histRegistry.add("hDistToITSTPC", "", kTH1F, {axisBcDist}); @@ -124,7 +132,8 @@ struct UpcCandProducer { histRegistry.get(HIST("BarrelsSelCounter"))->GetXaxis()->SetBinLabel(upchelpers::kBarrelSelDCAZ + 1, "DCAZ"); } - bool applyFwdCuts(const ForwardTracks::iterator& track) + template + bool applyFwdCuts(const T& track) { histRegistry.fill(HIST("MuonsSelCounter"), upchelpers::kFwdSelAll, 1); @@ -154,7 +163,8 @@ struct UpcCandProducer { return pass; } - bool applyBarCuts(const BarrelTracks::iterator& track) + template + bool applyBarCuts(const T& track) { // using any cuts at all? if (!upcCuts.getUseBarCuts()) @@ -251,9 +261,10 @@ struct UpcCandProducer { return (dbc1 <= dbc2) ? it1 : it2; } + template void skimMCInfo(o2::aod::McCollisions const& mcCollisions, o2::aod::McParticles const& mcParticles, - BCsWithBcSels const& bcs) + TBCs const& bcs) { std::vector newEventIDs(mcCollisions.size(), -1); @@ -325,7 +336,7 @@ struct UpcCandProducer { continue; } const auto& mcEvent = mcCollisions.iteratorAt(i); - auto bc = mcEvent.bc_as(); + const auto& bc = mcEvent.bc_as(); udMCCollisions(bc.globalBC(), mcEvent.generatorsID(), mcEvent.posX(), mcEvent.posY(), mcEvent.posZ(), mcEvent.t(), mcEvent.weight(), mcEvent.impactParameter()); } @@ -536,13 +547,13 @@ struct UpcCandProducer { } // "uncorrected" bcs - template + template void collectAmbTrackBCs(std::unordered_map& ambTrIds, TAmbTracks ambTracks) { for (const auto& ambTrk : ambTracks) { auto trkId = getAmbTrackId(ambTrk); - const auto& bcSlice = ambTrk.bc(); + const auto& bcSlice = ambTrk.template bc_as(); uint64_t trackBC = -1; if (bcSlice.size() != 0) { auto first = bcSlice.begin(); @@ -564,9 +575,10 @@ struct UpcCandProducer { // trackType == 0 -> hasTOF // trackType == 1 -> hasITS and not hasTOF + template void collectBarrelTracks(std::vector& bcsMatchedTrIds, int trackType, - BCsWithBcSels const& bcs, + TBCs const& bcs, o2::aod::Collisions const& collisions, BarrelTracks const& barrelTracks, o2::aod::AmbiguousTracks const& ambBarrelTracks, @@ -587,7 +599,7 @@ struct UpcCandProducer { if (trk.has_collision()) { const auto& col = trk.collision(); nContrib = col.numContrib(); - trackBC = col.bc_as().globalBC(); + trackBC = col.bc_as().globalBC(); } else { auto ambIter = ambBarrelTrBCs.find(trkId); if (ambIter != ambBarrelTrBCs.end()) @@ -601,9 +613,10 @@ struct UpcCandProducer { } } + template void collectForwardTracks(std::vector& bcsMatchedTrIds, int typeFilter, - BCsWithBcSels const& bcs, + TBCs const& bcs, o2::aod::Collisions const& collisions, ForwardTracks const& fwdTracks, o2::aod::AmbiguousFwdTracks const& ambFwdTracks, @@ -621,7 +634,7 @@ struct UpcCandProducer { if (ambIter == ambFwdTrBCs.end()) { const auto& col = trk.collision(); nContrib = col.numContrib(); - trackBC = col.bc_as().globalBC(); + trackBC = col.bc_as().globalBC(); } else { trackBC = ambIter->second; } @@ -677,11 +690,12 @@ struct UpcCandProducer { void createCandidatesCentral(BarrelTracks const& barrelTracks, o2::aod::AmbiguousTracks const& ambBarrelTracks, - BCsWithBcSels const& bcs, + o2::aod::BCs const& bcs, o2::aod::Collisions const& collisions, o2::aod::FT0s const& ft0s, o2::aod::FDDs const& fdds, o2::aod::FV0As const& fv0as, + o2::aod::Zdcs const& zdcs, const o2::aod::McTrackLabels* mcBarrelTrackLabels) { // pairs of global BCs and vectors of matched track IDs: @@ -691,7 +705,7 @@ struct UpcCandProducer { // trackID -> index in amb. track table std::unordered_map ambBarrelTrBCs; if (upcCuts.getAmbigSwitch() != 1) - collectAmbTrackBCs<0>(ambBarrelTrBCs, ambBarrelTracks); + collectAmbTrackBCs<0, o2::aod::BCs>(ambBarrelTrBCs, ambBarrelTracks); collectBarrelTracks(bcsMatchedTrIdsTOF, 0, @@ -711,31 +725,45 @@ struct UpcCandProducer { std::map mapGlobalBcWithTOR{}; std::map mapGlobalBcWithTVX{}; std::map mapGlobalBcWithTSC{}; - for (auto ft0 : ft0s) { - uint64_t globalBC = ft0.bc_as().globalBC(); + for (const auto& ft0 : ft0s) { + uint64_t globalBC = ft0.bc_as().globalBC(); int32_t globalIndex = ft0.globalIndex(); if (!(std::abs(ft0.timeA()) > 2.f && std::abs(ft0.timeC()) > 2.f)) mapGlobalBcWithTOR[globalBC] = globalIndex; - if (TESTBIT(ft0.triggerMask(), o2::fit::Triggers::bitVertex)) // TVX + if (TESTBIT(ft0.triggerMask(), o2::fit::Triggers::bitVertex)) { // TVX mapGlobalBcWithTVX[globalBC] = globalIndex; + } + if (TESTBIT(ft0.triggerMask(), o2::fit::Triggers::bitCen)) { // TVX & TCE + histRegistry.get(HIST("hCountersTrg"))->Fill("TCE", 1); + } if (TESTBIT(ft0.triggerMask(), o2::fit::Triggers::bitVertex) && (TESTBIT(ft0.triggerMask(), o2::fit::Triggers::bitCen) || - TESTBIT(ft0.triggerMask(), o2::fit::Triggers::bitSCen))) // TVX & (TSC | TCE) + TESTBIT(ft0.triggerMask(), o2::fit::Triggers::bitSCen))) { // TVX & (TSC | TCE) mapGlobalBcWithTSC[globalBC] = globalIndex; + } } std::map mapGlobalBcWithV0A{}; - for (auto fv0a : fv0as) { + for (const auto& fv0a : fv0as) { if (std::abs(fv0a.time()) > 15.f) continue; - uint64_t globalBC = fv0a.bc_as().globalBC(); + uint64_t globalBC = fv0a.bc_as().globalBC(); mapGlobalBcWithV0A[globalBC] = fv0a.globalIndex(); } + std::map mapGlobalBcWithZdc{}; + for (const auto& zdc : zdcs) { + if (std::abs(zdc.timeZNA()) > 2.f && std::abs(zdc.timeZNC()) > 2.f) + continue; + auto globalBC = zdc.bc_as().globalBC(); + mapGlobalBcWithZdc[globalBC] = zdc.globalIndex(); + } + auto nTORs = mapGlobalBcWithTOR.size(); auto nTSCs = mapGlobalBcWithTSC.size(); auto nTVXs = mapGlobalBcWithTVX.size(); auto nFV0As = mapGlobalBcWithV0A.size(); + auto nZdcs = mapGlobalBcWithZdc.size(); auto nBcsWithITSTPC = bcsMatchedTrIdsITSTPC.size(); // todo: calculate position of UD collision? @@ -829,6 +857,17 @@ struct UpcCandProducer { upchelpers::FITInfo fitInfo{}; if (!updateFitInfo(globalBC, fitInfo)) continue; + if (nZdcs > 0) { + auto itZDC = mapGlobalBcWithZdc.find(globalBC); + if (itZDC != mapGlobalBcWithZdc.end()) { + const auto& zdc = zdcs.iteratorAt(itZDC->second); + float timeZNA = zdc.timeZNA(); + float timeZNC = zdc.timeZNC(); + float eComZNA = zdc.energyCommonZNA(); + float eComZNC = zdc.energyCommonZNC(); + udZdcsReduced(candID, timeZNA, timeZNC, eComZNA, eComZNC); + } + } uint16_t numContrib = fNBarProngs; int8_t netCharge = 0; float RgtrwTOF = 0.; @@ -849,10 +888,10 @@ struct UpcCandProducer { fitInfo.BBFT0Apf, fitInfo.BBFT0Cpf, fitInfo.BGFT0Apf, fitInfo.BGFT0Cpf, fitInfo.BBFV0Apf, fitInfo.BGFV0Apf, fitInfo.BBFDDApf, fitInfo.BBFDDCpf, fitInfo.BGFDDApf, fitInfo.BGFDDCpf); - eventCandidatesSelsExtra(fitInfo.distClosestBcTOR, - fitInfo.distClosestBcTSC, - fitInfo.distClosestBcTVX, - fitInfo.distClosestBcV0A, 999); + eventCandidatesSelsCent(fitInfo.distClosestBcTOR, + fitInfo.distClosestBcTSC, + fitInfo.distClosestBcTVX, + fitInfo.distClosestBcV0A); candID++; } @@ -883,6 +922,17 @@ struct UpcCandProducer { upchelpers::FITInfo fitInfo{}; if (!updateFitInfo(globalBC, fitInfo)) continue; + if (nZdcs > 0) { + auto itZDC = mapGlobalBcWithZdc.find(globalBC); + if (itZDC != mapGlobalBcWithZdc.end()) { + const auto& zdc = zdcs.iteratorAt(itZDC->second); + float timeZNA = zdc.timeZNA(); + float timeZNC = zdc.timeZNC(); + float eComZNA = zdc.energyCommonZNA(); + float eComZNC = zdc.energyCommonZNC(); + udZdcsReduced(candID, timeZNA, timeZNC, eComZNA, eComZNC); + } + } uint16_t numContrib = fNBarProngs; int8_t netCharge = 0; float RgtrwTOF = 0.; @@ -903,11 +953,10 @@ struct UpcCandProducer { fitInfo.BBFT0Apf, fitInfo.BBFT0Cpf, fitInfo.BGFT0Apf, fitInfo.BGFT0Cpf, fitInfo.BBFV0Apf, fitInfo.BGFV0Apf, fitInfo.BBFDDApf, fitInfo.BBFDDCpf, fitInfo.BGFDDApf, fitInfo.BGFDDCpf); - eventCandidatesSelsExtra(fitInfo.distClosestBcTOR, - fitInfo.distClosestBcTSC, - fitInfo.distClosestBcTVX, - fitInfo.distClosestBcV0A, - 999); + eventCandidatesSelsCent(fitInfo.distClosestBcTOR, + fitInfo.distClosestBcTSC, + fitInfo.distClosestBcTVX, + fitInfo.distClosestBcV0A); barrelTrackIDs.clear(); candID++; } @@ -943,10 +992,10 @@ struct UpcCandProducer { // trackID -> index in amb. track table std::unordered_map ambBarrelTrBCs; - collectAmbTrackBCs<0>(ambBarrelTrBCs, ambBarrelTracks); + collectAmbTrackBCs<0, BCsWithBcSels>(ambBarrelTrBCs, ambBarrelTracks); std::unordered_map ambFwdTrBCs; - collectAmbTrackBCs<1>(ambFwdTrBCs, ambFwdTracks); + collectAmbTrackBCs<1, BCsWithBcSels>(ambFwdTrBCs, ambFwdTracks); collectForwardTracks(bcsMatchedTrIdsMID, o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack, @@ -1090,13 +1139,45 @@ struct UpcCandProducer { bcsMatchedTrIdsTOFTagged.clear(); } + template + void fillAmplitudes(const T& t, + const std::map& mapBCs, + std::vector& amps, + std::vector& relBCs, + int64_t gbc) + { + auto s = gbc - fBCWindowFITAmps; + auto e = gbc + (fBCWindowFITAmps - 1); + auto it = mapBCs.lower_bound(s); + while (it->first <= e && it != mapBCs.end()) { + int i = it->first - s; + auto id = it->second; + const auto& row = t.iteratorAt(id); + float totalAmp = 0.f; + if constexpr (std::is_same_v) { + const auto& itAmps = row.amplitudeA(); + totalAmp = std::accumulate(itAmps.begin(), itAmps.end(), 0.f); + } + if constexpr (std::is_same_v) { + const auto& itAmps = row.amplitude(); + totalAmp = std::accumulate(itAmps.begin(), itAmps.end(), 0.f); + } + if (totalAmp > 0.f) { + amps.push_back(totalAmp); + relBCs.push_back(gbc - (i + s)); + } + ++it; + } + } + void createCandidatesFwd(ForwardTracks const& fwdTracks, o2::aod::AmbiguousFwdTracks const& ambFwdTracks, - BCsWithBcSels const& bcs, + o2::aod::BCs const& bcs, o2::aod::Collisions const& collisions, o2::aod::FT0s const& ft0s, o2::aod::FDDs const& fdds, o2::aod::FV0As const& fv0as, + o2::aod::Zdcs const& zdcs, const o2::aod::McFwdTrackLabels* mcFwdTrackLabels) { // pairs of global BCs and vectors of matched track IDs: @@ -1105,7 +1186,7 @@ struct UpcCandProducer { // trackID -> index in amb. track table std::unordered_map ambFwdTrBCs; - collectAmbTrackBCs<1>(ambFwdTrBCs, ambFwdTracks); + collectAmbTrackBCs<1, o2::aod::BCs>(ambFwdTrBCs, ambFwdTracks); collectForwardTracks(bcsMatchedTrIdsMID, o2::aod::fwdtrack::ForwardTrackTypeEnum::MuonStandaloneTrack, @@ -1123,24 +1204,40 @@ struct UpcCandProducer { std::sort(bcsMatchedTrIdsMCH.begin(), bcsMatchedTrIdsMCH.end(), [](const auto& left, const auto& right) { return left.first < right.first; }); - std::map mapGlobalBcWithT0{}; - for (auto ft0 : ft0s) { + std::map mapGlobalBcWithT0A{}; + for (const auto& ft0 : ft0s) { + if (!TESTBIT(ft0.triggerMask(), o2::fit::Triggers::bitVertex)) + continue; + if (TESTBIT(ft0.triggerMask(), o2::fit::Triggers::bitCen)) { // TVX & TCE + histRegistry.get(HIST("hCountersTrg"))->Fill("TCE", 1); + } if (std::abs(ft0.timeA()) > 2.f) continue; - uint64_t globalBC = ft0.bc_as().globalBC(); - mapGlobalBcWithT0[globalBC] = ft0.globalIndex(); + uint64_t globalBC = ft0.bc_as().globalBC(); + mapGlobalBcWithT0A[globalBC] = ft0.globalIndex(); } std::map mapGlobalBcWithV0A{}; - for (auto fv0a : fv0as) { + for (const auto& fv0a : fv0as) { + if (!TESTBIT(fv0a.triggerMask(), o2::fit::Triggers::bitA)) + continue; if (std::abs(fv0a.time()) > 15.f) continue; - uint64_t globalBC = fv0a.bc_as().globalBC(); + uint64_t globalBC = fv0a.bc_as().globalBC(); mapGlobalBcWithV0A[globalBC] = fv0a.globalIndex(); } - auto nFT0s = mapGlobalBcWithT0.size(); + std::map mapGlobalBcWithZdc{}; + for (const auto& zdc : zdcs) { + if (std::abs(zdc.timeZNA()) > 2.f && std::abs(zdc.timeZNC()) > 2.f) + continue; + auto globalBC = zdc.bc_as().globalBC(); + mapGlobalBcWithZdc[globalBC] = zdc.globalIndex(); + } + + auto nFT0s = mapGlobalBcWithT0A.size(); auto nFV0As = mapGlobalBcWithV0A.size(); + auto nZdcs = mapGlobalBcWithZdc.size(); auto nBcsWithMCH = bcsMatchedTrIdsMCH.size(); // todo: calculate position of UD collision? @@ -1153,11 +1250,15 @@ struct UpcCandProducer { // storing n-prong matches int32_t candID = 0; for (auto& pair : bcsMatchedTrIdsMID) { - auto globalBC = pair.first; - auto& fwdTrackIDs = pair.second; // only MID-matched tracks at the moment + auto globalBC = static_cast(pair.first); + const auto& fwdTrackIDs = pair.second; // only MID-matched tracks at the moment int32_t nMIDs = fwdTrackIDs.size(); if (nMIDs > fNFwdProngs) // too many tracks continue; + std::vector trkCandIDs{}; + if (nMIDs == fNFwdProngs) { + trkCandIDs.insert(trkCandIDs.end(), fwdTrackIDs.begin(), fwdTrackIDs.end()); + } uint64_t closestBcMCH = 0; if (nMIDs < fNFwdProngs && nBcsWithMCH > 0) { // adding MCH tracks auto itClosestBcMCH = findClosestTrackBCiter(globalBC, bcsMatchedTrIdsMCH); @@ -1167,9 +1268,10 @@ struct UpcCandProducer { continue; auto& mchTracks = itClosestBcMCH->second; int32_t nMCHs = mchTracks.size(); - if (nMCHs + nMIDs > fNFwdProngs) + if ((nMCHs + nMIDs) != fNFwdProngs) continue; - fwdTrackIDs.insert(fwdTrackIDs.end(), mchTracks.begin(), mchTracks.end()); + trkCandIDs.insert(trkCandIDs.end(), fwdTrackIDs.begin(), fwdTrackIDs.end()); + trkCandIDs.insert(trkCandIDs.end(), mchTracks.begin(), mchTracks.end()); } upchelpers::FITInfo fitInfo{}; fitInfo.timeFT0A = -999.f; @@ -1178,47 +1280,59 @@ struct UpcCandProducer { fitInfo.ampFT0A = 0.f; fitInfo.ampFT0C = 0.f; fitInfo.ampFV0A = 0.f; - fitInfo.BBFT0Apf = -999; - fitInfo.BBFV0Apf = -999; + std::vector amplitudesT0A{}; + std::vector amplitudesV0A{}; + std::vector relBCsT0A{}; + std::vector relBCsV0A{}; if (nFT0s > 0) { - uint64_t closestBcT0 = findClosestBC(globalBC, mapGlobalBcWithT0); - int64_t distClosestBcT0 = globalBC - static_cast(closestBcT0); - if (std::abs(distClosestBcT0) < fFilterFT0) + uint64_t closestBcT0A = findClosestBC(globalBC, mapGlobalBcWithT0A); + int64_t distClosestBcT0A = globalBC - static_cast(closestBcT0A); + if (std::abs(distClosestBcT0A) <= fFilterFT0) continue; - fitInfo.BBFT0Apf = distClosestBcT0; - auto ft0Id = mapGlobalBcWithT0.at(closestBcT0); + fitInfo.distClosestBcT0A = distClosestBcT0A; + auto ft0Id = mapGlobalBcWithT0A.at(closestBcT0A); auto ft0 = ft0s.iteratorAt(ft0Id); fitInfo.timeFT0A = ft0.timeA(); fitInfo.timeFT0C = ft0.timeC(); const auto& t0AmpsA = ft0.amplitudeA(); const auto& t0AmpsC = ft0.amplitudeC(); - for (auto amp : t0AmpsA) - fitInfo.ampFT0A += amp; - for (auto amp : t0AmpsC) - fitInfo.ampFT0C += amp; + fitInfo.ampFT0A = std::accumulate(t0AmpsA.begin(), t0AmpsA.end(), 0.f); + fitInfo.ampFT0C = std::accumulate(t0AmpsC.begin(), t0AmpsC.end(), 0.f); + fillAmplitudes(ft0s, mapGlobalBcWithT0A, amplitudesT0A, relBCsT0A, globalBC); } if (nFV0As > 0) { uint64_t closestBcV0A = findClosestBC(globalBC, mapGlobalBcWithV0A); int64_t distClosestBcV0A = globalBC - static_cast(closestBcV0A); - if (std::abs(distClosestBcV0A) < fFilterFV0) + if (std::abs(distClosestBcV0A) <= fFilterFV0) continue; - fitInfo.BBFV0Apf = distClosestBcV0A; + fitInfo.distClosestBcV0A = distClosestBcV0A; auto fv0aId = mapGlobalBcWithV0A.at(closestBcV0A); auto fv0a = fv0as.iteratorAt(fv0aId); fitInfo.timeFV0A = fv0a.time(); const auto& v0Amps = fv0a.amplitude(); - for (auto amp : v0Amps) - fitInfo.ampFV0A += amp; + fitInfo.ampFV0A = std::accumulate(v0Amps.begin(), v0Amps.end(), 0.f); + fillAmplitudes(fv0as, mapGlobalBcWithV0A, amplitudesV0A, relBCsV0A, globalBC); + } + if (nZdcs > 0) { + auto itZDC = mapGlobalBcWithZdc.find(globalBC); + if (itZDC != mapGlobalBcWithZdc.end()) { + const auto& zdc = zdcs.iteratorAt(itZDC->second); + float timeZNA = zdc.timeZNA(); + float timeZNC = zdc.timeZNC(); + float eComZNA = zdc.energyCommonZNA(); + float eComZNC = zdc.energyCommonZNC(); + udZdcsReduced(candID, timeZNA, timeZNC, eComZNA, eComZNC); + } } uint16_t numContrib = fNFwdProngs; int8_t netCharge = 0; float RgtrwTOF = 0.; - for (auto id : fwdTrackIDs) { + for (auto id : trkCandIDs) { auto tr = fwdTracks.iteratorAt(id); netCharge += tr.sign(); } // store used tracks - fillFwdTracks(fwdTracks, fwdTrackIDs, candID, globalBC, closestBcMCH, mcFwdTrackLabels); + fillFwdTracks(fwdTracks, trkCandIDs, candID, globalBC, closestBcMCH, mcFwdTrackLabels); eventCandidates(globalBC, runNumber, dummyX, dummyY, dummyZ, numContrib, netCharge, RgtrwTOF); eventCandidatesSels(fitInfo.ampFT0A, fitInfo.ampFT0C, fitInfo.timeFT0A, fitInfo.timeFT0C, fitInfo.triggerMaskFT0, fitInfo.ampFDDA, fitInfo.ampFDDC, fitInfo.timeFDDA, fitInfo.timeFDDC, fitInfo.triggerMaskFDD, @@ -1226,13 +1340,20 @@ struct UpcCandProducer { fitInfo.BBFT0Apf, fitInfo.BBFT0Cpf, fitInfo.BGFT0Apf, fitInfo.BGFT0Cpf, fitInfo.BBFV0Apf, fitInfo.BGFV0Apf, fitInfo.BBFDDApf, fitInfo.BBFDDCpf, fitInfo.BGFDDApf, fitInfo.BGFDDCpf); + eventCandidatesSelsFwd(fitInfo.distClosestBcV0A, + fitInfo.distClosestBcT0A, + amplitudesT0A, + relBCsT0A, + amplitudesV0A, + relBCsV0A); candID++; + trkCandIDs.clear(); } ambFwdTrBCs.clear(); bcsMatchedTrIdsMID.clear(); bcsMatchedTrIdsMCH.clear(); - mapGlobalBcWithT0.clear(); + mapGlobalBcWithT0A.clear(); mapGlobalBcWithV0A.clear(); } @@ -1263,16 +1384,17 @@ struct UpcCandProducer { // create candidates for central region void processCentral(BarrelTracks const& barrelTracks, o2::aod::AmbiguousTracks const& ambBarrelTracks, - BCsWithBcSels const& bcs, + o2::aod::BCs const& bcs, o2::aod::Collisions const& collisions, o2::aod::FT0s const& ft0s, o2::aod::FDDs const& fdds, - o2::aod::FV0As const& fv0as) + o2::aod::FV0As const& fv0as, + o2::aod::Zdcs const& zdcs) { fDoMC = false; createCandidatesCentral(barrelTracks, ambBarrelTracks, bcs, collisions, - ft0s, fdds, fv0as, + ft0s, fdds, fv0as, zdcs, (o2::aod::McTrackLabels*)nullptr); } @@ -1307,11 +1429,12 @@ struct UpcCandProducer { // create candidates for central region void processCentralMC(BarrelTracks const& barrelTracks, o2::aod::AmbiguousTracks const& ambBarrelTracks, - BCsWithBcSels const& bcs, + o2::aod::BCs const& bcs, o2::aod::Collisions const& collisions, o2::aod::FT0s const& ft0s, o2::aod::FDDs const& fdds, o2::aod::FV0As const& fv0as, + o2::aod::Zdcs const& zdcs, o2::aod::McCollisions const& mcCollisions, o2::aod::McParticles const& mcParticles, o2::aod::McTrackLabels const& mcBarrelTrackLabels) { @@ -1319,7 +1442,7 @@ struct UpcCandProducer { skimMCInfo(mcCollisions, mcParticles, bcs); createCandidatesCentral(barrelTracks, ambBarrelTracks, bcs, collisions, - ft0s, fdds, fv0as, + ft0s, fdds, fv0as, zdcs, &mcBarrelTrackLabels); fNewPartIDs.clear(); } @@ -1328,26 +1451,28 @@ struct UpcCandProducer { // forward: n fwd tracks void processForward(ForwardTracks const& fwdTracks, o2::aod::AmbiguousFwdTracks const& ambFwdTracks, - BCsWithBcSels const& bcs, + o2::aod::BCs const& bcs, o2::aod::Collisions const& collisions, o2::aod::FT0s const& ft0s, o2::aod::FDDs const& fdds, - o2::aod::FV0As const& fv0as) + o2::aod::FV0As const& fv0as, + o2::aod::Zdcs const& zdcs) { fDoMC = false; createCandidatesFwd(fwdTracks, ambFwdTracks, bcs, collisions, - ft0s, fdds, fv0as, + ft0s, fdds, fv0as, zdcs, (o2::aod::McFwdTrackLabels*)nullptr); } void processForwardMC(ForwardTracks const& fwdTracks, o2::aod::AmbiguousFwdTracks const& ambFwdTracks, - BCsWithBcSels const& bcs, + o2::aod::BCs const& bcs, o2::aod::Collisions const& collisions, o2::aod::FT0s const& ft0s, o2::aod::FDDs const& fdds, o2::aod::FV0As const& fv0as, + o2::aod::Zdcs const& zdcs, o2::aod::McCollisions const& mcCollisions, o2::aod::McParticles const& mcParticles, o2::aod::McFwdTrackLabels const& mcFwdTrackLabels) { @@ -1355,7 +1480,7 @@ struct UpcCandProducer { skimMCInfo(mcCollisions, mcParticles, bcs); createCandidatesFwd(fwdTracks, ambFwdTracks, bcs, collisions, - ft0s, fdds, fv0as, + ft0s, fdds, fv0as, zdcs, &mcFwdTrackLabels); } diff --git a/PWGUD/TableProducer/fwdTrackPropagation.cxx b/PWGUD/TableProducer/fwdTrackPropagation.cxx new file mode 100644 index 00000000000..4064b9df538 --- /dev/null +++ b/PWGUD/TableProducer/fwdTrackPropagation.cxx @@ -0,0 +1,165 @@ +// 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. + +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/runDataProcessing.h" + +#include "CCDB/BasicCCDBManager.h" +#include "DataFormatsParameters/GRPMagField.h" +#include "DetectorsBase/Propagator.h" +#include "GlobalTracking/MatchGlobalFwd.h" +#include "MCHTracking/TrackExtrap.h" +#include "MCHTracking/TrackParam.h" +#include "Math/SMatrix.h" +#include "ReconstructionDataFormats/TrackFwd.h" + +#include "PWGUD/DataModel/UDTables.h" + +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct FwdTrackPropagation { + using ForwardTracks = o2::soa::Join; + + using SMatrix55 = ROOT::Math::SMatrix>; + using SMatrix5 = ROOT::Math::SVector; + + Produces propFwdTracks; + Produces propFwdTracksCov; + + Service fCCDB; + o2::ccdb::CcdbApi fCCDBApi; + + o2::globaltracking::MatchGlobalFwd fMatching; + + int fRun = 0; + + void init(InitContext&) + { + fCCDB->setURL("http://alice-ccdb.cern.ch"); + fCCDB->setCaching(true); + fCCDB->setLocalObjectValidityChecking(); + fCCDBApi.init("http://alice-ccdb.cern.ch"); + } + + template + auto propagateFwdToVtx(const T& muon, const std::array& vtx, const std::array& vtxCov) + { + double chi2 = muon.chi2(); + SMatrix5 tpars(muon.x(), muon.y(), muon.phi(), muon.tgl(), muon.signed1Pt()); + std::vector v1{muon.cXX(), muon.cXY(), muon.cYY(), muon.cPhiX(), muon.cPhiY(), + muon.cPhiPhi(), muon.cTglX(), muon.cTglY(), muon.cTglPhi(), muon.cTglTgl(), + muon.c1PtX(), muon.c1PtY(), muon.c1PtPhi(), muon.c1PtTgl(), muon.c1Pt21Pt2()}; + SMatrix55 tcovs(v1.begin(), v1.end()); + + o2::track::TrackParCovFwd fwdtrack{muon.z(), tpars, tcovs, chi2}; + o2::dataformats::GlobalFwdTrack propmuon; + + o2::dataformats::GlobalFwdTrack track; + track.setParameters(tpars); + track.setZ(fwdtrack.getZ()); + track.setCovariances(tcovs); + auto mchTrack = fMatching.FwdtoMCH(track); + o2::mch::TrackExtrap::extrapToVertex(mchTrack, vtx[0], vtx[1], vtx[2], vtxCov[0], vtxCov[1]); + auto proptrack = fMatching.MCHtoFwd(mchTrack); + propmuon.setParameters(proptrack.getParameters()); + propmuon.setZ(proptrack.getZ()); + propmuon.setCovariances(proptrack.getCovariances()); + return propmuon; + } + + void process(o2::aod::BCs const& bcs, ForwardTracks const& fwdTracks, o2::aod::Collisions const& cols) + { + int run = bcs.begin().runNumber(); + + if (run != fRun) { + fRun = run; + std::map metadata, headers; + headers = fCCDBApi.retrieveHeaders(Form("RCT/Info/RunInformation/%i", run), metadata, -1); + int64_t ts = std::atol(headers["SOR"].c_str()); + auto grpmag = fCCDBApi.retrieveFromTFileAny("GLO/Config/GRPMagField", metadata, ts); + o2::base::Propagator::initFieldFromGRP(grpmag); + if (!o2::base::GeometryManager::isGeometryLoaded()) + fCCDB->get("GLO/Config/GeometryAligned"); + o2::mch::TrackExtrap::setField(); + } + + propFwdTracks.reserve(fwdTracks.size()); + propFwdTracksCov.reserve(fwdTracks.size()); + + for (const auto& t : fwdTracks) { + if (t.z() < -90.f) { + std::array vtx = {0.f, 0.f, 0.f}; + std::array vtxCov = {0.f, 0.f}; + if (t.has_collision()) { + auto col = cols.iteratorAt(t.collisionId()); + vtx[0] = col.posX(); + vtx[1] = col.posY(); + vtx[2] = col.posZ(); + vtxCov[0] = col.covXX(); + vtxCov[1] = col.covYY(); + } + auto pft = propagateFwdToVtx(t, vtx, vtxCov); + propFwdTracks(t.collisionId(), t.trackType(), + pft.getX(), pft.getY(), pft.getZ(), pft.getPhi(), pft.getTgl(), pft.getInvQPt(), + pft.getEta(), pft.getPt(), pft.getP(), + t.nClusters(), t.pDca(), t.rAtAbsorberEnd(), + pft.getTrackChi2(), t.chi2MatchMCHMID(), t.chi2MatchMCHMFT(), + t.matchScoreMCHMFT(), t.matchMFTTrackId(), t.matchMCHTrackId(), + t.mchBitMap(), t.midBoards(), t.midBitMap(), + t.trackTime(), t.trackTimeRes()); + // debug + // LOGP(info, "track {}, before: {} {} {} {} {} {}", t.globalIndex(), t.x(), t.y(), t.z(), t.phi(), t.tgl(), t.signed1Pt()); + // LOGP(info, "track {}, after: {} {} {} {} {} {}", t.globalIndex(), pft.getX(), pft.getY(), pft.getZ(), pft.getPhi(), pft.getTgl(), pft.getInvQPt()); + SMatrix55 cov = pft.getCovariances(); + float sigX = TMath::Sqrt(cov(0, 0)); + float sigY = TMath::Sqrt(cov(1, 1)); + float sigPhi = TMath::Sqrt(cov(2, 2)); + float sigTgl = TMath::Sqrt(cov(3, 3)); + float sig1Pt = TMath::Sqrt(cov(4, 4)); + auto rhoXY = static_cast(128. * cov(0, 1) / (sigX * sigY)); + auto rhoPhiX = static_cast(128. * cov(0, 2) / (sigPhi * sigX)); + auto rhoPhiY = static_cast(128. * cov(1, 2) / (sigPhi * sigY)); + auto rhoTglX = static_cast(128. * cov(0, 3) / (sigTgl * sigX)); + auto rhoTglY = static_cast(128. * cov(1, 3) / (sigTgl * sigY)); + auto rhoTglPhi = static_cast(128. * cov(2, 3) / (sigTgl * sigPhi)); + auto rho1PtX = static_cast(128. * cov(0, 4) / (sig1Pt * sigX)); + auto rho1PtY = static_cast(128. * cov(1, 4) / (sig1Pt * sigY)); + auto rho1PtPhi = static_cast(128. * cov(2, 4) / (sig1Pt * sigPhi)); + auto rho1PtTgl = static_cast(128. * cov(3, 4) / (sig1Pt * sigTgl)); + propFwdTracksCov(sigX, sigY, sigTgl, sigPhi, sig1Pt, + rhoXY, rhoPhiX, rhoPhiY, rhoTglX, + rhoTglY, rhoTglPhi, rho1PtX, rho1PtY, + rho1PtPhi, rho1PtTgl); + } else { + propFwdTracks(t.collisionId(), t.trackType(), + t.x(), t.y(), t.z(), t.phi(), t.tgl(), t.signed1Pt(), + t.eta(), t.pt(), t.p(), + t.nClusters(), t.pDca(), t.rAtAbsorberEnd(), + t.chi2(), t.chi2MatchMCHMID(), t.chi2MatchMCHMFT(), + t.matchScoreMCHMFT(), t.matchMFTTrackId(), t.matchMCHTrackId(), + t.mchBitMap(), t.midBoards(), t.midBitMap(), + t.trackTime(), t.trackTimeRes()); + propFwdTracksCov(t.sigmaX(), t.sigmaY(), t.sigmaTgl(), t.sigmaPhi(), t.sigma1Pt(), + t.rhoXY(), t.rhoPhiX(), t.rhoPhiY(), t.rhoTglX(), + t.rhoTglY(), t.rhoTglPhi(), t.rho1PtX(), t.rho1PtY(), + t.rho1PtPhi(), t.rho1PtTgl()); + } + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc)}; +} diff --git a/PWGUD/Tasks/CMakeLists.txt b/PWGUD/Tasks/CMakeLists.txt index cdf9c2d6786..761c4172ee9 100644 --- a/PWGUD/Tasks/CMakeLists.txt +++ b/PWGUD/Tasks/CMakeLists.txt @@ -58,3 +58,12 @@ o2physics_add_dpl_workflow(upc-veto SOURCES upcVetoAnalysis.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(tautau13topo + SOURCES upcTauTau13topo.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::DGPIDSelector + COMPONENT_NAME Analysis) +o2physics_add_dpl_workflow(upc-tau-rl + SOURCES upcTauCentralBarrelRL.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::ReconstructionDataFormats O2::DetectorsBase O2::DetectorsCommonDataFormats + COMPONENT_NAME Analysis) diff --git a/PWGUD/Tasks/upcTauCentralBarrelRL.cxx b/PWGUD/Tasks/upcTauCentralBarrelRL.cxx new file mode 100644 index 00000000000..9345e99c514 --- /dev/null +++ b/PWGUD/Tasks/upcTauCentralBarrelRL.cxx @@ -0,0 +1,1020 @@ +// 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 +/// \author Roman Lavicka, roman.lavicka@cern.ch +/// \since 12.07.2022 + +// #include +// #include + +// O2 headers +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" + +// O2Physics headers +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/CCDB/EventSelectionParams.h" +#include "PWGUD/Core/UPCTauCentralBarrelHelperRL.h" +#include "PWGUD/DataModel/UDTables.h" + +#include "Common/Core/TrackSelection.h" +#include "Common/Core/TrackSelectionDefaults.h" +#include "Common/Core/trackUtilities.h" + +// ROOT headers +#include "TLorentzVector.h" +#include "TEfficiency.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct UpcTauCentralBarrelRL { + + // Global varialbes + bool isFirstReconstructedCollisions; + int countCollisions; + Service pdg; + + HistogramRegistry histos{ + "histos", + {{"Events/hCountCollisions", ";Number of analysed collision (-)", {HistType::kTH1D, {{10, 0.5, 10.5}}}}, + {"Events/hNreconstructedTracks", ";Number of tracks in a collision (-);Number of events (-)", {HistType::kTH1D, {{30, -0.5, 29.5}}}}, + {"Events/hNreconstructedPVGTelectrons", ";Number of good track electrons from primary vertex in a collision (-);Number of events (-)", {HistType::kTH1D, {{30, -0.5, 29.5}}}}, + {"Events/hNreconstructedPVGTmuons", ";Number of good track muons from primary vertex in a collision (-);Number of events (-)", {HistType::kTH1D, {{30, -0.5, 29.5}}}}, + {"Events/hNreconstructedPVGTpions", ";Number of good track pions from primary vertex in a collision (-);Number of events (-)", {HistType::kTH1D, {{30, -0.5, 29.5}}}}, + {"Events/hNreconstructedPVGTothers", ";Number of good track NOT electron/muon/pion particles from primary vertex in a collision (-);Number of events (-)", {HistType::kTH1D, {{30, -0.5, 29.5}}}}, + {"Events/hNreconstructedPVGT", ";Number of good track particles from primary vertex in a collision (-);Number of events (-)", {HistType::kTH1D, {{30, -0.5, 29.5}}}}, + {"Events/hNreconstructedNotPVGT", ";Number of good track particles from NOT primary vertex in a collision (-);Number of events (-)", {HistType::kTH1D, {{30, -0.5, 29.5}}}}, + {"Events/hChannelsRatio", ";Channels (-);Branching Ratio (-)", {HistType::kTH1D, {{10, -0.5, 9.5}}}}}}; + HistogramRegistry histosPID{ + "histosPID", + {{"Tracks/raw/PID/hTPCsignalVsZ", "All tracks;Track z-vertex (cm);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, -20., 20.}, {200, 0., 200}}}}, + {"Tracks/raw/PID/hTPCsignalVsP", "All tracks;Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/raw/PID/hTPCsignalVsPt", "All tracks;Track #it{p_{#rm T}} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/raw/PID/hTPCsignalVsEta", "All tracks;Track #eta (-);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{500, -2., 2.}, {200, 0., 200}}}}, + {"Tracks/raw/PID/hTPCsignalVsPhi", "All tracks;Track #phi (rad);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{64, 0, 2 * TMath::Pi()}, {200, 0., 200}}}}, + {"Tracks/raw/PID/PosCharge/hTPCsignalVsZ", "Positively charged track;Track z-vertex (cm);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, -20., 20.}, {200, 0., 200}}}}, + {"Tracks/raw/PID/PosCharge/hTPCsignalVsP", "Positively charged track;Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/raw/PID/PosCharge/hTPCsignalVsPt", "Positively charged track;Track #it{p_{#rm T}} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/raw/PID/PosCharge/hTPCsignalVsEta", "Positively charged track;Track #eta (-);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{500, -2., 2.}, {200, 0., 200}}}}, + {"Tracks/raw/PID/PosCharge/hTPCsignalVsPhi", "Positively charged track;Track #phi (rad);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{64, 0, 2 * TMath::Pi()}, {200, 0., 200}}}}, + {"Tracks/raw/PID/NegCharge/hTPCsignalVsZ", "Negatively charged track;Track z-vertex (cm);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, -20., 20.}, {200, 0., 200}}}}, + {"Tracks/raw/PID/NegCharge/hTPCsignalVsP", "Negatively charged track;Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/raw/PID/NegCharge/hTPCsignalVsPt", "Negatively charged track;Track #it{p_{#rm T}} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/raw/PID/NegCharge/hTPCsignalVsEta", "Negatively charged track;Track #eta (-);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{500, -2., 2.}, {200, 0., 200}}}}, + {"Tracks/raw/PID/NegCharge/hTPCsignalVsPhi", "Negatively charged track;Track #phi (rad);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{64, 0, 2 * TMath::Pi()}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/hTPCsignalVsZ", "All good tracks;Track z-vertex (cm);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, -20., 20.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/hTPCsignalVsP", "All good tracks;Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/hTPCsignalVsPt", "All good tracks;Track #it{p_{#rm T}} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/hTPCsignalVsEta", "All good tracks;Track #eta (-);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{500, -2., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/hTPCsignalVsPhi", "All good tracks;Track #phi (rad);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{64, 0, 2 * TMath::Pi()}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/PosCharge/hTPCsignalVsZ", "Positively charged track;Track z-vertex (cm);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, -20., 20.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/PosCharge/hTPCsignalVsP", "Positively charged track;Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/PosCharge/hTPCsignalVsPt", "Positively charged track;Track #it{p_{#rm T}} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/PosCharge/hTPCsignalVsEta", "Positively charged track;Track #eta (-);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{500, -2., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/PosCharge/hTPCsignalVsPhi", "Positively charged track;Track #phi (rad);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{64, 0, 2 * TMath::Pi()}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/NegCharge/hTPCsignalVsZ", "Negatively charged track;Track z-vertex (cm);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, -20., 20.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/NegCharge/hTPCsignalVsP", "Negatively charged track;Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/NegCharge/hTPCsignalVsPt", "Negatively charged track;Track #it{p_{#rm T}} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/NegCharge/hTPCsignalVsEta", "Negatively charged track;Track #eta (-);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{500, -2., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/NegCharge/hTPCsignalVsPhi", "Negatively charged track;Track #phi (rad);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{64, 0, 2 * TMath::Pi()}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Electron/hTPCsignalVsZ", "Identified electron;Track z-vertex (cm);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, -20., 20.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Electron/hTPCsignalVsP", "Identified electron;Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Electron/hTPCsignalVsPt", "Identified electron;Track #it{p_{#rm T}} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Electron/hTPCsignalVsEta", "Identified electron;Track #eta (-);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{500, -2., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Electron/hTPCsignalVsPhi", "Identified electron;Track #phi (rad);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{64, 0, 2 * TMath::Pi()}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Muon/hTPCsignalVsZ", "Identified Muon;Track z-vertex (cm);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, -20., 20.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Muon/hTPCsignalVsP", "Identified Muon;Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Muon/hTPCsignalVsPt", "Identified Muon;Track #it{p_{#rm T}} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Muon/hTPCsignalVsEta", "Identified Muon;Track #eta (-);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{500, -2., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Muon/hTPCsignalVsPhi", "Identified Muon;Track #phi (rad);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{64, 0, 2 * TMath::Pi()}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Pion/hTPCsignalVsZ", "Identified Pion;Track z-vertex (cm);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, -20., 20.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Pion/hTPCsignalVsP", "Identified Pion;Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Pion/hTPCsignalVsPt", "Identified Pion;Track #it{p_{#rm T}} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Pion/hTPCsignalVsEta", "Identified Pion;Track #eta (-);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{500, -2., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Pion/hTPCsignalVsPhi", "Identified Pion;Track #phi (rad);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{64, 0, 2 * TMath::Pi()}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Others/hTPCsignalVsZ", "Identified NOT electron/Muon/Pion;Track z-vertex (cm);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, -20., 20.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Others/hTPCsignalVsP", "Identified NOT electron/Muon/Pion;Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Others/hTPCsignalVsPt", "Identified NOT electron/Muon/Pion;Track #it{p_{#rm T}} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Others/hTPCsignalVsEta", "Identified NOT electron/Muon/Pion;Track #eta (-);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{500, -2., 2.}, {200, 0., 200}}}}, + {"Tracks/GoodTrack/PID/Others/hTPCsignalVsPhi", "Identified NOT electron/Muon/Pion;Track #phi (rad);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{64, 0, 2 * TMath::Pi()}, {200, 0., 200}}}}, + {"EventTwoTracks/PID/hTPCsignalVsP", ";Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"EventTwoTracks/TwoElectrons/PID/hTPCsignalVsP", ";Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"EventTwoTracks/TwoMuons/PID/hTPCsignalVsP", ";Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"EventTwoTracks/TwoPions/PID/hTPCsignalVsP", ";Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"EventTwoTracks/ElectronMuon/PID/hTPCsignalVsP", ";Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"EventTwoTracks/ElectronPion/PID/hTPCsignalVsP", ";Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"EventTwoTracks/MuonPion/PID/hTPCsignalVsP", ";Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"EventFourTracks/PID/hTPCsignalVsP", ";Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"EventFourTracks/WithElectron/PID/hTPCsignalVsP", ";Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"EventFourTracks/WithMuon/PID/hTPCsignalVsP", ";Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"EventFourTracks/WithPion/PID/hTPCsignalVsP", ";Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"EventSixTracks/PID/hTPCsignalVsP", ";Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}, + {"EventSixTracks/SixPions/PID/hTPCsignalVsP", ";Track #it{p} (GeV/c);TPC d#it{E}/d#it{x} (arb. units)", {HistType::kTH2D, {{200, 0., 2.}, {200, 0., 200}}}}}}; + + // declare configurables + Configurable verboseInfo{"verboseInfo", true, {"Print general info to terminal; default it true."}}; + Configurable verboseDebug{"verboseDebug", false, {"Print debug info to terminal; default it false."}}; + Configurable whichGapSide{"whichGapSide", 2, {"0 for side A, 1 for side C, 2 for both sides"}}; + + using FullUDTracks = soa::Join; + using FullUDCollision = soa::Join::iterator; + using FullSGUDCollision = soa::Join::iterator; + + // init + void init(InitContext&) + { + if (verboseInfo) + printLargeMessage("INIT METHOD"); + countCollisions = 0; + isFirstReconstructedCollisions = true; + + const AxisSpec axisZvtx{40, -20., 20.}; + const AxisSpec axisInvMass{400, 1., 5.}; + const AxisSpec axisInvMassWide{500, 0., 10.}; + const AxisSpec axisMom{40, 0., 2.}; + const AxisSpec axisMomWide{100, 0., 10.}; + const AxisSpec axisPt{40, 0., 2.}; + const AxisSpec axisPhi{64, -2 * TMath::Pi(), 2 * TMath::Pi()}; + const AxisSpec axisEta{50, -1.2, 1.2}; + const AxisSpec axisRap{50, -1.2, 1.2}; + const AxisSpec axisAcoplanarity{32, 0.0, o2::constants::math::PI}; + + histos.add("Tracks/raw/hTrackZ", ";Track z-vertex (cm);Number of events (-)", HistType::kTH1D, {axisZvtx}); + histos.add("Tracks/raw/hTrackP", ";Track #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("Tracks/raw/hTrackPt", ";Track #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("Tracks/raw/hTrackPhi", ";Track #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("Tracks/raw/hTrackEta", ";Track #eta (-);Number of events (-)", HistType::kTH1D, {axisEta}); + + histos.add("Tracks/GoodTrack/hTrackZ", ";Track z-vertex (cm);Number of events (-)", HistType::kTH1D, {axisZvtx}); + histos.add("Tracks/GoodTrack/hTrackP", ";Track #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("Tracks/GoodTrack/hTrackPt", ";Track #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("Tracks/GoodTrack/hTrackPhi", ";Track #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("Tracks/GoodTrack/hTrackEta", ";Track #eta (-);Number of events (-)", HistType::kTH1D, {axisEta}); + + histos.add("EventTwoTracks/hInvariantMass", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMass}); + histos.add("EventTwoTracks/hInvariantMassWide", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/hInvariantMassWideNoMothers", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/hInvariantMassWideAllPionMass", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/hInvariantMassWideAllPionMassPtCut", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/hAcoplanarity", ";#Delta#phi (rad);Number of events (-)", HistType::kTH1D, {axisAcoplanarity}); + histos.add("EventTwoTracks/hMotherP", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("EventTwoTracks/hMotherPwide", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventTwoTracks/hMotherPt", ";Mother #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("EventTwoTracks/hMotherPhi", ";Mother #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("EventTwoTracks/hMotherRapidity", ";Mother #it{y} (-);Number of events (-)", HistType::kTH1D, {axisRap}); + histos.add("EventTwoTracks/hDaughtersP", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMom, axisMom}); + histos.add("EventTwoTracks/hDaughtersPwide", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMomWide, axisMomWide}); + histos.add("EventTwoTracks/hDaughtersPt", ";Daughter 1 #it{p_{T}} (GeV/c);Daughter 2 #it{p_{T}} (GeV/c)", HistType::kTH2D, {axisPt, axisPt}); + histos.add("EventTwoTracks/hDaughtersPhi", ";Daughter 1 #phi (rad);Daughter 2 #phi (rad)", HistType::kTH2D, {axisPhi, axisPhi}); + histos.add("EventTwoTracks/hDaughtersRapidity", ";Daughter 1 #it{y} (-);Daughter 2 #it{y} (-)", HistType::kTH2D, {axisRap, axisRap}); + + histos.add("EventTwoTracks/TwoElectrons/hInvariantMass", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMass}); + histos.add("EventTwoTracks/TwoElectrons/hInvariantMassWide", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/TwoElectrons/hAcoplanarity", ";#Delta#phi (rad);Number of events (-)", HistType::kTH1D, {axisAcoplanarity}); + histos.add("EventTwoTracks/TwoElectrons/hMotherP", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("EventTwoTracks/TwoElectrons/hMotherPwide", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventTwoTracks/TwoElectrons/hMotherPt", ";Mother #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("EventTwoTracks/TwoElectrons/hMotherPhi", ";Mother #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("EventTwoTracks/TwoElectrons/hMotherRapidity", ";Mother #it{y} (-);Number of events (-)", HistType::kTH1D, {axisRap}); + histos.add("EventTwoTracks/TwoElectrons/hDaughtersP", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMom, axisMom}); + histos.add("EventTwoTracks/TwoElectrons/hDaughtersPwide", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMomWide, axisMomWide}); + histos.add("EventTwoTracks/TwoElectrons/hDaughtersPt", ";Daughter 1 #it{p_{T}} (GeV/c);Daughter 2 #it{p_{T}} (GeV/c)", HistType::kTH2D, {axisPt, axisPt}); + histos.add("EventTwoTracks/TwoElectrons/hDaughtersPhi", ";Daughter 1 #phi (rad);Daughter 2 #phi (rad)", HistType::kTH2D, {axisPhi, axisPhi}); + histos.add("EventTwoTracks/TwoElectrons/hDaughtersRapidity", ";Daughter 1 #it{y} (-);Daughter 2 #it{y} (-)", HistType::kTH2D, {axisRap, axisRap}); + histos.add("EventTwoTracks/TwoElectrons/hLeadingP", ";Leading #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("EventTwoTracks/TwoElectrons/hLeadingPwide", ";Leading #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventTwoTracks/TwoElectrons/hLeadingPt", ";Leading #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("EventTwoTracks/TwoElectrons/hLeadingPhi", ";Leading #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("EventTwoTracks/TwoElectrons/hLeadingRapidity", ";Leading #it{y} (-);Number of events (-)", HistType::kTH1D, {axisRap}); + + histos.add("EventTwoTracks/TwoMuons/hInvariantMass", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMass}); + histos.add("EventTwoTracks/TwoMuons/hInvariantMassWide", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/TwoMuons/hInvariantMassWidePtCut", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/TwoMuons/hAcoplanarity", ";#Delta#phi (rad);Number of events (-)", HistType::kTH1D, {axisAcoplanarity}); + histos.add("EventTwoTracks/TwoMuons/hMotherP", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("EventTwoTracks/TwoMuons/hMotherPwide", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventTwoTracks/TwoMuons/hMotherPt", ";Mother #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("EventTwoTracks/TwoMuons/hMotherPhi", ";Mother #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("EventTwoTracks/TwoMuons/hMotherRapidity", ";Mother #it{y} (-);Number of events (-)", HistType::kTH1D, {axisRap}); + histos.add("EventTwoTracks/TwoMuons/hDaughtersP", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMom, axisMom}); + histos.add("EventTwoTracks/TwoMuons/hDaughtersPwide", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMomWide, axisMomWide}); + histos.add("EventTwoTracks/TwoMuons/hDaughtersPt", ";Daughter 1 #it{p_{T}} (GeV/c);Daughter 2 #it{p_{T}} (GeV/c)", HistType::kTH2D, {axisPt, axisPt}); + histos.add("EventTwoTracks/TwoMuons/hDaughtersPhi", ";Daughter 1 #phi (rad);Daughter 2 #phi (rad)", HistType::kTH2D, {axisPhi, axisPhi}); + histos.add("EventTwoTracks/TwoMuons/hDaughtersRapidity", ";Daughter 1 #it{y} (-);Daughter 2 #it{y} (-)", HistType::kTH2D, {axisRap, axisRap}); + + histos.add("EventTwoTracks/TwoPions/hInvariantMass", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMass}); + histos.add("EventTwoTracks/TwoPions/hInvariantMassWide", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/TwoPions/hInvariantMassWidePtCut", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/TwoPions/hAcoplanarity", ";#Delta#phi (rad);Number of events (-)", HistType::kTH1D, {axisAcoplanarity}); + histos.add("EventTwoTracks/TwoPions/hMotherP", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("EventTwoTracks/TwoPions/hMotherPwide", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventTwoTracks/TwoPions/hMotherPt", ";Mother #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("EventTwoTracks/TwoPions/hMotherPhi", ";Mother #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("EventTwoTracks/TwoPions/hMotherRapidity", ";Mother #it{y} (-);Number of events (-)", HistType::kTH1D, {axisRap}); + histos.add("EventTwoTracks/TwoPions/hDaughtersP", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMom, axisMom}); + histos.add("EventTwoTracks/TwoPions/hDaughtersPwide", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMomWide, axisMomWide}); + histos.add("EventTwoTracks/TwoPions/hDaughtersPt", ";Daughter 1 #it{p_{T}} (GeV/c);Daughter 2 #it{p_{T}} (GeV/c)", HistType::kTH2D, {axisPt, axisPt}); + histos.add("EventTwoTracks/TwoPions/hDaughtersPhi", ";Daughter 1 #phi (rad);Daughter 2 #phi (rad)", HistType::kTH2D, {axisPhi, axisPhi}); + histos.add("EventTwoTracks/TwoPions/hDaughtersRapidity", ";Daughter 1 #it{y} (-);Daughter 2 #it{y} (-)", HistType::kTH2D, {axisRap, axisRap}); + + histos.add("EventTwoTracks/ElectronMuon/hInvariantMass", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMass}); + histos.add("EventTwoTracks/ElectronMuon/hInvariantMassWide", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/ElectronMuon/hAcoplanarity", ";#Delta#phi (rad);Number of events (-)", HistType::kTH1D, {axisAcoplanarity}); + histos.add("EventTwoTracks/ElectronMuon/hMotherP", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("EventTwoTracks/ElectronMuon/hMotherPwide", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventTwoTracks/ElectronMuon/hMotherPt", ";Mother #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("EventTwoTracks/ElectronMuon/hMotherPhi", ";Mother #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("EventTwoTracks/ElectronMuon/hMotherRapidity", ";Mother #it{y} (-);Number of events (-)", HistType::kTH1D, {axisRap}); + histos.add("EventTwoTracks/ElectronMuon/hDaughtersP", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMom, axisMom}); + histos.add("EventTwoTracks/ElectronMuon/hDaughtersPwide", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMomWide, axisMomWide}); + histos.add("EventTwoTracks/ElectronMuon/hDaughtersPt", ";Daughter 1 #it{p_{T}} (GeV/c);Daughter 2 #it{p_{T}} (GeV/c)", HistType::kTH2D, {axisPt, axisPt}); + histos.add("EventTwoTracks/ElectronMuon/hDaughtersPhi", ";Daughter 1 #phi (rad);Daughter 2 #phi (rad)", HistType::kTH2D, {axisPhi, axisPhi}); + histos.add("EventTwoTracks/ElectronMuon/hDaughtersRapidity", ";Daughter 1 #it{y} (-);Daughter 2 #it{y} (-)", HistType::kTH2D, {axisRap, axisRap}); + + histos.add("EventTwoTracks/ElectronPion/hInvariantMass", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMass}); + histos.add("EventTwoTracks/ElectronPion/hInvariantMassWide", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/ElectronPion/hAcoplanarity", ";#Delta#phi (rad);Number of events (-)", HistType::kTH1D, {axisAcoplanarity}); + histos.add("EventTwoTracks/ElectronPion/hMotherP", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("EventTwoTracks/ElectronPion/hMotherPwide", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventTwoTracks/ElectronPion/hMotherPt", ";Mother #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("EventTwoTracks/ElectronPion/hMotherPhi", ";Mother #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("EventTwoTracks/ElectronPion/hMotherRapidity", ";Mother #it{y} (-);Number of events (-)", HistType::kTH1D, {axisRap}); + histos.add("EventTwoTracks/ElectronPion/hDaughtersP", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMom, axisMom}); + histos.add("EventTwoTracks/ElectronPion/hDaughtersPwide", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMomWide, axisMomWide}); + histos.add("EventTwoTracks/ElectronPion/hDaughtersPt", ";Daughter 1 #it{p_{T}} (GeV/c);Daughter 2 #it{p_{T}} (GeV/c)", HistType::kTH2D, {axisPt, axisPt}); + histos.add("EventTwoTracks/ElectronPion/hDaughtersPhi", ";Daughter 1 #phi (rad);Daughter 2 #phi (rad)", HistType::kTH2D, {axisPhi, axisPhi}); + histos.add("EventTwoTracks/ElectronPion/hDaughtersRapidity", ";Daughter 1 #it{y} (-);Daughter 2 #it{y} (-)", HistType::kTH2D, {axisRap, axisRap}); + + histos.add("EventTwoTracks/MuonPion/hInvariantMass", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMass}); + histos.add("EventTwoTracks/MuonPion/hInvariantMassWide", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/MuonPion/hInvariantMassWidePtCut", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/MuonPion/hAcoplanarity", ";#Delta#phi (rad);Number of events (-)", HistType::kTH1D, {axisAcoplanarity}); + histos.add("EventTwoTracks/MuonPion/hMotherP", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("EventTwoTracks/MuonPion/hMotherPwide", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventTwoTracks/MuonPion/hMotherPt", ";Mother #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("EventTwoTracks/MuonPion/hMotherPhi", ";Mother #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("EventTwoTracks/MuonPion/hMotherRapidity", ";Mother #it{y} (-);Number of events (-)", HistType::kTH1D, {axisRap}); + histos.add("EventTwoTracks/MuonPion/hDaughtersP", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMom, axisMom}); + histos.add("EventTwoTracks/MuonPion/hDaughtersPwide", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMomWide, axisMomWide}); + histos.add("EventTwoTracks/MuonPion/hDaughtersPt", ";Daughter 1 #it{p_{T}} (GeV/c);Daughter 2 #it{p_{T}} (GeV/c)", HistType::kTH2D, {axisPt, axisPt}); + histos.add("EventTwoTracks/MuonPion/hDaughtersPhi", ";Daughter 1 #phi (rad);Daughter 2 #phi (rad)", HistType::kTH2D, {axisPhi, axisPhi}); + histos.add("EventTwoTracks/MuonPion/hDaughtersRapidity", ";Daughter 1 #it{y} (-);Daughter 2 #it{y} (-)", HistType::kTH2D, {axisRap, axisRap}); + + histos.add("EventTwoTracks/ElectronMuPi/hNeventsPtCuts", ";Selection (-);Number of events (-)", HistType::kTH1D, {{20, -0.5, 19.5}}); + histos.add("EventTwoTracks/ElectronMuPi/hInvariantMass", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMass}); + histos.add("EventTwoTracks/ElectronMuPi/hInvariantMassWide", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/ElectronMuPi/hAcoplanarity", ";#Delta#phi (rad);Number of events (-)", HistType::kTH1D, {axisAcoplanarity}); + histos.add("EventTwoTracks/ElectronMuPi/hMotherP", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("EventTwoTracks/ElectronMuPi/hMotherPwide", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventTwoTracks/ElectronMuPi/hMotherPt", ";Mother #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("EventTwoTracks/ElectronMuPi/hMotherPhi", ";Mother #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("EventTwoTracks/ElectronMuPi/hMotherRapidity", ";Mother #it{y} (-);Number of events (-)", HistType::kTH1D, {axisRap}); + histos.add("EventTwoTracks/ElectronMuPi/hElectronPtWide", ";Electron #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventTwoTracks/ElectronMuPi/hDaughtersP", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMom, axisMom}); + histos.add("EventTwoTracks/ElectronMuPi/hDaughtersPwide", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMomWide, axisMomWide}); + histos.add("EventTwoTracks/ElectronMuPi/hDaughtersPt", ";Daughter 1 #it{p_{T}} (GeV/c);Daughter 2 #it{p_{T}} (GeV/c)", HistType::kTH2D, {axisPt, axisPt}); + histos.add("EventTwoTracks/ElectronMuPi/hDaughtersPhi", ";Daughter 1 #phi (rad);Daughter 2 #phi (rad)", HistType::kTH2D, {axisPhi, axisPhi}); + histos.add("EventTwoTracks/ElectronMuPi/hDaughtersRapidity", ";Daughter 1 #it{y} (-);Daughter 2 #it{y} (-)", HistType::kTH2D, {axisRap, axisRap}); + + histos.add("EventTwoTracks/ElectronOther/hNeventsPtCuts", ";Selection (-);Number of events (-)", HistType::kTH1D, {{20, -0.5, 19.5}}); + histos.add("EventTwoTracks/ElectronOther/hInvariantMass", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMass}); + histos.add("EventTwoTracks/ElectronOther/hInvariantMassWide", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/ElectronOther/hAcoplanarity", ";#Delta#phi (rad);Number of events (-)", HistType::kTH1D, {axisAcoplanarity}); + histos.add("EventTwoTracks/ElectronOther/hMotherP", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("EventTwoTracks/ElectronOther/hMotherPwide", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventTwoTracks/ElectronOther/hMotherPt", ";Mother #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("EventTwoTracks/ElectronOther/hMotherPhi", ";Mother #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("EventTwoTracks/ElectronOther/hMotherRapidity", ";Mother #it{y} (-);Number of events (-)", HistType::kTH1D, {axisRap}); + histos.add("EventTwoTracks/ElectronOther/hElectronPtWide", ";Electron #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventTwoTracks/ElectronOther/hDaughtersP", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMom, axisMom}); + histos.add("EventTwoTracks/ElectronOther/hDaughtersPwide", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMomWide, axisMomWide}); + histos.add("EventTwoTracks/ElectronOther/hDaughtersPt", ";Daughter 1 #it{p_{T}} (GeV/c);Daughter 2 #it{p_{T}} (GeV/c)", HistType::kTH2D, {axisPt, axisPt}); + histos.add("EventTwoTracks/ElectronOther/hDaughtersPhi", ";Daughter 1 #phi (rad);Daughter 2 #phi (rad)", HistType::kTH2D, {axisPhi, axisPhi}); + histos.add("EventTwoTracks/ElectronOther/hDaughtersRapidity", ";Daughter 1 #it{y} (-);Daughter 2 #it{y} (-)", HistType::kTH2D, {axisRap, axisRap}); + + histos.add("EventTwoTracks/PionsSelection/hInvariantMass", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMass}); + histos.add("EventTwoTracks/PionsSelection/hInvariantMassWide", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/PionsSelection/hInvariantMassPtCut", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMass}); + histos.add("EventTwoTracks/PionsSelection/hInvariantMassWidePtCut", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/PionsSelection/hInvariantMassWidePtCutUS", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/PionsSelection/hInvariantMassWidePtCutLS", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventTwoTracks/PionsSelection/hAcoplanarity", ";#Delta#phi (rad);Number of events (-)", HistType::kTH1D, {axisAcoplanarity}); + histos.add("EventTwoTracks/PionsSelection/hMotherP", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("EventTwoTracks/PionsSelection/hMotherPwide", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventTwoTracks/PionsSelection/hMotherPt", ";Mother #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("EventTwoTracks/PionsSelection/hMotherPhi", ";Mother #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("EventTwoTracks/PionsSelection/hMotherRapidity", ";Mother #it{y} (-);Number of events (-)", HistType::kTH1D, {axisRap}); + histos.add("EventTwoTracks/PionsSelection/hDaughtersP", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMom, axisMom}); + histos.add("EventTwoTracks/PionsSelection/hDaughtersPwide", ";Daughter 1 #it{p} (GeV/c);Daughter 2 #it{p} (GeV/c)", HistType::kTH2D, {axisMomWide, axisMomWide}); + histos.add("EventTwoTracks/PionsSelection/hDaughtersPt", ";Daughter 1 #it{p_{T}} (GeV/c);Daughter 2 #it{p_{T}} (GeV/c)", HistType::kTH2D, {axisPt, axisPt}); + histos.add("EventTwoTracks/PionsSelection/hDaughtersPhi", ";Daughter 1 #phi (rad);Daughter 2 #phi (rad)", HistType::kTH2D, {axisPhi, axisPhi}); + histos.add("EventTwoTracks/PionsSelection/hDaughtersRapidity", ";Daughter 1 #it{y} (-);Daughter 2 #it{y} (-)", HistType::kTH2D, {axisRap, axisRap}); + + histos.add("EventFourTracks/hInvariantMass", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMass}); + histos.add("EventFourTracks/hInvariantMassWide", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventFourTracks/hInvariantMassWideNoMothers", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventFourTracks/hMotherP", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("EventFourTracks/hMotherPwide", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventFourTracks/hMotherPt", ";Mother #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("EventFourTracks/hMotherPhi", ";Mother #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("EventFourTracks/hMotherRapidity", ";Mother #it{y} (-);Number of events (-)", HistType::kTH1D, {axisRap}); + + histos.add("EventFourTracks/WithElectron/hInvariantMass", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMass}); + histos.add("EventFourTracks/WithElectron/hInvariantMassWide", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventFourTracks/WithElectron/hMotherP", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("EventFourTracks/WithElectron/hMotherPwide", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventFourTracks/WithElectron/hMotherPt", ";Mother #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("EventFourTracks/WithElectron/hMotherPhi", ";Mother #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("EventFourTracks/WithElectron/hMotherRapidity", ";Mother #it{y} (-);Number of events (-)", HistType::kTH1D, {axisRap}); + + histos.add("EventFourTracks/WithMuon/hInvariantMass", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMass}); + histos.add("EventFourTracks/WithMuon/hInvariantMassWide", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventFourTracks/WithMuon/hMotherP", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("EventFourTracks/WithMuon/hMotherPwide", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventFourTracks/WithMuon/hMotherPt", ";Mother #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("EventFourTracks/WithMuon/hMotherPhi", ";Mother #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("EventFourTracks/WithMuon/hMotherRapidity", ";Mother #it{y} (-);Number of events (-)", HistType::kTH1D, {axisRap}); + + histos.add("EventFourTracks/WithPion/hInvariantMass", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMass}); + histos.add("EventFourTracks/WithPion/hInvariantMassWide", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventFourTracks/WithPion/hMotherP", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("EventFourTracks/WithPion/hMotherPwide", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventFourTracks/WithPion/hMotherPt", ";Mother #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("EventFourTracks/WithPion/hMotherPhi", ";Mother #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("EventFourTracks/WithPion/hMotherRapidity", ";Mother #it{y} (-);Number of events (-)", HistType::kTH1D, {axisRap}); + + histos.add("EventSixTracks/hInvariantMass", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMass}); + histos.add("EventSixTracks/hInvariantMassWide", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventSixTracks/hInvariantMassWideNoMothers", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventSixTracks/hMotherP", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("EventSixTracks/hMotherPwide", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventSixTracks/hMotherPt", ";Mother #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("EventSixTracks/hMotherPhi", ";Mother #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("EventSixTracks/hMotherRapidity", ";Mother #it{y} (-);Number of events (-)", HistType::kTH1D, {axisRap}); + + histos.add("EventSixTracks/SixPions/hInvariantMass", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMass}); + histos.add("EventSixTracks/SixPions/hInvariantMassWide", ";Invariant mass (GeV/c^{2});Number of events (-)", HistType::kTH1D, {axisInvMassWide}); + histos.add("EventSixTracks/SixPions/hMotherP", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMom}); + histos.add("EventSixTracks/SixPions/hMotherPwide", ";Mother #it{p} (GeV/c);Number of events (-)", HistType::kTH1D, {axisMomWide}); + histos.add("EventSixTracks/SixPions/hMotherPt", ";Mother #it{p_{T}} (GeV/c);Number of events (-)", HistType::kTH1D, {axisPt}); + histos.add("EventSixTracks/SixPions/hMotherPhi", ";Mother #phi (rad);Number of events (-)", HistType::kTH1D, {axisPhi}); + histos.add("EventSixTracks/SixPions/hMotherRapidity", ";Mother #it{y} (-);Number of events (-)", HistType::kTH1D, {axisRap}); + + } // end init + + // run (always called before process :( ) + void run(ProcessingContext& context) + { + + if (verboseInfo) + printLargeMessage("RUN METHOD"); + if (verboseDebug) + LOGF(info, "countCollisions = %d", countCollisions); + + } // end run + + // process + + template + void fillHistograms(C reconstructedCollision, Ts reconstructedBarrelTracks) + { + + if (isFirstReconstructedCollisions) { + isFirstReconstructedCollisions = false; + if (verboseInfo) + printLargeMessage("START LOOPING OVER RECONSTRUCTED COLLISIONS"); + } + + histos.get(HIST("Events/hCountCollisions"))->Fill(4); // 1, 2 and 3 are reserved for single-gap + + // Loop over tracks without selections + for (auto& track : reconstructedBarrelTracks) { + float trkPx = track.px(); + float trkPy = track.py(); + float trkPz = track.pz(); + // histos.get(HIST("Tracks/raw/hTrackZ"))->Fill(track.z()); + histos.get(HIST("Tracks/raw/hTrackP"))->Fill(momentum(trkPx, trkPy, trkPz)); + histos.get(HIST("Tracks/raw/hTrackPt"))->Fill(track.pt()); + histos.get(HIST("Tracks/raw/hTrackPhi"))->Fill(phi(trkPx, trkPy)); + histos.get(HIST("Tracks/raw/hTrackEta"))->Fill(eta(trkPx, trkPy, trkPz)); + // histosPID.get(HIST("Tracks/raw/PID/hTPCsignalVsZ"))->Fill(track.z(),track.tpcSignal()); + histosPID.get(HIST("Tracks/raw/PID/hTPCsignalVsP"))->Fill(momentum(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/raw/PID/hTPCsignalVsPt"))->Fill(track.pt(), track.tpcSignal()); + histosPID.get(HIST("Tracks/raw/PID/hTPCsignalVsEta"))->Fill(eta(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/raw/PID/hTPCsignalVsPhi"))->Fill(phi(trkPx, trkPy), track.tpcSignal()); + if (track.hasTPC()) { + if (track.sign() == 1) { + // histosPID.get(HIST("Tracks/raw/PID/PosCharge/hTPCsignalVsZ"))->Fill(track.z(),track.tpcSignal()); + histosPID.get(HIST("Tracks/raw/PID/PosCharge/hTPCsignalVsP"))->Fill(momentum(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/raw/PID/PosCharge/hTPCsignalVsPt"))->Fill(track.pt(), track.tpcSignal()); + histosPID.get(HIST("Tracks/raw/PID/PosCharge/hTPCsignalVsEta"))->Fill(eta(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/raw/PID/PosCharge/hTPCsignalVsPhi"))->Fill(phi(trkPx, trkPy), track.tpcSignal()); + } else if (track.sign() == -1) { + // histosPID.get(HIST("Tracks/raw/PID/NegCharge/hTPCsignalVsZ"))->Fill(track.z(),track.tpcSignal()); + histosPID.get(HIST("Tracks/raw/PID/NegCharge/hTPCsignalVsP"))->Fill(momentum(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/raw/PID/NegCharge/hTPCsignalVsPt"))->Fill(track.pt(), track.tpcSignal()); + histosPID.get(HIST("Tracks/raw/PID/NegCharge/hTPCsignalVsEta"))->Fill(eta(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/raw/PID/NegCharge/hTPCsignalVsPhi"))->Fill(phi(trkPx, trkPy), track.tpcSignal()); + } else { + printMediumMessage("Track has no charge"); + } + } + } // Loop over tracks without selections + + int countPVGT = 0; + int countPVGTselected = 0; + int countPVGTelectrons = 0; + int countPVGTmuons = 0; + int countPVGTpions = 0; + int countPVGTothers = 0; + int countPVGTpionsSelection = 0; + std::vector vecPVidx; + // Loop over tracks with selections + for (auto& track : reconstructedBarrelTracks) { + if (track.isPVContributor() != 1) + continue; + float trkPx = track.px(); + float trkPy = track.py(); + float trkPz = track.pz(); + // histos.get(HIST("Tracks/GoodTrack/hTrackZ"))->Fill(track.z()); + histos.get(HIST("Tracks/GoodTrack/hTrackP"))->Fill(momentum(trkPx, trkPy, trkPz)); + histos.get(HIST("Tracks/GoodTrack/hTrackPt"))->Fill(track.pt()); + histos.get(HIST("Tracks/GoodTrack/hTrackPhi"))->Fill(phi(trkPx, trkPy)); + histos.get(HIST("Tracks/GoodTrack/hTrackEta"))->Fill(eta(trkPx, trkPy, trkPz)); + // histosPID.get(HIST("Tracks/GoodTrack/PID/hTPCsignalVsZ"))->Fill(track.z(),track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/hTPCsignalVsP"))->Fill(momentum(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/hTPCsignalVsPt"))->Fill(track.pt(), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/hTPCsignalVsEta"))->Fill(eta(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/hTPCsignalVsPhi"))->Fill(phi(trkPx, trkPy), track.tpcSignal()); + if (track.hasTPC()) { + if (track.sign() == 1) { + // histosPID.get(HIST("Tracks/GoodTrack/PID/PosCharge/hTPCsignalVsZ"))->Fill(track.z(),track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/PosCharge/hTPCsignalVsP"))->Fill(momentum(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/PosCharge/hTPCsignalVsPt"))->Fill(track.pt(), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/PosCharge/hTPCsignalVsEta"))->Fill(eta(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/PosCharge/hTPCsignalVsPhi"))->Fill(phi(trkPx, trkPy), track.tpcSignal()); + } else if (track.sign() == -1) { + // histosPID.get(HIST("Tracks/GoodTrack/PID/NegCharge/hTPCsignalVsZ"))->Fill(track.z(),track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/NegCharge/hTPCsignalVsP"))->Fill(momentum(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/NegCharge/hTPCsignalVsPt"))->Fill(track.pt(), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/NegCharge/hTPCsignalVsEta"))->Fill(eta(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/NegCharge/hTPCsignalVsPhi"))->Fill(phi(trkPx, trkPy), track.tpcSignal()); + } else { + printMediumMessage("Track has no charge"); + } + } + countPVGT++; + int hypothesisID = testPIDhypothesis(track); + if (hypothesisID == P_ELECTRON || hypothesisID == P_MUON || hypothesisID == P_PION) { + countPVGTselected++; + vecPVidx.push_back(track.index()); + if (hypothesisID == P_ELECTRON) { + countPVGTelectrons++; + // histosPID.get(HIST("Tracks/GoodTrack/PID/Electron/hTPCsignalVsZ"))->Fill(track.z(),track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/Electron/hTPCsignalVsP"))->Fill(momentum(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/Electron/hTPCsignalVsPt"))->Fill(track.pt(), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/Electron/hTPCsignalVsEta"))->Fill(eta(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/Electron/hTPCsignalVsPhi"))->Fill(phi(trkPx, trkPy), track.tpcSignal()); + } else if (hypothesisID == P_MUON) { + countPVGTmuons++; + // histosPID.get(HIST("Tracks/GoodTrack/PID/Muon/hTPCsignalVsZ"))->Fill(track.z(),track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/Muon/hTPCsignalVsP"))->Fill(momentum(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/Muon/hTPCsignalVsPt"))->Fill(track.pt(), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/Muon/hTPCsignalVsEta"))->Fill(eta(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/Muon/hTPCsignalVsPhi"))->Fill(phi(trkPx, trkPy), track.tpcSignal()); + } else { + countPVGTpions++; + // histosPID.get(HIST("Tracks/GoodTrack/PID/Pion/hTPCsignalVsZ"))->Fill(track.z(),track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/Pion/hTPCsignalVsP"))->Fill(momentum(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/Pion/hTPCsignalVsPt"))->Fill(track.pt(), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/Pion/hTPCsignalVsEta"))->Fill(eta(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/Pion/hTPCsignalVsPhi"))->Fill(phi(trkPx, trkPy), track.tpcSignal()); + } + } else { + countPVGTothers++; + // histosPID.get(HIST("Tracks/GoodTrack/PID/Others/hTPCsignalVsZ"))->Fill(track.z(),track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/Others/hTPCsignalVsP"))->Fill(momentum(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/Others/hTPCsignalVsPt"))->Fill(track.pt(), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/Others/hTPCsignalVsEta"))->Fill(eta(trkPx, trkPy, trkPz), track.tpcSignal()); + histosPID.get(HIST("Tracks/GoodTrack/PID/Others/hTPCsignalVsPhi"))->Fill(phi(trkPx, trkPy), track.tpcSignal()); + } + if (abs(track.tpcNSigmaPi()) < 3) + countPVGTpionsSelection++; + + } // Loop over tracks with selections + + histos.get(HIST("Events/hNreconstructedPVGT"))->Fill(countPVGT); + histos.get(HIST("Events/hNreconstructedNotPVGT"))->Fill(reconstructedBarrelTracks.size() - countPVGT); + histos.get(HIST("Events/hNreconstructedPVGTelectrons"))->Fill(countPVGTelectrons); + histos.get(HIST("Events/hNreconstructedPVGTmuons"))->Fill(countPVGTmuons); + histos.get(HIST("Events/hNreconstructedPVGTpions"))->Fill(countPVGTpions); + histos.get(HIST("Events/hNreconstructedPVGTothers"))->Fill(countPVGTothers); + + if (countPVGTselected == 2) { + TLorentzVector mother, daug[2], motherOfPions, pion[2]; + const auto& trkDaug1 = reconstructedBarrelTracks.iteratorAt(vecPVidx[0]); + const auto& trkDaug2 = reconstructedBarrelTracks.iteratorAt(vecPVidx[1]); + daug[0].SetPxPyPzE(trkDaug1.px(), trkDaug1.py(), trkDaug1.pz(), energy(pdg->Mass(trackPDG(trkDaug1)), trkDaug1.px(), trkDaug1.py(), trkDaug1.pz())); + daug[1].SetPxPyPzE(trkDaug2.px(), trkDaug2.py(), trkDaug2.pz(), energy(pdg->Mass(trackPDG(trkDaug2)), trkDaug2.px(), trkDaug2.py(), trkDaug2.pz())); + mother = daug[0] + daug[1]; + pion[0].SetPxPyPzE(trkDaug1.px(), trkDaug1.py(), trkDaug1.pz(), energy(pdg->Mass(211), trkDaug1.px(), trkDaug1.py(), trkDaug1.pz())); + pion[1].SetPxPyPzE(trkDaug2.px(), trkDaug2.py(), trkDaug2.pz(), energy(pdg->Mass(211), trkDaug2.px(), trkDaug2.py(), trkDaug2.pz())); + motherOfPions = pion[0] + pion[1]; + auto acoplanarity = calculateAcoplanarity(daug[0].Phi(), daug[1].Phi()); + auto sign = trkDaug1.sign() * trkDaug2.sign(); + + if (trkDaug1.hasTPC()) { + histosPID.get(HIST("EventTwoTracks/PID/hTPCsignalVsP"))->Fill(daug[0].P(), trkDaug1.tpcSignal()); + if (countPVGTelectrons == 2) + histosPID.get(HIST("EventTwoTracks/TwoElectrons/PID/hTPCsignalVsP"))->Fill(daug[0].P(), trkDaug1.tpcSignal()); + if (countPVGTmuons == 2) + histosPID.get(HIST("EventTwoTracks/TwoMuons/PID/hTPCsignalVsP"))->Fill(daug[0].P(), trkDaug1.tpcSignal()); + if (countPVGTpions == 2) + histosPID.get(HIST("EventTwoTracks/TwoPions/PID/hTPCsignalVsP"))->Fill(daug[0].P(), trkDaug1.tpcSignal()); + if (countPVGTelectrons == 1 && countPVGTmuons == 1) + histosPID.get(HIST("EventTwoTracks/ElectronMuon/PID/hTPCsignalVsP"))->Fill(daug[0].P(), trkDaug1.tpcSignal()); + if (countPVGTelectrons == 1 && countPVGTpions == 1) + histosPID.get(HIST("EventTwoTracks/ElectronPion/PID/hTPCsignalVsP"))->Fill(daug[0].P(), trkDaug1.tpcSignal()); + if (countPVGTpions == 1 && countPVGTmuons == 1) + histosPID.get(HIST("EventTwoTracks/MuonPion/PID/hTPCsignalVsP"))->Fill(daug[0].P(), trkDaug1.tpcSignal()); + } + if (trkDaug2.hasTPC()) { + histosPID.get(HIST("EventTwoTracks/PID/hTPCsignalVsP"))->Fill(daug[1].P(), trkDaug2.tpcSignal()); + if (countPVGTelectrons == 2) + histosPID.get(HIST("EventTwoTracks/TwoElectrons/PID/hTPCsignalVsP"))->Fill(daug[1].P(), trkDaug2.tpcSignal()); + if (countPVGTmuons == 2) + histosPID.get(HIST("EventTwoTracks/TwoMuons/PID/hTPCsignalVsP"))->Fill(daug[1].P(), trkDaug2.tpcSignal()); + if (countPVGTpions == 2) + histosPID.get(HIST("EventTwoTracks/TwoPions/PID/hTPCsignalVsP"))->Fill(daug[1].P(), trkDaug2.tpcSignal()); + if (countPVGTelectrons == 1 && countPVGTmuons == 1) + histosPID.get(HIST("EventTwoTracks/ElectronMuon/PID/hTPCsignalVsP"))->Fill(daug[1].P(), trkDaug2.tpcSignal()); + if (countPVGTelectrons == 1 && countPVGTpions == 1) + histosPID.get(HIST("EventTwoTracks/ElectronPion/PID/hTPCsignalVsP"))->Fill(daug[1].P(), trkDaug2.tpcSignal()); + if (countPVGTpions == 1 && countPVGTmuons == 1) + histosPID.get(HIST("EventTwoTracks/MuonPion/PID/hTPCsignalVsP"))->Fill(daug[1].P(), trkDaug2.tpcSignal()); + } + + histos.get(HIST("EventTwoTracks/hInvariantMass"))->Fill(mother.M()); + histos.get(HIST("EventTwoTracks/hInvariantMassWide"))->Fill(mother.M()); + histos.get(HIST("EventTwoTracks/hInvariantMassWideAllPionMass"))->Fill(motherOfPions.M()); + histos.get(HIST("EventTwoTracks/hAcoplanarity"))->Fill(acoplanarity); + histos.get(HIST("EventTwoTracks/hMotherP"))->Fill(mother.P()); + histos.get(HIST("EventTwoTracks/hMotherPwide"))->Fill(mother.P()); + histos.get(HIST("EventTwoTracks/hMotherPt"))->Fill(mother.Pt()); + histos.get(HIST("EventTwoTracks/hMotherPhi"))->Fill(mother.Phi()); + histos.get(HIST("EventTwoTracks/hMotherRapidity"))->Fill(mother.Rapidity()); + histos.get(HIST("EventTwoTracks/hDaughtersP"))->Fill(daug[0].P(), daug[1].P()); + histos.get(HIST("EventTwoTracks/hDaughtersPwide"))->Fill(daug[0].P(), daug[1].P()); + histos.get(HIST("EventTwoTracks/hDaughtersPt"))->Fill(daug[0].Pt(), daug[1].Pt()); + histos.get(HIST("EventTwoTracks/hDaughtersPhi"))->Fill(daug[0].Phi(), daug[1].Phi()); + histos.get(HIST("EventTwoTracks/hDaughtersRapidity"))->Fill(daug[0].Rapidity(), daug[1].Rapidity()); + if (motherOfPions.Pt() < 0.2) { + histos.get(HIST("EventTwoTracks/hInvariantMassWideAllPionMassPtCut"))->Fill(motherOfPions.M()); + } + + // ee, mm, em, pp, ep, mp, pppp, eppp, mppp, pppppp + if (countPVGTelectrons == 2) { + histos.get(HIST("Events/hChannelsRatio"))->Fill(0); + histos.get(HIST("EventTwoTracks/TwoElectrons/hInvariantMass"))->Fill(mother.M()); + histos.get(HIST("EventTwoTracks/TwoElectrons/hInvariantMassWide"))->Fill(mother.M()); + histos.get(HIST("EventTwoTracks/TwoElectrons/hAcoplanarity"))->Fill(acoplanarity); + histos.get(HIST("EventTwoTracks/TwoElectrons/hMotherP"))->Fill(mother.P()); + histos.get(HIST("EventTwoTracks/TwoElectrons/hMotherPwide"))->Fill(mother.P()); + histos.get(HIST("EventTwoTracks/TwoElectrons/hMotherPt"))->Fill(mother.Pt()); + histos.get(HIST("EventTwoTracks/TwoElectrons/hMotherPhi"))->Fill(mother.Phi()); + histos.get(HIST("EventTwoTracks/TwoElectrons/hMotherRapidity"))->Fill(mother.Rapidity()); + histos.get(HIST("EventTwoTracks/TwoElectrons/hDaughtersP"))->Fill(daug[0].P(), daug[1].P()); + histos.get(HIST("EventTwoTracks/TwoElectrons/hDaughtersPwide"))->Fill(daug[0].P(), daug[1].P()); + histos.get(HIST("EventTwoTracks/TwoElectrons/hDaughtersPt"))->Fill(daug[0].Pt(), daug[1].Pt()); + histos.get(HIST("EventTwoTracks/TwoElectrons/hDaughtersPhi"))->Fill(daug[0].Phi(), daug[1].Phi()); + histos.get(HIST("EventTwoTracks/TwoElectrons/hDaughtersRapidity"))->Fill(daug[0].Rapidity(), daug[1].Rapidity()); + histos.get(HIST("EventTwoTracks/TwoElectrons/hLeadingP"))->Fill(((daug[0].P() > daug[1].P()) ? daug[0].P() : daug[1].P())); + histos.get(HIST("EventTwoTracks/TwoElectrons/hLeadingPwide"))->Fill(((daug[0].P() > daug[1].P()) ? daug[0].P() : daug[1].P())); + histos.get(HIST("EventTwoTracks/TwoElectrons/hLeadingPt"))->Fill(((daug[0].P() > daug[1].P()) ? daug[0].Pt() : daug[1].Pt())); + histos.get(HIST("EventTwoTracks/TwoElectrons/hLeadingPhi"))->Fill(((daug[0].P() > daug[1].P()) ? daug[0].Phi() : daug[1].Phi())); + histos.get(HIST("EventTwoTracks/TwoElectrons/hLeadingRapidity"))->Fill(((daug[0].P() > daug[1].P()) ? daug[0].Rapidity() : daug[1].Rapidity())); + } + if (countPVGTmuons == 2) { + histos.get(HIST("Events/hChannelsRatio"))->Fill(1); + histos.get(HIST("EventTwoTracks/TwoMuons/hInvariantMass"))->Fill(mother.M()); + histos.get(HIST("EventTwoTracks/TwoMuons/hInvariantMassWide"))->Fill(mother.M()); + histos.get(HIST("EventTwoTracks/TwoMuons/hAcoplanarity"))->Fill(acoplanarity); + histos.get(HIST("EventTwoTracks/TwoMuons/hMotherP"))->Fill(mother.P()); + histos.get(HIST("EventTwoTracks/TwoMuons/hMotherPwide"))->Fill(mother.P()); + histos.get(HIST("EventTwoTracks/TwoMuons/hMotherPt"))->Fill(mother.Pt()); + histos.get(HIST("EventTwoTracks/TwoMuons/hMotherPhi"))->Fill(mother.Phi()); + histos.get(HIST("EventTwoTracks/TwoMuons/hMotherRapidity"))->Fill(mother.Rapidity()); + histos.get(HIST("EventTwoTracks/TwoMuons/hDaughtersP"))->Fill(daug[0].P(), daug[1].P()); + histos.get(HIST("EventTwoTracks/TwoMuons/hDaughtersPwide"))->Fill(daug[0].P(), daug[1].P()); + histos.get(HIST("EventTwoTracks/TwoMuons/hDaughtersPt"))->Fill(daug[0].Pt(), daug[1].Pt()); + histos.get(HIST("EventTwoTracks/TwoMuons/hDaughtersPhi"))->Fill(daug[0].Phi(), daug[1].Phi()); + histos.get(HIST("EventTwoTracks/TwoMuons/hDaughtersRapidity"))->Fill(daug[0].Rapidity(), daug[1].Rapidity()); + if (mother.Pt() < 0.2) { + histos.get(HIST("EventTwoTracks/TwoMuons/hInvariantMassWidePtCut"))->Fill(mother.M()); + } + } + if (countPVGTelectrons == 1 && countPVGTmuons == 1) { + histos.get(HIST("Events/hChannelsRatio"))->Fill(2); + histos.get(HIST("EventTwoTracks/ElectronMuon/hInvariantMass"))->Fill(mother.M()); + histos.get(HIST("EventTwoTracks/ElectronMuon/hInvariantMassWide"))->Fill(mother.M()); + histos.get(HIST("EventTwoTracks/ElectronMuon/hAcoplanarity"))->Fill(acoplanarity); + histos.get(HIST("EventTwoTracks/ElectronMuon/hMotherP"))->Fill(mother.P()); + histos.get(HIST("EventTwoTracks/ElectronMuon/hMotherPwide"))->Fill(mother.P()); + histos.get(HIST("EventTwoTracks/ElectronMuon/hMotherPt"))->Fill(mother.Pt()); + histos.get(HIST("EventTwoTracks/ElectronMuon/hMotherPhi"))->Fill(mother.Phi()); + histos.get(HIST("EventTwoTracks/ElectronMuon/hMotherRapidity"))->Fill(mother.Rapidity()); + histos.get(HIST("EventTwoTracks/ElectronMuon/hDaughtersP"))->Fill(daug[0].P(), daug[1].P()); + histos.get(HIST("EventTwoTracks/ElectronMuon/hDaughtersPwide"))->Fill(daug[0].P(), daug[1].P()); + histos.get(HIST("EventTwoTracks/ElectronMuon/hDaughtersPt"))->Fill(daug[0].Pt(), daug[1].Pt()); + histos.get(HIST("EventTwoTracks/ElectronMuon/hDaughtersPhi"))->Fill(daug[0].Phi(), daug[1].Phi()); + histos.get(HIST("EventTwoTracks/ElectronMuon/hDaughtersRapidity"))->Fill(daug[0].Rapidity(), daug[1].Rapidity()); + } + if (countPVGTpions == 2) { + histos.get(HIST("Events/hChannelsRatio"))->Fill(3); + histos.get(HIST("EventTwoTracks/TwoPions/hInvariantMass"))->Fill(mother.M()); + histos.get(HIST("EventTwoTracks/TwoPions/hInvariantMassWide"))->Fill(mother.M()); + histos.get(HIST("EventTwoTracks/TwoPions/hAcoplanarity"))->Fill(acoplanarity); + histos.get(HIST("EventTwoTracks/TwoPions/hMotherP"))->Fill(mother.P()); + histos.get(HIST("EventTwoTracks/TwoPions/hMotherPwide"))->Fill(mother.P()); + histos.get(HIST("EventTwoTracks/TwoPions/hMotherPt"))->Fill(mother.Pt()); + histos.get(HIST("EventTwoTracks/TwoPions/hMotherPhi"))->Fill(mother.Phi()); + histos.get(HIST("EventTwoTracks/TwoPions/hMotherRapidity"))->Fill(mother.Rapidity()); + histos.get(HIST("EventTwoTracks/TwoPions/hDaughtersP"))->Fill(daug[0].P(), daug[1].P()); + histos.get(HIST("EventTwoTracks/TwoPions/hDaughtersPwide"))->Fill(daug[0].P(), daug[1].P()); + histos.get(HIST("EventTwoTracks/TwoPions/hDaughtersPt"))->Fill(daug[0].Pt(), daug[1].Pt()); + histos.get(HIST("EventTwoTracks/TwoPions/hDaughtersPhi"))->Fill(daug[0].Phi(), daug[1].Phi()); + histos.get(HIST("EventTwoTracks/TwoPions/hDaughtersRapidity"))->Fill(daug[0].Rapidity(), daug[1].Rapidity()); + if (mother.Pt() < 0.2) { + histos.get(HIST("EventTwoTracks/TwoPions/hInvariantMassWidePtCut"))->Fill(mother.M()); + } + } + if (countPVGTelectrons == 1 && countPVGTpions == 1) { + histos.get(HIST("Events/hChannelsRatio"))->Fill(4); + histos.get(HIST("EventTwoTracks/ElectronPion/hInvariantMass"))->Fill(mother.M()); + histos.get(HIST("EventTwoTracks/ElectronPion/hInvariantMassWide"))->Fill(mother.M()); + histos.get(HIST("EventTwoTracks/ElectronPion/hAcoplanarity"))->Fill(acoplanarity); + histos.get(HIST("EventTwoTracks/ElectronPion/hMotherP"))->Fill(mother.P()); + histos.get(HIST("EventTwoTracks/ElectronPion/hMotherPwide"))->Fill(mother.P()); + histos.get(HIST("EventTwoTracks/ElectronPion/hMotherPt"))->Fill(mother.Pt()); + histos.get(HIST("EventTwoTracks/ElectronPion/hMotherPhi"))->Fill(mother.Phi()); + histos.get(HIST("EventTwoTracks/ElectronPion/hMotherRapidity"))->Fill(mother.Rapidity()); + histos.get(HIST("EventTwoTracks/ElectronPion/hDaughtersP"))->Fill(daug[0].P(), daug[1].P()); + histos.get(HIST("EventTwoTracks/ElectronPion/hDaughtersPwide"))->Fill(daug[0].P(), daug[1].P()); + histos.get(HIST("EventTwoTracks/ElectronPion/hDaughtersPt"))->Fill(daug[0].Pt(), daug[1].Pt()); + histos.get(HIST("EventTwoTracks/ElectronPion/hDaughtersPhi"))->Fill(daug[0].Phi(), daug[1].Phi()); + histos.get(HIST("EventTwoTracks/ElectronPion/hDaughtersRapidity"))->Fill(daug[0].Rapidity(), daug[1].Rapidity()); + } + if (countPVGTpions == 1 && countPVGTmuons == 1) { + histos.get(HIST("Events/hChannelsRatio"))->Fill(5); + histos.get(HIST("EventTwoTracks/MuonPion/hInvariantMass"))->Fill(mother.M()); + histos.get(HIST("EventTwoTracks/MuonPion/hInvariantMassWide"))->Fill(mother.M()); + histos.get(HIST("EventTwoTracks/MuonPion/hAcoplanarity"))->Fill(acoplanarity); + histos.get(HIST("EventTwoTracks/MuonPion/hMotherP"))->Fill(mother.P()); + histos.get(HIST("EventTwoTracks/MuonPion/hMotherPwide"))->Fill(mother.P()); + histos.get(HIST("EventTwoTracks/MuonPion/hMotherPt"))->Fill(mother.Pt()); + histos.get(HIST("EventTwoTracks/MuonPion/hMotherPhi"))->Fill(mother.Phi()); + histos.get(HIST("EventTwoTracks/MuonPion/hMotherRapidity"))->Fill(mother.Rapidity()); + histos.get(HIST("EventTwoTracks/MuonPion/hDaughtersP"))->Fill(daug[0].P(), daug[1].P()); + histos.get(HIST("EventTwoTracks/MuonPion/hDaughtersPwide"))->Fill(daug[0].P(), daug[1].P()); + histos.get(HIST("EventTwoTracks/MuonPion/hDaughtersPt"))->Fill(daug[0].Pt(), daug[1].Pt()); + histos.get(HIST("EventTwoTracks/MuonPion/hDaughtersPhi"))->Fill(daug[0].Phi(), daug[1].Phi()); + histos.get(HIST("EventTwoTracks/MuonPion/hDaughtersRapidity"))->Fill(daug[0].Rapidity(), daug[1].Rapidity()); + if (mother.Pt() < 0.2) { + histos.get(HIST("EventTwoTracks/MuonPion/hInvariantMassWidePtCut"))->Fill(mother.M()); + } + } + if ((countPVGTelectrons == 1 && countPVGTmuons == 1) || (countPVGTelectrons == 1 && countPVGTpions == 1)) { + double electronPt = (enumMyParticle(trackPDG(trkDaug1)) == P_ELECTRON) ? daug[0].Pt() : daug[1].Pt(); + histos.get(HIST("EventTwoTracks/ElectronMuPi/hInvariantMass"))->Fill(mother.M()); + histos.get(HIST("EventTwoTracks/ElectronMuPi/hInvariantMassWide"))->Fill(mother.M()); + histos.get(HIST("EventTwoTracks/ElectronMuPi/hAcoplanarity"))->Fill(acoplanarity); + histos.get(HIST("EventTwoTracks/ElectronMuPi/hMotherP"))->Fill(mother.P()); + histos.get(HIST("EventTwoTracks/ElectronMuPi/hMotherPwide"))->Fill(mother.P()); + histos.get(HIST("EventTwoTracks/ElectronMuPi/hMotherPt"))->Fill(mother.Pt()); + histos.get(HIST("EventTwoTracks/ElectronMuPi/hMotherPhi"))->Fill(mother.Phi()); + histos.get(HIST("EventTwoTracks/ElectronMuPi/hMotherRapidity"))->Fill(mother.Rapidity()); + histos.get(HIST("EventTwoTracks/ElectronMuPi/hElectronPtWide"))->Fill(electronPt); + histos.get(HIST("EventTwoTracks/ElectronMuPi/hDaughtersP"))->Fill(daug[0].P(), daug[1].P()); + histos.get(HIST("EventTwoTracks/ElectronMuPi/hDaughtersPwide"))->Fill(daug[0].P(), daug[1].P()); + histos.get(HIST("EventTwoTracks/ElectronMuPi/hDaughtersPt"))->Fill(daug[0].Pt(), daug[1].Pt()); + histos.get(HIST("EventTwoTracks/ElectronMuPi/hDaughtersPhi"))->Fill(daug[0].Phi(), daug[1].Phi()); + histos.get(HIST("EventTwoTracks/ElectronMuPi/hDaughtersRapidity"))->Fill(daug[0].Rapidity(), daug[1].Rapidity()); + histos.get(HIST("EventTwoTracks/ElectronMuPi/hNeventsPtCuts"))->Fill(0); + if (mother.Pt() < 9.) + histos.get(HIST("EventTwoTracks/ElectronMuPi/hNeventsPtCuts"))->Fill(1); + if (mother.Pt() < 8.) + histos.get(HIST("EventTwoTracks/ElectronMuPi/hNeventsPtCuts"))->Fill(2); + if (mother.Pt() < 7.) + histos.get(HIST("EventTwoTracks/ElectronMuPi/hNeventsPtCuts"))->Fill(3); + if (mother.Pt() < 6.) + histos.get(HIST("EventTwoTracks/ElectronMuPi/hNeventsPtCuts"))->Fill(4); + if (mother.Pt() < 5.) + histos.get(HIST("EventTwoTracks/ElectronMuPi/hNeventsPtCuts"))->Fill(5); + if (mother.Pt() < 4.) + histos.get(HIST("EventTwoTracks/ElectronMuPi/hNeventsPtCuts"))->Fill(6); + if (mother.Pt() < 3.) + histos.get(HIST("EventTwoTracks/ElectronMuPi/hNeventsPtCuts"))->Fill(7); + if (mother.Pt() < 2.) + histos.get(HIST("EventTwoTracks/ElectronMuPi/hNeventsPtCuts"))->Fill(8); + if (mother.Pt() < 1.) + histos.get(HIST("EventTwoTracks/ElectronMuPi/hNeventsPtCuts"))->Fill(9); + if (electronPt > 0.1 && electronPt < 1.) + histos.get(HIST("EventTwoTracks/ElectronMuPi/hNeventsPtCuts"))->Fill(10); + if (electronPt > 1. && electronPt < 2.) + histos.get(HIST("EventTwoTracks/ElectronMuPi/hNeventsPtCuts"))->Fill(11); + if (electronPt > 2. && electronPt < 100.) + histos.get(HIST("EventTwoTracks/ElectronMuPi/hNeventsPtCuts"))->Fill(12); + } + if ((countPVGTelectrons == 2) || (countPVGTelectrons == 1 && countPVGTmuons == 1) || (countPVGTelectrons == 1 && countPVGTpions == 1)) { + double electronPt = (enumMyParticle(trackPDG(trkDaug1)) == P_ELECTRON) ? daug[0].Pt() : daug[1].Pt(); + if (countPVGTelectrons == 2) + electronPt = (daug[0].Pt() > daug[1].Pt()) ? daug[0].Pt() : daug[1].Pt(); + histos.get(HIST("EventTwoTracks/ElectronOther/hInvariantMass"))->Fill(mother.M()); + histos.get(HIST("EventTwoTracks/ElectronOther/hInvariantMassWide"))->Fill(mother.M()); + histos.get(HIST("EventTwoTracks/ElectronOther/hAcoplanarity"))->Fill(acoplanarity); + histos.get(HIST("EventTwoTracks/ElectronOther/hMotherP"))->Fill(mother.P()); + histos.get(HIST("EventTwoTracks/ElectronOther/hMotherPwide"))->Fill(mother.P()); + histos.get(HIST("EventTwoTracks/ElectronOther/hMotherPt"))->Fill(mother.Pt()); + histos.get(HIST("EventTwoTracks/ElectronOther/hMotherPhi"))->Fill(mother.Phi()); + histos.get(HIST("EventTwoTracks/ElectronOther/hMotherRapidity"))->Fill(mother.Rapidity()); + histos.get(HIST("EventTwoTracks/ElectronOther/hElectronPtWide"))->Fill(electronPt); + histos.get(HIST("EventTwoTracks/ElectronOther/hDaughtersP"))->Fill(daug[0].P(), daug[1].P()); + histos.get(HIST("EventTwoTracks/ElectronOther/hDaughtersPwide"))->Fill(daug[0].P(), daug[1].P()); + histos.get(HIST("EventTwoTracks/ElectronOther/hDaughtersPt"))->Fill(daug[0].Pt(), daug[1].Pt()); + histos.get(HIST("EventTwoTracks/ElectronOther/hDaughtersPhi"))->Fill(daug[0].Phi(), daug[1].Phi()); + histos.get(HIST("EventTwoTracks/ElectronOther/hDaughtersRapidity"))->Fill(daug[0].Rapidity(), daug[1].Rapidity()); + histos.get(HIST("EventTwoTracks/ElectronOther/hNeventsPtCuts"))->Fill(0); + if (mother.Pt() < 9.) + histos.get(HIST("EventTwoTracks/ElectronOther/hNeventsPtCuts"))->Fill(1); + if (mother.Pt() < 8.) + histos.get(HIST("EventTwoTracks/ElectronOther/hNeventsPtCuts"))->Fill(2); + if (mother.Pt() < 7.) + histos.get(HIST("EventTwoTracks/ElectronOther/hNeventsPtCuts"))->Fill(3); + if (mother.Pt() < 6.) + histos.get(HIST("EventTwoTracks/ElectronOther/hNeventsPtCuts"))->Fill(4); + if (mother.Pt() < 5.) + histos.get(HIST("EventTwoTracks/ElectronOther/hNeventsPtCuts"))->Fill(5); + if (mother.Pt() < 4.) + histos.get(HIST("EventTwoTracks/ElectronOther/hNeventsPtCuts"))->Fill(6); + if (mother.Pt() < 3.) + histos.get(HIST("EventTwoTracks/ElectronOther/hNeventsPtCuts"))->Fill(7); + if (mother.Pt() < 2.) + histos.get(HIST("EventTwoTracks/ElectronOther/hNeventsPtCuts"))->Fill(8); + if (mother.Pt() < 1.) + histos.get(HIST("EventTwoTracks/ElectronOther/hNeventsPtCuts"))->Fill(9); + if (electronPt > 0.1 && electronPt < 1.) + histos.get(HIST("EventTwoTracks/ElectronOther/hNeventsPtCuts"))->Fill(10); + if (electronPt > 1. && electronPt < 2.) + histos.get(HIST("EventTwoTracks/ElectronOther/hNeventsPtCuts"))->Fill(11); + if (electronPt > 2. && electronPt < 100.) + histos.get(HIST("EventTwoTracks/ElectronOther/hNeventsPtCuts"))->Fill(12); + } + if (countPVGTpionsSelection == 2) { + histos.get(HIST("EventTwoTracks/PionsSelection/hInvariantMass"))->Fill(motherOfPions.M()); + histos.get(HIST("EventTwoTracks/PionsSelection/hInvariantMassWide"))->Fill(motherOfPions.M()); + histos.get(HIST("EventTwoTracks/PionsSelection/hAcoplanarity"))->Fill(acoplanarity); + histos.get(HIST("EventTwoTracks/PionsSelection/hMotherP"))->Fill(motherOfPions.P()); + histos.get(HIST("EventTwoTracks/PionsSelection/hMotherPwide"))->Fill(motherOfPions.P()); + histos.get(HIST("EventTwoTracks/PionsSelection/hMotherPt"))->Fill(motherOfPions.Pt()); + histos.get(HIST("EventTwoTracks/PionsSelection/hMotherPhi"))->Fill(motherOfPions.Phi()); + histos.get(HIST("EventTwoTracks/PionsSelection/hMotherRapidity"))->Fill(motherOfPions.Rapidity()); + histos.get(HIST("EventTwoTracks/PionsSelection/hDaughtersP"))->Fill(pion[0].P(), pion[1].P()); + histos.get(HIST("EventTwoTracks/PionsSelection/hDaughtersPwide"))->Fill(pion[0].P(), pion[1].P()); + histos.get(HIST("EventTwoTracks/PionsSelection/hDaughtersPt"))->Fill(pion[0].Pt(), pion[1].Pt()); + histos.get(HIST("EventTwoTracks/PionsSelection/hDaughtersPhi"))->Fill(pion[0].Phi(), pion[1].Phi()); + histos.get(HIST("EventTwoTracks/PionsSelection/hDaughtersRapidity"))->Fill(pion[0].Rapidity(), pion[1].Rapidity()); + if (motherOfPions.Pt() < 0.2) { + histos.get(HIST("EventTwoTracks/PionsSelection/hInvariantMassPtCut"))->Fill(motherOfPions.M()); + histos.get(HIST("EventTwoTracks/PionsSelection/hInvariantMassWidePtCut"))->Fill(motherOfPions.M()); + if (sign < 0) + histos.get(HIST("EventTwoTracks/PionsSelection/hInvariantMassWidePtCutUS"))->Fill(motherOfPions.M()); + if (sign > 0) + histos.get(HIST("EventTwoTracks/PionsSelection/hInvariantMassWidePtCutLS"))->Fill(motherOfPions.M()); + } + } + } else if (countPVGTselected == 4) { + + TLorentzVector mother, daug[4]; + const auto& trkDaug1 = reconstructedBarrelTracks.iteratorAt(vecPVidx[0]); + const auto& trkDaug2 = reconstructedBarrelTracks.iteratorAt(vecPVidx[1]); + const auto& trkDaug3 = reconstructedBarrelTracks.iteratorAt(vecPVidx[2]); + const auto& trkDaug4 = reconstructedBarrelTracks.iteratorAt(vecPVidx[3]); + daug[0].SetPxPyPzE(trkDaug1.px(), trkDaug1.py(), trkDaug1.pz(), energy(pdg->Mass(trackPDG(trkDaug1)), trkDaug1.px(), trkDaug1.py(), trkDaug1.pz())); + daug[1].SetPxPyPzE(trkDaug2.px(), trkDaug2.py(), trkDaug2.pz(), energy(pdg->Mass(trackPDG(trkDaug2)), trkDaug2.px(), trkDaug2.py(), trkDaug2.pz())); + daug[2].SetPxPyPzE(trkDaug3.px(), trkDaug3.py(), trkDaug3.pz(), energy(pdg->Mass(trackPDG(trkDaug3)), trkDaug3.px(), trkDaug3.py(), trkDaug3.pz())); + daug[3].SetPxPyPzE(trkDaug4.px(), trkDaug4.py(), trkDaug4.pz(), energy(pdg->Mass(trackPDG(trkDaug4)), trkDaug4.px(), trkDaug4.py(), trkDaug4.pz())); + mother = daug[0] + daug[1] + daug[2] + daug[3]; + + if (trkDaug1.hasTPC()) { + histosPID.get(HIST("EventFourTracks/PID/hTPCsignalVsP"))->Fill(daug[0].P(), trkDaug1.tpcSignal()); + if (countPVGTpions == 4) + histosPID.get(HIST("EventFourTracks/WithPion/PID/hTPCsignalVsP"))->Fill(daug[0].P(), trkDaug1.tpcSignal()); + if (countPVGTelectrons == 1 && countPVGTpions == 3) + histosPID.get(HIST("EventFourTracks/WithElectron/PID/hTPCsignalVsP"))->Fill(daug[0].P(), trkDaug1.tpcSignal()); + if (countPVGTpions == 3 && countPVGTmuons == 1) + histosPID.get(HIST("EventFourTracks/WithMuon/PID/hTPCsignalVsP"))->Fill(daug[0].P(), trkDaug1.tpcSignal()); + } + if (trkDaug2.hasTPC()) { + histosPID.get(HIST("EventFourTracks/PID/hTPCsignalVsP"))->Fill(daug[1].P(), trkDaug2.tpcSignal()); + if (countPVGTpions == 4) + histosPID.get(HIST("EventFourTracks/WithPion/PID/hTPCsignalVsP"))->Fill(daug[1].P(), trkDaug2.tpcSignal()); + if (countPVGTelectrons == 1 && countPVGTpions == 3) + histosPID.get(HIST("EventFourTracks/WithElectron/PID/hTPCsignalVsP"))->Fill(daug[1].P(), trkDaug2.tpcSignal()); + if (countPVGTpions == 3 && countPVGTmuons == 1) + histosPID.get(HIST("EventFourTracks/WithMuon/PID/hTPCsignalVsP"))->Fill(daug[1].P(), trkDaug2.tpcSignal()); + } + if (trkDaug3.hasTPC()) { + histosPID.get(HIST("EventFourTracks/PID/hTPCsignalVsP"))->Fill(daug[2].P(), trkDaug3.tpcSignal()); + if (countPVGTpions == 4) + histosPID.get(HIST("EventFourTracks/WithPion/PID/hTPCsignalVsP"))->Fill(daug[2].P(), trkDaug3.tpcSignal()); + if (countPVGTelectrons == 1 && countPVGTpions == 3) + histosPID.get(HIST("EventFourTracks/WithElectron/PID/hTPCsignalVsP"))->Fill(daug[2].P(), trkDaug3.tpcSignal()); + if (countPVGTpions == 3 && countPVGTmuons == 1) + histosPID.get(HIST("EventFourTracks/WithMuon/PID/hTPCsignalVsP"))->Fill(daug[2].P(), trkDaug3.tpcSignal()); + } + if (trkDaug4.hasTPC()) { + histosPID.get(HIST("EventFourTracks/PID/hTPCsignalVsP"))->Fill(daug[3].P(), trkDaug4.tpcSignal()); + if (countPVGTpions == 4) + histosPID.get(HIST("EventFourTracks/WithPion/PID/hTPCsignalVsP"))->Fill(daug[3].P(), trkDaug4.tpcSignal()); + if (countPVGTelectrons == 1 && countPVGTpions == 3) + histosPID.get(HIST("EventFourTracks/WithElectron/PID/hTPCsignalVsP"))->Fill(daug[3].P(), trkDaug4.tpcSignal()); + if (countPVGTpions == 3 && countPVGTmuons == 1) + histosPID.get(HIST("EventFourTracks/WithMuon/PID/hTPCsignalVsP"))->Fill(daug[3].P(), trkDaug4.tpcSignal()); + } + + histos.get(HIST("EventFourTracks/hInvariantMass"))->Fill(mother.M()); + histos.get(HIST("EventFourTracks/hInvariantMassWide"))->Fill(mother.M()); + histos.get(HIST("EventFourTracks/hMotherP"))->Fill(mother.P()); + histos.get(HIST("EventFourTracks/hMotherPwide"))->Fill(mother.P()); + histos.get(HIST("EventFourTracks/hMotherPt"))->Fill(mother.Pt()); + histos.get(HIST("EventFourTracks/hMotherPhi"))->Fill(mother.Phi()); + histos.get(HIST("EventFourTracks/hMotherRapidity"))->Fill(mother.Rapidity()); + + // ee, mm, em, pp, ep, mp, pppp, eppp, mppp, pppppp + if (countPVGTpions == 4) { + histos.get(HIST("Events/hChannelsRatio"))->Fill(6); + histos.get(HIST("EventFourTracks/WithPion/hInvariantMass"))->Fill(mother.M()); + histos.get(HIST("EventFourTracks/WithPion/hInvariantMassWide"))->Fill(mother.M()); + histos.get(HIST("EventFourTracks/WithPion/hMotherP"))->Fill(mother.P()); + histos.get(HIST("EventFourTracks/WithPion/hMotherPwide"))->Fill(mother.P()); + histos.get(HIST("EventFourTracks/WithPion/hMotherPt"))->Fill(mother.Pt()); + histos.get(HIST("EventFourTracks/WithPion/hMotherPhi"))->Fill(mother.Phi()); + histos.get(HIST("EventFourTracks/WithPion/hMotherRapidity"))->Fill(mother.Rapidity()); + } + if (countPVGTelectrons == 1 && countPVGTpions == 3) { + histos.get(HIST("Events/hChannelsRatio"))->Fill(7); + histos.get(HIST("EventFourTracks/WithElectron/hInvariantMass"))->Fill(mother.M()); + histos.get(HIST("EventFourTracks/WithElectron/hInvariantMassWide"))->Fill(mother.M()); + histos.get(HIST("EventFourTracks/WithElectron/hMotherP"))->Fill(mother.P()); + histos.get(HIST("EventFourTracks/WithElectron/hMotherPwide"))->Fill(mother.P()); + histos.get(HIST("EventFourTracks/WithElectron/hMotherPt"))->Fill(mother.Pt()); + histos.get(HIST("EventFourTracks/WithElectron/hMotherPhi"))->Fill(mother.Phi()); + histos.get(HIST("EventFourTracks/WithElectron/hMotherRapidity"))->Fill(mother.Rapidity()); + } + if (countPVGTpions == 3 && countPVGTmuons == 1) { + histos.get(HIST("Events/hChannelsRatio"))->Fill(8); + histos.get(HIST("EventFourTracks/WithMuon/hInvariantMass"))->Fill(mother.M()); + histos.get(HIST("EventFourTracks/WithMuon/hInvariantMassWide"))->Fill(mother.M()); + histos.get(HIST("EventFourTracks/WithMuon/hMotherP"))->Fill(mother.P()); + histos.get(HIST("EventFourTracks/WithMuon/hMotherPwide"))->Fill(mother.P()); + histos.get(HIST("EventFourTracks/WithMuon/hMotherPt"))->Fill(mother.Pt()); + histos.get(HIST("EventFourTracks/WithMuon/hMotherPhi"))->Fill(mother.Phi()); + histos.get(HIST("EventFourTracks/WithMuon/hMotherRapidity"))->Fill(mother.Rapidity()); + } + } else if (countPVGTselected == 6) { + TLorentzVector mother, daug[6]; + const auto& trkDaug1 = reconstructedBarrelTracks.iteratorAt(vecPVidx[0]); + const auto& trkDaug2 = reconstructedBarrelTracks.iteratorAt(vecPVidx[1]); + const auto& trkDaug3 = reconstructedBarrelTracks.iteratorAt(vecPVidx[2]); + const auto& trkDaug4 = reconstructedBarrelTracks.iteratorAt(vecPVidx[3]); + const auto& trkDaug5 = reconstructedBarrelTracks.iteratorAt(vecPVidx[4]); + const auto& trkDaug6 = reconstructedBarrelTracks.iteratorAt(vecPVidx[5]); + daug[0].SetPxPyPzE(trkDaug1.px(), trkDaug1.py(), trkDaug1.pz(), energy(pdg->Mass(trackPDG(trkDaug1)), trkDaug1.px(), trkDaug1.py(), trkDaug1.pz())); + daug[1].SetPxPyPzE(trkDaug2.px(), trkDaug2.py(), trkDaug2.pz(), energy(pdg->Mass(trackPDG(trkDaug2)), trkDaug2.px(), trkDaug2.py(), trkDaug2.pz())); + daug[2].SetPxPyPzE(trkDaug3.px(), trkDaug3.py(), trkDaug3.pz(), energy(pdg->Mass(trackPDG(trkDaug3)), trkDaug3.px(), trkDaug3.py(), trkDaug3.pz())); + daug[3].SetPxPyPzE(trkDaug4.px(), trkDaug4.py(), trkDaug4.pz(), energy(pdg->Mass(trackPDG(trkDaug4)), trkDaug4.px(), trkDaug4.py(), trkDaug4.pz())); + daug[4].SetPxPyPzE(trkDaug5.px(), trkDaug5.py(), trkDaug5.pz(), energy(pdg->Mass(trackPDG(trkDaug5)), trkDaug5.px(), trkDaug5.py(), trkDaug5.pz())); + daug[5].SetPxPyPzE(trkDaug6.px(), trkDaug6.py(), trkDaug6.pz(), energy(pdg->Mass(trackPDG(trkDaug6)), trkDaug6.px(), trkDaug6.py(), trkDaug6.pz())); + mother = daug[0] + daug[1] + daug[2] + daug[3] + daug[4] + daug[5]; + + if (trkDaug1.hasTPC()) { + histosPID.get(HIST("EventSixTracks/PID/hTPCsignalVsP"))->Fill(daug[0].P(), trkDaug1.tpcSignal()); + if (countPVGTpions == 6) + histosPID.get(HIST("EventSixTracks/SixPions/PID/hTPCsignalVsP"))->Fill(daug[0].P(), trkDaug1.tpcSignal()); + } + if (trkDaug2.hasTPC()) { + histosPID.get(HIST("EventSixTracks/PID/hTPCsignalVsP"))->Fill(daug[1].P(), trkDaug2.tpcSignal()); + if (countPVGTpions == 6) + histosPID.get(HIST("EventSixTracks/SixPions/PID/hTPCsignalVsP"))->Fill(daug[1].P(), trkDaug2.tpcSignal()); + } + if (trkDaug3.hasTPC()) { + histosPID.get(HIST("EventSixTracks/PID/hTPCsignalVsP"))->Fill(daug[2].P(), trkDaug3.tpcSignal()); + if (countPVGTpions == 6) + histosPID.get(HIST("EventSixTracks/SixPions/PID/hTPCsignalVsP"))->Fill(daug[2].P(), trkDaug3.tpcSignal()); + } + if (trkDaug4.hasTPC()) { + histosPID.get(HIST("EventSixTracks/PID/hTPCsignalVsP"))->Fill(daug[3].P(), trkDaug4.tpcSignal()); + if (countPVGTpions == 6) + histosPID.get(HIST("EventSixTracks/SixPions/PID/hTPCsignalVsP"))->Fill(daug[3].P(), trkDaug4.tpcSignal()); + } + if (trkDaug5.hasTPC()) { + histosPID.get(HIST("EventSixTracks/PID/hTPCsignalVsP"))->Fill(daug[4].P(), trkDaug5.tpcSignal()); + if (countPVGTpions == 6) + histosPID.get(HIST("EventSixTracks/SixPions/PID/hTPCsignalVsP"))->Fill(daug[4].P(), trkDaug5.tpcSignal()); + } + if (trkDaug6.hasTPC()) { + histosPID.get(HIST("EventSixTracks/PID/hTPCsignalVsP"))->Fill(daug[5].P(), trkDaug6.tpcSignal()); + if (countPVGTpions == 6) + histosPID.get(HIST("EventSixTracks/SixPions/PID/hTPCsignalVsP"))->Fill(daug[5].P(), trkDaug6.tpcSignal()); + } + + histos.get(HIST("EventSixTracks/hInvariantMass"))->Fill(mother.M()); + histos.get(HIST("EventSixTracks/hInvariantMassWide"))->Fill(mother.M()); + histos.get(HIST("EventSixTracks/hMotherP"))->Fill(mother.P()); + histos.get(HIST("EventSixTracks/hMotherPwide"))->Fill(mother.P()); + histos.get(HIST("EventSixTracks/hMotherPt"))->Fill(mother.Pt()); + histos.get(HIST("EventSixTracks/hMotherPhi"))->Fill(mother.Phi()); + histos.get(HIST("EventSixTracks/hMotherRapidity"))->Fill(mother.Rapidity()); + + // ee, mm, em, pp, ep, mp, pppp, eppp, mppp, pppppp + if (countPVGTpions == 6) { + histos.get(HIST("Events/hChannelsRatio"))->Fill(9); + histos.get(HIST("EventSixTracks/SixPions/hInvariantMass"))->Fill(mother.M()); + histos.get(HIST("EventSixTracks/SixPions/hInvariantMassWide"))->Fill(mother.M()); + histos.get(HIST("EventSixTracks/SixPions/hMotherP"))->Fill(mother.P()); + histos.get(HIST("EventSixTracks/SixPions/hMotherPwide"))->Fill(mother.P()); + histos.get(HIST("EventSixTracks/SixPions/hMotherPt"))->Fill(mother.Pt()); + histos.get(HIST("EventSixTracks/SixPions/hMotherPhi"))->Fill(mother.Phi()); + histos.get(HIST("EventSixTracks/SixPions/hMotherRapidity"))->Fill(mother.Rapidity()); + } + } else { + if (verboseDebug) { + printMediumMessage("Other particles"); + } + } + + } // end fillHistograms + + void processDGrecoLevel(FullUDCollision const& reconstructedCollision, + FullUDTracks const& reconstructedBarrelTracks) + { + countCollisions++; + + fillHistograms(reconstructedCollision, reconstructedBarrelTracks); + + } // end processDGrecoLevel + + void processSGrecoLevel(FullSGUDCollision const& reconstructedCollision, + FullUDTracks const& reconstructedBarrelTracks) + { + countCollisions++; + + if (reconstructedCollision.gapSide() == 0) + histos.get(HIST("Events/hCountCollisions"))->Fill(1); + if (reconstructedCollision.gapSide() == 1) + histos.get(HIST("Events/hCountCollisions"))->Fill(2); + if (reconstructedCollision.gapSide() == 2) + histos.get(HIST("Events/hCountCollisions"))->Fill(3); + if (reconstructedCollision.gapSide() != whichGapSide) + return; + + fillHistograms(reconstructedCollision, reconstructedBarrelTracks); + + } // end processDGrecoLevel + + void processAnalysisFinished(FullUDCollision const& collisions) + { + + if (verboseInfo) + LOGF(info, "####################################### END OF THIS DATAFRAME #######################################"); + if (verboseDebug) + LOGF(info, "countCollisions = %d"); + isFirstReconstructedCollisions = true; + + } // end processAnalysisFinished + + PROCESS_SWITCH(UpcTauCentralBarrelRL, processDGrecoLevel, "Iterate UD tables with reconstructed data created by DG-Candidate-Producer", false); + PROCESS_SWITCH(UpcTauCentralBarrelRL, processSGrecoLevel, "Iterate UD tables with reconstructed data created by SG-Candidate-Producer", false); + PROCESS_SWITCH(UpcTauCentralBarrelRL, processAnalysisFinished, "Simply runs in the end of the dataframe", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc, TaskName{"upc-tau-rl"})}; +} diff --git a/PWGUD/Tasks/upcTauTau13topo.cxx b/PWGUD/Tasks/upcTauTau13topo.cxx new file mode 100644 index 00000000000..7638350bc61 --- /dev/null +++ b/PWGUD/Tasks/upcTauTau13topo.cxx @@ -0,0 +1,576 @@ +// 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 tau tau analysis 1e+3pi topology +// \author Adam Matyja, adam.tomasz.matyja@cern.ch, adam.matryja@ifj.edu.pl +// \since January 2024 +// to run it execute: +// copts="--configuration json://tautauConfig.json -b" +// o2-analysis-ud-tautau13topo $copts > output.log + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" + +#include "TDatabasePDG.h" +#include "TLorentzVector.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" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +struct TauTau13topo { + + // configurables + ConfigurableAxis ptAxis{"pAxis", {100, 0., 5.}, "#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., 2.5}, "M_{inv} (GeV/#it{c}^{2})"}; + ConfigurableAxis phiAxis{"phiAxis", {100, 0., 3.2}, "#phi"}; + ConfigurableAxis vectorAxis{"vectorAxis", {100, 0., 2.}, "A_{V}"}; + ConfigurableAxis scalarAxis{"scalarAxis", {100, -1., 1.}, "A_{S}"}; + Configurable verbose{"Verbose", {}, "Additional print outs"}; + + // cut selection configurables + Configurable zvertexcut{"Zvertexcut", 15, "Z vertex cut"}; + Configurable trkEtacut{"TrkEtacut", 15, "max track eta cut"}; + Configurable minAnglecut{"minAnglecut", 0.05, "min angle between tracks cut"}; + Configurable minNsigmaElcut{"minNsigmaElcut", -2, "min Nsigma for Electrons cut"}; + Configurable maxNsigmaElcut{"maxNsigmaElcut", 3, "max Nsigma for Electrons cut"}; + Configurable maxNsigmaPiVetocut{"maxNsigmaPiVetocut", 4, "max Nsigma for Pion veto cut"}; + Configurable minPtEtrkcut{"minPtEtrkcut", 0.25, "min Pt for El track cut"}; + Configurable FITvetoFlag{"FITvetoFlag", {}, "To apply FIT veto"}; + Configurable FITvetoWindow{"FITvetoWindow", 1, "FIT veto window"}; + // a pdg object + TDatabasePDG* pdg = nullptr; + + // initialize histogram registry + HistogramRegistry registry{ + "registry", + {}}; + + void init(InitContext&) + { + pdg = TDatabasePDG::Instance(); + + // dgcandidates histograms + const AxisSpec axispt{ptAxis, "p_{T} axis"}; + const AxisSpec axiseta{etaAxis, "#eta - pseudo rapidity axis"}; + const AxisSpec axisdedx{dedxAxis, "dEdx axis"}; + const AxisSpec axisminv{minvAxis, "invariant mass axis"}; + const AxisSpec axisphi{phiAxis, "phi axis"}; + const AxisSpec axisav{vectorAxis, "AV axis"}; + const AxisSpec axisas{scalarAxis, "AS axis"}; + + registry.add("global/hVertexXY", "Vertex position in x and y direction; V_x; V_y; Collisions", {HistType::kTH2F, {{50, -0.05, 0.05}, {50, -0.05, 0.05}}}); + registry.add("global/hVertexZ", "Vertex position in z direction; V_z; Collisions", {HistType::kTH1F, {{100, -25., 25.}}}); + registry.add("global/hVertexZ15", "Vertex position in z direction; V_z; Collisions", {HistType::kTH1F, {{100, -25., 25.}}}); + registry.add("global/hVertexZ10", "Vertex position in z direction; V_z; Collisions", {HistType::kTH1F, {{100, -25., 25.}}}); + registry.add("global/hNTracks", ";N_{tracks};events", {HistType::kTH1D, {{20, 0., 20.}}}); + registry.add("global/hNTracksGlobal", ";N_{tracks,global};events", {HistType::kTH1D, {{20, 0., 20.}}}); + registry.add("global/hNTracksPV", ";N_{tracks,PV};events", {HistType::kTH1D, {{20, 0., 20.}}}); + registry.add("global/hNtofTrk", ";N_{TOF trk}; Entries", {HistType::kTH1F, {{5, 0., 5.}}}); + registry.add("global/hTrackPtPV", ";p_T^{trk}; Entries", {HistType::kTH1F, {axispt}}); + registry.add("global/hTrackPVTotCharge", "Q_{Tot};Q_{Tot}; Entries", {HistType::kTH1F, {{10, -5, 5}}}); + registry.add("global/hTrackEtaPhiPV", ";Eta;Phi;", {HistType::kTH2D, {axiseta, {140, -3.5, 3.5}}}); + registry.add("global/hSignalTPCvsPtPV", ";Pt;TPC Signal", {HistType::kTH2F, {axispt, {200, 0., 200}}}); + registry.add("global/hITSbitPVtrk", "ITS bit for PV tracks; Layer hit;Entries", {HistType::kTH1F, {{10, 0., 10.}}}); + registry.add("global/hITSnbitsVsEtaPVtrk", "n ITS bits vs #eta for PV tracks; #eta;Layer hit;Entries", {HistType::kTH2F, {axiseta, {8, -1., 7.}}}); + registry.add("global/hITSbitVsEtaPVtrk", "ITS bit vs #eta for PV tracks; #eta;Layer hit;Entries", {HistType::kTH2F, {axiseta, {8, 0., 8.}}}); + registry.add("global/hEventEff", "Event cut efficiency: 0-All,1-PV=4,2-Qtot=0,3-El;Cut;entries", {HistType::kTH1F, {{25, 0., 25.}}}); + registry.add("global/hNCombAfterCut", "Combinations after cut: 0-All,5-M3pi,10-Dphi,15-N_{e},20-N_{v#pi},25-Pt,30-Vcal,35-Tot;N_{comb};entries", {HistType::kTH1F, {{40, 0., 40.}}}); + // registry.add("global/hInvMassElTrack", ";M_{inv}^{2};entries", {HistType::kTH1F, {{100, -0.01, 0.49}}}); + registry.add("global/hDeltaAngleTrackPV", ";#Delta#alpha;entries", {HistType::kTH1F, {{100, -0.01, 0.49}}}); + + // cut0 + registry.add("control/h0Cut3piMassComb", "3#pi mass, 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});entries", {HistType::kTH1F, {minvAxis}}); + registry.add("control/h0Cut3trkPtTot", ";p_{T} (GeV/c);entries", {HistType::kTH1F, {ptAxis}}); + registry.add("control/h0CutDeltaPhi13topo", "#Delta #varphi 1+3 topo, 4 entries/event;#Delta#varphi^{1+3};entries", {HistType::kTH1F, {phiAxis}}); + registry.add("control/h0Cut13AssymPt1ProngAver", ";Delta Pt/Sum Pt (1Prong,Aver Pt)", {HistType::kTH1F, {{100, -1., 1.}}}); + registry.add("control/h0Cut13Vector", ";A_{V};entries", {HistType::kTH1F, {vectorAxis}}); + registry.add("control/h0Cut13Scalar", ";A_{S};entries", {HistType::kTH1F, {scalarAxis}}); + registry.add("control/h0Cut13EtaSum", ";#eta^{1-prong}+#eta^{3-prong};entries", {HistType::kTH1F, {{100, -4., 4.}}}); + registry.add("control/h0Cut4trkPtTot", ";p_{T} (GeV/c);entries", {HistType::kTH1F, {axispt}}); + registry.add("control/h0Cut4piMass", "4#pi mass;M_{inv}^{4#pi} (GeV/c^{2});entries", {HistType::kTH1F, {{100, 0., 10.}}}); + registry.add("control/h0Cut3piMassVsPt", "3#pi mass vs Pt, 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});p_{T}^{3#pi} (GeV/c);entries", {HistType::kTH2F, {minvAxis, axispt}}); + registry.add("control/h0Cut4trkMassVsPt", "4-track mass vs Pt;M_{inv}^{4track} (GeV/c^{2});p_{T}^{4track} (GeV/c);entries", {HistType::kTH2F, {{100, 1, 5.}, axispt}}); + // cut1 + registry.add("control/h1Cut3piMassComb", "3#pi mass, 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});entries", {HistType::kTH1F, {minvAxis}}); + registry.add("control/h1Cut3trkPtTot", ";p_{T} (GeV/c);entries", {HistType::kTH1F, {ptAxis}}); + registry.add("control/h1CutDeltaPhi13topo", "#Delta #varphi 1+3 topo, 4 entries/event;#Delta#varphi^{1+3};entries", {HistType::kTH1F, {phiAxis}}); + registry.add("control/h1Cut13AssymPt1ProngAver", ";Delta Pt/Sum Pt (1Prong,Aver Pt)", {HistType::kTH1F, {{100, -1., 1.}}}); + registry.add("control/h1Cut13Vector", ";A_{V};entries", {HistType::kTH1F, {vectorAxis}}); + registry.add("control/h1Cut13Scalar", ";A_{S};entries", {HistType::kTH1F, {scalarAxis}}); + registry.add("control/h1Cut13EtaSum", ";#eta^{1-prong}+#eta^{3-prong};entries", {HistType::kTH1F, {{100, -4., 4.}}}); + registry.add("control/h1Cut4trkPtTot", ";p_{T} (GeV/c);entries", {HistType::kTH1F, {axispt}}); + registry.add("control/h1Cut4piMass", "4#pi mass;M_{inv}^{4#pi} (GeV/c^{2});entries", {HistType::kTH1F, {{100, 0., 10.}}}); + registry.add("control/h1Cut3piMassVsPt", "3#pi mass vs Pt, 4 entries per event ;M_{inv}^{3#pi} (GeV/c^{2});p_{T}^{3#pi} (GeV/c);entries", {HistType::kTH2F, {minvAxis, axispt}}); + registry.add("control/h1Cut4trkMassVsPt", "4-track mass vs Pt;M_{inv}^{4track} (GeV/c^{2});p_{T}^{4track} (GeV/c);entries", {HistType::kTH2F, {{100, 1, 5.}, axispt}}); + registry.add("control/h1CutDcaZ", "All 4 tracks dca ;dca_{Z};entries", {HistType::kTH1F, {{100, -0.05, 0.05}}}); + registry.add("control/h1CutDcaXY", "All 4 tracks dca ;dca_{XY};entries", {HistType::kTH1F, {{100, -0.05, 0.05}}}); + registry.add("control/h1CutChi2TPC", "All 4 tracks Chi2 ;Chi2_{TPC};entries", {HistType::kTH1F, {{48, -2, 10.}}}); + registry.add("control/h1CutChi2ITS", "All 4 tracks Chi2 ;Chi2_{ITS};entries", {HistType::kTH1F, {{44, -2, 20.}}}); + registry.add("control/h1CutTPCnclsFindable", "All 4 tracks NclFind ;N_{TPC,cl,findable};entries", {HistType::kTH1F, {{160, 0, 160.}}}); + + // pid + registry.add("pidTPC/hpvsdedxElHipCut0", "In hip;p_{trk};dEdx_{trk}", {HistType::kTH2F, {ptAxis, dedxAxis}}); + registry.add("pidTPC/hpvsdedxElHipCut1", "All hip;p_{trk};dEdx_{trk}", {HistType::kTH2F, {ptAxis, dedxAxis}}); + // pid separately for each cut + registry.add("pidTPC/hpvsdedxElHipCut2", "IM hip;p_{trk};dEdx_{trk}", {HistType::kTH2F, {ptAxis, dedxAxis}}); + registry.add("pidTPC/hpvsdedxElHipCut3", "DP hip;p_{trk};dEdx_{trk}", {HistType::kTH2F, {ptAxis, dedxAxis}}); + registry.add("pidTPC/hpvsdedxElHipCut4", "El hip;p_{trk};dEdx_{trk}", {HistType::kTH2F, {ptAxis, dedxAxis}}); + registry.add("pidTPC/hpvsdedxElHipCut5", "Pi hip;p_{trk};dEdx_{trk}", {HistType::kTH2F, {ptAxis, dedxAxis}}); + registry.add("pidTPC/hpvsdedxElHipCut6", "Pt hip;p_{trk};dEdx_{trk}", {HistType::kTH2F, {ptAxis, dedxAxis}}); + registry.add("pidTPC/hpvsdedxElHipCut7", "Vc hip;p_{trk};dEdx_{trk}", {HistType::kTH2F, {ptAxis, dedxAxis}}); + // pid sequentialy + registry.add("pidTPC/hpvsdedxElHipCut10", "El hip;p_{trk};dEdx_{trk}", {HistType::kTH2F, {ptAxis, dedxAxis}}); + registry.add("pidTPC/hpvsdedxElHipCut11", "Pi+10 hip;p_{trk};dEdx_{trk}", {HistType::kTH2F, {ptAxis, dedxAxis}}); + registry.add("pidTPC/hpvsdedxElHipCut12", "Vc+11 hip;p_{trk};dEdx_{trk}", {HistType::kTH2F, {ptAxis, dedxAxis}}); + registry.add("pidTPC/hpvsdedxElHipCut13", "Pt+12 hip;p_{trk};dEdx_{trk}", {HistType::kTH2F, {ptAxis, dedxAxis}}); + // final electron spectrum + registry.add("global/hFinalPtSpectrumEl", ";p_{T}^{e} (GeV/c);entries", {HistType::kTH1F, {{40, 0., 5.}}}); + // fit histos + registry.add("fit/bbFT0Abit", "FT0A bits;bit;entries", {HistType::kTH1F, {{32, 0., 32.}}}); + registry.add("fit/bbFT0Cbit", "FT0C bits;bit;entries", {HistType::kTH1F, {{32, 0., 32.}}}); + registry.add("fit/bbFV0Abit", "FV0A bits;bit;entries", {HistType::kTH1F, {{32, 0., 32.}}}); + registry.add("fit/bbFDDAbit", "FDDA bits;bit;entries", {HistType::kTH1F, {{32, 0., 32.}}}); + registry.add("fit/bbFDDCbit", "FDDC bits;bit;entries", {HistType::kTH1F, {{32, 0., 32.}}}); + registry.add("fit/bbFT0Aamplitude", "FT0A amplitude;Amplitude;entries", {HistType::kTH1F, {{100, -5., 95.}}}); + registry.add("fit/bbFT0Camplitude", "FT0C amplitude;Amplitude;entries", {HistType::kTH1F, {{100, -5., 95.}}}); + registry.add("fit/bbFV0Aamplitude", "FV0A amplitude;Amplitude;entries", {HistType::kTH1F, {{100, -5., 95.}}}); + registry.add("fit/bbFDDAamplitude", "FDDA amplitude;Amplitude;entries", {HistType::kTH1F, {{100, -5., 95.}}}); + registry.add("fit/bbFDDCamplitude", "FDDC amplitude;Amplitude;entries", {HistType::kTH1F, {{100, -5., 95.}}}); + registry.add("fit/timeFT0", "FT0 time;time FT0A; time FT0C;entries", {HistType::kTH2F, {{100, -5., 35.}, {100, -5., 35.}}}); + registry.add("fit/timeFDD", "FDD time;time FDDA; time FDDC;entries", {HistType::kTH2F, {{100, -5., 35.}, {100, -5., 35.}}}); + } + + float CalculateDeltaPhi(TLorentzVector p, TLorentzVector p1) + { + float delta = p.Phi(); + if (delta < 0) + delta += TMath::TwoPi(); + if (p1.Phi() < 0) + delta -= (p1.Phi() + TMath::TwoPi()); + else + delta -= p1.Phi(); + if (delta < 0) + delta += TMath::TwoPi(); + if (delta > TMath::Pi()) + delta = TMath::TwoPi() - delta; + return delta; + } + + // fill control histograms per track + template + void FillControlHistos(T pi3invMass, float pi3pt, float pi3deltaPhi, float pi3assymav, float pi3vector, float pi3scalar, float pi3etasum) + { + static constexpr std::string_view histoname[] = {"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"}; + registry.get(HIST("control/h") + HIST(histoname[mode]) + HIST("Cut3piMassComb"))->Fill(pi3invMass); + registry.get(HIST("control/h") + HIST(histoname[mode]) + HIST("Cut3trkPtTot"))->Fill(pi3pt); + registry.get(HIST("control/h") + HIST(histoname[mode]) + HIST("CutDeltaPhi13topo"))->Fill(pi3deltaPhi); + registry.get(HIST("control/h") + HIST(histoname[mode]) + HIST("Cut13AssymPt1ProngAver"))->Fill(pi3assymav); + registry.get(HIST("control/h") + HIST(histoname[mode]) + HIST("Cut13Vector"))->Fill(pi3vector); + registry.get(HIST("control/h") + HIST(histoname[mode]) + HIST("Cut13Scalar"))->Fill(pi3scalar); + registry.get(HIST("control/h") + HIST(histoname[mode]) + HIST("Cut13EtaSum"))->Fill(pi3etasum); + } + + using UDCollisionsFull = soa::Join; + using UDCollisionFull = UDCollisionsFull::iterator; + using UDTracksFull = soa::Join; + + void process(UDCollisionFull const& dgcand, UDTracksFull const& dgtracks) + { + // global checks + registry.get(HIST("global/hVertexXY"))->Fill(dgcand.posX(), dgcand.posY()); + registry.get(HIST("global/hVertexZ"))->Fill(dgcand.posZ()); + if (TMath::Abs(dgcand.posZ()) < 15) + registry.get(HIST("global/hVertexZ15"))->Fill(dgcand.posZ()); + if (TMath::Abs(dgcand.posZ()) < 10) + registry.get(HIST("global/hVertexZ10"))->Fill(dgcand.posZ()); + + registry.get(HIST("global/hNTracks"))->Fill(dgtracks.size()); + + // setup PV tracks partition + Partition PVContributors = aod::udtrack::isPVContributor == true; + PVContributors.bindTable(dgtracks); + + registry.get(HIST("global/hNTracksPV"))->Fill(PVContributors.size()); + + UChar_t clustermap1; + int nTofTrk = 0; + int nEtaIn15 = 0; + int nITSbits = 0; + TLorentzVector p; + TParticlePDG* pion = pdg->GetParticle(211); + // loop over PV contributors + for (auto trk : PVContributors) { + p.SetXYZM(trk.px(), trk.py(), trk.pz(), pion->Mass()); + registry.get(HIST("global/hTrackPtPV"))->Fill(p.Pt()); + if (TMath::Abs(p.Eta()) < trkEtacut) + nEtaIn15++; // 1.5 is a default + registry.get(HIST("global/hTrackEtaPhiPV"))->Fill(p.Eta(), p.Phi()); + nITSbits = -1; + if (trk.hasITS()) { // ITS track + clustermap1 = trk.itsClusterMap(); + for (int bitNo = 0; bitNo < 7; bitNo++) { + if (TESTBIT(clustermap1, bitNo)) { // check ITS bits/layers for each PV track + registry.get(HIST("global/hITSbitPVtrk"))->Fill(bitNo, 1.); + registry.get(HIST("global/hITSbitVsEtaPVtrk"))->Fill(p.Eta(), bitNo, 1.); + nITSbits++; + } + } // end of loop over ITS bits + } // has ITS + registry.get(HIST("global/hITSnbitsVsEtaPVtrk"))->Fill(p.Eta(), nITSbits); + if (trk.hasTPC()) + registry.get(HIST("global/hSignalTPCvsPtPV"))->Fill(p.Pt(), trk.tpcSignal()); + if (trk.hasTOF()) + nTofTrk++; + } + registry.get(HIST("global/hNtofTrk"))->Fill(nTofTrk); + + // + // selection + // + registry.get(HIST("global/hEventEff"))->Fill(0., 1.); + + // skip events with too few/many tracks + if (dgcand.numContrib() != 4) { + if (verbose) { + LOGF(info, " Candidate rejected: Number of PV contributors is %d", dgcand.numContrib()); + } + return; + } + registry.get(HIST("global/hEventEff"))->Fill(1., 1.); + registry.get(HIST("global/hTrackPVTotCharge"))->Fill(dgcand.netCharge()); + + // if vz < 15 + if (TMath::Abs(dgcand.posZ()) >= zvertexcut) { // default = 15 + if (verbose) { + LOGF(info, " Candidate rejected: VertexZ is %d", dgcand.posZ()); + } + return; + } + registry.get(HIST("global/hEventEff"))->Fill(2., 1.); + + // if eta tracks <1.5 + if (nEtaIn15 != 4) { + if (verbose) { + LOGF(info, " Candidate rejected: Ntrk inside |eta|<1.5 is %d", nEtaIn15); + } + return; + } + registry.get(HIST("global/hEventEff"))->Fill(3., 1.); + + // skip events with net charge != 0 + if (dgcand.netCharge() != 0) { + if (verbose) { + LOGF(info, " Candidate rejected: Net charge is %d", dgcand.netCharge()); + } + return; + } + registry.get(HIST("global/hEventEff"))->Fill(4., 1.); + + // // skip events with out-of-range rgtrwTOF (fraction-of-good-tracks-with-TOF-hit) + // auto rtrwTOF = udhelpers::rPVtrwTOF(dgtracks, PVContributors.size()); + // if (rtrwTOF < 0.25) { + // if (verbose) { + // LOGF(debug, " Candidate rejected: rtrwTOF is %f", rtrwTOF); + // } + // return; + // } + // + // FIT informaton + for (auto bit = 0; bit <= 32; bit++) { + registry.get(HIST("fit/bbFT0Abit"))->Fill(bit, TESTBIT(dgcand.bbFT0Apf(), bit)); + registry.get(HIST("fit/bbFT0Cbit"))->Fill(bit, TESTBIT(dgcand.bbFT0Cpf(), bit)); + registry.get(HIST("fit/bbFV0Abit"))->Fill(bit, TESTBIT(dgcand.bbFV0Apf(), bit)); + registry.get(HIST("fit/bbFDDAbit"))->Fill(bit, TESTBIT(dgcand.bbFDDApf(), bit)); + registry.get(HIST("fit/bbFDDCbit"))->Fill(bit, TESTBIT(dgcand.bbFDDCpf(), bit)); + } + registry.get(HIST("fit/bbFT0Aamplitude"))->Fill(dgcand.totalFT0AmplitudeA()); + registry.get(HIST("fit/bbFT0Camplitude"))->Fill(dgcand.totalFT0AmplitudeC()); + registry.get(HIST("fit/bbFV0Aamplitude"))->Fill(dgcand.totalFV0AmplitudeA()); + registry.get(HIST("fit/bbFDDAamplitude"))->Fill(dgcand.totalFDDAmplitudeA()); + registry.get(HIST("fit/bbFDDCamplitude"))->Fill(dgcand.totalFDDAmplitudeC()); + + registry.get(HIST("fit/timeFT0"))->Fill(dgcand.timeFT0A(), dgcand.timeFT0C()); + registry.get(HIST("fit/timeFDD"))->Fill(dgcand.timeFDDA(), dgcand.timeFDDC()); + + // check FIT information + // auto bitMin = -1 + 16; + // auto bitMax = 1 + 16; + // for (auto bit = bitMin; bit <= bitMax; bit++) { + // if (TESTBIT(dgcand.bbFT0Apf(), bit) || + // TESTBIT(dgcand.bbFT0Cpf(), bit) || + // TESTBIT(dgcand.bbFV0Apf(), bit) || + // TESTBIT(dgcand.bbFDDApf(), bit) || + // TESTBIT(dgcand.bbFDDCpf(), bit)) { + // return; + // } + // } + registry.get(HIST("global/hEventEff"))->Fill(5., 1.); + + // + // here PID from TPC starts to be + // + // temporary control variables per event with combinatorics + float tmpMomentum[4]; + float tmpPt[4]; + float tmpDedx[4]; + float pi3invMass[4]; + float pi3pt[4]; + float pi3deltaPhi[4]; + float pi3assymav[4]; + float pi3vector[4]; + float pi3scalar[4]; + float pi3etasum[4]; + float deltaPhiTmp = 0; + float scalarPtsum = 0; + float nSigmaEl[4]; + float nSigmaPi[4]; + float dcaZ[4]; + float dcaXY[4]; + float chi2TPC[4]; + float chi2ITS[4]; + float nclTPCfind[4]; + + // first loop to add all the tracks together + TLorentzVector p1; + p = TLorentzVector(0., 0., 0., 0.); + for (auto trk : PVContributors) { + p1.SetXYZM(trk.px(), trk.py(), trk.pz(), pion->Mass()); + p += p1; + scalarPtsum += trk.pt(); + } + float pttot = p.Pt(); + float mass4pi = p.Mag(); + + TVector3 v1(0, 0, 0); + TVector3 vtmp(0, 0, 0); + float deltaphi = 0; + // remove combinatoric + bool flagVcalPV[4] = {false, false, false, false}; + + // second loop to calculate 1 by 1 each combinatorial variable + int counterTmp = 0; + for (auto trk : PVContributors) { + v1.SetXYZ(trk.px(), trk.py(), trk.pz()); + for (auto trk1 : PVContributors) { + if (trk.index() == trk1.index()) + continue; + vtmp.SetXYZ(trk1.px(), trk1.py(), trk1.pz()); + deltaphi = v1.Angle(vtmp); + registry.get(HIST("global/hDeltaAngleTrackPV"))->Fill(deltaphi); + if (deltaphi < minAnglecut) { // default 0.05 + flagVcalPV[counterTmp] = true; + } + } + nSigmaEl[counterTmp] = trk.tpcNSigmaEl(); + nSigmaPi[counterTmp] = trk.tpcNSigmaPi(); + dcaZ[counterTmp] = trk.dcaZ(); + dcaXY[counterTmp] = trk.dcaXY(); + chi2TPC[counterTmp] = trk.tpcChi2NCl(); + chi2ITS[counterTmp] = trk.itsChi2NCl(); + nclTPCfind[counterTmp] = trk.tpcNClsFindable(); + + p1.SetXYZM(trk.px(), trk.py(), trk.pz(), pion->Mass()); + tmpMomentum[counterTmp] = p1.P(); + tmpPt[counterTmp] = p1.Pt(); + tmpDedx[counterTmp] = trk.tpcSignal(); + + deltaPhiTmp = CalculateDeltaPhi(p - p1, p1); + 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.); + pi3vector[counterTmp] = (p + p1).Pt() / (p - p1).Pt(); + pi3scalar[counterTmp] = (p.Pt() - p1.Pt()) / (p.Pt() + p1.Pt()); + pi3etasum[counterTmp] = (p - p1).Eta() + p1.Eta(); + + counterTmp++; + } + + // control histos, max 4 per event + for (int i = 0; i < 4; i++) { + FillControlHistos<0>(pi3invMass[i], pi3pt[i], pi3deltaPhi[i], pi3assymav[i], pi3vector[i], pi3scalar[i], pi3etasum[i]); + registry.get(HIST("control/h0Cut3piMassVsPt"))->Fill(pi3invMass[i], pi3pt[i]); + registry.get(HIST("pidTPC/hpvsdedxElHipCut0"))->Fill(tmpMomentum[i], tmpDedx[i]); + } + // control, 1 per event + registry.get(HIST("control/h0Cut4trkPtTot"))->Fill(pttot); + registry.get(HIST("control/h0Cut4piMass"))->Fill(mass4pi); + registry.get(HIST("control/h0Cut4trkMassVsPt"))->Fill(mass4pi, pttot); + + // remove combinatoric + bool flagTotal[4] = {false, false, false, false}; + bool flagIM[4] = {false, false, false, false}; + bool flagDP[4] = {false, false, false, false}; + bool flagEl[4] = {false, false, false, false}; + bool flagPi[4] = {false, false, false, false}; + bool flagPt[4] = {false, false, false, false}; + + // bool flagVcalPV[4]={false,false,false,false}; + // float deltaphi=0; + + for (int i = 0; i < 4; i++) { + if (pi3invMass[i] < 1.8) { + flagIM[i] = true; + registry.get(HIST("pidTPC/hpvsdedxElHipCut2"))->Fill(tmpMomentum[i], tmpDedx[i]); + } + if (pi3deltaPhi[i] > 1.6) { + flagDP[i] = true; + registry.get(HIST("pidTPC/hpvsdedxElHipCut3"))->Fill(tmpMomentum[i], tmpDedx[i]); + } + if (minNsigmaElcut < nSigmaEl[i] && nSigmaEl[i] < maxNsigmaElcut) { // default (-2,3) + flagEl[i] = true; + registry.get(HIST("pidTPC/hpvsdedxElHipCut4"))->Fill(tmpMomentum[i], tmpDedx[i]); + } + if (TMath::Abs(nSigmaPi[i]) > maxNsigmaPiVetocut) { // default is 4 + flagPi[i] = true; + registry.get(HIST("pidTPC/hpvsdedxElHipCut5"))->Fill(tmpMomentum[i], tmpDedx[i]); + } + if (tmpPt[i] > minPtEtrkcut) { // 0.25 + flagPt[i] = true; + registry.get(HIST("pidTPC/hpvsdedxElHipCut6"))->Fill(tmpMomentum[i], tmpDedx[i]); + } + if (!flagVcalPV[i]) { + registry.get(HIST("pidTPC/hpvsdedxElHipCut7"))->Fill(tmpMomentum[i], tmpDedx[i]); + } + flagTotal[i] = flagEl[i] && flagPi[i] && flagPt[i] && !flagVcalPV[i]; + } + + int counterM3pi = flagIM[0] + flagIM[1] + flagIM[2] + flagIM[3]; + int counterDphi = flagDP[0] + flagDP[1] + flagDP[2] + flagDP[3]; + int counterEl = flagEl[0] + flagEl[1] + flagEl[2] + flagEl[3]; + int counterPi = flagPi[0] + flagPi[1] + flagPi[2] + flagPi[3]; + int counterPt = flagPt[0] + flagPt[1] + flagPt[2] + flagPt[3]; + int counterVcal = !flagVcalPV[0] + !flagVcalPV[1] + !flagVcalPV[2] + !flagVcalPV[3]; + int counterTotal = flagTotal[0] + flagTotal[1] + flagTotal[2] + flagTotal[3]; + + registry.get(HIST("global/hNCombAfterCut"))->Fill(5. + counterM3pi, 1.); + registry.get(HIST("global/hNCombAfterCut"))->Fill(10. + counterDphi, 1.); + registry.get(HIST("global/hNCombAfterCut"))->Fill(15. + counterEl, 1.); + registry.get(HIST("global/hNCombAfterCut"))->Fill(20. + counterPi, 1.); + registry.get(HIST("global/hNCombAfterCut"))->Fill(25. + counterPt, 1.); + registry.get(HIST("global/hNCombAfterCut"))->Fill(30. + counterVcal, 1.); + registry.get(HIST("global/hNCombAfterCut"))->Fill(35. + counterTotal, 1.); + + // draw control histograms + if (counterEl > 0) { // Nelectrons>0 + for (int i = 0; i < 4; i++) { + if (flagEl[i]) + registry.get(HIST("pidTPC/hpvsdedxElHipCut10"))->Fill(tmpMomentum[i], tmpDedx[i]); + } + registry.get(HIST("global/hEventEff"))->Fill(6., 1.); + if (flagEl[0] * flagPi[0] + flagEl[1] * flagPi[1] + flagEl[2] * flagPi[2] + flagEl[3] * flagPi[3] > 0) { // pi veto + for (int i = 0; i < 4; i++) { + if (flagEl[i] && flagPi[i]) + registry.get(HIST("pidTPC/hpvsdedxElHipCut11"))->Fill(tmpMomentum[i], tmpDedx[i]); + } + registry.get(HIST("global/hEventEff"))->Fill(7., 1.); + if (flagEl[0] * flagPi[0] * !flagVcalPV[0] + + flagEl[1] * flagPi[1] * !flagVcalPV[1] + + flagEl[2] * flagPi[2] * !flagVcalPV[2] + + flagEl[3] * flagPi[3] * !flagVcalPV[3] > + 0) { // vcal veto + for (int i = 0; i < 4; i++) { + if (flagEl[i] && flagPi[i] && !flagVcalPV[i]) + registry.get(HIST("pidTPC/hpvsdedxElHipCut12"))->Fill(tmpMomentum[i], tmpDedx[i]); + } + registry.get(HIST("global/hEventEff"))->Fill(8., 1.); + if (flagEl[0] * flagPi[0] * !flagVcalPV[0] * flagPt[0] + + flagEl[1] * flagPi[1] * !flagVcalPV[1] * flagPt[1] + + flagEl[2] * flagPi[2] * !flagVcalPV[2] * flagPt[2] + + flagEl[3] * flagPi[3] * !flagVcalPV[3] * flagPt[3] > + 0) { // pT veto + for (int i = 0; i < 4; i++) { + if (flagEl[i] && flagPi[i] && !flagVcalPV[i] && flagPt[i]) + registry.get(HIST("pidTPC/hpvsdedxElHipCut13"))->Fill(tmpMomentum[i], tmpDedx[i]); + } + registry.get(HIST("global/hEventEff"))->Fill(9., 1.); + } else { + if (verbose) { + LOGF(debug, " Candidate rejected: all electrons vetoed by piPID+Vcal+pT"); + } + } + } else { + if (verbose) { + LOGF(debug, " Candidate rejected: all electrons vetoed by piPID+Vcal"); + } + } + } else { + if (verbose) { + LOGF(debug, " Candidate rejected: all electrons vetoed by pi PID"); + } + } + } else { // no electron + if (verbose) { + LOGF(debug, " Candidate rejected: no electron PID among 4 tracks"); + } + } // end of Nelectrons check + + // check FIT information + if (FITvetoFlag) { + auto bitMin = 16 - FITvetoWindow; // default is +- 1 bc (1 bit) + auto bitMax = 16 + FITvetoWindow; + for (auto bit = bitMin; bit <= bitMax; bit++) { + if (TESTBIT(dgcand.bbFT0Apf(), bit) || + TESTBIT(dgcand.bbFT0Cpf(), bit) || + TESTBIT(dgcand.bbFV0Apf(), bit) || + TESTBIT(dgcand.bbFDDApf(), bit) || + TESTBIT(dgcand.bbFDDCpf(), bit)) { + return; + } + } + } + + if (counterTotal == 1) { + for (int i = 0; i < 4; i++) { + registry.get(HIST("control/h1CutDcaZ"))->Fill(dcaZ[i]); + registry.get(HIST("control/h1CutDcaXY"))->Fill(dcaXY[i]); + registry.get(HIST("control/h1CutChi2TPC"))->Fill(chi2TPC[i]); + registry.get(HIST("control/h1CutChi2ITS"))->Fill(chi2ITS[i]); + + if (flagTotal[i]) { + FillControlHistos<1>(pi3invMass[i], pi3pt[i], pi3deltaPhi[i], pi3assymav[i], pi3vector[i], pi3scalar[i], pi3etasum[i]); + registry.get(HIST("control/h1Cut3piMassVsPt"))->Fill(pi3invMass[i], pi3pt[i]); + registry.get(HIST("pidTPC/hpvsdedxElHipCut1"))->Fill(tmpMomentum[i], tmpDedx[i]); + registry.get(HIST("global/hFinalPtSpectrumEl"))->Fill(tmpPt[i]); + registry.get(HIST("control/h1CutTPCnclsFindable"))->Fill(nclTPCfind[i]); + } + } + registry.get(HIST("control/h1Cut4trkPtTot"))->Fill(pttot); + registry.get(HIST("control/h1Cut4piMass"))->Fill(mass4pi); + registry.get(HIST("control/h1Cut4trkMassVsPt"))->Fill(mass4pi, pttot); + + registry.get(HIST("global/hEventEff"))->Fill(10., 1.); + } else { // more than 1 electron candidate + if (verbose) { + LOGF(debug, " Candidate rejected: more than one electron candidate"); + } + } // end of Nelectrons check + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc, TaskName{"TauTau13topo"})}; +} diff --git a/Tools/ML/MlResponse.h b/Tools/ML/MlResponse.h index 9adddc17018..48729270d32 100644 --- a/Tools/ML/MlResponse.h +++ b/Tools/ML/MlResponse.h @@ -39,9 +39,9 @@ enum CutDirection { CutNot // do not cut on score }; } // namespace cuts_ml + namespace analysis { - // TypeOutputScore is the type of the output score from o2::ml::OnnxModel (float by default) template class MlResponse @@ -59,6 +59,10 @@ class MlResponse /// \param nClasses is the number of classes for each model void configure(const std::vector& binsLimits, const o2::framework::LabeledArray& cuts, const std::vector& cutDir, const uint8_t& nClasses) { + if (cutDir.size() != nClasses) { + LOG(fatal) << "Number of classes (" << static_cast(nClasses) << ") different from the number of cuts on model scores (" << cutDir.size() << ")! Please check your configurables."; + } + mBinsLimits = binsLimits; mCuts = cuts; mCutDir = cutDir; @@ -68,18 +72,19 @@ class MlResponse mPaths = std::vector(mNModels); } - /// Set models paths to CCDB + /// Set model paths to CCDB /// \param onnxFiles is a vector of onnx file names, one for each bin /// \param ccdbApi is the CCDB API - /// \param pathCCDB is the model path in CCDB + /// \param pathsCCDB is a vector of model paths in CCDB, one for each bin /// \param timestampCCDB is the CCDB timestamp + /// \note On the CCDB, different models must be stored in different folders void setModelPathsCCDB(const std::vector& onnxFiles, const o2::ccdb::CcdbApi& ccdbApi, const std::vector& pathsCCDB, int64_t timestampCCDB) { if (onnxFiles.size() != mNModels) { LOG(fatal) << "Number of expected models (" << mNModels << ") different from the one set (" << onnxFiles.size() << ")! Please check your configurables."; } if (pathsCCDB.size() != mNModels) { - LOG(fatal) << "Number of expected models (" << mNModels << ") different from the number of paths (" << onnxFiles.size() << ")! Please check your configurables."; + LOG(fatal) << "Number of expected models (" << mNModels << ") different from the number of CCDB paths (" << pathsCCDB.size() << ")! Please check your configurables."; } for (auto iFile{0}; iFile < mNModels; ++iFile) { @@ -88,24 +93,23 @@ class MlResponse if (retrieveSuccess) { mPaths[iFile] = onnxFiles[iFile]; } else { - LOG(fatal) << "Error encountered while accessing the ML model from CCDB! Maybe the ML model doesn't exist yet for this runnumber/timestamp?"; + LOG(fatal) << "Error encountered while accessing the ML model from " << pathsCCDB[iFile] << "! Maybe the ML model doesn't exist yet for this run number or timestamp?"; } } } - /// Set models paths to local or cvmfs + /// Set model paths to local or cvmfs /// \param onnxFiles is a vector of onnx file names, one for each bin void setModelPathsLocal(const std::vector& onnxFiles) { if (onnxFiles.size() != mNModels) { LOG(fatal) << "Number of expected models (" << mNModels << ") different from the one set (" << onnxFiles.size() << ")! Please check your configurables."; } - mPaths = onnxFiles; } /// Initialize class instance (initialize OnnxModels) - /// \param enableOptimizations is a switch no enable optimizations + /// \param enableOptimizations is a switch to enable optimizations /// \param threads is the number of active threads void init(bool enableOptimizations = false, int threads = 0) { @@ -125,7 +129,7 @@ class MlResponse if (mAvailableInputFeatures.count(inputFeature)) { mCachedIndices.emplace_back(mAvailableInputFeatures[inputFeature]); } else { - LOG(fatal) << "Input feature " << inputFeature << " not available. Please check your configurables."; + LOG(fatal) << "Input feature " << inputFeature << " not available! Please check your configurables."; } } } @@ -137,35 +141,22 @@ class MlResponse template std::vector getModelOutput(T1& input, const T2& nModel) { + if (nModel < 0 || static_cast(nModel) >= mModels.size()) { + LOG(fatal) << "Model index " << nModel << " is out of range! The number of initialised models is " << mModels.size() << ". Please check your configurables."; + } + TypeOutputScore* outputPtr = mModels[nModel].evalModel(input); return std::vector{outputPtr, outputPtr + mNClasses}; } - /// Finds pT bin in an array. - /// \param bins array of pT bins - /// \param value pT - /// \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) - { - if (value < binsPt->front()) { - return -1; - } - if (value >= binsPt->back()) { - return -1; - } - return std::distance(binsPt->begin(), std::upper_bound(binsPt->begin(), binsPt->end(), value)) - 1; - } - /// ML selections /// \param input is the input features - /// \param pt is the candidate transverse momentum + /// \param candVar is the variable value (e.g. pT) used to select which model to use /// \return boolean telling if model predictions pass the cuts template - bool isSelectedMl(T1& input, const T2& pt) + bool isSelectedMl(T1& input, const T2& candVar) { - auto nModel = findBin(&mBinsLimits, pt); + int nModel = findBin(candVar); auto output = getModelOutput(input, nModel); uint8_t iClass{0}; for (const auto& outputValue : output) { @@ -185,13 +176,13 @@ class MlResponse /// ML selections /// \param input is the input features - /// \param pt is the candidate transverse momentum + /// \param candVar is the variable value (e.g. pT) used to select which model to use /// \param output is a container to be filled with model output /// \return boolean telling if model predictions pass the cuts template - bool isSelectedMl(T1& input, const T2& pt, std::vector& output) + bool isSelectedMl(T1& input, const T2& candVar, std::vector& output) { - auto nModel = findBin(&mBinsLimits, pt); + int nModel = findBin(candVar); output = getModelOutput(input, nModel); uint8_t iClass{0}; for (const auto& outputValue : output) { @@ -218,9 +209,26 @@ class MlResponse std::vector mCutDir = {}; // direction of the cuts on the model scores (no cut is also supported) o2::framework::LabeledArray mCuts = {}; // array of cut values to apply on the model scores std::map mAvailableInputFeatures; // map of available input features - std::vector mCachedIndices; // vector of indices correspondance between configurable and available input features + std::vector mCachedIndices; // vector of index correspondance between configurables and available input features virtual void setAvailableInputFeatures() { return; } // method to fill the map of available input features + + private: + /// Finds matching bin in mBinsLimits + /// \param value e.g. pT + /// \return index of the matching bin, used to access mModels + /// \note Accounts for the offset due to mBinsLimits storing bin limits (same convention as needed to configure a histogram axis) + template + int findBin(T const& value) + { + if (value < mBinsLimits.front()) { + return -1; + } + if (value >= mBinsLimits.back()) { + return -1; + } + return std::distance(mBinsLimits.begin(), std::upper_bound(mBinsLimits.begin(), mBinsLimits.end(), value)) - 1; + } }; } // namespace analysis diff --git a/Tutorials/CMakeLists.txt b/Tutorials/CMakeLists.txt index feb0d900122..8a77f3dead9 100644 --- a/Tutorials/CMakeLists.txt +++ b/Tutorials/CMakeLists.txt @@ -112,6 +112,11 @@ o2physics_add_dpl_workflow(mc-histograms PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore COMPONENT_NAME AnalysisTutorial) +o2physics_add_dpl_workflow(mc-only + SOURCES src/mcOnly.cxx + PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore + COMPONENT_NAME AnalysisTutorial) + o2physics_add_dpl_workflow(ccdbaccess SOURCES src/ccdbaccess.cxx PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore O2::CCDB O2::Framework O2Physics::AnalysisCore diff --git a/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask1.cxx b/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask1.cxx index 272b2ddcaa0..acb7f799a7c 100644 --- a/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask1.cxx +++ b/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask1.cxx @@ -16,8 +16,8 @@ #include "Framework/runDataProcessing.h" /// FemtoDream includes -#include "PWGCF/FemtoDream/FemtoDreamMath.h" -#include "PWGCF/FemtoDream/FemtoUtils.h" +#include "PWGCF/FemtoDream/Core/femtoDreamMath.h" +#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" #include "PWGCF/DataModel/FemtoDerived.h" using namespace o2; diff --git a/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask2.cxx b/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask2.cxx index 3f0c43ccbe7..83894c509b2 100644 --- a/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask2.cxx +++ b/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask2.cxx @@ -16,8 +16,8 @@ #include "Framework/runDataProcessing.h" /// FemtoDream includes -#include "PWGCF/FemtoDream/FemtoDreamMath.h" -#include "PWGCF/FemtoDream/FemtoUtils.h" +#include "PWGCF/FemtoDream/Core/femtoDreamMath.h" +#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" #include "PWGCF/DataModel/FemtoDerived.h" using namespace o2; diff --git a/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask3.cxx b/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask3.cxx index 5924a06aa42..909bcc135f6 100644 --- a/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask3.cxx +++ b/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask3.cxx @@ -16,8 +16,8 @@ #include "Framework/runDataProcessing.h" /// FemtoDream includes -#include "PWGCF/FemtoDream/FemtoDreamMath.h" -#include "PWGCF/FemtoDream/FemtoUtils.h" +#include "PWGCF/FemtoDream/Core/femtoDreamMath.h" +#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" #include "PWGCF/DataModel/FemtoDerived.h" using namespace o2; diff --git a/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask4.cxx b/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask4.cxx index 8e31351fc0d..a7cf45f84a6 100644 --- a/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask4.cxx +++ b/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask4.cxx @@ -16,8 +16,8 @@ #include "Framework/runDataProcessing.h" /// FemtoDream includes -#include "PWGCF/FemtoDream/FemtoDreamMath.h" -#include "PWGCF/FemtoDream/FemtoUtils.h" +#include "PWGCF/FemtoDream/Core/femtoDreamMath.h" +#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" #include "PWGCF/DataModel/FemtoDerived.h" using namespace o2; diff --git a/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask5.cxx b/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask5.cxx index a1f74f745e1..8ed8b1488ff 100644 --- a/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask5.cxx +++ b/Tutorials/PWGCF/FemtoFramework/src/CFTutorialTask5.cxx @@ -17,8 +17,8 @@ #include "TDatabasePDG.h" /// FemtoDream includes -#include "PWGCF/FemtoDream/FemtoDreamMath.h" -#include "PWGCF/FemtoDream/FemtoUtils.h" +#include "PWGCF/FemtoDream/Core/femtoDreamMath.h" +#include "PWGCF/FemtoDream/Core/femtoDreamUtils.h" #include "PWGCF/DataModel/FemtoDerived.h" using namespace o2; diff --git a/Tutorials/Skimming/jetProvider.cxx b/Tutorials/Skimming/jetProvider.cxx index 5b5c30dbecb..5883d3471c9 100644 --- a/Tutorials/Skimming/jetProvider.cxx +++ b/Tutorials/Skimming/jetProvider.cxx @@ -37,21 +37,13 @@ struct JetProviderTask { Filter jetCuts = aod::jet::pt > jetPtMin; void process(soa::Filtered>::iterator const& jet, - aod::Tracks const& tracks, - aod::ChargedJetConstituentsSub const& constituentsSub) + aod::Tracks const& tracks) { outputJets(jet.pt(), jet.eta(), jet.phi(), jet.energy(), jet.mass(), jet.area()); if (keepConstituents) { - if (DoConstSub) { - outputConstituents.reserve(constituentsSub.size()); - for (const auto& constituent : constituentsSub) { - outputConstituents(outputJets.lastIndex(), constituent.pt(), constituent.eta(), constituent.phi()); - } - } else { - outputConstituents.reserve(jet.tracks().size()); - for (const auto& constituent : jet.tracks_as()) { - outputConstituents(outputJets.lastIndex(), constituent.pt(), constituent.eta(), constituent.phi()); - } + outputConstituents.reserve(jet.tracks().size()); + for (const auto& constituent : jet.tracks_as()) { + outputConstituents(outputJets.lastIndex(), constituent.pt(), constituent.eta(), constituent.phi()); } } } diff --git a/Tutorials/Skimming/jetSpectraReference.cxx b/Tutorials/Skimming/jetSpectraReference.cxx index 4e10a48a90f..79aa60fa70a 100644 --- a/Tutorials/Skimming/jetSpectraReference.cxx +++ b/Tutorials/Skimming/jetSpectraReference.cxx @@ -38,26 +38,16 @@ struct JetSpectraReference { {"hNJetConstituents", "Number of constituents;N;entries", {HistType::kTH1F, {{100, -0.5, 99.5}}}}, {"hConstituentPt", "Constituent pT; Constituent #it{p}_{T} (GeV/#it{c});entries", {HistType::kTH1F, {{100, 0., 100.}}}}}}; - //Configurable f_jetPtMin{"f_jetPtMin", 0.0, "minimum jet pT cut"}; - Configurable b_DoConstSub{"b_DoConstSub", false, "do constituent subtraction"}; - - //Filter jetCuts = aod::jet::pt > f_jetPtMin; //how does this work? + // Configurable f_jetPtMin{"f_jetPtMin", 0.0, "minimum jet pT cut"}; + // Filter jetCuts = aod::jet::pt > f_jetPtMin; //how does this work? void process(soa::Join::iterator const& jet, - aod::Tracks const& tracks, - aod::ChargedJetConstituentsSub const& constituentsSub) + aod::Tracks const& tracks) { registry.fill(HIST("hJetPt"), jet.pt()); - if (b_DoConstSub) { - registry.fill(HIST("hNJetConstituents"), constituentsSub.size()); - for (const auto& constituent : constituentsSub) { - registry.fill(HIST("hConstituentPt"), constituent.pt()); - } - } else { - registry.fill(HIST("hNJetConstituents"), jet.tracks().size()); - for (auto& constituent : jet.tracks_as()) { - registry.fill(HIST("hConstituentPt"), constituent.pt()); - } + registry.fill(HIST("hNJetConstituents"), jet.tracks().size()); + for (auto& constituent : jet.tracks_as()) { + registry.fill(HIST("hConstituentPt"), constituent.pt()); } } }; diff --git a/Tutorials/src/mcOnly.cxx b/Tutorials/src/mcOnly.cxx new file mode 100644 index 00000000000..e72295ecb3a --- /dev/null +++ b/Tutorials/src/mcOnly.cxx @@ -0,0 +1,93 @@ +// 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 Accessing MC data and the related MC truth. +/// \author +/// \since + +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "CommonConstants/MathConstants.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "TDatabasePDG.h" + +using namespace o2; +using namespace o2::framework; +using namespace constants::math; + +// Simple access to collision +struct VertexDistribution { + OutputObj vertex{TH1F("vertex", "vertex", 100, -10, 10)}; + + Configurable reduceOutput{"reduce-output", 0, "Suppress info level output (0 = all output, 1 = per collision, 2 = none)"}; + + // loop over MC truth McCollisions + void process(aod::McCollision const& mcCollision) + { + if (reduceOutput < 2) { + LOGF(info, "MC. vtx-z = %f", mcCollision.posZ()); + } + vertex->Fill(mcCollision.posZ()); + } +}; + +// Grouping between MC particles and collisions +struct AccessMcData { + OutputObj phiH{TH1F("phi", "phi", 100, 0., TwoPI)}; + OutputObj etaH{TH1F("eta", "eta", 102, -2.01, 2.01)}; + + Configurable reduceOutput{"reduce-output", 0, "Suppress info level output (0 = all output, 1 = per collision, 2 = none)"}; + + // group according to McCollisions + void process(aod::McCollision const& mcCollision, aod::McParticles const& mcParticles) + { + // access MC truth information with mcCollision() and mcParticle() methods + if (reduceOutput < 2) { + LOGF(info, "MC. vtx-z = %f", mcCollision.posZ()); + LOGF(info, "First: %d | Length: %d", mcParticles.begin().index(), mcParticles.size()); + } + int count = 0; + for (auto& mcParticle : mcParticles) { + if (mcParticle.isPhysicalPrimary()) { + phiH->Fill(mcParticle.phi()); + etaH->Fill(mcParticle.eta()); + count++; + // Loop over mothers and daughters + if (mcParticle.has_mothers()) { + // Check first mother + auto const& mother = mcParticle.mothers_first_as(); + if (reduceOutput == 0) { + LOGF(info, "First mother: %d has pdg code %d", mother.globalIndex(), mother.pdgCode()); + } + // Loop over all mothers (needed for some MCs with junctions etc.) + for (auto& m : mcParticle.mothers_as()) { + LOGF(debug, "M2 %d %d", mcParticle.globalIndex(), m.globalIndex()); + } + } + if (mcParticle.has_daughters()) { + for (auto& d : mcParticle.daughters_as()) { + LOGF(debug, "D2 %d %d", mcParticle.globalIndex(), d.globalIndex()); + } + } + } + } + if (reduceOutput < 2) { + LOGF(info, "Primaries for this collision: %d", count); + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + adaptAnalysisTask(cfgc)}; +}